pax_global_header00006660000000000000000000000064145626220140014514gustar00rootroot0000000000000052 comment=3f51346f3f04dd16f4e7adde78e4e4adc19fab68 paperwork-2.2.2/000077500000000000000000000000001456262201400135315ustar00rootroot00000000000000paperwork-2.2.2/.gitignore000066400000000000000000000020231456262201400155160ustar00rootroot00000000000000*~ *.tar.gz *.aux *.pyc build paperwork.conf paperwork_repo/ dist/ out/ paperwork.egg-info/ .idea *.traineddata *.app/ .flatpak-builder/ repo/ *.flatpak venv*/ *.pyo _version.py *.exe *.dll out.* rclone* AUTHORS.json AUTHORS.git.json paperwork_repo/ .buildozer/ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python env/ build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *,cover .hypothesis/ # Django stuff: *.log # Sphinx documentation _build/ # PyBuilder target/ #Ipython Notebook .ipynb_checkpoints # Appimage AppDir/ appimage-build/ *.AppImage* paperwork-2.2.2/.gitlab-ci.yml000066400000000000000000000251531456262201400161730ustar00rootroot00000000000000# image: $CI_REGISTRY_IMAGE/build:latest image: registry.gitlab.gnome.org/world/openpaperwork/paperwork/build:latest variables: GIT_STRATEGY: clone GIT_SUBMODULE_STRATEGY: none GIT_FETCH_EXTRA_FLAGS: --tags stages: # no point in waiting for the tests to end before generating the data files # or the development documentation - build_img - tests - data - deploy build_img: stage: build_img rules: - if: $CI_PIPELINE_SOURCE == "schedule" - if: $CI_PIPELINE_SOURCE == "web" - if: $CI_COMMIT_BRANCH == "main" changes: - ci/Dockerfile - if: $CI_COMMIT_BRANCH == "testing" changes: - ci/Dockerfile - if: $CI_COMMIT_BRANCH == "develop" changes: - ci/Dockerfile tags: - openpaper-flatpak script: # make sure to fetch the latest Debian image - docker system prune -f - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE/build:latest ci - docker push $CI_REGISTRY_IMAGE/build:latest check: stage: tests script: - source ./activate_test_env.sh && make check test: stage: tests script: - apt-get update - source ./activate_test_env.sh && pip3 install -U setuptools - source ./activate_test_env.sh && make install - source ./activate_test_env.sh && paperwork-gtk chkdeps -y - source ./activate_test_env.sh && paperwork-cli chkdeps -y - source ./activate_test_env.sh && make test test_chkdeps: image: debian:testing stage: tests script: - apt-get update # bare minimum to install Paperwork from sources - apt-get install -y build-essential gettext git libcairo2-dev libgirepository1.0-dev make python3 python3-dev python3-pip python3-virtualenv wget - virtualenv -p python3 /venv - source /venv/bin/activate && pip3 install -U setuptools - source /venv/bin/activate && make install - source /venv/bin/activate && paperwork-json chkdeps generate_data: stage: data script: - apt-get update - source ./activate_test_env.sh && pip3 install -U setuptools - source ./activate_test_env.sh && make install - source ./activate_test_env.sh && xvfb-run paperwork-gtk chkdeps -y - source ./activate_test_env.sh && xvfb-run paperwork-cli chkdeps -y - source ./activate_test_env.sh && make data upload_data doc_devel: stage: data script: - source ./activate_test_env.sh && pip3 install -U setuptools - source ./activate_test_env.sh && make doc - source ./activate_test_env.sh && make upload_doc linux_flatpak: stage: deploy timeout: 48h only: - branches@World/OpenPaperwork/paperwork - tags@World/OpenPaperwork/paperwork tags: - openpaper-flatpak script: # workaround error 'fatal: transport 'file' not allowed' - git config --global --add protocol.file.allow always # Running in from a gitlab-runner directly in a shell, as the user # 'gitlab-runner' # --> not running as root, so we cannot actually install anything # - apt-get update # - apt-get install -y -q rsync flatpak-builder make jq moreutils - ./ci/update_flatpak_repo.sh linux_appimage: stage: deploy timeout: 3h script: - virtualenv -p python3 /venv - source /venv/bin/activate && pip3 install -U setuptools - source /venv/bin/activate && pip3 install appimage-builder # Build - source /venv/bin/activate && make linux_exe - ./ci/deliver.sh paperwork-gtk/Paperwork-gtk-latest-x86_64.AppImage linux .appimage paperwork-gtk - ./ci/deliver.sh paperwork-shell/Paperwork-cli-latest-x86_64.AppImage linux .appimage paperwork-cli - ./ci/deliver.sh paperwork-shell/Paperwork-json-latest-x86_64.AppImage linux .appimage paperwork-json artifacts: expire_in: 2 days paths: - paperwork-gtk/Paperwork-gtk-latest-x86_64.AppImage - paperwork-shell/Paperwork-cli-latest-x86_64.AppImage - paperwork-shell/Paperwork-json-latest-x86_64.AppImage .windows: &windows variables: MSYSTEM: "MINGW64" CHERE_INVOKING: "yes" before_script: # Libinsane build dependencies - c:\msys64\usr\bin\pacman --needed --noconfirm -S make - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-cunit - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-doxygen - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-gcc - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-gobject-introspection - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-meson - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-gobject - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-vala # Paperwork build dependencies - c:\msys64\usr\bin\pacman --needed --noconfirm -S git # for 'make version' - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-ca-certificates - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-cairo - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-gdk-pixbuf2 - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-gettext - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-gtk3 - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-libhandy - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-libnotify - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-nsis - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-nsis-nsisunz - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-poppler - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-cairo - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-cx-freeze - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-psutil - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-pillow - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-pip - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-scikit-learn - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-setuptools - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-virtualenv - c:\msys64\usr\bin\pacman --needed --noconfirm -S wget # for downloading data files - c:\msys64\usr\bin\pacman --needed --noconfirm -S zip unzip # do not use the checkout from gitlab-runner. For some unknown reason, it mess up # setuptools_scm - c:\msys64\usr\bin\bash -lc "rm -rf /tmp/paperwork" - c:\msys64\usr\bin\bash -lc "rm -rf /tmp/venv" - c:\msys64\usr\bin\bash -lc "cd /tmp && git clone https://gitlab.gnome.org/World/OpenPaperwork/paperwork.git -b $CI_COMMIT_REF_NAME" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && git describe --tags --always" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && git submodule init" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && git submodule update --recursive --remote" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make clean" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make uninstall" # libinsane is not a Python library and therefore is installed system-wide - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make -C sub/libinsane uninstall PREFIX=/mingw64 || true" # a 2nd time just to be really sure # (that's the problem when can't use containers ..) - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make uninstall" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make -C sub/libinsane uninstall PREFIX=/mingw64 || true" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make -C sub/libinsane clean PREFIX=/mingw64 || true" # actual install - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make -C sub/libinsane install PREFIX=/mingw64" - c:\msys64\usr\bin\bash -lc "virtualenv --system-site-packages /tmp/venv" # Workaround for pycountry and Cx_freeze # See https://github.com/marcelotduarte/cx_Freeze/issues/930 - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && pip3 uninstall -y pycountry" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && pip3 install --no-cache --use-pep517 pycountry==20.7.3" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && make -C sub/libpillowfight install_py" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && make -C sub/pyocr install_py" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && make install" windows_tests: stage: tests only: - branches@World/OpenPaperwork/paperwork - tags@World/OpenPaperwork/paperwork tags: - windows - msys2 <<: *windows script: # Tesseract (required for unit tests) - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-libarchive # missing tesseract dependency - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-python-pytest - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-tesseract-ocr - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-tesseract-data-eng - c:\msys64\usr\bin\pacman --needed --noconfirm -S mingw-w64-x86_64-tesseract-data-fra # Build - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && export TESSDATA_PREFIX=/mingw64/share/tessdata && make test" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make uninstall" windows_exe: stage: deploy only: - branches@World/OpenPaperwork/paperwork - tags@World/OpenPaperwork/paperwork tags: - windows - msys2 <<: *windows artifacts: expire_in: 2 days paths: - dist/paperwork.zip script: # We need rclone to upload the files on OVH object storage - c:\msys64\usr\bin\rm -f rclone-v1.53.3-windows-386.zip - c:\msys64\usr\bin\rm -rf rclone-v1.53.3-windows-386 - c:\msys64\usr\bin\wget -q https://github.com/rclone/rclone/releases/download/v1.53.3/rclone-v1.53.3-windows-386.zip - c:\msys64\usr\bin\unzip rclone-v1.53.3-windows-386.zip - c:\msys64\usr\bin\cp rclone-v1.53.3-windows-386/rclone.exe /usr/bin # Build - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && pip install cx_Freeze" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && . /tmp/venv/bin/activate && export && make windows_exe" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && ./ci/deliver.sh dist/paperwork.zip windows .zip" - c:\msys64\usr\bin\bash -lc "cd /tmp/paperwork && make uninstall" paperwork-2.2.2/.gitmodules000066400000000000000000000005371456262201400157130ustar00rootroot00000000000000[submodule "sub/libinsane"] path = sub/libinsane url = https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git [submodule "sub/pyocr"] path = sub/pyocr url = https://gitlab.gnome.org/World/OpenPaperwork/pyocr.git [submodule "sub/libpillowfight"] path = sub/libpillowfight url = https://gitlab.gnome.org/World/OpenPaperwork/libpillowfight.git paperwork-2.2.2/AUTHORS.ui.json000066400000000000000000000002001456262201400161550ustar00rootroot00000000000000[ { "UI and UX": [ ["", "Mathieu Jourdan", 75], ["", "Jerome Flesch", 25] ] } ] paperwork-2.2.2/CONTRIBUTING.md000066400000000000000000000001411456262201400157560ustar00rootroot00000000000000[Moved to the wiki](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/-/wikis/Contributing) paperwork-2.2.2/LICENSE000066400000000000000000001045051456262201400145430ustar00rootroot00000000000000 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. {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year} {name of author} 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: {project} Copyright (C) {year} {fullname} 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 . paperwork-2.2.2/Makefile000066400000000000000000000126571456262201400152040ustar00rootroot00000000000000# order matters (dependencies) ALL_COMPONENTS = \ openpaperwork-core \ openpaperwork-gtk \ paperwork-backend \ paperwork-shell \ paperwork-gtk RELEASE ?= build: openpaperwork-core_install_py: echo "Installing openpaperwork-core" $(MAKE) -C openpaperwork-core install_py %_install_py: openpaperwork-core_install_py echo "Installing $(@:%_install_py=%)" $(MAKE) -C $(@:%_install_py=%) install_py clean: $(ALL_COMPONENTS:%=%_clean) rm -rf build dist rm -rf venv rm -f data.tar.gz make -C sub/libinsane clean || true make -C sub/libpillowfight clean || true make -C sub/pyocr clean || true install_py: download_data $(ALL_COMPONENTS:%=%_install_py) install: install_py uninstall: $(ALL_COMPONENTS:%=%_uninstall) uninstall_py: $(ALL_COMPONENTS:%=%_uninstall_py) uninstall_c: $(ALL_COMPONENTS:%=%_uninstall_c) check: $(ALL_COMPONENTS:%=%_check) test: $(ALL_COMPONENTS:%=%_test) data: $(ALL_COMPONENTS:%=%_data) upload_data: data tar -cvzf data.tar.gz \ paperwork-backend/src/paperwork_backend/authors/*.json \ paperwork-gtk/src/paperwork_gtk/model/help/out/*.pdf \ paperwork-gtk/src/paperwork_gtk/icon/out/*.png ci/deliver_data.sh data.tar.gz data.tar.gz: ci/download_data.sh data.tar.gz download_data: data.tar.gz tar -xvzf data.tar.gz doc: $(ALL_COMPONENTS:%=%_doc) upload_doc: $(ALL_COMPONENTS:%=%_upload_doc) release_pypi: download_data l10n_compile $(MAKE) $(ALL_COMPONENTS:%=%_release_pypi) RELEASE=${RELEASE} release: $(ALL_COMPONENTS:%=%_release) ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" @echo "Also makes sure to update:" @echo "- AUTHORS.ui.json" exit 1 else @echo "Will release: ${RELEASE}" git tag -a ${RELEASE} -m ${RELEASE} git push origin ${RELEASE} make clean make release_pypi @echo "All done" @echo "IMPORTANT: Don't forgot to add the latest release on Flathub !" endif linux_exe: $(ALL_COMPONENTS:%=%_linux_exe) libinsane_win64: ${MAKE} -C sub/libinsane clean ${MAKE} -C sub/libinsane install PREFIX=/mingw64 pyocr_win64: ${MAKE} -C sub/pyocr install libpillowfight_win64: ${MAKE} -C sub/libpillowfight install_py windows_exe: # dirty hack to make cx_freeze happy # Cx_freeze looks for a file sqlite3.dll whereas in MSYS2, it's called # libsqlite3-0.dll mkdir -p /mingw64/DLLs cp /mingw64/bin/libsqlite3-0.dll /mingw64/DLLs/sqlite3.dll rm -rf $(CURDIR)/build/exe $(MAKE) $(ALL_COMPONENTS:%=%_windows_exe) # a bunch of things are missing mkdir -p $(CURDIR)/build/exe/lib cp -Ra /mingw64/lib/gdk-pixbuf-2.0 $(CURDIR)/build/exe/lib # 2nd part of the dirty hack to make cx_freeze happy rm -f $(CURDIR)/build/exe/lib/sqlite3.dll mkdir -p $(CURDIR)/build/exe/share cp -Ra /mingw64/share/icons $(CURDIR)/build/exe/share cp -Ra /mingw64/share/locale $(CURDIR)/build/exe/share cp -Ra /mingw64/share/themes $(CURDIR)/build/exe/share cp -Ra /mingw64/share/fontconfig $(CURDIR)/build/exe/share cp -Ra /mingw64/share/poppler $(CURDIR)/build/exe/share cp -Ra /mingw64/share/glib-2.0 $(CURDIR)/build/exe/share mkdir -p dist (cd $(CURDIR)/build/exe ; zip -r ../../dist/paperwork.zip *) l10n_extract: $(ALL_COMPONENTS:%=%_l10n_extract) l10n_compile: $(ALL_COMPONENTS:%=%_l10n_compile) help: @echo "make build: run 'python3 ./setup.py build' in all components" @echo "make clean" @echo "make help: display this message" @echo "make install : run 'python3 ./setup.py install' on all components" @echo "make release" @echo "make uninstall : run 'pip3 uninstall -y (component)' on all components" @echo "make l10n_extract" @echo "make l10n_compile" @echo "Components:" ${ALL_COMPONENTS} %_check: echo "Checking $(@:%_check=%)" $(MAKE) -C $(@:%_check=%) check %_test: echo "Testing $(@:%_test=%)" $(MAKE) -C $(@:%_test=%) test %_upload_doc: echo "Uploading doc of $(@:%_upload_doc=%)" $(MAKE) -C $(@:%_upload_doc=%) upload_doc %_doc: echo "Generating doc of $(@:%_doc=%)" $(MAKE) -C $(@:%_doc=%) doc %_data: echo "Generating data files of $(@:%_data=%)" $(MAKE) -C $(@:%_data=%) data %_clean: echo "Cleaning $(@:%_clean=%)" $(MAKE) -C $(@:%_clean=%) clean %_uninstall: echo "Uninstalling $(@:%_uninstall=%)" $(MAKE) -C $(@:%_uninstall=%) uninstall %_uninstall_py: echo "Uninstalling $(@:%_uninstall_py=%)" $(MAKE) -C $(@:%_uninstall=%) uninstall_py %_uninstall_c: echo "Uninstalling $(@:%_uninstall_c=%)" $(MAKE) -C $(@:%_uninstall=%) uninstall_c %_release: echo "Releasing $(@:%_release=%)" $(MAKE) -C $(@:%_release=%) release RELEASE=$(RELEASE) %_release_pypi: echo "Releasing $(@:%_release_pypi=%)" $(MAKE) -C $(@:%_release_pypi=%) release_pypi %_linux_exe: echo "Building Linux exe for $(@:%_linux_exe=%)" $(MAKE) -C $(@:%_linux_exe=%) linux_exe %_windows_exe: l10n_compile download_data libinsane_win64 pyocr_win64 libpillowfight_win64 echo "Building Windows exe for $(@:%_windows_exe=%)" $(MAKE) -C $(@:%_windows_exe=%) windows_exe %_l10n_extract: echo "Extracting translatable strings from $(@:%_l10n_extract=%)" $(MAKE) -C $(@:%_l10n_extract=%) l10n_extract %_l10n_compile: echo "Compiling translated strings for $(@:%_l10n_compile=%)" $(MAKE) -C $(@:%_l10n_compile=%) l10n_compile venv: echo "Building virtual env" make -C sub/libinsane build_c virtualenv -p python3 --system-site-packages venv .PHONY: help build clean test check install install_py install_c uninstall \ uninstall_c uninstall_py release release_pypi libinsane_win64 \ pyocr_win64 libpillowfight_win64 doc upload_doc data upload_data \ download_data l10n_extract l10n_compile paperwork-2.2.2/README.markdown000066400000000000000000000075311456262201400162400ustar00rootroot00000000000000# Paperwork - [openpaper.work](https://openpaper.work/) ## Description Paperwork is a personal document manager. It manages scanned documents and PDFs. It's designed to be easy and fast to use. The idea behind Paperwork is "scan & forget": You can just scan a new document and forget about it until the day you need it again. In other words, let the machine do most of the work for you. ## Screenshots ### Main Window ### Search Suggestions ### Labels ### Settings window ### Command line ![Command line](https://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/search.gif) ## Main features * Scan * Automatic detection of page orientation * OCR * Document labels * Automatic guessing of the labels to apply on new documents * Search * Keyword suggestions * Quick edit of scans * PDF support * [Kick-ass command line interface](/paperwork-shell/README.markdown) Papers are organized into documents. Each document contains pages. ## Installation See [OpenPaper.work](https://openpaper.work/) ## Development * [GNU/Linux](doc/install.devel.markdown) * [Microsoft Windows](doc/devel.windows.markdown) ## Uninstallation ### GNU/Linux [Doc](doc/uninstall.linux.markdown) ### Windows If you used the installer from [OpenPaper](https://openpaper.work), Paperwork can be uninstalled like any other Windows application (something like Control Panel --> Applications --> Uninstall). If you installed it manually (for development), you can follow the same process than for [GNU/Linux](doc/uninstall.linux.markdown) ## Contact/Help * [Extra documentation / FAQ / Tips / Wiki](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/) * [Forum](https://forum.openpaper.work/) * [IRC](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contact#irc) * [Bug tracker](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contact#bug-trackers) * [Contributing to Paperwork](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contributing) ## Details It mainly uses: * [Sane](http://www.sane-project.org/)/[Libinsane](https://gitlab.gnome.org/World/OpenPaperwork/libinsane#readme): To scan the pages * [Tesseract](https://github.com/tesseract-ocr)/[Pyocr](https://gitlab.gnome.org/World/OpenPaperwork/pyocr#readme): To extract the words from the pages (OCR) * [GTK](https://www.gtk.org/): For the user interface * [Whoosh](https://pypi.python.org/pypi/Whoosh/): To index and search documents, and provide keyword suggestions * [Scikit-learn](https://scikit-learn.org/): To guess the labels * [Pillow](https://pypi.python.org/pypi/Pillow/)/[Libpillowfight](https://gitlab.gnome.org/World/OpenPaperwork/libpillowfight): Image manipulation ## Licence GPLv3 or later. See COPYING. ## Development All the information can be found on [the wiki](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis). paperwork-2.2.2/activate_test_env.sh000077500000000000000000000004601456262201400175770ustar00rootroot00000000000000if ! [ -e sub/libinsane/Makefile ] ; then git submodule init git submodule update --recursive --remote --init fi make venv && \ source venv/bin/activate && \ cd sub/libinsane && \ source ./activate_test_env.sh && \ cd ../.. && \ make -C sub/pyocr install_py && \ make -C sub/libpillowfight install_py paperwork-2.2.2/ci/000077500000000000000000000000001456262201400141245ustar00rootroot00000000000000paperwork-2.2.2/ci/Dockerfile000066400000000000000000000035741456262201400161270ustar00rootroot00000000000000FROM debian:sid RUN mkdir -p /usr/share/man/man1 RUN apt-get update \ && apt-get install -y -q \ binutils \ build-essential \ ca-certificates \ cmake \ coreutils \ desktop-file-utils \ doxygen \ fakeroot \ flake8 \ fuse3 \ gcc \ gettext \ git \ gobject-introspection \ graphviz \ gtk-doc-tools \ imagemagick \ libcunit1-ncurses-dev \ libgdk-pixbuf2.0-dev \ libgirepository1.0-dev \ libgtk-3-dev \ libjpeg-dev \ libreoffice \ libsane-dev \ make \ meson \ openjdk-11-jre \ patchelf \ plantuml \ po4a \ pycodestyle \ python3 \ python3-dev \ python3-gi \ python3-importlib-metadata \ python3-pefile \ python3-pil \ python3-pip \ python3-pkg-resources \ python3-recommonmark \ python3-scipy \ python3-sphinx \ python3-sphinxcontrib.plantuml \ python3-virtualenv \ python3-wheel \ rclone \ squashfs-tools \ strace \ texlive \ texlive-lang-english \ texlive-lang-french \ texlive-lang-german \ texlive-latex-extra \ texlive-latex-recommended \ tox \ util-linux \ valac \ valgrind \ virtualenv \ wget \ xvfb \ zlib1g-dev \ zsync \ && apt-get clean # Libinsane build dependencies # WORKAROUND(Jflesch): manpages is required to install some of the # openjdk-jre and openjdk-jre is required for plantuml, which is required # to generate documentation RUN apt-get install --no-install-recommends -y -q \ doxygen \ graphviz \ gtk-doc-tools \ plantuml \ && apt-get clean paperwork-2.2.2/ci/deliver.sh000077500000000000000000000020541456262201400161160ustar00rootroot00000000000000#!/bin/sh binary="$1" os="$2" exe_suffix="$3" name="$4" arch="amd64" if [ -z "$RCLONE_CONFIG_OPENPAPERWORK_ACCESS_KEY_ID" ] ; then echo "Delivery: No rclone credentials provided." exit 0 fi if ! which rclone; then echo "rclone not available." exit 1 fi if [ -z "$name" ] ; then name=paperwork fi echo "Delivering: ${binary} (${CI_COMMIT_REF_NAME} - ${CI_COMMIT_SHORT_SHA})" echo "Destination: ${os}/${arch} (${name} ${exe_suffix})" out_name="${name}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHORT_SHA}${exe_suffix}" latest_name="${name}-${CI_COMMIT_REF_NAME}-latest${exe_suffix}" echo "rclone: ${out_name}" if ! rclone --config ./ci/rclone.conf copyto "${binary}" "openpaperwork:openpaperwork-download/${os}/${arch}/${out_name}" ; then echo "rclone failed" exit 1 fi echo "rclone: ${latest_name}" if ! rclone --config ./ci/rclone.conf copyto \ "openpaperwork:openpaperwork-download/${os}/${arch}/${out_name}" \ "openpaperwork:openpaperwork-download/${os}/${arch}/${latest_name}" ; then echo "rclone failed" exit 1 fi echo Success exit 0 paperwork-2.2.2/ci/deliver_data.sh000077500000000000000000000015701456262201400171110ustar00rootroot00000000000000#!/bin/sh input_file="$1" if ! [ -f "${input_file}" ] ; then echo "You must specify an input file to upload" exit 1 fi if [ -z "$RCLONE_CONFIG_OPENPAPERWORK_ACCESS_KEY_ID" ] ; then echo "Delivery: No rclone credentials provided." exit 0 fi if ! which rclone; then echo "rclone not available." exit 1 fi echo "Delivering: ${input_file} (${CI_COMMIT_REF_NAME} - ${CI_COMMIT_SHORT_SHA})" out_name="${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHORT_SHA}" latest_name="${CI_COMMIT_REF_NAME}_latest" if ! rclone --config ./ci/rclone.conf copy \ "${input_file}" \ "openpaperwork:openpaperwork-download/data/paperwork/${out_name}/" ; then echo "rclone failed" exit 1 fi if ! rclone --config ./ci/rclone.conf sync \ "${input_file}" \ "openpaperwork:openpaperwork-download/data/paperwork/${latest_name}/" ; then echo "rclone failed" exit 1 fi echo Success exit 0 paperwork-2.2.2/ci/deliver_doc.sh000077500000000000000000000016521456262201400167460ustar00rootroot00000000000000#!/bin/sh directory="$1" destination="$2" if ! [ -d "${directory}" ] || [ -z "${destination}" ] ; then echo "You must specify a directory to upload and a destination directory" exit 1 fi if [ -z "$RCLONE_CONFIG_OPENPAPERWORK_ACCESS_KEY_ID" ] ; then echo "Delivery: No rclone credentials provided." exit 0 fi if ! which rclone; then echo "rclone not available." exit 1 fi echo "Delivering: ${directory} (${CI_COMMIT_REF_NAME} - ${CI_COMMIT_SHORT_SHA})" out_name="$(date "+%Y%m%d_%H%M%S")_${CI_COMMIT_REF_NAME}_${CI_COMMIT_SHORT_SHA}" latest_name="latest" if ! rclone --config ./ci/rclone.conf copy \ "${directory}/" \ "openpaperwork:openpaperwork-doc/${destination}/${out_name}" ; then echo "rclone failed" exit 1 fi if ! rclone --config ./ci/rclone.conf sync \ "${directory}/" \ "openpaperwork:openpaperwork-doc/${destination}/latest" ; then echo "rclone failed" exit 1 fi echo Success exit 0 paperwork-2.2.2/ci/download_data.sh000077500000000000000000000017651456262201400172740ustar00rootroot00000000000000#!/bin/sh WGET_OPTS="-q" if [ -n "${CI_COMMIT_REF_NAME}" ] ; then branch="${CI_COMMIT_REF_NAME}" else branch=$(git symbolic-ref -q HEAD) echo "Current ref: ${branch}" branch=${branch##refs/heads/} branch=${branch:-master} echo "Current branch: ${branch}" fi commit="$(git rev-parse --short HEAD)" echo "Current commit: ${commit}" download() { url="$1" out="$2" echo "${url} --> ${out} ..." if wget ${WGET_OPTS} "${url}" -O "${out}" ; then echo "OK" exit 0 fi rm -f "${out}" echo "FAILED" } filename="$1" if [ -f "${filename}" ] ; then echo "File ${filename} already downloaded" exit 0 fi download "https://download.openpaper.work/data/paperwork/${branch}_${commit}/${filename}" "${filename}" echo "[FALLBACK]" download "https://download.openpaper.work/data/paperwork/${branch}_latest/${filename}" "${filename}" echo "[FALLBACK]" download "https://download.openpaper.work/data/paperwork/master_latest/${filename}" "${filename}" echo "FAILED: Unable to download ${filename}" exit 1 paperwork-2.2.2/ci/rclone.conf000066400000000000000000000002301456262201400162500ustar00rootroot00000000000000[openpaperwork] type = s3 env_auth = false region = us-east-1 endpoint = https://objects.openpaper.work/ location_constraint = server_side_encryption = paperwork-2.2.2/ci/update_flatpak_repo.sh000077500000000000000000000054621456262201400205030ustar00rootroot00000000000000#!/usr/bin/bash echo $PWD git log -1 USER=gitlab-runner LOCKDIR=/tmp/build.lock.d PIDFILE=${LOCKDIR}/pid branch="${CI_COMMIT_REF_NAME}" echo "Branch: ${branch}" if [ "${branch}" != "master" ] && [ "${branch}" != "testing" ] && [ "${branch}" != "develop" ]; then echo Nothing to do exit 0 fi msg() { echo "#####" "$@" "######" } download() { url="$1" out="$2" echo "${url} --> ${out} ..." if ! wget -q "${url}" -O "${out}" ; then echo "FAILED" rm -f "${out}" exit 1 fi echo "OK" } export LANG=C if ! mkdir ${LOCKDIR} ; then pid=$(cat ${PIDFILE}) msg "Lock directory present (PID: ${pid})" if kill -0 ${pid} ; then msg "PID ${pid} alive" exit 1 fi fi cleanup() { msg "Cleaning up ${LOCKDIR}" rm -rf ${LOCKDIR} } # possible race condition if the other was stopping # -> re-mkdir mkdir -p ${LOCKDIR} msg "PID: $$ \> ${PIDFILE}" echo $$ > ${PIDFILE} # We make our own copy of the repository: there will be a big .flatpak-builder # created in it with a lot of cache files we want to reuse later. mkdir -p ~/git cd ~/git if ! [ -d paperwork ] ; then if ! git clone https://gitlab.gnome.org/World/OpenPaperwork/paperwork.git ; then echo "Clone failed !" exit 1 fi fi cd paperwork # reinit work.openpaper.Paperwork.json (only file we modify later) if ! git checkout work.openpaper.Paperwork.json ; then echo "Git checkout work.openpaper.Paperwork.json failed !" exit 1 fi if ! git checkout "${branch}" || ! git pull ; then echo "Git pull failed !" exit 1 fi # Set the branches correctly jq \ --arg branch "${branch}" \ '.branch |= $branch' \ work.openpaper.Paperwork.json \ | sponge work.openpaper.Paperwork.json jq \ --arg branch "${branch}" \ '(((.modules[] | select(type == "object")) | select(.name == "python-paperwork")).sources[] | select(.type == "git")).branch |= $branch' \ work.openpaper.Paperwork.json \ | sponge work.openpaper.Paperwork.json mkdir -p ~/flatpak # directory that contains the repository directory cd flatpak/ rm -f data.tar.gz download "https://download.openpaper.work/data/paperwork/${branch}_latest/data.tar.gz" ../data.tar.gz export EXPORT_ARGS="--gpg-sign=E5ACE6FEA7A6DD48" export REPO=/home/${USER}/flatpak/paperwork_repo for arch in x86_64 ; do msg "=== Architecture: ${arch} ===" export ARCH_ARGS=--arch=${arch} msg "Cleaning ..." if ! make clean ; then msg "Clean failed" cleanup exit 2 fi if [ -z "${branch}" ]; then msg "Building ..." if ! make ; then msg "Build failed" cleanup exit 2 fi else msg "Building branch ${branch} ..." if ! make ${branch}.app ; then msg "Build failed" cleanup exit 2 fi if ! make upd_repo ; then msg "Repo update failed" cleanup exit 2 fi fi msg "Cleaning ..." if ! make clean ; then msg "Clean failed" cleanup exit 2 fi done cd .. chmod -R a+rX ${HOME}/flatpak cleanup paperwork-2.2.2/doc/000077500000000000000000000000001456262201400142765ustar00rootroot00000000000000paperwork-2.2.2/doc/devel.windows.markdown000066400000000000000000000062701456262201400206370ustar00rootroot00000000000000# Paperwork development on Windows ## Build dependencies Paperwork build is based on [Msys2](https://www.msys2.org/). You must first compile and install [Libinsane](https://doc.openpaper.work/libinsane/latest/libinsane/install.html) in your MSYS2 environment. You can have a look at the [.gitlab-ci.yml](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/blob/develop/.gitlab-ci.yml) (target `windows_exe`) to have an exhaustive list of all the required MSYS2 packages. Some Python packages are automatically downloaded and installed by setuptools when running `make install` / `make install_py` / `python3 ./setup.py install` / etc. Once everything is installed: * `git clone https://gitlab.gnome.org/World/OpenPaperwork/paperwork.git` * You can run `make install` (GNU Makefile) to fetch all the Python dependencies not listed here and install Paperwork system-wide. However, it won't create any shortcut or anything (the installer creates them). Tesseract is not packaged in the same .zip than Paperwork and is not required to build Paperwork executable and .zip. It is only required for running it. Already-compiled version of Tesseract and its data files are available on [download.openpaper.work](https://download.openpaper.work/tesseract/) and are the files actually downloaded by the installer. ## Running Once installed system-wide, you can run `paperwork-gtk`. ## Packaging ```sh make windows_exe ``` It should create a directory 'paperwork' with all the required files, except Tesseract. This directory can be stored in a .zip file and deploy wherever you want. ## GDB ```sh pacman -Sy mingw-w64-x86_64-gdb git clone https://gitlab.gnome.org/World/OpenPaperwork/paperwork.git cd paperwork make install gdb python3 --args python3 paperwork-gtk/src/paperwork_gtk/main.py ``` In GDB: ``` source c:\msys64\mingw64\share\gdb\python3\python_gdb.py r ``` To get all the C stacktraces: ``` thread apply all bt ``` ## Adding Tesseract [PyOCR](https://gitlab.gnome.org/World/OpenPaperwork/pyocr) has 2 ways to call Tesseract. Either by running its executable (module ```pyocr.tesseract```), or using its library (module ```pyocr.libtesseract```). Currently, for convenience reasons, the packaged version of Paperwork uses only ```pyocr.tesseract```. By default, this module looks for tesseract in the PATH only, and let Tesseract look for its data files in the default location. However, when packaged with Pyinstaller, PyOCR will also look for tesseract in the subdirectory ```tesseract``` of the current directory (```os.path.join(os.getcwd(), 'tesseract')```). It will also set an environment variable so Tesseract looks for its data files in the subdirectory ```data\tessdata```. So in the end, you can put Paperwork in a directory with the following hierarchy: ``` C:\Program Files (x86)\OpenPaper\ (for example) |-- Paperwork\ (for example) | |-- Paperwork.exe |-- (...).dll | |-- Tesseract\ | |-- Tesseract.exe | |-- (...).dll | |-- Data | |-- paperwork.svg |-- (...) | |-- Tessdata\ |-- eng.traineddata |-- fra.traineddata ``` Note that it will only work if packaged with cx_freeze (`sys.frozen == True`). paperwork-2.2.2/doc/flatpak_saned_1.png000066400000000000000000002634701456262201400200340ustar00rootroot00000000000000‰PNG  IHDR— Çû#ªzTXtRaw profile type exifxÚ­œg’7´¥ÿc³ø ,6âí`–?ßA)R¢ž‹a‡ØÝÅ4ÈkŽrçÿþÇuÿ‡?­øìr±V{­ž?¹ç?4ÿùóù|~¿?ݾ?…ß?w~}Œ|O|OŸ¨çó= >/`ùûùüýsgëóClß }ÿ ¿?IwÖÏßãÚ÷B)~>ßß]ÿž7ò/óý/®Ÿñ¹öß~ÏF0váz)ºxRHž¿›î’>ÿ þ³÷wÕA|TRz—?ÇÎýüñoÁíç#þ;?¾G¤ßCá|ýPÿ£ïç¡üíóT„~Qð?³öÛ?Äø¶ÿgìîÝíÞóyº‘+‘ªîûP?Bø~âÀI(Ó;­òeüWøÙÞWç«ñˆ‹Œm²9ùZ.ô‰ö 9ì0 ç}_a1ÄO´¨Ñ­˜Þg-Yìq‘†²¾Â–zÚ.5r²ÈZâãøs,áÝ·¿û­Ð¸ó /ûrúðóõóB÷ªtCP0G{±b\/â C™ÓßEBÂýÆ´¼ø¾/÷3­ýQb,/Ì~~.1Kø«¶ÒËsâ8u¿ÿ´F°ý½!âÞ…Á„D| ©„¼Åh!ÇF~#)ÇIB)qwÉM¢,¶¨{sŽ…wl,ñó1ÐB"Jª´M#Cƒdå\¨ËôMv¥”Z¬´Ò˨©æZj­V…QÃ’e+VͬY·ÑRË­´Ú¬µÖÛè±' ¬ôÚÍõÖ{ƒ›.=8{pÄ3Î4ó,³N›mö9å³ò*«.[mõ5vÜiÓþ»ns»í¾Ç ‡R:ù”Svú—Z»éæ[n½vÛíwüÌÚ7«¿g-ü-sÿyÖÂ7kÊX~ÇÙ_Yãc³—‚“¢œ‘±˜7e€‚ŽÊ™o!ç¨Ì)g¾Gš¢D²Š’³ƒ2Fó ±Üð3weî?Í›+ù”·øo™sJÝÿÌ9¥î›¹æíYÛã1Jz R*¦>]€í–ug'quÛ£Û®cÚ­<Ô½i»kq.·£m¹Î­]ßS¸'䲈vg‰wpDå–1ö÷øÏÑŸcÿtYó3T;;Î3óNÎòìgÿãXîóû f°ïEÏß!ĵæ;§³3×¢×tò¤mõ½Ÿô}ßœ.ÀzÏÚmÞc3_}FðmÄxš÷0íÜÜâéŽsý.Æçç\°éo?j›¡-åçÔ5Qþ¸XÉcm!÷áD»î3¾vžŸŒa¯:FfØ v¡l9|å›c®évN&T~¡ÈJþ=MÌFÖF)£„6N…NÎÙ7®\Èâ^TñÜœA ëKÕVžvÄ;SQ÷Ò|Ägñ)Ûv}l~6hçš¿Â(‡‡­9œÕ¯Õ2ò„Dv®›ž¢@Š d‡˜JËsYÌíº~úl-Ý{¯·Ráß~lSWcÔ7ø?ûËÏï#p:ý¯Aü㲪ÿYý½¤}†ÿçÑîç(æF1ß©?Ê·qÀøÔÜ8„rÎÏ£Oý-ÌV#Чÿ¸ÎgŒ?®ôbYÁ?<Ð÷Ø>’Ëç_[ ‹?š¯‘q5Ï/Í÷£ÿéÓêVùÙ¨/CíGk§¸¾ Ò÷d˜¿5ñoÈà~‡†°{/ •Bmuï)³më¦z"§ÜÍ!`M—¨%¦Ù¬8è»4B÷Ùœr|¥b'—ƒ6¦ äÕõÎtð>‚ê’ÄPe¦®½©ÎIWB{NÑW¹Rz6ü¡9£ç|ôXäÔ5mê~‡šrq˜‰È£¢C<8î˜zX`tà•´p‚Ð<ɇÄ6oE£Ÿ‰è€Lé+'‚¸cخռè¤a§ˆ2gKôú>Ó׋"œ±~óuÞLÔnz kÀy@ÒMsv¨ý˜ @œc1¶zh„@ ÝØ2¸•jMê®+³F|z´a %«î¤•ò™â›ˆŸÛ¶9ûÚNjH— ù£öÝehe‹œ*™­¨ÜÞ§Õ§uT‹¢ß—š–2ŸÄúœâª3ŽÑS[yB4u¿F^˜ãþè ½Ç:2Òš½”a‡J÷Ó- Ø䱬ÒÆYP”è)pÛ@>5‘†p;’Чªº i€*fš€ŠÝ!m{2šéLJ¨ä#&sñÓh¿ÄÕ3§ßt`ƒ&e·?´(g èïÖ´4—ƒÙˆé¦ðãꨜ@'2¨…é5. x“­O§QRÐÓÚþðs¼ËÁ ÈDTHÄKhÎîuÕ@•pÙ±;ÿx^ÛÐ’%Lô¼•_¡s mwÃb€ç: ÞjHNÑSWmúçKcÌ;I£Ip¡ú¸"éìnO×@=Š‘p–c>Vu¥]d#A²Púþ˜ú‚œç‡I5…q•dÚ=Õ]øª‚˜5 SÚšå ¸Åa@ÏYB›Ð˜Þ‰\sFOjͧ#‚vm>.ØA×”5ˆÞ„°yø^­2àÇ™ m’"“¦;êäŠÚAS̲S»¹µ™ÜH‰6º WEe¬ýÎDrX˜<0)‘Œ]3nYxá·.j!£!1M’ ë´Oè€ÿ_Œá qµg:`#wéY¦ú}âxÿ<’i›f5t«z4ò—x%âN(·* 2#ÂBÝŒúM]Ÿ&‰²wQXx]: Õô¡µ_ŠÀ}ªàA…¤i®¸Ñ¡Ñ nÙN¤|Í0þ„”š´Ü÷_èÆá¤Ü—è‘»cꑦD­1!nTÖ #B©ï/¦=ˆ ׸C`­«Ks(š;AKßô ú=üÏ’_Rà~ËAä¬#;‹UÚ;ÈCk>ä~ =H1È¢¼½ÍÏå~ó]^Qú=Îo.Ãv+BgPªcí€Ô>„¬ŠÜCT¥5€ƒH›HbjWrŒ¡ ²wÀùZÈ3Àv]EzX°k{©°jö©3+ñ@I$8Žñª’îÈ8ØO…áùþö©û|\:ÄÖ€(ìè?(D€‘t6þè"¸éƒœÀ"ü[@ÜÂ#jÒíPĤfc‰`}ÌO#¸¥uy~@éÕBH(¹±Ðqè"ä£ËímÄU—ß4Ì1ás¤8–Šð2ûó£xNŒòz w&¼7¤O$`Gr9óC ´Œ™iQÅ&†)·ÑÏÕLV ¨#° tFÛ™he´a Èwìr£’%0{oØìÏãÂÎ×ÞÈ 2½Ñcçüò,ÒAcãZ€Z›sÇÙÑ9@‹¬p˜^DJ#.ð±ß9üô5¿úa³êÍ!UR¤U5˜Ñx:¿Vš¦/F‡Öþ’™ Y[…gÐÔ —Aó8ô×g óâÈ1¼¯YÐÆ8ìk/•³NfsR«ö˜d<0^øyŒfÊk§lBÅdbºv˜vTŸGMyôZÞ æ%!ž Fü~FÊ*LbƒŠáTÏÀ°"‘àGÛšIÞš­ˆ,qA¢ÙúÑT·ÇÊ¢ÁVN?Vˆ¦D4}iF£@G•]¾5à¶[ ñ£Ë]W¸ŽÁÜ-#¯IÕq¶ûÃý – äÕäÍjè&Dm7ß2~pƒUÂŒ.DH`’†lû‘Ë.TNñtŒ¹ii í¦Ä°5ÓPÖ”½b…ˆ®áJ4•:‹Ù…@ŸÅ)¥‰»RçüA!ÇRÛFÞl<¥p‹ ;ê AÄ?8D5"|±C#ÒýxmQ[ë=R)˜RÓxò¦‰jÊ‹1ôìîà—C<Í¢3<Õ‰¦<‡‘ºÏ|ì‡rò²JÙš¶Flç…ÊÐ_àT;Ÿp 0A8a)k¦DÏû„Åw-ܜѿTÚ`ªã3wôyÑ1A“=õ-P,Ñ–©ó{‹@'%é%RÌ10yðÓ‹ÉÕÔÁÖ23.°jš´MªD2j1ĉ¡7…k6ÄÝ[Ìa7 +ç`ëHÓ7bŠ{£„Hœ–3ä€ì½AÅ­Éhp%ò@ÔOÑ.“$~pÀÔ…Ö" ޵„.Žæ{ÀjÔH¹Ú³®%£@0í 2h™€RUt еƒ ôÂ}外|r jsD?oÊ…@¿aØXSX?D£|ääë3÷Èšêpaº€è‡íµðbÚ¨Âgp¨Á<œ¹xbSî©i21LÆé¶Ö~»iס_¯JÓ$u¥èš68x\… ГÑ_‰qÀ S{tWC°kçÃÔÃÅÕN²Œž[Ev–Ú"sÚ,kg… °t­ÕrV/$ä¤ÀRsªý§Òè𣡦Ö;ñwZ$^t¾ö] y6:ájÇ>sX\©€¡Ã/xe¡§¹xÔñM»‹xPÄè·ügWi/køX2è¸FŽÃX¡w0s_ ÙTJv%º±M@ˆ"ƒ˜F¢V5“'MêAññqÝ)>XÌ]ÓQ×iÏëZÂRŒÈE,ó:8· txžXs$â6‚¤%¼2‹ÖOÓFMŽ€ŸÊ.i1v6ìI[Ú6!šÖ¤¼C7Ù´!Ê1Éç•)HK„}8 Pæ^t8j&8*'i&¾¾¹’¼é"øÙWèìÍ¡#S¹çàöWr#^­vKhJm$i#‰‰ã6壕›¾´æ|1Ž;8Ô[ìoª€›žipjÚuê)—d]%iI¦æM¯áãðT J•J)¨V­9q½œØ’r£‚mBÓªPßß­ý)ßÓ®ƒý[ާ5€Gl˜¶th ¨kŒöÝô7³ïZ –6É…8dÆ¢o‡EЩ>«7å¡#þš€Æ› Äì@ºhùõ(†?µOB{«ÓʵüöæÈ„+…ñGк·V*Emø+heó“O4€Dô j‘5‰÷u`H-¥c\±|‚CBú™X <‰~^6gÚY…`ƒyažóŒÜô¬ÅD b%Ãs )ý¤¹°Vñ(Ñçˆþ?=¯}pÔÏ7eR¸œVÒ’Tf¡!º[»q!ÌRpé#3|$"6æIPßs¡@1?´ Ò3¢¦e–liͨœR š|=”O%gMxA©@”£å-ZáÃë5A¡U}¡üùN‚ò´*‘P´êÙÐhO¯A•šSÔòr{{‡è– A!¬‡V4A( »™Pn.4zðG“JÑ|ÅJÿWõ#VEkü·_‰VÈ‚¤Ñ/ˆuò‘ºkU7o !! V= ôƒ’ì+‚nGÁm½Ý´:‰aŒÁ­¦I>¼ˆ4, ô(JWK¤‘Aä¤&zš ÈlkDM'‘³6=7h«a|?kû;ßÝ4ѵ+JÓi2Ð'4ft™M„0…û @lš$ТQùné3€í u@!ìgƒÏŒÖ è’$càÅÈT)Í9·Ž£KPüøô"½F˜2Þ `ó—¤ÅLj‘^¯¢Ö)„)ø“…º¢ ÃަܢbGÌåèSéP‚ CkøomÈ`åbkQqá+ÞfþãÝ›4kš¾”°(Ë–Rc†¾5m$ØH¨¶?E!õ|úÖÜ”æ54“§åŒª#e{M}ky’ "TH´ß´YPÐHIé­EPþÒé’bP–&öO;êt¥)Jœó~V'ÿþ"ÿl‡}Ëß)š õÿ·S‹æ1IõdHåâm‚§yR>’×”c {ƒ­8m»]׎¶ƒáÈÁV0îð 1kef2ÞíQÊCÛc˜‰ôÖE•ùx‹¦ñôšîÑ·¢QZЛ-ä[sí=jÇ%Ñzûµe®ÝYq>'0/]×ÕÒXB˜]Gþè­®W’vß6{²¼Øø[<gÚýLÛÿÐf÷«Í²¦ÈðËk;Iéžô\šÒ¨©¼‹–ñ¦Ô<̯՜wuíNàš‹£#œV<ÓÔbÚÛ\ý«jC ­X™Iž]"©ÅÆÏVa ŽÖ ¶2\€ X†º²á•xl±ÆÛ?bVo¬ýþýí*K®wÓKAU²A›ýëÛø{CÐ ‡½Í`û»×þÄ™ÿå÷ëA(F8ÑA «ÐGZ}ÓTÙ,.ANFÀ‹¶T=å¢) llY–^—j’Éø}m×6ÒÓ}”â¬O°‡ûíM÷Gþj=ʶ5×ÏÖsŒ'LH Gí ¥hð@QE˜¹Ô:öÖ;˜6ß6oºK3ý`Œµ«Ö‹³9$ôÐð¾à b ˆáÝè>Ìñ6ð6TS¹ü"QžµX—Vz 8Äk{x2j¯ŠÕ+oõš>{;»xŒ:RÑ‚#e½àü½æ43–Î…ÿîèÚnÚÊáásÍÂQögð ‚e¹²(:Ñ—¨Ï”…ømªXR´e ÚN^ñÆ;‡Üt»…´Š&–©tÊT˜q½¶í¬)øÃК¶P-.Í/Œ £4É>ñ&g)íwµº|•Ñ‹ª]ÓA½i«ÚÔš2Æ´¥u½ þÚt´W5]UóîKhÔ çŒ!ǃi>üº÷® zò¼Ñ"H‘±xsiN¹ zÎ|ŹYöôM ´ÏuÑw¯îáþ­ÿñýÛ!4Ó/=‚”AÄëÅ-‡çæ)›ªžZö’Ód*>iG·LNZËêûAIÛ‹Šj\K«óáð‰è£¬‰$ :ž¡kÃÇ HˆêEàÿjõ”ÖŠú«âGK1 ʉs"êÇ’6ßkg¥×ÆVíN£¼æ*+‰î‘¦•# ÁiMl_H~šAâæˆÚw†è•<Ãdtá)ðv€œÖ/"D(^m× YoZÊ;ÑCï+ ŸdŸVrZBJ£)L³šÐàRÞµª…(F¶c¼‘7Ú§šM['N{Þó í=ÖæÒ@³ 2«´,˜£ gƒ¢¡å´¦´x:ؤœ&« Ï@+çÄår¢ ì\U‰QÚÈ'Ô4X‡Àfè`?ÙÑÔ”—=²‡†ç¹ Ö–%­ ×´ #ÇÍ?ïÓj“xÖˇâ8¸§Íí8“’ièKƈ,-y=Ã{€÷õ’ŒÖöàe·¤ã°qB$€GE—ôè"(½‡A¡¡<®5h×2jzµI›(j@-’¿ 0GQ…'dEJü©wm(\úŒ"Öü&/SÛK´ áN›Eêçub ™:üê%½c—öyM¬¤u3šR*ôj1j_«Þx"1xÝÇÆ:PZÎÁ šro²÷zãÄÓ݉‡€Ÿßæ¼òe£üµ_Z€…|êÀßÎ<Ÿ&/–Sv®*HzK§]åí¿C¨w$ ^®ñQÕskû Õ§Þš œ Æ’¯r{k'2u÷ ì½ÈñÑk0ÚÞsè?+þµ£«¶F¤Ù4€¤?¦Yå¾à)-QŠOó`AíæŸ\Æ-_N™zùƒìɵ¾—?TõcéM‡|×{ukyþÍ¢^³fìK«<·6U„&ÅK5“ô­¦µ—`ca‘Qº>yÞ¬Yr-·iîF¯ i«W3=Ëêrý®I䦕/‰ÛŽòš§ç·F`DYî€AkÏ<Κj ½“<’‘rGGÜ~$¥v½ü@ݬ¿âêû‡êÿŒ”nþP­èàòæ9\VéŽÏ– @Ôš?Z\ÔkyOåôøƒ‰ÞoØ)Ma!Ë x½ÐjF4í7JS•/EŸ„p›â)á(8J’†Äò—5uYô2 &lÀ%ðI{ô1OEk@Ú Q4`—Ç5Ø4Qµ‚çÇĶí &ž´!³ýD¤¡SÞ õ;¡W=¸ ÏCíó³öVÑúeÚ÷¢×aóÂz¹åàe„Ì´ NI$jkS*Kv.­_Q¢g~o´4?"–¯Ã¡Ö”UÔ’d.^ˆ²žAs÷t©,€Ôý˜€š‡¸3åáÛ¿Á÷)¥êúã¿Çÿ·ã8†Qs¿ÿ]ï–R¢µ}WØïî=Áç…M°î}Áqö_+¥¬i³ÿù¶mc†×o·íþ± ŽO°=B¯íî»´Ö8ŽS3?aóî¶Ûm—aÞïþñ ÎkðYQml4ïn{ýípÇ#Œ'ücê‡ûŒ oúÇ&ø>÷3?ý<íÞkFCð?ϽßýÌqœš¶ùûáòŽ¿­J) Ã@JYs¯nƒ|ëà;¢æÃ?þ6ûùÔ£àøùÚß&?ÿ¯UJÕñ·Ûg·ÍZkLÓ mcK]¿îý+­‘R€¥öóˆ‘ó+4èê¼J)qßêÞ¡DýXú×PpÜÜñô÷ß]£Áq…ã8˜Õ1–´Ò(­0„D¡#ç?j®Í ð .0ÿBh†‚ Ó/DƒŒìxprƒÂ%LØ_ðwÿ û0aêÜ£ 9¿  ~\øþöúÛ¤µ®(îµÊÇha`¥¸ ä^ë8N ö[G õ(Ð ŽYÔ}Aí8NMý‹>lŽÂžbaäŽMÔuþ÷… ‘Ñú¼Þ¶m¤”‘|&‚íY?¢nÞ‚¼\_acìƒ;Qãæ¿àýîk¤D†]ﮃ0°hôÞ(ùµfƒ2-8æÁw¸ÀW¥úµSsÇQ$´o|… ð1 ÐÞ~…DJ yçÊÖ(å×ß_|üЧ¿í¦é9Eå§ÐTÚ¢Uä˜Fɳ‘vÙ¬µÒhQ× lƒF…1O˜öëŸHÿ"k¯_‹ 2œ"Ü ðOVØ¢ À æRouéÐç¹Z¢û+üƒ‹,Ls ߨq |?CF©_0Žf1Ÿ«AùA±‘Vã×b ÓÝgE Ë(~EÇ?Ÿ~f¹øç£‘5öQŠNE¡R µªi³«u»¿ûÛæ»0~y‡”F5v]˜nfm7#'‚ë(lþš}VXߣø×?ÆÁ9 WÚdäsµÖ¡ÖE3ÊZ`…`ð» O-Pÿ3\eÖ?>®}¤µFúÆDR•?J¨}O3Ê„ÙHxŒ6Qî?BÚ¶*(¢&±‘)í7邿âÍá7Í•ÁêÚ8QÕHª×(æmäjpÁ' 0ƒ‹&Øæ ›¥‘åþ‰rù™4hZ»íŽž‘ök ŽAÎ2)9’¢§¬¶8ZPËî`)5q©HHEÒP¤L‡¶˜ã¹ ¨j}„€®÷^×zóÍ© Ž©Öèë.È43?ÏùywT«Lk¯øŸü%Dümsûäµ+ÊmìºcÜÒFëÀzu˜##éŽ}ˆ[*ÊÝ:š2eÅ6ò®×K#aî·ìý|t)†ƒòÖ8ÊA „”hŸÒt_‡)+u<äòa9æö óÕÉ‚j{TUÞU¿¨Qp•ÒT ,BV¬ßÂQZª¶]„áCõc¦ j]ž‰¦¾»ý,ä]îÏ'Wù\9Ž÷ á_Ü!ïsŸ#ý „œàÊõJ9h FÕT.³U[Ry®ñyjxVe+‹§úlé cÀÚ]]PAÍͯUV~è‘Ñк2Ð4A^›Ý1ªc8•OŽU™Ì?«AÀ¨~&j?íέòÆÇçÙ¦+cêÇŠ6cÔ*W»Tæ ÊÂU¾°ƒ%ÉP9Æ e4¯Ý¶ØŽ èÔûá;b6q›Ž¸M\T…£)<`—Õß+c.ªî†a.„»+óT3GÕ{DPTùbäy~WWe¬k„¨,Z­RT|éžÂㄤ5‚¦ÆMX“Âø>á!¤¨]èRøÖC¸†÷‡Ö^HÀZTÖ‘®~ Ñ5-ÐeL•ŸÀæò]…¤'¨.io]Ôò´üý¨¼§2®#·7f¾„7¾u!üÊ`@3¿pwtÈs« ã>K»Ö±ð)Kþ5Y£ij QgŒ(#²Í72àÊBjÇ]øûé“àZ+oxïÒ CÞüŠjÌÇ© ¡GFNH@Akoác:!èê!,~´¬7ýuˆIëµüÌá×"ÂÜ2ÁÅhþ‹*LU‹Î#LYüžÖ¥=!ÞÈ”¯ ·Št±…iýµ îKŽ2ñ…ß|–>K!`‡Æ™»û!¨Ì+­B“üzƒgê+êw`ìçgKÁd°Ü< Œ…†,“!Ë„\hºã%ºâZûã&"ÒSáÅú¤O¸V¥]¸OÞ ÔÖZš0"ŒýŸ —o`ä·…Þ˜†¹â¢¼“ø±ÒhñŠ0·KT°ßM#¿ëöRœÍÅD¨µ±³)!ú%ºãź gXŸýn•¨L¸ ›+*ðß(F–$Åaß)¥°m›X,Ö0^̪ òcIÏrñiÎBU¼ —“ .Ú.þlưŠ¿=~·‘û{T<(Lñõ­?Y"¨43õ¢ž̰ŒŠ—¸².*êÍÆW‚í Ë0 Ëÿ»ÜÀX°ßnüY8aÂ#˜ŒÐ€¢Ò3£5Ñp-Xê·ÆÂ€ØïŸ® krN‚Å$Ç`wSJ:ô%ò´›¥:~SD¢2Œ‚׺ £ ?ŒX&"2Vä¹°Tï°Ì …}PHÛà U ~ÏP‘iÿP::䯙‚ím$À›U:ƒë¾Q°?,•¬äù0%4xTÜ9¸®ƒÏö+ža¼œÃ°~7ÊØsÇ>,V–eÝÔ6¿ìCWÄÓÏ=_k¹¸ö{± üHfFÅT‹pG„æÄûN£1KØލ‰Ê8 ޹N¿·gv×÷Å3ÿàV³!ZÍK+ï~¿fìÞg;6†4FmïHq$ŽÒTš±Uˆ«+4/ÞÇ'Ž–l(¦°c³BѤ ›¤´HSÚÄ…&f€å€¥%–6))ƒ‚c’W14bLïè2‹L #…ã‘·0|>ì0!\øî8ç&¨k´7·Q©Á#î–Z?z³RuîMDC Ùå«}íš0‘õñí„ W]M|p½¥~ÞRVâ“oF3k²Ë:êó¦Á¥.¦QÏôRx ǶG”a)ë]nný ^@žú­ ¿LñÇ#שW¢”f¿,RÕjصA¥Øº&Œ.dT´~ôw{ý|êÙçt­°¯Åÿ\42ƒf«”Ó0êüòašD3VR3.Ÿ(·GÔçA 0ÊÒ Óšü×¹ÚYP³ˆÒNƒÚFpSW˜Æô£+åDšËÒ,k¨‰9HY‰;EeÔ… ÈœJ±±ÜŽ­›sÅ…CFiY´åQSЃãUP r*AÖIRÖÍYH¦PL ‘ùºy³ÔFÆÄÏT¦Üà঴`ÖST&_Ôþ±Ñ\ÜFQUféš®¢T£™Úu<èÍ—¨ªæ—Q›wÇ .Q æwËp¢I·zøõ#í§>q©.©Hxø¨ÌÍu×…Y9aÊ@£ ½Q! ¿Uáß7–‘êŽD5Ìn”µFŽã ÿçÓº>`£Çäà PŠ@Š›KþS—Ã;Œ)ÃÜiÁ Û9Ü(-Wùƒ—n:g@#©C]×Mbš5¾ô07R£`Ÿ?(èµ1$-2ÜÜÉ ±D‚‚m’× :ŽSøsâ[ˆQnÊÇœûF Û¬ Ûœö¦u§Q¤]æIÉbM®}Tì/+KÔ Bßœt’a•fX¥šjC¯¢Ëªsã5º°¸`[啨ÊQ>ø0Ë%*ÆÖÌfÍ0ß·÷·Ru±’`Uˆšw;UaصæmÉä«­`¬Ñ4M/Ù!jót#9¶Ž‚n¿±Äi#ûáš7ÿ©à>¬F{£öØ…ñ{ݺ¯Î§g)eµÖžÌV"hd9»òÎÁ_…dßù•ê0w§xäñ'tp‡™¢Á²uÌTEré×⪩¾~­Àu9øu0Åh‰ª¤vVì˾ª—Ží4dBG¤ùúÓ#Gyšk´Fþvûcø²âF€nĬ š³²š ä¦îÚŽC¬ªýú¯ Þ6Ù#e%F²ãòdØ¢§„ös¦±‘x\T5Öÿ{X€5lA¸í3 ƒÍv7C:=:¨ˆ,íb )d%ÛF i`;ŽÇ~W›n*}&¸£œj¾¨ÓcHu2DfÔötˆ,Ýl +—_å(%.‚¥süü_á¥zד;æaãéwÇ*_z¼—æí¦ô‹‘ôz¿»Ö/¤—ÞLÝV:r°þwT¶¨J_&¥”µà¢|k¾Îzó?oŒ1•(¯DXŒE»BÕoáû’½æ.æF±—(Ph¤|…ýî*Rî\¹rÄŸZ-}‡ëÎò»ÂÜëý.PÿóÜ猄&d Ÿ„¥ÛÛ"2Â/ʧ¸º[>üî×0…IâÇŠ še˪³4ÂÜa>èšA¬öÒ jS>MSƒŠ—ºtÁÆš‰ÀÑvEøàË8q…Ï(µ»T ˆŸá”o£•»ñ¨fS\Ðýä2^ó+ÇAVµBí«äŽ}p C-?w…Œ—qQ"!J$)"”ÍfÙï¥OŠê8ØztTÃ"AÍ `³šBŽÆÀÒ¦s´ëÄ(Už/%–c{©J»UU‹pl»Æ"P•‹Gbw‘þwE»³”L2,zÈ‹è¶ é ¶ô²ÉÓ¥QÓ!AÚ: ËÕ$CÜ?NÐÒ!ÔÈ}¾8# ,uÛ'8k,hß³=7‘»i¹nçumüÀµŠºßŠ–Žˆ¶Öª€äèQÙYQñ±€LP ÕŒUHRC”+n´šu£K+ß¶#­W¿ÜàêŸS¿•éO†R¢gÄjÎлâwŸùÞÕ(üP#CbFZk”a„ÊòpÑõclª&vUGíÖó×¢¡ˆ49ÇÂXQ“®Ü …UËÅ*—+Hï¶SE3’»OÃ?×~8Ì æÿN©Ê½(-¢†Q”¨j!¦ß1Œ—A#ËůzM}š@œzð4È’2*Å‚ªœôKÔBôïâ ]œJ±Ãè§ÐX :œ-$A¤”ØÕ ¯Þ÷Õþ:jD3ö÷CWw<µoÇs·Öc«·6TŽrÄe'CÆT”ÉäE­¦Òe¯ å7ǶG ¬Wj0éºyZ5} lDö[Š~‹Ì_—Çüz…².¸ë8øÖ±ªÙ¬ëèWøÍS}V” |˜ÔªÎr &¸„%øøŸïOïnD#ZüHETFeX…‰¨ëÂ\X¢ K5\"˵dýsà·æ‚s(ÂY±ô+..éÍ}Ø|ùe ìë ó¦„É@¿åâ·†„rjø®.qHWy.Ð2mÇF9ªµü¦¥”¢Fø7Ôy®¢*RJ)jÜÊ·1‘Ñ|¤u¹×ÍeÏT´_Ÿ†/«ïrT؉µÃb3ÁkÁÉq!5åi|ïTJUÐ_)lé€Ö”J¥Š5ãë{pÇoð»J‡¬™'Œ‰Tµ]›T·DX¶VVBз,ë3œüü0ŸEIF»žâö0™òz$6V@cöÌp¿Fåõ¥ÄÖ•øð}UÉX²…1@>9“²*È JÎ S\5ºï^„gθm­ŽTØ0ÇÊ€ÚŸã3FñgØsÛÆnLãφÒ>·r%¤Þr ®“K+j욌“ø-=[*|TÇßïªn,#¨sч%*…ƒ žBY'£Â6+†T¬n”5+}µuDXå„Äm–‹r”V˜†‰íØØ×ÝpcYþøŠ?†&Ç]pъܦU¶¼ú8ŠPJ‰ãC´ ïÚ}žã8•òÔçmëj€¶Îú ¦ãòïC]\Õz8†4PΈK.èŸö[Þ*©©c0òw ÈTË,¸ß+G!«~ÍíA)obkb$.U 5 !Õ9aé°Q{tõ^¿_;¸IÔq0Tãܶm¡íòèBÔÇ Á´Ú|j6e³#òÖdi3±Ü)Q ²½üãU"ÜŸC‰Eضí¥Hµ8ÿ|VøÓ!•]†L@195´Í%³ï'™[Uõ݋Ȕޠ@KvÛtéÖJõVº¾FS•Ýk»v¿B°LmuÂy]”ª-½"¼1ö¯§Ê—A¯QtíZñkÕê jçÁtéFUΛٷL$UR³Áü0þ4ªÞ„¨è°øWpçÐQNèxÕÌyU^Lj'cyr‚V`Y•Qneæ ¿IQÃîÜŸë÷ª8ŽSYw¾~yÞ ¦a€ª¸ÿýÀc>þøch¥=«£¦ãºÖÄöÒ îûjÔx@êæCû‚‹0Ñ^µ{ð3@àé™Ï"T ÒØÍH-¯ Bü”~ÁÌûBÖY;5×÷|ú_SãIÔ£rÿŽú>¨—"àªÔ"òÌWª¥6í½ÌX|K_XAypcóîH5"•ÖtÍ;Ž®ÎžÈë·/”áµOVÁAÖZ\~×Pˆ¿9Ìrõó”Î*š²¬Ö[“uÖW]ü €'è˜u$=󇶽ïeó† ¬|¸‘‘9·Q|]«Ý…æ^©“ 4ôU€÷´ÒѾ÷Ë<¸ëÜz~°rko¹©³ öj„Y%Á&“‚k [­I4>Ùãã‰:*õE+ÝwUƉšZ|þ¤£‘~û¹@ýµÐ¶zrÄÜúÝÛóâ¾$œYíCˆRj$#l½)¼±õ× te³Û?/øÛW™Þˆ8•”B³gÝ6ˆu§Fy(‹ã¯ÅÒ¢=–òeÅ—–xù 2‰ñ•bÙžSÜ»²ùý‰³âLë0öøñØ4äðÀšrä÷/ž› '-[ŒÓ¢M‰UË—¶Àe¤’cðÄP7Gt 2ì1?CiÁÓC]T8xÌoË1%QØkÆdk)Åò|x2BJ:Ö1€­åТMµTµEÒºB:XHö*`˜’(p@2¼Íe°®nMz‹Z4IdN¤Bq‹ö\jt\@3”µãl(%C¿ëŽ•éOfÙY§?™eËP™r¼³î» ¥$]±³Üb µh¢àÒ‚…Ñúb[¸©+4³SÙ½ºoéìRìÞc½ª¾Á~/Ì”#ºE{vìõîhC \Z´ßÓ€•`ÐŽ…~7'•#.½º†“gN*ÇŠ|ýžA;ÆŽr‚®XÑ;:¹E{·å¾[Û’IÕ—í·´©^²Ë´˜=Î’b`ûŠ…ü¨;±'‹¤”$Smt÷ô‘nïõú)ñ;Ê B@tS)E› T(Töµf¯—F›w•åbš1©±xb¿˜¸´¨ì8CVËŒdnÔû·mÙÄÀŽ­¤3íô¤§î²Å¤µ¦\.±qýºz¦ÐÛ7mÔ{f$s d»ê>vb *“sæÑÙÕƒa¶–ÉÞFî‘¿O>|?‹O:e·´Á±m¶³~ͪJÙ3¶_Œ -­lÕÝ¿77Ï[ˉMô@w±§\*ÒÝ3e—/ !‰D’x¿Äû¢·§›úûyéÉ/âå/=eŸ>‹E”R¤R©ý¶Ø\Y‡ƒËþDm!àR°ô¸¤Á­?¹Ç’¯ù {\?K¥Bâñxè÷J)¾qÃüþOÿKgG;ÿ~Ý'¹÷þûY0oÿrÒ‰œwñ%¼óÜ·sÚË^Úô{ïàA{âIÞ}Éő׬^³–Ür+ŸþøG' Á÷`·Øþd¹WΉÇK<cã¦M<ýìs<ùϧùÛßÿÁ'¯½zŸ¼ŸúÂWxöù%Ürã7èêìÜ/ÁRõÁü¤´vºžuþ»¯jNXçk;ÙvÑ$E¨ÝxYgN) ĺó?¾õÚR)®x÷e¡ßßy×=<úøüüÇ·!$q>ÿÕ¯Q,•ÿÕëyü©r×ïÿÄk_uz Ž÷Q²©W{yõã±RBÔ[j–IHÞ“™¥!‘†ŒlÛº ë9ôƒI§“UÅ_së÷¿‡£l¬r9 &›ëßsÏ/aåê5œúÒ—4¼Gø×³ßÀþü|üÚ{ÌÝÿöÔ9Ø?ÀEGëÜY³¸øoçs_ù:¿ÿÓÿòÚWVÀ¥\.ó“Ÿÿ7>ü(ƒCCÌ›3›óßv «šF¹\æö_T¾bÁܹ\pî[iK¥¸ìýdñQGð‰_ À-·ÿ”_ÿÏÝ\û+9þ˜£yã¹ðªÓNŲ,~ü R‰$gžñ Y´[nÿ)ËW¬bjßþß;Ïã°ƒ04<Ì-·ÿO<õO,Ëæ˜#ç¢óÞNGG;J)Þxî¼ö•§S¶,|ä1 CòºW¿Š³Ï| ×~êsž;ð—]ÁÔ¾)|ïú¯ð»_ßu7n"N3kf?ýÀû‰Åö½<ˆ°³MâÂÙéJÖø,’b¸õ`êLDÑôÝ{ñ»ßË)'¿ˆ¿Ýw?«Ö¬aÞÜ9\}Å{yüɧøÍ]w±eËV}×|àýtV­ç‹ßý^^õŠÓøóÿý…V¬`îìÙ¼ÿ½—sÈ¢…Õ9ÓÜvûr÷ïÿÈÀà Gq8ï¿ü=LŸ6Õ»ÿÍg¿»ÿžyþ9>÷ÉOðÀCó›ÿ¹ €ŸýòW\pÞÛyç¹o÷šü¥ÿ¸ž;ﺀ»îù=óæÎá–ïÞÀeb“O:‘7¿ñìÐq´,‹ïþðfþü—¿bY/=åd.¿ô’É @ýæ·wóº×¼º¢ÂhxࡇùþÍ·²rÕ*z{{8õ%/᲋/à¬×¼†3ßôf®x÷etvtŒÜ÷Ĉ~+[l„Ž=ú( Ã`ýÆ(¥Rò…¯“G’ƒÄý3xø±Çùègþo~éóLŸ6•/]ÿ-~ì æÎ™Í±GÅò«èhoǶ›óáÿîOÿËÌþ,\°€Çž|ŠÞv;RJ=x!³èçùe/𥯋ï㫘¦ÉuŸÿ2kÖ­ã¥'ŸL.Ÿã/÷ÝO.Ÿçcq¹üö÷¤Æt´€GŸxŠ[oÿ/>è@NÙKغm[¶nã g¾šÞžJ®V¬äú¿Ï”Þ^^óÊÓ)‹”Êå}X"™Cì_–‹ÁÎ믔’G‚O|äúúú¸þ[ßá¢w_Î[Þü&¾ñÕ¯`;Šk?þqnüáÍ|øª÷y÷Üý»?pÍÕ`Fÿ ~ôãŸðþ]Ã/~ò#2™ ß¿é~ì1¾öÅÏ“H&ùÚõßà}ú0?¹é†”’¯ç®ºâr®¾ê}Lë›ÂÉ/z¥r™Tª«ßw–U®±F>v͇èêêb``€ë>öQ”R y¤4†Ù¿¯~ã[‹%n¿õfÊå2ÿôgøîM7så»ßUñ‚¬ZÍâ£ö”Ák?ù)®ºâ½œñÊW°yófrù¼÷¬öLšöL†gž}ŽxÂ.çƒÿô¿¸ñ75¼æÂwœÇ…ï8·ežL\¤”ôtw±eë6ŠÅ«×®åÑÇŸä¨Ããºk?ˆ‚ÛþK~ö«ßpç=¿ç%ÿr?ö‡¼ˆÏ~üÚš8ÍÆMÍ•'éíéæ›_þDåÚ“O:Ÿýê7¬Y·Îûþ¸ÅG{ß3ÜW; †ax÷tà¼êg#>âE.`õšµds9V¯[À=ü3÷üñÏ5OÌæstuVÌjÓ4RTž¹ òÌáìp }#í:âðCé›Ò˃<ƃ<Æü¹s8çMoà„cÙo˜ÃÒc/¶^ • _j46ÆØÝkcpÍ)ÛA9•šgéjÏl6KG{ ´g2ä …š{ÛAÙ•9°ËeŽ<âpÖ®[ϺuëÑJ1gÖ,”v衬^³Î{†) lË_¿ô(.êßk×®CkÍ—\ê%f9ŽC±X ÅR‰íÛ·Ó×Û æÍ™Ãq‹óÖó/ä_N:‘×½ú Ž=æèšWM›ÚG.—cܸ>·˜U.óösÞ P0—^|œw.V©4nžÔûk@?HÏ-YŠeYÌ=«ªÙTLhÿ ƒ±X%}3™HTGàû åtBCÖ/xéËÂɤӜö²S8óU¯¬¹®»«3ôA£‰,ž®Înø/ñ‡á¡Gçï<ľö ¾ôéOp`œö%’hT ¨o)£š1¶óhwZ$õ`Z¿Œ )‚6~¡‚T*‰e[8Já8¶—µ¥µÆ4 ‰Ä.·L¦­5·ÝôCºº:Gú! ŸÍ"E¥}ƒÃCLí«$ }ûë_ã±'žàŽÿù-½îÓsôQ|þSŸôž988H<žØ}¼0°´,–&eJÚºm;ß»å6„¼åMo`æ3xàáG<ÁýèãO0wö,ú§O¯~ÿh`o«jk+V®ö¾+•'¶Ü½gŸ_ÊÌf0wÎ,ï_³©ÓfÕ—œÍfkPJÉÉ'ÀûÞ} g½æUh­Y¹f;©e„œïRRûW‡r¸ÄŒZ7K³ÿ…9h¯¡áS†sÙšOžyî9æÍËÌ™ µæÉ§Ÿ±¼›ç–,aÁü¹‘ïtßkÛö(mk=¡÷ϘF*•âOþ3ù\–|.K.7L®êˆÅMâñ8›6möî/rvÈ">ñ‘k¸é{7pïßïgóÖ­Þ÷7m®Ztû¯ñø6þ¯\.ñ¶sþ•K/ºK/º Î{;årqBmÙ¯ÜbÁ>ßò㟒H$غ}K_XA©Tâ­ÿz6‹<4,>òHæÌšÉsK–ñáO|†i}}ÜÿÐôg2œyÆ+I%“̘>%Ë^àšO~–ƒ:eËWð¾w_Jß”^˜1u6ò¡šL:Íÿ|:Úäþ 1s.XÀ⣎äÑ'žäÚë>ÇIÇ˺õɤ۸ð¼·5õ̹³gñÔ3Ïò­ïÝÄ⣎äßÎ>‹§Ÿyžo~ï¿ø’ÉþËßBpà¼yûd¶‡)å@áÊ‚ÚùuMwjÌeŒÙbEU_D,!a!—p×R_‡´í¦[Dÿ´ivè!üê7ÿC>_१¼ œùšW󕯃}øƒL2…›ü¦MÊ⣎ÆqìÈq˜6u*÷üálßöo´µ¥¼Œ®¦ÆO»–}ë×o@+! Î{Û[¹ñ71µ¯£Ž8œe/,Gi͡Ռ΃<Í[¶€®ôïýûýì±´·gxàI¥Rtut€®X`›·láÀùów‹[¬Æ‚)•¹ ¸/—&ÁbÙŸ³ÅþþàCH)™>m*Çy8gŸùZ0ÄÔ‘’ë®ù 7ýä?yêégØ´e Ç}žûVÚ3>õ‘qËÊ3Ï?Ïê5k™=k&ÃÙ,}Sz¹êòwñíïßÄÚõ˜?g6—^ðn¼éÖ uâCﻜŸþâW<ðÈ£üâ×w2ó€~Ž<üЦïÿ·³_Ϧ-[yòégغm;§½ôÅHC2µ¯{ï€B±È´©}œÿ¶·x–Ò¾F éX*9gÿªØ˜Wõ;ÖS±‰Jƒ± K½4<éø¸á?dÛ¶íqøa|÷[ßDèJIž«¯|/ߺñ{\û‰Oá8'x×åK8ŽÕ° ozÃY<öļõ‚‹xùKOñ²ÓšCÆÊgçüëùô¿eË_à×|ˆwžû6’‰_ÿöwØ´i3½½=œûÖs8ôàJÚôqÇÃ#>ÆÙ¯{-¹\Ž¿Þ÷w¾ûÛÉåóÌ™5‹/ýûg«É7š'ÿùOâñx56º›Ñ(·Ž¹ŸÇ÷…çŸní0jëKl´ÒuŸ•Þˆ!š‹‘mZ¿–T:½Gô§Ë1­fèw«W,cö¼GD‘[ÁS…þºkçwjô¨1¿?O M“b>W©¶ –UƶFÜÀ™öNò¹a/i˜&‰dŠ|¶’¥uéWñ¦×¿Ž7œõ:„8ŽC©T@{1KA"™À0cˆª««\*z.ç°wBå(èdª ) lÛ¢T,Ô¶=‘DQóy²­r’¢›¶lš1ÉTÍý±x‚X,†­4V¹„U}÷†M›yëùòÓ[HÿŒÄÉjâŽ@)E¹TÄ©nU¸îs_ »»›+ß}éøà¼z(—mÛ¬Y±Œ‹Ý#xò…çŸ!ÝÞa!÷ùóÂZU‘[TDû¬“ Ó,ìóýϪp×P:¦ÇUšªT*Ï’Ïe뮬ùÛ¶ll«6ý×q¹l6RC/Š@¸föNWøæs¹è¶‹¡`]ã.²,¬@Z¹TŠtõOŸÎ©/} ¿ºó·\vÑ…|ûZü´uë6îàA~|óÇ]¬UZl—Ö¸· i„ƒË “¤c/—±„\†œppiOìN'yн³÷’R—_v Ï/YÚ°?†aðñ\ÃÔ)=cÊ*mçU‚!§¾oèmk¹fZÔ¢ X.-š,*©ÃN’a'IQKÊÕ£ƒÒ¡Ó,2Å̆–ußc4 ¡é5 ¡šü+ÍœDãMdBˆŠbwçXjÝtu†-VxêtZ!ieí•vËèSJíw§Ü¶²Å&‰ÊÚä™ÂÔÐï ʤPΰÅJ3/¾Œ¹çnÊê1ó¡à²ÝNÑk&HÑcÆâ8Žƒaî^ÅqÌX|T§XÎI°=Â%6=³{]b-š¼°§¹ÅŠù,Ò0¼V ±ïsW+ ?I$4¤¤M§Q$#KÄ¥CLØØZSIÖ•»°´`y©‡ƒåfâbÏ<Ÿ>-‹dd™lÈnõMV;óe4¸´¥3 î@ÆnÓÒ´ÖX–EGg÷¨!—MV{x?(ÒÓ€ÑbìM‚Õâ°cÛÖêf×ÊûƒÜmô'‰bÂbQrcÈçÐeäH%Ê<_œŠB°ÝnczlpíK_,K¶ÔS÷ù“`»¦Ç ßœO$ˆÇ”ŠEb±Ø.­5Êq°,‹xgª™#c”к"ZÀ²w¯7òûî˜ý XZಠi‡¡¤+¾ûž]¼!ÑÒ&y'ïÄÉ©89sQû•TÌóñO5²ÄEy§æÞ[Ú$§’dY•ð@­EÑä Y[ê&c”HË"±j6_Å‚iÏÞ'Ô–ŒÞÚ°1RËrÙÉdkƒ¥>‚´Qfz|`§¼'«’dC*AAíÚC¾Úe‰Œ,a…)…!4…• ½D#DÅ^ht5Ö¢µ@!ÐH”®\éTŽ$ ØZbi«ê›ìejiÉ6§mNÅe–’²DÆ(‘­Ã¢ö5°iQ \önmX,/O¥„AJZÌ‹mqÃ×&`ØI1ä¤PIœIŽ—˜B‘6 a“6Ùˆ2)Ã*AÆ(Ñk6_ K¸Ž9¡«»Iœ19Æmm`i“rõ_I™”´IQ›Ø“0U‰Cm²3BÑ%‹tÚ¤Ía‹Z´OúÿÞsGk¥ìR2ÆPÇQر6L»HÇàH5ñ3¸Ë‰©”S(Å{ÐbrÅ´ó˜vÓÉaØ9 ;ÚÖáŽÃ(%z#Ÿ“(ï =¼dRú9±±O`ź(¤gc©É]0Z‘(o'^ÚJ¼´¹Åè-jQÔZyäþ¿¶Àe²…bó)‰$qm1Ã~C?CÌ)²²›aÙ‰-&flÆ´ERçIè •'®ócÒÄ·˜s–‘ßÚfг‘.3GwÏzú¦)¹uÓ4Ð7mƸû¸iXñô&‡Bƒ"1C`9cýt\2¯7ÎÌî™äØâZ'|n]k¡´hßÝŠèO*9Jó÷rl¶IÇ%/[”!Ÿ…±qÐbåÖ2kÇLí Éô“¾ŒIwÚ$Ÿ¸µóèª<Ë·5>cdv—Aº¸žÎ6“Þ©Ó›–Û¶ÐÕÛ7f€É•5/lU¬j¼é±] ñªãfS(+väl¶dm6Ù —Æ¿YrfgŒ¹SâLïl.ÞÕ—íëÔŠ¹L¦Å¢4ÿX^–¶¸ä¥ Ç,JÃêm%–n.1XŸ°›Ùcz‡É”vsÌu3´xN1Cðüæh÷×ê˜Fwqcº5©˜X†w0ᡬZ¾š´` –fÕÅ ÛG¯ùÝ6­f“ŠKRñ8ýÝq޲E‡­Ã + ¯´X;hÑ™”45ÁìÞ²DnQËriÑ„EÃ˳¬´IÅ/[˜!h^°;J³bK‰ç6•(Úc›)`NwŒþ®}í1Lc×Hµe›Š<¾®¹LªÙ’™’î6 ,sæ/ô**;¶ÍªåKhï쎘yÍÚAÅêÁæ@øÐ>ƒy½’gŸ|”Å'ÒðZÛÑl¶X?`±j‡…ã*Iš‚ƒ§%˜×—ÀA¿årìúÏrìq‹™7o>RH¼ÕœJ9†aŒ¤Ô ßêQÁ&Ži_Eà¹hªÖ­w”ƒm;ض…eÙ(¥*L•¢lYH!)—KÞÆSǶ1ªe¥j™ÐZã c;ØŽmÛ¥R Må½Ú)eå;!p”ƒ–•Ó,ÝÞÚ–4* œ!%¶ãxG?hÀ0L{¤s¦a€²*ù‰†cÛ)ÑnIüj¤ˆ£œjel!p„öU­ºúÏg!ÐJ¡´F ašØ–íËRÙÒé?•ÂÖG+”r*§tjã8‹Ebñ˜÷™”¥RJÊ–EÌ4±, Ã4±Ê–×N´Få¨ÊOU)¤¥5ÉDËOÇñêæR¢Ñ8ŽÂ0$Ž£R`[6†ibFåýBbÛ¦i¢ÑÂÀ¨Ž«4 ¤!1¤¢e¹L åmÖÚž&}÷Óà ]U¯:l$nñÂæÏl,R#¨ÌéŽq@wŒé1änP“œ–¤=iðÈêy«±€_]L\Ðß.èKKºÚD(°¦Éœù ë,˜¼fKN±~X“-77^)Ž˜nЗiÞŠ4 ÁŒ®83ºâ3[³qÈbÝŽ Ð4CE[óøº"Ïn*qèô$ ¦FoâÜ´i©tŠ£…YÿnnÇq²Òv÷§ûýXtCÿµAàÑ3pÜ3ìý›I]áæ^ë }[´®dJ ²ZÒG+í4[)Ún¶m{Ïvûh(Aµ´Ðh©Bûàž—â–XÑ~ÖfUîVöêǤª‚ÉÈî}Qm«”­4JI¤Þ8hCÕ­¨5¢ªqTÀÈU „'èÝ6ˆ*ÈV€¥*ì«ßi)=Üqûà8RT„½! œ*8»ýÓUª(ºnÂ{¦;'ÁùB ”òž¡•FÈJ›] q7kjŸáΙÖ©¥ªÇ¤µÖ-pÙ´v{™§7Çäëïi3˜×§¿+F"¶û˵LëŒqú!&O¯+ð¶ÑÏzÏ–5K¶i–l«ì}iiftMas^’ŠiæH°½d$ú²|ó–dó Û1ƃŸÓ)Y8Õ >ï ”‚þ®8ý]qŽœ©X?`±b[™íùÑ~+ÙšÇÖX¶¥Äa3’Ìì©/ZjÆLb±X °¸Ö]ì® “( ˆ²\’+@Ü:XÁçxZnUø˜¦é=ËVRÊš²+¨ª%Qy”@JákC,¹¿ú>%œÚB|‚š¶ûf=¨Œ˜dBÚ¾k4ŽR³Ò?ü„ ¢í»ý5¶vFN]Ô´EZºÀ –r¢òüCÅw·®`µ2²ÛG­|†êÈ8»€¥Ñè¸ïŽ“ îÁyUZÕU˜ðƒ¿_Ap\KOŒ\ë8Ž*î»ÝŸ®Rá”g8W·TÇDHÙ—É¢®´É¿.îjêÚÁ¼Ãß—eY?Ôü™.ózãÌíÓ›Ùó¦,n Ž™ÓFWŒ§7›ºP)‚™Õ)–îv4º§ ƘÓЕ,œ"Çd­4C‰˜d^_Åݵ-k³r[™M€êpIñ•yú·—9¬¿6=Ú±†‡‡½Eì×bGNÖ‹Ñ$Êr Ö·rŸã>?êÙÁ{‚µ×ü‚^ У쯸”DÄkçJ …>k ѰÏõßiÏ%Ph Nd<í^TÎ\†D‹Šví_§àn§Òœ*€OЇ L˜â¢ÃÏvñ÷#xäCpœüŠA£yó+ ÁïuÄé­A…"x•ù®ïkËrÙåô܆"ÿÜÐ\œÂpð´s¦$h‹ïùE%§uƘÖcõ¶2K6(îúRõ ÁüÉ;¼z3&½“Cf$Yµµ/ͲZ?d³~h˜7ç×ÿ¬€’iuÚa0„E”`>ÓïÎ +?ȸšëhîµ0í8¨ä{ïÒþ˜ƒíg૪5òÜÑA%TxzVÂÈÁ"øÿÿ•öÀÐk£yvµOÊQ­‘R „¬šlÚ®Œ±®ÆPËn<5ÊüãÔ`¢æÂÏGu q²y \víÈÙ<±¶ÀÖÜèZ}L ž`n_‚˜±÷¥Íî3»7Ά‹Ç–m&/Ó;ýÓ3‚Y’©í»„Ûâ’CúS8-ÉÊ-%žÙXÂ%`ᬗõüý¹2YYñïûã)Í ¿;*L „i¹Qd"Â- `‚ÝçÛjΉlºjCT»µ¦­U(¸T¹‘˜@õÒŠãkº?öàUÒ—¼ =áÛø´É pêбþ“8Q׎2Á˜]%¾M-pÙ´|K‰Gךºöˆþ$ úMe|Ý{Mm—L-/cî!ǰ%«Y·£Ì€=yuϦ¶ úÒЗ$ÍŠdMëv…n3ו$0¿/Æì“å[Ë<½±±»¬#-9ãØ$Ks1c;¼k#—Åhø0A5š0‰òÏ&œ%Œ&ÐÆbÍ\[n¾{Çó®`{Ã\‰QnªfÚ=–dŒ LÖØvM£9r¯¶Àe‘Öðøê|Sî…}qš–u“£;‰n`Ïý·§ž=R*•À.’*í`†â„ ÉÙCÅJ¶W®¬)XPr4¶¢&åW 0%$ A*é¸ ¤cŠõKɘíüòçwñ‡ዟ¹ŽŽŽŽ¦ÛT,îÜb”³;ajÚdåvÅŠ݃ýbìá€Íê-®2ˆŒG@ŒæÒñ_ã&xUƒS=›ILˆ°Æh"–@صQ`2à Zž€-× ›ëñ¸ÊKÔó¹ÎêÆîE/z‘~ùË_Îg?ûÙ4cYqûØÇ8çœs^W(+Z™gs¶qÐ~Z»ÉaýIzÒfSÌàjݶm“dxh€|6‹m•.ÜÝIm™vÛªK7ž¹û` Ã$ŸËî±ü"¥ÄŽu±MNeØilµõ¤àð©¸h,“á J—·šyF”ÐoF;‹e4+Èݬ» •ÚÈý8  š/6ØhÏ‹²\%qL„¢âkÍÜožyæ™~øá-Ô˜D*8Ü¿<7jŠñâY)æ÷%š^h.¨äsY6¯_ƒãØtõL¡§w*±x¼¡}_#Ã4½Ýü{2)¥°Êefd‡X¾M±IGþÜ^€‡WiŽ™%È$ëƒö“EaûYüÂ82Ó¢ÜFÀ¦ÙS>›ÚÁ,·0WbTvU³–ÊXÁ¼™gøÛL5Îw3VÊhI“Á+c[ó#ùH &‘ò6÷.Ë5Üe?£ÃäÈ™)Ú›,Íâ‹eYd‡ذfS¦M§»·¯5à{8I)I$“$’Iº{56ïàù&y«5ç-xh•âØÙ’ŽÔÎmW³~¬§rŽçžÉL¿PvûfíŽöí¾õ2™@$_ñŠWpýõ××h2ŸýìgY¸p!ÝÝÝœuÖY¬ZµÊûþøãçóŸÿ<'žx"™L†cŽ9†{ï½×ûþž{îáøã'Nsàríµ×†6Ķm®½öZæÎË”)S¸ä’KX¸p!/¼ðPñ‹à`öìÙL›6w½ë]är¹¦ÛÑÌý·Ýv§Ÿ~:üá \.sÕUWqÐAÑÖÖÆ¢E‹¸í¶Û¨ÿ=o{Ïǹç©í eËŠ§9ùÀ̘€E)Uqƒe³¬_³’þÙsZÀ²’‚þi=œ0zôŽÈëÊ<²F‘+×Z~K&*•·7QPû‘?†|·_0‡Y*cuÁ¸ïvÿù-š æ¼6¬½£m0 îÏi¦½þ¶5Z£Q®ªà½ÁöŸáŽ­üýßEµ%jNܱq†ád’êÞð±}Œ;ÿþïÿæá‡FJÉé§ŸîíÊøÝï~Ç 7ÜÀòåË9å”Sxó›ßL¹\fûöíœ}öÙ\xá…¬]»–_ÿú×¼ño mÄ5×\Ãï~÷;î¸ãï=K—.õ¾Ï{ÞÃÚµkyä‘Gxøá‡yþùç ZYQíhöþ+¯¼’sÏ=—{ï½—“O>™xæ s‡R©ÄÖké›6ƒt¦£%©÷bJg:XÔ'èÓ["ß-ÛðÐJ›lQ7J»š¢\S£ à±jÝ;£¯n}®ñ܉¶·Md|w6˜4²^Äé§Ÿ®Ï<óL®¼òJ …½½½Üwß}sÌ1 3gÎn¾ùf^ÿú×süñÇsÙe—qÑEËåhooç©§žBkÍQGÅŠ+˜={vd …===üíoã¸ãŽ X,’J¥X¶lÝÝÝôõõ±~ýz¦M›À_ÿúWÞñŽw°råJÏòˆjÇŒ3šºÿüóÏçòË/o8XÇs W]uçwPÐß¾};}}}¬Z³g’‘UŒ“†â”ƒ:él3Ƽ•R”J%†v°mózætHëÌÖ}´fùÒg¹ke3zã$Óí¡—epÂ\ƒD¬qºqXºòXŠ¿–X”O?¸›,‚:¬¾UÔuÞNÿQÚ4Vçw•E]3–XEp|ÃbTc‰/E½³™ »à˜Õu6 ¸YªIÝY¶lJ)Ž>úhï³öövN8áž}öY^ÿú××kaé4mmmd³YŽ;î8N=õT;ì0Î<óL.¾øbN;í´º{–/_Žã8,^¼8ñ–,Y‚Öš“N:Éû̲¬·V£v4{*UïÔÞºu+·ß~;÷Ýw[·neÙ²eäóùÐwºï¹ó±Mô͘zÍÐö-|ûŸâ'i'rýÃ{"eJÚà¼Sä“W]Üp<š—\¶åÛçÜcít›%¶¯[Âðò¿ÐÀßœÕ,ݤFˆ£Õ‰¯æÜÈ i&{h<®·`ü$ê³ñ<Ï¿¶Ç µ4F“1£í-‹²‚ã?kv¾‚î²°çFý…2–¶Ö€ËA„RŠûî»Ïû̶m}ôQŽ8∦ð²—½Œ[n¹…{ï½—;uëjOÝ[°`Bþö·¿…Þ?þ|Òé4wÞy縘s¼÷?üðÃlÛ¶/ùËœzê©pÀ ] SçpðQ'„ ޏäÄyib†uȪ?4 Mƒ À·¿ýmN?ýtÎ:ë,Ž<òH²Ù,wß}wSƒ000À/ùK/^Loo/ßÿþ÷ùÅ/~êRûæ7¿É©§žÊ™gžÉÑGí•ãpðŸøøÀ¸üòËéêêâ­o}+O=õTÓL0žû-ZÄ¿øE>ùÉO²hÑ"~ýë_óÊW¾²æš÷¾÷½|ñ‹_äK·ÞÃŽB8¸Ö?KOÚÓxLó·hï#­5‰De3mg Ÿ0CEͪ­ª) r²Á%Lè„¥(O†0ÝYà2‘64“’=–÷Œem‡¹ëÂ6†¥/G¥”6†£K3ÌsÌñ† 8à€ÈçóM ßÝEJÃoŸ =9rNwŒãçMN`÷¸Ó;v°yí 9rqKïcôì“rݾÌ[Þvg¼ú ï®§ÖiÖÖóWÜ€S6½£“òÅü¥Ù4ÔFåþGj‹E Ãf¬ƒ0º3,¤ñ–¼KÖ\0›/*VÖ¨MÁ÷4³×)Êm6^pKaÐ=¦^Èc=Æ‚ öx`X½­y$ñ¡ý©–ÄlÑ¥5§ !8hZøÒ,;°a@7UÉÖ/T‚›éê]t2´papSe˜¶<Ù–FðÚF›'bõL¤MAÀi õ#˜eÖ¨-6Swç»ÏŠº§Ñ‡~³×n«ŠüÜsÏñüóÏó²—½Œ7ò‘|„~ðƒ{…,XQåøÈþ$éÄžWß«¸Œ!VÌfÒ­XÇÁ¶­‰•ð×õšj[\°hªäùÍõBfÍÅÌ3T£ŽÊŠò[cÄ-·l¸°‹µ7™à¸·ÌÛn“„|îsŸ£¿¿Ÿ³Î:‹w¾ó\rÉ%{¸× “­%ôM7uÀ×.·Xb­ôå]Af,†Rθ,!Éd²ÎbHÍü^ÉÒ-õÖË@ÚSõÅ'Ý ®iš5gÿ„ "±mÈõÇ}F»ÆF–‡ˆ÷4Í]vì†ìƒcädK,Œ¶GS<«;¾2[ Xö†ñò¹¼WûÊ¿h§w† ·|tË`€½Q¡K¿¿}²©[ÅÛÝ ¯iÖŠ ³žÆ³ïÅŸ€0ÚáWaqŸF@ä)|v˜eÒÈÚkÆz ÷0Ëe2A$ÌÒrÛmFM›ü€Ý—±ºóBÒ{Ú ÚS{žÛ©å Û=Úóx°4Â]I™¤ +U/p†Šºfwy”ÐmäfÚYZn3î±ÝIQ”›³ñT~Þ—,ımÝ:æxŒ”+×/È­alªûæ?0*¨¡OIÃ@¡öú|YG&ÖÌÆ¾°]éÒˆw†€ËaaÁ¢™aω:¦·™¤‡ñ¿m O\i\JIƒS5'KQû»Qú´ûYK*Ž‘ÊN=t·µ†±E“ç~îGèj“@­Ål©ÆŒG—±—±¬Õ¬‹ªYÁæwïïsgÔóQ&"ÀÇã±Ç[‚%اFà»3À%LùhËN Lrïò.–Ëe~ô“ÛùíÝw³nýÚ3-\ÈåﺌC9¸©g”J%‚D<Þð³w\x1'—¿ë²£40²«ÒÉæZ3û'F”QVÀxÏbofï„krß#hê­²`F\ðû°Zf^ß•FSqm™¦YÓ/ï}”O¥RH4ºN¨†•„ñ·ÏŸÏf¬ŸfŽ>ŽrŸá·vÂ6vFYun¢HÔ<ûã0Rȸìôù/…%K—ñÉ~„Y³f188ÄO>IwWWÓÏøÂW¾J[*ůzÃÏ^rÊ‹9pÁ‚Ö 7F—Ðl±¨ê£ ò(m³™3U‚l¼%S¢¬°>¹V›ã8•Œ']›©å؈ŠÀRøNT²&HïØŽBT€"Ì]è|èD»±åTA]yŸ®´Í0 ,Ǫܣ1Òv×¥é•TüBÙoe7%ºíñ¦ŸüÂÛqœš¹ nšl´›^áe4úÓ£Ývú? nêt5 _,×U ¼ƒØ4X¶UÉT}ôk-î±Èx}uèÇž|–´Ú±S\%¥R‰¡á,Ó¦NαƎãðÛ»îæ{ßùGu½==ÌŸ7w§Œ×ż³Å4£Kbk„“Ÿò¥ÆVO˜ö ®h”‚H£Y5¡š³¨È_©Z’‚˜–hZÛ€ƒ!cdó%6lÙÆêõ›Ù¶c˜t['†4HÆãäóyâ©$¶ã‹™är92É i“JÅBÊf\R.—ª‚Y3L†‡sÄi†òEÚ;ºÉæ†I¥RäóyFŒ²U"‘HËçI&’Ê%Œx ©AhHÄâdí2(‡L2I*f’+•ˆ§’ä ©Ãۙ>¥“Í7ÒÛÕ…mY¤;3K%âfÛÑ$1ò¹añDÅͤqʶc‹Å(‹ttt0<4Lgg…B‘x,F!ŸóÚ›jk#—Í‘Ngª ¡(Û6¦iVXL‹Ç)—-ŠÅéTÊq*–š®ØY©tvÙÂ4 ²ù±d˱élË0<³8ºD<‘À0$ù\žtªÍ;3Ë‹˜«‚hŒR>O&•ô¬œááazº§Ëåˆ'(Ç¡äØC" ‰! ̘I®P@Û™DU¶‰Ç㔬2 „&‹c È ” #£#Ù†išäó•4xש•FU÷J9N¥¨êàà BVˆ©D‚¶x‚r®À ÑÙ‹ÍÓL3¼m;mmšr¶„¹ø¤SZˆ1xn˜íùÚàªlïcñÁó'ý]Á•“A±XŒ³^ûZ>÷…/²téRÎ:óµ,Z¸°îºÿÒ—Éåòüô¶[)•Ë|ìºOñïÜÀ‡?pW¿ïJr¹\ ,ì³0úûýÿàc×|˜iS§ò½›nâêk®åž;ï ‹ñõo}›z˜ë¿úÚ3~xË­¬^³€Á¡!Þõ‡¸úýïãŒW¾’Í[6Wâ<ûBÌÅ‘ÊÀæáz·T[¼ùã‚wEûkJƒ¡$¦M¹Xà÷ÞÏãO¯aã`ûÿ³wæq’e½ÿ¾ë9§ªºgÉNBHk@6¹J‚\e‹ ¹zÃâ ²ˆx…+^ÀPãF"‚ (Â5lBØBÂ!@bÈ6™d’É,Ý]Uçœw½¼ÕYº3 >ó|>ó™îªsªN>õþÎóüžç÷SÇÐU§“‰ä‰±,XèLÛM±Z‘b)Áô}‡qx“AT‘Bá\¢®Å{_Ê=!"Ìzbr(9ÒN–ˆd¤dïûH¡4¾ëJ#:ϼ°$$‹¡ÇIî2f®fœ¦H£ÑY“£@ MNžÎk\>šäkd½‘3>XÔ&ÝÞIäðº>b”aii‘Áð8ÆêA÷çܬԥV™4Jló©Æh8v:]ÀD•,bÚ¶+å1#4­hÌ5,õm$II‚,€%”d›÷Xcèü„aeé¦-Óº!{¶EÖuC¥K™O IìzL´[lB‘Å>0H‚D/™n¸‘œ3¿ôŒg­ìB yîÜ•Ñ4 u]3¶Ü´y31%î{ï{ïV2ZŽ{Þã<ü¡åܧý<:ã Î=çgyÄÃþC€.kû»ß²°:™¾~°÷Dþ]ìÙµß×—Èl¹õV.|ÛÅÜ4™£»~¸¡˜T˜Ô#„&0GŸ3“œÖ‘¥ th$º2´mË`0À9‡®&½#3$¸eâ4a´ÄXÃÀÎ3î¶#´Y!çkbRÀH…ëzTe "SÏÍáC"Ó ÙS'ƒÎPIÅ–JÐhM ›,"f" ÅGO-+äRÖbmMç##åq‹K(Y““%†ˆW*C"J(­5®Ä’¢Ö ã.cÌ Ót…Ë‚ˆ¡mZ+z_€O)…ï:4¥1'¦] uUÓûˆ–‚ièõÓ˜è{A‘{0† !*FÂ"¤ óf°‘^ úJ¶%+²ãA…šÐGT¨!x´”TÊ`²Â'p~‚%ã·!3¨~‰A=w\4Ž­~Ê®ºÍqÚ1õœ¾Ø¾âA§ŸÎƒN?%%ÿòáð”sŸÌhTÈÃwÿíÛYd½¶Š;lW)Õ@ñ­~_þÊWùàÅóë¿ù[üèÃÊ›Þø†C›Ç“’Ñ a{ÇB"\·-­.{wŠ ²Ú9^ÞfWâÿÎöé”DåŒu|ó;×ñÞ^έñXú¹yH]èÛb"§„V5J[\×sF(‰j¦Kã⸡óTº"'¨š1*U“eB"È©B×È„˜ˆ11ª7à\OV m5Ѥ˄èÑ3jæ˜NZDï©¥Ä9‡5Q×e±—‚aS³®ó1eº ÖèÎc&‘X –Tâ¨õñ$Z‘ñäYàDO¨j–¢£6.DJ£BO?o )£·­ ®#Ƅ̉Rø±£}Û±¡Ðùb&º)º²dƒŠV&FB£ÆJJl­B‚§š0í0JcKçº*çC ð™‰ÍcˆJBÀ$M®§R e .;p2gzái*H™¬2ACʹ¼§)2F•ÐL†Q4‡å_4FµâÈáÞ寘2×n=tëÿÇwÜÊ|Ê Çߦiøô¥Ÿ»Ó}–[:÷õØþÆ 'œÀW¿öõ;Ýîa}¿÷ÊÿË;.ºO}æ³Ü¶uë!}MŘè]¿ ܸ-WÁ– `X‰ÝJT«ñ¦ÄË®QGƒMž|ùê-¼íÿ}‡›ã ¦ý"/]"¸@’L„è\‹Ò M&'Oìµ¶ˆ äe;ƒ°Â=zï‰Þãû£$•±H)Êã1b­!I‰ª*”HŸ¨eÑÚ¢ëšÅÉ”ŽD²Š Éj§cDÎ(UHí¶ïpí„еäà9º£ŒRøàI1âûž\•…ZƒÕ b`P”L4µ&†ž<~Ú"c*ÛHFQkB¸èq9ÐÆžlSßAÎX£±F£¥¤T@FgÎ!µ¤6†èJ‡[ TÆ@Jh%1Zá¼C[ ­.Ÿ7'ÚvŠÖ këæF"®ÌM‰HBŠŒs½ëhû–:eê$麎qò,0RïƒËÁÄÉG¬.Rùï7wLúô}ìmÛòÛ¯|¿ä“\wýõܲe þèÇx×»ÿŸý™'`­å¼_úEÞ|Á|ñK_"„À•ßúßøæ•+¯sì1Çðù/^Îí۶ѶíšH ~æ‰gó{¯}ß¼òJ¶oßÁ[ÿúm+Ï/,.ò¹˜Û¶n¥ë:¾òµ¯Ñ4 ëÖ­;䯩å!½å˜º¼ª— ÀñëÅšmË«e&»z®¯åTx B{¾–ò 2ß¼úþâÝŸàÆé:vÄ9AöS:7ŵ-•­ˆ)ÒOŽ”z¤J™ÈÉ‘¦=né$þæoßÉM7ÝD“O>™W¼ì·xÂ㻲Ýs~åÙÔuÍk_ÿFnÙ²…£Ž<’g÷Ëœþ€ûð´Ÿ{ _þêWyÒ¹ÿƒÇ=æ1¼úw^±êc/ÿÍ—ò†?þ^ðë¿RŠŸ~ÂãWîÌ—––øÄ'?É›/¸€ÉxÂÉ'ÄýákwS8#/+ï2ýý·®,VÁñå^¥¯µ”‡w„Õžßñ¿?C”NM¹õæž÷¾÷J´n©‚ÅæÄ4Hz9DeAò¡ÜàÚ 1{"c,¹¥-;C œRkÚ¶EWÀ³b  P+­´iFÜK­±,Ö©DU2š ¢›cKUYÖU5ãKd¦2x稛×N²TÖb&ôaÙ'Ò¸ÃùÀhݽóDç±J(a’²ºK€`×Väû>ð!´3òçùöÛoç1?ýD¾ø¹Ï ÒN'´ý·ÿý«üß×ü!¿ü̧óØÇ>­57ï„oܼ:¸ÜïXÉIGÊ}pXbÕ í}í³gv²Z”sFfÈBIˆXl;.ø«K¸yû<­ìq²GŠu7FJË—Vi"™\*!P!âS$ÉR”®‡µ…Pî¢GH‰m Þ;$‘Á*MN‰<¨JV3[$­ÏH!pºÜ¥“ AÌ SYLeÑ9Ò·-F*¤(!ÉB`ššÛ—v`Ú¹“áëq]°¾±ÍõtƒŠä:Ö¡È¢‘Ø$˜˜“-]ð‘‘ ÂdŠA`¬EÈßyr$sMC7€­*¬øñ_©²€Oz–4ˆÊ€”Ñ•%º@žöTM'‘SF[KH‘ª®YœŽÉ­cã`DÊ™žˆ4š8ï°uMžö+J1F¤’D‘1MHáÄLÐ’#:fBŽØY¦Ø¶SÐ/‹»ð‘ I§2µÏ‡Ëb§]±aÖã/ߨ²}Ÿ¤» ¾}ÕÕÜý„ãùìäÎbW¾daš×–ùZì,wVÒZí÷=eàï,3ÙSu9çLŠ©LI¦L ‘3ïÿçOsó¶–1 2Á%¦ÂÑEK1%Æ€Ê`‘ômËt<Åw‘%}çIJ‘”]ßÑu-¶¶ÄÑZáúŽœ3!–Œ&zo;¦ Kdˆc`*tȨ4û\)!cBW0¨UŽ×ã\O3€(zx9' ÓûžjPƒ–ÌÖч„¨kTUÓ{‡Ö ‰q#Žˆè=1'úà·S| ôÑÓ¦„h¬i}ÄùXÈy-èc¡H}@&Îã½gai‘>y’O šoêªðKB ä¥2Êj|ðômÇ„8#æ#K;°J¡Œq9€.üJm µèœÑJâú9ãgŒÖd%˜¤ŽHIÈå|†Îr&IKÅé˜( x.{G”0U‰uÚÒ¹î0¸|/qúñk+ ~ñº)­K‡OÒÆu×_ϧ>óYÆã1×ßpúgÎyOúõgÎ9£¤¢ópÅæµ ÷9V®Y¶º³vá=ÛŠw5ÛˆVãev+¿Í¸ A„$¸âª›¹üÊÍ "y’È ª $ç‰ B­ÑFÏ fbRàR" @)¢a4B+’,?ç\Ê<ι²ÓÔ¨ÊÐÇ@–¢”}|@Îþ9‘´ÄŠ, €’à ø&KcbJE@Í€"2$L$ Š‘4%+Ê?mvžáÄ#Ç…Ê!blh† †CÒÀ’çP™B¶ÇržëÑOB›ÂÇ(­)âI¨¦¢š¢5ª©uCTš¤ !K”‹ô;—¨’ J-%Ó¶EjEtmé`V*I2B#]DHAÐÑØîÊ{_Ê_9b5Y ’xï @î'Ó’¡Î´Ëªª¢ª*Œ1+¿çœ(MÝ'ÚÈ´$BÔu}\¾—8zÞp¿cW/M\â‹×MðñpÕñ@biiÌ…oû~ꬳyáK^ÊÏ<é‰<åÉç*(qp™‹’WÞ"iýêÛÜë(É‘sr·’éžDý‰E®õØZà²gyìŽmA)D „ùøç¾‰«Ž!Ê¢G)‰— ÕT˜º*z]>"…DÍäJêº&äZ–;d£@+tS‘µ¤™‘”Xá „(³!Ú²–x2YI°c-v¶Ðu}V“­fÒw%ŒH¥MVi0šÐ;jcËÂi4‰Ìt<†˜P!c"Ä‘] .LÑJчHl:xP‚hK«­H™ÜyüÒÝÉUpAV˜, %ºàHFá‚G]¸ IKºHZ’Œ$×b8Ä EaiÒ1q=hE}ô„œ¨G| D‘AL†"!'²Õ,õ-ÍÜc É9Ú¥ }ß—y!]fd0YYú™öV[ e†EÆ !R×5Î9Ú¶•ЊÃèòØB a$ÌÊs‡ ýï1îw·†ÓÈÍ‹{—ÁnŸDþíš1¸çÚ|ÿq<ÅxȹQ>ðôð÷ïø›CòZ8Ø¶ß ÇžŠ:öáì\cFõè9Á½Ž3æ IDATU{•ÒvU²Ý_9ý»B& $n¾e;7ßÞÑ皌RŒ¦ïY§Š á<ÓÉBs"e‹àb‘*ÑÆÐ¹ž0kÇŽ9Í8å9Š2‡¡µ*ÊÉJašn¦¤ìIèÚ’c¦¡%]ßSkÕš˜R+Ú¾C+…ÑøAHr.%ž”S¼’`P…Œ—Ev¥¶Ÿ¾Òx‘Ñ)!¥@JAtä[êõ ãIKÒG¤* rR¤`0Òw˜B(\ Uø‹¡áB Ä@Eßï¨á<Ô†qtDBŽ(ÅÒü „@ Á1ÍÐèÅŸú…ƒ­úü\%8ýxµ›,üj|ÍžrïËÙÍ®’ì»ò.«Éº¯{J»g*f´Œ¼ç³W°Ý7TB¨b=iÚ3!ÇŒóŸFKæœ)¥¦z€‹´ÄËHè&$¯¨EÊr×+}Æ(Ťï‰)aŒAiÍ ¦ž,2},ú[ªèÄ ûHÊPd]U #ãdFx‡Kœ5Ù."t“Aô]W´"HS†›$ˈ¯)9¬ x! A“ƒÀ‹=F‡¥5:× {’RU„¥ÑYÊ[ÞwÄѺBH£ÌƒØvâÉ)¢jÃ:±VäZ1jä8"DÑÓµ&ÐBzÇ`0¢ ž¾¢…¢I™Üg`ݺ!¹]Dú ý$Ñ{–iÛݶ, ”DJH¦ÃÈ¢jK½$qRÐiUÞ7lÓÐ%pLŒT¦pBIŸÒá²Ø]•‘ü·{ iÌêw„‹]â’«–¸e§ÿ¾WŒ±n‡ã?Xfs·.%n6÷ ®®‘Vixð‰ŠÊˆ;ü2ö•åAÉ]],wÝfWïýÉnö§ô'ìœ$®¿i‰‚ÅÅů#¹ó˜$˜· µÐ8RáQ” ¦YBÖ(UÄÈ,;Ñ+×®Ñfe†E)…O±”ÅrDÏT±^×èÄap¹«b®Q<ò”!µ^C0Ãe×NøÎ-Ý÷õ¸¼w¸¾#ÅxМÀáX{¡M1âú®¡×ÜùòæHfõëÅ*x艒aŪ¦P»f {ò&1Æ•¬eÏÉ=Aiß1ï•¥ùú·7áôÆRBÊ‘¦^C)B $º²¸PFS­á%$!ˆ)cƘ%-R‚/YT¡d/³E[)µòÞº²x ±Ö%D% ™=lÀ(BN)!&¦ã )erÊ+†Òj’’x}¥*í¼"Ú”шA•K‡X¥ Jil]—¶fcV8 )%YJBJxï±J#g弜óLmXÓºâÖšÄÌš Æ™¢²ÇÅ€±}ÛÈÅc]rÌ{Éú¨±‹=*@3ZG”ê9Ñ4ÍÌÈkæ© 9)bhÝ uC¦bi©Ã(K­+²„¶'t=S‘• í:T,s3¹2Ôs#0…ódRç‘>¢4UM †€wtÍͯ[w¸,vWÆúæŒS‡|îš ]X}!ÿæ-Û&žÐ0WJVË‹Íáø¯qŸùöm‘Û&ký2°ÌÕ¬Èªï »ªï{ºÞµxš¾þ­ëÉÕQˆ¸€‘à„R"µaZkPIás$FT‚©ëRbm©&íAÆZƒoÇ+ã)%„Öø9,¥$h“G IŠe¶BAÌŸ˜t-ÃÁï=QHwQÎSÝÔø‰>¢§1kl!Ùëš$%.”R˜i˜eK™q芬Šs$é\ÀVrÙs亶„®ÇJ )“| 1[ç\iÜÈ0 ™LB™`JãB‡€ó˜ã锺²¨é4$Y¸¬ ¹õöí4Ã! “1U•ÑÁc´Æõ¾L܇eÕC;í©k ¢u)Y’9„I ªšè=mï ƒžô4ºtó»)M£$‘ŒJ™ÒhÆ‹‹èfĸsh™‘•¦õ=IE‚kg.ÿó¨{˜«Ö>µ·,>ö­¥CZ‹ìpxܸ#ñ™ëÂËÀÀÃNÌ7»g&«e-{fkýÛ5 Yî2;Øò˜™*GnÚ"¾¥¶"5aê0,Šì#C(º'©|¦Î’4TR£cÜ.“£ªBDlcÉ„d ¡/Æ|A„°˜¤(‹ #JJtÐ!!bÄuƒá=)EŒV  }Š„”èÚŽ<ÛW+Eç“З,¾#¥B\OEdœ<4YY°5Y•öèZID詈Ì+Å@[ú\°åÞ|íWùÒŽ-Lâ>ð“z#OÛøh6Ú knóÕM-›wzî·šÃ;þ‘x3ž/Ñ1¡Ò>{xu>Dcg›¹jkäöégšÌéÇKj³{Ùk­X-“Y 4ö·›lã¦[nã–Û'ø¹„²CB£$Í aiq‰”!zz×ÓÔ5*‰Ò…äÖV$DŒ ŽL&ÎÊ0ƒÁ©ÊT¾V‚v2ÁÌpÑ#´*þ#)+ߔХ°ÑUüX´Ñd2Æh¼÷H%K3³’¤œWÚj;ï¬Rt“)­K¶")•Œ%ÊLm,Þy9ó•‘Rc‘ð)¡D…óžfn·°«)bŠÈÙßχ0ã4©ëÁ–Î1=ãU´TÄ ítŠ2…[ŒÊ ¨EØTUÀjCH™aÒ1¯kœO#: ‚O`"Þ÷xßamEŒ…w’JÑy‡KåK‡«­ªRÊL™dÒ(¼›Ò IK%ÃêS‘Á1RѶ-2]´˜RºÉ´€`lظ‘$?——}ëRþðšË©å“a;WÜö^~Äc9©9aÍín] ÜzÕ˜ÓŽ²Üë˜mÿ?<¼"ÿDç3×nO\·cß܆ñ;xÐ)sX#÷š¨ßŸ¸3iü=»È¾—rYÊ™nÝN57G®}7Æ‹©$“Ɉ"þ“DÆˆŠ™¤B)ŒR¥µXëÒ.<;ÞeÒ{2™¬ Mj­™4,u“bm94ígR%BƒPJS!Æ™ où|Æ„Î)Q×5mÛÒ÷EkcñÓÁ$H9ÒTB(’.|‰˜«Ó a.„@Kˆ=.Å™ÿJœ•¿<9D¢($>RàœcÝü:"‰,%º¶ô9sb8hð½ÃÇRÔ•AÕ†íãEl3@ZÍT”‘#IgÚ®Gºâ;#P…O ‰äcy SÑ¥ŒLyš’èC±.–ŠJ(2« G6™LfÙqFÑRãs Ò5ÚCï]Ž´!B.n¶½wئ.×ÔL¦ß EÖ0i{s£ü²Ø·\sÈËrl#ñÒmã+‹ßØç¶Wou|蛋\µå B|Ìá•ùŽà»·G.ùnØ/`ùÎW> Û®X!c÷•±¬Í‡¬]"[~þ{–ò:‚ÅS²ÐŒ]K'{úÐBOÝ”· >El’"QI0ФQdÚ™¶•R cîº+\L™ªïºŽz¬*”Hž®-ºmËÛ !h]OëzúàAJbJ(¥îðšý¬µ.–¿B ú€O±Baœ©U®L®ÈÔ„÷RW5u]ÓÔ Ãá°ˆAΚ¹Aú"h¹ìši«2 /”ÄÔóë×ÑGOï=.\*ºi„Ï—#º¶e RJºé”¦iÈ¢4¨Ñ€¦)äy=iT!šŠº®ÁhÒ°"IG$h“… ’ŠZT.ò.ƒº&û€ÉgvÔ¢tµYmh”¢–@tŒ–¬Ý@“C #RF ¹bÏœsÆ4­3sJ¢ƒCdOE(ýAÿ¢¾éÚ¯ò‹Íë/çý[?Á‚_Ü÷Bsó\ò¿çÚ-$Ä'^©¡ð®Ý¹äÏwnß7¨l¨wó×qù‡.BIµêÄüZ²?YÌÁÆšÒ/³Ç'“—"¾wô1àd)O&(©ËÀë,ÃÆRIßw+r+BK¦}Gç<ÄD­-ŠR"Ê!b•£È3¿UL]¡¤$§Dßuô]GŽ©È»K)c« ;hJSÂ;Gè¡íI]ô±Ì¢¸@çÑ(’–dYÄ-åL‚ÆÎJbÎ9¼¥#­2!F¤Tèª.Ò*!Ò.,"rÆ *ŒÒ­ ¢¨ ÷Þ!f¥Ke%9zdŒÅÏ%¥"Di$Q RN$ÁÀÖØª*’:1¡b*ÊJ`êr|!FÆ®£ ލc×D.”Z#c*ç p}OŠÆZj­‰#L;H™¬‹z‚ï.'’Vt9↚…äPMEމ8›ÛÑÆà{!aPȘ©¤Æ .Ç-ò¬³Îâõ¯=oûÛùñÿqæçç¹ç=ïÉk^óš½.´ï~÷»œ}öÙlܸ‘‡>ô¡¼ûÝïÞëâ|ç;ßÉüü<7ÜpÃnÿîïþîޫŗvlù¡XxÞÝßÀ¯Üú>¾5¾z?î| ß¾ùQ|òÊ¿ãú­ÅÅg^¹€£õ™ÿØùÄ5žooM„ýÔ¿÷‘’?YSç1;vîØM÷k×…~O½¯}Ì&¸ÄQÊPެ6 £%¨Š(-¨†ŒE&ɼÕLºEz7!,-[Çxa±X kMï!D”T‹ä|ê=ýÒ„JjdÌ,Mƒ¨j‚1äÊBJ˜Y‰”1¯ü“ BÎL½§óžœ!ÇÒµe„DgÁÈTøàË„ý "hµ!h‰WL£/ÓèRàS¤OÅnÂŽéA ¼„¾÷˜f@ª-MÈÌS&ò[‘ ΧL«1U‘™QB+ä±!R9OšL>±NQ4Ʀm[TŸ“¤_—Œ®C†ÈH[jŸP}ÀO;ˆ‘Zt‚ùÁ€Fk*Y\AÛèè\Gòž…É";' 躖¶o±MQÅ€¬Ï‘˜B7ÄÁ‰P¨j@ìÜÌú ´##ƒÑBT]á:Gr‘h Q*º¶‡Jc5ú²Ë.ãÕ¯~5_øÂ¸è¢‹xÅ+^Áýîw?>ýéOsþùçsì±Çò¬g/õÛn»3Î8ƒóÎ;·¼å-\rÉ%œwÞy4MÃ9çœÃÎ;yÎsžÃ¥—^ÊÒÒÒ^íd2á—~é—¸à‚ öûB?Èû‰Wî¼”Ÿk¯ç¿Ï?„£ª#÷Qß–\¿ýÀ#éEŽf6 ¾wBöíï|yÑ&\6¬çxÏ;ÿqÒ‰wÿ/=?Ëuq»† ò3Ï.OþÙ'ñ3gÿôùßrÇ4³i!±iaÿe_Ž N;J1_ïÞŵë@Þ]AºßU± (+Ò1ÀÂŽ¸(‘9ÑÔ }’eˆI¥4B¤‘ ›šiÛ27Ѷ¥M9ÄH?m)KêfÔ0™(Ë&Té2“n€P$‡Hß{ì¬kny(q¹´VŠŽ”ö^ ½IȺ!ÏBôTÆ 3$Qˆ‰nÚa+KÈAñ1U±aFJl—ÐmÄ+W™ÁpŽétJÖªdGLÔuŠ¡H³HIê=J‘Je5Hóž„Â6 ¹ ¨©ÄäŠrHä<³"È`„¢ Ëu¢µf‚G k|ïPFc4hšÒúÜO¤DÖš‘i©d=Q„Ò¤ $ã¤ê"6JꙜ¾²úPäq€Q3``ãé¤xÄô‘niBXähĤR Åtq̨iµF†„ sæ!yZk.½ôÒ• ûÏxŸúÔ§øÐ‡>´.^x!÷¾÷½yÝë^À)§œÂUW]Åë_ÿzÎ9ç¶mÛÆqÇÇ¥—^Ê©§žº×…:9âˆ#~(œ¿—x_¿‰÷mÝÄ‹Fâ¬c~”¥ýp¯ËyþíÆÀúZp÷u’cçVü"ôàyoxÍï“SbË­·ñ^Ä‹ó·xÏ;ß¾æÂþýˆ?zË šš¿àù?;2[– ¨ììöŸ¿YÁiGJŽ›—«.à»ÉÚï1‰¿–äZÒùû«q¶¼ï2±ë{®µm*mZ@ŠÄ¾% T -Uñ+‰ !-K­'„Lç‹UN©,Z1QW^•I«t^l*¼óÔ¦ÿ:‹â§¢bfÖ¥¥išâùn Ói»rÌ¥KÌHà¶±e(ÐHÚ¥1ÚN¤Š-eɘ¤)-̦"Q8¤*ú[©ÇXànˆAœÃhƒ5eRÝÍ:Á6ŽF,d‡ÖŠ~6}¯di×] xOÕ4¥kLlSÍüS©Ÿb³@»Dª-Eä3Δ…cŒˆ”éd±OV>1”YU%ð“ 9@Ip¡§Ÿ¶) ˆ³l#õž‰ïz¤VE+ŒL=9&´,ÝgÞJ«8Að¡K[¹tZ(Z‘¡2tí†àHdBN˜º" @JR*ס<óÌ3W$ö¼ˆ:ê¨Ý~ÿ§ú'žúÔ§îöØÓžö4>ÿùϳ}ûvN9åÞô¦71­®“4™››»k¾åÓ~÷"øÅß—]pH‚Ì›ÇWðøûÏóàªýŠ]æ·F>~Màë›#·.%ÒAp´ZiFÃ!sssÜëÔSxåo¿œ[¶láêk®9\çÚ+ƒ,R-_ß\Îû7nû ,VÁŽVüÄ=õªÀ ´ÂZ˲oߊ¥±TÔ¶"‘ñqv‡;:=“𩛆.$B”¡ŽÐÖbf‹»È°£Ð©b:fBf„.6¼Zïˆ9 m°RAˆ…Ců}ÙàjùF(¥T”{s†¨´)†W>2J Ýd˜· v¶ð« Ñû2÷"Ê{IŠ>VÕFæ’b%iÜëb#É>Âb‹Û¶ˆ”jETs8β S¸ ïq]OS7H©˜¶Ó’•IMç#(C–¤DgÐ>!RÆZ‹É‚Ø9Rï mA2·~GáOâÂÙ:º¥ UÔ®ÌÔTUU 2¨PJ`}(C§ÒG”(©H"#µb( ƒª"[…«¾.jÍnÜ"gC9Dª$P!•áN“Që‡h­Ãp³Y#ðK“®Z£ýèG¯yA]vÙeœsÎrç›6mâ”SNÙm›ÓN; €Í›7³qãÆ;¿ûyó›ßÌßøF6nÜÈ#ùH^ûÚ×îõšûŸ¸ÚÞùjwA_ ÿžò“ð¨ß¿¸§]qò‘–«·~€kný1úPï×~›—›—@ŠÈñs’cæG %ú NGe+¤¼£å½çÏßzŸüôgpÞñßu&¿ö¼çÒÔõJyê¬Ç?–òS|÷Úë8ù¤yé‹_ÄýîsïÙ—=óŽwýþØ¿²sçNôÀÓyé‹_ȱdz²ÿSŸr.þèǸòÛßáu¿÷j>ÿÅËù—}¸dwïÿÏ>ï—yÖy{{¹üÛç¿Àß¿ç}ܶu+÷¿ï}øÍ_1'Þ½´{?ágžÌk÷U<øGÀ•ßú6/xÉKùÔG?”‰÷¿úë·ñ¯Ÿø$mÛòèGÉW¿~ozÃë8þnwÛ…÷‚m“Ä­K™Íà•‚SPÜ}½DÉ}®Ü»Y÷î¯sär–sg^÷ûzüζYýP!u ´„pÉ#‚dÝüº²è“‘9chSZŽsŒçÑJ‘…¤™ +^#D )AA•9e$‚>˜J´Ôt}‡0ŠàŠx%Ë_!VjŒ(àE­>~HJIC™í@–yK[í¤%…ˆQ5wX]!Æb,æd]ñY@Ì!iiVÊÕ9cFš‰/ÆhZas!Ñ­OÌE…ìãuEV­2†´s e ­ðè¦!ç„M¢€âìøå°bœ`4Òµ!Còe†È5°=„˳¹“HUW,U*­¯)a-9ȺìŸ%5’¹t± ¥ec"z¢x‘‰ÀáˆAÑÔ5C™HÞ}@jïzŒÒÔ¦&ˆ€Vš` NF:×"×—|ä#\y啜þù+wÛ¶mc~~~·íÖ¯_”’mÛ¶íó ñ²—½ŒÏ}îs\{íµ¼ë]ïbÓ¦M<æ1a<øjxëv8鸻Xîª/±¢¤àäcÎå§N4<ñ#ÌÕ;èÎzÓbâË›#»Úó•››v$&nÿVÄ;vò'z÷»Ï}9mVÎ|ß¼™Û¶nåþ%oë_rÛø‹·^´Û~ø£¼ð¹¿Ê{ÞùvN¿ÿýyáK^ÊÒìoùWý×|ös—ñºß5o¿ð/‘Rò‚_én24ü– xÂcÃ[/x |ÀxÑóŸË“Îþižö”s¹ì“_Xn»ývþàU¿Ã»Þv!7lày/úuºnÿÔþì¯.ä —™7¼æ÷WŽkÓM7~Ïe6íH|å¦ÀÇ®ö|ysdÓâËœ<ðÅOj8yã~ „D+½¦[äÁÆZ-Ȼꋭ•¡¬‰ƒ&ÓŽ¶íÉY€P4Í€Éd‚÷ž4ÓÖŠ1’b\Δ»|¶ñxL4’i e0ÑEŒÏE²ev\1”…\IIïŠ:²ZÖð¢ð@Ëï'fŸÇVYB*¥¥eÇÊétºbTæ½'8O ±Ø‡È n°Ö⃟é„)²ì\X@iÍ`8Dtž4èÊÍN›¸U:¦Ô B­Hx+éÀ‰2Å£^ kvèÀ¶*¡•BiE×½¿2쩈©x¤ô)°ú¢+b©Ã„L¿4a:ž”&%ÈV¡¥¤N‚:bˆÔU…œÙ·m‡Ñ…dÝÜî¸ã¸øâ‹9ñÄù×ýWÎ=÷ÜýÿÖ\ð^¸ìßËÏ_» žðcðäGÿ\ ý<ܾF8óGàégŠåRÚß}.ÿ,Nàè ðüŸƒË¾›oƒ‹>Xž?õøÍ§Ã¯ü>üêÿ€‡Ý·ì¿ugyìÝ¿ƒºd;?z?øöõ°s ?ÿزí»>_üfɬî{8ÿ8zã~.Wq÷#ÿ'w?¶ìøSnØz·O> EeË8³eWjýG ‚õ ž)7é+_á¿ýÄO®ìsÆÿo|ݰ¸¸ÄÅù¿ÿY¿~=¿òÌgðê?x-/yá VöyʹçpúîÀ‹žÿ<.ûüøø%Ÿâì'<Žxß?q៽…Sîq^õÛ/çgŸú \öù/ð¨3 ÀùÏz&gŸuàíÖç<鉜rÏ{ðŠ—ýožüóÿ“K>ýiÎ~Âã÷Ù,ðÿüþê‚7s¯SO¡ó™_|æó™;íÑ|{¼‘~ñà­© î¾^rôèÀovB¨]JÓ« A®–ÑÜ™AØj ³?-Î{ÊÅì RÉ(’0@&Í|PcVÈÿ"Ö!´²+ ¶¬z,„`:É4R—®§ÊÛÍMD3Ïš,Š f™’¿Cí¹› cjYsaÒA€Qšõ`°D)%T.­³Á÷ l…‚n6ô®/Ç40n'h§©mQ8^ð©Öø¬HR1é>$†BÇ-˜  iP… Wæˆd¬0ô®Ãh…1›ÍYžQÚ€ÑE-ÙEdL´­CW†nù³KY¼WR±w6Eò¦1–Ø;$’aÓ}``-)FR  $­. \Ïܰf§kiÇ=•ÐÔóCû–¬J ŒPèJ“¬Â‰L% j—c­ªŠ…Å%Ú®'¦â«£•Fô%³ÑË|Ër,..röÙgsæ™gòœçûì•Ç®»î:„üñü¥:âˆ#8í´ÓØ´iÓíø‚§Âòqÿê. ´a^ñ,8öؼþàmpÄ:xÒ™åù?y7ôþà¹X6o-â³®¸æàÊbŸ»^û|Ø0WT‡ÿðoKóÆ€û»ÂkÞüâÎ²Žšÿ5æ,¼ð¥¿Æ³Ÿõ"úúH¦þÀê3c—»Ìu;ï –çO}¿ðÜ»ñô'žÉÈÂo¿êÕXcX?k´¸ñ¦Mä ÏþÕçï¶vÝÚŠÎR ø€û³é¦MÜ´y3)%îµKSÇ`0àþ÷½×ßpã ¸TÕ÷Þ8`ŒáA§ŸÎõ7ܸ¯Êß½iûù_#ÌÂg® Œ]'Ýëôáó50‚»¯7/ÚƒÏ2–K‘ûZüw}~W•âýåjÖj1^ ¸V›"¶!ÄL£L”öÚ匥C9áÖV¸Xf1ÄlZÜ{ÖŠA,s=1ercÙ:èýÊ]qŒ±´Sf?ú §B’Ϭª*jU²˜Š:¯Ð c48óKB IDATÙ|ç°Z¯t•- ªÜé[!É.à€Þ•‰sïÒ(̬üR¤u=jnŽ±ë‘¶p9ƒ$É.")Sø]NÔ¶¢i–––H9S55S×— ‚”=Î;ˆ31ȘPVSUU9¾>0КÿÏÞ»‡[v—užŸßu­µ×>—º&EÈ…ÜI! ˜Áˆ„Q ¤al¡Díž‹-3*#ÎÈ3Ý-­´[mÑqð¢ âLP@BÈ…$TªÎÙ—µÖï:üö9uª¨ªT.\Îû<û9§ö^g­µ×Þõ{×û~¿ï÷}`ŽQÛb¤`zF¶b¶6¥Ö¶T ÊaF ë®Ç(Ã0›#bBfÁòʘéÝè²'Kɸ±(2Áõø”pRCDÔ 3ïHsOÖŠº© ƒ£m IAê=ËYÓ‹2ÀZ×5³ÙŒínÖ#¥%…Löž‘±Ì‡þpù—/xÁ hÛ–·¿ýí_õå|ö³ŸÍ;ßùN^ÿú×o>÷®w½‹+®¸â«Úe']×ñÅ/~‘óÎ;ïÁiK}ÇÅ[2á^xÖ“àºJr¹ë |ìÓpÕÿZ À){ø1Ÿ~yI,÷¬Ãßý#ü—«‹ç^ü,xï‡á–/Ãûî×!nøÄ[ØñÒÉ£Ï:™»g‰;'™ÛÖñ~,ˆS—©vìãìûø»Ò â™?ô¿pý 7ðÉ÷ó¨};©GËäœùÍ·½u3áœH_‹šÁùÃ|Ú7IZM˜hÖÏFD¡90ÏÌ\f¿8‰ùß÷~Î{¸äÛŸÁ-ë÷8W¹\Øz»Û§%ëçXyåèÕýc#Gc–ωòhB˜xÎVZˆçÖQIÒ»žLBê37 µB)ͨj8¸ÿ´ôƒC/@f|©\tDƒ÷ Ò$Uá$Šd‹Î…Ê«¬¡Ï¥Å&S&9_œaÞ÷ µ­  Ap`šŠ”b±&bÑÅÓõi ¥Œ—†¤$Ãà°µÅ/0‘)ý€ÈU[úè‘UWt"R«Í¹µ00x #KZº¡ÇyO[7äÞ3¸9Q j£‹1WŽ".'rUÀt“ÒhœÌô1#¢‡àJÒ ….-²¤]s°Ÿ¿¦˜R¹&ž„Ö 1™ÑXKe,ž\’Îà©ÚŠ9‘>‚ô!*‹1…ö¤àIÞ¡µaî:¬°È‰!’e¢ij¼+7³éŒåfTl² ²ýúcôáÉå5¯y ×_=üàI)1›¹…¦iRòêW¿š«®ºŠ×½îuüøÿ8ÿøÇyó›ßÌ»Þõ®ÃZw¸Ã00 ÃfV~Õ«^Å _øB.¸àöïßÏÞðÎ<óL®¸âŠg•ùøgá®;÷ƒV¥-µ‘@¾rO©NÞõà®l»¶$Õ;÷}ïŸ~ë·× N€}øp»[Éî.vKàGßøÛ|ÙÖ|ù–E‹K,±¼ã1­‚}ãB˜ØÝJì1!mÛÕmrcöåH|ä¾0ËND¸òDö§”"g…5™4̨¬"ÅÅÄzÎTºø›ÌÒ µÔ*…Uå}é9JÈ$Y2uðËD{Z€õRŠÅ´¾,ù2S`T5Ä”hG5“n^¼ä³f>›•–›­¨Œ&§ŒP i5YJ¬5(mŠà¢’¥Jõ ª®¨¬!…€È ùC7g,,C4íˆ~ÞCLt8¢ÈŒv/3ïç Æš&Ö‚‘•ÄB¸s£ÕY*7%Ú*k‰1b‘~©¤@)É~Úâs¤K m4*œkCþ)iwì`ÍõøÆ@ïJ‹Of´.ŸG=6B¤Ì Ž–—˜O:lĉöMi¹‰¢'‰H•Ôè”É9 ¤ åÈH(äPYP7Cr„I>ÐÏ:´6Ì\¿Ùrì£#‹DºCÉåºë®ãª«®àŒ3ïñ_{íµ\|ñÅœvÚi\sÍ5¼þõ¯ç’K.áüóÏçw÷wyúÓŸ¾É{ä#‰4nT$wÞy'mÛ²gÏ^ûÚ×róÍ7³wï^žùÌgò¶·½mSdîÅÚ´´Ÿ~úepéùe‘÷ßÀ‡ØÌÞeÀêÎýGO0ª˜ qK|øs“ÙÑn×ý¾«üÒka¹ýšr„€=cÉž1\„âÀA[†Î úyΫ~Y·|àó‡ð‘s÷$"p×aÛ†J&“IÑ9«Ú¦a6ôŒªâ #†Hcª…ŽBŠbèµ6ÌȵA‰IŠ*–êÄJ…O ½Pè¼£¾T*"2®F¨uèÚ …¤O™la¶6ÃJª Òš‚¥)Sì| «€i¤BæˆD€µô}OÛ¶8ïYOž¶ª%—‹/¾ø„¾p_|1W_}õQ_;å”SŽ»7½éM¼éMoúÚü톒•iÐ*c‰…`¦ÝÚ,˜Ïµµ›URXÜTO〲'FJk,¤€nêÒ¢Ü CÄH V[DÊ#'Ê“wÁKŸ ?ók°s¥°¹žðèÂäÚˆŸøWðŽ÷–¡ËI'-Øb'ï‚ç=­°ÐþûGà¼Óá ¯,xÉ[~^ûfX°ÿ¯îEHóÇ_ï|üû·Ùò.:«$¯SÔF°Ïö-:v½Ï¬õ™µ.s ÏÜÓåû5xùp )`g#ØQ D˜ñ†Ÿ{#¿õËoÄZõ 9¡$;VW|uÕr4ìêXÉFBÙ¨NŽü›{Ã]Ž…õlÕ6SJ1›ÎIHæóbïµÀX…4†Î;Bö 2SWš™wXm® \ ¡™»9£•eÜ‚ýS"„ˆU¦€ÿJ¡2QWˆ m5ÂOf…Z¢HЄâ<¼/×1—6œb![C ùÀŽåef]OŒ™¦-U_0µü0PÙŠ™ŽøœO—""ÃHôØ7V›É,“Y6š0ïÑTïJ2Ÿw;Ò©Ëö,&û X.¼£Vs 9AŒ¥!’Ã0P+[tØ ÏÙö¶Ë̉ }ÃÕ¥mS*)áúžj<*´pÊ€ª]iÉI’ZƒrÕ'¬Ï J%¨œ!a•f*=UeV)š$hmMŸ\Jø,9•ëàíx‰4™“´x'—= uù¹O-cÒ{jø×Ï+#ãÑgÀ¯ü»ÃŸÛ»~þGî—úý—ò«÷ÓTðòç”ǃ¿÷.X¿í%›ÚNÚ=L‡ÌdñXï3ëC¦ ¿DÒhX®˵`©*quhaýðG>‹_¿ã*yC*ê)§£&þhØËÑȉ$Œ{ÃeŽó%³2Iv0dV)w)!…DðÅ.×d0"!ã@g ^I²€Ø 5°2¬""<éSi‰ºÂSZOݤ0“üÈËÊ‹QÝ™{m1uÅZ7ÐT¥5ê}ÑÐÊFF–Ø;j/HóJŒ’ [¿›='ïà`ó¤~%›¹dÏn.9wKËËüÁ{¯ES¡¤ ósjkI.‘»RAÉœÆf=- ‘É(¨ ¾ë0UU¼a´ÆfèR)%IŽ¥Õw0öh­ˆƒ/¨J ëйø…”ñ“ɈœhdFùˆÎ4ÌSÍ)AJÌjÐýByYdúZ‚ÖÄ.û€ ‰ïAV@—‰}_f´+c|?Ðö¹—®iA&•;´T&þ­±ˆÆ2Q7Dë4£Êe;îSŒ‹ìVŠ0÷™Îeæ.3÷0óåç}¥@=cd#íâçÈ +9¢¹ù–[øä-·ré%cÿþ{xë¯ÿ/~Ñ ¿¡çŸÓ7•`åñ “ÉœuMejbø”˜ws”5ä¨ë†˜Ü¡Ù41zteËœF,­kmˆÌ¾V …N‡#g¤R ΡTñ1‹©ù _7 øÈA”¹™vTÌÆ”ÂçH”,˜D¬î†ÙŒi³¾ûRN9eŸÿâ]4ãNÛÛrÊj…if\ûéÏóÁ}Š>S0’f\0ŸQMì{ڤɱLÔçÈ#ËdÚQi¨Q2TÎEÖ%§Lß÷›çžsfä2¹/í±dzT£‡H Säu´RH¦ªpðy³°±Ÿ !ÏËOYÛÂÊË’ºnð&£…$ªÀD–eQn¢ÀfMï=A &®'‰„]´fcŒTUE™ í!ÅC¡|k;B&Aß­ckÛÉe;¶„Q°¢+õÑzò0ÄŒ E¼ñíïz?çsçý(|±ÙƧLˆм1•ö[Ê994 ÈE«JŠ¢T %hQF–aXU~¯X-°*%î{k2òöwüoøù7²wÏž÷}ßÇ÷?çÊoèu×ZmV-[ÛZGIn­Z6–­ÕÅýÑ&ÛÚN;²‚9ê\LÎTuMUE2…6B:Ìì+fÏl6c¼4a†œ/ž÷VЇˆÔ’”‹˜R mJëÅ ®Øþú€c@*¹¹ û-FaBˆ‚­hM–‚Þ•Éöª-6È2'Њ¬tœÆ&¡ãœ½¯yþ÷°sIáÃŒ³öœ‰¬F6N¹ùöŽ÷þÅçør¿ÊàÆãr+nUÃÜä˜ÈÎútÊ(-b(4`Ã0 ª )J++„€r³*Ü j$!‘¦àCÙHœó˜Ìf2EI4¢r@KI;1ŸÏ6µÕRÎH¥L¼E·"Kz!pŠìq>‚g¦ª¸”ÆØªÐ«sFW!¥PÒ4Ô¡ÕZ[²óX©Ai’ È,QZ±dG¬Mg£90_ÿæO.­2;ÙýXÒG¶bZ`öMy®B@­µ.w-?õCÏ|H^ó‹.¸€ÿzÕ[¿©Î)çLS7÷«rÙêÿrÿþDÏ1/*‰J ÆÍçôÙ£U³yü¾ï1ÓT–ét‚e[á%Rzç©«Š#~ááî½GHwE*?§DŽ Ÿ%ňȚJ7ÔH„ FÐêÿSÙa" Dq#b ƒÈ–ßþ³¿â®¯!'*%±(4—ÁÔhE2) ¸àiÚŸËߦé 5¨«šaQµx_®¿¤H ž¥¡ =9:ÒiVÆT:Ó2úæO.ß¶ãd>x÷­ËäòøÕÃ%s$ßFâƒÛ%Ô·`¤œî“„ËV ýÈØ ÜŸhår´}lM*›ÛÁÏi›Uœ *Jr*C†!bJ$Ñ(‚K€b‰„5„àI!¡wòƆaÀj… +‹Ã!³ V ï‹kd ‘ÕhÄÔ ¸è©]B¨Bóü@‹ÖظnŠûeŸÑVäœǨÊóª+/åK™˜#…L«ŠžœNHöO3óX‘ôã*BC\G„„‘ŠSá‹ú¯R„¡´õà°+5zîh8‘‘ÆS!*øë9¢ÁºŒ›9tmɺûLïç̳§^]b ¢¬@¥R±OBG¶ ²EgÁ0¸2ý(!+I™H*î•J£SÊô*à£ÇW š:’È,!¡³'ÉLŒEYjU9¥aý`ÏÎÕ=L¦sði$Y dc9ØÏÑ•Eô+R:Ê\Û7½Íñëϼìa» üäY?¼=Âë·WÙoÉ›¢^¥ùÀð›#]17ÚP1F†¾cmí`q• G"ZEª]ˆÆâ V9¬)8…€fÔ …¤®ëÃ&ÿµÑDï †²¨d„ ¥"IÁº¾ÇO‘ª©RÅß]¦ŒL™à=JHÆU<"¡yü9§qÎ#v#RX´jsQa IF Jëè ¯ÉÉãã ¥µ)ï)ÄÒâÓeø3ú"M?ô=CŠÌUbR æRU¦íecIZH M·6E«K¸€Î(Ž–´UCX›¢§ŽÁ̺9™Ò¶ ƒC†Dà$ô*SY[¦õ7…¿V½r½ Ùyê CÈ™D¦®k¼sˆXŒÙÈsfmºN7ô $sçèúbù,•bÞuŧ§ªH)c•FÄÈ|6ÁRþæO.Ï9ù,~úÜËvËÉÎ{"Ï>éÌÞS<ÍOo¯µßb!¥dÔŒî5Y‹åuäk[éÆÇ›È?®úñ1_ÏìÙµ %ŠáVck¼Ìx#èdB.•b–<ÁHæ9+MçÄGˆÎá¶èÔyï‹ —6è……qE1¹mÛ²0S’Í¢-&€¶m‹ç½’E×Ìó«˜â¡¤%Ú;ÚfÌHIžrá(1ï¶Ò¬Ë@eD ÁŠ¡mBÈ¢D`mñMÙ¸®-#!Š e#5Â'fÉ1Ô §À´ }¸*Ñ `2Áϧ¨0) ‚G¸ßÏéc F¦¢Š­4r¡œR¢µ5&•ç³.l¸aÖ¡³@ÄŒ›u„…ÎÛ0 EЈÎÓ¦’`úa *XwQeã°Ðt˹$¤$+Éxu…YßcF5vT3 JÂÁBˆå\]@Ň@rxãùßÁ»/.OÛ}êQpЇÆrÅîÓø³ËŸÇÏž÷¤£ncx#–w#y°´½ò~ DΉélº)ýò`T[÷–¬Ž·ÍW×X¢°ƒ„D!™ÏfÔ¦¢REÍ"9L…‘äG¥ *ƒÐŠz´Ð B"8D(òPr&…"-¢dÆ'Ó ]7Ç9ON£Í¡Å2F¦Ý¼8HJ‰Õ¶8+*½©ú‘r„ZÐ)“‘S÷ÕŠ%ÀV´,É~ô‡Ÿn†ïÀÅàBÑ+ÊfJçÜBO¯$OBz}`G4ØiK˜÷ˆnÀ„Ä:´wÔÞS+A[iŒHX‘iŒD‹L–Œà@vìמ˜ÚB,XM·HÜRJiP}@eý€Ê0²vÁªÛÀwºä‘㦼g£‰#SèÒV3uIK¤Õ›ƒ²óù¼¼§œp‹áXa Rk„”([ÜCÝBˆÔ˜ÒîtÀ(¬Ÿ‡[ìÊ“ÎäÊ#îô®¡¸Å•h"‚žž¬sÓö*üpý¼7&­O ±œˆÄþÖ$sÌ$±e?['óïí8 p!b„"XÃ|>£&“b@‘©ªŠÁ9*¡òF€R¤ÑY€1d)‰9—9й—LI¡)Ç‹U†,JÇB”$”_Ô‘•Fec2E°’ Kâ)ŠÊŒ¦rŠÜsà K»[´ª6õ³RŠäEàXSBˆFCÒ?‚ ØÚ’•“BÑÖ†>ºRÁiÅ$qÍFj’ÏLãI‡¬-ʧ¢“–‹š·¡0äB Ç£5ÚÖTíˆýnN½¼Ê|mZ*¢‹Dç .!Û†„n@ÇL•ŠIZ ã[0ú*rm°9» Á9G×{l]ƒ‘ØPÆ.˜x?8¬-¤ï=‘Äi£ñ.µ\mE„1€"ú&C6tƒAk‹È¥ S²$v­ËÏœJin¼ånÚñ ˜€ð#[¤2¸˜A ´²¸˜ÉF‚#õÐJ¬¦›w$­˜Þ} (;W’•$¨°Pi‚ÅÍHL3bzp !4~dÙrB ‘ñ H"0j[¢.l¹Îy”P¬Ú)w…ÅüШ"Ä@`Þ÷ôK†±Ó´Y“e&ô²©IJ r¦J0‰žñŽ1q}†‚ÁyŒZÈÚ¤L’ÙÐS5¥ÂãsÙ(ÆuƒŸÌ‘B2 =ÚXT„/»uvVívrÙŽíø†‡€ÙtvBí©­ó(FÜ›å‘ò/BHF£uèe©´!>F„[dÞ¥´ØÆRÆh®´¢Œ„Þ‡Íczï5#R*€´6c4Ò{bLÄœÉdB(xˆ.FTęɃ#I…7KÈѾà.IÚ`„Âʄி…GŸuF$È-kt6ä\°c øâ­Xï¡Ç£@E–U—vÛ´ëP¶.†dn U™$R–¡Ï¦iXëf´Ê°¼´Â="`R"eJà$8 *Ôb<¥ªk‰è3ËYPÍ> ²Èøn 91/ѯO™Ìg¨Ê$…@èR)¼4UE²[â@Û¶2} h-è,„¨è†žQ!GT–#£ªbð ™2¤â¢9‰$°ÈÉÀ†($B¢AÝ4ˆÑ²~h`.Û±ç[˜XGRŒ¬Z¶øG>îKE³ï þßÛ>sNxçˆ1 D± PÖ€XcÉ1ÒX‹‘Šä=Ä„¤´dÚæ|¨Ü8c̦‰ZI ! R™ÆÍn!AÎ9rθ…k¥P–±“¨¬EK¢–i¥é»"cßX…TŠ¿ºöF>óù; ¨ân™R®Å–SæsŸÿ N²•TK;¨Mü¡óžhƒ-Fkz•aѺS‹iùz…âz)å"ñ*lWl’'Ü©…Nz³EBµ2†Õñ*A[7¬_ï©üBަ­ÙŠvÍ»’¡yÚÓ(³\¶c;¾Ñ¡”¢®ê£*›ôÐ#eöïÜËñª™©\„(cP²AHÝ )ˆEREœÒ+@ ´RÅd}Žóž‰ˆ8#˜Ç€E|²¶•ÔÔÆ"3¸®G‹¢,ŒA7m-YeªÚ £¦I’ÚO‰N³o—å‰;%•Ð –‰ ÂJ†b˜£Ó*ÇxÈLó©¼åÂú0C GN™ÁEl.ÊÁŸºþfn5IMÐ.‘¥£µ9?KX½ŠN5­” bÕÐÍ}ß1‘žaÅB£YΙLBÔËè¹ÄZÍj¨y15 9¡lR-5"GšFaM"Ï'´ÞQ‰Žì"£z;r쉃ÅÆxMKE5´QcmƒB±´Y5cŒ²Œ£ ×s»BOÅHÅ^»L$KβÃZQ¤d"3ëÙ+‰2 •3I ²–Ì\Gï{:×ãb(íÄœQRáø±ÝN.ß (Çÿ IDATŠñöwü?öÿö¨¯ýÐ+~„?úÓwŸð¾~ðe¯àWo« <ˆ í©ûŠ•Ï@ìÁL<[[F1Fªº¨üzW?cN Î-ZÐjK%Ægê$1®ÜMûa@ÄâJ©ÆÖhQì„ÃPþÞC]×E7Múà‹\ 4d­èPt¢f׊á¤=;Xi+ž{ÅeÔBãCƒ‰’ªëÐG†Ä"S™ðrÊ]wi~ímçÖ»aˆ=Ê÷„¸õ®)üøõHBŽˆ®a”–ñY,1ÅúÛ9ÉÞÙmÏcödž|î*O<³åI§,sŽåi‡î±—¤)˜Yb—ƒ¥õn³ýiŒ)´`U’ÄV5Zƒ"ág= «4ó±EDGe3>;Ìx2¶®Q¶ÂàØÕdr¥ Jà%L|ÏÐhæ•àºF“êšÐ{dp%˜ºˆ•!%!xv6’;Ö}Ç@BXƒ‹Id\`»F9ÜÃÊÈ •„¦¢¯3? |BvŽ‘©ñƒÛô·c;ŽŒ_½ê×yõ¿þŸ¾nÇ+VÁá«*–ÅS¶ÎhlMÇkËv¼¿)ç黾Ȅ¨Åù*‰P#$2f¼„ýUÂ6–õ¡G·Š:ÔÔUE7›#SBˆŒß9j­YZZfæ‡Í*Mk]¢”@ÊL–ž¦ þ‡ Nãqœ‰Š.?/ÿtÃm\G Ç Ièà  jS(»12 #nú²æÿúõ?㉗ìcøÂÍ·òÅž5±LN‘>!c»ýØ&²sϘ']r!œ¾—­¦Vn!ZZ{:ÏЦåîiæ#ÿt#ýüüÃMû1z…y×ÓªTäøíF¥F$ÚJ²£N\vþé\tö©œ¹s •3ˆÜzn¿ù qÍG¹»ÕœÌ¤ë‘Æ2ÄÀαâùO{,fºÆxõQEëL+f}Çxy‰ÙlFJ‰ë¿ùèç1®gyç>n½Ë†ž^Õd‘Ø·dxÞ÷?†‘,Ÿ§©-³~ޔžšP„r/Y‚ßßǘô¯]ö¤,Ð(¬6ÌçÝ6y;¶ãhñÛÿí÷¾n f£-cBÊt˜sä½-ú[/ìjå¨I¸{ÿÝX»L¥ ôýB¾GdÌ’Ø ¬6–~:§BubÝt†• -%9ŒTͨ,\¹TE‰,„€¨ Î9Fm‹›÷ä”Q*æ<ç{.æÜ³w²ªZlœ!¢ÇdÇ•O<_}ç5ÌØÃÔ;*#iÚ1n6Ç$rñ+„zÊ æ8Zþìãí ]¢ZÞKRc¬›aÆK„áNVk<÷Oâ¼óÏB&UƒØ ]ÀT„ìÔŠ§^z6O¼ì\>ü7ò§ï¿Ž 4–…gå¦ЮÚsÁY«<ï™—ÓŠ•ÎhêmŒ,[ɹçîã‰>?ºæ£\ý‰Û¨äŸaÎ/8ʯ!L15‹"£²À¨"™c$dÅ•ßq>Ÿºî³üñÕŸdÕŒËЩ‘³cE \öèGP«ÂÐËãâÊ,€Tdr´l¸½ÏüÊm7²sßEL{ÁRÕ t]OT‘*J²TÛÉe;ŽÞ{~õm¿ÁÕ×üÎ;žö”'óc¯~M}t¯ú—ÿÈ«xÖ3ŸÎû¯þ 7~á&Î8ý4~êÇ_Ç矷`ŽÙr‚vÜ"¥Ø”Ñ¿×EþüåD&î×î:‘×KO]2nFeÈNe°š˜#I%æ½C˜ ‘ 4#ݽ'87¢hƒY]€eýtNHe . ”VE3rŠø¡ãCס„ÀÇŒ› ÎÜ»Âw<öTdˆT²$f¡Nß×òÊ~;ïx÷ßsÓW:ê•Ýô“€Ì?DŒQ˜0 ÆË`lÅŒ—Öi—v1ïäHQÃ$ <îÌ%^ü¬++GÍ¡ËuöQ}½ð‰(ø’†32gl†:{®|ì,‡Ìÿ÷—Ÿ¦7{¨jAµæñZ㺠O¿äd¾ï»ž@MÑ7ó9SÌÄžZXÞ÷Ñ[˜‰VDDö¥‚5>WPwàŠ@LE¢!ÈÊcdâòKÏá¬sÏåW~çÝÜqç@›S!ìÈDkqI ªbY,$D-p¡¨a1Ì >VwŒ™'+DN½L™°Y ÉÛÉå[¶Ï#Ý}§­ýÿ­ñKÿá?1›Ïù­_ÿ5çø¹_øEÞú¶ßà'^ûšcîû=ïý þíë_ÇÉ'ŸÄïüÞïóÚŸø)þè~¥ñx;Á£ú¨ëú¸ ý±*“ ûãqÙe÷»RYhnm=à=JU¸Ð#%Œ³†¨ñ!`c¢¿\#¥ …£x«k­˜ÎgÅð‹ŒY˜nÙª*R*F2t=mÓb*´g*vÈÉ;ÿ¸Ç"Â:*-!U¬Œ”v—pú¾ü»Wü\û雹çàŒ;ïº}§<‚¥•e¤V|æc×ó±/dV&d¡§®[¢’ô~Ž–!8^ðÝßÅ^RMD‘cI°È€PI@¢˜5ŠÍyœ¤Ìã/;‡Üð%®½mŽêa9W8‘8å¤1ßûÔÇшŽZReîÞ'·Ý3c\Wœ}Ê.‚aS¦ÁóŒ'?†¿üÐ?¢eKÛVh¯ˆdlX1‡Ž;n™qÇ=3rxÔi'³wç2";$ ™2#™ùáù ~ñ­ï™¨êšƒþ }pT"]™7ºóÎ;éf´®Ð²"FZ3ëFˆÚ"]BúF(dVLd@‰íÊå[6>yíµ<í™ß{ÜmÖ×'¼çÏÿœ÷¼ëY]]à•/?û¾é¸Éå_<ïûyÌEðºój>ôwáýùAž÷}ÏyÈ]§¯G‚ÉÀÁÃAŽ”d9žxdÔƒŒ|ø“Ÿá¯?=EŠóqö)«üà ¾—“wV˜X©$¶2<í;ÍÕßÏ5K•¥®+„ëB`­åoÿþSüíg¢•%FIŠà„ÂgH£dTŠäÀûÂKÀ(i²ÑÛÉå[5žpÙe¼åÿù¥¯zþ‡^ñ#›¿ßrÛ­ä ¯øÑ³ù\þ(ϱïʽèBn½í¡ëÉc«¯­XjNcÍa ãÞ0”#‘µö^'üï‹l+à_žÀ‡€s‘¥c&ëkÈ•U heÑ)b«ªHµhEèzêªÚÄST¥Z*ÕØªb–9DŒÒȘ°J‘¡a!˯³ásÿ| gí;™4Jz?ZëEÂS‘AKr4b•œ!‘‘$”sÖiä _ÜQ\qQU)[“Cb2ϼïßæ1§í¢m"ýlå¥%Ö'öœtíòJQpÎ%"Jêî™Ô %2*:.9÷4®¾æãôZ#­ÄŒà’ó÷¡³AèYxn»cüí{6Ú1v…¿øägøögÌ8u÷+%)+sÎi|èï¾€Èc´Ðå»ã&e²d»Œ7 çšqÍgïžñŸ~ûÏøùŸ| F9È©2ßyñ¼ÿ¯¿f«¶Á,° #1Dê¥ô+{ÉI2 ‘a°Ȉ"ƒ+d+ Jâ%h)Ùå$3µ]¹lÇqbܶäœùÍ·½•Õ••Ôö©ªú!y ^ùò—òÊ—½ôkzŒ”"“ɤ”0Çi¹Øß—q4&Ú‘¯Ÿh™e´Fhè½§©jâ<`bB lS1ÏÞ{œ÷ŒF#rˆÅë>g¢T¶BfA?  ^ \ôà#5rAn„IR Œ.IƒŠ|쟹èì1gî[:@"¤¡Ð¶Y”Š(%I%ŒèHH2Š3:dðkW nŽ`BgQü\rÀdÒ5ÿý#_à¯ÿþóô}de4*jÁZá»mìÙµ£â²KÎå;žt)+­Eä²$¡È©G3†s+û¿rC<‰ÎyF™ºªm)QchrG¯WñL ó$ÑÍ 3²Ý‡ï_‰3þæ3÷ð§ó_ùÉW¼ˆóNÛƒÌ=^\ˆX‘‰Bñ¡ko¢Ó 5œsòn²D= ¤$ÆÌ9œÁ¿Ú1¦ 3ºa §N~Ä#J’„$¡QHôŠa6q4qJM ‹DÐ *)|¤#) lŠ´œÝÃG®¿…K.ÚIZŒò$UsÞé+|næ£e¼shyèóÿžïúv.üÊk51e´’¤hxë{>ÌÝv…±­ðÎ1×3#cQ&3xWa·—Ðí8VcøÁx!¿rÕÛ8iï^.¹ø±\ÿùÉ)qá`ee…/Ý~Ça Ôo¼ý·xä)§ð˜ /àÿøO˜Íç<í)OÙN,Ǫì”b6Ÿ ä6GÎÄÜLec» ŒàD·oêúKËI¦M¯¾ï‘RâÕu]oz»Ç…Kbe‹Ï{Xà/~p4UEN ©$1D©H¿(U¤`‚/ž/i AJ å.þÛ{¯ç37Ýų¿û)¬Víg4Qjc*!ÑIž(ÿ|ý§ù­÷|ǑՑ å@Ö F ââ=ÀYiq®G")aµÅ;‡i+‚†ƒÌ1B1@ÝžÏoþÉ_ò3?öÆ)b½D&Ï'¯»™?øãOr@Õôu¢+tý|Ó\«©5Â9šœ8su‰SWVÑÉc&çˆRšNÖE‡ !£Ù­4· Y‰¢F G !MÓâ¤.|€‘ºæÀcPY"”"úDÓŒpn ¹|´:ô9ï޹ʮ«…ݧd±=Àrj›é& YHtŽø¾'˜ ¡à1 Fv;¹lÇñã‡_úCTuÅ›ÿã/óå¯|™];wñÒ|ÑfryÁóŸËñÿæ 7ÝÄÏþLqÑü¶Ç?žÿükWq÷þý<æÂ yë/ÿŒyè|Õ^ù²¯_b‚cm AÙ¢:²B9²:9Ú¶÷µuv"XÌæ6ç0>‘ç!‹¡Ô†5@¡hZ-\74Òt. ·s]b h)‘Qã½+ì°¥-9'ºÞSÕÕ&.‡ˆÒŠy˜`„Å™U>zý~>ú©ßå;/;Ës§ž¬1bºh7&²ÌôÀíw Þõ|ú³ÖFûTöP)’$@ëšÙtZ,{Z]…Р>°¶¶F[7¬<ˆYm ˜5ËzñjÌ«ÿ·ÿÈcOÛͨjùÒ—neÒY:s&¾V$±Ÿ¾ï ómájɆpf0DbÌH²8O )Ù™÷½¢w ¥ÚŽñY#L Úã³ ÊrFHÁÚúZ¬µ‚”$J+rV[ p¦V7 %ù#ÜB= ÊÍ3FI‚wd!ñÖB̈>0Ą֛JQZŒÆ`›†YØžÐÿ–Œ—½äżì%/>êk¿ý_ÞvIJà%/ú^ò¢8êöO}Ê“yêSž|ØsO¼üÛxÓÏýÙëóÊ—¿ôë{À|È·åXþ*Ý[iÁ÷VÝ|m†*3.xL?¢†veÌd6ÙÜô>l²·´.ּтzi„Њnæy1Ùn,Â@/2‚"¢„Ücìûž¦i°I“§©;t]Ñ»ÀÔYŒÜÍ>õÞ÷‰›X–:e7uÝRdm}ÂÖ™:Í,ŽãÐ E„µ¤ðJ c@-3¥´¶b6ôØv„–ª5ƄՆJSØa)SYˆÌ©kÁ\¬`VÎâÚÛ€rTê4rXw¡¼bÕ,ád¹‘X^^"ň² ´AHÃǯ»‘OÝðE0ÅA2ÆT®·wLE˜%¢_§Ò’ÏÞ“˜Û%ÔÈ#ULŠY$t]*“”è\ϸ#Ñ]öUEK$’\ÄûrºyW/qÃ0ð×}šÛîÈ)3MFLµæÖuAH𴣆48btä”ð>¢æ¹Ð¤·—ÚíØŽolH)6ã‰û#“ÅåøÞfa6’ÔýÁ}ŽÖ;òõ”Î{:­˜YÞ1t3< Æ_ZëÒæ²ç=‰D½ð_I½+÷)ô‚nl4C? „d”9Fz]ØVþÿgï݃l˯ú¾Ïï½÷>§ûÞ;£™ÑhA6$–l!ž*Æv †Py‚ v‚±]¸Ê”©Ä¦‚ ¡H„C ÁÄ€‘ÍKÖƒA’õII#ƒ„FÒ<43÷v÷9gïßsåßéž;£{gFƒ`¨L¯ªþ£{Ÿ³_çôoíµÖ÷+? ª€Vˆ7˜R)s&:… µ4’xD4—¹ÀÑÝŠw´RÇ5EÖh«Ðua Sw´7œ¤„Õ‡´9±ZÄ%cÅ1… [ƒ™#®î(Õ`íÄt°f‰;¼¼œàVœ,7]àJ:"ÔMÕ#v½bWªª c³ܲ p\þèH}&¹:< rd×à͈•C$x–ù&;si›ØèÀ¬ ¶¶ ƒ›°ËŽmT3”š¡iŒi´V0ua)3ÚJœÑjæÖ[?… ÆÌHðŠ{Ê %YnºéšhDJW¬±Üy÷ŽW½ó˜Z*n Üwrk€Ôç=+˨•ê ~56 –óþyœÇŸŽ˜¦édöñ:JþŠ,œµŒë‰™Q *n/[_Å «"çÂ…õÀÑö¨'é‰).Kïí+ÍáÁ6ÇǤ±Ö[¥´Šžà4)&¬µ a`ÞízÂÓ ”>›Y4YP@,%‚B º{w×FçÈ%c¬%ÆDm†€aðŽZ"NAœ7x7Ñr#Æjá@®ð•/ülÖ«‰;ïÛò?øNÌ„&r©HUÄã™iУ(1áœgÉ O¹.ÞPjO´¸Ôó ²¯\œ2¤+'„JYv5¡µ>ëçÊv& Æ"Jõ×- KM˜Ö=Jšó<ïÛköN”§3Óaøà™ç#Š”ƒóXc°ÎkA¹ý1œ!îfBÛñ…îélSáïû U¹ %W&kPyË·}ÓWðœ§`Ô õÚ~÷Ãíoû}^÷Ö÷pE&T†iÕ]4›R  M„\+i·Ã”vÆQJ¡üŠØ2¹ïˆ+»ÄÁ¨º±4nºø+_ó"~êUoÃÕÀ .ÔÈÌÌyÑsŸÉ­—žÍOþÒk1fEj%F´Ñ(jÿ—eak+™2X¾ú¥/æÓn9À´™ÜMïýƒ{{ˆj¥#jïå‚êž/ëÕÎ-¨à™QتÐÒ%g¼Õ()”’0aeÐÞÒZ¦ 4£Î“Ëy|bã'þ·=¿ g˜ÑyĪäzɵàÄ´Ÿ·ºÖñrɤԨ¶`t7Ñ*%a¼ºç‡Vš,r¦ö|Êú>3!ËÝ ,· FÆ‘9GŠï.ŽLènˆÒÅ&sÎøàº™1gl©‚HëòüÖRÞ?ÁÛ3GÈTa© ¬÷ÜzQñ·¾áËù3+È4~îµ_ÓïcÃŒo5-Ž|øÎûøsO;@tÖÈ-kÇ×ñ§òò~¯ùßçW^ó.¶ ‚Љ:GÂ4rpxÈv·ctúìÚÁWaV†6òoßòþÊŸMn+†ÏûäÛøäÿâ~÷}÷pù£¬e|ÊžÿOgÒ‰¦ ¯zÃÛ¸|¥ÏWZS8ç‘´;ûü×ë5ŸrÛ -.Üra๟ó>óSžÂް!ÐÄb•â—õÍÄæhÚ²[¶(½Gª®Ô-MH©Ñ.’1°+8Ó(yFvµ¢±|ºKI‰†!ž'—ó8':¬u=Á——ö'S¥ ´yH»Nï:Çqd‘®2áÖ7pO 7òÊW½™ÿú?ù ¬t——iXh}ø} *ßòÒç¢/G^ÿîs¢m2xX ˆSà'Jêž4§s§œ3÷Õ‘þÊÏW|á§ñ’ç*«±_kiÝ"ÙØ>ŸúÀ]÷óæwÝÉ[ßõAîšu¸‘3 ©m;qÔ[Û]BsÁEÊÖü{ï~oxû»xçû.£>Ýp#JŸP«ÆëÊzZ3bqJÈεppëÍð¡íC‚ÔJEãÆ€µŽjA;×Û¡KÂÇ8Žìæù<¹œÇy<Ñ¡”¾®ÍñãÑ{¤ÊåTBÿáÉåá*ËWÿ¡m2Ý!E±Ä¥ÒKEŒæxî}-á~ª¨¼^¯Ç‘yžI)U6FkÚU×g”¦Ô†ªR"R*M®+”œ1Jc´Á­&¬Ö´–PÒxöÓX–.ƒ±‘©iá`‚Oÿ”‹|É žÏgÜz# Êzòмw]¦dªT* 3¬È¥#¿ZÖüÁ½™·¿ïN^øi·€TP ˆñ4)¨Úø¦¯{1Ù½‰ß|ï}øâ;{?gj° VãsO–qÛ4Žû‹ãgë÷yÕí¿Í¥©°>4Œ+È©’’åÃw±`§§€?DÅ…¤TÙî ï¼’“úÐU®VÕ^–ï1 D} rðT–x…à?Š™o$:(ÞûáþËïýjš1Á“[ÅNIú¦³s­µbœ¥!¨àÉ-¢½Ò¨¥§´3´Úpã9Cÿ<Îã c Ö¹?$¦>FÊÿq”>Œã„÷7[Š4ªR,©0Œ¥TjÊ8ïÙÃP –»WR”Z»þ—V Â0 ¶Û`Œ&˜@¨P¬¦ªÆkÞ'ƒÖåóµ&å ÞaóÌÍCå¯ÿµ—óû÷ÜÏ•Òöˆ§\ZóŒÛnå¢6›ÉD5¢÷Ji´‚e;?è¿bÖ:¶iÁ‘ 5b Ä:qû[ßÃ>ë&´¦·ÿ¤±(KÖ#ˆcÅe¾æ/~!ï{ÿ¯ptß°Åe5Û+ÇŒM±´Â4Ž”Ú«5Ý"ÅNÄ鮤‰±ÔDÍ´ c¸Ä‰+­em ‹ì(“æÞ40·0r M„xª‚‰Æe IDAT°o?&)ÃÀ<#.³4Ï¡¹‰qsŒÒÛnò%¸qÓm¤˜µÅÔÆn™™™±J£N4šš]œñZwR1øa i˜SâÀ T97 ;óxÂc·Ýrß}åYÏzæu½X®N§dËk½î‘ˆ–—\yZñ´ÖàdУX(‹Æ)©á”ÂiC4©”±_aÎù –ku×ýÒ€*™\ 6´tô×Òê™`¥’‚ª‡Âu1Þ£ä Åû?tÎj>÷i#­¬½¸—¢I½ÚQ†Ú$S˜1*@ Xã8:~€º¹—A œØÀ q(ÔÜÈÚK±k>rt…¢ ¡‘µ ZÃÈŽK¾ñå_ðI¼òWߎžneU*±dªÖÕÐa$9K4pR7™‘Õ’1ñ~N$ÓWˆ+”Ò!ÊÕ.ø˜*ÂÎZŠø‰æ ¾.ÈüQAXM,¥°#áR…¸`e;ïðºë’E3³m3Êi¤vH·kÂ.ÎT¥°ÞÑræä{±£Çžõqæ¸%L,¨Õ„ß]HÓ,³ò”Ú¥k¬µl6´³çýó8'¼-f4%—?REq ñ½:éüqÈ¿(`šRŠÝQ²Mƒr¶stë(©i°(ÌR˜šÆÌ™©iÈ÷cì.”WÍ?rÎ]iàªY÷<:8Ĩý&nðÀåî{`‹`ÎdrNù0W·•R}ÎSgš>aW®ðÿðNRµ4-ˆjl63%ç~}û¹MÍ’l‰*RÔ2Ÿ%ò³{ ¥òüç~&+yÙqtttÖ ôÖ1$AÌèMd]5Û¸ÐFO´°aWó^ú¥ÏJNNNH9±Í‘, ÛÀaXâ²,4i,óB+•íñ y‰X4~À[Š¥¶)ÒJ%ˆÆ5%gß—Ýn(|v2³ÛmQ«@± ³ë6â4\˜(Ò½ž\U §À®$P #`J;«ŽÏ“ËyœÇRi?Ô¿º}u­ äj¤ØÃ‘]×·||ݯkKú pÿýÅZMÎÄ€±å UwËß3’ º -4 g,Þ:Z©xëÎzùý8"ØNù0n¯KvªOVjeΉŒPµ"·JÞlh¹²Z]âλŽh<¨¿ÖZëfeÎp²ÛRU·AöÆâ´fÙîÐM`t$ %¢ª~PŒ³§’s&ï+†a`G Ï¥”ÑT%L+R+ˆQ¨œqÊ`ÝÈÑ.!Ê<¤m(ò [çYåÒ­j ðs?ÿ:r} a}#â4a(¥_«³–õzM¡fÅûÿð2¯óï±4{¦Ö¬µÆ9‡U 5¡ÊÂmO9`5ôÊiYºupʉE**xŽápÊ—*kÕµºH¥Wrû§!xOs†¢á†Õ!䩳\.¹FT£{½ X¹ÀhA‡y¯Ý¶ÖŽ€¦JOÞÃ0 µ!ÆH †…#–É8ß+DS»|O©¥'•Áã½Ç4È1!ưHÅÙ^ñ'—ó8'ºriò¨ƒöë%™?®äs]Â¥((½Ò­ "…JÃ;‡) )ë,£rLX‚¶ì–¹ O"˜½Ÿý)ÄùÔ¢¹–òi]e^(K·?n13bis‰Â)ƒñ#†3ÿúWÞ›ßq'­y¤Ø>Ѫ,¹)¢(œ$Èž_ú•·óÆ;îç –¸$|º]¨µPZ#˜kç}hmqeÍ¿þÕ÷ðüWøÍwÝKm É3-ÏTÔµ`´å®»/S›¦äÌd=n©LU³´Ä.î0F1o7¸ÞôV"¥b•f'•mN(kñ¡ódÔœI›™ãy¦•‚jj ÚÔ$,¹°:p²Ì4¤Wh¥!ìè0Ã@Úì°«‘X2àiFŸ'—'s¼ý¿‹sާÜx#·¿á¼ì/¼ôOôøÿìŸÿ/LãÀû7ÿÆ“ús0Ö2S÷^¿N’x<‰ãñpd®nÇ\[^F@k¤4†¦Q­b›¦äk`»Ûa‚g»Ìˆ9Óœ;ÞcúâYi·`¤ÝÜ ’M0ZíjÁ/]äøèˆ9gB°äZ0yÁX‹(PÖ ÷°ç÷Ÿ üá;·üÆ»ÿ ñè.>ý™ŸÄÁá%RklãÂGî¹›+ùf´½k4¹FŒzÐò@í[“ƒqè'\a5Œ ®?íÇ,(çÙUÍkß·ã£ý5^þùÏæäûøÅÛïà#—w´p† ˆ@,‰`,­ Úuxð©¸ä©bj=¡¤ÜÛa¤J« ãóf†Ã>Dz¶+ ”&Ä˜Ñ jŒCp¦ß;e ¶VRLˆ4\<š]ÜíÛÒ+3y³Áys5¶G3’ v.¬C`£*Î;PŠ cèm´VÞ´ZÉû‡ÄZ»ÉÙ’2ÖÙóäòdŽ_ýõßàK^ü"rμúµ¯ûO.ç±Ot”«$Í_å±$žOdB:ƒ: \8<³eÓfŒ3k©E@)FgYJ¡j8Yf|(g±ªç%éÃí˜ ª°•îˆÚ¨.!£ºkåfÙQTYÓÁ*u/Ë¿ÄØÏ= ¿ŸûĶŽl¥â/ÝÈïÜ—ÑG ÆPÕŠâŸnU+»eÇ|'–‚j•Ü*µ5Œî(´Vq»C‡š3ÊŽ;P–Ƽɼó¸ãŽW#(Rõ¨ƒ§sRÀªD´wûФ’raeƇ€ns]÷¶ÎIXƒó–"Ý¿FzÖg»,L«‰¹*B΢DQJD;‹ÑýÞ…¦HY+tm`a5»´`½§4a6°Ö—ÆÛ™O¶LÊ2 Ž0ö¿51Üà­#L1%–%ã¼%„@“DÉ µÏ\ž¬QkåÕ¯}_òâñE_ðÞð¦7±,ñc^÷[ox#õ›¿•—~ÅWóû»ùà:ÛÖšð¯ü—|Ã7~3/ûªWðÝßó½Ü}Ï=gÛ¿ü_ÏoÿÎÛÏ~×ï½›—|ùWðC?ò£üÒ/¿ŠŸý¹ŸçE/}ÿâ'êIûYXk§ñš±G“…9Ý~½jçÑÌ£½÷ZÛŽ._Á(EtŠNL#¯<‹Žç1Ft¤5P0owHi]iWúÌEïÙùZkj©ˆ‚†œIÆ(J©±´ÚÏ9w{eH»…¸Ä3ƒ2”"׊ÝÜÍÅt—ôŒÏ;VVã%ákdÈ‘UI¸¶E—-Á@m•q½&×Â’ú¢Y[¥¦‚Ò?ØÕ"Ⱦ²£ J A2ÊäáfvÃÓÈb1Í\ ‡ŽŠkíÌ nvXQxmÑj©¤ZºAmhš®l—-WN.Sè°äœƒ÷Ðh… âŒA Ží¼ƒÚP² ®óVjé÷¹UJéÐj”ÂŽ€Ýna. ¥-Áˆ2§Hµ–`KŠìv;ò¼pådC…¸tá7¸Þ*3rÁ¤‚މºÙW.OÖxó[߆´Æç<ç³H)Óšð†7½‰—|é—<äu÷Þwßÿ}ÿ€qù±ÿý_ðíßù]üÜOÿK†!ðc?þãü‡7¿•øÇÿˆ!~èG~”¿ù]ßÍÏþÔÿq†º^|çßø6¶»Ýy[ ˜—…|Ïå‘|W^I@_Á “ ÁzJéT³v3z“pÃ@8´±Y%Z‘J ëÕŠ ³âs-l–-ã8â¤?)  B'gj§pUÐÚ¢'ƒ”ÎúO)Ñ”"M}¯4UWjí<Ô†AA­,Õ1XKKãmxï5ÓLÛKÑÔ†q–ã¸CyÚUœd‰yƒY”¼ ¢°R´¢]z îÊŒ °l37Ø‘¨ JÊô„ŠˆÁ¸.#ã-Õk–’ñ¥1ŠkÚ[TLr‚sX¥Øžlp«mŠh¥8¸xÈnžíYù3Y5ÌÁ6gªÍYb­4ÔŠ, Û¢> l—ÌÖ{Ä(.M+X2*AžgŒ”!B6aDJÖJ<¾Ÿy0?b«bhš¼j+Œþ¼ry²Æ¯ýÆ«yÑ}!Zk†!ðyŸû\^ýÚ×}Ìë¾îk¾šg=ó™<íÖ[ùûÿÃß¿ñš×cägþŸÅ÷ü¿Í³žñ n{ÚÓø¾ïýŽŽ¹ý o<¿ÁÏÌEk”zP×ëOz|J¼Vr9ó^¹j£”âË—¹xñbw.l ›*n.øØpsÆTÈM+š4´5,RØå­a«`P¤’1΂Öä’ !B ÆxÖ:rΡö6ÐKJˆé¾¦ ·†2wÑj#8×û*ÇÚ‡a'…´ò‰f UCÊI+@®¬ü€•çݳ²_­¡Ôº¯ ã) š²ˆq,9!FcßÛa JëZbÚZŠmˆA“Ãì È­â†@˜&š€j0„ƒCŠ÷ Õ”z†ÎR†`eI˜"¬N2a© ÆQ6ó®“Sî ÅÆ0 ÙåAJ [„œ2~˜¬gRŠx|DK R"Ú@‘Æ  Ž®¸°#¥V²ê·ÀkƒŒë†p³jTmÉ{õ…óx’EΙ׼þõ|þóŸÇ¼,ÌËÂó>÷¹Üþ†7’Rºîûœs|ÎsžÃþðƒ|èæµÆ§>ûÙgÛ§iâ3ÿìgð?üàùMþ¸ª„áÈ×u\¥(|-ƒ°Çc¾ùòá‰æZï»z»RŠK7\"¥„¢/úÎX¼1¨Úh©ÐZEËÒ ¹URJÈ~hÝö­2ë¢ ÕzF”½gH­çÎ9rÎHkE® ¶Ê&ÎÄÖç:E ¥œµÔ%QOåÿ÷MeºÂo3 í-ÇÛ ND)Üz;§Ô^ÕäŠn`€hÀ­'æ’‰¥_‡ìyö¨¶¦,U;²hæTIU KÉØ1ô$LkRÉÄ’ˆ9a|'N†iDLgÓ+ï(4”ó(È–,`ºú°Ý«8c»ξ=¥j£²GÙpF„(KBím¦OÛŽZk†ÚÉŽ…ÆÊ8Ôná‚·”Ý –Š1Ý—Gb¡-‰Ø óåã¾ÿÉcƒ'ÏûÖ¤4’†, M’s´Ø“2nã›Ønwü£ïÿ'ü£ïÿ'Ùö¦7¿…/~Ñ ¯û^ïÞ9bÊgOµW/ˆÖÚ‡@‹9¿áV=ÔÊ•£+×\ôOüS&øãÑ»–¼þãq¥ìɶ›-¥(’d¼ÖÌ9¡¦jCØ,3ÊYŒê>õˆÂÖΰ/§ ¥€9#IʾµuJxTª?u{ï:·H7³Î¢­Åø>t—Z)©àŒÁ‡Ð«‘=" kˆ¡¿ÎŠâ‚’4Äôï­A‘爷–¸›QFÓ.Žd¥¨¥£Ü&m ¥BM©ÛhÇ… —HÛ™š2ÁC%õ§öV0Á3Ç´bp#ÛÝÌä¶AÚìÐÞPÌËŽPéZka@rA hÖ곇ŠR *+Z* “GkCÒ…“•eJ–ŒÑ¬EpŽT2vŸ¬O«: ßÛ”iÇÚXNqÐôvâñnæ?0/KGå•ÊÒ2níÈËÂj˜Xrf—+n=²‘Â8ŒTÎúOΖدÿ/Ù_ä¯}õC~žóYŸÉ«_óÚ}¬¾jù½÷¼‡g>ó<ý“nC¤ñöwþîÙöZ+ï½ã}<ë™Ïºü÷ÑÑñ#žK÷ñxr‡ÒŠõj}M†þÕ¿ŸÊš<žùÉc©\®®œ®žåœž—1£5Ákf'{*‹l§‡kׄaÍ¡ŒhÚÜ Ð«3reDã”Æ¹VvËJãl7S(j©´&(­˜s·vÎâíÒ/R± Lª$«0U(¹0ÓóëqBÓÛrfɘ҈»¹_Óh€Ew8sp˜Ã5z½B­'ÌÁšËóŽÔ­ SIÒØI!(F1„€ß.¤ËWð Ê:C6 ›*«Mahšt²í¤Ï}2œc9Þ`re¬  \ÙbCZCY‹K†67rª²œ¤™]Ž”ÚùC®)B™ìd? ¯…YÊÊ‘¬Ð¼!J=K2^ê"ÖlŰՆš…A´ƒ]ZÐa@#n}@̳ÙX¡ZÅ$†µ4Â``tˆ6è¥Wñ0ká©É\fòœ'—'[ÌóÌo¾á|Å—½ìc¶½ì¥/áõ·ÿV׌ÚÇÏüÜ¿â=c˗¯ðÃ?úcÔÚøÒ¿ˆƒõš¯|ùËùúƒ¼ç½wðÀåËü³úan¾ù&>ÿyŸÀç<ç³ø?æÿæî{îåî{îåþÍ/?äx·Ü|ÿá-oáþ`^–'o[ Øî¶"fa5]+¹(ÛÝLÝ·g4B*‰¶¯*”RŒaسùû÷-îåö­5 !u K~hËMïç,¾+ÐÁ"BÛ*­1=a˜Þë§uÞQ]‚E[C-•Ýn×¥ý¬6Øýl IoË9ïÈ) S*­Ù-3y?X5ƒÞ%\¬ø¥áEw À^#­JÃ]\aœE¥ÂZ ÅRrº¬…H£u0°Uwa…„q ©Uj¼óh:rTÃ:Íj5¢hXc)¹'‰Úú5u…jAéž”}Ñø&Q¬«fh D;UIFØ-[òf˺)ª74§iV1SÐÁï¥`WŽŽPF“SêB¤®_³k ª4¤ .rÎxë°Jc$.3¹äóäòd‹×ýæí¬W+^ðüç}̶—þù/e7ïxËÛÞvö·ç}îsùïÿþ?ä/Ó7óÁ;ïäý¡<ü;ßõ¼àùŸÇwÿ½ïå¿õ?gžgþçÿñÎÞûßþß°>XóŸ~óÆßúï¾›Oºí¶³÷ü¥¯ÿ:n¾é&þÒ_ûëüàýð“¸/vm‘Èk-îŸðªéû¿Z‡ëê¶šR]¾%Œë½g{ƒš»K¤Ú·ðJWéE+´5<å–›c$+¥ aϯå 0p*œ˜s>si,¥tËzÛ“FÜ-PÛÙ<&¥Ô=ÝKWº0e-¥Õ™úƒóîŒ[sZ…íæ¥¦iƒ³–”!„}5]•Å¤Šš3jIxzkRѵ bÖ=§Ä ðÒ™óIúß•³ëD£—ÂZ9Ô’¦‘T+Eƒ=ÕÀ..ýÜcb™·T•i’99¾J„RúâíaÉEÿ®¬V+v› Ve‰]mº4òÑ VT_è]Y ޵ÕLÒΪáF›NH¥«/Õ¹-EމR+~lZ"Ç„- «4sÍhc°¥QS¦…1–¸D”<ªxçñ˜¢Öʲ,\¾|™{?ô~þìgÞùMùÿY¼ûoãû~àâÛ¿ãÛù¢=zïêÿzãO”CåõöóðªâTž]ZãÿúÅ×ñK兀%’òL2­ ãxÀñfÞ'¡ns|ªp\J!. ÝÝÎVc—YѤKô_=ß)ºKí—%ö»R¸i ÆùX²‹lFÍÅ¢œeCfÂ’æ…¸) p–¼N¥Ú~ß”Bïç„§¢‘I*4Á6PMPÞ¡¦¥Ìh=KŠ}à¿Ùâ´éÜ’Á ¡srêÑ+6x´é­¾& ñž\ 1gü°ZQRBïó~8‰;4 ¹2†’K¯ö´zÐ?óxâg. .]¼ø…þ±ë¶Gbþ?Z[ìáɧ!”–¹8®ÙmÚXŒ²{—†Ӫ[!k‹¢k‡ï1JVÓ™(e«#SFiƒ1šg‚{Y|¡¡ÈËÒ¥a”¢¶†Îu•³ M %E$gŠ*ÝÑr­‘¦H)ÆhE[漜§¥Œ6–¥frNXë¨T´m4¹$ƨ»…éÂ!³–V@A:Þt¯’XP¤’–{¢h‘^exM­RÀ_XSÚ×4¹´îò5Ú*’é°Þ°+4çÙ]9îü¡½„}Áø.Ÿ3Zƒ¨žíä1¹‹†¢sœÛ«‘´ì%-™ñ`E¡{±ˆnˆU``­K^k8YfVësŒ¸=CTW`–¸`!·¹Ï[ ·ÏLU3Øn4zþ¯}çñDÏ8®ž;<:´ø±$‡ë ïþûµ$þ)aµÖ¨%Óæ™¢¡)Åè'ZíLüZ2ÎuÙûVKçbÄÔýîìJ ¡K¶´n*Ör¦åβŸãLi…\ Áê.¤Ø,B+…VJ×Óm5ƒ¨îziºa•²†…Æ¢‰®­1ÇÈvžQ{ñÇ¥d_1„`-ZNkL®˜ÚðºWZÃ8‰;$RIÕGµ‚Á9Œ9Fti¨½O‹u–) xeð¢hB˜˜S!å ¬êºchCŠÑìæ™²$vTÆÃ¤6jÎP{ò(¥·(ŒÖXg‘TpU˜QÆ0ú€1šE7êdÙQ(V1çD)•4Gœí5j´TݵÝN._ÁCË…–Û8³ÄbT†•¶X£iJ¨µ0iÛ!èª6Ú‰)QJ>¯\Îã<žè°¶©K»ê±ÄÕœ˜gW@¾V¢ÑJuOuéêûÆ9¶óŒ¨C¯©Ï`–í‚·–ívÛÛi ÌÔ«’X"uÖ‚‚¾Ÿæ{U²]fÁ—ÒªöÜRz«íÔøëì¼÷0mc 9X¶R¨F‘[Aj⢠h*º Öh–yf‘Êz½ÂÑpUP±Âþúuv­B`Y´Ö,VÈÆKFåý±­>³mžç™Z»d "d‰{Ò‡ÓŠs‡’KƤ‚+…‚õÎyrª¬VkšNÄQãRG]V„yžqã€Õ†‚P‡D¨ÛcuݳeXÈxep t‡„»U ,‘RJWÏPpcuÜu´¡L7¬Ç[eN¸ÑDQÖQ 6Vl*ÔÑa¤áC&Cl•f4"Ý‘tÿyW.çq B+}ÍJá‘|\)I\Kìz¿?ZµòàA»Ëi^€Jcu¸î|çpƒGYÓͱR~pÐ^+Ûíö,9”\rÖdOÔJ3MÓC””•RgƒüÓùÖ´, )%¶Ûޏ3Jc‚hm(yÁRQ%rèÁû>Ì׆bJ(­)%“syбò*§Igl×ø¢aÖ#Ùô$~p§ ëq™}[ÈÂzb—#MC3ÐH„Z8Њitgvŧɕ³î ¬µîXï»”‰í®R)}f¢jÂGn-ÝCe·9¦²ŽínÇ`4!Rñ멣؀I¹¾ÇØ%WbÁÅ,Âbm‡­_{I‘†¶=IkøˆR™ãBËm=R¥]+”ʼے›à}`GvóŒjݳ&ngŒÛJY¯zÒÔŠ¤ZOZÁâm¥¥Ê#4“³e(óBAJa0 UiZ+÷.°^­¹o‰lkfuñ™ÇKD9C* ­U¬søZÁ°†¹T-­‘˜1Çîß3xâ.vñMc:Qöü_û<Î㉠ç\_8y)u½ÄqšɹòZ²-W'«÷{õúÕ„Ikíƒ'WWAJÂ%”Öä¼ežRŒÔ11sQy\,´}esꊿ13ÄÖÉ‚©0K!;MAÈKb{¼áD7êà™[¥jÝU‘Lã g=Æì90hRÌXãÎl†OÏÙ9Ç4MXëã@7bÕÀ0’ÃÀ"šVú;¸@Y ——-Ñkbè|œ˜v ¸õˆr†• ¨“…Q ’ %õYÑà:ÇC´êž3ÞQZ%hCÍ´ZA¦¢ðsç­x:—fo~V唳bÑÁƒÑ¸¥pÙ5®ŒŠ˜3jÉ̵p¯Ì¤V9,W=œ øiE29ð\· IDATX‘SÁP.L°žh(´ql7;$5$V¼±ŒUQ޶ÔZ™¬gt7†>Ó*BVйŠ€÷%Uj;ŒÝSÆ‚óÈfÁ‹ÂX‹ikÏ…+Ïã<žðüžÿq-}±?jœÎ#¯¿ËÕɪ‰°3D#h˺Xd,¹?ݦˆ(X–å úÛZëôšitÖ½³M6M8ﻼûvKI §5Öt¯ÍfpÖ;m‹A‡*ÃpÆŸ2ZSKAÍã™F™µ–Z¼Ó 7¬H» Ž>ÔÖu‹fÕ퉃u˜ñdK™«aääÊEÕ•æþA¸ÇÒÍȾ œç™œ3¥VֻϊwT ²ÌvV(“§zƒY dî '1«4ÎY:d­ÏŽÔz`q Ã0ž‰OžZDç\8>>Æùþ=ºé©·pùøˆ”i^º€¦3èõˆ¬;ÓX‚&iA‹à– "¤Zˆ»…T ÍiܨMAÚ'Nå vè­¹}-‹Ê][c1B çfaçqO|[,ŽŽŽ®)sÚæºêë±&‹G’|¹Þ>®n»ϵְWúU¦ŸÓ2Ïäa$µŠR‚÷Ý+ě޶rÎõ…P :¸î¤ ¶ìÛ&ÒE,µ3DÎ8TéŠÇnßö:­¾NÕ’OÛwB']ÖZñÞœ§”ÚE2RÊh»7°R m46WŒÖ”yKPŠsç¯ø@Ó©}˜/"8úùÄy!–Âtဋë´RÄ“Zk‚¶¨ãÄ.gj­¬×kNNN˜SdGE‡‘ ÒØ¦Ì0 {Æ½àŒ¥,‘ªÍZŒ­œ'¦„›cÍ]ßl:±1í?—SÀÑ •ËÙ îî™60^dN )UŒs¤ÒäÁXœ(0ýü[Î]‚Åü^a¸–rv|c 1FV«›e¦…s}nß&7Æ0‘bÄ6Í2÷ ¤¥Ì8ˆR,K$KÃ*Å…jØÄ…\vQT_»ârk]$V)rά÷UK3‚V²O’ž£ãVãH‰\#6xŒ1¬aQ½ZÁ{Š·¨*äe!Ó¨N£œ¥IB©.¹_‚5”šñã@U=¶ZC /9Ù1¬Æó¶ØyœÇŸ†¶Ø¼ÌñN¹VñðEÿñ¸L>Þ–Ûé<`˜FJ*(4Æy– ~ââ°¦.]^?Kg‚Çyat”S7®’Övélã-ÅBÖgbŒ¦iHTbJä ÎQRêòø RN(Eç[(m˜ÆÕ^;³#È2=¹€F¦rùÿØ{óx;ëúÞ÷ýža {ï„`Ã(–ÈhTœ@{[AOî­E{Ú¾¯ç\O{ï}u8…V†ÃAV¥ŠtЫÛ:µ8™Ñ"!@H! !ÙÃZë™~Ãýã÷¬•µ{‡ižõ}½ö+{ï¬õ¬çyÖÚ¿Ïï;|>ºÝŒ¤Ù¦pPJIæ FT”8tÚÀÔJR+d#fΕÈ$ÂÅšLyà³’TéAo )i4ƒò£÷ž†Ô4{†t&'Í,‘õhçC¿¦(ð Oª5yäÉ´ÃdsJ2)*¥Q¥ ëJâH£*‹5¶4YRIl‰)!Ë 2ø*Hðá™-sK&˜ëvPi¤Äy‡É šÍ&¹5” (+d–St»4¨™Q'#A!¬Df‚ÄÛäHkš*‚¼$F ëLSN5q3e9—qŒc¿‡cAòä/J¨ªgbF6zŒÒTLëUË3GÉ,ã=¦ VºIœ ‘µÖ” ¾&‘ 'AÞDkdí) L—U†8ÒH!¨Œ¡—g”Ö •ÂäFšÍ`ß q¬ƒ«²ÌtAÀ9ã5ÉÏ8¦ð|èUÆP%¢Ý¢ãBcZ”×bE×úg’0 ]Yƒ+ÀøÚÛ„p,ÝJ™Žݦ¢ÛPt©³©¾-³Ô*(ÔÇp±¥¨¬¥rG¸CBKd‘D ©ˆµÆKèÔ™†µ6 }(‰S‚öÒID¬0Âa±(/CùÍY’FJ–gDq$ø­©Ù÷&PmPg.{í(¢cp¥AØ $M]bT2ðª¢$‰bʪ¢ÄC$¨0cpy^”M„@J…scyú_*LqaÒI*9ð5Y¨¯²Ýð3†á…€g¡×Ív$ž%ÎÐÈrÚ¹a©Ñh©È]En*rØõ”¡¯‘W%Dšr¶‹¨l0—rç¶^Ðb/P&x¿GR¡…@'ûCeU–­._Ùp u©¬, Œs”Ü”XÂd]Y+ &Õˆ4EU6°Ì ®Š62îܵ‹8Š©ªài„C"ˆ­À[KV–h$ÿuai¡Èó|À{ñÞSzG.s®DM4èzOFç=%Ô\/¸oöòMçiŽ\”dÝ.’Ý“h^8J“¡cÒâE¸ª^#¤Æh±LX…Ì«ï¦(ŠÛgeÂhrEõ‡`·o‚,Ë<%DO¯‚Bé »æf‘ZÇqÝ›3AÃÌÚéxZì9*ý/ETe5¾)¿DQ•%ÈïÝ€\ølª ï ˜{ÑÇ<õw’²ëÑ$H¯(óœ^ÖÃ«ÐøMÛMl$)‰Å#*‹›î¢PÖ‡ ,©ÀyÒ(¡%˜^ެ\XdëO"ȳl0&¥DÕ²ïEY U÷„t:Ýð¸H!“#<*‰é ›è“c&À*cXrðAÖ ¬Çä%Zo,‰ãÙ°p{­‚jr^ÒH¤Mšiœ ‹ 7—Ñj4=¡f³I«Ù ׋p~ªú¼ @ØÉÐhoë)4#æÊ9ÚR0å<º Feý ¸nž!¬A—%2Ï‘y†(ò0ä $J…ûÕUÕLñÞ‘»0ù%…D×@✠¯WËö;zaý¾QT“8 Ùœ Ùœ`X º‘àk«ë>×ÈZƒ-2cžËó$k‘4š-ºÙñ ù%ŠîÜ;«%Õ€}½¯ÙÉž2–ÅŽ³{ô¹Î¹A£|ïFJ¦•¦£4½XR´tůóÖYœT*4Úm/ÞCç3(Q™ ±Ÿ6TÎR¹à5ï­Cº ’éðHÔ˜¥< ©Tð§'ŒpWÆé•Z\Qkt¸œÇØÀG‘2ƒ!ª[2©S<ž¹"@­k\™“(˜˜œÄ ˆ´cÓlQÒh4ð.d.[Ë.sMEG{z½2'N*cÈòœîì>¯hé˜TÇDRÕ‹u16Î!”‚(( ½œBK4½NŸ•,‰äyN'H¥™jOcœ6MS8Ga yY "I7ë1[ô(L°cÄŸÖ:0ñkS?óóÎQä!«”6(!{ +K”VapBX”atYj¤S”øšäŠq´U´Üб¶ØóX´ÖDIÊôΰìAFwÏëðÞ3½k?\•àÚǘG \è3ñl¼öBߨN¹DÖZм m%­¬"rA)4U^’Û)ÅBÒ’*ø‰“—(•/øÚ2·´&ðO¼Á§š^Þ £¿6('7§ÚÁª7k ÂFAAYzt#¡[äAšEøÁn\†¶“‚¬Ž5HA”&ïh‚(ŽQÖ£„BÄ1ÆTx)Bï§T ËZmºyŽÈ«Àª•DDyÅ’FDǖɳ8Œ«°>,´iš"ÄV†^Q Ó˜(ޱõ`‚už(ŽÐJSÄž¸Õ@jIו4BF)Þ:ŠÊA³³¶GŽK°JácE,¦ï[_z|i‰1E•Ó0áý+æ:´T&R!»‘œ@$ÿÁÓ+{¤Ö£½D'i=IæPU(ƒ¡-£I¬@z‹‚$m"¤$3 ÄNè5§Â{1þ3n‡”Á,É …Ò;Ÿ|b|S~ bדOÐ3ŠoÞ›‡&ñP£ý_¤´ÖïËô‰—ýñhkÃbÒh6ˆ¦ÚØ©³1*¨K­h´DI]w–L8JU»HY5Çq…“˜²*˜YKEÄQ„Š42Ò%¥$•1¡'’ÈÜZëäHžë } @ô ¢Ò¡ ¥AE:”¸ŒÅ•†^UR8K^=­ÊX*'q‚LØZ-AAY”XkBo¡‘¢“˜Ê;Â+ö¹?"9•Æ‹D`«*jÖ>0UQ’g%ŽÊT4uŒ˜Í >+°EEÞé’¢H… OÔn„é8éS˜XRèÐñRµ4»OÙC‘P´’”X*b‘¦é€Dêœd£¶.É•} ä(aã$Á+…Š#t’` |¥$I ß*ïpR„lË”ÎPá‘&nMï}è•ÿÌŸà’¦)Ic‚'·o—Çžïå°Î,;¶oã¯ì:Ôµ›Íæàÿ‡õgdöÔÀ}ìpl4ƒî—PònJƒj§XšäOQUá«(pÞSD‚BüX û²,}炊÷­ÇB"‚´Œ³TÆÔuüNEYâ¥Ä჊VÄ* DQ2ŒWÞ!´BÇ…©è•Eè¹Sí d#ÆjS‚¼*H›m¢´E%4s•¥ŠâüMYUyAé N TcðÈXÈ(« á舕£ÓPjkŠÀ웂㤤Ùn’kèäq¤±Æ…]zž£[ QKÞØz9Ršª((mN1Ǭ(H’°©+Ê‚¥K_ÀÖíÛñiLW"d“„²,w›ŽÕ%*¼§ÈsâFhÜ—•Á{O7ë¡âˆNÖE ‰BaMF… Ýná Ú{„5D:&ïuIš1YY1uÀ:½¹AÏZ,´BÄMœ1$li™"¡0«ñÄÊ:N‚W–x'pJ’åù T«¤Äz&ïLÐÅSq¤u¤=¢(ôqÆàò<˜þ$Qÿû8ŽÉó〨‰”ñ ް>ßâU?CDÍ}+MU=~õøSþ]Þ7\žp""‰Úi&‰¢ !uð›wvž³âÞd{ÊLö”åŒöWötÜQ@ê&ÇRQæs¾‹ Aª43Ýn0ŒÂãDèYô¸´‡†ºp(_á• µÇTE`Ç×b—}@ñÞ‡þMÝrJ`„'1ï ÀôôtÐØÒFèE¤_”Æx *oQ:BèãCSßyOä@ÔŠ‚0^[Ö<þpCÕËhÄ)½¬W—…‚o¼·±’ÄÍs³sx<½ª@ꄲ0¨ÒTœ³š·Ó´ÖDip»Ä ´Šq2ÈßÈ(Ö€1¡Ô$UŒÒžng†%í LQ HéB¹/Š™››#NÚzšqB¯× Sb¢ë%"è¤éDã¤`®Û¡‰ ›‡(Â+‰–*ØD{?P¸F*+t„”e]J Ÿ-Ô\žoÓÏdúMþªªBCu]ª_æX2µï#¸”a:ðÀÿÝÀe0N>$ÿ.TT/2áÿÛíö<öWY(ƒýyŸ%™ÏÈßpp]¤¤J"PÆ;O!¡S´ÓE·‡RÙL»~á*4>mhX—Ö m˜®òÆ’Õõú¾ûdÿu ú]¹©0 T^¡=Xéñ0P0H ˜Êa… ë+\,)œE+I¥”ÖáçfP“ mL^«Ò”¦"ïv±Þ£j S/(òcLhè AÒ×Xت…ö´[mŠ^†Î<¥3x¹ÛG1°3î7/ƒrœÆØ¢Bà1ÞSXG$"Ò¦•ÉQtéP¶ÂÚŠ¼W’4[Ì Oì$~®¢)…¡¼($ØŠª[Š”ªòÈ4L¼¹¦ `ZU¤IŠ) K&(Ê"”À„ˆpæyúc aÔçiƒ^‘!<4“”²(h•1I,Çàò|,‘ ¬W£h°«û_ X&'Úˆ¤½oàR„òÏÒ¥KÿÝÞ³á÷m¾gËîlŸ‰þt¥®Q0u“Ü ƒÊ0 õåUÊ‚†®J[bŒ¼ 3*Rxc‰dh’w³,LpÕQvr"­ñ>4ŒwÄÆ²l¢MžôÊ aMa¼ ¢ÚM,-Þ Ên^E1e/ǤEh„’c‹nY!bM‰£4%ͤHU‰³Ž–ÄNgaÑ•q° öõTÎ"­C8ˆãˆî쮨˜hµÂ㢖"VD•ÄXO‰¤™‚"Zâó*8GJ·S™@Uõ߯cÉ ·)ª^.ª5ÍŒ êÓR‚µ$Q\Omy"¡#Þ»éZEø*Lõõ5À¼ fnû’8ލtˆˆ"…5‡u%éd“¬Û%³ÎVÌvf‰´¦¬,‰$JB¢!Ž™žA+E¤5¦æ- au .ÏC€Ýãª{ÛýeŒ$II²oàB5¨åÿ{¿gó›ô»p[o†·X¹k1ÆýbÊBe±§Ød0 ‘,¿÷ž²×㤠«2¼PaYx|$PbÏ{ÝHFH±÷$_”U‘ i\iQZâ”Ä8‡óá}Æ:p -Xá°Î‘HÆ—… Ï3â8f®èá¤G:G¬H‡Í3’$ÁzK+¨ƆA‡¬ÇÕT˜œh@Mø ,Ùl·>1Öý.jà𔓘߈°­k\Q†’Z^)MÇt»]¢8&MEAÃKŒtÊ çq6ÆÐ-3¼Šèöz´˜¢éLY‘•/Á§i” „Àçj½²1ÙŽ9äDŠÈs&[LWŠ¢DxÜ"³íAF’"ï—N­É K!˜™™iÚÍ)\Yb*‹œÌä]&ÛÌÌÍñÒ©_anfŽÖDWïöºhᬥ,+ðŽ%K–RY‹pK—R¹­Có¾ÙhÐëvHtDž·‘}»ƒÚÊ9老lŠNO‘´Û `®×#M²NJ’¤$uvé%èªâ¨ƒ—³éÉ'0ILÕ-ÑRÅ Ö]2ÉÖ]»Æà2Žqìtñt:–-[¶Ï%¯Ñÿ¾öS±…È›ý‰´ÉÉ”©©ÝÒ4ÂS—õÄq”kK„9È#‡ÒR@QàkúVx¼ ã¹R_÷@Ü:×Xd­pP™ !$RÔ"˜CªRb…˜·z,}û@Æ«ƒ¯ÇXïå¡úp®^ìææ`AÙ&V€hŸî‹x@8B ôã„’o<!%x‰­ÏÉX‹Š£0J\[,W•¼}ɘ¾ki Ö CR9A0u8+•J`mE¤k¢£›»ù Î×VÕRHPEá^kQR¢°D™!FRE˱J!Mý’ ¼CÙ¡ƒË8Æñ\ˆ~_cx¡ß°ØÁÊÅž?üšÃ£ÌÆS •âÄKv‡snÞÂ<8–˜/õzƒègM¾BÕr%JxÀ"¨ð¸¾Š Þ÷ûvpÞZ†ñ×pþA»¬Ÿ W“ÁZ‡P"Œ<ûÐãZP¹ Ös’HÔ‹iY+ Œ¼FfVÔ`)Cv" ý"ç>¬Î=zn{ò‹.•=Ýïšf[è<³)V..Õ>nøÿž®œ¸Ðõ s‚öF^g¡éÀáž×B™c¿$¹˜ßO?CÕž[è3¶·Ÿa§Òáãöí?RƒË8Æñ—²,Ì{Ê:ö|[Ôöe²l4Y(“é—¿Xl!•ñ_È£f! ^ì>ö%m†ftV€îO‹–GÁqø¼ºÃÿöàáó\L4tô¼â6-´Ãzr£Ÿ™ÅÞû~4zM‹½Öð÷{êÃõxôŽÁeãxÄÔÔÔ¿¹}ÂÓ-@{£;ã…|…Fwߣ¯½Ð÷lÄBSoÏ$ú€4l/>Z.\èZûÌùÅ&ížÉkÞ·áû? €}×Îgë³4œ±ìk¦;—qŒc?‡ZÀ†wßÏ–ÌËÞZïí¢=<6=zÌÑlaÔ/f±ÌjxÚl¡Å{10þýèÄÚhÉlt‘î<ô³—áÝ÷(€ŽÚ,”)ŽNÜ gv£`;zìÑ’×B÷t¡ÏCô{ôÜû?ï ˆ{¿F¯}_fûØÿ× M FQ4—qŒc‡³ŽªªöZ¥ø™_ø|‡®½µ×¶Q€áŸ÷v§ß†Q€á~Á3Íd†Ï{og\ŸîúûýŽÑßI)©ªjpŽý’ÕBÀ»[èBê Àå†È¢£ÈBóL>ÃÇîŸÿà~ÿ´Ç1ŽýBî^,÷´ .4ÅÕÿy¡]sÿ9Ï$ ¨ 5‚GÓá,fOΞÙ{ʽ¾>غڼjô÷Þ£%£yJÎ dƘy äð÷}Ó0S™yΔ‹ ßûáÇ {ìôc˜ÿSUÕ`‚Î9‡©Ìî)²ú±}Õã…2©Qðê¿~Èúzuø¡{ÌîkYì³³P ¬ÿž Ÿÿphô>Áeãx„w.Œô.’qôŸ=íìû ËècžÍ~F?”R|üŠÏÛ /vn£ ôt`ä½gõêÕlxdÃî1ߦ¹ú;ÿÑ©¦þB7üØ>ˆEÁõ×]?XVß·šU«V±fÍÖ®];X´šÀê/ÆE^pËOnYôzúeªU«V¡¤â¦Ü4xþc[cݺuH)™ž™fÇ“;敘†÷ó2'çÜŸþ±ZÿP°=¨ïCÿ8›6m¢Óé<å^¬y` ;vìØ§ÒiÏ ×ÜßX,vcÉýqŒã9qï,–Á,&Ëÿ‹4µGwÊûüû¸¿æO蚥®¢ö¡oÛÍõà­ ¾ö6ÈÁ;[/¤5—D!. ½óÌÍÍ1777à¸ÄîÌÃ:¤á|8îH–ÐÏBªªÚ…ÕÏ©ò‚믻áÂBè­eÍý÷³nÍZvîÜI·Û,ÆýLÃSgo,Â{v=ù$ßýö·‘è_£óàv_Ÿ”’üã)¸áÞ0X¨?ówÏT{W¾sÝõÜróÍXWáœÁ{ ¸hhÿË{Ç¥—]J·ÛÁÚ𳳎p#;v<¥\eÀ:n¿í6ž|b_ùÊW¸çž{÷拟û<íF³æ™ <»Á'¼wn^öˆ—Ž-[¶pÅǯØýÞd@ýliÜsÇ8öwæâ=Y–155µG®ÆÓãéÆŸqÙnDàÒ×ÂŽÃ}€­Û¶r饗b­eÅŠ¼ÿýÿ'išb­ezz—\üa¤¼ùÍgòÆ7¾‘¾æ_¸ë®»‘RrÁ…p÷]wók¯CGü·ÿv!ÏG?ú1N9å¼óLïšæ#—_ÎöíÛxÿûßÏÉ'̧ÿú“<¸îAÎ<óLÞñŽwéÛ·oçSŸüN‡F³Áy<«®ú4ïz×Y,áÁ\pþùüñÿ1³ÓÓüáü!SSS\xáÎyfggqmÇŽ'vpùå—33;ßýÙŸqÌ1Ç Àå¡õëùË¿üKŽ:ê(¦&'±Æpóoæëßø:§vï<ë¬Û Ù ÿ'žx"ÆV­Z…³–ŸÞ}7o{ÛÛBÐnµèÎÎñµ¯ý3Û·oã÷ÿ÷9èàåCǼ÷½ïå°CA Á½÷ÞË£>Ê1ÇÃwÜÉT{‚ûï[ÍÊS_…ñáÃ{ûàƒòÿøœrÊ)¼ímocnnŽÏ}îs¼ç=ïá¦ÞÄÖÇ·rÿý÷sÔQG 2ªù—køÑ~È[ßúVN;í´qæ2Žq<À¥_ÊØ[0ØdoŸ¿/}˜y„Mļµ”’ïÿû¼å-oáÃú0Û¶mcÇŽ¡§ ÷üë=wÜq|ðƒÁÎ;Ù¹s'÷Üs—^v)o|ãùîw¿K¯×åð#çÜsÏeÙ²xä‘G¸ýöÛ9üˆÃ™žžf®3ÇþÇøoy —]zßøÆ7øÖµßbù!Ëùô§?Ím·ÝÆ£>$OêöC?Ä%—\‘GÉ÷oü>›6n¬E2=7nD)EQ\vÙ¥¬8î8®¹æšÀÌÌ ½^Ï~ö³¼ýíoç/þâ/øÂ¾0ïýºøâ‹¹ð 9þøãÉóœ5kÖðÕ¯}K/½”‡zˆÿøÇóvôyžEïz×»˜™™áꫯæø=öwÞy'¢¶/øÒ?|•‰æg½ów¸ø¢KèÌu¸üòË9ûì³¹ÿþûÙ¹s'Zk^ùÊWðÐÃñðÃsòÉ'sÛm·¢¤â²¿¼ŒÓ^ÿz^ò’—ðµ¯~oü3³3,_¾œN8M›6ñ£ÿˆ³Ï>››~x›6m˜ƒu»]®ºê*>ð°sçN¾óïò•¯|…—½ìeüñ\{íµüñrè!uÔQèÚuò®;ïâî»ïââ‹/æ{ßû?üð\Æ1Žý.°Ç¦ñÞÌè4Ñž²›Å³˜|˼œ B›Ã ÝM›6ñ­o}‹sÎ=‡5kÖçù๧¾úTÙ°³Ï>›‰‰ 6oÚÌÚ5kyÏ{ÞÃ_ò¯Ù°a½^N8V«Å)§œÂí·ßÎ~pgžy&•©˜œ˜dóæÍœxÒ‰¼àW^ÀGþê#lܸ‘o~ó›¼ï}ïãç?¿—­oE°»!ôÑG£#ÍI'žÄÃ?LY–¤iб–÷¹Ïñø–-¬_ÿÐàó·yófœs\ýé«yðÁYuャX±‚Ï|泬]»–·¿íí7Ñ8ŽA€’ŠU÷­âmo{¼êU¯bË–-ã²Ø8Ʊ¿CII'O‘¿ß[€YLzåéú({Sn[èqÂC™å(JiŒ5¼àÀpÆg°råJ®ù—aéÒ¥ƒzýº×ñ÷w9ôÐC¹à‚óù/ÿåXùŠ•œþ<ôðClݺ•Í›6ã öÉ'ŸÌõ×_OÒl²lÙ2¬ =€f³ÉÜÜí ®¼òJ¬µüéŸþ)¯~õ«ùÞ 7pìK×—ét:(¥Øüèf\v ›ÒMc(Ê"xÆ(ÅÎ]»ð¶ïØÎË–a½#’Ñ Ôn·™™™abb‚þÚ?óÎß~'¸ œ¤)®.iÆI0:ûß~íœuÖY<òÈ#Äi:o2«1ÄqÌ«O}5oúõ_çTÜ|óÍ$I‚- ¿÷¥¬YC3m„~•u<øÀÍF Z2(D«Ý¥ÔF£|_¢ˆÙÙYî¾ûnʪ싟ÑHx<§Ÿ~:+O8‰Ç·oãXc9æ%Çð[ïü-ºÝ.eYéˆO_ußþη¹ü£—óÞ÷¼w>oG†ìµÛ颤"Ë2´;QŽcû=âzØ[pØSO¤_¦ÚÛRÚb%µáé³§0ê‹ [”œõ¿ÿc9aåÉüÁþß\pá|ö3Ÿåˆ#ŽàíïxÇ`¢kéÒ¸ô²K±ÖñÒ—Ë‘GE^œsÎ9<¶å1.ºè"6oÞLå,Æ{–¸ŒÆD›+V€‡8ŽBð–·¼…‹.ºˆe,ãÐÃå·Þü[œûçÎë^ûZV­ZÅ©¯}MPö޲*Y³f —]v<ðŸøø'pÞqÞyçÑh4hN´É«’GßÂ…_Ī{WqÅǯà¶ÛnCÔ&eEYðÖß|+—|ø–°”ø‚yüž#^üb>|Ùelß¶ƒ^x¿ö†7ðŸÿóÿE«ÑâÛ×_Ïy]¸{øÂíÝ¢ˆO<‘/}éKvøa\{íµ¼ï}ï#n4pÂó–ÿðëüÓ—¾À 'žÀ ß»ÓN¿œ k×ñ?¿ó=¾úÕ¯rч.&IR~ò“Ÿàœ£,+¬ ÷$NX¹r%Ÿþ›¿afv†cŽ9†¬*ÉŠà{7|3Ï8“¿úÈ_Ñnµ¹æë×pî¹ç†‚Tüêq¿Ê—¿òeî¼óNn¾ùf~çw~‡;WÝÉŽ;˜˜˜ààƒFkÍ}÷ÝǦ›8ô°CqÎqÆgpá…23;Ë~ð®úÔUÿo1«8Žqü;ÄÏn¿‘´÷­Ut8åÔ×ï×så% ¾?îáó¸øÃÿ¥K–ÖÆXâi)âVì+Yr!«Å@gŸÃÖòõµªqéj ÁQsjjj·âpÝÌît:ÌÎÎrÐA!…ÄXÃŽ'v6R¦&§èöºÄQLš¦ `çΤiJ³Ùdff¥´Áã[gff†c=)%;wîdã#9nÅq®4xôÑGùÔ§>Åïþîï±|ù‹˜hO`­eãÆ¡œ”õXºt)Ó»¦yrç“,;`Ë–-£Óí j•RIÚí66l`ff†ãŽ;.ljðîõzÜó¯÷ðƒ_ˆ1†~;¶?ÁwÝÅŠ+8ò¨#õn¶üwÜÁÊ•+ »sçNn»í6Ž8üN8ázø!ÚÍ/Xv wÜq;;vìàôÓOgrr’;wqë­·rÌ1/áècŽaýC±iófŽ>ê(&&'Xºt)?ÿùÏ9öØcIâ„›~x­V‹SO=•õëÖsÈ¡‡õ2î¸óÞô¦7±ñ‘¬ºo/?ååvøaƒRŸ‚;wò£ýˆÃ;Œ“N:‰²,¹ýö;0¦â §¿ç–ŸÜÂÑ/9šC9d °yÓf~ú³Ÿòš×¼†¥K—ŽÁecpÙßàräê?á’Ë>̈Öz–Ã{;®¼7ÀòL£oƒ»Ø1†¹£ÌüQ±Ë…bOlòሢhA滂Ƿ<Î'?õ)>üá=E¹yT­Ïd_HDsO?ï-7dXbe!‘Îa¹ŸÝÈb¡‚ašà©ÊÄ e«û2q¸ªA$y˜¨ºÐuö膯q\Ç8öwY,Šh6›OY "þ[‹[î@+‰©­rµÖcâæŸë3mÜÛèËÛ/¿è`.ºè¿-h 0¬Š¼·ò5ÃÏYìÚìH5RzjÓ³Å7|u„•ÁPÒ¼Õr`°)#ÿ¹§Ïξ\ÛB›kí`ô|´lºÇãŽÿ´Ç1Žý¡n^&‘“à]<[\÷fÁ\h':úz£Ó`7ë@Xòa¶Vâíó„˜Ê Xá‹íð½÷lݺ•-m »qcÊukÖ²}Ûöy º'BèB^(‘½g-Þ¹¾™ã¼]º¯]/^·žÇ7?Šô Ø :ë\7˜>{ hÖ¥?kmð:+-±ÈÒ¢*‹7vpÏÊ6 <÷É'Ÿ¬À 4 …@×_Ê "!Q”È=Húìi pPFµÒ†ÏsxÊm8#yоY †ý/?Ô;ƒË8Ʊ¿3ïƒÍ±Øûá§Û‰î 3O’1ìëa=©>PŠÝ¾’ýïúZXÆpÞyça­}Š üpIhýúõ¬[¿žÞôC¾ùoà£37ÇG/¿œ$‰ç•ÇÊÞ†•ú€;8Wês%¸GŠ:“ð#r0Z+®øØÇB6Tsss\ré%ƒRÞ@g­ComÍÊ÷üù¹çb+ƒV}wH?o#п—ÃçX–%W^y%[ßÊý³ÿZßÏÂ8[³ûë~HÿÞ÷ï÷B’+{+¦Ù_úJ{¨=m ¨/ ¾†þ\Ç8ö;¸°Ç,d±úùžL³öÐöX iF gZßüÆ7¹á†8ðÀù“?ýî_}?KXÊK_úRþîïþŽ×¾öµlÛ¶ë®»Ž7¾ñ|þóŸ§×ëñŸÞÿŸH)7Þx#÷ß?gžy&I’pí·®%ïv9óÌ3Y³f Ë—/çá‡7ð²—½ŒÇ·>Î׿þuŽ<òH~ó7s Õ%…äÎ;ïä–[ná­¿ùVŽ8òV­ZÅ­·ÞÊ駟αÇ˪{W‘u:Ü{|}öÙ¤iÊÏïßHŸ+V¬`õêûyÑ‹^Äúõë9è ƒèõzüã—¿ÌäÔ$­V ï=kÖ¬á–[ná°Ãã×~í׸oÕ*"¡X}ÿýœqÆ›xâ‰'ؾ};ÙÀòå˹å–[‘ZñÚ×½Üu×]dYÆ©¯:•$MYÂM?¸‰Ó^Q‘¦)ÁÖ­[ùéÝ?åå+_ÎK`nnŽ;+Vð¾p^ë‘GaãÆ¼â¯ Žc¶<¶…õ­ç5¯~ i#å±G£ÓéÐËz{ì±Ü~û¼ü”Shµ[lß¾-[¶ðƒÂ17<²SO=•<Ëét;ô+±ný:Ž<òH}ôQzÝ[·må oxZkxàÖ­}׿îu¼àÀÙ¹k?ùÉO8úØcsü§=ŽqìßR’¦é‚;ó§SJ~¦e±Å2ác/¦ÔÜ™ëpë­·rÕUWq‰'°zõjÙøÓÓÓ¬Y³†£:š©©)^ÿú×sùå—³råJÞô¦7ñ‰+?A¯×ã‹_ü"Ç<?ü0®}åË—ó⿘m[·ñ·û·œuÖY\}õÕ<¾õq>òWáôÓNçG?ú«ï[5!{XÿÐzþþïÿžÓO??úã?bËc[¸òÊ+yõ«_Íǯø8ëÖ­ãúë®ãÖŸÜB3mð?>ÿZ·žO}ò“üÆoü]ôßÙ°a]toyó[øò—¿Ìúõë¹úoþ†4M™`zzšóÏ?ŸãŽ;Žo~ó›Üó¯÷ðƒÀ?|ñ‹tç:\vÉ¥”yRŠ<ÏùЇ>ÌÚ5k¸ýöÛø§/ýwÜ~×~ëZVß·šO\ù‰y–·Þv+'žt"Æ¢(b箜sÎ9<ñÄ\tÑEô²W|ì üqÎ=÷\¦wM²Ž{ï½—O~ò“<ðÀ\vÙelÞ¼™K.½„-máÜsÏ¥ª*οà|®ùú5|ùË_æƒü k×®ácW|Œ¢(øÃ?øC~þóŸsñ‡.æóŸÿ<ßÿþ÷ùö·¿ÍOúSn»õ6<ž«¯¾š,ËøÈG.çúë¯çÆoä;ßù®}+®¸‚¬×ã‚¿8¼—ñGÿÏÿ‹3–óÏ?Ÿ'¶?1—qŒã¹Pë/è •$žÍ&þÓgJ£M\êrM»Ñä ¯{=öÇÂ÷®ÿ3ÓÓt»ÝÁCz½ív˜â›šœbzzšS_ù*NxÙñtfgñÖqì1ÇpÆgP•qÓjµ8è…/äö;ïààåËùñÍ7359ɪ{î¥Ýjñõk®á]¿}ÇwÜ@:þ†nà¬ß>‹ã?ž«?}5?¾ùǼûÝïæ„Nàïxk׬e×ô.Þõîw³ò¯`ë¶mÜy×]üÞïý'¼ìx®øèGY½ê>=ôîúÙOYºl·ÝqwÿônÞýîwñîw¿‹4MY25Åyü Ûß Î³ã‰'Èz=ÞõîwñÎß~'s‡~8Î{ŽzÉÑl~ìQŽ>æ%œtòÉÜ~ûídyÆìÜ,Yæ9Õ IDAT+_±’÷¾÷½ƒ÷ùÿoï¼ã«(óýÿž™SrNzH(„$Z( 7z¥¨‹»ŠŠ¬?wDÀŠJUJ`‘"‚ëêµ]”b¡ºVºWšÔÐ[HHo§L»Ì™É$DïÝ»÷u¾¼x¥œ3ó<óLÎó™où|¾¢ ’ŸŸO\\²,#Š"ëÖ­£_¿~dff’‘‘ÁÎ;),*¤aƼøÂ‹DÇD[U\ß~û-£GfäÈ‘Ü3p k¿ü’§žzŠÁLjÓTΟ;Oýúõ?~Ÿ¥p-JÆøN§“ÈÈH~þùgrssñTÍR¸6A·K—.œ?ŸËí·ßÆwß}‡,ËŒ=šÛo¿n¸òòr¤É“'O¼Ãö¯h¹gO#8\¿î 5@£&M¯éÜ—~_n}_¯`#Y=³ðz½5BSö0Ù•$]êêQ_—æØåäükŸÏî-Õîf©ÞˆnìÞ¤úõ¹gà@§¤Ð&½ mÒÛеkWzõêE||<¸#ÜôëÛ˜¨(’’’}ûàpžKzz:‡â£>bøC‘™™ÉÉ“'Y¹j%÷ÝwÍš5£²¢’´Viø}~bbbHLL¤¤¤„´´4ä LZë4JKKiÑ¢…1'2339rä?þø#7Þp×µ¹Ž²²2Úµk•s½zö¢´´”+Vп:uêD›ëÚðþïÓ°aCn»í¶0C?lÿºö…¡Ÿ~tÓ_›nå)jÄ•<’ºÀår^ϯ•…©=¶ÕÎV3B]ÆØ*†J² ƒÙKœEQ4ÊiCÇ‹æ¹Äjé~;BD4Ý]ަéH¢ˆªk¶Öö9B¨KbèÉÚ,®‹«!…dkÅ! (6¯NÓ4d9hC’$TYÁåpVŸK×$É…$^¬ç[[b³(ÂôL7¯;??Ÿ5kÖðÐCUçbj‘ÍsØ• Ìs©ŠŠ(‰¨ŠbôÂ1¯MU‘DÉ`ú׺§’(…Ä-5ZI›cȲl+Hš—Æu×l£ º®Õ ©ÚÛ!‡K‘ökl&?¤.¸ZYÚ=èk{2Wû{ì?_î8Éá0¸+¢€CªÞpQ@ÔE T,éÑðxtÝP6¯Ë Ó˜óµ'!Uˈ:º èR¹ÖöÎI¸„÷b—w±6OE1€Ë!!kRs½u"j„%§Y³§Ž 2-öÙ^ag^Ÿ,Ë–þ–ùó˜z tèÐE‘m€T½.š ÈÍM\’$TU1ÖPW‘Ñ dM𱯃5w]C”Ä%æk&ߺsm­¶Ò:BL%IBUtD‡ñ ª*„òaažKØÂvÍM×ʬ«iV—ôHíÜË?2Q[‹Ë>–}“ýß0I/Kò¼\þÈ*ûëf²ÜØ&Wæ×Zí볟£.²¨9Vm¯F’$ë^effZ9(sƒ7¯Ñ‰šÞ‡8šuó@MðºÜ}0ç\ûõÚ7µ¯ÅJûqöÈæ|̹„úa Û56§ËPóµWgÕxò¿‰ò9ŽZ¡ «Ù,IcË>Q ¶¸­Ç}]"•5¼(!´Ùë5+ÜL"!:5¤GÌÞí{÷ìeëÖ­ÕÒ+6v{]‚‰v°1ÖB½`Ìõ¬KIJöšÉ²L0¬Þ¤…šÇÕnCP»ÊNQ6n؈(ŠL:•’’4MCQdY6î³^sl—Óe1ïk÷õѵ‚ƒn¨=ÿç~Lqq1~øaHÞF«÷Ð?s=-EеÙAÈ<ÆôšÍ¿?ŸÏÇîÝ»­×uÝP»ž3g‡ÃâÙC~ÖXZõZ†Á%la»Æáv£„µŸÂ¯Ä{¹œ^Õÿ¶ÕØø5@0À×ß|Í~Àºõë Ñu8À[Kߢ° Ðê¿oï>V¯YßïgãÆ\,@×uü~?ß}÷G!(‘e™üü|~üñGΟ?,Ëlß¾œœ4MãüùóìÛ·ÏØôµNTU•“'OräðË{¹XpMÓ¨(¯°¸8æµÈ²LÁÅöÿ¼ßØÀýΜ9ƒ$I”••QVV†¦iÉ9ÂÙ³g\„$QZZÊéÓ§-)Q)+-³H¤~ŸŸ¿ýwä Ì AƒŒ]¡ñL“9Ô8L6$sT…  µ:–C¡¯dŒfT»)ª‚”9>¿ßO^^žQ¾¬À%`”`ƒÑR×ôàa†²jƒ£$IV ¹®5¿ùú›K¼Ò³gÏZa³ŠŠ «|Y@Àïó ­œ„Ãba Û57ŸÏW#”q%¹ô+u‘ü-}].—s©ýµF>D’˜9c&ãÆcÓW›HªWQùøã¹õÖ[™øÌ3,^¼˜Þÿ€ø„xÊËÊY»v-]ºtáÃ>bÙ²·˜1m:õê%°rÅ'ÜsÏ=4nܘ±cÇÒ»wo¶oß΢E‹8yüUU•ÜØõ^~ùeÚ¦§ó·åeîüyè€&zV¦­[·ŽÕ«V‘OË–-1bÏN˜È’%Kغy š¦rûí·£al¢;¶nãíåo“š’ÂÚÈ/5jOŽ~‚7ÞXÀØqãxéÅùáðaÖ®[‡ôï­Zµä•W^¡eË–$$$ðÄO0tÈâããñûý <˜‚ÂÎ>þ={X¹r%O?ý4ßû-ÿ¹b‘^/÷ß?mÛ¶å±ñO㉌¤ÊçcÚ´©ìÙ³—>øÇCÆ yúé§Ù¼y K/!""‚I“&j0ˆÛáÄ!ˆHL}åU ‹pºœÌ˜>ƒeËÞbßî=”——Ó&=³gÎ":D^Ÿ5‹C‡1wî\DIdØÐatíÖ•±OEÓ4ª|UÌz}Ÿ­^ÍÎ;9>`-ÓZY4²,# "Ï?÷••TUV2{ölvïÞÍÒ¥KñûýŒ5Šž7÷6¼ÜðG;la»¶ær¹/ñJþìr’ÿªªÒ¦MúôíÃCä¿~ü/~ܹ“¦©MQe…˜èhN?ަª<üÐpúöéCf§N<4ì!JŠK8yò$í3Úq[ÿþ¬Z¹tŒë¯ç©'Ÿ¤]Fùyy\׺5ýûõ§ª²¯ÇCŸ[û0tȃFåY-IzQùlÍgÌzíu¦M™ÊŽíÛñû|ÄÅÆâr:‘D—Ói‰VJ¢È§Ÿ| ûîãî?ü ¹P…çéqãÈêÞƒô6møàý˜óú,^ž<™Øèh>Y±‚qcÇ2fôhŽ;ޝª MU™:e 3¦Ogí—_ÒïÖ¾4iܘÝ»£È2’(²níZ.XÀÌ3X½j.§“† ’MVVÇŽGUUî¸ãæÏŸOaa!k×®eÉâżÌ3‡ÈP9}Øs [ØþYBcW½Ñ×eWj0öKV[Ëì—Ô‡E1T¤j–’³,ˤ¤¤àñzèÛ·/III¹PÓ4""<[ÜH®á—ÊÊJzöìe½×étZ`Ïç£C‡<øàƒ|úÉ'äçå³ü·ÑT]4úÈ›ó+-+Ãív#9$"""ðûüÁêü‹ÕÏÞ UVV²g÷n84mÚUUÉÈÈÀçóѵ[W‚Á R¨¥Ëíâ†oà“O?aÓ¦¯P…úõ“ÈÈ(c\Q"X$GEV¬ð– Vц9—˜˜TUÅãñXké´¾ƒœ9s†§Ÿ~—ËÅu×]*i–¬ÜñãÇÙ¾};?ý´ ]×IMMÅétÒ0¹:: ‰ ãÞeTõ>}Š'ŸzÇc•¾×¯_]׉‹‹# £SZZjüØBgº¦ST\LNN£… ÜzkþøÇ?òæ›o2räH~øaº`¨„=—°…í[ à·ªp®Äg© —cåÿV`¹Ü¹k#Ë2dÏÞ=¬ZµŠÌÌLÚ·ïÀþýûIMMåÓOW¢ªªÕF@’ @QT£š*6.AèySOÚ¶mËáÇ °µ°—ìnß¾mÛ¶1þ™ñ8gÏž±ýfKåÔ”öïßOîyƒY,ÉËËãСCÖ&. Æ:7nܘnݺqÿý÷sðàA¼/ .bРA,Xðº®ãõzÉ9šÃ‘#G˜:uMš4!3³ãÆÅï ÅÅE”–”rêÔ)bbbB v£äWUUÜn7‚ PQQAQQ‘Uf 0+­"<»]nRSS™={&L ~R}+!àñxHIIáæÞ7óÆ‚78p 4°rC’ÃËíFdÙX«V­Z1oÞ<ÞXðmÚ´Á!9 Õ‡Q éDÓ4œNg6 Á`o¤7DxmÉâE‹4h5dýúõ ¼{ óæÍã믿±šæ„=—°…훪j5’½¿Ås©ëýÿ›!6û¹\NÍš5ãÀôìÙ“ÿÖUQñù}¬]»–GG=JRý$n¿ã\n7MRšàŽôЫW/œN'&LdÙÛËq¹\<þøãø|>:v숪i´¾î:bbcéÒµ+s³³yéÅÙ²u+S§M£O¿¾x¼^Þùë; >œ”ädknO<ùó³ç¡* S¦NÅérqçïÏ´éÓiÚ´)±qqh袄¢ªŒ3šùÙá³Ï?çþÁƒÈ/¸HJj ÷ „¢ªìÚ½›ç_xåË—5j‡ƒììlV¯YÀ¿#2*’F“™6c:ªª2qâ$§DYy›¾úŠ”ÔTt`È™8éYbb¢9r$:QÑQ–Gcziáá¹\.$‡Ä]wÝÅ“cŸB’D^|áEdYÆåŽ@VUQ¤k·n|ûÝw<ôðp5jÄäɓٶ};* h’Ó¬*¸<ÖzLzv~€aÆ¡¡Ó$%w„Ñ!ÇÆMéÙ«é× iРi­ÓˆOˆgä¨G‰‰‰á¥—^"¡^=ædÏEQF=öXu]˜¡¶Uû¿ÂÐO;ô Ó_›FBBÂU{!W«lü[A¦®³Ü4 2nì8-^tI ²ö2yöj·Úó2½óu“GaêaÕfÛ«äÞ{ï=î¼óNbbbj”l×hjF5gÜ‹ù;{‰®©þ\WY²¥2`ûj¨¡]×1bK–,±€B‘•ùÓè}i®‡Ý°_{’sKXõ&S×ôjò£ ¢£‡*Î+l¥jF5—Yê,‚å1šŒ}K$U0¸9è 9$‹‰ožÏ¸Þšeåæü£ß²E‘eíªÚá-*la»¶&J"çªBV¿Æs±·òý-Ç_ xõè%œs£³ûê’_±sNì›-dR;hµdYÌãï»ï>+?c߈Í÷Úyæ†ér¹¬ßÕ–S±îE-Œ=gbŸ§¬(ˆ!Èú·,ÅèÇ¢ªª±i« ‚& IÕÌyEQp:œÕ½–mã™k!†Ê}“¶ƒÅ)ÑÕK»{ Õ糄 Uƒ‰]%Àbí‹F~Çép jju36»ÊCL̹›ï3Ï%Š"¨Ô Œ†Á%laû'0sS¾Zåj€¨®¶´—µü5€åv»iÛ¶­µ9Úç`gïÛår•pµ‰ æZÔèqo>‹Õ’(&PØÛ[jõiçr˜`hßMž†ŸaW¸œh¨1?c®C‡ ½äÞ9‚Á ˜VI×,É|ûõ™´I¶4Ïaš½ÍrícíkgÎÕ^; [ *İúõ„"ìºpÕ*uÿ­˜ãèº^ ª¡µ·¤nÂë°…íÚšB²oh—“&±ËßÛÍ$:þI“ˉýœÿÓèùo‘†1Ç|çw(.*®öó¼ýöÛ—mY`nÄ›6nâìÙ³u‚Ü‚¿,¨±™_iE! ¢( §OŸfËæ-5rf¦ç`‚†éùÔ5®ÙUò³Ï>£¬¬¬FU™yìå®Ù®âpY¯8$?cop!ï7l´îm^~šª!ÙúÄ\µ×-ÖÔ’³¯Y\¶km¡RÞººDÖfè×¥Vl¾ÿ—x2uåQêzO]ªÖkš† éè²BA^>…ù0Xé>Ÿ€Ò’M§²´ AÕPAªªªeŸÏ‡Ïç3*½4½†´‹ j)RQñ•W ©*šªqâÄ ÊÊË 6EEÔAÔt¤Ð· |ÿý÷hª† ¢* Á@UV¬~1‡"??ß’„ñû*½ ¤õu­ øÕhš†ª¨ÈÁ %qcª—è (¿}»÷ aˆYúªëF¡† ªf#°ºT ÈËË#.6®†G`߬eY®Ðvub{Yí1‚Á !¯£ë+¨Ö®£Uóæ¨Š‘?›>}º•O“DG¨¼[@×@ Ê8T ]VP㞈‚h(%„IuMC•cýC€‹…-l×[øŸu•üGySu…ÏtŒîŒ>ú(iiiìܹ“W¦LáØ‰ã”””rÿ AŒóK.däÈG™6m*ËÞZFVïžÄÅÇ3wî\âp8ÌŸ?ŸÇG?ÎüùóÙ¶m/äqë­·2iÒ$t$7bÂÄ €Q­ôÞ»ï±cÛ6TUcöìYDGG[ª½É¢*|ùù¬_·Ž²Ò2ùÓ#ôìÙÓš{0hHœ;~Œììl‚A™wßÍ-ÿ~ kÖ|Fß¾}Ca"UVxþ¹ç).)Æír1oÁ_mb“Öoà‹Ï>'1± 4@×tæ/˜ÇáǹñÆyàX³f 'NœàÐÁC 6Œ.]º°üíåœ;w¯×˨Q£ˆŒŒdõêÕìÝ»—Í[6Ó­[7+¤¥( »wíæÝwßå†o`È!ìØ¾ƒeË–‘’’“O=ÉáÇٺu+?ÿü3:e’——Gqq'NäàÁƒlݺ•œœþxÿ`z÷ìINNàÄñã<ùô8~øáN?Á–-[hÖ¼ ß0:eŽ3¯×ËÒÅ‹Éͽ@LL 'NÀ/˼>kEE… :”N;2?{999ôïߟ?üáÕ^Lø£¶°]û¼®äûÿ/°¹Ü8uæl9(óç?ä‘Gá¶þ·qààä LLL´ÑN×á &&†qãÆ²páB*«*éÛ· .dáÂ…L™:…ªª*ÐÁï÷PYY‰”YµjwÜqK–,¦ª²’óçÏSYQItt4«×¬á•—_aàÀ”””XÞ@ @EöíÝË_æÏgÆôélÚ¸ÑÚè$É 8FEE±hÑ"&N˜ÈÂ7Þ`É›Kðx<”•–"‰’ §Nœ$3³Ë—-£AƒœƒáÆCrr#$QD mv>ŸMÓ8~ü8M›6EQ¼^¯Qþì2º[šè’ܨïþ|€¡C¤²² 1Ô·ÅétrîÜ9’’ê#IÍ›7'??ŸC‡ñûwÈÈÈ   €ªª*š7oNTT‡ä 99ÙúYQNœ8Ann®Õ®øÜ¹sÄÆÆZ]*[µj…Ëåbü3ã9|è0mÛ¶%""‚víÚ±}ûvZ´hAë´ÖDDD””Dbb"QQQ(²¡Àܹsg\.Mš4áÂ… äææ2gÎ\TU¡2àGÓ4ü>?EÅEäææ2{öl‚Á …E…ƒAêׯÛí&¡^ûöíã±ÇÇáfÊ”)Ì~íuN?ÁاÆrîÜ9rŽ!¹iŠáM†?Ùa ÛµÆÉ!ÕÉIùGNíÜÊå$`êò`çäмUKÆÏüùó ƒ8òóó)+-£´¬ EUùàãéÒ­+ï¾ÿtï™Ebb" .RUU…ÏçCƒÅŸ@£ ¸±k7n¾åfV¬^I£äFF_ÉA^~ïðKÞ|“Mÿ;÷Þ{¯*’$Q^VΗ_|Á»ï¼Ã‘#GX¹r%¨z(>áŽÀåtQ?!‘‚ yÄÅÅ!Wù‘Ѫì2¯õ³/>§}‡ö¼üê+¼úê+`« ‹ŠŠ¢ °EÓ(.-ÅévÓ¨qcrssIKKãüùó4kÖÌ B†ªÔ*++QT¥F™¯!µïä±Ç£QÆìüq' 4°*ü^/>Ÿ‡ÃÁ7_ƒä(..Fªªªˆ5Bh–°¤YZlžÃï÷R7U•x##i’šÊ”iS üýÛo¬÷{½^’““™üòddYfÇŽˆ Ñ!¡h*¢Ã¢ª$$ÔãBÞ’’’˜7o ±q<ôðp:wîÂ7_Múõ×[¹¡0¸„-l×:,v™Ê¤¤§rµäÌÚ}Kt]çºô6,{{9üéO4kÞŒò²rúõïÇøñãùþûïINN¦°¤˜ï7ofÉ’%(ÚR6¬ßÀ„g&0fÌ"##-@hÖ´<ò.§‹;ûßÎ€ß `̘Ѭ\µ’r_ÈÈH4]ãܹó<1ö)Μ>ÃÌ×f¢êFI]7úDDDPQYÉäW^&??Ÿ¸¸8tA@ µS®òU0äÿ=À„ñÏàp8èÛ§ª¬\Ò¦iË,\¸Ýû÷… Ê-@ˆ‹‹#.6ŽgŸŽÜÜ\úõëGÏž=™ð̶nÙʹóçøóŸÿÌ_|,Ëx<ëØŠŠ DA´š—uïÑ™3fÙ9“ƒòê+¯Z¥Ð©©©\¸p¥K—²gÏf̘ÁêÕ«Y¼x ‡bèС6ïK³­¢¢œØØXbbbXöÖ2víÚ…+€õ6`ÖœÙTVV’––†Óáäèѣ؀ԔTf2l›4—IDATLŸAiY)mÛ¶%5%A’@ñüTú}Üu÷]Ì™=‡úõëãp:èÛ¿?Ï>û,=zô`ûCÍÚ*8 3ôÃö¯jÿWúéG'1{îl\n×5Ã~É ùµa°Ú”uy)uIÐ3}™ä<‡ÃaU.éš^C+ B휃2`À©Ìž¦j””–‡®a§€ßOqq1 I‰‚HEeÑÑÑ\Ƚ€Çë!66ÀšGaA! (²L~î%7¢¼¼œ¸øx à.))ÁáÁítR\\Œßï'!>Éé ¨¤„¤¤¤j@EàbAŠ,ƒ O÷æSy àü¹óÄÆÅ¢( ñññTVVrìØ1ÒÓÓq9]s¸˜‘FÉÈËË#))ɆŒ‹‹ãܹ³œçu\.—•Ì­«q˜½Lµ®í¯ ¡Õ`WÃq0ùöcM^†ýg»¥EªT5|>ÙÙÙL˜8¡F¹­ ÕbÌë5Èì—½{ßz4£¬ÙÜ A©'Û¬ ÔÆ”DÑê6iŽm í¥½v.’é]˜ÿíNQ/~4ÐN.5¾¯~͸·\"ec‚¹]RÇ$ƒV{˜Z­ ?·Þz‹6mÚ••UãÂ~oÌ{fo"Vó¼—–ÁÛ µ ©vûo²,O¢y‹IEND®B`‚paperwork-2.2.2/doc/flatpak_saned_2.png000066400000000000000000001441211456262201400200240ustar00rootroot00000000000000‰PNG  IHDR3G~»d‡zTXtRaw profile type exifxÚ­ši–#¹ „ÿó>7Äq¸¾çøøþ™R-]ÓÓžçÖ”¤Êb‚$–ˆsÜþÏ¿ûÿróÍe©­h)žY³ÆÎ—æï÷gðùzý‹ÏÕ/×]JÏ×Ègâ3Ý(ûþ ëòqCÍÏõñõº«ó™¦=†Â—y}²™íû3®=†R¼¯‡çw§Ï}=ÚÎóçcö1þý÷\qÆì¥èâN!yޛ͒îŸÎO½Þ‹ âÕ“¤v½ÇŸ}çÞ_¿9Oõ½Å/¾óý‘¾ºÂùò (ß|ô\òíúË yèóŠ‚GíËFÿæ»sV;gß»ë¹à©âžM½\x}càÀ•麭ðªüßëõR^-N"¶ˆæà5]Ðñö 9¬Ðà ûúœa²Äw¬|Æ8cº®µT£ÆIBÊö 'Ö¤i9bÓ$j‰Ëñ½–pÍ«×|34f^‘1`,\qüör?]ü'¯·¡s,uqp»BîGË–a‘³wFpŸÊåßëåüר¼›ˆ \nnl°ûq›>r+]qNŒŸ¿K#ÔõÀEÌ-,&$"àKHJð5Æ~lħ³ò˜rD ˆÄÜ!6‰J¨±E››{j¸ÆF‰÷e …@H*”M#B`å,äOÍê’$;)R¥‰J/©ä"¥”Z £zM5W©¥ÖÚªÖÞRËMZiµµ¦­kÔ„‰­N›ªöΤÓ»;#zq¤‘‡Œ2êhCGŸ¤ÏÌSf™u¶©³¯¸Ò¢üWYÕ­¶tõ6©´ó–]vÝmëî‡\;éä#§œzÚÑÓßQ{¢ú5já[ä~µðDÍ"–¯qõ#j\®õe"œˆÅŒˆÅˆxµÐÑbæ[È9Zä,f^#E!‘¨±à¬`#‚y‡('¼c÷¹ßÆÍIþŸâÿ*rÎB÷ÿˆœ³Ð=‘û5n?Dmõ‹Qn³*4Ÿút¶#s¨6 C«±ÞMqÍfba Ñ)š[3ŸÑë*}jÙì~Z%¸wug×ëÔt¨ë´$é:R.EeÖ’sÚ²&p$ŸUÚu«ÝÙ¹“”6Ý Õ—Ù˪„û.vpß×Ë\A{Üá“ìA®ß²»Fʧ‘¸ömñãkÚÁPÁÛ­òš(_ \Z“»7â7cñÃØû«D•Aº ­Á-Ëã(?»akþ:i-™µ&ÊwRË—IúøBÌ ã–öx¦pýåÍ`ÞL¶=wžõõQ”™êJÓË>ä8iBˆ<ËH§µH®ìyy4„BœÏÑÝȈu¯Ù=A“H4Ÿq,û à>ñZcbÁ®-JŒ÷že¹êÏÈÍªåš  {Võt©¯5·)ëý‹ž·ós%éÙÚ³ÀXÖè¶Ün¿} RN,}¼’&_¾)PÒ$)@> @EDì1g«{î’–Žq*?Ig¥¾V*gIÏ €G(æÑv^i´> ;jdO9ž<[tÓ ;Dp¥žR™ö•á\’îûœ=t¦±ë#Î5i3QUË<•Yqd_”®M"S‰@X_%ϲ’t6MXw‹`DÂ̓-^ÎÀ~uDê0U|JB®9w™‚Eê•rN!ÚW ILóñcð\6®§²4?×!Kô®Dûã"xõ±qmó¶²b AË.¿Nï®ùÛ+Ø {2Ûó)ÕŸæmâ¶qmÀ}ìµ÷}þôÕìàç 0µ{¯ÿ¯Wÿž·ýºý÷ÒÝ{íïYÿ™óÝwïÿSç»ñÓüÿÀùî»÷ëü>XT‡T|´b¥k{)Û lÙZèTGÆ,#fݤ¥¥UÇF‹ª7×’#ä7ÅØnÕDù4T­ǹڣ«Â`òJr¡r÷euVƒ‚C¡ÇØÐjíÖv*c‘°ØÇ®RÎBÙ2÷òUãQ R; –®Š\x*Œ¢_rf%Nù”†-Àa[tj…i™5åPâ°7šA¥öŠØ:ž +[Aßû\½Q¼¹ÛL“ß[¥Þ×ôs“G,±€r`ÄÀWŠÇÔ˜UtJÐíÜYm‚´+°ç«‰ؾdÀCEmó_1uš[ßÝoä›Ë[^=¬–™Öà)C:îE8Iñ&”ÔÈ) ݆߰– ȈF>lIàJXû²žó·¿»¿ð§¿»_ÈýýúÄM}ç¦AäAGJAМeDŸß¦4d6Äe½ðˆQ”Æ5*dâëu1f7¨E’5æW½YÖÞu7-Û,÷u5£¨½¨µs]ßd$zЛ°Dš( \äF¦PL%àÌzÈLDaoÌ0öIÉBAYál;V«IÚ;ZHÛ†”¬ $Þäâí•mìk®äÞ‘–pyÚÝ™*‹ØDžò;Eƒt÷]ϧdã6Xƒj,£Ä hË4áLòMµö¶ª£’Ö‰Z,éèøhPX"ÈÄE*‡´¨ô­gÞhjk2¿î<¬éqjÕ‰‚¥C#ÏŒ¹¬Þ6ÍbzÍûLÛUñ/ú=œ¡¾®ì+(#“&p¢X)†ì!D˜wÕs$øa½·uïoûÎ&ÐcI“¾Ïûãvë²c•ù}Íٜ씟¡ ïR<þ$lý2˜<`´$·›,¤®“—«ÛÂÐÜŠ{¤ª¥Á¹ß켬ìHxµNI¾t:“ "×èZ4а?6ñi°6L Ð¥Óžu†Ô :Mr…ÀØ}yȲËÐÞµ/ó‹®0„Õ@Ñ7ÐÇ:ä€R ¹sI…ðÑShUŽûýþKn¬0Éã9|Ò2{£(*ºWqGåVõˆ0Gc†;—"ï[7£<m˜Êúc÷0+˜švëŠÍÑŠÞáˆú²Ïtiá)Úµ\4¢¡½PYÐQ”ΖÁÍÆ—žÁ-™Š¦z ; D‹v"æLž‡R½©ÚF™#/w!–A¤†NPlGÜQOˆÛçñôDÄQÙ9±¦Ã0n4t†C»KöÈeVK5ûV£': 2ÔF’þÖE.t0×Ô­&œ»züO ð“£Â)C²¸ÄUñxšñ’À†Ô¿yþ˜~tÙU6 G-%(!Žç[Dô¿`„†:Ÿ&t7Ó´cBëaaû›gª;kŠ› Ùtºd ¾†qÌñ‘ÆÍyzþ¨wðë2öjŸmüµ…Ç€ûdá‡û_kH²v`{&¸³µ¢&‹|¨Ô0ôE¯«aJžÛÀh3$t”tÍ÷üÖ¦þt-ÂþjÃv Á½­ü¹IKF6 rGÛQ«³+Wáb3oÏû8/í:b¦[ ç—§›<­à:ÉJælZsn@1(P8“Ê@}°{e.Ë àKÚZxíy„‘þˆÜ"£z<~]ŒBwô¹¶/\—åîÝhAgÍNˆt‡EÄJ¥öd ™"k#÷ÖŽtÁÙw—rÓý‘2L|•‹Çý´ÝSÍeeª5 %¤{VKHCHÊüx¤Š¥«;½f)‰®8HÓ`ÆŠRÀ¢’á_sd1J^Ñ QÜ´S\1–iPFø˧ýrÿß|º_þÐ Õ «Mc#}©·•Ì̵ӘžŽ \O«•ˆFQWöT¥·Ï±5éÐ:ú2Ò Ð@CPÍJ÷JÓ¸Yiñ ¼– ø´á£P\Œpn£O…}JyfsUwõ©Æ†;a+dA¡ØÑ{3©4J¹ }¥AEœŽ’¦Ë^Ð{ž”¤†"8OŽMDìK´Kßälƒ[´0ŒìLÌzñÒMì4KûìBÃ~¶æc ômCŒ‚M¨æc"-2JX‘…´ƒåúu(œÁm·!ïûD8ŒIjÉRÀÞ†h‹:À·’!%²a[µÈfcTbŠRˆI ¦yÔ! OÙěּçT;9k§|Ù™¤ÑÅ@3 àä ‹tôùûøa©Y¦óæÔdRü騡¤ÌÓ•N&C5Ñè¶`ÅóãªU7vâA”f¼á,ì+À–âß • ‡ã€L w n(¼ù7h /Zµ‡VÖê¸OÃÁ*Ã%ÒO í¬˜Y"Ô ª˜†&< :»U+]4¿å±jE{]_–pÛ¼©ûϬºÏf?-ö'»¿µên³íóbÇïp gz3Ï{îË  ˆ®ñ+U¤p éP@º…Ïæ¹)¥ÇÙºE CçÉt5EÒ JÈtª#kÎP=¹iÇ¥¤óèC“Àµc‘ :РƯ5šÜȳ*jYÃHœ©úH@5™-èèø·Q'þî«a†j¢ƒ”¼fÎ †¹ÐÅd9 b' öø"Žë9! ݰøÝü¢åYÀ |ÔGÒÐúþÒèbtm0 ›˜›Fù ë”Ò€†âŒHñÈßm@Ÿ÷ q ®SáÞ\3¬Ï­i•=‚6;­·ò-XA2ÑeU5;v†ˆŠ†Â!3*Dòómá‰íVœá òAJ륽ǧÂÄéÕΣ=…f1 ˆô²Ð^ðÏ#|:ýšu‰" Ù¹æ¦Ék/ôBMÅ÷Á®íĶÎh­3þ& †¢£„1h+ýÒÒ¤×'·@J¶Ð ÝgFHôÚè¸ÁcYè-Ÿ <6Ù· @ÎÈAv/ÓÑÐÖ€;ù½ZñÉŠòý>³­CO8Ãõ"þtÅýÉ oWJÍÚ" §Åˆ;iéí2ÌAbÇL(µ¸©lÚŒ€Ï¨ôÅ’„Ô‹¢’ÀF³Ú£V´5“7ÅR%/ë‹B"AüQ²¥ÝïÖ‚>^3v´+ºP s¯Dh\)v24M?Q¸M'šø|ö“„×Nhh2=¢ÈòÊhˆräwA¢¥­(°Ñâç°ìæ’õuW—@Dâ ‹®(ZækoH SÁ]¢¹ÊZ´ðMÁG¢ìU;§½ š-]­°&%‰¹9áÜ—e,Tc±>Šx£æãá>•D`…DzàÊL[o§c,~.úßmãG£L §ƒÔ $¤¨;*@“) ±E*:¶ 7uc«F«üCŒ‘‚MV4ù}‚LË"“b¨&®Øêì†ÜË{Pfz{d r`vê£Ý’öÉlRøäZ‚&òGœ™ÛQ•áZÛ€Zu ×c1cpÂ,!jè*iˆ@++k™PöTåºÎ÷*­UGàºnÂÓ>’"â+É×~έӆiaI5H%µÞã}R¢Ð]p×Ó¨ëƒL!ÆË¿èþxä/Kµ'‹øÄ&Íq´‚BöÄq~ LË éÅž¼Yßök¥fžg¿(.B¨Ï3¬úa¯²^¯eµìÔÎõ‘_¤Ç´–ÝÊ5Ýš5£¿f9!N"’½iCTBMb¯4V¡A— „ÒPú6b˜±µ³[K4±Ír®è¢=jÏšw –Ó#I’=ê×ÿ)b§'3E„¥0Ì‚uð@‹T"Ê£‰ña­½-säQÅRÞ€AîtMvÒYkíà¢#?ѼX°ÞÂ¥juçôSLî[C\Úûèv(m| öš6?fAè’ú÷Ùm*ì´‚&k TÌÀö”VMéµsôû€¾ G îh;èe¬b`7à¸Æ¤Ô„Qò˜@UMà±!ó’)R¸y¢6Ué^¥Ýí™§ÂBÑtÇGûáþ¤ayª>ø !ÏëÑ¢ÚCÛR:ÀFÒ‚ïd‰ª•ë@óIE?X* ¼B4êÀºìñ}ôâÒ'T}0†ƒi½ªõ(¹Ú£Å‘ìÜöÝi0eg;ÒC#ÓúpAiIÛ"ÝÀ ~;öî•S!ÞzÊ´©¬²B÷è:² m’Ãñ¨}#¢m5gÑ7 F…Rƒ¬~­ë8XØ2XŠ9g¡ÏÜë4(âƒbˆ¤bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEä:4ÉxQ˜ IDATxÚìw¼e¸Ÿ·Ìœsî½é$@HHèHobE׎DuÕ±¯«,®½£»êª»¶ÕµìÏ{YØÐ% „"%”P’›{ï93ó–ßSÎÌÜsCUƒyŸÏç$÷´93ó–o_ñÇ6xï=%Þ{„Õÿåku„8çªÏ•)eõïÇ xßðÅ_pÞ>ÿ®Ï?ã½Ç9WKI‰§üAï=RŠâÞ;¤È¿#ŠÏ{@–çL~>Õ{Þƒ ¸†Çª.ºþ[Íß-ïUy_Ê{ …ÀyàœÞ—ê^ êœoÜ×z[äOEã7×Lþ™öyå¿7¼J_{žŸ§(¾Óü~ý:òöqH¡ðØê~9?<Ïê>‰á/ _œŸRà=®¸ãp€ç‡íQþ¾à…ïpÞ£¤Â{W]½õ«þW¼Voƒz›øZߣö:Þç}O€’*?fq<ʾë=ˆaÛ ;ƒ,ïtþùV›U¿UÞÃò»í߯#…†÷¡¼ á}c¬x<®hM!®º/þì[_H!òöiõÿül‡ý³Þ¤µ+/jw¿8¦–8cб“÷iï|Ñ®Ì>nk.5Žëí8<Ÿü5ëÞSÌT㣼Nk]õýzÛ×{Øïgÿî¨sT¸áoIQÜ3Y]›s®Ö/}mì‰jN¡8—|L£¨ìûEKH)Šy¢9ñxïQJb­EJ‰ó!eÞþÅ9ál~~¾ìO͹\J9ì÷Å9Wã·>Õ÷VI•ÏßÕ<#«9¡~}åo¸ÚgëÏëmPo“Qç‘_§j|·¼æv(“JUs7¾œÏŠ>"E5ÎgïóŽ[œ££9ç—Ÿ)¯»ñûUß)®Ý Ç~)ÊÏESù}9kž/¯³9Ÿ—×_×ê¹hÈàaÿ!‹y&?OØúu\}Ýõ¾~Qõ tÔà¥( ¹ï±®¢.àfw¦ªCk”ëÎÚaç¡x´¿_ž·”cLÕ‰„”UÃÖ?[¿Yåwmñ›£”r‹êò‰º>¸fß|fýVý÷êÊD® ¸ïù¢-@©æo(¥Zíиݳ:Mûœ†¿%ŠþïGÄá5€Ö‚,ËÐZWÇ.;zùûÃIEÔ”-ªÉ¤€õ6l†r#gÝÇú=¯O åñæRR‡ç郻°Þ¹\@ú潓2Ÿ@êmèœÇ¸ÞÊûQö‡²OÕZЉsnV[VíçÊBD,¾êƒåµ7ÆBywk÷ª<ï}C¨ßW)üÈßoj¼å´Ó¬JI~VûàüH…LÊ\m¡P3ï1 N uç¸æä\í¾>j^uÍí¾£% ¡&¥'f ÂR|4…’­¹2ïè¢! êB>ïíy£ì'Î9y±Å¼ë_(ì…Ò, ÏlaÓ8§B8UJy﬩4´•ëz_.?kGÌá£úV[¦”c¡>–럩·µÇWÂmx} …jÍŸ/Ŭß%ã\¡ø‹Y†”hŒÕ¹¨·]ù{²6'æs‘ªæó¶rV'sÉçlnà–F¦mÊÖáwryZw…~4lúP?ÀÖëÜÐ «]X{`·­øºÅ,E¡ÅZ‹(µ|ŽI¿îYȵë¡w¡Ôº¬µy#Õ-±â<]Ý#ÑjÜúäQ×d£1ê–´¬Î˵—s®²ËI]Ô´CZAeQÔ«eaÖ½ £eéU© ‡úwsh¥ªÎáýlͼíÑÈÛÂϳ¦qT¶&„ý©u¯«ß©YF¢¥U—÷´ìSM¡3´J/ÓðÜ ¹õùz¿s>÷PˆZçBVÖDcÐ{‡Ö²!Äëš²Ñ×ÊûV{m”EVŸtÚ}€â|•Ï…?"/•¢Sëó£ÆëHAל`òcÙY TûXÈG}KÙn¶¢[xvÚc¾­Ü¶Ó¶ÂÖwB抷Êû“ÃçmïiŽÙb¬UÖkí•ý­œÈ˾U¶Sý3Õë”lÞßüóïZ÷¼°!G)>\»?mE°ü¿®`·çA_xŸ¼,^þ¦Íy¬m ·ûX[h—†]}ÞiYõ~_ŸGÉYÊZ1.šŸAyÏ Y©<Ïa]‹šÏe´%]ô¡Â=-Ú>šV?BŒTÊq$Šñ£”ªÚº.ðÛsz{Ì8g WMá@Ì2Br9=œ+Y$ŽšøÇ6øÆäv'Z9‰R™º¦gŒ~ǵ³YIñ~9™ŽR†“Iî®”BV–x£‹ZuÊ–³ÍËšƒÞ h»zÚ.×zH¨ +5&<çÖa®ˆ™†KrÔø/Çj9,†Þ›Z8¡îA´>7Zñn[•s¹—}ár÷Åx1Öæîx?THëã­vóíÀEq>ƘjÎð£Â–åg½e9;d¥Ì‹¢¥w•;¸dr”G%?ŸRH´½[³Ts@!åÐ#ä¤@W!U_ÝûQÍÊ%]W°ja,omn’ˆ‘»®°”FW[%Of[¨#<­³Bœ²¡\ÌRÊ~^„žœw†s½R¹âèe=ÄYžŸlÆtëófÑŸê^¼zè¨m´”áÍJɪæÒ¡B[)VżZwû‹–Â\WÒg+Bç,U@Îù‘ ui¤´+jaÔ2 =gY'5^oèÊÅRü_NÄåg¬µÍI²eå×…ˆ²Šƒµ'E1ÂÒ©+CEÀñÎaÎÀ,ëfŽã5´´B0 1œ¸ kÞ5_o¸©ŠI¢º¿µ Fú„£ŠïVÞŠÂ:-½ %©G˜ËÂjO´mÍÛ¹¡P¶¥¬¹¥‡Ç´[µ0GõÑštÛ÷¼nuµ­‹¶9ËÊ« ˆ­M,ÕuÖ¼MÒ~s2¤¥¸\ÈÕ&%ï©FZ2ÔòÚJOÛû1ËÛš(¤ºy£C<¥5éG„ºf¹aÝì{$ESy¢æih„†çD¡d”a×°‡|1·…Ð\FÝû1Ê›QY…"·Ž½(ÆyiÑy–¹«÷ûÚ\SwÑ:kóã–“ô`©Ä)áªÜ‚j>¡*ÇŸ÷(Ñì^Ìâ¢ÈÇ`D{·þYy,ÞƒP•[»ô”]Î9-áÝ-}¤ºŸuD‹¦÷®-Œçj³¹B­õ~5Ê€j{‹GyÍê}²qoK£EJœ¦ïTJ‡ÌÇ¿›Ã ×V:Ú¡«rÞ9yŸ{:j×Ræ­ÕáR©F¸ºœ”ÖszƒëáÁJ–J*ë¿.*ï®ÖUè8÷œ5=IU¿ñ=Ê3*‰£~Áõx¾wS ¨òFyï±ÅÄdÚ± ÚdX?vi•ðu ¹rý—¿oº{Û‚c˜Y6ŒÁ6“ZT-ÉÉÏrÏ—îֹܫu—cÛz‘…×AÔ0k® º5hŠ×©ÇÎË{U8õ„–ZÂ]Ý%^÷²Ì¶È}1IÈ¢£0fx¿²lö5×!Î!µ®&èòú¥’€hXúª¦XˆÖ$=ëžUÕloϬ¾‰(#â’µ*Z¡‰ÒžôÃä®Ê’²ˆ#ŠšÇièÚvÕýÍš®ÿ2áoDÛÈ‘I¬r¶E_sOûQá¥Ù9ª %f8Q¹Õ¤&«kV~vâé\nÙÊý\…¢šçåóàt#—c”wkT\ºêK­>‘{·l5™:Ÿå‰¤#”T)|¡ä½¼HBb½'MÓÊEà3²Ý|+¡mØž¥‹97:tazœC ZIkªJ ,ǵó¡¥;E Ù°p󢫆SÞ…„Àaò4ÔR {ù5gÞUÊW{\•cÑ32´P¿VçF4Ïe.%»í‰j+-£úÖ(ÏШÐ(ÏÀ0ÐW¶W™øÛ²âá™lˇºÉÓTh “MY&‹°-Æ•R²JHÕ:Îe©µo•dm-JFõ€,æ±2Á½è,yÛT§”+ÆÆº|^Çc½CÞ¢2 °LÐvÎå ÀÅ\êÏ˸Q9¡—agmáªË3q];©®Ö#´ÅÊ…X !ä. WÉ9Y\\™¼Uwi‹Â)µÞ2K½œ{U+ƒ³îú‚¬ájÊèæñ]-T fUÔ*¨MY†”¹7Â:;ÂRXsù¼1Y6ªZ 3R5ËÒê|g Lz?ô˜”I€ ‘u¶óÈf~„³(YN>¿§YVy(lá’•V5-Bï1µLxësÅP …õ¶rqK•Ç-]}â¢âT‚žÊCaLVeïÏÊ8®ÅíȪ;´ÔëÀ…Õ3ô4ˆÆýwÖÍiÕVZÍýÎnÝ­%8Œu–㦰&ÚIVõë-E á‰)-¾z–w#Ýïí’¼ä,ÛvÏŽJ´¥È1G~Ĭ|Àûzu‚Ç‹—`®ÐÏÖ¼u[S2mRÜŸ*(/©’#ó•â[¯r’#ŒºR1ôàùF5MÃSTʇ¬ö¾ØJ™”Eb˜×ádîáVJ7î‹R á\®´úþpœ‹Ê»=¬©jçÖ¹J±wÎʽÓU^@Í_ö=ªL¦­‘þι\S*´çÖšª$Á–št-9®´VóØŠ)*j嵨nu“ý褤FZ­|%/Ws5ëÖájɆÔÊÆf' _©@Ô]iCAÔÚv1ç¥sy£-\ E·v¢YìñUHûщoƒ"‘[i¢&,ó¾"+ Œ=;ï±Þæncgž9 E•wc¬EÅ:–.ÝFv.(ʼ‘»âmšfiõvI^=ä;W{·‡9óIFPO`»³¤ÀÊ ]åšøFIc9GšÒÛ%<­:ôaR_½ä[4Ëšó<7«DVP«*Žáh™ÏCZ«|n.~ÇCÇx/ñÞTóºW–¹×$fWpÍš—F”VãyÔñü]C0g…J»ht-3³2ýËsªO-¢6ø]¶Ôà âáµÎÀ¡LªúE-Üמ[Eퟲýe¡DqÄÄļʻ¤¤F*IEH—§QQþ.káÚQ9y¾òzŒ(“®ÿÒ)×…íé(= ºžX1Ë-Y‹”±ðJ È2¬s¹ÎÜo_¬I±ÆluÊ @à¯2µJëˆÌzÖ]öæ-X€p¹×)Q…¥®”B(E^R;A± {{çjv¸Íù܃I]Ñ™£œ¿îåÓs¹xšÊ¼¯,;c-6Ëò$‘,# 8èû°ùŽs–@ °=2ð}¤Rì±v5—^q ,ÈßP ¨š·½,­,…{UºWx`¤R8o«Ríº#¨‘+àë•-m—×л©Ûî¦ú¢8õÅ}l‘éï‹çi’29¹…½×®bËäæaVñ,õÀö„³-$;-]Â[¦+Y©¼GÆÑPÐ×’{›‰£b¼ókŠ¡¯•ÖJ€+ó€ YÞ++Çž9«c֚ǵ:ÿ*ÁÏÍ7ßÄXo,ý@ ¶B–¥Ìcjj*_‹Â9¬³ÕâtÊ-_+×m®²›{ì}Í¢oîmS þZÞDs “f)®n¯‘]_¨¡^ëŠZ}ç]á pLOOc‹Ìó@ £B$)Yš+¶d±–D!ê«ßÖªŒÚë*¸úšŠ1«Œ³¾xS;¯ Z ,÷ð#VF+¿\-‘ŒÉpÖ’f)xËÈZ½@ 5Yš‘™ “åå£ÊiœpÕ²Ôe@пޑí9ëU5©>ç¾¥aß^PZõÏZ›/](%I’T%*®XTÀd&w_[ßI1ÀxÖX¬³H#1"_q5*WS-7AsU­©V ðúZÃ`«õsjûoÔ7#ª—ð·1«’Ûu‡5¶ÚþÖ”+ý_6Y–Ç%BÒ w c Ö䛺)=ô¾;Øú\ùºùª‚µ5%|¹¡œ­üp¡°æVñ¥g¡|^W f•67Ìi–R,5hkyåî!ÀxÈ=ìÆæ{Hhëp2ßÝÏ9¯ÞëªXY¶Ïæ ½ ²ØÏûA´þê‚Ôº±åf-ù \ãß—Kþú|tç=&3Üïƒü¶Q+¿´0ôHƒµ¥u^· =öµ}6†º¨–ß¶Ö5ö¡) öQû2ØÂ‹_WôPà»ê«²¿b§¿r+çÖ˜<ÐX²,Ã×6“ ÷žHëj³rÏ9üûµC¾tèL¿ÏÄÄD(Õ ¶ù_ìûP&Ô»¨¨²«ôTcÃ¥úLÍ­\¹L|éU(7>jíÎÙÚª¹ÑT±•’uå~àÕzù?µé²ÌT„³®r;ó?¸ï˜Ü²…·¼û}ì²j-»¬Zç?÷ÅFBOÌd\qÅúj@gÙð¹pÃ7±ÿA‡6v‡ w¥dk¿{ºê­¯</ü“ƒÉòʺúκ®Xj¿¾O¾éž­y™~±ýQ­Иš¼.6ì˲¬z¿|Og&›µÅ©÷>ÿpñÅü„ ÆZ2“‘e¦x^¹ À½´<_üÒ—‰´â¢ Ï«xòdOEU¸ÎC–e<æñǰþòu‘/4ò˜ÇÕ—¯CÁŠ–sÉÅà¼%Š"¨m”eyXOk[ÅvºišV¯•JEð¶gâ8â ÿüVžòß²ë®+AÀ?ú<õ‰gç+îöñr™šïÀ©µFYC±*E^}á(·ø­”Ú–¾yµ@s)ÿúfmÖ»Y’¹4ÚËÍŽd–e˜R g&Í7ô±Æ“LZ”ýYL–¿ç\®¥Xc‡.ƒðð¸Wg›7ofÐOH ã,^¸þ)žü˜¿á¿>ú¯<æ'òŒ§=™¼õ ŽzÈcøÍy?fÁüù¼ÿ­gð ‡>ŽóÏ;‡ó°iÓ¦ÊC·háB’,囟û$oß¿ðïÿˆÃ>¯ÿðǬ»øB~ô“Ÿ±aÃ~·îR>ÿõoó_:“ÝV­Bk&°]“Ã)ÏóæMðÒ×¾ ·oæ§ßú ó{ÖJ|wj5]g‰|„·¡U.•Ê_×Ƙü¹µH9¬Ò+·d. òøÊ/¥,¶c/–°)(¶°Ï·$öµÈ…¾ý曇‹ P&æôÞ®S­˜¤iš$)›7ÝQì¿@ྫྷ]³š_}çËüâWçñ£³ÊÑ'=Ÿ?œý-6Þv;?8çþï¼_óðÃ%Í2æ/˜$Œõ@@§ÛôÆzYíd_Ñññq&&Æ9ò°ƒ¹ìò+¸ôò+8þ˜Ç2oþË—-c0HØoß½ùÛ§<ÿÃéìµÛjÞvÆëX¼xQˆò¶kúý¦§&¤‹æÏãö·0¾òî»ÿwLnÚD¬é`@ÒíE1Z)t¡”B)’!@HUí܇/|²/)Š×¨-Ê'ŠP‚Î-Bˆb¡a²°>êÈ#ó)¢Xq¨L8(“ Œµù¶¿iJ’ä‚0è3$Ø4 ^€@à>BÁÍ·ÜÂ.;ïÌÑ}Ë–.åSŸüQ±dÑBvÙy/ú»çàú‘ÿǪìʯ½‘}èƒ(©xâãË»?øoÜxóFnß4Éé¯>ñ±1Ž{æ3xÞË^Íßñf̟ϱÇËóN}5zç[ˆ´.ä½ M3áÁÇ›&yðGð_ÿýerÌqì´dK,àòõWsìs^ÆsOx"??ï|žù´§ s}íçY³f _ü[: ^ü‚¿cbl%õݾ¶·N!C‡2Öâ¬ÀÖ?^+é⾯æ3ÓS~k @f-Ö˜Ê0Hý>I’rÁrìS ÖA p1 HÒ¼GJÅÄÄxµ(È–-SkR2>>Ž’’™~Ÿ4Mëõˆã˜™™>i–?WZ399ÉâE‹Ø²e Á¼‰ ¦gf°Æ0þ|¦¦§±Æòë ~Ë·¾û=ÞrÆ?V^@Uûý@`»ÅC§Û%ËÒ*ÇL‘wè÷\vÅÕ,[¶Ýn—N·K·Ó¡ÓéEQ^Px”RýþãP‡Ö ¶r—`wöä=ã³^ëõëõ†ÏÇzŒ1|¾háÂâ»ÕqÊÏg™ajjŠ(Џø÷¿g·Õ»21~ Ð4“!I—Ò4ù«¸´{­„@ pÿ¤Ÿ xó»ßÏ/^ÇSvÿôÚWæÛ†[ü©œ E €@ peÞø8ÿà™ùâ!Þ“fYËÀŸTضØ}@ p‹Ò4 7"ØN‘á@ °ýqïsü6çÕ@`›ã¯+ º¤ @ p§ó6ÄÖCEýq ¿.äܲ_°iÓfnݸ1Ü¥@ þʨB‘ÖÕÞ¶ØYèŠ+×sÓÍ·ðøG?ФØL@)…Ö“å«ÿ•«@ ˜›mmã<}ûw°léRÞõþ°Ï^{rÝu׳b§9êÈ#ùÃëIÓ”Ïý÷—8þا±îÒKùõùà¼cǥ˪%JC˜ ­Slé³í(çýú7<ñ GIÉ!È‘‡ÆW¿ñM6mÚÌîkvã–9úa£ßïsÉe—±ûÚµ¬Ým5ƒÁ€ß_²Ž ×ÿ±ò@ Mšf¹í(zþüùÕ^Ácc=:ccc$IRlF ó]żg¯=ö`ݺKùý%—pàþûãgáÂÅD¡ 9¬!¹åæÙ<³yÛQ|Ôó¿êòÛÿ«oG¸ß>û²j×]Ywé¥\zÙeÌŸ7Ÿ¸Ûc—Uk‚ø@ -øÉ«ÿ”VÜxÃuÛÔ¹é /º˜Ã=„4K+!n¬Á9Ç.+VðûKÖñ¿ßÿ{ȃùÖw¿‹RŠoeéÒ¥8k‡u!0pΡ¼*ÔmH9Ù¼éESSÓôz]¼÷ÌôûÈbâ-ÓÓdiŠ’’©©)¦gfH“ç<ÿîwó˜G²Ë굡 ƒ$!KSæÍŸÏo~ñS6nšféÒèv»tº]ºN‡(ŠÐZ£”ª¢ÃÀŸ$Ù^GQ„÷žññ±Jˆ÷º]¬µ8kév:DJ‘¦)qã¼GI’†° [óåõÛ¢—<åÈlø IDATlÀvHP@  @  @  @  @  @  @  @ m//(B€s)‘Þ绺|§À¹@ î b«òTH‰,ùk²’³’¥€¯½z}µ°÷<8ï°ÖáœÅX‹5†,ÍH³ŒA’ko¼åÆ @ pðÞqÛ-×#lŸN'¦ÓéЉcâ8&Š4ªÜ  ¡”ŠÜ×› éÞØxCð>?Ik-Î9Œ1c*Cè „D‰”Š8î„ @à.`¬à…ß[‹êBƒê€î€Œ@)„)s_zéÿ ÀŠ•«‡Ö?ù¶…Þ{¬µXk1Æeiš’$ ƒÁ€¤ð,¾ñæ° ` wt%{wBId¤ºxH…P !ò¿Š0€Ï}÷ùnº.ü›ž€ækM7†¯Â@ î‰å¥;œÃ¢E‹ˆãˆ¸Ø8Š4RIâ(FªÜí/(þ/þǂ\)(væEˆ<‹Ï"—ËBÊêóB€”²0î%yî¿GJŸ+@ þ´(¥xØ#ÇÒ¥Kèözt;< ÛÉ¡´FkUå×U 5€¢2Î¥”•Qž |QêBœs(¥jƼÄ{‡ ? EH¿.¤+ÅÿyE@½`¤7¡ø|]¨+uÂ{Ÿÿ,J¼A@àÏ…,âúR”RHUzD!Ô›eõÿëáùöëmË¿¤þyê"÷ÆPj(@ î­¹÷ËuÚr¶ý¼nå×)¿Rj–g`N~OOü¶ÛnãÜ_ü"¬À=À»|ÍšoúQB»ý^)ôKÁßþ윿í}¾`ùEcLþ¢Ö•æ`ŒAJ‰R ­uu@ç333Eb ;7ûEClJY—¡C7~iÑÏåί{Úa¹^o{äwÜÁ©§žÊ)§œÂ­·ÞŠ”’üãüà?àYÏz×\s ?üáyÅ+^Ák^ó®¼òÊ`õ@ p/RV!€¡pö•rÐŽå—Ê@™ÔWŒ ´?_þf]!ÐoyË[xÛÛÞÆ`0àÕ¯~5Ÿÿü癞žæ‚ .àø‹-brr’3Î8ƒ-[¶ðŽw¼ƒÓO?=´^ ÷ï=Þ¹†Àn(s$õR$FY÷Î9„XkGæH)Ñ^x!/ù˱Öò…/|ÏþódYÆÑGͲeËȲŒ=ö؃³Î:‹Ë/¿ÈC@ î9³{Íúo[úuÅaTX`”€wÎ5„»Z@qÄ|æ3ŸásŸûÞ{²,kÄZËk^óöÜsON;í´F¢A@ p·LÿbÏ®{_å6äl;Þ_>J·WóëoÙëõøþ÷¿Oš¦\|ñÅU`](-þõë×399YýèæÉI‚ À]6û·òÞ¼]Äôë±ÿ¹âÿ¥`«Ç:ýôÓ¹í¶ÛøØÇ>ÆÆñÞsðÁ³dɼ÷t:^ùÊWrá…rÕUWq ' ”bþüùì¸ãòИ@ Ü ÀÜò_JÀh- Ü¬¯îwæ…/óF­à½GGQÄñÇ_½`ŒáxDµ s޵kײråJÒ4¥ßï3 ðÞsÔˆ«%1@ ØŠ/EµÜo/vÖsÞçûù´6ã•0J ×?W ÿ¹J«…€Ú®„¹Ü £â@ î¢À±Õ²=Asï}Ãо+¹weòߨŀû„æ@àÏå`–¡-Õ:@µP]1¸+®Øÿ¨=‚À_€|! –@÷ „lÄúçäwõ½¹B¶@àÏfþ×—Ó÷Îðx@ÌŠõom€QVýý¹<A¸$ ×]wÆ´Öì¼bcccEˆ¤‰@ l]0×3ü·VÊçý½“)²Œ5”Qÿ»ª9”ÕV…åk#ÝÛ9Zk^ùÚ×qÐãŸÌéozx×ÝpJ)ÿÔ§³ñÖ[ÃâI@ °ÝR&ÜϽsï]õ¾s®hÿ_þ=j]€öæA퇾ø7¿,ʇ_tÎc]^h¬ÅC–R“‘$ i’’f)\9â m H!¸úä3Ÿü3ÓSôÆÆHÓœãŠ+Öó“__À¥—]†wžeË–233Ãu×_sŽ•»¬dÁ‚ù\²nó&æ±ej ‹-¦?è33=ƒ”’w^ÁÄÄB®¾æfffX°`!ýþ »¯]Ëää$7lØ€”’=vß}«Zc þâßynØpýÔÇ1DR!ãˆNÜ!Ž#¤T/ˆtnx“'ì )qxÈR´ ^€°!%^ ðäßk ÞƒÖÎzœP(‡Ã¡÷9ð°Vù_—°ÖbÅd†ÌÒ4%MúƒI’$ ›¦’{í‚øëÑë`É’%¼ð%§rìÓŸÊ1},BJ.^·ŽÕ;-ç'?;—yóX±b'žÿâS™é÷‹Naùúÿ|‰WþÃ?295͢ŋyÝË_ÆßþNöÞkO~yÞoxÚÇO=—¬[Ç‹^ö V®\Ɇ 8üƒ9óÝïäÉǟȇ̮¸‚C:ˆ·½é Ò4 ÛÖzÞý¿W²çÒièh”PD2"²’¸ÛE鈴7Ž5%`B¼’x ô3Œô)ˆŒº³9µ¨8"’ a,™1 @w&38 qÔÅ[ÈÆÁß~,E.X‚VJµ‰.V så=J)¤Rùÿµ0A`èjïõ8ÿüóùú7¿ÅÓŸý÷ÐëpÅÏÄ3}:'>ó™¼ô”ï²ÓŽËùñÏÎåªk®å7??‡[6näØgÈù^€VŠ×œv*Ï|Æqxï9òÈ#¸éƹöúxÌ£ŸÄO=?<ûñð‡ò¾w½‹ÿüìgùíEóÍo‡Ìd<ÿägó»K.áäg?›3^ÿºnmŒ¥ÂÛð"ÕaLkf:–;…4Šhz†^§‹õŽLJR%qZ¢Ãj‰u–N¬q2"í'D3¼ï`T–wÂá² ŸA§Óa:5dÞptE¬:¤B‘LO‡2ÀûZ Øoß}xí«^Á —^À#؇óÏ¿ ÚKÁƒsžë®»Ž°Y–1ob‚n§SeƒNŒ“¦)wlÚÄsŸÿ÷œõµo°dñb`ÀM7ÝÂêU«ðÎÒ‰;¤YÆ’… ¤ {칿üÕÿ!EhÚ@ ØÖèg‚¾Ð8‘e‚©ì "51>ž‡ëN0™ˆ1YD6å‘I„‘cH1®G¤æA_ úp‡‚˜˜Aæ1©ÀZéŽÓ×zq¬ Ò-ž™T2åc2Ý À}…‚©©i¾ýÝïrÕUWsà 7pǦÍLÌ›À.ûîÏo/ú›6mâ‡ÎçþóÓ\zÙeüßyçñÓ /aÕª]Ç»í¶Û¸lýz9ø ¬5•‚qÈ!ò…/ÅúõWrùú+°Öò #ä‡ßý6±ŽX¶d/\4@`Û3ÑJÒ5í=6IñÖÐíH´rX;  °ƒ—Z¤VxÞ9¬ÍrY`-ý™ŒÍK·×Ãf2ŽH•'‹òœ‚ÔÓÍ<>IðR z¬ôH]¥ÐBà¾dzfš¯û{<üiÇó¨ãO┾€¿yÄÑ8çøä¿œÉßžv_ýú7Øuו|ë;ßæÏ}!¯ú§7qáÙßa×]vášëo¨¼»­^ÍqO}2Ê üÏW¾ÊžÀ1{«wÙ™G<ùiܼq#ÖZ–/_Æ9çœÃ O{O=áÙü÷ÿ|¥±ms ¶ S1O®žÌ<“Y¤ l‚´)Ú8´(ë$¤”h©‘©C$ƒË HI&<2Ö8!Ðé.àñ±ÂG’¾3˜Ä0ÝŸ!íiÂh/ˆ£aŒñí=œsÕF@Y–aŠ$À$I  ŠDÀ /ü-}äCÙeõÚ Xx¢(j,ôey"žR ­uõZù Ë2¬µt»ÝÆöËqWåB’$AA·×ï~ïû°ÆðŠÓNEk]Ï;Gš…À@ øKÓï÷1Æ0oÞ<þïg?á”ý” qR÷ÆP€TDÝ.‰M ‘ÔÐÇ8‹”g-ãcc$ƒa^@–¦t» ™9¤Ô8 ¦£@JL’ÒívQÞ’˜oqg ¬Ç‹Ä†…€îSçŽ÷yéßÊÝçz^ ø:£Žuõ5×ð‰O†¥Kwà3Ÿÿ">ó½!f/Ûœ”@9·–HvI%$Œ Ô0ÞÕL ‡µ…Dk‰¶ç,*ŽI Y’ Š¯nA2À 1uñTñp™!q™P/B+RŸàþÆ‚ 8üƒI’„ûÀ™<ôÁª<@ ضC¼8çé©ë®#QqÌ-“w0Þ§§"´ìŒçpY¾žlOÇgñ@’¦H›!„ ŽÇ°Îañ¡ñÎa¼ÇËÜàì*5'=ž<!(÷3-\ÈSŸò$ʵ¢ƒðûilé»>^t‹#„¡Ç˜vß'“‰uÄq1e ŽÐ±¢o Þ zÎ"â93CW€UãttDb2¼r,ì“&3dY„d^o‚Ä2%Á%`â8Âx’ï”ËH@àþE,ÁøØ8ÖækîÈ™„ ¯˜§:H©PZcñ0 ¡56µH¥ÐQ„ôÒ4½Û¥?®¹Õ °±D+Åôô4R)ˆñ.©µ¤Þ!;¢ÓÁ+Í µ(Ê@ ø3º Ê Òt@GDZ“jëhRå«ýv´Ž$2å±]1I’¡ðˆt€ˆ"ŒÔ(—çÄQ§J&d)z¼‡‘`µ¬þ6BÑ™XˆèŽãQè‹nºzhMz++¬ÅZ‡5c Y–‘¥)É !MÒ4åªM·„Õæ@ ¸‹¸¸KæIæN+"¯ði†ðž4ÒãéÅ‚H)”—8gé¦!,NIân„%¥£"¼É 1h› ”ÀEa3CwI]FÜíà¼7 ?3×Q¾GÀ¡ç êîdçÖç[ Ö±™ü‘dyb•—qªxFhÑ@ îq-5*±X,rbœ ¯:æçYÿú"¬»ßÏÏÏøÿ>nßûíËÃÕ`ÆК-œµl¸áj¦6o"tý@ °J~”R,Ýq‹wX”€æÍ©ècˆ'&°ZáTŒS‚þ¦iÆ/"Áä›ÅšžUô±8™sDÝØ”4MB2˜œ"RšLZ‰GODãqI†V ¤(6øŸz¤ˆrYïAó’ãàƒ_‚7½>ü%8|?xÅ °q3,žßû5¼íŹàÓ_çòˆ€sù#Ðþ×ÿ‘]vÝÞÞá†í–Û6ÞÌu×\É.«Ö„›Q#KS„Ê=èÖ[„PøXb¼e~·ƒ5J œw€Ç§;&AH<ç-Â9zÝ.S[f€êJ”ð¨H“YG߬–©ÀæI…h‰ÏR|’æ shÞñi¸úFH3øýUðÒgäÏ˵çóÚÿPö·U„l¸ájvÞu7zãAøí›%K—ã½gËäfæÍ_nHA¬!3}´ŠñǘV¸É)ë ”Bbè@X”w$Ý7è#DBä¶· fút”"u„!¶ ‰ÃŒu°Öäʃ‡^á-h­p6á…äí/Äì¹2W´‚AšÇüo›)@ÊüõéAþÿÕB@C€©Í› Â?X¼Ã2ÒdnD ‰ Š"„¥5™ÉP˜(³d8Œ18Yfˆ¢ˆ,ËJa´d <>VøH“áQc1t4 ŸWX‹’ kZë< Y–a­ÁZ‹³×OÐ|ô,ÀæìïŸoülÚX Ï*üýà%ïg<{¼ê_`í.°fg!¶S'ĺ@ n‰0/¶p¬óDR!¥Äyè›=#a^ŒÏÎfÄQ„-:Žéd/<‰±¸XÑ™CÅ„wH!éuÆHnaý{O§Ó!³c2´ÒxïPRžÈ 4¯¼þ9¹Û¿Á™¯ÈÏÒØüµ£‡’ÿ=Há?Þ/œepÉ¥¡5@ ¸k*¨BÄH+‘q«4±™Auc\:`ll‰÷tt‡ÌHºV10¡4‰wXïèÉÖXúSãtI³ç-^”RxçèHÍ KIÓ„xá|Äôç5YQèçðH2“ ÷’ò¹±ùjÆåÂÞØáû¦ØÀÍ.»Š1©%BÒ4Å9 qÕ™€hŒwÈ^ÌÀYT¬I'b"¥éÆðžÞø3É-$ÊC"=F œËÝú2µèb ï=Îy¬Í½üÚ{´õdtŒC‡æ@àÏCE8g±^ ™çÖËI–âe;.á±û.&"æ³?½–LÃXæé÷St$é'ÓHƒþ4ã±<¤)¼“D¬7d™Gêç2ÒØ,ƒ$cÞØ8éÌ4ÂZ¶H–@àσgÊ |2ÀJA–1ÊÀux7æ÷,Ò*”³HíÐ p 2&ChèÛR¹ §nCG)ñ˜fÊ÷aL“áðÞ#•¢§#2“±if ¤¤wб@“õ›Û{Ÿ?œÏëü­knlêÝÀ]ÿ°8N8ú Ý˜·d.IøÕº[Hä;.ì±zù8Ë{ŽDºã]_Ó¥Óëñ‹uwàÒóÈ5 ØaÙHÅ·ÜÁ9¿ÛD$æ“"H˜×‰p™ÇGOÅXë0iF41Nš¥ëHÒÆºÿ¤×VYšðÎá¼/–´dÆ`²Œ4ÍWê÷$É€$I¸pü·Ø°P pÿ›ˆBfvàn"BÙ÷½F)É)O?”5ËÒíÅÌïNð C÷åôŸË£Þ™g>j²N„G°ÛêUìµz“›á'¿:?Ñãô—=žÝâ>‘H¡Hý€'?NrÆ»¾Œè.fÁ‚%lÚ2‰ö)%Æ$tâ.cðZÐÕÖeˆñ.^&èHé¡à=^È|• Ÿ×+âü…óØ49I¦<ÒeHëɤ'Aucœµô:]úÎá#N†$À@`û±úá¶7²ñæ›X³ûÞD0‘î†â8=Åå—\ÄêÝ÷f|b^ðܬµ|çÜkq|çâ_°ß~»Ó1ößk)?úŸËøÃµžVíΪ¥n¼åvþóÐó;¬Úq){¬è1“d|ök¿âªÎ8^ó Þð¼G³j—%ì´ób6lØ’/2d=Κ|™`/È)J©Üõ/‘LÛ Û‰ð÷¤i¦ÛogÏ} M f¦Ã Üe”Öìý€ƒ¸öê+Y½û^A¸‡JøÆcç ‰Ò ¸uÓ;ŽuéŒuѽ :QDæB‹BÙˆ…]Éb³9‹8èÀ=x °Æ"µ¥ï- bÍ6¨˜Ì9:BãD¾ ²“Y:2_ØFY,‰T/(ÀöBš$,ÞaÉ Ÿ¿&ðÀÝÀ9Gšæ–¤+…TèCwŽ;ôTÒ0e –nÜŘŒN''r!Þ‰H,tlJ¼p!™²ŒÅ’Ç?ä`:.ÃyœðÄ^²¸›çî[ëȼÀx‰v§$jL#£ˆ~–ÇÓ[¶à¼ @ °½xœsxâþ{¯„$Ò{<Ip̘>RBš¦H!™é÷éõÆ0.Oº—Râ=ÈHƒw 6Ïà¤?3É¿t!oÛL§Óév0Þ‘Mõ¹ñŽbŒŽ€ioÑ"Œ=Îû=w̺qvÛq ã‹'xó¿žÍTÏCÜ!g2:F ½$‘†y:").ó¤6Ãx€@`;¿· â(â˜cg¬³ìÓ9é„gm—mSÆ×}QÇíÂ:+uƒÏù[¦û %Îy´R@kÍYgÿ–‡°Š]5}ØÞ >ý_óÁ¯žË©O û­YÎ㼩¥#¤æº›ûø$Ct:8kQR •FA2“áµÀ;ët0N"»1½©4()6n¼•eË–’eZkþxíu¬^µ+민’µkÖÊb—[oÛÀ’Å‹ïôx?ùéϸþ† œtÂ3·ú¹/Ÿu‡~8n¸ß]²Ž½àù÷ø~{ÑE¬Üe%K–, zÿ0?†+}nCüð;ßâ€Ãލž¿ò­ïdb¬ÇÊ•+«XóûïOÔòüµGxâSøØ¿œÉÚÝvãE/{9ùÀ™Ûž•âÿ÷Ž¾ÅŽÁ½.ßþþüÀ¦d˜ Ñ%Ëãc‹ùÇ÷ŸÅ#Þƒæk †NwS¾Ë[>ùö^¹„#öÜ^œ2m=ç_t+—oHX°x©á*óx%H¥GkpSÞÒñ]¤Ô¤iFÒ !€¿K—îÀ '?‡KÖ]ÊìÏÆ·ð¦·¿ƒõë׳vÍ®½öZNzî‰wIøD‘¦Û½óºî^¯‡’’u:ê¨{u _ýÆ7yÖ3Ž ÀýÊñÛT ·<—-ÓÓl¸cY»¿{íªÍFÍÍ×sÃõ×¢#](Æ¢‘^·˜ËýçKËYJY}§ýú\Ÿ-9ê3sÑþlûwïÊ98<»î¼©$Ï’%K¶Éx»^ÿ{éæ8¡{®ï ”Ç‹˜î˜†HeЛXÁùW¥¤"#±SxaQ©EEó¹üvÁµÿ·™$¤N¢âˆÎ‚™‡Tæã;ò`2‹”Š{×bnºîÆ(ã&$þEyæqÇqÍ5×pàûóÛ‹.æu¯zïzï{yÌ£Í7ÝÄsþö$®¼ò*>ü±±jוÜzëí¼íÍÿÌÏÏýgŸóc&§¶ð‚ç=­òU'''9òoÿõ –/_À.¿œ}ä£ìµÇî|à?>ÅO¾ýu~öóŸó‡+®àÏ{G>ì‘<æoŽf¬×ã´—¾„õW^ÅY_ûË—îÀøøÏ=ùÙl™šâŒ7¿•µ«W±ñ¶ÛxÞÉ's饗òo|“ÉÉIöÛw_^û†b¿½÷ä›ÿû>óeéÒ¥œðìç°ë®+yÒžÀÏùK÷¨Gq衇pî/~ÉÎù1o<ýõ¡#ü™]Û”L)Îå;_ù2ƒA!å¿…`ýú+Y0k׬aý•Wñ‰Ï|–=Ö¬åÇçžËi§ü=Gv(¯û§7³ï^{pÁEqÆë^ËòåË9åe¯`Õ®+Y¾ãr~ý› xÏÛÞŒsŽw¼÷ýxÀøÞÎæÿ|;¯XÁÃ÷drÔázÐ<á±á-ïy7{¬]ËÔô4Ï{öIh=zº¼êê«ù÷O}†°/RiþîÙ'qìI'sàþ`ÅN;±îÒKY¶t)‹-âÿ}åk|òÃÿʲåËøÇ3ÞÌ>{îÁ¿½ˆ·œqúP‘®·‘ßFûPàß¼éŽd¾Ëèd/$>Šèô¶Ä†‰,•×ð§Ù€´ÓE‰‘t[(Žb€Ñã-ã>#ëí@:ÐAb½ÃY÷8 IDAT‹DÍgÓ¦MÌS=¼sXgq„Š"lf‘ À_’'ó^ÆyÊ“ŸÄu×ß@·Ûaãm·á½ç7\X¹ç_ø’—ðå/~Å‹óÿý_ÎùÉO™?1ÁêÝVsòI'ð‹_þ)%¯xí?ð›ŸœÍøØXõ;ÏÑ‹ùÆW¾Ì¢… Y¹reá1ˆèõz¬]½+Ï>ñDöØ}-Á ^ü~õ³Ÿ ¥äï}/çœ}/xîsxÀ~ûVÎÞ{ïÍŸx ûí»/gõN{É)ì³÷Þœtâ‰|ìß?Îë^ûjV¬XÁûÞõN;ô>û¹Ïs衇pée—ñª—¿,t‚à`ñ¢…,ßqö?ôð9?ûü“ObÍÚÝ:àN:áxNyÑ 8áäçñþÞóö7á½ç!>Šÿü\N8þ8.˜Ï1Oxûìµ'Gv_ûÖ·ÙcíN{é‹ÙyÅŽrðÁüðì³9ùoOb¯=ÖðOÿøDZñÿÙ{ó8»Êúðÿý<ÏYî½³Ïd²/“°%!a «ÙQP”o¬v±­]´µjkkõç¯ÖÝÒ~k«Ôµu«UAq! @¶„ û2Ùf½Ë9çY¾œ¹wf’€b “çýzÝÌäžuι÷|öÏgÛöt´µrÃõ×zqÝ„<¶b%úGÀ¬™Ó1Æ’ê”î®N®yÍUì1üø§·sú©§2}ÆTfÏšÅ#?Æ•—_ÆÇ?šŸïI‹qï˹öš«ÇÝ%ÁË5ãÞk/AVIˆÛ»À:‘—ûÙ(¤I*djI¤!0#–¡Š¨T«¨RJ¹LÑD©Äº4(‘IG&*3¨@’ÖRZ»'1X) • ¡( FÔ’aTÆ ¯¼”H))W* rÜ1yÜÿ’¥²{϶nߎ”’Á¡!öõõÓ9 ˜:e*¿|äÎZrú8!¯¤âÞûîgñÂ…ãÞb¸R¡³£cd½CO€Ž¢!}ýý$IÂn¹k-ÇÍ;€§Ö¬áê«_s«òlà§×®åõ¯¿€ö¶6víÙƒbܹ‹EžXýTîÕØ´™ææfÿ!ð€ú‡¨!PŸûÑ9zþÎ9œ±c™6mÎ:¾ó_ßcϾýXchooÍV7gq²ãÙgiokcÃÆM´´¶HÅé§ Äjƒ‚9³f1{öÞöÎwqÍå—rõ«¯:ä¹9çxÕÒ¥|í?¿Áæ­Û¸ñ†ë9ëÌ%Æ:¬±´57S.—qÆÑÞÚÊ@ß~pðŸßø6ƒÃà 1·§g¼Õï^†÷ÊËÿÃrñ:Š%œ6(R+W b‡Š ÔRM„H!ÈÒ”ææ’,—QˆcDMƒÎ…vJ† Bœ±0\Ë•kÐÖQ(¨UkÄA€ #2[%RRK4‰Œdæ«^r®¸ä¾þŸß`Éi§pì±Çró—¿Â’“OFJIKs3Q°oÿ~º:;)—‡YtâBÌÍ8Œ5¼âÜsغu+÷üâ^.8ÿ•´¶´à¬ml/…|Þ/uG{;Jœyæ™Ìœ1£±xÚÔ)¬Y»–Ž?~ÌÃ/ßNAÏìY¬Z½šÅ'žˆ1†™3¦åé1ç(¥ä•çœÍÆM›¸à¼sýÍÉäÿËÏðëœÓØs®”„”¤Iµ608<Èþþï°~ýzzøÑ|]!H²$iÂ1óæ1{Ö ž~¦Â«¯¸ =Rn˜GàˆÜúÎtÆ5¯¹’×_ûZ~pë­lÛ¹“Ù3g²N{{+ú®? 3–+¯~?½õûsu8,!Eãw(ž|úišš›xãõÿ‡+W°aÓÖüøÎn+^ž/ÿ_œ MÓ\™´–¦°ˆ3Ž@;d › dÃ5B!±Ã5d`R !K3¢("3#! MŠ(–H“”¢’€#¬±dÚPhnB‰1¬+@†d™C$‰W^jzzæðê«®¤\Îû²Ï›;—¿ùÀûyࡇÑ?~ú“|è#å’W-å±+ùðß|û4MûÑÚ¦)ïü½ßeᙯà§ÿýmN8þ8þù³Ÿæo?ü.»øb>þ¹›øÆ—oFkM’$ìÜÕ;.Ééßÿí_øäg>ËÕW]ɳ»zyó odé…òÛ¿ÿ‡¼ç]ÀÚ ù³wý—^|ßþîw¹rø2.¹øÞþÎ?ä7¾™ýìv>ú·ƒsŽÁ¡¡qïI'-æÆßý}¾ô¯ÿâoþKòôv/K@ôëdøœ»‚[~x‚gÖ¯çÆ7ÝÀñÇË?|êst´µñÐ#努Ë˪¾pó—¸ò²Kyø±•üÍ_½—¤–ðßü/t–R«%œ}ö™,œ{ûúòÚv`_?_ýo°øÄÜ·üA^uÁá˜<h­yè—³}ÇNÒ$á²K.¦T,°wÆXp S5yF­ ÕJ•ysæð±O~g-wýâ^Î:ã œµœ}æ™,»ãNÞqã[©Õj<òècœ}æù¾¼ 0!ÈŒ%K5… ˆuÂÔBAiB'¡©@ªSd()Û  ¬TØ0¦DB™˜ Fk ME’j §--Ä$º† µþ!‚ÖmÃT›ö!l2ŽI[ŠZk7nðHFª1k-Y–¡µ&MS’$¡V«Q«ÕH’„Ç_Áe½’™=Çõ­!¥”¬^ñ§ýÊÿáó8¿ÞJŽV6Æ42„ǾW?N=s¸žù<öÞI)1Æ „窯o_ßG}›úúÏu<„h„ Æî£~¾Æ˜Æ:õlì±Ç6Æ¢ÔèyT«U–^z9üânßDäb­ehpZe˜ÂHîÇË(Š(5·rþE³` Qp¨óçÛ߯[ÞôF6nÚÌÃ=ÎÛo¼‘4MIÓ8GÅ(`­ÁXþêCÿo¹ázNZ|Y–¢³\iVA8RV(H“*ÖZ¢¸HšTŠwRb´&KÖ¬]Ç;ÿôÝ ù×ÞÞÎw¾þe …"a¤I «5Q¡D–%8k Âktž;£$J…diBR5ÎWë¥B‚0"©Uˆ¢BîH“—ÕgiOï³Ì9æ”R…õ|Û¾e#“&O=j¿{Õj­5---…o-ßÁþj -›iW–a íQþýC„aJ!3\{Õt¾p§¢?1wZ ׿â¯xެðyàÁùíßê/ÆK¦q¾¼žàÎÁ¬Ó˜5sú¯!t€¹U$ê‚Ó¢¸[Ól4Ž~Àß>~}7n_‡Z®uÆÐàÀs(ò‡Ú××zìyºCœïs-÷w¢ ÁÂîˆË—.`ÎÔ6ž\½»·fÌéT¼åªÅlÝÑOçôn&ª,_½Qlañ “™W¹kK?ç< YÏÂù3yGG;ÓeʼYSxÏ?~—÷üÖùÌhïæ?ø)ç¿ù ¨&7glNÛ8ó„fžyæNÞpíë ]?7ýÛ·HÌL¤¿%ž#éíøówÿY£¢ÁóÒy^v/ëžÿ5æ¼=öXÞö–7‘¦Ùóî3M3þñÓŸdñ¢_¾÷ÿÆ—WH^Ä3PR ÇÌìäŽ;ïfÁÂ) ÷UX0¿“[n¿‹?¶—}[·rãçàœç¡Ó^î¿ïan½ ëV®d玌ïÝòJ9šÇWîäö‡6sÉ9 )×*üô+˜Ü5 eŸúê]ì®øâ×ïb`OÆ#Ïôq÷=÷²úéõœ=>2©x€ÇsÔ9þ—?ÀµÎÐ:;Èb?”U^:ÈÂö>…Þó?ÿþ¹r™ÖT <¾j3Í­Ã{jœrêBÊèžÚÉEóÚÙ¾·ëJT]Fs (F„´Ì=f2((6…T«EQIª$Ã5Ö®ÞÄî´ÈÜS§iÒ$Êô·v)8ç‚ShJvÊJ15áyÂ=<µeýehý^ðxŽk-Šb†úiniöó\Ò*ôõƒêàÎ ûhr1w?݇5‚5ýûIFƧ™ö €Çs´†!Óg÷°uÃZ‚(zÎ’;çÂßååáóŽ[ˆRʇ^ …²´B¨5i!$KŶ‘iŒ©á\ŒŠ›)hH•ÚÒZ'‰BGæ ĉFÆ(ª™Á¹2rÈbc4R¤tZhb˜!€°H-éÇXMqM‘W<ž£Å ¥¤¹¥•ãÒèéà¼+Àók~~ ‚ /ë…ÿ ½’ƒ&+1Xb'q /5´•š°©¡ÄÄ"¤æRŒƒX…8§1N µE!ª¹™Z¥‚2G)S‡ ÚY¸ˆÓ“dô9R` (œ$™@hãçhzˆ×›·üªñ¶Ï¡¨7 ó À §’¥´ÅíÔ2C@Æ1¤eÆœsÄaeMJ’Ì@!¤Çhk©%I^Ù"&É"…• F¦þI¥°¡À©™²j’·ÎòvÂA k™W<ž£Î’ópÏ‹øüx^™TËJ2Æ`¨A$)… & h•wP­VªTH" is$I )$NŠa€)×PB„‚I(l-¥„á¨%qEÖZ¬µ¤iŠÅzÀãñrÇs¤°I†,:ˆ$ÎZ”q*Œq˜‚ M5q«ˆÁ¤J Q"EHª@ ®%H!‘…¬J\Ó\"±–&&FK(еU T„T!©Ñ„*ð€<Çã9rÚw.À6‹E µ†ZšhMÇ”‡+dFƒH“á¬Å*3†(Œ0Öb´Æf›jâ0‚‘Y,µ,Å( $)U,  a!ÆRÊ ïðx<çÈàPR¢T@† Úh"§hŽ ˜Ôâ¤% ”4[…Ì8A†&u––b‰$K‰¢!ek‰ŠµÔ!•ka@M'¡òž ¬W-SŒ ¤:+½Àãñx<ž#eþkcPJá$¹ $‘Èœ%ˆBlšáŒÅCNS“Âç *ÄJ5Ú1;!FKR)A b¥È,4;h¥‰æbFKH%QBãLÑyÀãñx<ž#åˆÃÌjŒ1DQ„ÑiZ j‘@(I†Xcˆ¢¥D ¡µ€.… ›h­‘a@‚¥¨"'Ð:ßo¡©DÅ$¤ÂaRMS!(š©¦H’ć'¿j6¶ÇãñMcüsñ€µ¨‘뢤$i]€«¤ )1B"…C 1—¬ˆL#€0 …¤h$¶¨¡$ty! M%ªƒØ´– ˜Ô‚Š› D‰ö€Ã¦×9Ǥ)ÓèÛ»Ç_ ÇãvlÝH©©Ù_ˆ1¤@…!. ¨Bd«5FB&²ª±Å€@HT`±U@IqLlÖúA jCèj‚1&¯ñOØOKòŒ,±ÁMlÅá„Z¹â€ÃªLžÊžÝ;Ù·g·¿ ç(¶ü5›×¯!BŠ¥&AÆúŒE‹J4E œ£\© ¥$P ´!.Ñ$iBšæ.ÿZ-ÁŽ(.ÐÂ! 2 q$,D!HÓ”$MPA€±–f@9ñ<8¤”k‘QèC‡[ ˜Õs,ýûÙ¼~Ÿ˜åñxŽJ¤”´¶wPjjöí¦Äæ¥zÊAVKK%”3 e@ÄçÆaÞÒW T¨°Æ ¤ÄHIb ”`,Å m°8¬µDq¬!ŠcúMb#’ Y$ÖVkDH¯ü&hk來½Ó_ÇsÔEžqö?Z Rb¬T¤ÖJ‹BãŒÅEˆ"q†Bâjªµˆ­¦EH­\ÃG,.IQVbØ@`­EN4--Eš„$CC¬°J¡Âå B(¯x<Çs„T"b—âÑ™FŰ„8bœ(!‚ $KSb¥0ÎRhk‰Š1™‚¨P€Ô J`…kä2@„!$Z'HÖÕã\>S@û$@ÇãñxŽ˜ÀXK(ªµ*ÆY¬68¡¨ZG(¬sHB€t qXi(IÔ´FYÈ*5¬pX›’fU” dY†5YZ¥<<œ’˜@ •@Æk5azÀãñx<ž#F ±8‚8&Í2$ù\k4­¥&œsÔª5Œ6y»ÞbŒÑQK(A`Æ9Œ5TBKA8b«iJà$Í¥&Bã(D’(€D§¨á”Ô$èh[#Kj^ðx<çHá¬#Å"¤ Ž"ÀX(‰(#@¶•ŒÃÎ4RHTB)ÂÄ =¢@¨ "µM­Ý¨¸„ŠC²j‚NÓF8 ï0µ‹šSˆ!¼àñx<ÏÿXk‘€56oé+*3ØX’EÃ¥ ˜ ‡$&¥–Ô&cx°…#N qU ¥ˆ8¦Š%s¬4Q!"li¡b,“K­ˆTãšbkUL¦±Æä%þ†x<ÇsdB`•D©¼¬/.@€P;XAMì aQäSþ¬¤ä$d ¡ë ÕP`BI(%NB9«a…EØ\FÔ2K—Hµ!Ë2!)„5a Šœ÷x<Çsä°Î±(%QA@­VC"œ±‚QŠÉBE”TH¥a@ØÒDâ 5“Ì@d-£…u–@d:£:ÂÌ¢­ÁZ›÷þòÂ?­3œs¾ Ðãñx<ž#E…4©%Ö‚ÀQÍRЬa’Œ(ÑDhs–H+T¨pTªÖˉd¸B*t#J"…"@Æ’Lfâ&úö’P…È+Çãñ PKRªÕ*J ¤P45·‘9K!Ô)ÍN!µÁ …L¤”()q‰¥P*`¤#N £ò¶¾‘T AĹG!t:œpXwf´ÖR,Ö€*‰x<Çs¤h.éìè ËR¬sÔjUB$®–RqÆ:T m B´Ñh¡F\ýRJp‹œÖ毦¨€T2×8R ‰&c‡5–̯x<Çs$ú+« Fó8›"b…Î2L °Í4`¡X,†ŠH¥ª3D!$ŽL@P U‡ ÔtF„`4zhˆ¶bL¤0¢ÅA;Lšb…ïèñx<Ï£ $RB(¥TH¡âù?ÃYë As‘KØ\$‹-Q‘‚c-q!FYG±’RÊ Nkd1FE!*Ó4«€þÚ ¥r5*FD i,q”Çÿ½àñx<ÏÁa6Y¦²4!Ó¥$Qä((K˜U ¤B Ë EãHÊe¢  $C\MHÉph©¶Eˆ–"JHœ³Ô¤Å5Gh­ÚÐVjÂV¬Ö!òðAø$@ÇãñxŽ ç"° ¡"†*UœrØb3a`´@8…t!8K6h(›1‰«(FMÈ($!! $‚ Vå1}%A…X+‘™¢$B2)pVÒÖÖ„I3¬È@”^ðx<çH ÁŸÝ°ˆöö6â¸@G475ce>¨'P‘ R!•D ™O ´v¤lР¤™'óYcqÎ!c …” !IZË'Š<ÿÀ)I-K"/-ô €Çãñxd(U`) ¬C'aæ³ü-ñx<çHh#jX•@¤ H±ÂáÂbQ€¤.E©<þo¤BFŽÔ¦H)NƒDXòùè`£-À9„RhéòÑÂ!À:Œ€¨)ÀÚ‹ö €Çãñx¯¾³ X0EÑYþÂJ p¶áâ¯ë£ñ{——ý¸ð•Ê•ƒºÐ?00v™”2oþ#Ęc†Ä+Çs”ZüÖÂÖ>Ë–~Ëþª#P$ü£Ö¼ƒFÖ¹ã5»‰З8îÙ¤™TÌi—ÌêHá= ãÑÌ4~Œ 꺵_ÿiFåB<ÂŒµî­5#Â? bœÂp°â¼ÀãñxŽVªŽ_lÖ áªC˪–X0­EÐ^4G‚L;†Sè«Zž²”Óñy‚¼Êm0q¬ê5¬ê5\07 9ö)RІ†Ñ¤ãË÷¬³HTÃz¯¿_ÔóÆ&õ˜à—+ õcˆF¡®@Œ xÀãñxŽ*©ãÁ­šr6ç·nTðOi‘(É8áÿB°¦µI&·Hv Zžì5¤††Â±¿ê¸{CÆÙ³ áÑé È…´CI5¢N¸ûGw] 7<$þÕ]ük~@¼¿î9¨ üºgà@|Çã™à›[þU=*üƒ©Í‚¥Ç„Lk=¼IzÎåÇ™Þ&¹èØÉM¢‘# E^9pÿµG¥ô±Ðó—’jœ7ÆZ—·ü=H苃”ˆºõ_Ô×­ç4cJ ëÛyÀãñx&8‰†»7fÔÆ¸ã3 'MUœ='8(V¸ $œ='`ÑdE6FàW3¸gcFfŽ2ùOÿ¯ ac̸R@1¦1³k •ry\?!dãåÑo!o”—¦iJ¥R¦R©ŒË°Â+Ç3¡yt»¦¦G]ðÖÁù=s:可>¿I¬ƒ¹]’ófƒPÑùù5€‘ļz߃µ“²,kxiV®\É7¿ùM¤”Ü¿ü~öìÙCš¦dY†µ­uc}c Y¦ÉÒ|Y}¿}}}<þøã|ü>Á§?õi Ì÷¯5õ}<gB"<¾]³·âP#¦ž¶pö,EW“8â5ùÎAw‹`ÉtÅ/w˜†ç¡·ìX¹SsòŒ`Â÷ ÐZsûÏn§­½•b¡ÈÕ×\Íc>ʪU«PJqýßÈ­·ÞŠ‚öövjÕ*F”T¬[·Ž¯}ýkLŸ6óÏ?Ÿ›nº‰K/½”Ç}ŒW½ê"–ß¿¼öškxäÑÇèéé!Ë2N>ùd6oÚÌÆ±ÖÐÛÛËw¾ýæÌ˜é=Ç3Ù3äØ14*üƒÓ¦çYþ Úz º1c Zëüªï£nå¨Ìh—œ2UaF¶:ö•'~— !{w÷²÷^†Ù²q#=³{XxÂ|Ö­y†-6𪠗rÑàŒfvÏl„h£ùú׿Î{Þý†‡Ëô÷ð÷€'V®dæ´iLîšÄ—]Æ›®#ƒýlÙ¼…Ý»w£¦¹X䱇!’ Üzëinifùƒx€ÇãñL4¤€§v®Ïm—Ìé‡Ìò¯”‡èÛOSKR¼x‡¼u–áÁAÚ;»hjn9[Æ IDAT`ôtIúªŽCy ‘÷&¸à˜àˆ…%^*æÏ_ÀÚµk9ÿüóùîw¿Ç«_}%÷/¿Ÿ¹s!IÒ4% Câ¸Àž={ Ú”)SXµj»v=K(¬³{Ìq ö÷ñ÷ûW^qsçÎ¥©ÔÄž=»éìí¤P,€e$I‚ÐÔÔÄàÀÝÝÝÞàñx<Møoé³ôÕÆKúã»þÎ9’Z•Þ;˜{Ü:º&ÑÖÙõ¢_]ÝÌ;~»vn#Mj‡ôÌŸ<Þ±¯êØÚwps¢‰„sŽ Xºt)óŽ™G[[+çœsó,àœsΡ»{23fLgê´©\qùTk5Ò4eÖ¬Ù¼÷½ï実ßÅõ×_O©T" C/^ĺuëøÜg?K„üè¶ÛhimcþüPJ1sæL‚“O=…Å‹£á†ÞÈî=»Y¸`Bkíê7gl;º '˲F&a’$Ôj5jµI’ðøã+¸ì¢W2³ç˜ƒn°ÇãñxŽ<ÖÁ²uY£OfᬙŠm+ÖZööî¢{êTTÞ‚,©Ñ·o]Ý“*c“¶õ[ÞaGLÑX .:6˜P«Õ*ZkZZZxäÁû褳³“ûsÎ=›éÓ§ÓÜÒL„™Oö«—õÅqÜhù+„# #²,Éþwæ@õuúúú(—ËÌž={\‚`àÙV†¡oäñx<½e;®{_wIÔÝo,ÚèÃ/üGÌü Œ0F7„ÕŠÊôVI×~Ë`’Ÿ\j}KWÓDuN¶ù½è¢¥ÄÅBˆ†¨–«X,ÍÍͤi:¦¹ÿ×;Ö«„ %£©©iÜvBŒ6qÁι|9‡<g"±kh¼¤ŸÓþò}Ì ³ÚÆ´±z‡ÝÄ- )¬V*lذÞgŸE8°Æ¢3ÍÞ}{ùò—¿Äƒ÷?€‚ýûö”øå%‚u|­RÅê¼?€!ÀY˶-[Ùºy ”˜L£„D AR­a^Q(”R|÷»ÿå=Ç3‘Ø3<>‹nJ‹|#ýÈ„nŸï8Ó[%«zMÃí¿kÈrâT5~¼à!Ë2ú÷÷ñŽß~oºámLš4‰§ž\ÍÊÕOò¾÷ý%kÖ¬a°Ç}”Û·³kÏnŽ9öz{{yÛÛÞÆ‡þöCttt ¬ÅËàð ïÿÀèììäƒü å!>øÁrÅe—!ïyÏ{¸ùæ/ÒÕÕÅÛßþvÞò޹âò+ùÄÇ?Ò+‡)%A4z8k­®ÇãùYÓäÝõÓ|¯u0«UPyQ™õJ)‚à¹EE½ôï…RŒ`z‹`çC èO –A<¥“‚ÞÞ^®ºòuœtòÉH)Ù¶eK–œNgG' ,döô™|òŸdÚ´©üù_ü9wÜqûöîC him¡³³ƒ?üýwróofv8‹$M(WÊüÞïü“»'Ó»«—óÏ¿€ PlÛ¶•w½ë]twO¦¿¿+/½’¹sç5B>p˜Y³n×¾ñMÊ\ûÆظi“¿(çØ=lQ#–´qÐÓ¡^ôpŸû—/§kαtÏ=Žî¹Çû}Ú1óyô±Ç_Ôþ­ƒ¹cÎS‰Ü‹1«œstuu¡‚ëýý,+_I¥RAƺº»(Wª¬[»Žááa„¬]»–b±H¡Xd¸<̱ÇÇe—ç–¾’ŠÇV¬dï¾ý<üè#wì1Ì™=“åùÆY~ä.»ârvî܉@„¡÷NÍ®V«qòI'³ìöÛiima`p¶¶¶†g @ ³ „hhÕõj €8ŽqÖ"d>ó9MS …Bcþs= ŠÂF6hý½8Žë&IâoŒÇsÑWœ±‚öÒ‹ïø×××ÏÌÉ“ògNòïÿú/üŸ·ÜHE8`` ÿE Eè( B5:D¨¯ê˜Ý1ñ¢AÐÞÙÁ¥W\Nw÷$´6LŸ6j­Š±––æâ8æ­o{ëÖ­c㦴··sñÅóìÎg¹îºë( ´wu1mÆ ¶íÜÁé§ŸNÇ,Z´ˆÞ=»yÍk¯áÉ•OP,hmi¥½«“¨sý 7°råJ^íëÑFsÊi§zàp*›·n`þÂt¶·Ëz}bÕ“|àCf×Þ}|õóÿÄàÐùØ'غc'¿{ã›yÏŸü1ÖZÎ8)—,½ÿÖwøà»ÿ„?ýÃ?`Ñ’³¸îÚ×ò£ŸþŒÅ rÓ§>sŽôcü÷m?æò /àÿÿȇˆ¢ˆó.¹Œ«/¿œ¿ÿ×›Ùµêу2o=ÏÄõ ÖF{þ·Å‡é»?f7J)N:é$ÒLGÑÈxûÃsœÖH0¸üïù9Ñ4!*™6}q¡@E Ú:Ú(ÄyE@K±•¶ö6ªµ*ßÿþ÷yÿûßOKK “&M"‚FÀ¢Å‹Æí{ñI‹¹çžÿJœµ r¤Zà¼Wž×0$çÎëC‡ k-'wþÞ÷1kæ,Þý—ïcÙw°¿¯3Ï<“¿yß{¹ù¦ÏÒ3g=³góŸü¾óÕ/ñõo|‹ú%-¿Ë/¾ˆÏüïùðÇ?ͺõë™ÔÑN)Žùüg?ëžäG?ù)·ýä'ìëïcÙ-ÿÍæm[¹ëî{xட3{Ö,îüÎxáïñeTõh}Stø¿ÿÆ~ùˇ‰ÂÃÝ3Šá¨¾QÓ·¯Ìºµk‘"ŸôW«Õr﯇Ôg-§Ÿ~:ÿøÇikkkŒü­+cŸíŒÎr®/ ㈕«žhèPõíêý”R^8Ü|ì£æÑGsËû¯>ôî¹÷^–?ð¿õæ·púi§ròI‹)•J¨ ä _ú òÞ¿D)ÅððpcKN?3–,ᘙÓ`Áüù,:q!¯}õUlظ‘•«žäáGåªk¯£¿¯oÜö¯»æ5,Z¸Ðß çhòcåf¬ÿ1‚@qæ™gŽ„,ç¹GjT¨é œ7}Ï]waµF)ŲeË(—ÁÒ˜îg2’ c I’`ÇdpfYÖðŠXkQBäe„Zãl®@XkÑiÖ±cË6„£‘î¬kì/Ë28œ(¥ä´SNæŸ>ói^sí(—‘J°vý C¬1|þß¾@gg'·ßú®¾öºC¸Š} )˜:y KN;•›>ó©<›SŽ©¥=DÓ Çsà~õ3äåŠô¾¿æ o~+³fLçÝïzS&Oæ?¿û]Ò$a_ÿÀ¡¿ËcZ4¾ÆY.¼à|þã[ßæï>ú÷c¸öê×púi§úáñŲ_ÊÑ’¿ÔüŽáƘì‡ùÜÇžïDUœsÄqŧžÌ-·ÜBOOë7l`ÇÖíT*Ö<õ4¼ò|âBÌÓÏ}:q£”¢FH)òÑÉ*OÖ ‚€¢0¢¥­¤Df–Û¶1kîöìÞƒ6†IS&³ß~:»:BP©TØ´a# O˜ÏöÛ‘aÀÔiÓ¨V«B²ê‰'xâ‰'xÃoý–÷x<ÏDÀ9h/Hv åÂx8Ë;ê^d¾1æEuúû•F1PËå B™{Ú 7?])EG{ÖÚÆxà0Žò¾0 •DJɤI“ù]N€$3çÎÁ!è˜Ô•'ý9Çä)“å¥R‰“N> g-=óæaGCZZZÀñ æ3yÚ4ÚÛÛ|€ÇãñL »Y4¬f)`kŸyÙÇÓ…€­}£ ­ƒIÍ/¾ÑËó&ü#Æþý„À‰|±; ù)%’<Ü8‡ •‚‘qÀõõêë:À ÑþcßÑÙÉœ¹sòþkãñx<C¶´ÑÈS] ØØoŸwÀ‘Êz¾ã›Ÿ§ÓÁ°­ ˜¨Aå1¢ rá=¶V¿Z?Ð S¯ôìÆ½ÆÎŸ»k-ÖZù1¼àñx<ˆ)ÍrœpÝ[~þ¢ú¼SÜoÆÅoFfÕ?½Cv\¬Z³d¢§”·ÖÇÿ±Æä­Ü믱XkQJ!Æt÷«çêU«Õƒ¶«£¾ÎØýå^ÇãñL `¼ÀÝÚoŸ·j¯ÔÜÂŽ­›Ÿ7Iï… ”âÙí[)–šžw½ÏojËĵþëBÙƒc™óŒXéõºUìc­ÿ±‚¾>fì>ë ýuÏBÝ›P÷ ø$@Çã™@t7 ÄhgX¶8Nèv´Ä V!¥¦fj• ϬZÁœyÇ¡‚€ׄ_`²ŒMÖÐÞÑE±ÔtH/€jŽÃŽpLØ¢³4˘ÅÁ­|!û !(WÊ4•šÆ¹ìÝ-~Çnëœk(uÀX`ì±”R B¯x<Ï¢ zÚ$ëGëBo7\0/8(!°nE¶wM"Œ"žÝ¹}D¼8@Jɤ)Óinig}ŽÅ¸ü¼‚áo,3IRÅ„(ÿ{.ê}øÕ˜xýý¦R*P !]·øu Ǻó낾¾N]¨o_ßÇÞ¯x<ÏÂX8qšbÛ E[M¶ì·Ìí:8ê+¥$ZÚÚiji=lçñ\qì:÷Zjc†Å,œ¢&´ð¯ kkÇ&ìéø:ò)ݸìþC)côŒU,µMãù¯‹ÇãñL4+té?½×0Pu‡, ¬+aÁ‹z…aØØÏ¡„¿ÐWq¬Ý?>ñpÑä£@ø#Xñø ¾÷½ïÑ×ׇ”Š( G¸DQÄÝwÝMy¸<Ò`|¦#pŒÕ?6 .øÇæ aOÿ“!%B Ö¯_ïÇ㙈Ìî‚Qg¾sð‹Íšrêž×:k¹¿×¡bÜcJ÷nÖ4…0£}â‹#k-·/[Æ+^q.RHÖ®YÃý÷ÝäÓÓ$eŃ¿dÅcS­V¸ëö;Ù¿«§ ÎÁöíÛyzõS(›×®gÓºõd•ÏnÛΆuëÈÒ¬1ùoõêÕ ô0<0Èš'Ÿ&«ÖØß»›kÖRâ[ÿñ Ô‡?üw'¥@JR¥ %A ‡‰,œ38gÁYv÷îbîœÙ´¶wúo›Çãñ¼¬¬M˜Þ*Ù1`1®.àa×eZ‹"<Â`) ’Áò-š±…‰çõtÖk-q³sÛ~´lg.YBµZå+_ý AÐÚÜÊÔiS¹ûž»‰¢ˆGþ%ë×­§««‹ï}ï{\üªW¡¢€ÓÏ:•žY=tµw±víöîÛÇÀÀÿüOÿÄÖmÛ˜>sÜßýdYÆ­?¼•ŸßùszæÌaíÚµ|ó›ßdú´é|å«_! ‚æ¿Ý¨Çpù€ç΂3X«‘VƒÉ@§]€I\ÝÇÆ ýàÇãy¹á€8,™ðÀ¶Q‹»ªaÙúŒ ç´ÄGîùÝ_uܵQ7’þêJÁ™3¢`b—þõ° º»»`ÆôÌ7—¡A‚;vrÎYgsâÂ…ìÙµ›U«ž Œ6«ù÷ý2ù¾÷2}ê4-ZL†lÚ´‰…'žÈŒY3éÛßGpBÀ£=Êï¼ãw˜2e ?ùñ9é¤Å|ùË_fÒ¤nN:ù$–ݱŒææ‚…±—ðéõ~„8›·ctFàŒÀJ“+Áx*ò_2Çãy9ÓÕ$8s†â¡ífœà½³æÄÉŠÙ¿ùÆ;[ö[žÚcÆ œ53 ½$&|ìÜýèìÌ'Æ " #¥ÈtƹçžË÷ðV=¹ŠK/¾„þ=ûˆ¢%%* øáÈ—]ɤ©S¹í§?AkÍœv–$M) XçxÕÒ¥üø·òäê'iïêâ»ßÿgœ}?úÑmçÐÖRKSÄÝîFï¾kd"â ÎZœËpÆàL†Õ)N×°º†3)O­^ÅÆ/^Í´Ùóü4@Çãy³{ÈòÈN3NØ; ³ 8kv€ú „൅¶h7®ÙOÝòïjšøäqÓ¸—ÞÁ!º&uQ,)•J„QD剓¡ ) ~¡ pÖæÝeÞ÷߃֚0 qÖa¬AŠ<±ÏZ›WX#5ÿ–¼ùO}ÀÖ:ÿ™i_èñxË»ôH•ר2Ð[vìܨimA{!Ÿ2X …0¯3jÚQɵüÕ_…¡Ô¡ãz 8ÚÁ)S³:$€£9`¼{ÏŒ5´´4sÏ=÷$5´1TÊî½ï^öîÞËëÞð:~èajµ„5kŸ¡{R7sçÎ¥wW/.½{}ûöqÖÙgqÏÏïá©§žâÆoä¶Û~ÄUW^‰´°sÛv–/€¥¯ZʦM›X´h+V¬@JÉðÐ0.½Ð+‡›,MÙµs•á!1<ÏËšcU^5›ª ¹ˆ¼{`%s<;DcY}œ=bt¤ýXaàSÀ¤&Á©3q þG^…‰J´´´ðì®Ý 0{ÎîX¶ŒI]]<ôÐ/¹úµWóÙO–%K–0kÖ,ž~æ)æ/˜ÏòåËyõoà©§ŸâÁä”SNaÅã+˜7w½»{ùÚ×¾ÆMÿx_úò—xÿ_¼—ßò#Î8ãtž^ýË|€ù'Ì燷þ0 ùã?þã¼Aÿ >t–±§w'=Çœ@Çþ‚x<žÿ T4Ûö§lØ—QN-ãû¸ýçqnZÚ:š#ɱÝ1•Þõœ8«„À牉YF…ìííÅZ‡1†–B‘þ½ûPNUk”â˜îÎ.º»»1ÚÇ1ÝÝÝ4µ41Ø?@wg§žt¯XÅR©TPR²kÇNæLŸ‰¶–/` ZeߞݸÌàŒÆM{G;S§M¥Z©ú€Ã…’Û63sΡ™9! Eà¹d¾Qêëöt„\:¿…«OncáôÇΙÆà`¿¿Àc(–Š8çX²d «ŸZÍ—þýfN[r:'Ÿz*2Püõ_ÿ¯yÍk¸ãŽ;øÔ§>Å óOà‹ÿöEšJMd™æŒ3ÎàÉ'Ÿä÷~ï÷™2y2­­­ìéÝCkk+ÿ÷ÿþ3Ý“'–þA¾pó¿Ç1Ó§Oã/þü½Ì˜>¥Tž (_x¸RòÔÊG9õ¬óü'ÜãñLª©%É©±hëÆYñR€’‚HIâPPŒ¶'­µìܺ™®ÉSŽÞkx@àîá2 ššJDaL‡DaHEH!‚ ï÷¯$QQ«Õ(•Jcò¬~!FJûNäÇh*–(ÑÔÔ„ô÷÷ÓÒÔ„3c-ÚZT ÃV|/Ç3¡¬ÕHRŒÔ Ú^Ã?Ç+E!N€q+p‚HJ”sãî¢Ãù€Çãñxúè#ªkªyì±ÇHÏHçù矧ªªŠ«®ºŠÍ[6³eónºé&–.]Jß¾}9p Š¾ýúa…,‚Á ¯¿þ:çœ}]²»ðÒ‹/rì±1 áÃGðÕŠ¯8s™´¶´ðÐC1iÒ$’=üíÕW¹úš«)ÜX¨FEQåhRRZZЦkøZ[imiaú´i¬]¹ ·é`ká&Λ2…gž~«—«¯¹šÍ[6Sºw/Í õ4ÔÕ±qÝz>ûd/¿ð‰qqÜxý5¬®¡[—V._Ágаuó&œºÁKÏ¿ÀÌ /Âm8˜ýÜsÜrã<ô»ß³yãF5 (Š¢(G‹¦iøý~¦ƒXw ñ 456 ¥$>>ž¸øx4]Çív…¯ùGVSB‘‘Aqq1~¿ŸÜÜîŒ1œcŽ9†¯7|Mß~}©:P‰°m|>B„'õÛB˜˜ÈÞ½¥¤¦¦áñxÐtƒ„„(Š¢(ÊÑ`9™9l߸“N:‘á§Ž 5-„„lÛæ´á§“ž‘ÎØqgâE‹˜>}: ¨©aРAÄ%$ŸHJj sߟüüž =å$V®\É€c%++‹wÞ{¬.YØRpñ̼öúë 9ñDFÃO=Åõ7Þ@EÅ>•øsÑuí›6pÜÐaê¿\Q…ðwEY i™ÿµÇ càÚ5_òVë'¤¦'a¸ RÝiœáCLŒÃ0q9]è‘Ô?MÓ¢·ö }zd})Bˆð$AMCH‰¡ëáZ‘ííý„á‰ÂŽ!¶.8¤FEQå(^´g“A:5f-£ÌQŒd¶-0Œpc­:¶mGgü·Wøk¯D²t¤ §B8¥°=X°…8lÔ!d…"õi4,ËBk_G@EQEùß§…4Æ=3Ž ^¿Ûåí8¤dxyà`(íÁÛ¶ ‚ ³gÏÆ0 ‚Á ¡P+dHÛ¦¤xe¥eH½‚X¡²v¸²àßß|“•UXÁ ²CØ–…¶PEQ”£A×uNyý ú²B~…¡éì¯ÜÏÛsÞ&';‡éçÀú ë9r$º¦³}ûvvìØÁÊ•+‘B’Ï„3ÏdÞ¼yÄÅÅïñн{w–,ZDáÆdff’——GAA¯½úUª°öï¯$¿gOêRpጋÕ€¢(Š¢ RJ*öWP[wèè,Zº˜›o¾™¤äd6~DR[W.är2`ÀŠ‹‹™6m:©é©,\¼ˆ`0Èþý•œ8t(} †‚téÚ•¼y,[¶œ¶¶6¤”øý~ÒÒÒzÒIô-à˜~Çàp:hlh¤ÍÛöÏKlluQØìdS³“--N¶¶8ÙÞâdG‹šêŒ*Š¢(Ê0 ƒQ£F‘—ײ–2$Ý5›•+W²}û6ºew£è›oØ]´;rͪ««‰qÇðÍÎ|³ã²2³Ø¼e E»ŠRrð`¦iòλšŠ%,tÓ¤´¼œ½åe„l›ŠÊJüÁ š©“àñ—^að‡#Ó{/çë›ó¨úCoÊw »ï;Ž­wŸÌúÛGòÕÍãøËõwb 5ˆðc½ü·WÑœ‰œ6j ã&Ëç_,ü·÷±zÍžxúÔÁTþÏ«©©AÓ4ÊÊÊ£ÛÖ­ßÀ3Ï>÷ñþvìÜÉ„s&óâ˯D'cýMM?yu|MÓðú|?¸ÿWss3`Pý–nãµüìöîÆÆfìè3pºœ\tÑEäåçQ]]ÃùœOLL ±1± 8ˆ¼¼ò(ÃÏÇksæDgQ?õ—g8cÂY\wó­X–}íì_âÓÏ?g섉,^²„—]Îì—^fЉ'SYUE(â†[ncÔ¸ñüíµ×‘R²±°§Ÿy–³&Oãä‘c¨®©á¥¿þ•«V3jì™lݶ ¯×ËÌ+¯fܤIüã‹/X»nÿóÌsœ5y*ÃÆŒ£²ª €…›˜8y 3¯¸ŠÆ–Öï=~ÏÎ~U«×0vÂD¾)*¢µµ•—_É™gŸÃÒ/—P±?çN?ŸQãÆóô3ϲ{Ͼøb!3.¿’W_ŸÀoÿðcÆOàžûƒmÛH)¹÷·¿cÆåWòìó³Õ?ê»a 8†>²€‹™ÁqÖqØ,¤$à÷û£j!h`Ûv4K@Ó5jkk#v;ú\¿ßeYüÚZÛƒø}~ìP0²¾Ä²¬è¾¾üÞ‚Ütuª~ ÙYY %_.[Æ„3DZðÓO?î ¾X´ˆ;n½™­Û¶E¿ ï»ë,ÛÆétpÍõ7ríUWòÉG2rÄpÁ kÖ®åÃwßá¹§ŸbÖM7«¬üG ƒ ;õîýÍïini¡cgûw>Ä‹Ï=Ã'¼Ïõ·ÞBSS3 ññœ0ø8>_ð1ƒ¤´¬”.]ºðæ«cõ²¥,_¾‚½¥¥8žxô-ø„‹¯¸’Ë/ÉâÏðõ¦Í6|½‘SO>‰/|ÌyS§ðÁ¼yÑ¿=ëê«Æ|¾àFI’ÇC·œlV~¹˜ÎYY\wÓÍ\{õ•üã“ùH)غ};N‡¤äãÞã—_äí·ßáªË/cì˜Q,þü3ús ̼„¿<ñ'þ1>ë¿ÞÍÿÖu?xŸ¿Í~–ùó?FJÉ«sæðÎsxæ©'ˆ‹qïñ»~Ö5œ1zŸ/ø„>½{3õ‹xîÏOóÙGóXüå—,øôSžxôÿãS®¼ôzæç3鬉ÌùëË\:só?ù„ó¦Naá§ vê)¬^³€ovíæÉÇþÈ5W]©þQ$.³.ã ërn×3¾~ùy$&$`}ûôFÓ4ŠKJ˜ûᇘ¦‰Ã4™:yòáŸM!Â3³Nl[Ð-§±11x½^ 7o¥_ß¾ 9á–-_ÁÈá§“Ù©=zt§î`}d?Û¶ikóÒØÐÈu7Ý„‚ææ–È¨ Œ¾.?/÷Þÿ€’½{1lq±±á‘#\ ÞçóE—Ë],FJISSµµu̺þ„446DßßeW]ÍyÓ§qùÌ™ðˆÇ¾ò ÞzçÝpƒe:¸áÚYá÷Ò½;éiiêŸó'¸*k+IÉH¦pk!ï¿ÿ>·rWý¯xþùç¨:PÀhhh`Ïžb¼mmœ{î¹ :nPt‘ŸúúzB¡ó?žOß~} TUUñë{î%=#;vp×]wqê©§Ò£{¶oÝFcCË—¯`äè‘ìÚ³‡_ÿú×¼óÎ;G¶€Ó ýò`ý0ÕÄÿŸw@¨CPµ¯b?½ó{ iéiÜuǯ4ðØÃž?zøiÔÕÕÑ­k×îE†ßï' EkDçvËáâó¦óë»îTZù?¥_ß¾lÚ²…=ÅÅhh$&ij¿²2úxc}#ÉÉÉÐq:]¤†ú§ÿøœÁƒ2mÊd~óûøÞéI²Ã‡O†ݬÌLn¿å†ž8äßz¯N§)l|~?1n7RºfwE|ûú©v(Ð4„„šZZ˜ÿç?ãñ$þàþ¥x)ß·¯Ã÷F¸1سg¡Èä½îÝ{àñ$"exÿ‡¦–Vf?û ññÑ×8Íc÷î=œ6f,ëV,‹¾'€””dî½ûnŽé×·Ã{¨«Á?Ç÷½NKc3º¦³¹p3÷Þs >ù”€"%5 WL,} (//ã@Õ2³2Ùºm+' 9˲B°lÙ2tCgÑâE\qŤ¦¦²jÕ*žþŸ§X²x o¿õ6“&M¢°°)“§0jø¾Z±‚3ÆŒ¡êÀbœ.œ†IŠ'éÈ×Èîrè8 OT“F")ill¤¶®ŽÏ.↛oæÂ .DÓ4ú÷ïÏmwÝEqI ë7l ²2ÜÓïÓ§—^=‹ýû¶Ó0˜yá…Ìùûß©­­eë¶m$&&r ºšÅK—²oß>¾ÞX¨Ž¹òüyà°ÙõãÇŽão¯ÏÁ0MióúXºl96nä`c=óó±"+¦ul¨<‰ ,øìsJJö²vÝú ï¡çÚ¶uxã&%½{õä׿ûE»v±±°²ò}ß8ü~xg¦iríÕWñç¿{÷–²Bd¤g••©>…ʤ@ À¾}äççE·í--ÅétÒ¥sg{Š‹AJz÷îiš”””DJœ&ÒÒÒB(d‘Ïžâb„¸ÝnÒRSñx<ìÞ½›¼¼!žô´tŠ‹‹q»Ýäææðz©?Xßï'6.Ã0¨?XOFFÆ¿ÌûÖ®†ÄÈé‹ÂŒÉÛéÒMª ¢(Š þY°aõ jš[IKOÅårãv¹p¹Ý8ÝN\§#\½Ïá@ÓÃ)€íi{HÈh‘ Ã0…Bèú¡t?)et’_x¤ËÆÐ—š5Mש…ÿv”îwLøÍ8Õœ2EQE9"š¦Q¸yõõÔ××ãõûزu @€šÚšpî)¢e{“=‘xÛ¼áµü#ƒjkkiii¡ºº]×Y·n^¯7œ†úõF„X¶ ²$–mc‰£ · „ Ž… 'Cc|ø!èj!@EQE9¢‘%K– iáœýúúââ┕•ÓÜÒLM] VÈâÀ4753ïÃyìÝ»—Ö–V›ñù}´¶¶ÒÜÜL0dÃú ¼ÿÞûAV®\…É)++‹dƒ4ãózyã7øzÃ׃AÚZÛBY€eÁ[óÂ=Ó„wæCM Œj^ˆ¢(Š¢YP×Ð@ll,--Í|úñÇd¤§ÓÖ¯‡ÉS=Á‰C‡`˜ê뉡hçN²;wæ½wße츱ÄÇÅóÄ£“œ”Ä©§Jå¾ jëxèà .déâ%œqÆ”ìÙCey›7ofûŽíÄÇÅSZ\ÌÆõë9ùäSð$yŽ,ò{…—ÿµ,ÈÌ„ädhm©rCEQå_Òu¾½zc:LÊÊÊÙµkÅ»váv»qºœlÙº…êšjzõìÉôó¦Ó½{wlÛ&3+‹RЧ€?šÏ!C˜6m*›7m¦5©!õuyúé§ÉÎÎaÂøñ[`Û§œr2û+*R’œœÌúõëÙ²e S§NýáÀV={EQEùÙX–ÅG|Ä 7^O¿‚–-YJjR2'œp-­-¤¦¤Ò¿N9ùd>œû!†žðW[[KFçL‚¡ C† áчaù²eŒŸ0ž$O¥{÷’œœÂ¨aÃHMMEÚZ[ñz½$&&â÷ûILL`ëÖ­tÎêL^^¹¹¹ßŸðÏÁ’Yyä¥ù†À¶T1 #‰ìT€¢(Ê!* à»YZZÈHOÇéráv»1 ƒ¸ø8LÃÀáp …HHL  "ؘšš›ˆ§œ¶¯ãðûñx<¦IYi]ºt¦¤d/ù½z"¥Äçõ ÐuƒíÛ·Ó#¯û*èSÐûû'öv‡xuÑáxî¸å.¿âJ~÷Ûßãæâ‹g°|Ù2–/_A·n9466ÐÜÜLRR2ÿøì3ÖnØ€ ÑÜÜLUÅ~¼^/ñ ñ|½©|Ã0hiiæ•—ÿJ÷ü!?a<ýᮼò*žxìq Ž, PQEQ”ŸÆ4LR’S¨ŒÙO @“àóù2<ÔŸŸŸG||]»veÑ¢… <˜®]»PSSC(" ²mû6ÆŽKYi)@ÃÐÉÊì„Ð4†Çã¡ÆWaävïŽnèx½^z÷ìMŠ'‰¬N™äætCMñSEQ”£@" X!ÔÖRW_Ock n—‹Þ} X½n-!) ¦Î©§ÆÜ¹syñÅÃMƒEEœsîdfÿå/ÌÿàC2ÓÓñ…BTÖÖ …Ð#×ù5Cç`S#­Íx}>4=¼ÝˆqÑ£ 7~Û¦¾¡Q(Š¢(ÊQŠÈÎÉæ’K.!!!ž¸¸8,ËâÆ›n¤µµ•¬Ì,n·›ü^=IHˆ' ÐÀ¹œ8N|>/(Ú]DÿþýéIûóx<„B¡èý“N:‰Þ½{ãt:1 ƒ`0ȬY³p»Ý<ð‡ßãkmSÀÏI¬Á,l57BQEH®©æ¨ÈôǃÛíÂ8N2Ò3Ðu¸ø84M#)ÉÃÃ?LȲÈìÔ‰èºNjJ ×^w-±±±ÄÆÅ›˜áïv»Ñ4 §Ó‰DÒ©S§hµ@€ääd¤”$%%‘”èQÀÏÉ4xÛZ£¥EQþ»{¼]-&óÝ8@ W¶McCu5µ7x¦n µöÔ?ð¤$SXXHFV&š§þYÂ&¿w/„”h†Ž@‚¦£I‰´Ã)‚†Ã d S!AÂÇÌI'Djjjø=º ~NÁ€Ÿø„Du EQçœ75Ö«Ñ~<„doé^›¨®®fÂÄ lݶ•ý¥ådef±mû†Åž’=ôèу=»÷ðÁ‡гg/¶nÝJzz:Ý{tGëòõƯuúÊÊÊð‡‚äåçQQQA}ÝAŽ?n0›¶l!=³2¨¨Øa6nÜHFF† EQåhD«W­¢kvW ˆ²0 HxÿÝ÷8çœI,^²˜¾fÆ%3Yöå2RSSÙ±sû+X»v-3fÌ 6.–Wþú “ϙ̟ýƒòòr4Ó ººš††4!Ù¹e[·lfÌøñH úôêÅì矧¾¾žÏäå_R€¢(Š¢-†nïŽ%=£š®‡æ4‰‹u‘”žFÓšÕ¸œ‚>·§éÀï÷SUY…išÑ }ä÷Ì£hçzôÆér±~ãΚ8‰ÖÖfÒ’SihnäÃæ2pà šq8”ïÝË c°ø‹/T ¢(Š¢ BâãâHJJÂá0ABçÎYìÙ½‡¸Ø8þúÊ+ =q(C‡eþÇÓ93 !n—›øøx„¸Ü.q;ÝüñÒ³g/,XÀGóç3qâDBVˆ$O••(++£G<ΞX·›µ«Váv:)/ÙKK[ ðõšuLŸ2YŠ¢(Šr´ØR …°"×í¥”ø|~êëà &egwÅëõbè:š® …0M“¸¸8B¡mm­ô왦iøü>êêëÈÊÊÂIÔuP(Dkk —Ë…'11} øfç7x½^233yûÝwYðÙ?HÉH#1%‰¤”LÃnêìÚ³‹Y×_‡¶«¼M†'„³¥)¶mÛX¶…mYƒABÁþ€Ÿ` @0`ó–M\:u$]ºå©4@•¨(ŠòO¥J\³b ;Ë*0à\.ÍÍÍ|0÷âã˜uÝ5ÄÆÆb&R ÃÀ0 4MCJy¨o ÓOæ‹<¦k:I( §j:Á`M×ðÙ!ÜN†C×1].»ô2žyæÌ]ÑÆ»}¶`ÇY†¡ŽeéƒHü~ß/ÕÉþËÛ}EQE9"¦ÃIf§ l;<›?==Û~uN§$Ø–®‡sþMÓŒv.;v4;þ®iZx½)ÐÐp¸hh)p8Ä8MSÓ°…ÄïD3ÔEQEù_âp: M7‰¦k躾f¶ÄŽTÕ5=Úoïá·ß:joøÛ·ëZø¾Æ÷<04 H$„וøKòz}ƒè‰ŠÇ0ŒŸ´Ï@ €”·Û}DÏonn&1QU0T”ÿK|>`p x—Ë„óÁ[ZZдðóíß'?´ýÛÂÒ|ÄÆÆþà÷ELL ‡C„#íõ&Ob¸0[¶lÅír³sÛV úR[[K¢'‘K/»ÍáŒ6æÿ®o_†·m;<)0²YFÚ™öÀBüÂÞz÷]^{}ÅÅ%üõµ×xøþä}®Y»–EK–üàã{Š‹™¿`Aô÷ÇŸþ³:ŠòÌ?ªU«ùÇ_pã­·G¿üâIæ~8Ù/¿Â›o½}þcz‚æ}Äó/½Ì[ï¼ûƒû ƒ¼þÆ?øøƒ>FÅþýêü{M3Bš1ïóûhnibàÀA¤¥¥ÒÐÐÀÆUk8XS‹”ùOõöÑ€Ž—ë;>öíûïøz!« ª€_224Múö-`ðàã<ø8†;Y×\MzZÍÍÍ!ˆÅét"„ µµ[¦I||<---ضÛíÆívG'Ž455EGÚÚÚˆ‹‹£²ªŠM›63zÄbcc¹÷Î_u‘ð †×‰NHH￵5ºzT\\œŠüå?À#x z¿¸¤Û¶)Úµ›ýUUÜuGø3}ÑeWpñ…°cçNªª«¹ûÎ;¸à’˸ðüó»–ÜÖÖF(Â"|=Âß7‘Ï~||<¦iòûûî>®ü˜P@RW]K·®Ù$xq»ÝL;o:¶?ˆî0ñùý$8ßéÙ·7è/ ü«‰÷í«¶´ ´Ÿw)¥ø¥9áSii ^/éii|òé§üýíwرs'¿yàA¤”¬[¿žç_|‰¢¢"Ö¬[À’/¿äÙÙ/P¸y33¯¸êÐ8OÄᣨohà/Ï=„‡ðÚ¼^FrNoº=ü¥P±?—]}-ÛvìàÂK/gÇŽH)9eô8V®^ÃÍçÁ‡ÿ¨N˜¢üÙS\LuM†aPWWËÙg}ì¬qg°¯b?õ뿳½c/¾¢¢‚‹/»’m;vðëßþž˜˜¤” >š¥Ë–3÷Ãyüᡇ¸ìêkÙ[Zªüd[6™ÈÍÍ%%5•Þ}úPRº—ºÖ&Z}>*++!r¿c£Ï÷Œ ´Ïè¸TðÍh_ ýñö Bü‚4Mãžûï'7;›%_Ròõ:l!¸çþß²|ñB ]gùÊ•H)Ù³gçL:‹ÜnÝ¢×ûnºýN6¬\¾Þ/%Ÿ|úéi©ÐÞçŒôèßrE¢öÎYIKM%»kWbccX½z úãCdwíʉC†ðëûÃã<Ì„Ñ#?n,ŽÂ·ß}På—óäÓÿʯVrÖĉØB`…B$§¦FOKK£¶¶˶HNI9´=5ÚÚ:r²³ðeçþô(¹99œŸÃУ“ý9P]Þ1üžˆð‡ì--Óãü»IDAT$²ûLj‰qö»¢(¿œÛn¹™·ÞœC|\,|8øøö––E¯¬¬¢G÷\LÓ¤´Ãöý•Utïžý½¬|¹99XJÍÚâÐg½¿~uÐú·>2R¨½ñ¶¬RÁo[v´Ñïxko3+îÓá±o7úG¾êß>j €_˜á3åÜs¸í®{ˆ‹¥Gn.Í­­äå呦i¦É´)“yëµ×¸û·àp:IMN¢¬¼)%••• 9áxl[DSJ<žÄè\ŸÏý§hkkûÎûèÓ»K¾ü€ÆÆFò;|A|+¦T'MQ~Éï )iimŲ,œ™™hnn¦s—μô×W‘RX¾j5)))tîÜ™—þvhûWk×’’œÝ_ï^=Y¸h1­^o¸áР¦¦–`0ÀªµëIKKSÿ§·ÿHNÅ“Rb ;š¾×±Ú_û¾mÛƒÁê~»`ÇŠ€–e„B¡ès¿€JüE…Óð¾l/*¢°p³Ÿù3wßÿ[ºfeât¹¸çÎ;X²ôK–,]JKK ýæ>LÃൗ_â¶»î!¿G.}z÷aÒ1ÇP\RÂ÷ÝO¯ü|úÝï¸áÖÛØÿV¯ßÀ=wÝIÏžù,^¾ãáG¸ÿ×÷P]S ÀèQ£¸ñ¶ÛYðég4¶´òÔ£ ¥¤¶î`ôý®ûjRªõŸå— yä±?ÑÔØ@lL ©iiÜrã ¸Ýn~uëML»èb<‰‰Ü0kùyyÜzÓ L¿x‰ ‰ÜxݬÃö7bÄfÝp#Ÿþã$%§Ð-» PR^ÎU×ÝHüí}x<‰ìÛ_©FŠHÿ©}AC¯ô'¤@HÁ¡´MMÓHt݈6êÁP]Ó"“½ul[F¯ó£iè&ZÖ¡óÔ\tB Y–%ÿùJ€!¬ÈRÀ@¿ßßï'PX¸‰±#‡Ñ5W-¬–Våÿ›Žª”Ü}ßý<úЃ?y?ÿíK·3 ƒµ_}Iy}#qñ1¤z<¸Ü±Ä'ÆcºÑ.b&ºSÇír¡a i&Bó£k 5S|B²–-1±p¾C¸Bºf œšŽ%À²$Èðß÷ûýÑ@ÀétªEQå»Ú/O*?÷ €N§”dÜNwº°‚´Ú1ØÍA¤mašŸà@s¥’ärÓð#m·Ža„Ð 6¿NÐg‘—€ÃáLì †Ã0‘vèá5ÚSÅÛ/«@QEùŽÜn9ê üì$Þƒû˜¿øm’Ó:!cÓéß» ßí$7ÕÅIg_‰e,žû:)ŽFr7z8™¹sŸcÄù³º‡µK?ÀÒ¼ôêC\·Ð\Ãço~Žm̤útOg×–5ÄgfÓoàPZƒ.NgtÂx[[RJ\.— EQ”oõR5ëg]£ÄÏÝü V>Ù‰dõJjF*w­åÔãŘ‚® bã9cÊeT¯›G¯ÑR¶m5ƒŽLŠáG&ç`ôíDfÓ(\þwúgç£%'ß5Ž^#¦ ¹ãØ´ôCFŒA«å"9«+YδÈtÿö…€Úç¨@QEQŽJÿ_bKZ ™†Ší‚!:÷JÃö/(ßÒBfvšÛ@wÆ4@‹¥¾¢„^Çö ªx]d²o÷Vvmú†AÃÒL ¡FìÆ2Ö}úYyÇßk›¶l&^6™ß A2š8|Áèºê”(Š¢(Êÿ>]ÓÐ1¦NF÷c‰‰M¢¬p%ž~Ãp%ÄÐì¯EFzêBØøƒµ8„—æzIKí~LÙ}Žgȸ™4W—áBÇ6]ÈÄ4†M½†ƒFQ²g' = Ívh®…ïYF¸}A5 (Š¢(G¦ĺ]X Ôï+Æ™˜LîqCØ¿c%)Ýâñä"l‰© bºô…E—ãN!³k‚î*kpÅw&&-•ƒE݉m¬%!%½Ó±èvÜqôЗ-‹æ‘Þ½ž”~øl†ˆ®hšfx ]W€¢(Š¢ ˜ÄLÒ{÷ÂátïJ ÖŒ!ndb iK4-ˆîr5à$$&‰)É´Y1t+8Í €¦!q0hä$¤°1¤àØ´<4acI g—wá1„d]ڠ똦-îáu @QEQŽJ 1dÍÖp ÂlʼnMat.MÃÔM\°Á´|H$ˆÄ6A8üX2€­ÙH'h&„t)‰ µ¢#±­ šѼÿo¯(¥š¨(Š¢(G‡–icë[wÒhš‡æͦ™hºŽ­kÒB†f 9#«¢#¤D“fxf¿¤¡k` Àˆ4ì!Ð4„4ÐM›ØqÑ>(Š¢(ÊÑŠdø&„!Ðí8š‘;èºÙ¾5ò¢C•ÿÚ—ûÕ#5¤X¢½r †Œ,'Üþ:¤üÞRÁ .(Š¢(ÊQ#¤DÉ¡ž¸äÐ ýCm·ö‚?{ð‡óÛ_÷íÊ€×ÿï˜Ðþ˜ EQåèôÿ£ vÇÂ=wÉÙÿWõu:>GÓ´h‘¦Žyþí }tô@×£A]PEQ”£D¢iÖ×Ú‡ù#í½nèß©Ü×þüooïØÈw)èP´çü·ùë8@Š¢(Šr”F4ôh£oášK4ÐôðÈ€®‡oš¦GÖñ 7ì†nRZ‘ù‘=¼_CÓ2<{Àá‹ BØá¿)/¾ò¾§€Ÿ+®“àI¦d×Nu0EQ"ÝÚ„Ä$u;$:H:.Li``¢ ƒV_€¸xU•µää䀌\³×- †0Ñ4ɾªL7¤''`# ‚pïô#tšp¢éh‰†D  ¡I „Y×ÖŽ"Qˆ)¶.°, ˲ƒƒAü~?@€` @sÀ{høâ¿=®Ó ¹±žÁ'¦†¢(JľÒbâ=ê@D"ÃÐùxùFž8݉—3 hiáÓU›8aðqÌû÷ßr1¶¸Ýn$&^Û‡´¼¦ÆûŸ|ÌŒK.ÂÛÛ ¦Ie]•~ÁÝãA4ã&˶Ɇ®aY&±Žm ÝéÀÌ\üB¸ûÚ±++% B€¹Y6„¬ð-ù¹óΟp¦:§Ñ @CŠ¢(‡š©·„‚>Öîª$7/› Ÿ,%>®+çM=…+6àŠóêNdÕÆ­d?ˆ—ÞùKZœ~êöêÁ×JY²h£Î8‘˜Ä.|¹liI±²®Ž™3&¡Ì·’ªƒmŒ8©ë7ï"( i ˜|ú±Ìùðc2²2Ð1üàMÜ t3²­ý~ä§¢(Š¢(G2€Ëa’ŸÝ…ìÔ$NT@kk ¥ |Î .?Œ F îËI}óhlò“”FçŒ4ܶÎo×]{>›v5‘‘塸¼ž¹Ë¶qñ´á8Ü|„hl<ÈW[ëÉéžÏêMe4»3¸hÒ ôBKô°bu±9hi ª4@EQE9Zb…díærÞ[¼ÃM}Sk8•/Äçóƒî¢­ÕÂ~ZZ% —ï&¼ê–P+Ý:ÇQ^y§¿™né |2ouuN$=6išTVV‘™™FÀׂ°CXÂ"NX¸Râ(Û]Ic‹_MTEQ”£Bƒ - ÖŒ8ú祑˜–†Ó­Ñ»GW\NÁ¤a=Iõ§%péä©ì®,ã„A}±„Í1}º“ïbÜ ,Ú¢sâè“ÙÛròûHËÄ» 2’u .ÃÎ’bŽ?®?û*qÆ@§N‰t1;‘Ú%“®qôdÇNüB8EQEù ,,f;^%3)ËÍ+èœÕ§Ó…ÓåÄåt¡zgÅ¡éñšŽ®ëtÊî‚ fÓ«SfxQ`Ìt]'Å DÓ˜xJWr“R0“Ðdg‡‚S ²ˆ—ÍÓ )%ƒO̬¨k6‘_Ó@×Ã?]˜z7øƒáßµH£(Š¢(Ê¿EJÉW­+˜«}H@-œÃÉÑ·m;²$@x¡¯×‹eYhšFSSµÕµ„B¡hm)©n)£s|ß\t;H„ä°•ÛWì¸`”9Ÿ/p¨ñÿh¼0>[K7„·ÿý3ذVmšúðó*ë î :£Š¢(ŠrÒÁMÞ›‘šÄišT¨Æ „– j%¦i ¥ÀÛæÅåtòÞ»ïÑÜÜŒ‚9¯Ï¡¶®–¶¶6¤¿^ÁüÏ?ÅáŒÁ4œ¶.AZ§Ã¡i˜†¡éx[[q:hš†ÓáDCÃäÔcáÙ¹p÷Lxyd¤ÂuÓ`tJw—Ẩ`ð· #%<à@À¯Î¨¢(Š¢! ÷Ì×n^Ê×Vз_?N?ý4 9xð ÉÉÉhšF§ÌN¬Y¿ŽÑcFãrº(-+eÕêU8M'[ 7¢i—^v å%eÜwÿýĸܨ:À 7ßH¼<ÿ㣔—йsgÎ:ë,Þy÷]0tœN'þ@€»î¼ÏVÁŠÂpná.˜xJ8Ç?Ísh=€^ @ ÿ+Š¢(Ê¢k:n§€>Ý èÝ»7q±±¬]»–믻Žää$JJйóÎ;@‰CN$11—ÛEß‚¾Œ;– &””Ä­·ÝÊ‹/¾H0$ЧOoü>ŸM×p¹\<øÐƒhš†išÄÆÄâp8hniæ<@\|:—L„ÄDpÐ-Ê«Ãs¬p”BÈ ·û`è …¯mT¢(Š¢qš;œ}¿zû²:g²- úöeíºu´z}tîÒ%¼N¿Ã$&6†`0ˆmÛx}^öìÙMIi¯Ï™Ã„‰¹ä’KHKOcëömÜy÷]lß¹-l¬Z¹ t5ë×1cæÅ466âóù0 #2™pâ©’O¾‚OŸ†êz¸çY86\.¸`lx.Àîr8¶äd½/Àðà B‚MÉ_Þ%+§ûýŠOº®³}ÓŽ:Lý“+Š¢žlVQVBZFæý±0 ƒ•+2Ò7 Òa.ï“К@BbÉÉÉ455‘ššŠm ’’=´µ¶a:L111475KSSn—¯ÏKJr uuu¸Ýn ੹‰ôô bÝ.þçÉÿaܸ±dv팮´´¶à0Ø–Mz§ttMÇ亩pí”pÏ>9^¾7\À¶ÃÛ&œ~÷ÁP8`ö]áû¡lW…oEQåHhèœo_@ºJ¼OzF:1±1†AçÎq8¦a¤¤¦ iZ´·ž’š‚‚´´44M#!14èÒµK8¥O×ñ$…k.HàØã‘™Ó•Ä„t]'Ñ“øŽº]ß¿]È 7î– Ä¡ß,+|ßDê*Š¢(Šò¯F0™*¦094žDyy9Má=.Àg[áŸB*È „ ¢¢]×AFê,ÈCõÊËÊ04i 4 #†'!..úa „‡‚)ÕRÀŠ¢(ŠrTH‰-lliSUUÉî]»iii£¦ªšêýUH˦úÀª*«ðy}ÔÔÔà÷û‘R²cû>]ð)MMMì¯ÜeY¬;H(¢¶¦Ž'Ÿ|Š€ÏGCÝAZ›x}ÔU×à÷û£šFmm-ÍÍÍX!‹Úêµð/iáâ%8&§Ÿvx á?=ñ$Ó¦M¥[NοÜǺõëÉÉÉ!³S'u@E9Ìîâb>øàCšššèÞ£W]~Ù>÷¿ÿ‹/¼P´ÿí@ššš8Xwú†zvlßNrBë֭禛n¤h÷.JKKinnbøéÃ)+-gèI'b~¿Ÿçž{žiS§²há"6ndÖ¬Y<ù䤦¦RQQA[›—]EEíÚÅñƒÓêó2yÊ 7²jÕ*tM§oß¾d¥¥£#,þõ͎ܬoý´ÕÙü ªàG®Ø°ó›oxóÝ÷Â!Ž@cC#@@LEQ³zíZž}îyÎ9ûln½åfz÷ìùOŸ¿³h—:hGƒ¦Q__OF§Näçç—ÏÂÏ¿àË%‹øüôîÕ‹$‡°`ÁêêÑ4˜Ø4]#11œn9”–•ât8Bàt:1 ƒ–æ^yå¾ÞXÈ Aƒøô³Ïp8œ Cvv6[7o!>.Ž/—.áåWÿ†¹oøåákýÈHÚ¿ˆ\/°±meYXVˆ`0D0$à÷‚l6rªÞóO ’¸Ýn–,[Ƙ‘#ørÙrôï½NS]]ÍK¯ü!7ßx#O"Ͻðûöá„èݧ7óæÌW_}ÅñÇÏùÓ§©¬(ÿÅ^{ãï<ûô“†@ú°S£}þÅB–,]JÏž=¹ü’KÐïöù|ùå—ôêÕ‹Ë.™‰¦iÌ›ÿ1ûöí#3³Ó§NUøÇñ“‘щ9sæÐÔÔÈàãc#©­=@cK3±žü?»Švþò}躎Ëåbó¦Í¤¥¥1ûùÙ 8U«WñôÓOãrº±l›}ääd †ØUTDjj K—.æìsϦ¶¦–ä¤$Þ÷]~ÿûßóÕšÕ˜Y )ÑÆ¦}}àöÉBB¡–eý¿öÎå%ª0ÃÏ™3zNsfEÌ3Ž“#¥v¡R*­…4jeÔBjSN¸p¡¥Žš©…RáŸê¢u£ •x©,/ ƒŠˆ„Š4˜ G;ç´˜ Z墅çÙ}¼»÷[¼¼ü¾K,ü£Q–D‰%q‰¨%E¶¯ùë«åTõ Z.^â@I ápY–pØíq½¾ñ×z®°°ð ;vúðž¦@+û÷s²ºšsMÍ@lðu~ž«½=\îéeüÙsŠöî1 61YƒèºNV¦;þ¿óòÕ$Ã##´µèäÖÛ­¨ˆë/&&§½5Àþî q¨¼œÓ Ü»9À–¼<Óànÿ`E’’ÔÕÕápØ‘eC×èìîD’d,V+U•UH²D0$-- ]×q¹\tuw¡ª*sçÈòfQT\D0D±)|„‘$ v!‡×³³x7æ°²²Bnn.þšRSSq:$®“ÍC€ÿ›Lwçꥭ£ƒRŸ‹%ö Ô§Ï_8\z—ª²}ÛVªÊJ™œšbèþÊ|>Ç*Ž oÞ¾#¸¸Èõ¾>B¡‘HØ4×ÄdÍ–Lƒp$òWmzf†ö@ ŠÍF­ßÏ£'ÃèSÓ3´š±ÙlÔžõóðñSAàLåqv¢(Šiðêv)11¾’m6~…¿h­"š¦‘œœŒöCÃÐcåÜívcÞl/{[@UU»BºË…#ÅIz†‹õ.–uœÍ›@´ a°lhx²½ØN òòóù ô °POnæ¨IEND®B`‚paperwork-2.2.2/doc/flatpak_saned_3.png000066400000000000000000001245331456262201400200320ustar00rootroot00000000000000‰PNG  IHDRl(|VËÃ"zTXtRaw profile type exifxÚ­œçu\;²…ÿ#Š Þ„»ÖËà…?ßF·èDJ¢4âIuƒƒªÚ¦€¾fÿÿÿóþ4磉©ÔÜr¶ü‰-6ßù¥ÚÇŸÇOgãý~ÿäùüͽÝøúüÕó3ð3{ño¾^.tŽR×9MæzÌãºÎ09}ç(âÎsNÓßûe^ÂúúG D0Ýi®<`·ãq‰‘Ükn…çÀqÉFc¥áÊz^€)âÞ‰Á¸@lv!¹ìlñ¾8ÇR20Öœ±#Fr¼!'tÁ:>œàR \}…’×XÛ£ϵa¸A¥À•4lÛ™ák£›%:ÕCž.×%Fž„^Š–ï¿Ãד}¾óu¾óu¾ó¤ûÕÚß%]6µQ3 Á¬õMÌ’W­t¢EÁ±¨–8ª[6çtÍu߃œ8£V]|-wf-Ä ¡´©N%3’{׳}Øàe]<|ˆ9‹{ºü8™cóÖÉv0äÍ·u(m;çšË‘fB0“†/üØf-ýºÖùQÐ\àá›ãuøÇƒï¡ äçG÷âæ³«ÿÍŰ5ò±A N$Ájß¾Õ,“3Œ7óš;ðT±êåXî’W®=Lê ±Rj–ò…Ð`„„šøuµ¹³Wðc´_ÍÎcüP6ô®„i@iŽj 4°Óé–ª ðÉ 7sâZŒ§ÇQЫ° J`#Y‡Íšâìiú>Àõã8@lx¦ïé§CÍOÓø>=~ó@¯1î7îçáÉ.X}Œlü8éOµþi'ºv Oì3ÝOÜm–87EkÏOn5™s‹‰;QN–Ç¢ª33¸AІòíılkI ŒTÚê‘ÐöJ¼#š!J®ŸeÌDìÙ)m,…bꄵ¡{^:2à>ƒ}ÁøQ !5Á@»Ñ¾("`,H¿:]ï§ì‘ÉÜ^öÿ‹¬ oô™ux#¼éY¾7aY™«ùd ôŠ>ˤÿàb£0{œ‚’9y‹–*åÈúp§l(È4`Qd8±ÜºÉÍ¡ì&R­%„V¢R¸ÔäáÑ!ˆ±‚‹ðWªzž»—¸áˆŠ†ªaY½Z\63Æ zŠmù½ÓIn‘¼­–ëBÞ ò¸¥Åm““Ë;Œ\ا›1TÁ›;Üé=ßZc3¥ÐíÈE³ dtìn » 6j ›H½Ç”Ýæ"WMy|?¢kŽÝ!è>gèDÂùQ}N¤b~U%ç< †ØÕ2†ò¬ÍCw4r­ÑäÙSjy£õ 9bõ¤©!Y$‰÷ ‹ëEت8Ì@é*¢¸:2¼€1Ñwîrê† 4/0u­0ËÈ}’(£ ²¸Ã´ywÄyj•±û71Í-ò„ÖrFYôÆmÑ« ïPjœŒævZð z›IMÈÒ­i‚rí•ÐDuµ»!:x¬ÀÉÛ`Ëî%3Á'Q‹d©q-ÉN\DF/Ò¸7¾/"L~2P)ÃýÇF„â E“dRq øÇ]m—(V_ÆV¤n®iqã @ÌD¶cÒøcæ¤vnULò2Éä0Ö$¥ElÐ뼸,) ·Îs$²æ´b eG.Ìß™rg†ð`yèØõØ€ÍI½àN©D]Ä’GiNC7”€n®5ŽÚÆ)‚A’¨äH³¹Ü‹®MŒ'Á’ýPø§CÒ\9Œ›ͺ§ÄCšx˜jFÑ»*Øç1 F[›¡'ÚsO/ÁÀ %â̘·ß<  3 2¤~g®ÀëR˜ex˜Té†>[ñð Aæ ý&H›„ âF½CÉŽÒdîÒ:ÈšSš?ÏLž¢ §Ö¸'92ÏaÆ-"ÇÂIW9ú†%Bð½¨Ýf!´ƒ¤ƒÍ ¨8`)C4§$ü:`’…âøâÃyIP‰˜V¶É *PÜIOD/ŒaT—•~Ó…Èô“eaN h„ÌJ½‚ö TX8P”Áþ¼À\÷ÈUÛ0B¯í"òDŒòÁà`šA³¼ºôn‹ª[òå~G;u˜ ^Y >Y9[,-³Ù,Ü{g€•£@9õ‘)®HBHNR4X£P1®¦!5€ì¬*r÷T|%˜9&¾`²j"]üuÞp®Ä;IÒ9bbO;u&b‚4ΓsZC¯J2h)  ç)©.†•Iç,l ìOËO&ÛîˆxáRÀZv j }˜‹Žƒ%ΰO…²AßZ‰€c­ëåðDT0yT¨€ÆD ¡äRÜA¬‚£¹3Ûk5øE®W åü€n⌻O4N ’lü™ø”¶3ß\.Kš {¬S‹xwȨ˯³÷q[€å m\âNæ)‘·žQ¯Ž´“Na¢@x&â í$©.$O$Ã"™?zZ U®«µˆ X y@$ ù™:y´§©“1¡b@¬áH»9õ¤áÀs°°"œ9`ʺÕPæ[’$U 6¬š·™uL+ -¡š ;»gz—BJr4 ºÁ̈¡ >‘wj·73" <@0EüöŸÁW7©=JBFÆsÐÉøc¨l[!$'ôÅD€òÑ~'w%P¦²ä00F7ˆhCXJˆ¢-N*†)*Z³ö@šÏA`•Ù4Ɖ͢î¯c’<«"E´£E½>-¡ôŒ« 3 !î Äa<ðqÀ´BÞ!Ù)_,ƒƒ—ЇìDà.„95¤•èÕÒbµÉê§‹’ùÏåi>UI„ •’nȸ»‚k›b)¡ŒÂWzq¹3Éê F&,¥ Ü ¥3ò®ë;%­ÆD€ §(™ÆÔ²—W^í¶ƒµIBK$iÕ‰$2¥kŠ€=Z—I‘¦ÞÖg°¡7Rî­C ·kXÐ8$l>@§@„ï§kÅ¥ÁæñÊÈ0oÓ7¤G©õU¦®7—F$fêÚÛ×õrýìdùÚÏ5½zÖ±_ù›‹šÇþíEͯŽýÎEÍŸ<ÿŸ\Ô|wR¿º¨ù—H½½¨ysÕŠù=ÔÙCþß¼€¸'û—“­xí^ñCò'‚mZ˜¡&®w U;X¥*y]Õ¦¤Š—]`.¿0ðú‰jÚ¥TiXPzf?Þ@‰c>(ò'HEs†ç©c(#£]—Cbª½dš‡ŽÐ\µ&çáhœu•ÚÆ0hyoƒGˆc„*A¡UµVRë€w³~\çÛpŒô£¦,èöhŽ-Ì[,8d8ÂÁÁ½€F`¶ªî씟ñ@4¸œÔYrQ50D–%ÄàÞASµé ËáZYõÏîE®ZÈÓ¡BàôТ91ɸ†uœQË£‘-èƒ-P豀 ìum_ NpR±¸,(ÈBe—D¤ŒsÎ>˜Œ‘vj˜aBòpëÀü6Ç„€ÏŒ 3؃8¯zÇ<«-:ˆUß–¾PåÐ+*ÍÀS|75ˆTNÌ\©d´{D僪HÑ:p…­nKÕ)§ÊP˜’û’,È("B[W(äÑ© ›Í‘¼óEØiÙ«Í“Ža0˜¾’H…¹ÁTŒè4-ê@»¤e4$SûúUË£Œ8#z9b6&·T¯´@=ªÙO¥¦® †:§h1„B¬Úh¼ { æ½ê0ÈL$zá€{Ì sA©h­ž)ô”ûì¸Z*2­Úšœ j‡y´\_Í0³Ì„+‡] Ðr$Ü[‡ ¥j”<ä oÓ¹0¼ƒÅ®/dê²D-"ø€&šÅwxæ+{­öbäFñhÇ¥çD a‡ Ô,F4–°ÕtMÓo|¡5±“E _ÁõáŠÂŠZÛ´‚ã>>göZ<ã‰2ã¦ÂÕO¹ ⸡ÓS!ÌkI8^õ©<ާWAâÍôçHÀa ç<ðÀµ‰UÒt ¨îX–mÑ[1ÌøD~7{ º£øºŸÐéè{Èå´«¿€l"#°JÊ܈)寤Æhïž1=hÖê@¥Æ2&“GÓÁÝÇ0$›ä ­´ÔÌFÊA­'0ɨûMAv­­5âÆ‚s12zb…D¦—ŽÒ‡sźZHDC<ö!ÍLœAƒÙ;^›œbÖú3ÆÉjCmÞà´ð£U“èaæ<ãÔz¥ÕxæÍCTJß² X ’‚ßç!}®~—’ªÚŽÙNQ6`«O¡%jíÁ+„-õ«@Þ5Ê‘°ëÄ ¡šE]Ì->I8€Q¯·Ñž äÍ£G@ñ\ÞHN·5Z-@=à(%œÕT'ã:œo°PXÔZCÆútx¸>H»gÒS1L’Üô%•@Ü+ ¦µ×=x @}œ¬ é4I¸Ô¿‚š„?‡©§C¿ä·ì=nÄ“RÐ7!¥81yð7\]Õ:šd"ت­WÒÆcܟͶƒ`¨ Ò×Û|wO¿\ÄÓº_ð§ï›¯˜B+jxàÉoi€¾ðhWÐÈ (­¥ÆøNÓ»¶KcçcµNæÞäsK@HADGÂŒð àK9™£û´jÜÍ:Žó¬i„Xä¾èHõZ§×ºÓV[‚Ò»k™Ç¡9lYmÚEù£þj‡Ç„©©{2»ïi§kœÇY9ªß\€LWÜ8¢·k·äUk…AÛHµÄ‹Ôc¿M·”º9eÂ@‹“çÐzËB{QHYM­Í#~¸<±LNÈñq—Ÿ?¼B¢ QÓ…¤á´,šzS×oÕ…ùxa ÓŽ¾ …Yówv‡b_ºÖ# PQ>"|L@<ƒ jn­WmyG¬ A“úžH“ÉÜÜÈDàOPwSŒf)´†¼— £fàPË«Ú àÉhí¼ë"(À«VÎoð–q<ç65ØN†QyÊá©m*¼WÔKÅymÿÇÔøtW"ºZNôbGµm¡î™ƒiÌŒZ´Úˆ¤NZéüepÀ0rjÑÂ"ÆGi´³‚ÕRżX˜nq¤Z g—ý(Êz<°Ä,;–ÞÊFâ‚h+?”öâh ÉÏQäÕ!Å “—õ–à–q“1jËZ5| è$] >c¨6¨/cÜᮀ¶w«œ6!,„Õ½´wæÌLEÛ…ŒîDÒbdôá®Å ’±[ï²köZå$«±åÔÓÀSê.¥êÕíOù.Òç¨MT#>±ˆ?çÁ]‚SIÚ͕ފRœìCPdo“Ù)fá‡ô=ôj‘z'= ó˜8oœÐz8A(I=û¨óÚ¦¿àlЇ*´æu;ËØîsF*'-Æ -]T7]¼í5Ue¥=j«OP ¡=""Ÿ@ž­F5ÄUÕù©Ú–eÔ)V+™{ܬlÒ ŒKe–yÓÆˆ-¦|ªr·M^ä·]KjmqÌH"ÛŒjjªF­wQOpSxJa‚ÊÔ–Ô‹¶àëÓjjá¬Í|³®æ¬ÅÔ`àc-TmmhšeÈõ|x,aöûg-­hïô$‘AÝsZ1duÆM(oÜtå1SiZsÇü¡nP¡è>ßLXß´çKK„È3·\w1ÆÈž`¡´[`l7AÆC -ÅOé,ÔÔ¤LŠZÍÙ¢’$½+‰Ü÷hãŠ)vSìiX)8 ãŒ-eøuièc9VwY”µE êã;ˆ ’IÍ6Íl‚Vd´ Âx ܃«¡üÚÀÖŒ—Ž“QO•"Rw(.jKdЖ‡Ã'þe‘´hø/|õÀðð^O¥^¤ÍѶmhàÄa“6‡A ]P³Ö"´º Ô„ÕÛÜÏÆÙiW2DXÎÜ‘Q þ†þa|)w3ªXähã[±w™Æ¬å5à- )SÊBO:Í•ÕYaÒÁö͈SK.‘G2÷P=¤ 5¡»… H‚£]|Ð$hÿGUFùÓQN&¬ûäâÒþEëµ’‡ì1[‘wiZµDÉ»ƒŸ@`D™2Ù¦ua+lÑ™ûaÉ.9!݃¬Q–Û…RmÚëúP1Ì)‚ÈÀ¾©!ˆ”¬Ú¹:%Äš%nå’V$£VP›+É3¹ï oø([®mÚ¬CD †%å”]PdÓ(ZEÍ8I†µ?‹I@°Ë?y±­õ´Z‘æƒ'¤áê†e¤Hµ9Úc\â^Ú¤ »dF¸iäKµ@{ããÝOù©3œµ­ij'WÔºhÕÎÆŒä˜Ú/‚uCªßNê-Þšº:ª¤2ͳ¨5ÊcO¹ÜºÂåè£Pƒ2‡†œö!¥9&2™r†rôq)oHE²œáiÕA*N@¨W}” ”ï‚• ü7?ͧopÏ ÷‡ ¹[š^mÈu!æaCð¨&ù÷Œ… j!m5 %© TŠçn%Õ†tÝã,Ò¬/ÎÓ¦gãïgPàȤ•t€aÞ.A}ç­ƒšÜÛ€ÜZ¡µ'hÑN§ëgR}}õa`ÚHnßÏ' q´6¤àÊ‘µBZ{Hí¹¸ ¾z}X%OmÉÄ©kÙ#NÝ‘êž\ìc¤ÚúEÔQœÚö(µäÑÂË©`Iö(¾ƒÉ¾[3µÏE›¥!ÓºùQÌ J&.8{¢@vvYÛ¶Àß@¬ƒÆDŒcŽ>†aØèÜ£OΉ²7\¤"3®>åƒ_ÙÚïfÚ7CûÕ¯Â!\RGIVhÜ©ÝãS[Tб#‡³T/#E¼Ï»­µ9™£TWê’då wdíMEô@ ²ÄI„iÍÆ …)gõVB’&Iðú DêÜ š\D©; Ô¶Ê_Äý|,];ªÍÜeOŸµ/°2¡+è“% Ô¼ä­d\šê,9¥„G íâ¢Ò(ik³õQÄØŒ}á>ÑÙUkÚj!”;7vܹÇLjµ¹g¦³6NÍŠVå}ÎÈcÌ.N5Ë8j¼úˆ„5!`¡j³qÔ3¹{5GXÔŒõöZí4·. ¦ÖnP-iáIŠø3JÈô5³Z­/í¬–…:#û2¬öÛ6íùÅeo™± ã6£fµÛªOØQZ~ZQ̺û’ÕãÛ“Ú!]Eë ¨ÂÃÏZ›7êá%0Âðh‹× ˆZ*"2PM9íZV÷dhïªvþyuMp¤HXê  XÃ炜¦E´LÜýÐ(*ÐWN+«=‰‚ÂHjÒÒÎZ°Âm­5Éu G1RuLéÌNíE ?‡tÈo<.‡ØÕÆ–Þn/ônÕÁ]ïüÁméå§ùøÂŸÿ|vaГ„ò˜u‰6ö'µ'EæZTzY†HB¢ÇZ>JX[@wêó€t¹ojê~NÊWíèÛˆ5ŸRÝzØG­w5òVîð©>vq³„̈š}¥W}øàèS®ùçÔ»ßihú,šô(îð|8Ø|u‡ßßàÇ)ÚÕÚ«ùæY_ÞÈüîNz#óÍG’ý$²¹›Se^û˜€@…RU&ˆm¿ø8Ìûý»/›>Ìݾ‹±S–aRþ29m2_½³…7)xçê•—± ôí\÷C íîÓVM$U&xp„‰K¯÷“!ú@HÓ*?X¹<èÇ{IK€Øæ€™¦6³öâq¦ºj~áQý¿4 `àKç@(··ÓÚ vÄ/ ¹ie¿BWúŒ@YêècI”©ÁôLÒÏií™Ú >´ã N¥$3Gm6ý¯,fíê^OäSÖ‡ÌÕë0GjØߊ%½»)ô9¨í°c*Ó]ò]TD¯jŧï˜ûÖ–þ–•ƒ¥ñä&õ™ËØúíÞŠBµ‘âî²x,ª~|Ï<ßz*d*ÝÞ!•—¤{kûêîôùð®yÿö§C{ó×a½{Ýœ?ÒÌ’y¾õϳd^ÞüÇY2ßþÛY2¯oüÛ,™—·þq–Ì›7ÿi–ÌÏoÿù,u¯Ï^@Ðu °Ëú„< Ë`nîÙ‘©Ÿ~TEØq¸a£è¢C ¬T¥nÌ—gé+Û‡_Ôf?}`8WÞa´´‹Gƒš½wý?êãÿ5ô?q¸Ö†6ó_§«mXïWŠ!bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEä;o¹k IDATxÚìw|TÅöÀ¿÷nOïÐ;ÒDŠ€ˆ(‚¢"úT°ìÒ©DT@¤(ÒÄò|4Az³Ñ{I!¤·M²õÞß›]³ÉnXæûùì{²Ù™9÷Ì™sçž{fFZ¹b…Ê I¹yy<þøãL}5â @’$6mÞÌ×ßýÐ :´¿Ž>·ÝÆÙóçøbÅ* Íô¾µ';väó/–£Ñi9uæ,×¶hŽFÖ²kß>,+·÷º…N: ( ÿ]·Ž»÷Юu+N>ͳ£F‘œœÌšo¾Ãj³rÿ=÷ШQCEA þ©h¯´ ªªD„‡óôÓÏ0nÌXZµmG“F¸«ïtëÒ…¯×­gÀýÿ¡v­Zäæåñܳc™õÎëè4:¦Í|›ÐÐPt:Y9Ù ôF£UQèzCgÌEE q­Z¶$%5•oÖoàéÓØÿóÏœ9{Ž‹éLžõoOžˆÓédĈ¬^µRô¦@ ÛŠ¢ÐýÆn´lÙ‚}û÷³eë6ôz=ýûÝ ˜LFŒF#'OâÚ¶-‰ŠˆÄ`0Ðú𿤥] âb㈊ŒDQŽ8ÁªµßDBD8§NŸ¡W÷ &:: EQHJN!@«aþ§‹Ðé´t¹ñF¬+:½^ô¨@ Û†¬¬,bb¢éuË-¤¥]Än³¹B&¨Ø4 &“‰ÓI©¨ªŠ¢¨ääæÒ¼ysòóòPUWD¦¤¤„å+VrGŸÞ´kÓš~÷ôG‚CƒÙ¿å7> CUTTU%.6–Ì )LíÂBÃ@’@UEo ‚4šûî»ïÕ+)(I™Y™ :ŒÍ{öðåÚo±ZJ¸½÷m„‡‡c³XXòÅJLí¯kÇÅ´ |úÅ >ˆAgàÞþwó˯¿!Ë2Íš6EUUÎObûîÝüüëT–oèLbB<Ûvì`Íwÿãä©“ zßz+’FÃGŸ-Å\XÀ¶;éx}{Ãÿh¤+}éè‰ãp8½^O`P ª¢ât:),,D£ÑŒÓéÄl6£èu: $‰   Ï,Ûjµ¢ÑjQ… À@4 EEE8Ž8ɶíÛ5â t:…f3ª¢ Ñh ñÌÖ@„DÊ!˲ÇÙºQÕ. ó Ÿ„††þþ;U%88Ø«¬ÉdÂd2U¸)8œN´Z-çÏŸ£FB b4ê©ß¨)'OB£‘Õë7®±¢z•ug³Ûxÿ˯½þ&úB|ü}.¦§S£v=2³2‘eØûóÏÔ¨UƒA‰²Õû§½b-T[˜OÂb³Ó£[WÚ¶¾EQQ'%‹+|!I¤¤^`ý¦Í™ÍÔ­W{úöáÛï×Ó´U[–|þ%×_×–»îèì÷> nݺœ9{–¶mZsC‡ëùqûN> @—ÎhÙ¼™Ë†%ø~ÝÒ.¦óà}ýÑ‹ƒœ>ˆŠŠæñáO0îÕ)tîО×Þüo¾ý›ÕV¹?¬f_yÙ3l± ]ð'xlLÞ|ïCx–CždÛÎÝ^¡EQ0 ÔH¬ÁÜùŸ²á‡iX¿>ZŽ¦ÍšP·n]fÎ|›S§OÁ€ƒ8xä(99Ù$”žTôÚë3ÉËÏÀ`Гz!‰oÏ¡m›VFÑ?!˜:qç/fðùªµLxq$­®izÉ“®ªÛ]^þ [R‰}‚êu×*V›á  E³¦(Š‚)ÀäÙ£FQâ㈎Žâè±ãr>9™ž=ºáD¢]«V4lPEu=~|à>ÂBC9îÕý‘P•ðÐ0¢£¢ˆŽŠ"( Ðõ†Ðiµ¬ß´™k¿¥ÿÝwÒúšæ ª¨NWŠSñÔ :U$$$Y¢ °ˆ©oÌÄbµ2üñÁœ8ð‹§]£AO½:µYñÕ·8NÑâã÷“™™Å¨QÏ0æ™QìÙô=6¢Ó ÝÐkõÿŸ!ì+=À@ô øüù½^À®}û).)Áa·säèqŽ?á™™7¬U“5ß|ÇÁÃGpGP>]ö9+Ö¬å£yqc—NX­6róòù߆ÄÔoì©ÿ¹=<€Ô´4Ö|óxñ(>~?111œ;{š›ºv"/;“ñ/>CÒùóX­–K”­ÞÀÈe9l PJ"â#>ÕõQT…ž]:€¢þn_H4ߢK§Žtº®-ç’’èÓëbb¢±Ùí¼ôâÓ„„rüäI¥!°Ð0Ò3ÒYûÕjZ4oÆ£@§Õ`2™ñðh44:-#îêMDD8Ã{ˆ´´4ò DˆoUØ,E® ð›Õ‚¥8U’*/'Uo¹ÊÛ«J’ÄñãÇpìvqÆ¢ šõdUU+¼Äq/¨ñ•o­(Š×©G†Úõ±o÷"#"<õ•?Éë–%ɳ8Çó½x=#¨f»Þ°i3Ñ1±Õ²Hë2_:J¥i"ªÕ‹¢8/ù½¯—;.§L©Ã–ʪî¹ß¶‚?Œz•ó°…»üU±;œìض™ÐÐPa£‚¿†¿®æ4±pFðϪJLTôïv*\õGÇ«í°…Ç‚«Âå¯t:‚«â/¯ †­^r9¦@ (=Fý*í‡-I6‹‡C¤õ AU|¦â¼JG„9œâk‹ýƒ J[Æ`:pu¶ª(c³ÙDOÁ%e­V[}õ • Áßä T Âa @8l@ [ Âa @8l@ [ Âa @8l@ [ Âa @8l@ [ Âa  ګѨÙlÆf³¸NeHOO'** YþëÞCrssÑju]vY§ÓIvNN‡I’ $((è/y’$‘‘‘Addd…þ$‰‚ÂBÌ……„„„ðÿg7EE˜ =GÔ©*$&Ö ;;£É„Éh¬öþ6Œ˜þßõŸžžNdd$¦ZëÍÎÎÁjµ€$¡×뉊ŒüËù÷ÿ¥ÿììlªU×ÿ¨¶F£¡ïýR\\Œ,ËìÚ³—9ÎûK;kY–ù~Ã=Š$IWt“þô³Xm6:ÄcÃGPXXø—¼V½^ϰ§ž£¨¸¸Âߊ‹‹yé•Iäb³Y¯HWªÿ»vóÁGSTRBaQEEfdYæ£OpìøqŸ²È²Ì¦Í[غ};òeÈ*Ë2 >ýŒß¬Ök¬Š<:Ž÷?þ„’’’êiµÌ™7óÉɤ§gðü˜qü°åÇ¿ä¸û³ôïë&6yÚtÌfóÿ›-ÿífØAAA¼6~û~ú‰.;óÉÂ…Ì|}Š¢’••…¢(DD„c0ÈÎÎ&((ƒÁ@a¡ƒAN§Àáp““ƒSQ  44€ÌÌL$YÆépYú] åu7ÍÉÉ©P¿V«%''›Í†N¯#:*о½û ÕjJg ™ ¹Ú !00I’ÈÌÊÂf³¡×ë 0™0™LnË 80˜ÆѨAôz='OŸæÚ-ÉÎΪ Ff&’$a·Û %0 ÀÕnf&v›  @‚ƒƒq8””X(.)& «ÅBXX8:–ìœtZ-ÁÁÁØívl6AAA˜ÍE k4D—>Õ”ÕW ˜LH€Ýá ?/èèh’SR±;DGEâCÏR…þËÉÉE’$J,% ôz=………È 1¥õºÉÊÎÆn·£Ój‰ŒŒôD²,Q#¡6DQ”R{QÐjµH’ìj;;Ë«¼Ãáàô™³è´š7kFXh(æ¢",¥Î022 ­V[¡œÛÁɲŒ,Ë\HK#ªÌŒWUU2³²PœNÂÂÂ0™L>õZÞNL&Sy²³³½úßn·óÜÈ' Àáp`6a±Z€ˆÈHtZ-Š¢T°çÜÜ\´:f³™ððpŒCÅ›VGƒzõ‰‰‰æõ©Sxõµ×èÚårss+è=77Y£¡¸¸ƒÞ@xx²,»ž°ÌftZ­Ç.Üv 8.½i4„†„àp8ÈËÏ':* ÈÈp=I«*>ì$Ç#Td$:Χþ+åLJ牰Œ¼ªª¢( YYY€„ÓéIÂf³‘““ƒªªºÊ‹vix s§Ž,Z¼”»v3ðˆG§Õ²hÉRöþ´ŸCGóô £1Ìšý©©Ðh4ìØµ‹¬ìlO]…lÜò#©)6êiÌEEèõzºô¹›ÅË>'%5Õ5c™÷1gΞåðÑcÌýdºÒc{dY®Pvv6ÉÉ)Ì?Ÿ‚Â>‚N§åÓÅKؽwz½ž›îìÏî={9>‰¡#ŸB§Ó±kÏ^^›ö:™™™<ùì‹9z´ÂìEUUœN'q±1hd …>å¿ñö~ü¸u;gΞeè“£e™·mã㟒_PÀ³cÆQXh&77—ûz„Í[~¤¤ÄÂ+W‘“ãrz“&Oå³¥ËÐétìØµ›Ì¬,ÌEE<7f<©iiÌ~ÿCV®^ƒÑhôÒ—ëYÅh21iê4²srÊÌH@UTUE§Óy•Óúé¿ÅK—1gî<òóóõüh^{YYL{ã-¶lÝæÑ‘N«å³¥Ÿ“žžÁÇ qô˜¯Y³Šêùßò3ÓK—ÏÍÍå¡ÁC9}öK—¯`ÑâÅ>Ëɲäyü~Ýz>ýl R©œZ­–Ï—ÉŽ»9—”DvvE~ôZÞN´-”ÉŸý>ñÌ ˜ÍEääæ2øÉQ¤¤¤²tù –.ûƒÁPÁž ‹—}ÎøW&ràà¡JÊVQQU•ȈpœN½VWáúµZ-‹—~ÎÌwf“•Íóã^"íâE ûÊ«ñΜ÷Ù¾sƒÁc©Ò8xøÎýNËþŸ~¦V­FÒ.^dæ;³Ñëõ¾íÄK~§_ýûzŸã£À‡¼z½žù‹>cמ½=~œù‹Wðñülݱ“¤”Î%%ÿ%gÜWíYÈd4òØ#óÚ´é´o×§Ó‰ÅjeÇÎôéÕ‹[{ö¤Vb víÞƒÉh*=.Þå`˪122‚{îìKýõhѬ)‡A’$Ú4k°ÇÓ®m ÍüôÓ~êÕ­CÃõYûÝ‘Ḛ̈õ:Wý²,s1#ŽíÛÇÍÝoÄápzf\­›5¦ÇMÝéÜ©#µkÔ )9™åË¿dòÄ—i}íµÌš1¥\lPQœ¤¥¹ zæ{ïS¯n]"ÂÃ}Êßöš¦ôîu ݺt¡Ãuíø~ýV­ZÃ#$*2‚7v£¨ÈŒ ôíÓ›G~ˆØ˜húÝÙ—»vS\RB×®]8}ú ‡ƒ ›6Ajj*C?Âõ×]ÇS'³ôË•zéK£Ñ Ë2¯NžJû¶miÚ¤ ªêäQQQ˜HHH@§Óy•³Ûí>ûO–ezÝÒ“kš7çå1/pÿ=÷ЦU+?ú»÷ìñèÇîpðüÓ£¨]«&÷ÜÕ—m;wz= I’Ī5kyqÌX^=–/¾\áu^žÝn¯PÞ`0Bxx8ÑQQ(ŠÊ·÷¦{·.¼4v ß­ßèrHåÛ•5H²ÄÁC‡Øº}Æõ„0ìv;ØÌ]}o§S‡Ô¬™Hн–·“´ôtÂBC=òDDøî“Ñèrì*ôîy3;v`ì ϱióÒ32+Ú³,£ª*x€>·õ"(0ÐïØKOOç|R“¦NgÀƒ ¢ú¸~W}wÞчV-[2súT–|ñ%)©p_‚CBèw×]¬[¿Ák¼µiÝŠÝoäà‘#X¬6vîÙË=ÿé͹óçÙºm·Ür3V?ã\–äßå Ÿú÷5þÎ?Ï—+Vzâ’bΞ=ç%ïú °Z­ìÚµ›¾·÷¡G÷n<ýÄÃ8Ž?Nû¶miyÍ5´¾¶å_2¶Õ¶ª(´nÕ’æMc2™$‰´‹é$ÄÇ£ÕjQU•ØØXò @rûSÕ§ñMk&‡» DQœžÁít8PU•Bs!ƒÁ5+Ôjù죽Vñ®_QÚ¶nA¯çÉç^ä™o£×ë½ÚWÅéDUU´:-EEÅdæd…SQ°Û>g6…æ"ÂBC˜5c!!Á~åwÏÄE!:*šÜÜ\¬v›' Ô½[W¢¢¢<¡Géµ±qËØ¬6:wè@­ÚµJm„……q.)™Ä5p8H²DB|N§Ó£/w¨¡¸¤„[~$>>þ’1@·žýõŸ$á¹–€€ŠJŠQUƒAâT¼â–c'¼Âæ­Û\áE©ðtÒ¿ßݼýæ¼ýæ<ðŸû<3I© åÝ?t:8 N‡úõêT,',ÉœOvéËí,$I"%õ‰ hKC’$ùÕky;)?óõ×ÿeåu88KÛ‘$™‚‚ü öl·Û=æét:/ùòVQTžõ$7víâ÷ú]¶æ,Õ£ŠÝf§   EQHˆãÙ§FztPÖ~:v耹ÐLA~>ƒ~ˆM›·ðÛÜÔíF.¤]ôk'nùUÕ·þý?‹Å‚Õæ=>¢£¢ÈËËó’÷™§Fq1=ñqh4œNÅéD§Õ2}òd¶íÜÉÃeýÆMÍØþULE ì LUUøõÐa²³s°Ûí9r”¦Mš`4¸§E-}Q÷ûãêÞý?ñØÀtër!>².TU%±F Χ¦!É2ñññ„……S¶ñ€€ïú%Wwìp=KæÄþŸ~¢   ÒG$£ÑHㆠپsùùù”ÿµFÖÒ¸QC B–e¿òš)4›q:ÿ[’$NŸ9ƒ¤¨ÜÛïnj$$øœá¨Šâqþ‡,¢ªœ9{ÖgyY–).YK@JJ*V› sQ9Ù9¤¤¦ú,çt:¹éÆ9wîë7ý€$I¨ªJB|¿>B^^Š¢`³Ùª¬×²òTÅ~+„'5+س/]ú|±Ý ^}êÔ®Edi––?½Ë™ŒŒŒÒx}6-¯iNÝ:uÙ´åGbcbˆŠŒ$ÐÇLÞn·s÷}X¶|9mÛ´æÆ®]™ÿÙb¢¢cÐë´U³?ú¯lü5mÜØk|H’D£† ¼å $!>_!;'‡ÃIQq ªª"Ë>4÷ßy›+WUVúW½t,3ʹ˜‘ñ»!K2Ó_ÈÓ/Ž&(0G !>ŽøýLÛæM ¥c‡ë=Ú¾];1’¦õë‘’žÎu×µC’àä¹$á9>˜õ6/OšBÉÈ5×\ðÇyf¥|À«þÎ;rôØ >øø#ddzÜt“çeÍnC’$Oý’$‘“›‡âtòôÈ‘ zb$qQs_¿»Ê8•ÓÉ) Ò—üæâbÆN˜ˆÉhàÞ~ýhP¿O Ê+S¦°~ý´:¯Œƒª({n’$Ñ©s'–.ûœûï모Œ3†‚|—s©™˜ˆÙlfè“£°ÚìÌœ1ƒAï¥/€£§ÎR#>7¦Ná‘¡OðÍ—_xbŸé™Yžß•-ç«ÿj$Ä“_Pàš–†…¥ON§“¼Ò›¢ªÔ«[—b›ÁÞ 0(ˆ:µk{ R«Í†¹|抪ұÃõŒ~i«–-®P^UUn¾©;ÝúÜɹóI<9lç“Sx|ø ‹Š™9} uëÔ©P$ Íf4²Ì”I©ý ìúf ñèt:^ó"£ž‘à€@ž6„¦MWªW·8n¾©;]{÷å|R2O ̀LJUèÿó©\a¨2ý+Ipüô9ŸöMJZ:£Ÿ…F£ùË…E¤•+V¨U›K>|˜ñãÇy…þhJN§óªO–eOˆÝn÷ê®S§Ó¡ª®pGÙúõz=ŽÒÇAƒÁ€,ËìÞ³—Ȉp½Ú°Z­tP^~­VÃ}cþ‡ïy2Aܹz©4¾è¾­Vëu=FƒÍfóÙ®®ô->ªŠÕfCŒƒ—¾ ¥ÿv¿äq—/ßg†rå|õŸ^§ÃY:3–eÙõø\úßZ­Ö«ÿõz’${bæe¯Ë• "y}ç¾^w=:ÖgyƒÁªJrJ k¿ûž§žât”éÊ햕Û`0x®§üuºûçRz-o'¨*6»Ýý°Ù¼ûWUUŒF#V«Õ§=—•×è)›îº¼S9½¯ßét2ëÝ÷¸á†ÎÜЩ‡ÓËÞÜOw‡Ãÿx+c7e¯½*vâ¶uú7øÑkùñ¡ªjyݶçj_\"eßQ•më¦'~ùå ‚‚‚ª¥>íÕ`«œ¿¢(œšªª¾«ìo’$ù®ÃÏÆW®8§³Â£ž¯úm6RiBNn ñÌ¿€¯½zÉkðõ½;¶g³Ù*üÍVÎY•åe÷U¿Ýá€2{TøMÙ—ýïò}V¾œ¯þ++sY£u‡¼~k³ûµ¨e¯×_yL’„¢8±Û¬^õù*WVîª\ç¥ôêOo¾í×V©Ýù²çò¶a÷a+þ&[å¯ßí¸‹ÕËÁ»ô%Ç›Ÿk¯Š\Jÿþêö5>ÊËë·ÿìv‘‡ý¯A’°Ùí,ûâ l6#‡ %<<üŠîªŠ¢ÐẶ^™,‚êA§Õ’è'>.ð¦v­šÿEWãþkÝÌÕ ‰üó|¶ä‰¹º-ÿÈ£Tu)™„5Ðh4^ùðU±ûœÜ\&LžÊüæ`±X|†Ý}Q¾Žòvn0èyà±!Ìš1•ð°°*ùòuüÝn8WÅa; ¹Ù™4oÖ½^O»6­=Š\°è3Nžúd9ÙÙ ø 4`ÇÎ]^rìÞ»—µk¿!,<œaÂh4²|ÅJ9B£F2è1ùùù|¹j #† AUUV®ùŠn]nÀd41ïãOÈÏÏgð G©U³&K–}Î]»’˜Xƒ={÷Q·NmdYæð±cìÚµ›ö×]ÇM7vÃét¥d•oO£Ñx]Oß>·óéâªé¿°°]{öò˯¿Æ &:* ³ÙÌœç¢( #†#<,ŒUk¾".>ޝ¿þ†'†C¯Ó2ágØlVnéy3]:uª°Œ_’\ÎE–\7_Mé “e™ŸùÕg¿Uhß·üf>]¼˜¬¬,zÜt·ö쨚y”óè#Ó ~=/¹Ê×R:øá왳<üð@×fD¥ÛΪ°mÇ~ز¥4çÿAÔ¯GNNN•ô‚A¯gáâÅ>|„ø„:^ßÞëæQ^AÌš=½NÇùóç¹ïÞþž™~ùqÐïξ\H»Èä©3°;•ÊáF£Ñ°s÷¾ùö[š5mêåå0ÙUÆîG>1ŒE‹—rüØq^š0‘gžEpPÆk|Œ1œù ñЃ÷ʯ’’J»¶­ùdÁ"l6+½n½‡ÃɉãÇ÷Ò8€îݺ28qœÞ½zÑå†Îäää°c×~ýí7´Z ÀêµkÉÉÉaøÐ!ÄFGówrÙWe¥£,KÜ{÷] ùûþ™B³k›LFCíZµxyÜ8رk7†”Ô $%'3qÂË\ÌÌä|R2/¦³yë6fLy   溣ÁÀ“Ͻ@ŸÛzñÈñYOÓ  ãö>·ñèC1l(©Ò˜ÿé"žî5lÀ+¯¾æeååÐjµ,Yö9™™Œ;††õ`47a"=ºßȨ‘#ˆŠŒâBZš—\ }Fqq ÏŽÏKãÆ0ðÁû1™L;~Y£aÚäIôèÞÝ30Mü°e‹gÎ7ß}OHp0ÏŒÃm½neðcrÍÍ}p8œ:}KiNnn^v»‡ÓÉØW^£Ïm·Ñ¡}{ÏŒ´|{@…ëÑëuUÖ¿ÓédÙÊUŒñݺváÍ·f¡Õjþôs ô<4gGC¯×“vñ"ß~÷=O>1œññLš2»ïêËsÏÛ¯ ÿÙs„„„ 8,[¾«ÕÆù¤$$jÕH ±F j&&2ñ¹§Ø²m›k3,I"9%µBýî]ýE¡ë ù쓉‹‰aðˆQ|óÝÑhdÚµmï¿`ýÆ8œNlV+*j•ôçp8øqëv† D`@÷ö»ËëQß—> Ífj&ÄS§v-¢¢"¹ïöÛ¸vÑVp[éâž.;U©îëpØ´iÝڣϤ¤dÎ;WA»Ýîe÷F£»ÍîÊ›·ÿ¾È¦üøÐét´mÓš5_‹ÕjãLR­Z¶ >!Þc7uj×Âé°áp:±ZmsüøqvíÞÍäiÓ9q껽ôú:AÏ7ÑêšfÄÅÆR#!½Fú[ì}Õ¶{ÎÃ`Ðñ~Ã&¬V+½îîO«–-yä¡¥·óŠq8¥tïà¡âõiS˜7ç]Þœ1«ÍZºyŽoPÖ/X¬6œe6Š2H¥Fi±X*Èát*[€ßå0•>ªÿûó%—¢(œýe/µkÕâűãINI¡^ݺ¼>í5Ò.^¤M×›<ÎWUUn»õV¶ïÜņ?л׭XmvÏ–¦îê^%¦¨ PÑðÊîËà^~\¶=$‰âïëñuݾô_öÿ=ÿkO–[ºÞÀÔ×^åÍéÓP¬eâ”îßOžø ýÕkÖ0íõ7]視ÑNeýVYûee•$‰#G²{ï^Ý»u­°¸0¹¶áuý-0ÀT¡þ’‹W™`:v¸žÅŸÌãíæ!K2Ͼ8“ÉÄc?„ÁhôXgUôWRR‚ÓéÀétT]¥ûô”}¿Qö¦XþþX59,~Ë€ŠÕf÷’Ã`0 I’—ݧ¤¦Rf¯úÊÿ.$$„C‡PPPÀ­7÷Àétú°Ù½PY–)±”0nÌh¦M~ß}MBBB…wN§k¹6|+ ³]†ýý+¶ ,ùü .¦§s1=ƒ-[·Ñªe róò‰§nÚ<|ØïÛu§¢P§vmÆ¿:™¤ädR/¤qîüyâã9vú,";'—}¿üæUÎd2rþ|v‡ƒ&2qÊtòòòÙ°éâcc * /T”Ã`0Юmk>]¼U…c'NP+1‘vïåô™3””XÈËϧnº^r%%%c·;øù×ßè{ûíÜÔ½‹…ŒŒL$Iæ‘QˬÄRU•úõêr6)™­;wѼYSâã8rò ‡!#3“e«¿¢ãõ퉈ŒdÛö—°eë6¿³בS^íi5ÚµùýzNœ:UeýûBQ¢"£°;¶nßÍfãðÑc>÷ßµgÍš6å¾þýINNrí£½xé%OàQÅo¿©ªJTDÄ%Ûw‡ä²²²‰ŽŽ&,$Äë´š3IÉœ=wž¬ìlæ.\L×.7 "¹6Õªx}e7àúîûÿqüÄI Íf¶íÜÉí={`³ÛÉÍÉ£FB©iiäää^–þL&¯ïÀ‡}‚ÍfãÛï×yv®«L•áN?©|¾ä¨ìø,‡ÓIㆠ¼äHˆ‹Áh4zÙ}II ²,sððQ¯Ušv›½ÂïL&;^Ï}BÇëÛãp8*Øëfä:ÍI«ÓÑ£ûM¼þæL, ÇOœôz©YY6Ù–mÛÙ´yËßÂikî»ï¾W«š&—™™I—.]þpZ•Óáàô™3|ÿ¿uìÚµ›^·ÞBÏ7äJZþ%&“‰š5iÔ !©©©$ÄÇÕjÅb±Ò¨aCš6iÌâ%KÙ¹kõêÖ%**’Û{õbÙË9xð Íš6¦mëVèõzTU¥qÆlÛ±ƒÝ{öqûm½ˆŠŠà³%K(..aÌ Ïýï« Gà ¸þºöìÚ½‡Õ_­A#khÔ°!ýûÞÁ¢ÅKؼe 6¤VÍDš5iâ‘«~½z±bÕjVµ†˜˜XnèÔ‰´ô‹,øô36ýð/>û4µjÖôšé´7¨O³¦Mp8ôíÝ‹e_.gÏž½Ìœ6“Éĵ׶dËÖm¬[¿žíÛS§v-4 ùù4nÔÐkF™š–Æ‚OyÚ«™˜Èõí¿Y–éØázôz}•ôïÞº²q£†®-G““iÓº½néÉwÿýžUk\ø7kÚÄ«¼ÓédϾý,]ö9§NŸaäˆ' cã›iÕҵѽDZJYYÄÆÄxÎõ  "6&Úg¿9…[zô¨´}«ÕJqI ­[·â‡Í[زe+Íš5¥víZ$ÄÅ‘Ÿ›Ëé3gøqëVÞ˜2‰ð°0âââX±j-®iNß>}ÊÕßEqÍàòòóùþëØ¸éô:=CB£ÑP¯^]¾Xþ%™™´kÛ†&¡ªª§Ÿ*Ó_Ó&h];~ýí7Ö|õ56$11‘ÈÈ¿ú$‰””Ú´i^¯'5õ6 (0°Â8èØázrsr«Ð®ë”$‰´´´ öФq#b¢£¼ä(**fåê5»ïÜ©£ëTà /YJÛÖ­1—TøF–‰ŒˆdñÒeÜß½® žrvH«–-ø`î<ÿ¹·?™™|¶x iii\Û²¥GÏMJÇCjj*mÛ¶EUT22Òéܱë6l$,,”zuëþ)yó‡ñø ?\ßÕZéX•T«²)>¾Ò×|¥K•ý®²t=EQ\3•*¤õU– v)|¥–ù+WöQ|þ§‹èÕófbcc+¤=ùO S\ûûXQ•òåÓú.¥ÿK¥ú*ï/åÌßâ _ E*ë·Kµ_^~_r”ÿέ»K¥cú³=ßWU•¥éùÓGùúü¥x–O¡»”åëóÒ§9ü]Keé²’$ñÓ/¿òãÖ­<ÿÌÓl³âXSQÿi}•]ßSÏ=ÏŒ©S|©V~î±ÒÑŸð—Zqå‹«˜Gy©ÜJ¯Í‡\¾?$_Ue¨J¹²¿]óõwÜÛ¯ß%_ÕjU-9ú/¿‘SU뼜Uu>e®¤ß.Õž?ù/Gw•Éêsï*è¾2ýUÖ¦?}\N}—#G¥ú¼„—ûÝ×ß|Ë=ýîözwu%}s©ë›>y2&£ño‘“-6ú b³ÛùäƒÙž0€@ðoCQž>´ôÀÞ?בšLÆ¿Íá°ÿŠ¢ÑxŽÿþH’ä9‘]P&Ä"TP}èõú«ž×é>`àJdw§bùÂý·+­¿¬|ú¿Ùb…?Ã*ÓõÕ¶Ÿ+響êõ‡-ðkèyŒÜ¼¼j1\»ÝÎ…´´ ‡új7+;›œÜ\$\›½>sViþpÕ°Ùl <”G‡ #+;§‚üƒÖoÄl6“–v‘9Îó:­ürHOÏàÙ1ãÿÓÿ»ÛÁ` C[ÉÍÍûCí”í÷êâJú§¬}þ!‘²G¹:²X­èt:O¾§ÍfCQ”Ò£‡¬¨ªË0,‹×@p ä>&É5CÐ’ç8 ½N‡Êïo·m6½[™#„Ê=åëH!I’|!äž‘H’D\lLÙÊ·[þ82_mÚl6,+ïÍýˆwÞ|KI±gæV¶mJëþaËVŒF=÷Ýs’$„Vo@Öh|³V¶¼F£aóÖ­ÜÜ­+ƒ}˜’ÒÃaËÊаN-$dYòŠ­»¯Ý}-eõª×뽎\“$‰¨¨H&OÝn÷ØAYý”Õ…;®X6+©ìÑXî¾)¯;·Ý¸³ÜíËåì¤l:ìv4eì@Q”?l¾Ž™s˸nõ ½ßúÊë·ì‘W¾úÝb±xéÍs„›^ïY¨c³Ù<§­ûÓË¥úÇŸýºíÃßQx‚¿©Ã–e™EK–R_ÀˆáCÉÉÉáÉçGóåg Y¸h1;vïæLR2¿÷6¤ùuؾá¿H’L».7qhß,—1X­VÆO|ü¼š6mʓÆrúÌ9Þyÿ} òóydàƒôêÙ“W§L#0(S§N£J³Þ˜Á£CŸà­i“‰‰‰aÍÚ¯¹˜žÎ°Ç£ª*K>_ÎÿÖo ¯ ŸC‡pëÍ=¸x1÷æÎÃ\XÈþß1gæ Ú¶nͱãÇyëÙhµZ®ýž1£_ô\gùv_ŸòEE®ÃueT6jÈØçŸC’dæ}ò ûú£)€©¯¾Â' ?eß¾ýŒéež{æi’’“ùhþJ,%Œ>œ–-®qmæ“—Ç÷ÿ[‡¹ÈLVV6ýîìËO¿üÆð‘#Ù÷ËAœ‡ñY>'7—Ï—¯Àl6³ÿ矙ýö[|úÙ¯~hÔ°¡Ï¾,±Xxqü˘ ‰ŒŒdÊ«¯ðŸG3sêd¢££xêÙçhÑ¢ƒy˜ÃGŽ’—ŸOƒzu™;!“_y™W'OA£Õ“š’B‰Íʬקc2™˜÷É|öìÛOhh(V‹…·ß|­FãZ9wîoÏ~›ÕÂS#GЬIŸòÖnyýzõàâÅ‹ô¿û.ŽŸ<ʼn'HHH`ÜèÈÉÎáÝ÷?¤¸¸ˆý1õ¥ñløagÏ%ñôÈt¼¾ý²ƒ±cF³s×.fÎ~Ÿˆ°Pîì{}zÝê:wP¯§ÇýXµd!–K…úZ_{miŠ¡†áO=ƒÍbÁætòæ”ÉžüëòýþøcòÁGsìè1ròóy÷­7‰‰âºn=¹áúvt:^ðu®m_©^rsrøhá"ßýóÆ Ÿö[–ŒŒ z?ð¶þà÷H>ÁßÈa+ŠÂ½ýîfØ“#yÜö(¹yy¼ðÔ“$%%c2øàÝYäåå1ê¹Xòé׫S;…Æõëx²†dYföœ÷yð¾þ4oÖ”‹NǤ©Syÿ·1 <ûâh5lDHH0M›4áé'Gpäè1V­YË„±/rüäIbccÙ¾c'/‹ª(¨À½{ñŸþýÐétÜÿðcÜб#’,Ê”‰((,ä…ÑãøxîûLœ2¹³ßÁåRŠ‚‚iÞ¬™§Ýµß|Ç€ûïcîìYòÚÔi:r„¸¸8víÞË‚æ–Îþd{x Ùy¹L< ‹Åœ?äƒÙïb³Ù6ê–.ü«ÕJXh(·õºƒAÏ=wÝÅ…´4Ö¯ËóO?å’sÌ8>˜ý®ßòáaaÜs÷óЃpîÜùŠý°p¾ÏGòwÞ}Ç@Ó&MØ¿ÿ'ÖoÜÄË/>Çé3g0Q§N]Ž?À÷ë7ðÈ€q*NÏJ¼ÀÀ@®iÞœ1Ï?ÃþŸæè±ãÔHH ((ˆysfSTTÄócÆzùµZ-“¦Nç·Þ 0 Àµ èŸò^Û¸>/<óAAA 6œYo¼ALL oÏ~ÜÜ\$Y"22‚é“_åBZã'LdîœÙ—”0äɧùfåÈl6s?þ„ùs? $8kéÌ\©hµk$¸ìº\}ÏËÜ9³KgÊ Ó^}…°°0Î?ÏúM?ðЃ÷ãp8*ôûÉ“§hÕ²O?9‚_àãùó™0~QáaŒ>Œ˜˜ Cô"ûíŸ#GÑ®Mk/û=xø0íÚ´ñØEDDÿ[¾ÌçÙŠ‚¿i ;00‰5±X,|ûý:êթñãÇéÒ¹³ë‘2.Ž€À ×>~tV«•_¢]Û¶H’D`@É))Ô©U“°°0ŒF#mZ·æä©SH@Pé²ó¸Ø>D|\«×~Kqq1²VKTDDéþùÌzï}^2 Föì‘„V«%&: ‹Õ¹óIÔ¯]›ððpô:A^2ªŠêÕî¡£GJs¬¿aüÄIìØ½—‚‚Bââ¨_¿÷=ü;wïÁ½@UUE!95…m»öòʤÉLñ: åzPUUQ=ÁKN‹•³çÏU^^ù}/”'OVè‹Ç[«ÍÊ¡#GhÛ¦ ’$Q¯^]~þõ |ó¿uØl6zö¸ Y«£ÐlæÌ™3„„WÐO`éá5(((äôÙ³tëÒI’ Åáø}Š”ÔTãã‰wíó¡Óqâ„oyõ:=½£Á@¸xôzLÝÚ5Q=z D£ÑX£²ì M˜ŒFô: ü!;0 T§ƒ¤”þÓ¿Ÿ'gµZ=þe>ýx xìñ ò«*(*D„‡söüyl6{©á—ÛoA«Ý:µj³}ÇÚ¶nEÿ~wóÑÇó=±ÉWÆ%'7—·nåØñÄÇÅ¡ª.G•˜Pƒš5˜ðÒ8 z=²,{Åu]ƒ£tÅ—Z^N…š‰‰•–/[¯~Ðiu K2Z–°°PRRS‰ŽŠBjÕJ$$8[I1‡£yÓ&ô½í6~ܶ–-ZTž} ª¨ªBLt'Nœ fb 4eצDiééØív4—Sõ-oy³V_ç×Hî_V›íÙ¢(ÜÞ»7tîÄùóç™4y*oLŸZé iW7JžTrj*Ë¿\É”I),4óåêÕú $U¥níÚÜØ­«çp÷Ólå~³*zù]8­VÇö;+ØoY º³ˆÄ¹¯ÿ ¶ªªÄÆÆ0iê :^ßFCZµy烹ìܽ›©3Þä{ûh2qm‹ìع‹Ý{÷±rùç^/.ï¹ëN&N™Ê©S§ùnÝz‚ƒ‚¸öÚkYýÕ×lß±“ÜüÚ´iF£aÞ' øíÀ¦¾ù÷ß{Š¢Ðã¦îŒ~i"µkÖòl ¯Ñjiܰ+V¯aõÚ¯)*2{ Ö=Û×FöAA´iÝšUkÖ°gï~ÞY¶Êk¥—^¯÷j÷Þ»ï",,œO—,ãÈ‘#lÚºµ´®b涘œœ\~9xˆˆð0tz§OŸæð‘#ü§?>[²ŒS§N³ñ‡Íž›ƒ{'¾·måÔ™3ȲTNÎbô:ßòàÚƒÃét¢ªªÏ~ ,,Œ”ÔTt:‡£Ðlæþ{ïååW_ãð‘£¼2y·ßÖ €ë®»ŽÏ–.# €ú êqÏÝýèÝë×à.ÝÞÓý"Ï&Àµ‰Pb¼ûá<¶íØÉ¼ù ‰Œ÷\gdD‰‰‰¬Û°‘”’JÝÚu*ÊDqI‰çÞeµÙ<ýâqb¥ýévŸž‚T(..AûíÀétòù—«HJJâàá#Ô¯W×óbQ*ÿ£V¬¯¸¸ÄÓNhH(‡Žçð‘#,þü /yË÷{B|߯[φ›Øº}B’e/=UÔ‹¿þqëe¿*®>uÛGvv6÷ |øŸºyÕ²®Ö^"N§“áO>Ŭ™oˆ š]§`h5bbb\o¦ívr²³=o¿cccËÜÕ%2³2qØ ÂÃÃP…¬ìl×l12½^Ï;³çЬYSZ4o†Á` ,,̳+߸—_fλïxN4q šb Ðh\oÝCÃBQ³ÙLxx¸çåJTT”«½¬l\Û(HDDD¸öO–eŸíºåSV‹ÉdÂ`0íÊhÑ뉈ˆ@’$òòó)))!:* FCVé†ìF“‰ˆðp¯ÙMFF*Iaaa9¿å QTÕsªHù~ 4.¥Ôš‰ˆ'''ƒÁH@€ »ÝŽÕj#88ˆ‚‚ŠŠŠ@’xsæÛÌ|ãuÏu:²³³QT•ð°0L&……äÍÈÈ 22Y–ÉÎÎ&,, ­VK~A&“ ¼û33“¨ÈHTU%;;›ØØXÌfóÛAxx8……f,VWVSDxx™Ã$223=}à«>÷±vÙ¹¹XJ,®™»Vë9 «|¿ÇÇÅ•Ê[¨„„„DzzºG’$UI/þûÇJ`` ™YY^öè±èèh²²³‰-¿ÿúq5ï%rÕv^~>^›ÂGsfÿ©)@²,3ëÝ÷èÐáz:´¿Î+-êëo¿#/?Ÿ‡;;›%K–Tø~ôèÑäçç_±999Ì™3ÇóïÜÜ\Þzë-Ï¿EáÝwßÅáp°téRöíÛ÷‡{.‡+V°yófÏ¿üñG.\Xáw ,`÷îÝUÒ‡?ÊëA ‡íaß¾}Œ;–3fЩS'ºwïNJJŠßßÛívNœ8QáûöíÛ£×ë¯Xެ¬,š6mêÕNY'©ª*;wîDUUNž<ù‡n³fÍâƒ>¨òï7nÜè%[FFƒ "++Ëó]ff&ƒ&''§Júe™ìììKêA ‡í…V«%((ˆ^½z±~ýz^ýuÏßÞzë-FŒÁÿû_ÏwÇŽãÅ_dܸqpòäIœN'YYYL˜0Q£F±zõjO™I“&1cÆ FÅÎ;+ȰlÙ2š7o^ey¿þúkžzê)/^Œ¢(dee±aÃ’““Y°`Ïv ùöÛoY²d 3fÌ   Àg97ùùùlÙ²…¸¸8¯›G»víX¹r¥ç»U«VѸqcÏÌùäÉ“8ÏÉsÏ=Ç /¼@ZZß~û-#GŽdݺuW¬@à$I ŸŸ«±ÊûOaGü{çEµþñÏÌfÓ{B"éWC)Ò¥Š"â^"EDš HŽ (E"˜«4ׂ„ª¡…L€ôÞwgç÷GÜùe“"<ŸçáyÈìžsÞ9göwÞ9ç{<=Y½zµæìjÕªÅÒ¥KùðÃINNàØ±cLš4‰æÍ›3|øp>þøc ¶¶¶„††2sæLÞÿ}âãã˜>}:;wfêÔ©´iÓEQ,ÚýüóÏqpp¸íAñóócöìÙ?~œ3gÎ`45ûŠŠŠ8wîœÕv]\\xöÙg>|8“&M"//Ïj93EEEôïß¿‚ ]»veÇŽSTTÄ7ß|Cxx¸öùÇŒÑhÄ`0ðöÛo3yòd:uêÄ´iÓ ¥K—.¬Y³†nݺÝq?Krsóè;p’$[üëÕ·¿\>P Q£FZ”xäÈÆOTT”æd‡Š——áááDGG“ŸŸ¯•uuuEQV®\I^^ž–> ¤~ýúøùù1fÌ‹\yFF­ZµÂÍÍíwµªª Z¶l‰««+o¿ý6 .D_É¢ òíÆÇÇc2™0 ·ÕW®\áù矯p¼ZµjŒ=šÕ«W³råJFU©ýC† ÁÇLJž={rþüyTUEQŠ‹‹-¾w»ý ¬ãââ̧Ö1|ä(nÜ”º4ãß/¿Ê¶O7âââò—Ûcs·ÈÈÈà¹çž   €5kÖàèèÈ|@RR’Å÷}||´G Y–9}ú4‡æ¹çž£¨¨HK˜L&íÿ’$a2ý¿ˆKTT<òˆåI–¹xñ¢ö·¢($$$`kkkñÂN–em ŒF£vÌLùvÕ_5 Ê>Y+gfÓ¦MÌš5«ÂqƒÁ@hh(’$ѨQ#Þxã ¢¢¢¬öiÙs-›V)µ~·ªªÈ²ÌÂys7q2&“‰EïÏC'ËU¾:òo‹°UU¥¸¸˜¨¨(^zé%^zé%ºté¤I“PU•ØØX-"œ9s&©©©8p€zõêáèè¨9¼[·nQ½zu¼¼¼*¤*ãÌ™3tìØÑ☇‡?þ8›6m";;›/¾ø‚=z ×ëùöÛo)**béÒ¥Œ9EQ˜7o………|ÿý÷ØÛÛWÚž½½=×®]Ãd2¡Óé~³Ü?þˆ““S¥uÅÅűwïÞ?>²Lvv¶ÅEd­²²²X¼x1ùùù,_¾œ¼¼<>úè#ñË~ãIÜÆÆ†¹³f0ïÝYèmlþ6•Ò*wØ!!!Ìž=›qãÆñÝwß±gÏ<<<øÏþCÓ¦M1bÛ·oÇ`0 ×ëY±b³fÍâðáìY³@‹Ê;tèÀ7˜>}:mÚ´ÑêzñÅÑét<òÈ#šc,..æèÑ£4kÖÌÂ.Ndž ¸víS§N%==É“'DµjÕ7n5â‘GÁÇLJwÞy‡ñãÇ£ÓéhРÕvmmmyá…(..æÍ7ßÄÏÏÏj9€øøxÚ´iSÁaûúúR«V-êÖ­K`` f—§§§Ö666èõzêׯ¯• Å`0°iÓ&/^ÌŽ;~³Ì/TUU%-- EQHMM¿Jàw‚Pþ–ÈZ»y|q[­K’Äùóç™òÖ.ütš&µ¸';6;;›O>ù„‘#GÞs¶8p“ÉTáÅà?­‚{Á›T•‹?¢^Uªõ•ñ——/œ¥vÝìØ±gg«©Ì?ŠÍƒ6nnn÷¬“êÚµ«è@pï¤D@ ¶@ ‡ý‡PAlã(¿ÍÝð“wa«¸¹{‘™.f5 z[;@ªÒ î襣·_5nüª‚§·@pŸE¿:IBâ×nU4KDòss¸v5Žu€ªÝÀàŽg‰øÖ&-9‰›‰×PMª¸Á}„ŠÑhÄÖΞèoUéBGGgjÖÂÁÁá×z«®î?5­Ï§Zu|ªUc/î;L&Š¢Pó¡:U½Ë2²$!I’UyŠ¿Íaÿ+~àÏ"Ër•;U àW‡]ÕØˆ!ÿD¤»äTïê F ›@ ‡-‚*äŽR"’X9#÷‡Ã¾™xüÜ@8n@ ¨Hé¦&õ7û›¶$‘Ÿ›C“ÇZŠ1‚J¸s¦Ê×§ßa[DÖ@ðÛ1vÕO{þË_:¦¤¤ÜõùÛééédggWiƒŒŒ ­þ²ßKܺuKÛ]Ýl¯@ x0øËöÀµMj«‚Ù³g“••eqlóæÍDGGÿézÊ’––ƪU«˜7o'Ož¼'033“yóæi9’üü| {ÁƒÁŸZ8“’’‚Á`ÀÆÆ???ÒÒÒpvvÆÞÞžœœÐëõäää——‡^¯×ö(4™L$''£ª*žžž›ÕfeeQPP€»»;ŽŽŽ rss)**B’$¼½½)))a×®]ôîÝ[û.ÀСCµ}“’’$ £Ñˆ««+...iѧ““666õH’¤EÐæöllJ»ËÖÖ¶Âꨜœrss‘emÏD“É„£££¶¥5{’““1899içaí¦Q¶œœ¸qãdذaxzz²nÝ:\\\(((Ðì-{¾ŽŽŽ•Ö/À[’$®_ÿ…É“'“‘‘ÁÑ£GÒÝϯ\¹ÀÞ½{III!''‡¶mÛÇœ9sðññA¯×3oÞ<:ıcÇ µ¨?""‚cÇŽɬY³P…ôôt¼¼¼ˆ‰‰aþüù¿=.Z´ˆýû÷P½zuöíÛÇ¥K—hÙ²ôEéâÅ‹‰ŒŒ$..Ž‹/ZLS”eÙjû¿…¢(tïÞ„„Nž>>¤¥¥1lØ0^yå,X`µo—?þ¸Âù ‚JJP]»v%??Ÿèèh °··'!!(ÍC+ŠBÓ¦MÙ¸q#&“‰ÜÜ\$I¢nݺlÞ¼™´´4ŒF#111PPPÀ’%KX´hÁÁÁ¤¥¥ií^¹r£ÑHQQ™™™888`4ÿÐKLU-Ð>vìXöïßÏÖ­[µ›ÑhüÍöKJJ´:ʦIL&¾¾¾ìرƒ_|‘k×®qäÈfÏžMhh¨–··†³³3Íš5ãèÑ£øûûãááN§ÃÛÛ›õë׳fÍÆ€EÿšIMµ¾ûÙ^Àâ|/Å#¤”ˆNÇ™3§™:u*ÎÎÎtíÚGGG^}õUéׯ=zô 00ŒŒ ž|òI‚‚‚PNÇ®]»èÖ­5jÔ`ܸqÔªUKKMŒ1I’ ÃÛÛ[s²?ýômÛ¶%::š¸¸8t:³fÍ"<<œ×_gžy€ììlŠ‹‹HLLÔ"äÔÔTŠŠŠ˜={6¿üò ûöícûöíZ=£FbôèÑÚwpp`õêÕ4lØöíÛÓ±cGÒÓÓñôô$##ƒºuëF||<‘‘‘x{{S³fM Ä–-[hÕª•U{ 'N¤_¿~ìÝ»—ÂÂBÖ­[g5%2|øð ýëîîÎÃ?ÌàÁƒY³f qqqö˵k×´ó5¿÷Òç·5)Z’$Ο?Ï”·¦pá§SùJǤ¤$V­ZÅôéÓÿp4}¯p¯Ù#îbNS·á#lÛº ggg--ú—§Dþ®•ŽôQþ^sŽÂY ‚¿Áaÿõèõzêׯ/FL ‡}¯ãååÅàÁƒÅˆ á°@ ¶ .¼#-‘éÓ§kó•ÿ yyy¼ýöÛäååñá‡þ¡²›7oæÄ‰¨ŒÑhdÆŒäää¥ËÄ,XÀ¨Q£X³f ûöíã•W^á?ÿù#GŽd„ œ;w΢UUùôÓO5jÿýï­¶•ŸŸÏäÉ“™0açÏŸ·úˆˆˆJ?»S"""8|øðŸª£lýܼy“üñ/oÿN¯ÿÊÈÍÍe„ ,Y²„ï¿ÿž-[¶ðùçŸÿéñ‡ À‘#GîH­oýúõU¢ò§ª*ÿýï1™LÚ2ïÛ%..î© ×ë™>}ºö#=zô(ÿú׿˜2e ûöícÇŽtïÞåË—³dÉfΜÉ'Ÿ|Â#K§N0`=zô°°Õd21~üx"""ÈÍÍ­`kùeî¿w¼,¤aÆV?KKK³X8UÙ˜DGG[èÉÜm ƒÖ?eûwzýWƸqãøÏþÃk¯½ÀÕ«WILLüKo~‚¿Ž;R1* +W¬ 66–ÀÀ@&NœÈ† èСµk׿ÿû7ÆÛۛdzsçNêÔ©£-¡.,,dîܹäåå1räHêÔ©£ÕþóÏ?³|ùr ={öÔt:æÎKnn.Ï>û,­[·þM ‹ŠŠ˜7o™™™¼üòË4nÜ(©qöìYTUÕÄ‘,XÀÏ?ÿLhh(={öàØ±clݺÞzë-ôz=ûöíãË/¿¤Q£F 6 [[[¾ûî;¶oߎ««+o½õ@é‹Ò´´4Þxã ­óò{€§Ÿ~š«W¯jß…ÒyÚK—.­p>C† áܹs¸»»3gÎÖ®]K÷îݵÏ322ðõõ¥k×®L›6äädm>·$I¼õÖ[\¿~]Ö*ËüùóÉÉÉaÒ¤IcQÙq3ÙÙÙ9r„jÕªYíÇyóæ‘••ÅØ±c™6möööÆ%**Š–-[bkkKTT_|ñ...Lš4 ƒÁÀ’%KÈÊÊ¢cÇŽôíÛW‹ˆíìì¸qã†Åõ`m˲dÉ._¾Œ———ÖWw»}k×YÊ^g“&MÂÝÝ•+WrþüyÚ¶mË€ÈÌÌdïÞ½œ>}Y–7nÇŽcýúõÓ±cGš5kF^^¶¶¶×¶àî°eYǹ³çPU•%K–ðóÏ?pþüyZ´h”. )))!99™™3g²}ûvŽ=JLL z½žàà`>ýôSœœœ ¢¸¸[[[Eá­·Þb̘1QXXháàjÕªEµjÕ0¿¹ä©§žbÞ¼yÔ¬Y[[[í¸³³³ᘗ|Ϙ1ƒÆ3fÌz÷îMpp0’$ñÎ;ï°iÓ&âãã5U=777&L˜À´iÓˆÇÃÃ3f°mÛ6öïßÏÈ‘#Y·n’$¡×ëñðð¨4¢Š‰‰ÑÍ :T®*‹§§§vÍš5ãܹsiQ¡¢(´k×Nû~‡8w-"IÄÇÇ[µeÁ‚œ={–¹sçÒ°aC^~ùe\\\*=^öÆØ¿ÿJûqêÔ©\¹r…E‹¥’åÇ娱c<þøãäççÓ¥K²³³ÉÌÌÄÞÞI’ ¥^½zôìÙ“G}”Úµk3}útŽ?N`` ÕªUÃd21kÖ,5jdѾŸŸŸfë¢E‹P…9sæ0gÎ ‡y·Ú*\ÿåŸ`Ê^gîîî,Y²£ÑÈ»ï¾ËرciÒ¤ >>>¼ýöÛ?~œ'N0mÚ4Ö®]Kß¾}Y¶l®®®<úè£Â«‰”HÅGX777öíÛÇ–-[¬ A©–Hll,k×®ÅÇLJ§Ÿ~šÌÌLiݺ5M›6%((ˆY³f±gÏ­ŒÛ¶m#66–€€iذ!~~~Œ3†k×®Uj_zz:AAA4oÞœjÕªýæÒðââb._¾Ì‘#G?~û,ûöíûM]m3—.]"99™öíÛkÇ.\¸À£>jÕÞ’’ÍñK’„N§«0¯»ìø€ââbªU«FZZšÕȸì1UU),,´x‰äëëû» dRSSiР«W¯¶8¾qãFÂÃí–¿té’Ö±±±4jÔÈ¢ÏdYæÀQceyekÄÇÇ3xð`>ÿüsrss ÿÍãf6mÚ„‡‡²,WèÇ5jXôYvvv…qÉÉÉ!==Y–‘$é×k«6Ï?ÿ<‰‰‰œ9s†Ã‡3hР´ºÊ_²,SXXhµ}³ ƒA+sçææÞµö«U«Váú·–ã/{M™L&Š‹‹-~Gæ'šò+åîöÎM‚ÄaK’DJj*²,3fÌí¸»»; °°ˆˆL&Mš4!<<œääd8€››AAA¬Y³†'N””Ä”)S´|¬Édâ»ï¾#$$„çž{®BDbaƱzõjÖ¯_O§N¨U««V­âÂ… äææþæVY666téÒ…I“&iQqq1Í›7gРAäååcuY¹Á` Y³fôïߟÔÔTvïÞMË–--¤^ÍeÌ7°ÜÜ\6lHBBNNNÚ.++‹ùóçÓ£G­ìîÝ»µ—‹»víbñ⍦¦òÖ[oiz" .$++ 222Ø»w/çÏŸgîܹøøø••ÅâÅ‹+ŒŸµ<ê’%K˜1cÎÎο{ÜÌ?þ¨ma­%I⫯¾BQêÔ©Sa\ŒF#ÿþ÷¿µ›ûwß}Ç AƒèÑ£EEEܺu‹êÕ«ãååUaæLYìíí騱c…öÍçokkKÛ¶m™;w.………lܸY–1 wµýò׿§§'z½ž… ’]á:³µµ¥C‡š ,`èС¿éôÿt ˜~»N:55•vO´##%™"ƒÂÒ¥KÙ·osçÎ¥N:´jÕŠ={öðÕW_ѱcG푱víÚ¬_¿{{{üýýù׿þÅØ±cY·nß|ó ‘‘‘š3P…#Gް~ýzâââ?~<ÚF¶¶¶Ü¸qƒúõë[H23|øp–/_Î×_MÆ ­¾ì1Â7øè£¸~ý:-[¶ÄÛÛ___Ö¬YCLL mÛ¶%-- üýý)..&??ŸÆS§NÖ­[GVV–…jnn.Ï?ÿûì3ž}öYºtéÀW_}E›6mpvv¦gÏžlÙ²…S§NñþûïS£F ˆŠŠ¢sçÎ,Z´ˆo¿ý– .pñâEZ´h¡9ï&MšXÕÊ®ì¸9ú¾uë½zõª´ÝÝÝiذ!«V­¢uëÖŒ3F—Gy„³gÏÒ®];\\\ÈÍÍeÆ ìØ±ƒêÕ«Ó±cGÙ¿?ûöí£qãÆÔ¯_Ÿš5kV¸êÖ­KçÎ+´o4µóâ‰'8zô(Ô¯_ŸzõêÝõö½¼¼,®ÿš5kÒ¼ys¾úê+Z·nŸŸŸÅuöøãóä“OÍöíÛéСmÚ´¡¸¸˜ÌÌLš6m ”îPÔ®];nÞ¼Éc=¦½èÜ;¤&ßÂËÇ—sçÎakk[%OD÷ø“àÞãÀ˜L&ºuëvÇu,_¾œÁƒÿæÍ÷nòw·/xp¹âOw8÷Gˆ ЦÅýFŒñ·žÃßݾ@ðGKÓ@8l@ ‡-¸/ÓЂûÌaûúúÞµ)JÉÉÉ·¥}ñgê½qãS§N­ÒúGÅ®]»,ŽÝvî„+W®pðàÁ*©K’$$Iº­…E×®]SÙ‚»å°o7z ¹k'óÅ_°{÷î*ðvîÜ©Õ+˲¶ ¸ªððð¨0ÇùNÛ©ê(ÖÁÁAÓ9© jÖ¬y[;ï<óÌ3‰_¨@ðg¶Dé µ.]º0hÐ † †$IüûßÿÖ´>ýôS1™L¼ûî»tïÞ'žx‚€€dYæâÅ‹tïÞ6mÚiQÿðññá©§žbûöí¬X±‚Y³f¥Ë›%I¢°°Ð¢ý‚‚¶oßÎÚµkyï½÷€RIÖçž{222´oÀ€tíÚ•-[¶ðúë¯Ó»wo^|ñEmõ‡~H÷îÝ àêÕ«|ñÅZ½euIÌdggÂÀ™4iF£‘›7oNŸ>}$‰£GмysÂÂÂhÖ¬ÉÉÉØÚÚ2kÖ,úöíKïÞ½+ˆ3Y«ßLFFF…qXºt)mÚ´ÁÞÞžˆˆ€Jí9sæ }ûö¥[·nštl^^ÁÁÁôéÓ‡ààà KÜËŽÏ–-[¬Žgaa!aaaôíÛ—)S¦h7>¬­b-;NYYYìÚµ‹èèh^yå¾þúkñ+~厦õét:N:Í´iÓxâ‰'´HÈÛÛ[[zloo,Ë$&&âééÉž={ÈÉÉᥗ^B–e^xá¾þúkxþùçiذ!õë×§¤¤„E‹‹———¶Œ½OŸ> 2228~ü8GµhßÞÞž`ggÇСC‰‹‹£cÇŽLŸ>3gΰ`ÁMðÇ,–Ó»wo6lØ@Íš5yã7´•wz½žÝ»wSXXˆ³³3}ûöÕê½uëV…þ˜8q"{÷îÅÛÛ›5kÖúë*P–.]JFFÆ cÇŽDEEáææÆµkר¶m£GÆ`00räHúôéÉ'ؼy3aaa¿YõêÕ8yòd…q:t(#GŽD–e6lH=*Øóâ‹/²mÛ6fΜÉ_|AQQíÚµãĉÌœ9“+VÂÉ“'-"]kãTÏÆ³iÓ&&OžLóæÍµ›¯¯/;vìà믿æÓO?­0NóçÏgΜ9têÔ‰åË—ÿ¦Œ@ "ìÛÀ¨(7fþüùôêÕ‹7nTêØcbbèÓ§²,ãîîŽÉd"..ŽvíÚááá½½=!!!üôÓOZ´ùòË/Ó²“Œåý IDATeKæÏŸOII ööö8::RXXÈÊ•+©U«=öX…öËê;œ;wŽ•+W2bÄ>ýôSM^µfÍšØÛÛãàà@ݺu5=ŽÆ#Ë2?þø#O?ý4:NKS”­·<………dee1}útFŒAll¬…›cxzz’””„Ñh$&&†!C†0eÊRSSµ¨ÓÙÙI’¨]»6{öìÑn|F£±ÒúÍ)¦òý™™ÉÈ‘#yå•WðññÑ"ò²ödddpáÂ"##µMZ´h¡iC·lÙY–ñññ±8÷òãc0¸víZ…ñüöÛo9uê-Z´@–e­/Ïœ9à /¼À’%K$©ÒqRUµJÿøT\]\ˆŒŒ$))‰~ýúqäÈt:éõzTU¥fÍšœ>}š§žzJs@¾¾¾œ?EQÐétääähª|€öˆ~ùòeFÅúõë™1cׯ_'%%lll*´_–Fѹsg^~ùåÛÊ÷ªªŠªªxzz«é;[Ë —0rppÀÍÍW^yE[6 ””dQÆÞÞžK—.±iÓ&Ö¬YCnn®&9Z¶NY–iÔ¨&“ISܳVÙüwÙ~ؽ{7Ï<ó GŽÁÖÖ¶R%EEQ¨[·.,^¼XËS›L&zè!°š¿.;>£GfÑ¢EƳU«Vxzz’’’‚¯¯¯V¶AƒL:•×^{-[¶T:NF£Qì2/TE„-Ë:âââ8tèÉÉɘL&ìííµ¨ëôéÓL˜0AS>{úé§9xð ï½÷xxxиqcÖ¯_OTTñññ<þøãš#Yµj?ÿü3ÇŽ£Q£FH’D5 ¥mÛ¶ØØØpáÂ… í7hЀ}ûöqéÒ%غu+»wïæÀZ~611Q;²²”Š¢ ( 5¢cÇŽœ8q‚õë×SRRBÆ µzmmmùþûï-vôxî¹çxýõ×¹téäååiêpfRSSñññaݺuœ>}š÷Þ{O‹ %IbÕªUüøãtëÖ±cÇ¢( ßÿ=¹¹¹ <¸BýfÊ÷ƒ§§'­ZµbÕªUlÚ´Is¸åíINNÆÁÁQ£F±páB._¾Ì_|,Ë 8ÁƒsæÌ „,ˤ¦¦j´ìø4hÐ77· ãùÄOЧO^zé%bccÙ¶mPª4د_?Z´hÁöíÛ+§Î;ÍÍ›7ůT ø•;Ò¹sšºš‘žžŽªª¸¸¸àêꊪª$%%iÔÕÕ½^OVVšŠ··7&“‰””TUÅÇÇDZ¤§§kJožžžØÛÛc00`6lÀÝÝ‚‚²²²,Ú¸u몪R£F rssÉÍÍEUU\]]qqq!)) t:©©©Z´ž••…““z½žÌÌL $ ___lll´z«W¯NJJ 666xyyiý“––Fqq±¦çm2™ÈÉÉѾ“œœŒŸŸŸö=½^N§ÃËË‹ôôtL&%%%888àéé‰Éd"55Uk§|ýæˆÜZ?˜Ï[–et:V_y{Ì‚X)))(Š‚ÞÞÞÚçF£;;;°³³Órçf[ÊŽ¢(VÇ3))É¢nsÿ›?ó÷÷·:N%%%¤¦¦jý!ÜoÜ -‘;:M“ÇZü¥'ŸžžÎSO=űcÇÄ• þ‘û¾YéxñâEmjŸ@ ü¹ovêlÛ¶­-@ðFh‰pØÖ1¿˜º_1/ÞyP¨ÊñHOO·˜Á"îs‡=pà@‹¥ÕUIddäoj‰TE½iii¬ZµêwËÌž=û¶DŽÌdff2oÞ<îçñX¸p!ßÿýß6NÁƒÎŸÊa§¤¤`0°±±Ñ¦¬9;;cooONNŽ&”““C^^z½^›¢e2™HNNÖ«ØÛÛkõiQ¬““&“ I’pwwGQRSS©V­šEû¾¾¾\¼x½^OHH¾¾¾dgg“——§Ù¥SÉ$IBQÜÝÝ),,¤¨¨ÈbúX^^999H’„———E½²,WÐÖ(o¯ »ví¢wïÞ@é ›üü| t£bGGG ùùùâèèÈÍ›79xð Æ Ó¦B©f‹yŠžyÕaZZ&“ GGG<<<,ÎËh4jSãàÿ§ç999i›[3&“‰´´4‹q…Òyäe§–ï§jÕªakk«m6|óæMmy³fН¯¯¦#SvœÁ]Œ°%Iâúõ_˜û춢ϲö^¼xÑÂY–‰ˆˆàرcDFF2kÖ,E!==ooo>ûì3²²²¬®êS…îÝ»“ÀÉ“'),,$33“Ï>ûŒ+W®Ð±cG²³³µó2/îiÙ²t¿Í={ö0cÆ ÒÒÒhݺ5ÙÙÙVÇ£,ñññÆõÈ‘#¼úê«Z?¥§§WÚO666ìܹ“¹sçbccÔ)S¸xñ"§NâwÞѺ@ ø‹"ìRQ§ÂÃà  I“&@©Î„Ùñèt:dY&!!e˖Ѿ}{:tè@¯^½(((àèÑ£Lœ8Y–9~ü8‡¢S§N Nœ8Á¼yóð÷÷×vì~ã7˜:u*qqqLš4‰«W¯VhßÍÍ ;;;|}}9~ü8óçÏÇËË‹W^y…ˆˆºwïNíÚµ ÃÙÙ™M›6ñæ›oâèèÈ‚ (..&))‰wÞy‡öíÛÓ¹sç õ–ªÌ^GGGjÔ¨««+/½ôYYYèt:š4i¤I“˜0acÆŒÑ"XGGG šžžŽ««+=ôÍ›7ÇÆÆ†N~~¾¶ðÉ'Ÿ¤víÚ„‡‡ãììL—.]¸zõ*[·neöìÙ8::2bÄ ÈÈȰ³d€™„ËqUU• 6°nÝ:<==ùå—_X¹r%ƒ ªÐO’$ñÃ?péÒ%6nÜHNN.\`ôèÑÓ»woÞ}÷]‹þw9ÂV…6mÚh p&L°ˆ¾Íèt:._¾Lݺuµcz½žøøxêÕ«§E[æèÖüùÇÌW_}Epp0_~ù% Àh4²páBÜÜÜhÛ¶ío¶oVÌS…   ÞyçÍÁ*Š¢¥/Ì© 777t:gÏžµª¿Q™®Eeö–ýþúõë™9s&±±±øúúj/ùʧVÊãëëËòåË9r$ýúõ#;;››7o2tèP~øáòòò´ÉøeÏËÆÆ†üü|í`II aaaT«V­Âx”xÛµkW¡_cccµ4ˆ™™™œ?¾B?ɲL\\µjÕJóò¨ªŠ­­­…H˜Ð þª” (&ºvíJ~~>ÑÑÑ`ooOBBYYY(ŠBÓ¦MÙ¸q#&“‰ÜÜ\$I¢nݺlÞ¼™´´4MÁ.88Ø¢±cDzÿ~¶nÝŠ¢(¼üòËIPP¦è¶k×.ºuëF57nœ• fÍšÅ7Ø·oÛ·oפNßÿ}-pêÔ)f̘aÑ~XX~~~œ?ž•+WÒ¬Y3:wîŒ$ILœ8‘nݺ‘˜˜¨E¸f}³Ó1+Ø-[¶ŒððpNžT«V… ¥¶æ~:wîÙÙÙèõzV®\‰­­- ÄÆÆNƒ  bÚ´iôíÛ×bœÁmËw¦%rŠ&µüK -))¡OŸ>ìٳ綾¯ªj…ÇnkÇîµózPûY ø#ÜCZ"ý1;;ÛB£úvn0·sì¸ëÞcç%œµ@pw¸oæXýòË/Ú¾€@ðOä¾*ÿRR D„-á°¡To¢*´+¬Õ³zõê?¤ßq/qóæM~üñÇßýÞŒ3´¹ãw³@ 6GŽ©u8kõÄÄÄXì[x?a0´eæ¿Å'Ÿ|ò§Þ6ßn;àÞãŽwM7* +W¬ 66–ÀÀ@&NœÈ† èСµk׿ÿû7ÆÛۛdzsçNêÔ©£-½.,,dîܹäåå1räHêÔ©£Õ¾gÏ<ˆªª 6L[zn­ž¼¼<æÎ‹¢(|þùçÌœ9“?þ˜öíÛ[Øáââš5k,ìX°`?ÿü3¡¡¡ôìÙ“ôôt¢££ùæ›ohÛ¶­¦sR\\\¡¼5;ÓÓÓÙ»w/§OŸF–eÞxã üýýÉÉÉaöìÙ¨ªÊäÉ“µE/K–,áòåËxyyѵkW­ÒÓÓ9tèÑÑÑH’Äøñã5!&(U |¸vƒX¼xq…v’’’عs'+V¬ÀÃÃE‹ñè£j²§YYY‰_ˆ@p¿Gتªâæîƾ}ûpwwgÈ!V¿§ÓéˆeíÚµøøøðôÓO³aÃiݺ5M›6JWîÙ³‡>}úо}{¶nÝJ||<999”””X­çæÍ›<ùä“<ú裼öÚk•ÛëfioQQ—/_&55•ï¾ûލ¨(EA–e¦Nª)Þ™)_ÞšEEE 2zöìÉû￯Ý@fÏžÁ` ))I{bøê«¯>|8ׯ_·hsÚ´iøûûãïïÏ›o¾ù›¹kY–ÉÈÈ gÏžýQTTÄÿþ÷?"##µvnܸÁO?ýDzz:£GÖ¤P~øaM£äË/¿¤oß¾â"ÜﶪªÔ®]‹µk×’˜˜¨-”$I˯šE…ÌQ§I’(..¶È?ët:ììì€RýŒAƒáääĘ1c4'e­ž’’MðÈ|ÌšªªR·n] {íìì(,,dþüù|ðÁS£FJϹ|y ‚æs*›cVWWWž}öY–-[ƪU«PUU;ó‹Sk‹MʾTuuu­ðóçæ¾.+U¶̺&æcªªâêêÊ›o¾ÉÒ¥KùüóÏY±b…vóÌËËcïÞ½šö‡@ ¸¶$I¤üª†g–…R=ŒPXXHDD&“‰&MšNrr2ÀÍÍ   Ö¬YÉ'HJJbÊ”)tïÞ]s:999<ôÐC\»vüüüJë©U«}ôÇŽ#%%…mÛ¶iÑpY;dYæÖ­[ìíܹ3“&MBUUbcc+¤%ÊR¾|AA¹¹¹vVætkÔ¨Á¹sç8pà€–:²³³£mÛ¶Ì;—ÂÂB6nÜh¡œ'IsæÌáòåË|óÍ7Ô®]GGG®^½ªI×Λ7ÂÂB¾ÿþ{lmmñóó³èÏ?ÿZ·nmÑŽªªÔ«W¹uë–Ý·jÕŠ©S§Ò¾}{Ä/D ¸ß¶,Id¤§3þ|&L˜ÀÁƒR}ç´´4ÆOÏž=ÑëõT¯^ 0{öl®_¿Îã?ŽÑh$33“;w2þ|m·(•ï|뭷ظq#‘‘‘Œ7NWi=DFF²téR^ýudY®`‡­­-éåì•$‰ÿüç?4mÚ”#F°}ûv z½žúõëW8çòå™2eJ;Ë— Å`0ͱcÇ>|8'Ož`êÔ©ØØØ0nÜ8 5;óSÌÀY·n»wïfõêÕìÚµ‹I“&Q­Z5ÞyçÆN§£AƒZ|ðÁØØØh›”oÇËË‹£G²`ÁÞ}÷]-MãææFÆ E:D ¸¹oÄŸþi$%%±bÅ fΜyGåF#!!!œ9sFt¦@ð7p7ÄŸîpZŸ÷¹Û¨ªjUwû÷8räNNN\½zµÂÌ@pc#ºàÞÄÛÛÛb'Ûå±Ç#77—€€‹yÛ@8lÁ]B¯×ãååõ‡Ë¹ººâêê*:P xâO@ ¶u|}}«DïÃZ=}úô!%%很+W®h³mà®:ìÛt ©’ö¬Õð—ívRVeqpp@¯×‹+R T­Ã–€œœºté Aƒ6l’$ñïÿ›˜˜>ýôS1™L¼ûî»tïÞ'žx‚€€dYæâÅ‹tïÞ6mÚh˦Í,]º”6mÚ`ooODD@¥õœ={–öíÛÓ«W/>üðCt:Æ «`GFF†…½PºíXHHdÒ¤IFnÞ¼Éøñã äóÏ?×l*_^’$«vÞ¼y“ððpúôéƒ$I=z€3gÎзo_ºuëÆ‰'€Ráªàà`úôéCpp0666•¶¥‚YaaaôíÛ—)S¦ ª*Í›7',,ŒfÍšiÚ"cÇŽåµ×^ãÙgŸ%$$„ÜÜÜ?d×èÑ£™1c5kÖäÂ… âW"Ü#ÜÑKGNÇ©S§™6mO<ñ„¦¡áííN§ÀÞÞY–ILLÄÓÓ“={ö““ÃK/½„,˼ð |ýõ×888ðüóÏÓ°aCmÁÉСC9r$²,Ó°aCzôèAFF†Õz† BTTÎÎÎ :Ôªz½ž“'OV°wâĉìÝ»oooÖ¬YC꯫7ÓÓÓ‰‹‹ÃÖÖV;gkå­Ù)Ë2þþþ,]º”ŒŒ ^|ñE¶mÛÆÌ™3ùâ‹/(**¢]»vœ8q‚™3g²bÅ BBB8yò¤VoeíÍš5‹É“'Ó¼ys $‰¨¨(ÜÜܸvíÛ¶mcôèѸººÒ®];ÂÂÂ8zô(gΜ¡Aƒ·m—§§'AAA\½zU“ ÷i„mT‚›3þ|zõêÅ7*uì111ôéÓY–qwwÇd2G»víðððÀÞÞž~úé'­\ff&#GŽä•W^ÑdT­ÕsåÊ:t耧§'¶¶¶•ÎŽP… {‹‹‹ÉÊÊbúôéŒ1‚ØØXÍAh7œ²)˜òç[ÞN³^‡››žžždddpáÂ"##9r$&L E‹¨ªJtt4-[¶D–e|||,Ò,åÛ3 |ÿý÷´hÑY–qvvÖúeÈ!L™2…ÔÔT-]cþ¼víÚ$''#ËòmÙe~šñóóÎZ x"lPquq!22’¤¤$úõëÇ‘#GÐétZ4¨×ëQU•š5krúôižzê©Rgo4âëëËùóçQNGNN@©ThÿþýùöÛo±µµ¥^½z˜L¦Jë9{ö,F£Q[† ¥«2ËÚàááaaoTTîîî¼òÊ+šj ”®0´–Ÿ._~÷îÝ<óÌ39rD³³²›Eݺu `ñâÅš=&“‰‡zˆ„„*ä¯Ë·÷õ×_S½zuRRRðõõJ_TnÚ´‰5kÖ››Ë¢E‹*Ž”ªj‚O·c—@ xÀ"lYÖÇ¡C‡HNNÆd2aooOË–-™?>§OŸf„ ¿ªúÕæé§ŸæàÁƒ¼÷Þ{xxxàááAãÆY¿~=QQQÄÇÇóøã—ÞAllhÓ¦ «V­bÓ¦MèõzL&“ÕzÜÜÜhÚ´)k×®å›o¾áÃ?DUUZµjea‡N§ãÂ… ö:991hÐ ^ýu.]ºDDDyyy¨ªjuKùòžžž´jÕÊÂN³ƒ,[>99FÅÂ… ¹|ù2_|ñ²,3pà@Ì™3g4hED_¾=777ú÷ïÏK/½Dll,Ÿ}öžžž¬[·ŽÓ§OóÞ{ïiK_ ƒöUU5¿Û±«|y@pïpGZ"cNS·Q3ÒÓÓQU\]]QU•¤¤$Í»ºº¢×ëÉÊÊ¢  [[[TUÅÛÛ“ÉDJJ ªªâããcáåææ’››‹,Ëèt:<==ÑétVëQEKH’¤å¯ËÚáææFII YYYöBéÎ-ÅÅÅèt:|||0™LäääTX´RPPP¡¼5;Ë—ONNÖÒ:)))(Š‚ÞÞÞÚçF£;;;prrª´=ó@Ù:Ìöëõzt:^^^¤§§cgg‡³³3ƒÂÂBÉÎξ-»Ê–wÆÝйCñ§Ó4y¬…@ ø ¶Xé(÷ Âa pØ@ ¸¯¶ùEãݨǼCúýHII‰Å&»ƒŒŒ q… ‚¿Ïa8°Jœªµz&NœHffæ}9‰‰‰?~\û;--U«V‰+T hü)=ì”” 666øùù‘––†³³3öööäääh‚F999äåå¡×ëñôôJŽ$''£ª*žžžØÛÛkõš§ïAéÆ¾ŽŽŽ¿YyuI’HOOÇÉÉÉÂNGZZš…½ðÿÓꜜœpwwÇ`0ŸŸOaa!öööxxxhí”/oÍNó&Âæ }½½½±µµEQMëÃ××W[ä“’’¢íMi^N¯ ίßIOOG–e °³³ÃËËë/¹÷y„-IׯÿÂäÉ“ÉÈÈЄ„fΜɕ+WØ»w/)))äääжm[âââ˜3gŽ6çzÞ¼y:tˆcÇŽjQDDÇŽ#22’Y³f¡(J¥õÌž=›ýû÷sêÔ)6oÞŒ,ËÌš5ËÂŽÔÔTâãã+Ø»gÏf̘AZZ­[·&;;›ôôt¼½½ùì³ÏÈÊÊÒl²VÞšæòqqq,X°@Ûúè#mvˆÙÛÙÙYØ!IŠ¢XØ›ŸŸOpp0GÅßßJSf§_¶|rr2Ë—/·°Óƒzõꪪøûûãî­--[¶äðáÃ@ižº|^Ú¼kºN§ãÖ­[¨ªJrr2½zõW®@ R"·éåu:Μ9ÍÔ©Sqvv¦k×®8::òꫯH¿~ýèÑ£dddðä“O¤)ôíÚµ‹nݺQ£F ÆG­Zµ´ô„$I„……iº#Öê‘$‰ƒÒ¡CBBBؼy3‹-âÕW_% @³#44”S§N19ÞH×”IDATcÆ Í^'''&NœHÿþýÙ»w/………¬[·“Édu¦Iùò~~~¼úê«vªªZ¡ü?ü€ÑhäâÅ‹„‡‡Ó A‚‚‚˜6mS§NÅËË‹~ýúQTTÄØ±cµr¬^½šFaggǪU«øòË/qpp`íÚµâÊþÜ¡–È)š<ÖRôÞï`–6ý³L›6N:Ñ¡CÑ©Á}Â=¤%"¦”ÝîM®ªê©Š‹ÁýXš~P¯^=ÜÝÝEGÿplDÜû<÷Üs¢ˆ°@8l@ ‡-Âa @8l@ ‡-Âa @8l@ ‡-Âa @8l@ ‡-Âa @8l@ ‡-Âa à®rÇ¢(ŠèA@ (‡$I(ƪßÖï;lU%°öÃäçå‰Q‚J¨ùPLUÔÞQ„mkg'FC þbD[ „ÃpØ@ ¶@ îUlD‚¿ UU‘$Iz€Î©ôÄ„ÃEE…d¤&SRRƒâ³eYÆÕÝWwd¹j“Âa ‚¿%²...&5é&Õ©[e?0¶J^n69Yxxù‡-îRo%âP “ɘ¨sspt&-9éW‡]uéá°Á_]—FØEèmmQŒÆî%IÂh0”ž«ˆ°Á;ÀTÅí;½Ò—ªÂa ‚û? IUïÚŒŠ{ÃeW-Âa ‚¿ Ó]qk¥”¡Qš'ÿÿãæ¿¥_çª÷ÉMC,œcªÞ•ŠÑÈÇŸ|ÊÔw¦³zÝGF$ //å«V£·±ÁF§ãø‰“üï›oÑÉò]°C8l@ ø{€Ê3C_äá  &¿9‘êÕ«óü‹/SPXªá*æ²,s)î2>ÝL›6­1*÷Ç‹O‘«s­Êt„,Ëlß±“gÂûÒ®õã(ŠBX¯Pœøé§7nªJVv6Sf½ËÖõk‘%é×Ù÷~ZDDØàâR\6kŠ¢(¨ªJII 4jÀ©ŸbeOw7F¼1žõË—Aß0„Ã|„]•ÿPUJJ ÇL&öö¥ÜPB‡'ÚrîÂ9t:Ý]±A½KӅçˮò~øaNœ<©Í±±±áRÜe‚ÿÕ EQÈÍ+`ȳÏ0}îû\ûåí{"‚J‘~PQuQ­¢(<Ó¿?ËÖLÔá#äåç³wÿ¶lÿœúõëaRLÈ’„ Û6|D×þÏ’ŸŸw"ý»p3[ ü9‘_[ÕýSÑ¿&áÆ –|¸‚ä”T>Zµ[½L‹àÇ0™\]œØ·m ;þû%66º*·ãn f‰‚¿5!Rõïü$LŠ‘~I’QU…8ý_{÷×Ú4Æqüw’Úÿ,«‹së,ú–¼ÁW7ߌà0¤:ݬLE‡&i/*ÅŠ+M¶%ý~îš‹r’À/‡‡sÎSoèÅóg ÃH’4ØßÓpðTQgss6€â$v6{ͤ8ŽþsÝGáâw’Ì”$³Ü<.À ΰ]q!°0Ã&°àz9§¤È‡õe°ZÀp#Z­¶¾½P³ÝÉÕnëˆãX•JM’£€VGênÝ“WÖé——?tz2V0Ò¼JO`Èyhû¾¯Ý‡úôñ½Þ¼~¥Ä’B4â­×›ê©V¯ÿÙE™Þ]­Øf&¿tGå®ÀÊÌ””ËʆVŒ,qNž7ïïyž|ß_j¤°öß¿<:²«Ãi2™h:.¾§'c Ÿäj#€[•p*H%d‘“ïÞkg·¯$Id&U«F£¥®7™Ï°ÍLA(‚ŵn§¡áèq*€"v£ZÖƒ½ý¥\L+#W.‰ü=0Yú@¾Yf¹˜BqÅñ~à¬ؾïi–“^hùÜÚLžËîTouº[:ÿ|&ç8¥ÀfsÎ)ŠBUkµÌÊÄk­Ã®Öê Ã_:Ÿž©ÑlËQ°¡Âð§¾}¹Poûþí l3S«}W³8VF¼1Ëó|õ‚L'®©ìtôK%ù%6M@¦Øl °€ÀØŠè7'J5¥~˜1—IEND®B`‚paperwork-2.2.2/doc/install.devel.markdown000066400000000000000000000141461456262201400206140ustar00rootroot00000000000000## Contributing Please read [CONTRIBUTING.md](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/-/wikis/Contributing) carefully before submitting any merge request. In this document, it is assumed you are already familiar with the basics of Git. ### Paperwork system-wide Those instructions are useful if you just want to install Paperwork and don't plan on contributing. #### Installation ```sh sudo apt install \ python3-virtualenv virtualenv python3-dev \ gettext \ git \ make \ meson \ build-essential \ libsane-dev \ libgirepository1.0-dev gobject-introspection \ python3-gi \ valac \ gtk-doc-tools cd /tmp git clone git@gitlab.gnome.org:World/OpenPaperwork/paperwork.git cd paperwork # switch to the stable branch ('master') # other possible branches are 'testing' and 'develop' git checkout master sudo make install cd - rm -rf paperwork # Install missing dependencies paperwork-gtk chkdeps # Add icon to menus (you may have to log out and log back in to see them) sudo paperwork-gtk install ``` Later, if you want to update Paperwork, uninstall it (see below) and reinstall it (see above). #### Uninstallation ```sh cd /tmp git clone git@gitlab.gnome.org:World/OpenPaperwork/paperwork.git cd paperwork sudo make uninstall cd - rm -rf paperwork ``` Uninstallation never deletes your work directory nor your documents. Uninstallation doesn't delete Paperwork icons. ## Paperwork in a Virtualenv This is the recommended approach for development. If you intend to work on Paperwork (or just try it), this is probably the most convenient way to install safely a development version of Paperwork. Virtualenv allows to run Paperwork in a specific environment, with the latest versions of most of its dependencies. It also make it easier to remove it (you just have to delete the directory containing the virtualenv). However the user that did the installation will be the only one able to run Paperwork. No shortcut will be installed in the menus of your window manager. Paperwork won't be available directly on your PATH. Paperwork depends on various libraries. Development should be done against the latest versions of the OpenPaper.work's librairies (Libinsane, Libpillowfight, PyOCR, etc). To make things simpler, Paperwork repository includes a script to create and load a Python virtualenv (`source ./activate_test_env.sh`). It will automatically get OpenPaper.work's librairies fresh from Git and install them in this virtualenv. Then the command `make install` will install Paperwork components using Python setuptools. Python setuptools will automatically fetch and install pure-Python dependencies. Finally, `paperwork-cli chkdeps` and `paperwork-gtk chkdeps` will take care of installing the remaining dependencies system-wide using the package manager of your Linux distribution (APT, Dnf, Pacman, etc). ### Requirements You will have to install [python3-virtualenv](https://pypi.python.org/pypi/virtualenv): ```sh sudo apt install python3-virtualenv virtualenv python3-dev ``` [Libinsane](https://gitlab.gnome.org/World/OpenPaperwork/libinsane/-/blob/master/README.markdown) will also be built. This build requires various dependencies: ```sh sudo apt install \ gettext \ make \ meson \ build-essential \ libsane-dev \ libgirepository1.0-dev gobject-introspection \ python3-gi \ valac \ gtk-doc-tools ``` Paperwork requires some data files (documentation, etc) that require a lot of dependencies and time to build. By default, if you don't have those data files, Makefiles and scripts will download the latest version made by the CI/CD builds. If you want to generate the data file (documentation, etc) yourself, you are going to need a whole lot of other dependencies: ```sh sudo apt install \ imagemagick \ po4a \ texlive \ texlive-lang-english \ texlive-lang-french \ texlive-lang-german \ texlive-latex-extra \ texlive-latex-recommended \ xvfb ``` ### Setting up a virtualenv ```sh mkdir -p ~/git cd ~/git git clone https://gitlab.gnome.org/World/OpenPaperwork/paperwork.git cd paperwork # - 'develop' is the branch where any new features, bug fixes, etc should go by # default. # - 'testing' is only for bug fixes, translations and documentations during # the testing phase *only* # - 'master' is the latest stable version of Paperwork + some bug fixes (only # the project maintainer add commits in this branch). git checkout develop # Delete existing Python virtualenv if there is one. # Delete all Paperwork data files if they have been generated or downloaded. make clean # Will create the Python virtualenv if it doesn't exist. # It will compile Libinsane and some other librairies. It will then set the # correct environment variables to use them without installing them # system-wide. source ./activate_test_env.sh # you're now in the virtualenv # 'make install' will install Paperwork in the virtualenv make install # takes care of the dependencies that cannot be installed in the virtualenv # (Gtk, Tesseract, etc) paperwork-cli chkdeps paperwork-gtk chkdeps ``` ### Running Paperwork from the virtualenv ```sh cd ~/git/paperwork source ./activate_test_env.sh # you're now in a virtualenv # Running Paperwork paperwork-gtk # or paperwork-cli --help # or paperwork-json --help ``` ### Updating ```sh cd ~/git/paperwork git pull make clean git submodule update --recursive --remote source ./activate_test_env.sh # you're now in a virtualenv make install ``` ### Generating data files Data files are: - Documentation files (.tex turned into .pdf) - Screenshots (taken with xvfb-run + a script ; used in the documentation files) - Icons at various sizes To generate the screnshots, [the script](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/-/blob/develop/paperwork-gtk/src/paperwork_gtk/model/help/screenshot.sh) will automatically fetch test documents from here: https://gitlab.gnome.org/World/OpenPaperwork/paperwork-test-documents ```sh cd ~/git/paperwork source ./activate_test_env.sh make install make data ``` paperwork-2.2.2/doc/install.flatpak.markdown000066400000000000000000000171661456262201400211440ustar00rootroot00000000000000# Introduction Flatpak is a package manager for Linux. It is available on all major GNU/Linux distributions. It also keeps applications and all their dependencies inside containers, making them easy to update and uninstall. Its advantages: - You get the latest version of Paperwork, directly from its developers. - Paperwork remains nicely packaged. It won't make a mess on your system. Its drawback: - Using Flatpak, Paperwork comes directly from its developers. It has not been reviewed by your distribution maintainers. It may not include some changes that your distribution maintainers would have added. - Scanners are harder to setup - Accessing files outside of your home directory requires some extra manipulations # Quick start ## Installing Flatpak * GNU/Linux Debian: `sudo apt install flatpak` * GNU/Linux Fedora: `sudo dnf install flatpak` ## Installing Paperwork ```sh # Install Paperwork (for the current user only) # can be: # - 'master': stable branch (latest release + some bug fixes) # - 'testing': stabilization branch # - 'develop': development branch (new untested features) flatpak --user install https://builder.openpaper.work/paperwork_.flatpakref # For example: flatpak --user install https://builder.openpaper.work/paperwork_master.flatpakref ``` Flatpak will add a Paperwork icon in your menus. You may have to log out and log back in to see it. Alternatively, you can start Paperwork from a terminal: ```sh flatpak run work.openpaper.Paperwork ``` ## Allowing Paperwork to access scanners IMPORTANT: Paperwork in Flatpak uses Saned to access scanners, and Saned gives access only to local scanners (non-network scanner). If you want to use a network scanner, you will have to install Paperwork from your Linux distribution packages or [from sources](install.devel.markdown). When installed using Flatpak, Paperwork runs in a container. This container prevents Paperwork from accessing devices directly. Therefore the scanning daemon [Saned](https://linux.die.net/man/1/saned) must be enabled on the host system, and connection must be allowed from 127.0.0.1. Instructions can be found in the settings of Paperwork: ![Flatpak + Saned instructions: Step 1](flatpak_saned_1.png) ![Flatpak + Saned instructions: Step 2](flatpak_saned_2.png) ![Flatpak + Saned instructions: Step 3](flatpak_saned_3.png) If after a reboot your scanner is still not found, please see the FAQ below. ## Updating Paperwork ```sh flatpak --user update work.openpaper.Paperwork ``` # FAQ ## Even after following the integrated instructions, my scanner is still not found For some scanners, extra work is required to make them available to Paperwork in Flatpak. It usually comes down to a permission problem: the Saned daemon doesn't have the permissions to access your scanner. ### Debian or Ubuntu The simplest solution is to run Saned as the very same user as you. ```sh sudo sh -c "echo RUN_AS_USER=$(whoami) > /etc/default/saned" sudo reboot ``` ### Other distributions You must add specific udev rules. For example, with a Canon Lide 30: ```console $ lsusb (...) Bus 003 Device 008: ID 04a9:220e Canon, Inc. CanoScan N1240U/LiDE 30 (...) ``` `04a9` is the vendor ID. `220e` is the product ID. The following command will add and enable the required udev rule. You must just change the idVendor and the idProduct in it. ```sh sudo sh -c "echo 'ATTRS{idVendor}==\"04a9\", ATTRS{idProduct}==\"220e\", MODE=\"0666\"' > /lib/udev/rules.d/10-my-scanner.rules" sudo systemctl restart udev ``` Then, you can either disconnect or reconnect your scanner, or reboot your computer. Beware the udev rule above is quite large and will allow any user on your computer to use your scanner. ## No text appears when rendering PDF files. What do I do ? If you run Paperwork from a terminal, you can see the message `some font thing has failed` every time you open a PDF file from Paperwork. This issue is related to fontconfig cache. To fix it: - Stop Paperwork - Run: `flatpak run --command=fc-cache work.openpaper.Paperwork -f` ## How do I run paperwork-cli / paperwork-json ? When using Flatpak, paperwork-cli is also available. Note that it will run inside Paperwork's container and cannot access files outside your home directory. ```sh flatpak run --command=paperwork-cli work.openpaper.Paperwork [args] flatpak run --command=paperwork-cli work.openpaper.Paperwork --help ``` Examples: ```sh flatpak run --command=paperwork-cli work.openpaper.Paperwork help import flatpak run --command=paperwork-cli work.openpaper.Paperwork -bq import ~/tmp/pdf ``` ## Installing support for additional languages By default, Flatpak installs support for English and the language of your system. If you want support for additional languages, you can use the following commands: ```sh flatpak config --user --set languages "en;fr;de" flatpak update --user ``` To get support for all the languages supported by Tesseract (OCR): ```sh flatpak install --reinstall --user work.openpaper.Paperwork.Locale ``` ## What about i386 and ARM architectures ? [Continous integration](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/pipelines) only builds Paperwork for amd64 (aka x86\_64). If you want to run Paperwork on i386 or ARM systems, you can use the [Flathub version](https://flathub.org/apps/details/work.openpaper.Paperwork). If you don't know what architecture your computer is based and if your computer has more than 2GB of RAM, it is probably compatible with amd64. ## How do I update The GPG public key of the Flatpak repository ? Paperwork repository GPG key expires every 2 years. When that happens, when you try updating Paperwork, you will get an output similar to the following one: ``` $ flatpak --user update Looking for updates… F: Error updating remote metadata for 'paperwork-origin': GPG signatures found, but none are in trusted keyring F: Warning: Treating remote fetch error as non-fatal since runtime/work.openpaper.Paperwork.Locale/x86_64/master is already installed: Unable to load summary from remote paperwork-origin: GPG signatures found, but none are in trusted keyring F: Warning: Can't find runtime/work.openpaper.Paperwork.Locale/x86_64/master metadata for dependencies: Unable to load metadata from remote paperwork-origin: summary fetch error: GPG signatures found, but none are in trusted keyring F: Warning: Treating remote fetch error as non-fatal since app/work.openpaper.Paperwork/x86_64/master is already installed: Unable to load summary from remote paperwork-origin: GPG signatures found, but none are in trusted keyring F: Warning: Can't find app/work.openpaper.Paperwork/x86_64/master metadata for dependencies: Unable to load metadata from remote paperwork-origin: summary fetch error: GPG signatures found, but none are in trusted keyring (...) Warning: org.freedesktop.Platform.openh264 needs a later flatpak version Error: GPG signatures found, but none are in trusted keyring Error: GPG signatures found, but none are in trusted keyring Changes complete. error: There were one or more errors ``` The simplest way to fix that is to reinstall Paperwork. Uninstalling Paperwork will never delete your documents. ``` flatpak --user remove work.openpaper.Paperwork flatpak --user remote-delete paperwork-origin flatpak --user install https://builder.openpaper.work/paperwork_master.flatpakref ``` # Build Here are the instructions if you want to try to build the Flatpak version yourself. ```sh git clone https://gitlab.gnome.org/World/OpenPaperwork/paperwork.git cd paperwork/flatpak flatpak --user remote-add --if-not-exists gnome https://sdk.gnome.org/gnome.flatpakrepo flatpak --user install gnome org.gnome.Sdk//3.26 flatpak --user install gnome org.gnome.Platform//3.26 make ``` paperwork-2.2.2/doc/uninstall.linux.markdown000066400000000000000000000006761456262201400212220ustar00rootroot00000000000000Uninstallation *won't* delete your work directory nor your documents. # Paperwork uninstallation using Flatpak If you installed Paperwork using Flatpak, you can uninstall it with: ```sh flatpak --user uninstall work.openpaper.Paperwork ``` # Paperwork uninstallation using virtual-env If you installed Paperwork using Python's virtualenv (`source ./active_test_env.sh`), you can simply delete the Git repository (`rm -rf ~/git/paperwork`). paperwork-2.2.2/flatpak/000077500000000000000000000000001456262201400151535ustar00rootroot00000000000000paperwork-2.2.2/flatpak/1.2.2.json000066400000000000000000000416141456262201400165140ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "1.2.2", "runtime": "org.gnome.Platform", "runtime-version": "3.26", "sdk": "org.gnome.Sdk", "command": "paperwork", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=x11", "--socket=wayland", "--filesystem=home", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.DBus", "--socket=session-bus", "--own-name=work.openpaper.paperwork" ], "modules": [ "shared-modules/tesseract-3.05.01.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-six", "no-autogen": true, "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b3/b2/238e2590826bfdd113244a40d9d3eb26918bd798fc187e2360a8367068db/six-1.10.0.tar.gz", "sha256": "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/51/fc/39a3fbde6864942e8bb24c93663734b74e281b984d1b8c4f95d64b0c21f6/python-dateutil-2.6.0.tar.gz", "sha256": "62a2f8df3d66f878373fd0072eacf4ee52194ba302e00082828e0d263b0418d2" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/93/73/66854f63b1941aad9af18a1de59f9cf95ad1a87c801540222e332f6688d7/Pillow-4.1.1.tar.gz", "sha256": "00b6a5f28d00f720235a937ebc2f50f4292a5c7e2d6ab9a8b26153b625c4f431" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" }, { "type": "patch", "path": "python-pillow-disable-multithreaded-compilation.diff", "strip-components": 0, "dest": ".", "use-git": false } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/35/17/c15d41d5a8f8b98cc3df25eb00c5cee76193114c78e5674df6ef4ac92647/olefile-0.44.zip", "sha256": "61f2ca0cd0aa77279eb943c07f607438edf374096b66332fae1ee64a6f0f73ad" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/4b/51/9155a48faed108db64a0ff45227c752fda8126f3585475cef30b7abaa536/pycountry-17.1.8.tar.gz", "sha256": "c5ccad49e47caee92779bf83da81565159b1fe3d8f48b063068ac118b73dd1f8" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyinsane2", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/89/02/d516f6676ce668626275207e1bb4567404c900854157ea2d1b9b1f2bc2b6/pyinsane2-2.0.9.tar.gz", "sha256": "879cecc7679acac0129b5e3e297236197cbd6991a89faa6dadfae89ce10f8abc" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/6b/5e/0eaa5c939426b0f6a51f9fc883a1d756ad54ac9568faab129440a1dbca24/pyocr-0.4.6.tar.gz", "sha256": "3626ea30ca3d52c8282da672692b216f28cca62fe0e5f97e58f57b7b1d38d56f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/c6/89/a32d817e56314ca8c1532bce4553ba2ca8c93d75766bfd748730841f2cf5/pypillowfight-0.2.1.tar.gz", "sha256": "57bb003ff66979b9b3d5e1e32189f6cd23bb63f2a659f3b97c84ad05ba07992a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/26/28/ee953bd2c030ae5a9e9a0ff68e5912bd90ee50ae766871151cd2572ca570/pyxdg-0.25.tar.gz", "sha256": "81e883e0b9517d624e8b0499eb267b82a815c0b7146d5269f364988ae031279d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-backend", "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/05/36/08c1f5ff9ade9611be788455ed6cac50b3779353d0e8c5594b73df2afe57/paperwork-backend-1.2.2.tar.gz", "sha256": "2d7a957b33592c9bf3107103ed129c81188ca4a1c9052e38cbe583452f0fee0a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-natsort", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8e/6b/a4e3031e573ef29a251984ac0a6bd26cedac6f5e67a7607c9746bd64b3fe/natsort-5.0.3.tar.gz", "sha256": "d57b7a0156f16f49c6c010c9ce97e2125956697846f31bba7cd544cd24b007c1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyenchant", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/73/73/49f95fe636ab3deed0ef1e3b9087902413bcdf74ec00298c3059e660cfbb/pyenchant-1.6.8.tar.gz", "sha256": "7ead2ee74f1a4fc2a7199b3d6012eaaaceea03fbcadcb5df67d2f9d0d51f050a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-termcolor", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz", "sha256": "1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/a9/23/720c7558ba6ad3e0f5ad01e0d6ea2288b486da32f053c73e259f7c392042/setuptools-36.0.1.zip", "sha256": "e17c4687fddd6d70a6604ac0ad25e33324cec71b5137267dd5c45e103c4b288a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "poppler-data", "buildsystem": "cmake", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.7.tar.gz", "sha256": "e752b0d88a7aba54574152143e7bf76436a7ef51977c55d6bd9a48dccde3a7de" } ] }, { "name": "poppler", "buildsystem": "autotools", "config-opts": [ "--enable-libopenjpeg=none", "--enable-xpdf-headers" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.55.0.tar.xz", "sha256": "537f2bc60d796525705ad9ca8e46899dcc99c2e9480b80051808bae265cdc658" } ] }, { "name": "python-paperwork", "make-install-args": ["prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-shell install_system /app/share/icons /app/share"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/11/c9/7027fd39165666236faffa3a5a6ebc9d9c4732df36684b0c5e9b6a675e56/paperwork-1.2.2.tar.gz", "sha256": "18fe3bccd5f9ad16e920baa88985b7e9ba36858b83cdf43cb3591be59cbfc50f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/1.2.3.json000066400000000000000000000420501456262201400165100ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "1.2.3", "runtime": "org.gnome.Platform", "runtime-version": "3.26", "sdk": "org.gnome.Sdk", "command": "paperwork", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=x11", "--socket=wayland", "--filesystem=home", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.DBus", "--socket=session-bus", "--own-name=work.openpaper.paperwork", "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro", "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf" ], "modules": [ "shared-modules/tesseract-3.05.01.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-six", "no-autogen": true, "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b3/b2/238e2590826bfdd113244a40d9d3eb26918bd798fc187e2360a8367068db/six-1.10.0.tar.gz", "sha256": "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/51/fc/39a3fbde6864942e8bb24c93663734b74e281b984d1b8c4f95d64b0c21f6/python-dateutil-2.6.0.tar.gz", "sha256": "62a2f8df3d66f878373fd0072eacf4ee52194ba302e00082828e0d263b0418d2" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/93/73/66854f63b1941aad9af18a1de59f9cf95ad1a87c801540222e332f6688d7/Pillow-4.1.1.tar.gz", "sha256": "00b6a5f28d00f720235a937ebc2f50f4292a5c7e2d6ab9a8b26153b625c4f431" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" }, { "type": "patch", "path": "python-pillow-disable-multithreaded-compilation.diff", "strip-components": 0, "dest": ".", "use-git": false } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/35/17/c15d41d5a8f8b98cc3df25eb00c5cee76193114c78e5674df6ef4ac92647/olefile-0.44.zip", "sha256": "61f2ca0cd0aa77279eb943c07f607438edf374096b66332fae1ee64a6f0f73ad" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/4b/51/9155a48faed108db64a0ff45227c752fda8126f3585475cef30b7abaa536/pycountry-17.1.8.tar.gz", "sha256": "c5ccad49e47caee92779bf83da81565159b1fe3d8f48b063068ac118b73dd1f8" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyinsane2", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/89/02/d516f6676ce668626275207e1bb4567404c900854157ea2d1b9b1f2bc2b6/pyinsane2-2.0.9.tar.gz", "sha256": "879cecc7679acac0129b5e3e297236197cbd6991a89faa6dadfae89ce10f8abc" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/6b/5e/0eaa5c939426b0f6a51f9fc883a1d756ad54ac9568faab129440a1dbca24/pyocr-0.4.6.tar.gz", "sha256": "3626ea30ca3d52c8282da672692b216f28cca62fe0e5f97e58f57b7b1d38d56f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/c6/89/a32d817e56314ca8c1532bce4553ba2ca8c93d75766bfd748730841f2cf5/pypillowfight-0.2.1.tar.gz", "sha256": "57bb003ff66979b9b3d5e1e32189f6cd23bb63f2a659f3b97c84ad05ba07992a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/26/28/ee953bd2c030ae5a9e9a0ff68e5912bd90ee50ae766871151cd2572ca570/pyxdg-0.25.tar.gz", "sha256": "81e883e0b9517d624e8b0499eb267b82a815c0b7146d5269f364988ae031279d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-backend", "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/3f/b9/8cae7c26a9a56a06fa3b1b3c5fc97f633a9a3f543a2a92f9a96edb7df8c0/paperwork-backend-1.2.3.tar.gz", "sha256": "b25aacb754f123465f77ebfbd68adf083025fbc3b240bf8f6cd4019dd9a91bd1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-natsort", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8e/6b/a4e3031e573ef29a251984ac0a6bd26cedac6f5e67a7607c9746bd64b3fe/natsort-5.0.3.tar.gz", "sha256": "d57b7a0156f16f49c6c010c9ce97e2125956697846f31bba7cd544cd24b007c1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyenchant", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/73/73/49f95fe636ab3deed0ef1e3b9087902413bcdf74ec00298c3059e660cfbb/pyenchant-1.6.8.tar.gz", "sha256": "7ead2ee74f1a4fc2a7199b3d6012eaaaceea03fbcadcb5df67d2f9d0d51f050a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-termcolor", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz", "sha256": "1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/a9/23/720c7558ba6ad3e0f5ad01e0d6ea2288b486da32f053c73e259f7c392042/setuptools-36.0.1.zip", "sha256": "e17c4687fddd6d70a6604ac0ad25e33324cec71b5137267dd5c45e103c4b288a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "poppler-data", "buildsystem": "cmake", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.7.tar.gz", "sha256": "e752b0d88a7aba54574152143e7bf76436a7ef51977c55d6bd9a48dccde3a7de" } ] }, { "name": "poppler", "buildsystem": "autotools", "config-opts": [ "--enable-libopenjpeg=none", "--enable-xpdf-headers" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.55.0.tar.xz", "sha256": "537f2bc60d796525705ad9ca8e46899dcc99c2e9480b80051808bae265cdc658" } ] }, { "name": "python-paperwork", "make-install-args": ["prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-shell install_system /app/share/icons /app/share"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/a2/4f/dbc66c0338307528a8ca95a875aeb5bbd12c353723fcd43852cebaa8c715/paperwork-1.2.3.tar.gz", "sha256": "0a715c4aa292d2da73f1a1840d59b628f4907553f30a8557f30041625bab7883" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/1.2.4.json000066400000000000000000000416651456262201400165240ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "1.2.4", "runtime": "org.gnome.Platform", "runtime-version": "3.26", "sdk": "org.gnome.Sdk", "command": "paperwork", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=x11", "--socket=wayland", "--filesystem=home", "--talk-name=org.freedesktop.Notifications", "--own-name=work.openpaper.paperwork", "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro", "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf" ], "modules": [ "shared-modules/tesseract-3.05.01.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-six", "no-autogen": true, "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b3/b2/238e2590826bfdd113244a40d9d3eb26918bd798fc187e2360a8367068db/six-1.10.0.tar.gz", "sha256": "105f8d68616f8248e24bf0e9372ef04d3cc10104f1980f54d57b2ce73a5ad56a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/51/fc/39a3fbde6864942e8bb24c93663734b74e281b984d1b8c4f95d64b0c21f6/python-dateutil-2.6.0.tar.gz", "sha256": "62a2f8df3d66f878373fd0072eacf4ee52194ba302e00082828e0d263b0418d2" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/93/73/66854f63b1941aad9af18a1de59f9cf95ad1a87c801540222e332f6688d7/Pillow-4.1.1.tar.gz", "sha256": "00b6a5f28d00f720235a937ebc2f50f4292a5c7e2d6ab9a8b26153b625c4f431" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" }, { "type": "patch", "path": "python-pillow-disable-multithreaded-compilation.diff", "strip-components": 0, "dest": ".", "use-git": false } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/35/17/c15d41d5a8f8b98cc3df25eb00c5cee76193114c78e5674df6ef4ac92647/olefile-0.44.zip", "sha256": "61f2ca0cd0aa77279eb943c07f607438edf374096b66332fae1ee64a6f0f73ad" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/4b/51/9155a48faed108db64a0ff45227c752fda8126f3585475cef30b7abaa536/pycountry-17.1.8.tar.gz", "sha256": "c5ccad49e47caee92779bf83da81565159b1fe3d8f48b063068ac118b73dd1f8" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyinsane2", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/89/02/d516f6676ce668626275207e1bb4567404c900854157ea2d1b9b1f2bc2b6/pyinsane2-2.0.9.tar.gz", "sha256": "879cecc7679acac0129b5e3e297236197cbd6991a89faa6dadfae89ce10f8abc" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/08/ba/2f3a9f05db05826831b7df5d3c5b3b6d0705819414b2bb5ecfb10c737cf1/pyocr-0.5.1.tar.gz", "sha256": "9ee8b5f38dd966ca531115fc5fe4715f7fa8961a9f14cd5109c2d938c17a2043" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/fb/bf/1716de65f4ef463f9297c61426c0fcba8193a529074450babc407412ccd8/pypillowfight-0.2.3.tar.gz", "sha256": "83653eecf4d58278ab3e01c5188d9a2b33dcaf9603c613d3c8160b31e542d8c9" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/26/28/ee953bd2c030ae5a9e9a0ff68e5912bd90ee50ae766871151cd2572ca570/pyxdg-0.25.tar.gz", "sha256": "81e883e0b9517d624e8b0499eb267b82a815c0b7146d5269f364988ae031279d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-natsort", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8e/6b/a4e3031e573ef29a251984ac0a6bd26cedac6f5e67a7607c9746bd64b3fe/natsort-5.0.3.tar.gz", "sha256": "d57b7a0156f16f49c6c010c9ce97e2125956697846f31bba7cd544cd24b007c1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyenchant", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/73/73/49f95fe636ab3deed0ef1e3b9087902413bcdf74ec00298c3059e660cfbb/pyenchant-1.6.8.tar.gz", "sha256": "7ead2ee74f1a4fc2a7199b3d6012eaaaceea03fbcadcb5df67d2f9d0d51f050a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-termcolor", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz", "sha256": "1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/a9/23/720c7558ba6ad3e0f5ad01e0d6ea2288b486da32f053c73e259f7c392042/setuptools-36.0.1.zip", "sha256": "e17c4687fddd6d70a6604ac0ad25e33324cec71b5137267dd5c45e103c4b288a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.7.tar.gz", "sha256": "e752b0d88a7aba54574152143e7bf76436a7ef51977c55d6bd9a48dccde3a7de" } ] }, { "name": "poppler", "buildsystem": "autotools", "config-opts": [ "--enable-libopenjpeg=none", "--enable-xpdf-headers" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.55.0.tar.xz", "sha256": "537f2bc60d796525705ad9ca8e46899dcc99c2e9480b80051808bae265cdc658" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/e6/3c/ba77e8c087e32e2ef1f34b2eff28f7ce0e3f04989e390bfad0a411530345/paperwork-backend-1.2.4.tar.gz", "sha256": "cfd54f739e1fb8d7acc5ae4f7ff484cb03be8b2c73be185ec3ea30dc1219c0bb" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-shell install_system /app/share/icons /app/share"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/e1/ee/83ed1ebe896ce4f135a204c8a632a80a931840603f2321ab76287f78db65/paperwork-1.2.4.tar.gz", "sha256": "9045d297076dfc219b62bb994ca46fff53b5a990b2f077946d279f366ae3ab4d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/1.3.0.json000066400000000000000000000432541456262201400165150ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "1.3.0", "runtime": "org.gnome.Platform", "runtime-version": "3.30", "sdk": "org.gnome.Sdk", "command": "paperwork", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=home", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--own-name=work.openpaper.paperwork", "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro", "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf", "--device=all" ], "modules": [ "shared-modules/tesseract-4.0.0.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm-git-archive", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-distro", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ca/e3/78443d739d7efeea86cbbe0216511d29b2f5ca8dbf51a6f2898432738987/distro-1.4.0.tar.gz", "sha256": "362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz", "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3c/7e/443be24431324bd34d22dd9d11cc845d995bcd3b500676bcf23142756975/Pillow-5.4.1.tar.gz", "sha256": "5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/87/c7/c2c76c3ae4ac79c74c1871ae775ed97b70d475dd90d1e824b1d2fc0cd54f/pycountry-18.12.8.tar.gz", "sha256": "8ec4020b2b15cd410893d573820d42ee12fe50365332e58c0975c953b60a16de" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "tag": "1.0.1", "disable-shallow-clone": true } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/86/17/5fa0edc8da817a7da0198f03319850cb36cf2f20a38b6c7616fcb36211ef/pyocr-0.7.2.tar.gz", "sha256": "fa15adc7e1cf0d345a2990495fe125a947c6e09a60ddba0256a1c14b2e603179" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/90/70/575e3d04d581e04dccefd52cbb75e26aa07934147b2e85f3fa2896e61eed/pypillowfight-0.2.4.tar.gz", "sha256": "9208518494df900b8842b3d826c55ff673127634bdb2d2c85cca93b5017fd061" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/47/6e/311d5f22e2b76381719b5d0c6e9dc39cd33999adae67db71d7279a6d70f4/pyxdg-0.26.tar.gz", "sha256": "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-natsort", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/b3/5d/c0fbee4ed688fe2ed6533dd4a0124e1470d6692bc29e1da06bc0861ed4ab/natsort-6.0.0.tar.gz", "sha256": "ff3effb5618232866de8d26e5af4081a4daa9bb0dfed49ac65170e28e45f2776" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-termcolor", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz", "sha256": "1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.9.tar.gz", "sha256": "1f9c7e7de9ecd0db6ab287349e31bf815ca108a5a175cf906a90163bdbe32012" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.74.0.tar.xz", "sha256": "92e09fd3302567fd36146b36bb707db43ce436e8841219025a82ea9fb0076b2f" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/38/55/3776279e0f725ab739ba09f6e7db241cde251eb79dcc5681415cf94a13f9/paperwork-backend-1.3.0.tar.gz", "sha256": "08262a62c948b1c75f6dce30f290e181ba7f98b212dcbb05f46d71744b50408a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-shell install_system /app/share/icons /app/share"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/1d/d3/b7ffd1ae7eb5c29f8587145a9cb908e3971fff3d79a6f0322e81c2663089/paperwork-1.3.0.tar.gz", "sha256": "36c32cad431b0119f34ade74b01168df87731e0967028af509ba95f751dcd2fd" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/1.3.1.json000066400000000000000000000432541456262201400165160ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "1.3.1", "runtime": "org.gnome.Platform", "runtime-version": "3.34", "sdk": "org.gnome.Sdk", "command": "paperwork", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=home", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--own-name=work.openpaper.paperwork", "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro", "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf", "--device=all" ], "modules": [ "shared-modules/tesseract-4.0.0.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm-git-archive", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-distro", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ca/e3/78443d739d7efeea86cbbe0216511d29b2f5ca8dbf51a6f2898432738987/distro-1.4.0.tar.gz", "sha256": "362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz", "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3c/7e/443be24431324bd34d22dd9d11cc845d995bcd3b500676bcf23142756975/Pillow-5.4.1.tar.gz", "sha256": "5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/87/c7/c2c76c3ae4ac79c74c1871ae775ed97b70d475dd90d1e824b1d2fc0cd54f/pycountry-18.12.8.tar.gz", "sha256": "8ec4020b2b15cd410893d573820d42ee12fe50365332e58c0975c953b60a16de" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "tag": "1.0.3", "disable-shallow-clone": true } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/86/17/5fa0edc8da817a7da0198f03319850cb36cf2f20a38b6c7616fcb36211ef/pyocr-0.7.2.tar.gz", "sha256": "fa15adc7e1cf0d345a2990495fe125a947c6e09a60ddba0256a1c14b2e603179" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/90/70/575e3d04d581e04dccefd52cbb75e26aa07934147b2e85f3fa2896e61eed/pypillowfight-0.2.4.tar.gz", "sha256": "9208518494df900b8842b3d826c55ff673127634bdb2d2c85cca93b5017fd061" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/47/6e/311d5f22e2b76381719b5d0c6e9dc39cd33999adae67db71d7279a6d70f4/pyxdg-0.26.tar.gz", "sha256": "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-natsort", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/b3/5d/c0fbee4ed688fe2ed6533dd4a0124e1470d6692bc29e1da06bc0861ed4ab/natsort-6.0.0.tar.gz", "sha256": "ff3effb5618232866de8d26e5af4081a4daa9bb0dfed49ac65170e28e45f2776" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-termcolor", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz", "sha256": "1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.9.tar.gz", "sha256": "1f9c7e7de9ecd0db6ab287349e31bf815ca108a5a175cf906a90163bdbe32012" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.74.0.tar.xz", "sha256": "92e09fd3302567fd36146b36bb707db43ce436e8841219025a82ea9fb0076b2f" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/8d/80/293051b9fb7da187ee4dd77b387312c319099f760472ff9b5aedbea27d07/paperwork-backend-1.3.1.tar.gz", "sha256": "7d0ef35bac1904a981ae40693eb8da99ea65ee644c7def084194824808489fa4" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-shell install_system /app/share/icons /app/share"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/d8/ee/429bb189358a558968a7b01148cd4936e1e0734fc35d1640ba75b7ef2b0c/paperwork-1.3.1.tar.gz", "sha256": "d8d229cfa4a0fb9118c93f2d3e9d8f8c5b9ec41397ae4864d8ceeefd141743a2" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/2.0.1.json000066400000000000000000000475131456262201400165160ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "master", "runtime": "org.gnome.Platform", "runtime-version": "3.36", "sdk": "org.gnome.Sdk", "command": "paperwork-gtk", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=home", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*", "--own-name=work.openpaper.paperwork" ], "modules": [ "shared-modules/tesseract-4.1.1.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm-git-archive", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-distro", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ca/e3/78443d739d7efeea86cbbe0216511d29b2f5ca8dbf51a6f2898432738987/distro-1.4.0.tar.gz", "sha256": "362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz", "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-getkey", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/74/f2/3312ea94369f410967667eeca61d261cdf3037df6ea827078ac7c5321150/getkey-0.6.5.tar.gz", "sha256": "68c7c702c3b34deacf427f6c0f1fd66c5c2aa12d7801aa32442fc1a71c8ce059" }, { "type": "patch", "path": "getkey-setup.diff" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-fabulous", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/53/2d/5750798dbb1cd3029c17b6f7456f79948b15f63e4781ffa0be8cf35cfc22/fabulous-0.3.0.tar.gz", "sha256": "54040da01d7ce1e937fc4b61d265e872b007463bea411a3a5762f4d6ee55c312" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3c/7e/443be24431324bd34d22dd9d11cc845d995bcd3b500676bcf23142756975/Pillow-5.4.1.tar.gz", "sha256": "5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/87/c7/c2c76c3ae4ac79c74c1871ae775ed97b70d475dd90d1e824b1d2fc0cd54f/pycountry-18.12.8.tar.gz", "sha256": "8ec4020b2b15cd410893d573820d42ee12fe50365332e58c0975c953b60a16de" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/47/6e/311d5f22e2b76381719b5d0c6e9dc39cd33999adae67db71d7279a6d70f4/pyxdg-0.26.tar.gz", "sha256": "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.9.tar.gz", "sha256": "1f9c7e7de9ecd0db6ab287349e31bf815ca108a5a175cf906a90163bdbe32012" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.74.0.tar.xz", "sha256": "92e09fd3302567fd36146b36bb707db43ce436e8841219025a82ea9fb0076b2f" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "tag": "1.0.8", "disable-shallow-clone": true } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/86/17/5fa0edc8da817a7da0198f03319850cb36cf2f20a38b6c7616fcb36211ef/pyocr-0.7.2.tar.gz", "sha256": "fa15adc7e1cf0d345a2990495fe125a947c6e09a60ddba0256a1c14b2e603179" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/76/73/ce51023006387551b37b286d918e1a4e467f754374dec98d253aaa9ea121/pypillowfight-0.3.0.tar.gz", "sha256": "ec5bcf4b935f3b6e49b327c17f5a804d41ab72966c2b0edfbd45220fb7ad9316" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-openpaperwork-core", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/67/d4/ce1835b729d5e0cf8abbe373d3f2b3140fa42ed92c1df6c69545f6beaba6/openpaperwork-core-2.0.1.tar.gz", "sha256": "5eb92bacb672bae25f85f1012da3ad084ea951f5ef252f38a6bad2f4c7b5da08" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-openpaperwork-gtk", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/9a/71/5ef7c4c7c39a181a715748fa1f59efb5068781fb114697afc8b4cddc4190/openpaperwork-gtk-2.0.1.tar.gz", "sha256": "a137a4a327075125a9b14e510b7cc387af18c5bc7ab6f57f87512f0510b0213f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/64/7d/b3bc8ba5efd1e316989e7a0955e8db58906a119e97d7773e485efc01d66c/paperwork-backend-2.0.1.tar.gz", "sha256": "4a813edf5e517a01b76e9fa7703a0b255241e585e899745d0133c5b655e5c6f4" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-shell", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c0/5e/a3a243025198aff48bc8dc4143e4ed35656d00639feacf40cee13c945a4c/paperwork-shell-2.0.1.tar.gz", "sha256": "bab9baf3199d79fe789ead8e01e5a5c0313b4ef1726fa06f43543c702230e1eb" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-gtk", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-gtk install --icon_base_dir=/app/share/icons --data_base_dir=/app/share"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/cd/42/9434bfc27a03a65fca505b9ed92313081bb29a915a3cb498a44ade11465a/paperwork-2.0.1.tar.gz", "sha256": "b8c376b1afe206436042f5c64b56c3160cb3144887f841d4706271e08e61394b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/2.0.2.json000066400000000000000000000510661456262201400165150ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "master", "runtime": "org.gnome.Platform", "runtime-version": "3.36", "sdk": "org.gnome.Sdk", "command": "paperwork-gtk", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=home", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*", "--own-name=work.openpaper.paperwork" ], "modules": [ "shared-modules/tesseract-4.1.1.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm-git-archive", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-distro", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ca/e3/78443d739d7efeea86cbbe0216511d29b2f5ca8dbf51a6f2898432738987/distro-1.4.0.tar.gz", "sha256": "362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz", "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-getkey", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/74/f2/3312ea94369f410967667eeca61d261cdf3037df6ea827078ac7c5321150/getkey-0.6.5.tar.gz", "sha256": "68c7c702c3b34deacf427f6c0f1fd66c5c2aa12d7801aa32442fc1a71c8ce059" }, { "type": "patch", "path": "getkey-setup.diff" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-fabulous", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/53/2d/5750798dbb1cd3029c17b6f7456f79948b15f63e4781ffa0be8cf35cfc22/fabulous-0.3.0.tar.gz", "sha256": "54040da01d7ce1e937fc4b61d265e872b007463bea411a3a5762f4d6ee55c312" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3c/7e/443be24431324bd34d22dd9d11cc845d995bcd3b500676bcf23142756975/Pillow-5.4.1.tar.gz", "sha256": "5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/87/c7/c2c76c3ae4ac79c74c1871ae775ed97b70d475dd90d1e824b1d2fc0cd54f/pycountry-18.12.8.tar.gz", "sha256": "8ec4020b2b15cd410893d573820d42ee12fe50365332e58c0975c953b60a16de" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/47/6e/311d5f22e2b76381719b5d0c6e9dc39cd33999adae67db71d7279a6d70f4/pyxdg-0.26.tar.gz", "sha256": "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-psutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/e1/b0/7276de53321c12981717490516b7e612364f2cb372ee8901bd4a66a000d7/psutil-5.8.0.tar.gz", "sha256": "0c9ccb99ab76025f2f0bbecf341d4656e9c1351db8cc8a03ccd62e318ab4b5c6" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.9.tar.gz", "sha256": "1f9c7e7de9ecd0db6ab287349e31bf815ca108a5a175cf906a90163bdbe32012" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.74.0.tar.xz", "sha256": "92e09fd3302567fd36146b36bb707db43ce436e8841219025a82ea9fb0076b2f" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "tag": "1.0.9", "disable-shallow-clone": true } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/86/17/5fa0edc8da817a7da0198f03319850cb36cf2f20a38b6c7616fcb36211ef/pyocr-0.7.2.tar.gz", "sha256": "fa15adc7e1cf0d345a2990495fe125a947c6e09a60ddba0256a1c14b2e603179" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/76/73/ce51023006387551b37b286d918e1a4e467f754374dec98d253aaa9ea121/pypillowfight-0.3.0.tar.gz", "sha256": "ec5bcf4b935f3b6e49b327c17f5a804d41ab72966c2b0edfbd45220fb7ad9316" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-openpaperwork-core", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/1b/12/3238d0226b9b276cb6cda94facc82d55f4efe6c1b218c8c255d7858fb02c/openpaperwork-core-2.0.2.tar.gz", "sha256": "c60ddafcecd03466ebad2448b3764d9e168b956c484e3030357ba31d28c6b13a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-openpaperwork-gtk", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/05/76/89335123b672a4e577ff474591bf1f7080e942be366ef110a538a35a892f/openpaperwork-gtk-2.0.2.tar.gz", "sha256": "2491a506c6d966096a744a5a274898c3f297d228121fcc6f0e5db394d621c508" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/0f/43/bc1f8ddf1a80fc3514a6544258e566057bc12b963a8ca9aac1f7acd0f79a/paperwork-backend-2.0.2.tar.gz", "sha256": "b72914e1ff8d7742f4a07db5db0d0e2ec3cf4bcb9b3bf46dc9fe3dc8199cb8d8" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-shell", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/50/b7/6d4029ed9fbb3702f6687c235b1769cf23351ba4b191888735e9a34053f6/paperwork-shell-2.0.2.tar.gz", "sha256": "9c80590b81a475c94cbb49adef64e0f75c84ea6da814908e6b2b98a70583687a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-gtk", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-gtk install --icon_base_dir=/app/share/icons --data_base_dir=/app/share"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/09/57/f9f60dd2d724bc7a4be2352d37a9a33e1177acb0c8a962344ca5eb061b29/paperwork-2.0.2.tar.gz", "sha256": "1a0a161acdd4d8f0741729460b39813a5f1bbbd5ecb032244706f9bcc0189de5" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/2.0.json000066400000000000000000000475011456262201400163540ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "master", "runtime": "org.gnome.Platform", "runtime-version": "3.36", "sdk": "org.gnome.Sdk", "command": "paperwork-gtk", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=home", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--talk-name=org.gtk.vfs", "--talk-name=org.gtk.vfs.*", "--own-name=work.openpaper.paperwork" ], "modules": [ "shared-modules/tesseract-4.1.1.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm-git-archive", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-distro", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ca/e3/78443d739d7efeea86cbbe0216511d29b2f5ca8dbf51a6f2898432738987/distro-1.4.0.tar.gz", "sha256": "362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz", "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-getkey", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/74/f2/3312ea94369f410967667eeca61d261cdf3037df6ea827078ac7c5321150/getkey-0.6.5.tar.gz", "sha256": "68c7c702c3b34deacf427f6c0f1fd66c5c2aa12d7801aa32442fc1a71c8ce059" }, { "type": "patch", "path": "getkey-setup.diff" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-fabulous", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/53/2d/5750798dbb1cd3029c17b6f7456f79948b15f63e4781ffa0be8cf35cfc22/fabulous-0.3.0.tar.gz", "sha256": "54040da01d7ce1e937fc4b61d265e872b007463bea411a3a5762f4d6ee55c312" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3c/7e/443be24431324bd34d22dd9d11cc845d995bcd3b500676bcf23142756975/Pillow-5.4.1.tar.gz", "sha256": "5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/87/c7/c2c76c3ae4ac79c74c1871ae775ed97b70d475dd90d1e824b1d2fc0cd54f/pycountry-18.12.8.tar.gz", "sha256": "8ec4020b2b15cd410893d573820d42ee12fe50365332e58c0975c953b60a16de" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/47/6e/311d5f22e2b76381719b5d0c6e9dc39cd33999adae67db71d7279a6d70f4/pyxdg-0.26.tar.gz", "sha256": "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.9.tar.gz", "sha256": "1f9c7e7de9ecd0db6ab287349e31bf815ca108a5a175cf906a90163bdbe32012" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.74.0.tar.xz", "sha256": "92e09fd3302567fd36146b36bb707db43ce436e8841219025a82ea9fb0076b2f" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "tag": "1.0.8", "disable-shallow-clone": true } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/86/17/5fa0edc8da817a7da0198f03319850cb36cf2f20a38b6c7616fcb36211ef/pyocr-0.7.2.tar.gz", "sha256": "fa15adc7e1cf0d345a2990495fe125a947c6e09a60ddba0256a1c14b2e603179" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/76/73/ce51023006387551b37b286d918e1a4e467f754374dec98d253aaa9ea121/pypillowfight-0.3.0.tar.gz", "sha256": "ec5bcf4b935f3b6e49b327c17f5a804d41ab72966c2b0edfbd45220fb7ad9316" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-openpaperwork-core", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/f8/1b/9735c4835429086e7d6b732a678fa4dedfb7347c0a723326d9416c8d683b/openpaperwork-core-2.0.tar.gz", "sha256": "65492f937f1e166f0aeac99e8488526d0cf30e30ea1ba1621d83b8cfb21b0514" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-openpaperwork-gtk", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ea/9a/b9f8bea49b99d78b87a9d9bfcef6bf2b5b54d66ee207da8aadc0d582de6a/openpaperwork-gtk-2.0.tar.gz", "sha256": "062052779defa9979069e8eef9e858f2870937d47e2477b14be8a03e03f456d7" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/5e/9d/7b8986069c54777460db75a1882bcab19cd7d1e4f9f7017140ccde4fc1c4/paperwork-backend-2.0.tar.gz", "sha256": "bfe938cf0dd17a91b10e2449da979d608cf3635e721cd1bebc5cf5b29ae87fd9" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-shell", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/77/24/56696480a4509aca5fde27ec50045b103e9fc5fb21aa76393ff70da902c7/paperwork-shell-2.0.tar.gz", "sha256": "8940974d2f23e942c6beec40c1052625515ab14150d470e72ed539f6b546fe6a" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork-gtk", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-gtk install --icon_base_dir=/app/share/icons --data_base_dir=/app/share"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/67/ee/1232f268d06b08cdda5d32ad1ef29a0a45ada23fb0b9381f16c818e86555/paperwork-2.0.tar.gz", "sha256": "252f8f13375c2e8590561ed876939bdf5a0365e1bd93f17226c964df21d2fa41" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/Makefile000066400000000000000000000030301456262201400166070ustar00rootroot00000000000000REPO ?= $(abspath paperwork_repo) APP = work.openpaper.Paperwork ALL_TARGETS = $(patsubst %.json,%,$(wildcard *.json)) ALL_BRANCHES = master testing develop all: upd_branches # clean: remove all intermediate files clean: rm -rf *.app *.flatpak # dist-clean: remove *everything* that is not stored in Git dist-clean: clean rm -rf $(REPO) .flatpak-builder # Build a specific branch / tag # Will export to the Flatpak repository $(REPO) %.app: ../work.openpaper.Paperwork.json @echo flatpak-builder $< --\> $@ \($(REPO) ${EXPORT_ARGS} ${ARCH_ARGS}\) cd ../ && flatpak-builder --repo=$(REPO) -s "Build of Paperwork $(@:%.app=%) `date`" ${EXPORT_ARGS} ${ARCH_ARGS} flatpak/$@ work.openpaper.Paperwork.json upd_repo: @echo flatpak build-update-repo $(REPO) \($(REPO) ${EXPORT_ARGS} ${ARCH_ARGS}\) flatpak build-update-repo --generate-static-deltas ${EXPORT_ARGS} $(REPO) # Build all branches and tags and update the Flatpak repository $(REPO) mk_all: $(patsubst %,%.app,$(ALL_TARGETS)) $(MAKE) upd_repo # Build only the branches and update the Flatpak repository $(REPO) upd_branches: $(patsubst %,%.app,$(ALL_BRANCHES)) $(MAKE upd_repo) # Can be used if you call %.app manually first # Build a Flatpak bundle %.flatpak: %.app $(MAKE) upd_repo @echo flatpak build-bundle $(REPO) --\> $@ \(${EXPORT_ARGS} ${ARCH_ARGS} branch: $(@:%.flatpak=%)\) flatpak -v build-bundle ${ARCH_ARGS} $(REPO) $@ $(APP) $(@:%.flatpak=%) # Build all Flatpak bundles bundles: $(patsubst %,%.flatpak,$(ALL_TARGETS)) .PHONY: all clean dist-clean mkrepo bundles upd_repo paperwork-2.2.2/flatpak/getkey-setup.diff000066400000000000000000000003141456262201400204310ustar00rootroot00000000000000--- a/setup.py 2020-06-28 23:11:43.217511302 +0200 +++ b/setup.py 2020-06-28 23:11:53.353700987 +0200 @@ -71,6 +71,5 @@ install_requires=[ ], setup_requires=[ - 'flake8', ], ) paperwork-2.2.2/flatpak/pip-Makefile000066400000000000000000000001271456262201400174010ustar00rootroot00000000000000all: python3 setup.py build install: python3 setup.py install --prefix=/app ${ARGS} paperwork-2.2.2/flatpak/pypillowfight-Makefile000066400000000000000000000040161456262201400215130ustar00rootroot00000000000000# If you want to build in MSYS2 on Windows # export CMAKE_OPTS=-G "MSYS Makefiles" VERSION_FILE = src/pillowfight/_version.h PYTHON = python3 build: build_c build_py install: ${VERSION_FILE} python3 setup.py install --prefix=/app ${ARGS} uninstall: uninstall_py build_py: ${VERSION_FILE} ${PYTHON} ./setup.py build build_c: ${VERSION_FILE} build/libpillowfight.so build/libpillowfight.so: ${VERSION_FILE} build/Makefile (cd build && make -j4) build/Makefile: mkdir -p build (cd build && cmake ${CMAKE_OPTS} ..) ${VERSION_FILE}: echo -n "#define INTERNAL_PILLOWFIGHT_VERSION \"" >| $@ echo -n $(shell git describe --always) >> $@ echo "\"" >> $@ version: ${VERSION_FILE} doc: install_py (cd doc && make html) doxygen doc/doxygen.conf cp doc/index.html doc/build/index.html check: flake8 # pydocstyle src test: build_py tox linux_exe: windows_exe: release: ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" else @echo "Will release: ${RELEASE}" @echo "Checking release is in ChangeLog ..." grep ${RELEASE} ChangeLog | grep -v "/xx" @echo "Releasing ..." git tag -a ${RELEASE} -m ${RELEASE} git push origin ${RELEASE} make clean make version ${PYTHON} ./setup.py sdist upload @echo "All done" endif clean: rm -rf doc/build rm -rf build dist *.egg-info rm -f ${VERSION_FILE} install_py: ${VERSION_FILE} ${PYTHON} ./setup.py install ${PIP_ARGS} install_c: build/Makefile ${VERSION_FILE} (cd build && make install) uninstall_py: pip3 uninstall -y pypillowfight uninstall_c: echo "Can't uninstall C library. Sorry" help: @echo "make build || make build_c || make build_py" @echo "make check" @echo "make doc" @echo "make help: display this message" @echo "make install || make install_c || make install_py" @echo "make release" @echo "make test" @echo "make uninstall || make uninstall_py" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ exe \ help \ install \ install_c \ install_py \ release \ test \ uninstall \ uninstall_c \ version paperwork-2.2.2/flatpak/python-pillow-disable-multithreaded-compilation.diff000066400000000000000000000005511456262201400274010ustar00rootroot00000000000000--- setup.py 2017-11-16 21:02:44.002328167 +0100 +++ setup.py 2017-11-16 21:03:48.353489990 +0100 @@ -22,7 +22,7 @@ # monkey patch import hook. Even though flake8 says it's not used, it is. # comment this out to disable multi threaded builds. -import mp_compile +# import mp_compile _IMAGING = ("decode", "encode", "map", "display", "outline", "path") paperwork-2.2.2/flatpak/release.json000066400000000000000000000432561456262201400175000ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "release", "runtime": "org.gnome.Platform", "runtime-version": "3.34", "sdk": "org.gnome.Sdk", "command": "paperwork", "copy-icon": true, "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=home", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--own-name=work.openpaper.paperwork", "--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro", "--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf", "--device=all" ], "modules": [ "shared-modules/tesseract-4.0.0.json", "shared-modules/sane-backends-1.0.27.json", { "name": "python-setuptools", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-setuptools-scm-git-archive", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-distro", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ca/e3/78443d739d7efeea86cbbe0216511d29b2f5ca8dbf51a6f2898432738987/distro-1.4.0.tar.gz", "sha256": "362dde65d846d23baee4b5c058c8586f219b5a54be1cf5fc6ff55c4578392f57" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-dateutil", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ad/99/5b2e99737edeb28c71bcbec5b5dda19d0d9ef3ca3e92e3e925e7c0bb364c/python-dateutil-2.8.0.tar.gz", "sha256": "c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-Levenshtein", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/42/a9/d1785c85ebf9b7dfacd08938dd028209c34a0ea3b1bcdb895208bd40a67d/python-Levenshtein-0.12.0.tar.gz", "sha256": "033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pillow", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3c/7e/443be24431324bd34d22dd9d11cc845d995bcd3b500676bcf23142756975/Pillow-5.4.1.tar.gz", "sha256": "5233664eadfa342c639b9b9977190d64ad7aca4edc51a966394d7e08e7f38a9f" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "python-olefile", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] }, { "name": "python-pycountry", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/87/c7/c2c76c3ae4ac79c74c1871ae775ed97b70d475dd90d1e824b1d2fc0cd54f/pycountry-18.12.8.tar.gz", "sha256": "8ec4020b2b15cd410893d573820d42ee12fe50365332e58c0975c953b60a16de" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-nose", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "tag": "1.0.3", "disable-shallow-clone": true } ] }, { "name": "python-pyocr", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/86/17/5fa0edc8da817a7da0198f03319850cb36cf2f20a38b6c7616fcb36211ef/pyocr-0.7.2.tar.gz", "sha256": "fa15adc7e1cf0d345a2990495fe125a947c6e09a60ddba0256a1c14b2e603179" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pypillowfight", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/90/70/575e3d04d581e04dccefd52cbb75e26aa07934147b2e85f3fa2896e61eed/pypillowfight-0.2.4.tar.gz", "sha256": "9208518494df900b8842b3d826c55ff673127634bdb2d2c85cca93b5017fd061" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pyxdg", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/47/6e/311d5f22e2b76381719b5d0c6e9dc39cd33999adae67db71d7279a6d70f4/pyxdg-0.26.tar.gz", "sha256": "fe2928d3f532ed32b39c32a482b54136fe766d19936afc96c8f00645f9da1a06" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-pydbus", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-natsort", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/b3/5d/c0fbee4ed688fe2ed6533dd4a0124e1470d6692bc29e1da06bc0861ed4ab/natsort-6.0.0.tar.gz", "sha256": "ff3effb5618232866de8d26e5af4081a4daa9bb0dfed49ac65170e28e45f2776" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-simplebayes", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/b9/73/764578df72934940d95a8941cbd374b56319562dda72630fc8bfeaefc350/simplebayes-1.5.8.tar.gz", "sha256": "363418c0ef185ac2158ebbd6d8afb45aa997254fcb809a73ed20a7d5dccf8b85" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-whoosh", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-termcolor", "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz", "sha256": "1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.9.tar.gz", "sha256": "1f9c7e7de9ecd0db6ab287349e31bf815ca108a5a175cf906a90163bdbe32012" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-0.74.0.tar.xz", "sha256": "92e09fd3302567fd36146b36bb707db43ce436e8841219025a82ea9fb0076b2f" } ] }, { "name": "python-paperwork-backend", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/8d/80/293051b9fb7da187ee4dd77b387312c319099f760472ff9b5aedbea27d07/paperwork-backend-1.3.1.tar.gz", "sha256": "7d0ef35bac1904a981ae40693eb8da99ea65ee644c7def084194824808489fa4" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] }, { "name": "python-paperwork", "make-install-args": ["PIP_ARGS=--prefix=/app"], "no-autogen": true, "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "post-install": ["paperwork-shell install_system /app/share/icons /app/share"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/d8/ee/429bb189358a558968a7b01148cd4936e1e0734fc35d1640ba75b7ef2b0c/paperwork-1.3.1.tar.gz", "sha256": "d8d229cfa4a0fb9118c93f2d3e9d8f8c5b9ec41397ae4864d8ceeefd141743a2" }, { "type": "file", "path": "pip-Makefile", "dest-filename": "Makefile" } ] } ] } paperwork-2.2.2/flatpak/shared-modules/000077500000000000000000000000001456262201400200675ustar00rootroot00000000000000paperwork-2.2.2/flatpak/shared-modules/libreoffice-7.0.4.2.json000066400000000000000000001020061456262201400240360ustar00rootroot00000000000000{ "_comment": "Copy pasta from https://raw.githubusercontent.com/flathub/org.libreoffice.LibreOffice/master/org.libreoffice.LibreOffice.json", "name": "libreoffice-complete", "modules": [ { "name": "openjdk", "buildsystem": "simple", "build-commands": [ "/usr/lib/sdk/openjdk11/install.sh" ] }, { "name": "libreoffice", "sources": [ { "type": "git", "url": "https://gerrit.libreoffice.org/core", "branch": "libreoffice-7.0.4.2", "disable-fsckobjects": true }, { "type": "archive", "url": "https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.5-bin.tar.xz", "sha256": "cebb705dbbe26a41d359b8be08ec066caba4e8686670070ce44bbf2b57ae113f", "dest": "ant" }, { "commands": [ "mkdir external/tarballs" ], "type": "shell" }, { "url": "https://dev-www.libreoffice.org/src/pdfium-4306.tar.bz2", "sha256": "eca406d47ac7e2a84dcc86f93c08f96e591d409589e881477fa75e488e4851d8", "type": "file", "dest-filename": "external/tarballs/pdfium-4306.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz", "sha256": "983941d31ee8d366085cadf28db75eb1f5cb03ba1e5853b98f12f7f51c63b776", "type": "file", "dest-filename": "external/tarballs/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/xmlsec1-1.2.30.tar.gz", "sha256": "2d84360b03042178def1d9ff538acacaed2b3a27411db7b2874f1612ed71abc8", "type": "file", "dest-filename": "external/tarballs/xmlsec1-1.2.30.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz", "sha256": "c48d1c2fd613c9c06c959c34da7b8388059e2408d2bb19845dc3ed35f76e4d09", "type": "file", "dest-filename": "external/tarballs/368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz", "sha256": "4bd12b6cbc321c1cf16da76e2c585c925ce956a08067ae6f6c64eff6ccfdaf5a", "type": "file", "dest-filename": "external/tarballs/c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip", "sha256": "7576310b219e04159d35ff61dd4a4ec4cdba4f35c00e002a136f00e96a908b0a", "type": "file", "dest-filename": "external/tarballs/33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip" }, { "url": "https://dev-www.libreoffice.org/src/1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip", "sha256": "2f1a2c5491d7305dffd3520c6375d2f3e14931ee35c6d8ae1e8f098bf1a7b3cc", "type": "file", "dest-filename": "external/tarballs/1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip" }, { "url": "https://dev-www.libreoffice.org/src/liberation-narrow-fonts-ttf-1.07.6.tar.gz", "sha256": "8879d89b5ff7b506c9fc28efc31a5c0b954bbe9333e66e5283d27d20a8519ea3", "type": "file", "dest-filename": "external/tarballs/liberation-narrow-fonts-ttf-1.07.6.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/liberation-fonts-ttf-2.00.4.tar.gz", "sha256": "c40e95fc5e0ecb73d4be565ae2afc1114e2bc7dc5253e00ee92d8fd6cc4adf45", "type": "file", "dest-filename": "external/tarballs/liberation-fonts-ttf-2.00.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip", "sha256": "54adcb2bc8cac0927a647fbd9362f45eff48130ce6e2379dc3867643019e08c5", "type": "file", "dest-filename": "external/tarballs/e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip" }, { "url": "https://dev-www.libreoffice.org/src/907d6e99f241876695c19ff3db0b8923-source-code-pro-2.030R-ro-1.050R-it.tar.gz", "sha256": "09466dce87653333f189acd8358c60c6736dcd95f042dee0b644bdcf65b6ae2f", "type": "file", "dest-filename": "external/tarballs/907d6e99f241876695c19ff3db0b8923-source-code-pro-2.030R-ro-1.050R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz", "sha256": "e7bc9a1fec787a529e49f5a26b93dcdcf41506449dfc70f92cdef6d17eb6fb61", "type": "file", "dest-filename": "external/tarballs/edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/source-serif-pro-3.000R.tar.gz", "sha256": "826a2b784d5cdb4c2bbc7830eb62871528360a61a52689c102a101623f1928e3", "type": "file", "dest-filename": "external/tarballs/source-serif-pro-3.000R.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/EmojiOneColor-SVGinOT-1.3.tar.gz", "sha256": "d1a08f7c10589f22740231017694af0a7a270760c8dec33d8d1c038e2be0a0c7", "type": "file", "dest-filename": "external/tarballs/EmojiOneColor-SVGinOT-1.3.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/boost_1_71_0.tar.xz", "sha256": "35e06a3bd7cd8f66be822c7d64e80c2b6051a181e9e897006917cb8e7988a543", "type": "file", "dest-filename": "external/tarballs/boost_1_71_0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz", "sha256": "ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8c51d79732eab", "type": "file", "dest-filename": "external/tarballs/48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/CoinMP-1.7.6.tgz", "sha256": "86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f", "type": "file", "dest-filename": "external/tarballs/CoinMP-1.7.6.tgz" }, { "url": "https://dev-www.libreoffice.org/src/cppunit-1.15.1.tar.gz", "sha256": "89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7", "type": "file", "dest-filename": "external/tarballs/cppunit-1.15.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Firebird-3.0.0.32483-0.tar.bz2", "sha256": "6994be3555e23226630c587444be19d309b25b0fcf1f87df3b4e3f88943e5860", "type": "file", "dest-filename": "external/tarballs/Firebird-3.0.0.32483-0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/glm-0.9.9.7.zip", "sha256": "c5e167c042afd2d7ad642ace6b643863baeb33880781983563e1ab68a30d3e95", "type": "file", "dest-filename": "external/tarballs/glm-0.9.9.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/gpgme-1.9.0.tar.bz2", "sha256": "1b29fedb8bfad775e70eafac5b0590621683b2d9869db994568e6401f4034ceb", "type": "file", "dest-filename": "external/tarballs/gpgme-1.9.0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libassuan-2.5.1.tar.bz2", "sha256": "47f96c37b4f2aac289f0bc1bacfa8bd8b4b209a488d3d15e2229cb6cc9b26449", "type": "file", "dest-filename": "external/tarballs/libassuan-2.5.1.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libgpg-error-1.27.tar.bz2", "sha256": "4f93aac6fecb7da2b92871bb9ee33032be6a87b174f54abf8ddf0911a22d29d2", "type": "file", "dest-filename": "external/tarballs/libgpg-error-1.27.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libabw-0.1.3.tar.xz", "sha256": "e763a9dc21c3d2667402d66e202e3f8ef4db51b34b79ef41f56cacb86dcd6eed", "type": "file", "dest-filename": "external/tarballs/libabw-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcdr-0.1.6.tar.xz", "sha256": "01cd00b04a030977e544433c2d127c997205332cd9b8e35ec0ee17110da7f861", "type": "file", "dest-filename": "external/tarballs/libcdr-0.1.6.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcmis-0.5.2.tar.xz", "sha256": "d7b18d9602190e10d437f8a964a32e983afd57e2db316a07d87477a79f5000a2", "type": "file", "dest-filename": "external/tarballs/libcmis-0.5.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libe-book-0.1.3.tar.xz", "sha256": "7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9", "type": "file", "dest-filename": "external/tarballs/libe-book-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libetonyek-0.1.9.tar.xz", "sha256": "e61677e8799ce6e55b25afc11aa5339113f6a49cff031f336e32fa58635b1a4a", "type": "file", "dest-filename": "external/tarballs/libetonyek-0.1.9.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libexttextcat-3.4.5.tar.xz", "sha256": "13fdbc9d4c489a4d0519e51933a1aa21fe3fb9eb7da191b87f7a63e82797dac8", "type": "file", "dest-filename": "external/tarballs/libexttextcat-3.4.5.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libfreehand-0.1.2.tar.xz", "sha256": "0e422d1564a6dbf22a9af598535425271e583514c0f7ba7d9091676420de34ac", "type": "file", "dest-filename": "external/tarballs/libfreehand-0.1.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/language-subtag-registry-2020-09-29.tar.bz2", "sha256": "cbe9fca811a37056560aab73e9fc9d3522b46b6785cb02db165f521bf42c230f", "type": "file", "dest-filename": "external/tarballs/language-subtag-registry-2020-09-29.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/liblangtag-0.6.2.tar.bz2", "sha256": "d6242790324f1432fb0a6fae71b6851f520b2c5a87675497cf8ea14c2924d52e", "type": "file", "dest-filename": "external/tarballs/liblangtag-0.6.2.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libmspub-0.1.4.tar.xz", "sha256": "ef36c1a1aabb2ba3b0bedaaafe717bf4480be2ba8de6f3894be5fd3702b013ba", "type": "file", "dest-filename": "external/tarballs/libmspub-0.1.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libmwaw-0.3.16.tar.xz", "sha256": "0c639edba5297bde5575193bf5b5f2f469956beaff5c0206d91ce9df6bde1868", "type": "file", "dest-filename": "external/tarballs/libmwaw-0.3.16.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libodfgen-0.1.6.tar.bz2", "sha256": "2c7b21892f84a4c67546f84611eccdad6259875c971e98ddb027da66ea0ac9c2", "type": "file", "dest-filename": "external/tarballs/libodfgen-0.1.6.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libpagemaker-0.0.4.tar.xz", "sha256": "66adacd705a7d19895e08eac46d1e851332adf2e736c566bef1164e7a442519d", "type": "file", "dest-filename": "external/tarballs/libpagemaker-0.0.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/librevenge-0.0.4.tar.bz2", "sha256": "c51601cd08320b75702812c64aae0653409164da7825fd0f451ac2c5dbe77cbf", "type": "file", "dest-filename": "external/tarballs/librevenge-0.0.4.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libstaroffice-0.0.7.tar.xz", "sha256": "f94fb0ad8216f97127bedef163a45886b43c62deac5e5b0f5e628e234220c8db", "type": "file", "dest-filename": "external/tarballs/libstaroffice-0.0.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/ltm-1.0.zip", "sha256": "083daa92d8ee6f4af96a6143b12d7fc8fe1a547e14f862304f7281f8f7347483", "type": "file", "dest-filename": "external/tarballs/ltm-1.0.zip" }, { "url": "https://dev-www.libreoffice.org/src/libvisio-0.1.7.tar.xz", "sha256": "8faf8df870cb27b09a787a1959d6c646faa44d0d8ab151883df408b7166bea4c", "type": "file", "dest-filename": "external/tarballs/libvisio-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpd-0.10.3.tar.xz", "sha256": "2465b0b662fdc5d4e3bebcdc9a79027713fb629ca2bff04a3c9251fdec42dd09", "type": "file", "dest-filename": "external/tarballs/libwpd-0.10.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpg-0.3.3.tar.xz", "sha256": "99b3f7f8832385748582ab8130fbb9e5607bd5179bebf9751ac1d51a53099d1c", "type": "file", "dest-filename": "external/tarballs/libwpg-0.3.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwps-0.4.11.tar.xz", "sha256": "a8fdaabc28654a975fa78c81873ac503ba18f0d1cdbb942f470a21d29284b4d1", "type": "file", "dest-filename": "external/tarballs/libwps-0.4.11.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libzmf-0.0.2.tar.xz", "sha256": "27051a30cb057fdb5d5de65a1f165c7153dc76e27fe62251cbb86639eb2caf22", "type": "file", "dest-filename": "external/tarballs/libzmf-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz", "sha256": "171816288f14215c69e730f7a4f1c325739873e21f946ff83884b350574e6695", "type": "file", "dest-filename": "external/tarballs/26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.1.8-src.tar.gz", "sha256": "431434d3926f4bcce2e5c97240609983f60d7ff50df5a72083934759bb863f7b", "type": "file", "dest-filename": "external/tarballs/mariadb-connector-c-3.1.8-src.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mdds-1.6.0.tar.bz2", "sha256": "f1585c9cbd12f83a6d43d395ac1ab6a9d9d5d77f062c7b5f704e24ed72dae07d", "type": "file", "dest-filename": "external/tarballs/mdds-1.6.0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/neon-0.30.2.tar.gz", "sha256": "db0bd8cdec329b48f53a6f00199c92d5ba40b0f015b153718d1b15d3d967fbca", "type": "file", "dest-filename": "external/tarballs/neon-0.30.2.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/noto-fonts-20171024.tar.gz", "sha256": "29acc15a4c4d6b51201ba5d60f303dfbc2e5acbfdb70413c9ae1ed34fa259994", "type": "file", "dest-filename": "external/tarballs/noto-fonts-20171024.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/openldap-2.4.45.tgz", "sha256": "cdd6cffdebcd95161a73305ec13fc7a78e9707b46ca9f84fb897cd5626df3824", "type": "file", "dest-filename": "external/tarballs/openldap-2.4.45.tgz" }, { "url": "https://dev-www.libreoffice.org/src/liborcus-0.15.4.tar.bz2", "sha256": "cfb2aa60825f2a78589ed030c07f46a1ee16ef8a2d1bf2279192fbc1ae5a5f61", "type": "file", "dest-filename": "external/tarballs/liborcus-0.15.4.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/poppler-0.82.0.tar.xz", "sha256": "234f8e573ea57fb6a008e7c1e56bfae1af5d1adf0e65f47555e1ae103874e4df", "type": "file", "dest-filename": "external/tarballs/poppler-0.82.0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/postgresql-9.2.24.tar.bz2", "sha256": "a754c02f7051c2f21e52f8669a421b50485afcde9a581674d6106326b189d126", "type": "file", "dest-filename": "external/tarballs/postgresql-9.2.24.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/QR-Code-generator-1.4.0.tar.gz", "sha256": "fcdf9fd69fde07ae4dca2351d84271a9de8093002f733b77c70f52f1630f6e4a", "type": "file", "dest-filename": "external/tarballs/QR-Code-generator-1.4.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz", "sha256": "ada7f0ba54787b33485d090d3d2680533520cd4426d2f7fb4782dd4a6a1480ed", "type": "file", "dest-filename": "external/tarballs/a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz", "sha256": "6924c9ac6570bd241a9669f83b467c728a322470bf34f4b2da4f69492ccfd97c", "type": "file", "dest-filename": "external/tarballs/1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz", "sha256": "de1847f7b59021c16bdc72abb4d8e2d9187cd6124d69156f3326dd34ee043681", "type": "file", "dest-filename": "external/tarballs/e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/ReemKufi-0.7.zip", "sha256": "f60c6508d209ce4236d2d7324256c2ffddd480be7e3d6023770b93dc391a605f", "type": "file", "dest-filename": "external/tarballs/ReemKufi-0.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/libepubgen-0.1.1.tar.xz", "sha256": "03e084b994cbeffc8c3dd13303b2cb805f44d8f2c3b79f7690d7e3fc7f6215ad", "type": "file", "dest-filename": "external/tarballs/libepubgen-0.1.1.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libqxp-0.0.2.tar.xz", "sha256": "e137b6b110120a52c98edd02ebdc4095ee08d0d5295a94316a981750095a945c", "type": "file", "dest-filename": "external/tarballs/libqxp-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/alef-1.001.tar.gz", "sha256": "b98b67602a2c8880a1770f0b9e37c190f29a7e2ade5616784f0b89fbdb75bf52", "type": "file", "dest-filename": "external/tarballs/alef-1.001.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Amiri-0.111.zip", "sha256": "1fbfccced6348b5db2c1c21d5b319cd488e14d055702fa817a0f6cb83d882166", "type": "file", "dest-filename": "external/tarballs/Amiri-0.111.zip" }, { "url": "https://dev-www.libreoffice.org/src/culmus-0.131.tar.gz", "sha256": "dcf112cfcccb76328dcfc095f4d7c7f4d2f7e48d0eed5e78b100d1d77ce2ed1b", "type": "file", "dest-filename": "external/tarballs/culmus-0.131.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/libre-hebrew-1.0.tar.gz", "sha256": "f596257c1db706ce35795b18d7f66a4db99d427725f20e9384914b534142579a", "type": "file", "dest-filename": "external/tarballs/libre-hebrew-1.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Scheherazade-2.100.zip", "sha256": "251c8817ceb87d9b661ce1d5b49e732a0116add10abc046be4b8ba5196e149b5", "type": "file", "dest-filename": "external/tarballs/Scheherazade-2.100.zip" }, { "url": "https://dev-www.libreoffice.org/src/ttf-kacst_2.01+mry.tar.gz", "sha256": "dca00f5e655f2f217a766faa73a81f542c5c204aa3a47017c3c2be0b31d00a56", "type": "file", "dest-filename": "external/tarballs/ttf-kacst_2.01+mry.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip", "sha256": "9e93c73e23aff644b17dfff656444474c14150e7f3b38b19635e622235e01c96", "type": "file", "dest-filename": "external/tarballs/beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip" }, { "url": "https://dev-www.libreoffice.org/src/commons-logging-1.2-src.tar.gz", "sha256": "49665da5a60d033e6dff40fe0a7f9173e886ae859ce6096c1afe34c48b677c81", "type": "file", "dest-filename": "external/tarballs/commons-logging-1.2-src.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip", "sha256": "233f66e8d25c5dd971716d4200203a612a407649686ef3b52075d04b4c9df0dd", "type": "file", "dest-filename": "external/tarballs/ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip" }, { "url": "https://dev-www.libreoffice.org/src/d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip", "sha256": "1b5b24f7bc543c0362b667692f78db8bab4ed6dafc6172f104d0bd3757d8a133", "type": "file", "dest-filename": "external/tarballs/d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip", "sha256": "d30b13f4ba2e3b6a2d4f020c0dee0a9fb9fc6fbcc2d561f36b78da4bf3802370", "type": "file", "dest-filename": "external/tarballs/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip" }, { "url": "https://dev-www.libreoffice.org/src/eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip", "sha256": "75c80359c9ce343c20aab8a36a45cb3b9ee7c61cf92c13ae45399d854423a9ba", "type": "file", "dest-filename": "external/tarballs/eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip", "sha256": "e0531091787c0f16c83965fdcbc49162c059d7f0c64669e7f119699321549743", "type": "file", "dest-filename": "external/tarballs/3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip", "sha256": "5826d1551bf599b85742545f6e01a0079b93c1b2c8434bf409eddb3a29e4726b", "type": "file", "dest-filename": "external/tarballs/3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip", "sha256": "e1fb87f3f7b980d33414473279615c4644027e013012d156efa538bc2b031772", "type": "file", "dest-filename": "external/tarballs/db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip" }, { "url": "https://dev-www.libreoffice.org/src/97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip", "sha256": "3d853b19b1d94a6efa69e7af90f7f2b09ecf302913bee3da796c15ecfebcfac8", "type": "file", "dest-filename": "external/tarballs/97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip", "sha256": "abe2c57ac12ba45d83563b02e240fa95d973376de2f720aab8fe11f2e621c095", "type": "file", "dest-filename": "external/tarballs/8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip", "sha256": "05640a1f6805b2b2d7e2cb9c50db9a5cb084e3c52ab1a71ce015239b4a1d4343", "type": "file", "dest-filename": "external/tarballs/f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip", "sha256": "7d2797fe9f79a77009721e3f14fa4a1dec17a6d706bdc93f85f1f01d124fab66", "type": "file", "dest-filename": "external/tarballs/ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip", "sha256": "1fb458d6aab06932693cc8a9b6e4e70944ee1ff052fa63606e3131df34e21753", "type": "file", "dest-filename": "external/tarballs/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip" }, { "url": "https://dev-www.libreoffice.org/src/39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip", "sha256": "085f2112c51fa8c1783fac12fbd452650596415121348393bb51f0f7e85a9045", "type": "file", "dest-filename": "external/tarballs/39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip" }, { "url": "https://dev-www.libreoffice.org/src/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip", "sha256": "64585ac36a81291a58269ec5347e7e3e2e8596dbacb9221015c208191333c6e1", "type": "file", "dest-filename": "external/tarballs/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip" }, { "url": "https://dev-www.libreoffice.org/src/libnumbertext-1.0.6.tar.xz", "sha256": "739f220b34bf7cb731c09de2921771d644d37dfd276c45564401e5759f10ae57", "type": "file", "dest-filename": "external/tarballs/libnumbertext-1.0.6.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libatomic_ops-7.6.8.tar.gz", "sha256": "1d6a279edf81767e74d2ad2c9fce09459bc65f12c6525a40b0cb3e53c089f665", "type": "file", "dest-filename": "external/tarballs/libatomic_ops-7.6.8.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/dtoa-20180411.tgz", "sha256": "0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4", "type": "file", "dest-filename": "external/tarballs/dtoa-20180411.tgz" }, { "url": "https://dev-www.libreoffice.org/extern/884ed41809687c3e168fc7c19b16585149ff058eca79acbf3ee784f6630704cc-opens___.ttf", "sha256": "884ed41809687c3e168fc7c19b16585149ff058eca79acbf3ee784f6630704cc", "type": "file", "dest-filename": "external/tarballs/884ed41809687c3e168fc7c19b16585149ff058eca79acbf3ee784f6630704cc-opens___.ttf" } ], "buildsystem": "simple", "build-commands": [ "./autogen.sh --prefix=/run/build/libreoffice/inst --with-distro=LibreOfficeFlatpak --with-gdrive-client-id=280867422816-9jc83t6phkfb2q8p94dtk8kr5fa8af3r.apps.googleusercontent.com --with-gdrive-client-secret=Hnzikj7HqdqsUYLru4jmFo1p --disable-pdfimport --disable-crashdump --disable-odk --disable-dbus --disable-gui --disable-sdremote --disable-sdremote-bluetooth --disable-cups --disable-extension-update --disable-dconf --disable-skia --without-helppack-integration", "make $(if test \"$FLATPAK_ARCH\" = i386; then printf build-nocheck; fi)", "make distro-pack-install", "make cmd cmd='$(SRCDIR)/solenv/bin/assemble-flatpak.sh'", "printf '\\nfalse' >/app/libreoffice/share/registry/flatpak.xcd" ] } ] } paperwork-2.2.2/flatpak/shared-modules/libreoffice-7.2.3.2.json000066400000000000000000001106701456262201400240450ustar00rootroot00000000000000{ "name": "libreoffice-complete", "modules": [ { "name": "openjdk", "buildsystem": "simple", "build-commands": [ "/usr/lib/sdk/openjdk11/install.sh" ] }, { "name": "krb5", "subdir": "src", "config-opts": [ "--disable-static", "--disable-rpath", "--sbindir=/app/bin" ], "cleanup": [ "/include", "/lib/pkgconfig", "/var" ], "sources": [ { "type": "archive", "url": "https://kerberos.org/dist/krb5/1.16/krb5-1.16.2.tar.gz", "sha256": "9f721e1fe593c219174740c71de514c7228a97d23eb7be7597b2ae14e487f027" } ] }, { "name": "libreoffice", "sources": [ { "type": "git", "url": "https://gerrit.libreoffice.org/core", "tag": "libreoffice-7.2.3.2", "disable-fsckobjects": true }, { "type": "archive", "url": "https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.5-bin.tar.xz", "sha256": "cebb705dbbe26a41d359b8be08ec066caba4e8686670070ce44bbf2b57ae113f", "dest": "ant" }, { "commands": [ "mkdir external/tarballs" ], "type": "shell" }, { "url": "https://dev-www.libreoffice.org/src/pdfium-4500.tar.bz2", "sha256": "26a03dd60e5ed0979cdaba9cc848242895110ddfdf347d40989ce2f14020f304", "type": "file", "dest": "external/tarballs", "dest-filename": "pdfium-4500.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz", "sha256": "983941d31ee8d366085cadf28db75eb1f5cb03ba1e5853b98f12f7f51c63b776", "type": "file", "dest": "external/tarballs", "dest-filename": "0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/xmlsec1-1.2.32.tar.gz", "sha256": "e383702853236004e5b08e424b8afe9b53fe9f31aaa7a5382f39d9533eb7c043", "type": "file", "dest": "external/tarballs", "dest-filename": "xmlsec1-1.2.32.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz", "sha256": "c48d1c2fd613c9c06c959c34da7b8388059e2408d2bb19845dc3ed35f76e4d09", "type": "file", "dest": "external/tarballs", "dest-filename": "368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz", "sha256": "4bd12b6cbc321c1cf16da76e2c585c925ce956a08067ae6f6c64eff6ccfdaf5a", "type": "file", "dest": "external/tarballs", "dest-filename": "c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip", "sha256": "7576310b219e04159d35ff61dd4a4ec4cdba4f35c00e002a136f00e96a908b0a", "type": "file", "dest": "external/tarballs", "dest-filename": "33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip" }, { "url": "https://dev-www.libreoffice.org/src/1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip", "sha256": "2f1a2c5491d7305dffd3520c6375d2f3e14931ee35c6d8ae1e8f098bf1a7b3cc", "type": "file", "dest": "external/tarballs", "dest-filename": "1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip" }, { "url": "https://dev-www.libreoffice.org/src/liberation-narrow-fonts-ttf-1.07.6.tar.gz", "sha256": "8879d89b5ff7b506c9fc28efc31a5c0b954bbe9333e66e5283d27d20a8519ea3", "type": "file", "dest": "external/tarballs", "dest-filename": "liberation-narrow-fonts-ttf-1.07.6.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/liberation-fonts-ttf-2.1.4.tar.gz", "sha256": "26f85412dd0aa9d061504a1cc8aaf0aa12a70710e8d47d8b65a1251757c1a5ef", "type": "file", "dest": "external/tarballs", "dest-filename": "liberation-fonts-ttf-2.1.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip", "sha256": "54adcb2bc8cac0927a647fbd9362f45eff48130ce6e2379dc3867643019e08c5", "type": "file", "dest": "external/tarballs", "dest-filename": "e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip" }, { "url": "https://dev-www.libreoffice.org/src/907d6e99f241876695c19ff3db0b8923-source-code-pro-2.030R-ro-1.050R-it.tar.gz", "sha256": "09466dce87653333f189acd8358c60c6736dcd95f042dee0b644bdcf65b6ae2f", "type": "file", "dest": "external/tarballs", "dest-filename": "907d6e99f241876695c19ff3db0b8923-source-code-pro-2.030R-ro-1.050R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz", "sha256": "e7bc9a1fec787a529e49f5a26b93dcdcf41506449dfc70f92cdef6d17eb6fb61", "type": "file", "dest": "external/tarballs", "dest-filename": "edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/source-serif-pro-3.000R.tar.gz", "sha256": "826a2b784d5cdb4c2bbc7830eb62871528360a61a52689c102a101623f1928e3", "type": "file", "dest": "external/tarballs", "dest-filename": "source-serif-pro-3.000R.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/EmojiOneColor-SVGinOT-1.3.tar.gz", "sha256": "d1a08f7c10589f22740231017694af0a7a270760c8dec33d8d1c038e2be0a0c7", "type": "file", "dest": "external/tarballs", "dest-filename": "EmojiOneColor-SVGinOT-1.3.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/boost_1_75_0.tar.xz", "sha256": "cc378a036a1cfd3af289f3da24deeb8dba7a729f61ab104c7b018a622e22d21b", "type": "file", "dest": "external/tarballs", "dest-filename": "boost_1_75_0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz", "sha256": "ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8c51d79732eab", "type": "file", "dest": "external/tarballs", "dest-filename": "48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/CoinMP-1.7.6.tgz", "sha256": "86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f", "type": "file", "dest": "external/tarballs", "dest-filename": "CoinMP-1.7.6.tgz" }, { "url": "https://dev-www.libreoffice.org/src/cppunit-1.15.1.tar.gz", "sha256": "89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7", "type": "file", "dest": "external/tarballs", "dest-filename": "cppunit-1.15.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Firebird-3.0.7.33374-0.tar.bz2", "sha256": "acb85cedafa10ce106b1823fb236b1b3e5d942a5741e8f8435cc8ccfec0afe76", "type": "file", "dest": "external/tarballs", "dest-filename": "Firebird-3.0.7.33374-0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/glm-0.9.9.7.zip", "sha256": "c5e167c042afd2d7ad642ace6b643863baeb33880781983563e1ab68a30d3e95", "type": "file", "dest": "external/tarballs", "dest-filename": "glm-0.9.9.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/gpgme-1.13.1.tar.bz2", "sha256": "c4e30b227682374c23cddc7fdb9324a99694d907e79242a25a4deeedb393be46", "type": "file", "dest": "external/tarballs", "dest-filename": "gpgme-1.13.1.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libassuan-2.5.3.tar.bz2", "sha256": "91bcb0403866b4e7c4bc1cc52ed4c364a9b5414b3994f718c70303f7f765e702", "type": "file", "dest": "external/tarballs", "dest-filename": "libassuan-2.5.3.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libgpg-error-1.37.tar.bz2", "sha256": "b32d6ff72a73cf79797f7f2d039e95e9c6f92f0c1450215410840ab62aea9763", "type": "file", "dest": "external/tarballs", "dest-filename": "libgpg-error-1.37.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libabw-0.1.3.tar.xz", "sha256": "e763a9dc21c3d2667402d66e202e3f8ef4db51b34b79ef41f56cacb86dcd6eed", "type": "file", "dest": "external/tarballs", "dest-filename": "libabw-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcdr-0.1.7.tar.xz", "sha256": "5666249d613466b9aa1e987ea4109c04365866e9277d80f6cd9663e86b8ecdd4", "type": "file", "dest": "external/tarballs", "dest-filename": "libcdr-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcmis-0.5.2.tar.xz", "sha256": "d7b18d9602190e10d437f8a964a32e983afd57e2db316a07d87477a79f5000a2", "type": "file", "dest": "external/tarballs", "dest-filename": "libcmis-0.5.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libe-book-0.1.3.tar.xz", "sha256": "7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9", "type": "file", "dest": "external/tarballs", "dest-filename": "libe-book-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libetonyek-0.1.10.tar.xz", "sha256": "b430435a6e8487888b761dc848b7981626eb814884963ffe25eb26a139301e9a", "type": "file", "dest": "external/tarballs", "dest-filename": "libetonyek-0.1.10.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libexttextcat-3.4.5.tar.xz", "sha256": "13fdbc9d4c489a4d0519e51933a1aa21fe3fb9eb7da191b87f7a63e82797dac8", "type": "file", "dest": "external/tarballs", "dest-filename": "libexttextcat-3.4.5.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libfreehand-0.1.2.tar.xz", "sha256": "0e422d1564a6dbf22a9af598535425271e583514c0f7ba7d9091676420de34ac", "type": "file", "dest": "external/tarballs", "dest-filename": "libfreehand-0.1.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/language-subtag-registry-2021-08-06.tar.bz2", "sha256": "08452d3997c78e21f2d81e31409dc46557707be6dc1df3129674019659e5ff9b", "type": "file", "dest": "external/tarballs", "dest-filename": "language-subtag-registry-2021-08-06.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/liblangtag-0.6.2.tar.bz2", "sha256": "d6242790324f1432fb0a6fae71b6851f520b2c5a87675497cf8ea14c2924d52e", "type": "file", "dest": "external/tarballs", "dest-filename": "liblangtag-0.6.2.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libmspub-0.1.4.tar.xz", "sha256": "ef36c1a1aabb2ba3b0bedaaafe717bf4480be2ba8de6f3894be5fd3702b013ba", "type": "file", "dest": "external/tarballs", "dest-filename": "libmspub-0.1.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libmwaw-0.3.19.tar.xz", "sha256": "b272e234eefc828c4bb8344af0f047a62e070f530e9e2fba11b04c8db8eda5af", "type": "file", "dest": "external/tarballs", "dest-filename": "libmwaw-0.3.19.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libodfgen-0.1.8.tar.xz", "sha256": "55200027fd46623b9bdddd38d275e7452d1b0ff8aeddcad6f9ae6dc25f610625", "type": "file", "dest": "external/tarballs", "dest-filename": "libodfgen-0.1.8.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libpagemaker-0.0.4.tar.xz", "sha256": "66adacd705a7d19895e08eac46d1e851332adf2e736c566bef1164e7a442519d", "type": "file", "dest": "external/tarballs", "dest-filename": "libpagemaker-0.0.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/librevenge-0.0.4.tar.bz2", "sha256": "c51601cd08320b75702812c64aae0653409164da7825fd0f451ac2c5dbe77cbf", "type": "file", "dest": "external/tarballs", "dest-filename": "librevenge-0.0.4.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libstaroffice-0.0.7.tar.xz", "sha256": "f94fb0ad8216f97127bedef163a45886b43c62deac5e5b0f5e628e234220c8db", "type": "file", "dest": "external/tarballs", "dest-filename": "libstaroffice-0.0.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/ltm-1.0.zip", "sha256": "083daa92d8ee6f4af96a6143b12d7fc8fe1a547e14f862304f7281f8f7347483", "type": "file", "dest": "external/tarballs", "dest-filename": "ltm-1.0.zip" }, { "url": "https://dev-www.libreoffice.org/src/libvisio-0.1.7.tar.xz", "sha256": "8faf8df870cb27b09a787a1959d6c646faa44d0d8ab151883df408b7166bea4c", "type": "file", "dest": "external/tarballs", "dest-filename": "libvisio-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpd-0.10.3.tar.xz", "sha256": "2465b0b662fdc5d4e3bebcdc9a79027713fb629ca2bff04a3c9251fdec42dd09", "type": "file", "dest": "external/tarballs", "dest-filename": "libwpd-0.10.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpg-0.3.3.tar.xz", "sha256": "99b3f7f8832385748582ab8130fbb9e5607bd5179bebf9751ac1d51a53099d1c", "type": "file", "dest": "external/tarballs", "dest-filename": "libwpg-0.3.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwps-0.4.12.tar.xz", "sha256": "e21afb52a06d03b774c5a8c72679687ab64891b91ce0c3bdf2d3e97231534edb", "type": "file", "dest": "external/tarballs", "dest-filename": "libwps-0.4.12.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libzmf-0.0.2.tar.xz", "sha256": "27051a30cb057fdb5d5de65a1f165c7153dc76e27fe62251cbb86639eb2caf22", "type": "file", "dest": "external/tarballs", "dest-filename": "libzmf-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz", "sha256": "171816288f14215c69e730f7a4f1c325739873e21f946ff83884b350574e6695", "type": "file", "dest": "external/tarballs", "dest-filename": "26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.1.8-src.tar.gz", "sha256": "431434d3926f4bcce2e5c97240609983f60d7ff50df5a72083934759bb863f7b", "type": "file", "dest": "external/tarballs", "dest-filename": "mariadb-connector-c-3.1.8-src.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mdds-1.7.0.tar.bz2", "sha256": "a66a2a8293a3abc6cd9baff7c236156e2666935cbfb69a15d64d38141638fecf", "type": "file", "dest": "external/tarballs", "dest-filename": "mdds-1.7.0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/neon-0.31.2.tar.gz", "sha256": "cf1ee3ac27a215814a9c80803fcee4f0ede8466ebead40267a9bd115e16a8678", "type": "file", "dest": "external/tarballs", "dest-filename": "neon-0.31.2.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/noto-fonts-20171024.tar.gz", "sha256": "29acc15a4c4d6b51201ba5d60f303dfbc2e5acbfdb70413c9ae1ed34fa259994", "type": "file", "dest": "external/tarballs", "dest-filename": "noto-fonts-20171024.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/openldap-2.4.59.tgz", "sha256": "99f37d6747d88206c470067eda624d5e48c1011e943ec0ab217bae8712e22f34", "type": "file", "dest": "external/tarballs", "dest-filename": "openldap-2.4.59.tgz" }, { "url": "https://dev-www.libreoffice.org/src/liborcus-0.16.1.tar.bz2", "sha256": "c700d1325f744104d9fca0d5a019434901e9d51a16eedfb05792f90a298587a4", "type": "file", "dest": "external/tarballs", "dest-filename": "liborcus-0.16.1.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/poppler-21.01.0.tar.xz", "sha256": "016dde34e5f868ea98a32ca99b643325a9682281500942b7113f4ec88d20e2f3", "type": "file", "dest": "external/tarballs", "dest-filename": "poppler-21.01.0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/poppler-data-0.4.10.tar.gz", "sha256": "6e2fcef66ec8c44625f94292ccf8af9f1d918b410d5aa69c274ce67387967b30", "type": "file", "dest": "external/tarballs", "dest-filename": "poppler-data-0.4.10.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/postgresql-13.5.tar.bz2", "sha256": "9b81067a55edbaabc418aacef457dd8477642827499560b00615a6ea6c13f6b3", "type": "file", "dest": "external/tarballs", "dest-filename": "postgresql-13.5.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz", "sha256": "ada7f0ba54787b33485d090d3d2680533520cd4426d2f7fb4782dd4a6a1480ed", "type": "file", "dest": "external/tarballs", "dest-filename": "a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz", "sha256": "6924c9ac6570bd241a9669f83b467c728a322470bf34f4b2da4f69492ccfd97c", "type": "file", "dest": "external/tarballs", "dest-filename": "1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz", "sha256": "de1847f7b59021c16bdc72abb4d8e2d9187cd6124d69156f3326dd34ee043681", "type": "file", "dest": "external/tarballs", "dest-filename": "e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/ReemKufi-0.7.zip", "sha256": "f60c6508d209ce4236d2d7324256c2ffddd480be7e3d6023770b93dc391a605f", "type": "file", "dest": "external/tarballs", "dest-filename": "ReemKufi-0.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/libepubgen-0.1.1.tar.xz", "sha256": "03e084b994cbeffc8c3dd13303b2cb805f44d8f2c3b79f7690d7e3fc7f6215ad", "type": "file", "dest": "external/tarballs", "dest-filename": "libepubgen-0.1.1.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libqxp-0.0.2.tar.xz", "sha256": "e137b6b110120a52c98edd02ebdc4095ee08d0d5295a94316a981750095a945c", "type": "file", "dest": "external/tarballs", "dest-filename": "libqxp-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/alef-1.001.tar.gz", "sha256": "b98b67602a2c8880a1770f0b9e37c190f29a7e2ade5616784f0b89fbdb75bf52", "type": "file", "dest": "external/tarballs", "dest-filename": "alef-1.001.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Amiri-0.111.zip", "sha256": "1fbfccced6348b5db2c1c21d5b319cd488e14d055702fa817a0f6cb83d882166", "type": "file", "dest": "external/tarballs", "dest-filename": "Amiri-0.111.zip" }, { "url": "https://dev-www.libreoffice.org/src/culmus-0.133.tar.gz", "sha256": "c0c6873742d07544f6bacf2ad52eb9cb392974d56427938dc1dfbc8399c64d05", "type": "file", "dest": "external/tarballs", "dest-filename": "culmus-0.133.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/libre-hebrew-1.0.tar.gz", "sha256": "f596257c1db706ce35795b18d7f66a4db99d427725f20e9384914b534142579a", "type": "file", "dest": "external/tarballs", "dest-filename": "libre-hebrew-1.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Scheherazade-2.100.zip", "sha256": "251c8817ceb87d9b661ce1d5b49e732a0116add10abc046be4b8ba5196e149b5", "type": "file", "dest": "external/tarballs", "dest-filename": "Scheherazade-2.100.zip" }, { "url": "https://dev-www.libreoffice.org/src/ttf-kacst_2.01+mry.tar.gz", "sha256": "dca00f5e655f2f217a766faa73a81f542c5c204aa3a47017c3c2be0b31d00a56", "type": "file", "dest": "external/tarballs", "dest-filename": "ttf-kacst_2.01+mry.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip", "sha256": "9e93c73e23aff644b17dfff656444474c14150e7f3b38b19635e622235e01c96", "type": "file", "dest": "external/tarballs", "dest-filename": "beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip" }, { "url": "https://dev-www.libreoffice.org/src/ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip", "sha256": "233f66e8d25c5dd971716d4200203a612a407649686ef3b52075d04b4c9df0dd", "type": "file", "dest": "external/tarballs", "dest-filename": "ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip" }, { "url": "https://dev-www.libreoffice.org/src/d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip", "sha256": "1b5b24f7bc543c0362b667692f78db8bab4ed6dafc6172f104d0bd3757d8a133", "type": "file", "dest": "external/tarballs", "dest-filename": "d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip", "sha256": "d30b13f4ba2e3b6a2d4f020c0dee0a9fb9fc6fbcc2d561f36b78da4bf3802370", "type": "file", "dest": "external/tarballs", "dest-filename": "17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip" }, { "url": "https://dev-www.libreoffice.org/src/eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip", "sha256": "75c80359c9ce343c20aab8a36a45cb3b9ee7c61cf92c13ae45399d854423a9ba", "type": "file", "dest": "external/tarballs", "dest-filename": "eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip", "sha256": "e0531091787c0f16c83965fdcbc49162c059d7f0c64669e7f119699321549743", "type": "file", "dest": "external/tarballs", "dest-filename": "3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip", "sha256": "5826d1551bf599b85742545f6e01a0079b93c1b2c8434bf409eddb3a29e4726b", "type": "file", "dest": "external/tarballs", "dest-filename": "3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip", "sha256": "e1fb87f3f7b980d33414473279615c4644027e013012d156efa538bc2b031772", "type": "file", "dest": "external/tarballs", "dest-filename": "db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip" }, { "url": "https://dev-www.libreoffice.org/src/97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip", "sha256": "3d853b19b1d94a6efa69e7af90f7f2b09ecf302913bee3da796c15ecfebcfac8", "type": "file", "dest": "external/tarballs", "dest-filename": "97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip", "sha256": "abe2c57ac12ba45d83563b02e240fa95d973376de2f720aab8fe11f2e621c095", "type": "file", "dest": "external/tarballs", "dest-filename": "8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip", "sha256": "05640a1f6805b2b2d7e2cb9c50db9a5cb084e3c52ab1a71ce015239b4a1d4343", "type": "file", "dest": "external/tarballs", "dest-filename": "f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip", "sha256": "7d2797fe9f79a77009721e3f14fa4a1dec17a6d706bdc93f85f1f01d124fab66", "type": "file", "dest": "external/tarballs", "dest-filename": "ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip", "sha256": "1fb458d6aab06932693cc8a9b6e4e70944ee1ff052fa63606e3131df34e21753", "type": "file", "dest": "external/tarballs", "dest-filename": "798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip" }, { "url": "https://dev-www.libreoffice.org/src/39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip", "sha256": "085f2112c51fa8c1783fac12fbd452650596415121348393bb51f0f7e85a9045", "type": "file", "dest": "external/tarballs", "dest-filename": "39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip" }, { "url": "https://dev-www.libreoffice.org/src/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip", "sha256": "64585ac36a81291a58269ec5347e7e3e2e8596dbacb9221015c208191333c6e1", "type": "file", "dest": "external/tarballs", "dest-filename": "35c94d2df8893241173de1d16b6034c0-swingExSrc.zip" }, { "url": "https://dev-www.libreoffice.org/src/libnumbertext-1.0.7.tar.xz", "sha256": "17b8249cb89ae11ae15a85612d2665626c0e0e3e56b35654363ba6566d8b61fc", "type": "file", "dest": "external/tarballs", "dest-filename": "libnumbertext-1.0.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libatomic_ops-7.6.8.tar.gz", "sha256": "1d6a279edf81767e74d2ad2c9fce09459bc65f12c6525a40b0cb3e53c089f665", "type": "file", "dest": "external/tarballs", "dest-filename": "libatomic_ops-7.6.8.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/dtoa-20180411.tgz", "sha256": "0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4", "type": "file", "dest": "external/tarballs", "dest-filename": "dtoa-20180411.tgz" }, { "url": "https://dev-www.libreoffice.org/src/box2d-2.3.1.tar.gz", "sha256": "58ffc8475a8650aadc351345aef696937747b40501ab78d72c197c5ff5b3035c", "type": "file", "dest": "external/tarballs", "dest-filename": "box2d-2.3.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/zxing-cpp-1.1.1.tar.gz", "sha256": "e595b3fa2ec320beb0b28f6af56b1141853257c2611686685639cebb3b248c86", "type": "file", "dest": "external/tarballs", "dest-filename": "zxing-cpp-1.1.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/extern/f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140-opens___.ttf", "sha256": "f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140", "type": "file", "dest": "external/tarballs", "dest-filename": "f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140-opens___.ttf" } ], "buildsystem": "simple", "build-commands": [ "./autogen.sh --prefix=/run/build/libreoffice/inst --with-distro=LibreOfficeFlatpak --with-gdrive-client-id=280867422816-9jc83t6phkfb2q8p94dtk8kr5fa8af3r.apps.googleusercontent.com --with-gdrive-client-secret=Hnzikj7HqdqsUYLru4jmFo1p --disable-pdfimport --disable-crashdump --disable-odk --disable-dbus --disable-gui --disable-sdremote --disable-sdremote-bluetooth --disable-cups --disable-extension-update --disable-dconf --disable-skia --without-helppack-integration", "make $(if test \"$FLATPAK_ARCH\" = i386; then printf build-nocheck; fi)", "make distro-pack-install", "make cmd cmd='$(SRCDIR)/solenv/bin/assemble-flatpak.sh'", "printf '\\nfalse' >/app/libreoffice/share/registry/flatpak.xcd" ] } ] } paperwork-2.2.2/flatpak/shared-modules/libreoffice-7.4.3.2.json000066400000000000000000001107021456262201400240430ustar00rootroot00000000000000{ "name": "libreoffice-complete", "modules": [ { "name": "openjdk", "buildsystem": "simple", "build-commands": [ "/usr/lib/sdk/openjdk11/install.sh" ] }, { "name": "krb5", "subdir": "src", "config-opts": [ "--disable-static", "--disable-rpath", "--sbindir=/app/bin" ], "cleanup": [ "/include", "/lib/pkgconfig", "/var" ], "sources": [ { "type": "archive", "url": "https://kerberos.org/dist/krb5/1.16/krb5-1.16.2.tar.gz", "sha256": "9f721e1fe593c219174740c71de514c7228a97d23eb7be7597b2ae14e487f027" } ] }, { "name": "libreoffice", "sources": [ { "type": "git", "url": "https://gerrit.libreoffice.org/core", "tag": "libreoffice-7.4.3.2", "disable-fsckobjects": true }, { "type": "archive", "url": "https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.5-bin.tar.xz", "sha256": "cebb705dbbe26a41d359b8be08ec066caba4e8686670070ce44bbf2b57ae113f", "dest": "ant" }, { "commands": [ "mkdir external/tarballs" ], "type": "shell" }, { "url": "https://dev-www.libreoffice.org/src/pdfium-5058.tar.bz2", "sha256": "eaf4ce9fad32b5d951c524139df23119b66c67720057defb97acab2dfb2582ac", "type": "file", "dest": "external/tarballs", "dest-filename": "pdfium-5058.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz", "sha256": "983941d31ee8d366085cadf28db75eb1f5cb03ba1e5853b98f12f7f51c63b776", "type": "file", "dest": "external/tarballs", "dest-filename": "0168229624cfac409e766913506961a8-ucpp-1.3.2.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/xmlsec1-1.2.34.tar.gz", "sha256": "52ced4943f35bd7d0818a38298c1528ca4ac8a54440fd71134a07d2d1370a262", "type": "file", "dest": "external/tarballs", "dest-filename": "xmlsec1-1.2.34.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz", "sha256": "c48d1c2fd613c9c06c959c34da7b8388059e2408d2bb19845dc3ed35f76e4d09", "type": "file", "dest": "external/tarballs", "dest-filename": "368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz", "sha256": "4bd12b6cbc321c1cf16da76e2c585c925ce956a08067ae6f6c64eff6ccfdaf5a", "type": "file", "dest": "external/tarballs", "dest-filename": "c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip", "sha256": "7576310b219e04159d35ff61dd4a4ec4cdba4f35c00e002a136f00e96a908b0a", "type": "file", "dest": "external/tarballs", "dest-filename": "33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip" }, { "url": "https://dev-www.libreoffice.org/src/1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip", "sha256": "2f1a2c5491d7305dffd3520c6375d2f3e14931ee35c6d8ae1e8f098bf1a7b3cc", "type": "file", "dest": "external/tarballs", "dest-filename": "1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip" }, { "url": "https://dev-www.libreoffice.org/src/liberation-narrow-fonts-ttf-1.07.6.tar.gz", "sha256": "8879d89b5ff7b506c9fc28efc31a5c0b954bbe9333e66e5283d27d20a8519ea3", "type": "file", "dest": "external/tarballs", "dest-filename": "liberation-narrow-fonts-ttf-1.07.6.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/liberation-fonts-ttf-2.1.4.tar.gz", "sha256": "26f85412dd0aa9d061504a1cc8aaf0aa12a70710e8d47d8b65a1251757c1a5ef", "type": "file", "dest": "external/tarballs", "dest-filename": "liberation-fonts-ttf-2.1.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip", "sha256": "54adcb2bc8cac0927a647fbd9362f45eff48130ce6e2379dc3867643019e08c5", "type": "file", "dest": "external/tarballs", "dest-filename": "e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip" }, { "url": "https://dev-www.libreoffice.org/src/907d6e99f241876695c19ff3db0b8923-source-code-pro-2.030R-ro-1.050R-it.tar.gz", "sha256": "09466dce87653333f189acd8358c60c6736dcd95f042dee0b644bdcf65b6ae2f", "type": "file", "dest": "external/tarballs", "dest-filename": "907d6e99f241876695c19ff3db0b8923-source-code-pro-2.030R-ro-1.050R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz", "sha256": "e7bc9a1fec787a529e49f5a26b93dcdcf41506449dfc70f92cdef6d17eb6fb61", "type": "file", "dest": "external/tarballs", "dest-filename": "edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/source-serif-pro-3.000R.tar.gz", "sha256": "826a2b784d5cdb4c2bbc7830eb62871528360a61a52689c102a101623f1928e3", "type": "file", "dest": "external/tarballs", "dest-filename": "source-serif-pro-3.000R.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/EmojiOneColor-SVGinOT-1.3.tar.gz", "sha256": "d1a08f7c10589f22740231017694af0a7a270760c8dec33d8d1c038e2be0a0c7", "type": "file", "dest": "external/tarballs", "dest-filename": "EmojiOneColor-SVGinOT-1.3.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/boost_1_79_0.tar.xz", "sha256": "2058aa88758a0e1aaac1759b3c4bad2526f899c6ecc6eeea79aa5e8fd3ea95dc", "type": "file", "dest": "external/tarballs", "dest-filename": "boost_1_79_0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz", "sha256": "ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8c51d79732eab", "type": "file", "dest": "external/tarballs", "dest-filename": "48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/CoinMP-1.7.6.tgz", "sha256": "86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f", "type": "file", "dest": "external/tarballs", "dest-filename": "CoinMP-1.7.6.tgz" }, { "url": "https://dev-www.libreoffice.org/src/cppunit-1.15.1.tar.gz", "sha256": "89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7", "type": "file", "dest": "external/tarballs", "dest-filename": "cppunit-1.15.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Firebird-3.0.7.33374-0.tar.bz2", "sha256": "acb85cedafa10ce106b1823fb236b1b3e5d942a5741e8f8435cc8ccfec0afe76", "type": "file", "dest": "external/tarballs", "dest-filename": "Firebird-3.0.7.33374-0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/glm-0.9.9.8.zip", "sha256": "6bba5f032bed47c73ad9397f2313b9acbfb56253d0d0576b5873d3dcb25e99ad", "type": "file", "dest": "external/tarballs", "dest-filename": "glm-0.9.9.8.zip" }, { "url": "https://dev-www.libreoffice.org/src/gpgme-1.16.0.tar.bz2", "sha256": "6c8cc4aedb10d5d4c905894ba1d850544619ee765606ac43df7405865de29ed0", "type": "file", "dest": "external/tarballs", "dest-filename": "gpgme-1.16.0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libassuan-2.5.5.tar.bz2", "sha256": "8e8c2fcc982f9ca67dcbb1d95e2dc746b1739a4668bc20b3a3c5be632edb34e4", "type": "file", "dest": "external/tarballs", "dest-filename": "libassuan-2.5.5.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libgpg-error-1.43.tar.bz2", "sha256": "a9ab83ca7acc442a5bd846a75b920285ff79bdb4e3d34aa382be88ed2c3aebaf", "type": "file", "dest": "external/tarballs", "dest-filename": "libgpg-error-1.43.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libabw-0.1.3.tar.xz", "sha256": "e763a9dc21c3d2667402d66e202e3f8ef4db51b34b79ef41f56cacb86dcd6eed", "type": "file", "dest": "external/tarballs", "dest-filename": "libabw-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcdr-0.1.7.tar.xz", "sha256": "5666249d613466b9aa1e987ea4109c04365866e9277d80f6cd9663e86b8ecdd4", "type": "file", "dest": "external/tarballs", "dest-filename": "libcdr-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcmis-0.5.2.tar.xz", "sha256": "d7b18d9602190e10d437f8a964a32e983afd57e2db316a07d87477a79f5000a2", "type": "file", "dest": "external/tarballs", "dest-filename": "libcmis-0.5.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libe-book-0.1.3.tar.xz", "sha256": "7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9", "type": "file", "dest": "external/tarballs", "dest-filename": "libe-book-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libetonyek-0.1.10.tar.xz", "sha256": "b430435a6e8487888b761dc848b7981626eb814884963ffe25eb26a139301e9a", "type": "file", "dest": "external/tarballs", "dest-filename": "libetonyek-0.1.10.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libexttextcat-3.4.6.tar.xz", "sha256": "6d77eace20e9ea106c1330e268ede70c9a4a89744ddc25715682754eca3368df", "type": "file", "dest": "external/tarballs", "dest-filename": "libexttextcat-3.4.6.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libfreehand-0.1.2.tar.xz", "sha256": "0e422d1564a6dbf22a9af598535425271e583514c0f7ba7d9091676420de34ac", "type": "file", "dest": "external/tarballs", "dest-filename": "libfreehand-0.1.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/language-subtag-registry-2022-08-08.tar.bz2", "sha256": "e2d9224e0e50fc8ad12a3cf47396bbcadf45b2515839d4770432653a88972c00", "type": "file", "dest": "external/tarballs", "dest-filename": "language-subtag-registry-2022-08-08.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/liblangtag-0.6.3.tar.bz2", "sha256": "1f12a20a02ec3a8d22e54dedb8b683a43c9c160bda1ba337bf1060607ae733bd", "type": "file", "dest": "external/tarballs", "dest-filename": "liblangtag-0.6.3.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libmspub-0.1.4.tar.xz", "sha256": "ef36c1a1aabb2ba3b0bedaaafe717bf4480be2ba8de6f3894be5fd3702b013ba", "type": "file", "dest": "external/tarballs", "dest-filename": "libmspub-0.1.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libmwaw-0.3.21.tar.xz", "sha256": "e8750123a78d61b943cef78b7736c8a7f20bb0a649aa112402124fba794fc21c", "type": "file", "dest": "external/tarballs", "dest-filename": "libmwaw-0.3.21.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libodfgen-0.1.8.tar.xz", "sha256": "55200027fd46623b9bdddd38d275e7452d1b0ff8aeddcad6f9ae6dc25f610625", "type": "file", "dest": "external/tarballs", "dest-filename": "libodfgen-0.1.8.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libpagemaker-0.0.4.tar.xz", "sha256": "66adacd705a7d19895e08eac46d1e851332adf2e736c566bef1164e7a442519d", "type": "file", "dest": "external/tarballs", "dest-filename": "libpagemaker-0.0.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/librevenge-0.0.4.tar.bz2", "sha256": "c51601cd08320b75702812c64aae0653409164da7825fd0f451ac2c5dbe77cbf", "type": "file", "dest": "external/tarballs", "dest-filename": "librevenge-0.0.4.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libstaroffice-0.0.7.tar.xz", "sha256": "f94fb0ad8216f97127bedef163a45886b43c62deac5e5b0f5e628e234220c8db", "type": "file", "dest": "external/tarballs", "dest-filename": "libstaroffice-0.0.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/ltm-1.0.zip", "sha256": "083daa92d8ee6f4af96a6143b12d7fc8fe1a547e14f862304f7281f8f7347483", "type": "file", "dest": "external/tarballs", "dest-filename": "ltm-1.0.zip" }, { "url": "https://dev-www.libreoffice.org/src/libvisio-0.1.7.tar.xz", "sha256": "8faf8df870cb27b09a787a1959d6c646faa44d0d8ab151883df408b7166bea4c", "type": "file", "dest": "external/tarballs", "dest-filename": "libvisio-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpd-0.10.3.tar.xz", "sha256": "2465b0b662fdc5d4e3bebcdc9a79027713fb629ca2bff04a3c9251fdec42dd09", "type": "file", "dest": "external/tarballs", "dest-filename": "libwpd-0.10.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpg-0.3.3.tar.xz", "sha256": "99b3f7f8832385748582ab8130fbb9e5607bd5179bebf9751ac1d51a53099d1c", "type": "file", "dest": "external/tarballs", "dest-filename": "libwpg-0.3.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwps-0.4.12.tar.xz", "sha256": "e21afb52a06d03b774c5a8c72679687ab64891b91ce0c3bdf2d3e97231534edb", "type": "file", "dest": "external/tarballs", "dest-filename": "libwps-0.4.12.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libzmf-0.0.2.tar.xz", "sha256": "27051a30cb057fdb5d5de65a1f165c7153dc76e27fe62251cbb86639eb2caf22", "type": "file", "dest": "external/tarballs", "dest-filename": "libzmf-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz", "sha256": "171816288f14215c69e730f7a4f1c325739873e21f946ff83884b350574e6695", "type": "file", "dest": "external/tarballs", "dest-filename": "26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.1.8-src.tar.gz", "sha256": "431434d3926f4bcce2e5c97240609983f60d7ff50df5a72083934759bb863f7b", "type": "file", "dest": "external/tarballs", "dest-filename": "mariadb-connector-c-3.1.8-src.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mdds-2.0.3.tar.bz2", "sha256": "9771fe42e133443c13ca187253763e17c8bc96a1a02aec9e1e8893367ffa9ce5", "type": "file", "dest": "external/tarballs", "dest-filename": "mdds-2.0.3.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/noto-fonts-20171024.tar.gz", "sha256": "29acc15a4c4d6b51201ba5d60f303dfbc2e5acbfdb70413c9ae1ed34fa259994", "type": "file", "dest": "external/tarballs", "dest-filename": "noto-fonts-20171024.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/openldap-2.4.59.tgz", "sha256": "99f37d6747d88206c470067eda624d5e48c1011e943ec0ab217bae8712e22f34", "type": "file", "dest": "external/tarballs", "dest-filename": "openldap-2.4.59.tgz" }, { "url": "https://dev-www.libreoffice.org/src/liborcus-0.17.2.tar.bz2", "sha256": "2a86c405a5929f749b27637509596421d46805753364ab258b035fd01fbde143", "type": "file", "dest": "external/tarballs", "dest-filename": "liborcus-0.17.2.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/poppler-22.09.0.tar.xz", "sha256": "d7a8f748211359cadb774ba3e18ecda6464b34027045c0648eb30d5852a41e2e", "type": "file", "dest": "external/tarballs", "dest-filename": "poppler-22.09.0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/poppler-data-0.4.11.tar.gz", "sha256": "2cec05cd1bb03af98a8b06a1e22f6e6e1a65b1e2f3816cb3069bb0874825f08c", "type": "file", "dest": "external/tarballs", "dest-filename": "poppler-data-0.4.11.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/postgresql-13.8.tar.bz2", "sha256": "73876fdd3a517087340458dca4ce15b8d2a4dbceb334c0441424551ae6c4cded", "type": "file", "dest": "external/tarballs", "dest-filename": "postgresql-13.8.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz", "sha256": "ada7f0ba54787b33485d090d3d2680533520cd4426d2f7fb4782dd4a6a1480ed", "type": "file", "dest": "external/tarballs", "dest-filename": "a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz", "sha256": "6924c9ac6570bd241a9669f83b467c728a322470bf34f4b2da4f69492ccfd97c", "type": "file", "dest": "external/tarballs", "dest-filename": "1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz", "sha256": "de1847f7b59021c16bdc72abb4d8e2d9187cd6124d69156f3326dd34ee043681", "type": "file", "dest": "external/tarballs", "dest-filename": "e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/ReemKufi-1.2.zip", "sha256": "c4fd68a23c0ea471cc084ae7efe888da372b925cb208eeb0322c26792d2ef413", "type": "file", "dest": "external/tarballs", "dest-filename": "ReemKufi-1.2.zip" }, { "url": "https://dev-www.libreoffice.org/src/libepubgen-0.1.1.tar.xz", "sha256": "03e084b994cbeffc8c3dd13303b2cb805f44d8f2c3b79f7690d7e3fc7f6215ad", "type": "file", "dest": "external/tarballs", "dest-filename": "libepubgen-0.1.1.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libqxp-0.0.2.tar.xz", "sha256": "e137b6b110120a52c98edd02ebdc4095ee08d0d5295a94316a981750095a945c", "type": "file", "dest": "external/tarballs", "dest-filename": "libqxp-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/alef-1.001.tar.gz", "sha256": "b98b67602a2c8880a1770f0b9e37c190f29a7e2ade5616784f0b89fbdb75bf52", "type": "file", "dest": "external/tarballs", "dest-filename": "alef-1.001.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Amiri-0.117.zip", "sha256": "9c4e768893e0023a0ad6f488d5c84bd5add6565d3dcadb838ba5b20e75fcc9a7", "type": "file", "dest": "external/tarballs", "dest-filename": "Amiri-0.117.zip" }, { "url": "https://dev-www.libreoffice.org/src/culmus-0.133.tar.gz", "sha256": "c0c6873742d07544f6bacf2ad52eb9cb392974d56427938dc1dfbc8399c64d05", "type": "file", "dest": "external/tarballs", "dest-filename": "culmus-0.133.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/libre-hebrew-1.0.tar.gz", "sha256": "f596257c1db706ce35795b18d7f66a4db99d427725f20e9384914b534142579a", "type": "file", "dest": "external/tarballs", "dest-filename": "libre-hebrew-1.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Scheherazade-2.100.zip", "sha256": "251c8817ceb87d9b661ce1d5b49e732a0116add10abc046be4b8ba5196e149b5", "type": "file", "dest": "external/tarballs", "dest-filename": "Scheherazade-2.100.zip" }, { "url": "https://dev-www.libreoffice.org/src/ttf-kacst_2.01+mry.tar.gz", "sha256": "dca00f5e655f2f217a766faa73a81f542c5c204aa3a47017c3c2be0b31d00a56", "type": "file", "dest": "external/tarballs", "dest-filename": "ttf-kacst_2.01+mry.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip", "sha256": "9e93c73e23aff644b17dfff656444474c14150e7f3b38b19635e622235e01c96", "type": "file", "dest": "external/tarballs", "dest-filename": "beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip" }, { "url": "https://dev-www.libreoffice.org/src/ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip", "sha256": "233f66e8d25c5dd971716d4200203a612a407649686ef3b52075d04b4c9df0dd", "type": "file", "dest": "external/tarballs", "dest-filename": "ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip" }, { "url": "https://dev-www.libreoffice.org/src/d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip", "sha256": "1b5b24f7bc543c0362b667692f78db8bab4ed6dafc6172f104d0bd3757d8a133", "type": "file", "dest": "external/tarballs", "dest-filename": "d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip", "sha256": "d30b13f4ba2e3b6a2d4f020c0dee0a9fb9fc6fbcc2d561f36b78da4bf3802370", "type": "file", "dest": "external/tarballs", "dest-filename": "17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip" }, { "url": "https://dev-www.libreoffice.org/src/eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip", "sha256": "75c80359c9ce343c20aab8a36a45cb3b9ee7c61cf92c13ae45399d854423a9ba", "type": "file", "dest": "external/tarballs", "dest-filename": "eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip", "sha256": "e0531091787c0f16c83965fdcbc49162c059d7f0c64669e7f119699321549743", "type": "file", "dest": "external/tarballs", "dest-filename": "3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip", "sha256": "5826d1551bf599b85742545f6e01a0079b93c1b2c8434bf409eddb3a29e4726b", "type": "file", "dest": "external/tarballs", "dest-filename": "3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip", "sha256": "e1fb87f3f7b980d33414473279615c4644027e013012d156efa538bc2b031772", "type": "file", "dest": "external/tarballs", "dest-filename": "db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip" }, { "url": "https://dev-www.libreoffice.org/src/97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip", "sha256": "3d853b19b1d94a6efa69e7af90f7f2b09ecf302913bee3da796c15ecfebcfac8", "type": "file", "dest": "external/tarballs", "dest-filename": "97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip", "sha256": "abe2c57ac12ba45d83563b02e240fa95d973376de2f720aab8fe11f2e621c095", "type": "file", "dest": "external/tarballs", "dest-filename": "8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip", "sha256": "05640a1f6805b2b2d7e2cb9c50db9a5cb084e3c52ab1a71ce015239b4a1d4343", "type": "file", "dest": "external/tarballs", "dest-filename": "f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip", "sha256": "7d2797fe9f79a77009721e3f14fa4a1dec17a6d706bdc93f85f1f01d124fab66", "type": "file", "dest": "external/tarballs", "dest-filename": "ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip", "sha256": "1fb458d6aab06932693cc8a9b6e4e70944ee1ff052fa63606e3131df34e21753", "type": "file", "dest": "external/tarballs", "dest-filename": "798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip" }, { "url": "https://dev-www.libreoffice.org/src/39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip", "sha256": "085f2112c51fa8c1783fac12fbd452650596415121348393bb51f0f7e85a9045", "type": "file", "dest": "external/tarballs", "dest-filename": "39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip" }, { "url": "https://dev-www.libreoffice.org/src/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip", "sha256": "64585ac36a81291a58269ec5347e7e3e2e8596dbacb9221015c208191333c6e1", "type": "file", "dest": "external/tarballs", "dest-filename": "35c94d2df8893241173de1d16b6034c0-swingExSrc.zip" }, { "url": "https://dev-www.libreoffice.org/src/libnumbertext-1.0.10.tar.xz", "sha256": "a285573864eaac8d36a0f66d946e9b1d3cf01c5d93d31fda00264a76f2633beb", "type": "file", "dest": "external/tarballs", "dest-filename": "libnumbertext-1.0.10.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libatomic_ops-7.6.8.tar.gz", "sha256": "1d6a279edf81767e74d2ad2c9fce09459bc65f12c6525a40b0cb3e53c089f665", "type": "file", "dest": "external/tarballs", "dest-filename": "libatomic_ops-7.6.8.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/dragonbox-1.1.0.tar.gz", "sha256": "293247ccba995ec47ae3abb52c3e83904a7d71efb7093d4c0d2c6367c1cc1e20", "type": "file", "dest": "external/tarballs", "dest-filename": "dragonbox-1.1.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/dtoa-20180411.tgz", "sha256": "0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4", "type": "file", "dest": "external/tarballs", "dest-filename": "dtoa-20180411.tgz" }, { "url": "https://dev-www.libreoffice.org/src/box2d-2.4.1.tar.gz", "sha256": "d6b4650ff897ee1ead27cf77a5933ea197cbeef6705638dd181adc2e816b23c2", "type": "file", "dest": "external/tarballs", "dest-filename": "box2d-2.4.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/zxing-cpp-1.2.0.tar.gz", "sha256": "653d9e44195d86cf64a36af9ff3a1978ec5599df3882439fefa56e7064f55e8a", "type": "file", "dest": "external/tarballs", "dest-filename": "zxing-cpp-1.2.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/extern/f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140-opens___.ttf", "sha256": "f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140", "type": "file", "dest": "external/tarballs", "dest-filename": "f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140-opens___.ttf" } ], "buildsystem": "simple", "build-commands": [ "./autogen.sh --prefix=/run/build/libreoffice/inst --with-distro=LibreOfficeFlatpak --with-gdrive-client-id=280867422816-9jc83t6phkfb2q8p94dtk8kr5fa8af3r.apps.googleusercontent.com --with-gdrive-client-secret=Hnzikj7HqdqsUYLru4jmFo1p --disable-pdfimport --disable-crashdump --disable-odk --disable-dbus --disable-gui --disable-sdremote --disable-sdremote-bluetooth --disable-cups --disable-extension-update --disable-dconf --disable-skia --without-helppack-integration", "make $(if test \"$FLATPAK_ARCH\" = i386; then printf build-nocheck; fi)", "make distro-pack-install", "make cmd cmd='$(SRCDIR)/solenv/bin/assemble-flatpak.sh'", "printf '\\nfalse' >/app/libreoffice/share/registry/flatpak.xcd" ] } ] } paperwork-2.2.2/flatpak/shared-modules/libreoffice-7.5.4.2.json000066400000000000000000001055551456262201400240570ustar00rootroot00000000000000{ "name": "libreoffice-complete", "modules": [ { "name": "openjdk", "buildsystem": "simple", "build-commands": [ "/usr/lib/sdk/openjdk11/install.sh" ] }, { "name": "krb5", "subdir": "src", "config-opts": [ "--disable-static", "--disable-rpath", "--sbindir=/app/bin" ], "cleanup": [ "/include", "/lib/pkgconfig", "/var" ], "sources": [ { "type": "archive", "url": "https://kerberos.org/dist/krb5/1.16/krb5-1.16.2.tar.gz", "sha256": "9f721e1fe593c219174740c71de514c7228a97d23eb7be7597b2ae14e487f027" } ] }, { "name": "libreoffice", "sources": [ { "type": "git", "url": "https://git.libreoffice.org/core", "tag": "libreoffice-7.5.4.2", "disable-fsckobjects": true }, { "type": "archive", "url": "https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.13-bin.tar.xz", "sha512": "26e56bf670c22c8093fe51ec952fa51e813b1ab4200cb09fcd68fa291c5f6f626d7c6a42b4d3358b38111466e249d4bc6089b8c4093383759d6f8a08d39bc32d", "dest": "ant" }, { "commands": [ "mkdir external/tarballs" ], "type": "shell" }, { "url": "https://dev-www.libreoffice.org/src/pdfium-5408.tar.bz2", "sha256": "7db59b1e91f2bc0ab4c5e19d1a4f881e6a47dbb0d3b7e980a7358225b12a0f35", "type": "file", "dest": "external/tarballs", "dest-filename": "pdfium-5408.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/xmlsec1-1.2.37.tar.gz", "sha256": "5f8dfbcb6d1e56bddd0b5ec2e00a3d0ca5342a9f57c24dffde5c796b2be2871c", "type": "file", "dest": "external/tarballs", "dest-filename": "xmlsec1-1.2.37.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz", "sha256": "c48d1c2fd613c9c06c959c34da7b8388059e2408d2bb19845dc3ed35f76e4d09", "type": "file", "dest": "external/tarballs", "dest-filename": "368f114c078f94214a308a74c7e991bc-crosextrafonts-20130214.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz", "sha256": "4bd12b6cbc321c1cf16da76e2c585c925ce956a08067ae6f6c64eff6ccfdaf5a", "type": "file", "dest": "external/tarballs", "dest-filename": "c74b7223abe75949b4af367942d96c7a-crosextrafonts-carlito-20130920.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip", "sha256": "7576310b219e04159d35ff61dd4a4ec4cdba4f35c00e002a136f00e96a908b0a", "type": "file", "dest": "external/tarballs", "dest-filename": "33e1e61fab06a547851ed308b4ffef42-dejavu-fonts-ttf-2.37.zip" }, { "url": "https://dev-www.libreoffice.org/src/1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip", "sha256": "2f1a2c5491d7305dffd3520c6375d2f3e14931ee35c6d8ae1e8f098bf1a7b3cc", "type": "file", "dest": "external/tarballs", "dest-filename": "1725634df4bb3dcb1b2c91a6175f8789-GentiumBasic_1102.zip" }, { "url": "https://dev-www.libreoffice.org/src/liberation-narrow-fonts-ttf-1.07.6.tar.gz", "sha256": "8879d89b5ff7b506c9fc28efc31a5c0b954bbe9333e66e5283d27d20a8519ea3", "type": "file", "dest": "external/tarballs", "dest-filename": "liberation-narrow-fonts-ttf-1.07.6.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/liberation-fonts-ttf-2.1.4.tar.gz", "sha256": "26f85412dd0aa9d061504a1cc8aaf0aa12a70710e8d47d8b65a1251757c1a5ef", "type": "file", "dest": "external/tarballs", "dest-filename": "liberation-fonts-ttf-2.1.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip", "sha256": "54adcb2bc8cac0927a647fbd9362f45eff48130ce6e2379dc3867643019e08c5", "type": "file", "dest": "external/tarballs", "dest-filename": "e7a384790b13c29113e22e596ade9687-LinLibertineG-20120116.zip" }, { "url": "https://dev-www.libreoffice.org/src/edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz", "sha256": "e7bc9a1fec787a529e49f5a26b93dcdcf41506449dfc70f92cdef6d17eb6fb61", "type": "file", "dest": "external/tarballs", "dest-filename": "edc4d741888bc0d38e32dbaa17149596-source-sans-pro-2.010R-ro-1.065R-it.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/boost_1_80_0.tar.xz", "sha256": "322e567e98c466c0aa0e380ed8c647552fe4af48998648428f1b5f0c8eff4666", "type": "file", "dest": "external/tarballs", "dest-filename": "boost_1_80_0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz", "sha256": "ddfdc433dd8ad31b5c5819cc4404a8d2127472a3b720d3e744e8c51d79732eab", "type": "file", "dest": "external/tarballs", "dest-filename": "48d647fbd8ef8889e5a7f422c1bfda94-clucene-core-2.3.3.4.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/CoinMP-1.7.6.tgz", "sha256": "86c798780b9e1f5921fe4efe651a93cb420623b45aa1fdff57af8c37f116113f", "type": "file", "dest": "external/tarballs", "dest-filename": "CoinMP-1.7.6.tgz" }, { "url": "https://dev-www.libreoffice.org/src/cppunit-1.15.1.tar.gz", "sha256": "89c5c6665337f56fd2db36bc3805a5619709d51fb136e51937072f63fcc717a7", "type": "file", "dest": "external/tarballs", "dest-filename": "cppunit-1.15.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Firebird-3.0.7.33374-0.tar.bz2", "sha256": "acb85cedafa10ce106b1823fb236b1b3e5d942a5741e8f8435cc8ccfec0afe76", "type": "file", "dest": "external/tarballs", "dest-filename": "Firebird-3.0.7.33374-0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/glm-0.9.9.8.zip", "sha256": "6bba5f032bed47c73ad9397f2313b9acbfb56253d0d0576b5873d3dcb25e99ad", "type": "file", "dest": "external/tarballs", "dest-filename": "glm-0.9.9.8.zip" }, { "url": "https://dev-www.libreoffice.org/src/gpgme-1.18.0.tar.bz2", "sha256": "361d4eae47ce925dba0ea569af40e7b52c645c4ae2e65e5621bf1b6cdd8b0e9e", "type": "file", "dest": "external/tarballs", "dest-filename": "gpgme-1.18.0.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libassuan-2.5.5.tar.bz2", "sha256": "8e8c2fcc982f9ca67dcbb1d95e2dc746b1739a4668bc20b3a3c5be632edb34e4", "type": "file", "dest": "external/tarballs", "dest-filename": "libassuan-2.5.5.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libgpg-error-1.43.tar.bz2", "sha256": "a9ab83ca7acc442a5bd846a75b920285ff79bdb4e3d34aa382be88ed2c3aebaf", "type": "file", "dest": "external/tarballs", "dest-filename": "libgpg-error-1.43.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libabw-0.1.3.tar.xz", "sha256": "e763a9dc21c3d2667402d66e202e3f8ef4db51b34b79ef41f56cacb86dcd6eed", "type": "file", "dest": "external/tarballs", "dest-filename": "libabw-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcdr-0.1.7.tar.xz", "sha256": "5666249d613466b9aa1e987ea4109c04365866e9277d80f6cd9663e86b8ecdd4", "type": "file", "dest": "external/tarballs", "dest-filename": "libcdr-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libcmis-0.5.2.tar.xz", "sha256": "d7b18d9602190e10d437f8a964a32e983afd57e2db316a07d87477a79f5000a2", "type": "file", "dest": "external/tarballs", "dest-filename": "libcmis-0.5.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libe-book-0.1.3.tar.xz", "sha256": "7e8d8ff34f27831aca3bc6f9cc532c2f90d2057c778963b884ff3d1e34dfe1f9", "type": "file", "dest": "external/tarballs", "dest-filename": "libe-book-0.1.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libetonyek-0.1.10.tar.xz", "sha256": "b430435a6e8487888b761dc848b7981626eb814884963ffe25eb26a139301e9a", "type": "file", "dest": "external/tarballs", "dest-filename": "libetonyek-0.1.10.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libexttextcat-3.4.6.tar.xz", "sha256": "6d77eace20e9ea106c1330e268ede70c9a4a89744ddc25715682754eca3368df", "type": "file", "dest": "external/tarballs", "dest-filename": "libexttextcat-3.4.6.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libfreehand-0.1.2.tar.xz", "sha256": "0e422d1564a6dbf22a9af598535425271e583514c0f7ba7d9091676420de34ac", "type": "file", "dest": "external/tarballs", "dest-filename": "libfreehand-0.1.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/language-subtag-registry-2022-08-08.tar.bz2", "sha256": "e2d9224e0e50fc8ad12a3cf47396bbcadf45b2515839d4770432653a88972c00", "type": "file", "dest": "external/tarballs", "dest-filename": "language-subtag-registry-2022-08-08.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/liblangtag-0.6.3.tar.bz2", "sha256": "1f12a20a02ec3a8d22e54dedb8b683a43c9c160bda1ba337bf1060607ae733bd", "type": "file", "dest": "external/tarballs", "dest-filename": "liblangtag-0.6.3.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libmspub-0.1.4.tar.xz", "sha256": "ef36c1a1aabb2ba3b0bedaaafe717bf4480be2ba8de6f3894be5fd3702b013ba", "type": "file", "dest": "external/tarballs", "dest-filename": "libmspub-0.1.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libmwaw-0.3.21.tar.xz", "sha256": "e8750123a78d61b943cef78b7736c8a7f20bb0a649aa112402124fba794fc21c", "type": "file", "dest": "external/tarballs", "dest-filename": "libmwaw-0.3.21.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libodfgen-0.1.8.tar.xz", "sha256": "55200027fd46623b9bdddd38d275e7452d1b0ff8aeddcad6f9ae6dc25f610625", "type": "file", "dest": "external/tarballs", "dest-filename": "libodfgen-0.1.8.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libpagemaker-0.0.4.tar.xz", "sha256": "66adacd705a7d19895e08eac46d1e851332adf2e736c566bef1164e7a442519d", "type": "file", "dest": "external/tarballs", "dest-filename": "libpagemaker-0.0.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/librevenge-0.0.4.tar.bz2", "sha256": "c51601cd08320b75702812c64aae0653409164da7825fd0f451ac2c5dbe77cbf", "type": "file", "dest": "external/tarballs", "dest-filename": "librevenge-0.0.4.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/libstaroffice-0.0.7.tar.xz", "sha256": "f94fb0ad8216f97127bedef163a45886b43c62deac5e5b0f5e628e234220c8db", "type": "file", "dest": "external/tarballs", "dest-filename": "libstaroffice-0.0.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/ltm-1.0.zip", "sha256": "083daa92d8ee6f4af96a6143b12d7fc8fe1a547e14f862304f7281f8f7347483", "type": "file", "dest": "external/tarballs", "dest-filename": "ltm-1.0.zip" }, { "url": "https://dev-www.libreoffice.org/src/libvisio-0.1.7.tar.xz", "sha256": "8faf8df870cb27b09a787a1959d6c646faa44d0d8ab151883df408b7166bea4c", "type": "file", "dest": "external/tarballs", "dest-filename": "libvisio-0.1.7.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpd-0.10.3.tar.xz", "sha256": "2465b0b662fdc5d4e3bebcdc9a79027713fb629ca2bff04a3c9251fdec42dd09", "type": "file", "dest": "external/tarballs", "dest-filename": "libwpd-0.10.3.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwpg-0.3.4.tar.xz", "sha256": "b55fda9440d1e070630eb2487d8b8697cf412c214a27caee9df69cec7c004de3", "type": "file", "dest": "external/tarballs", "dest-filename": "libwpg-0.3.4.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libwps-0.4.12.tar.xz", "sha256": "e21afb52a06d03b774c5a8c72679687ab64891b91ce0c3bdf2d3e97231534edb", "type": "file", "dest": "external/tarballs", "dest-filename": "libwps-0.4.12.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libzmf-0.0.2.tar.xz", "sha256": "27051a30cb057fdb5d5de65a1f165c7153dc76e27fe62251cbb86639eb2caf22", "type": "file", "dest": "external/tarballs", "dest-filename": "libzmf-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz", "sha256": "171816288f14215c69e730f7a4f1c325739873e21f946ff83884b350574e6695", "type": "file", "dest": "external/tarballs", "dest-filename": "26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mariadb-connector-c-3.1.8-src.tar.gz", "sha256": "431434d3926f4bcce2e5c97240609983f60d7ff50df5a72083934759bb863f7b", "type": "file", "dest": "external/tarballs", "dest-filename": "mariadb-connector-c-3.1.8-src.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/mdds-2.0.3.tar.bz2", "sha256": "9771fe42e133443c13ca187253763e17c8bc96a1a02aec9e1e8893367ffa9ce5", "type": "file", "dest": "external/tarballs", "dest-filename": "mdds-2.0.3.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/noto-fonts-20171024.tar.gz", "sha256": "29acc15a4c4d6b51201ba5d60f303dfbc2e5acbfdb70413c9ae1ed34fa259994", "type": "file", "dest": "external/tarballs", "dest-filename": "noto-fonts-20171024.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/openldap-2.4.59.tgz", "sha256": "99f37d6747d88206c470067eda624d5e48c1011e943ec0ab217bae8712e22f34", "type": "file", "dest": "external/tarballs", "dest-filename": "openldap-2.4.59.tgz" }, { "url": "https://dev-www.libreoffice.org/src/liborcus-0.17.2.tar.bz2", "sha256": "2a86c405a5929f749b27637509596421d46805753364ab258b035fd01fbde143", "type": "file", "dest": "external/tarballs", "dest-filename": "liborcus-0.17.2.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/poppler-22.12.0.tar.xz", "sha256": "d9aa9cacdfbd0f8e98fc2b3bb008e645597ed480685757c3e7bc74b4278d15c0", "type": "file", "dest": "external/tarballs", "dest-filename": "poppler-22.12.0.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/poppler-data-0.4.11.tar.gz", "sha256": "2cec05cd1bb03af98a8b06a1e22f6e6e1a65b1e2f3816cb3069bb0874825f08c", "type": "file", "dest": "external/tarballs", "dest-filename": "poppler-data-0.4.11.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/postgresql-13.10.tar.bz2", "sha256": "5bbcf5a56d85c44f3a8b058fb46862ff49cbc91834d07e295d02e6de3c216df2", "type": "file", "dest": "external/tarballs", "dest-filename": "postgresql-13.10.tar.bz2" }, { "url": "https://dev-www.libreoffice.org/src/a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz", "sha256": "ada7f0ba54787b33485d090d3d2680533520cd4426d2f7fb4782dd4a6a1480ed", "type": "file", "dest": "external/tarballs", "dest-filename": "a39f6c07ddb20d7dd2ff1f95fa21e2cd-raptor2-2.0.15.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz", "sha256": "6924c9ac6570bd241a9669f83b467c728a322470bf34f4b2da4f69492ccfd97c", "type": "file", "dest": "external/tarballs", "dest-filename": "1f5def51ca0026cd192958ef07228b52-rasqal-0.9.33.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz", "sha256": "de1847f7b59021c16bdc72abb4d8e2d9187cd6124d69156f3326dd34ee043681", "type": "file", "dest": "external/tarballs", "dest-filename": "e5be03eda13ef68aabab6e42aa67715e-redland-1.0.17.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/ReemKufi-1.2.zip", "sha256": "c4fd68a23c0ea471cc084ae7efe888da372b925cb208eeb0322c26792d2ef413", "type": "file", "dest": "external/tarballs", "dest-filename": "ReemKufi-1.2.zip" }, { "url": "https://dev-www.libreoffice.org/src/libepubgen-0.1.1.tar.xz", "sha256": "03e084b994cbeffc8c3dd13303b2cb805f44d8f2c3b79f7690d7e3fc7f6215ad", "type": "file", "dest": "external/tarballs", "dest-filename": "libepubgen-0.1.1.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libqxp-0.0.2.tar.xz", "sha256": "e137b6b110120a52c98edd02ebdc4095ee08d0d5295a94316a981750095a945c", "type": "file", "dest": "external/tarballs", "dest-filename": "libqxp-0.0.2.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/alef-1.001.tar.gz", "sha256": "b98b67602a2c8880a1770f0b9e37c190f29a7e2ade5616784f0b89fbdb75bf52", "type": "file", "dest": "external/tarballs", "dest-filename": "alef-1.001.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Amiri-1.000.zip", "sha256": "926fe1bd7dfde8e55178281f645258bfced6420c951c6f2fd532fd21691bca30", "type": "file", "dest": "external/tarballs", "dest-filename": "Amiri-1.000.zip" }, { "url": "https://dev-www.libreoffice.org/src/culmus-0.133.tar.gz", "sha256": "c0c6873742d07544f6bacf2ad52eb9cb392974d56427938dc1dfbc8399c64d05", "type": "file", "dest": "external/tarballs", "dest-filename": "culmus-0.133.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/libre-hebrew-1.0.tar.gz", "sha256": "f596257c1db706ce35795b18d7f66a4db99d427725f20e9384914b534142579a", "type": "file", "dest": "external/tarballs", "dest-filename": "libre-hebrew-1.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/Scheherazade-2.100.zip", "sha256": "251c8817ceb87d9b661ce1d5b49e732a0116add10abc046be4b8ba5196e149b5", "type": "file", "dest": "external/tarballs", "dest-filename": "Scheherazade-2.100.zip" }, { "url": "https://dev-www.libreoffice.org/src/beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip", "sha256": "9e93c73e23aff644b17dfff656444474c14150e7f3b38b19635e622235e01c96", "type": "file", "dest": "external/tarballs", "dest-filename": "beeca87be45ec87d241ddd0e1bad80c1-bsh-2.0b6-src.zip" }, { "url": "https://dev-www.libreoffice.org/src/ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip", "sha256": "233f66e8d25c5dd971716d4200203a612a407649686ef3b52075d04b4c9df0dd", "type": "file", "dest": "external/tarballs", "dest-filename": "ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip" }, { "url": "https://dev-www.libreoffice.org/src/d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip", "sha256": "1b5b24f7bc543c0362b667692f78db8bab4ed6dafc6172f104d0bd3757d8a133", "type": "file", "dest": "external/tarballs", "dest-filename": "d8bd5eed178db6e2b18eeed243f85aa8-flute-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip", "sha256": "d30b13f4ba2e3b6a2d4f020c0dee0a9fb9fc6fbcc2d561f36b78da4bf3802370", "type": "file", "dest": "external/tarballs", "dest-filename": "17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip" }, { "url": "https://dev-www.libreoffice.org/src/eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip", "sha256": "75c80359c9ce343c20aab8a36a45cb3b9ee7c61cf92c13ae45399d854423a9ba", "type": "file", "dest": "external/tarballs", "dest-filename": "eeb2c7ddf0d302fba4bfc6e97eac9624-libbase-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip", "sha256": "e0531091787c0f16c83965fdcbc49162c059d7f0c64669e7f119699321549743", "type": "file", "dest": "external/tarballs", "dest-filename": "3bdf40c0d199af31923e900d082ca2dd-libfonts-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip", "sha256": "5826d1551bf599b85742545f6e01a0079b93c1b2c8434bf409eddb3a29e4726b", "type": "file", "dest": "external/tarballs", "dest-filename": "3404ab6b1792ae5f16bbd603bd1e1d03-libformula-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip", "sha256": "e1fb87f3f7b980d33414473279615c4644027e013012d156efa538bc2b031772", "type": "file", "dest": "external/tarballs", "dest-filename": "db60e4fde8dd6d6807523deb71ee34dc-liblayout-0.2.10.zip" }, { "url": "https://dev-www.libreoffice.org/src/97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip", "sha256": "3d853b19b1d94a6efa69e7af90f7f2b09ecf302913bee3da796c15ecfebcfac8", "type": "file", "dest": "external/tarballs", "dest-filename": "97b2d4dba862397f446b217e2b623e71-libloader-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip", "sha256": "abe2c57ac12ba45d83563b02e240fa95d973376de2f720aab8fe11f2e621c095", "type": "file", "dest": "external/tarballs", "dest-filename": "8ce2fcd72becf06c41f7201d15373ed9-librepository-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip", "sha256": "05640a1f6805b2b2d7e2cb9c50db9a5cb084e3c52ab1a71ce015239b4a1d4343", "type": "file", "dest": "external/tarballs", "dest-filename": "f94d9870737518e3b597f9265f4e9803-libserializer-1.1.6.zip" }, { "url": "https://dev-www.libreoffice.org/src/ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip", "sha256": "7d2797fe9f79a77009721e3f14fa4a1dec17a6d706bdc93f85f1f01d124fab66", "type": "file", "dest": "external/tarballs", "dest-filename": "ace6ab49184e329db254e454a010f56d-libxml-1.1.7.zip" }, { "url": "https://dev-www.libreoffice.org/src/798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip", "sha256": "1fb458d6aab06932693cc8a9b6e4e70944ee1ff052fa63606e3131df34e21753", "type": "file", "dest": "external/tarballs", "dest-filename": "798b2ffdc8bcfe7bca2cf92b62caf685-rhino1_5R5.zip" }, { "url": "https://dev-www.libreoffice.org/src/39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip", "sha256": "085f2112c51fa8c1783fac12fbd452650596415121348393bb51f0f7e85a9045", "type": "file", "dest": "external/tarballs", "dest-filename": "39bb3fcea1514f1369fcfc87542390fd-sacjava-1.3.zip" }, { "url": "https://dev-www.libreoffice.org/src/35c94d2df8893241173de1d16b6034c0-swingExSrc.zip", "sha256": "64585ac36a81291a58269ec5347e7e3e2e8596dbacb9221015c208191333c6e1", "type": "file", "dest": "external/tarballs", "dest-filename": "35c94d2df8893241173de1d16b6034c0-swingExSrc.zip" }, { "url": "https://dev-www.libreoffice.org/src/libnumbertext-1.0.11.tar.xz", "sha256": "5dcb4db3b2340f81f601ce86d8d76b69e34d70f84f804192c901e4b7f84d5fb0", "type": "file", "dest": "external/tarballs", "dest-filename": "libnumbertext-1.0.11.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/libatomic_ops-7.6.8.tar.gz", "sha256": "1d6a279edf81767e74d2ad2c9fce09459bc65f12c6525a40b0cb3e53c089f665", "type": "file", "dest": "external/tarballs", "dest-filename": "libatomic_ops-7.6.8.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/skia-m103-b301ff025004c9cd82816c86c547588e6c24b466.tar.xz", "sha256": "c094a6247e44104beaaa0d00c825beb6baf1a8e532dc22214747495317a65bd9", "type": "file", "dest": "external/tarballs", "dest-filename": "skia-m103-b301ff025004c9cd82816c86c547588e6c24b466.tar.xz" }, { "url": "https://dev-www.libreoffice.org/src/dragonbox-1.1.3.tar.gz", "sha256": "09d63b05e9c594ec423778ab59b7a5aa1d76fdd71d25c7048b0258c4ec9c3384", "type": "file", "dest": "external/tarballs", "dest-filename": "dragonbox-1.1.3.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/dtoa-20180411.tgz", "sha256": "0082d0684f7db6f62361b76c4b7faba19e0c7ce5cb8e36c4b65fea8281e711b4", "type": "file", "dest": "external/tarballs", "dest-filename": "dtoa-20180411.tgz" }, { "url": "https://dev-www.libreoffice.org/src/box2d-2.4.1.tar.gz", "sha256": "d6b4650ff897ee1ead27cf77a5933ea197cbeef6705638dd181adc2e816b23c2", "type": "file", "dest": "external/tarballs", "dest-filename": "box2d-2.4.1.tar.gz" }, { "url": "https://dev-www.libreoffice.org/src/zxing-cpp-1.4.0.tar.gz", "sha256": "126767bb56f8a1f25ae84d233db2e9b9be50d71f5776092d0e170ca0f0ed1862", "type": "file", "dest": "external/tarballs", "dest-filename": "zxing-cpp-1.4.0.tar.gz" }, { "url": "https://dev-www.libreoffice.org/extern/f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140-opens___.ttf", "sha256": "f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140", "type": "file", "dest": "external/tarballs", "dest-filename": "f543e6e2d7275557a839a164941c0a86e5f2c3f2a0042bfc434c88c6dde9e140-opens___.ttf" } ], "buildsystem": "simple", "build-commands": [ "./autogen.sh --prefix=/run/build/libreoffice/inst --with-distro=LibreOfficeFlatpak --with-gdrive-client-id=280867422816-9jc83t6phkfb2q8p94dtk8kr5fa8af3r.apps.googleusercontent.com --with-gdrive-client-secret=Hnzikj7HqdqsUYLru4jmFo1p --disable-pdfimport --disable-crashdump --disable-odk --disable-dbus --disable-gui --disable-sdremote --disable-sdremote-bluetooth --disable-cups --disable-extension-update --disable-dconf --disable-skia --without-helppack-integration", "make", "make distro-pack-install", "make cmd cmd='$(SRCDIR)/solenv/bin/assemble-flatpak.sh'", "printf '\\nfalse' >/app/libreoffice/share/registry/flatpak.xcd" ] } ] } paperwork-2.2.2/flatpak/shared-modules/noop-Makefile000066400000000000000000000000661456262201400225020ustar00rootroot00000000000000all: @echo no-op install: @echo no-op .PHONY: all paperwork-2.2.2/flatpak/shared-modules/sane-backends-1.0.27.json000066400000000000000000000011261456262201400242030ustar00rootroot00000000000000{ "name": "sane-backends", "buildsystem": "autotools", "config-opts": [ "--disable-saned" ], "sources": [ { "type": "archive", "url": "https://ftp.osuosl.org/.1/blfs/conglomeration/sane-backends/sane-backends-1.0.27.tar.gz", "sha256": "293747bf37275c424ebb2c833f8588601a60b2f9653945d5a3194875355e36c9" } ], "post-install": [ "rm /app/etc/sane.d/dll.conf", "rm /app/etc/sane.d/net.conf", "echo 127.0.0.1 > /app/etc/sane.d/net.conf", "echo net > /app/etc/sane.d/dll.conf" ] } paperwork-2.2.2/flatpak/shared-modules/sane-backends-1.0.29.json000066400000000000000000000012571456262201400242120ustar00rootroot00000000000000{ "name": "sane-backends", "buildsystem": "autotools", "config-opts": [ "--disable-saned" ], "sources": [ { "type": "archive", "url": "https://ftp.osuosl.org/.1/blfs/conglomeration/sane-backends/sane-backends-1.0.29.tar.gz", "sha256": "aa027b4e5f59849cd41b8c26d54584cf31fffd986049019be6ad4140e11ea8ed" }, { "type": "patch", "path": "sanei_usb.c.diff" } ], "post-install": [ "rm /app/etc/sane.d/dll.conf", "rm /app/etc/sane.d/net.conf", "echo 127.0.0.1 > /app/etc/sane.d/net.conf", "echo net > /app/etc/sane.d/dll.conf" ] } paperwork-2.2.2/flatpak/shared-modules/sane-backends-1.0.32.json000066400000000000000000000013211456262201400241740ustar00rootroot00000000000000{ "name": "sane-backends", "buildsystem": "autotools", "config-opts": [ "--disable-saned" ], "sources": [ { "type": "archive", "url": "https://gitlab.com/sane-project/backends/uploads/104f09c07d35519cc8e72e604f11643f/sane-backends-1.0.32.tar.gz", "sha256": "3a28c237c0a72767086202379f6dc92dbb63ec08dfbab22312cba80e238bb114" } ], "post-install": [ "rm /app/etc/sane.d/dll.conf", "rm /app/etc/sane.d/net.conf", "echo 127.0.0.1 > /app/etc/sane.d/net.conf", "echo net > /app/etc/sane.d/dll.conf", "echo escl >> /app/etc/sane.d/dll.conf", "echo airscan >> /app/etc/sane.d/dll.conf" ] } paperwork-2.2.2/flatpak/shared-modules/sane-backends-1.1.1.json000066400000000000000000000013201456262201400241100ustar00rootroot00000000000000{ "name": "sane-backends", "buildsystem": "autotools", "config-opts": [ "--disable-saned" ], "sources": [ { "type": "archive", "url": "https://gitlab.com/sane-project/backends/uploads/7d30fab4e115029d91027b6a58d64b43/sane-backends-1.1.1.tar.gz", "sha256": "dd4b04c37a42f14c4619e8eea6a957f4c7c617fe59e32ae2872b373940a8b603" } ], "post-install": [ "rm /app/etc/sane.d/dll.conf", "rm /app/etc/sane.d/net.conf", "echo 127.0.0.1 > /app/etc/sane.d/net.conf", "echo net > /app/etc/sane.d/dll.conf", "echo escl >> /app/etc/sane.d/dll.conf", "echo airscan >> /app/etc/sane.d/dll.conf" ] } paperwork-2.2.2/flatpak/shared-modules/sanei_usb.c.diff000066400000000000000000000004111456262201400231060ustar00rootroot00000000000000--- a/sanei/sanei_usb.c 2021-01-04 22:01:10.399478905 +0100 +++ b/sanei/sanei_usb.c 2021-01-04 22:01:13.091463360 +0100 @@ -48,6 +48,7 @@ #include "../include/sane/config.h" +#include #include #include #include paperwork-2.2.2/flatpak/shared-modules/scikit-learn-0.24.0.json000066400000000000000000000147141456262201400240750ustar00rootroot00000000000000{ "name": "python-scikit-sklearn", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/db/e2/9c0bde5f81394b627f623557690536b12017b84988a4a1f98ec826edab9e/scikit-learn-0.24.0.tar.gz", "sha256": "076369634ee72b5a5941440661e2f306ff4ac30903802dc52031c7e9199ac640" } ], "modules": [ { "name": "python-cython", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/6c/9f/f501ba9d178aeb1f5bf7da1ad5619b207c90ac235d9859961c11829d0160/Cython-0.29.21.tar.gz", "sha256": "e57acb89bd55943c8d8bf813763d20b9099cc7165c0f16b707631a7654be9cad" } ] }, { "name": "python-pybind11", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/d8/47/2eb4be23fa8cc1a08c855c012c1aa4348d06ab1a5527f876515bbf689644/pybind11-2.6.1.tar.gz", "sha256": "ab7e60a520fe6ae25eca939191bb2ac416cd58478ce754740238a8bf1af18934" } ] }, { "name": "lapack", "buildsystem": "cmake", "builddir": true, "buildsystem": "cmake", "builddir": true, "config-opts": [ "-DCMAKE_INSTALL_prefix=/app --root=/ --optimize=1", "-DCMAKE_INSTALL_LIBDIR=lib", "-DCMAKE_BUILD_TYPE=Release", "-DBUILD_SHARED_LIBS=ON", "-DBUILD_TESTING=OFF", "-DLAPACKE=ON", "-DCBLAS=ON" ], "sources": [ { "type": "archive", "url": "https://github.com/Reference-LAPACK/lapack/archive/v3.9.0.tar.gz", "sha256": "106087f1bb5f46afdfba7f569d0cbe23dacb9a07cd24733765a0e89dbe1ad573" } ], "cleanup": [ "/lib/cmake" ] }, { "name": "python-threadpoolctl", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/78/e8/e39dc842f512ab5be11efe83160ddb7ad3c0cc1b8d42ce8c0469a0d2b926/threadpoolctl-2.1.0.tar.gz", "sha256": "ddc57c96a38beb63db45d6c159b5ab07b6bced12c45a1f07b2b92f272aebfa6b" } ] }, { "name": "python-joblib", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/69/a1/68266edcfabe8dc240d7c9e06972a121b011b232f0d1796a016192438435/joblib-1.0.0.tar.gz", "sha256": "7ad866067ac1fdec27d51c8678ea760601b70e32ff1881d4dc8e1171f2b64b24" } ] }, { "name": "python-numpy", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "build-options": { "env": { "ATLAS": "None", "BLAS": "/app/lib", "LAPACK": "/app/lib" } }, "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c5/63/a48648ebc57711348420670bb074998f79828291f68aebfff1642be212ec/numpy-1.19.4.zip", "sha256": "141ec3a3300ab89c7f2b0775289954d193cc8edb621ea05f99db9cb181530512" } ] }, { "name": "python-scipy", "build-options": { "env": { "ATLAS": "None", "BLAS": "/app/lib", "LAPACK": "/app/lib", "LDFLAGS": "-shared" } }, "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/aa/d5/dd06fe0e274e579e1dff21aa021219c039df40e39709fabe559faed072a5/scipy-1.5.4.tar.gz", "sha256": "4a453d5e5689de62e5d38edf40af3f17560bfd63c9c5bd228c18c1f99afa155b" } ] } ] } paperwork-2.2.2/flatpak/shared-modules/scikit-learn-1.2.0.json000066400000000000000000000216371456262201400240140ustar00rootroot00000000000000{ "name": "python-scikit-sklearn", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/27/a0/95eae31ceabeb7710a694367816edfcc0ccb001c794c14b3b234c148ae50/scikit-learn-1.2.0.tar.gz", "sha256": "680b65b3caee469541385d2ca5b03ff70408f6c618c583948312f0d2125df680" } ], "modules": [ { "name": "python3-meson-python", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"meson-python\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/ee/22/da1cc8cafca80283c795ebf58d4218017225df8288d70cb8fc32eb46f5e0/meson_python-0.12.0-py3-none-any.whl", "sha256": "3a2e7bfabf37f1878ad7b5556399deaf2dbffead85a50fc681a8bd4f4ef63da5" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/ed/35/a31aed2993e398f6b09a790a181a7927eb14610ee8bbf02dc14d31677f1c/packaging-23.0-py3-none-any.whl", "sha256": "714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/87/d4/beeb6ecb90df146a0d8e23599133d4298a0ae9a1ab1547146216965b2551/pyproject_metadata-0.6.1-py3-none-any.whl", "sha256": "36577274efd87df1bedb6fb335620cf7f4959d5457ef39881a7710c5b8c356a9" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/0b/8e/f1a0a5a76cfef77e1eb6004cb49e5f8d72634da638420b9ea492ce8305e8/typing_extensions-4.4.0-py3-none-any.whl", "sha256": "16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e" } ] }, { "name": "python3-numpy", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"numpy\" --no-build-isolation" ], "build-options": { "env": { "ATLAS": "None", "BLAS": "/app/lib", "LAPACK": "/app/lib" } }, "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/ce/b8/c170db50ec49d5845bd771bc5549fe734ee73083c5c52791915f95d8e2bc/numpy-1.24.1.tar.gz", "sha256": "2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2" } ] }, { "name": "python3-pythran", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"pythran\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/cc/4a/af3f1b3d00efd47309b7a0e28351e06453727fa55d9b3a45fd4b91031a63/beniget-0.4.1-py3-none-any.whl", "sha256": "cb061256631313f9d06031b824f7f403baecaf609b2d3d14d43f23356cf143f2" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/5f/1c/b59500a88c5c3d9d601c5ca62b9df5e0964764472faed82a182958a922c5/gast-0.5.3-py3-none-any.whl", "sha256": "211aac1e58c167b25d3504998f2db694454a24bb1fb1225bce99420166f21d6a" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl", "sha256": "096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/f4/1a/71f510d40adfefa5369388c0fe186981821cfb34bc4de2e6729b03363ea9/pythran-0.12.0-py3-none-any.whl", "sha256": "f06c23e1045030a29cabe07161b61c511edf662cd0cd0b439ecde24a50e28eb5" } ] }, { "name": "python3-pybind11", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"pybind11\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/17/4e/9b2f39b5d0ae5f81541e03a98379462871ccfbadfa315d24b3d8854c6a9f/pybind11-2.10.3-py3-none-any.whl", "sha256": "123e303f39ad5de97ddfa4f1f473cb85881a0a94ee5714eb3c37e2405371fc12" } ] }, { "name": "lapack", "buildsystem": "cmake", "builddir": true, "config-opts": [ "-DCMAKE_INSTALL_LIBDIR=lib", "-DCMAKE_BUILD_TYPE=Release", "-DBUILD_SHARED_LIBS=ON", "-DBUILD_TESTING=OFF", "-DLAPACKE=ON", "-DCBLAS=ON" ], "sources": [ { "type": "archive", "url": "https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.11.tar.gz", "sha256": "5a5b3bac27709d8c66286b7a0d1d7bf2d7170ec189a1a756fdf812c97aa7fd10" } ], "cleanup": [ "/lib/cmake" ] }, { "name": "python3-scipy", "buildsystem": "simple", "build-commands": [ "python3 setup.py build -j 0", "python3 setup.py install --prefix=/app --root=/ --optimize=1" ], "build-options": { "env": { "ATLAS": "None", "BLAS": "/app/lib", "LAPACK": "/app/lib", "LDFLAGS": "-shared" } }, "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/0a/2e/44795c6398e24e45fa0bb61c3e98de1cfea567b1b51efd3751e2f7ff9720/scipy-1.9.3.tar.gz", "sha256": "fbc5c05c85c1a02be77b1ff591087c83bc44579c6d2bd9fb798bb64ea5e1a027" } ] }, { "name": "python3-scikit-learn", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"scikit-learn\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/91/d4/3b4c8e5a30604df4c7518c562d4bf0502f2fa29221459226e140cf846512/joblib-1.2.0-py3-none-any.whl", "sha256": "091138ed78f800342968c523bdde947e7a305b8594b910a0fea2ab83c3c6d385" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/27/a0/95eae31ceabeb7710a694367816edfcc0ccb001c794c14b3b234c148ae50/scikit-learn-1.2.0.tar.gz", "sha256": "680b65b3caee469541385d2ca5b03ff70408f6c618c583948312f0d2125df680" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/61/cf/6e354304bcb9c6413c4e02a747b600061c21d38ba51e7e544ac7bc66aecc/threadpoolctl-3.1.0-py3-none-any.whl", "sha256": "8b99adda265feb6773280df41eece7b2e6561b772d21ffd52e372f999024907b" } ] } ] } paperwork-2.2.2/flatpak/shared-modules/setuptools-40.8.0.json000066400000000000000000000044221456262201400237320ustar00rootroot00000000000000{ "name": "python-setuptools-all", "modules": [ { "name": "python-setuptools", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build", "python3 setup.py install --prefix=/app" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/c2/f7/c7b501b783e5a74cf1768bc174ee4fb0a8a6ee5af6afa92274ff964703e0/setuptools-40.8.0.zip", "sha256": "6e4eec90337e849ade7103723b9a99631c1f0d19990d6e8412dc42f5ae8b304d" } ] }, { "name": "python-setuptools-scm", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build", "python3 setup.py install --prefix=/app" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/54/85/514ba3ca2a022bddd68819f187ae826986051d130ec5b972076e4f58a9f3/setuptools_scm-3.2.0.tar.gz", "sha256": "52ab47715fa0fc7d8e6cd15168d1a69ba995feb1505131c3e814eb7087b57358" } ] }, { "name": "python-setuptools-scm-git-archive", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 setup.py build", "python3 setup.py install --prefix=/app" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/7e/2c/0c15b29a1b5940250bfdc4a4f53272e35cd7cf8a34159291b6b4ec9eb291/setuptools_scm_git_archive-1.1.tar.gz", "sha256": "6026f61089b73fa1b5ee737e95314f41cb512609b393530385ed281d0b46c062" } ] } ] } paperwork-2.2.2/flatpak/shared-modules/setuptools-59.5.0.json000066400000000000000000000014061456262201400237400ustar00rootroot00000000000000{ "name": "python-setuptools-all", "modules": [ { "name": "python-setuptools", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 ./setup.py install --prefix=/app --root=/" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/e6/e2/f2bfdf364e016f7a464db709ea40d1101c4c5a463dd7019dae0a42dbd1c6/setuptools-59.5.0.tar.gz", "sha256": "d144f85102f999444d06f9c0e8c737fd0194f10f2f7e5fdb77573f6e2fa4fad0" } ] } ] } paperwork-2.2.2/flatpak/shared-modules/setuptools-65.6.3.json000066400000000000000000000014061456262201400237410ustar00rootroot00000000000000{ "name": "python-setuptools-all", "modules": [ { "name": "python-setuptools", "buildsystem": "simple", "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "build-commands": [ "python3 ./setup.py install --prefix=/app --root=/" ], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/b6/21/cb9a8d0b2c8597c83fce8e9c02884bce3d4951e41e807fc35791c6b23d9a/setuptools-65.6.3.tar.gz", "sha256": "a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75" } ] } ] } paperwork-2.2.2/flatpak/shared-modules/tesseract-3.05.01.json000066400000000000000000000073131456262201400235650ustar00rootroot00000000000000{ "name": "tesseract-bundle", "no-autogen": true, "sources": [ { "type": "file", "path": "noop-Makefile", "dest-filename": "Makefile" } ], "modules": [ { "name": "libleptonica", "buildsystem": "autotools", "config-opts": [ ], "sources": [ { "type": "archive", "url": "https://github.com/DanBloomberg/leptonica/releases/download/1.74.4/leptonica-1.74.4.tar.gz", "sha256": "29c35426a416bf454413c6fec24c24a0b633e26144a17e98351b6dffaa4a833b" } ] }, { "name": "tesseract", "buildsystem": "autotools", "config-opts": [ "--disable-graphics" ], "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tesseract/archive/3.05.01.tar.gz", "sha256": "05898f93c5d057fada49b9a116fc86ad9310ff1726a0f499c3e5211b3af47ec1" } ] }, { "name": "tessdata", "no-autogen": true, "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tessdata/archive/3.04.00.tar.gz", "sha256": "5dcb37198336b6953843b461ee535df1401b41008d550fc9e43d0edabca7adb1" }, { "type": "file", "path": "noop-Makefile", "dest-filename": "Makefile" } ], "post-install": [ "mkdir -p /app/share/tessdata", "cp eng.traineddata /app/share/tessdata", "cp osd.traineddata /app/share/tessdata", "mkdir -p /app/share/locale/bg", "cp bul.traineddata /app/share/locale/bg", "mkdir -p /app/share/locale/da", "cp dan.traineddata /app/share/locale/da", "mkdir -p /app/share/locale/de", "cp deu.traineddata /app/share/locale/de", "mkdir -p /app/share/locale/eo", "cp epo.traineddata /app/share/locale/eo", "mkdir -p /app/share/locale/fi", "cp fin.traineddata /app/share/locale/fi", "mkdir -p /app/share/locale/fr", "cp fra.traineddata /app/share/locale/fr", "mkdir -p /app/share/locale/gl", "cp glg.traineddata /app/share/locale/gl", "mkdir -p /app/share/locale/hu", "cp hun.traineddata /app/share/locale/hu", "mkdir -p /app/share/locale/it", "cp ita.traineddata /app/share/locale/it", "mkdir -p /app/share/locale/ja", "cp jpn.traineddata /app/share/locale/ja", "mkdir -p /app/share/locale/nl", "cp nld.traineddata /app/share/locale/nl", "mkdir -p /app/share/locale/nb", "cp nor.traineddata /app/share/locale/nb", "mkdir -p /app/share/locale/pt", "cp por.traineddata /app/share/locale/pt", "mkdir -p /app/share/locale/ru", "cp rus.traineddata /app/share/locale/ru", "mkdir -p /app/share/locale/es", "cp spa.traineddata /app/share/locale/es", "mkdir -p /app/share/locale/sv", "cp swe.traineddata /app/share/locale/sv", "mkdir -p /app/share/locale/uk", "cp ukr.traineddata /app/share/locale/uk" ] } ] }paperwork-2.2.2/flatpak/shared-modules/tesseract-4.0.0.json000066400000000000000000000062741456262201400234250ustar00rootroot00000000000000{ "name": "tesseract", "buildsystem": "autotools", "config-opts": [ "--disable-graphics" ], "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tesseract/archive/4.0.0.tar.gz", "sha256": "a1f5422ca49a32e5f35c54dee5112b11b99928fc9f4ee6695cdc6768d69f61dd" } ], "modules": [ { "name": "libleptonica", "buildsystem": "autotools", "sources": [ { "type": "archive", "url": "https://github.com/DanBloomberg/leptonica/releases/download/1.77.0/leptonica-1.77.0.tar.gz", "sha256": "161d0b368091986b6c60990edf257460bdc7da8dd18d48d4179e297bcdca5eb7" } ] }, { "name": "tessdata", "buildsystem": "simple", "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tessdata/archive/4.0.0.tar.gz", "sha256": "38c637d3a1763f6c3d32e8f1d979f045668676ec5feb8ee1869ee77cedd31b08" } ], "build-commands": [ "mkdir -p /app/share/tessdata", "cp eng.traineddata /app/share/tessdata", "cp osd.traineddata /app/share/tessdata", "mkdir -p /app/share/locale/bg", "cp bul.traineddata /app/share/locale/bg", "mkdir -p /app/share/locale/da", "cp dan.traineddata /app/share/locale/da", "mkdir -p /app/share/locale/de", "cp deu.traineddata /app/share/locale/de", "mkdir -p /app/share/locale/eo", "cp epo.traineddata /app/share/locale/eo", "mkdir -p /app/share/locale/fi", "cp fin.traineddata /app/share/locale/fi", "mkdir -p /app/share/locale/fr", "cp fra.traineddata /app/share/locale/fr", "mkdir -p /app/share/locale/gl", "cp glg.traineddata /app/share/locale/gl", "mkdir -p /app/share/locale/hu", "cp hun.traineddata /app/share/locale/hu", "mkdir -p /app/share/locale/it", "cp ita.traineddata /app/share/locale/it", "mkdir -p /app/share/locale/ja", "cp jpn.traineddata /app/share/locale/ja", "mkdir -p /app/share/locale/nl", "cp nld.traineddata /app/share/locale/nl", "mkdir -p /app/share/locale/nb", "cp nor.traineddata /app/share/locale/nb", "mkdir -p /app/share/locale/pt", "cp por.traineddata /app/share/locale/pt", "mkdir -p /app/share/locale/ru", "cp rus.traineddata /app/share/locale/ru", "mkdir -p /app/share/locale/es", "cp spa.traineddata /app/share/locale/es", "mkdir -p /app/share/locale/sv", "cp swe.traineddata /app/share/locale/sv", "mkdir -p /app/share/locale/uk", "cp ukr.traineddata /app/share/locale/uk" ] } ] } paperwork-2.2.2/flatpak/shared-modules/tesseract-4.1.1.json000066400000000000000000000062741456262201400234270ustar00rootroot00000000000000{ "name": "tesseract", "buildsystem": "autotools", "config-opts": [ "--disable-graphics" ], "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tesseract/archive/4.1.1.tar.gz", "sha256": "2a66ff0d8595bff8f04032165e6c936389b1e5727c3ce5a27b3e059d218db1cb" } ], "modules": [ { "name": "libleptonica", "buildsystem": "autotools", "sources": [ { "type": "archive", "url": "https://github.com/DanBloomberg/leptonica/releases/download/1.79.0/leptonica-1.79.0.tar.gz", "sha256": "045966c9c5d60ebded314a9931007a56d9d2f7a6ac39cb5cc077c816f62300d8" } ] }, { "name": "tessdata", "buildsystem": "simple", "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tessdata/archive/4.0.0.tar.gz", "sha256": "38c637d3a1763f6c3d32e8f1d979f045668676ec5feb8ee1869ee77cedd31b08" } ], "build-commands": [ "mkdir -p /app/share/tessdata", "cp eng.traineddata /app/share/tessdata", "cp osd.traineddata /app/share/tessdata", "mkdir -p /app/share/locale/bg", "cp bul.traineddata /app/share/locale/bg", "mkdir -p /app/share/locale/da", "cp dan.traineddata /app/share/locale/da", "mkdir -p /app/share/locale/de", "cp deu.traineddata /app/share/locale/de", "mkdir -p /app/share/locale/eo", "cp epo.traineddata /app/share/locale/eo", "mkdir -p /app/share/locale/fi", "cp fin.traineddata /app/share/locale/fi", "mkdir -p /app/share/locale/fr", "cp fra.traineddata /app/share/locale/fr", "mkdir -p /app/share/locale/gl", "cp glg.traineddata /app/share/locale/gl", "mkdir -p /app/share/locale/hu", "cp hun.traineddata /app/share/locale/hu", "mkdir -p /app/share/locale/it", "cp ita.traineddata /app/share/locale/it", "mkdir -p /app/share/locale/ja", "cp jpn.traineddata /app/share/locale/ja", "mkdir -p /app/share/locale/nl", "cp nld.traineddata /app/share/locale/nl", "mkdir -p /app/share/locale/nb", "cp nor.traineddata /app/share/locale/nb", "mkdir -p /app/share/locale/pt", "cp por.traineddata /app/share/locale/pt", "mkdir -p /app/share/locale/ru", "cp rus.traineddata /app/share/locale/ru", "mkdir -p /app/share/locale/es", "cp spa.traineddata /app/share/locale/es", "mkdir -p /app/share/locale/sv", "cp swe.traineddata /app/share/locale/sv", "mkdir -p /app/share/locale/uk", "cp ukr.traineddata /app/share/locale/uk" ] } ] } paperwork-2.2.2/flatpak/shared-modules/tesseract-5.3.0.json000066400000000000000000000063251456262201400234260ustar00rootroot00000000000000{ "name": "tesseract", "buildsystem": "autotools", "config-opts": [ "--disable-graphics" ], "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tesseract/archive/refs/tags/5.3.0.tar.gz", "sha256": "7e70870f8341e5ea228af2836ce79a36eefa11b01b56177b4a8997f330c014b8" } ], "modules": [ { "name": "libleptonica", "buildsystem": "autotools", "sources": [ { "type": "archive", "url": "https://github.com/DanBloomberg/leptonica/releases/download/1.83.0/leptonica-1.83.0.tar.gz", "sha256": "206591dd58cf84ef380836dad133b58c9d1af92491f5a9825c346a162044bcfe" } ] }, { "name": "tessdata", "buildsystem": "simple", "sources": [ { "type": "archive", "url": "https://github.com/tesseract-ocr/tessdata_best/archive/refs/tags/4.1.0.tar.gz", "sha256": "bb05b738298ae73e7130e2913ed002b49d94cd1cea508e63be1928fe47770b32" } ], "build-commands": [ "mkdir -p /app/share/tessdata", "cp eng.traineddata /app/share/tessdata", "cp osd.traineddata /app/share/tessdata", "mkdir -p /app/share/locale/bg", "cp bul.traineddata /app/share/locale/bg", "mkdir -p /app/share/locale/da", "cp dan.traineddata /app/share/locale/da", "mkdir -p /app/share/locale/de", "cp deu.traineddata /app/share/locale/de", "mkdir -p /app/share/locale/eo", "cp epo.traineddata /app/share/locale/eo", "mkdir -p /app/share/locale/fi", "cp fin.traineddata /app/share/locale/fi", "mkdir -p /app/share/locale/fr", "cp fra.traineddata /app/share/locale/fr", "mkdir -p /app/share/locale/gl", "cp glg.traineddata /app/share/locale/gl", "mkdir -p /app/share/locale/hu", "cp hun.traineddata /app/share/locale/hu", "mkdir -p /app/share/locale/it", "cp ita.traineddata /app/share/locale/it", "mkdir -p /app/share/locale/ja", "cp jpn.traineddata /app/share/locale/ja", "mkdir -p /app/share/locale/nl", "cp nld.traineddata /app/share/locale/nl", "mkdir -p /app/share/locale/nb", "cp nor.traineddata /app/share/locale/nb", "mkdir -p /app/share/locale/pt", "cp por.traineddata /app/share/locale/pt", "mkdir -p /app/share/locale/ru", "cp rus.traineddata /app/share/locale/ru", "mkdir -p /app/share/locale/es", "cp spa.traineddata /app/share/locale/es", "mkdir -p /app/share/locale/sv", "cp swe.traineddata /app/share/locale/sv", "mkdir -p /app/share/locale/uk", "cp ukr.traineddata /app/share/locale/uk" ] } ] } paperwork-2.2.2/flatpak/stacktrace.sh000077500000000000000000000047661456262201400176530ustar00rootroot00000000000000#!/usr/bin/bash # Needed: # flatpak install --user https://builder.openpaper.work/paperwork_master.flatpakref # flatpak install --user paperwork-origin work.openpaper.Paperwork.Debug//master # flatpak install --user https://builder.openpaper.work/paperwork_testing.flatpakref # flatpak install --user paperwork-origin work.openpaper.Paperwork.Debug//testing # flatpak install --user https://builder.openpaper.work/paperwork_develop.flatpakref # flatpak install --user paperwork-origin work.openpaper.Paperwork.Debug//develop # The stack trace file must contain something similar to: # /app/lib/libinsane.so.1(+0x1aa14)[0x7f2ad73b5a14] # /usr/lib/x86_64-linux-gnu/libc.so.6(+0x39690)[0x7f2adf6e7690] # /usr/lib/x86_64-linux-gnu/libc.so.6(+0x9cc2a)[0x7f2adf74ac2a] # /usr/lib/x86_64-linux-gnu/libc.so.6(+0x6a716)[0x7f2adf718716] # /usr/lib/x86_64-linux-gnu/libc.so.6(+0x7c78a)[0x7f2adf72a78a] # /app/lib/libinsane.so.1(lis_log+0x125)[0x7f2ad73a3fb5] # /app/lib/libinsane.so.1(+0x1b7ba)[0x7f2ad73b67ba] # /app/lib/libinsane.so.1(+0x1b9f8)[0x7f2ad73b69f8] # /app/lib/libinsane.so.1(lis_worker_main+0x23a)[0x7f2ad73b6c6a] # /app/lib/libinsane.so.1(lis_api_workaround_dedicated_process+0x3a8)[0x7f2ad73b4518] # /app/lib/libinsane.so.1(lis_safebet+0x1b2)[0x7f2ad73ab502] # /app/lib/libinsane_gobject.so.1(libinsane_api_new_safebet+0x5a)[0x7f2ad766cf5a] # /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_call_unix64+0x4c)[0x7f2ade490b78] # /usr/lib/x86_64-linux-gnu/libffi.so.6(ffi_call+0x1d4)[0x7f2ade490374] # /usr/lib/python3.7/site-packages/gi/_gi.cpython-37m-x86_64-linux-gnu.so(+0x2a12d)[0x7f2addfdf12d] if [ $# -lt 2 ] ; then echo "Syntax:" echo " $0 " exit 1 fi stacktrace_file="$1" nb_commits="$2" for branch in master testing develop ; do for commit in $(flatpak remote-info \ --log -c paperwork-origin \ work.openpaper.Paperwork//${branch} \ | head -n ${nb_commits}) ; do echo "===================================" echo "Branch: ${branch}" echo "Flatpak Commit: ${commit}" echo for line in $(< ${stacktrace_file}) ; do if [ -z "${line}" ] || [ "${line}" = "-" ] ; then echo "(...)" echo continue fi filename=$(echo "${line}"|cut -d'(' -f1) addr=$(echo "${line}"|cut -d'(' -f2|cut -d')' -f1) result=$(flatpak run --devel --command=addr2line \ work.openpaper.Paperwork//${branch} \ -i -p -f -e "${filename}" "${addr}") echo "IN: ${filename}(${addr})" echo "ADDR2LINE: ${result}" echo done echo echo done done paperwork-2.2.2/nsis/000077500000000000000000000000001456262201400145055ustar00rootroot00000000000000paperwork-2.2.2/nsis/Makefile000066400000000000000000000045021456262201400161460ustar00rootroot00000000000000all: paperwork_stable_installer.exe paperwork_testing_installer.exe paperwork_develop_installer.exe dll/INetC.dll: mkdir -p dll rm -rf tmp mkdir tmp cd tmp ; wget http://nsis.sourceforge.net/mediawiki/images/c/c9/Inetc.zip cd tmp ; unzip Inetc.zip cd tmp ; mv Plugins/x86-ansi/INetC.dll ../dll rm -rf tmp dll/nsisunz.dll: mkdir -p dll rm -rf tmp mkdir tmp cd tmp ; wget http://nsis.sourceforge.net/mediawiki/images/1/1c/Nsisunz.zip cd tmp ; unzip Nsisunz.zip cd tmp ; mv nsisunz/Release/nsisunz.dll ../dll rm -rf tmp out.nsi: gen_installer_nsi.py if [ -z "${RELEASE}" ] ; then echo "Syntax: make RELEASE=x.y.z DOWNLOAD_URI=https://pouet" ; exit 1 ; fi echo Release: ${RELEASE} echo Download URI: ${DOWNLOAD_URI} python3 ./gen_installer_nsi.py ${RELEASE} ${DOWNLOAD_URI} paperwork_stable_installer.exe: dll/INetC.dll dll/nsisunz.dll rm -f out.nsi $(MAKE) out.nsi RELEASE=stable DOWNLOAD_URI=https://download.openpaper.work/windows/amd64/paperwork-master-latest.zip makensis ./out.nsi mv -f paperwork_installer.exe paperwork_stable_installer.exe paperwork_testing_installer.exe: dll/INetC.dll dll/nsisunz.dll rm -f out.nsi $(MAKE) out.nsi RELEASE=testing DOWNLOAD_URI=https://download.openpaper.work/windows/amd64/paperwork-testing-latest.zip makensis ./out.nsi mv -f paperwork_installer.exe paperwork_testing_installer.exe paperwork_develop_installer.exe: dll/INetC.dll dll/nsisunz.dll rm -f out.nsi $(MAKE) out.nsi RELEASE=develop DOWNLOAD_URI=https://download.openpaper.work/windows/amd64/paperwork-develop-latest.zip makensis ./out.nsi mv -f paperwork_installer.exe paperwork_develop_installer.exe clean: rm -rf dll rm -f out.nsi rm -f paperwork_installer.exe rm -f paperwork_stable_installer.exe rm -f paperwork_testing_installer.exe rm -f paperwork_develop_installer.exe upload: rclone --config ../ci/rclone.conf \ copyto \ paperwork_stable_installer.exe \ openpaperwork:openpaperwork-download/windows/installer/paperwork_stable_installer.exe rclone --config ../ci/rclone.conf \ copyto \ paperwork_testing_installer.exe \ openpaperwork:openpaperwork-download/windows/installer/paperwork_testing_installer.exe rclone --config ../ci/rclone.conf \ copyto \ paperwork_develop_installer.exe \ openpaperwork:openpaperwork-download/windows/installer/paperwork_develop_installer.exe .PHONY: all clean upload paperwork-2.2.2/nsis/data/000077500000000000000000000000001456262201400154165ustar00rootroot00000000000000paperwork-2.2.2/nsis/data/gpl-3.0.txt000066400000000000000000001045131456262201400172430ustar00rootroot00000000000000 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 . paperwork-2.2.2/nsis/data/licences.txt000066400000000000000000001076121456262201400177530ustar00rootroot00000000000000Paperwork is released under the licence GPL v3+. However, other components are used by Paperwork and must be installed. All of them are licensed under GPLv3+ or less restrictive licences. It's hard (if not impossible) to list them all, but here is a non-exhaustive list with their corresponding licences: - PyOCR : https://gitlab.gnome.org/World/OpenPaperwork/pyocr (GPL v3+) - Libinsane : https://gitlab.gnome.org/World/OpenPaperwork/libinsane (LGPL v3+) - Libpillowfight : https://gitlab.gnome.org/World/OpenPaperwork/libpillowfight (GPL v3+) - Python interpreter : https://python.org/ (PSF) - GTK+ : https://www.gtk.org/ (LGPL v2.1) - Poppler : https://poppler.freedesktop.org/ (GPL v2 / GPL v3) - Pillow : http://pillow.readthedocs.io/en/3.1.x/about.html (MIT-like) - Whoosh : https://pypi.python.org/pypi/Whoosh/ (Two-clause BSD) - Simplebayes : https://github.com/hickeroar/simplebayes (MIT) - Pycountry : https://pypi.python.org/pypi/pycountry/ (LGPL v2.1) Translated versions of the GPL v3 are available here: https://www.gnu.org/licenses/gpl-3.0.html https://www.gnu.org/licenses/quick-guide-gplv3.html PSF licence is available here: https://docs.python.org/3/license.html Translated versions of the LGPL v3 are available here: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html Translated versions of the GPL v2 are available here: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html A copy of the MIT licence is available here: https://opensource.org/licenses/MIT A copy of the two-clause BSD licence is available here: https://opensource.org/licenses/BSD-2-Clause ----- 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 . paperwork-2.2.2/nsis/data/paperwork_64.ico000066400000000000000000000410761456262201400204450ustar00rootroot00000000000000@@ (B(@€ @iiik@@@666!~~~w±±±Õûûûÿ———¢’’’­iiiÏGGG]]]UšššÏÏÏèÿÿÿÿÿÿÿÿÿÿÿÿìììùgggORRR5äääôÕÕÕÿ¡¡¡×aaa7 \\\V››››½½½Ûøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶¶¶Í žžž©ÿÿÿÿÿÿÿÿ¶¶¶ÿÖÖÖègggc+++0SSSS~~~q›››”¯¯¯ºÇÇÇéúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ„„„‡XXX:äääöÿÿÿÿÿÿÿÿðððÿŽŽŽÿ¾¾¾þÏÏÏúëëëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÚÚíXXX1eeeL™™™ÊªªªëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇÇÇÿÛÛÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸŸŸ·\\\E¢¢¢¬ìììùÿÿÿÿçççùŽŽŽÝéééýÿÿÿÿÿÿÿÿÿÿÿÿ×××ÿÁÁÁÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøþ}}}hEEE;‡‡‡}±±±Ãíííúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³³³â«««êÿÿÿÿÿÿÿÿÿÿÿÿðððÿ¶¶¶ÿùùùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÅÅÜ;;;111NNN™™™™§¤¤¤£©©©—¤¤¤Ÿ««««µµµÁÀÀÀáñññþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäää÷áïïïþÿÿÿÿÿÿÿÿþþþÿÃÃÃÿæææþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ“““œlll\¡¡¡»íííûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹¹¹å±±±îÿÿÿÿÿÿÿÿÿÿÿÿËËËÿÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèèè÷gggHhhhB®®® áááòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàààø‰‰‰âòòòÿÿÿÿÿÿÿÿÿåååÿ¾¾¾ÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°°°ÉDDD-‹‹‹•ÎÎÎèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ¯¯¯áµµµîÿÿÿÿÿÿÿÿ÷÷÷ÿ³³³ÿðððþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýÿƒƒƒ999‹‹‹„ÄÄÄÜþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿáááô‰‰‰àôôôÿÿÿÿÿÿÿÿÿÈÈÈÿÛÛÛýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÙÙêSSS+tttg¦¦¦È÷÷÷þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ¯¯¯â···ñÿÿÿÿÿÿÿÿÚÚÚÿÇÇÇýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ±iii\¢¢¢»íííúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÞÞôŒŒŒå÷÷÷ÿÿÿÿÿìììÿ¬¬¬ÿúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõývvvaYYY<žžžžÛÛÛñÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýÿªªªÞÀÀÀñÿÿÿÿþþþÿÅÅÅÿæææýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÆÆÚ===AAA+‹‹‹•ÌÌÌçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØØØðâúúúÿÿÿÿÿÊÊÊÿÉÉÉüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–;;;‹‹‹„»»»Üüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûÿ§§§ÞÃÃÃòÿÿÿÿåååÿ¶¶¶ýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãããöbbbFsssh§§§ÈöööþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÕÕ‰ãûûûÿ÷÷÷ÿ°°°þðððþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¨¨¨Ähhh[¬¬¬¸ìììúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÿ¨¨¨àÈÈÈõÿÿÿÿ¿¿¿ÿÕÕÕûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÿ~~~yVVV;žžžžÚÚÚðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÍÍðæýýýÿÙÙÙÿÁÁÁùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÔÔæNNN$CCC*‹‹‹•ËËËçÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷þÝÍÍÍöìììÿ©©©ùúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿœœœª@@@’’’wºººÖüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌÌÌìåüüüÿ¶¶¶ýæææûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñññûoooZqqqh¨¨¨Çöööþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöööþ¡¡¡ÜÐÐÐ÷ÌÌÌÿËËË÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¼¼¼Ö333rrrU´´´­ëëëøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÊÊìŽŽŽæßßßÿ¦¦¦ôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRRR>”””¢ÙÙÙðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõý¡¡¡ÞÓÓÓùªªªõóóóþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãããò___;DDD)•••‘ÎÎÎæÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÄÄÄ蟟Ÿæ±±±ú×××÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥¥¥¾ ~~~w±±±×üüüÿÿÿÿÿÿÿÿÿðððû–––Ý···û»»»ñÿÿÿÿÿÿÿÿÿÿÿÿûûûÿƒƒƒspppi©©©ÇõõõþÿÿÿÿÿÿÿÿÀÀÀç–––éïûûûÿÿÿÿÿÿÿÿÿÍÍÍåKKK"cccM¦¦¦«åååøÿÿÿÿïïïúß”””òçççúÿÿÿÿÿÿÿÿ˜˜˜¤QQQ<”””¢ÙÙÙðÿÿÿÿ¶¶¶é‚‚‚îÍÍÍïÿÿÿÿíííùcccUDDD)•••‘ÅÅÅæèèèù~~~椤¤íÿÿÿÿ¸¸¸Ð ~~~w±±±Õ­­­å{{{ìôôôý‰‰‰ˆoooj‹‹‹Ïwwwí···ëZZZ3ZZZRLLLÖPPPØ222g-ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÏÿàÿÿÿÿÿÇÿÿÿÿÿƒø?ÿÿÿÿ€?ÿÿÿÿÿÿÿþÿÿÿøÿÿÿ€ÿÿ€ÿÿÀÿÿøÿÿþÿÿÿ€ÿÿÿàÿÿÿøÿÿÿ?ÿÿÿÀ?ÿÿÿðÿÿÿüÿÿÿÿÿÿÿÿàÿÿÿÿøÿÿÿÿþÿÿÿÿÿ€ÿÿÿÿÿàÿÿÿÿÿüÿÿÿÿÿÿÿÿÿÿÿÀÿÿÿÿÿð?ÿÿÿÿÿü?ÿÿÿÿÿÿ€ÿÿÿÿÿÿàÿÿÿÿÿÿøÿÿÿÿÿÿþÿÿÿÿÿÿÿƒÿÿÿÿÿÿÿóÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿpaperwork-2.2.2/nsis/gen_installer_nsi.py000077500000000000000000000376141456262201400205740ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # TODO(Jflesch): PEP8 ... # flake8: noqa import pycountry import re import sys DEFAULT_DOWNLOAD_URI = ( "https://download.openpaper.work/windows/amd64/paperwork-master-latest.zip" ) ALL_LANGUAGES = [ "eng", # English (always first) "afr", "amh", "ara", "asm", "aze", {"lower": "aze_cyrl", "upper": "AZECYRL", "long": "Azerbaijani - Cyrilic"}, "bel", "ben", "bod", # Tibetan "bos", "bre", "bul", "cat", "ceb", "ces", # Czech {"lower": "chi_sim", "upper": "CHISIM", "long": "Chinese (simplified)"}, { "lower": "chi_sim_vert", "upper": "CHISIMVERT", "long": "Chinese (simplified, vertical)" }, {"lower": "chi_tra", "upper": "CHITRA", "long": "Chinese (traditional)"}, { "lower": "chi_tra_vert", "upper": "CHITRAVERT", "long": "Chinese (traditional, vertical)" }, "chr", "cos", "cym", # Welsh "dan", "deu", # German "div", "dzo", {"lower": "ell", "upper": "ELL", "long": "Greek (modern)"}, "enm", "epo", # Esperanto "est", "eus", # Basque "fao", {"lower": "fas", "upper": "FAS", "long": "Persian"}, "fil", "fin", "fra", # French "frk", # Frankish "frm", "fry", "gla", "gle", # Irish "glg", {"lower": "grc", "upper": "GRC", "long": "Greek (ancient)"}, "guj", "hat", "heb", "hin", "hrv", # Croatian "hun", "hye", "iku", # Inuktitut "ind", "isl", # Icelandic "ita", {"lower": "ita_old", "upper": "ITAOLD", "long": "Italian (old)"}, "jav", "jpn", # Japanese "kan", "kat", # Georgian "khm", "kir", "kor", "lao", "lat", "lav", "lit", "ltz", "mal", "mar", "mkd", # Macedonian "mlt", # Maltese "mon", "mri", "msa", # Malay "mya", # Burmese "nep", "nld", # Dutch "nor", "oci", "ori", "pan", "pol", "por", "pus", "que", {"lower": "ron", "upper": "RON", "long": "Romanian"}, "rus", "san", "sin", "slk", "slv", "spa", # Spanish "sqi", # Albanian "srp", # Serbian {"lower": "srp_latn", "upper": "SRPLATN", "long": "Serbian (Latin)"}, "swa", "swe", "syr", "tam", "tat", "tel", "tgk", # Tajik {"lower": "tha", "upper": "THA", "long": "Thai"}, "tir", "ton", "tur", "uig", "ukr", "urd", "uzb", {"lower": "uzb_cyrl", "upper": "UZBCYRL", "long": "Uzbek - Cyrilic"}, "vie", "yid", "yor", ] UNKNOWN_LANGUAGE = { 'download_section': """ Section /o "{long}" SEC_{upper} inetc::get "https://download.openpaper.work/tesseract/4.0.0/tessdata/{lower}.traineddata" "$INSTDIR\\Data\\Tessdata\\{lower}.traineddata" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download of {lower}.traineddata failed: $0" Quit SectionEnd """, 'lang_strings': """ LangString DESC_SEC_{upper} ${{LANG_ENGLISH}} "Data files required to run OCR on {long} documents" LangString DESC_SEC_{upper} ${{LANG_FRENCH}} "Data files required to run OCR on {long} documents" LangString DESC_SEC_{upper} ${{LANG_GERMAN}} "Data files required to run OCR on {long} documents" """, } KNOWN_LANGUAGES = { 'deu': { "download_section": """ Section /o "German / Deutsch" SEC_DEU inetc::get "https://download.openpaper.work/tesseract/4.0.0/tessdata/{lower}.traineddata" "$INSTDIR\\Data\\Tessdata\\{lower}.traineddata" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download of {lower}.traineddata failed: $0" Quit SectionEnd """, "lang_strings": """ LangString DESC_SEC_DEU ${{LANG_ENGLISH}} "Data files required to run OCR on German documents" LangString DESC_SEC_DEU ${{LANG_FRENCH}} "Fichiers requis pour la reconnaissance de caractères sur les documents en allemand" LangString DESC_SEC_DEU ${{LANG_GERMAN}} "Data files required to run OCR on German documents" ; TODO """, }, 'eng': { "download_section": """ Section "English / English" SEC_ENG SectionIn RO ; Mandatory section inetc::get "https://download.openpaper.work/tesseract/4.0.0/tessdata_eng_4_0_0.zip" "$PLUGINSDIR\\tess_eng.zip" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download of {lower}.traineddata failed: $0" Quit nsisunz::UnzipToLog "$PLUGINSDIR\\tess_eng.zip" "$INSTDIR\\Data\\Tessdata" SectionEnd """, "lang_strings": """ LangString DESC_SEC_ENG ${{LANG_ENGLISH}} "Data files required to run OCR on English documents" LangString DESC_SEC_ENG ${{LANG_FRENCH}} "Fichiers requis pour la reconnaissance de caractères sur les documents en anglais" LangString DESC_SEC_ENG ${{LANG_GERMAN}} "Data files required to run OCR on English documents" ; TODO """, }, 'fra': { "download_section": """ Section /o "French / Français" SEC_FRA inetc::get "https://download.openpaper.work/tesseract/4.0.0/tessdata/{lower}.traineddata" "$INSTDIR\\Data\\Tessdata\\{lower}.traineddata" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download of {lower}.traineddata failed: $0" Quit SectionEnd """, "lang_strings": """ LangString DESC_SEC_FRA ${{LANG_ENGLISH}} "Data files required to run OCR on French documents" LangString DESC_SEC_FRA ${{LANG_FRENCH}} "Fichiers requis pour la reconnaissance de caractères sur les documents en français" LangString DESC_SEC_FRA ${{LANG_GERMAN}} "Data files required to run OCR on French documents" ; TODO """, }, } VERSION = """ !define PRODUCT_VERSION "{version}" !define PRODUCT_SHORT_VERSION "{short_version}" !define PRODUCT_DOWNLOAD_URI "{download_uri}" """ HEADER = """ !define PRODUCT_NAME "Paperwork" !define PRODUCT_PUBLISHER "Openpaper.work" !define PRODUCT_WEB_SITE "https://openpaper.work" !define PRODUCT_UNINST_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" !include x64.nsh !addplugindir ".\dll" ; MUI 1.67 compatible ------ !include "MUI.nsh" !include "Sections.nsh" !include "LogicLib.nsh" ; MUI Settings !define MUI_ABORTWARNING !define MUI_ICON "data\\paperwork_64.ico" !define MUI_UNICON "data\\paperwork_64.ico" ; Language Selection Dialog Settings !define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}" !define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}" !define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language" ; Welcome page !insertmacro MUI_PAGE_WELCOME ; License page !insertmacro MUI_PAGE_LICENSE "data\\licences.txt" ; Components page !insertmacro MUI_PAGE_COMPONENTS ; Directory page !insertmacro MUI_PAGE_DIRECTORY ; Instfiles page !insertmacro MUI_PAGE_INSTFILES ; Finish page !define MUI_FINISHPAGE_RUN "$INSTDIR\\paperwork.exe" !insertmacro MUI_PAGE_FINISH ; Uninstaller pages !insertmacro MUI_UNPAGE_INSTFILES ; Language files !insertmacro MUI_LANGUAGE "English" !insertmacro MUI_LANGUAGE "French" !insertmacro MUI_LANGUAGE "German" ; MUI end ------ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "paperwork_installer.exe" InstallDir "$PROGRAMFILES64\\Paperwork" ShowInstDetails hide ShowUnInstDetails hide BrandingText "OpenPaper.work" Section "Paperwork" SEC_PAPERWORK SectionIn RO ; Mandatory section SetOutPath "$INSTDIR" SetOverwrite on inetc::get "${PRODUCT_DOWNLOAD_URI}" "$PLUGINSDIR\\paperwork.zip" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download of ${PRODUCT_DOWNLOAD_URI} failed: $0" Quit inetc::get "https://download.openpaper.work/tesseract/4.0.0/tesseract_4_0_0.zip" "$PLUGINSDIR\\tesseract.zip" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download failed: $0" Quit inetc::get "https://download.openpaper.work/tesseract/4.0.0/tessconfig_4_0_0.zip" "$PLUGINSDIR\\tessconfig.zip" /END Pop $0 StrCmp $0 "OK" +3 MessageBox MB_OK "Download failed: $0" Quit CreateDirectory "$INSTDIR" nsisunz::UnzipToLog "$PLUGINSDIR\\paperwork.zip" "$INSTDIR" ; CreateShortCut "$DESKTOP.lnk" "$INSTDIR\\paperwork.exe" ; CreateShortCut "$STARTMENU.lnk" "$INSTDIR\\paperwork.exe" SetOutPath "$INSTDIR\\Tesseract" CreateDirectory "$INSTDIR\\Tesseract" nsisunz::UnzipToLog "$PLUGINSDIR\\tesseract.zip" "$INSTDIR" SetOutPath "$INSTDIR\\Data\\Tessdata" CreateDirectory "$INSTDIR\\Data\\Tessdata" nsisunz::UnzipToLog "$PLUGINSDIR\\tessconfig.zip" "$INSTDIR\\Data\\Tessdata" SectionEnd Section "Desktop icon" SEC_DESKTOP_ICON CreateShortCut "$DESKTOP\\Paperwork.lnk" "$INSTDIR\\paperwork.exe" "" "$INSTDIR\\Data\\paperwork_64.ico" 0 SW_SHOWNORMAL "" "Paperwork" SectionEnd """ MIDDLE = """ !macro SecSelect SecId Push $0 SectionSetFlags ${SecId} ${SF_SELECTED} SectionSetInstTypes ${SecId} 1 Pop $0 !macroend !define SelectSection '!insertmacro SecSelect' Function .onInit InitPluginsDir !insertmacro MUI_LANGDLL_DISPLAY StrCmp $LANGUAGE ${LANG_FRENCH} french maybegerman french: ${SelectSection} ${SEC_FRA} Goto end maybegerman: StrCmp $LANGUAGE ${LANG_GERMAN} german end german: ${SelectSection} ${SEC_DEU} end: FunctionEnd Section -AdditionalIcons SetOutPath $INSTDIR WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}" CreateDirectory "$SMPROGRAMS\\Paperwork" CreateShortCut "$SMPROGRAMS\\Paperwork\\Paperwork.lnk" "$INSTDIR\\paperwork.exe" "" "$INSTDIR\\Data\\paperwork_64.ico" 0 SW_SHOWNORMAL "" "Paperwork" CreateShortCut "$SMPROGRAMS\\Paperwork\\Website.lnk" "$INSTDIR\\${PRODUCT_NAME}.url" CreateShortCut "$SMPROGRAMS\\Paperwork\\Uninstall.lnk" "$INSTDIR\\uninst.exe" SectionEnd Section -Post WriteUninstaller "$INSTDIR\\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\\uninst.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "Publisher" "${PRODUCT_PUBLISHER}" SectionEnd LangString DESC_SEC_PAPERWORK ${LANG_ENGLISH} "Paperwork and all the required libriaires (Tesseract, GTK, etc)" LangString DESC_SEC_PAPERWORK ${LANG_FRENCH} "Paperwork et toutes les librairies requises (Tesseract, GTK, etc)" LangString DESC_SEC_PAPERWORK ${LANG_GERMAN} "Paperwork and all the required libriaires (Tesseract, GTK, etc)" ; TODO LangString DESC_SEC_OCR_FILES ${LANG_ENGLISH} "Data files required to run OCR" LangString DESC_SEC_OCR_FILES ${LANG_FRENCH} "Fichiers de données nécessaires pour la reconnaissance de caractères" LangString DESC_SEC_OCR_FILES ${LANG_GERMAN} "Data files required to run OCR" ; TODO """ FOOTER = """ LangString DESC_SEC_DESKTOP_ICON ${LANG_ENGLISH} "Icon on the desktop to launch Paperwork" LangString DESC_SEC_DESKTOP_ICON ${LANG_FRENCH} "Icône sur le bureau pour lancer Paperwork" LangString DESC_SEC_DESKTOP_ICON ${LANG_GERMAN} "Icon on the desktop to launch Paperwork" ; TODO Function un.onUninstSuccess HideWindow MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) has been deleted successfully" FunctionEnd Function un.onInit !insertmacro MUI_UNGETLANGUAGE MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to uninstall $(^Name) ? (your documents won't be deleted)" IDYES +2 Abort FunctionEnd Section Uninstall Delete "$SMPROGRAMS\\Paperwork\\Paperwork.lnk" Delete "$SMPROGRAMS\\Paperwork\\Uninstall.lnk" Delete "$SMPROGRAMS\\Paperwork\\Website.lnk" Delete "$DESKTOP\\Paperwork.lnk" ; Delete "$STARTMENU.lnk" ; Delete "$DESKTOP.lnk" RMDir /r "$INSTDIR\\data" RMDir /r "$INSTDIR\\etc" RMDir /r "$INSTDIR\\gi_typelibs" RMDir /r "$INSTDIR\\include" RMDir /r "$INSTDIR\\lib2to3" RMDir /r "$INSTDIR\\pycountry" RMDir /r "$INSTDIR\\share" RMDir /r "$INSTDIR\\tcl" RMDir /r "$INSTDIR\\tesseract" RMDir /r "$INSTDIR\\tk" RMDir /r "$INSTDIR\\*.*" Delete "$INSTDIR\\*.*" RMDir "$INSTDIR" RMDir "$SMPROGRAMS\\Paperwork" RMDir "" SetRegView 64 DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" SetAutoClose true SectionEnd """ def find_language(lang_str): lang_str = lang_str.lower() if "_" in lang_str: lang_str = lang_str.split("_")[0] print("System language: {}".format(lang_str)) attrs = ( 'iso_639_3_code', 'iso639_3_code', 'iso639_2T_code', 'iso639_1_code', 'terminology', 'bibliographic', 'alpha_3', 'alpha_2', 'alpha2', 'name', ) for attr in attrs: try: r = pycountry.pycountry.languages.get(**{attr: lang_str}) if r is not None: return r except (KeyError, UnicodeDecodeError): pass raise Exception("Unable to find language !") def get_lang_infos(lang_name): if isinstance(lang_name, dict): return lang_name lang = lang_name.split("_") lang_name = lang[0] suffix = "" if len(lang) <= 1 else lang[1] lang = find_language(lang_name) if not suffix: long_name = lang.name else: long_name = "{} ({})".format(lang.name, suffix) return { "lower": lang_name.lower() + suffix.lower(), "upper": lang_name.upper() + suffix.upper(), "long": long_name, } def main(args): if (len(args) < 2): print ("ARGS: {} []".format(args[0])) return download_uri = DEFAULT_DOWNLOAD_URI if len(args) == 3: version = short_version = args[1] download_uri = args[2] else: version = args[1] m = re.match(r"([\d\.]+)", version) # match everything but the suffix short_version = m.string[m.start():m.end()] download_uri = DEFAULT_DOWNLOAD_URI with open("out.nsi", "w") as out_fd: out_fd.write(VERSION.format(version=version, short_version=short_version, download_uri=download_uri)) out_fd.write(HEADER) out_fd.write(""" SectionGroup /e "Tesseract OCR data files" SEC_OCR_FILES """) langs = {} for lang_name in ALL_LANGUAGES: print ("Adding download section {}".format(lang_name)) lang = UNKNOWN_LANGUAGE if isinstance(lang_name, str) and lang_name in KNOWN_LANGUAGES: lang = KNOWN_LANGUAGES[lang_name] txt = lang['download_section'] infos = get_lang_infos(lang_name) txt = txt.format(**infos) langs[infos['long']] = txt lang_sorted = sorted(langs.keys()) for lang_name in lang_sorted: out_fd.write(langs[lang_name]) out_fd.write(""" SectionGroupEnd """) out_fd.write(MIDDLE) for lang_name in ALL_LANGUAGES: print ("Adding strings section {}".format(lang_name)) lang = UNKNOWN_LANGUAGE if isinstance(lang_name, str) and lang_name in KNOWN_LANGUAGES: lang = KNOWN_LANGUAGES[lang_name] txt = lang['lang_strings'] txt = txt.format(**get_lang_infos(lang_name)) out_fd.write(txt) out_fd.write(""" !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN !insertmacro MUI_DESCRIPTION_TEXT ${SEC_PAPERWORK} $(DESC_SEC_PAPERWORK) """) for lang_name in ALL_LANGUAGES: print ("Adding MUI section {}".format(lang_name)) infos = get_lang_infos(lang_name) txt = " !insertmacro MUI_DESCRIPTION_TEXT ${{SEC_{upper}}} $(DESC_SEC_{upper})\n".format(upper=infos['upper']) out_fd.write(txt) out_fd.write(""" !insertmacro MUI_DESCRIPTION_TEXT ${SEC_DESKTOP_ICON} $(DESC_SEC_DESKTOP_ICON) !insertmacro MUI_FUNCTION_DESCRIPTION_END """) out_fd.write(FOOTER) print ("out.nsi written") if __name__ == "__main__": main(sys.argv) paperwork-2.2.2/openpaperwork-core/000077500000000000000000000000001456262201400173535ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/.flake8000066400000000000000000000001141456262201400205220ustar00rootroot00000000000000[flake8] exclude = src/openpaperwork_core/_version.py max-line-length = 100 paperwork-2.2.2/openpaperwork-core/ChangeLog000066400000000000000000000050211456262201400211230ustar00rootroot000000000000002023/02/13 - 2.2.2: - No changes 2023/09/17 - 2.2.1: - Add build-system.build-backend to pyproject.toml 2023/09/16 - 2.2.0: - setup.py has been replaced by pyproject.toml - fix various depreciation warnings - beacon: if openpaper.work is unreachable, catch the exception to not bother the user uselessly - pillow.img: make sure Pillow optimize the PNG files as much as possible - pillow.img: pillow_to_url(): If unspecified, guess the expected file format based on the output file name instead of assuming JPEG. - config: do not crash on empty values (shouldn't happen unless the configuration file has been manually edited) - FS: Fix use of URLs like `davs://` or `dav://` - Take into account that `openpaper.work` has become `www.openpaper.work` (there is a HTTP 301 not taken into account correctly) 2023/01/08 - 2.1.2: - Fine-tune sqlite settings - Fix: TIFF images can have the file extension ".tiff" but ".tif" too - Fix: Report *all* uncaught exceptions 2022/01/31 - 2.1.1: - Fix tests of plugins cmd.config and cmd.plugins - thread.pool: Fix: take into account that the main loop can started and stopped many times in a Paperwork instance lifetime (broke some paperwork-shell commands in some cases) 2021/12/05 - 2.1.0: - Bug report censoring: Take into account that some strings in the logs may be URL-encoded - Version data files: If the version changes, rebuild them all - Handle gracefully copies from fake in-memory files (memory://) to non-fake files (thanks to Benjamin Li) - If unable to load or init a plugin, don't hide the problem anymore ; instead clearly fail 2021/05/24 - 2.0.3: - Add LICENSE file in pypi package 2021/01/01 - 2.0.2: - Commands "config": When parsing boolean value, accepts "false" and "0" as input for False - bug_report censoring: Do not censor text files that have already been censored (avoid renaming the file again and making the file name even longer) 2020/11/15 - 2.0.1: - Bug report censoring: Take into account that some strings in the logs may be URL-encoded and censor them too (for instance, path to the user home directory) - fault handler: Prefer dumping the output of faulthandler in the log file instead of stderr (can't do both inforunately) - Logs archive + bug report: by default, report the logs of the last 2 previous sessions too - fs.python: Text files must be encoded in UTF-8 - Windows packaging: Fix HTTPS support: Use the certifi module to provide root certificates - Include tests in Pypi package (thanks to Elliott Sales de Andrade) 2020/10/17 - 2.0: - Initial release paperwork-2.2.2/openpaperwork-core/LICENSE000066400000000000000000001045051456262201400203650ustar00rootroot00000000000000 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. {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year} {name of author} 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: {project} Copyright (C) {year} {fullname} 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 . paperwork-2.2.2/openpaperwork-core/MANIFEST.in000066400000000000000000000001271456262201400211110ustar00rootroot00000000000000recursive-include src *.py *.mo recursive-include tests * include *.md include LICENSE paperwork-2.2.2/openpaperwork-core/Makefile000066400000000000000000000045221456262201400210160ustar00rootroot00000000000000PYTHON ?= python3 PIP_DEPS ?= build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: l10n_compile ${PYTHON} ./setup.py build build_c: doc: install_py $(MAKE) -C doc html doc/_build/html/index.html: doc upload_doc: doc/_build/html/index.html cd .. && ./ci/deliver_doc.sh ${CURDIR}/doc/_build/html openpaperwork_core data: check: if ! hash flake8 ; then PIP_DEPS=[lint] $(MAKE) install_py ; fi flake8 --append-config $(CURDIR)/.flake8 $(CURDIR)/src/openpaperwork_core test: if ! hash pytest ; then PIP_DEPS=[dev] $(MAKE) install_py ; fi python3 -m pytest -xv tests/ linux_exe: windows_exe: install # ugly, but "import pkg_resources" doesn't work in frozen environments # and I don't want to have to patch the build machine to fix it every # time. mkdir -p $(CURDIR)/../build/exe/data (cd $(CURDIR)/src && find . -name '*.mo' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) release: ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" exit 1 else @echo "Will release: ${RELEASE}" @echo "Checking release is in ChangeLog ..." grep ${RELEASE} ChangeLog | grep -v "/xx" endif release_pypi: @echo "Releasing openpaperwork-core ..." rm -rf /tmp/venv virtualenv /tmp/venv . /tmp/venv/bin/activate && pip install build . /tmp/venv/bin/activate && ${PYTHON} -m build -s rm -rf /tmp/venv twine upload $(CURDIR)/dist/*.tar.gz @echo "All done" clean: rm -rf doc/_build rm -rf build dist *.egg-info rm -f src/openpaperwork_core/_version.py # PIP_ARGS is used by Flatpak build install_py: l10n_compile cd $(CURDIR) && ${PYTHON} -m pip install ${PIP_ARGS} .$(PIP_DEPS) install_c: uninstall_py: pip3 uninstall -y openpaperwork-core uninstall_c: l10n_extract: $(CURDIR)/../tools/l10n_extract.sh "$(CURDIR)/src" "$(CURDIR)/l10n" l10n_compile: $(CURDIR)/../tools/l10n_compile.sh \ "$(CURDIR)/l10n" \ "$(CURDIR)/src/openpaperwork_core/l10n" \ "openpaperwork_core" help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ l10n_extract \ l10n_compile \ release \ test \ uninstall \ uninstall_c paperwork-2.2.2/openpaperwork-core/README.md000066400000000000000000000003661456262201400206370ustar00rootroot00000000000000# OpenPaperwork Core The core manages Plugins, Callbacks and Interfaces. This package also provide some basic plugins that may be used in any kind of application. [Documentation](https://doc.openpaper.work/openpaperwork_core/latest/index.html) paperwork-2.2.2/openpaperwork-core/doc/000077500000000000000000000000001456262201400201205ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/doc/Makefile000066400000000000000000000011111456262201400215520ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = python3 -msphinx SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) paperwork-2.2.2/openpaperwork-core/doc/conf.py000066400000000000000000000130401456262201400214150ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = 'Openpaperwork-core' copyright = '2019, Jerome Flesch' author = 'Jerome Flesch' # The short X.Y version version = '' # The full version, including alpha/beta/rc tags release = '' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinxcontrib.plantuml', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = None # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'Openpaperwork-coredoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'Openpaperwork-core.tex', 'Openpaperwork-core Documentation', 'Jerome Flesch', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'openpaperwork-core', 'Openpaperwork-core Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'Openpaperwork-core', 'Openpaperwork-core Documentation', author, 'Openpaperwork-core', 'One line description of project.', 'Miscellaneous'), ] # -- Options for Epub output ------------------------------------------------- # Bibliographic Dublin Core info. epub_title = project # The unique identifier of the text. This can be a ISBN number # or the project homepage. # # epub_identifier = '' # A unique identification for the text. # # epub_uid = '' # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True autodoc_inherit_docstrings = False paperwork-2.2.2/openpaperwork-core/doc/config.rst000066400000000000000000000022231456262201400221160ustar00rootroot00000000000000Configuration plugin ==================== Configuration management plugins provide a way to store an application configuration. Openpaperwork_core provides the plugin `openpaperwork_core.config` that acts a frontend for backend plugins (`openpaperowkr_core.config.backend.*`). It provides some high level operations (like registering options and their default value). Other plugins and applications should use this frontend only. When initialized, plugins are expected to register any setting they need. Only the plugin responsible for a setting register it ; Plugins depending on settings registered by one of their dependency do not need to register them. Backends provide access to the configuration storage (Python's ConfigParser, Windows registry, Android Content Provider, etc). Reference implementation for backends is `openpaperwork_core.config.backend.configparser` (based on Python's ConfigParser). ---- Frontend plugin ~~~~~~~~~~~~~~~ .. automodule:: openpaperwork_core.config :members: :undoc-members: ---- Backend plugin: File ~~~~~~~~~~~~~~~~~~~~ .. automodule:: openpaperwork_core.config.backend.configparser :members: :undoc-members: paperwork-2.2.2/openpaperwork-core/doc/core.rst000066400000000000000000000034701456262201400216060ustar00rootroot00000000000000Core & Plugins ============== Basic concepts -------------- The idea behind OpenPaperwork's plugins is similar to `Python duck typing `_: When you request something, it does not matter who does the job as long as it's done. To that end, when the calling code wants something done, it uses the core. It gives it a callback name and some arguments. It does not know which plugin will handle this call (nor if one will) and it doesn't matter to them as long as the job is done. Many plugins can provide the same callback names but with different implementations. Calling code can: * call all the callbacks with a given name one after the other: :py:meth:`~openpaperwork_core.Core.call_all`, * call them until one of them reply with a value != `None`: :py:meth:`~openpaperwork_core.Core.call_success`, * or call just one of them semi-randomly: :py:meth:`~openpaperwork_core.Core.call_one`. A plugin is a Python module containing a class named `Plugin` (subclassing :py:class:`~openpaperwork_core.PluginBase`). This class must be instantiable without arguments. Callbacks are all the methods provided by this class `Plugin` (with some exceptions, like methods starting with `_` and those coming from :py:class:`~openpaperwork_core.PluginBase`). Each plugin can implement many interfaces. Those interfaces are used to define dependencies and are simply conventions: Plugins pretending to implement some interfaces should implement the corresponding methods but no check is done to ensure they do. Examples -------- .. toctree:: example_plugin example_app API --- You're strongly advised to read the documentation of :py:meth:`~openpaperwork_core.Core.call_all`, :py:meth:`~openpaperwork_core.Core.call_success`, :py:meth:`~openpaperwork_core.Core.call_one`. .. toctree:: core_api paperwork-2.2.2/openpaperwork-core/doc/core_api.rst000066400000000000000000000001261456262201400224320ustar00rootroot00000000000000Core API ======== .. automodule:: openpaperwork_core :members: :undoc-members: paperwork-2.2.2/openpaperwork-core/doc/example_app.rst000066400000000000000000000016321456262201400231470ustar00rootroot00000000000000Calling Code Example ==================== .. code-block:: python import openpaperwork_core core = openpaperwork_core.Core() # Load mandatory plugins core.load("openpaperwork_plugin_a") core.load("mandatory_plugin_a") core.load("mandatory_plugin_b") # `init()` will load dependencies and call method `init()` on all the plugins # You can safely call `core.init()` many times core.init() # Load plugins requested by your user if any. # You can used previously loaded to get the plugin to load if you want. # For instance, you can load and initialize `openpaperwork_core.config` # and then use it to get a plugin list from a configuration file. core.load(...) core.init() nb_called = core.call_all('some_method_a', "random_argument") assert(nb_called > 0) return_value = core.call_success('some_method_a', "random_argument") assert(return_value is not None) paperwork-2.2.2/openpaperwork-core/doc/example_plugin.rst000066400000000000000000000043721456262201400236710ustar00rootroot00000000000000Plugin Example ============== .. code-block:: python import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): # callbacks will always be run before those of priority <= 21 # but after those of priority >= 23 PRIORITY = 22 def __init__(self): # do something, but the least possible # cannot rely on any dependencies here. pass def get_interfaces(self): # indicates which interfaces this plugin satisfies. # note that this is only used for controlling that dependencies are # satisfied (see get_deps()). There are no checks at all to ensure # that the methods corresponding to each interface are actually # implemented. return ['interface_name_toto', 'interface_name_tutu'] def get_deps(self): # specify that we are looking for plugins implementing the # specified interface(s). # Provide also some default plugins to load if no plugins provide # the requested interface yet. # Note that plugins may be loaded in any order. Dependencies may # not be satisfied yet when they are loaded. # When initializing plugins, the core will make sure that # all dependencies are satisfied, loaded and initialized before # calling the method `init()` of this plugin. return [ { 'interface': 'interface_name_a', 'defaults': [ 'suggested_default_plugin_a', 'suggested_default_plugin_b', ], }, { 'interface': 'inteface_name_b', 'defaults': [ 'suggested_default_plugin_d', 'suggested_default_plugin_e', ], } ] def init(self, core): # all the dependencies have loaded and initialized. # we can safely rely on them here. super().init(core) def some_method_a(self, arg_a): # do something self.core.call_all("some_method_of_other_plugins", "arg_a", 22) paperwork-2.2.2/openpaperwork-core/doc/fs.rst000066400000000000000000000014651456262201400212700ustar00rootroot00000000000000File system plugins =================== Those plugins provide methods to access files on various storages. For instance, 'python' plugin uses the python API to access local files (`file://`), so does the GIO implementation (openpaperwork-gtk). Memory plugin allow storing data in filesystem-like manner (`memory://`). Later other plugins could provide access to other storages (MariaDB, HTTP, etc). The reference implementation is 'python'. A fake/mock implementation is provided for testing. It behaves in a way similar to the memory plugin. ---- Python-based implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. automodule:: openpaperwork_gtk.fs.python :members: :undoc-members: ---- In-Memory implementation ~~~~~~~~~~~~~~~~~~~~~~~~ .. automodule:: openpaperwork_core.fs.memory :members: :undoc-members: paperwork-2.2.2/openpaperwork-core/doc/index.rst000066400000000000000000000006271456262201400217660ustar00rootroot00000000000000.. Openpaperwork-core documentation master file, created by sphinx-quickstart on Thu Nov 21 12:27:52 2019. Welcome to Openpaperwork-core's documentation! ============================================== .. toctree:: :maxdepth: 3 :caption: Contents: core config logs fs mainloop promise Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` paperwork-2.2.2/openpaperwork-core/doc/logs.rst000066400000000000000000000016601456262201400216210ustar00rootroot00000000000000Log management plugins ====================== Log management plugins catch Python logs (see `logging`), format them and send them somewhere. `uncaught_exception` --------------------- Broadcast uncaught exceptions (see `sys.excepthook`) by calling `self.core.call_all("on_uncaught_exception", exc_info)`. `logs.print` ------------ Send the logs to stderr, stdout or a file. It can send to many outputs at the same time. Configuration entries are as follow: .. code-block:: ini [logging] level = str:info # none, critical, error, warn, warning, info, debug files = str:stderr,temp,/tmp/test.txt # 'stderr', 'temp', or a file path format = str:[%(levelname)-6s] [%(name)-30s] %(message)s It monitors the configuration. So to change its settings, you can just update the configuration using the plugin `openpaperwork_core.config`. ---- .. automodule:: openpaperwork_core.log_collector :members: :undoc-members: paperwork-2.2.2/openpaperwork-core/doc/mainloop.rst000066400000000000000000000015221456262201400224700ustar00rootroot00000000000000Mainloop plugins ================ Most GUI applications need a main loop. A main loop is a thread dedicated to running callbacks provided by other threads (or stacked before the main loop is started). Depending on the environment in which you're working, you may need different mainloop implementations. For instance, Python 3 provide main loop support through `asyncio`. If you're working in a GTK environment, you will have to use the GLib mainloop instead. Openpaperwork_core provides an implementation that uses Python 3's `asyncio` module. More advanced main loops may provide features such as waiting for an event to occur on a file descriptor. The main loop interface provided here is kept simple so it can easily be implemented for any other platforms. .. automodule:: openpaperwork_core.mainloop_asyncio :members: :undoc-members: paperwork-2.2.2/openpaperwork-core/doc/promise.rst000066400000000000000000000001361456262201400223300ustar00rootroot00000000000000Promises ======== .. automodule:: openpaperwork_core.promise :members: :undoc-members: paperwork-2.2.2/openpaperwork-core/examples/000077500000000000000000000000001456262201400211715ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/examples/core_plugins.py000077500000000000000000000010231456262201400242330ustar00rootroot00000000000000#!/usr/bin/env python3 import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) def main(): LOGGER.info("Start") core = openpaperwork_core.Core() core.load("openpaperwork_core.logs.print") core.load("openpaperwork_core.uncaught_exception") core.load('openpaperwork_core.config') core.load('openpaperwork_core.config.backend.configparser') core.init() core.init_logs("some_app_name", default_log_level="info") LOGGER.info("End") if __name__ == "__main__": main() paperwork-2.2.2/openpaperwork-core/l10n/000077500000000000000000000000001456262201400201255ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/l10n/ca.po000066400000000000000000000176411456262201400210610ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-30 11:53+0100\n" "PO-Revision-Date: 2022-04-02 09:11+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "Avui" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "Ahir" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "%3.1f bytes" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "%3.1f KiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "%3.1f GiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "%3.1f tiB" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "Comproveu que totes les dependències estiguin instal·lades" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "Falten aquestes dependències:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "- {dep_name} (paquet: {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "Desconegut" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "Comanda suggerida:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "Voleu executar aquesta comanda?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "Ni idea de com instal·lar les dependències que falten. Ho sento." #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "no queda res per fer." #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:58 msgid "Manage Paperwork configuration" msgstr "Configura Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:62 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 msgid "sub-command" msgstr "sub-commanda" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:66 msgid "Get a value from Paperwork's configuration" msgstr "Obté un valor de la configuració del Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:71 msgid "Set a value in Paperwork's configuration" msgstr "Estableix un valor a la configuració del Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:74 msgid "See 'config list_type'" msgstr "Veure 'config list_type'" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Show Paperwork's configuration" msgstr "Mostra la configuració del Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:83 msgid "Show value types you can use from command line" msgstr "Mostra les variables possibles per a la línia de comandes" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "Gestiona els complements de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "Mostra els complements activats de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "Afegeix un complement al %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "No corregeixis automàticament les dependències" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "Elimina el complement de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "" "Neteja el guirigall que heu creat restablint els valors inicials de la " "llista de complements" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "Mostra la informació d'un complement (ha d'estar activat)" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "Error: No s'ha trobat el complement %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" "Afegint el complement «{plugin_name}» per satisfer la depèndencia de " "«{other_plugin_name}» a la interfície «{interface}»" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "Complement {} afegit" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" "Eliminant el complement «{plugin_name}» perquè falten les dependències " "«{interface}»" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "Complement {} eliminat" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "Complements activats:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "El complement \"%s\"no està activat." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "Complement \"%s\":" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "Implementa:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "Depèn de:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "recomanat: %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "Nom del complement" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "Interfície" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "S/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "s/N" #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "Fitxer de registre" #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:333 msgid "App. config." msgstr "Conf. de l'App" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "Info. del Sistema & l'App" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "Selecciona per generar" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "Recollint les estadístiques…" paperwork-2.2.2/openpaperwork-core/l10n/de.po000066400000000000000000000176461456262201400210730ustar00rootroot00000000000000# German translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2021-10-25 05:49+0000\n" "Last-Translator: Andreas Forster \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "App. & System info." #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "Wähle zum Erzeugen" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "Sammle Statistiken ..." #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:363 msgid "App. config." msgstr "App. Konfiguration." #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "Logdatei" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "Heute" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "Gestern" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "%3.1f Bytes" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "%3.1f KiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "%3.1f GiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "%3.1f TiB" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "Y/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "y/N" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "Überprüfe, dass alle benötigten Abhängigkeiten installiert sind" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "Fehlende Abhängigkeiten:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "-{dep_name} (Paket: {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "Unbekannt" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "Vorgeschlagener Befehl:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "Möchtest du dieses Kommando jetzt ausführen?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "" "Die Installationsroutine für unbekannte Abhängigkeiten konnte nicht erkannt " "werden." #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "Es gibt nichts zu tun." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "Verwalte Erweiterungen für %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:69 msgid "sub-command" msgstr "Unterkommando" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "Zeige alle aktivierten Erweiterungen für %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "Aktiviere Erweiterung für %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "Korrigiere Abhängigkeiten nicht automatisch" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "Deaktiviere Erweiterung für %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "Setze die Liste an Erweiterungen zurück" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "Zeige Informationen über eine aktivierte Erweiterung" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "Fehler: Plugin '%s' nicht gefunden" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" "Füge Plugin '{plugin_name}' hinzu, um die Abhängigeit von " "'{other_plugin_name}' am Interface '{interface}' zu erfüllen" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "Plugin {} hinzugefügt" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" "Entferne das Plugin '{plugin_name}' wegen der fehlenden Abhängigkeit " "'{interface}'" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "Plugin {} entfernt" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "Aktive Erweiterungen:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "Plugin '%s' nicht aktiviert." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "Plugin '%s':" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "Implementiert:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "Hängt ab von:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "vorgeschlagen: %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "Plugin Name" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "Schnittstelle" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:65 msgid "Manage Paperwork configuration" msgstr "Verwalte die Konfiguration von Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:73 msgid "Get a value from Paperwork's configuration" msgstr "Gebe einen spezifischen Eintrag der Konfiguration aus" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Set a value in Paperwork's configuration" msgstr "Setze einen spezifischen Eintrag der Konfiguration" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:81 msgid "See 'config list_type'" msgstr "Siehe 'config list_type'" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:85 msgid "Show Paperwork's configuration" msgstr "Gebe die Konfiguration von Paperwork aus" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:90 msgid "Show value types you can use from command line" msgstr "" "Zeige die möglichen Werte, die über die Kommandozeile verwendet werden können" paperwork-2.2.2/openpaperwork-core/l10n/es.po000066400000000000000000000200331456262201400210720ustar00rootroot00000000000000# Spanish translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2022-03-19 11:45+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "Info de la Ap & del sistema." #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "Selecciona para generar" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "Reuniendo estadísticas..." #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:363 msgid "App. config." msgstr "Config. de la Ap." #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "Registro de datos" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "Hoy" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "Ayer" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "%3.1f bytes" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "%3.1f KiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "%3.1f GiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "%3.1f TiB" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "S/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "s/N" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "Compruebe que todas las dependencias necesarias están instaladas" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "Faltan estas dependencias:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "- {dep_name} (paquete: {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "Desconocido" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "Comando de terminal sugerido:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "¿Quiere ejecutar el comando de terminal ahora?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "No se pueden instalar las dependencias necesarias. Lo sientimos." #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "No queda nada por hacer." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "Gestiona los complementos de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:69 msgid "sub-command" msgstr "sub-comando" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "Muestra los complementos activados de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "Añade complementos a %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "No corregir automáticamente las dependencias" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "Elimina el complemento de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "" "Limpia este follón que has creado restableciendo la lista de complementos " "que viene por defecto" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "Muestra información de los complementos (debe estar activado)" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "Error: No se ha encontrado el complemento \"%s\"" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" "Añadiendo el complemento \"{plugin_name}\" para satisface la dependencia de " "\"{other_plugin_name}\" en la interfaz \"{interface}\"" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "Complemento {} añadido" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" "Eliminando el complemento \"{plugin_name}\" por la falta de dependencia con " "\"{interface}\"" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "Complemento {} eliminado" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "Comlementos activos:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "El complemento \"%s\" no está activado." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "Complemento \"%s\":" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "Implementa:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "Depende de:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "recomendado: %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "Nombre del complemento" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "Interfaz" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:65 msgid "Manage Paperwork configuration" msgstr "Gestionar la configuración de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:73 msgid "Get a value from Paperwork's configuration" msgstr "Obtener un valor de la configuración de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Set a value in Paperwork's configuration" msgstr "Establece un valor en la configuración de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:81 msgid "See 'config list_type'" msgstr "Ver \"config list_type\"" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:85 msgid "Show Paperwork's configuration" msgstr "Muestra la configuración de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:90 msgid "Show value types you can use from command line" msgstr "" "Muestra los posibles valores que se pueden utilizar en la línea de comandos" paperwork-2.2.2/openpaperwork-core/l10n/fr.po000066400000000000000000000176551456262201400211120ustar00rootroot00000000000000# French translations for PACKAGE package # Traductions françaises du paquet PACKAGE. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2021-11-16 17:11+0000\n" "Last-Translator: Jerome Flesch \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.9\n" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "App. & info. système" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "Sélectionnez pour générer" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "Collecte de statistiques en cours …" #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:363 msgid "App. config." msgstr "Config. de l'app." #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "Traces" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "Aujourd'hui" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "Hier" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "%3.1f octets" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "%3.1f Kio" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiO" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "%3.1f Gio" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "%3.1f Tio" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "O/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "o/N" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "Vérifie que toutes les dépendances requises sont installées" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "Dépendances manquantes :" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "- {dep_name} (paquet : {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "INCONNU" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "Commande suggérée :" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "Voulez-vous exécuter cette commande ?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "Je ne sais pas comment installer ces dépendances. Désolé." #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "Rien à faire." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "Gérer les plugins de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:69 msgid "sub-command" msgstr "sous-commande" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "Montre les plugins activés pour %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "Ajoute un plugin dans %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "Ne pas corriger les dépendances automatiquement" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "Retire le plugin de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "Réinitialise la liste des plugins à sa valeur par défaut" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "Montre les informations concernant un plugin (doit être activé)" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "Erreur : Plugin '%s' non-trouvé" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" "Ajoute le plugin '{plugin_name}' pour satisfaire la dépendance de " "'{other_plugin_name}' sur l'interface '{interface}'" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "Plugin {} ajouté" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" "Retire le plugin '{plugin_name}' à cause de la dépendance manquante " "'{interface}'" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "Plugin {} retiré" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "Plugins actifs :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "Plugin '%s' non-activé." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "Plugin '%s' :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "Implémente :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "Dépend de :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "Suggéré : %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "Nom du plugin" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "Interface" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:65 msgid "Manage Paperwork configuration" msgstr "Gérer la configuration de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:73 msgid "Get a value from Paperwork's configuration" msgstr "Renvoi une valeur depuis la configuration de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Set a value in Paperwork's configuration" msgstr "Défini une valeur dans la configuration de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:81 msgid "See 'config list_type'" msgstr "Voir 'config list_type'" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:85 msgid "Show Paperwork's configuration" msgstr "Affiche la configuration de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:90 msgid "Show value types you can use from command line" msgstr "" "Affiche les types de valeurs que vous pouvez utiliser depuis la ligne de " "commande" paperwork-2.2.2/openpaperwork-core/l10n/messages.pot000066400000000000000000000145221456262201400224640ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "" #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:363 msgid "App. config." msgstr "" #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:69 msgid "sub-command" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:65 msgid "Manage Paperwork configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:73 msgid "Get a value from Paperwork's configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Set a value in Paperwork's configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:81 msgid "See 'config list_type'" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:85 msgid "Show Paperwork's configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:90 msgid "Show value types you can use from command line" msgstr "" paperwork-2.2.2/openpaperwork-core/l10n/oc.po000066400000000000000000000176431456262201400211010ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2021-10-23 15:04+0000\n" "Last-Translator: Quentin PAGÈS \n" "Language-Team: Occitan \n" "Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.4\n" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "Aplicacion e info sustèma" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "Seleccionar per generar" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "Reculhida d’estatisticas..." #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:363 msgid "App. config." msgstr "Config. de l'ap." #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "Fichièr d'istoric" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "Uèi" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "Ièr" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "%3.1f octets" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "%3.1f Kio" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiO" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "%3.1f Gio" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "%3.1f Tio" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "O/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "o/N" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "Verificar que totas las dependéncias requeridas son installadas" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "Dependéncias mancantas :" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "- {dep_name} (paquet : {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "DESCONEGUT" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "Comanda suggerida :" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "Volètz executar aquesta comanda ara ?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "Sabi pas cossí installar aquestas dependéncias. Desconsolat." #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "Res a far." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "Gerir lo modul %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:69 msgid "sub-command" msgstr "jos-comanda" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "Mostrar los moduls activats per %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "Ajustar un modul dins %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "Corregir pas automaticament las dependéncias" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "Tirar lo modul de %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "Reïnicializar la lista dels moduls a la valor de defaut" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "Mostrar las informacions que concernisson un modul (deu èsser activat)" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "Error : modul « %s » pas trobat" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" "Ajusta l modul « {plugin_name} » per satisfar la dependéncia de " "« {other_plugin_name} » sus l’interfàcia « {interface} »" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "Modul {} ajustat" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" "Tira lo modul « {plugin_name} » a causa de la dependéncia mancanta " "« {interface} »" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "Modul {} tirat" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "Moduls actius :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "Modul « %s » pas activat." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "Modul « %s » :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "Implementa :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "Depend de :" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "Suggerit : %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "Nom modul" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "Interfàcia" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:65 msgid "Manage Paperwork configuration" msgstr "Gerir la configuracion de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:73 msgid "Get a value from Paperwork's configuration" msgstr "Obténer una valor a partir de la configuracion de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Set a value in Paperwork's configuration" msgstr "Definir una valor dins la configuracion de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:81 msgid "See 'config list_type'" msgstr "Veire « config list_type »" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:85 msgid "Show Paperwork's configuration" msgstr "Mostrar la configuracion de Paperwork" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:90 msgid "Show value types you can use from command line" msgstr "" "Mostrar los tipes de valors que podètz utilizar a partir de la linha de " "comanda" paperwork-2.2.2/openpaperwork-core/l10n/sv.po000066400000000000000000000167461456262201400211330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-01-04 15:31+0000\n" "Last-Translator: Ã…ke Engelbrektson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:123 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 msgid "Log file" msgstr "Loggfil" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "J/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "j/N" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:50 msgid "Manage Paperwork configuration" msgstr "Hantera Paperwork-konfigurationen" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:54 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 msgid "sub-command" msgstr "underkommando" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:58 msgid "Get a value from Paperwork's configuration" msgstr "Hämta ett värde frÃ¥n Paperworks konfiguration" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:63 msgid "Set a value in Paperwork's configuration" msgstr "Ange ett värde i Paperworks konfiguration" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:66 msgid "See 'config list_type'" msgstr "See \"config list_type\"" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:70 msgid "Show Paperwork's configuration" msgstr "Visa Paperworks konfiguration" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:75 msgid "Show value types you can use from command line" msgstr "Visa värdetyper du kan använda i kommandoraden" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "Kolla om alla beroenden är installerade" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "Saknade beroenden:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "- {dep_name} (package: {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "OKÄND" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "Föreslaget kommando:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "Vill du köra det här kommandot?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "Vet inte hur man installerar saknade beroenden, tyvärr." #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "Inget att göra." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "Hantera %s insticksmoduler" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "Visa insticksmoduler aktiverade för %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "Lägg till insticksmodul %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "Korrigera inte beroenden automatiskt" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "Ta bort insticksmodul frÃ¥n %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "" "Städa upp din röra genom att Ã¥terställa instickslistan till dess " "standardvärde" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "Visa information rörande en insticksmodul (mÃ¥ste vara aktiverat)" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "Fel: Insticksmodul \"%s\" hittades inte" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" "Lägger till insticksmodul \"{plugin_name}\" för att tillfredsställa beroende " "för \"{other_plugin_name}\" eller gränssnittet \"{interface}\"" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "Insticksmodul {} tillagd" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" "Tar bort insticksmodul \"{plugin_name}\" pÃ¥ grund av saknat beroende \"" "{interface}\"" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "Insticksmodul {} borttagen" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "Aktiva insticksmoduler:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "Insticksmodul \"%s\" är inte aktiverad." #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "Insticksmodul \"%s\":" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "Implementerar:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "Beroende av:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "föreslaget: %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "Insticksnamn" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "Gränssnitt" #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:333 msgid "App. config." msgstr "App. config." #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:31 msgid "Today" msgstr "Idag" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:32 msgid "Yesterday" msgstr "I gÃ¥r" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:34 #, python-format msgid "%3.1f bytes" msgstr "%3.1f bytes" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:35 #, python-format msgid "%3.1f KiB" msgstr "%3.1f KiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:36 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:37 #, python-format msgid "%3.1f GiB" msgstr "%3.1f GiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 #, python-format msgid "%3.1f TiB" msgstr "%3.1f TiB" paperwork-2.2.2/openpaperwork-core/l10n/uk.po000066400000000000000000000147021456262201400211100ustar00rootroot00000000000000# Ukrainian translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2020-05-03 15:35+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:126 msgid "App. & system info." msgstr "" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:127 msgid "Select to generate" msgstr "" #: openpaperwork-core/src/openpaperwork_core/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "" #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:363 msgid "App. config." msgstr "" #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:145 msgid "Log file" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 msgid "Today" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:39 msgid "Yesterday" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:41 #, python-format msgid "%3.1f bytes" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:42 #, python-format msgid "%3.1f KiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:43 #, python-format msgid "%3.1f MiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:44 #, python-format msgid "%3.1f GiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:45 #, python-format msgid "%3.1f TiB" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:69 msgid "sub-command" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:65 msgid "Manage Paperwork configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:73 msgid "Get a value from Paperwork's configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:78 msgid "Set a value in Paperwork's configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:81 msgid "See 'config list_type'" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:85 msgid "Show Paperwork's configuration" msgstr "" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:90 msgid "Show value types you can use from command line" msgstr "" paperwork-2.2.2/openpaperwork-core/l10n/zh_Hans.po000066400000000000000000000163041456262201400220630ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-02-06 09:20+0000\n" "Last-Translator: 玉堂白鹤 \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.4\n" #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:123 #: openpaperwork-core/src/openpaperwork_core/logs/archives.py:134 msgid "Log file" msgstr "日志文件" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:10 msgid "Y/n" msgstr "Y/n" #: openpaperwork-core/src/openpaperwork_core/cmd/util.py:13 msgid "y/N" msgstr "y/N" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:50 msgid "Manage Paperwork configuration" msgstr "ç®¡ç† Paperwork é…ç½®" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:54 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:49 msgid "sub-command" msgstr "å­å‘½ä»¤" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:58 msgid "Get a value from Paperwork's configuration" msgstr "从 Paperwork çš„é…置中获å–值" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:63 msgid "Set a value in Paperwork's configuration" msgstr "设置一个值到 Paperwork çš„é…置中" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:66 msgid "See 'config list_type'" msgstr "查看 'config list_type'" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:70 msgid "Show Paperwork's configuration" msgstr "显示 Paperwork é…ç½®" #: openpaperwork-core/src/openpaperwork_core/cmd/config.py:75 msgid "Show value types you can use from command line" msgstr "显示å¯ä»¥ä»Žå‘½ä»¤è¡Œä½¿ç”¨çš„值类型" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:52 msgid "Check that all required dependencies are installed" msgstr "检查是å¦å·²å®‰è£…所有必需的ä¾èµ–项" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:73 msgid "Missing dependencies:" msgstr "缺少ä¾èµ–项:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:75 #, python-brace-format msgid "- {dep_name} (package: {pkg_name})" msgstr "- {dep_name} (软件包: {pkg_name})" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:80 msgid "UNKNOWN" msgstr "未知" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:100 msgid "Suggested command:" msgstr "建议的命令:" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:105 msgid "Do you want to run this command now ?" msgstr "您是å¦è¦ç«‹å³è¿è¡Œæ­¤å‘½ä»¤ ?" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:119 msgid "Don't know how to install missing dependencies. Sorry." msgstr "ä¸çŸ¥é“如何安装缺少的ä¾èµ–项。抱歉。" #: openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py:122 msgid "Nothing to do." msgstr "无事å¯åšã€‚" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:45 #, python-format msgid "Manage %s plugins" msgstr "管ç†%sæ’ä»¶" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:54 #, python-format msgid "Show plugins enabled for %s" msgstr "显示为 %s å¯ç”¨çš„æ’ä»¶" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:60 #, python-format msgid "Add plugin in %s" msgstr "添加æ’件至 %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:66 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:77 msgid "Do not correct dependencies automatically" msgstr "ä¸è¦è‡ªåŠ¨æ›´æ­£ä¾èµ–关系" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:71 #, python-format msgid "Remove plugin from %s" msgstr "从 %s 移除æ’ä»¶" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:82 msgid "Clean up your mess by reseting the plugin list to its default value" msgstr "通过将æ’件列表é‡ç½®ä¸ºé»˜è®¤å€¼æ¥æ¸…ç†æ··ä¹±" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:89 msgid "Show information regarding a plugin (must be enabled)" msgstr "显示有关æ’ä»¶çš„ä¿¡æ¯ (å¿…é¡»å¯ç”¨)" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:125 #, python-format msgid "Error: Plugin '%s' not found" msgstr "错误: 找ä¸åˆ°æ’ä»¶ %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:143 #, python-brace-format msgid "" "Adding plugin '{plugin_name}' to satisfy dependency of '{other_plugin_name}' " "on interface '{interface}'" msgstr "添加æ’ä»¶ '{plugin_name}' ä»¥æ»¡è¶³æŽ¥å£ '{interface}' 上 '{other_plugin_name}' çš„ä¾èµ–" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:162 msgid "Plugin {} added" msgstr "æ’ä»¶ {} 已添加" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:184 #, python-brace-format msgid "Removing plugin '{plugin_name}' due to missing dependency '{interface}'" msgstr "由于缺少ä¾èµ–项 “{interface}â€ï¼Œæ­£åœ¨åˆ é™¤æ’件“{plugin_name}â€" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:201 msgid "Plugin {} removed" msgstr "æ’ä»¶ {} 已移除" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:207 msgid "Active plugins:" msgstr "活动æ’ä»¶:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:293 #, python-format msgid "Plugin '%s' not enabled." msgstr "æ’ä»¶ '%s' 未å¯ç”¨ã€‚" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:298 #, python-format msgid "Plugin '%s':" msgstr "æ’ä»¶ '%s':" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:300 msgid "Implements:" msgstr "工具:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:303 msgid "Depends on:" msgstr "ä¾èµ–于:" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:309 #, python-format msgid "suggested: %s" msgstr "建议: %s" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:317 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:330 msgid "Plugin name" msgstr "æ’ä»¶åç§°" #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:318 #: openpaperwork-core/src/openpaperwork_core/cmd/plugins.py:331 msgid "Interface" msgstr "接å£" #: openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py:333 msgid "App. config." msgstr "App. é…ç½®." #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:31 msgid "Today" msgstr "今天" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:32 msgid "Yesterday" msgstr "昨天" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:34 #, python-format msgid "%3.1f bytes" msgstr "%3.1f 字节" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:35 #, python-format msgid "%3.1f KiB" msgstr "%3.1f KiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:36 #, python-format msgid "%3.1f MiB" msgstr "%3.1f MiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:37 #, python-format msgid "%3.1f GiB" msgstr "%3.1f GiB" #: openpaperwork-core/src/openpaperwork_core/i18n/python.py:38 #, python-format msgid "%3.1f TiB" msgstr "%3.1f TiB" paperwork-2.2.2/openpaperwork-core/pyproject.toml000066400000000000000000000012371456262201400222720ustar00rootroot00000000000000[project] name = "openpaperwork-core" description = "OpenPaperwork's core" dynamic = ["version"] authors = [ {name = "Jerome Flesch", email = "jflesch@openpaper.work" }, ] license = {text = "GPL-3.0-or-later"} readme = {file = "README.md", content-type = "text/markdown"} dependencies = [ "certifi", "distro", ] [project.optional-dependencies] dev = [ "pytest", ] lint = [ "flake8", ] [tool.setuptools_scm] root = ".." relative_to = "__file__" write_to = "openpaperwork-core/src/openpaperwork_core/_version.py" version_scheme = "post-release" [build-system] requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta" paperwork-2.2.2/openpaperwork-core/setup.cfg000066400000000000000000000000661456262201400211760ustar00rootroot00000000000000[tool:pytest] addopts = -ra python_files = tests_*.py paperwork-2.2.2/openpaperwork-core/src/000077500000000000000000000000001456262201400201425ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/000077500000000000000000000000001456262201400240465ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/__init__.py000066400000000000000000000441561456262201400261710ustar00rootroot00000000000000import collections import gettext import importlib import itertools import logging import os import time LOGGER = logging.getLogger(__name__) MINIMUM_CONFIG_PLUGINS = [ # You also have to provide a plugin providing the interface 'app' 'openpaperwork_core.archives', 'openpaperwork_core.cmd.config', 'openpaperwork_core.cmd.plugins', 'openpaperwork_core.config', 'openpaperwork_core.config.automatic_plugin_reset', 'openpaperwork_core.config.backend.configparser', 'openpaperwork_core.data_versioning', 'openpaperwork_core.frozen', 'openpaperwork_core.fs.python', 'openpaperwork_core.logs.archives', 'openpaperwork_core.mainloop.asyncio', 'openpaperwork_core.paths.xdg', 'openpaperwork_core.uncaught_exception', ] RECOMMENDED_PLUGINS = [ 'openpaperwork_core.external_apps.dbus', 'openpaperwork_core.external_apps.windows', 'openpaperwork_core.external_apps.xdg', 'openpaperwork_core.flatpak', 'openpaperwork_core.fs.memory', 'openpaperwork_core.http', 'openpaperwork_core.i18n.python', 'openpaperwork_core.l10n.python', 'openpaperwork_core.perfcheck.log', 'openpaperwork_core.resources.frozen', 'openpaperwork_core.resources.setuptools', 'openpaperwork_core.sqlite', 'openpaperwork_core.thread.pool', 'openpaperwork_core.urls', 'openpaperwork_core.work_queue.default', ] if os.name != 'nt': RECOMMENDED_PLUGINS += [ 'openpaperwork_core.cmd.chkdeps', ] def _(s): return gettext.dgettext('openpaperwork_core', s) class DependencyException(Exception): """ Failed to satisfy dependencies. """ pass class PluginBase(object): """ Indicates all the methods that must be implemented by any plugin managed by OpenPaperwork core. Also provides default implementations for each method. """ # Priority defines in which order callbacks will be called. # Plugins with higher priorities will have their callbacks called first. PRIORITY = 0 # Convenience for the applications: Indicates if users should be able # to enable/disable this plugin in the UI. USER_VISIBLE = False def __init__(self): """ Called as soon as the module is loaded. Should be as minimal as possible. Most of the work should be done in `init()`. You *must* *not* rely on any dependencies here. """ self.core = None def get_interfaces(self): """ Indicates the list of interfaces implemented by this plugin. Interface names are arbitrarily defined. Methods provided by each interface are arbitrarily defined (and no checks are done). Returns a list of string. """ return [] def get_deps(self): """ Return the dependencies required by this plugin. Example: .. code-block:: python [ { "interface": "some_interface_name", # required "defaults": ['plugin_a', 'plugin_b'], # required "expected_already_satisfied": False, # optional, default: True }, ] """ return [] def init(self, core): """ Plugins can initialize whatever they want here. When called, all dependencies have been loaded and initialized, so using them is safe. Does nothing by default. """ self.core = core class Core(object): """ Manage plugins and their callbacks. """ def __init__(self, auto_load_dependencies=False): """ `auto_load_dependencies=True` means that missing dependencies will be loaded automatically based on the default plugin list provided by plugins. This should be only used for testing. """ self.plugins = {} self.initialized = False self._to_initialize = set() self._initialized = set() # avoid double-init self.interfaces = collections.defaultdict(list) self.callbacks = collections.defaultdict(list) self.auto_load_dependencies = auto_load_dependencies self.log_all = bool(os.getenv("CORE_LOG_ALL", 0)) self.count_limit_per_second = int(os.getenv("CORE_CALL_LIMIT", 0)) self.counters_last_reset = 0 self.counters = collections.defaultdict(lambda: 0) def load(self, module_name): """ - Load the specified module - Instantiate the class 'Plugin()' of this module - Register all the methods of this plugin object (except those starting by '_' and those from the class PluginBase) as callbacks BEWARE of dependency loops ! Arguments: - module_name: name of the Python module to load """ if module_name in self.plugins: return self.plugins[module_name] LOGGER.info("Loading plugin '%s' ...", module_name) module = importlib.import_module(module_name) return self._load_module(module_name, module) def _load_module(self, module_name, module): """ should be called from outside for testing only """ if module_name in self.plugins: LOGGER.debug("Module %s already loaded", module_name) return self.plugins[module_name] self.initialized = False plugin = module.Plugin() self.plugins[module_name] = plugin for interface in plugin.get_interfaces(): LOGGER.debug("- '%s' provides '%s'", str(type(plugin)), interface) self.interfaces[interface].append(plugin) self._to_initialize.add(plugin) LOGGER.info("Plugin '%s' loaded", module_name) return plugin def _check_deps(self): to_examine = [ (plugin_name, plugin) for (plugin_name, plugin) in self.plugins.items() ] while len(to_examine) > 0: (plugin_name, plugin) = to_examine[0] to_examine = to_examine[1:] LOGGER.info("Examining dependencies of '%s' ...", plugin_name) deps = plugin.get_deps() for dep in deps: interface = dep['interface'] if len(self.interfaces[interface]) > 0: LOGGER.debug( "- Interface '%s' already provided by %d plugins", interface, len(self.interfaces[interface]) ) continue defaults = dep['defaults'] if len(defaults) <= 0: continue if (not self.auto_load_dependencies and ( 'expected_already_satisfied' not in dep or dep['expected_already_satisfied'] )): LOGGER.warning( "Plugin '{}' requires interface '{}' but no plugins" " provide this interface (suggested: {}). Plugin '{}'" " will not be initialized.".format( plugin_name, interface, defaults, plugin_name ) ) plugin = self.plugins.pop(plugin_name) self._to_initialize.remove(plugin) # return False to indicate we actually dropped a plugin # and need to reevaluate all the dependencies again. return False else: LOGGER.info( "Loading plugins %s to satisfy dependency." " Required by '%s' for interface '%s'", defaults, type(plugin), interface ) for default in defaults: to_examine.append((default, self.load(default))) return True def _register_plugin(self, plugin): for attr_name in dir(plugin): if attr_name[0] == "_": continue if attr_name in dir(PluginBase): # ignore base methods of plugins continue callback = getattr(plugin, attr_name) if not hasattr(callback, '__call__'): continue LOGGER.debug("- %s.%s()", str(type(plugin)), attr_name) self.callbacks[attr_name].append(( plugin.PRIORITY, str(type(plugin)), callback )) self.callbacks[attr_name].sort(reverse=True) def _init(self, plugin, stack=list()): nb = 0 if plugin in self._initialized: return nb if plugin in stack: LOGGER.error("Dependency loop:") for p in itertools.chain(stack, [plugin]): LOGGER.error( "- %s %s depends on %s", p, p.get_interfaces(), [d['interface'] for d in p.get_deps()] ) raise DependencyException("Dependency loop: %s" % str(stack)) stack.append(plugin) self.initialized = True deps = plugin.get_deps() for dep in deps: dep_plugins = self.interfaces[dep['interface']] for dep_plugin in dep_plugins: nb += self._init(dep_plugin, stack) LOGGER.info("Initializing plugin '%s' ...", type(plugin)) stack.remove(plugin) plugin.init(self) self._register_plugin(plugin) nb += 1 self._initialized.add(plugin) return nb def init(self): """ - Make sure all the dependencies of all the plugins are satisfied. - Call the method init() of each plugin following the dependency order (those without dependencies are called first). BEWARE of dependency loops ! """ LOGGER.info("Initializing all plugins") while not self._check_deps(): pass nb = 0 for plugin in self._to_initialize: nb += self._init(plugin) self._to_initialize = set() LOGGER.info("%d plugins initialized", nb) def get_by_name(self, module_name): """ Returns a Plugin instance based on the corresponding module name (assuming it has been loaded). You shouldn't use this function, except for: - unit tests - configuration (see cmd.plugins) """ return self.plugins[module_name] def get_by_interface(self, interface_name): return self.interfaces[interface_name] def get_plugins(self): """ You shouldn't use this function, except for: - unit tests - configuration (see cmd.plugins) """ return dict(self.plugins) def _check_call_limit(self, callback_name): if self.count_limit_per_second <= 0: return now = time.time() if now - self.counters_last_reset >= 1.0: self.counters = collections.defaultdict(lambda: 0) self.counters_last_reset = now self.counters[callback_name] += 1 if self.counters[callback_name] >= self.count_limit_per_second: raise Exception( "Too many calls to '{}' (>= {}) in one second".format( callback_name, self.count_limit_per_second ) ) def call_all(self, callback_name, *args, **kwargs): """ Call all the methods of all the plugins that have `callback_name` as name. Arguments are passed as is. Returned values are dropped (use callbacks for return values if required) Method call order is defined by the plugin priorities: Plugins with a higher priority get their methods called first. When we need a return value from callbacks called with `call_all()`, we need a way to get the results from all of them. The usual way to do that is to instantiate an empty `list` or `set`, and pass it as first argument of the callbacks (argument `out`). Callbacks can then complete this list or set using `list.append()` or `set.add()`. .. uml:: Caller -> Core: call "func" Core -> "Plugin A": plugin.func() Core <- "Plugin A": returns "something_a" Core -> "Plugin B": plugin.func() Core <- "Plugin B": returns "something_b" Core -> "Plugin C": plugin.func() Core <- "Plugin C": returns "something_c" Caller <- Core: returns 3 """ if self.log_all: print( "[{}] call_all({}, args={}, kwargs={})".format( time.time(), callback_name, args, kwargs ) ) assert \ self.initialized, \ "A plugin has been loaded without being initialized." \ " Call core.init() first" self._check_call_limit(callback_name) callbacks = self.callbacks[callback_name] if len(callbacks) <= 0: if callback_name.startswith("on_"): # those are 'observer' callback. If nobody is observing, # it's usually fine. log_method = LOGGER.debug else: log_method = LOGGER.warning log_method("No method '%s' found", callback_name) return 0 for (priority, plugin, callback) in callbacks: if self.log_all: print( "[{}] call_all({}, args={}, kwargs={}) -> {}:{}".format( time.time(), callback_name, args, kwargs, priority, callback ) ) callback(*args, **kwargs) return len(callbacks) def call_one(self, callback_name, *args, **kwargs): """ Look for a plugin method called `callback_name` and calls it. Raises an error if no such method exists. If many exists, call one at random. Returns the value return by the callback. Method call order is defined by the plugin priorities: Plugins with a higher priority get their methods called first. .. uml:: Caller -> Core: call "func" Core -> "Plugin A": plugin.func() Core <- "Plugin A": returns X Caller <- Core: returns X You're advised to use `call_all()` or `call_success()` instead whenever possible. This method is only provided as convenience for when you're fairly sure there should be only one plugin with such callback (example: mainloop plugins). """ assert \ self.initialized, \ "A plugin has been loaded without being initialized." \ " Call core.init() first" self._check_call_limit(callback_name) if self.log_all: print( "[{}] call_one({}, args={}, kwargs={})".format( time.time(), callback_name, args, kwargs ) ) callbacks = self.callbacks[callback_name] if len(callbacks) <= 0: raise IndexError( "No method '{}' found !".format(callback_name) ) if self.log_all: print( "[{}] call_one({}, args={}, kwargs={}) -> {}:{}".format( time.time(), callback_name, args, kwargs, callbacks[0][0], callbacks[0][2] ) ) return callbacks[0][2](*args, **kwargs) def call_success(self, callback_name, *args, **kwargs): """ Call methods of all the plugins that have `callback_name` as name until one of them return a value that is not None. Arguments are passed as is. First value to be different from None is returned. If none of the callbacks returned a value different from None or if no callback has the specified name, this method will return None. Method call order is defined by the plugin priorities: Plugins with a higher priority get their methods called first. Callbacks should never raise any exception. .. uml:: Caller -> Core: call "func" Core -> "Plugin A": plugin.func() Core <- "Plugin A": returns None Core -> "Plugin B": plugin.func() Core <- "Plugin B": returns None Core -> "Plugin C": plugin.func() Core <- "Plugin C": returns "something" Caller <- Core: returns "something" """ assert \ self.initialized, \ "A plugin has been loaded without being initialized." \ " Call core.init() first" self._check_call_limit(callback_name) if self.log_all: print( "[{}] call_one({}, args={}, kwargs={})".format( time.time(), callback_name, args, kwargs ) ) callbacks = self.callbacks[callback_name] if len(callbacks) <= 0: LOGGER.warning("No method '%s' found", callback_name) for (priority, plugin, callback) in callbacks: if self.log_all: msg = "[{}] call_success({}, args={}, kwargs={}) -> {}:{}" print(msg.format( time.time(), callback_name, args, kwargs, priority, callback )) r = callback(*args, **kwargs) if r is not None: return r return None def get_deps(self, plugin_name): plugin = self.plugins[plugin_name] for dep in plugin.get_deps(): if 'interface' not in dep: raise KeyError( "Missing interface in dependency list of plugin" " '{}'".format(plugin_name) ) if 'defaults' not in dep: raise KeyError( "Missing default plugins in dependency list of plugin" " '{}' (interface={})".format( plugin_name, dep['interface'] ) ) yield { 'interface': dep['interface'], 'actives': { x.__module__ for x in self.get_by_interface(dep['interface']) }, 'defaults': set(dep['defaults']), } def get_active_plugins(self): return self.plugins.keys() paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/app.py000066400000000000000000000006711456262201400252040ustar00rootroot00000000000000from . import PluginBase class Plugin(PluginBase): """ Plugin implementing the interface 'app' just provide some very basic information regarding the application we are building. """ def get_interfaces(self): return ['app'] def app_get_name(self): return "OpenPaperwork Core" def app_get_fs_name(self): return "openpaperwork_core" def app_get_version(self): return "0.0" paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/archives.py000066400000000000000000000070331456262201400262270ustar00rootroot00000000000000""" Used to archive logs, screenshots, etc. Do not depends on 'fs' plugins (this plugin is used for logging and therefore is critical --> has minimum dependencies). """ import datetime import logging from . import PluginBase LOGGER = logging.getLogger(__name__) ARCHIVE_FILE_DATE_FORMAT = "%Y%m%d_%H%M_%S" MAX_DAYS = 31 class ArchiveHandler(object): def __init__(self, core, storage_name, storage_dir, file_extension): self.core = core self.storage_name = storage_name self.storage_dir = storage_dir self.file_extension = file_extension def get_new(self, name=None): if name is None: name = self.storage_name out_file_name = datetime.datetime.now().strftime( ARCHIVE_FILE_DATE_FORMAT ) out_file_name += "_{}.{}".format(name, self.file_extension) out_file_path = self.core.call_success( "fs_join", self.storage_dir, out_file_name ) return out_file_path def get_archived(self): for f in self.core.call_success("fs_listdir", self.storage_dir): f = self.core.call_success("fs_basename", f) if not f.lower().endswith(".{}".format(self.file_extension)): continue short_f = "_".join(f.split("_", 3)[:3]) try: date = datetime.datetime.strptime( short_f, ARCHIVE_FILE_DATE_FORMAT ) except ValueError as exc: LOGGER.warning( "Unexpected filename: %s. Ignoring it", f, exc_info=exc ) continue yield ( date, self.core.call_success("fs_join", self.storage_dir, f) ) def delete_obsoletes(self): now = datetime.datetime.now() for (date, file_path) in self.get_archived(): if (now - date).days <= MAX_DAYS: continue LOGGER.info("Deleting obsolete log file: %s", file_path) self.core.call_success("fs_unlink", file_path, trash=False) class Plugin(PluginBase): def __init__(self): super().__init__() self.storage_dirs = [] def get_interfaces(self): return ['file_archives'] def get_deps(self): return [ { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, ] def init(self, core): super().init(core) data_dir = self.core.call_success("paths_get_data_dir") self.base_archive_dir = self.core.call_success( "fs_join", data_dir, "openpaperwork" ) LOGGER.info("Archiving to %s", self.base_archive_dir) def file_archive_get(self, storage_name, file_extension): self.core.call_success("fs_mkdir_p", self.base_archive_dir) storage_dir = self.core.call_success( "fs_join", self.base_archive_dir, storage_name ) self.storage_dirs.append(storage_dir) LOGGER.info("Archiving '%s' to %s", storage_name, storage_dir) self.core.call_success("fs_mkdir_p", storage_dir) archiver = ArchiveHandler( self.core, storage_name, storage_dir, file_extension ) archiver.delete_obsoletes() return archiver paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/beacon/000077500000000000000000000000001456262201400252755ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/beacon/__init__.py000066400000000000000000000040321456262201400274050ustar00rootroot00000000000000""" openpaperwork_core.beacon contains everything related to the communication with the website https://www.openpaper.work/ """ import datetime import logging LOGGER = logging.getLogger(__name__) class PeriodicTask(object): def __init__( self, config_section_name, min_delay: datetime.timedelta, periodic_callback, else_callback=lambda: None ): self.config_section_name = config_section_name self.min_delay = min_delay self.periodic_callback = periodic_callback self.else_callback = else_callback def register_config(self, core): setting = core.call_success( "config_build_simple", self.config_section_name, "last_run", lambda: datetime.date(year=1970, month=1, day=1) ) core.call_all( "config_register", self.config_section_name + "_last_run", setting ) def do(self, core): now = datetime.date.today() last_run = core.call_success( "config_get", self.config_section_name + "_last_run" ) if hasattr(last_run, 'value'): # ConfigDate object from # openpaperwork_core.config.backend.configparser last_run = last_run.value LOGGER.info( "[%s] Last run: %s ; Now: %s", self.config_section_name, last_run, now ) if now - last_run < self.min_delay: LOGGER.info( "[%s] Nothing to do (%s < %s)", self.config_section_name, now - last_run, self.min_delay ) self.else_callback() return LOGGER.info( "[%s] Running %s (%s >= %s)", self.config_section_name, self.periodic_callback, now - last_run, self.min_delay ) self.periodic_callback() LOGGER.info("[%s] Updating last run date", self.config_section_name) core.call_all( "config_put", self.config_section_name + "_last_run", now ) core.call_all("config_save") paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/beacon/stats.py000066400000000000000000000121611456262201400270060ustar00rootroot00000000000000import datetime import json import logging import uuid import openpaperwork_core import openpaperwork_core.promise from . import PeriodicTask from .. import _ LOGGER = logging.getLogger(__name__) POST_STATS_INTERVAL = datetime.timedelta(days=7) POST_STATS_PATH = "/beacon/post_statistics" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.periodic = None self.http = None def get_interfaces(self): return [ "bug_report_attachments", "stats_post", ] def get_deps(self): return [ { 'interface': 'app', 'defaults': ['paperwork_backend.app'], }, { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'fs', 'defaults': [ 'openpaperwork_core.fs.memory', 'openpaperwork_core.fs.python', ], }, { 'interface': 'http_json', 'defaults': ['openpaperwork_core.http'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def init(self, core): super().init(core) self.periodic = PeriodicTask( "statistics", datetime.timedelta(days=7), self.stats_send ) self.http = self.core.call_success( "http_json_get_client", "statistics" ) self._register_config(core) self.periodic.register_config(core) if self.core.call_success("config_get", "send_statistics"): self.periodic.do(core) def _register_config(self, core): setting = self.core.call_success( "config_build_simple", "statistics", "enabled", lambda: False ) self.core.call_all( "config_register", "send_statistics", setting ) setting = self.core.call_success( "config_build_simple", "statistics", "uuid", lambda: uuid.getnode() ) self.core.call_all("config_register", "uuid", setting) def _collect_stats(self, node_uuid): stats = { 'uuid': node_uuid, 'paperwork_version': self.core.call_success("app_get_version"), 'nb_documents': 0, 'os_name': '', 'platform_architecture': '', 'platform_processor': '', 'platform_distribution': '', 'cpu_count': 0, } self.core.call_all("stats_get", stats) return {'statistics': stats} def stats_send(self): node_uuid = self.core.call_success("config_get", "uuid") promise = openpaperwork_core.promise.ThreadedPromise( self.core, self._collect_stats, args=(node_uuid,) ) promise = promise.then(self.http.get_request_promise(POST_STATS_PATH)) def on_request_done(reply): LOGGER.info("Statistics posted. Reply: {}".format(reply)) self.core.call_all('on_stats_sent') promise = promise.then(on_request_done) promise = promise.catch(self._on_stats_send_error) promise.schedule() def _on_stats_send_error(self, exc): LOGGER.warning("Failed to send stats", exc_info=exc) def bug_report_get_attachments(self, out: dict): out['stats'] = { 'include_by_default': True, 'date': None, 'file_type': _("App. & system info."), 'file_url': _("Select to generate"), 'file_size': 0, } def _write_stats_to_tmp_file(self, stats): stats = json.dumps( stats, indent=4, separators=(",", ": "), sort_keys=True ) (file_url, fd) = self.core.call_success( "fs_mktemp", prefix="statistics_", suffix=".json", mode="w", on_disk=True ) with fd: fd.write(stats) return file_url def on_bug_report_attachment_selected(self, attachment_id, *args): if attachment_id != 'stats': return self.core.call_all( "bug_report_update_attachment", attachment_id, {"file_url": _("Collecting statistics ...")}, *args ) node_uuid = self.core.call_success("config_get", "uuid") promise = openpaperwork_core.promise.ThreadedPromise( self.core, self._collect_stats, args=(node_uuid,) ) promise = promise.then(self._write_stats_to_tmp_file) promise = promise.then( lambda file_url: self.core.call_all( "bug_report_update_attachment", attachment_id, { 'file_url': file_url, 'file_size': self.core.call_success( 'fs_getsize', file_url ), }, *args ) ) promise.schedule() paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/beacon/sysinfo.py000066400000000000000000000030161456262201400273410ustar00rootroot00000000000000import os import multiprocessing import platform import psutil import sys try: import distro except (ImportError, ValueError): assert os.name == "nt" import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def get_interfaces(self): return ['stats'] def stats_get(self, out: dict): if os.name == 'nt': distribution = str(platform.win32_ver()) else: distribution = str(( distro.id(), distro.version(), distro.name() )) processor = "" os_name = os.name if os_name != 'nt': # processor contains too much infos on Windows processor = str(platform.processor()) cpu_freq = None if hasattr(psutil, 'cpu_freq'): cpu_freq = psutil.cpu_freq() if cpu_freq is not None: cpu_freq = int(cpu_freq.max) if cpu_freq is not None: out['cpu_freq'] = cpu_freq out['cpu_count'] = multiprocessing.cpu_count() out['os_name'] = os_name out['platform_architecture'] = str(platform.architecture()) out['platform_distribution'] = distribution out['platform_machine'] = platform.machine() out['platform_mem'] = int(psutil.virtual_memory().total) out['platform_processor'] = processor out['software_python'] = sys.version out['software_release'] = platform.release() out['software_system'] = platform.system() return out paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/bug_report/000077500000000000000000000000001456262201400262165ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/bug_report/__init__.py000066400000000000000000000000001456262201400303150ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/bug_report/censor.py000066400000000000000000000035121456262201400300620ustar00rootroot00000000000000import logging from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): """ Censor bug report attachments """ PRIORITY = -10000 def get_interfaces(self): return ['bug_report_attachments'] def get_deps(self): return [ { 'interface': 'censor', 'defaults': ['openpaperwork_core.censor'], }, ] def _censor_attachment(self, attachment_id, args): url = self.core.call_success( "bug_report_get_attachment_file_url", attachment_id, *args ) if url is None: LOGGER.info( "Attachment %s has no URL yet. Can't censor", attachment_id ) return if not url.endswith(".conf") and not url.endswith(".txt"): LOGGER.info( "Unknown file type: %s:%s. Can't censor", attachment_id, url ) return basename = self.core.call_success("fs_basename", url) if basename.startswith("censored_"): LOGGER.info("Attachmnent %s appears to be already censored", url) return LOGGER.info("Censoring %s:%s", attachment_id, url) censored = self.core.call_success( "censor_txt_file", url, tmp_on_disk=True ) self.core.call_all( "bug_report_update_attachment", attachment_id, { "censored": True, "file_url": censored, }, *args ) def on_bug_report_attachment_selected(self, attachment_id, *args): self._censor_attachment(attachment_id, args) def bug_report_update_attachment(self, attachment_id, infos: dict, *args): if 'censored' in infos: return self._censor_attachment(attachment_id, args) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/censor.py000066400000000000000000000047541456262201400257230ustar00rootroot00000000000000import getpass import logging import os import socket import urllib.parse from . import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def __init__(self): self.replacements = ( (os.path.expanduser("~"), "###HOME_DIR###"), (urllib.parse.quote(os.path.expanduser("~")), "###HOME_DIR###"), (getpass.getuser(), "###USER_NAME###"), (urllib.parse.quote(getpass.getuser()), "###USER_NAME###"), (socket.gethostname(), "###HOST_NAME###"), (urllib.parse.quote(socket.gethostname()), "###HOST_NAME###"), ) def get_interfaces(self): return ['censor'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, ] def censor_string(self, string): """ Rewrite a string by censoring anything close to personal information (username, home directory path, host name, ...). """ for r in self.replacements: string = string.replace(*r) return string def censor_txt_file( self, input_url, output_url=None, tmp_on_disk=False): """ Rewrite a file but censor anything close to personal information (username, home directory path, host name, ...). Arguments: - file_input_url: file to censor - file_output_url: output file. If None, a temporary file will be created - tmp_on_disk: only used if file_output_url is None. If true, the temporary file will be written on disk. If false, we may return a memory:// URI (won't work outside of Paperwork). Returns: censored file URL """ if output_url is not None: fd_out = self.core.call_success("fs_open", output_url, 'w') else: basename = self.core.call_success("fs_basename", input_url) (output_url, fd_out) = self.core.call_success( "fs_mktemp", prefix="censored_", suffix="_" + basename, mode="w", on_disk=tmp_on_disk ) with fd_out: with self.core.call_success("fs_open", input_url, 'r') as fd_in: while True: line = fd_in.readline() if line == '': break line = self.censor_string(line) fd_out.write(line) return output_url paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/cmd/000077500000000000000000000000001456262201400246115ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/cmd/__init__.py000066400000000000000000000001741456262201400267240ustar00rootroot00000000000000class DummyConsole: def print(self, *args, **kwargs): pass def input(self, prompt=""): return None paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/cmd/chkdeps.py000066400000000000000000000076431456262201400266160ustar00rootroot00000000000000import collections import distro import logging import os import sys from . import util from .. import (_, PluginBase) LOGGER = logging.getLogger(__name__) PACKAGE_TOOLS = { 'debian': 'apt-get install -y', 'fedora': 'dnf install', 'gentoo': 'emerge', 'linuxmint': 'apt-get install -y', 'raspbian': 'apt-get install -y', 'suse': 'zypper in', 'ubuntu': 'apt-get install -y', } class Plugin(PluginBase): def __init__(self): self.console = None def get_interfaces(self): return ['shell'] def get_deps(self): # will call method from interface 'chkdeps', but we can still # work if no other plugin implement 'chkdeps'. return [] def _get_distribution(self): distribution = distro.linux_distribution(full_distribution_name=False) self.console.print(f"Detected system: {' '.join(distribution)}") distribution = distribution[0].lower() if distribution not in PACKAGE_TOOLS: LOGGER.warning( "WARNING: Unknown distribution." " Can't suggest packages to install" ) return distribution def cmd_set_console(self, console): self.console = console def cmd_complete_argparse(self, parser): p = parser.add_parser( 'chkdeps', help=_("Check that all required dependencies are installed") ) p.add_argument( "--yes", "-y", required=False, default=False, action='store_true' ) def cmd_run(self, console, args): if args.command != 'chkdeps': return None auto = args.yes if auto: LOGGER.warning("Confirmation disabled") distribution = self._get_distribution() missing = collections.defaultdict(dict) self.core.call_all("chkdeps", missing) if len(missing) > 0: console.print(_("Missing dependencies:")) for (dep_name, distrib_packages) in missing.items(): console.print(_("- {dep_name} (package: {pkg_name})").format( dep_name=dep_name, pkg_name=( distrib_packages[distribution] if distribution in distrib_packages else _("UNKNOWN") ) )) if distribution in PACKAGE_TOOLS: command = PACKAGE_TOOLS[distribution] if os.getuid() != 0: command = "sudo {}".format(command) else: command = None has_pkg = False for (dep_name, distrib_packages) in missing.items(): if distribution in distrib_packages: if command is not None: command += " " + distrib_packages[distribution] has_pkg = True if has_pkg and command is not None: console.print("") console.print(_("Suggested command:")) console.print(" " + command) console.print("") if not auto: r = util.ask_confirmation( console, _("Do you want to run this command now ?"), default_interactive='n', default_non_interactive='n', ) if r != 'y': return { "missing": missing, "command": command, } console.print("Running command ...") r = os.system(command) console.print("Command returned {}".format(r)) if r != 0: sys.exit(r) elif len(missing) > 0: console.print( _("Don't know how to install missing dependencies. Sorry.") ) else: console.print(_("Nothing to do.")) return { "missing": missing, "command": command, } paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/cmd/config.py000066400000000000000000000104531456262201400264330ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import datetime import logging from .. import (_, PluginBase) LOGGER = logging.getLogger(__name__) def bool_from_str(s): s = s.strip() if s == "" or s == "0" or s.lower() == "false": return False return True # Only basic types are handled by shell commands CMD_VALUE_TYPES = { 'str': str, 'int': int, 'float': float, 'bool': bool_from_str, } DATE_FORMAT = "%Y-%m-%d" TO_JSON = { datetime.date: lambda x: x.strftime(DATE_FORMAT) } class Plugin(PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['shell'] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, ] def cmd_complete_argparse(self, parser): config_parser = parser.add_parser( 'config', help=_("Manage Paperwork configuration") ) subparser = config_parser.add_subparsers( help=_("sub-command"), dest='subcommand', required=True ) get_parser = subparser.add_parser( 'get', help=_("Get a value from Paperwork's configuration") ) get_parser.add_argument('opt_name') put_parser = subparser.add_parser( 'put', help=_("Set a value in Paperwork's configuration") ) put_parser.add_argument('opt_name') put_parser.add_argument('type', help=_("See 'config list_type'")) put_parser.add_argument('value') subparser.add_parser( 'show', help=_("Show Paperwork's configuration") ) subparser.add_parser( 'list_types', help=_( "Show value types you can use from command line" ) ) def cmd_run(self, console, args): if args.command != 'config': return None if args.subcommand == "get": return self._cmd_get(args.opt_name) elif args.subcommand == "put": return self._cmd_put(args.opt_name, args.type, args.value) elif args.subcommand == "show": return self._cmd_show() elif args.subcommand == "list_types": return self._cmd_list_types() else: return None def _cmd_get(self, opt_name): v = self.core.call_success("config_get", opt_name) if v is None: LOGGER.warning("No such option '%s'", opt_name) return None self.core.call_all("print", f"{opt_name} = {v}") self.core.call_success("print_flush") return {opt_name: v} def _cmd_put(self, opt_name, vtype, value): value = CMD_VALUE_TYPES[vtype](value) self.core.call_success("print", f"{opt_name} = {value}") self.core.call_success("print_flush") self.core.call_all("config_put", opt_name, value) self.core.call_all("config_save") return {opt_name: value} def _cmd_show(self): opts = self.core.call_success("config_list_options") out = {} opts.sort() for opt in opts: v = self.core.call_success("config_get", opt) if type(v) in TO_JSON: v = TO_JSON[type(v)](v) out[opt] = v self.core.call_success( "print", f"{opt} = {out[opt]} ({type(v).__name__})" ) self.core.call_success("print_flush") return out def _cmd_list_types(self): r = list(CMD_VALUE_TYPES.keys()) self.core.call_success("print", str(r)) self.core.call_success("print_flush") return r paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/cmd/plugins.py000066400000000000000000000262701456262201400266530ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import importlib import logging from .. import (_, PluginBase) LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, ] def cmd_complete_argparse(self, parser): application = self.core.call_success("config_get_plugin_list_name") config_parser = parser.add_parser( 'plugins', help=(_("Manage %s plugins") % application) ) subparser = config_parser.add_subparsers( help=_("sub-command"), dest='subcommand', required=True ) subparser.add_parser( 'list', help=( _("Show plugins enabled for %s") % application ) ) p = subparser.add_parser( 'add', help=( _("Add plugin in %s") % application ) ) p.add_argument('plugin_name') p.add_argument( '--no_auto', '-n', action="store_true", help=_("Do not correct dependencies automatically") ) p = subparser.add_parser( 'remove', help=( _("Remove plugin from %s") % application ) ) p.add_argument('plugin_name') p.add_argument( '--no_auto', '-n', action="store_true", help=_("Do not correct dependencies automatically") ) subparser.add_parser( 'reset', help=(_( "Clean up your mess by reseting the plugin list to its" " default value" )) ) p = subparser.add_parser( 'show', help=( _("Show information regarding a plugin (must be enabled)") ) ) p.add_argument('plugin_name') def cmd_run(self, console, args): if args.command != 'plugins': return None elif args.subcommand == "list": return self._cmd_list_plugins(console) elif args.subcommand == "add": return self._cmd_add_plugin( console, args.plugin_name, not args.no_auto ) elif args.subcommand == "remove": return self._cmd_remove_plugin( console, args.plugin_name, not args.no_auto ) elif args.subcommand == "reset": return self._cmd_reset_plugins(console) elif args.subcommand == "show": return self._cmd_show_plugin(console, args.plugin_name) else: return None def _cmd_add_plugin( self, console, plugin_name, auto=True, added=set(), save=True ): added.add(plugin_name) if auto: # Load the plugin, and check that all its dependencies are # satisfied. # Do not use the core to load it, otherwise we won't be able # to use 'call_success()' or 'call_all(). try: module = importlib.import_module(plugin_name) except ModuleNotFoundError: console.print( _("Error: Plugin '%s' not found") % plugin_name ) return False plugin = module.Plugin() deps = plugin.get_deps() for dep in deps: try: actives = self.core.get_by_interface(dep['interface']) if len(actives) > 0: continue except KeyError: pass for default in dep['defaults']: if default in added: continue console.print( _( "Adding plugin '{plugin_name}' to satisfy" " dependency of '{other_plugin_name}' on interface" " '{interface}'" ).format( plugin_name=default, other_plugin_name=plugin_name, interface=dep['interface'] ) ) r = self._cmd_add_plugin( default, auto=True, added=added, save=False ) if not r: return r self.core.call_all("config_add_plugin", plugin_name) if save: self.core.call_all("config_save") console.print(_("Plugin {} added").format(plugin_name)) return True def _cmd_remove_plugin( self, console, plugin_name, auto=True, removed=set(), save=True): removed.add(plugin_name) if auto: # look for plugins depending on this one # if they have no other plugin satisfying their dependency, # remove them too. for other_plugin in self.core.get_active_plugins(): if other_plugin in removed: continue deps = self.core.get_deps(other_plugin) for dep in deps: actives = dep['actives'] actives = actives.difference(removed) if len(actives) <= 0: console.print( _( "Removing plugin '{plugin_name}' due to" " missing dependency '{interface}'" ).format( plugin_name=other_plugin, interface=dep['interface'] ) ) self._cmd_remove_plugin( console, other_plugin, auto=auto, removed=removed, save=False ) break self.core.call_all("config_remove_plugin", plugin_name) if save: self.core.call_all("config_save") console.print(_("Plugin {} removed").format(plugin_name)) return True def _cmd_list_plugins(self, console): plugins = self.core.call_success("config_list_plugins") console.print(" " + _("Active plugins:")) for plugin in plugins: console.print(plugin) return list(plugins) def _cmd_reset_plugins(self, console): self.core.call_success("config_reset_plugins") self.core.call_all("config_save") console.print("Plugin list reseted") return True def _print_columns(self, console, columns): out = "" for (column_size, string) in columns: out += "| " out += ("{:" + str(column_size) + "}").format(string) out = out[1:] console.print(out) def _get_printable_deps( self, plugin_name, parents_requirements=set(), depth=0, already_printed=set()): header = "| " * (depth - 1) try: plugin = self.core.get_by_name(plugin_name) except KeyError: # Plugin not loaded --> can't get the info yield ( header + "|-- " + plugin_name, "(not loaded)", ) return str_plugin_name = plugin_name if plugin_name in already_printed: str_plugin_name = plugin_name + " (dup)" interfaces = plugin.get_interfaces() interfaces = [i for i in interfaces if i in parents_requirements] if len(interfaces) <= 0: interfaces = [""] for (idx, interface) in enumerate(interfaces): if idx == 0: yield ( header + "|-- " + str_plugin_name if depth > 0 else str_plugin_name, interface, ) else: yield ( header + "| |", interface, ) if plugin_name in already_printed: return [] already_printed.add(plugin_name) deps = plugin.get_deps() requirements = {d['interface'] for d in deps} requirements.update(parents_requirements) plugin_names = set() for (idx, dep) in enumerate(deps): plugins = self.core.get_by_interface(dep['interface']) plugin_names.update({plugin.__module__ for plugin in plugins}) plugin_names.update(dep['defaults']) plugin_names = list(plugin_names) plugin_names.sort() for (idx, plugin_name) in enumerate(plugin_names): for line in self._get_printable_deps( plugin_name, requirements, depth + 1, already_printed): yield line def _cmd_show_plugin(self, console, plugin_name): try: plugin = self.core.get_by_name(plugin_name) except KeyError: console.print(_("Plugin '%s' not enabled.") % plugin_name) return {} console.print(_("Plugin '%s':") % plugin_name) console.print("* " + _("Implements:")) for interf in plugin.get_interfaces(): console.print(" + " + interf) console.print("* " + _("Depends on:")) for dep in plugin.get_deps(): console.print(" + " + dep['interface']) for default in dep['defaults']: console.print(" - " + (_("suggested: %s") % default)) console.print("") deps = list(self._get_printable_deps(plugin_name)) column_headers = ( _("Plugin name"), _("Interface"), ) column_sizes = [len(c) + 1 for c in column_headers] for d in deps: for (idx, column_value) in enumerate(d): column_sizes[idx] = max( column_sizes[idx], len(column_value) + 1 ) total = sum(column_sizes) + (2 * len(column_sizes)) self._print_columns( console, ( (column_sizes[0], _("Plugin name")), (column_sizes[1], _("Interface")), ) ) console.print("-" * total) for d in deps: self._print_columns( console, [ (column_sizes[idx], column_value) for (idx, column_value) in enumerate(d) ] ) return { 'interface': plugin.get_interfaces(), 'deps': plugin.get_deps() } paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/cmd/util.py000066400000000000000000000016161456262201400261440ustar00rootroot00000000000000from .. import _ def ask_confirmation( console, question, default_interactive='n', default_non_interactive='n' ): if default_interactive == 'y': yesno = _("Y/n") else: yesno = _("y/N") if default_interactive == 'y': default_interactive = yesno[0].lower() # l10n else: default_interactive = yesno[-1].lower() # l10n if default_non_interactive == 'y': default_non_interactive = yesno[0].lower() # l10n else: default_non_interactive = yesno[-1].lower() # l10n try: reply = console.input(f"{question} [{yesno}] ") except KeyboardInterrupt: return 'n' if reply is None: reply = default_non_interactive else: reply = reply.strip().lower() if reply == "": reply = default_interactive return 'y' if reply == yesno[0].lower() else 'n' paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/000077500000000000000000000000001456262201400253135ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/__init__.py000066400000000000000000000156061456262201400274340ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2014 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . """ Paperwork configuration management code """ import collections import logging from .. import PluginBase LOGGER = logging.getLogger(__name__) class Setting(object): def __init__(self, core, section, token, default_value_func): self.core = core self.section = section self.token = token self.default_value_func = default_value_func def get(self): value = self.core.call_success( "config_backend_get", self.section, self.token, None ) if value is None: return self.default_value_func() else: return value def put(self, value): self.core.call_all( "config_backend_put", self.section, self.token, value ) class Plugin(PluginBase): """ Translate values from the configuration into more usable ones. Provides default values (except for plugins). """ def __init__(self): self.core = None self.settings = {} self.values = {} # applicatiom here is a bit more specific: paperwork-gtk, # paperwork-shell, etc. # It is used to known which plugin list must be loaded self.plugin_list_name = None self.observers = collections.defaultdict(set) def get_interfaces(self): return ['config'] def get_deps(self): return [ { 'interface': 'app', 'defaults': ['openpaperwork_core.app'], }, { 'interface': 'config_backend', 'defaults': ['openpaperwork_core.config.backend.configparser'], }, ] def init(self, core): self.core = core self.settings = {} def config_load(self): application = self.core.call_success("app_get_fs_name") LOGGER.info("Loading configuration for %s", application) self.values = {} self.core.call_all('config_backend_load', application) for observers in self.observers.values(): for observer in observers: observer() def config_load_plugins(self, plugin_list_name, default_plugins=[]): LOGGER.info("Loading plugins for '%s'", plugin_list_name) self.plugin_list_name = plugin_list_name self.core.call_all( 'config_backend_load_plugins', plugin_list_name, default_plugins ) def config_get_plugin_list_name(self): return self.plugin_list_name def config_save(self): LOGGER.info("Saving configuration") self.core.call_all('config_backend_save') def config_build_simple( self, section, token, default_value_func ): """ Provide a default simple implementation for a new setting that can be registered using 'config_register'. Arguments: - section: Section in which option must be stored (see ConfigParser) - token: token name for the option (see ConfigParser) - default_value_func: function to call to get the default value if none is stored in the file. """ return Setting(self.core, section, token, default_value_func) def config_register(self, key: str, setting): """ Add another setting to manage. Make this setting available to other components. Arguments: - key: configuration key - setting: Setting must be an object providing a method `get()` and a method `put(value)`. See :func:`config_build_simple` to get quickly a default implementation. """ LOGGER.debug("Registering configuration: %s", key) self.settings[key] = setting def config_list_options(self): return list(self.settings.keys()) def config_get_setting(self, key: str): return self.settings[key] def config_get(self, key: str): LOGGER.debug("Config get: %s", key) if key not in self.settings: return None if key not in self.values: self.values[key] = self.settings[key].get() return self.values[key] def config_get_default(self, key: str): return self.settings[key].default_value_func() def config_put(self, key: str, value): """ Store a setting value. Warning: You must call :func:`config_save` so the changes are actually saved. Arguments: - key: configuration key, - value: can be of many types (`str`, `int`, etc). """ LOGGER.debug("Config put: %s", key) self.settings[key].put(value) self.values[key] = value if key in self.observers: for callback in self.observers[key]: callback() def config_add_plugin(self, plugin, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name LOGGER.debug("Config add plugin: %s -> %s", plugin, plugin_list_name) self.core.call_all( 'config_backend_add_plugin', plugin_list_name, plugin ) def config_remove_plugin(self, plugin, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name LOGGER.debug( "Config remove plugin: %s -> %s", plugin, plugin_list_name ) self.core.call_all( 'config_backend_remove_plugin', plugin_list_name, plugin ) def config_list_plugins(self, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name return self.core.call_success( "config_backend_list_active_plugins", plugin_list_name ) def config_reset_plugins(self, plugin_list_name=None): if plugin_list_name is None: plugin_list_name = self.plugin_list_name LOGGER.debug("Config reset plugin: %s", plugin_list_name) return self.core.call_success( "config_backend_reset_plugins", plugin_list_name ) def config_add_observer(self, key: str, callback): self.observers[key].add(callback) def config_remove_observer(self, key: str, callback): self.observers[key].remove(callback) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/automatic_plugin_reset.py000066400000000000000000000027211456262201400324350ustar00rootroot00000000000000import logging from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): PRIORITY = 1000 def config_load_plugins(self, plugin_list_name, default_plugins=[]): old_default = self.core.call_success( "config_backend_get", "default_plugins", plugin_list_name, None ) if old_default is None: # no previously known list of default plugins. Weird but not much # we can do about it. self.core.call_all( "config_backend_put", "default_plugins", plugin_list_name, default_plugins ) self.core.call_all("config_backend_save") return old_default = sorted(old_default) default_plugins = sorted(default_plugins) if old_default == default_plugins: # default list hasn't changed. So we assume the custom list # is still fine. return LOGGER.warning( "Default plugin list has changed." " Reseting plugin list to its new default." ) LOGGER.warning("Old default list: %s", old_default) LOGGER.warning("New default list: %s", default_plugins) self.core.call_all("config_backend_reset_plugins", plugin_list_name) self.core.call_all( "config_backend_put", "default_plugins", plugin_list_name, default_plugins ) self.core.call_all("config_backend_save") paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/backend/000077500000000000000000000000001456262201400267025ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/backend/__init__.py000066400000000000000000000000001456262201400310010ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/backend/configparser.py000066400000000000000000000253331456262201400317440ustar00rootroot00000000000000""" Manages a configuration file using configparser. """ import collections import configparser import datetime import logging from ... import (_, PluginBase) LOGGER = logging.getLogger(__name__) class ConfigBool(object): def __init__(self, value=False): if isinstance(value, str): self.value = (value.lower() == 'true') else: self.value = value def __eq__(self, o): return (self.value == o) def __bool__(self): return self.value def __str__(self): return str(self.value) def get_value(self): return self.value class ConfigDate(object): DATE_FORMAT = "%Y-%m-%d" def __init__(self, value=datetime.datetime(year=1971, month=1, day=1)): if isinstance(value, str): self.value = ( datetime.datetime .strptime(value, self.DATE_FORMAT) .date() ) else: self.value = value def __eq__(self, o): return (self.value == o) def __str__(self): return self.value.strftime(self.DATE_FORMAT) def get_value(self): return self.value class ConfigList(object): SEPARATOR = ";" def __init__(self, value=None, elements=None): if elements is None: elements = [] self.elements = elements if value is not None: if isinstance(value, str): if value != '': elements = value.split(self.SEPARATOR) for i in elements: (t, v) = i.split(_TYPE_SEPARATOR, 1) self.elements.append(_STR_TO_TYPE[t](v)) elif hasattr(value, 'elements'): self.elements = value.elements[:] else: self.elements = list(value) def __iter__(self): return iter(self.elements) def __contains__(self, o): return o in self.elements def __getitem__(self, *args, **kwargs): return self.elements.__getitem__(*args, **kwargs) def __setitem__(self, *args, **kwargs): return self.elements.__setitem__(*args, **kwargs) def __len__(self): return len(self.elements) def append(self, value): self.elements.append(value) def remove(self, value): self.elements.remove(value) def __str__(self): out = [] for e in self.elements: out.append("{}{}{}".format( _TYPE_TO_STR[type(e)], _TYPE_SEPARATOR, str(e) )) return self.SEPARATOR.join(out) def get_value(self): return [ e.get_value() if hasattr(e, 'get_value') else e for e in self.elements ] class ConfigDict(object): SEPARATOR_ITEMS = ";" SEPARATOR_KEYVALS = "=" def __init__(self, value=None, elements={}): self.elements = elements if value is not None: if isinstance(value, str): elements = value.split(self.SEPARATOR_ITEMS) for i in elements: (k, v) = i.split(self.SEPARATOR_KEYVALS, 1) (t, v) = v.split(_TYPE_SEPARATOR, 1) self.elements[k] = _STR_TO_TYPE[t](v) elif hasattr(value, 'elements'): self.elements = value.elements[:] else: self.elements = dict(value) def __iter__(self): return iter(self.elements) def __contains__(self, o): return o in self.elements def __getitem__(self, *args, **kwargs): return self.elements.__getitem__(*args, **kwargs) def __setitem__(self, *args, **kwargs): return self.elements.__setitem__(*args, **kwargs) def __len__(self): return len(self.elements) def __str__(self): out = [] for (k, v) in self.elements.items(): out.append("{}{}{}{}{}".format( k, self.SEPARATOR_KEYVALS, _TYPE_TO_STR[type(v)], _TYPE_SEPARATOR, str(v) )) return self.SEPARATOR_ITEMS.join(out) def get_value(self): return { k: v.get_value() if hasattr(v, 'get_value') else v for (k, v) in self.elements.items() } _TYPE_TO_STR = { bool: "bool", ConfigBool: "bool", ConfigDate: "date", ConfigDict: "dict", ConfigList: "list", datetime.date: "date", dict: "dict", float: "float", int: "int", list: "list", str: "str", tuple: "list", } _STR_TO_TYPE = { "bool": ConfigBool, "date": ConfigDate, "dict": ConfigDict, "list": ConfigList, "float": float, "int": int, "str": str, } _TYPE_SEPARATOR = ":" class Plugin(PluginBase): TEST_FILE_URL = None # unit tests only def __init__(self): self.config = configparser.RawConfigParser() self.base_path = None self.application_name = None self.config_path = None self.observers = collections.defaultdict(set) self.core = None self.default_plugins = [] def get_interfaces(self): return ['config_backend'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, ] def init(self, core): self.core = core if self.base_path is None: self.base_path = self.core.call_success("paths_get_config_dir") def _get_filepath(self): if self.TEST_FILE_URL is not None: return self.TEST_FILE_URL return self.core.call_success( "fs_join", self.base_path, self.application_name + ".conf" ) def config_backend_load(self, application_name): self.application_name = application_name self.config_path = self._get_filepath() self.config = configparser.RawConfigParser() LOGGER.info("Loading configuration '%s' ...", self.config_path) if self.core.call_success("fs_exists", self.config_path) is not None: fd = self.core.call_success("fs_open", self.config_path, 'r') with fd: self.config.read_file(fd) else: LOGGER.warning( "Cannot load configuration '%s'. File does not exist", self.config_path ) for observers in self.observers.values(): for observer in observers: observer() def config_backend_save(self, application_name=None): if application_name is not None: self.application_name = application_name config_path = self._get_filepath() LOGGER.info("Writing configuration '%s' ...", config_path) with self.core.call_success("fs_open", config_path, 'w') as fd: self.config.write(fd) def config_backend_load_plugins(self, opt_name, default=[]): """ Load and init the plugin list from the configuration. """ self.default_plugins = default modules = self.config_backend_get( "plugins", opt_name, ConfigList(None, self.default_plugins) ) LOGGER.info( "Loading and initializing plugins from configuration: %s", str(modules) ) for module in modules: self.core.load(module) self.core.init() def config_backend_list_active_plugins(self, opt_name): return self.config_backend_get( "plugins", opt_name, ConfigList(None, self.default_plugins) ) def config_backend_reset_plugins(self, opt_name): self.config_backend_del("plugins", opt_name) def config_backend_add_plugin(self, opt_name, module_name): LOGGER.info("Adding plugin '%s' to configuration", module_name) modules = self.config_backend_list_active_plugins(opt_name) modules.append(module_name) self.config_backend_put("plugins", opt_name, modules) def config_backend_remove_plugin(self, opt_name, module_name): LOGGER.info("Removing plugin '%s' from configuration", module_name) modules = self.config_backend_list_active_plugins(opt_name) try: modules.remove(module_name) except ValueError: LOGGER.warning("Plugin '%s' not found", module_name) self.config_backend_put("plugins", opt_name, modules) def config_backend_put(self, section, key, value): """ Section must be a string. Key must be a string. """ LOGGER.debug("Configuration: %s:%s <-- %s", section, key, str(value)) if value is None: if section not in self.config: return if key not in self.config[section]: return self.config[section].pop(key) return t_str = _TYPE_TO_STR[type(value)] t = _STR_TO_TYPE[t_str] value = t(value) value = "{}{}{}".format(t_str, _TYPE_SEPARATOR, str(value)) if section not in self.config: self.config[section] = {key: value} else: self.config[section][key] = value for observer in self.observers[section]: observer() def config_backend_del(self, section, key): if section not in self.config: return if key not in self.config[section]: return self.config.remove_option(section, key) def config_backend_get(self, section, key, default=None): try: value = self.config[section][key] if value.strip() == "": return None (t, value) = value.split(_TYPE_SEPARATOR, 1) r = _STR_TO_TYPE[t](value) if hasattr(r, 'get_value'): r = r.get_value() LOGGER.debug("Configuration: %s:%s --> %s", section, key, str(r)) return r except KeyError: LOGGER.debug( "Configuration: %s:%s --> %s (default value)", section, key, str(default) ) return default def config_backend_add_observer(self, section, callback): self.observers[section].add(callback) def config_backend_remove_observer(self, section, callback): self.observers[section].remove(callback) def bug_report_get_attachments(self, out: dict): if self.config_path is None: return if self.core.call_success("fs_exists", self.config_path) is None: return out['config'] = { 'include_by_default': True, 'date': None, 'file_type': _("App. config."), 'file_url': self.config_path, 'file_size': self.core.call_success("fs_getsize", self.config_path) } paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/config/fake.py000066400000000000000000000045101456262201400265730ustar00rootroot00000000000000from .. import PluginBase class Setting(object): def __init__(self, value, default_func): self.value = value self.default_value_func = default_func self.observers = [] def get(self): if self.value is None: return self.default_value_func() return self.value def put(self, v): self.value = v for obs in self.observers: obs() def add_observer(self, obs): self.observers.append(obs) def remove_observer(self, obs): self.observers.remove(obs) class Plugin(PluginBase): """ Translate values from the configuration into more usable ones. Provides default values (except for plugins). """ def __init__(self): super().__init__() self._settings = {} def __get_settings(self): return {k: v.get() for (k, v) in self._settings.items()} def __set_settings(self, new_settings): self._settings = { k: Setting(v, lambda: None) for (k, v) in new_settings.items() } settings = property(__get_settings, __set_settings) def get_interfaces(self): return ['config'] def config_load(self): pass def config_load_plugins(self, plugin_list_name, default_plugins=[]): pass def config_save(self): pass def config_build_simple(self, section, token, default): return Setting(None, default) def config_register(self, key, setting): if key not in self._settings: # don't smash test settings self._settings[key] = setting def config_get_setting(self, key): return self._settings[key] def config_get(self, key): return self._settings[key].get() def config_get_default(self, key): return self._settings[key].default_value_func() def config_put(self, key, value): self._settings[key].put(value) def config_add_plugin(self, plugin): raise NotImplementedError() def config_remove_plugin(self, plugin): raise NotImplementedError() def config_list_plugins(self): raise NotImplementedError() def config_add_observer(self, key: str, callback): self._settings[key].add_observer(callback) def config_remove_observer(self, key: str, callback): self._settings[key].remove_observer(callback) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/data_versioning.py000066400000000000000000000037531456262201400276040ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) # TODO(Jflesch): this version shouldn't be common to all applications using # Openpaperwork-core DATA_VERSION = 2 class Plugin(openpaperwork_core.PluginBase): """ Keep a version number in ~/.local/share/paperwork2/data_version. If the version doesn't match 'DATA_VERSION', right before syncing, delete ~/.local/share/paperwork2 to force a full synchronisation. """ def get_interfaces(self): return ['data_versioning'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, ] def init(self, core): super().init(core) data_dir = self.core.call_success("paths_get_data_dir") data_ver_file = self.core.call_success( "fs_join", data_dir, "data_version" ) data_version = -1 if self.core.call_success("fs_exists", data_ver_file): with self.core.call_success("fs_open", data_ver_file, 'r') as fd: data_version = int(fd.read().strip()) LOGGER.info( "Expected data version: %d ; Current data version: %d", DATA_VERSION, data_version ) if data_version != DATA_VERSION: LOGGER.warning( "Data version doesn't match (%d != %d). Forcing full sync", data_version, DATA_VERSION ) self.core.call_success("fs_rm_rf", data_dir, trash=False) # call 'paths_get_data_dir' again to recreate the data directory data_dir = self.core.call_success("paths_get_data_dir") with self.core.call_success("fs_open", data_ver_file, 'w') as fd: fd.write(str(DATA_VERSION)) self.core.call_all("on_data_files_deleted") paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/debug/000077500000000000000000000000001456262201400251345ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/debug/__init__.py000066400000000000000000000000001456262201400272330ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/debug/objgraph.py000066400000000000000000000024521456262201400273050ustar00rootroot00000000000000import gc import logging import tempfile import weakref import objgraph from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def __init__(self): super().__init__() self.objs = [] self.graph_path = tempfile.mktemp(suffix='.png') def get_interfaces(self): return ['memleak_detector'] def on_objref_track(self, obj): assert obj is not None self.objs.append((str(type(obj)), weakref.ref(obj))) def on_objref_graph(self): to_graph = [] objs = self.objs.copy() gc.collect() for (idx, (type_name, wref)) in reversed(list(enumerate(objs))): obj = wref() if obj is None: LOGGER.info("Object of type %s has disappeared", type_name) self.objs.pop(idx) continue to_graph.append(obj) if len(to_graph) <= 0: LOGGER.info("Nothing to graph") return LOGGER.info( "Making reference graph for %d objects to %s", len(to_graph), self.graph_path ) objgraph.show_backrefs(to_graph, filename=self.graph_path) def on_memleak_track_stop(self): LOGGER.info("Most common object types:") objgraph.show_most_common_types() paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/debug/pympler.py000066400000000000000000000014571456262201400272050ustar00rootroot00000000000000import gc import logging import pympler.tracker from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def __init__(self): super().__init__() self.tracker = None def get_interfaces(self): return ['memleak_detector'] def on_memleak_track_start(self): self.tracker = None LOGGER.info("Garbage collecting ...") gc.collect() LOGGER.info("Starting memory leaks tracking ...") self.tracker = pympler.tracker.SummaryTracker() def on_memleak_track_stop(self): if self.tracker is not None: LOGGER.info("Garbage collecting ...") gc.collect() LOGGER.info("Stopping memory leaks tracking ...") self.tracker.print_diff() self.tracker = None paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/deps.py000066400000000000000000000024161456262201400253560ustar00rootroot00000000000000CAIRO = { 'debian': 'python3-gi-cairo', 'fedora': 'python3-pycairo', 'gentoo': 'dev-python/pycairo', # Python 3 ? 'linuxmint': 'python-gi-cairo', # Python 3 ? 'raspbian': 'python3-gi-cairo', 'suse': 'python-cairo', # Python 3 ? 'ubuntu': 'python3-gi-cairo', } GDK = { 'debian': 'gir1.2-gdkpixbuf-2.0', 'linuxmint': 'gir1.2-gdkpixbuf-2.0', 'raspbian': 'gir1.2-gdkpixbuf-2.0', 'ubuntu': 'gir1.2-gdkpixbuf-2.0', } GI = { 'debian': 'python3-gi', 'fedora': 'python3-gobject-base', 'gentoo': 'dev-python/pygobject', # Python 3 ? 'linuxmint': 'python3-gi', 'raspbian': 'python3-gi', 'suse': 'python-gobject', # Python 3 ? 'ubuntu': 'python3-gi', } GLIB = { 'debian': 'gir1.2-glib-2.0', 'linuxmint': 'gir1.2-glib-2.0', 'raspbian': 'gir1.2-glib-2.0', 'ubuntu': 'gir1.2-glib-2.0', } PANGO = { 'debian': 'gir1.2-pango-1.0', 'linuxmint': 'gir1.2-pango-1.0', 'raspbian': 'gir1.2-glib-2.0', 'ubuntu': 'gir1.2-pango-1.0', } POPPLER = { 'debian': 'gir1.2-poppler-0.18', 'fedora': 'poppler-glib', 'gentoo': 'app-text/poppler', 'linuxmint': 'gir1.2-poppler-0.18', 'raspbian': 'gir1.2-poppler-0.18', 'suse': 'typelib-1_0-Poppler-0_18', 'ubuntu': 'gir1.2-poppler-0.18', } paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/display/000077500000000000000000000000001456262201400255135ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/display/__init__.py000066400000000000000000000000001456262201400276120ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/display/print.py000066400000000000000000000021571456262201400272260ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import sys import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.output = [] def get_interfaces(self): return ['print'] def print(self, txt): self.output.append(txt) def print_flush(self): output = "\n".join(self.output) sys.stdout.write(output) self.output = [] paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/external_apps/000077500000000000000000000000001456262201400267135ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/external_apps/__init__.py000066400000000000000000000000001456262201400310120ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/external_apps/dbus.py000066400000000000000000000033711456262201400302260ustar00rootroot00000000000000""" This plugin requires pydbus. If Pydbus is not installed. It just does nothing. """ import logging import os import socket import time try: import pydbus PYDBUS_AVAILABLE = True except ImportError: PYDBUS_AVAILABLE = False from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): PRIORITY = 50 def get_interfaces(self): return ['external_apps'] def get_deps(self): return [] def _get_file_manager_proxy(self): bus = pydbus.SessionBus() proxy = bus.get( "org.freedesktop.FileManager1", "/org/freedesktop/FileManager1" ) iface = proxy['org.freedesktop.FileManager1'] return iface def _open_url(self, func_name, url): if not PYDBUS_AVAILABLE: LOGGER.info("Pydbus is not available") return None try: uid = "{}{}_TIME{}".format( socket.gethostname(), os.getpid(), int(time.time()) ) iface = self._get_file_manager_proxy() LOGGER.info("Opening %s using Dbus", url) getattr(iface, func_name)([url], uid) except Exception as exc: LOGGER.error( "Failed to open %s using Dbus", url, exc_info=exc ) return None return True def external_app_open_file(self, file_url): # doesn't really open the file, but close enough. return self._open_url('ShowItems', file_url) def external_app_open_folder(self, folder_url): return self._open_url('ShowFolders', folder_url) def external_app_can_send_as_attachment(self) -> None: return None def external_app_send_as_attachment(self, uri) -> None: return None paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/external_apps/windows.py000066400000000000000000000020071456262201400307560ustar00rootroot00000000000000import logging import os from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): PRIORITY = 100 def get_interfaces(self): return ['external_apps'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, ] def external_app_open_file(self, file_url): if not hasattr(os, 'startfile'): return None # os.startfile() is Windows-only. LOGGER.info("Opening %s with os.startfile()", file_url) assert file_url.startswith("file://") file_path = self.core.call_success("fs_safe", file_url) os.startfile(file_path) return True def external_app_open_folder(self, folder_url): return self.external_app_open_file(folder_url) def external_app_can_send_as_attachment(self) -> None: return None def external_app_send_as_attachment(self, uri) -> None: return None paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/external_apps/xdg.py000066400000000000000000000031561456262201400300540ustar00rootroot00000000000000import logging import os import subprocess import shutil from typing import Optional from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def get_interfaces(self): return ['external_apps'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, ] def external_app_open_file(self, file_url): if shutil.which("xdg-open") is None: return None LOGGER.info("Opening %s with xdg-open", file_url) os.spawnlp(os.P_NOWAIT, 'xdg-open', 'xdg-open', file_url) return True def external_app_open_folder(self, folder_url): return self.external_app_open_file(folder_url) def external_app_can_send_as_attachment(self) -> bool: return shutil.which("xdg-email") is not None def external_app_send_as_attachment(self, file_url: str) -> Optional[bool]: if not self.external_app_can_send_as_attachment(): return None LOGGER.info("Sending %s as attachment with xdg-email", file_url) assert file_url.startswith("file://") file_path = self.core.call_success("fs_unsafe", file_url) # xdg-email returns immediately, and we are interested in whether is # raises an exception try: subprocess.run(['xdg-email', '--attach', file_path], check=True) except subprocess.CalledProcessError as e: raise OSError( f"Failed to run xdg-email to send {file_path} as attachment" ) from e return True paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/flatpak.py000066400000000000000000000052171456262201400260470ustar00rootroot00000000000000import logging import os import shutil import tempfile from . import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): PRIORITY = 75 def __init__(self): super().__init__() self.tmp_files = set() self.flatpak = False self.tmp_dir = None def get_interfaces(self): return [ 'flatpak', 'stats', ] def get_deps(self): return [ { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, ] def init(self, core): super().init(core) self.flatpak = (os.name == 'posix') and bool(self.core.call_success( "fs_isdir", "file:///app" )) LOGGER.info("Flatpak environment: %s", self.flatpak) self.tmp_dir = self.core.call_success( "fs_join", self.core.call_success("paths_get_data_dir"), "tmp" ) def is_in_flatpak(self): if self.flatpak: return True return None def fs_mktemp(self, prefix=None, suffix=None, mode='w+b', **kwargs): """ Modifies slightly the behaviour of fs_mktemp(): When making a bug report, we use temporary files. We need the user to be able to access those temporary files with external applications. With Flatpak, the easiest way for that is to place the temporary files somewhere in the user home directory. """ if not self.flatpak: return None self.core.call_success("fs_mkdir_p", self.tmp_dir) tmp = tempfile.NamedTemporaryFile( prefix=prefix, suffix=suffix, delete=False, mode=mode, dir=self.core.call_success("fs_unsafe", self.tmp_dir) ) LOGGER.info("Flatpak tmp file: %s --> %s", self.tmp_dir, tmp.name) self.tmp_files.add(tmp.name) return (self.core.call_success("fs_safe", tmp.name), tmp) def on_quit(self): if not self.flatpak: return if self.core.call_success("fs_exists", self.tmp_dir) is not None: shutil.rmtree(self.core.call_success("fs_unsafe", self.tmp_dir)) def stats_get(self, out: dict): if not self.flatpak: return if 'os_name' in out: out['os_name'] += ' (flatpak)' else: out['os_name'] = 'GNU/Linux (flatpak)' paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/frozen.py000066400000000000000000000020211456262201400257160ustar00rootroot00000000000000""" Takes care of the few things that must be done if we are running in an executable created with cx_freeze. It must be loaded as early as possible. """ import multiprocessing import os import sys from . import PluginBase class Plugin(PluginBase): def __init__(self): if not getattr(sys, 'frozen', False): return self._set_meipass() multiprocessing.freeze_support() def get_interfaces(self): return ['frozen'] def _set_meipass(self): # If sys.frozen, then Pyocr (and possibly others) needs MEIPASS to be # set *before* importing it. if getattr(sys, '_MEIPASS', False): # Pyinstaller case return # Cx_Freeze case if "python" not in sys.executable or '__file__' not in globals(): sys._MEIPASS = os.path.dirname(os.path.realpath(sys.executable)) else: sys._MEIPASS = os.path.realpath(os.path.join( os.path.dirname(os.path.realpath(__file__)), "..", ".." )) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/fs/000077500000000000000000000000001456262201400244565ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/fs/__init__.py000066400000000000000000000055711456262201400265770ustar00rootroot00000000000000import hashlib import logging import os import pathlib import urllib import urllib.parse import openpaperwork_core LOGGER = logging.getLogger(__name__) class CommonFsPluginBase(openpaperwork_core.PluginBase): def __init__(self): """ Should be used only by sub-classes """ super().__init__() def get_interfaces(self): return ['fs'] @staticmethod def fs_safe(uri): """ Make sure the specified URI is actually an URI and not a Unix path. Returns: - An URI """ LOGGER.debug("safe: %s", uri) if uri[:2] == "\\\\" or "://" in uri: LOGGER.debug("safe: --> %s", uri) return uri return pathlib.Path(uri).as_uri() @staticmethod def fs_unsafe(uri): """ Turn an URI into an Unix path, whenever possible. Shouldn't be used at all. """ LOGGER.debug("unsafe: %s", uri) if "://" not in uri and uri[:2] != "\\\\": LOGGER.debug("unsafe: --> %s", uri) return uri if not uri.startswith("file://"): LOGGER.debug("unsafe: --> EXC") raise Exception("TARGET URI SHOULD BE A LOCAL FILE") uri = uri[len("file://"):] if os.name == 'nt' and uri[0] == '/': # for some reason, URIs on Windows start with # "file:///C:\..." instead of "file://C:\..." uri = uri[1:] uri = urllib.parse.unquote(uri) return uri # It seems urllib.parse.urljoin doesn't work any protocol. For instance, # it doesn't play nice with smb:// and davs:// URLLIB_SUPPORTED_PROTOCOLS = {"http", "https", "file", "ftp"} def fs_join(self, base, url): if not base.endswith("/"): base += "/" protocol = base.split("://", 1)[0].lower() if protocol in self.URLLIB_SUPPORTED_PROTOCOLS: return urllib.parse.urljoin(base, url) return base + url def fs_basename(self, url): parsed_url = urllib.parse.urlparse(url) path = parsed_url.path if path == "": path = parsed_url.hostname if path is None: return None basename = os.path.basename(path) # Base name can be safely unquoted return urllib.parse.unquote(basename) def fs_dirname(self, url): # dir name should not be unquoted. It could mess up the URI return os.path.dirname(url) def fs_hash(self, url): with self.core.call_success("fs_open", url, 'rb') as fd: content = fd.read() return int(hashlib.sha256(content).hexdigest(), 16) def fs_copy(self, origin_url, dest_url): """ default generic implementation """ with open(origin_url, 'rb') as fd: content = fd.read() with open(dest_url, 'wb') as fd: fd.write(content) return True paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/fs/fake.py000066400000000000000000000140661456262201400257450ustar00rootroot00000000000000""" Mock implementation of the plugin interface 'fs'. Useful for tests only. """ import io import logging import os from . import CommonFsPluginBase from . import memory LOGGER = logging.getLogger(__name__) class FakeFileAdapter(io.RawIOBase): def __init__(self, fs_plugin, path, content, mode='r'): super().__init__() self.fs_plugin = fs_plugin self.path = path self.content = content if 'w' not in mode else None self.pos = len(self.content) if 'a' in mode else 0 self.mode = mode if self.content is None: self.content = b'' if 'b' in mode else '' def readable(self): return True def writable(self): return 'w' in self.mode or 'a' in self.mode def read(self, size=-1): if size < 0: r = len(self.content[self.pos:]) else: r = min(size, len(self.content[self.pos:])) out = self.content[self.pos:self.pos + r] self.pos += r return out def readall(self): return self.content def readinto(self, b): raise NotImplementedError() def readline(self, size=-1): r = self.content[self.pos:] r = r.split("\n", 1) self.pos += len(r[0]) + 1 return r[0] + "\n" def readlines(self, hint=-1): self.pos = len(self.content) return [ r + "\n" for r in self.content.split("\n") ] def seek(self, offset, whence=os.SEEK_SET): if whence == os.SEEK_CUR: self.pos += offset elif whence == os.SEEK_SET: self.pos = offset else: raise NotImplementedError() def seekable(self): return True def tell(self): return self.pos def flush(self): pass def truncate(self, size=None): raise NotImplementedError() def isatty(self): return False def write(self, b): self.content = self.content[:self.pos] self.content += b self.pos += len(b) return len(b) def writelines(self, lines): raise NotImplementedError() def close(self): if 'a' in self.mode or 'w' in self.mode: d = self.fs_plugin.fs for p in self.path[:-1]: d = d[p] d[self.path[-1]] = self.content self.flush() super().close() def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() class Plugin(CommonFsPluginBase): def __init__(self, fs=None): """ Test implementation. `fs` should have the following format: { 'base_dir': { 'sub_dir_a': {}, 'sub_dir_b': { 'file_a': "content_file_a", 'file_b': "content_file_b", } } } """ super().__init__() if fs is None: self.fs = {} else: self.fs = fs @staticmethod def _get_path(url): assert url.lower().startswith("file:///") url = url[len('file:///'):] return url.split('/') def fs_open(self, url, mode='r', **kwargs): path = self._get_path(url) f = self.fs for p in path[:-1]: f = f[p] if path[-1] in f: f = f[path[-1]] assert isinstance(f, str) or isinstance(f, bytes) elif 'b' in mode: f = b"" else: f = "" return FakeFileAdapter(self, path, f, mode) def fs_exists(self, url): path = self._get_path(url) f = self.fs for p in path: if p not in f: return None f = f[p] return True def fs_listdir(self, url): path = self._get_path(url) f = self.fs for p in path: try: f = f[p] except KeyError: return None assert isinstance(f, dict) return [url + "/" + k for k in f.keys()] def fs_rename(self, old_url, new_url): old_path = self._get_path(old_url) old_dir = self.fs for p in old_path[:-1]: old_dir = old_dir[p] new_path = self._get_path(new_url) new_dir = self.fs for p in new_path[:-1]: new_dir = new_dir[p] old_file = old_dir.pop(old_path[-1]) new_dir[new_path[-1]] = old_file def fs_unlink(self, url, **kwargs): self.fs_rm_rf(url) def fs_rm_rf(self, url, **kwargs): path = self._get_path(url) f = self.fs for p in path[:-1]: if p not in f: return None f = f[p] assert isinstance(f, dict) filename = url.split("/")[-1] if filename in f: f.pop(filename) return True return None def fs_get_mtime(self, url): return 0 def fs_getsize(self, url): path = self._get_path(url) f = self.fs for p in path: f = f[p] return len(f) def fs_isdir(self, url): path = self._get_path(url) f = self.fs for p in path: if p not in f: return None f = f[p] if isinstance(f, dict): return True return None def fs_copy(self, old_url, new_url): raise NotImplementedError() def fs_mkdir_p(self, url): path = self._get_path(url) f = self.fs for p in path[:-1]: if p not in f: f[p] = {} f = f[p] name = url.split("/")[-1] if name not in f: f[name] = {} return True def fs_recurse(self, parent_uri, dir_included=False): raise NotImplementedError() def fs_hide(self, uri): pass def fs_get_mime(self, uri): pass def fs_iswritable(self, url): return True def fs_mktemp(self, prefix=None, suffix=None, mode='w+b', **kwargs): name = "file://tmp/temporary_file" + suffix return (name, memory.MemoryFileAdapter(self, name, mode)) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/fs/memory.py000066400000000000000000000170171456262201400263460ustar00rootroot00000000000000""" Provides support for URIs "memory://". Those files are actually stored in memory. It is only useful for temporary files. It has been made as a plugin so it can easily be disabled on low-memory systems (will fall back on gio.fs --> real on-disk files). """ import io import itertools import logging import time from . import CommonFsPluginBase LOGGER = logging.getLogger(__name__) class _MemoryFileAdapter(io.RawIOBase): def __init__(self, plugin, key, mode='r'): super().__init__() self.plugin = plugin self.mode = mode self.key = key self.io = None self.io_cls = io.BytesIO if 'b' in mode else io.StringIO if 'r' in mode or 'a' in mode: if key not in self.plugin.fs: raise FileNotFoundError(key) data = self.plugin.fs[key][1] if 'b' in mode and isinstance(data, str): data = data.encode("utf-8") elif 'b' not in mode and isinstance(data, bytes): data = data.decode("utf-8") self.io = self.io_cls(data) elif 'w' in mode: self.io = self.io_cls() self.plugin.fs[self.key] = ( time.time(), b"" if 'b' in mode else "" ) self.get_content = ( self.io.getbuffer if 'b' in mode else self.io.getvalue ) self.read = self.io.read if hasattr(self.io, 'read') else None self.readall = self.io.readall if hasattr(self.io, 'readall') else None self.readinto = ( self.io.readinto if hasattr(self.io, 'readinto') else None ) self.readline = ( self.io.readline if hasattr(self.io, 'readline') else None ) self.readlines = ( self.io.readlines if hasattr(self.io, 'readlines') else None ) self.seek = self.io.seek if hasattr(self.io, 'seek') else None self.tell = self.io.tell if hasattr(self.io, 'tell') else None self.truncate = ( self.io.truncate if hasattr(self.io, 'truncate') else None ) self.write = self.io.write if hasattr(self.io, 'write') else None self.writelines = ( self.io.writelines if hasattr(self.io, 'writelines') else None ) def readable(self): return 'r' in self.mode or '+' in self.mode def writable(self): return 'w' in self.mode or 'a' in self.mode def seekable(self): return True def fileno(self): raise io.UnsupportedOperation("fileno() called on memory object") def isatty(self): return False def writelines(self, lines): if 'b' in self.mode: self.write(b"".join(lines)) else: self.write("".join(lines)) def flush(self): super().flush() if hasattr(self.io, 'flush'): self.io.flush() if 'w' not in self.mode and 'a' not in self.mode: return if 'b' in self.mode: self.plugin.fs[self.key] = (time.time(), bytes(self.get_content())) else: self.plugin.fs[self.key] = (time.time(), str(self.get_content())) def close(self): self.flush() super().close() def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() class Plugin(CommonFsPluginBase): PRIORITY = 100 # to be called first for fs_mktemp def __init__(self): super().__init__() # self.fs = {id: (mtime, content), id: (mtime, content), ...} self.fs = {} self.id_gen = itertools.count() @staticmethod def _get_memory_id(uri): if not uri.startswith("memory://"): return None return uri[len("memory://"):] def fs_open(self, uri, mode='r', needs_fileno=False, **kwargs): if needs_fileno: return None mem_id = self._get_memory_id(uri) if mem_id is None: return None return _MemoryFileAdapter(self, mem_id, mode) def fs_exists(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return None return mem_id in self.fs def fs_listdir(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return mem_id += '/' out = [] for k in self.fs.keys(): if k.startswith(mem_id) and '/' not in k[len(mem_id):]: out.append(k) return out def fs_rename(self, old_url, new_url): old_mem_id = self._get_memory_id(old_url) new_mem_id = self._get_memory_id(old_url) if old_mem_id is None or new_mem_id is None: return f = self.fs.pop(old_mem_id) self.fs[new_mem_id] = f return True def fs_unlink(self, url, **kwargs): mem_id = self._get_memory_id(url) if mem_id is None: return self.fs.pop(mem_id) return True def fs_rm_rf(self, url, **kwargs): mem_id = self._get_memory_id(url) if mem_id is None: return if mem_id in self.fs: self.fs.pop(mem_id) mem_id += '/' for k in list(self.fs.keys()): if k.startswith(mem_id): self.fs.pop(k) return True def fs_get_mtime(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return return self.fs[mem_id][0] def fs_getsize(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return return len(self.fs[mem_id][1]) def fs_isdir(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return None mem_id += '/' for k in list(self.fs.keys()): if k.startswith(mem_id): return True return None def fs_copy(self, old_url, new_url): old_mem_id = self._get_memory_id(old_url) new_mem_id = self._get_memory_id(old_url) if old_mem_id is None and new_mem_id is None: return None if old_mem_id is None or new_mem_id is None: # One memory url, one local filesystem url # use the more generic and cross-FS method return super().fs_copy(old_url, new_url) self.fs[new_mem_id] = self.fs[old_mem_id] return new_url def fs_mkdir_p(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return None # nothing to do actually return True def fs_recurse(self, parent_url, dir_included=False): mem_id = self._get_memory_id(parent_url) if mem_id is None: return mem_id += '/' out = [] for k in self.fs.keys(): if k.startswith(mem_id): out.append(k) return out def fs_hide(self, url): return None def fs_get_mime(self, url): return None def fs_iswritable(self, url): mem_id = self._get_memory_id(url) if mem_id is None: return None return True def fs_mktemp( self, prefix=None, suffix=None, mode='w+b', on_disk=False, **kwargs ): assert prefix is None or '/' not in prefix assert suffix is None or '/' not in suffix if on_disk: return name = "{}{}{}".format( prefix if prefix is not None else "", next(self.id_gen), suffix if suffix is not None else "" ) return ("memory://" + name, _MemoryFileAdapter(self, name, mode)) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/fs/python.py000066400000000000000000000120211456262201400263450ustar00rootroot00000000000000""" Provides support for URIs "file://". """ import codecs import logging import os import os.path import shutil import tempfile from . import CommonFsPluginBase LOGGER = logging.getLogger(__name__) class Plugin(CommonFsPluginBase): def __init__(self): super().__init__() self.tmp_files = set() def _uri_to_path(self, uri): if not uri.lower().startswith("file://"): return None return self.fs_unsafe(uri) def fs_open(self, uri, mode='r', **kwargs): path = self._uri_to_path(uri) if path is None: return None if 'w' not in mode and 'a' not in mode and not os.path.exists(path): return None if 'b' in mode: return open(path, mode) return codecs.open(path, mode, encoding='utf-8') def fs_exists(self, uri): path = self._uri_to_path(uri) if path is None: return None r = os.path.exists(path) if not r: return None return r def fs_listdir(self, uri): path = self._uri_to_path(uri) if path is None: return None if not os.path.exists(path): return None for f in os.listdir(path): yield self.fs_safe(os.path.join(path, f)) def fs_rename(self, old_uri, new_uri): old_path = self._uri_to_path(old_uri) new_path = self._uri_to_path(new_uri) if old_path is None or new_path is None: return None if not os.path.exists(old_path): return None os.rename(old_path, new_path) return True def fs_unlink(self, uri, **kwargs): path = self._uri_to_path(uri) if path is None: return if not os.path.exists(path): return None os.unlink(path) return True def fs_rm_rf(self, uri, **kwargs): path = self._uri_to_path(uri) if path is None: return shutil.rmtree(path, ignore_errors=True) return True def fs_get_mtime(self, uri): path = self._uri_to_path(uri) if path is None: return return int(os.stat(path).st_mtime) def fs_getsize(self, uri): path = self._uri_to_path(uri) if path is None: return return os.stat(path).st_size def fs_isdir(self, uri): path = self._uri_to_path(uri) if path is None: return if os.path.isdir(path): return True return None def fs_copy(self, old_uri, new_uri): old_path = self._uri_to_path(old_uri) new_path = self._uri_to_path(new_uri) if old_path is None or new_path is None: return None shutil.copy(old_path, new_path) return True def fs_mkdir_p(self, uri): path = self._uri_to_path(uri) if path is None: return os.makedirs(path, mode=0o700, exist_ok=True) return True def fs_recurse(self, parent_uri, dir_included=False): path = self._uri_to_path(parent_uri) if path is None: return for (root, dirs, files) in os.walk(path): if dir_included: for d in dirs: p = os.path.join(path, root, d) yield self.fs_safe(p) for f in files: p = os.path.join(path, root, f) yield self.fs_safe(p) def fs_hide(self, uri): pass def fs_get_mime(self, uri): path = self._uri_to_path(uri) if path is None: return None # should use 'magic', but Core can't have any dependency on it. # other we would pull it on all platforms. path = path.lower() if path.endswith(".pdf"): return "application/pdf" if path.endswith(".png"): return "image/png" if path.endswith(".tiff"): return "image/tiff" if path.endswith(".bmp"): return "image/x-ms-bmp" if path.endswith(".jpeg") or path.endswith(".jpg"): return "image/jpeg" if path.endswith(".txt"): return "text/plain" return None def fs_iswritable(self, uri): path = self._uri_to_path(uri) if path is None: return None return os.access(path, os.W_OK) def fs_mktemp( self, prefix=None, suffix=None, mode='w+b', on_disk=False, **kwargs ): if 'b' not in mode: tmp = tempfile.NamedTemporaryFile( prefix=prefix, suffix=suffix, delete=False, mode=mode, encoding='utf-8' ) else: tmp = tempfile.NamedTemporaryFile( prefix=prefix, suffix=suffix, delete=False, mode=mode ) self.tmp_files.add(tmp.name) return (self.fs_safe(tmp.name), tmp) def on_quit(self): for tmp_file in self.tmp_files: try: os.unlink(tmp_file) except FileNotFoundError: pass paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/http.py000066400000000000000000000077051456262201400254100ustar00rootroot00000000000000""" module 'http' contains all the code to communicate using HTTP+JSON with https://www.openpaper.work/: - update notification - anonymous statistics - etc """ import base64 import http import http.client import json import logging import os import ssl import urllib from . import PluginBase from . import promise if os.name == "nt": import certifi LOGGER = logging.getLogger(__name__) DEFAULT_SERVER = "www.openpaper.work" DEFAULT_PROTOCOL = "https" class JsonHttp(object): def __init__(self, core, module_name): self.core = core self.user_agent = "{} {}".format( core.call_success("app_get_name"), core.call_success("app_get_version") ) self.config_section_name = module_name settings = { self.config_section_name + "_protocol": core.call_success( "config_build_simple", self.config_section_name, "protocol", lambda: DEFAULT_PROTOCOL ), self.config_section_name + "_server": core.call_success( "config_build_simple", self.config_section_name, "server", lambda: DEFAULT_SERVER ), } for (k, setting) in settings.items(): core.call_all("config_register", k, setting) def _convert(self, data): if isinstance(data, str): return data if isinstance(data, bytes): return base64.encodebytes(data).decode("utf-8").strip() return json.dumps(data) def _request(self, data, protocol, server, path): if protocol == "http": h = http.client.HTTPConnection(host=server) elif os.name == "nt": # On Windows, when frozen, we must specify a cafile cafile = certifi.where() ssl_context = ssl.create_default_context(cafile=cafile) h = http.client.HTTPSConnection(host=server, context=ssl_context) else: h = http.client.HTTPSConnection(host=server) if data is None or (isinstance(data, str) and data == ""): LOGGER.info("Sending GET %s/%s", server, path) h.request('GET', url=path, headers={'User-Agent': self.user_agent}) else: body = urllib.parse.urlencode({ k: self._convert(v) for (k, v) in data.items() }) LOGGER.info("Sending POST %s/%s", server, path) h.request( 'POST', url=path, headers={ "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain", 'User-Agent': self.user_agent, }, body=body ) r = h.getresponse() reply = r.read().decode('utf-8') LOGGER.info("Got HTTP %s: %s - %s", r.status, r, reply) if r.status != http.client.OK: raise ConnectionError("HTTP {}: {} - {}".format( r.status, r, reply )) if reply[0] != '[' and reply[0] != '{': return reply return json.loads(reply) def get_request_promise(self, path): protocol = self.core.call_success( "config_get", self.config_section_name + "_protocol" ) server = self.core.call_success( "config_get", self.config_section_name + "_server" ) return promise.ThreadedPromise( self.core, self._request, args=(protocol, server, path) ) class Plugin(PluginBase): def get_interfaces(self): return ['http_json'] def get_deps(self): return [ { 'interface': 'app', 'defaults': ['openpaperwork_core.app'], }, { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, ] def http_json_get_client(self, module_name): return JsonHttp(self.core, module_name) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/i18n/000077500000000000000000000000001456262201400246255ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/i18n/__init__.py000066400000000000000000000000001456262201400267240ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/i18n/python.py000066400000000000000000000062351456262201400265260ustar00rootroot00000000000000import collections import datetime import locale import unicodedata from .. import (_, PluginBase) class Plugin(PluginBase): MONTH_FORMATS = collections.defaultdict( lambda: "%B", oc="%b", # Occitan ) def __init__(self): self.today = datetime.date.today() self.yesterday = self.today - datetime.timedelta(days=1) # Need the l10n plugin to be loaded first before getting the # translations self.i18n_today = None self.i18n_yesterday = None self.i18n_sizes = () def get_interfaces(self): return ['i18n'] def get_deps(self): return [ { 'interface': 'l10n', 'defaults': ['openpaperwork_core.l10n.python'], }, ] def init(self, core): super().init(core) self.i18n_today = _("Today") self.i18n_yesterday = _("Yesterday") self.i18n_sizes = ( _('%3.1f bytes'), _('%3.1f KiB'), _('%3.1f MiB'), _('%3.1f GiB'), _('%3.1f TiB'), ) def i18n_date_short(self, date): if hasattr(date, 'date'): date = date.date() # datetime --> date if date == self.today: return self.i18n_today elif date == self.yesterday: return self.i18n_yesterday else: return date.strftime("%x") def i18n_parse_date_short(self, txt): if txt == self.i18n_today: return self.today elif txt == self.i18n_yesterday: return self.yesterday else: try: return datetime.datetime.strptime(txt, "%x").date() except ValueError: return None def i18n_date_long_year(self, date): if hasattr(date, 'date'): date = date.date() # datetime --> date return date.strftime("%Y") def i18n_date_long_month(self, date): if hasattr(date, 'date'): date = date.date() # datetime --> date locale_msg = None if hasattr(locale, 'LC_MESSAGES'): locale_msg = locale.getlocale(locale.LC_MESSAGES) elif hasattr(locale, 'LC_ALL'): locale_msg = locale.getlocale(locale.LC_ALL) if locale_msg is None or locale_msg[0] is None: locale_msg = None else: locale_msg = locale_msg[0].split("_", 1)[0] return date.strftime(self.MONTH_FORMATS[locale_msg]) def i18n_file_size(self, num): for string in self.i18n_sizes: if num < 1024.0: return string % (num) num /= 1024.0 return self.i18n_sizes[-1] % (num) def i18n_strip_accents(self, string): """ Strip all the accents from the string """ return u''.join( ( character for character in unicodedata.normalize('NFD', string) if unicodedata.category(character) != 'Mn' ) ) def i18n_sort(self, string_list): t = [ (self.i18n_strip_accents(str(e).lower()), e) for e in string_list ] t.sort() return [e[1] for e in t] paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/interactive.py000066400000000000000000000146401456262201400267420ustar00rootroot00000000000000import atexit import code import os import os.path import readline import rlcompleter # noqa: F401 import time import threading from . import PluginBase class HistoryConsole(code.InteractiveConsole): def __init__( self, locals=None, filename="", histfile=os.path.expanduser("~/.console-history")): super().__init__(locals, filename) self.init_history(histfile) def init_history(self, histfile): readline.parse_and_bind("tab: complete") if hasattr(readline, "read_history_file"): try: readline.read_history_file(histfile) except FileNotFoundError: pass atexit.register(self.save_history, histfile) def save_history(self, histfile): readline.set_history_length(1000) readline.write_history_file(histfile) class ProxyCore(object): def __init__(self, core): self.core = core def call_all(self, *args, **kwargs): return self.core.call_one( "mainloop_execute", self.core.call_all, *args, **kwargs ) def call_success(self, *args, **kwargs): return self.core.call_one( "mainloop_execute", self.core.call_success, *args, **kwargs ) def call_one(self, *args, **kwargs): return self.core.call_one( "mainloop_execute", self.core.call_one, *args, **kwargs ) class Plugin(PluginBase): def __init__(self): super().__init__() self.has_quit = False # used for wait(): self.progress_condition = threading.Condition() self.progresses = {} self._previous_progresses = {} self.nb_windows_to_realize = 0 def get_interfaces(self): return [ 'gtk_window_listener' ] def get_deps(self): return [ { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, ] def init(self, core): super().init(core) data_dir = self.core.call_success("paths_get_data_dir") base_hist_dir = self.core.call_success( "fs_join", data_dir, "openpaperwork" ) self.core.call_success("fs_mkdir_p", base_hist_dir) histfile = self.core.call_success( "fs_join", base_hist_dir, "interactive_history" ) print("Objects provided:") print(" core : reference to OpenPaperwork's core") print(" stop(): shut down the application (but not this shell)") print(" exit(): stops this shell (but not the application)") print(" wait(): wait for all background tasks to end") print(" Ctrl-D / EOF: stops this shell and the application") console = HistoryConsole({ "core": ProxyCore(core), "stop": self._stop, "wait": self._wait, }, histfile=self.core.call_success("fs_unsafe", histfile)) threading.Thread(target=self._interact, args=(console,)).start() def on_gtk_window_opened(self, window): with self.progress_condition: if window.get_window() is not None: return self.nb_windows_to_realize += 1 realize_handler_id = None def on_realize(): self.nb_windows_to_realize -= 1 window.disconnect(realize_handler_id) self.progress_condition.notify_all() realize_handler_id = window.connect("realize", on_realize) def on_gtk_window_closed(self, window): pass def _interact(self, console): console.interact() self._stop() def on_quit(self): self.has_quit = True def _stop(self): if self.has_quit: return print("Quitting") self.core.call_one( "mainloop_execute", self.core.call_all, "mainloop_quit_graceful" ) def on_progress(self, upd_type, progress, description=None): progress = int(progress * 100) with self.progress_condition: if progress >= 100: if upd_type in self.progresses: self.progresses.pop(upd_type) self.progress_condition.notify_all() elif (upd_type not in self.progresses or progress != self.progresses[upd_type]): self.progresses[upd_type] = progress self.progress_condition.notify_all() def _wait(self): # WORKAROUND(Jflesch): sometimes, for some reason, we never get the # notification for the end of boxes loading MAX_TIME = 30 # seconds start = time.time() time_diff = 0 # wait a little, in case the call to _wait() came slightly before # the background task creation. print("Waiting for all background tasks to end") time.sleep(3.0) with self.progress_condition: while ((len(self.progresses) > 0 or self.nb_windows_to_realize > 0) and time_diff <= MAX_TIME): while ((len(self.progresses) > 0 or self.nb_windows_to_realize > 0) and time_diff <= MAX_TIME): print("Waiting for all background tasks to end") print("Remaining background tasks:") for (upd_type, progress) in self.progresses.items(): print(" {}: {}%".format(upd_type, int(progress))) self.progress_condition.wait(1.0) time_diff = time.time() - start if time_diff > MAX_TIME: break # wait again a little ; sometime background tasks are # sequentially removed and added self.progress_condition.release() try: time.sleep(3) finally: self.progress_condition.acquire() if time_diff <= MAX_TIME: print("All background tasks have ended") else: print("TIMEOUT") paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/l10n/000077500000000000000000000000001456262201400246205ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/l10n/__init__.py000066400000000000000000000000001456262201400267170ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/l10n/python.py000066400000000000000000000057471456262201400265300ustar00rootroot00000000000000import ctypes import gettext import locale import logging import os import sys from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def __init__(self): super().__init__() self.libintl = None def get_interfaces(self): return [ 'l10n', 'l10n_init', ] def get_deps(self): return [ { # if frozen, we need sys._MEIPASS to be set correctly 'interface': 'frozen', 'defaults': ['openpaperwork_core.frozen'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, ] def init(self, core): super().init(core) if os.name == "nt" and os.getenv('LANG') is None: (lang, enc) = locale.getdefaultlocale() os.environ['LANG'] = lang try: locale.setlocale(locale.LC_ALL, '') except locale.Error: # happens, for instance when LC_ALL is set to a nonexisting locale LOGGER.warning( "Failed to set localization. Localization will be disabled" ) return self.libintl = None if getattr(sys, 'frozen', False): libintl_path = os.path.abspath(os.path.join( sys._MEIPASS, "libintl-8.dll" )) if not os.path.exists(libintl_path): LOGGER.warning("Failed to find library libintl-8.dll") else: self.libintl = ctypes.cdll.LoadLibrary(libintl_path) self.l10n_load('openpaperwork_core.l10n', 'openpaperwork_core') def l10n_load(self, python_package, text_domain): path = self.core.call_success( "resources_get_dir", python_package, 'out' ) if path is None: LOGGER.error( "Failed to access ressources '%s/out'", python_package ) return None path = self.core.call_success("fs_unsafe", path) mo_file = gettext.find(text_domain, path) if mo_file is None: # expected if we don't have translation for the user language LOGGER.info( "Failed to find valid locale for '%s' (path=%s)", text_domain, path ) # we still try to keep going LOGGER.info("Binding text domain %s to '%s'", text_domain, path) if self.libintl is not None: self.libintl.bindtextdomain(text_domain, path) self.libintl.bind_textdomain_codeset(text_domain, 'UTF-8') for module in (gettext, locale): if hasattr(module, 'bindtextdomain'): module.bindtextdomain(text_domain, path) if hasattr(module, 'textdomain'): module.textdomain(text_domain) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/logs/000077500000000000000000000000001456262201400250125ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/logs/__init__.py000066400000000000000000000000001456262201400271110ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/logs/archives.py000066400000000000000000000106401456262201400271710ustar00rootroot00000000000000import faulthandler import logging import os from .. import (_, PluginBase) LOGGER = logging.getLogger(__name__) LOG_DATE_FORMAT = "%Y%m%d_%H%M_%S" MAX_DAYS = 31 class LogLine(object): def __init__(self, line): self.line = line self.next = None class LogHandler(logging.Handler): LOG_FORMAT = '[%(levelname)-6s] [%(name)-30s] %(message)s' MAX_LINES = 5000 MAX_UNCAUGHT_LOGGUED = 20 def __init__(self, core, archiver): super().__init__() self.core = core self.archiver = archiver self.first_line = None self.last_line = None self.nb_lines = 0 self.nb_uncaught_loggued = 0 self.out_file_url = self.archiver.get_new() self.formatter = logging.Formatter(self.LOG_FORMAT) self.out_fd = self.core.call_success( "fs_open", self.out_file_url, 'w', needs_fileno=True ) faulthandler.disable() faulthandler.enable(file=self.out_fd) def emit(self, record): line = self.formatter.format(record) + "\n" self.out_fd.write(line) line = LogLine(line) if self.last_line is not None: self.last_line.next = line self.last_line = line if self.first_line is None: self.first_line = line if self.nb_lines >= self.MAX_LINES: self.last_line = self.last_line.next else: self.nb_lines += 1 def log_uncaught_exception(self): if self.nb_uncaught_loggued >= self.MAX_UNCAUGHT_LOGGUED: # avoid logging too much return self.nb_uncaught_loggued += 1 out_file_url = self.archiver.get_new( name="uncaught_exception_logs" ) self.formatter = logging.Formatter(self.LOG_FORMAT) with self.core.call_success("fs_open", out_file_url, 'w') as fd: line = self.first_line while line is not None: fd.write(line.line) line = line.next class Plugin(PluginBase): PRIORITY = -10000 def __init__(self): super().__init__() logging.getLogger().setLevel(logging.INFO) self.archiver = None def get_interfaces(self): return [ 'bug_report_attachments', 'log_archiver', 'uncaught_exception_listener', ] def get_deps(self): return [ { 'interface': 'file_archives', 'defaults': ['openpaperwork_core.archives'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'uncaught_exception', 'defaults': ['openpaperwork_core.uncaught_exception'], }, ] def init(self, core): super().init(core) self.archiver = self.core.call_success( "file_archive_get", storage_name="logs", file_extension="txt" ) self.log_handler = LogHandler(core, self.archiver) logging.getLogger().addHandler(self.log_handler) def on_uncaught_exception(self, exc_info): self.log_handler.log_uncaught_exception() def bug_report_get_attachments(self, inputs: dict): archived = list(self.archiver.get_archived()) archived.sort(key=lambda x: x[0], reverse=True) for (nb, (date, file_url)) in enumerate(archived): inputs[file_url] = { 'date': date, # Users tend to send only the pre-selected elements in the bug # reports. However, when they report a sudden crash, we need # the logs of the previous session, not just the current one. # --> Include the logs of the last 2 previous sessions too. 'include_by_default': nb <= 2, 'file_type': _("Log file"), 'file_url': file_url, 'file_size': self.core.call_success("fs_getsize", file_url), } LOGGER.info("Flushing logs to disk") self.log_handler.out_fd.flush() os.fsync(self.log_handler.out_fd.fileno()) file_url = self.log_handler.out_file_url inputs[file_url] = { 'date': None, # now 'include_by_default': True, 'file_type': _("Log file"), 'file_url': file_url, 'file_size': self.core.call_success("fs_getsize", file_url), } paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/logs/print.py000066400000000000000000000122511456262201400265210ustar00rootroot00000000000000import datetime import logging import sys import tempfile from .. import PluginBase LOGGER = logging.getLogger(__name__) g_tmp_file = None def _get_tmp_file(): global g_tmp_file if g_tmp_file is not None: return g_tmp_file date = datetime.datetime.now() date = date.strftime("%Y%m%d_%H%M_%S") t = tempfile.NamedTemporaryFile( mode='w', suffix=".txt", prefix="openpaperwork_{}_".format(date), encoding='utf-8' ) if sys.stderr is not None: sys.stderr.write("Temporary file = {}\n".format(t.name)) g_tmp_file = t return t class _LogHandler(logging.Handler): def __init__(self): super().__init__() self.log_level = logging.DEBUG self.formatter = logging.Formatter(Plugin.DEFAULT_LOG_FORMAT) self.out_fds = set() if sys.stderr is not None: self.out_fds.add(sys.stderr) def emit(self, record): if record.levelno < self.log_level: return line = self.formatter.format(record) for fd in self.out_fds: fd.write(line + "\n") class Plugin(PluginBase): CONFIG_FILE_SEPARATOR = "," DEFAULT_LOG_FILES = 'stderr' DEFAULT_LOG_FORMAT = '[%(levelname)-6s] [%(name)-30s] %(message)s' LOG_LEVELS = { 'none': logging.CRITICAL, 'critical': logging.CRITICAL, 'error': logging.ERROR, 'warn': logging.WARN, 'warning': logging.WARNING, 'info': logging.INFO, 'debug': logging.DEBUG, } SPECIAL_FILES = { 'stdout': lambda: sys.stdout, 'stderr': lambda: sys.stderr, 'temp': _get_tmp_file, } def __init__(self): super().__init__() self.log_file_paths = set() self.log_handler = None def get_interfaces(self): return [ 'logs', 'uncaught_exception_listener', ] def get_deps(self): return [ { 'interface': 'uncaught_exception', 'defaults': ['openpaperwork_core.uncaught_exception'], }, { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, ] def init_logs(self, app_name, default_log_level): section_name = "logging:" + app_name s = self.core.call_success( "config_build_simple", section_name, "level", lambda: default_log_level ) self.core.call_all("config_register", "log_level", s) self.core.call_all( 'config_add_observer', "log_level", self._reload_config ) s = self.core.call_success( "config_build_simple", section_name, "files", lambda: self.DEFAULT_LOG_FILES ) self.core.call_all("config_register", "log_files", s) self.core.call_all( 'config_add_observer', "log_files", self._reload_config ) s = self.core.call_success( "config_build_simple", section_name, "format", lambda: self.DEFAULT_LOG_FORMAT ) self.core.call_all("config_register", "log_format", s) self.core.call_all( 'config_add_observer', "log_format", self._reload_config ) self.log_handler = _LogHandler() logging.getLogger().addHandler(self.log_handler) self._reload_config() def _disable_logging(self): for fd in self.log_handler.out_fds: if fd != sys.stdout and fd != sys.stderr and fd != g_tmp_file: fd.close() self.log_handler.out_fds = set() def _enable_logging(self): self.log_handler.out_fds = set() first = None for file_path in self.log_file_paths: if file_path.lower() not in self.SPECIAL_FILES: fd = open(file_path, 'a') self.log_handler.out_fds.add(fd) else: fd = self.SPECIAL_FILES[file_path.lower()]() if fd is not None: # stderr doesn't exist when frozen self.log_handler.out_fds.add(fd) if first is None and fd is not None: first = fd def _reload_config(self, *args, **kwargs): self._disable_logging() LOGGER.info("Reloading logging configuration") try: log_level = self.core.call_success('config_get', "log_level") self.set_log_level(log_level) self.log_file_paths = self.core.call_success( 'config_get', "log_files", ).split(self.CONFIG_FILE_SEPARATOR) self.log_handler.formatter = logging.Formatter( self.core.call_success('config_get', "log_format") ) finally: self._enable_logging() def set_log_level(self, log_level): lvl = self.LOG_LEVELS[log_level] self.log_handler.log_level = lvl if lvl > logging.INFO: # Never disable info level ; it may be used by other plugins lvl = logging.INFO logging.getLogger().setLevel(lvl) def on_uncaught_exception(self, exc_info): LOGGER.error("=== UNCAUGHT EXCEPTION ===", exc_info=exc_info) LOGGER.error("==========================") paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/mainloop/000077500000000000000000000000001456262201400256645ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/mainloop/__init__.py000066400000000000000000000000001456262201400277630ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/mainloop/asyncio.py000066400000000000000000000142271456262201400277110ustar00rootroot00000000000000import asyncio import logging import sys import threading import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): """ A main loop based on asyncio. Not as complete as GLib main loop, but good enough for shell commands. """ def __init__(self): super().__init__() self.halt_on_uncaught_exception = True self.loop = None self.loop_ident = None self.halt_cause = None self.task_count = 0 self.log_uncaught = True def _check_mainloop_instantiated(self): if self.loop is None: self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.task_count = 0 def get_interfaces(self): return [ "mainloop", ] def mainloop(self, halt_on_uncaught_exception=True, log_uncaught=True): """ Wait for callbacks to be scheduled and execute them. This method is blocking and will block until `mainloop_quit*()` is called. """ self._check_mainloop_instantiated() self.log_uncaught = log_uncaught self.halt_on_uncaught_exception = halt_on_uncaught_exception self.mainloop_schedule(self.core.call_all, "on_mainloop_start") self.loop_ident = threading.current_thread().ident try: self.loop.run_forever() finally: self.loop_ident = None self.core.call_all("on_mainloop_quit") if self.halt_cause is not None: halt_cause = self.halt_cause self.halt_cause = None LOGGER.error("Main loop stopped because %s", str(halt_cause)) raise halt_cause self.loop = None return True def mainloop_get_thread_id(self): """ Gets the ID of the thread running the main loop. `None` if no thread is running it. """ return self.loop_ident def mainloop_quit_graceful(self): """ Wait for all the scheduled callbacks to be executed and then stops the main loop. """ self.mainloop_schedule(self._mainloop_quit_graceful) return True def _mainloop_quit_graceful(self): if self.task_count > 1: # keep in mind this function is in a task too LOGGER.info( "Quit graceful: Remaining tasks: %d", self.task_count - 1 ) self.mainloop_schedule(self._mainloop_quit_graceful, delay_s=0.2) return LOGGER.info("Quit graceful: Quitting") self.mainloop_quit_now() self.task_count = 1 # we are actually the one task still running def mainloop_quit_now(self): """ Stops the main loop right now. Note that it cannot interrupt a callback being executed, but no callback scheduled after this one will be executed. """ if self.loop is None: return None self.loop.stop() self.loop = None self.task_count = 0 def mainloop_ref(self, obj): """ If you run a task independently from the main loop, you may want to increment the reference counter of the main loop so `mainloop_quit_graceful` does not interrupt the main loop while your task is still running. ThreadedPromise already takes care of incrementing and decrementing this reference counter. """ self.task_count += 1 def mainloop_unref(self, obj): self.task_count -= 1 def mainloop_schedule(self, func, *args, delay_s=0, **kwargs): """ Request that the main loop executes the callback `func`. Will return immediately. """ assert hasattr(func, '__call__') self._check_mainloop_instantiated() self.task_count += 1 async def decorator(args, kwargs): try: func(*args, **kwargs) except Exception as exc: exc_info = sys.exc_info() if self.halt_on_uncaught_exception: LOGGER.error( "Main loop: Uncaught exception (%s) ! Quitting", func, exc_info=exc ) self.halt_cause = exc self.mainloop_quit_now() elif self.log_uncaught: LOGGER.error( "Main loop: Uncaught exception (%s) !", func, exc_info=exc ) self.core.call_all( "mainloop_schedule", self.core.call_all, "on_uncaught_exception", exc_info ) finally: self.task_count -= 1 coroutine = decorator(args, kwargs) args = (self.loop.create_task, coroutine) if delay_s != 0: args = (self.loop.call_later, delay_s) + args self.loop.call_soon_threadsafe(args[0], *(args[1:])) return True def mainloop_execute(self, func, *args, **kwargs): """ Ensure a function is run on the main loop, even if called from a thread. Will return only once the callback `func` has been executed. Will return the value returned by `func`. This method makes it easier to work with non-thread-safe modules (sqlite3 for instance). """ current = threading.current_thread().ident # XXX(Jflesch): # if self.loop_ident is None, it means the mainloop hasn't been started # yet --> we cannot run the function on the mainloop anyway, so # we assume we are on the same thread that will later run the main # loop. if self.loop_ident is None or current == self.loop_ident: return func(*args, **kwargs) event = threading.Event() out = None exc = None def get_result(): nonlocal out nonlocal exc try: out = func(*args, **kwargs) except Exception as e: exc = e event.set() self.mainloop_schedule(get_result) event.wait() if exc is not None: raise exc return out paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/mainloop/tests.py000066400000000000000000000061671456262201400274120ustar00rootroot00000000000000import unittest from .. import (Core, promise) class AbstractTestCallback(unittest.TestCase): def get_plugin_name(self): """ Must be overloaded by subclasses """ assert False def setUp(self): self.core = Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() self.val = None def test_basic(self): def set_val(value): self.val = value # queue some calls self.core.call_all("mainloop_schedule", set_val, 22) self.core.call_all("mainloop_quit_graceful") self.core.call_one('mainloop') self.assertEqual(self.val, 22) class AbstractTestPromise(unittest.TestCase): def get_plugin_name(self): """ Must be overloaded by subclasses """ assert False def setUp(self): self.core = Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() self.alpha_called = False self.beta_called = False self.stop_called = False self.exc_raised = False self.idx = 0 def test_single(self): self.stop_called = False def stop(): self.stop_called = True p = promise.Promise(self.core, stop) p.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(self.stop_called) def test_chain(self): self.alpha_called = -1 self.beta_called = -1 self.stop_called = -1 self.idx = 0 def alpha(): self.alpha_called = self.idx self.idx += 1 return "alpha" def beta(previous): self.assertEqual(previous, "alpha") self.beta_called = self.idx self.idx += 1 def stop(): self.stop_called = self.idx self.idx += 1 p = promise.Promise(self.core, alpha) p = p.then(beta) p = p.then(stop) p.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(self.alpha_called, 0) self.assertEqual(self.beta_called, 1) self.assertEqual(self.stop_called, 2) def test_catch(self): self.alpha_called = False self.beta_called = False self.stop_called = False self.exc_raised = False def alpha(): self.alpha_called = True def beta(): self.beta_called = True raise Exception("paf") def stop(): self.stop_called = True def on_exc(exc): self.exc_raised = True p = promise.Promise(self.core, alpha) p = p.then(beta) p = p.then(stop) p = p.catch(on_exc) p.hide_caught_exceptions = True p.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(self.alpha_called) self.assertTrue(self.beta_called) self.assertFalse(self.stop_called) self.assertTrue(self.exc_raised) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/paths/000077500000000000000000000000001456262201400251655ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/paths/__init__.py000066400000000000000000000000001456262201400272640ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/paths/xdg.py000066400000000000000000000027451456262201400263310ustar00rootroot00000000000000import os from .. import PluginBase class Plugin(PluginBase): def get_interfaces(self): return ['paths'] def get_deps(self): return [ { 'interface': 'app', 'defaults': ['openpaperwork_core.app'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'] }, ] def paths_get_config_dir(self): config_dir = self.core.call_success( "fs_safe", os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config")) ) self.core.call_success("fs_mkdir_p", config_dir) if os.name == 'nt': # hide ~/.local on Windows self.core.call_success("fs_hide", config_dir) return config_dir def paths_get_data_dir(self): local_dir = os.path.expanduser("~/.local") data_dir = os.getenv("XDG_DATA_HOME", os.path.join(local_dir, "share")) data_dir = self.core.call_success("fs_safe", data_dir) app_name = self.core.call_success("app_get_fs_name") app_dir = self.core.call_success("fs_join", data_dir, app_name) self.core.call_success("fs_mkdir_p", app_dir) if os.name == 'nt': # hide ~/.local on Windows local_dir = self.core.call_success("fs_safe", local_dir) if self.core.call_success("fs_isdir", local_dir) is not None: self.core.call_success("fs_hide", local_dir) return app_dir paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/perfcheck/000077500000000000000000000000001456262201400260005ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/perfcheck/__init__.py000066400000000000000000000000001456262201400300770ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/perfcheck/log.py000066400000000000000000000014461456262201400271400ustar00rootroot00000000000000import logging import threading import time from .. import PluginBase LOGGER = logging.getLogger(__name__) MIN_TIME_MS = 200 class Plugin(PluginBase): def __init__(self): super().__init__() self.pending = {} def get_interfaces(self): return ['perfcheck'] def on_perfcheck_start(self, task_name): k = (task_name, threading.get_ident()) self.pending[k] = time.time() def on_perfcheck_stop(self, task_name, **extras): stop = time.time() k = (task_name, threading.get_ident()) start = self.pending.pop(k) if (stop - start) * 1000 >= MIN_TIME_MS: LOGGER.warning( "Task '%s' took %dms (> %dms) ! (%s)", task_name, (stop - start) * 1000, MIN_TIME_MS, extras ) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/pillow/000077500000000000000000000000001456262201400253545ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/pillow/__init__.py000066400000000000000000000000001456262201400274530ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/pillow/img.py000066400000000000000000000075411456262201400265110ustar00rootroot00000000000000import logging import PIL import PIL.Image from .. import ( PluginBase, promise ) LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): FILE_EXTENSIONS = [ "bmp", "gif", "jpeg", "jpg", "png", "tif", "tiff", ] def get_interfaces(self): return [ 'page_img_size', 'pillow', ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'] }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { 'interface': 'pillow_util', 'defaults': ['openpaperwork_core.pillow.util'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def _check_is_img(self, file_url): return file_url.rsplit(".", 1)[-1].lower() in self.FILE_EXTENSIONS def url_to_img_size(self, file_url): if not self._check_is_img(file_url): return None task = "url_to_img_size({})".format(file_url) size = (0, 0) self.core.call_all("on_perfcheck_start", task) try: with self.core.call_success("fs_open", file_url, mode='rb') as fd: img = PIL.Image.open(fd) size = img.size return size except PIL.Image.DecompressionBombError as exc: LOGGER.warning("Image %s is too big", file_url, exc_info=exc) return self.core.call_success( "pillow_get_error", "too_big" ).size finally: self.core.call_all("on_perfcheck_stop", task, size=size) def url_to_img_size_promise(self, file_url): if not self._check_is_img(file_url): return None return promise.ThreadedPromise( self.core, self.url_to_img_size, args=(file_url,) ) def url_to_pillow(self, file_url): if not self._check_is_img(file_url): return None task = "url_to_pillow({})".format(file_url) size = (0, 0) self.core.call_all("on_perfcheck_start", task) try: with self.core.call_success("fs_open", file_url, mode='rb') as fd: img = PIL.Image.open(fd) img.load() self.core.call_all("on_objref_track", img) size = img.size return img except PIL.Image.DecompressionBombError as exc: LOGGER.warning("Image %s is too big", file_url, exc_info=exc) return self.core.call_success( "pillow_get_error", "too_big" ) finally: self.core.call_all("on_perfcheck_stop", task, size=size) def url_to_pillow_promise(self, file_url): return promise.ThreadedPromise( self.core, self.url_to_pillow, args=(file_url,) ) def pillow_to_url(self, img, file_url, format=None, quality=0.75): expected_format = file_url.rsplit(".", 1)[-1].upper() if expected_format == "JPG": expected_format = "JPEG" if expected_format == "TIF": expected_format = "TIFF" if format is None: format = expected_format if format != expected_format: LOGGER.warning( "File %s written with format %s. Expected %s", file_url, format, expected_format ) if format != 'PNG': # drop the alpha channel if there is one img = img.convert("RGB") with self.core.call_success("fs_open", file_url, mode='wb') as fd: return img.save( fd, format=format, optimize=True, quality=int(quality * 100) ) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/pillow/util.py000066400000000000000000000033641456262201400267110ustar00rootroot00000000000000import logging import PIL import PIL.Image import PIL.ImageDraw import PIL.ImageFont from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): ID_TO_MSG = { 'invalid': "Invalid image", 'too_big': "Image too big.\nImage not loaded.", } def get_interfaces(self): return ['pillow_util'] def pillow_get_error(self, error_id): msg = self.ID_TO_MSG[error_id] font = PIL.ImageFont.load_default() longest_line = max(((len(line), line) for line in msg.split("\n"))) longest_line = longest_line[1] if hasattr(font, 'getbbox'): size = font.getbbox(longest_line) size = (size[2], size[3]) elif hasattr(font, 'getsize'): size = font.getsize(longest_line) else: size = (100, 100) size = (size[0], size[1] * (1 + (2 * msg.count("\n")))) img = PIL.Image.new("RGB", size, (255, 255, 255)) draw = PIL.ImageDraw.Draw(img) draw.text((0, 0), msg, font=font, fill=(0, 0, 0)) img = img.resize( tuple([s * 8 for s in size]), getattr(PIL.Image, 'Resampling', PIL.Image).LANCZOS ) return img def pillow_add_border(self, img, color="#a6a5a4", width=1): """ Add a border of the specified color and width around a PIL image """ img_draw = PIL.ImageDraw.Draw(img) for line in range(0, width): img_draw.rectangle( [ (line, line), ( img.size[0] - 1 - line, img.size[1] - 1 - line ) ], outline=color ) return img paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/promise.py000066400000000000000000000175721456262201400261120ustar00rootroot00000000000000import logging import threading import traceback LOGGER = logging.getLogger(__name__) class BasePromise(object): def __init__( self, core, func=None, args=None, kwargs=None, parent=None, hide_caught_exceptions=False ): # we allow dummy Promise with not function provided. It allows to # write cleaner code in some cases. self.core = core self.func = func self.hide_caught_exceptions = hide_caught_exceptions if args is None: self.args = () else: self.args = args if kwargs is None: self.kwargs = {} else: self.kwargs = kwargs self.parent = parent self._then = [] self._catch = [] self.scheduled = False self.parent_promise_return = None self.created_by = traceback.extract_stack() def __str__(self): return "Promise<{}>({})".format(str(self.func), id(self)) def __repr__(self): return str(self) def then(self, callback, *args, **kwargs): if isinstance(callback, BasePromise): assert args is None or len(args) <= 0 assert kwargs is None or len(kwargs) <= 0 last_promise = callback while callback.parent is not None: callback = callback.parent next_promise = callback next_promise.parent = self else: next_promise = Promise( self.core, callback, args, kwargs, parent=self ) last_promise = next_promise if not next_promise.hide_caught_exceptions: next_promise.hide_caught_exceptions = self.hide_caught_exceptions self._then.append(next_promise) return last_promise def catch(self, callback, *args, **kwargs): self._catch.append((callback, args, kwargs)) return self def on_error(self, exc, hide_caught_exceptions=False): self.scheduled = False hide_caught_exceptions = ( hide_caught_exceptions or self.hide_caught_exceptions ) if len(self._catch) > 0: if hide_caught_exceptions: trace = lambda *args, **kwargs: None # NOQA: E731 else: trace = LOGGER.warning caught = "caught" elif len(self._then) > 0: for t in self._then: t.scheduled = False t.on_error(exc, hide_caught_exceptions) return else: trace = LOGGER.error caught = "uncaught" trace("=== %s exception in promise ===", caught, exc_info=exc) trace("promise.func=%s", self.func) trace("promise.args=%s", self.args) trace("promise.kwargs=%s", self.kwargs) trace("promise.parent=%s", self.parent) trace( "promise.parent_promise_return=%s", self.parent_promise_return ) trace("=== Promise was created by ===") for (idx, stack_el) in enumerate(self.created_by): trace( "%2d: %20s: L%5d: %s", idx, stack_el[0], stack_el[1], stack_el[2] ) if len(self._catch) > 0: for (c, args, kwargs) in self._catch: self.core.call_one( "mainloop_schedule", c, exc, *args, **kwargs ) return raise exc def _do(self, args): try: self.do(args) finally: self.scheduled = False def schedule(self, *args): scheduled = self.scheduled s = self while s.parent is not None: scheduled = scheduled or s.scheduled s.scheduled = True s = s.parent s.scheduled = True if scheduled: # a parent promise already scheduled --> we made sure to mark # all the children promises as scheduled, but there is no # need to actually schedule the parent. return if args == (): args = None self.core.call_one("mainloop_schedule", s._do, args) def wait(self): assert ( # must never be called from main loop. threading.current_thread().ident != self.core.call_success("mainloop_get_thread_id") ) event = threading.Event() out = None def wakeup(r=None): nonlocal out out = r self.then(event.set) event.wait() return out class Promise(BasePromise): """ Executed in the main loop thread. Requires a plugin implementing the interface 'mainloop'. """ def do(self, parent_r=None): self.parent_promise_return = parent_r try: if self.func is None: our_r = None else: if parent_r is None: args = self.args else: args = (parent_r,) + self.args LOGGER.debug( "Promise: Begin: %s(%s, %s)", self.func, args, self.kwargs ) our_r = self.func(*args, **self.kwargs) LOGGER.debug( "Promise: End: %s(%s, %s)", self.func, args, self.kwargs ) for t in self._then: self.core.call_one("mainloop_schedule", t._do, our_r) except Exception as exc: self.on_error(exc) class DelayPromise(BasePromise): """ Promise adding delay between 2 other promises. Requires a plugin implementing the interface 'mainloop' """ def __init__(self, core, delay_s): super().__init__(core) self.delay_s = delay_s def __str__(self): return "DelayPromise({})".format(self.delay_s, id(self)) def _call_then(self, parent_r): for t in self._then: self.core.call_one("mainloop_schedule", t._do, parent_r) def do(self, parent_r=None): LOGGER.debug("Promise: delay: %fs", self.delay_s) self.core.call_one( "mainloop_schedule", self._call_then, parent_r, delay_s=self.delay_s ) class ThreadedPromise(BasePromise): """ Promise for which the provided callback will be run in another thread, leaving the main loop thread free to do other things. Requires a plugin implementing the interface 'mainloop' and a plugin implementing the interface 'thread'. IMPORTANT: This should ONLY be used for long-lasting tasks that cannot be split in small tasks (image processing, OCR, etc). The callback provided must be really careful regarding thread-safety. """ def __str__(self): return "ThreadedPromise<{}>({})".format(str(self.func), id(self)) def _threaded_do(self, parent_r): try: if parent_r is None: args = self.args else: args = (parent_r,) + self.args LOGGER.debug( "Threaded promise: Begin: %s(%s, %s)", self.func, args, self.kwargs ) our_r = self.func(*args, **self.kwargs) LOGGER.debug( "Threaded promise: end: %s(%s, %s)", self.func, args, self.kwargs ) for t in self._then: self.core.call_one("mainloop_schedule", t._do, our_r) except Exception as exc: self.core.call_one("mainloop_schedule", self.on_error, exc) def do(self, parent_r=None): self.parent_promise_return = parent_r try: if self.func is None: # no thread, we immediately schedule the next promises for t in self._then: self.core.call_one("mainloop_schedule", t._do, None) return self.core.call_one("thread_start", self._threaded_do, parent_r) except Exception as exc: self.on_error(exc) return paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/resources/000077500000000000000000000000001456262201400260605ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/resources/__init__.py000066400000000000000000000000001456262201400301570ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/resources/frozen.py000066400000000000000000000023541456262201400277410ustar00rootroot00000000000000""" Workaround for the fact that "import pkg_resources" never works when frozen with Msys2 + cx_freeze ... """ import logging import os import sys from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): PRIORITY = 100 def get_interfaces(self): return ['resources'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, ] def resources_get_file(self, pkg, filename): if not getattr(sys, 'frozen', False): return None # cx_freeze: pkg_resources doesn't work (can't import it), so we keep # the data files beside the executable. path = os.path.join( os.path.dirname(sys.executable), "data", pkg.replace(".", os.path.sep), filename ) if not os.path.exists(path): LOGGER.warning( "Failed to find %s/%s (tried %s)", pkg, filename, path ) return None return self.core.call_success("fs_safe", path) def resources_get_dir(self, pkg, dirname): return self.resources_get_file(pkg, dirname) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/resources/setuptools.py000066400000000000000000000024501456262201400306540ustar00rootroot00000000000000import logging import os try: import pkg_resources PKG_RESOURCES_AVAILABLE = True except Exception: PKG_RESOURCES_AVAILABLE = False from .. import PluginBase LOGGER = logging.getLogger(__name__) class Plugin(PluginBase): def get_interfaces(self): return ['resources'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, ] def resources_get_file(self, pkg, filename): if not PKG_RESOURCES_AVAILABLE: return try: path = pkg_resources.resource_filename(pkg, filename) except KeyError: LOGGER.warning( "Failed to find resource file %s/%s," " unknown to pkg_resources.", pkg, filename ) return None if not os.access(path, os.R_OK): LOGGER.warning( "Failed to find resource file %s/%s," " tried at path %s.", pkg, filename, path ) return None LOGGER.debug("%s:%s --> %s", pkg, filename, path) return self.core.call_success("fs_safe", path) def resources_get_dir(self, pkg, dirname): return self.resources_get_file(pkg, dirname) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/spatial/000077500000000000000000000000001456262201400255035ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/spatial/__init__.py000066400000000000000000000000001456262201400276020ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/spatial/rtree.py000066400000000000000000000163661456262201400272120ustar00rootroot00000000000000""" Spatial indexer that works in a way very similar to R-tree. Except for the way the nodes are split because I'm a lazy bastard and it's good enough. """ import math import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) NB_CHILDREN_PER_NODES = 4 # must be a multiple of 2 because I'm a lazy bastard # Node: R-tree page (leaf or not) # Non-leaf: children are other nodes # Leaf: last R-tree node: children are tuples (box, obj) def compute_area(box): return abs((box[1][0] - box[0][0]) * (box[1][1] - box[0][1])) class Node(object): def __init__(self, box=None): self.leaf = True self.children = [] self.box = None self.area = 0 self.set_box(box) self.parent = None def compute_enlargment(self, box): enlarged = ( ( min(self.box[0][0], box[0][0]), min(self.box[0][1], box[0][1]), ), ( max(self.box[1][0], box[1][0]), max(self.box[1][1], box[1][1]), ), ) enlarged = compute_area(enlarged) return enlarged - self.area def set_box(self, box): self.box = box if box is None: # root node self.area = math.inf else: self.area = compute_area(box) def recompute_box(self, recurse=True): depth = 0 s = self while True: depth += 1 assert depth < 512 if s.leaf: box = ( ( min(x[0][0][0] for x in s.children), min(x[0][0][1] for x in s.children), ), ( max(x[0][1][0] for x in s.children), max(x[0][1][1] for x in s.children), ), ) else: box = ( ( min(x.box[0][0] for x in s.children), min(x.box[0][1] for x in s.children), ), ( max(x.box[1][0] for x in s.children), max(x.box[1][1] for x in s.children), ), ) s.set_box(box) if not recurse or s.parent is None: break s = s.parent def is_full(self): assert self.leaf return len(self.children) >= NB_CHILDREN_PER_NODES @staticmethod def _pick_seed(boxes): """ Returns a pair of nodes that would be the most wasteful. (see Guttman Quadratic Split algorithm) """ assert len(boxes) >= 2 if len(boxes) == 2: # minor optim return tuple(boxes) max_waste = -1 r = None for (a_idx, a) in enumerate(boxes): for b in boxes[a_idx + 1:]: new_rect = ( ( min(a[0][0][0], b[0][0][0]), min(a[0][0][1], b[0][0][1]), ), ( max(a[0][1][0], b[0][1][0]), max(a[0][1][1], b[0][1][1]), ) ) new_area = ( (new_rect[1][0] - new_rect[0][0]) * (new_rect[1][1] - new_rect[0][1]) ) waste = new_area - a[2] - b[2] if waste > max_waste or r is None: r = (a, b) assert r is not None return r def split(self): assert self.leaf our_children = self.children picked = [] while len(our_children) > 0: p = self._pick_seed(our_children) picked.append(p) for c in p: our_children.remove(c) node_a = Node() node_a.parent = self node_a.children = [b[0] for b in picked] node_a.recompute_box(recurse=False) node_b = Node() node_b.parent = self node_b.children = [b[1] for b in picked] node_b.recompute_box(recurse=False) self.children = [node_a, node_b] self.leaf = False def insert_box(self, box): assert self.leaf self.children.append(box) self.recompute_box() def __gt__(self, o): return False class RTreeSpatialIndexer(object): def __init__(self, boxes): self.root = Node() boxes = list(boxes) LOGGER.info("Loading %d boxes in rtree", len(boxes)) for (pos, obj) in boxes: self.insert(pos, obj) # self.print_stats() def print_stats(self): """ Not used at the moment, but useful to make sure the tree looks OK when debugging. """ nb_boxes = 0 nb_nodes = 0 max_depth = 0 to_examine = [(0, self.root)] while len(to_examine) > 0: nb_nodes += 1 (depth, n) = to_examine.pop(0) max_depth = max(max_depth, depth) if n.leaf: nb_boxes += len(n.children) else: for c in n.children: to_examine.append((depth + 1, c)) LOGGER.info( "Rtree: %d boxes, %d nodes, max depth: %d", nb_boxes, nb_nodes, max_depth ) def _choose_leaf(self, box_position, node): # keep picking up the child node that overlap as much of # box_position as possible return min({ (c.compute_enlargment(box_position), c) for c in node.children })[1] def _find_leaf(self, box_position, root=None): if root is None: n = self.root else: n = root while not n.leaf: n = self._choose_leaf(box_position, n) return n def insert(self, box_position, obj): new_child = (box_position, obj, compute_area(box_position)) leaf = self._find_leaf(box_position) if leaf.is_full(): leaf.split() leaf = self._find_leaf(box_position, leaf) leaf.insert_box(new_child) @staticmethod def is_in(box_position, pt_x, pt_y): if box_position[0][0] > pt_x: return False if box_position[0][1] > pt_y: return False if box_position[1][0] < pt_x: return False if box_position[1][1] < pt_y: return False return True def get_boxes(self, pt_x, pt_y): """ Returns all the boxes that contains the point (pt_x, pt_y) """ examined = 0 to_examine = [self.root] while len(to_examine) > 0: n = to_examine.pop(0) examined += 1 if not n.leaf: for c in n.children: if self.is_in(c.box, pt_x, pt_y): to_examine.append(c) else: for c in n.children: if self.is_in(c[0], pt_x, pt_y): yield (c[0], c[1]) # LOGGER.debug("Examined nodes: %d", examined) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'spatial_index' ] def spatial_indexer_get(self, boxes): return RTreeSpatialIndexer(boxes) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/spatial/simple.py000066400000000000000000000012371456262201400273510ustar00rootroot00000000000000import openpaperwork_core class SpatialIndexer(object): def __init__(self, boxes): self.boxes = list(boxes) def get_boxes(self, pt_x, pt_y): for (pos, obj) in self.boxes: if pos[0][0] > pt_x: continue if pos[0][1] > pt_y: continue if pos[1][0] < pt_x: continue if pos[1][1] < pt_y: continue yield (pos, obj) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'spatial_index' ] def spatial_indexer_get(self, boxes): return SpatialIndexer(boxes) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/spatial/tests.py000066400000000000000000000036501456262201400272230ustar00rootroot00000000000000import unittest from .. import Core class AbstractTest(unittest.TestCase): def get_plugin_name(self): """ Must be overloaded by subclasses """ assert False def setUp(self): self.core = Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_basic(self): boxes = [ (((0, 0), (10, 10)), "a"), (((10, 10), (50, 40)), "b"), (((25, 25), (100, 100)), "c"), ] indexer = self.core.call_success("spatial_indexer_get", boxes) self.assertEqual( list(indexer.get_boxes(5, 5)), [ (((0, 0), (10, 10)), "a"), ] ) self.assertEqual( list(indexer.get_boxes(5, 10)), [ (((0, 0), (10, 10)), "a"), ] ) self.assertEqual( list(indexer.get_boxes(10, 10)), [ (((0, 0), (10, 10)), "a"), (((10, 10), (50, 40)), "b"), ] ) self.assertEqual( list(indexer.get_boxes(25, 20)), [ (((10, 10), (50, 40)), "b"), ] ) self.assertEqual( list(indexer.get_boxes(75, 75)), [ (((25, 25), (100, 100)), "c"), ] ) def test_real(self): boxes = [ (((584, 360), (1097, 415)), "CROIX-ROUGE"), (((1126, 361), (1540, 428)), "FRANCAISE"), (((865, 430), (1006, 464)), "EQUIPES"), (((1028, 437), (1258, 462)), "SECOURISTES"), (((724, 675), (911, 718)), "Madame"), ] indexer = self.core.call_success("spatial_indexer_get", boxes) self.assertEqual( list(indexer.get_boxes(836, 701)), [ (((724, 675), (911, 718)), "Madame"), ] ) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/sqlite.py000066400000000000000000000031021456262201400257150ustar00rootroot00000000000000import logging import os import sqlite3 from . import PluginBase LOGGER = logging.getLogger(__name__) # Beware that we use Sqlite, but sqlite python module is not thread-safe # --> all the calls to sqlite module functions must happen on the main loop, # even those in the transactions (which are run in a thread) class Plugin(PluginBase): def get_interfaces(self): return ['sqlite'] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, ] def sqlite_open(self, db_url, *args, **kwargs): LOGGER.info("Opening DB %s ...", db_url) db_path = self.core.call_success("fs_unsafe", db_url) if 'timeout' not in kwargs: kwargs['timeout'] = 60 sql = sqlite3.connect(db_path, *args, **kwargs) sql.execute("pragma journal_mode = wal;") sql.execute("pragma synchronous = normal;") sql.execute("pragma temp_store = memory;") if os.name == "posix": sql.execute("pragma mmap_size = 30000000000;") return sql def sqlite_execute(self, cb, *args, **kwargs): return self.core.call_one("mainloop_execute", cb, *args, **kwargs) def sqlite_schedule(self, cb, *args, **kwargs): return self.core.call_one("mainloop_schedule", cb, *args, **kwargs) def sqlite_close(self, db, optimize=True): if optimize: LOGGER.info("Optimizing database ...") db.execute("pragma optimize;") db.close() return True paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/tests/000077500000000000000000000000001456262201400252105ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/tests/__init__.py000066400000000000000000000000001456262201400273070ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/tests/local_file.py000066400000000000000000000400101456262201400276460ustar00rootroot00000000000000import os import tempfile import time import unittest import openpaperwork_core class AbstractTestSafe(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() @unittest.skipUnless(os.name == 'posix', reason="Linux only") def test_linux(self): v = self.core.call_one('fs_safe', '/home/flesch jerome') self.assertEqual(v, "file:///home/flesch%20jerome") v = self.core.call_one('fs_safe', 'file:///home/flesch%20jerome') self.assertEqual(v, "file:///home/flesch%20jerome") @unittest.skipUnless(os.name == 'nt', reason="Windows only") def test_windows(self): v = self.core.call_one('fs_safe', 'c:\\Users\\flesch jerome') self.assertEqual(v, "file:///c:/Users/flesch%20jerome") v = self.core.call_one('fs_safe', '\\\\someserver\\someshare') self.assertEqual(v, "\\\\someserver\\someshare") class AbstractTestUnsafe(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() @unittest.skipUnless(os.name == 'posix', reason="Linux only") def test_linux(self): v = self.core.call_one('fs_unsafe', 'file:///home/flesch%20jerome') self.assertEqual(v, "/home/flesch jerome") v = self.core.call_one('fs_unsafe', 'file:///home/flesch jerome') self.assertEqual(v, "/home/flesch jerome") v = self.core.call_one('fs_unsafe', '/home/flesch jerome') self.assertEqual(v, "/home/flesch jerome") @unittest.skipUnless(os.name == 'nt', reason="Windows only") def test_windows(self): v = self.core.call_success( 'fs_unsafe', 'file://c:\\Users\\flesch%20jerome' ) self.assertEqual(v, "c:\\Users\\flesch jerome") v = self.core.call_one('fs_safe', '\\\\someserver\\someshare') self.assertEqual(v, "\\\\someserver\\someshare") class AbstractTestOpen(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_read_binary(self): file_name = None with tempfile.NamedTemporaryFile(mode='wb', delete=False) as fd: file_name = fd.name fd.write(b"content") try: safe_file_name = self.core.call_one('fs_safe', file_name) with self.core.call_one( 'fs_open', safe_file_name, mode='rb' ) as fd: content = fd.read() self.assertEqual(content, b"content") finally: os.unlink(file_name) def test_write_binary(self): file_name = None with tempfile.NamedTemporaryFile(mode='wb', delete=False) as fd: file_name = fd.name try: safe_file_name = self.core.call_one('fs_safe', file_name) with self.core.call_one( 'fs_open', safe_file_name, mode='wb' ) as fd: fd.write(b"content\n") with open(file_name, 'rb') as fd: content = fd.read() self.assertEqual(content, b"content\n") finally: os.unlink(file_name) def test_read(self): file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name fd.write("content") try: safe_file_name = self.core.call_one('fs_safe', file_name) with self.core.call_one('fs_open', safe_file_name, mode='r') as fd: content = fd.read() self.assertEqual(content, "content") finally: os.unlink(file_name) def test_write(self): file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name try: safe_file_name = self.core.call_one('fs_safe', file_name) with self.core.call_one('fs_open', safe_file_name, mode='w') as fd: fd.write("content\n") with open(file_name, 'r') as fd: content = fd.read() self.assertEqual(content, "content\n") finally: os.unlink(file_name) class AbstractTestExists(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_not_exist(self): self.assertEqual(self.core.call_one('fs_exists', "/whatever"), None) def test_exists(self): file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name fd.write("content") try: safe_file_name = self.core.call_one('fs_safe', file_name) self.assertTrue(self.core.call_one('fs_exists', safe_file_name)) finally: os.unlink(file_name) class AbstractTestListDir(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() self.dirname = tempfile.mkdtemp() self.uri_dirname = self.core.call_one('fs_safe', self.dirname) with open(os.path.join(self.dirname, 'test1.txt'), 'w') as fd: fd.write('test1') with open(os.path.join(self.dirname, 'test2.txt'), 'w') as fd: fd.write('test2') os.mkdir(os.path.join(self.dirname, 'test3')) with open(os.path.join(self.dirname, 'test3', 'test4.txt'), 'w') as fd: fd.write('test4') def tearDown(self): # check fs_rm_rf at the same time self.core.call_one("fs_rm_rf", self.uri_dirname, trash=False) self.assertFalse(os.path.exists(self.dirname)) def test_listdir(self): files = list(self.core.call_one('fs_listdir', self.uri_dirname)) files.sort() self.assertEqual(files, [ self.uri_dirname + '/test1.txt', self.uri_dirname + '/test2.txt', self.uri_dirname + '/test3' ]) def test_recurse(self): files = list(self.core.call_one('fs_recurse', self.uri_dirname)) files.sort() self.assertEqual(files, [ self.uri_dirname + '/test1.txt', self.uri_dirname + '/test2.txt', self.uri_dirname + '/test3/test4.txt' ]) class AbstractTestRename(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_rename(self): src_file_name = None dst_file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: src_file_name = fd.name fd.write("content") with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: dst_file_name = fd.name fd.write("content") os.unlink(dst_file_name) try: safe_src_file_name = self.core.call_one('fs_safe', src_file_name) safe_dst_file_name = self.core.call_one('fs_safe', dst_file_name) self.assertTrue(os.path.exists(src_file_name)) self.assertFalse(os.path.exists(dst_file_name)) self.core.call_one( 'fs_rename', safe_src_file_name, safe_dst_file_name ) self.assertFalse(os.path.exists(src_file_name)) self.assertTrue(os.path.exists(dst_file_name)) finally: if os.path.exists(src_file_name): os.unlink(src_file_name) if os.path.exists(dst_file_name): os.unlink(dst_file_name) class AbstractTestUnlink(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_unlink(self): file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name fd.write("content") try: safe_file_name = self.core.call_one('fs_safe', file_name) self.assertTrue(os.path.exists(file_name)) self.core.call_one('fs_unlink', safe_file_name, trash=False) self.assertFalse(os.path.exists(file_name)) finally: if os.path.exists(file_name): os.unlink(file_name) class AbstractTestGetMtime(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_get_mtime(self): now = time.time() file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name fd.write("content") try: safe_file_name = self.core.call_one('fs_safe', file_name) mtime = self.core.call_one('fs_get_mtime', safe_file_name) self.assertTrue(int(now) <= mtime) self.assertTrue(mtime <= now + 2) time.sleep(2) # :-( with open(file_name, 'a') as fd: fd.write("content") new_mtime = self.core.call_one('fs_get_mtime', safe_file_name) self.assertTrue(int(now) <= new_mtime) self.assertTrue(mtime < new_mtime) finally: os.unlink(file_name) class AbstractTestGetsize(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_getsize(self): file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name fd.write("content") # 7 bytes try: safe_file_name = self.core.call_one('fs_safe', file_name) s = self.core.call_one('fs_getsize', safe_file_name) self.assertEqual(s, 7) finally: os.unlink(file_name) class AbstractTestIsdir(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_isdir_true(self): dirname = tempfile.mkdtemp() uri_dirname = self.core.call_one('fs_safe', dirname) try: self.assertTrue(self.core.call_one("fs_isdir", uri_dirname)) finally: # check fs_rm_rf at the same time self.core.call_one("fs_rm_rf", uri_dirname, trash=False) self.assertFalse(os.path.exists(dirname)) def test_isdir_false(self): file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: file_name = fd.name fd.write("content") try: safe_file_name = self.core.call_one('fs_safe', file_name) self.assertFalse(self.core.call_one('fs_isdir', safe_file_name)) finally: os.unlink(file_name) class AbstractTestCopy(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_copy(self): src_file_name = None dst_file_name = None with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: src_file_name = fd.name fd.write("content") with tempfile.NamedTemporaryFile(mode='w', delete=False) as fd: dst_file_name = fd.name fd.write("xxxxxxx") os.unlink(dst_file_name) try: safe_src_file_name = self.core.call_one('fs_safe', src_file_name) safe_dst_file_name = self.core.call_one('fs_safe', dst_file_name) self.assertTrue(os.path.exists(src_file_name)) self.assertFalse(os.path.exists(dst_file_name)) self.core.call_one( 'fs_copy', safe_src_file_name, safe_dst_file_name ) self.assertTrue(os.path.exists(src_file_name)) self.assertTrue(os.path.exists(dst_file_name)) with open(dst_file_name, 'r') as fd: content = fd.read() self.assertEqual(content, 'content') finally: if os.path.exists(src_file_name): os.unlink(src_file_name) if os.path.exists(dst_file_name): os.unlink(dst_file_name) class AbstractTestMkdirP(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_mkdir_p(self): dirname = tempfile.mkdtemp() uri_dirname = self.core.call_one('fs_safe', dirname) try: new_dirs = uri_dirname + "/testA/testB/testC" self.core.call_one("fs_mkdir_p", new_dirs) self.assertTrue(os.path.exists(os.path.join( dirname, "testA", "testB", "testC" ))) finally: # check fs_rm_rf at the same time self.core.call_one("fs_rm_rf", uri_dirname, trash=False) self.assertFalse(os.path.exists(dirname)) class AbstractTestBasename(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_basename(self): out = self.core.call_success("fs_basename", "file:///a/b/c.txt") self.assertEqual(out, "c.txt") out = self.core.call_success("fs_basename", "file:///c.txt") self.assertEqual(out, "c.txt") out = self.core.call_success("fs_basename", "memory://camion.txt") self.assertEqual(out, "camion.txt") class AbstractTestTemp(unittest.TestCase): def get_plugin_name(self): """ must be subclassed """ assert False def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load(self.get_plugin_name()) self.core.init() def test_mktemp(self): (tmp_url, tmp_fd) = self.core.call_success( "fs_mktemp", prefix="test", suffix=".txt", mode="w" ) with tmp_fd: tmp_fd.write("TEST\n") self.assertNotEqual( self.core.call_success("fs_exists", tmp_url), None ) self.core.call_all("on_quit") self.assertEqual( self.core.call_success("fs_exists", tmp_url), None ) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/thread/000077500000000000000000000000001456262201400253155ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/thread/__init__.py000066400000000000000000000016711456262201400274330ustar00rootroot00000000000000import logging LOGGER = logging.getLogger(__name__) class Task(object): def __init__(self, core, func, args, kwargs): self.core = core self.func = func self.args = args self.kwargs = kwargs # The mainloop can't track other threads, but if there is # a graceful shutdown waiting, we don't want it to stop the main # loop before our thread is done. # --> increment mainloop ref counter before core.call_all("mainloop_ref", self) def __str__(self): return "Task<{}>({}, {})".format(self.func, self.args, self.kwargs) def __repr__(self): return str(self) def do(self): try: self.func(*self.args, **self.kwargs) except Exception as exc: LOGGER.error( "==== UNCAUGHT EXCEPTION IN THREAD ===", exc_info=exc ) finally: self.core.call_all("mainloop_unref", self) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/thread/pool.py000066400000000000000000000034011456262201400266360ustar00rootroot00000000000000import logging import multiprocessing import queue import threading from . import Task from .. import PluginBase LOGGER = logging.getLogger(__name__) class Thread(threading.Thread): def __init__(self, plugin, thread_id): super().__init__(name="paperwork_thread_{}".format(thread_id)) self.daemon = True self.task_queue = plugin.queue self.core = plugin.core self.running = True def run(self): LOGGER.info("Thread %s ready", self.name) while True: task = self.task_queue.get() if task is None: break task.do() LOGGER.info("Thread %s stopped", self.name) class Plugin(PluginBase): def __init__(self): super().__init__() self.queue = queue.Queue() self.pool = None def get_interfaces(self): return ['thread'] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, ] def on_mainloop_start(self): if self.pool is None: self.pool = [ Thread(self, x) for x in range(0, max(4, multiprocessing.cpu_count())) ] for t in self.pool: t.start() def on_mainloop_quit(self): if self.pool is not None: for t in self.pool: self.queue.put(None) # in case the mainloop is restarted later: self.queue = queue.Queue() self.pool = None def thread_start(self, func, *args, **kwargs): if self.pool is None: self.on_mainloop_start() task = Task(self.core, func, args, kwargs) self.queue.put(task) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/thread/simple.py000066400000000000000000000013071456262201400271610ustar00rootroot00000000000000import threading from . import Task from .. import PluginBase class Plugin(PluginBase): """ Simply create a thread for each task to run. Less efficient than a thread pool, but may be useful for testing or debugging. """ def get_interfaces(self): return ['thread'] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, ] def thread_start(self, func, *args, **kwargs): task = Task(self.core, func, args, kwargs) thread = threading.Thread(target=task.do) thread.daemon = True thread.start() return True paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/thread/tests.py000066400000000000000000000042671456262201400270420ustar00rootroot00000000000000import threading import unittest from .. import (Core, PluginBase) class AbstractTestThread(unittest.TestCase): def get_plugin_name(self): """ Must be overloaded by subclasses """ assert False def setUp(self): class DummyMainloop(object): class Plugin(PluginBase): def get_interfaces(s): return ['mainloop'] def mainloop_ref(s, r): pass def mainloop_unref(s, r): pass self.core = Core(auto_load_dependencies=True) self.core._load_module("dummy_mainloop", DummyMainloop()) self.core.load(self.get_plugin_name()) self.core.init() def test_basic(self): out = { 'task_a_done': False, 'task_b_done': False, } sem = threading.Semaphore(value=0) def task_a(): out['task_a_done'] = True sem.release() def task_b(): out['task_b_done'] = True sem.release() self.core.call_all("on_mainloop_start") self.core.call_one("thread_start", task_a) self.core.call_one("thread_start", task_b) for _ in range(0, 2): sem.acquire() self.assertTrue(out['task_a_done']) self.assertTrue(out['task_b_done']) self.core.call_all("on_mainloop_quit") def test_mainloop_restart(self): # mainloop can be stopped and started again many times out = {} sem = threading.Semaphore(value=0) def task_a(): out['task_a_done'] = True sem.release() out['task_a_done'] = False self.core.call_all("on_mainloop_start") self.core.call_one("thread_start", task_a) for _ in range(0, 1): sem.acquire() self.assertTrue(out['task_a_done']) self.core.call_all("on_mainloop_quit") out['task_a_done'] = False self.core.call_all("on_mainloop_start") self.core.call_one("thread_start", task_a) for _ in range(0, 1): sem.acquire() self.assertTrue(out['task_a_done']) self.core.call_all("on_mainloop_quit") paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/uncaught_exception.py000066400000000000000000000026501456262201400303170ustar00rootroot00000000000000import sys from . import PluginBase class Plugin(PluginBase): def __init__(self): super().__init__() self.original_hook = sys.excepthook def get_interfaces(self): return ['uncaught_exception'] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, ] def init(self, core): super().init(core) sys.excepthook = self._on_uncaught_exception def _on_uncaught_exception(self, exc_type, exc_value, exc_tb): exc_info = (exc_type, exc_value, exc_tb) try: self.core.call_one( "mainloop_execute", self._broadcast_exception, exc_info ) finally: if getattr(sys, 'frozen', False): # Assumes that cx_freeze has put a specific handler # for uncatched exceptions (popup and stuff) self.original_hook(exc_type, exc_value, exc_tb) def _broadcast_exception(self, exc_info): # make sure we don't loop sys.excepthook = self.original_hook try: nb = self.core.call_all("on_uncaught_exception", exc_info) if nb <= 0: # no log handler yet --> switch back to default self.original_hook(*exc_info) finally: sys.excepthook = self._on_uncaught_exception paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/urls.py000066400000000000000000000015201456262201400254030ustar00rootroot00000000000000from . import PluginBase class Plugin(PluginBase): def get_interfaces(self): return ['urls'] def url_args_join(self, *args, **kwargs): out = "".join(args) if len(kwargs) <= 0: return out first = True for (k, v) in sorted(list(kwargs.items())): if v is None: continue if first: out += "#" first = False else: out += "&" out += "{}={}".format(k, v) return out def url_args_split(self, url): if "#" not in url: return (url, {}) (base, kwargs) = url.split("#", 1) kwargs = kwargs.split("&") out = {} for kwarg in kwargs: (k, v) = kwarg.split("=", 1) out[k] = v return (base, out) paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/work_queue/000077500000000000000000000000001456262201400262345ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/work_queue/__init__.py000066400000000000000000000000001456262201400303330ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/src/openpaperwork_core/work_queue/default.py000066400000000000000000000110371456262201400302340ustar00rootroot00000000000000import logging import heapq import threading import traceback from .. import PluginBase LOGGER = logging.getLogger(__name__) class Task(object): def __init__(self, work_queue, priority, insert_number, promise): self.work_queue = work_queue self.priority = priority self.insert_number = insert_number self.promise = promise self.active = True self.created_by = traceback.extract_stack() def _on_error(self, exc, hide_error): if not hide_error: LOGGER.error("=== Promise was queued by ===") for (idx, stack_el) in enumerate(self.created_by): LOGGER.error( "%2d: %20s: L%5d: %s", idx, stack_el[0], stack_el[1], stack_el[2] ) self.work_queue._run_next_promise_locked() raise exc def __lt__(self, o): if self.priority < o.priority: return True if self.priority > o.priority: return False if self.insert_number < o.insert_number: return True return False class WorkQueue(object): def __init__(self, name, stop_on_quit, hide_uncatched): self.insert_number = 0 self.name = name self.lock = threading.RLock() self.queue = [] self.all_tasks = {} self.running = False self.stop_on_quit = stop_on_quit self.hide_uncatched = hide_uncatched def add_promise(self, promise, priority=0): self.insert_number += 1 task = Task(self, -1 * priority, self.insert_number, promise) with self.lock: heapq.heappush(self.queue, task) assert ( promise not in self.all_tasks or not self.all_tasks[promise].active ) self.all_tasks[promise] = task if not self.running: self._run_next_promise() def _run_next_promise(self): self.running = True try: task = None while task is None or not task.active: task = heapq.heappop(self.queue) if task.active: self.all_tasks.pop(task.promise) except IndexError: self.running = False return promise = task.promise.then(self._run_next_promise_locked) promise.catch(task._on_error, self.hide_uncatched) promise.schedule() def _run_next_promise_locked(self, *args, **kwargs): with self.lock: self._run_next_promise() def cancel(self, promise): try: with self.lock: task = self.all_tasks[promise] task.active = False except KeyError: LOGGER.debug( "Cannot cancel promise [%s]. (already running ?)", promise ) def cancel_all(self): # reset the queue with self.lock: self.queue = [] self.all_tasks = {} class Plugin(PluginBase): def __init__(self): self.queues = {} def get_interfaces(self): return ['work_queue'] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, ] def work_queue_create( self, queue_name, stop_on_quit=False, hide_uncatched=False): LOGGER.debug( "Creating work queue [%s] (stop_on_quit=%s)", queue_name, stop_on_quit ) self.queues[queue_name] = WorkQueue( queue_name, stop_on_quit, hide_uncatched ) return True def work_queue_add_promise(self, queue_name, promise, priority=0): if queue_name not in self.queues: return None self.queues[queue_name].add_promise(promise, priority) return True def work_queue_cancel(self, queue_name, promise): if queue_name not in self.queues: return None self.queues[queue_name].cancel(promise) return True def work_queue_cancel_all(self, queue_name): if queue_name not in self.queues: return None self.queues[queue_name].cancel_all() return True def mainloop_quit(self): # violent quit (does it ever happen ?) for queue in self.queues.values(): queue.cancel_all() def mainloop_quit_graceful(self): for queue in self.queues.values(): if queue.stop_on_quit: queue.cancel_all() def on_quit(self): self.mainloop_quit_graceful() paperwork-2.2.2/openpaperwork-core/tests/000077500000000000000000000000001456262201400205155ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/__init__.py000066400000000000000000000000001456262201400226140ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/beacon/000077500000000000000000000000001456262201400217445ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/beacon/__init__.py000066400000000000000000000000001456262201400240430ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/beacon/tests_stats.py000066400000000000000000000126661456262201400247110ustar00rootroot00000000000000import cgi import datetime import http import http.server import json import unittest import threading import time import urllib import openpaperwork_core class TestStats(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) class FakeAppModule(object): class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['app'] def app_get_name(self): return "Paperwork" def app_get_fs_name(self): return "paperwork2" def app_get_version(self): return "2.1" self.core._load_module("fake_app", FakeAppModule()) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.beacon.stats") self.config = self.core.get_by_name("openpaperwork_core.config.fake") self.received = [] self.stats_sent = False def test_send_stats(self): self.received = [] class TestRequestHandler(http.server.BaseHTTPRequestHandler): def do_POST(s): (ctype, pdict) = cgi.parse_header( s.headers['Content-Type'] ) if ctype == 'multipart/form-data': data = cgi.parse_multipart(s.rfile, pdict) elif ctype == 'application/x-www-form-urlencoded': length = int(s.headers['Content-Length']) data = urllib.parse.parse_qs( s.rfile.read(length), keep_blank_values=1 ) else: data = {} self.received.append( (s.path, json.loads(data[b'statistics'][0])) ) s.send_response(200) s.send_header('Content-type', 'text/html') s.end_headers() s.wfile.write(b"

OK

") with http.server.HTTPServer(('', 0), TestRequestHandler) as h: self.config.settings = { "send_statistics": True, "uuid": 1245, "statistics_last_run": datetime.date(1995, 1, 1), "statistics_protocol": "http", "statistics_server": "127.0.0.1:{}".format(h.server_port), } threading.Thread(target=h.handle_request).start() time.sleep(0.1) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def stats_get(self, stats): stats['nb_documents'] += 122 stats['truck'] = 42 def on_stats_sent(s): self.stats_sent = True self.core._load_module( "fake_module", FakeModule() ) self.core.init() self.core.call_all("mainloop_quit_graceful") self.core.call_one('mainloop') self.assertTrue(self.stats_sent) self.assertEqual(len(self.received), 1) self.assertEqual(self.received[0][0], "/beacon/post_statistics") self.assertEqual(self.received[0][1]['uuid'], 1245) self.assertEqual(self.received[0][1]['nb_documents'], 122) self.assertEqual(self.received[0][1]['truck'], 42) def test_server_down(self): self.received = [] class TestRequestHandler(http.server.BaseHTTPRequestHandler): def do_POST(s): (ctype, pdict) = cgi.parse_header( s.headers['Content-Type'] ) if ctype == 'multipart/form-data': data = cgi.parse_multipart(s.rfile, pdict) elif ctype == 'application/x-www-form-urlencoded': length = int(s.headers['Content-Length']) data = urllib.parse.parse_qs( s.rfile.read(length), keep_blank_values=1 ) else: data = {} self.received.append( (s.path, json.loads(data[b'statistics'][0])) ) s.send_response(500) s.send_header('Content-type', 'text/html') s.end_headers() s.wfile.write(b"

KO

") with http.server.HTTPServer(('', 0), TestRequestHandler) as h: self.config.settings = { "send_statistics": True, "uuid": 1245, "statistics_last_run": datetime.date(1995, 1, 1), "statistics_protocol": "http", "statistics_server": "127.0.0.1:{}".format(h.server_port), } threading.Thread(target=h.handle_request).start() time.sleep(0.1) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def stats_get(self, stats): stats['nb_documents'] += 122 stats['truck'] = 42 def on_stats_sent(s): self.stats_sent = True self.core._load_module( "fake_module", FakeModule() ) self.core.init() self.core.call_all("mainloop_quit_graceful") self.core.call_one('mainloop') self.assertFalse(self.stats_sent) paperwork-2.2.2/openpaperwork-core/tests/beacon/tests_sysinfo.py000066400000000000000000000022541456262201400252350ustar00rootroot00000000000000import unittest import openpaperwork_core class TestSysinfo(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) class FakeAppModule(object): class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['app'] def app_get_name(self): return "Paperwork" def app_get_fs_name(self): return "paperwork2" def app_get_version(self): return "2.1" self.core._load_module("fake_app", FakeAppModule()) self.core.load("openpaperwork_core.beacon.sysinfo") self.core.init() def test_get(self): # just go through the code to make sure it actually runs correctly # (we cannot check the output since it's system-dependant) out = {} self.core.call_all("stats_get", out) self.assertIn('os_name', out) self.assertIn('platform_architecture', out) self.assertIn('platform_processor', out) self.assertIn('platform_distribution', out) self.assertIn('cpu_count', out) paperwork-2.2.2/openpaperwork-core/tests/cmd/000077500000000000000000000000001456262201400212605ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/cmd/__init__.py000066400000000000000000000000001456262201400233570ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/cmd/tests_config.py000066400000000000000000000122631456262201400243250ustar00rootroot00000000000000import argparse import unittest import openpaperwork_core import openpaperwork_core.cmd class MockConfigBackendModule(object): """ Plugin paperwork_backend.config uses openpaperwork.config_file. This mock mocks openpaperwork.config_file so we can test paperwork_backend.config.file """ class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.calls = [] self.returns = {} self.config_backend_load = ( lambda *args, **kwargs: self._handle_call('config_backend_load', args, kwargs) ) self.config_backend_save = ( lambda *args, **kwargs: self._handle_call('config_backend_save', args, kwargs) ) self.config_backend_load_plugins = ( lambda *args, **kwargs: self._handle_call('config_backend_load_plugins', args, kwargs) ) self.config_backend_add_plugin = ( lambda *args, **kwargs: self._handle_call('config_backend_add_plugin', args, kwargs) ) self.config_backend_remove_plugin = ( lambda *args, **kwargs: self._handle_call('config_backend_remove_plugin', args, kwargs) ) self.config_backend_put = ( lambda *args, **kwargs: self._handle_call('config_backend_put', args, kwargs) ) self.config_backend_get = ( lambda *args, **kwargs: self._handle_call('config_backend_get', args, kwargs) ) self.config_backend_add_observer = ( lambda *args, **kwargs: self._handle_call('config_backend_add_observer', args, kwargs) ) self.config_backend_remove_observer = ( lambda *args, **kwargs: self._handle_call( 'config_backend_remove_observer', args, kwargs ) ) self.config_backend_list_active_plugins = ( lambda *args, **kwargs: self._handle_call( 'config_backend_list_active_plugins', args, kwargs ) ) def _handle_call(self, func, args, kwargs): self.calls.append((func, args, kwargs)) if func not in self.returns: return None r = self.returns[func].pop(0) if len(self.returns[func]) <= 0: self.returns.pop(func) return r def get_interfaces(self): return ["config_backend"] class TestConfig(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core._load_module( "openpaperwork_core.config.backend.configparser", MockConfigBackendModule() ) self.core.load("openpaperwork_core.cmd.config") self.core.init() setting = self.core.call_success( "config_build_simple", "Global", "WorkDirectory", lambda: "file:///home/toto/papers" ) self.core.call_all("config_register", "workdir", setting) def test_get_put(self): self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).returns = { 'config_backend_put': [None], 'config_backend_save': [None], 'config_backend_get': ['file:///pouet/path'] } parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args( ['config', 'put', 'workdir', 'str', 'file:///pouet/path'] ) self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertTrue(r) self.assertEqual( self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).calls, [ ( 'config_backend_put', ('Global', "WorkDirectory", "file:///pouet/path"), {} ), ('config_backend_save', (), {}), ] ) args = parser.parse_args(['config', 'get', 'workdir']) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertEqual(r, {"workdir": "file:///pouet/path"}) self.assertEqual( self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).calls, [ ( 'config_backend_put', ('Global', "WorkDirectory", "file:///pouet/path"), {} ), ('config_backend_save', (), {}), # it uses the cache for the get # --> no call to config_backend_get ] ) paperwork-2.2.2/openpaperwork-core/tests/cmd/tests_plugins.py000066400000000000000000000055761456262201400245520ustar00rootroot00000000000000import argparse import os import tempfile import unittest import openpaperwork_core import openpaperwork_core.cmd class TestConfig(unittest.TestCase): def setUp(self): self.config_path = tempfile.NamedTemporaryFile(delete=False) self.config_path.close() self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.cmd.plugins") self.core.init() self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).TEST_FILE_URL = "file://" + self.config_path.name self.core.load = lambda *args, **kwargs: None setting = self.core.call_success( "config_build_simple", "Global", "WorkDirectory", lambda: "file:///home/toto/papers" ) self.core.call_all("config_register", "workdir", setting) def tearDown(self): os.unlink(self.config_path.name) def test_add_remove_list_plugin(self): self.core.call_all('config_load') self.core.call_all( 'config_load_plugins', 'paperwork-shell', default_plugins=['pouet'] ) parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) args = parser.parse_args( ['plugins', 'add', 'plugin_a', '--no_auto'] ) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertTrue(r) args = parser.parse_args( ['plugins', 'add', 'plugin_b', '--no_auto'] ) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertTrue(r) args = parser.parse_args( ['plugins', 'add', 'plugin_c', '--no_auto'] ) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertTrue(r) args = parser.parse_args(['plugins', 'list']) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertEqual( sorted(r), ['plugin_a', 'plugin_b', 'plugin_c', 'pouet'] ) args = parser.parse_args( ['plugins', 'remove', 'plugin_b', '--no_auto'] ) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertTrue(r) args = parser.parse_args(['plugins', 'list']) r = self.core.call_success( "cmd_run", openpaperwork_core.cmd.DummyConsole(), args ) self.assertEqual(sorted(r), ['plugin_a', 'plugin_c', 'pouet']) paperwork-2.2.2/openpaperwork-core/tests/config/000077500000000000000000000000001456262201400217625ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/config/__init__.py000066400000000000000000000000001456262201400240610ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/config/backend/000077500000000000000000000000001456262201400233515ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/config/backend/__init__.py000066400000000000000000000000001456262201400254500ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/config/backend/tests_configparser.py000066400000000000000000000251241456262201400276330ustar00rootroot00000000000000import datetime import tempfile import unittest import unittest.mock import openpaperwork_core class TestReadWrite(unittest.TestCase): def test_simple_getset(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() core.call_all( 'config_backend_put', 'test_section', 'test_key', 'test_value' ) v = core.call_one('config_backend_get', 'test_section', 'test_key') self.assertEqual(v, 'test_value') v = core.call_one( 'config_backend_get', 'wrong_section', 'test_key', 'default' ) self.assertEqual(v, 'default') self.assertIsNone( core.call_success( 'config_backend_get', 'test_section', 'wrong_key' ) ) core.call_all('config_add_plugin', 'some_opt', 'some_test_module') finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_no_config_file(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() # must not throw an exception core.call_all('config_backend_load', 'openpaperwork_test') finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_simple_readwrite(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() core.call_all( 'config_backend_put', 'test_section', 'test_key', 'test_value' ) core.call_all( 'config_backend_add_plugin', 'some_opt', 'some_test_module' ) core.call_all('config_backend_save', 'openpaperwork_test') core.call_all('config_backend_load', 'openpaperwork_test') v = core.call_one('config_backend_get', 'test_section', 'test_key') self.assertEqual(v, 'test_value') v = core.call_one( 'config_backend_get', 'wrong_section', 'test_key', 'default' ) self.assertEqual(v, 'default') self.assertIsNone( core.call_success( 'config_backend_get', 'test_section', 'wrong_key' ) ) finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_observers(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) class Observer(object): def __init__(self): self.count = 0 def obs(self): self.count += 1 try: core.init() obs = Observer() core.call_all( 'config_backend_add_observer', 'test_section', obs.obs ) core.call_all( 'config_backend_put', 'other_section', 'test_key', 'test_value' ) self.assertEqual(obs.count, 0) core.call_all( 'config_backend_put', 'test_section', 'test_key', 'test_value' ) self.assertEqual(obs.count, 1) core.call_all( 'config_backend_add_plugin', 'some_opt', 'some_test_module' ) self.assertEqual(obs.count, 1) core.call_all('config_backend_save', 'openpaperwork_test') self.assertEqual(obs.count, 1) core.call_all('config_backend_load', 'openpaperwork_test') self.assertEqual(obs.count, 2) finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_simple_readwrite_list(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() v = core.call_success( 'config_backend_get', 'test_section', 'test_key', default=["test_value_a", "test_value_b"] ) self.assertNotEqual(v, None) self.assertEqual(len(v), 2) v[1] = 'test_value_c' core.call_all('config_backend_put', 'test_section', 'test_key', v) v = core.call_success( 'config_backend_get', 'test_section', 'test_key', default=["test_value_a", "test_value_b"] ) self.assertEqual(len(v), 2) self.assertEqual(v[1], "test_value_c") core.call_all('config_backend_save', 'openpaperwork_test') core.call_all('config_backend_load', 'openpaperwork_test') v = core.call_success( 'config_backend_get', 'test_section', 'test_key', default=["test_value_a", "test_value_b"] ) self.assertEqual(len(v), 2) self.assertEqual(v[1], "test_value_c") finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_simple_readwrite_dict(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() v = core.call_success( 'config_backend_get', 'test_section', 'test_key', default={ "test_key_a": "test_key_b", "test_key_b": "test_value_b" } ) self.assertNotEqual(v, None) self.assertEqual(len(v), 2) v['test_key_b'] = 'test_value_c' core.call_all('config_backend_put', 'test_section', 'test_key', v) v = core.call_success( 'config_backend_get', 'test_section', 'test_key', default={ "test_key_a": "test_key_b", "test_key_b": "test_value_b" } ) self.assertEqual(len(v), 2) self.assertEqual(v['test_key_b'], "test_value_c") core.call_all('config_backend_save', 'openpaperwork_test') core.call_all('config_backend_load', 'openpaperwork_test') v = core.call_success( 'config_backend_get', 'test_section', 'test_key', default={ "test_key_a": "test_key_b", "test_key_b": "test_value_b" } ) self.assertEqual(len(v), 2) self.assertEqual(v['test_key_b'], "test_value_c") finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_getset_date(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() core.call_all( 'config_backend_put', 'test_section', 'test_key', datetime.date(year=1985, month=1, day=1) ) core.call_all('config_backend_save', 'openpaperwork_test') core.call_all('config_backend_load', 'openpaperwork_test') v = core.call_one('config_backend_get', 'test_section', 'test_key') self.assertEqual(v, datetime.date(year=1985, month=1, day=1)) self.assertTrue(isinstance(v, datetime.date)) finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) def test_getset_bool(self): core = openpaperwork_core.Core(auto_load_dependencies=True) core.load('openpaperwork_core.config.backend.configparser') core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path = "file://" + tempfile.mkdtemp( prefix='openpaperwork_core_config_tests' ) try: core.init() core.call_all( 'config_backend_put', 'test_section', 'test_key', True ) core.call_all('config_backend_save', 'openpaperwork_test') core.call_all('config_backend_load', 'openpaperwork_test') v = core.call_one('config_backend_get', 'test_section', 'test_key') self.assertTrue(v) self.assertTrue(isinstance(v, bool)) finally: core.call_success("fs_rm_rf", core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).base_path, trash=False) paperwork-2.2.2/openpaperwork-core/tests/config/tests_config.py000066400000000000000000000123501456262201400250240ustar00rootroot00000000000000import unittest import openpaperwork_core class MockConfigBackendModule(object): """ Plugin paperwork_backend.config uses openpaperwork.config_file. This mock mocks openpaperwork.config_file so we can test paperwork_backend.config.file """ class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.calls = [] self.rets = {} self.config_backend_load = ( lambda *args, **kwargs: self._handle_call('config_backend_load', args, kwargs) ) self.config_backend_save = ( lambda *args, **kwargs: self._handle_call('config_backend_save', args, kwargs) ) self.config_backend_load_plugins = ( lambda *args, **kwargs: self._handle_call('config_backend_load_plugins', args, kwargs) ) self.config_backend_add_plugin = ( lambda *args, **kwargs: self._handle_call('config_backend_add_plugin', args, kwargs) ) self.config_backend_remove_plugin = ( lambda *args, **kwargs: self._handle_call('config_backend_remove_plugin', args, kwargs) ) self.config_backend_put = ( lambda *args, **kwargs: self._handle_call('config_backend_put', args, kwargs) ) self.config_backend_get = ( lambda *args, **kwargs: self._handle_call('config_backend_get', args, kwargs) ) self.config_backend_add_observer = ( lambda *args, **kwargs: self._handle_call('config_backend_add_observer', args, kwargs) ) self.config_backend_remove_observer = ( lambda *args, **kwargs: self._handle_call( 'config_backend_remove_observer', args, kwargs ) ) def _handle_call(self, func, args, kwargs): self.calls.append((func, args, kwargs)) if func not in self.rets: return None r = self.rets[func].pop(0) if len(self.rets[func]) <= 0: self.rets.pop(func) return r def get_interfaces(self): return ["config_backend"] class TestConfig(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core._load_module( "openpaperwork_core.config.backend.configparser", MockConfigBackendModule() ) self.core.load("openpaperwork_core.config") self.core.init() setting = self.core.call_success( "config_build_simple", "Global", "WorkDirectory", lambda: "file:///home/toto/papers" ) self.core.call_all("config_register", "workdir", setting) def test_config_load(self): self.core.call_all('config_load') self.core.call_all( 'config_load_plugins', 'some_plugin_list_name', default_plugins=['pouet'] ) self.assertEqual( self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).calls, [ ('config_backend_load', ('openpaperwork_core',), {}), ( 'config_backend_load_plugins', ('some_plugin_list_name', ['pouet'],), {} ), ] ) def test_get_default(self): default = self.core.call_success("config_get", "workdir") self.assertEqual( self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).calls, [ ('config_backend_get', ('Global', "WorkDirectory", None), {}), ] ) self.assertEqual(default, "file:///home/toto/papers") def test_get_nondefault(self): self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).rets = { 'config_backend_get': ['file:///pouet/path'] } val = self.core.call_success( "config_get", "workdir" ) self.assertEqual( self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).calls, [ ('config_backend_get', ('Global', "WorkDirectory", None), {}), ] ) self.assertEqual(val, "file:///pouet/path") def test_get_cache(self): self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).rets = { # only one call expected 'config_backend_get': ['file:///pouet/path'] } val1 = self.core.call_success("config_get", "workdir") val2 = self.core.call_success("config_get", "workdir") self.assertEqual( self.core.get_by_name( 'openpaperwork_core.config.backend.configparser' ).calls, [ ('config_backend_get', ('Global', "WorkDirectory", None), {}), ] ) self.assertEqual(val1, "file:///pouet/path") self.assertEqual(val1, val2) paperwork-2.2.2/openpaperwork-core/tests/fs/000077500000000000000000000000001456262201400211255ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/fs/__init__.py000066400000000000000000000000001456262201400232240ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/fs/tests_memory.py000066400000000000000000000037161456262201400242400ustar00rootroot00000000000000import unittest import openpaperwork_core class TestSafe(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.memory") self.core.init() def test_write_read_bytes(self): with self.core.call_success( "fs_open", "memory://test_file", mode="wb" ) as file_desc: file_desc.write(b"abcdef") file_desc.write(b"ghijf") with self.core.call_success( "fs_open", "memory://test_file", mode="rb" ) as file_desc: r = file_desc.read() self.assertEqual(r, b'abcdefghijf') self.core.call_success("fs_unlink", "memory://test_file", trash=False) def test_write_read_string(self): with self.core.call_success( "fs_open", "memory://test_file", mode="w" ) as file_desc: file_desc.write("abcdef\n") file_desc.write("ghijf\n") with self.core.call_success( "fs_open", "memory://test_file", mode="r" ) as file_desc: r = file_desc.readlines() self.assertEqual(r, [ 'abcdef\n', 'ghijf\n' ]) self.core.call_success("fs_unlink", "memory://test_file", trash=False) def test_write_read_tempfile(self): (name, file_desc) = self.core.call_success( "fs_mktemp", "camion", "tulipe", mode="w" ) with file_desc: self.assertTrue(name.startswith("memory://")) file_desc.write("abcdef\n") file_desc.write("ghijf\n") with self.core.call_success("fs_open", name, mode="r") as file_desc: r = file_desc.readlines() self.assertEqual(r, [ 'abcdef\n', 'ghijf\n' ]) self.core.call_success("fs_unlink", name, trash=False) paperwork-2.2.2/openpaperwork-core/tests/fs/tests_python.py000066400000000000000000000036501456262201400242460ustar00rootroot00000000000000import openpaperwork_core.tests.local_file PLUGIN_NAME = "openpaperwork_core.fs.python" class TestSafe(openpaperwork_core.tests.local_file.AbstractTestSafe): def get_plugin_name(self): return PLUGIN_NAME class TestUnsafe(openpaperwork_core.tests.local_file.AbstractTestUnsafe): def get_plugin_name(self): return PLUGIN_NAME class TestOpen(openpaperwork_core.tests.local_file.AbstractTestOpen): def get_plugin_name(self): return PLUGIN_NAME class TestExists(openpaperwork_core.tests.local_file.AbstractTestExists): def get_plugin_name(self): return PLUGIN_NAME class TestListDir(openpaperwork_core.tests.local_file.AbstractTestListDir): def get_plugin_name(self): return PLUGIN_NAME class TestRename(openpaperwork_core.tests.local_file.AbstractTestRename): def get_plugin_name(self): return PLUGIN_NAME class TestUnlink(openpaperwork_core.tests.local_file.AbstractTestUnlink): def get_plugin_name(self): return PLUGIN_NAME class TestGetMtime(openpaperwork_core.tests.local_file.AbstractTestGetMtime): def get_plugin_name(self): return PLUGIN_NAME class TestGetsize(openpaperwork_core.tests.local_file.AbstractTestGetsize): def get_plugin_name(self): return PLUGIN_NAME class TestIsdir(openpaperwork_core.tests.local_file.AbstractTestIsdir): def get_plugin_name(self): return PLUGIN_NAME class TestCopy(openpaperwork_core.tests.local_file.AbstractTestCopy): def get_plugin_name(self): return PLUGIN_NAME class TestMkdirP(openpaperwork_core.tests.local_file.AbstractTestMkdirP): def get_plugin_name(self): return PLUGIN_NAME class TestBasename(openpaperwork_core.tests.local_file.AbstractTestBasename): def get_plugin_name(self): return PLUGIN_NAME class TestTemp(openpaperwork_core.tests.local_file.AbstractTestTemp): def get_plugin_name(self): return PLUGIN_NAME paperwork-2.2.2/openpaperwork-core/tests/mainloop/000077500000000000000000000000001456262201400223335ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/mainloop/__init__.py000066400000000000000000000000001456262201400244320ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/mainloop/tests_asyncio.py000066400000000000000000000005531456262201400255770ustar00rootroot00000000000000import openpaperwork_core.mainloop.tests class TestCallback(openpaperwork_core.mainloop.tests.AbstractTestCallback): def get_plugin_name(self): return "openpaperwork_core.mainloop.asyncio" class TestPromise(openpaperwork_core.mainloop.tests.AbstractTestPromise): def get_plugin_name(self): return "openpaperwork_core.mainloop.asyncio" paperwork-2.2.2/openpaperwork-core/tests/pillow/000077500000000000000000000000001456262201400220235ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/pillow/test_doc.png000066400000000000000000001263371456262201400243510ustar00rootroot00000000000000‰PNG  IHDR L $¶È¬¦IDATxœìÝg˜U塸í5•™‘^DT"R”¢R4ö^4ŠL +*1ösŒQcþ»49Ñ(VD;⨈H3€à(‚ "½Ã~?ì÷¬kŸa¦Á̃÷ýÁk•g¯õì2øáw­µÒ‰D„#½º'”Èù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"&³º'ÕiöìÙóæÍ+¶±Y³f:t¨ŽéUoñâÅ/½ôÒ„ –.]š““Ó¬Y³îÝ»_~ùåeymQQQ~~þ¶Û÷Ýwß¶mÛVõLÊ!-‘HT÷ Ú<üð÷ÞzëºuëR7öíÛ÷¹çž«®)UhàÀ7ß|óúõëS7ÖªUkãÆeyù† :è o¿ý¶¨¨(u{ÿþýÿñTåDÊÉ•|„aõêÕ/¼ðBÕ³k×®×^{í5×\3wîÜaÆÝ|óÍUrØ+VÜu×]³gÏîÑ£Çå—_ž––V%‡ nT‰üüü¯¾úªô1YYYuêÔ©[·îþûïߦM›ôôíÞ‡¹,GKJKKËÎÎÎÍÍmÔ¨Ñ^{íÕºuëÜÜܪöÕªU뢋.ªÌî½÷Þäßõµ×^Û¿ÿ7¾øâ‹÷Þ{o±a¥ü½äææÎ™3góæÍ³gÏ:tèwÜQ™ùT!‘0,]ºôÊ+¯¬ÚcþùÏîÚµkZZZË–-»wï^%ÇL$§Ÿ~ú„ ¢(9räš5kn¼ñÆ*9rXs ªŒ5êïÿ{±ËÈJ‘——÷óŸÿ¼_¿~çwÞ{ìQÉ£ÅÒÓÓ[µjuôÑGŸ~úé={öÌÉÉ©Úi—¨^½z•‰|Ó§OÿãÿEÑQGõÐC%7rÈ!Ï?ÿü²eËâaeù{ÉÎÎnß¾}×®]+<€*çv„aöìÙmÚ´‰¢(##£yóæ{î¹gÆ sssóòò222222ÒÓÓ?øàƒ9sæ$Ççææžy晉DbË–-EEE6lX·nÝÚµkW¬X±téÒäúþüç?ß~ûíÉñ|ðÁñÇŸ\®Ìí:ç̙ӺuëxµsçΟ}öYEßtÕ„9P…’—‘}õÕW<ðÀ¸qã’333O=õÔ(жlÙ²zõê%K–Ì›7/õßó}öÙçïÿû9çœS®£Åc–/_¾|ùò%K–lذ¡ØêÕ«wå•WÞxã5ªð´c‰D¢¨¨¨¨¨hÓ¦M7n\µjÕòåËüñÇD"Q¯^½•+W–ùs*®W¯^¯¿þzE÷ßÿ 7Üo¿ùæ›y䑸veÿ{yýõ×{õê•\v»N Ú¹’ddd¬^½://¯Ä½ýúõ‹#_Æ ‡ ²½ãœsÎ9#FŒØ3lذaffæ–-[’«{î¹çÎ8KÍŸU(yYûöíßy縖í±ÇÉ‚[µjÕk¯½öÀLŸ>=Š¢ï¾û®wïÞ>øàu×]W£%þç?ÿ7nÜ /¼0yòäøD÷ÜsÏO<1pàÀ>}úTrÚ%zçwN;í´+ŲeËÞ~ûíärÛ¶mSw]yå• 4ˆWý½Ú ÚgŸ}¶WøÊ%õªՠAƒ¿ýíoɇ¢5iÒäî»ïÞI'ªás`׫W¯Þ\0iÒ¤~ýúů¿þú·Þz«ÂÇÌÊÊêÞ½ûu×]7iÒ¤üüü£Ž:*ÞµlÙ²óÏ?ÿOúS¥&½p@%ŸŸ¿½n×¢E‹?üáñª¿ P"!ÙÿýkÔqJtýõ×õÕWï¼óάY³:wî¼óNTÃç°kÜ}÷ÝiiiüquO¤d»~zÙÙÙO>ùdj$»þúë+ùl¼¤ãŽ;îƒ>øãÿ˜––o¼ë®»î¹çžÊ¼˜ýöÛ¯V­Z•9´iÓâåÜÜÜÒÿtþ^€Ý‰ÈGHZ´hQ£Ž³=­[·>å”Sêׯ¿SÏRóç°³mذáᇮîYlWuM/;;ûw¿û]¼úå—_N˜0¡JŽœ‘‘ñ׿þõñÇOÝxë­·Ž;¶JŽKOOoÕªUeŽðí·ßÆË™™;¾1õOáïØÍˆ|„!---##£eË–Ur´–-[fdd$oÐG¸žx≥K—V÷,¶«§wâ‰'¦®¾óÎ;Uxðþýû_uÕUñjQQÑoûÛ­[·Vá)¢Jß±sõêÕU5€šiÇ×7@MЪU«ø [•wà–r´Ô»RcÞÿýÕ=‹íªÞéxàéééqx›;wnÕÿÁ1bÄâÅ‹“«Ó§Oíµ×Î>ûì*<ÅSO=µ~ýú ¿¼2¯‚ÈÅ¥ÞÜoëÖ­“'O?~üÂ… ‰DË–-{ôèQâÝ>‰Ä¶O>KOO/åzÁD"1qâÄO?ýô»ï¾[¿~}nnn“&M~ö³ŸpÀíÚµÛáƒÄjæŠùñÇgΜ¹xñâ+V¬X±"==½aÆ:tèÚµkvvveŽüÜsÏÍŸ??¹\TT”Zm322¶Wj Ç7eÊ”¥K—nÚ´©Q£FmÚ´9þøã›6mZúéÊûAUlzU%--­^½z+V¬H®þðÃU{üZµjÝxã7ÜpC¼åþçª6òÕ¯_¿Â7ÏL$›7oŽW‹}þÑÿþWà良*ü{Ø!‘ŠËËË‹¢hÒ¤IO=õÔK/½´|ùòÔ½×]wÝßþö·b%àùçŸÿõ¯]ìP}ûö}î¹çJ<˨Q£n¼ñÆY³f•¸7##ã•W^9묳Ê5óš0‡ØUW]5bĈ%K–”¸·qãÆ7ÜpÃM7Ý”‘‘Q®Ã~ÿý÷¯¼òʈ#>øàƒxãqÇ—:fôèÑ'tR±nذáÁ¼ï¾ûV­ZUlWZZÚ¹çž{÷Ýwoï9peÿ *<½*—šµ²²²ªüøýû÷¿å–[â––ŸŸ¿víÚÚµkWù‰Êî›o¾9räG}4vìØeË–ÅÛ:è b# 333Ëû÷R.•ù½”…ÈÅ-X°à„NÈÏÏ/qoQQÑý÷ߟý׿þ5uûyçwàN:uôèÑ/¿ür駸ï¾û~ÿûßGQ”žžþË_þòè£Þ{ï½W¯^=}úô!C†ÌŸ?¿¨¨hÆ åyM˜Cì³Ï>K¾<ðÌ3Ï<äCêׯ¿dÉ’ÿûßãÇ_¶lÙ-·Ü2sæÌgŸ}¶\‡}ì±ÇxàbsssS›k굘IK–,9õÔS§OŸEQNNÎ\pì±ÇæääL:õñÇ_¶lÙË/¿ÈرcK¹aÆvíÚ%G6jÔhÚ´i©{çÏŸ¿Ï>û$÷6mÚtÙ²e©{+üA•}ze׿ÿø˜õêÕ+eäÔ©SSÿ¿÷Þ{+s´íùïÿþïÔ³<øàƒ•œöôéÓ÷ØcaÆU`2Åœxâ‰ñI J¼Ã¿—¤Q£FÅÃú÷�a•ù½”]•=yv§Ÿ~ú°aÃn»í¶Þ½{sÌ1:t8òÈ#¯ºêªÏ?ÿ<¾"ª°°ðÕW_­Øñï¿ÿþD"EQÏž={ôèQloNNÎÕW_]‰é× 9äææ^tÑEÅ6fff&/ŒKzá…*¢ÒÝvÛmÉåýë_‡rHêÞæÍ›Ç—}ÿý÷wÞygêÞšðeUÀû￟ºzꩧ´mÛ6uuÞ¼y•<àgŸ}¶nݺÂÂÂJ§zUæ÷Pv"”UÆ ¯»îºxuÚ´i;Nü´¶Î;—8 W¯^-[¶ÌÎήØñkÎŽ;î¸ÜÜÜm·wëÖ-^®ðÇXF«V­8p`r¹}ûögŸ}ö¶cz÷î?Lî™gžÙ¸qc¼«&|YåUXX8hРxµk×®Å:SUiÔ¨Qêê÷ß_Éþç?ÿ©äª]%oeç™|P|p¼üã?Và[·n_¸téÒÇdeeÍ™3§¯Qs1bDNNN‰»RãЊ+*s–2dHüÀ¼³Î:«Ä1™™™‡~ø{ï½EÑÊ•+'Ož|ÔQGE5ã˪€k®¹&žRZZÚ½÷Þ»“NÔ°aÃÔÕ²<Á±¨¨hòäÉÛÛûÉ'ŸTÁ´ªUe~oåâJ>(‡½öÚ+^Þ´iSŽžž¾Ç{$—‡ºdÉ’ª™YÍ›C³fÍ4hP⮌ŒŒx¹¨¨hgœ=–zãÊN:moXË–-ãå)S¦$j—U._|ñE¯^½üñx˽÷Þ{üñÇï¤Óeee¥®&^Xºµk×vÛ¾I“&í¤©î2•ù½”‹+ù`W;äCÆEÑòåË=öØçŸ¾k×®?Á9ìŸ}öY¼¼ÿþûooXÓ¦MãåÅ‹ÇË5öƒÚ¼ysò¶[·n]½zõÂ… 'L˜0uêÔxÀ{ìñÀôïßçÍaÍš5©«Ûkº©ÒÒÒöÜsÏííýñÇ·lÙR3«>•ü½”È»Ú%—\’ìFQÍš5«[·n'žxâe—]Ö«W¯¼¼¼ŸÎvD"ñÍ7ßÄ«ñƒÐ¶•úìÀ•+WÆË5öƒÚ°aÃÕW_]â®úõëÿú׿¾þúë[´h±SçPÈW·nÝR.ˆìÕ«×믿^3«&•ÿ½”È»ÚÅ_üꫯ¦ÆŒ1cÆŒ3¦víÚ½{÷¾ä’KŽ>úèÝcëׯÏÏÏŸ2eÊܹsøá‡5kÖlܸqÓ¦M»Ói¬Y³fëÖ­ñj×®]·wKÉÂÂÂxyãÆñrMø²J”™™yÆg$—322êÔ©S¯^½–-[vëÖ­K—.Û{bÕ*öXÊÔG-VL§N‚Ž|•ÿ½”È»ZZZÚðáï»îºüã©O¤[»víàÁƒܽ{÷AƒíÔÛBîì9¬_¿þŽ;îxì±ÇÖ®]›Ü’žžÞ¸qã:uêäääĺÛÙŠ]j–““³½è’ZÅêÔ©/ׄ/«D{ì±Ç«¯¾º‹OZÌÌ™3SW>øàJ°”‡Ø¡ò¿7€²ù dee 8ðšk®4hЋ/¾¸téÒÔ½'N<òÈ#‡zÖYg…8‡µk×wÜqS¦L‰¢(==½ÿþ^xaçγ³³ã1Û‹U+3óÿü7cÆŒfÍš•÷ 5á˪™¦OŸ/§¥¥yä‘•<`÷îÝÏ8ãŒ}öÙ§’Ç©.Uò{(£ôêžütµiÓæá‡^´hј1c P·nÝx×æÍ›ûõë·páÂçpçw& _E=öØc=vØa‡¥¾]¦Ø5R•¹MhMø²j”-[¶Lž<9^m×®]åo×Ù¼yó×_½ºî€ZyUø{Ø!‘ªYFFÆ 'œ0pàÀ ÜtÓMñöµk×>òÈ#ÁÍ¡°°ð©§žJ.ï³Ï>—]vYUN´œòòò²²²âÕåË—Wò€5á˪!Þ~ûíÔgòõéÓ§'SCTùï  "ÔuëÖ½÷Þ{ï¹çžxË{ï½Ü¾þúëeË–%—?üðôôjþGæÀŒ—çÍ›WU‡­ _Võzæ™gâå¼¼¼TãdjŽô{ؖȻںuëJÙ{à 7ìµ×^ÉåÅ‹7‡ï¾û.^nܸqæVµ:vì/Oœ8±¼/¯ _V 4nܸaÆū—]vYåïÕ¹{¨äï  ìD>ØÕêÕ«WÊU_™™™q'ÈÉÉ nEEEñòæÍ›+6½*t 'ÄË/¿üraaa¹^^¾¬šfÍš5ýû÷O$ÉÕöíÛßu×]Õ;¥š£’¿7€²ù <ýôÓ¥ìÝ´iSraÿý÷nMš4‰—gΜYþy•UFFF¼¼bÅŠí ;÷Üssss“Ëß|óÍ£>ZÞUìƒ*ãô‚³bÅŠ“O>9þfëÔ©3|øðÚµkWï¬jŽÊÿÞŠŠŠn»í¶æÍ›7oÞüÎ;ïܺukUÏØMˆ|P †¾zõêw­\¹rÒ¤IÉå=z7‡:dee%—'Mš4yòämÇL:µ\Ç,QÆ ãåO>ùd{ÃêÖ­{õÕWÇ«·ÜrË /¼P®Uìƒ*ãô’H$^|ñÅ.]ºL˜0!¹¥yóæcÆŒI} •ÿ½=øàƒùË_.\¸páÂ?ÿùÏÈ„ÀO„ÈÕ`Æ guÖܹs·Ý~饗&Ÿ׬Y³+®¸"¸9äääôìÙ3¹œH$zöìùÔSO}ýõ׳gÏ7nÜÃ?Ü­[·.]ºdggWrþÝ»w—ÿþ÷¿¿ôÒK7nܲeË¢E‹òóó·lÙï½ãŽ;:tè\Þ¼ys¿~ýzõê5räÈùóç'‡­_¿þ›o¾ÉÏÏÿç?ÿùÈ#;QÅ>¨²O¯&(**š9sæüùó—-[¶fÍšM›6þðÃo¾ùæõ×_ß®]»_ýêWóæÍK¾äÔSOýì³ÏºuëV­¯‰*ù{1bDêê+¯¼²k¦ '-~®gæÌ™“&Mšû¿¦M›¶f͚䮌ŒŒÎ;ïÿ¿Ú¶m{ÜqÇ•x‚‚‚‰'¾þúëÆ Kniݺõ¥—^z衇víÚµ~ýúQmݺuæÌ™S¦L=zt|]Î~ûí7`À€Ÿÿüçݺu«U«Ö¼yó¾üòË‚‚‚>úèÕW_MŽiÕªUß¾}Ûµk×¶mÛ¶mÛ&Û–™™™|p]FFÆ)§œrÄG4mÚ´°°ð«¯¾zå•W¾ûî»(Š7nüî»ïvîܹ\HM˜CE_~ù塇º~ýú÷æåå <øÉ'Ÿ|ûí·“«7Þxãa‡vøá‡§^ý¶Ck×®mӦ͒%Kâ-éééñ½ ׬Y“zÉeË–yæ™ãÇ/v´´´ôôôÔçöéÓgÈ!ñj…?¨rM¯Ë–-{ã7f̘1cÆŒO?ýtåÊ•ñÑ:uêÿÂÛ´isòÉ'ïðhŸþùÇ\PPðå—_Nš4)>ZÙ¥¥¥õêÕ릛n:ꨣ*6íŽ;¶hÑb¿ýöKþ÷ÔSOïoYyÉÿرcGŽÿkеk×N:µoß¾}ûö:tØwß}“ÛËø÷2wîÜä'6f̘7ß|39¬mÛ¶çŸ~<¬X´®ðï-Š¢ÓN;íwÞ‰W{öì9jÔ¨Ê2Àn(ÁºðÂ Ëø;ßo¿ýJÀîÄ•|P=6nÜXPP0wîÜï¿ÿ~ݺuÙÙÙ 4hß¾ýÁ\ù[YÖ„9}úé§3fÌX·n]£FößÿŸÿüçñãúªÊúõëß{ï½9sædffî³Ï>:ujÙ²eé/ùá‡&Nœ¸téÒ+VÔªU«aÃ†É ¼¶Wò¢J|P˜Þ®TTT´õÿJÝEQ:uªð2»Ÿ¦ üÞ&L˜ðÌ3Ϥ¥¥]xá…nˆ lÈI¯î å#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>LfuOø‰zï½÷¶ÝxÌ1ÇdggïúÉT£Å‹¿ôÒK&LXºtiNNN³fͺwï~É%—äçço;xß}÷mÛ¶í®ŸdÕš={ö¼yóŠmlÖ¬Y‡ªc:AJK$Õ=২eË–óæÍ+öOÐâÅ‹÷Úk¯êšÒ®7pàÀ›o¾yýúõ©kÕªµbÅŠƒ:èÛo¿-**JÝÕ¿ÿüã»vŽUïᇾõÖ[×­[—º±oß¾Ï=÷\uM 8®ä# O>ùdaaaéc.»ì²ŒŒŒÊœeéҥÇ/eÀyçרQ£òvÅŠwÝu×ìÙ³{ôèqùå—§¥¥UbŽ»o¾ùfíÚµ3fÌèׯߜ9sª{:1sæÌ±cÇ–>¦uëÖ'tR‰»î½÷Þ›o¾9Š¢k¯½¶ÿþ7n|ñÅï½÷Þ(ŠrssçÌ™³yóæÙ³g:ôŽ;î¨òÉW£k¯½öšk®™;wî°aÃ’Ÿå%ò†?ýéO‹/.e@“&M.¾øâJF¾E‹ÝrË-+W®,qo­ZµŽ=öØòF¾D"qúé§O˜0!Š¢‘#G®Y³æÆo¬Ì$w'µk×>üðÃëׯ_Ý© )S¦\{íµ›6mÚÞ€´´´þýû—ù¦OŸþÇ?þ1Š¢£Ž:ꡇJn<äCžþùeË–%W³³³Û·oßµk×0÷j–––Ö²eËîÝ»W÷DB•^Ý€2ùî»ïf̘qß}÷¥n<ýôÓGŒ1mÚ´5kÖ,]ºt‡Ïr›3gÎ÷ß_Ê€N:­X±bÕªUS§N}õÕWÏ?ÿüäöK/½tüøñ«W¯n×®]ygþÍ7ß$ _Ò /¼PÞ#Pc]pÁëÖ­›={ö›o¾Ù¯_¿Ô]?üð§Ÿ~ºzõêǼÄ×þ÷ÿwòVœ¿øÅ/âééé}ûöÝ™S`7áJ>––Ö¡C‡:üóŸÿœ={vrãÊ•+SIéŠŠŠŽ>úè#<òå—_.}dݺu;vìØ±cÇçŸ>Š¢ôôô»îº«iÓ¦›yÆ 333·lÙ’\ÝsÏ=+vj¦ŒŒŒV­ZµjÕê»ï¾K}¤\Ÿ>}Jy¸à²eËÞ~ûíärÛ¶mSw]yå• 4ØI³`·áJ>Ó§OŸxùÓO?]°`A_øÆo,^¼xÔ¨QË—//Ëø7¾õÖ[Q{ì±.|Q5hÐàoû[zzzEMš4¹ûî»+|(vùùùÛë¾-Z´øÃþP“ $"‰o¡EQ"‘:th_øä“OFQ´iÓ¦_|±,ãßyçµk×Fÿ7+VÌõ×_ÿÕW_½óÎ;³fÍêܹs)#ï¾ûî´´´?þx‡Ç,ûHj iÓ¦Å˹¹¹Õ8%ò˜ƒ:¨C‡ñj#ß’%KÞ|óÍäòàÁƒËò’áÇGQ”™™Ù»wïòO³¸Ö­[ŸrÊ)õë×/ĕ ~øá²­ì#ƒ“––VÝSؾýöÛx93Óm“(7‘ð¤^Ì7qâÄyóæíð%O?ýt|wÄI“&}ñť߲e˨Q£¢(:þøã7n\ñ¹–ÇO<±téÒªœŸHñZ½zuuO€°‰|„'5òEe»˜ïßÿþwêêÓO?]úø÷ßÅŠQUÜ«³Œ ï¿ÿþª¢ìììêžÂ®°~ýúêžB󹈠ªü$.ša7ÓºuëC=tÊ”)ÉÕ¡C‡þþ÷¿/eü‡~øõ×_§nyî¹çî¾ûŒí½$y¯Î¬¬¬³Ï>;Þ_ ËÈÈH-›6mzï½÷>ýôÓÎ;ŸsÎ9‰D¢¨¨¨ØKÒÓÓÓÓKˆëÏ=÷Üüùó“ËEEE©ç*v–²ŒŽ7nÊ”)K—.Ý´iS£FÚ´isüñÇ7mÚtÛÁEEE‰Db{osëÖ­S¦L7nÜ‚ 222Ú´isÆgì½÷ÞÛ§b’¨[²dÉØ±c¿øâ‹+Vdgg7iÒ¤cÇŽÇsLNNζ/)ñsŽ¥¥¥¥~ÑÛ\lØN•H$6oÞ¯û£J_ÎX®¯»ØÄ&Nœøé§Ÿ~÷ÝwëׯÏÍÍmÒ¤ÉÏ~ö³8 ]»veyvàúõë?úè£/¾øbÙ²ekÖ¬Ùc=êÖ­[¿~ý-ZpÀûï¿)rê»ÞºuëäɓǿpáÂD"ѲeË=z´hѢ̟ÀO@tß}÷¥þŒgÏž]Êà~ýúmûËã7¶7¾¨¨h¯½öŠ¢¨GñÆ5kÖl{Aƒ%÷.^¼øúë¯oРArû 7ÜH$ž}öÙm_Ò·oßÔs-Y²dРA'tR)]gôèÑå™jýúõwÝuW½zõ¶œ––vÞyçmûÑm›‚~øáD"1mÚ´ßýîwÛÞ¼´V­Zÿïÿý¿~e¥8ôÐC“‡ÊÊÊš5kÖ9çœSb ÊÍͽá†~üñÇb/ôÑG·÷DQt衇¦~üñÇË2¬þõ¯¥pñâÅÅÌ™3硇:ûì³wxØÂÂÂÔ&ï›Ô¿ÿRæP¯;6räÈ8`{SÊÈÈxõÕWK9uAAAŸ>}J¿3;;;???õUùùùñÞ«®º*‘HLœ8ñÊ+¯lذᶸñÆ“€D"áJ>‚Ô§OŸßÿþ÷‰ÿ½àlèС·ÜrK‰#W®\ùÊ+¯DQtúé§3&¾‚êé§ŸîÑ£G‰/7nÜ’%K¢(ú¯ÿú¯xcíÚµ¿øâ‹I“&½ñÆñ B—-[¶~ýú;î¸ãÑGݰaC±ãœwÞyxàÔ©SGýòË/—x®Ç{ì(¶1777õj¿dÕ+ûÈØ’%KN=õÔéÓ§GQ”““sÁ{ì±999S§N}üñÇ—-[öòË/3fÔ¨QGqDüªñãÇòÉ'£Fz饗’[Þÿýüüü×^{­Ä·°iÓ¦?þñµk×¾úê«KPvEEE‡rÈÆ£(J^À·qãÆåË—'¿è 6<ðÀÆ {ûí·Û¶m¿êâ‹/nÕªÕ[o½•ZûŽ>úèž={rÈ!:uJ=Åo~ó›nݺ͜9óóÏ?OÞõ´W¯^^xáá‡^ÉÉïÐàÁƒão0###¾ 0//¯Øõ—»qežî¤ûî»/y9lzzú/ùË£>zï½÷^½zõôéÓ‡ 2þü¢¢¢m᱇z覛nJ¾£½öÚë—¿üe§N6l¸zõêY³f½ÿþûüq"‘ؼysòË-Ñ‚ N8á„Ôì—ª¨¨èþûïÏÎÎþë_ÿZ`7T½*ìÈ#ŒÆ;vÜÞ°Aƒ%ÇäççŸsÎ9ñKjÕª•¬GÛºöÚk£(ÊÎÎ^¹rå¶{S#ĉ'žØ¦M›är£F:è :uêDÿ{%_‰/)v%_,õácÇŽ-å—qä† ÚµkÏmÚ´i©{çÏŸ¿Ï>û$÷6mÚtÙ²e¥¼Í† öîÝûÎ;ï|å•W>ú裙3gNž<ù¡‡jÒ¤I<¦~ýúëÖ­+eÚ¥ˆ¯ä‹¢èæ›o;vlêåz?üðÃc=–zõ[Ó¦M—.]ºíq9äx̯~õ«ÒOúÖ[oEQ”––6wîÜŠM»˜^É—êÄOŒG”~ä²\ÉW™¯{üøñɬ˜––¶í®6l8î¸ã¢(zñÅK<õ­·ÞOï¿þë¿V­Zµí˜‚‚‚¼¼¼(ŠÞzë­ÔíÛþÌî¸ãŽaÆ}øá‡3fÌøøã ”z3ج¬¬%K–”þqüD”ðl0ÂùçŸ/O›6mÖ¬Y%{â‰'¢(jݺõ±Ç{ÑEÅÛ7mÚ4dÈ_2bĈ(ŠN;í´o{˜jâĉÇsÌðáÿÿþûeË–}þùçùË_ÊûFv’Ûn»­   ¹ü¯ý+5€EQÔ¼yóøª²ï¿ÿþÎ;ï,åP§Ÿ~ú°aÃþô§?sÎ9G}tûöí=ôÐk¯½öÃ?ÌÊÊJŽY¹råèÑ£+?ík¯½ö¨£ŽJ½[cãÆ¯¼òÊÏ>ûìg?ûY<álûÚ+®¸"^>|øŠ+J9ÑÓO?EÑÉ'Ÿ¼{<é­2_÷ý÷ߟH$¢(êٳ綗·æää”ræ»ï¾_ZwÌ1Ç<ÿüóuëÖÝvXÛ¶mS«|‰’?³Ûn»­wïÞÇsL‡Ž<òÈ«®ºêóÏ?sraa᫯¾Zúq~"D>BuÞyç¥>¹-¾…fª©S§þç?ÿ‰¢èâ‹/NKK;í´Ó’ÛKJfžb¦L™òí·ßFÿ÷^Ûsæ™g>ñÄgŸ}öž{î™ÜrÅWÄ-ª­ZµjàÀÉåöíÛŸ}öÙÛŽéÝ»wíÚµ“ËÏ<óL)÷QÜžvíÚýú׿ŽW§M›V¡É–IóæÍ“½6iذaß|óM±1ýúõ‹ßÑÆ_xá…ímÕªUÉ»^vÙe;a²»Z%¿î>ø ¹Ð¹sçß«W¯–-[nû¼½D"qõÕW'aZZÚ#û,^Þÿý·7¬iÓ¦ñòâÅ‹+p¢´´´ ¼ªÂRï'™úc:u:ì°ÃâÕ/æ›5kÖøñã£(ºôÒKw«A%¿îø~Ë—/?öØcË~Mç'Ÿ|/wìØ±ôÁ'tR£FÊxpJ'ò° œrÊ)ñj±Çò%OÓ¦M{ö왺ý7¿ùM¼¼hÑ¢wß}7^>|xEyyyÅ^–D"‘ú¼ºøIlÛÊÍÍ—“A´†kݺu¼¼råÊuëÖm;æŠ+®ˆ—ŸþùmŸ5˜¼|ó˜cŽ9ðÀwÊ,w­ÊÝ©|Ö¬Yݺu;餓^zé¥õë×—rÞ¯¾ú*^MýjØD>–zÇ΂‚‚3f$—çÌ™óá‡FQtÁdff¦¾äW¿úU­ZµâÕÔ;v&o?سgÏø†!Z³fÍÖ­[ãÕ®]»ÖÞŽÛo¿=¶m «ŠÝCuÕªUÛŽéÓ§Oƒ ’Ë+W®L†ÛØÖ­[Ÿ{î¹h7ºŒ¯ò_÷Å_\¬j3æüóÏoÚ´éo~ó›±cÇ–xÞ+V$‰xµ~ýúUô†(‘°uÖY©×'Åwì|òÉ'“"õ*¥¤ œyæ™ñêk¯½–¼ªiîܹS§N¿Wçš5kRWs¶¯N:þW…ŸA¸+åä䤮nذaÛ1¹¹¹^xa¼ZìŽcÆŒY°`AýúõÏ=÷Ü4É]¬ò_wZZÚðáà ‘‘‘z¨µk×<ø˜cŽ9ì°Ã¶½‡g±K?ƒîâ!ù[:uzôè¯&ïØYTT4xðà(ŠŽ:ê¨oÉxÑEÅË›6m2dHô¿÷ê¬]»vêCTìÊÅ3f,+ƒG}´º&\vŪÞöÂdê;óóóSïf™üaôë×/µ ï »ìi…Uòugee 8°  àšk®ÙsÏ=‹bâĉGyäk¯½VÊy «ôm°"ÁK½cç¬Y³¦Núæ›o.Z´(*é2¾¤SN9eï½÷ŽW“wìLF¾3ς׳gÏÔÎ1tèÐ'žx"Š¢:uêœwÞy%¾$##£_¿~ñê„ òóóÇEQŸ>}vò|wº¼¼¼¬¬¬xuùòåÕ8™ª•™7nœúlÅbR/æ{úé§“O­:tèúõë»uëÖ±cÇ:ϼ¼¼¼¼¼zŠÔsUíב‘q ' 8pÁ‚7ÝtS¼}íÚµ<òH¼Z¯^½Ô‹ù’Y€]Fä#x999©ÏØù$^>üðÃK™••uñÅÇ«O>ùäœ9s>þøãÚµk§þZv’ÔŸÖ.Pɯ{ݺu¥ì½á†öÚk¯äòâÅ‹Sw¥¾ÍÔþÀ. ò±;8õÔS4hºå ƒÚahùÍo~SlËnp¯Î¤N8!^~ùå— «q2U¥¨¨èÝwßM.§¥¥¥ÞpµD—_~yzúÿÿOÜÈ‘#ï»ï¾(ŠúôéSɧåÕ®];5ÆR†wúé§WæåUɯ»^½z¥$ºÌÌÌ8"æää¤î:÷Üsãå×_}éÒ¥å:/•!ò±;ÈÊÊ:çœsR·”~_Òù矟-4hpòÉ'WýäÊ&###^^±bE%Gž{î¹¹¹¹Éåo¾ùæÑG­Š9V³#F|÷ÝwÉå“O>¹uëÖ¥oÑ¢E|óÕÂÂÂþóŸQUÜ«sݺucÇŽÝv{üPºÚµkŸqÆ•øà¾ûîûãÿX¥ïûÿ7bĈÔÕW^yegœ FIK$Õ=¨¿ýío EÑÛo¿ß§±t[·nÝo¿ý.\ظqãÅ‹gff–2¸  `âĉ¯¿þú°aÃ’[ZµjÕ·oßvíÚµmÛ¶mÛ¶ÅžX6oÞ¼/¿ü²  à£>zõÕWKÉÚµkÛ´i³dÉ’øåéééqFZ³fMíÚµË;rÙ²egžyæøñ㋽‘´´´ôôô¢¢¢xKŸ>}† ’\ž;wî¸qãFŽùòË/'·´nÝúÒK/=ôÐC»víZ¿~ý(жlÙòùçŸOžï¼óÊ~ð¿üå/·Ýv[E999‹-*öìÆ ˆ/\Ûÿý=öغuëN›6íÃ?Œ¢¨{÷îo¿ýv)§HþÆŽ;räÈ5kÖ$7víÚµS§NíÛ·oß¾}‡öÝwßäö¹sç|ùå—cÆŒyóÍ7“Û¶m{þùçÇ¿Ÿìììøàûº£(ÊÌÌLîÍÈÈ8å”SŽ8∦M›~õÕW¯¼òJò©7~÷Ýw;wî\âûúÇ?þqíµ×n{ _zzz"‘Hý¿Ìi§öÖ[oE%ý5mû3ÛºuëÌ™3§L™2zôèøÚÄýöÛoÀ€?ÿùÏ»uëV«V­ø°ï¼óN|–ž={Æ?K€ÝVvÉ'¥5oÞ¼¨¨¨ì¯ºå–[¢(ºüòËK'™íyüñÇ‹½d‡}Å^2~üøfÍšÓªU«{î¹§Ø;*ûÈ-[¶ <¸cÇŽqšJ•——wî¹çŽ92õ%ñ‘Ûºä’KR?êí=ztÙ?ÿD"±yóæ7Þx㪫®êرczzÉ—7iÒdÀ€K–,)ב‰Ä¢E‹’í¶oß¾å}m‰öÜsÏm§W§N›o¾yíÚµ¥¿6õyŠ%jÚ´iräoQ=ûì³ÅŽ_¯;‘HÜzë­]ºtÙ^á®_¿þ€–.]Zú[[¸páï~÷»½öګădffžtÒIO=õÔ–-[vøîâŸÙ×_]Æ·ÿÞ{ïÅŸmFFÆ|°£¯ x®äc÷‘H$úôésâ‰'öï߿쯚={öoûÛÛo¿ýðÃßys+£õë׿÷Þ{sæÌÉÌÌÜgŸ}:uêÔ²eËJŽLúá‡&Nœ¸téÒ+VÔªU«aÆÉëÆJ¿xq×[¿~ýìÙ³çÌ™óÃ?¬]»6;;»I“&­[·îÒ¥K‰áj‡‰Ä¾ûî»hÑ¢>øàØc­ü ·nÝZPPPPP°dÉ’ 6äääpÀG}t^^^å^U*ðuoܸ±  `îܹßÿýºuë²³³4hо}ûƒ>8õzÁJ~8?þøãªU«òòò4hpÀ´oß>77·*ÞÙvM˜0á™gžIKK»ð »uë¶SÏPˆ|Àî,??ÿ„N8à€¾úê«êž T™’{øŸÿùŸ(ŠÊuq'Ô|®äv[‹/nÑ¢EVVÖ‚ 4hPÝÓ€*ãJ>`·uÿý÷oÞ¼ù¢‹.RøØÍˆ|@ðºwïþÑGÛ8uêÔAƒÕªUëæ›o®–YÀÎ#òÁûâ‹/ž}öÙÔ- ,8ï¼ó6mÚtýõ×ï»ï¾Õ51ØI<“^íÚµ³²²ž~úé#Ž8bãÆo½õÖí·ß¾xñâÃ;ìÃ?¬U«VuOª˜È¯víÚëÖ­+¶±}ûö£GÞ{ォeJ°S¹]'¼¬¬¬ÔÕœœœË/¿|üøñ »+WòÁÛ¼yóW_}µhÑ¢µk×6mÚ´C‡ 4¨îIÀN$ò@`Ü®#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘€ÿ=; ôÿu;½!3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$@ìÙ € ÿ¯Ûè `FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒäjÏHýÝŽ@oÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€™Ñi³ßÔà÷IEND®B`‚paperwork-2.2.2/openpaperwork-core/tests/pillow/tests_img.py000066400000000000000000000023411456262201400243730ustar00rootroot00000000000000import os import unittest import openpaperwork_core class TestPillowImg(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.python") self.core.load("openpaperwork_core.fs.memory") self.core.load("openpaperwork_core.pillow.img") self.core.init() self.img_path = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_doc.png" ) ) def test_img_url_to_pillow(self): img = self.core.call_success("url_to_pillow", self.img_path) self.assertIsNotNone(img) self.assertEqual(img.size, (2380, 3364)) def test_pillow_to_url(self): img = self.core.call_success("url_to_pillow", self.img_path) (img_url, fd) = self.core.call_success( "fs_mktemp", prefix="paperwork-test", suffix=".png" ) fd.close() self.core.call_success("pillow_to_url", img, img_url, format="PNG") # no real way to make sure the image was correctly written I guess self.core.call_success("fs_unlink", img_url, trash=False) paperwork-2.2.2/openpaperwork-core/tests/spatial/000077500000000000000000000000001456262201400221525ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/spatial/__init__.py000066400000000000000000000000001456262201400242510ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/spatial/tests_rtree.py000066400000000000000000000002751456262201400250730ustar00rootroot00000000000000import openpaperwork_core.spatial.tests class TestSpatial(openpaperwork_core.spatial.tests.AbstractTest): def get_plugin_name(self): return "openpaperwork_core.spatial.rtree" paperwork-2.2.2/openpaperwork-core/tests/spatial/tests_simple.py000066400000000000000000000002751456262201400252430ustar00rootroot00000000000000import openpaperwork_core.spatial.tests class TestSimple(openpaperwork_core.spatial.tests.AbstractTest): def get_plugin_name(self): return "openpaperwork_core.spatial.simple" paperwork-2.2.2/openpaperwork-core/tests/tests_core.py000066400000000000000000000310531456262201400232430ustar00rootroot00000000000000import unittest import unittest.mock import openpaperwork_core class TestLoading(unittest.TestCase): @unittest.mock.patch("importlib.import_module") def test_simple_loading(self, import_module): class TestModule(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called = False self.test_method_called = False def init(self, core): self.init_called = True def test_method(self): self.test_method_called = True core = openpaperwork_core.Core(auto_load_dependencies=True) import_module.return_value = TestModule() core.load('whatever_module') import_module.assert_called_once_with('whatever_module') core.init() self.assertTrue(core.get_by_name('whatever_module').init_called) core.call_all('test_method') self.assertTrue(core.get_by_name('whatever_module').test_method_called) class TestInit(unittest.TestCase): @unittest.mock.patch("importlib.import_module") def test_init_order(self, import_module): global g_idx g_idx = 0 class TestModuleA(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called_a = -1 def get_interfaces(self): return ['module_a'] def init(self, core): global g_idx self.init_called_a = g_idx g_idx += 1 class TestModuleB(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called_b = -1 def get_interfaces(self): return ['module_b'] def get_deps(self): return [ { 'interface': 'module_a', 'defaults': ['module_a'], } ] def init(self, core): global g_idx self.init_called_b = g_idx g_idx += 1 class TestModuleC(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called_c = -1 def get_deps(self): return [ { 'interface': 'module_b', 'defaults': ['module_b'], 'expected_already_satisfied': False, } ] def init(self, core): global g_idx self.init_called_c = g_idx g_idx += 1 core = openpaperwork_core.Core() import_module.return_value = TestModuleA() core.load('module_a') import_module.assert_called_once_with('module_a') import_module.reset_mock() import_module.return_value = TestModuleC() core.load('module_c') import_module.assert_called_once_with('module_c') import_module.reset_mock() import_module.return_value = TestModuleB() core.init() # will load 'module_b' because of dependencies import_module.assert_called_once_with('module_b') self.assertEqual(core.get_by_name('module_a').init_called_a, 0) self.assertEqual(core.get_by_name('module_b').init_called_b, 1) self.assertEqual(core.get_by_name('module_c').init_called_c, 2) class TestCall(unittest.TestCase): @unittest.mock.patch("importlib.import_module") def test_default_interface(self, import_module): class TestModuleB(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called_b = False self.test_method_called_b = False def get_interfaces(self): return ["test_interface"] def init(self, core): self.init_called_b = True def test_method(self): self.test_method_called_b = True class TestModuleC(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called_c = False self.test_method_called_c = False def get_deps(self): return [ { 'interface': 'test_interface', 'defaults': ['module_a', 'module_b'] }, ] def init(self, core): self.init_called_c = True def test_method(self): self.test_method_called_c = True core = openpaperwork_core.Core(auto_load_dependencies=True) import_module.return_value = TestModuleC() core.load('module_c') import_module.assert_called_once_with('module_c') import_module.reset_mock() import_module.return_value = TestModuleB() core.load('module_b') import_module.assert_called_once_with('module_b') import_module.reset_mock() # interface already satisfied --> won't load 'module_a' core.init() self.assertTrue(core.get_by_name('module_b').init_called_b) self.assertTrue(core.get_by_name('module_c').init_called_c) core.call_all('test_method') self.assertTrue(core.get_by_name('module_b').test_method_called_b) self.assertTrue(core.get_by_name('module_c').test_method_called_c) @unittest.mock.patch("importlib.import_module") def test_call_success_priority(self, import_module): class TestModuleB(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 33 def __init__(self): self.test_method_called_b = False def test_method(self): self.test_method_called_b = True return None class TestModuleC(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 22 def __init__(self): self.test_method_called_c = False def test_method(self): self.test_method_called_c = True return "value" class TestModuleD(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 11 def __init__(self): self.test_method_called_d = False def test_method(self): self.test_method_called_d = True return None core = openpaperwork_core.Core(auto_load_dependencies=True) import_module.return_value = TestModuleB() core.load('module_b') import_module.assert_called_once_with('module_b') import_module.reset_mock() import_module.return_value = TestModuleC() core.load('module_c') import_module.assert_called_once_with('module_c') import_module.reset_mock() import_module.return_value = TestModuleD() core.load('module_d') import_module.assert_called_once_with('module_d') import_module.reset_mock() # interface already satisfied --> won't load 'module_a' core.init() r = core.call_success('test_method') self.assertEqual(r, "value") self.assertTrue(core.get_by_name('module_b').test_method_called_b) self.assertTrue(core.get_by_name('module_c').test_method_called_c) self.assertFalse(core.get_by_name('module_d').test_method_called_d) @unittest.mock.patch("importlib.import_module") def test_priority(self, import_module): class TestModuleA(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 22 def test_method(self): return "A" class TestModuleB(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 33 def test_method(self): return "B" core = openpaperwork_core.Core(auto_load_dependencies=True) import_module.return_value = TestModuleA() core.load('module_a') import_module.assert_called_once_with('module_a') import_module.reset_mock() import_module.return_value = TestModuleB() core.load('module_b') import_module.assert_called_once_with('module_b') import_module.reset_mock() core.init() r = core.call_success('test_method') self.assertEqual(r, "B") class TestDependencies(unittest.TestCase): @unittest.mock.patch("importlib.import_module") def test_default_interface(self, import_module): class TestModuleA(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called = False self.test_method_called = False def get_interfaces(self): return [ "test_interface", "some_interface", ] def init(self, core): self.init_called = True def test_method(self): self.test_method_called = True class TestModuleB(object): class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.init_called = False def get_interfaces(self): return ['some_interface'] def get_deps(self): return [ { 'interface': 'test_interface', 'defaults': ['module_a'], } ] def init(self, core): self.init_called = True core = openpaperwork_core.Core(auto_load_dependencies=True) import_module.return_value = TestModuleB() core.load('module_b') import_module.assert_called_once_with('module_b') import_module.reset_mock() import_module.return_value = TestModuleA() core.init() # will load 'module_a' because of dependencies import_module.assert_called_once_with('module_a') self.assertTrue(core.get_by_name('module_a').init_called) self.assertTrue(core.get_by_name('module_b').init_called) core.call_all('test_method') self.assertTrue(core.get_by_name('module_a').test_method_called) self.assertEqual( core.get_by_interface('some_interface'), [ core.get_by_name('module_b'), core.get_by_name('module_a'), ] ) self.assertEqual(core.get_by_interface('unknown_interface'), []) @unittest.mock.patch("importlib.import_module") def test_no_init_if_dropped(self, import_module): self.init_called = False class TestModuleA(object): class Plugin(openpaperwork_core.PluginBase): def get_interfaces(s): return [ "test_interface", "some_interface", ] def init(s, core): self.init_called = True class TestModuleB(object): class Plugin(openpaperwork_core.PluginBase): def __init__(s): s.init_called = False def get_interfaces(s): return ['some_interface'] def get_deps(s): return [ { 'interface': 'test_interface', 'defaults': ['module_a'], } ] def init(s, core): self.init_called = True core = openpaperwork_core.Core(auto_load_dependencies=False) import_module.return_value = TestModuleB() core.load('module_b') import_module.assert_called_once_with('module_b') import_module.reset_mock() import_module.return_value = TestModuleA() core.init() # will NOT load 'module_a' and will drop 'module_b' self.assertFalse(self.init_called) self.assertRaises(KeyError, core.get_by_name, 'module_a') self.assertRaises(KeyError, core.get_by_name, 'module_b') paperwork-2.2.2/openpaperwork-core/tests/tests_url.py000066400000000000000000000027551456262201400231240ustar00rootroot00000000000000import unittest import openpaperwork_core class TestUrl(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.urls") self.core.init() def test_url_join(self): self.assertEqual( self.core.call_success("url_args_join", "file://something.txt"), "file://something.txt" ) self.assertEqual( self.core.call_success( "url_args_join", "file://something.txt", page=1 ), "file://something.txt#page=1" ) self.assertEqual( self.core.call_success( "url_args_join", "file://something.txt", page=1, password="test1234" ), "file://something.txt#page=1&password=test1234" ) def test_url_split(self): self.assertEqual( self.core.call_success("url_args_split", "file://something.txt"), ("file://something.txt", {}) ) self.assertEqual( self.core.call_success( "url_args_split", "file://something.txt#page=1" ), ("file://something.txt", {"page": "1"}) ) self.assertEqual( self.core.call_success( "url_args_split", "file://something.txt#page=1&password=test1234" ), ("file://something.txt", {"page": "1", "password": "test1234"}) ) paperwork-2.2.2/openpaperwork-core/tests/thread/000077500000000000000000000000001456262201400217645ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/thread/__init__.py000066400000000000000000000000001456262201400240630ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/thread/tests_pool.py000066400000000000000000000002761456262201400245360ustar00rootroot00000000000000import openpaperwork_core.thread.tests class TestThread(openpaperwork_core.thread.tests.AbstractTestThread): def get_plugin_name(self): return "openpaperwork_core.thread.pool" paperwork-2.2.2/openpaperwork-core/tests/thread/tests_simple.py000066400000000000000000000003001456262201400250420ustar00rootroot00000000000000import openpaperwork_core.thread.tests class TestThread(openpaperwork_core.thread.tests.AbstractTestThread): def get_plugin_name(self): return "openpaperwork_core.thread.simple" paperwork-2.2.2/openpaperwork-core/tests/work_queue/000077500000000000000000000000001456262201400227035ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/work_queue/__init__.py000066400000000000000000000000001456262201400250020ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-core/tests/work_queue/tests_default.py000066400000000000000000000140761456262201400261330ustar00rootroot00000000000000import unittest import openpaperwork_core class TestQueue(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.work_queue.default") self.core.init() def test_single_task(self): self.task_done = False def do_task(): self.task_done = True self.core.call_all("work_queue_create", "some_work_queue") self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task) ) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(self.task_done) def test_many_tasks(self): self.task_a_done = False self.task_b_done = False def do_task_a(): self.assertFalse(self.task_a_done) self.assertFalse(self.task_b_done) self.task_a_done = True def do_task_b(): self.assertTrue(self.task_a_done) self.assertFalse(self.task_b_done) self.task_b_done = True self.core.call_all("work_queue_create", "some_work_queue") self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_a) ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_b) ) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(self.task_a_done) self.assertTrue(self.task_b_done) def test_uncaught(self): # make sure the work queue doesn't stop if an exception is raised # by one of the task/promise. self.task_a_done = False self.task_b_done = False def do_task_a(): self.assertFalse(self.task_a_done) self.assertFalse(self.task_b_done) self.task_a_done = True raise Exception("Test exception. May be normal. Do not panic :-)") def do_task_b(): self.assertTrue(self.task_a_done) self.assertFalse(self.task_b_done) self.task_b_done = True self.core.call_all( "work_queue_create", "some_work_queue", hide_uncatched=True ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise( self.core, do_task_a, hide_caught_exceptions=True ) ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_b) ) self.core.call_all("mainloop_quit_graceful") self.core.call_one( "mainloop", halt_on_uncaught_exception=False, log_uncaught=False ) self.assertTrue(self.task_a_done) self.assertTrue(self.task_b_done) def test_cancel_all(self): self.task_a_done = False self.task_b_done = False def do_task_a(): self.assertFalse(self.task_a_done) self.assertFalse(self.task_b_done) self.task_a_done = True return "some_crap" def do_task_b(): self.assertTrue(self.task_a_done) self.assertFalse(self.task_b_done) self.task_b_done = True self.core.call_all("work_queue_cancel_all", "some_work_queue") def do_task_c(): self.assertTrue(False) self.core.call_all("work_queue_create", "some_work_queue") self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_a) ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_b) ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_c) ) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(self.task_a_done) self.assertTrue(self.task_b_done) def test_cancel(self): self.task_a_done = False self.task_b_done = False self.task_d_done = False def do_task_a(): self.assertFalse(self.task_a_done) self.assertFalse(self.task_b_done) self.task_a_done = True return "some_crap" def do_task_b(): self.assertTrue(self.task_a_done) self.assertFalse(self.task_b_done) self.task_b_done = True self.core.call_all( "work_queue_cancel", "some_work_queue", task_c ) def do_task_c(): self.assertTrue(False) def do_task_d(): self.assertTrue(self.task_a_done) self.assertTrue(self.task_b_done) self.task_d_done = True return "some_crap" task_c = openpaperwork_core.promise.Promise(self.core, do_task_c) self.core.call_all("work_queue_create", "some_work_queue") self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_a) ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_b) ) self.core.call_one( "work_queue_add_promise", "some_work_queue", task_c ) self.core.call_one( "work_queue_add_promise", "some_work_queue", openpaperwork_core.promise.Promise(self.core, do_task_d) ) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(self.task_a_done) self.assertTrue(self.task_b_done) self.assertTrue(self.task_d_done) paperwork-2.2.2/openpaperwork-core/tox.ini000066400000000000000000000002641456262201400206700ustar00rootroot00000000000000[tox] envlist=py3 [testenv] deps= pytest setuptools >= 9.0.1 commands=pytest {posargs} [flake8] exclude = .tox, build, dist, venv*, *.egg*, .git, paperwork-2.2.2/openpaperwork-gtk/000077500000000000000000000000001456262201400172105ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/.flake8000066400000000000000000000001131456262201400203560ustar00rootroot00000000000000[flake8] exclude = src/openpaperwork_gtk/_version.py max-line-length = 100 paperwork-2.2.2/openpaperwork-gtk/ChangeLog000066400000000000000000000022201456262201400207560ustar00rootroot000000000000002024/02/13 - 2.2.2: - dependencies: Make really sure python3-gi-cairo is installed 2023/09/17 - 2.2.1: - Add build-system.build-backend to pyproject.toml 2023/09/16 - 2.2.0: - setup.py has been replaced by pyproject.toml - fs.gio.fs_get_mtime(): do not trust Gio.File.query_info(TIME_CHANGED) on Windows. Prefer os.stat() 2023/01/08 - 2.1.2: - dependencies: fix: depends on openpaperwork-core - autoscrolling: take into account that Gdk.Cursor.new_for_display() may fail on some systems (wayland-only systems) - Core-GTK: Add a plugin showing a dialog when the app is closed and any running background task is still running. Hopefully, it will help for issue #1034 ("sqlite: database is locked") 2022/01/31 - 2.1.1: - Fix: take into account that Cursor.new_for_display() may fail with Wayland 2021/12/05 - 2.1.0: - Bug report: Clarify the use of the author field 2021/05/24 - 2.0.3: - Swedish translations added - Add LICENSE file in pypi package 2021/01/01 - 2.0.2: - No changes 2020/11/15 - 2.0.1: - fs.gio: Text files must be encoded in UTF-8 - Include tests in Pypi package (thanks to Elliott Sales de Andrade) 2020/10/17 - 2.0: - Initial release paperwork-2.2.2/openpaperwork-gtk/LICENSE000066400000000000000000001045051456262201400202220ustar00rootroot00000000000000 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. {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year} {name of author} 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: {project} Copyright (C) {year} {fullname} 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 . paperwork-2.2.2/openpaperwork-gtk/MANIFEST.in000066400000000000000000000001671456262201400207520ustar00rootroot00000000000000recursive-include src *.py *.glade *.xml *.css *.svg *.png *.mo recursive-include tests * include *.md include LICENSE paperwork-2.2.2/openpaperwork-gtk/Makefile000066400000000000000000000050031456262201400206460ustar00rootroot00000000000000PYTHON ?= python3 build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: l10n_compile ${PYTHON} ./setup.py build build_c: version: doc: install_py $(MAKE) -C doc html doc/_build/html/index.html: doc data: upload_doc: doc/_build/html/index.html cd .. && ./ci/deliver_doc.sh ${CURDIR}/doc/_build/html openpaperwork_gtk check: if ! hash flake8 ; then PIP_DEPS=[lint] $(MAKE) install_py ; fi flake8 --append-config $(CURDIR)/.flake8 $(CURDIR)/src/openpaperwork_gtk test: if ! hash pytest ; then PIP_DEPS=[dev] $(MAKE) install_py ; fi python3 -m pytest -xv tests/ linux_exe: windows_exe: install # ugly, but "import pkg_resources" doesn't work in frozen environments # and I don't want to have to patch the build machine to fix it every # time. mkdir -p $(CURDIR)/../build/exe/data (cd $(CURDIR)/src && find . -name '*.css' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.glade' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.mo' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) release: ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" exit 1 else @echo "Will release: ${RELEASE}" @echo "Checking release is in ChangeLog ..." grep ${RELEASE} ChangeLog | grep -v "/xx" endif release_pypi: @echo "Releasing openpaperwork-gtk ..." rm -rf /tmp/venv virtualenv /tmp/venv . /tmp/venv/bin/activate && pip install build . /tmp/venv/bin/activate && ${PYTHON} -m build -s rm -rf /tmp/venv twine upload $(CURDIR)/dist/*.tar.gz @echo "All done" clean: rm -rf doc/_build rm -rf build dist *.egg-info rm -f src/openpaperwork_gtk/_version.py # PIP_ARGS is used by Flatpak build install_py: l10n_compile ${PYTHON} -m pip install ${PIP_ARGS} .${PIP_DEPS} install_c: uninstall_py: pip3 uninstall -y openpaperwork-gtk uninstall_c: l10n_extract: $(CURDIR)/../tools/l10n_extract.sh "$(CURDIR)/src" "$(CURDIR)/l10n" l10n_compile: $(CURDIR)/../tools/l10n_compile.sh \ "$(CURDIR)/l10n" \ "$(CURDIR)/src/openpaperwork_gtk/l10n" \ "openpaperwork_gtk" help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ l10n_compile \ l10n_extract \ release \ test \ uninstall \ uninstall_c paperwork-2.2.2/openpaperwork-gtk/README.md000066400000000000000000000001561456262201400204710ustar00rootroot00000000000000# OpenPaperwork GTK GLib/GTK plugins. [Documentation](https://doc.openpaper.work/openpaperwork_gtk/latest/) paperwork-2.2.2/openpaperwork-gtk/doc/000077500000000000000000000000001456262201400177555ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/doc/Makefile000066400000000000000000000011041456262201400214110ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)paperwork-2.2.2/openpaperwork-gtk/doc/conf.py000066400000000000000000000130271456262201400212570ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = 'OpenPaperwork-GTK' copyright = '2019, Jerome Flesch' author = 'Jerome Flesch' # The short X.Y version version = '' # The full version, including alpha/beta/rc tags release = '' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinxcontrib.plantuml', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = None # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'OpenPaperwork-GTKdoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'OpenPaperwork-GTK.tex', 'OpenPaperwork-GTK Documentation', 'Jerome Flesch', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'openpaperwork-gtk', 'OpenPaperwork-GTK Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'OpenPaperwork-GTK', 'OpenPaperwork-GTK Documentation', author, 'OpenPaperwork-GTK', 'One line description of project.', 'Miscellaneous'), ] # -- Options for Epub output ------------------------------------------------- # Bibliographic Dublin Core info. epub_title = project # The unique identifier of the text. This can be a ISBN number # or the project homepage. # # epub_identifier = '' # A unique identification for the text. # # epub_uid = '' # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True autodoc_inherit_docstrings = False paperwork-2.2.2/openpaperwork-gtk/doc/index.rst000066400000000000000000000007231456262201400216200ustar00rootroot00000000000000.. OpenPaperwork-GTK documentation master file, created by sphinx-quickstart on Sat Dec 14 13:12:28 2019. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to OpenPaperwork-GTK's documentation! ============================================= .. toctree:: :maxdepth: 2 :caption: Contents: Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` paperwork-2.2.2/openpaperwork-gtk/l10n/000077500000000000000000000000001456262201400177625ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/l10n/ca.po000066400000000000000000000141271456262201400207120ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-30 11:53+0100\n" "PO-Revision-Date: 2022-03-19 08:45+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "Fitxer ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the ticket." msgstr "" "Genera un fitxer ZIP amb tots els adjunts.\n" "Si voleu, podeu enviar l'informe d'errors manualment al " "Sistema de seguiment d'errors del Paperwork i adjuntar aquest ZIP a la " "vostra incidència." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "Creant l'informe d'errors..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "Enviant l'informe d'errors..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "Envia automàticament" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "Envia automàticament l'informe d'errors a OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "Èxit" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "Ha fallat la transferència:\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "HA FALLAT" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "Ara" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "Captura de pantalla" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "Selecciona per generar" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "Total: {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "Total" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "Error inesperat" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "Informa" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "Ha aparegut un error inesperat." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "Data" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "Fitxer" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "Mida" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "Obre el fitxer" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "" "Per respectar la vostra privacitat, els adjunts que seleccioneu poden " "censurar-se parcialment" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "Fitxer adjunts que s'ha d'incloure a l'informe d'errors" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Descripció de l'error" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "" "Necessari si accepteu ser contactats en relació a aquest informe d'errors" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "El teu correu electrònic" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" "L'enviament de l'informe d'errors ha estat un èxit.\n" "\n" "A sota, teniu l'enllaç privat al vostre informe.\n" "\n" "Aneu amb molt de compte al compartir-lo. Els adjunts de l'informe (" "registres, captures de pantalla... ) no haurien de tenir cap informació " "privada. Es recomana, i és molt important, revisar-ho tot abans d'enviar " "aquest enllaç.\n" "\n" "Podeu demanar eliminar el vostre informe d'errors enviant un correu " "electrònic a jflesch@openpaper." "work." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "Si us plau, selecciona on s'ha de desar el fitxer ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "Mostra les tasques en segon pla" paperwork-2.2.2/openpaperwork-gtk/l10n/de.po000066400000000000000000000153131456262201400207150ustar00rootroot00000000000000# German translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-04-02 15:24+0000\n" "Last-Translator: Matthias Preiss \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.16.4\n" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "Gesamt: {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "Gesamt" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "Bildschirmfotos" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "Wähle zum Erzeugen" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "Jetzt" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "Erstelle Fehlerbericht ..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "Sende Fehlerberichte als Anhänge ..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "Automatisch senden" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "Sende den Fehlerbericht automatisch an OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "Erfolg" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "Übertragung fehlgeschlagen:\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "FEHLGESCHLAGEN" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "ZIP Datei" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the " "ticket." msgstr "" "Erstelle eine ZIP Datei mit allen Anhängen.\n" "Die ZIP Datei kann als Anhang für einen Fehlerbericht im Bug " "Tracker von Paperwork verwendet werden." #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "Zeige Hintergrundaktivitäten" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "Unerwarteter Fehler" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "Bericht" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "Ein unerwarteter Fehler ist aufgetreten." #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:1 msgid "Background tasks" msgstr "Hintergrundaufgaben" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:2 msgid "Force quit now" msgstr "Beenden jetzt erzwingen" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:3 msgid "" "Some background tasks are still running.\n" "Please wait ..." msgstr "" "Hintergrundaufgaben werden ausgeführt.\n" "Bitte warten ..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Fehlerbeschreibung" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "" "Erforderlich, wenn Sie damit einverstanden sind, bezüglich dieses " "Fehlerberichts kontaktiert zu werden" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "Ihre Email Adresse" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" "Die Fehlerbeschreibung wurde erfolgreich übermittelt.\n" "\n" "Weiter unten erhältst einen geheimen Link zu deinem Fehlerbericht.\n" "\n" "Sei vorsichtig, mit wem du diesen Link teilst. Die Anhänge für den " "Fehlerbericht beinhalten keine privaten Informationen. Trotzdem solltest du " "sie prüfen, bevor du den Link weitergibst.\n" "\n" "Du kannst jederzeit eine Löschung deines Fehlerberichts verlangen. Schreibe " "dafür eine E-Mail an jflesch@openpaper.work." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "Bitte wähle einen Ablageort für die ZIP Datei aus" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "Datum" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "Datei" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "Dateigröße" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "Datei öffnen" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "Aus Datenschutzgründen könnten die Anhänge teilweise zensiert werden" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "Anhänge für den Fehlerbericht" #~ msgid "Anonymous" #~ msgstr "Anonym" #~ msgid "Bug Report Author" #~ msgstr "Fehlerbericht Author" paperwork-2.2.2/openpaperwork-gtk/l10n/es.po000066400000000000000000000137101456262201400207330ustar00rootroot00000000000000# Spanish translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-02-24 02:42+0000\n" "Last-Translator: andres felipe santamaria \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.2\n" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "Total: {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "Total" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "Captura de pantalla" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "Selecciona para generar" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "Ahora" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "Creando informe de bugs ..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "Enviando anexo de informede bug ..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "Enviar automaticamente" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "Enviar el informe de bug automaticamente a OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "Operación exitosa" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "Transferencia fallida:\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "HA FALLADO" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "archivo ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the " "ticket." msgstr "" "Construye un archivo ZIP con todos los anexos.\n" " Si quiere, puede remitir un informe de bugs manualmente en Seguidor de bugs de Paperwork y anexar este archivo ZIP al " "formulario." #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "Error inesperado" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "Informar" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "Apareció un error inesperado." #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:1 msgid "Background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:2 msgid "Force quit now" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:3 msgid "" "Some background tasks are still running.\n" "Please wait ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Descripción del bug" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "Requerido si acepta ser contactado sobre este informe de bug" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "Su dirección de correo electrónico" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "Fecha" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "Fichero" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "Tamaño" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "Abre el fichero" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "" "Para respetar tu privacidad, los archivos adjuntos que selecciones pueden " "ser censurados" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "Fichero a adjuntar en el informe" paperwork-2.2.2/openpaperwork-gtk/l10n/fr.po000066400000000000000000000156571456262201400207470ustar00rootroot00000000000000# French translations for PACKAGE package # Traductions françaises du paquet PACKAGE. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-05-07 17:12+0000\n" "Last-Translator: Frédéric S \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.17\n" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "Total : {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "Total" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "Captures d'écran de l'app." #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "Sélectionnez pour générer" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "Maintenant" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "Création d'un rapport de bogue…" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "Envoi de la pièce jointe du rapport de bogue…" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "Envoyer automatiquement" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "Envoyer le rapport de bug automatiquement à OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "Succès" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "Le transfert a échoué :\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "ÉCHEC" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "Fichier ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the " "ticket." msgstr "" "Crée un fichier ZIP qui contient tous les documents.\n" "Si vous le souhaitez, vous pouvez soumettre un rapport de bogue manuellement " "sur le suivi de bogue de paperwork et joignez ce fichier " "ZIP au ticket." #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "Afficher les tâches de fond" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "Erreur inattendue" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "Signaler" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "Une erreur inattendue s'est produite." #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:1 msgid "Background tasks" msgstr "Taches de fond" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:2 msgid "Force quit now" msgstr "Forcer à quitter" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:3 msgid "" "Some background tasks are still running.\n" "Please wait ..." msgstr "" "Des tâches de fond sont en cours.\n" "Merci de patienter..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Description du bogue" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "Requis si vous acceptez d'être contacté au sujet de ce rapport de bug" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "Votre adresse email" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" "Le rapport de bogue a été envoyé avec succès.\n" "\n" "Vous pouvez trouver le lien privé de votre rapport de bogue ci-dessous.\n" "\n" "Soyez prudent en partageant ce lien. Les fichiers joints au rapport " "de bogue (journaux, captures d'écran,…) ne contiennent pas d'informations " "privées. Mais il est vivement conseillé de les vérifier avant de partager ce " "lien.\n" "\n" "Vous pouvez demander la suppression de votre rapport de bogue en envoyant un " "courriel à cette adresse jflesch@openpaper.work." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "Veuillez sélectionner la destination où sauvegarder le fichier ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "Date" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "Fichier" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "Taille" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "Ouvrir un fichier" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "" "Pour protéger votre vie privée, les fichiers joints peuvent être " "partiellement censurés quand vous les sélectionnez" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "Fichiers à joindre à votre rapport de bogue" #~ msgid "Anonymous" #~ msgstr "Anonyme" #~ msgid "Bug Report Author" #~ msgstr "Auteur du rapport de bug" paperwork-2.2.2/openpaperwork-gtk/l10n/messages.pot000066400000000000000000000117401456262201400223200ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the " "ticket." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:1 msgid "Background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:2 msgid "Force quit now" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:3 msgid "" "Some background tasks are still running.\n" "Please wait ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "" paperwork-2.2.2/openpaperwork-gtk/l10n/oc.po000066400000000000000000000154771456262201400207410ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2022-01-05 18:30+0000\n" "Last-Translator: Quentin PAGÈS \n" "Language-Team: Occitan \n" "Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.9\n" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "Total : {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "Total" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "Captura d’ecran de l’aplicacion" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "Seleccionar per generar" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "Ara" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "Creacion d’un senhalament de bug…" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "Mandadís de la pèça-junta del senhalament de bug…" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "Enviar automaticament" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "Enviar lo senhalament de bug automaticament a OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "Succès" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "Lo transferiment a pas reüssit :\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "FRACÀS" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "Fichièr ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the " "ticket." msgstr "" "Crear un fichièr ZIP que conten totes los documents.\n" "Se volètz, podètz enviar un senhalament de bug manualament sul seguiment de bugs de paperwork e ajustar aqueste fichièr ZIP " "al ticket." #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "Afichar los prètzfaches de fons" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "Error inesperada" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "Senhalar" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "Una error inesperada s’es producha." #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:1 msgid "Background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:2 msgid "Force quit now" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:3 msgid "" "Some background tasks are still running.\n" "Please wait ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Descripcion del bug" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "" "Requerit s’acceptatz qu’òm vos contacte a prepaus d’aqueste senhalament " "d’anomalia" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "Vòstra adreça electronica" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" "Lo senhalament de bug es corrèctament estat enviat.\n" "\n" "Traparetz çai-jos lo ligam privat de vòstre senhalament de bug.\n" "\n" "Siatz prudents en partejant aqueste ligam. Las pèças juntas del " "senhalament de bug (jornals, capturas d’ecran, …) contenon pas cap " "d’informacions privadas mas seriatz ben avisats de las verificar abans de " "partejar aqueste ligam.\n" "\n" "Podètz demandar la supression de vòstre senhalament de bug en escrivent a " "l’adreça seguenta jflesch@openpaper.work." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "Mercés de seleccionar la destinacion de la salvagarda del fichièr ZIP" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "Data" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "Fichièr" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "Talha" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "Dobrís lo fichièr" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "" "Per protegir vòstra vida privada, los fichièrs junts pòdon èsser " "parcialament censurat quand los seleccionatz" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "Fichièrs de juntar al senhalament de bug" #~ msgid "Anonymous" #~ msgstr "Anonim" #~ msgid "Bug Report Author" #~ msgstr "Autor del senhalament del bug" paperwork-2.2.2/openpaperwork-gtk/l10n/sv.po000066400000000000000000000134231456262201400207550ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-01-04 15:31+0000\n" "Last-Translator: Ã…ke Engelbrektson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "ZIP-fil" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the ticket." msgstr "" "Skapa en ZIP-fil innehÃ¥llande alla bilagor.\n" "Om du vill kan du sedan manuellt skicka in en felrapport pÃ¥Paperwork's bug tracker och bifoga ZIP-filen i ärendet." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "Skapar felrapport..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "Skickar felrapportbilagor..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "Skicka automatiskt" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "Skicka felrapporten automatiskt till OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "Klart" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "Överföring misslyckades:\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "MISSLYCKADES" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "Nu" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "Totalt: {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "Totalt" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "App. skärmklipp" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "Välj för att generera" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "Välj var ZIP-filen skall sparas" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Felbeskrivning" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Anonymous" msgstr "Anonymt" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Bug Report Author" msgstr "Felrapportförfattare" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" "Felrapport skickad.\n" "\n" "Du hittar den privata länken till felrapporten nedan.\n" "\n" "Var försiktig med att dela den. Felrapportbilagor (loggar, skärmklipp " "m.m.) innehÃ¥ller ingen personlig information. ÄndÃ¥ rekommenderas du starkt " "att kontrollera dem alla innan du delar denna länk.\n" "\n" "Du kan begära radering av din felrapport genom att skicka ett e-" "postmeddelande till jflesch@openpaper.work." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "Datum" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "Fil" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "Storlek" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "Öppna fil" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "För din integritets skull, kan bilagor delvis censureras när de väljs" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "Bilagor att inkludera i felrapporten" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "Oväntat fel" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "Rapport" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "Ett oväntat fel inträffade." #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "Visa bakgrundsÃ¥tgärder" paperwork-2.2.2/openpaperwork-gtk/l10n/uk.po000066400000000000000000000121221456262201400207370ustar00rootroot00000000000000# Ukrainian translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2020-05-03 15:37+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the " "ticket." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:1 msgid "Background tasks" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:2 msgid "Force quit now" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/wait_for_background_tasks.glade.h:3 msgid "" "Some background tasks are still running.\n" "Please wait ..." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Required if you agree to be contacted regarding this bug report" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Your email address" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "" paperwork-2.2.2/openpaperwork-gtk/l10n/zh_Hans.po000066400000000000000000000132301456262201400217130ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-02-06 07:20+0000\n" "Last-Translator: 玉堂白鹤 \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.4\n" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:56 msgid "ZIP file" msgstr "ZIP 文件" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py:61 #, python-format msgid "" "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report manually on Paperwork's bug tracker and attach this ZIP file to the ticket." msgstr "" "æž„å»ºåŒ…å«æ‰€æœ‰é™„ä»¶çš„ZIP文件。\n" "如果需è¦ï¼Œæ‚¨å¯ä»¥åœ¨Paperwork 追踪系统上手动æäº¤ bug 报告,并将此 ZIP 文件附加到报告。" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:40 msgid "Creating bug report ..." msgstr "创建 bug 报告..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:42 msgid "Sending bug report attachment ..." msgstr "å‘é€é”™è¯¯æŠ¥å‘Šé™„ä»¶ ..." #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:161 msgid "Send automatically" msgstr "自动å‘é€" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:162 msgid "Send the bug report automatically to OpenPaper.work" msgstr "将错误报告自动å‘é€ OpenPaper.work" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:262 msgid "Success" msgstr "æˆåŠŸ" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:278 #, python-format msgid "" "Transfer failed:\n" "\n" "%s" msgstr "" "传输失败:\n" "\n" "%s" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py:284 msgid "FAILED" msgstr "失败" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py:77 msgid "Now" msgstr "现在" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:417 msgid "Total: {}" msgstr "总计: {}" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py:427 msgid "Total" msgstr "总计" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:258 #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:266 msgid "App. screenshots" msgstr "App. 截å±" #: openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py:267 msgid "Select to generate" msgstr "选择生æˆ" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade.h:1 msgid "Please select where to save the ZIP file" msgstr "请选择è¦ä¿å­˜ ZIP 文件的ä½ç½®" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:1 msgid "Bug description" msgstr "Bug 详情" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:2 msgid "Anonymous" msgstr "匿å" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:3 msgid "Bug Report Author" msgstr "Bug 报告者" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade.h:4 msgid "" "Bug report successfully submitted.\n" "\n" "You can find below the private link to your bug report.\n" "\n" "Be careful before sharing it. Bug report attachments (logs, " "screenshots, …) do not contain any private information. Still you're " "strongly advised to check them all before sharing this link.\n" "\n" "You can request deletion of your bug report by sending an email to jflesch@openpaper.work." msgstr "" "Bug 报告已æˆåŠŸæäº¤ã€‚\n" "\n" "您å¯ä»¥åœ¨ä¸‹é¢æ‰¾åˆ°æ‚¨çš„ bug 报告的ç§äººé“¾æŽ¥ã€‚\n" "\n" "分享å‰è¯·å°å¿ƒã€‚Bug 报告附件(日志ã€å±å¹•截图等…)ä¸è¦åŒ…å«ä»»ä½•ç§äººä¿¡æ¯ã€‚å¼ºçƒˆå»ºè®®æ‚¨åœ¨å…±äº«æ­¤é“¾æŽ¥ä¹‹å‰æ£€æŸ¥æ‰€æœ‰é“¾æŽ¥ã€‚\n" "\n" "您å¯ä»¥é€šè¿‡å‘jflesch@openpaper.workå‘é€ç”µå­é‚®ä»¶è¯·æ±‚删除此 bug 报告。" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:3 msgid "Date" msgstr "日期" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:5 msgid "File" msgstr "文件" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:6 msgid "Size" msgstr "大å°" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:7 msgid "Open file" msgstr "打开文件" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:8 msgid "For your privacy, attachments may be partially censored when selected" msgstr "ä¸ºä¿æŠ¤æ‚¨çš„éšç§ï¼Œé€‰æ‹©é™„ä»¶æ—¶å¯èƒ½ä¼šå¯¹å…¶è¿›è¡Œéƒ¨åˆ†å®¡æŸ¥" #: openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade.h:9 msgid "Attachments to include in the bug report" msgstr "è¦åŒ…å«åœ¨ bug 报告中的附件" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:1 msgid "Unexpected Error" msgstr "æ„外错误" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:2 msgid "Report" msgstr "报告" #: openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade.h:3 msgid "An unexpected error occured." msgstr "å‘生æ„外错误。" #: openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade.h:1 msgid "Show background tasks" msgstr "显示åŽå°ä»»åŠ¡" paperwork-2.2.2/openpaperwork-gtk/pyproject.toml000066400000000000000000000012311456262201400221210ustar00rootroot00000000000000[project] name = "openpaperwork-gtk" description = "OpenPaperwork's GTK plugins" dynamic = ["version"] authors = [ {name = "Jerome Flesch", email = "jflesch@openpaper.work" }, ] license = {text = "GPL-3.0-or-later"} readme = {file = "README.md", content-type = "text/markdown"} dependencies = [ "pygobject", ] [project.optional-dependencies] dev = [ "pytest", ] lint = [ "flake8", ] [tool.setuptools_scm] root = ".." relative_to = "__file__" write_to = "openpaperwork-gtk/src/openpaperwork_gtk/_version.py" version_scheme = "post-release" [build-system] requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta" paperwork-2.2.2/openpaperwork-gtk/setup.cfg000066400000000000000000000000661456262201400210330ustar00rootroot00000000000000[tool:pytest] addopts = -ra python_files = tests_*.py paperwork-2.2.2/openpaperwork-gtk/src/000077500000000000000000000000001456262201400177775ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/000077500000000000000000000000001456262201400235405ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/__init__.py000066400000000000000000000015741456262201400256600ustar00rootroot00000000000000import gettext def _(s): return gettext.dgettext('openpaperwork_gtk', s) CLI_PLUGINS = [ # plugins that can make sense to use even in the CLI application 'openpaperwork_gtk.external_apps.gio', 'openpaperwork_gtk.fs.gio', 'openpaperwork_gtk.l10n', 'openpaperwork_gtk.mainloop.glib', ] GUI_PLUGINS = [ 'openpaperwork_gtk.bug_report', 'openpaperwork_gtk.bug_report.http', 'openpaperwork_gtk.bug_report.zip', 'openpaperwork_gtk.busy.mouse', 'openpaperwork_gtk.colors', 'openpaperwork_gtk.dialogs.single_entry', 'openpaperwork_gtk.dialogs.yes_no', 'openpaperwork_gtk.pixbuf.pillow', 'openpaperwork_gtk.resources', 'openpaperwork_gtk.screenshots', 'openpaperwork_gtk.uncaught_exception', 'openpaperwork_gtk.wait_for_background_tasks', 'openpaperwork_gtk.widgets.calendar', 'openpaperwork_gtk.widgets.progress', ] paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/000077500000000000000000000000001456262201400257105ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/__init__.py000066400000000000000000000243621456262201400300300ustar00rootroot00000000000000import datetime import logging import openpaperwork_core import openpaperwork_core.deps from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def __init__(self): super().__init__() self.url_selected = None self.method_radio = None self.method_set_file_urls_callbacks = {} self.windows = [] self.widget_tree = None def get_interfaces(self): return [ 'gtk_bug_report_dialog', 'gtk_window_listener', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'external_apps', 'defaults': [ 'openpaperwork_core.external_apps.dbus', 'openpaperwork_core.external_apps.windows', 'openpaperwork_core.external_apps.xdg', ], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _shorten_url(self, url): if "://" not in url: return url dir_path = self.core.call_success("fs_dirname", url) dir_name = self.core.call_success("fs_basename", dir_path) if dir_name is None or dir_name == "": return url file_name = self.core.call_success("fs_basename", url) return dir_name + "/" + file_name def _format_date(self, date): if date is None: return _("Now") return date.strftime("%c") def _format_timestamp(self, date): if date is None: date = datetime.datetime.now() return int(date.timestamp()) def _refresh_attachment_page_complete(self, widget_tree): # check we have at least one entry toggled model = widget_tree.get_object("bug_report_model") assistant = widget_tree.get_object("bug_report_dialog") page = widget_tree.get_object("bug_report_attachment_selector") enabled = False for row in model: if row[0]: enabled = True if row[0] and "://" not in row[4]: enabled = False break assistant.set_page_complete(page, enabled) def _i18n_file_size(self, file_size): if isinstance(file_size, str) or file_size <= 0: return "" return self.core.call_success("i18n_file_size", file_size) def open_bug_report(self): self.method_radio = None self.url_selected = None self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.bug_report", "bug_report.glade" ) dialog = self.widget_tree.get_object("bug_report_dialog") self.core.call_all("bug_report_complete", self.widget_tree) self.widget_tree.get_object("bug_report_toggle_renderer").connect( "toggled", self._on_attachment_toggle, self.widget_tree ) self.widget_tree.get_object("bug_report_treeview").connect( "row-activated", self._on_row_selected, self.widget_tree ) self.widget_tree.get_object("bug_report_open_file").connect( "clicked", self._open_selected ) model = self.widget_tree.get_object("bug_report_model") model.clear() inputs = {} self.core.call_all("bug_report_get_attachments", inputs) now = datetime.datetime.now() for (k, v) in inputs.items(): v['id'] = k v['sort_date'] = ( v['date'].timestamp() if v['date'] is not None else now.timestamp() ) inputs = list(inputs.values()) inputs.sort( key=lambda i: (-i['sort_date'], i['file_type'], i['file_url']), ) for i in inputs: model.append( [ i['include_by_default'], i['sort_date'], self._format_date(i['date']), i['file_type'], i['file_url'], self._shorten_url(i['file_url']), i['file_size'], self._i18n_file_size(i['file_size']), i['id'], ] ) for i in inputs: if not i['include_by_default']: continue self.core.call_all( "on_bug_report_attachment_selected", i['id'], self.widget_tree ) if len(self.windows) > 0: dialog.set_transient_for(self.windows[-1]) dialog.connect("close", self._on_close) dialog.connect("cancel", self._on_close) dialog.connect("prepare", self._on_prepare, self.widget_tree) dialog.set_visible(True) self.core.call_all("on_gtk_window_opened", dialog) self._refresh_attachment_page_complete(self.widget_tree) def close_bug_report(self): dialog = self.widget_tree.get_object("bug_report_dialog") dialog.destroy() def _on_attachment_toggle(self, cell_renderer, row_path, widget_tree): model = widget_tree.get_object("bug_report_model") val = not model[row_path][0] model[row_path][0] = val if val: self.core.call_all( "on_bug_report_attachment_selected", model[row_path][-1], widget_tree ) else: self.core.call_all( "on_bug_report_attachment_unselected", model[row_path][-1], widget_tree ) self._refresh_attachment_page_complete(widget_tree) def _on_row_selected(self, treeview, row_path, column, widget_tree): self._on_url_selected(widget_tree) def _on_url_selected(self, widget_tree): button = widget_tree.get_object("bug_report_open_file") treeview = widget_tree.get_object("bug_report_treeview") model = widget_tree.get_object("bug_report_model") (has_selected, model_iter) = ( treeview.get_selection().get_selected() ) if not has_selected or model_iter is None: button.set_sensitive(False) return self.url_selected = model[model_iter][4] button.set_sensitive("://" in self.url_selected) def _open_selected(self, button): self.core.call_success("external_app_open_file", self.url_selected) def bug_report_update_attachment( self, attachment_id, infos: dict, widget_tree): model = widget_tree.get_object("bug_report_model") for row in model: if row[-1] != attachment_id: continue if 'date' in infos: row[1] = self._format_timestamp(infos['date']) row[2] = self._format_date(infos['date']) if 'file_type' in infos: row[3] = infos['file_type'] if 'file_url' in infos: row[4] = infos['file_url'] row[5] = self._shorten_url(infos['file_url']) if 'file_size' in infos: row[6] = infos['file_size'] row[7] = self._i18n_file_size(infos['file_size']) break self._on_url_selected(widget_tree) self._refresh_attachment_page_complete(widget_tree) def bug_report_get_attachment_file_url(self, attachment_id, widget_tree): model = widget_tree.get_object("bug_report_model") for row in model: if row[-1] != attachment_id: continue if "://" not in row[4]: return None return row[4] return None def _on_close(self, dialog): dialog.set_visible(False) self.core.call_all("on_gtk_window_closed", dialog) def bug_report_add_method( self, title, description, enable_callback, disable_callback, widget_tree): widget_tree_method = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.bug_report", "bug_report_method.glade" ) widget_tree_method.get_object("bug_report_method_title").set_text( title ) widget_tree_method.get_object( "bug_report_method_description" ).set_markup(description) widget_tree.get_object("bug_report_methods").pack_start( widget_tree_method.get_object("bug_report_method"), expand=False, fill=False, padding=20 ) radio = widget_tree_method.get_object("bug_report_method_radio") radio.connect( "toggled", self._on_method_toggled, widget_tree, enable_callback, disable_callback ) if self.method_radio is None: self.method_radio = radio enable_callback(widget_tree) else: radio.join_group(self.method_radio) self.method_radio.set_active(True) def _on_method_toggled( self, radio, widget_tree, enable_callback, disable_callback): if radio.get_active(): enable_callback(widget_tree) else: disable_callback(widget_tree) def _on_prepare(self, assistant, page, widget_tree): self._set_file_urls(widget_tree) def _set_file_urls(self, widget_tree): model = widget_tree.get_object("bug_report_model") file_urls = [row[4] for row in model if row[0]] self.core.call_all("bug_report_set_file_urls_to_send", file_urls) def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("bug_report_dialog"), self.core.call_success("fs_join", out_dir, "bug_report.png") ) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report.glade000066400000000000000000000247761456262201400310760ustar00rootroot00000000000000 False 12 Image /home/jflesch/.local/share/camion/21211212_crash_screenshot.png True 1 Text /home/jflesch/camion/20200101_logs.txt False Bug Spray 1000 520 True dialog 1 True False 20 20 20 20 0 none True False 12 True False vertical True True in True True bug_report_model 3 True True 0 Date 1 2 Type 3 3 File 4 5 Size 6 7 True True 0 True False Open file True False True True False True end 0 True False For your privacy, attachments may be partially censored when selected True False True 1 False True 1 True False 10 Attachments to include in the bug report False True False 20 20 20 20 vertical True True False paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_http.glade000066400000000000000000000157761456262201400321350ustar00rootroot00000000000000 True False vertical bug_report_http_description_page True False 20 20 0 none True False 12 True True in True True word bug_report_http_description_buffer GTK_INPUT_HINT_SPELLCHECK | GTK_INPUT_HINT_NONE True False 10 Bug description True True 0 True False 0 none True False 12 True True Required if you agree to be contacted regarding this bug report GTK_INPUT_HINT_NO_SPELLCHECK | GTK_INPUT_HINT_NONE True False 10 Your email address False True 1 True False center 20 20 20 20 True True True True False vertical True True center True Bug report successfully submitted. You can find below the private link to your bug report. <b>Be careful before sharing it.</b> Bug report attachments (logs, screenshots, …) do not contain any private information. Still you're strongly advised to check them all before sharing this link. You can request deletion of your bug report by sending an email to <a href="mailto:jflesch@openpaper.work">jflesch@openpaper.work</a>. True center True True False True 0 True True center True <a href="https://openpaper.work/pouetpouet">https://openpaper.work/pouetpouet</a> True True char True False True 1 paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_method.glade000066400000000000000000000042241456262201400324200ustar00rootroot00000000000000 True False vertical True True False True True True False 15 10 10 label 0 False True 0 True False 30 10 10 label True 0 True True 1 paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/bug_report_zip.glade000066400000000000000000000033461456262201400317460ustar00rootroot00000000000000 application/zip True False 0 none True False 12 True True save filefilterZip False False True False 10 Please select where to save the ZIP file paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/http.py000066400000000000000000000214761456262201400272530ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise from .. import (_, deps) LOGGER = logging.getLogger(__name__) PATH_MAKE_BUG_REPORT = "/beacon/bug_report/create" PATH_ADD_ATTACHMENT = "/beacon/bug_report/add_attachment" class Sender(object): def __init__(self, core, http, progress, description, file_urls): self.core = core self.http = http self.progress = progress self.description = description self.file_urls = file_urls self.infos = None self.nb_steps = len(self.file_urls) + 2 self.current_step = 0 def _notify_progress(self, *args, **kwargs): assert self.current_step <= self.nb_steps if self.current_step == 0: txt = _("Creating bug report ...") else: txt = _("Sending bug report attachment ...") self.core.call_all( "on_progress", "bug_report_http", self.current_step / self.nb_steps, txt ) self.progress.set_fraction(self.current_step / self.nb_steps) self.progress.set_text(txt) self.current_step += 1 def _set_report_infos(self, infos): self.infos = infos def _str_to_http(self, file_name, string): data = { "file_name": file_name, "binary": string.encode("utf-8") } data.update(self.infos) return data def _file_to_http(self, file_url): with self.core.call_success("fs_open", file_url, "rb") as fd: data = { "file_name": self.core.call_success("fs_basename", file_url), "binary": fd.read() } data.update(self.infos) return data def get_promise(self): LOGGER.info("Will send %s", self.file_urls) promise = openpaperwork_core.promise.Promise( self.core, self._notify_progress ) promise = promise.then(lambda *args, **kwargs: { "app_name": self.core.call_success("app_get_name"), "app_version": self.core.call_success("app_get_version"), }) promise = promise.then(self.http.get_request_promise( PATH_MAKE_BUG_REPORT )) promise = promise.then(self._set_report_infos) promise = promise.then(self._notify_progress) promise = promise.then( self._str_to_http, "description.txt", self.description ) promise = promise.then(self.http.get_request_promise( PATH_ADD_ATTACHMENT )) promise = promise.then(self._notify_progress) for file_url in self.file_urls: promise = promise.then(self._file_to_http, file_url) promise = promise.then(self.http.get_request_promise( PATH_ADD_ATTACHMENT )) promise = promise.then(self._notify_progress) return promise def get_report_url(self): return self.infos['url'] class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def __init__(self): super().__init__() self.widget_tree = None self.assistant = None self.file_urls = [] self.http = None self.progress = None self.prepare_handler_id = None self.description = None def get_interfaces(self): return [ 'bug_report_method', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'app', 'defaults': [], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'http_json', 'defaults': ['openpaperwork_core.http'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, ] def init(self, core): super().init(core) self.http = self.core.call_success( "http_json_get_client", "bug_report" ) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(deps.GTK) def bug_report_complete(self, *args): self.core.call_all( "bug_report_add_method", _("Send automatically"), _("Send the bug report automatically to OpenPaper.work"), self._enable_http, self._disable_http, *args ) def _enable_http(self, bug_report_widget_tree): self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.bug_report", "bug_report_http.glade" ) assistant = bug_report_widget_tree.get_object("bug_report_dialog") self.assistant = assistant page = self.widget_tree.get_object("bug_report_http_description_page") description_page = page assistant.append_page(page) assistant.set_page_complete(page, False) self.description = self.widget_tree.get_object( "bug_report_http_description_buffer" ) self.description.connect( "changed", lambda txt_buffer: assistant.set_page_complete( description_page, txt_buffer.get_char_count() > 0 ) ) page = self.widget_tree.get_object("bug_report_http_progress") self.progress = page assistant.append_page(page) assistant.set_page_complete(page, False) page = self.widget_tree.get_object("bug_report_http_result") self.page_idx = assistant.append_page(page) assistant.set_page_complete(page, True) assistant.set_page_type(page, Gtk.AssistantPageType.CONFIRM) self.prepare_handler_id = assistant.connect( "prepare", self._on_prepare ) def _disable_http(self, bug_report_widget_tree): if self.widget_tree is None: return assistant = bug_report_widget_tree.get_object("bug_report_dialog") assistant.remove(self.widget_tree.get_object( "bug_report_http_description_page" )) assistant.remove(self.widget_tree.get_object( "bug_report_http_progress" )) assistant.remove(self.widget_tree.get_object( "bug_report_http_result" )) assistant.disconnect(self.prepare_handler_id) self.widget_tree = None def bug_report_set_file_urls_to_send(self, file_urls): self.file_urls = file_urls def _on_prepare(self, assistant, page): if page != self.progress: return self._send() def _get_description(self): author = self.widget_tree.get_object("bug_report_http_author") author = author.get_text() start = self.description.get_iter_at_offset(0) end = self.description.get_iter_at_offset(-1) description = self.description.get_text(start, end, False) return "Author: {}\n\n{}".format(author, description) def _send(self): promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_busy",) ) sender = Sender( self.core, self.http, self.progress, self._get_description(), self.file_urls ) promise = promise.then(sender.get_promise()) promise = promise.then(self._show_result, sender) promise = promise.catch(self._on_error) promise.schedule() def _show_result(self, sender): self.core.call_all("on_idle") if self.widget_tree is None: return LOGGER.info("Transfer successful") url = self.widget_tree.get_object("bug_report_http_url") url.set_markup('{url}'.format( url=sender.get_report_url(), )) self.assistant.set_page_complete(self.progress, True) self.progress.set_fraction(1.0) self.progress.set_text(_("Success")) self.assistant.set_current_page( # no point in staying on the progress bar page self.assistant.get_current_page() + 1 ) def _on_error(self, exc): self.core.call_all("on_idle") if self.widget_tree is None: return LOGGER.error("Transfer failed", exc_info=exc) exc_txt = str(exc)[:256] txt = self.widget_tree.get_object("bug_report_http_result_txt") txt.set_text(_("Transfer failed:\n\n%s") % exc_txt) url = self.widget_tree.get_object("bug_report_http_url") url.set_text("") self.assistant.set_page_complete(self.progress, True) self.progress.set_fraction(1.0) self.progress.set_text(_("FAILED")) self.core.call_all("on_progress", "bug_report_http", 1.0) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/bug_report/zip.py000066400000000000000000000077221456262201400270740ustar00rootroot00000000000000import logging import re import zipfile try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core from .. import (_, deps) LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def __init__(self): super().__init__() self.widget_tree = None self.file_urls = [] self.apply_handler_id = None def get_interfaces(self): return [ 'bug_report_method', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(deps.GTK) def bug_report_complete(self, *args): url = "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues" self.core.call_all( "bug_report_add_method", _("ZIP file"), re.sub( '[ \t]+', ' ', ( _( "Build a ZIP file containing all the attachments.\n" " If you want, you can then submit a bug report" ' manually on Paperwork\'s bug' " tracker and attach this ZIP file to the ticket." ) % url ).strip() ), self._enable_zip, self._disable_zip, *args ) def _enable_zip(self, bug_report_widget_tree): self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.bug_report", "bug_report_zip.glade" ) assistant = bug_report_widget_tree.get_object("bug_report_dialog") page = self.widget_tree.get_object("bug_report_zip_page") assistant.append_page(page) assistant.set_page_complete(page, False) assistant.set_page_type(page, Gtk.AssistantPageType.CONFIRM) self.apply_handler_id = assistant.connect("apply", self._make_zip) filechooser = self.widget_tree.get_object("bug_report_zip_filechooser") filechooser.connect( "selection-changed", lambda filechooser: assistant.set_page_complete( page, filechooser.get_uri() is not None ) ) def _disable_zip(self, bug_report_widget_tree): if self.widget_tree is None: return assistant = bug_report_widget_tree.get_object("bug_report_dialog") page = self.widget_tree.get_object("bug_report_zip_page") assistant.remove(page) assistant.disconnect(self.apply_handler_id) self.widget_tree = None def bug_report_set_file_urls_to_send(self, file_urls): self.file_urls = file_urls def _make_zip(self, assistant): in_file_urls = self.file_urls out_file_url = self.widget_tree.get_object( "bug_report_zip_filechooser" ).get_uri() out_file_url = out_file_url.strip() if not out_file_url.lower().endswith(".zip"): out_file_url += ".zip" LOGGER.info("Adding attachments to %s", out_file_url) out_file_path = self.core.call_success("fs_unsafe", out_file_url) with zipfile.ZipFile(out_file_path, 'w') as out_zip: for in_file_url in in_file_urls: file_name = self.core.call_success("fs_basename", in_file_url) with self.core.call_success( "fs_open", in_file_url, "rb") as in_fd: with out_zip.open(file_name, 'w') as out_fd: out_fd.write(in_fd.read()) LOGGER.info("%s written", out_file_url) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/busy/000077500000000000000000000000001456262201400245225ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/busy/__init__.py000066400000000000000000000000001456262201400266210ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/busy/mouse.py000066400000000000000000000056141456262201400262320ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps GI_AVAILABLE = False GDK_AVAILABLE = False try: import gi GI_AVAILABLE = True except (ImportError, ValueError): pass if GI_AVAILABLE: try: gi.require_version('Gdk', '3.0') from gi.repository import Gdk GDK_AVAILABLE = True except (ImportError, ValueError): pass LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.refcount = 0 self.windows = [] self.realize_handler_id = None def get_interfaces(self): return [ 'busy', 'chkdeps', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def chkdeps(self, out: dict): if not GDK_AVAILABLE: out['gdk'].update(openpaperwork_core.deps.GDK) def _set_mouse_cursor(self, offset): self.refcount += offset assert self.refcount >= 0 if len(self.windows) <= 0: LOGGER.warning( "Cannot change mouse cursor: no main window defined" ) return if self.refcount > 0: LOGGER.info("Mouse cursor --> busy") try: display = self.windows[-1].get_display() cursor = Gdk.Cursor.new_for_display( display, Gdk.CursorType.WATCH ) except TypeError as exc: # may happen with Wayland LOGGER.error("Failed to switch mouse cursor", exc_info=exc) return else: LOGGER.info("Mouse cursor --> idle") cursor = None self.windows[-1].get_window().set_cursor(cursor) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def on_busy(self): self._set_mouse_cursor(1) def on_idle(self): self._set_mouse_cursor(-1) def on_widget_busyness_changed(self, widget, busy): if busy: cursor = None else: display = widget.get_display() cursor = Gdk.Cursor.new_for_display(display, Gdk.CursorType.WATCH) window = widget.get_window() def _set_cursor(*args, **kwargs): window = widget.get_window() window.set_cursor(cursor) if self.realize_handler_id is not None: widget.disconnect(self.realize_handler_id) self.realize_handler_id = None if window is not None: _set_cursor() else: # assuming the widget will be realized soon widget.connect("realize", _set_cursor) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/colors.py000066400000000000000000000024331456262201400254150ustar00rootroot00000000000000try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core from . import deps class Plugin(openpaperwork_core.PluginBase): def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(deps.GTK) def get_interfaces(self): return [ 'chkdeps', 'gtk_colors', ] def gtk_entry_set_colors(self, gtk_entry, fg="black", bg="#CC3030"): css = """ * { color: %s; background: %s; } * selection { color: white; background: #3b84e9; } """ % (fg, bg) css_provider = Gtk.CssProvider() css_provider.load_from_data(css.encode()) css_context = gtk_entry.get_style_context() css_context.add_provider( css_provider, Gtk.STYLE_PROVIDER_PRIORITY_USER ) def gtk_entry_reset_colors(self, gtk_entry): self.gtk_entry_set_colors( gtk_entry, fg="@theme_text_color", bg="@theme_bg_color" ) def gtk_theme_get_color(self, color_name): style = Gtk.StyleContext() return style.lookup_color("theme_bg_color")[1] paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/deps.py000066400000000000000000000016001456262201400250420ustar00rootroot00000000000000GDK_PIXBUF = { 'debian': 'gir1.2-gdkpixbuf-2.0', 'linuxmint': 'gir1.2-gdkpixbuf-2.0', 'raspbian': 'gir1.2-gdkpixbuf-2.0', 'ubuntu': 'gir1.2-gdkpixbuf-2.0', } GTK = { 'debian': 'gir1.2-gtk-3.0', 'fedora': 'gtk3', 'gentoo': 'x11-libs/gtk+', 'linuxmint': 'gir1.2-gtk-3.0', 'raspbian': 'gir1.2-gtk-3.0', 'suse': 'python-gtk', 'ubuntu': 'gir1.2-gtk-3.0', } HDY = { 'debian': 'gir1.2-handy-1', 'fedora': 'libhandy1', 'gentoo': 'gui-libs/libhandy', 'linuxmint': 'gir1.2-handy-1', 'raspbian': 'gir1.2-handy-1', 'suse': 'libhandy-1-0', 'ubuntu': 'gir1.2-handy-1', } NOTIFY = { 'debian': 'gir1.2-notify-0.7', 'fedora': 'libnotify', 'ubuntu': 'gir1.2-notify-0.7', } PANGO = { 'debian': 'gir1.2-pango-1.0', 'linuxmint': 'gir1.2-pango-1.0', 'raspbian': 'gir1.2-pango-1.0', 'ubuntu': 'gir1.2-pango-1.0', } paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/dialogs/000077500000000000000000000000001456262201400251625ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/dialogs/__init__.py000066400000000000000000000000001456262201400272610ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/dialogs/single_entry/000077500000000000000000000000001456262201400276645ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/dialogs/single_entry/__init__.py000066400000000000000000000045371456262201400320060ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.windows = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_dialog_single_entry', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def gtk_show_dialog_single_entry( self, origin, title, original_value, *args, **kwargs): widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.dialogs.single_entry", "single_entry.glade" ) widget_tree.get_object("entry").set_text(original_value) dialog = widget_tree.get_object("dialog") dialog.set_title(title) dialog.set_transient_for(self.windows[-1]) dialog.set_modal(True) dialog.connect( "response", self._on_response, (widget_tree, origin, args, kwargs) ) dialog.show_all() return True def _on_response(self, dialog, response_id, args): (widget_tree, origin, args, kwargs) = args new_value = widget_tree.get_object("entry").get_text() dialog.destroy() if (response_id != 0 and response_id != Gtk.ResponseType.ACCEPT and response_id != Gtk.ResponseType.OK and response_id != Gtk.ResponseType.YES and response_id != Gtk.ResponseType.APPLY): LOGGER.info("User cancelled") r = False else: r = True self.core.call_all( "on_dialog_single_entry_reply", origin, r, new_value, *args, **kwargs ) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/dialogs/single_entry/single_entry.glade000066400000000000000000000056561456262201400334000ustar00rootroot00000000000000 False 30 dialog False vertical 2 False end gtk-cancel True True True True True True 0 gtk-ok True True True True True True 1 False False 0 True True False True 1 button_cancel button_validate paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/dialogs/yes_no.py000066400000000000000000000040101456262201400270230ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): """ Provides a simple way to show a Yes/No question popup (usually something along the line of "are you really really really sure you want to do that ?"). """ def __init__(self): super().__init__() self.windows = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_dialog_yes_no', 'gtk_window_listener', ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def gtk_show_dialog_yes_no(self, origin, msg, *args, **kwargs): confirm = Gtk.MessageDialog( parent=self.windows[-1], flags=( Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT ), message_type=Gtk.MessageType.WARNING, buttons=Gtk.ButtonsType.YES_NO, text=msg ) confirm.connect("response", self._on_response, origin, (args, kwargs)) confirm.show_all() return True def _on_response(self, dialog, response, origin, args): (args, kwargs) = args if response != Gtk.ResponseType.YES: LOGGER.info("User cancelled") dialog.destroy() self.core.call_all( "on_dialog_yes_no_reply", origin, False, *args, **kwargs ) return dialog.destroy() self.core.call_all( "on_dialog_yes_no_reply", origin, True, *args, **kwargs ) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/drawer/000077500000000000000000000000001456262201400250245ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/drawer/__init__.py000066400000000000000000000000001456262201400271230ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/drawer/pillow.py000066400000000000000000000065731456262201400267170ustar00rootroot00000000000000""" Draw a Pillow image on top of GtkDrawingArea. """ import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Drawer(object): BACKGROUND = (0.75, 0.75, 0.75) def __init__(self, core, drawing_area, pil_img): self.core = core self.drawing_area = drawing_area # expected: Gtk.DrawingArea self.img = core.call_success("pillow_to_surface", pil_img) self.draw_connect_id = drawing_area.connect("draw", self.on_draw) def stop(self): if self.draw_connect_id is not None: self.drawing_area.disconnect(self.draw_connect_id) self.draw_connect_id = None self.img = None # free the memory def on_draw(self, drawing_area, cairo_ctx): widget_height = self.drawing_area.get_allocated_height() widget_width = self.drawing_area.get_allocated_width() factor_w = self.img.surface.get_width() / widget_width factor_h = self.img.surface.get_height() / widget_height factor = max(factor_w, factor_h) # background cairo_ctx.save() try: cairo_ctx.set_source_rgb( self.BACKGROUND[0], self.BACKGROUND[1], self.BACKGROUND[2] ) cairo_ctx.rectangle(0, 0, widget_width, widget_height) cairo_ctx.clip() cairo_ctx.paint() finally: cairo_ctx.restore() # image cairo_ctx.save() try: cairo_ctx.scale(1.0 / factor, 1.0 / factor) cairo_ctx.set_source_surface(self.img.surface) cairo_ctx.rectangle( 0, 0, self.img.surface.get_width(), self.img.surface.get_height() ) cairo_ctx.clip() cairo_ctx.paint() finally: cairo_ctx.restore() class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() # drawing area --> Drawer self.active_drawers = {} def get_interfaces(self): return [ 'gtk_drawer_pillow', ] def get_deps(self): return [ { 'interface': 'pillow_to_surface', 'defaults': ['paperwork_backend.cairo.pillow'], }, ] def draw_pillow_start(self, drawing_area, pil_img): drawer = Drawer(self.core, drawing_area, pil_img) self.active_drawers[drawing_area] = drawer return drawer def draw_pillow_stop(self, drawing_area): drawer = self.active_drawers.pop(drawing_area) drawer.stop() return drawer if __name__ == "__main__": import sys import PIL import PIL.Image import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk img = PIL.Image.open(sys.argv[1]) core = openpaperwork_core.Core() core.load("openpaperwork_core.mainloop.asyncio") core.load("openpaperwork_gtk.fs.gio") core.load("openpaperwork_core.thread.simple") core.load("openpaperwork_core.work_queue.default") core.load("paperwork_backend.cairo.pillow") core.load("openpaperwork_core.pillow.img") core._load_module("test", sys.modules[__name__]) core.init() window = Gtk.Window() window.set_size_request(600, 600) drawing_area = Gtk.DrawingArea() window.add(drawing_area) core.call_success("draw_pillow_start", drawing_area, img) window.show_all() Gtk.main() paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/drawer/scan.py000066400000000000000000000242571456262201400263340ustar00rootroot00000000000000""" Plugin to draw scan on GTK widgets. This code should be on Paperwork-gtk, but Ironscanner needs it to. """ import logging import openpaperwork_core import openpaperwork_core.deps CAIRO_AVAILABLE = False try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): pass LOGGER = logging.getLogger(__name__) class Drawer(object): BACKGROUND = (0.75, 0.75, 0.75) def __init__(self, core, drawing_area=None): self.core = core self.drawing_areas = [] self.draw_connect_ids = {} self.scan_size = (0, 0) self.last_line = 0 self.show_scan_border = False self.image = None self.scan_ended = False if drawing_area is not None: self.add_drawing_area(drawing_area) def add_drawing_area(self, drawing_area): self.drawing_areas.append(drawing_area) self.draw_connect_ids[drawing_area] = drawing_area.connect( "draw", self.on_draw ) def remove_drawing_area(self, drawing_area): connect_id = self.draw_connect_ids.pop(drawing_area) drawing_area.disconnect(connect_id) self.drawing_areas.remove(drawing_area) if len(self.drawing_areas) <= 0: self.stop() def stop(self): for (drawing_area, connect_id) in self.draw_connect_ids.items(): drawing_area.disconnect(connect_id) self.draw_connect_ids = {} self.drawing_areas = [] self.image = None # release the memory def request_redraw(self): for d in self.drawing_areas: d.queue_draw() def on_scan_page_start(self, scan_params): self.scan_size = (scan_params.get_width(), scan_params.get_height()) self.last_line = 0 LOGGER.info( "Scan started: %s (expected: %dx%dpx)", self.scan_size, self.scan_size[0], self.scan_size[1] ) self.scan_size = ( # WORKAROUND(Jflesch): Some scanners (Fujistu mainly) return an # image far too big in height. Cairo only allows a maximum image # size of 32767 (see #define MAX_IMAGE_SIZE in # cairo-image-surface.c) min(self.scan_size[0], 32766), min(self.scan_size[1], 32766), ) self.image = cairo.ImageSurface( cairo.FORMAT_RGB24, self.scan_size[0], self.scan_size[1] ) cairo_ctx = cairo.Context(self.image) cairo_ctx.set_source_rgb( self.BACKGROUND[0], self.BACKGROUND[1], self.BACKGROUND[2] ) cairo_ctx.rectangle(0, 0, self.scan_size[0], self.scan_size[1]) cairo_ctx.fill() self.show_scan_border = True self.request_redraw() def on_scan_page_end(self): self.show_scan_border = False self.request_redraw() def on_scan_chunk(self, img_chunk): if self.image is None: return size = img_chunk.size LOGGER.debug("Scan chunk: %s", size) img_chunk = self.core.call_success( "pillow_to_surface", img_chunk ) cairo_ctx = cairo.Context(self.image) cairo_ctx.translate(0, self.last_line) cairo_ctx.set_source_surface(img_chunk.surface) cairo_ctx.rectangle(0, 0, size[0], size[1]) cairo_ctx.clip() cairo_ctx.paint() self.last_line += size[1] self.request_redraw() def on_draw(self, drawing_area, cairo_ctx): widget_height = drawing_area.get_allocated_height() widget_width = drawing_area.get_allocated_width() factor_w = self.scan_size[0] / widget_width factor_h = self.scan_size[1] / widget_height factor = max(factor_w, factor_h) # background cairo_ctx.save() try: cairo_ctx.set_source_rgb( self.BACKGROUND[0], self.BACKGROUND[1], self.BACKGROUND[2] ) cairo_ctx.rectangle(0, 0, widget_width, widget_height) cairo_ctx.clip() cairo_ctx.paint() finally: cairo_ctx.restore() # chunks if self.image is not None: cairo_ctx.save() try: cairo_ctx.scale(1.0 / factor, 1.0 / factor) cairo_ctx.set_source_surface(self.image) cairo_ctx.rectangle(0, 0, self.scan_size[0], self.scan_size[1]) cairo_ctx.clip() cairo_ctx.paint() finally: cairo_ctx.restore() # scan border if self.show_scan_border: cairo_ctx.save() try: position = int(self.last_line / factor) cairo_ctx.set_operator(cairo.OPERATOR_OVER) cairo_ctx.set_source_rgba( 1.0, 0.0, 0.0, 0.5 ) cairo_ctx.set_line_width(10.0) cairo_ctx.move_to(0, position) cairo_ctx.line_to(widget_width, position) cairo_ctx.stroke() finally: cairo_ctx.restore() class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() # scan id --> Drawer (scan id = None ==> any scan) self.active_drawers = {} def get_interfaces(self): return [ 'chkdeps', 'gtk_drawer_scan', ] def get_deps(self): return [ { 'interface': 'pillow_to_surface', 'defaults': ['paperwork_backend.cairo.pillow'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], } ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) def draw_scan_start(self, drawing_area, scan_id=None): if scan_id in self.active_drawers: drawer = self.active_drawers[scan_id] else: drawer = Drawer(self.core) self.active_drawers[scan_id] = drawer drawer.add_drawing_area(drawing_area) return drawer def draw_scan_stop(self, drawing_area): for (k, drawer) in self.active_drawers.items(): for d in drawer.drawing_areas: if d == drawing_area: break else: continue break else: return None drawer.remove_drawing_area(drawing_area) if drawer.scan_ended and len(drawer.drawing_areas) <= 0: self.active_drawers.pop(k) return drawer def draw_scan_get_max_size(self, scan_id): if scan_id not in self.active_drawers: return self.active_drawers[scan_id].scan_size def on_scan_feed_start(self, scan_id): self.core.call_all("on_busy") if scan_id not in self.active_drawers: return # we show the app as busy when the user clicks on 'scan' # and we stop the busy indicator when a page is actually scanning # instantiate a default drawer to keep track of the size and the chunks if scan_id not in self.active_drawers: self.active_drawers[scan_id] = Drawer(self.core) def on_scan_page_start(self, scan_id, page_nb, scan_params): self.core.call_all("on_idle") if None in self.active_drawers: self.active_drawers[None].on_scan_page_start(scan_params) if scan_id in self.active_drawers: self.active_drawers[scan_id].on_scan_page_start(scan_params) def on_scan_chunk(self, scan_id, scan_params, img_chunk): for k in (None, scan_id): if k not in self.active_drawers: continue self.active_drawers[k].on_scan_chunk(img_chunk) def on_scan_page_end(self, scan_id, page_nb, img): self.core.call_all("on_busy") for k in (None, scan_id): if k not in self.active_drawers: continue self.active_drawers[k].on_scan_page_end() self.active_drawers[k].scan_ended = True if len(self.active_drawers[k].drawing_areas) <= 0: self.active_drawers.pop(k) def on_scan_feed_end(self, scan_id): self.core.call_all("on_idle") for k in (None, scan_id): if k not in self.active_drawers: continue self.active_drawers[k].scan_ended = True if __name__ == "__main__": import sys import PIL import PIL.Image import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from gi.repository import GLib img = PIL.Image.open(sys.argv[1]) chunks = [ img.crop((0, line, img.size[1], line + 100)) for line in range(0, img.size[1], 100) ] class FakeScanParams(object): def __init__(self, img): self.img = img def get_width(self): return self.img.size[0] def get_height(self): return self.img.size[1] class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['scan'] scan_params = FakeScanParams(img) core = openpaperwork_core.Core() core.load("openpaperwork_core.mainloop.asyncio") core.load("openpaperwork_core.thread.simple") core.load("openpaperwork_core.work_queue.default") core.load("openpaperwork_gtk.fs.gio") core.load("paperwork_backend.cairo.pillow") core.load("openpaperwork_core.pillow.img") core._load_module("scan", FakeModule) core._load_module("test", sys.modules[__name__]) core.init() window = Gtk.Window() window.set_size_request(600, 600) drawing_area = Gtk.DrawingArea() window.add(drawing_area) core.call_all("draw_scan_start", drawing_area, scan_id="pouet") calls = [ ("on_scan_page_start", "pouet", 0, scan_params), ] calls += [ ("on_scan_chunk", "pouet", scan_params, chunk) for chunk in chunks ] calls += [ ("on_scan_page_end", "pouet", 0, img) ] calls = 2 * calls def wrapper(func, *args): func(*args) return False for (t, call) in enumerate(calls): t = t * 500 + 500 GLib.timeout_add(t, wrapper, core.call_all, *call) window.show_all() Gtk.main() paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/external_apps/000077500000000000000000000000001456262201400264055ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/external_apps/__init__.py000066400000000000000000000000001456262201400305040ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/external_apps/gio.py000066400000000000000000000017051456262201400275400ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except ImportError: GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 75 def get_interfaces(self): return [ 'chkdeps', 'external_apps', ] def get_deps(self): return [] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'] = openpaperwork_core.deps.GLIB def external_app_open_file(self, file_url): LOGGER.info("Opening file '%s' using Gio", file_url) if not Gio.AppInfo.launch_default_for_uri(file_url): LOGGER.warning("Failed to opening file '%s' using Gio", file_url) return None return True def external_app_open_folder(self, folder_url): return self.external_app_open_file(folder_url) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/fs/000077500000000000000000000000001456262201400241505ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/fs/__init__.py000066400000000000000000000000001456262201400262470ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/fs/gio.py000066400000000000000000000474001456262201400253050ustar00rootroot00000000000000import ctypes import io import logging import os import tempfile try: from gi.repository import Gio from gi.repository import GLib GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core.deps import openpaperwork_core.fs LOGGER = logging.getLogger(__name__) class _GioFileAdapter(io.RawIOBase): def __init__(self, gfile, mode='r'): super().__init__() self.gfile = gfile self.mode = mode if 'w' in mode and 'r' not in mode: self.size = 0 elif ('w' in mode or 'a' in mode) and not gfile.query_exists(): self.size = 0 else: try: fi = gfile.query_info( Gio.FILE_ATTRIBUTE_STANDARD_SIZE, Gio.FileQueryInfoFlags.NONE ) self.size = fi.get_attribute_uint64( Gio.FILE_ATTRIBUTE_STANDARD_SIZE ) except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) self.gfd = None self.gin = None self.gout = None if 'r' in mode and 'w' in mode: if gfile.query_exists(): self.gfd = gfile.open_readwrite() else: # create_readwrite() doesn't seem to always work on # Windows+MSYS2 self.gfd = gfile.create_readwrite(Gio.FileCreateFlags.PRIVATE) if 'w' in mode: self.gfd.seek(0, GLib.SeekType.SET) self.gfd.truncate(0) self.gin = self.gfd.get_input_stream() self.gout = self.gfd.get_output_stream() elif 'r' in mode: self.gfd = gfile.read() self.gin = self.gfd elif 'w' in mode or 'a' in mode: if 'w' in mode: self.gfd = gfile.replace( None, # etag False, # make_backup Gio.FileCreateFlags.PRIVATE ) elif 'a' in mode: self.gfd = gfile.append_to( Gio.FileCreateFlags.PRIVATE ) self.gout = self.gfd def readable(self): return True def writable(self): return 'w' in self.mode or 'a' in self.mode def read(self, size=-1): if not self.readable(): raise OSError("File is not readable") if size <= 0: size = self.size if size <= 0: return b"" assert size > 0 return self.gin.read_bytes(size).get_data() def readall(self): return self.read(-1) def readinto(self, b): raise OSError("readinto() not supported on Gio.File objects") def readline(self, size=-1): raise OSError("readline() not supported on Gio.File objects") def readlines(self, hint=-1): LOGGER.warning("readlines() shouldn't be called on a binary file" " descriptor. This is not cross-platform") return [(x + b"\n") for x in self.readall().split(b"\n")] def seek(self, offset, whence=os.SEEK_SET): whence = { os.SEEK_CUR: GLib.SeekType.CUR, os.SEEK_END: GLib.SeekType.END, os.SEEK_SET: GLib.SeekType.SET, }[whence] self.gfd.seek(offset, whence) def seekable(self): return True def tell(self): return self.gin.tell() def flush(self): pass def truncate(self, size=None): if size is None: size = self.tell() self.gfd.truncate(size) def fileno(self): if self.gout is not None and hasattr(self.gout, 'get_fd'): return self.gout.get_fd() if self.gin is not None and hasattr(self.gin, 'get_fd'): return self.gin.get_fd() raise io.UnsupportedOperation("fileno() on Gio.File unsupported") def isatty(self): return False def write(self, b): res = self.gout.write_all(b) if not res[0]: raise OSError("write_all() failed on {}: {}".format( self.gfile.get_uri(), res) ) return res[1] def writelines(self, lines): self.write(b"".join(lines)) def close(self): self.flush() super().close() if self.gin is not None and self.gin is not self.gfd: self.gin.close() if self.gout is not None and self.gout is not self.gfd: self.gout.close() if self.gfd: self.gfd.close() def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() class _GioUTF8FileAdapter(io.RawIOBase): def __init__(self, raw): super().__init__() self.raw = raw self.line_iterator = None def readable(self): return self.raw.readable() def writable(self): return self.raw.writable() def read(self, *args, **kwargs): r = self.raw.read(*args, **kwargs) return r.decode("utf-8") def readall(self, *args, **kwargs): r = self.raw.readall(*args, **kwargs) return r.decode("utf-8") def readinto(self, *args, **kwargs): r = self.raw.readinto(*args, **kwargs) return r.decode("utf-8") def readlines(self, hint=-1): all = self.readall() if os.linesep != "\n": all = all.replace(os.linesep, "\n") lines = [(x + "\n") for x in all.split("\n")] if lines[-1] == "\n": return lines[:-1] return lines def readline(self, hint=-1): if self.line_iterator is None: self.line_iterator = (line for line in self.readlines(hint)) try: return next(self.line_iterator) except StopIteration: return '' def seek(self, *args, **kwargs): return self.raw.seek(*args, **kwargs) def seekable(self, seekable): return self.raw.seekable() @property def closed(self): return self.raw.closed def tell(self): # XXX(Jflesch): wrong ... return self.raw.tell() def flush(self): return self.raw.flush() def truncate(self, *args, **kwargs): # XXX(Jflesch): wrong ... return self.raw.truncate(*args, **kwargs) def fileno(self): return self.raw.fileno() def isatty(self): return self.raw.isatty() def write(self, b): b = b.encode("utf-8") return self.raw.write(b) def writelines(self, lines): lines = [ (line + os.linesep).encode("utf-8") for line in lines ] return self.raw.writelines(lines) def close(self): self.raw.close() def __enter__(self): return self def __exit__(self, type, value, traceback): self.close() class Plugin(openpaperwork_core.fs.CommonFsPluginBase): PRIORITY = 50 def __init__(self): super().__init__() self.vfs = None if GLIB_AVAILABLE: self.vfs = Gio.Vfs.get_default() self.tmp_files = set() def get_interfaces(self): return super().get_interfaces() + ['chkdeps'] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def fs_open(self, uri, mode='r', needs_fileno=False, **kwargs): if needs_fileno: # On Windows, `Gio.[Unix]OutputStream.get_fd()` doesn't seem # to be available return f = self.vfs.get_file_for_uri(uri) if ('w' not in mode and 'a' not in mode): if self.fs_exists(uri) is None: return None try: raw = _GioFileAdapter(f, mode) if 'b' in mode: return raw return _GioUTF8FileAdapter(raw) except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError("fs_open({}, mode={}): {}".format( uri, mode, str(exc) )) def fs_exists(self, url): if not GLIB_AVAILABLE: return None try: f = self.vfs.get_file_for_uri(url) if not f.query_exists(): # this file does not exist for us, but it does not mean # another implementation of the plugin interface 'fs' # cannot handle it return None return True except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_listdir(self, url): if not GLIB_AVAILABLE: return None try: f = self.vfs.get_file_for_uri(url) if not f.query_exists(): return None children = f.enumerate_children( Gio.FILE_ATTRIBUTE_STANDARD_NAME, Gio.FileQueryInfoFlags.NONE, None ) for child in children: child = f.get_child(child.get_name()) yield child.get_uri() except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_rename(self, old_url, new_url): try: old = self.vfs.get_file_for_uri(old_url) new = self.vfs.get_file_for_uri(new_url) assert not old.equal(new) if not old.query_exists(): return None old.move(new, Gio.FileCopyFlags.NONE) return True except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_unlink(self, url, trash=True, **kwargs): try: f = self.vfs.get_file_for_uri(url) if not f.query_exists(): return None LOGGER.info("Deleting %s (trash=%s) ...", url, trash) if not trash: deleted = f.delete() if not deleted: raise IOError("Failed to delete %s" % url) return None deleted = False try: deleted = f.trash() if not deleted: LOGGER.warning( "Failed to trash %s. Will try to delete it instead", url ) except Exception as exc: LOGGER.warning("Failed to trash %s. Will try to delete it" " instead", url, exc_info=exc) if deleted and self.fs_exists(url) is not None: deleted = False # WORKAROUND(Jflesch): It seems in Flatpak, f.trash() # returns True when it actually does nothing. LOGGER.warning( "trash(%s) returned True but file wasn't trashed." " Will try to deleting it instead", f.get_uri() ) if not deleted: try: deleted = f.delete() except Exception as exc: LOGGER.warning("Failed to deleted %s", url, exc_info=exc) if not deleted: raise IOError("Failed to delete %s" % url) return True except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_rm_rf(self, url, trash=True, **kwargs): if self.fs_exists(url) is None: return None try: LOGGER.info("Deleting %s ...", url) f = self.vfs.get_file_for_uri(url) deleted = False if trash: try: deleted = f.trash() if not deleted: LOGGER.warning( "Failed to trash %s." " Will try to delete it instead", url ) except Exception as exc: LOGGER.warning( "Failed to trash %s (trash()=%s)." " Will try to delete it instead", url, trash, exc_info=exc ) if deleted and self.fs_exists(url) is not None: deleted = False # WORKAROUND(Jflesch): It seems in Flatpak, f.trash() # returns True when it actually does nothing. LOGGER.warning( "trash(%s) returned True but file wasn't trashed." " Will try to deleting it instead", url ) if not deleted: self._rm_rf(f) LOGGER.info("%s deleted", url) return True except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def _rm_rf(self, gfile): try: to_delete = [ f for f in self._recurse( gfile, dir_included=True, follow_symlinks=False ) ] # make sure to delete the parent directory last: to_delete.sort(reverse=True, key=lambda f: f.get_uri()) for f in to_delete: if not f.delete(): raise IOError("Failed to delete %s" % f.get_uri()) except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_get_mtime(self, url): try: f = self.vfs.get_file_for_uri(url) if not f.query_exists(): raise IOError("File {} does not exist".format(str(url))) if os.name == "nt": # WORKAROUND(Jflesch): # On Windows+MSYS2, it seems Gio.File.query_info() # return always 0 for Gio.FILE_ATTRIBUTE_TIME_CHANGED. path = self.fs_unsafe(url) return int(os.stat(path).st_mtime) fi = f.query_info( Gio.FILE_ATTRIBUTE_TIME_CHANGED, Gio.FileQueryInfoFlags.NONE ) r = fi.get_attribute_uint64(Gio.FILE_ATTRIBUTE_TIME_CHANGED) if int(r) != 0: return r except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) def fs_getsize(self, url): try: f = self.vfs.get_file_for_uri(url) fi = f.query_info( Gio.FILE_ATTRIBUTE_STANDARD_SIZE, Gio.FileQueryInfoFlags.NONE ) return fi.get_attribute_uint64(Gio.FILE_ATTRIBUTE_STANDARD_SIZE) except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_isdir(self, url): if not GLIB_AVAILABLE: return None try: f = self.vfs.get_file_for_uri(url) if not f.query_exists(): return None fi = f.query_info( Gio.FILE_ATTRIBUTE_STANDARD_TYPE, Gio.FileQueryInfoFlags.NONE ) if fi.get_file_type() == Gio.FileType.DIRECTORY: return True return None except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def fs_copy(self, old_url, new_url): try: old = self.vfs.get_file_for_uri(old_url) new = self.vfs.get_file_for_uri(new_url) if new.query_exists(): new.delete() old.copy(new, Gio.FileCopyFlags.ALL_METADATA) return new_url except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) return None def fs_mkdir_p(self, url): if not GLIB_AVAILABLE: return None try: f = self.vfs.get_file_for_uri(url) if not f.query_exists(): if os.name == "nt": # WORKAROUND(Jflesch): On Windows+MSYS2, # Gio.File.make_directory_with_parents() raises # a Gio.GError "Unsupported operation" (bug ?) path = self.fs_unsafe(url) os.makedirs(path, mode=0o700, exist_ok=True) return True f.make_directory_with_parents() except GLib.GError as exc: LOGGER.warning("Gio.GError", exc_info=exc) raise IOError("fs_mkdir_p({}): {}".format(url, str(exc))) return True def _recurse(self, parent, dir_included=False, follow_symlinks=True): """ Yield all the children (depth first), but not the parent. """ try: children = parent.enumerate_children( ( Gio.FILE_ATTRIBUTE_STANDARD_NAME + "," + Gio.FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ), Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, None ) except GLib.GError: # assumes it's a file and not a directory yield parent return for child in children: name = child.get_name() if not follow_symlinks: is_symlink = child.has_attribute("standard::is-symlink") is_symlink = is_symlink and child.get_is_symlink() if is_symlink: yield parent.get_child(name) continue child = parent.get_child(name) try: for sub in self._recurse( child, dir_included=dir_included, follow_symlinks=follow_symlinks): yield sub except GLib.GError: yield child if dir_included: yield parent def fs_recurse(self, parent_uri, dir_included=False): parent = self.vfs.get_file_for_uri(parent_uri) for f in self._recurse(parent, dir_included): yield f.get_uri() def fs_hide(self, uri): if os.name != 'nt': LOGGER.warning("fs_hide('%s') can only works on Windows", uri) return None filepath = self.fs_unsafe(uri) LOGGER.info("Hiding file: {}".format(filepath)) ret = ctypes.windll.kernel32.SetFileAttributesW( filepath, 0x02 # hidden ) if not ret: raise ctypes.WinError() return True def fs_get_mime(self, uri): if os.name == 'nt': # WORKAROUND(Jflesch): # Gio.File.query_info().get_content_type() returns crap on Windows # (for instance '.pdf' instead of 'application/pdf'). return None gfile = self.vfs.get_file_for_uri(uri) info = gfile.query_info( "standard::content-type", Gio.FileQueryInfoFlags.NONE ) return info.get_content_type() def fs_mktemp(self, prefix=None, suffix=None, mode='w+b', **kwargs): if 'b' not in mode: tmp = tempfile.NamedTemporaryFile( prefix=prefix, suffix=suffix, delete=False, mode=mode, encoding='utf-8' ) else: tmp = tempfile.NamedTemporaryFile( prefix=prefix, suffix=suffix, delete=False, mode=mode ) self.tmp_files.add(tmp.name) return (self.fs_safe(tmp.name), tmp) def fs_iswritable(self, url): try: f = self.vfs.get_file_for_uri(url) fi = f.query_info( Gio.FILE_ATTRIBUTE_ACCESS_CAN_WRITE, Gio.FileQueryInfoFlags.NONE ) return fi.get_attribute_boolean( Gio.FILE_ATTRIBUTE_ACCESS_CAN_WRITE ) except GLib.GError as exc: LOGGER.warning("Gio.Gerror", exc_info=exc) raise IOError(str(exc)) def on_quit(self): for tmp_file in self.tmp_files: try: os.unlink(tmp_file) except FileNotFoundError: pass paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/gesture/000077500000000000000000000000001456262201400252165ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/gesture/__init__.py000066400000000000000000000000001456262201400273150ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/gesture/autoscrolling.py000066400000000000000000000103721456262201400304600ustar00rootroot00000000000000""" Scrolling with the middle mouse button. Useful for: - smoother scrolling - horizontal scrolling: the horizontal scrollbar is blocked by the half-transparent lower toolbar """ import logging import openpaperwork_core import openpaperwork_gtk.deps GI_AVAILABLE = False GTK_AVAILABLE = False try: import gi GI_AVAILABLE = True except (ImportError, ValueError): pass if GI_AVAILABLE: try: gi.require_version('Gdk', '3.0') from gi.repository import Gdk GTK_AVAILABLE = True except (ImportError, ValueError): pass LOGGER = logging.getLogger(__name__) class AutoScrollingHandler(object): def __init__(self, core, scrollview): self.core = core self.refcount = 0 self.mouse_start_position = (0, 0) # relative to the screen self.mouse_position = (0, 0) # relative to the screen self.cursors = { 'inactive': None, 'active': None, } try: display = scrollview.get_display() self.cursors['active'] = Gdk.Cursor.new_for_display( display, Gdk.CursorType.TCROSS ) except TypeError: # may not work with pure-Wayland systems pass self.scrollview = scrollview scrollview.add_events( Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.POINTER_MOTION_MASK ) self.button_press_id = scrollview.connect( "button-press-event", self._on_button_press ) self.button_release_id = scrollview.connect( "button-release-event", self._on_button_release ) self.motion_notify_id = scrollview.connect( "motion-notify-event", self._on_mouse_motion ) def disable(self): self.scrollview.disconnect(self.button_press_id) self.scrollview.disconnect(self.button_release_id) self.scrollview.disconnect(self.motion_notify_id) def _on_tick(self): if self.mouse_start_position is None: self.refcount -= 1 return hdiff = (self.mouse_position[0] - self.mouse_start_position[0]) / 5 vdiff = (self.mouse_position[1] - self.mouse_start_position[1]) / 5 hadj = self.scrollview.get_hadjustment() vadj = self.scrollview.get_vadjustment() hval = hadj.get_value() + hdiff hval = max(hval, hadj.get_lower()) hval = min(hval, hadj.get_upper()) hadj.set_value(hval) vval = vadj.get_value() + vdiff vval = max(vval, vadj.get_lower()) vval = min(vval, vadj.get_upper()) vadj.set_value(vval) self.core.call_one("mainloop_schedule", self._on_tick, delay_s=0.1) def _on_button_press(self, scrollview, event): if event.button != 2: return LOGGER.info("Starting autoscrolling") self.mouse_start_position = (event.x_root, event.y_root) self.mouse_position = (event.x_root, event.y_root) if self.refcount <= 0: self.core.call_one("mainloop_schedule", self._on_tick, delay_s=0.1) self.refcount += 1 self.scrollview.get_window().set_cursor(self.cursors['active']) def _on_button_release(self, scrollview, event): if event.button != 2: return LOGGER.info("Ending autoscrolling") self.mouse_start_position = None self.scrollview.get_window().set_cursor(self.cursors['inactive']) def _on_mouse_motion(self, scrollview, event): if self.mouse_start_position is None: return self.mouse_position = (event.x_root, event.y_root) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'gtk_gesture_autoscrolling', ] def get_deps(self): return [] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def gesture_enable_autoscrolling(self, scrollview): LOGGER.info("Enabling autoscrolling on %s", scrollview) try: return AutoScrollingHandler(self.core, scrollview) except TypeError as exc: # may happen with Wayland LOGGER.error("Failed to switch mouse cursor", exc_info=exc) return None paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/gtk_init.py000066400000000000000000000061041456262201400257230ustar00rootroot00000000000000import logging GI_AVAILABLE = False GTK_AVAILABLE = False try: import gi from gi.repository import Gio from gi.repository import GLib GI_AVAILABLE = True except (ValueError, ImportError): pass if GI_AVAILABLE: try: gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): pass import openpaperwork_core # noqa: E402 import openpaperwork_core.deps # noqa: E402 from . import deps # noqa: E402 LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.activated = False self.app = None def get_interfaces(self): return [ 'chkdeps', 'gtk_init', ] def init(self, core): super().init(core) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) out['gtk'].update(deps.GTK) def gtk_init(self, main_func, *args): if hasattr(GLib, 'set_application_name'): GLib.set_application_name("Paperwork") GLib.set_prgname("work.openpaper.Paperwork") self.app = Gtk.Application( application_id="work.openpaper.Paperwork", flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE | Gio.ApplicationFlags.HANDLES_OPEN ) self.app.connect("handle-local-options", main_func, *args) self.app.connect("activate", self._on_activate) self.app.connect("open", self._on_open) Gtk.Application.set_default(self.app) self.app.register() # self.app.run(in_args) self.app.run() def on_quit(self): if self.app is not None: self.app.quit() def gtk_get_app(self): return self.app # called when paperwork is launched without a file to import as argument. # when a second instance of paperwork is run, this is called in the main # instance instead. def _on_activate(self, _app): if not self.activated: self.activated = True self.core.call_all("on_gtk_initialized") LOGGER.info("Ready") self.core.call_one("mainloop", halt_on_uncaught_exception=False) LOGGER.info("Quitting") self.core.call_all("config_save") self.core.call_all("on_quit") else: # a second instance was activated, we are the main one self.core.call_all("mainwindow_present") # called when paperwork is launched with files to import as argument. # when a second instance of paperwork is run, this is called in the main # instance instead. def _on_open(self, app, files, _count, _hint): uris = [file.get_uri() for file in files] self.core.call_one( "mainloop_schedule", self.core.call_all, "gtk_doc_import", uris ) # either start paperwork if we are the main instance, or focus it if # this signal is raised remotely self._on_activate(app) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/l10n/000077500000000000000000000000001456262201400243125ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/l10n/__init__.py000066400000000000000000000007351456262201400264300ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['l10n_init'] def get_deps(self): return [ { 'interface': 'l10n', 'defaults': ['openpaperwork_core.l10n.python'], }, ] def init(self, core): super().init(core) self.core.call_all( "l10n_load", "openpaperwork_gtk.l10n", "openpaperwork_gtk" ) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/mainloop/000077500000000000000000000000001456262201400253565ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/mainloop/__init__.py000066400000000000000000000000001456262201400274550ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/mainloop/glib.py000066400000000000000000000153651456262201400266570ustar00rootroot00000000000000import collections import faulthandler import logging import sys import threading try: from gi.repository import GLib GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 """ A main loop based on GLib's mainloop. See `openpaperwork_core.mainloop.asyncio` for doc. """ def __init__(self): super().__init__() self.halt_on_uncaught_exception = True self.log_uncaught = True self.loop = None self.loop_ident = None self.halt_cause = None self.task_count = 0 self.lock = threading.RLock() self.active_tasks = collections.defaultdict(lambda: 0) def get_interfaces(self): return [ "chkdeps", "mainloop", ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def _check_mainloop_instantiated(self): if self.loop is None: self.loop = GLib.MainLoop.new(None, False) # !running def mainloop(self, halt_on_uncaught_exception=True, log_uncaught=True): if not GLIB_AVAILABLE: return None self._check_mainloop_instantiated() self.log_uncaught = log_uncaught self.halt_on_uncaught_exception = halt_on_uncaught_exception self.loop_ident = threading.current_thread().ident self.mainloop_schedule(self.core.call_all, "on_mainloop_start") try: self.loop.run() except Exception: faulthandler.dump_traceback() raise finally: self.loop_ident = None self.core.call_all("on_mainloop_quit") if self.halt_cause is not None: halt_cause = self.halt_cause self.halt_cause = None LOGGER.error("Main loop stopped because %s", str(halt_cause)) raise halt_cause self.loop = None return True def mainloop_get_thread_id(self): return self.loop_ident def mainloop_quit_graceful(self): self.mainloop_schedule(self._mainloop_quit_graceful) return True def _mainloop_quit_graceful(self): quit_now = True with self.lock: # keep in mind this function is in a task too if self.task_count > 1: quit_now = False LOGGER.info( "Quit graceful: Remaining tasks: %d", self.task_count - 1 ) for (k, v) in self.active_tasks.items(): LOGGER.info("Quit graceful: Remaining: %s = %d", k, v) if not quit_now: self.mainloop_schedule( self._mainloop_quit_graceful, delay_s=0.2 ) return LOGGER.info("Quit graceful: Quitting") self.mainloop_quit_now() with self.lock: self.task_count = 1 # we are actually the one task still running self.active_tasks = collections.defaultdict(lambda: 0) def mainloop_quit_now(self): if self.loop is None: return None with self.lock: self.loop.quit() self.loop = None self.task_count = 0 self.active_tasks = collections.defaultdict(lambda: 0) def mainloop_ref(self, obj): with self.lock: self.task_count += 1 self.active_tasks[str(obj)] += 1 def mainloop_unref(self, obj): with self.lock: self.task_count -= 1 assert self.task_count >= 0 try: s = str(obj) self.active_tasks[s] -= 1 if self.active_tasks[s] <= 0: self.active_tasks.pop(s) except KeyError: pass def mainloop_schedule(self, func, *args, delay_s=0, **kwargs): if not GLIB_AVAILABLE: return None assert hasattr(func, '__call__') with self.lock: self._check_mainloop_instantiated() self.task_count += 1 self.active_tasks[str(func)] += 1 def decorator(func, args): (args, kwargs) = args try: func(*args, **kwargs) except Exception as exc: exc_info = sys.exc_info() if self.halt_on_uncaught_exception: LOGGER.error( "Main loop: uncaught exception (%s) ! Quitting", func, exc_info=exc ) self.halt_cause = exc self.mainloop_quit_now() elif self.log_uncaught: LOGGER.error( "Main loop: uncaught exception (%s) !", func, exc_info=exc ) self.core.call_all( "mainloop_schedule", self.core.call_all, "on_uncaught_exception", exc_info ) finally: with self.lock: self.task_count -= 1 try: s = str(func) self.active_tasks[s] -= 1 if self.active_tasks[s] <= 0: self.active_tasks.pop(s) except KeyError: pass return False args = (args, kwargs) if delay_s is None: GLib.idle_add(decorator, func, args, priority=GLib.PRIORITY_LOW) else: GLib.timeout_add(delay_s * 1000, decorator, func, args) return True def mainloop_execute(self, func, *args, **kwargs): current = threading.current_thread().ident # XXX(Jflesch): # if self.loop_ident is None, it means the mainloop hasn't been started # yet --> we cannot run the function on the mainloop anyway, so # we assume we are on the same thread that will later run the main # loop. if self.loop_ident is None or current == self.loop_ident: return func(*args, **kwargs) event = threading.Event() out = None exc = None def get_result(): nonlocal out nonlocal exc try: out = func(*args, **kwargs) except Exception as e: LOGGER.warning( "mainloop_execute exception (func=%s, args=%s, kwargs=%s)", func, args, kwargs, exc_info=e ) exc = e event.set() self.mainloop_schedule(get_result) event.wait() if exc is not None: raise exc return out paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/pixbuf/000077500000000000000000000000001456262201400250355ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/pixbuf/__init__.py000066400000000000000000000000001456262201400271340ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/pixbuf/pillow.py000066400000000000000000000042511456262201400267170ustar00rootroot00000000000000import io import logging import PIL import PIL.Image try: from gi.repository import GLib GLIB_AVAILABLE = True except (ValueError, ImportError): GLIB_AVAILABLE = False try: import gi gi.require_version('GdkPixbuf', '2.0') from gi.repository import GdkPixbuf GDK_PIXBUF_AVAILABLE = True except (ValueError, ImportError): GDK_PIXBUF_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from .. import deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'pixbuf_pillow', ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GDK_PIXBUF_AVAILABLE: out['gdk_pixbuf'].update(deps.GDK_PIXBUF) @staticmethod def pixbuf_to_pillow(pixbuf): (width, height) = (pixbuf.get_width(), pixbuf.get_height()) pixels = pixbuf.get_pixels() colors = "RGB" if (width * height * 4 == len(pixels)): colors = "RGBA" return PIL.Image.frombytes( colors, (width, height), pixbuf.get_pixels() ) def pillow_to_pixbuf(self, img): """ Convert an image object to a GDK pixbuf """ if not GDK_PIXBUF_AVAILABLE: return None if img is None: return None img = img.convert("RGB") if hasattr(GdkPixbuf.Pixbuf, 'new_from_bytes'): data = GLib.Bytes.new(img.tobytes()) (width, height) = img.size return GdkPixbuf.Pixbuf.new_from_bytes( data, GdkPixbuf.Colorspace.RGB, False, 8, width, height, width * 3 ) file_desc = io.BytesIO() try: img.save(file_desc, "ppm") contents = file_desc.getvalue() finally: file_desc.close() loader = GdkPixbuf.PixbufLoader.new_with_type("pnm") try: loader.write(contents) pixbuf = loader.get_pixbuf() finally: loader.close() return pixbuf paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/resources.py000066400000000000000000000202021456262201400261200ustar00rootroot00000000000000import gettext import logging import os import re if os.name == "nt": import webbrowser import xml.etree.ElementTree LOGGER = logging.getLogger(__name__) GI_AVAILABLE = False GDK_PIXBUF_AVAILABLE = False GTK_AVAILABLE = False HDY_AVAILABLE = False try: import gi GI_AVAILABLE = True except (ValueError, ImportError) as exc: LOGGER.error("Failed to load Gobject-Introspection", exc_info=exc) if GI_AVAILABLE: try: gi.require_version('GdkPixbuf', '2.0') from gi.repository import GdkPixbuf GDK_PIXBUF_AVAILABLE = True except (ValueError, ImportError) as exc: LOGGER.error("Failed to load GDK-Pixbuf", exc_info=exc) try: gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') from gi.repository import Gdk from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError) as exc: LOGGER.error("Failed to load Gtk", exc_info=exc) try: gi.require_version('Handy', '1') from gi.repository import Handy HDY_AVAILABLE = True except (ImportError, ValueError) as exc: LOGGER.error("Failed to load Handy", exc_info=exc) import openpaperwork_core # noqa: E402 import openpaperwork_core.deps # noqa: E402 from . import deps # noqa: E402 class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.cache = {} def get_interfaces(self): return [ 'chkdeps', 'gtk_resources' ] def get_deps(self): return [ { 'interface': 'l10n_init', 'defaults': [ 'openpaperwork_core.l10n.python', 'openpaperwork_gtk.l10n', ], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, ] def init(self, core): super().init(core) if not HDY_AVAILABLE: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to initalize Libhandy") return Handy.init() def chkdeps(self, out: dict): if not GDK_PIXBUF_AVAILABLE: out['gdk_pixbuf'].update(deps.GDK_PIXBUF) if not GTK_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) out['gtk'].update(deps.GTK) if not HDY_AVAILABLE: out['hdy'].update(deps.HDY) @staticmethod def _translate_xml(xml_str): root = xml.etree.ElementTree.fromstring(xml_str) translation_domain = "openpaperwork_gtk" if 'domain' in root.attrib: translation_domain = root.attrib['domain'] labels = root.findall('.//*[@translatable="yes"]') for label in labels: label.text = gettext.dgettext(translation_domain, label.text) out = xml.etree.ElementTree.tostring(root, encoding='UTF-8') return out.decode('utf-8') @staticmethod def _windows_fix_widgets(widget_tree): def open_uri(uri): # XXX(Jflesch): Seems we get some garbarge in the URI sometimes ?! uri = uri.replace("\u202f", "") LOGGER.info("Opening URI [%s]", uri) webbrowser.open(uri) for obj in widget_tree.get_objects(): if isinstance(obj, Gtk.LinkButton): obj.connect( "clicked", lambda button: open_uri(button.get_uri()) ) elif (isinstance(obj, Gtk.AboutDialog) or isinstance(obj, Gtk.Label)): obj.connect( "activate-link", lambda widget, uri: open_uri(uri) ) def gtk_load_widget_tree(self, pkg, filename): """ Load a .glade file Arguments: pkg -- Python package name filename -- css file name to load Returns: GTK Widget Tree """ if not GTK_AVAILABLE or not HDY_AVAILABLE: LOGGER.error( "gtk_load_widget_tree(): GTK|Libhandy is not available" ) return None LOGGER.debug("Loading GTK widgets from %s:%s", pkg, filename) screen = Gdk.Screen.get_default() if screen is None: LOGGER.warning( "Cannot load widget tree: Gdk.Screen.get_default()" " returned None" ) return None k = (pkg, filename) if k not in self.cache: try: filepath = self.core.call_success( "resources_get_file", pkg, filename ) with self.core.call_success("fs_open", filepath, 'r') as fd: xml = fd.read() if os.name == "nt": # WORKAROUND(Jflesch): # for some reason, # Gtk.Builder.new_from_file()/new_from_string doesn't # translate on Windows xml = self._translate_xml(xml) self.cache[k] = xml except Exception: LOGGER.error( "Failed to load widget tree from file %s:%s", pkg, filename ) raise try: content = self.cache[k] widget_tree = Gtk.Builder.new_from_string(content, -1) if os.name == "nt": self._windows_fix_widgets(widget_tree) return widget_tree except Exception: LOGGER.error("Failed to load widget tree %s:%s", pkg, filename) raise def gtk_load_css(self, pkg, filename): """ Load a .css file Arguments: pkg -- Python package name filename -- css file name to load. """ if not GTK_AVAILABLE or not HDY_AVAILABLE: LOGGER.error("gtk_load_css(): GTK|Libhandy is not available") return None LOGGER.debug("Loading CSS from %s:%s", pkg, filename) k = (pkg, filename) if k not in self.cache: try: filepath = self.core.call_success( "resources_get_file", pkg, filename ) with self.core.call_success("fs_open", filepath, 'rb') as fd: self.cache[k] = fd.read() except Exception: LOGGER.error("Failed to load CSS file %s:%s", pkg, filename) raise try: content = self.cache[k] css_provider = Gtk.CssProvider() css_provider.load_from_data(content) screen = Gdk.Screen.get_default() if screen is None: LOGGER.warning( "Cannot apply CSS: Gdk.Screen.get_default()" " returned None" ) return None Gtk.StyleContext.add_provider_for_screen( Gdk.Screen.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION ) except Exception: LOGGER.error("Failed to load CSS %s:%s", pkg, filename) raise return True def gtk_load_pixbuf(self, pkg, filename): filepath = self.core.call_success("resources_get_file", pkg, filename) if filepath is None: return None filepath = self.core.call_success("fs_unsafe", filepath) return GdkPixbuf.Pixbuf.new_from_file(filepath) def gtk_fix_headerbar_buttons(self, headerbar): settings = Gtk.Settings.get_default() default_layout = settings.get_property("gtk-decoration-layout") default_layout = re.split("[:,]", default_layout) # disable the elements that are not enabled globally layout = headerbar.get_decoration_layout().split(":", 1) layout = [side.split(",") for side in layout] layout = ":".join([ ",".join([ element for element in side if element in default_layout ]) for side in layout ]) headerbar.set_decoration_layout(layout) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/screenshots.py000066400000000000000000000222151456262201400264540ustar00rootroot00000000000000import logging import math try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): CAIRO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from . import _ LOGGER = logging.getLogger(__name__) SCREENSHOT_DATE_FORMAT = "%Y%m%d_%H%M_%S" MAX_DAYS = 31 MAX_UNCAUGHT_EXCEPTION_SCREENSHOTS = 5 class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.windows = [] self.archiver = None self.nb_uncaught = 0 def get_interfaces(self): return [ 'bug_report_attachments', 'chkdeps', 'gtk_window_listener', 'uncaught_exception_listener', 'screenshot', ] def get_deps(self): return [ { 'interface': 'file_archives', 'defaults': ['openpaperwork_core.archives'], }, { 'interface': 'fs', 'defaults': [ 'openpaperwork_core.fs.memory', 'openpaperwork_core.fs.python', ], }, { 'interface': 'uncaught_exception', 'defaults': ['openpaperwork_core.uncaught_exception'], }, ] def init(self, core): super().init(core) self.archiver = self.core.call_success( "file_archive_get", storage_name="screenshots", file_extension="png" ) def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'] = openpaperwork_core.deps.CAIRO def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _snap_screenshot(self, fd): image_size = (0, 0) for window in self.windows: if not window.is_drawable(): LOGGER.warning("Window %s cannot be screenshoted", window) else: LOGGER.info("Screenshoting window %s", window) for window in self.windows: if not window.is_drawable(): continue alloc = window.get_allocation() image_size = ( max(image_size[0], alloc.width), image_size[1] + alloc.height ) surface = cairo.ImageSurface(cairo.FORMAT_RGB24, *image_size) cairo_ctx = cairo.Context(surface) for window in self.windows: if not window.is_drawable(): continue alloc = window.get_allocation() window.draw(cairo_ctx) cairo_ctx.translate(0, alloc.height) surface.write_to_png(fd) def screenshot_snap_all_promise(self, temporary=True, name="screenshots"): if temporary: (file_url, fd) = self.core.call_success( "fs_mktemp", prefix="{}_".format(name), suffix=".png", mode="wb", on_disk=True ) else: file_url = self.archiver.get_new(name=name) fd = self.core.call_success("fs_open", file_url, mode='wb') promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_screenshot_before",) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_one, "mainloop_execute", self._snap_screenshot, fd ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.catch(lambda *args, **kwargs: fd.close()) promise = promise.then(fd.close) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_all, "on_screenshot_after") promise = promise.then(lambda *args, **kwargs: None) return (file_url, promise) def screenshot_snap_widget( self, gtk_widget, out_file_url, margins=(20, 20, 20, 20), highlight=(0.67, 0.80, 0.93) ): assert out_file_url.endswith(".png") if not gtk_widget.is_drawable() or not gtk_widget.get_visible(): LOGGER.warning( "%s is not visible. Cannot screenshot", gtk_widget ) return None # find the GTK window of the widget window = gtk_widget.get_toplevel() if not window.is_drawable() or not window.get_visible(): LOGGER.warning( "%s's window is not visible. Cannot screenshot", gtk_widget ) return None # take a screenshot of the whole window win_alloc = window.get_allocation() win_surface = cairo.ImageSurface( cairo.FORMAT_RGB24, win_alloc.width, win_alloc.height ) cairo_ctx = cairo.Context(win_surface) window.draw(cairo_ctx) widget_position = gtk_widget.translate_coordinates(window, 0, 0) widget_alloc = gtk_widget.get_allocation() # highlight if highlight is not None: cairo_ctx.save() try: cairo_ctx.new_path() border_width = 5 margin = 5 cairo_ctx.set_source_rgba(*highlight, 0.85) cairo_ctx.set_line_width(border_width) center = ( widget_position[0] + (widget_alloc.width / 2), widget_position[1] + (widget_alloc.height / 2), ) cairo_ctx.translate(*center) radius = ( (widget_alloc.width / 2) + (widget_alloc.height / 2) + margin ) if widget_alloc.width > widget_alloc.height: scale = (1.0, widget_alloc.height / widget_alloc.width) else: scale = (widget_alloc.width / widget_alloc.height, 1.0) cairo_ctx.scale(*scale) cairo_ctx.arc(0, 0, radius, 0, 2 * math.pi) cairo_ctx.scale(1.0 / scale[0], 1.0 / scale[1]) cairo_ctx.stroke() finally: cairo_ctx.restore() # check it's visible enough start = ( max(0, widget_position[0]), max(0, widget_position[1]), ) size = ( min(win_alloc.width - start[0], widget_alloc.width), min(win_alloc.height - start[1], widget_alloc.height), ) if size[0] <= 15 or size[1] <= 15: LOGGER.warning( "%s is folded/hidden. Cannot screenshot", gtk_widget ) return None # then cut it start = ( max(0, widget_position[0] - margins[0]), max(0, widget_position[1] - margins[1]) ) size = ( min( win_alloc.width - start[0], widget_alloc.width + margins[0] + margins[2] ), min( win_alloc.height - start[1], widget_alloc.height + margins[1] + margins[3], ) ) LOGGER.info( "Making screenshot of %s: %s (%s, %s)", gtk_widget, out_file_url, start, size ) surface = cairo.ImageSurface(cairo.FORMAT_RGB24, *size) cairo_ctx = cairo.Context(surface) cairo_ctx.translate(-start[0], -start[1]) cairo_ctx.set_source_surface(win_surface) cairo_ctx.paint() with self.core.call_success("fs_open", out_file_url, "wb") as fd: surface.write_to_png(fd) return True def on_uncaught_exception(self, exc_info): self.nb_uncaught += 1 if self.nb_uncaught > MAX_UNCAUGHT_EXCEPTION_SCREENSHOTS: # limit the number of screenshots in one session. return LOGGER.info("Uncaught exception. Taking screenshots") (_, promise) = self.screenshot_snap_all_promise( name="uncaught_exception_screenshots" ) promise.schedule() def bug_report_get_attachments(self, out: dict): for (date, file_url) in self.archiver.get_archived(): out[file_url] = { 'date': date, 'include_by_default': False, 'file_type': _("App. screenshots"), 'file_url': file_url, 'file_size': self.core.call_success("fs_getsize", file_url), } out['screenshot_now'] = { 'include_by_default': False, 'date': None, 'file_type': _("App. screenshots"), 'file_url': _("Select to generate"), 'file_size': 0, } def _update_attachment(self, file_url, *args): self.core.call_all( "bug_report_update_attachment", "screenshot_now", { "file_url": file_url, "file_size": self.core.call_success("fs_getsize", file_url), }, *args ) def on_bug_report_attachment_selected(self, attachment_id, *args): if attachment_id != 'screenshot_now': return (file_url, promise) = self.screenshot_snap_all_promise(temporary=True) promise = promise.then(self._update_attachment, file_url, *args) promise.schedule() paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/000077500000000000000000000000001456262201400274345ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/__init__.py000066400000000000000000000055761456262201400315620ustar00rootroot00000000000000import logging import traceback try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core from .. import deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.nb_dialogs = 3 self.windows = [] self.visible = False def get_interfaces(self): return [ 'chkdeps', 'gtk_uncaught_exception', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'gtk_bug_report_dialog', 'defaults': ['openpaperwork_gtk.bug_report'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'uncaught_exception', 'defaults': ['openpaperwork_core.uncaught_exception'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def on_uncaught_exception(self, exc_info): if exc_info[-1] is None: LOGGER.warning("No stacktrace. Won't display error dialog") return if self.visible: LOGGER.warning( "Error dialog currently displayed. Won't display another one" ) return if self.nb_dialogs <= 0: LOGGER.warning( "Too many error dialogs displayed. Won't display them anymore" ) return LOGGER.info("Uncaught exception. Showing error dialog") content = traceback.format_exception(*exc_info) content = ''.join(content) widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.uncaught_exception", "uncaught_exception.glade" ) if widget_tree is None: LOGGER.warning("Failed to load widget tree") return widget_tree.get_object("error").set_text(content, -1) dialog = widget_tree.get_object("dialog") if len(self.windows) > 0: dialog.set_transient_for(self.windows[-1]) dialog.connect("response", self._on_response) dialog.show_all() self.visible = True self.nb_dialogs -= 1 def _on_response(self, dialog, response_id): LOGGER.info("Response: %s", response_id) dialog.destroy() self.visible = False if response_id != Gtk.ResponseType.ACCEPT: return self.core.call_all("open_bug_report") paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/uncaught_exception/uncaught_exception.glade000066400000000000000000000162561456262201400343400ustar00rootroot00000000000000 False Unexpected Error 640 320 dialog False vertical 2 False end Report True True True True True 0 gtk-ok True True True True True True 1 False False 0 True False True False 20 20 20 20 gtk-dialog-error 6 False True 0 True False 20 20 20 20 vertical 20 True False An unexpected error occured. 0 False True 0 True True in True True False char 5 5 5 5 error True True 1 True True 1 True True 1 button1 button2 paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/000077500000000000000000000000001456262201400307565ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks/__init__.py000066400000000000000000000126311456262201400330720ustar00rootroot00000000000000import logging import sys import threading import time import openpaperwork_core import openpaperwork_core.deps # TODO(Jflesch): refactor with openpaperwork_gtk.widgets.progress LOGGER = logging.getLogger(__name__) TIME_BETWEEN_UPDATES = 0.3 # Tasks are often chained one after the other. We don't want the button/popover # to disappear and reappear continually. So when a task ends, we # give them some extra time to live. # STAY_ALIVES is the number of updates we wait before hiding them. STAY_ALIVES = int(2.0 / TIME_BETWEEN_UPDATES) class ProgressDialog: def __init__(self, plugin): LOGGER.info("Opening dialog 'wait for background tasks'") self.plugin = plugin self.core = plugin.core self.progress_widget_trees = {} self.dialog_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.wait_for_background_tasks", "wait_for_background_tasks.glade" ) if self.dialog_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.dialog_tree.get_object("dialog").connect( "response", self._suicide ) self.dialog_tree.get_object("dialog").show_all() # A thread updates the widgets every 300ms. We don't update them # each time on_progress() is called to not degrade performances self.thread = threading.Thread(target=self._thread) self.thread.daemon = True self.thread.start() def _thread(self): self.stay_alives = STAY_ALIVES while self.thread is not None: time.sleep(TIME_BETWEEN_UPDATES) self.core.call_one( "mainloop_execute", self._upd_progress_widgets ) def _upd_progress_widgets(self): with self.plugin.lock: progresses = self.plugin.progresses.items() self.plugin.progresses = {} for (upd_type, (progress, description)) in progresses: self._upd_progress_widget( upd_type, progress, description ) if len(self.progress_widget_trees) > 0: self.stay_alives = STAY_ALIVES return if self.stay_alives > 0: self.stay_alives -= 1 return self.thread = None self.dialog_tree.get_object("dialog").destroy() def _upd_progress_widget(self, upd_type, progress, description): box = self.dialog_tree.get_object("task_list") if progress >= 1.0: # deletion of progress if upd_type not in self.progress_widget_trees: return LOGGER.info("Task '%s' has ended", upd_type) widget_tree = self.progress_widget_trees.pop(upd_type) details = widget_tree.get_object("progress_bar") box.remove(details) details.unparent() LOGGER.info( "Task '%s' has ended (%d remaining)", upd_type, len(self.progress_widget_trees) ) return if upd_type not in self.progress_widget_trees: # creation of progress widget LOGGER.info( "Task '%s' has started (%d already active)", upd_type, len(self.progress_widget_trees) ) # reuse the progress widgets from # openpaperwork_gtk.widgets.progress widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.widgets.progress", "progress_details.glade" ) box.add(widget_tree.get_object("progress_bar")) self.progress_widget_trees[upd_type] = widget_tree else: widget_tree = self.progress_widget_trees[upd_type] # update of progress progress_bar = widget_tree.get_object("progress_bar") progress_bar.set_fraction(progress) progress_bar.set_text(description if description is not None else "") def _suicide(self, *args, **kwargs): LOGGER.warning("User requested a forced quit") # In theory, the following shouldn't hurt any more than a power outtage # and is really reliable way to end Paperwork sys.exit(0) class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.dialog = None self.progresses = {} self.lock = threading.Lock() def get_interfaces(self): return [ 'progress_listener', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, ] def _mainloop_quit_graceful(self): self.dialog = ProgressDialog(self) def mainloop_quit_graceful(self): self.core.call_one("mainloop_execute", self._mainloop_quit_graceful) def on_progress(self, upd_type, progress, description=None): with self.lock: if progress > 1.0: LOGGER.warning( "Invalid progression (%f) for [%s]", progress, upd_type ) progress = 1.0 self.progresses[upd_type] = (progress, description) wait_for_background_tasks.glade000066400000000000000000000073511456262201400371210ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/wait_for_background_tasks False Background tasks 640 320 dialog False False vertical 2 False end Force quit now True True True True True 0 False False 0 True False vertical True False 20 20 Some background tasks are still running. Please wait ... center False True 0 True False vertical 20 True True True 1 True True 1 force_quit_button paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/000077500000000000000000000000001456262201400252065ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/__init__.py000066400000000000000000000000001456262201400273050ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/calendar/000077500000000000000000000000001456262201400267575ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/calendar/__init__.py000066400000000000000000000036641456262201400311010ustar00rootroot00000000000000import datetime import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'gtk_calendar_popover', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def gtk_calendar_add_popover(self, gtk_entry): widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.widgets.calendar", "calendar.glade" ) widget_tree.get_object("calendar_popover").set_relative_to( gtk_entry ) gtk_entry.connect( "icon-release", self._open_calendar, widget_tree ) widget_tree.get_object("calendar_calendar").connect( "day-selected-double-click", self._update_date, gtk_entry, widget_tree ) def _open_calendar( self, gtk_entry, icon_pos, event, widget_tree): date = self.core.call_success( "i18n_parse_date_short", gtk_entry.get_text() ) if date is None: return widget_tree.get_object("calendar_calendar").select_month( date.month - 1, date.year ) widget_tree.get_object("calendar_calendar").select_day( date.day ) widget_tree.get_object("calendar_popover").set_visible(True) def _update_date(self, gtk_calendar, gtk_entry, widget_tree): date = widget_tree.get_object("calendar_calendar").get_date() date = datetime.datetime(year=date[0], month=date[1] + 1, day=date[2]) date = self.core.call_success("i18n_date_short", date) gtk_entry.set_text(date) widget_tree.get_object("calendar_popover").set_visible(False) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/calendar/calendar.glade000066400000000000000000000005301456262201400315240ustar00rootroot00000000000000 True paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/000077500000000000000000000000001456262201400264725ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/__init__.py000066400000000000000000000000001456262201400305710ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/charts/lines.py000066400000000000000000000632561456262201400301720ustar00rootroot00000000000000import collections import logging import math import random import statistics import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps from openpaperwork_gtk import _ GI_AVAILABLE = False GTK_AVAILABLE = False PANGO_AVAILABLE = False try: import gi from gi.repository import GObject GI_AVAILABLE = True except (ImportError, ValueError): pass if GI_AVAILABLE: try: gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') from gi.repository import Gdk from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): pass try: gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango from gi.repository import PangoCairo PANGO_AVAILABLE = True except (ImportError, ValueError): pass LOGGER = logging.getLogger(__name__) SUM_COLOR = (0, 0, 0) class Schema(object): def __init__( self, column_value_id_idx, column_line_id_idx, column_axis_x_values_idx, column_axis_x_names_idx, column_axis_y_values_idx, column_axis_y_names_idx, highlight_x_range=(math.inf, -math.inf)): self.column_value_id_idx = column_value_id_idx self.column_line_id_idx = column_line_id_idx self.column_axis_x_values_idx = column_axis_x_values_idx self.column_axis_x_names_idx = column_axis_x_names_idx self.column_axis_y_values_idx = column_axis_y_values_idx self.column_axis_y_names_idx = column_axis_y_names_idx self.highlight_x_range = highlight_x_range class ColorGenerator(object): def __init__(self): self.colors = [] self.color_idx = -1 def reset(self): self.color_idx = -1 def __next__(self): self.color_idx += 1 if self.color_idx >= len(self.colors): self.colors.append(( random.randint(0, 0xFF) / 0xFF, random.randint(0, 0xFF) / 0xFF, random.randint(0, 0xFF) / 0xFF, )) return self.colors[self.color_idx] class DrawContext(object): """ Custom drawing context around cairo context, so we can change the scale without changing the line width. """ def __init__(self, ctx): self.ctx = ctx def get_cairo(self): if hasattr(self.ctx, 'get_cairo'): return self.ctx.get_cairo() return self.ctx def translate_pt(self, pt_x, pt_y): return (pt_x, pt_y) def untranslate_pt(self, pt_x, pt_y): return (pt_x, pt_y) def distance(self, pt_a_x, pt_a_y, pt_b_x, pt_b_y): d_x = abs(pt_a_x - pt_b_x) d_y = abs(pt_a_y - pt_b_y) return (d_x ** 2) + (d_y ** 2) def arc(self, x, y, radius, angle1, angle2): self.ctx.arc(x, y, radius, angle1, angle2) def save(self): self.ctx.save() def restore(self): self.ctx.restore() def set_source_rgb(self, r, g, b): self.ctx.set_source_rgb(r, g, b) def set_source_rgba(self, r, g, b, a): self.ctx.set_source_rgba(r, g, b, a) def set_line_width(self, line_width): self.ctx.set_line_width(line_width) def move_to(self, pt_x, pt_y): self.ctx.move_to(pt_x, pt_y) def line_to(self, pt_x, pt_y): self.ctx.line_to(pt_x, pt_y) def rectangle(self, x, y, w, h): self.ctx.rectangle(x, y, w, h) def stroke(self): self.ctx.stroke() def fill(self): self.ctx.fill() def translate(self, x, y): return DrawContextTranslated(self, x, y) def scale(self, x, y): return DrawContextScaled(self, x, y) class DrawContextTranslated(DrawContext): def __init__(self, ctx, translation_x, translation_y): super().__init__(ctx) self.x = translation_x self.y = translation_y def translate_pt(self, pt_x, pt_y): (pt_x, pt_y) = (pt_x + self.x, pt_y + self.y) return self.ctx.translate_pt(pt_x, pt_y) def untranslate_pt(self, pt_x, pt_y): (pt_x, pt_y) = self.ctx.untranslate_pt(pt_x, pt_y) return (pt_x - self.x, pt_y - self.y) def distance( self, pt_untranslated_x, pt_untranslated_y, pt_translated_x, pt_translated_y): pt_a_x = pt_untranslated_x + self.x pt_a_y = pt_untranslated_y + self.y return self.ctx.distance( pt_a_x, pt_a_y, pt_translated_x, pt_translated_y, ) def arc(self, x, y, radius, angle1, angle2): self.ctx.arc(x + self.x, y + self.y, radius, angle1, angle2) def move_to(self, pt_x, pt_y): self.ctx.move_to(pt_x + self.x, pt_y + self.y) def line_to(self, pt_x, pt_y): self.ctx.line_to(pt_x + self.x, pt_y + self.y) def rectangle(self, x, y, w, h): self.ctx.rectangle(x + self.x, y + self.y, w, h) class DrawContextScaled(DrawContext): def __init__(self, ctx, scale_x, scale_y): super().__init__(ctx) self.x = scale_x self.y = scale_y def translate_pt(self, pt_x, pt_y): (pt_x, pt_y) = (pt_x * self.x, pt_y * self.y) return self.ctx.translate_pt(pt_x, pt_y) def untranslate_pt(self, pt_x, pt_y): (pt_x, pt_y) = self.ctx.untranslate_pt(pt_x, pt_y) return (pt_x / self.x, pt_y / self.y) def distance( self, pt_unscaled_x, pt_unscaled_y, pt_scaled_x, pt_scaled_y): pt_a_x = pt_unscaled_x * self.x pt_a_y = pt_unscaled_y * self.y return self.ctx.distance( pt_a_x, pt_a_y, pt_scaled_x, pt_scaled_y, ) def arc(self, x, y, radius, angle1, angle2): self.ctx.arc(x * self.x, y * self.y, radius, angle1, angle2) def move_to(self, pt_x, pt_y): self.ctx.move_to(pt_x * self.x, pt_y * self.y) def line_to(self, pt_x, pt_y): self.ctx.line_to(pt_x * self.x, pt_y * self.y) def rectangle(self, x, y, w, h): self.ctx.rectangle(x * self.x, y * self.y, w * self.x, h * self.y) class Point(object): RADIUS = 2 LABEL_LINE_HEIGHT = 14 def __init__(self, liststore_idx, x, y, label_x, label_y, color): self.liststore_idx = liststore_idx self.x = x self.y = y self.label_x = label_x self.label_y = label_y self.color = color def copy(self): return Point( self.liststore_idx, self.x, self.y, self.label_x, self.label_y, self.color ) def __lt__(self, other): if self.x < other.x: return True if self.y < other.y: return True return False @staticmethod def merge(pts): merged_pt = pts[0].copy() merged_pt.y = statistics.mean([p.y for p in pts]) merged_pt.label_y = "\n".join([p.label_y for p in pts]) return merged_pt @staticmethod def merge_same_x(all_pts): pack = [] last_x = None pts = [] for pt in all_pts: if last_x is None: pack.append(pt) last_x = pt.x elif last_x == pt.x: pack.append(pt) else: pts.append(Point.merge(pack)) last_x = pt.x pack = [pt] if len(pack) > 0: pts.append(Point.merge(pack)) return pts @staticmethod def from_liststore_line(liststore_idx, line, schema, color): return Point( liststore_idx, line[schema.column_axis_x_values_idx], line[schema.column_axis_y_values_idx], line[schema.column_axis_x_names_idx], line[schema.column_axis_y_names_idx], color ) def draw_label_x(self, widget_size, draw_ctx): height = (self.label_x.count("\n") + 1) * self.LABEL_LINE_HEIGHT cairo_ctx = draw_ctx.get_cairo() x = draw_ctx.translate_pt(self.x, widget_size[1] - self.y)[0] widget_size = draw_ctx.translate_pt(widget_size[0], widget_size[1]) layout = PangoCairo.create_layout(cairo_ctx) layout.set_text(self.label_x, -1) txt_size = layout.get_size() if 0 in txt_size: return cairo_ctx.save() try: txt_scale = height / txt_size[1] txt_width = txt_size[0] * txt_scale if x <= widget_size[0] / 2: x += 5 else: x -= (txt_width + 10) cairo_ctx.set_source_rgb(0, 0, 0) cairo_ctx.translate(x, 0) cairo_ctx.scale(txt_scale * Pango.SCALE, txt_scale * Pango.SCALE) PangoCairo.update_layout(cairo_ctx, layout) PangoCairo.show_layout(cairo_ctx, layout) finally: cairo_ctx.restore() def draw_label_y(self, widget_size, draw_ctx): height = (self.label_y.count("\n") + 1) * self.LABEL_LINE_HEIGHT cairo_ctx = draw_ctx.get_cairo() y = draw_ctx.translate_pt(self.x, widget_size[1] - self.y)[1] widget_size = draw_ctx.translate_pt(widget_size[0], widget_size[1]) layout = PangoCairo.create_layout(cairo_ctx) layout.set_text(self.label_y, -1) txt_size = layout.get_size() if 0 in txt_size: return cairo_ctx.save() try: txt_scale = height / txt_size[1] if y <= widget_size[1] / 2: y += 2 else: y -= (height + 2) cairo_ctx.set_source_rgb(0, 0, 0) cairo_ctx.translate(0, y) cairo_ctx.scale(txt_scale * Pango.SCALE, txt_scale * Pango.SCALE) PangoCairo.update_layout(cairo_ctx, layout) PangoCairo.show_layout(cairo_ctx, layout) finally: cairo_ctx.restore() def draw_highlight(self, widget_size, draw_ctx): draw_ctx.set_source_rgb(0.57, 0.7, 0.837) draw_ctx.set_line_width(1) # TODO(Jflesch): we should use the real widget size, and not # the widget size relative to point (0, 0) draw_ctx.move_to(-widget_size[0] * 2, widget_size[1] - self.y) draw_ctx.line_to(widget_size[0] * 2, widget_size[1] - self.y) draw_ctx.stroke() # TODO(Jflesch): we should use the real widget size, and not # the widget size relative to point (0, 0) draw_ctx.move_to(self.x, -widget_size[1] * 2) draw_ctx.line_to(self.x, widget_size[1] * 2) draw_ctx.stroke() self.draw_label_x(widget_size, draw_ctx) self.draw_label_y(widget_size, draw_ctx) def distance(self, widget_size, draw_ctx, x, y): return draw_ctx.distance(self.x, widget_size[1] - self.y, x, y) class Line(object): LEGEND_CIRCLE_RADIUS = 8 LEGEND_LINE_HEIGHT = 16 LEGEND_SPACING = 8 def __init__(self, line_name, points, color, line_width=1.0): self.line_name = line_name self.points = points self.points.sort(key=lambda pt: pt.x) self.color = color self.minmax = ((math.inf, 0), (0, 0)) self.line_width = line_width for pt in points: self.minmax = ( ( min(self.minmax[0][0], pt.x), max(self.minmax[0][1], pt.x), ), ( min(self.minmax[1][0], pt.y), max(self.minmax[1][1], pt.y), ), ) @staticmethod def from_liststore_lines(line_name, liststore_lines, schema, color): pts = [ Point.from_liststore_line(liststore_idx, line, schema, color) for (liststore_idx, line) in liststore_lines ] pts = Point.merge_same_x(pts) return Line(line_name, pts, color) @staticmethod def make_line_sum(other_lines): pts = [] for line in other_lines: pts += [ (line.line_name, pt.copy()) for pt in line.points ] pts.sort(key=lambda pt: pt[1].x) total_txt = _("Total: {}") last_y = collections.defaultdict(lambda: 0) for (line_name, pt) in pts: last_y[line_name] = pt.y pt.y = sum(last_y.values()) pt.label_y = total_txt.format(pt.y) pts = [pt for (line_name, pt) in pts] pts = Point.merge_same_x(pts) return Line(_("Total"), pts, SUM_COLOR, 2.0) def draw_chart(self, widget_size, draw_ctx): draw_ctx.save() try: draw_ctx.set_line_width(self.line_width) draw_ctx.set_source_rgb(*self.color) for (idx, pt) in enumerate(self.points): if idx == 0: draw_ctx.move_to(pt.x, widget_size[1] - pt.y) else: draw_ctx.line_to(pt.x, widget_size[1] - pt.y) draw_ctx.stroke() finally: draw_ctx.restore() def draw_legend(self, widget_size, cairo_ctx, x, y): layout = PangoCairo.create_layout(cairo_ctx) layout.set_text(self.line_name, -1) txt_size = layout.get_size() if 0 in txt_size: return (x, y) cairo_ctx.save() try: txt_scale = self.LEGEND_LINE_HEIGHT / txt_size[1] txt_width = txt_size[0] * txt_scale width = txt_width width += 2 * self.LEGEND_CIRCLE_RADIUS width += 2 * self.LEGEND_SPACING if x + width >= widget_size[0]: y += self.LEGEND_LINE_HEIGHT + self.LEGEND_SPACING x = 0 cairo_ctx.set_source_rgb(*self.color) cairo_ctx.arc( x + self.LEGEND_CIRCLE_RADIUS, y + self.LEGEND_CIRCLE_RADIUS, self.LEGEND_CIRCLE_RADIUS, 0, math.pi * 2 ) cairo_ctx.fill() x += (2 * self.LEGEND_CIRCLE_RADIUS) + self.LEGEND_SPACING cairo_ctx.set_source_rgb(0.0, 0.0, 0.0) cairo_ctx.translate(x, y) cairo_ctx.scale(txt_scale * Pango.SCALE, txt_scale * Pango.SCALE) PangoCairo.update_layout(cairo_ctx, layout) PangoCairo.show_layout(cairo_ctx, layout) x += txt_width + self.LEGEND_SPACING finally: cairo_ctx.restore() return (x, y) def get_closest_point(self, widget_size, draw_ctx, x, y): return min(( (point.distance(widget_size, draw_ctx, x, y), point) for point in self.points ), default=None) class Lines(object): HIGHLIGHT_COLOR = (0.5, 0.5, 0.5, 0.5) def __init__(self, schema, liststore, color_generator): self.schema = schema self.liststore = liststore self.color_generator = color_generator self.active_point = None self.lines = [] self.minmax = ((math.inf, 0), (0, 0),) def reset(self): self.lines = [] def reload(self): self.minmax = ((math.inf, 0), (0, 0),) self.color_generator.reset() lines = collections.defaultdict(list) for (liststore_idx, line) in enumerate(self.liststore): line_name = line[self.schema.column_line_id_idx] lines[line_name].append((liststore_idx, line)) self.lines = [ Line.from_liststore_lines( k, v, self.schema, next(self.color_generator) ) for (k, v) in lines.items() ] if len(self.lines) > 1: self.lines = [Line.make_line_sum(self.lines)] + self.lines for line in self.lines: self.minmax = ( ( min(self.minmax[0][0], line.minmax[0][0]), max(self.minmax[0][1], line.minmax[0][1]), ), ( min(self.minmax[1][0], line.minmax[1][0]), max(self.minmax[1][1], line.minmax[1][1]), ), ) def draw_chart_highlight(self, widget_size, draw_ctx): x_range = self.schema.highlight_x_range if x_range[1] <= x_range[0]: return if x_range[0] is -math.inf: x_range = (self.minmax[0][0], self.x_range[1]) if x_range[1] is math.inf: x_range = (x_range[0], self.minmax[0][1]) x_range = ( ( x_range[0] - self.minmax[0][0] ) / ( self.minmax[0][1] - self.minmax[0][0] ), ( x_range[1] - self.minmax[0][0] ) / ( self.minmax[0][1] - self.minmax[0][0] ), ) x_range = (x_range[0] * widget_size[0], x_range[1] * widget_size[0]) draw_ctx.save() try: draw_ctx.set_source_rgba(*self.HIGHLIGHT_COLOR) draw_ctx.rectangle( int(x_range[0]) + 1, 0, x_range[1] - x_range[0], widget_size[1] ) draw_ctx.fill() finally: draw_ctx.restore() def draw_chart(self, widget_size, draw_ctx): w = self.minmax[0][1] - self.minmax[0][0] h = self.minmax[1][1] - self.minmax[1][0] if w == 0 or h == 0: return draw_ctx = draw_ctx.scale(widget_size[0] / w, widget_size[1] / h) widget_size = (w, h) self.draw_chart_highlight(widget_size, draw_ctx) draw_ctx = draw_ctx.translate( -self.minmax[0][0], min(0, self.minmax[1][0]) ) widget_size = (widget_size[0] + self.minmax[0][0], widget_size[1]) draw_ctx.save() try: for line in self.lines: line.draw_chart(widget_size, draw_ctx) finally: draw_ctx.restore() if self.active_point is not None: self.active_point.draw_highlight(widget_size, draw_ctx) def draw_legend(self, widget_size, cairo_ctx): x = 0 y = 0 for line in self.lines: (x, y) = line.draw_legend(widget_size, cairo_ctx, x, y) return (x, y) def get_closest_point(self, widget_size, draw_ctx, x, y): w = self.minmax[0][1] - self.minmax[0][0] h = self.minmax[1][1] - self.minmax[1][0] if w == 0 or h == 0: return None draw_ctx = draw_ctx.scale(widget_size[0] / w, widget_size[1] / h) widget_size = (w, h) draw_ctx = draw_ctx.translate( -self.minmax[0][0], min(0, self.minmax[1][0]) ) widget_size = (widget_size[0] - self.minmax[0][0], widget_size[1]) return min(( line.get_closest_point(widget_size, draw_ctx, x, y) for line in self.lines ), default=None) class ChartDrawer(object): MARGIN = 5 def __init__(self, core, schema, liststore, color_generator): self.core = core self.lines = Lines(schema, liststore, color_generator) self.chart_widget = Gtk.DrawingArea.new() self.chart_widget.set_size_request(-1, 200) self.chart_widget.set_visible(True) self.chart_widget.connect("draw", self.draw_chart) self.chart_widget.connect("realize", self._on_chart_realized) self.chart_widget.connect("motion-notify-event", self._on_mouse_motion) self.legend_widget = Gtk.DrawingArea.new() self.legend_widget.set_visible(True) self.legend_widget.connect("draw", self.draw_legend) liststore.connect("row-changed", self.reload) liststore.connect("row-deleted", self.reload) liststore.connect("row-inserted", self.reload) liststore.connect("rows-reordered", self.reload) self._on_chart_realized() self.has_changed = False self.reload_planned = False self._reload() def _on_chart_realized(self, *args, **kwargs): mask = Gdk.EventMask.POINTER_MOTION_MASK self.chart_widget.add_events(mask) if self.chart_widget.get_window() is not None: self.chart_widget.get_window().set_events( self.chart_widget.get_window().get_events() | mask ) def reload(self, *args, **kwargs): self.lines.reset() self.chart_widget.queue_draw() self.legend_widget.queue_draw() if self.reload_planned: self.has_changed = True else: self.has_changed = False self.reload_planned = True promise = openpaperwork_core.promise.DelayPromise( self.core, delay_s=0.25 ) promise.then(self._reload) promise.schedule() def _reload(self): self.reload_planned = False if self.has_changed: self.reload() return self.lines.reload() self.chart_widget.queue_draw() self.legend_widget.queue_draw() def _on_mouse_motion(self, widget, event): draw_ctx = DrawContext(None) draw_ctx = draw_ctx.translate(self.MARGIN, self.MARGIN) widget_size = ( widget.get_allocated_width() - (2 * self.MARGIN), widget.get_allocated_height() - (2 * self.MARGIN), ) r = self.lines.get_closest_point( widget_size, draw_ctx, event.x, event.y ) if r is None: self.lines.active_point = None return (dist, point) = r if self.lines.active_point is not point: self.lines.active_point = point self.chart_widget.queue_draw() def draw_chart(self, widget, cairo_ctx): widget_size = ( widget.get_allocated_width() - (2 * self.MARGIN), widget.get_allocated_height() - (2 * self.MARGIN), ) draw_ctx = DrawContext(cairo_ctx) draw_ctx = draw_ctx.translate(self.MARGIN, self.MARGIN) self.lines.draw_chart(widget_size, draw_ctx) def draw_legend(self, widget, cairo_ctx): widget_size = ( widget.get_allocated_width() - (2 * self.MARGIN), widget.get_allocated_height() - (2 * self.MARGIN), ) cairo_ctx.translate(self.MARGIN, self.MARGIN) (x, y) = self.lines.draw_legend(widget_size, cairo_ctx) if x > 0: # the y we got is relative to the top of the current line. # the height is starting at the bottom of the current line. y += Line.LEGEND_SPACING + Line.LEGEND_LINE_HEIGHT if y + self.MARGIN != widget_size[1]: widget.set_size_request(-1, y + self.MARGIN) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.color_generator = ColorGenerator() def get_interfaces(self): return [ 'chkdeps', 'gtk_charts_lines', ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) if not PANGO_AVAILABLE: out['pango'].update(openpaperwork_core.deps.PANGO) def gtk_charts_lines_get( self, liststore, *args, **kwargs): """ Return a Gtk.Widget showing the specified line chart. Can display multiple lines on single chart. In the model, each row is a value (x, y) for a given line. Arguments: - model: Gtk.ListStore to use as model - column_value_id_idx: column in the model that contains the value IDs. - column_line_id_idx: column that contains the name of the line to which this value belongs. - column_axis_x_values_idx: column that contains the values for the X axis. Must contain integers, floats or doubles. - column_axis_x_names_idx: column that contains the names corresponding to the values on the X axis. Must be strings. - column_axis_y_values_idx: column that contains the values for the Y axis. Must contain integers, floats or doubles. - column_axis_y_names_idx: column that contains the names corresponding toi the values on the Y axis. Must be strings """ schema = Schema(*args, **kwargs) return ChartDrawer(self.core, schema, liststore, self.color_generator) if __name__ == "__main__": model = Gtk.ListStore.new(( GObject.TYPE_STRING, # value id GObject.TYPE_STRING, # line id GObject.TYPE_INT64, # value X GObject.TYPE_INT64, # value Y GObject.TYPE_STRING, # name X GObject.TYPE_STRING, # name Y )) model_content = ( ("value A55", "line A", 5, 5, "A5", "A5"), ("value B55", "line B", 5, 5, "B5", "B5"), ("value A67", "line A", 6, 7, "A6", "A7"), ("value B66", "line B", 6, 6, "B6", "B6"), # graph must support having many values at the same position in X ("value A77", "line A", 7, 7, "A7", "A7"), ("value A73", "line A", 7, 3, "A7", "A3"), ("value A79", "line A", 7, 9, "A7", "A9"), ("value B79", "line B", 7, 9, "B7", "B9"), ("value A83", "line A", 8, 3, "A8", "A3"), ("value B88", "line B", 8, 8, "B8", "B8"), ("value A97", "line A", 9, 7, "A9", "A7"), ("value B95", "line B", 9, 5, "B9", "B5"), ("value A10-5", "line A", 10, -5, "A10", "A-5"), ("value B910", "line B", 9, 10, "B9", "B10"), ) model.clear() for line in model_content: model.append(line) core = openpaperwork_core.Core() core.load("openpaperwork_gtk.widgets.charts.lines") core.init() chart_lines = core.call_success( "gtk_charts_lines_get", model, column_value_id_idx=0, column_line_id_idx=1, column_axis_x_values_idx=2, column_axis_y_values_idx=3, column_axis_x_names_idx=4, column_axis_y_names_idx=5 ) window = Gtk.Window() window.set_default_size(600, 600) window.add(chart_lines.chart_widget) window.show_all() window_legend = Gtk.Window() window_legend.set_default_size(100, 100) window_legend.add(chart_lines.legend_widget) window_legend.show_all() Gtk.main() paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/000077500000000000000000000000001456262201400270525ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/__init__.py000066400000000000000000000214371456262201400311720ustar00rootroot00000000000000import logging import math import threading import time import openpaperwork_core import openpaperwork_core.deps try: import gi gi.require_version('Gdk', '3.0') from gi.repository import Gdk GDK_AVAILABLE = True except (ImportError, ValueError): GDK_AVAILABLE = False NEEDS_ATTENTION_TIMEOUT = 2.1 LOGGER = logging.getLogger(__name__) TIME_BETWEEN_UPDATES = 0.3 # Tasks are often chained one after the other. We don't want the button/popover # to disappear and reappear continually. So when a task ends, we # give them some extra time to live. # STAY_ALIVES is the number of updates we wait before hiding them. STAY_ALIVES = int(2.0 / TIME_BETWEEN_UPDATES) class ProgressWidget(object): def __init__(self, core): self.core = core self.widget = None # A thread updates the widgets every 300ms. We don't update them # each time on_progress() is called to not degrade performanes self.thread = None self.lock = threading.RLock() self.progress_widget_trees = {} # self.progresses is only used to transmit new progress updates # to the thread self.progresses = {} self.button_widget_tree = None self.details_widget_tree = None self.stay_alives = STAY_ALIVES self.button_widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.widgets.progress", "progress_button.glade" ) if self.button_widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.details_widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.widgets.progress", "progress_popover.glade" ) if self.details_widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.button_widget_tree.get_object("progress_button").set_popover( self.details_widget_tree.get_object( "progresses_popover" ) ) self.button_widget_tree.get_object("progress_icon").connect( "draw", self._on_icon_draw ) self.widget = self.button_widget_tree.get_object("progress_revealer") def needs_attention(self): button = self.button_widget_tree.get_object("progress_button") button.get_style_context().add_class("progress_button_needs_attention") self.core.call_success( "mainloop_schedule", button.get_style_context().remove_class, "progress_button_needs_attention", delay_s=NEEDS_ATTENTION_TIMEOUT ) def _thread(self): self.stay_alives = STAY_ALIVES while self.thread is not None: time.sleep(TIME_BETWEEN_UPDATES) self.core.call_one( "mainloop_execute", self._upd_progress_widgets ) def _upd_progress_widgets(self): with self.lock: for (upd_type, (progress, description)) in self.progresses.items(): self._upd_progress_widget( upd_type, progress, description ) self.progresses = {} if len(self.progress_widget_trees) > 0: self.stay_alives = STAY_ALIVES return if self.stay_alives > 0: self.stay_alives -= 1 return self.button_widget_tree.get_object( "progress_revealer" ).set_reveal_child(False) self.thread = None return def _upd_progress_widget(self, upd_type, progress, description): if progress >= 1.0: # deletion of progress if upd_type not in self.progress_widget_trees: LOGGER.warning( "Got 2 notifications of end of task for '%s'", upd_type ) return LOGGER.info("Task '%s' has ended", upd_type) widget_tree = self.progress_widget_trees.pop(upd_type) box = self.details_widget_tree.get_object( "progresses_box" ) details = widget_tree.get_object("progress_bar") box.remove(details) details.unparent() self.button_widget_tree.get_object("progress_button").queue_draw() self.needs_attention() LOGGER.info( "Task '%s' has ended (%d remaining)", upd_type, len(self.progress_widget_trees) ) return if upd_type not in self.progress_widget_trees: # creation of progress LOGGER.info( "Task '%s' has started (%d already active)", upd_type, len(self.progress_widget_trees) ) widget_tree = self.core.call_success( "gtk_load_widget_tree", "openpaperwork_gtk.widgets.progress", "progress_details.glade" ) box = self.details_widget_tree.get_object( "progresses_box" ) box.add(widget_tree.get_object("progress_bar")) self.progress_widget_trees[upd_type] = widget_tree self.needs_attention() else: widget_tree = self.progress_widget_trees[upd_type] # update of progress progress_bar = widget_tree.get_object("progress_bar") progress_bar.set_fraction(progress) progress_bar.set_text(description if description is not None else "") self.button_widget_tree.get_object("progress_button").queue_draw() self.button_widget_tree.get_object( "progress_revealer" ).set_reveal_child(True) def on_progress(self, upd_type, progress, description=None): with self.lock: if progress > 1.0: LOGGER.warning( "Invalid progression (%f) for [%s]", progress, upd_type ) progress = 1.0 self.progresses[upd_type] = (progress, description) if self.thread is None: self.thread = threading.Thread(target=self._thread) self.thread.daemon = True self.thread.start() def _on_icon_draw(self, drawing_area, cairo_ctx): if len(self.progress_widget_trees) <= 0: ratio = 1.0 else: ratio = sum([ widget_tree.get_object("progress_bar").get_fraction() for widget_tree in self.progress_widget_trees.values() ]) / len(self.progress_widget_trees) # Translated in Python from Nautilus source code # (2020/02/29: src/nautilus-toolbar.c:on_operations_icon_draw()) style_context = drawing_area.get_style_context() foreground = style_context.get_color(drawing_area.get_state_flags()) background = foreground background.alpha *= 0.3 w = drawing_area.get_allocated_width() h = drawing_area.get_allocated_height() Gdk.cairo_set_source_rgba(cairo_ctx, background) cairo_ctx.arc(w / 2.0, h / 2.0, min(w, h) / 2.0, 0, 2 * math.pi) cairo_ctx.fill() cairo_ctx.move_to(w / 2.0, h / 2.0) Gdk.cairo_set_source_rgba(cairo_ctx, foreground) cairo_ctx.arc( w / 2.0, h / 2.0, min(w, h) / 2.0, -math.pi / 2.0, (ratio * 2 * math.pi) - (math.pi / 2.0) ) cairo_ctx.fill() class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widgets = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_progress_widget', 'progress_listener', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, ] def init(self, core): super().init(core) self.core.call_success( "gtk_load_css", "openpaperwork_gtk.widgets.progress", "progress.css" ) def chkdeps(self, out: dict): if not GDK_AVAILABLE: out['gdk'].update(openpaperwork_core.deps.GDK) def gtk_progress_make_widget(self): widget = ProgressWidget(self.core) if widget.widget is not None: # gtk may not be available self.widgets.append(widget) return widget.widget def on_progress(self, upd_type, progress, description=None): for widget in self.widgets: widget.on_progress(upd_type, progress, description) paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress.css000066400000000000000000000013651456262201400314350ustar00rootroot00000000000000/* copied from Nautilus and modified slightly */ @keyframes progress_needs_attention_keyframes { 0% { background-image: linear-gradient( to bottom, #fafafa, #ededed 40%, #e0e0e0 ); border-color: @borders; } 30% { background-image: linear-gradient( to bottom, @theme_base_color, @theme_base_color, @theme_base_color ); border-color: @theme_fg_color; } 90% { background-image: linear-gradient( to bottom, @theme_base_color, @theme_base_color, @theme_base_color ); border-color: @theme_fg_color; } 100% { background-image: linear-gradient( to bottom, #fafafa, #ededed 40%, #e0e0e0 ); border-color: @borders; } } .progress_button_needs_attention { animation: progress_needs_attention_keyframes 2s ease-in-out; } paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_button.glade000066400000000000000000000024721456262201400333140ustar00rootroot00000000000000 True False center center slide-right True True True False Show background tasks 6 16 16 True False center center paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_details.glade000066400000000000000000000012471456262201400334250ustar00rootroot00000000000000 True False center 2 4 True 0.05 True paperwork-2.2.2/openpaperwork-gtk/src/openpaperwork_gtk/widgets/progress/progress_popover.glade000066400000000000000000000011641456262201400334700ustar00rootroot00000000000000 False 500 True False vertical 18 paperwork-2.2.2/openpaperwork-gtk/tests/000077500000000000000000000000001456262201400203525ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/tests/__init__.py000066400000000000000000000000001456262201400224510ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/tests/fs/000077500000000000000000000000001456262201400207625ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/tests/fs/__init__.py000066400000000000000000000000001456262201400230610ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/tests/fs/tests_gio.py000066400000000000000000000034321456262201400233360ustar00rootroot00000000000000import openpaperwork_core.tests.local_file PLUGIN_NAME = "openpaperwork_gtk.fs.gio" class TestSafe(openpaperwork_core.tests.local_file.AbstractTestSafe): def get_plugin_name(self): return PLUGIN_NAME class TestUnsafe(openpaperwork_core.tests.local_file.AbstractTestUnsafe): def get_plugin_name(self): return PLUGIN_NAME class TestOpen(openpaperwork_core.tests.local_file.AbstractTestOpen): def get_plugin_name(self): return PLUGIN_NAME class TestExists(openpaperwork_core.tests.local_file.AbstractTestExists): def get_plugin_name(self): return PLUGIN_NAME class TestListDir(openpaperwork_core.tests.local_file.AbstractTestListDir): def get_plugin_name(self): return PLUGIN_NAME class TestRename(openpaperwork_core.tests.local_file.AbstractTestRename): def get_plugin_name(self): return PLUGIN_NAME class TestUnlink(openpaperwork_core.tests.local_file.AbstractTestUnlink): def get_plugin_name(self): return PLUGIN_NAME class TestGetMtime(openpaperwork_core.tests.local_file.AbstractTestGetMtime): def get_plugin_name(self): return PLUGIN_NAME class TestGetsize(openpaperwork_core.tests.local_file.AbstractTestGetsize): def get_plugin_name(self): return PLUGIN_NAME class TestIsdir(openpaperwork_core.tests.local_file.AbstractTestIsdir): def get_plugin_name(self): return PLUGIN_NAME class TestCopy(openpaperwork_core.tests.local_file.AbstractTestCopy): def get_plugin_name(self): return PLUGIN_NAME class TestMkdirP(openpaperwork_core.tests.local_file.AbstractTestMkdirP): def get_plugin_name(self): return PLUGIN_NAME class TestTemp(openpaperwork_core.tests.local_file.AbstractTestTemp): def get_plugin_name(self): return PLUGIN_NAME paperwork-2.2.2/openpaperwork-gtk/tests/mainloop/000077500000000000000000000000001456262201400221705ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/tests/mainloop/__init__.py000066400000000000000000000000001456262201400242670ustar00rootroot00000000000000paperwork-2.2.2/openpaperwork-gtk/tests/mainloop/tests_gtk.py000066400000000000000000000005431456262201400245530ustar00rootroot00000000000000import openpaperwork_core.mainloop.tests class TestCallback(openpaperwork_core.mainloop.tests.AbstractTestCallback): def get_plugin_name(self): return "openpaperwork_gtk.mainloop.glib" class TestPromise(openpaperwork_core.mainloop.tests.AbstractTestPromise): def get_plugin_name(self): return "openpaperwork_gtk.mainloop.glib" paperwork-2.2.2/paperwork-backend/000077500000000000000000000000001456262201400171305ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/.flake8000066400000000000000000000001131456262201400202760ustar00rootroot00000000000000[flake8] exclude = src/paperwork_backend/_version.py max-line-length = 100 paperwork-2.2.2/paperwork-backend/ChangeLog000066400000000000000000000304161456262201400207060ustar00rootroot000000000000002023/02/13 - 2.2.2: - export: Add export pipe to export to PDF by automatically selecting the original PDF if available or generating one else - docexport PDF: Workaround Cairo bug that causes occasional crashes when exporting to generated PDF. - make it possible to edit help documents: it seems that this is actually often the first thing that people do try in Paperwork. - sklearn: Fix stuck progress bar when switching work directories - model.pdf: tolerate corrupted PDF page mapping. - pagetracker: handle more gracefully invalid documents - model.workdir: ignore files and directory with a name starting with ".". - model.thumbnail: do not crash if a document is corrupted. - model.thumbnail: when computing the size of the thumbnail, make sure neither the width or height ever end up at 0px. - Support exporting corrupted PDFs. Some PDFs may declare more pages than they actually contain. It must not block a mass export. - docexport/pdf: remove old workaround: call to time.sleep() isn't useful anymore 2023/09/17 - 2.2.1: - Add build-system.build-backend to pyproject.toml - datadirhandler: when removing a directory, don't move it to the trash. Instead delete it entirely 2023/09/16 - 2.2.0: - By default, use PNG instead of JPEG (See issue #1021 for rationale). - setup.py has been replaced by pyproject.toml - drop dependency on python-Levenshtein. - model.pdf: Fix: When moving an edited PDF page from one document to another, make sure to export the PDF page as the original image page (paper.X.png) instead of the edited one (paper.X.edited.png). - cairo.pillow: optimization: use cairo.ImageSurface.create_from_data() now that it's available. - beacon: if openpaper.work is unreachable, catch the exception to not bother the user uselessly - guesswork.labels.sklearn: store the model on-disk to reload it more quickly as long as nothing has changed. - Help documents: Help documents are read-only. Therefore if the user tries to add pages to them, redirect the new pages to a new document. - model.thumbnail: handle gracefully corrupted thumbnails. - cairo.pillow: do not assume that on-disk images are RGB/RGBA (they may have been optimized by scripts with 'convert' for instance). - PDF: Handle gracefully UnicodeDecodeError that happen sometimes on Windows. - Handle images too big for pillow as gracefully as possible: do not crash but replace them by a tile with a text explaining the image is too big. - Libinsane: Make it possible to specify custom scan option values (thanks to auriocus on forum.openpaper.work) - PDF: in case a page_map.csv is corrupted, log which one. - PDF: Make the readign of page_map.csv more resilient. - chkworkdir: in case page_map.csv is corrupted, fix the document by deleting the page_map.csv and moving the pages around 2023/01/08 - 2.1.2: - Cairo renderers (Image/PDF): optimisation: add a cache - Cairo image renderer: optimisation: cairo.ImageSurface.create_for_data() has been implemented and can now be used - Cairo renderers: cleanup: Move the blurring code to a dedicated plugin - autoselect_scanner: workaround: instead of looking for scanners when Paperwork starts, look for a scanner if and only if we failed to find the scanner currently defined in Paperwork's configuration. With some Sane backends, it's much safer to not try listing devices when starting. - Fix: TIFF files may have the extension .tiff but also .tif - ignore files at the root of the work directory - libreoffice converter: fix file descriptor leak - guesswork.label.sklearn: fix weird crash based on user logs (original cause is still unclear) - fix test failure with recent pillow (thanks to Guillaume Girol) 2022/01/31 - 2.1.1: - guesswork.label.sklearn: Fix: Handle gracefully documents without text - model.pdf: take into account some PDF may be really really damaged 2021/12/05 - 2.1.0: - Support for all document types supported by LibreOffice (requires LibreOffice to be installed) - Support for password-protected PDF files - Label guessing: replace simplebayes by sklearn (GaussianNB): require more resources but much more accurate - Version data files: If the version changes, rebuild them all - Fix page export: img: do not use page number in file names - Cropping by scanner calibration: Never crop pages that already have text (fix issue where cropping was applied when changing document date / ID) - API: rename transaction methods: add_obj() --> add_doc(), upd_obj() --> upd_doc(), del_obj() --> del_doc(), unchanged_obj() --> unchanged_doc() 2021/05/24 - 2.0.3: - hOCR: fix page_get_text_by_url(): Do not return the hOCR title in the text (it's always "OCR output"). - Image loading (used for file import): file extension check must be case-insensitive (".jpeg" and ".JPEG" must be both accepted) - OCR: Fix: By default, never run OCR on pages that already have text. - Take into account Cairo image size limitations (dimensions can't be higher than 32k). Crop images accordingly if required. - PDF: work around possible weird replies from LibPoppler regarding line/word boxes (avoid useless background exception) - Swedish translations added - Backend: openpaperwork_gtk.fs.gio has been removed from the minimum list of required plugins. fs.python is good enough to load the configuration. - Backend: model.labels: Call to callbacks "on_all_labels_loaded" has been removed. It was redundant with the call to callbacks "on_label_loading_end" 2021/01/01 - 2.0.2: - beacon.sysinfo: report some extra infos to openpaper.work: CPU max frequency, number of CPU cores, amount of memory, version of Python. - add dependency on psutil - PyOCR: Fix for people who seem to have no locale configured (?!) - PDF: Fix: Write page mapping in the order of original page indexes, as expected when we read it back later. (otherwise, we may get weird behaviours) - Labels: When removing labels, don't add extra empty lines 2020/11/15 - 2.0.1: - Model: Fix: When the user move a page, they may actually creating a new document. - Libinsane + bug report: the file to attach to the bug report should be called 'scanner_*.json', not 'statistics_*.json' - Import: Don't use the same name for recursive importer and single importer. - Import: If the single file importer has matched a file to import, make sure the recursive one doesn't match it too. - Windows: poppler.memory: work around suspected memory leak regarding Gio.MemoryInput.new_from_data() - When thumbnail are deleted by user action, never send them to trash, really delete them instead. - Include tests in Pypi package (thanks to Elliott Sales de Andrade) 2020/10/17 - 2.0: - Full rewrite - Use of plugin system of openpaperwork_core to split features - PDF can be edited - Pages can be reinitialized to their initial states (reset) - Multiple languages can be used for OCR - Automated tests have been added - Features that could be reused in other applications have been move to openpaperwork_core and openpaperwork_gtk - Thumbnails are slightly smaller (they will be resized automatically) 2019/12/20 - 1.3.1: - Backend: Check if thumbnail file is writable before updating it (thanks to Gregor Godbersen) - Backend: Make indexation more resilient to errors (corrupted PDFs, etc). - Backend: chkdeps: look for Libinsane (no known package yet) 2019/08/17 - 1.3.0: - PDF export: PDFs can now be regenerated when exporting. Regenerated versions will include words from the OCR, but some metadata may be lost. - Optimization: Speed up conversions from PIL image to GdkPixbuf (used for export previews and thumbnail display) - Disable the use of a dedicated process for index operations: it prevents debugging - New dependency: Do not use platform.dist() or platform.linux_distribution() anymore: It's deprecated and will be removed in Python 3.8. Use instead the module 'distro'. - paperwork-shell: Add name and label arguments to command 'import' (thanks to Stéphane Brunner) - Backend: Fix importing PNG files with transparency (thanks to Balló György) - Fix warnings related to regexes escaping + various other cleanups (thanks to Elliott Sales de Andrade) 2018/03/01 - 1.2.4: - Import: Remove ambiguity: Importers designed for import of directory will not try to import individual files. They will just let the importers designed for importing single file take care of it. - Label guessing: Fix the way bayesian filters are updated (will trigger an index rebuild). - paperwork-shell/labels/guessing: return scores as well as labels (useful for testing/debuging) - Optim: PDF: Keep in memory the page sizes. It's an information very often requested when rendering and it cannot change with PDFs 2018/02/01 - 1.2.3: - Windows: Fix labels handling: Fix CSV file reading - Fix global deletion of a label - Flatpak: Fix deletion of documents - PDF: Fix file descriptor leak - Flatpak: Fix support on English systems 2017/11/14 - 1.2.2: - PDF: Fix thumbnail sizes. Incorrect thumbnails will be automatically regenerated 2017/08/26 - 1.2.1: - paperwork-shell: improve help string of 'paperwork-shell chkdeps' - Fix label deletion / renaming - Windows: Fix FS.safe() when used for PDF import - Windows: Fix FS.unsafe() (used for PDF export) 2017/07/11 - 1.2.0: - API: remove methods doc.drop_cache() and page.drop_cache() - API: docsearch: add method close() - paperwork-shell: Use JSON format for the output (except for 'paperwork-shell dump') - Use GIO functions instead of Python functions (open(), read(), close(), etc) - Use URIs instead of Unix file paths (file:///...) - Index is now managed in a separate process (avoid Python GIL locking + UI freezes) - Import: Make it possible to import image folder - Importers: provide a list of supported file formats (mime types) - Import: To figure out a file type, look at the file extensions but also the mime type in case the extension is not set - Import: Make the importers able to handle multiple Files/URIs instead of just one - paperwork-shell import: Run OCR on imported pages that have no words - paperwork-shell: add command 'ocr' - Configuration: [Global]:workdirectory is now an URI encoded in base64 (base64 encoding was required due to limitations of Python's ConfigParser) - DocSearch: When unable to open the index, destroy it and rebuild it from scratch - Add a new document type: ExternalPdfDoc: Used to display PDF that are outside of the work directory (for instance application help manual) - Configuration setting [OCR]:lang is now managed by the backend instead of the frontend 2017/02/09 - 1.1.2: - PDF: When PdfDoc.drop_cache() is called, make sure *all* the references to the Poppler objects are dropped, including those to the pages of the document 2017/02/05 - 1.1.1: - No change. Version created only to match Paperwork-gui version. 2017/01/30 - 1.1.0: - Add methods doc.has_ocr() and page.has_ocr() indicating if OCR has already been run on a given doc/page or not yet. Used in GUI for the option "Redo OCR on all documents" as it must act only on documents where OCR has already been done in the past (ie not PDF with text included) - Optim: Provides a method page.get_image() returning an already resized Pillow image (PDF rendering optimisation) - Export: Report progression - Optim: PDF thumbnail rendering: Keep a cached version of the first page only. The other pages can be rendered on the fly - Fix: Label directory name use base64 encoding, and this encoding can result in strings containing '/'. Those characters must be replaced (by '_') - Fix: util/find_language(): If the system locale is not set properly, pycountry may raise UnicodeDecodeError. - paperwork-shell: Add commands 'search', 'dump', 'switch_workdir', 'rescan', 'show', 'import', 'delete_doc', 'guess_labels', 'add_label', 'remove_label', 'rename' - Import: When importing a single PDF, don't import it if it was already previously imported - Import: Provides detailed information and statistics regarding what has been imported (return value of Importer.import_doc() has changed) 1.0.6: - No change. Version created only to match Paperwork-gui version. 1.0.5: - Doc deletion: Drop cache and file descripts *before* deleting document (optional on GNU/Linux, but required on Windows) 1.0.4: - Windows: Fix image import 1.0.3: - Windows: Fix import/export 1.0.2: - No change. Version created only to match Paperwork-gui version. 1.0.1: - util/find_language(): fix pycountry db lookup - Windows: hide ~/.config instead of ~/.config/paperwork.conf paperwork-2.2.2/paperwork-backend/LICENSE000066400000000000000000001045051456262201400201420ustar00rootroot00000000000000 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. {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year} {name of author} 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: {project} Copyright (C) {year} {fullname} 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 . paperwork-2.2.2/paperwork-backend/MANIFEST.in000066400000000000000000000001441456262201400206650ustar00rootroot00000000000000recursive-include src *.py *.mo *.json recursive-include tests * include *.markdown include LICENSE paperwork-2.2.2/paperwork-backend/Makefile000066400000000000000000000047001456262201400205710ustar00rootroot00000000000000PYTHON ?= python3 PIP_DEPS ?= build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: l10n_compile ${PYTHON} ./setup.py build build_c: doc: install_py $(MAKE) -C doc html doc/_build/html/index.html: doc upload_doc: doc/_build/html/index.html cd .. && ./ci/deliver_doc.sh ${CURDIR}/doc/_build/html paperwork_backend data: $(MAKE) -C $(CURDIR)/src/paperwork_backend/authors data check: if ! hash flake8 ; then PIP_DEPS=[lint] $(MAKE) install_py ; fi flake8 --append-config $(CURDIR)/.flake8 $(CURDIR)/src/paperwork_backend test: if ! hash pytest ; then PIP_DEPS=[dev] $(MAKE) install_py ; fi python3 -m pytest -xv tests/ linux_exe: windows_exe: install # ugly, but "import pkg_resources" doesn't work in frozen environments # and I don't want to have to patch the build machine to fix it every # time. mkdir -p $(CURDIR)/../build/exe/data (cd $(CURDIR)/src && find . -name '*.mo' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) release: ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" exit 1 else @echo "Will release: ${RELEASE}" @echo "Checking release is in ChangeLog ..." grep ${RELEASE} ChangeLog | grep -v "/xx" endif release_pypi: @echo "Releasing paperwork-backend ..." rm -rf /tmp/venv virtualenv /tmp/venv . /tmp/venv/bin/activate && pip install build . /tmp/venv/bin/activate && ${PYTHON} -m build -s rm -rf /tmp/venv twine upload $(CURDIR)/dist/*.tar.gz @echo "All done" clean: rm -rf build dist *.egg-info rm -f src/paperwork_backend/_version.py $(MAKE) -C $(CURDIR)/src/paperwork_backend/authors clean # PIP_ARGS is used by Flatpak build install_py: l10n_compile ${PYTHON} -m pip install ${PIP_ARGS} .${PIP_DEPS} install_c: uninstall_py: pip3 uninstall -y paperwork-backend uninstall_c: l10n_extract: $(CURDIR)/../tools/l10n_extract.sh "$(CURDIR)/src" "$(CURDIR)/l10n" l10n_compile: $(CURDIR)/../tools/l10n_compile.sh \ "$(CURDIR)/l10n" \ "$(CURDIR)/src/paperwork_backend/l10n" \ "paperwork_backend" help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ data \ doc \ exe \ help \ install \ install_c \ install_py \ l10n_compile \ l10n_extract \ release \ test \ upload_data \ upload_doc \ uninstall \ uninstall_c paperwork-2.2.2/paperwork-backend/README.markdown000066400000000000000000000035011456262201400216300ustar00rootroot00000000000000## Description [Paperwork](https://gitlab.gnome.org/World/OpenPaperwork/paperwork#readme) is a GUI to make papers searchable. This is the backend part of Paperwork. It manages: - The work directory / Access to the documents - Indexing - Searching - Suggestions - Import - Export There is no GUI here. The GUI is located here: https://gitlab.gnome.org/World/OpenPaperwork/paperwork/tree/master/paperwork-gtk . Regarding the name "Paperwork", it can refer to both the GUI or the backend. If you want to be specific, you can call the gui "paperwork-gtk" instead of just Paperwork. ## Dependencies * [Pillow](https://pypi.python.org/pypi/Pillow/): Image manipulation (with JPEG support) * [Whoosh](https://pypi.python.org/pypi/Whoosh/): To index and search documents, and provide keyword suggestions * Libpoppler (PDF support) * Cairo * Gobject Introspection ## Usage You can find some examples in scripts/. You can also look at the code of [Paperwork](https://gitlab.gnome.org/World/OpenPaperwork/paperwork#readme) for reference. Here are some snippets: ```py # TODO(Jflesch): UPDATE ``` ## Contact/Help Developement is strongly related to Paperwork-gui. * [Mailing-list](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contact) * [Extra documentation / FAQ / Tips / Wiki](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/) * [Bug trackers](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contact) ## Contact * [Mailing-list](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contact) * [Bug tracker](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis/Contact) ## Licence GPLv3 or later. See LICENSE. ## Development Developement is strongly related to Paperwork-gui. All the information can be found on [the wiki](https://gitlab.gnome.org/World/OpenPaperwork/paperwork/wikis). paperwork-2.2.2/paperwork-backend/doc/000077500000000000000000000000001456262201400176755ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/doc/Makefile000066400000000000000000000011041456262201400213310ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)paperwork-2.2.2/paperwork-backend/doc/conf.py000066400000000000000000000130271456262201400211770ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # # This file does only contain a selection of the most common options. For a # full list see the documentation: # http://www.sphinx-doc.org/en/master/config # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = 'Paperwork-Backend' copyright = '2019, Jerome Flesch' author = 'Jerome Flesch' # The short X.Y version version = '' # The full version, including alpha/beta/rc tags release = '' # -- General configuration --------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.ifconfig', 'sphinx.ext.viewcode', 'sphinxcontrib.plantuml', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # The name of the Pygments (syntax highlighting) style to use. pygments_style = None # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # The default sidebars (for documents that don't match any pattern) are # defined by theme itself. Builtin themes are using these templates by # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', # 'searchbox.html']``. # # html_sidebars = {} # -- Options for HTMLHelp output --------------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = 'Paperwork-Backenddoc' # -- Options for LaTeX output ------------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'Paperwork-Backend.tex', 'Paperwork-Backend Documentation', 'Jerome Flesch', 'manual'), ] # -- Options for manual page output ------------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'paperwork-backend', 'Paperwork-Backend Documentation', [author], 1) ] # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'Paperwork-Backend', 'Paperwork-Backend Documentation', author, 'Paperwork-Backend', 'One line description of project.', 'Miscellaneous'), ] # -- Options for Epub output ------------------------------------------------- # Bibliographic Dublin Core info. epub_title = project # The unique identifier of the text. This can be a ISBN number # or the project homepage. # # epub_identifier = '' # A unique identification for the text. # # epub_uid = '' # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # -- Extension configuration ------------------------------------------------- # -- Options for todo extension ---------------------------------------------- # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True autodoc_inherit_docstrings = False paperwork-2.2.2/paperwork-backend/doc/index.rst000066400000000000000000000003571456262201400215430ustar00rootroot00000000000000Welcome to Paperwork-Backend's documentation! ============================================= .. toctree:: :maxdepth: 2 :caption: Contents: Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` paperwork-2.2.2/paperwork-backend/l10n/000077500000000000000000000000001456262201400177025ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/l10n/ca.po000066400000000000000000000443151456262201400206340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-30 11:53+0100\n" "PO-Revision-Date: 2022-04-05 13:32+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "centrat" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "Alimentador" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "Escàner pla" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "alineat a l'esquerra" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "alineat a la dreta" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "Anglès" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "Francès" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "Alemany" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:80 msgid "Color equalization" msgstr "Equalització de color" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:92 msgid "Cropping" msgstr "Retallant" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:103 msgid "Clockwise Rotation" msgstr "Gira en sentit horari" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:112 msgid "Counterclockwise Rotation" msgstr "Gira en sentit anti-horari" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:231 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "" "Endevinador d'etiquetes: Netejant les característiques no utilitzades del " "document..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:254 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "Endevinador d'etiquetes: Netejant les paraules no utilitzades..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:571 #, python-format msgid "Label guesser: added document %s" msgstr "Endevinador d'etiquetes: S'ha afegit el document %s" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:581 #, python-format msgid "Label guesser: updated document %s" msgstr "Endevinador d'etiquetes: s'ha actualitzat el document %s" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:596 #, python-format msgid "Label guesser: deleted document %s" msgstr "Endevinador d'etiquetes: S'ha eliminat el document %s" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:681 msgid "Commiting changes for label guessing ..." msgstr "Desant els canvis de l'endevinador d'etiquetes..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:873 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:929 msgid "Label guessing: Training ..." msgstr "Endevinador d'etiquetes: Entrenant..." #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" "La pàgina {page_idx} del document {doc_id} conté text. No cal inferir el " "sentit de la pàgina." #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "" "Endevinant la orientació de les pàgines del document {doc_id} p{page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "Endevinant la orientació de les pàgines" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "" "Els colors de la pàgina {page_idx} del document {doc_id} ja han corregits" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "Ajustant els colors de la pàgina {page_idx} del document {doc_id}" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "Ajustant els colors del document" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" "La pàgina {page_idx} del document {doc_id} ja conté text. No cal passar-hi " "l'OCR" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "Passant l'OCR per la pàgina {page_idx} del document {doc_id}" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "Passant l'ORC" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "La pàgina {page_idx} del document {doc_id} ja ha estat retallada" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" "La pàgina {page_idx} del document {doc_id} ja conté text. No cal retallar-la." #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" "Utilitzant el calibratge per retallar la pàgina {page_idx} del document " "{doc_id}" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "Endevinant els marges de la pàgina {page_idx} del document {doc_id}" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "Endevinant els marges de la pàgina" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "Començant l'escaneig..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "Escanejant la pàgina %d..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "Examinant %s" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "Aconseguint la llista d'escàners..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:752 msgid "Scanner info." msgstr "Informació de l'escàner." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:753 msgid "Select to generate" msgstr "Selecciona per generar" #: paperwork-backend/src/paperwork_backend/doctracker.py:68 #, python-format msgid "Document %s added" msgstr "Document %s afegit" #: paperwork-backend/src/paperwork_backend/doctracker.py:73 #, python-format msgid "Document %s updated" msgstr "Document %s actualitzat" #: paperwork-backend/src/paperwork_backend/doctracker.py:89 #, python-format msgid "Document %s deleted" msgstr "Document %s esborrat" #: paperwork-backend/src/paperwork_backend/doctracker.py:99 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "Examinant el document %s: sense canvis" #: paperwork-backend/src/paperwork_backend/doctracker.py:104 msgid "Rolling back changes" msgstr "Desfés els canvis" #: paperwork-backend/src/paperwork_backend/doctracker.py:110 msgid "Committing changes" msgstr "Desant els canvis" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "Examinant el document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label \"%s" "\" with color=%s" msgstr "" "El document %s té l'etiqueta «%s» amb el color %s. El document %s també té " "l'etiqueta %s però amb el color %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "Establiu el color %s per a l'etiqueta «%s» del document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "Arreglant les etiquetes pel document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "El document %s és buit" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "Elimina el document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "Eliminant el document buit %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "Indexant el nou document %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "Eliminant el document %s de l'índex" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "Indexant el document actualitzat %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "Desant els canvis a l'índex..." #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 msgid "Already imported" msgstr "Ja es va importar" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:44 msgid "PDF" msgstr "PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 #: paperwork-backend/src/paperwork_backend/docimport/img.py:61 #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 msgid "Documents" msgstr "Documents" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:61 msgid "Import PDF" msgstr "Importa el PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:65 msgid "Import PDFs recursively" msgstr "Importa PDF recursivament" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:121 msgid "PDF folder" msgstr "Carpeta de PDFs" #: paperwork-backend/src/paperwork_backend/docimport/img.py:58 msgid "Images" msgstr "Imatges" #: paperwork-backend/src/paperwork_backend/docimport/img.py:64 msgid "Pages" msgstr "Pàgines" #: paperwork-backend/src/paperwork_backend/docimport/img.py:83 msgid "Append the image to the current document" msgstr "Enganxa les imatges al document actual" #: paperwork-backend/src/paperwork_backend/docimport/img.py:88 msgid "Find the images recursively and import them to the current document" msgstr "Troba les imatges de manera recursiva i importa-les al document actual" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "Importa un document de l'oficina" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "Importa documents de l'oficina recursivament" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "Carpeta dels documents de l'oficina" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:60 msgid "Microsoft Word template (.dot)" msgstr "Plantilla del Microsoft Word (.dot)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:68 msgid "Microsoft Excel template (.xlt)" msgstr "Plantilla del Microsoft Excel (.xlt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:76 msgid "Microsoft PowerPoint template (.ppt)" msgstr "Plantilla del Microsoft PowerPoint (.ppt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:80 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "Gràfic de l'OpenOffice/LibreOffice (.odc)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:84 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "Base de dades del OpenOffice/LibreOffice (.odb)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:88 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "Fórmula de l'OpenOffice/LibreOffice (.odf)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:92 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "Gràfic de l'OpenOffice/LibreOffice (.odg)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:96 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "Plantilla de gràfics de l'OpenOffice/LibreOffice (.otg)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:100 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "Plantilla d'imatge de l'OpenOffice/LibreOffice (.odi)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:104 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "Presentació de l'OpenOffice/LibreOffice (.odp)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:108 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "Plantilla de presentació de l'OpenOffice/LibreOffice (.otp)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:112 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "Full de càlcul de l'OpenOffice/LibreOffice (.ods)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:116 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "Plantilla del full de càlcul de l'OpenOffice/LibreOffice (.ots)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:120 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "Text de l'OpenOffice/LibreOffice (.odt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:124 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "Document global de l'OpenOffice/LibreOffice (.odm)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:128 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "Plantilla de text de l'OpenOffice/LibreOffice (.ott)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:132 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "Text web de l'OpenOffice/LibreOffice (.oth)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:144 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "Diapositiva del Microsoft PowerPoint (.sldx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:150 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "Presentació del Microsoft PowerPoint (.ppsx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:156 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "Plantilla de presentació del Microsoft PowerPoint (.potx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:168 msgid "Microsoft Excel template (.xltx)" msgstr "Plantilla del Microsoft Excel (.xltx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:180 msgid "Microsoft Word template (.dotx)" msgstr "Plantilla del Microsoft Word (.dotx)" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "[\"Víctor Fancelli Capdevila\"]" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "Carregant les etiquetes del document {}" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "Convertint el document %s en PDF..." #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "Controlant els documents convertits" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "PDFs originals" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:293 msgid "Generated PDF(s)" msgstr "Genera PDFs" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "Processant una pàgina darrere l'altra" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "Exportant la pàgina {page_idx} del document {doc_id}..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "Exportant..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "Separant text i imatges de les pàgines" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "Fitxer de la imatge ({})" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "Blanc i negre" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "Escala de Grisos" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "Simplificació suau" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "Simplificació forta" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "Simplificació extrema" paperwork-2.2.2/paperwork-backend/l10n/de.po000066400000000000000000000500611456262201400206340ustar00rootroot00000000000000# German translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-07-31 15:21+0000\n" "Last-Translator: Jannik Wilhelm \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.18.2\n" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "Starte Scan..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "Scanne Seite %d ..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "Prüfe %s" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "Erhalte Scannerliste..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:749 msgid "Scanner info." msgstr "Scanner Info." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:750 msgid "Select to generate" msgstr "Wähle zum Erzeugen" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "Dokument {doc_id} S{page_idx} wurde bereits farbkorrigiert" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "Passe die Farben auf Dokument {doc_id} Seite {page_idx} an" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "Passe die Farben des Dokuments an" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" "Dokument {doc_id} S{page_idx} hat bereits Text. Überspringe Ausrichtungs-" "Bestimmung." #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "Schätze Textrichtung von Dokument {doc_id} Seite {page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "Schätze Textrichtung" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" "Dokument {doc_id}p{page_idx} hat bereits erkannten Text. Überspringe OCR" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "Führe OCR auf Dokument {doc_id} Seite {page_idx} aus" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "Führe OCR aus" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:235 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "Label guesser: Garbage-collecting ungenutzer Dokumenten-Features ..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:261 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "Label guesser: Garbage-collecting ungenutzter Wörter ..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:585 #, python-format msgid "Label guesser: added document %s" msgstr "Label guesser: Document %s hinzugefügt" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:595 #, python-format msgid "Label guesser: updated document %s" msgstr "Label guesser: Document %s aktualisiert" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:610 #, python-format msgid "Label guesser: deleted document %s" msgstr "Label guesser: Document %s gelöscht" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:702 msgid "Commiting changes for label guessing ..." msgstr "Speichere Änderungen für label guessing ..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:912 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:968 msgid "Label guessing: Training ..." msgstr "Schlagwort-Schätzer: Training ..." #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "Dokument {doc_id} S{page_idx} wurde bereits zugeschnitten" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "Schätze Seitenrand von Dokument {doc_id} Seite {page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "Schätze Seitenränder" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" "Dokument {doc_id} Seite {page_idx} enthält bereits Text. Wird nicht " "beschnitten." #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" "Nutze Kalibrierung um den Rand des Dokuments {doc_id} Seite {page_idx} zu " "schneiden" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:40 #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "Prüfe %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:51 #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:68 #, python-format msgid "Document %s is not a directory" msgstr "Dokument %s ist kein Verzeichnis" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:55 #, python-format msgid "Turn %s into /doc.pdf" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:71 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "Lösche Dokument %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:88 #, python-format msgid "Fixing %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label " "\"%s\" with color=%s" msgstr "" "Dokument %s hat das Label \"%s\" (%s) während Dokument %s Label \"%s\" (%s) " "hat" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "Setze Labelfarbe %s auf Label \"%s\" des Dokuments %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "Korrigiere Label auf Dokument %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "Dokument %s ist leer" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "Lösche das leere Dokument %s" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "Leichte Vereinfachung" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "Starke Vereinfachung" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "Extreme Vereinfachung" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "Seitenweise Verarbeitung" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "Originale(s) PDF(s)" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:296 msgid "Generated PDF(s)" msgstr "Generierte PDF(s)" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "Exportiere {doc_id} p{page_idx} ..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "Exportiere ..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "Teile Seite(n) in Bild(er) und Text" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "Bilddatei ({})" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "Schwarz-Weiss" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "Graustufen" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "Englisch" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "Französisch" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "Deutsch" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "zentriert" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "Einzug" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "Flachbett" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "linksbündig" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "rechtsbündig" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:61 msgid "Microsoft Word template (.dot)" msgstr "Microsoft Word Vorlage (.dot)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:69 msgid "Microsoft Excel template (.xlt)" msgstr "Microsoft Excel Vorlage (.xlt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:77 msgid "Microsoft PowerPoint template (.ppt)" msgstr "Microsoft PowerPoint Vorlage (.ppt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:81 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "OpenOffice/LibreOffice Bild (.odc)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:85 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "OpenOffice/LibreOffice Datenbank (.odb)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:89 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "OpenOffice/LibreOffice Formel (.odf)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:93 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "OpenOffice/LibreOffice Zeichnung (.odg)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:97 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "OpenOffice/LibreOffice Zeichnung Vorlage (.otg)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:101 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "OpenOffice/LibreOffice Bild Vorlage (.odi)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:105 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "OpenOffice/LibreOffice Präsentation (.odp)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:109 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "OpenOffice/LibreOffice Präsentation Vorlage (.otp)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:113 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "OpenOffice/LibreOffice Tabellendokument (.ods)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:117 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "OpenOffice/LibreOffice Tabellendokument Vorlage (.ots)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:121 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "OpenOffice/LibreOffice Textdatei (.odt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:125 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "OpenOffice/LibreOffice Globaldokument (.odm)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:129 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "OpenOffice/LibreOffice Text Vorlage (.ott)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:133 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "OpenOffice/LibreOffice HTML-Vorlage (.oth)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:145 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "Microsoft PowerPoint Folie (.sldx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:151 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "Microsoft PowerPoint Präsentation (.ppsx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:157 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "Microsoft PowerPoint Präsentation Vorlage (.potx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:169 msgid "Microsoft Excel template (.xltx)" msgstr "Microsoft Excel Vorlage (.xltx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:181 msgid "Microsoft Word template (.dotx)" msgstr "Microsoft Word Vorlage (.dotx)" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:82 msgid "Color equalization" msgstr "Farbausgleich" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:94 msgid "Cropping" msgstr "Schneiden" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:105 msgid "Clockwise Rotation" msgstr "Drehen im Uhrzeigersinn" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:114 msgid "Counterclockwise Rotation" msgstr "Drehen gegen Uhrzeigersinn" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 msgid "Already imported" msgstr "Bereits importiert" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:46 #: paperwork-backend/src/paperwork_backend/docimport/img.py:68 msgid "Documents" msgstr "Dokumente" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "Importiere Office-Datei" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "Importiere Office-Dateien rekursiv" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "Office-Dateien Verzeichnis" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 msgid "PDF" msgstr "PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:62 msgid "Import PDF" msgstr "Importiere PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:66 msgid "Import PDFs recursively" msgstr "Importiere PDFs rekursiv" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:122 msgid "PDF folder" msgstr "PDF Ordner" #: paperwork-backend/src/paperwork_backend/docimport/img.py:65 msgid "Images" msgstr "Bilder" #: paperwork-backend/src/paperwork_backend/docimport/img.py:71 msgid "Pages" msgstr "Seiten" #: paperwork-backend/src/paperwork_backend/docimport/img.py:90 msgid "Append the image to the current document" msgstr "Hänge das Bild an das aktuelle Dokument an" #: paperwork-backend/src/paperwork_backend/docimport/img.py:95 msgid "Find the images recursively and import them to the current document" msgstr "Suche Bilder rekursiv und importiere sie in das aktuelle Dokument" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "[\"Andreas Forster\", \"Anna Lazic\", \"Tobias\"]" #: paperwork-backend/src/paperwork_backend/doctracker.py:65 #, python-format msgid "Document %s added" msgstr "Dokument %s hinzugefügt" #: paperwork-backend/src/paperwork_backend/doctracker.py:70 #, python-format msgid "Document %s updated" msgstr "Dokument %s aktualisiert" #: paperwork-backend/src/paperwork_backend/doctracker.py:86 #, python-format msgid "Document %s deleted" msgstr "Dokument %s gelöscht" #: paperwork-backend/src/paperwork_backend/doctracker.py:96 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "Prüfe Dokument %s: unverändert" #: paperwork-backend/src/paperwork_backend/doctracker.py:101 msgid "Rolling back changes" msgstr "Mache Änderungen rückgängig" #: paperwork-backend/src/paperwork_backend/doctracker.py:107 msgid "Committing changes" msgstr "Speichere Änderungen" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "Lade Dokumentenlabels {}" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "Konvertiere Dokument %s nach PDF ..." #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "Prüfe konvertierte Dokumente" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "Indiziere das neue Dokument %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "Entferne Dokument %s vom Index" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "Indiziere das aktualisierte Dokument %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "Speichere Änderungen im Index ..." #~ msgid "App. & system info." #~ msgstr "App. & System info." #~ msgid "Collecting statistics ..." #~ msgstr "Sammle Statistiken ..." #, python-brace-format #~ msgid "" #~ "Using calibration to crop page borders of document {doc_id} page " #~ "{page_idx}" #~ msgstr "" #~ "Nutze Kalibrierung um den Rand des Dokuments {doc_id} Seite {page_idx} zu " #~ "schneiden" #, python-brace-format #~ msgid "Guessing page borders of document {doc_id} page {page_idx}" #~ msgstr "Schätze Seitenrand von Dokument {doc_id} Seite {page_idx}" #, python-brace-format #~ msgid "Guessing orientation on document {doc_id} page {page_idx}" #~ msgstr "Schätze Textrichtung von Dokument {doc_id} Seite {page_idx}" #, python-brace-format #~ msgid "Running OCR on document {doc_id} page {page_idx}" #~ msgstr "Führe OCR auf Dokument {doc_id} Seite {page_idx} aus" #, python-format #~ msgid "Training label guesser with added document %s" #~ msgstr "Trainiere Label-Vorschlag mit hinzugefügtem Dokument %s" #, python-format #~ msgid "Untraining label guesser due to deleted document %s" #~ msgstr "Bereinige Label-Vorschlag wegen gelöschtem Dokument %s" #, python-format #~ msgid "Training label guesser with updated document %s" #~ msgstr "Trainiere Label-Vorschlag mit aktualisiertem Dokument %s" #~ msgid "Training label guesser for label '{}' with all known documents ..." #~ msgstr "" #~ "Trainiere Label-Vorschlag für das Label '{}' mit allen bekannten " #~ "Dokumenten ..." #~ msgid "Training label guessing ..." #~ msgstr "Trainiere Label-Vorschlag ..." #, python-brace-format #~ msgid "Adjusting colors of document {doc_id} page {page_idx}" #~ msgstr "Passe die Farben auf Dokument {doc_id} Seite {page_idx} an" paperwork-2.2.2/paperwork-backend/l10n/es.po000066400000000000000000000361451456262201400206620ustar00rootroot00000000000000# Spanish translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2022-03-22 11:49+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:749 msgid "Scanner info." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:750 msgid "Select to generate" msgstr "Selecciona para generar" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:235 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:261 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:585 #, python-format msgid "Label guesser: added document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:595 #, python-format msgid "Label guesser: updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:610 #, python-format msgid "Label guesser: deleted document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:702 msgid "Commiting changes for label guessing ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:912 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:968 msgid "Label guessing: Training ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:40 #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:51 #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:68 #, python-format msgid "Document %s is not a directory" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:55 #, python-format msgid "Turn %s into /doc.pdf" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:71 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:88 #, python-format msgid "Fixing %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label " "\"%s\" with color=%s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:296 msgid "Generated PDF(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "Blanco y Negro" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "Escala de Grises" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "alineado al centro" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "Alimentador" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:61 msgid "Microsoft Word template (.dot)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:69 msgid "Microsoft Excel template (.xlt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:77 msgid "Microsoft PowerPoint template (.ppt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:81 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:85 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:89 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:93 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:97 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:101 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:105 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:109 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:113 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:117 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:121 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:125 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:129 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:133 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:145 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:151 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:157 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:169 msgid "Microsoft Excel template (.xltx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:181 msgid "Microsoft Word template (.dotx)" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:82 msgid "Color equalization" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:94 msgid "Cropping" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:105 msgid "Clockwise Rotation" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:114 msgid "Counterclockwise Rotation" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 msgid "Already imported" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:46 #: paperwork-backend/src/paperwork_backend/docimport/img.py:68 msgid "Documents" msgstr "Documentos" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 msgid "PDF" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:62 msgid "Import PDF" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:66 msgid "Import PDFs recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:122 msgid "PDF folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:65 msgid "Images" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:71 msgid "Pages" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:90 msgid "Append the image to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:95 msgid "Find the images recursively and import them to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:65 #, python-format msgid "Document %s added" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:70 #, python-format msgid "Document %s updated" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:86 #, python-format msgid "Document %s deleted" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:96 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:101 msgid "Rolling back changes" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:107 msgid "Committing changes" msgstr "" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "" paperwork-2.2.2/paperwork-backend/l10n/fr.po000066400000000000000000000512061456262201400206550ustar00rootroot00000000000000# French translations for PACKAGE package # Traductions françaises du paquet PACKAGE. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2021-11-29 21:07+0000\n" "Last-Translator: Jerome Flesch \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "Démarrage du scan…" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "Scan de la page %d…" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "Examen de %s" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "Récupération de la liste des scanners…" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:749 msgid "Scanner info." msgstr "Info. du scanner" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:750 msgid "Select to generate" msgstr "Sélectionnez pour générer" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "La p{page_idx} du document {doc_id} est déjà correctement colorisée" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "Ajustement des couleurs de la p{page_idx} du document {doc_id}" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "Ajustement des couleurs du document" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" "La p{page_idx} du document {doc_id} a déjà du texte. Pas de tentative de " "deviner l'orientation de la page." #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "" "Entrain de deviner l'orientation de la p{page_idx} du document {doc_id}" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "Détection de l'orientation de la page" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" "Le document {doc_id} p{page_idx} a déjà du texte associé. La ROC ne sera pas " "effectuée" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "Exécution de la ROC sur le document {doc_id} p{page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "Exécution de la ROC" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:235 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "" "Devineur d'étiquettes : Suppression des caractéristiques de documents qui ne " "sont plus utilisées ..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:261 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "Devineur d'étiquettes : Suppression des mots non-utilisés ..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:585 #, python-format msgid "Label guesser: added document %s" msgstr "Devineur d'étiquettes : document %s ajouté" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:595 #, python-format msgid "Label guesser: updated document %s" msgstr "Devineur d'étiquettes : document %s mis à jour" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:610 #, python-format msgid "Label guesser: deleted document %s" msgstr "Devineur d'étiquettes : document %s effacé" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:702 msgid "Commiting changes for label guessing ..." msgstr "Enregistrement des changements pour le devinage d'étiquettes ..." #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:912 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:968 msgid "Label guessing: Training ..." msgstr "Devineur d'étiquettes : entraînement ..." #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "Document {doc_id} p{page_idx} déjà découpée" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "Détection des bords de la page de {doc_id} p{page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "Détection des bords de la page" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" "La page p{page_idx} du document {doc_id} a déjà du texte. Ne sera pas " "découpée." #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" "Utilisation de la calibration pour découper les bords de la page {doc_id} " "p{page_idx}" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:40 #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "Vérification du document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:51 #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:68 #, python-format msgid "Document %s is not a directory" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:55 #, python-format msgid "Turn %s into /doc.pdf" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:71 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "Effacer le document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:88 #, python-format msgid "Fixing %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label " "\"%s\" with color=%s" msgstr "" "Document %s a l'étiquette \"%s\" avec la couleur %s tandis que le document " "%s a l'étiquette \"%s\" avec la couleur %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "Mise de la couleur %s sur l'étiquette \"%s\" du document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "Correction de l'étiquette sur le document %s" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "Le document %s est vide" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "Effacement du document vide %s" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "Simplification douce" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "Simplification forte" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "Simplification extrême" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "Traitement page par page" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "PDF(s) d'origine" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:296 msgid "Generated PDF(s)" msgstr "PDF(s) généré(s)" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "Export de {doc_id} p{page_idx}…" #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "Export en cours…" #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "Sépare le(s) page(s) en image(s) et texte(s)" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "Fichier image ({})" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "Noir et blanc" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "Niveaux de gris" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "Anglais" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "Français" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "Allemand" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "centré" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "Bac d'alimentation" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "Plateau" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "aligné à gauche" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "aligné à droite" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:61 msgid "Microsoft Word template (.dot)" msgstr "Modèle de document Microsoft Word (.dot)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:69 msgid "Microsoft Excel template (.xlt)" msgstr "Modèle de document Microsoft Excel (.xlt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:77 msgid "Microsoft PowerPoint template (.ppt)" msgstr "Modèle de document Microsoft PowerPoint (.ppt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:81 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "Graphique LibreOffice (.odc)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:85 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "Base de données LibreOffice (.odb)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:89 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "Formule LibreOffice (.odf)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:93 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "Graphique LibreOffice (.odg)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:97 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "Modèle de document graphique LibreOffice (.otg)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:101 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "Modèle d'image LibreOffice (.odi)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:105 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "Présentation LibreOffice (.odp)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:109 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "Modèle de présentation LibreOffice (.otp)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:113 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "Tableau LibreOffice (.ods)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:117 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "Modèle de tableau LibreOffice (.ots)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:121 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "Texte LibreOffice (.odt)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:125 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "Document texte maître LibreOffice (.odm)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:129 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "Modèle de texte LibreOffice (.ott)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:133 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "Texte web LibreOffice (.oth)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:145 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "Diapositive Microsoft PowerPoint (.sldx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:151 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "Présentation Microsoft PowerPoint (.ppsx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:157 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "Modèle de présentation Microsoft PowerPoint (.potx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:169 msgid "Microsoft Excel template (.xltx)" msgstr "Modèle de tableau Microsoft Excel (.xltx)" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:181 msgid "Microsoft Word template (.dotx)" msgstr "Modèle de document Microsoft Word (.dotx)" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:82 msgid "Color equalization" msgstr "Égalisation des couleurs" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:94 msgid "Cropping" msgstr "Recadrage" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:105 msgid "Clockwise Rotation" msgstr "Rotation dans le sens horaire" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:114 msgid "Counterclockwise Rotation" msgstr "Rotation dans le sens anti-horaire" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 msgid "Already imported" msgstr "Déjà importé" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:46 #: paperwork-backend/src/paperwork_backend/docimport/img.py:68 msgid "Documents" msgstr "Documents" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "Importer les documents Office/LibreOffice" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "Import les documents Office/Libreoffice récursivement" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "Dossier de documents Office/LibreOffice" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 msgid "PDF" msgstr "PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:62 msgid "Import PDF" msgstr "Importer un PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:66 msgid "Import PDFs recursively" msgstr "Importer les PDFs récursivement" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:122 msgid "PDF folder" msgstr "Répertoire de PDFs" #: paperwork-backend/src/paperwork_backend/docimport/img.py:65 msgid "Images" msgstr "Images" #: paperwork-backend/src/paperwork_backend/docimport/img.py:71 msgid "Pages" msgstr "Pages" #: paperwork-backend/src/paperwork_backend/docimport/img.py:90 msgid "Append the image to the current document" msgstr "Ajouter l'image au document actuel" #: paperwork-backend/src/paperwork_backend/docimport/img.py:95 msgid "Find the images recursively and import them to the current document" msgstr "" "Trouver les images récursivement et les importer dans le document actif" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "[\"Flesch Jérôme\"]" #: paperwork-backend/src/paperwork_backend/doctracker.py:65 #, python-format msgid "Document %s added" msgstr "Document %s ajouté" #: paperwork-backend/src/paperwork_backend/doctracker.py:70 #, python-format msgid "Document %s updated" msgstr "Document %s mis à jour" #: paperwork-backend/src/paperwork_backend/doctracker.py:86 #, python-format msgid "Document %s deleted" msgstr "Document %s supprimé" #: paperwork-backend/src/paperwork_backend/doctracker.py:96 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "Examen du document %s : inchangé" #: paperwork-backend/src/paperwork_backend/doctracker.py:101 msgid "Rolling back changes" msgstr "Annulation des modifications" #: paperwork-backend/src/paperwork_backend/doctracker.py:107 msgid "Committing changes" msgstr "Enregistrement des modifications" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "Chargement des étiquettes du document {}" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "Conversion du document %s en PDF …" #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "Vérification des documents convertis" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "Indexation du nouveau document %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "Suppression du document %s de l'index" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "Indexation de la mise à jour du document %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "Enregistrement des modifications dans l'index…" #~ msgid "App. & system info." #~ msgstr "Info. app. & système" #~ msgid "Collecting statistics ..." #~ msgstr "Récupération des statistiques…" #, python-brace-format #~ msgid "" #~ "Using calibration to crop page borders of document {doc_id} page " #~ "{page_idx}" #~ msgstr "" #~ "Utilisation de la calibration pour recadrer la page {page_idx} du " #~ "document {doc_id}" #, python-brace-format #~ msgid "Guessing page borders of document {doc_id} page {page_idx}" #~ msgstr "Estimation des bords de la page {page_idx} du document {doc_id}" #, python-brace-format #~ msgid "Guessing orientation on document {doc_id} page {page_idx}" #~ msgstr "" #~ "Détection de l'orientation de la page {page_idx} du document {doc_id}" #, python-brace-format #~ msgid "Running OCR on document {doc_id} page {page_idx}" #~ msgstr "ROC en cours sur la page {page_idx} du document {doc_id}" #, python-format #~ msgid "Training label guesser with added document %s" #~ msgstr "" #~ "Entraînement de l'estimateur d'étiquettes avec le document %s ajouté" #, python-format #~ msgid "Untraining label guesser due to deleted document %s" #~ msgstr "" #~ "Dé-entraînement de l'estimateur d'étiquettes suite à la suppression du " #~ "document %s" #, python-format #~ msgid "Training label guesser with updated document %s" #~ msgstr "" #~ "Entraînement de l'estimateur d'étiquettes avec la mise à jour du document " #~ "%s" #~ msgid "Training label guesser for label '{}' with all known documents ..." #~ msgstr "" #~ "Entraînement de l'estimateur pour l'étiquette '{}' avec tous les " #~ "documents connus…" #~ msgid "Training label guessing ..." #~ msgstr "Entraînement de l'estimateur d'étiquettes…" #, python-brace-format #~ msgid "Adjusting colors of document {doc_id} page {page_idx}" #~ msgstr "Ajustement des couleurs de la page {page_idx} du document {doc_id}" paperwork-2.2.2/paperwork-backend/l10n/messages.pot000066400000000000000000000355451456262201400222510ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:749 msgid "Scanner info." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:750 msgid "Select to generate" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:235 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:261 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:585 #, python-format msgid "Label guesser: added document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:595 #, python-format msgid "Label guesser: updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:610 #, python-format msgid "Label guesser: deleted document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:702 msgid "Commiting changes for label guessing ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:912 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:968 msgid "Label guessing: Training ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:40 #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:51 #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:68 #, python-format msgid "Document %s is not a directory" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:55 #, python-format msgid "Turn %s into /doc.pdf" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:71 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:88 #, python-format msgid "Fixing %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label " "\"%s\" with color=%s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:296 msgid "Generated PDF(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:61 msgid "Microsoft Word template (.dot)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:69 msgid "Microsoft Excel template (.xlt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:77 msgid "Microsoft PowerPoint template (.ppt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:81 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:85 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:89 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:93 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:97 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:101 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:105 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:109 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:113 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:117 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:121 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:125 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:129 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:133 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:145 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:151 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:157 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:169 msgid "Microsoft Excel template (.xltx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:181 msgid "Microsoft Word template (.dotx)" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:82 msgid "Color equalization" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:94 msgid "Cropping" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:105 msgid "Clockwise Rotation" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:114 msgid "Counterclockwise Rotation" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 msgid "Already imported" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:46 #: paperwork-backend/src/paperwork_backend/docimport/img.py:68 msgid "Documents" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 msgid "PDF" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:62 msgid "Import PDF" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:66 msgid "Import PDFs recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:122 msgid "PDF folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:65 msgid "Images" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:71 msgid "Pages" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:90 msgid "Append the image to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:95 msgid "Find the images recursively and import them to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:65 #, python-format msgid "Document %s added" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:70 #, python-format msgid "Document %s updated" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:86 #, python-format msgid "Document %s deleted" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:96 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:101 msgid "Rolling back changes" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:107 msgid "Committing changes" msgstr "" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "" paperwork-2.2.2/paperwork-backend/l10n/oc.po000066400000000000000000000440341456262201400206500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2020-09-02 17:30+0000\n" "Last-Translator: Quentin PAGÈS \n" "Language-Team: Occitan \n" "Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.1.1\n" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "Aviada del numerizador…" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "Num. de la pagina %d…" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "Analisi de %s" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "Recuperacion de la lista dels numerizadors…" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:749 msgid "Scanner info." msgstr "Informacion del numerizador" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:750 msgid "Select to generate" msgstr "Seleccionar per generar" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" "Lo document {doc_id} p{page_idx} a ja un tèxt associat. La ROC serà pas " "realizada" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:235 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:261 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:585 #, python-format msgid "Label guesser: added document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:595 #, python-format msgid "Label guesser: updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:610 #, python-format msgid "Label guesser: deleted document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:702 msgid "Commiting changes for label guessing ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:912 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:968 msgid "Label guessing: Training ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:40 #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:51 #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:68 #, python-format msgid "Document %s is not a directory" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:55 #, python-format msgid "Turn %s into /doc.pdf" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:71 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:88 #, python-format msgid "Fixing %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label " "\"%s\" with color=%s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "Simplificacion doça" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "Simplificacion fòrta" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "Simplificacion extrèma" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "Tractament pagina per pagina" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "PDF original" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:296 msgid "Generated PDF(s)" msgstr "PDF generat(s)" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "Export. de {doc_id} p{page_idx}…" #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "Export. en cors…" #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "Separar la(s) pagina(s) en imatge(s) e tèxte(s)" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "Fichièr imatge ({})" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "Blanc e negre" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "Nivèls de gris" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "Anglés" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "Francés" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "Alemand" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "centrat" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "Cargador de documents" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "Platèl" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "alinhat a esquèrra" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "alinhat a drecha" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:61 msgid "Microsoft Word template (.dot)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:69 msgid "Microsoft Excel template (.xlt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:77 msgid "Microsoft PowerPoint template (.ppt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:81 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:85 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:89 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:93 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:97 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:101 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:105 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:109 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:113 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:117 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:121 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:125 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:129 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:133 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:145 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:151 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:157 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:169 msgid "Microsoft Excel template (.xltx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:181 msgid "Microsoft Word template (.dotx)" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:82 msgid "Color equalization" msgstr "Egalisacion de las colors" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:94 msgid "Cropping" msgstr "Retalhatge" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:105 msgid "Clockwise Rotation" msgstr "Rotacion orària" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:114 msgid "Counterclockwise Rotation" msgstr "Rotacion anti-orària" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 msgid "Already imported" msgstr "Ja importat" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:46 #: paperwork-backend/src/paperwork_backend/docimport/img.py:68 msgid "Documents" msgstr "Documents" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 msgid "PDF" msgstr "PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:62 msgid "Import PDF" msgstr "Importar un PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:66 msgid "Import PDFs recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:122 msgid "PDF folder" msgstr "Repertòri dels PDF" #: paperwork-backend/src/paperwork_backend/docimport/img.py:65 msgid "Images" msgstr "Imatges" #: paperwork-backend/src/paperwork_backend/docimport/img.py:71 msgid "Pages" msgstr "Paginas" #: paperwork-backend/src/paperwork_backend/docimport/img.py:90 msgid "Append the image to the current document" msgstr "Ajustar l’imatge al document actual" #: paperwork-backend/src/paperwork_backend/docimport/img.py:95 msgid "Find the images recursively and import them to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "[\"Quentin PAGÈS\"]" #: paperwork-backend/src/paperwork_backend/doctracker.py:65 #, python-format msgid "Document %s added" msgstr "Document %s ajustat" #: paperwork-backend/src/paperwork_backend/doctracker.py:70 #, python-format msgid "Document %s updated" msgstr "Document %s mes a jorn" #: paperwork-backend/src/paperwork_backend/doctracker.py:86 #, python-format msgid "Document %s deleted" msgstr "Document %s suprimit" #: paperwork-backend/src/paperwork_backend/doctracker.py:96 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "Analisi del document %s : pas cambiat" #: paperwork-backend/src/paperwork_backend/doctracker.py:101 msgid "Rolling back changes" msgstr "Anullacion de las modificacions" #: paperwork-backend/src/paperwork_backend/doctracker.py:107 msgid "Committing changes" msgstr "Enregistrament de las modificacions" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "Cargament de las etiquetas del document {}" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "Indexacion del document novèl %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "Supression del document %s de l’ensenhador" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "Indexacion de la mesa a jorn del document %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "Enregistrament de las modificacion dins l’ensenhador…" #~ msgid "App. & system info." #~ msgstr "Info. ap. e sistèma" #~ msgid "Collecting statistics ..." #~ msgstr "Recuperacion de las estatisticas…" #, python-brace-format #~ msgid "" #~ "Using calibration to crop page borders of document {doc_id} page " #~ "{page_idx}" #~ msgstr "" #~ "Utilizacion del calibratge per retalhar la pagina {page_idx} del document " #~ "{doc_id}" #, python-brace-format #~ msgid "Guessing page borders of document {doc_id} page {page_idx}" #~ msgstr "" #~ "Localizacion dels bòrds de la pagina {page_idx} del document {doc_id}" #, python-brace-format #~ msgid "Guessing orientation on document {doc_id} page {page_idx}" #~ msgstr "" #~ "Deteccion de l’orientacion de la pagina {page_idx} del document {doc_id}" #, python-brace-format #~ msgid "Running OCR on document {doc_id} page {page_idx}" #~ msgstr "ROC en cors sus la pagina {page_idx} del document {doc_id}" #, python-format #~ msgid "Training label guesser with added document %s" #~ msgstr "Entrainament del devinaire d’etiquetas amb lo document %s ajustat" #, python-format #~ msgid "Untraining label guesser due to deleted document %s" #~ msgstr "" #~ "Mesa al deslembrièr de l’entrainament d’etiquetas en seguida de la " #~ "supression del document %s" #, python-format #~ msgid "Training label guesser with updated document %s" #~ msgstr "" #~ "Entrainament del devinaire d’etiquetas amb la mesa a jorn del document %s" #~ msgid "Training label guesser for label '{}' with all known documents ..." #~ msgstr "" #~ "Entrainament del devinaire d’etiquetas per l’etiqueta « {} » amb totes " #~ "los documents coneguts…" #~ msgid "Training label guessing ..." #~ msgstr "Entrainament del devinaire d’etiquetas…" #, python-brace-format #~ msgid "Adjusting colors of document {doc_id} page {page_idx}" #~ msgstr "" #~ "Ajustament de las color de la pagina {page_idx} del document {doc_id}" paperwork-2.2.2/paperwork-backend/l10n/sv.po000066400000000000000000000232671456262201400207040ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-01-04 15:31+0000\n" "Last-Translator: Ã…ke Engelbrektson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #: paperwork-backend/src/paperwork_backend/doctracker.py:68 #, python-format msgid "Document %s added" msgstr "Dokument %s tillagt" #: paperwork-backend/src/paperwork_backend/doctracker.py:73 #, python-format msgid "Document %s updated" msgstr "Dokument %s uppdaterat" #: paperwork-backend/src/paperwork_backend/doctracker.py:89 #, python-format msgid "Document %s deleted" msgstr "Dokument %s borttaget" #: paperwork-backend/src/paperwork_backend/doctracker.py:99 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "Undersöker dokument %s: Oförändrat" #: paperwork-backend/src/paperwork_backend/doctracker.py:104 msgid "Rolling back changes" msgstr "Ã…ngrar ändringar" #: paperwork-backend/src/paperwork_backend/doctracker.py:110 msgid "Committing changes" msgstr "Tillämpar ändringar" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:32 msgid "Already imported" msgstr "Redan importerat" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:40 msgid "PDF" msgstr "PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:41 #: paperwork-backend/src/paperwork_backend/docimport/img.py:55 msgid "Documents" msgstr "Dokument" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:57 msgid "Import PDF" msgstr "Importera PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:105 msgid "PDF folder" msgstr "PDF-mapp" #: paperwork-backend/src/paperwork_backend/docimport/img.py:52 msgid "Images" msgstr "Bilder" #: paperwork-backend/src/paperwork_backend/docimport/img.py:58 msgid "Pages" msgstr "Sidor" #: paperwork-backend/src/paperwork_backend/docimport/img.py:77 msgid "Append the image to the current document" msgstr "Bifoga bilden till det aktuella dokumentet" #: paperwork-backend/src/paperwork_backend/beacon/stats.py:126 msgid "App. & system info." msgstr "App. & systeminfo." #: paperwork-backend/src/paperwork_backend/beacon/stats.py:127 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:690 msgid "Select to generate" msgstr "Välj för att generera" #: paperwork-backend/src/paperwork_backend/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "Samlar in statistik..." #: paperwork-backend/src/paperwork_backend/model/labels.py:47 msgid "Loading labels of document {}" msgstr "Läser in etiketter för dokument {}" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "Original-PDF(:er)" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:293 msgid "Generated PDF(s)" msgstr "Genererade PDF(:er)" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "Exporterar {doc_id} s.{page_idx}..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "Exporterar..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "Dela upp sida/sidor i bild(er) och text" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "Bildfil ({})" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "Svartvit" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "GrÃ¥skala" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "Bearbetning sida för sida" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "Mjuk förenkling" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "HÃ¥rd förenkling" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "Extrem förenkling" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:208 msgid "Starting scan ..." msgstr "Startar skanning..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:216 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:268 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:279 #, python-format msgid "Scanning page %d ..." msgstr "Skannar sida %d..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:423 #, python-format msgid "Examining %s" msgstr "Undersöker %s" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:494 msgid "Getting scanner list ..." msgstr "Hämtar skannerlista..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:689 msgid "Scanner info." msgstr "Skannerinfo." #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "Engelska" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "Franska" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "Tyska" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "centrerat" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "Matare" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "Flatbädd" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "vänsterjusterat" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "högerjusterat" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:80 msgid "Color equalization" msgstr "Färgutjämning" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:92 msgid "Cropping" msgstr "Beskär" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:103 msgid "Clockwise Rotation" msgstr "Medurs rotation" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:112 msgid "Counterclockwise Rotation" msgstr "Moturs rotation" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:53 #, python-brace-format msgid "" "Using calibration to crop page borders of document {doc_id} page {page_idx}" msgstr "" "Använder kalibrering för att beskära sidkantlinjer i dokument {doc_id} sida " "{page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:57 #, python-brace-format msgid "Guessing page borders of document {doc_id} page {page_idx}" msgstr "Gissar sidkantlinjer för dokument {doc_id} sida {page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:39 #, python-brace-format msgid "Guessing orientation on document {doc_id} page {page_idx}" msgstr "Gissar orientering pÃ¥ dokument {doc_id} sida {page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:50 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "Dokument {doc_id} s.{page_idx} har redan text. Ingen OCR-körning" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:58 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx}" msgstr "Kör OCR pÃ¥ dokument {doc_id} sida {page_idx}" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:92 #, python-format msgid "Training label guesser with added document %s" msgstr "Tränar etikettgissaren med tillagt dokument %s" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:100 #, python-format msgid "Untraining label guesser due to deleted document %s" msgstr "Rensar etikettgissaren med anledning av borttaget dokument %s" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:107 #, python-format msgid "Training label guesser with updated document %s" msgstr "Tränar etikettgissaren med uppdaterat dokument %s" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:240 msgid "Training label guesser for label '{}' with all known documents ..." msgstr "Tränar etikettgissaren för etikett \"{}\" med alla kända dokument..." #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:333 msgid "Training label guessing ..." msgstr "Tränar etikettgissaren..." #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:53 #, python-brace-format msgid "Adjusting colors of document {doc_id} page {page_idx}" msgstr "Justerar färger i dokument {doc_id} sida {page_idx}" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "Indexerar nytt dokument %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "Tar bort dokument %s frÃ¥n index" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "Indexerar uppdaterat dokument %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "Tillämpar ändringar i index..." #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "[]" paperwork-2.2.2/paperwork-backend/l10n/uk.po000066400000000000000000000357251456262201400206750ustar00rootroot00000000000000# Ukrainian translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2020-05-03 15:37+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:233 msgid "Starting scan ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:241 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:293 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:304 #, python-format msgid "Scanning page %d ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:457 #, python-format msgid "Examining %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:538 msgid "Getting scanner list ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:749 msgid "Scanner info." msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:750 msgid "Select to generate" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} already correctly colorized" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:64 #, python-brace-format msgid "Adjusting colors of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:88 msgid "Adjusting colors of document" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:43 #, python-brace-format msgid "" "Document {doc_id} p{page_idx} has already some text. Not guessing page " "orientation." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:53 #, python-brace-format msgid "Guessing orientation of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:77 msgid "Guessing page orientation" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:48 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:57 #, python-brace-format msgid "Running OCR on document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:83 msgid "Running OCR" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:235 msgid "Label guesser: Garbage-collecting unused document features ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:261 msgid "Label guesser: Garbage-collecting unused words ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:585 #, python-format msgid "Label guesser: added document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:595 #, python-format msgid "Label guesser: updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:610 #, python-format msgid "Label guesser: deleted document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:702 msgid "Commiting changes for label guessing ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:912 #: paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py:968 msgid "Label guessing: Training ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:51 #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:45 #, python-brace-format msgid "Document {doc_id} p{page_idx} already cropped" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:60 #, python-brace-format msgid "Guessing page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:85 msgid "Guessing page borders" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:58 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. Not cropping." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:68 #, python-brace-format msgid "Using calibration to crop page borders of document {doc_id} p{page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:40 #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:55 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:44 #, python-format msgid "Checking doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:51 #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:68 #, python-format msgid "Document %s is not a directory" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:55 #, python-format msgid "Turn %s into /doc.pdf" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:71 #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:60 #, python-format msgid "Delete document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py:88 #, python-format msgid "Fixing %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:87 #, python-format msgid "" "Document %s has label \"%s\" with color=%s while document %s has label " "\"%s\" with color=%s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:106 #, python-format msgid "Set label color %s on label \"%s\" of document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py:130 #, python-format msgid "Fixing label on doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:59 #, python-format msgid "Document %s is empty" msgstr "" #: paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py:74 #, python-format msgid "Deleting empty doc %s" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:296 msgid "Generated PDF(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:61 msgid "Microsoft Word template (.dot)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:69 msgid "Microsoft Excel template (.xlt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:77 msgid "Microsoft PowerPoint template (.ppt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:81 msgid "OpenOffice/LibreOffice Chart (.odc)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:85 msgid "OpenOffice/LibreOffice Database (.odb)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:89 msgid "OpenOffice/LibreOffice Formula (.odf)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:93 msgid "OpenOffice/LibreOffice Graphics (.odg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:97 msgid "OpenOffice/LibreOffice Graphics template (.otg)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:101 msgid "OpenOffice/LibreOffice Image template (.odi)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:105 msgid "OpenOffice/LibreOffice Presentation (.odp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:109 msgid "OpenOffice/LibreOffice Presentation template (.otp)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:113 msgid "OpenOffice/LibreOffice Spreadsheet (.ods)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:117 msgid "OpenOffice/LibreOffice Spreadsheet template (.ots)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:121 msgid "OpenOffice/LibreOffice Text (.odt)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:125 msgid "OpenOffice/LibreOffice Text master (.odm)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:129 msgid "OpenOffice/LibreOffice Text template (.ott)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:133 msgid "OpenOffice/LibreOffice Text web (.oth)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:145 msgid "Microsoft PowerPoint slide (.sldx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:151 msgid "Microsoft PowerPoint slideshow (.ppsx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:157 msgid "Microsoft PowerPoint presentation template (.potx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:169 msgid "Microsoft Excel template (.xltx)" msgstr "" #: paperwork-backend/src/paperwork_backend/converter/libreoffice.py:181 msgid "Microsoft Word template (.dotx)" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:82 msgid "Color equalization" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:94 msgid "Cropping" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:105 msgid "Clockwise Rotation" msgstr "" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:114 msgid "Counterclockwise Rotation" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:33 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:33 msgid "Already imported" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:41 #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:46 #: paperwork-backend/src/paperwork_backend/docimport/img.py:68 msgid "Documents" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:67 msgid "Import office document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:71 msgid "Import office documents recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/converted.py:139 msgid "Office document folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:45 msgid "PDF" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:62 msgid "Import PDF" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:66 msgid "Import PDFs recursively" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:122 msgid "PDF folder" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:65 msgid "Images" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:71 msgid "Pages" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:90 msgid "Append the image to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/docimport/img.py:95 msgid "Find the images recursively and import them to the current document" msgstr "" #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:65 #, python-format msgid "Document %s added" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:70 #, python-format msgid "Document %s updated" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:86 #, python-format msgid "Document %s deleted" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:96 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:101 msgid "Rolling back changes" msgstr "" #: paperwork-backend/src/paperwork_backend/doctracker.py:107 msgid "Committing changes" msgstr "" #: paperwork-backend/src/paperwork_backend/model/labels.py:72 msgid "Loading labels of document {}" msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:111 #, python-format msgid "Converting document %s to PDF ..." msgstr "" #: paperwork-backend/src/paperwork_backend/model/converted.py:186 msgid "Checking converted documents" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "" paperwork-2.2.2/paperwork-backend/l10n/zh_Hans.po000066400000000000000000000221321456262201400216340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-02-06 09:20+0000\n" "Last-Translator: 玉堂白鹤 \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.4\n" #: paperwork-backend/src/paperwork_backend/doctracker.py:68 #, python-format msgid "Document %s added" msgstr "文档 %s 已添加" #: paperwork-backend/src/paperwork_backend/doctracker.py:73 #, python-format msgid "Document %s updated" msgstr "文档 %s 已更新" #: paperwork-backend/src/paperwork_backend/doctracker.py:89 #, python-format msgid "Document %s deleted" msgstr "文档 %s 已删除" #: paperwork-backend/src/paperwork_backend/doctracker.py:99 #: paperwork-backend/src/paperwork_backend/index/whoosh.py:140 #, python-format msgid "Examining document %s: unchanged" msgstr "正在检查文档 %s:未更改" #: paperwork-backend/src/paperwork_backend/doctracker.py:104 msgid "Rolling back changes" msgstr "回滚更改" #: paperwork-backend/src/paperwork_backend/doctracker.py:110 msgid "Committing changes" msgstr "æäº¤æ›´æ”¹" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:32 msgid "Already imported" msgstr "已导入" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:40 msgid "PDF" msgstr "PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:41 #: paperwork-backend/src/paperwork_backend/docimport/img.py:55 msgid "Documents" msgstr "文档" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:57 msgid "Import PDF" msgstr "导入 PDF" #: paperwork-backend/src/paperwork_backend/docimport/pdf.py:105 msgid "PDF folder" msgstr "PDF 文件夹" #: paperwork-backend/src/paperwork_backend/docimport/img.py:52 msgid "Images" msgstr "图åƒ" #: paperwork-backend/src/paperwork_backend/docimport/img.py:58 msgid "Pages" msgstr "页é¢" #: paperwork-backend/src/paperwork_backend/docimport/img.py:77 msgid "Append the image to the current document" msgstr "将图åƒè¿½åŠ åˆ°å½“å‰æ–‡æ¡£" #: paperwork-backend/src/paperwork_backend/beacon/stats.py:126 msgid "App. & system info." msgstr "App. 和系统信æ¯ã€‚" #: paperwork-backend/src/paperwork_backend/beacon/stats.py:127 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:690 msgid "Select to generate" msgstr "选择生æˆ" #: paperwork-backend/src/paperwork_backend/beacon/stats.py:149 msgid "Collecting statistics ..." msgstr "æ”¶é›†ç»Ÿè®¡æ•°æ® ..." #: paperwork-backend/src/paperwork_backend/model/labels.py:47 msgid "Loading labels of document {}" msgstr "加载文档标签 {}" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:100 msgid "Original PDF(s)" msgstr "原始 PDF" #: paperwork-backend/src/paperwork_backend/docexport/pdf.py:293 msgid "Generated PDF(s)" msgstr "生æˆçš„ PDF" #: paperwork-backend/src/paperwork_backend/docexport/img.py:41 #, python-brace-format msgid "Exporting {doc_id} p{page_idx} ..." msgstr "正在导出 {doc_id} 页{page_idx} ..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:86 msgid "Exporting ..." msgstr "正在导出 ..." #: paperwork-backend/src/paperwork_backend/docexport/img.py:121 msgid "Split page(s) into image(s) and text(s)" msgstr "将页颿‹†åˆ†ä¸ºå›¾åƒå’Œæ–‡æœ¬" #: paperwork-backend/src/paperwork_backend/docexport/img.py:171 msgid "Image file ({})" msgstr "å›¾åƒæ–‡ä»¶ ({})" #: paperwork-backend/src/paperwork_backend/docexport/img.py:184 msgid "Black & White" msgstr "黑白" #: paperwork-backend/src/paperwork_backend/docexport/img.py:195 msgid "Grayscale" msgstr "ç°åº¦" #: paperwork-backend/src/paperwork_backend/docexport/generic.py:98 msgid "Page by page processing" msgstr "é€é¡µå¤„ç†" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:31 msgid "Soft simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:50 msgid "Hard simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docexport/pillowfight.py:52 msgid "Extreme simplification" msgstr "" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:208 msgid "Starting scan ..." msgstr "开始扫æ ..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:216 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:268 #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:279 #, python-format msgid "Scanning page %d ..." msgstr "扫æé¡µé¢ %d ..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:423 #, python-format msgid "Examining %s" msgstr "åˆ†æž %s" #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:494 msgid "Getting scanner list ..." msgstr "æ­£åœ¨èŽ·å–æ‰«æä»ªåˆ—表 ..." #: paperwork-backend/src/paperwork_backend/docscan/libinsane.py:689 msgid "Scanner info." msgstr "扫æä»ªä¿¡æ¯ã€‚" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:9 msgid "English" msgstr "英语" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:10 msgid "French" msgstr "法语" #: paperwork-backend/src/paperwork_backend/i18n/pycountry.py:11 msgid "German" msgstr "德语" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:38 msgid "centrally aligned" msgstr "中心对é½" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:39 msgid "Feeder" msgstr "馈纸å¼" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:40 msgid "Flatbed" msgstr "å¹³å°å¼" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:41 msgid "left aligned" msgstr "左对é½" #: paperwork-backend/src/paperwork_backend/i18n/scanner.py:42 msgid "right aligned" msgstr "å³å¯¹é½" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:80 msgid "Color equalization" msgstr "色彩å‡è¡¡" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:92 msgid "Cropping" msgstr "è£å‰ª" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:103 msgid "Clockwise Rotation" msgstr "顺时针旋转" #: paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py:112 msgid "Counterclockwise Rotation" msgstr "逆时针旋转" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py:53 #, python-brace-format msgid "" "Using calibration to crop page borders of document {doc_id} page {page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py:57 #, python-brace-format msgid "Guessing page borders of document {doc_id} page {page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py:39 #, python-brace-format msgid "Guessing orientation on document {doc_id} page {page_idx}" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:50 #, python-brace-format msgid "Document {doc_id} p{page_idx} has already some text. No OCR run" msgstr "文档{doc_id}页é¢{page_idx}å·²ç»æœ‰ä¸€äº›æ–‡æœ¬ã€‚æ—  OCR è¿è¡Œ" #: paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py:58 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx}" msgstr "正在文档 {doc_id} é¡µé¢ {page_idx} 上è¿è¡Œ OCR" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:92 #, python-format msgid "Training label guesser with added document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:100 #, python-format msgid "Untraining label guesser due to deleted document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:107 #, python-format msgid "Training label guesser with updated document %s" msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:240 msgid "Training label guesser for label '{}' with all known documents ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/label/simplebayes.py:333 msgid "Training label guessing ..." msgstr "" #: paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py:53 #, python-brace-format msgid "Adjusting colors of document {doc_id} page {page_idx}" msgstr "调整文档 {doc_id} é¡µé¢ {page_idx} 的颜色" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:113 #, python-format msgid "Indexing new document %s" msgstr "索引新文档 %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:122 #, python-format msgid "Removing document %s from index" msgstr "从索引中移除文档 %s" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:132 #, python-format msgid "Indexing updated document %s" msgstr "文档 %s 索引更新中" #: paperwork-backend/src/paperwork_backend/index/whoosh.py:163 msgid "Committing changes in the index ..." msgstr "正在æäº¤ç´¢å¼•中的更改 ..." #: paperwork-backend/src/paperwork_backend/authors/translators.py:23 msgid "[]" msgstr "[\"玉堂白鹤\"]" paperwork-2.2.2/paperwork-backend/pyproject.toml000066400000000000000000000014131456262201400220430ustar00rootroot00000000000000[project] name = "paperwork-backend" description = "Paperwork's backend" dynamic = ["version"] authors = [ {name = "Jerome Flesch", email = "jflesch@openpaper.work" }, ] license = {text = "GPL-3.0-or-later"} readme = {file = "README.markdown", content-type = "text/markdown"} dependencies = [ "openpaperwork-core", "Pillow", "psutil", "pycountry", "pyocr", "pypillowfight>=0.3.0", "scikit-learn", "Whoosh", ] [project.optional-dependencies] dev = [ "pytest", ] lint = [ "flake8", ] [tool.setuptools_scm] root = ".." relative_to = "__file__" write_to = "paperwork-backend/src/paperwork_backend/_version.py" version_scheme = "post-release" [build-system] requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta" paperwork-2.2.2/paperwork-backend/src/000077500000000000000000000000001456262201400177175ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/000077500000000000000000000000001456262201400234005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/__init__.py000066400000000000000000000057431456262201400255220ustar00rootroot00000000000000import gettext import openpaperwork_core import openpaperwork_gtk def _(s): return gettext.dgettext('paperwork_backend', s) DEFAULT_CONFIG_PLUGINS = openpaperwork_core.MINIMUM_CONFIG_PLUGINS + [ 'paperwork_backend.app', ] DEFAULT_PLUGINS = ( openpaperwork_core.RECOMMENDED_PLUGINS + openpaperwork_gtk.CLI_PLUGINS + [ 'openpaperwork_core.beacon.stats', 'openpaperwork_core.beacon.sysinfo', 'openpaperwork_core.bug_report.censor', 'openpaperwork_core.censor', 'openpaperwork_core.pillow.img', 'openpaperwork_core.pillow.util', 'paperwork_backend.authors', 'paperwork_backend.authors.translators', 'paperwork_backend.beacon.update', 'paperwork_backend.cairo.blur', 'paperwork_backend.cairo.cache', 'paperwork_backend.cairo.pillow', 'paperwork_backend.cairo.poppler', 'paperwork_backend.chkworkdir.corrupted_page_map', 'paperwork_backend.chkworkdir.empty_doc', 'paperwork_backend.chkworkdir.file_at_workdir_root', 'paperwork_backend.chkworkdir.label_color', 'paperwork_backend.converter.libreoffice', 'paperwork_backend.datadirhandler', 'paperwork_backend.docexport.automatic', 'paperwork_backend.docexport.generic', 'paperwork_backend.docexport.img', 'paperwork_backend.docexport.pdf', 'paperwork_backend.docexport.pillowfight', 'paperwork_backend.docimport.converted', 'paperwork_backend.docimport.img', 'paperwork_backend.docimport.pdf', 'paperwork_backend.docscan.libinsane', 'paperwork_backend.docscan.scan2doc', 'paperwork_backend.doctracker', # ACE is disabled by default: it's slow, and actually makes some scans # harder to read. # 'paperwork_backend.guesswork.color.libpillowfight', 'paperwork_backend.guesswork.label.sklearn', 'paperwork_backend.guesswork.ocr.pyocr', 'paperwork_backend.guesswork.orientation.pyocr', 'paperwork_backend.i18n.pycountry', 'paperwork_backend.i18n.scanner', 'paperwork_backend.imgedit.color', 'paperwork_backend.imgedit.crop', 'paperwork_backend.imgedit.rotate', 'paperwork_backend.index.whoosh', 'paperwork_backend.l10n', 'paperwork_backend.model', 'paperwork_backend.model.converted', 'paperwork_backend.model.extra_text', 'paperwork_backend.model.hocr', 'paperwork_backend.model.img', 'paperwork_backend.model.img_overlay', 'paperwork_backend.model.labels', 'paperwork_backend.model.pdf', 'paperwork_backend.model.thumbnail', 'paperwork_backend.model.workdir', 'paperwork_backend.pageedit.pageeditor', 'paperwork_backend.pagetracker', 'paperwork_backend.pillow.pdf', 'paperwork_backend.poppler.file', 'paperwork_backend.poppler.memory', 'paperwork_backend.pyocr', 'paperwork_backend.sync', ] ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/app.py000066400000000000000000000005121456262201400245300ustar00rootroot00000000000000import openpaperwork_core from . import _version class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['app'] def app_get_name(self): return "Paperwork" def app_get_fs_name(self): return "paperwork2" def app_get_version(self): return _version.version paperwork-2.2.2/paperwork-backend/src/paperwork_backend/authors/000077500000000000000000000000001456262201400250655ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/authors/Makefile000066400000000000000000000006261456262201400265310ustar00rootroot00000000000000AUTHORS.git.json: $(CURDIR)/../../../../tools/get_git_authors.py $(CURDIR)/../../../.. >| $(CURDIR)/AUTHORS.git.json AUTHORS.json: \ ../../../../AUTHORS.ui.json \ AUTHORS.git.json $(CURDIR)/../../../../tools/merge_authors_json.py $^ \ >| $(CURDIR)/AUTHORS.json data: $(MAKE) clean $(MAKE) AUTHORS.json clean: rm -f $(CURDIR)/AUTHORS.git.json rm -f $(CURDIR)/AUTHORS.json .PHONY: clean data paperwork-2.2.2/paperwork-backend/src/paperwork_backend/authors/__init__.py000066400000000000000000000024741456262201400272050ustar00rootroot00000000000000import json import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['authors'] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, ] def authors_get(self, out: dict): file_path = self.core.call_success( "resources_get_file", "paperwork_backend.authors", "AUTHORS.json" ) if file_path is None: LOGGER.error("AUTHORS.json is missing !") return None try: with self.core.call_success("fs_open", file_path, 'r') as fd: content = fd.read() except FileNotFoundError as exc: LOGGER.error( "AUTHORS.json is missing ! (expected={})".format(file_path), exc_info=exc ) return None content = json.loads(content) for category in content: for (category_name, authors) in category.items(): out[category_name] = authors return True paperwork-2.2.2/paperwork-backend/src/paperwork_backend/authors/translators.py000066400000000000000000000014121456262201400300110ustar00rootroot00000000000000import json import logging import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['authors'] def authors_get(self, out: dict): try: translators = json.loads( # Translators: put your names here. See French translation # for reference. # Must valid JSON. Must be a list of strings (your names) _("[]") ) except json.JSONDecodeError as exc: LOGGER.error("Failed to load translator list", exc_info=exc) return translators = [('', translator, -1) for translator in translators] out['Translators'] = translators paperwork-2.2.2/paperwork-backend/src/paperwork_backend/beacon/000077500000000000000000000000001456262201400246275ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/beacon/__init__.py000066400000000000000000000000001456262201400267260ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/beacon/update.py000066400000000000000000000072701456262201400264710ustar00rootroot00000000000000import datetime import logging import os import re import openpaperwork_core import openpaperwork_core.beacon import openpaperwork_core.promise from .. import _version LOGGER = logging.getLogger(__name__) UPDATE_CHECK_INTERVAL = datetime.timedelta(days=7) UPDATE_PATH = "/beacon/latest" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.periodic = None self.http = None def get_interfaces(self): return ["update_detection"] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'http_json', 'defaults': ['openpaperwork_core.http'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def _register_config(self, core): setting = self.core.call_success( "config_build_simple", "update", "enabled", lambda: False ) self.core.call_all( "config_register", "check_for_update", setting ) setting = self.core.call_success( "config_build_simple", "update", "last_update_found", lambda: _version.version ) self.core.call_all( "config_register", "last_update_found", setting ) def _parse_version(self, version): version = re.split('[^0-9]', version)[:3] version = tuple([ int(x.strip()) for x in version if x.strip() != '' ]) return version def update_check(self): LOGGER.info("Looking for updates...") def on_success(update_data, core): latest_version = update_data['paperwork'][os.name] LOGGER.info("Version advertised: %s", latest_version) self.core.call_all( "config_put", "last_update_found", latest_version ) self.core.call_all("config_save") self.update_compare() promise = openpaperwork_core.promise.Promise(self.core, lambda: "") promise = promise.then(self.http.get_request_promise(UPDATE_PATH)) promise = promise.then(on_success, self.core) promise = promise.catch(self._on_upd_check_error) promise.schedule() def _on_upd_check_error(self, exc): LOGGER.warning("Failed to look for update", exc_info=exc) def update_compare(self): remote_version = self.core.call_success( "config_get", "last_update_found" ) remote_version = self._parse_version(remote_version) LOGGER.info("Remote version: %s", remote_version) local_version = self._parse_version(_version.version) LOGGER.info("Current version: %s", local_version) if remote_version > local_version: self.core.call_all( "on_update_detected", local_version, remote_version ) def init(self, core): super().init(core) self.periodic = openpaperwork_core.beacon.PeriodicTask( "update", UPDATE_CHECK_INTERVAL, self.update_check, self.update_compare ) self.http = self.core.call_success("http_json_get_client", "update") self._register_config(core) self.periodic.register_config(core) if self.core.call_success("config_get", "check_for_update"): self.core.call_all("mainloop_schedule", self.periodic.do, core) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/cairo/000077500000000000000000000000001456262201400244755ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/cairo/__init__.py000066400000000000000000000000001456262201400265740ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/cairo/blur.py000066400000000000000000000104141456262201400260130ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise CAIRO_AVAILABLE = False GLIB_AVAILABLE = False try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): pass try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): # dummy so chkdeps can still be called class GObject(object): class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass LOGGER = logging.getLogger(__name__) BLUR_FACTOR = 8 class BlurRenderer(GObject.GObject): __gsignals__ = { 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), } OUTLINE = (0.5, 0.5, 0.5) def __init__( self, core, work_queue_name, wrapped_renderer): super().__init__() self.core = core self.work_queue_name = work_queue_name self.wrapped_renderer = wrapped_renderer self.blurry = False wrapped_renderer.connect( "getting_size", self._on_wrapped_getting_size ) wrapped_renderer.connect( "size_obtained", self._on_wrapped_size_obtained ) wrapped_renderer.connect( "img_obtained", self._on_wrapped_img_obtained ) def __str__(self): return f"BlurRenderer({self.wrapped_renderer})" def _on_wrapped_getting_size(self, wrapped_renderer): self.emit('getting_size') def _on_wrapped_size_obtained(self, wrapped_renderer): self.emit('size_obtained') def _on_wrapped_img_obtained(self, wrapped_renderer): self.emit('img_obtained') @property def size(self): return self.wrapped_renderer.size def _set_zoom(self, z): self.wrapped_renderer.zoom = z def _get_zoom(self): return self.wrapped_renderer.zoom zoom = property(_get_zoom, _set_zoom) def start(self): self.wrapped_renderer.start() def render(self): self.wrapped_renderer.render() def hide(self): self.wrapped_renderer.hide() def close(self): self.wrapped_renderer.close() def draw(self, cairo_ctx): renderer = self.wrapped_renderer if not self.blurry: return renderer.draw(cairo_ctx) zoom = self.zoom / BLUR_FACTOR reduced_surface = cairo.ImageSurface( cairo.FORMAT_ARGB32, int(renderer.size[0] * zoom), int(renderer.size[1] * zoom), ) ctx = cairo.Context(reduced_surface) ctx.scale(1 / BLUR_FACTOR, 1 / BLUR_FACTOR) renderer.draw(ctx) cairo_ctx.save() try: cairo_ctx.scale(BLUR_FACTOR, BLUR_FACTOR) cairo_ctx.set_source_surface(reduced_surface) cairo_ctx.paint() finally: cairo_ctx.save() def blur(self): self.blurry = True self.wrapped_renderer.blur() def unblur(self): self.blurry = False self.wrapped_renderer.unblur() if GLIB_AVAILABLE: GObject.type_register(BlurRenderer) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 2000 def get_interfaces(self): return [ 'cairo_url', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'urls', 'defaults': ['openpaperwork_core.urls'], }, ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def cairo_renderer_by_url( self, work_queue_name, file_url, blur=True, **kwargs): if not blur: return None wrapped_renderer = self.core.call_success( "cairo_renderer_by_url", work_queue_name, file_url, blur=False, **kwargs ) if wrapped_renderer is None: LOGGER.error("Unable to get renderer for '%s' !?", file_url) return None return BlurRenderer( self.core, work_queue_name, wrapped_renderer ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/cairo/cache.py000066400000000000000000000112151456262201400261120ustar00rootroot00000000000000""" Rendering cache: actually used to keep a copy of the rendered page at the expected size, and only recompute it when the zoom level changes. Otherwise we overuse Poppler and some PDF may be slow to render correctly (those with full-page images in it for instance) """ import logging import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise CAIRO_AVAILABLE = False GLIB_AVAILABLE = False try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): pass try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): # dummy so chkdeps can still be called class GObject(object): class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass LOGGER = logging.getLogger(__name__) class CacheRenderer(GObject.GObject): __gsignals__ = { 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), } OUTLINE = (0.5, 0.5, 0.5) def __init__( self, core, work_queue_name, wrapped_renderer): super().__init__() self.core = core self.work_queue_name = work_queue_name self.wrapped_renderer = wrapped_renderer wrapped_renderer.connect( "getting_size", self._on_wrapped_getting_size ) wrapped_renderer.connect( "size_obtained", self._on_wrapped_size_obtained ) wrapped_renderer.connect( "img_obtained", self._on_wrapped_img_obtained ) self.rendering = None def __str__(self): return f"CacheRenderer({self.wrapped_renderer})" def _on_wrapped_getting_size(self, wrapped_renderer): self.emit('getting_size') def _on_wrapped_size_obtained(self, wrapped_renderer): self.emit('size_obtained') def _on_wrapped_img_obtained(self, wrapped_renderer): self.rendering = None self.emit('img_obtained') @property def size(self): return self.wrapped_renderer.size def _set_zoom(self, z): self.rendering = None self.wrapped_renderer.zoom = z def _get_zoom(self): return self.wrapped_renderer.zoom zoom = property(_get_zoom, _set_zoom) def start(self): self.wrapped_renderer.start() def render(self): self.wrapped_renderer.render() def hide(self): self.wrapped_renderer.hide() def close(self): self.rendering = None self.wrapped_renderer.close() def draw(self, cairo_ctx): if self.rendering is None: LOGGER.info("Cache miss. Rendering") renderer = self.wrapped_renderer rendering_w = int(renderer.size[0] * renderer.zoom) rendering_h = int(renderer.size[1] * renderer.zoom) rendering = cairo.ImageSurface( cairo.FORMAT_ARGB32, rendering_w, rendering_h ) rendering_ctx = cairo.Context(rendering) renderer.draw(rendering_ctx) self.rendering = rendering cairo_ctx.save() try: cairo_ctx.set_source_surface(self.rendering) cairo_ctx.paint() finally: cairo_ctx.restore() def blur(self): self.rendering = None self.wrapped_renderer.blur() def unblur(self): self.rendering = None self.wrapped_renderer.unblur() if GLIB_AVAILABLE: GObject.type_register(CacheRenderer) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def get_interfaces(self): return [ 'cairo_url', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'urls', 'defaults': ['openpaperwork_core.urls'], }, ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def cairo_renderer_by_url( self, work_queue_name, file_url, cache=True, **kwargs): if not cache: return None wrapped_renderer = self.core.call_success( "cairo_renderer_by_url", work_queue_name, file_url, cache=False, **kwargs ) if wrapped_renderer is None: LOGGER.error("Unable to get renderer for '%s' !?", file_url) return None return CacheRenderer( self.core, work_queue_name, wrapped_renderer ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/cairo/pillow.py000066400000000000000000000232271456262201400263630ustar00rootroot00000000000000import array import io import logging import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise CAIRO_AVAILABLE = False GLIB_AVAILABLE = False try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): pass try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): # dummy so chkdeps can still be called class GObject(object): # type: ignore[no-redef] class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass DELAY_SHORT = 0.01 DELAY_LONG = 0.3 LOGGER = logging.getLogger(__name__) MAX_IMG_DIMENSION = 16 * 1024 - 1 class ImgSurface(object): # wrapper so it can be weakref def __init__(self, surface): self.surface = surface def limit_img_size(size): (width, height) = size # Handle Cairo limitation: Dimensions of the image can't exceed 32k if width > MAX_IMG_DIMENSION: width = MAX_IMG_DIMENSION if height > MAX_IMG_DIMENSION: height = MAX_IMG_DIMENSION return (width, height) def pillow_to_surface(core, img, intermediate="pixbuf", quality=90): """ Convert a PIL image into a Cairo surface """ if intermediate != "jpeg": img.putalpha(256) (width, height) = img.size img = img.convert("RGBA") imgd = img.tobytes('raw', 'BGRA') imga = array.array('B', imgd) stride = width * 4 return ImgSurface(cairo.ImageSurface.create_for_data( imga, cairo.FORMAT_ARGB32, width, height, stride )) else: img = img.convert("RGB") if not hasattr(cairo.ImageSurface, 'set_mime_data'): LOGGER.warning( "Cairo %s does not support yet 'set_mime_data'." " Cannot include image as JPEG in the PDF." " Image will be included as PNG (much bigger)", cairo.version ) intermediate = 'png' else: # IMPORTANT: The actual surface will be empty. # but mime-data will have attached the correct data # to the surface that supports it img_surface = ImgSurface(cairo.ImageSurface( cairo.FORMAT_RGB24, img.size[0], img.size[1] )) img_io = io.BytesIO() img.save(img_io, format="JPEG", quality=quality) img_io.seek(0) data = img_io.read() img_surface.surface.set_mime_data(cairo.MIME_TYPE_JPEG, data) if img_surface is None: raise Exception( "pillow_to_surface(): unknown intermediate: {}".format( intermediate ) ) core.call_all("on_objref_track", img_surface) return img_surface class CairoRenderer(GObject.GObject): __gsignals__ = { 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), } BACKGROUND = (0.5, 0.5, 0.5) OUTLINE = (0.5, 0.5, 0.5) def __init__(self, core, work_queue_name, file_url): super().__init__() self.core = core self.work_queue_name = work_queue_name self.file_url = file_url self.size = (0, 0) self.zoom = 1.0 self.cairo_surface = None self.visible = False promise = openpaperwork_core.promise.Promise( self.core, self.emit, args=("getting_size",) ) promise = promise.then( core.call_success("url_to_img_size_promise", file_url) ) promise = promise.then(self._set_img_size) # Gives back a bit of CPU time to GTK so the GUI remains # usable promise = promise.then(openpaperwork_core.promise.DelayPromise( core, DELAY_SHORT )) self.get_size_promise = promise self.getting_size = False # Gives back a bit of CPU time to GTK so the GUI remains # usable # Give also time so the loading can be cancelled promise = openpaperwork_core.promise.DelayPromise( core, DELAY_LONG ) promise = promise.then(core.call_success( "url_to_cairo_surface_promise", file_url )) promise = promise.then(self._set_cairo_surface) self.render_img_promise = promise self.render_job_in_queue = False def start(self): if self.getting_size: # seems render() may be called before start() in some cases # --> avoid calling twice work_queue_add_promise() to get the size return self.core.call_success( "work_queue_add_promise", self.work_queue_name, self.get_size_promise ) self.getting_size = True def render(self, force=False): if self.visible and not force: return self.visible = True if self.size == (0, 0): self.core.call_all( "work_queue_cancel", self.work_queue_name, self.get_size_promise ) # re add with a higher priority self.core.call_success( "work_queue_add_promise", self.work_queue_name, self.get_size_promise, priority=200 ) self.getting_size = True return if self.render_job_in_queue: return self.render_job_in_queue = True self.core.call_success( "work_queue_add_promise", self.work_queue_name, self.render_img_promise, priority=100 ) def hide(self): if not self.visible: return self.visible = False if self.size == (0, 0): self.core.call_all( "work_queue_cancel", self.work_queue_name, self.get_size_promise ) # re add with a lower priority self.core.call_success( "work_queue_add_promise", self.work_queue_name, self.get_size_promise ) self.getting_size = True if self.cairo_surface is not None: self.cairo_surface.surface.finish() self.cairo_surface = None self.render_job_in_queue = False self.core.call_all( "work_queue_cancel", self.work_queue_name, self.render_img_promise ) def close(self): self.hide() self.core.call_all( "work_queue_cancel", self.work_queue_name, self.get_size_promise ) self.get_size_promise = None self.getting_size = False self.render_img_promise = None def _set_img_size(self, size): self.size = limit_img_size(size) self.getting_size = False if self.get_size_promise is None: # Document has been closed while we looked for its size return self.emit("size_obtained") if self.visible: self.render(force=True) def _set_cairo_surface(self, surface): self.render_job_in_queue = False if not self.visible: # visibility has changed surface.surface.finish() return self.cairo_surface = surface self.emit("img_obtained") def _draw(self, cairo_ctx): cairo_ctx.save() try: cairo_ctx.scale(self.zoom, self.zoom) cairo_ctx.set_source_surface(self.cairo_surface.surface) cairo_ctx.paint() size = self.size cairo_ctx.set_source_rgb(*self.OUTLINE) cairo_ctx.set_line_width(1) cairo_ctx.rectangle( 0, 0, size[0] - 1, size[1] - 1 ) cairo_ctx.stroke() finally: cairo_ctx.restore() def draw(self, cairo_ctx): if self.cairo_surface is None: cairo_ctx.save() try: size = self.size cairo_ctx.set_source_rgb(*self.BACKGROUND) cairo_ctx.rectangle(0, 0, size[0], size[1]) cairo_ctx.clip() cairo_ctx.paint() finally: cairo_ctx.restore() else: self._draw(cairo_ctx) def blur(self): pass def unblur(self): pass if GLIB_AVAILABLE: GObject.type_register(CairoRenderer) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'cairo_url', 'pillow_to_surface', ] def get_deps(self): return [ { 'interface': 'pillow', 'defaults': ['openpaperwork_core.pillow.img'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def pillow_to_surface(self, pillow, intermediate="pixbuf", quality=90): return pillow_to_surface(self.core, pillow, intermediate, quality) def url_to_cairo_surface_promise(self, file_url): promise = self.core.call_success("url_to_pillow_promise", file_url) promise = promise.then(self.pillow_to_surface) return promise def url_to_cairo_surface(self, file_url): pil_img = self.core.call_success("url_to_pillow", file_url) return self.pillow_to_surface(pil_img) def cairo_renderer_by_url(self, work_queue_name, file_url, **kwargs): return CairoRenderer(self.core, work_queue_name, file_url) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/cairo/poppler.py000066400000000000000000000257231456262201400265410ustar00rootroot00000000000000from typing import Any from typing import Dict from typing import Tuple import logging import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise # TODO(Jflesch): bad import paperwork_backend.model.pdf CAIRO_AVAILABLE = False GLIB_AVAILABLE = False try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): pass try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): # dummy so chkdeps can still be called class GObject(object): # type: ignore[no-redef] class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass LOGGER = logging.getLogger(__name__) DELAY = 0.01 POPPLER_DOCS: Dict[str, Tuple[Any, int]] = {} class ImgSurface(object): # wrapper so it can be weakref def __init__(self, surface): self.surface = surface class CairoRenderer(GObject.GObject): __gsignals__ = { 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), } OUTLINE = (0.5, 0.5, 0.5) def __init__( self, core, work_queue_name, file_url, page_idx, password=None): global POPPLER_DOCS super().__init__() self.core = core self.work_queue_name = work_queue_name self.file_url = file_url self.page_idx = page_idx self.password = password self.visible = False self.size = (0, 0) self.zoom = 1.0 if file_url in POPPLER_DOCS: (doc, refcount) = POPPLER_DOCS[file_url] else: LOGGER.info("Opening PDF file {}".format(file_url)) doc = self.core.call_success( "poppler_open", file_url, password=password ) refcount = 0 POPPLER_DOCS[file_url] = (doc, refcount + 1) self.page = doc.get_page(page_idx) promise = openpaperwork_core.promise.Promise( self.core, self.emit, args=("getting_size",) ) promise = promise.then(openpaperwork_core.promise.Promise( self.core, self.page.get_size )) promise = promise.then(lambda size: ( size[0] * paperwork_backend.model.pdf.PDF_RENDER_FACTOR, size[1] * paperwork_backend.model.pdf.PDF_RENDER_FACTOR, )) promise.then(self._set_size) if page_idx % 25 == 0: # Gives back a bit of CPU time to GTK so the GUI remains # usable, but not too much so we don't recompute the layout too # often promise = promise.then(openpaperwork_core.promise.DelayPromise( core, DELAY )) self.get_size_promise = promise def __str__(self): return "CairoRenderer({} p{})".format(self.file_url, self.page_idx) def _set_size(self, size): if self.page is None: # Document has been closed while we looked for its size return self.size = size self.emit('size_obtained') if self.visible: self.render(force=True) def start(self): self.core.call_success( "work_queue_add_promise", self.work_queue_name, self.get_size_promise ) def render(self, force=False): if self.visible and not force: return self.visible = True if self.size == (0, 0): return self.emit('img_obtained') def hide(self): self.visible = False def close(self): global POPPLER_DOCS self.hide() self.page = None self.size = (0, 0) (doc, refcount) = POPPLER_DOCS.get(self.file_url, (None, None)) if refcount is None: LOGGER.warning("Double close for %s", self.file_url) return refcount -= 1 if refcount > 0: POPPLER_DOCS[self.file_url] = (doc, refcount) return LOGGER.info("Closing PDF file %s", self.file_url) POPPLER_DOCS.pop(self.file_url, None) def _draw(self, cairo_ctx, zoom): try: cairo_ctx.save() try: cairo_ctx.set_source_rgb(1.0, 1.0, 1.0) cairo_ctx.scale(zoom, zoom) cairo_ctx.rectangle(0, 0, self.size[0], self.size[1]) cairo_ctx.scale( paperwork_backend.model.pdf.PDF_RENDER_FACTOR, paperwork_backend.model.pdf.PDF_RENDER_FACTOR, ) cairo_ctx.clip() cairo_ctx.paint() self.page.render(cairo_ctx) cairo_ctx.scale( 1 / paperwork_backend.model.pdf.PDF_RENDER_FACTOR, 1 / paperwork_backend.model.pdf.PDF_RENDER_FACTOR, ) cairo_ctx.set_source_rgb(*self.OUTLINE) outline_width = 1 / zoom cairo_ctx.set_line_width(outline_width) cairo_ctx.rectangle( 0, 0, self.size[0] - outline_width, self.size[1] - outline_width ) cairo_ctx.stroke() finally: cairo_ctx.restore() except Exception as exc: LOGGER.error("CairoRenderer.draw() failed (PDF)", exc_info=exc) # WORKAROUND(Jflesch): with some malformed PDF file, we get an # exception on ctx.restore(), but the drawing was actually done. def draw(self, cairo_ctx): if not self.visible or self.page is None or self.size[0] == 0: return task = "pdf_to_cairo_draw({}, p{})".format( self.file_url, self.page_idx ) self.core.call_all("on_perfcheck_start", task) self._draw(cairo_ctx, self.zoom) self.core.call_all("on_perfcheck_stop", task, size=self.size) def blur(self): pass def unblur(self): pass if GLIB_AVAILABLE: GObject.type_register(CairoRenderer) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 FILE_EXTENSION = ".pdf" def get_interfaces(self): return [ 'cairo_url', 'chkdeps', 'page_img_size', 'pdf_cairo_url', ] def get_deps(self): return [ { 'interface': 'poppler', 'defaults': ['paperwork_backend.poppler.memory'], }, { 'interface': 'urls', 'defaults': ['openpaperwork_core.urls'], }, ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def _check_is_pdf(self, file_url): (url, args) = self.core.call_success("url_args_split", file_url) if not url.lower().endswith(self.FILE_EXTENSION): return (None, None, None) password = args.get('password', None) if password is not None: password = bytes.fromhex(password).decode("utf-8") page_idx = int(args.get('page', 1)) - 1 return (url, page_idx, password) def url_to_img_size(self, file_url): (file_url, page_idx, password) = self._check_is_pdf(file_url) if file_url is None: return None task = "url_to_img_size({})".format(file_url) self.core.call_all("on_perfcheck_start", task) doc = self.core.call_success( "poppler_open", file_url, password=password ) page = doc.get_page(page_idx) base_size = page.get_size() size = ( # scale up because default size if too small for reading int(base_size[0]) * paperwork_backend.model.pdf.PDF_RENDER_FACTOR, int(base_size[1]) * paperwork_backend.model.pdf.PDF_RENDER_FACTOR, ) self.core.call_all("on_perfcheck_stop", task, size=size) return size def url_to_img_size_promise(self, file_url): (page_url, page_idx, password) = self._check_is_pdf(file_url) if page_url is None: return None return openpaperwork_core.promise.Promise( self.core, self.url_to_img_size, args=(file_url,) ) def pdf_page_to_cairo_surface(self, file_url, page_idx, password=None): task = "pdf_page_to_cairo_surface({} p{})".format(file_url, page_idx) self.core.call_all("on_perfcheck_start", task) doc = self.core.call_success( "poppler_open", file_url, password=password ) page = doc.get_page(page_idx) # WORKAROUND(Jflesch): # Some corrupted PDFs may cause `page = None` here. (PDF declaring # more pages than they actually have). if page is None: return None base_size = page.get_size() size = ( # scale up because default size if too small for reading int(base_size[0]) * paperwork_backend.model.pdf.PDF_RENDER_FACTOR, int(base_size[1]) * paperwork_backend.model.pdf.PDF_RENDER_FACTOR, ) width = int(size[0]) height = int(size[1]) factor_w = width / base_size[0] factor_h = height / base_size[1] surface = ImgSurface(cairo.ImageSurface( cairo.FORMAT_ARGB32, width, height )) self.core.call_all("on_objref_track", surface) try: ctx = cairo.Context(surface.surface) ctx.save() try: ctx.set_source_rgb(1.0, 1.0, 1.0) ctx.rectangle(0, 0, width, height) ctx.clip() ctx.paint() ctx.scale(factor_w, factor_h) page.render(ctx) finally: ctx.restore() except Exception as exc: LOGGER.error("pdf_page_to_cairo_surface() failed", exc_info=exc) # WORKAROUND(Jflesch): with some malformed PDF file, we get an # exception on ctx.restore(), but the drawing was actually done. self.core.call_all("on_perfcheck_stop", task, size=(width, height)) return surface def url_to_cairo_surface(self, file_url): (file_url, page_idx, password) = self._check_is_pdf(file_url) if file_url is None: return None return self.pdf_page_to_cairo_surface(file_url, page_idx, password) def url_to_cairo_surface_promise(self, file_url): (file_url, page_idx, password) = self._check_is_pdf(file_url) if file_url is None: return None return openpaperwork_core.promise.Promise( self.core, self.pdf_page_to_cairo_surface, args=(file_url, page_idx, password) ) def cairo_renderer_by_url(self, work_queue_name, file_url, **kwargs): (file_url, page_idx, password) = self._check_is_pdf(file_url) if file_url is None: return None return CairoRenderer( self.core, work_queue_name, file_url, page_idx, password ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/chkworkdir/000077500000000000000000000000001456262201400255475ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/chkworkdir/__init__.py000066400000000000000000000000001456262201400276460ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/chkworkdir/corrupted_page_map.py000066400000000000000000000121751456262201400317670ustar00rootroot00000000000000from typing import List from typing import Tuple import logging import re import openpaperwork_core import paperwork_backend.model.pdf from .. import _ LOGGER = logging.getLogger(__name__) PAGE_FILENAME_REGEX = re.compile(r"paper\.(\d+)\.(.*)") PAGE_FILENAME_FMT = "paper.{idx}.{file_ext}" class Plugin(openpaperwork_core.PluginBase): """ Label files in each document contains both the label names and their color. If the user changes a label color, label files are updated one-by-one. If this process is interrupted, we end up with 2 colors for the same label. """ PRIORITY = 10000 def get_interfaces(self): return ['chkworkdir'] def get_deps(self): return [ { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'doc_pdf_url', 'defaults': ['paperwork_backend.model.pdf'], }, ] def check_work_dir(self, out_problems: list): all_docs: List[Tuple[str, str]] = [] self.core.call_all("storage_get_all_docs", all_docs, only_valid=False) all_docs.sort() total = len(all_docs) LOGGER.info("Checking work directory (%d documents)", total) for (idx, (doc_id, doc_url)) in enumerate(all_docs): self.core.call_all( "on_progress", "chkworkdir_corrupted_page_map", idx / total, _("Checking doc %s") % (doc_id,) ) page_map_url = self.core.call_success( "fs_join", doc_url, paperwork_backend.model.pdf.PdfPageMapping.MAPPING_FILE ) if not self.core.call_success("fs_exists", page_map_url): continue # simplest way to see if the page map is readable is to # try to get the number of pages of the doc try: self.core.call_success("doc_get_nb_pages_by_url", doc_url) continue except Exception: out_problems.append({ "problem": "corrupted_page_map", "doc_id": doc_id, "doc_url": doc_url, "human_description": { "problem": ( _( "Page mapping of document %s has been" " corrupted" ) % (doc_id,) ), "solution": ( _( "Page mapping of document %s must be" " reinitialized" ) % (doc_id,) ) } }) self.core.call_all("on_progress", "chkworkdir_corrupted_page_map", 1.0) def fix_work_dir(self, problems): total = len(problems) for (idx, problem) in enumerate(problems): if problem['problem'] != 'corrupted_page_map': continue doc_id = problem['doc_id'] doc_url = problem['doc_url'] LOGGER.info("Fixing document %s", doc_url) self.core.call_all( "on_progress", "fixworkdir_corrupted_page_map", idx / total, _("Fixing page mapping of doc %s") % (doc_id,) ) page_map_url = self.core.call_success( "fs_join", doc_url, paperwork_backend.model.pdf.PdfPageMapping.MAPPING_FILE ) if self.core.call_success("fs_exists", page_map_url): self.core.call_success("fs_unlink", page_map_url) # Move all the scanned page files after the PDF pages doc_nb_pages = self.core.call_success( "doc_pdf_get_real_nb_pages_by_url", doc_url ) page_map = {} files = self.core.call_success("fs_listdir", doc_url) if files is None: return None for file_url in files: file_name = self.core.call_success("fs_basename", file_url) match = PAGE_FILENAME_REGEX.match(file_name) if match is None: continue old_page_nb = int(match.group(1)) file_ext = match.group(2) if old_page_nb in page_map: new_page_nb = page_map[old_page_nb] else: new_page_nb = doc_nb_pages + 1 doc_nb_pages += 1 page_map[old_page_nb] = new_page_nb new_page_url = self.core.call_success( "fs_join", doc_url, PAGE_FILENAME_FMT.format( idx=new_page_nb, file_ext=file_ext ) ) self.core.call_success("fs_rename", file_url, new_page_url) self.core.call_all("on_progress", "fixworkdir_corrupted_page_map", 1.0) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/chkworkdir/empty_doc.py000066400000000000000000000052211456262201400301040ustar00rootroot00000000000000import logging import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): """ Locates (and optionnally deletes) empty directories in the work directory. """ def get_interfaces(self): return ['chkworkdir'] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'nb_pages', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, ] def check_work_dir(self, out_problems: list): all_docs = [] self.core.call_all("storage_get_all_docs", all_docs, only_valid=False) all_docs.sort() total = len(all_docs) LOGGER.info("Checking work directory (%d documents)", total) for (idx, (doc_id, doc_url)) in enumerate(all_docs): self.core.call_all( "on_progress", "chkworkdir_empty_doc", idx / total, _("Checking doc %s") % (doc_id,) ) isdir = self.core.call_success("fs_isdir", doc_url) if not isdir: continue try: nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) except Exception: # handled by 'paperwork_backend.chkworkdir.corrupted_page_map' continue if nb_pages is not None and nb_pages > 0: continue out_problems.append({ "problem": "empty_doc", "doc_id": doc_id, "doc_url": doc_url, "human_description": { "problem": _("Document %s is empty") % (doc_id,), "solution": _("Delete document %s") % (doc_id,), }, }) self.core.call_all("on_progress", "chkworkdir_empty_doc", 1.0) def fix_work_dir(self, problems): total = len(problems) for (idx, problem) in enumerate(problems): if problem['problem'] != 'empty_doc': continue LOGGER.info("Fixing document %s", problem['doc_url']) self.core.call_all( "on_progress", "fixworkdir_empty_doc", idx / total, _("Deleting empty doc %s") % (problem['doc_id'],) ) self.core.call_all("storage_delete_doc_id", problem['doc_id']) self.core.call_all("on_progress", "fixworkdir_empty_doc", 1.0) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/chkworkdir/file_at_workdir_root.py000066400000000000000000000066441456262201400323420ustar00rootroot00000000000000import logging import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): """ Locates (and optionally deletes) files at the root of the work directory. """ def get_interfaces(self): return ['chkworkdir'] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'doc_pdf_import', 'defaults': ['paperwork_backend.model.pdf'], }, ] def check_work_dir(self, out_problems: list): all_docs = [] self.core.call_all("storage_get_all_docs", all_docs, only_valid=False) all_docs.sort() total = len(all_docs) LOGGER.info("Checking work directory (%d documents)", total) for (idx, (doc_id, doc_url)) in enumerate(all_docs): self.core.call_all( "on_progress", "chkworkdir_file_at_workdir_root", idx / total, _("Checking doc %s") % (doc_id,) ) isdir = self.core.call_success("fs_isdir", doc_url) if isdir: continue if doc_url.lower().endswith(".pdf"): out_problems.append({ "problem": "file_at_workdir_root", "doc_id": doc_id, "doc_url": doc_url, "human_description": { "problem": _("Document %s is not a directory") % ( doc_id, ), "solution": _( "Turn %s into /doc.pdf" ) % ( doc_id, ), }, "solution": "import_pdf", }) else: out_problems.append({ "problem": "file_at_workdir_root", "doc_id": doc_id, "doc_url": doc_url, "human_description": { "problem": _("Document %s is not a directory") % ( doc_id, ), "solution": _("Delete document %s") % (doc_id,), }, "solution": "delete", }) self.core.call_all( "on_progress", "chkworkdir_file_at_workdir_root", 1.0 ) def fix_work_dir(self, problems): total = len(problems) for (idx, problem) in enumerate(problems): if problem['problem'] != 'file_at_workdir_root': continue self.core.call_all( "on_progress", "fixworkdir_file_at_workdir_root", idx / total, _("Fixing %s") % (problem['doc_url'],) ) if problem['solution'] == "import_pdf": LOGGER.info("Importing %s", problem['doc_url']) self.core.call_success("doc_pdf_import", problem['doc_url']) self.core.call_success("fs_unlink", problem['doc_url']) else: LOGGER.info("Deleting %s", problem['doc_url']) self.core.call_all("fs_unlink", problem['doc_url']) self.core.call_all( "on_progress", "fixworkdir_file_at_workdir_root", 1.0 ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/chkworkdir/label_color.py000066400000000000000000000123071456262201400304010ustar00rootroot00000000000000import logging import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): """ Label files in each document contains both the label names and their color. If the user changes a label color, label files are updated one-by-one. If this process is interrupted, we end up with 2 colors for the same label. """ def get_interfaces(self): return ['chkworkdir'] def get_deps(self): return [ { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, ] @staticmethod def _is_same_color(a, b): a = (int(a[0] * 0xFF), int(a[1] * 0xFF), int(a[2] * 0xFF)) b = (int(b[0] * 0xFF), int(b[1] * 0xFF), int(b[2] * 0xFF)) return a == b def check_work_dir(self, out_problems: list): all_docs = [] self.core.call_all("storage_get_all_docs", all_docs, only_valid=False) all_docs.sort() total = len(all_docs) LOGGER.info("Checking work directory (%d documents)", total) # label text --> ( # label color, first_seen_doc_id, first_seen_exact_color # ) first_seen_labels = {} for (idx, (doc_id, doc_url)) in enumerate(all_docs): self.core.call_all( "on_progress", "chkworkdir_label_color", idx / total, _("Checking doc %s") % (doc_id,) ) doc_labels = set() self.core.call_all("doc_get_labels_by_url", doc_labels, doc_url) for (doc_label_txt, doc_label_color_orig) in doc_labels: doc_label_color = self.core.call_success( "label_color_to_rgb", doc_label_color_orig ) first_color = first_seen_labels.get(doc_label_txt, None) if first_color is None: first_seen_labels[doc_label_txt] = ( doc_label_color, doc_id, doc_label_color_orig ) continue (first_color, first_docid, first_exact_color) = first_color if self._is_same_color(first_color, doc_label_color): continue out_problems.append({ "problem": "label_color", "doc_id": doc_id, "doc_url": doc_url, "problem_color": doc_label_color, "solution_color": first_color, "current_label": (doc_label_txt, doc_label_color), "fixed_label": (doc_label_txt, first_exact_color), "human_description": { "problem": ( _( "Document %s has label \"%s\" with color=%s" " while document %s has label" " \"%s\" with color=%s" ) % ( doc_id, doc_label_txt, self.core.call_success( "label_color_rgb_to_text", doc_label_color ), first_docid, doc_label_txt, self.core.call_success( "label_color_rgb_to_text", first_color ) ) ), "solution": ( _( "Set label color %s on label \"%s\"" " of document %s" ) % ( self.core.call_success( "label_color_rgb_to_text", first_color ), doc_label_txt, doc_id ) ) } }) self.core.call_all("on_progress", "chkworkdir_label_color", 1.0) def fix_work_dir(self, problems): total = len(problems) for (idx, problem) in enumerate(problems): if problem['problem'] != 'label_color': continue LOGGER.info("Fixing document %s", problem['doc_url']) self.core.call_all( "on_progress", "fixworkdir_label_color", idx / total, _("Fixing label on doc %s") % (problem['doc_id'],) ) self.core.call_success( "doc_remove_label_by_url", problem['doc_url'], problem['current_label'][0] ) self.core.call_success( "doc_add_label_by_url", problem['doc_url'], problem['fixed_label'][0], problem['fixed_label'][1] ) self.core.call_all("on_progress", "fixworkdir_label_color", 1.0) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/converter/000077500000000000000000000000001456262201400254075ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/converter/__init__.py000066400000000000000000000000001456262201400275060ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/converter/libreoffice.py000066400000000000000000000212371456262201400302370ustar00rootroot00000000000000import logging import os import subprocess import tempfile import openpaperwork_core import paperwork_backend.deps from .. import _ LOGGER = logging.getLogger(__name__) LIBREOFFICE = [ r'libreoffice', r'soffice', r'soffice.exe', r'C:\Program Files\LibreOffice\program\soffice.exe', r'/app/libreoffice/program/soffice.bin', # Flatpak ] LIBREOFFICE_ARGS = [ '--nocrashreport', '--nodefault', '--nofirststartwizard', '--nolockcheck', '--nologo', '--norestore', '--headless', '--convert-to', 'pdf', '--outdir', '{out_dir}', '{in_doc}', ] def is_exe(fpath): return os.path.isfile(fpath) and os.access(fpath, os.X_OK) def which(program): if os.path.sep in program: if is_exe(program): return program else: for path in os.environ["PATH"].split(os.pathsep): exe_file = os.path.join(path, program) if is_exe(exe_file): return exe_file return None class Plugin(openpaperwork_core.PluginBase): FILE_TYPES = { ( "application/msword", "doc", "Microsoft Word (.doc)", ), ( "application/msword", "dot", _("Microsoft Word template (.dot)"), ), ( "application/vnd.ms-excel", "xls", "Microsoft Excel (.xls)", ), ( "application/vnd.ms-excel", "xlt", _("Microsoft Excel template (.xlt)"), ), ( "application/vnd.ms-powerpoint", "pps", "Microsoft PowerPoint (.pps)", ), ( "application/vnd.ms-powerpoint", "ppt", _("Microsoft PowerPoint template (.ppt)"), ), ( "application/vnd.oasis.opendocument.chart", "odc", _("OpenOffice/LibreOffice Chart (.odc)"), ), ( "application/vnd.oasis.opendocument.database", "odb", _("OpenOffice/LibreOffice Database (.odb)"), ), ( "application/vnd.oasis.opendocument.formula", "odf", _("OpenOffice/LibreOffice Formula (.odf)"), ), ( "application/vnd.oasis.opendocument.graphics", "odg", _("OpenOffice/LibreOffice Graphics (.odg)"), ), ( "application/vnd.oasis.opendocument.graphics-template", "otg", _("OpenOffice/LibreOffice Graphics template (.otg)"), ), ( "application/vnd.oasis.opendocument.image", "odi", _("OpenOffice/LibreOffice Image template (.odi)"), ), ( "application/vnd.oasis.opendocument.presentation", "odp", _("OpenOffice/LibreOffice Presentation (.odp)"), ), ( "application/vnd.oasis.opendocument.presentation-template", "otp", _("OpenOffice/LibreOffice Presentation template (.otp)"), ), ( "application/vnd.oasis.opendocument.spreadsheet", "ods", _("OpenOffice/LibreOffice Spreadsheet (.ods)"), ), ( "application/vnd.oasis.opendocument.spreadsheet-template", "ots", _("OpenOffice/LibreOffice Spreadsheet template (.ots)"), ), ( "application/vnd.oasis.opendocument.text", "odt", _("OpenOffice/LibreOffice Text (.odt)"), ), ( "application/vnd.oasis.opendocument.text-master", "odm", _("OpenOffice/LibreOffice Text master (.odm)"), ), ( "application/vnd.oasis.opendocument.text-template", "ott", _("OpenOffice/LibreOffice Text template (.ott)"), ), ( "application/vnd.oasis.opendocument.text-web", "oth", _("OpenOffice/LibreOffice Text web (.oth)"), ), ( "application/vnd.openxmlformats-officedocument.presentationml" ".presentation", "pptx", "Microsoft PowerPoint presentation (.pptx)", ), ( "application/vnd.openxmlformats-officedocument.presentationml" ".slide", "sldx", _("Microsoft PowerPoint slide (.sldx)"), ), ( "application/vnd.openxmlformats-officedocument.presentationml" ".slideshow", "ppsx", _("Microsoft PowerPoint slideshow (.ppsx)"), ), ( "application/vnd.openxmlformats-officedocument.presentationml" ".template", "potx", _("Microsoft PowerPoint presentation template (.potx)"), ), ( "application/vnd.openxmlformats-officedocument.spreadsheetml" ".sheet", "xlsx", "Microsoft Excel (.xlsx)", ), ( "application/vnd.openxmlformats-officedocument.spreadsheetml" ".template", "xltx", _("Microsoft Excel template (.xltx)"), ), ( "application/vnd.openxmlformats-officedocument" ".wordprocessingml.document", "docx", "Microsoft Word (.docx)", ), ( "application/vnd.openxmlformats-officedocument" ".wordprocessingml.template", "dotx", _("Microsoft Word template (.dotx)"), ), } def __init__(self): self.libreoffice = None def get_interfaces(self): return [ "chkdeps", "doc_converter", ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'] }, ] def init(self, core): super().init(core) for exe in LIBREOFFICE: self.libreoffice = which(exe) if self.libreoffice is not None: break LOGGER.info("Libreoffice: %s", self.libreoffice) def chkdeps(self, out: dict): if self.libreoffice is None: out['libreoffice'] = paperwork_backend.deps.LIBREOFFICE def converter_get_file_types(self, out: set): if self.libreoffice is None: return out.update(self.FILE_TYPES) def convert_file_to_pdf(self, doc_file_uri, mime_type, out_pdf_file_url): if self.libreoffice is None: return None file_types = {mime: ext for (mime, ext, desc) in self.FILE_TYPES} if mime_type not in file_types: return None LOGGER.info( "Converting %s (%s) to %s (PDF)", doc_file_uri, mime_type, out_pdf_file_url ) file_name = self.core.call_success("fs_basename", doc_file_uri) if "." not in file_name: LOGGER.error("No file extension ? %s", doc_file_uri) return None file_ext = file_name.rsplit(".", 1)[-1] cwd = os.getcwd() with tempfile.TemporaryDirectory() as tmp_dir: src_file = os.path.join(tmp_dir, "doc." + file_ext) dst_file = os.path.join(tmp_dir, "doc.pdf") # Assume Libreoffice only supports local files self.core.call_success( "fs_copy", doc_file_uri, self.core.call_success("fs_safe", src_file) ) if not self.core.call_success( "fs_exists", self.core.call_success("fs_safe", src_file)): LOGGER.error("Failed to copy file %s", doc_file_uri) return None os.chdir(tmp_dir) try: args = [ x.format(in_doc=src_file, out_dir=tmp_dir) for x in LIBREOFFICE_ARGS ] popen = subprocess.Popen( [self.libreoffice] + args, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) with popen: (stdout, stderr) = popen.communicate() dst_file_url = self.core.call_success("fs_safe", dst_file) if not self.core.call_success("fs_exists", dst_file_url): LOGGER.error( "Failed to convert %s (%s) to %s|%s (PDF)", doc_file_uri, mime_type, dst_file_url, out_pdf_file_url ) LOGGER.error("Command was: %s", [self.libreoffice] + args) LOGGER.error("LibreOffice stdout: %s", stdout) LOGGER.error("LibreOffice stderr: %s", stderr) return False self.core.call_success( "fs_copy", dst_file_url, out_pdf_file_url ) finally: os.chdir(cwd) return True paperwork-2.2.2/paperwork-backend/src/paperwork_backend/datadirhandler.py000066400000000000000000000064611456262201400267270ustar00rootroot00000000000000""" This plugin handles different working directories by hashing their path and adding a part of this hash to the data directory. If a working directly was not loaded for at least one month, it is deleted, again. """ import datetime import logging import base64 import hashlib import os import openpaperwork_core LOGGER = logging.getLogger(__name__) WORK_DIR_NAME = "workdir_data" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ["data_dir_handler"] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, ] def init(self, core): super().init(core) self._delete_old_directories() def on_storage_changed(self): LOGGER.info( "Work directory has changed --> data directory has to change too" ) self.core.call_all("on_data_dir_changed") @staticmethod def _hash_dir(url): dir_hash = hashlib.sha256(url.encode()).digest()[:6] encoded_hash = base64.urlsafe_b64encode(dir_hash).decode()[:8] return encoded_hash def get_dir_mtime(self, dir_url): mtime = 0 file_urls = self.core.call_success( "fs_recurse", dir_url, dir_included=True ) for file_url in file_urls: file_mtime = self.core.call_success("fs_get_mtime", file_url) if file_mtime > mtime: mtime = file_mtime return mtime def _delete_old_directories(self, days_to_data_dir_deletion=31): data_dir = self.core.call_success("paths_get_data_dir") work_data_dir = self.core.call_success( "fs_join", data_dir, WORK_DIR_NAME) folder_content = self.core.call_success( "fs_listdir", work_data_dir) now = datetime.datetime.now() for file in folder_content: if self.core.call_success("fs_isdir", file): mtime = self.get_dir_mtime(file) modified = datetime.datetime.fromtimestamp(mtime) time_diff = now - modified if time_diff.days >= days_to_data_dir_deletion: LOGGER.info( "Removing directory %s as it is older than %i days." % (file, days_to_data_dir_deletion)) self.core.call_success("fs_rm_rf", file, trash=False) def data_dir_handler_get_individual_data_dir(self): work_dir = self.core.call_success("storage_get_id") data_dir = self.core.call_success("paths_get_data_dir") encoded_hash = Plugin._hash_dir(work_dir) workdir_data_folder = self.core.call_success( "fs_join", data_dir, WORK_DIR_NAME) individual_data_dir = self.core.call_success( "fs_join", workdir_data_folder, "%s_%s" % (os.path.basename(work_dir), encoded_hash) ) self.core.call_success("fs_mkdir_p", individual_data_dir) return individual_data_dir paperwork-2.2.2/paperwork-backend/src/paperwork_backend/deps.py000066400000000000000000000002121456262201400247000ustar00rootroot00000000000000LIBREOFFICE = { 'debian': 'libreoffice', 'linuxmint': 'libreoffice', 'raspian': 'libreoffice', 'ubuntu': 'libreoffice', } paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/000077500000000000000000000000001456262201400254075ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/__init__.py000066400000000000000000000231551456262201400275260ustar00rootroot00000000000000""" Doc and page exporting are designed as pipelines. UI build the pipelines and run it. Data to export are represented as tree: Document set to export: data = set of (doc_id, doc_url)) |-- Document to export: data = (doc_id, doc_url) | |-- Page to export: data = (page_idx) | | |-- img_boxes: data = (Pillow image, boxes) | |-- Page to export | |-- Document_to_export | (...) When a pipes says it needs a given type in input, it means the content of the tree must be extended up to this data type. For example, if a pipe says it needs ExportDataType.PAGE as input, it must get an ExportData of type ExportDataType.DOCUMENT_SET as input, but expanded up to ExportDataType.PAGE: Document set to export |-- Document to export | |-- Page to export | |-- Page to export | |-- Document_to_export | (...) It must *not* be expanded any further either (for instance, no img+boxes (ExportDataType.IMG_BOXES) if the pipe says it expects a ExportDataType.PAGE as input). There are pipes dedicated to expanding unexpanded data (see docexport.generic). """ import abc import enum import openpaperwork_core class ExportDataType(enum.Enum): DOCUMENT_SET = 0 DOCUMENT = 1 PAGE = 2 IMG_BOXES = 3 # the following ones are for final output only. # A list of paths (str) will be returned instead of an ExportData object. OUTPUT_URL_FILE = -1 class ExportData: def __init__(self, dtype, data): self.dtype = dtype self.data = data self._children = [] self.expanded = False def clone(self): out = ExportData(self.dtype, self.data) out._children = [c.clone() for c in self._children] out.expanded = self.expanded return out def iter(self, dtype): if self.dtype == dtype: yield self return for c in self.get_children(): for s in c.iter(dtype): yield (self, s) def get_children(self): assert self.expanded return self._children def set_children(self, children): self._children = children self.expanded = True @staticmethod def build_doc_set(docs): return ExportData(ExportDataType.DOCUMENT_SET, docs) @staticmethod def build_doc(doc_id, doc_url): root = ExportData.build_doc_set({(doc_id, doc_url)}) doc = ExportData(ExportDataType.DOCUMENT, (doc_id, doc_url)) root.set_children([doc]) return root @staticmethod def build_page(doc_id, doc_url, page_idx): return ExportData.build_pages(doc_id, doc_url, [page_idx]) @staticmethod def build_pages(doc_id, doc_url, page_indexes): root = ExportData.build_doc_set({(doc_id, doc_url)}) doc = ExportData(ExportDataType.DOCUMENT, (doc_id, doc_url)) pages = [ ExportData(ExportDataType.PAGE, page_idx) for page_idx in page_indexes ] doc.set_children(pages) root.set_children([doc]) return root class AbstractExportPipe(abc.ABC): """ Pipes are used by the frontend/user to build an export pipeline (a list of pipes to apply in a specific order). There are input pipes, taking either DOCUMENT_SET, DOCUMENT, or PAGES as input. There are output pipes, providing a file URL (FILE_URL) as output or a directory URL. And there are processing pipes (usually taking Pillow images and text boxes as input (IMG_BOXES)). Once the pipeline is defined, the frontend code can obtain promises from the pipes (`export_get_pipe_*()`), chain them together, and schedule them (see get_promise()). """ def __init__(self, name, input_type, output_type): """ Arguments: name -- name of the export pipe input_type -- accepted ExportDataType output_type -- ExportDataType """ self.name = name self.input_type = input_type self.output_type = output_type self.can_change_quality = False self.can_change_page_format = False self.quality = 0.75 self.page_format = (595.2755905511812, 841.8897637795276) # A4 def can_export_doc(self, doc_url): return False def can_export_page(self, doc_url, page_idx): return False @abc.abstractmethod def export(self, input_data, result="final", target_file_url=None): ... def get_promise(self, result='final', target_file_url=None): """ Returns a promise. Beware that the promise will modify the ExportData object given as input. If you want to preserve your copy, please use ExportData.clone(). Arguments: - result: either 'preview' (only one page) or 'final' (all pages) - target_file_url: Where the final pipe should write the file (None = temporary file) Returns: - A promise, that expect ExportData object as input and will return either an ExportData (if it must be chained to another pipe) or a list of str (list of paths) """ return openpaperwork_core.promise.ThreadedPromise( self.core, self.export, kwargs={ "result": result, "target_file_url": target_file_url, } ) def get_estimated_size_factor(self, input_data): """ Return the factor to apply to the preview size to get an estimation of the final result size. Arguments: input_data -- ExportData. Won't be modified """ return 1 def set_quality(self, quality): """ Allow to define an output quality (between 0 and 100). Check `can_change_quality` before calling this method. """ assert self.can_change_quality self.quality = quality def set_page_format(self, page_format): """ Allow to define the expected output page format. Check `can_change_quality` before calling this method. Arguments: page_format: tuple (width, height), in points (1 point == 1/72.0 inch) """ assert self.can_change_page_format self.page_format = page_format def get_output_mime(self): """ If the pipe outputs a file, specifies its mime type and a list of possible file extensions. None if it doesn't outputs a file. """ return None @abc.abstractmethod def __str__(self): ... class ExportDataTransformedImgBoxes(ExportData): """ Page images takes a lot of memory --> we only generate them when actually requested. """ def __init__(self, pipe, original_page): super().__init__(ExportDataType.PAGE, original_page.data) self.expanded = True self.pipe = pipe self.original_page = original_page def get_children(self): children = self.original_page.get_children() for img_boxes in children: (img, boxes) = img_boxes.data img = self.pipe.transform(img) yield ExportData(ExportDataType.IMG_BOXES, (img, boxes)) class AbstractSimpleTransformExportPipe(AbstractExportPipe): """ Base template class for page image to page image transformations. """ def __init__(self, core, name): super().__init__( name=name, input_type=ExportDataType.IMG_BOXES, output_type=ExportDataType.IMG_BOXES ) self.core = core def transform(self, img): # sub-classes must implement it assert False def export(self, input_data, result='final', target_file_url=None): assert input_data.dtype == ExportDataType.DOCUMENT_SET docs = input_data.iter(ExportDataType.DOCUMENT) docs = list(docs) # replace the document page list by objects that will # generate their children (img+boxes) on-the-fly. for (doc_set, doc) in docs: assert doc.expanded doc.set_children([ ExportDataTransformedImgBoxes(self, page) for page in doc.get_children() ]) return input_data class AbstractExportPipePlugin(openpaperwork_core.PluginBase): def __init__(self): self.pipes = [] def get_interfaces(self): return ['export_pipes'] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def export_get_pipe_by_name(self, name): for pipe in self.pipes: if pipe.name == name: return pipe def export_get_pipes_by_input(self, out: list, input_type): for pipe in self.pipes: if input_type == pipe.input_type: out.append(pipe) def export_get_pipes_by_doc_urls(self, out: list, doc_urls): for pipe in self.pipes: if pipe.input_type != ExportDataType.DOCUMENT: continue for doc_url in doc_urls: if not pipe.can_export_doc(doc_url): break else: out.append(pipe) def export_get_pipes_by_doc_url(self, out: list, doc_url): return self.export_get_pipes_by_doc_urls(out, [doc_url]) def export_get_pipes_by_page(self, out: list, doc_url, page_nb): for pipe in self.pipes: if pipe.input_type != ExportDataType.PAGE: continue if not pipe.can_export_page(doc_url, page_nb): continue out.append(pipe) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/automatic.py000066400000000000000000000070221456262201400277500ustar00rootroot00000000000000from paperwork_backend import _ from paperwork_backend.docexport import ( AbstractExportPipe, AbstractExportPipePlugin, ExportData, ExportDataType ) class AutomaticPdfExportPipe(AbstractExportPipe): """ Composite pipe that generates PDF using the original PDF if possible. It automatically select between: - copying the original PDF file (if available and if the doc is unmodified) - exporting a generated PDF """ def __init__(self, core): super().__init__( name="automatic_pdf", input_type=ExportDataType.DOCUMENT, output_type=ExportDataType.OUTPUT_URL_FILE, ) self.core = core self.can_change_quality = True self.can_change_page_format = True self.pipes_original_pdf = [ self.core.call_success("export_get_pipe_by_name", "unmodified_pdf") ] assert None not in self.pipes_original_pdf self.pipes_generated_pdf = [ self.core.call_success("export_get_pipe_by_name", "doc_to_pages"), self.core.call_success("export_get_pipe_by_name", "img_boxes"), self.core.call_success("export_get_pipe_by_name", "generated_pdf"), ] assert None not in self.pipes_generated_pdf def can_export_doc(self, doc_url): return True def export(self, input_data, result="final", target_file_url=None): assert input_data.dtype == ExportDataType.DOCUMENT_SET list_docs = input_data.iter(ExportDataType.DOCUMENT) out_files = [] for (idx, (doc_set, doc)) in enumerate(list_docs): assert doc.dtype == ExportDataType.DOCUMENT (doc_id, doc_url) = doc.data doc_input = ExportData.build_doc(doc_id, doc_url) out_url = target_file_url if idx != 0: # automatic names files slightly differently: we assume # the user is doing a bulk export. out_url = target_file_url.rsplit(".", 1) out_url = f"{out_url[0]}_{doc_id}.{out_url[1]}" pdf_url = self.core.call_success( "doc_get_pdf_url_by_url", doc_url, allow_mapped=False ) if pdf_url is not None: pipes = self.pipes_original_pdf else: pipes = self.pipes_generated_pdf r = doc_input for pipe in pipes: if pipe.can_change_quality: pipe.set_quality(self.quality) if pipe.can_change_page_format: pipe.set_page_format(self.page_format) r = pipe.export(r, result, out_url) out_files += r return out_files def get_output_mime(self): return ("application/pdf", ("pdf",)) def __str__(self): return _("Automatic PDF export (original PDF if possible, generated one else)") class Plugin(AbstractExportPipePlugin): def get_deps(self): return super().get_deps() + [ { "interface": "export_pipes_generic", "defaults": ["paperwork_backend.docexport.generic"], }, { "interface": "export_pipes_img", "defaults": ["paperwork_backend.docexport.img"], }, { "interface": "export_pipes_pdf", "defaults": ["paperwork_backend.docexport.pdf"], }, ] def init(self, core): super().init(core) self.pipes = [ AutomaticPdfExportPipe(core), ] paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/generic.py000066400000000000000000000061461456262201400274040ustar00rootroot00000000000000import logging from . import ( AbstractExportPipe, AbstractExportPipePlugin, ExportData, ExportDataType ) from .. import _ LOGGER = logging.getLogger(__name__) class DocSetToDoc(AbstractExportPipe): def __init__(self, core): super().__init__( name="doc_set_to_docs", input_type=ExportDataType.DOCUMENT_SET, output_type=ExportDataType.DOCUMENT ) self.core = core def export(self, input_data, result='final', target_file_url=None): assert input_data.dtype == ExportDataType.DOCUMENT_SET assert not input_data.expanded docs = input_data.data if result == 'preview': docs = docs[:1] children = [ ExportData(ExportDataType.DOCUMENT, doc) for doc in docs ] input_data.set_children(children) return input_data def get_estimated_size_factor(self, input_data): assert input_data.dtype == ExportDataType.DOCUMENT_SET return len(input_data.data) def __str__(self): # this pipe shouldn't ever be visible to end-user return "Expand document set into documents (internal)" class DocToPage(AbstractExportPipe): def __init__(self, core): super().__init__( name="doc_to_pages", input_type=ExportDataType.DOCUMENT, output_type=ExportDataType.PAGE ) self.core = core def can_export_doc(self, doc_url): return True def export(self, input_data, result='final', target_file_url=None): assert input_data.dtype == ExportDataType.DOCUMENT_SET docs = input_data.iter(ExportDataType.DOCUMENT) for (doc_set, doc) in docs: assert not doc.expanded nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc.data[1] ) pages = [ ExportData(ExportDataType.PAGE, page_idx) for page_idx in range(0, nb_pages) ] doc.set_children(pages) return input_data def get_estimated_size_factor(self, input_data): # average number of pages per document assert input_data.dtype == ExportDataType.DOCUMENT_SET nb_pages = 0 nb_docs = len(input_data.data) for (doc_id, doc_url) in input_data.data: nb_pages += self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) return nb_pages / nb_docs def __str__(self): return _("Page by page processing") class Plugin(AbstractExportPipePlugin): def get_deps(self): return [ { 'interface': 'pages', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, ] def get_interfaces(self): return super().get_interfaces() + [ "export_pipes_generic", ] def init(self, core): super().init(core) self.pipes = [ DocSetToDoc(self.core), DocToPage(self.core), ] paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/img.py000066400000000000000000000171621456262201400265440ustar00rootroot00000000000000import logging from . import ( AbstractExportPipe, AbstractExportPipePlugin, AbstractSimpleTransformExportPipe, ExportData, ExportDataType ) from .. import _ LOGGER = logging.getLogger(__name__) class ExportDataPage(ExportData): """ Page images takes a lot of memory --> we only load them when actually requested. """ def __init__(self, core, doc_id, doc_url, page_idx, progress, final=False): super().__init__(ExportDataType.PAGE, page_idx) self.expanded = True self.core = core self.doc_id = doc_id self.doc_url = doc_url self.page_idx = page_idx self.progress = progress self.final = final def get_children(self): # ASSSUMPTION(Jflesch): pages are always requested sequentially self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "export", self.progress, _("Exporting {doc_id} p{page_idx} ...").format( doc_id=self.doc_id, page_idx=(self.page_idx + 1) ) ) page_url = (self.core.call_success( "page_get_img_url", self.doc_url, self.page_idx )) assert page_url is not None img = self.core.call_success("url_to_pillow", page_url) if img is None: # WORKAROUND(Jflesch): may happen with corrupted PDFs return boxes = self.core.call_success( "page_get_boxes_by_url", self.doc_url, self.page_idx ) or [] yield ExportData(ExportDataType.IMG_BOXES, (img, boxes)) if self.final: self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "export", 1.0 ) class DocToPillowBoxesExportPipe(AbstractExportPipe): def __init__(self, core): super().__init__( name="img_boxes", input_type=ExportDataType.PAGE, output_type=ExportDataType.IMG_BOXES ) self.core = core def can_export_page(self, doc_url, page_nb): return True def export(self, input_data, result='final', target_file_url=None): assert input_data.dtype == ExportDataType.DOCUMENT_SET docs = input_data.iter(ExportDataType.DOCUMENT) docs = list(docs) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "export", 0.0, _("Exporting ...") ) total_pages = 0 for (doc_set, doc) in docs: assert doc.expanded total_pages += len(doc.get_children()) nb_pages = 0 last_page = None for (doc_set, doc) in docs: assert doc.expanded # replace the document page list by objects that will # generate their children (img+boxes) on-the-fly. new_pages = [ ExportDataPage( self.core, doc.data[0], doc.data[1], page.data, (nb_pages + idx) / total_pages ) for (idx, page) in enumerate(doc.get_children()) ] doc.set_children(new_pages) nb_pages += len(new_pages) last_page = new_pages[-1] last_page.final = True return input_data def __str__(self): return _("Split page(s) into image(s) and text(s)") class PageToImageExportPipe(AbstractExportPipe): def __init__(self, core, name, format, file_extensions, mime, has_quality): super().__init__( name=name, input_type=ExportDataType.IMG_BOXES, output_type=ExportDataType.OUTPUT_URL_FILE, ) self.can_change_quality = has_quality self.format = format self.file_extensions = file_extensions self.mime = mime self.core = core def export(self, input_data, result='final', target_file_url=None): if target_file_url is None: (target_file_url, file_desc) = self.core.call_success( "fs_mktemp", prefix="paperwork-export-", suffix="." + self.file_extensions[0], mode="w" ) file_desc.close() list_img_boxes = input_data.iter(ExportDataType.IMG_BOXES) out_files = [] for (doc_set, (doc, (page, img_boxes))) in list_img_boxes: out = target_file_url if len(out_files) != 0: out = target_file_url.rsplit(".", 1) out = "{}_{}.{}".format(out[0], len(out_files), out[1]) self.core.call_success( "pillow_to_url", img_boxes.data[0], out, format=self.format, quality=self.quality ) out_files.append(out) return out_files def get_output_mime(self): return (self.mime, self.file_extensions) def __str__(self): return _("Image file ({})".format(self.format)) class BlackAndWhiteExportPipe(AbstractSimpleTransformExportPipe): def __init__(self, core): super().__init__(core, "bw") def transform(self, pil_img): pil_img = pil_img.convert("L") # to grayscale pil_img = pil_img.point(lambda x: 0 if x < 128 else 255, '1') return pil_img def __str__(self): return _("Black & White") class GrayscaleExportPipe(AbstractSimpleTransformExportPipe): def __init__(self, core): super().__init__(core, "grayscale") def transform(self, pil_img): return pil_img.convert("L") def __str__(self): return _("Grayscale") class Plugin(AbstractExportPipePlugin): def init(self, core): super().init(core) self.pipes = [ BlackAndWhiteExportPipe(core), DocToPillowBoxesExportPipe(core), GrayscaleExportPipe(core), PageToImageExportPipe( core, "bmp", "BMP", ("bmp",), "image/x-ms.bmp", False ), PageToImageExportPipe( core, "gif", "GIF", ("gif",), "image/gif", False ), PageToImageExportPipe( core, "jpeg", "JPEG", ("jpeg", "jpg"), "image/jpeg", True ), PageToImageExportPipe( core, "png", "PNG", ("png",), "image/png", False ), PageToImageExportPipe( core, "tiff", "TIFF", ("tiff", "tif"), "image/tiff", False ), ] def get_interfaces(self): return super().get_interfaces() + [ "export_pipes_img", ] def get_deps(self): return [ { 'interface': 'doc_text', 'defaults': [ # load also model.img because model.pdf will # satisfy the interface 'page_img' anyway 'paperwork_backend.model.img', 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'page_img', 'defaults': [ # load also model.hocr because model.pdf will # satisfy the interface 'doc_text' anyway 'paperwork_backend.model.img', 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, ] paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/pdf.py000066400000000000000000000245031456262201400265360ustar00rootroot00000000000000import logging import PIL import PIL.Image import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise from . import ( AbstractExportPipe, AbstractExportPipePlugin, ExportDataType ) from .. import _ CAIRO_AVAILABLE = False GI_AVAILABLE = False GLIB_AVAILABLE = False PANGO_AVAILABLE = False try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): pass try: import gi GI_AVAILABLE = True except (ImportError, ValueError): pass if GI_AVAILABLE: try: gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango from gi.repository import PangoCairo PANGO_AVAILABLE = True except (ImportError, ValueError): pass LOGGER = logging.getLogger(__name__) class PdfDocUrlToPdfUrlExportPipe(AbstractExportPipe): """ Simply copy the PDF we have. """ def __init__(self, core): super().__init__( name="unmodified_pdf", input_type=ExportDataType.DOCUMENT, output_type=ExportDataType.OUTPUT_URL_FILE ) self.core = core def can_export_doc(self, doc_url): pdf_url = self.core.call_success("doc_get_pdf_url_by_url", doc_url) return pdf_url is not None def export(self, input_data, result='final', target_file_url=None): if target_file_url is None: (target_file_url, file_desc) = self.core.call_success( "fs_mktemp", prefix="paperwork-export-", suffix=".pdf", mode="wb", on_disk=True ) file_desc.close() list_docs = input_data.iter(ExportDataType.DOCUMENT) out_files = [] for (idx, (doc_set, doc)) in enumerate(list_docs): out = target_file_url if idx != 0: out = target_file_url.rsplit(".", 1) out = "{}_{}.{}".format(out[0], idx, out[1]) assert not doc.expanded pdf_url = self.core.call_success( "doc_get_pdf_url_by_url", doc.data[1] ) assert pdf_url is not None self.core.call_success("fs_copy", pdf_url, out) out_files.append(out) return out_files def get_output_mime(self): return ("application/pdf", ("pdf",)) def __str__(self): return _("Original PDF(s)") class PdfCreator(object): def __init__(self, core, target_file_url, page_format, quality): self.core = core self.page_format = page_format self.quality = quality self.file_descriptor = core.call_success( "fs_open", target_file_url, 'wb' ) self.pdf_surface = cairo.PDFSurface( self.file_descriptor, self.page_format[0], self.page_format[1] ) self.pdf_context = cairo.Context(self.pdf_surface) self.gc_protection = [] # WORKAROUND(Jflesch): Cairo crash def set_page_size(self, img_size): # portrait or landscape if (img_size[0] < img_size[1]): self.pdf_size = ( min(self.page_format[0], self.page_format[1]), max(self.page_format[0], self.page_format[1]) ) else: self.pdf_size = ( max(self.page_format[0], self.page_format[1]), min(self.page_format[0], self.page_format[1]) ) self.pdf_surface.set_size(self.pdf_size[0], self.pdf_size[1]) def paint_txt(self, boxes, img_size): scale_factor_x = self.pdf_size[0] / img_size[0] scale_factor_y = self.pdf_size[1] / img_size[1] scale_factor = min(scale_factor_x, scale_factor_y) for line in boxes: for word in line.word_boxes: if word.position[0][0] <= 0 and line.position[0][1] <= 0: continue box_size = ( (word.position[1][0] - word.position[0][0]) * scale_factor, (line.position[1][1] - line.position[0][1]) * scale_factor ) if 0 in box_size: continue layout = PangoCairo.create_layout(self.pdf_context) layout.set_text(word.content, -1) txt_size = layout.get_size() if 0 in txt_size: continue txt_factors = ( float(box_size[0]) * Pango.SCALE / txt_size[0], float(box_size[1]) * Pango.SCALE / txt_size[1], ) self.pdf_context.save() try: self.pdf_context.set_source_rgb(0, 0, 0) self.pdf_context.translate( word.position[0][0] * scale_factor, line.position[0][1] * scale_factor ) # make the text use the whole box space self.pdf_context.scale(txt_factors[0], txt_factors[1]) PangoCairo.update_layout(self.pdf_context, layout) PangoCairo.show_layout(self.pdf_context, layout) finally: self.pdf_context.restore() return self def paint_img(self, img): img_size = img.size scale_factor_x = self.pdf_size[0] / img_size[0] scale_factor_y = self.pdf_size[1] / img_size[1] scale_factor = min(scale_factor_x, scale_factor_y) img_surface = self.core.call_success( "pillow_to_surface", img, intermediate="jpeg", quality=int(self.quality * 100) ) # WORKAROUND(Jflesch): # If Cairo supports JPEG embedding, we use # cairo.ImageSurface.set_mime_data() instead of the usual Cairo # surface functions to draw the image. It seems this function does # not increment the ref counter of the surface object # --> the Python GC tends to collect it while Cairo is still going # to use it to generate the PDF. # --> we have to keep a reference on it ourselves, until the page has # been generated. self.gc_protection.append(img_surface) self.pdf_context.save() try: self.pdf_context.identity_matrix() self.pdf_context.scale(scale_factor, scale_factor) self.pdf_context.set_source_surface(img_surface.surface) self.pdf_context.paint() finally: self.pdf_context.restore() def next_page(self): self.pdf_context.show_page() self.gc_protection = [] # WORKAROUND(Jflesch): Cairo crash def finish(self): self.pdf_surface.flush() self.pdf_surface.finish() self.file_descriptor.close() class PagesToPdfUrlExportPipe(AbstractExportPipe): def __init__(self, core): super().__init__( name="generated_pdf", input_type=ExportDataType.IMG_BOXES, output_type=ExportDataType.OUTPUT_URL_FILE ) self.core = core self.can_change_quality = True self.can_change_page_format = True def set_page_format(self, page_format): self.page_format = page_format def export(self, input_data, result='final', target_file_url=None): if target_file_url is None: (target_file_url, file_desc) = self.core.call_success( "fs_mktemp", prefix="paperwork-export-", suffix=".pdf", mode="w", on_disk=True ) # we need the file name, not the file descriptor file_desc.close() last_doc = None doc_idx = 0 out = target_file_url list_img_boxes = input_data.iter(ExportDataType.IMG_BOXES) creator = self.core.call_one( "mainloop_execute", PdfCreator, self.core, target_file_url, self.page_format, self.quality ) out_files = [] for (doc_set, (doc, (page, img_boxes))) in list_img_boxes: if doc.data[1] != last_doc and last_doc is not None: # another doc, another output file, another PDFCreator self.core.call_one("mainloop_execute", creator.finish) out_files.append(out) doc_idx += 1 out = target_file_url.rsplit(".", 1) out = "{}_{}.{}".format(out[0], doc_idx, out[1]) creator = self.core.call_one( "mainloop_execute", PdfCreator, self.core, out, self.page_format, self.quality ) last_doc = doc.data[1] (img, boxes) = img_boxes.data self.core.call_one( "mainloop_execute", creator.set_page_size, img.size ) self.core.call_one( "mainloop_execute", creator.paint_txt, boxes, img.size ) img_size = img.size img_size = ( int(self.quality * img_size[0]), int(self.quality * img_size[1]) ) img = img.resize( img_size, getattr(PIL.Image, 'Resampling', PIL.Image).LANCZOS ) self.core.call_one("mainloop_execute", creator.paint_img, img) self.core.call_one("mainloop_execute", creator.next_page) self.core.call_one("mainloop_execute", creator.finish) out_files.append(out) return out_files def get_output_mime(self): return ("application/pdf", ("pdf",)) def __str__(self): return _("Generated PDF(s)") class Plugin(AbstractExportPipePlugin): def init(self, core): super().init(core) self.pipes = [ PdfDocUrlToPdfUrlExportPipe(core), PagesToPdfUrlExportPipe(core), ] def get_interfaces(self): return super().get_interfaces() + [ "chkdeps", "export_pipes_pdf", ] def get_deps(self): return super().get_deps() + [ { 'interface': 'pillow_to_surface', 'defaults': ['paperwork_backend.cairo.pillow'], }, ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) if not GI_AVAILABLE: out['gi'].update(openpaperwork_core.deps.GI) if not PANGO_AVAILABLE: out['pango'].update(openpaperwork_core.deps.PANGO) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docexport/pillowfight.py000066400000000000000000000036171456262201400303200ustar00rootroot00000000000000import logging import pillowfight from . import ( AbstractExportPipePlugin, AbstractSimpleTransformExportPipe ) from .. import _ LOGGER = logging.getLogger(__name__) class UnpaperExportPipe(AbstractSimpleTransformExportPipe): def __init__(self, core): super().__init__(core, "unpaper") def transform(self, img): # Unpaper algorithms in Unpaper's order img = pillowfight.unpaper_blackfilter(img) img = pillowfight.unpaper_noisefilter(img) img = pillowfight.unpaper_blurfilter(img) img = pillowfight.unpaper_masks(img) img = pillowfight.unpaper_grayfilter(img) img = pillowfight.unpaper_border(img) return img def __str__(self): return _("Soft simplification") class SwtExportPipe(AbstractSimpleTransformExportPipe): def __init__(self, core, swt_output_type): super().__init__( core, "swt_soft" if swt_output_type == pillowfight.SWT_OUTPUT_ORIGINAL_BOXES else "swt_hard" ) self.swt_output_type = swt_output_type def transform(self, pil_img): pil_img = pil_img.convert("L") return pillowfight.swt(pil_img, output_type=self.swt_output_type) def __str__(self): if self.swt_output_type == pillowfight.SWT_OUTPUT_ORIGINAL_BOXES: return _("Hard simplification") else: return _("Extreme simplification") class Plugin(AbstractExportPipePlugin): def init(self, core): super().init(core) self.pipes = [ UnpaperExportPipe(core), SwtExportPipe(core, pillowfight.SWT_OUTPUT_ORIGINAL_BOXES), SwtExportPipe(core, pillowfight.SWT_OUTPUT_BW_TEXT), ] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': 'openpaperwork_gtk.mainloop.glib', }, ] paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docimport/000077500000000000000000000000001456262201400254005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docimport/__init__.py000066400000000000000000000121151456262201400275110ustar00rootroot00000000000000import collections import openpaperwork_core.promise class FileImport(object): """ Used as both input and output for importer objects. Users may import many files at once and files may not be imported at all (for example if they were already imported) --> FileImport objects indicate what must still be done, what has been done, and what has not been done at all. """ def __init__(self, file_uris_to_import, active_doc_id=None, data=None): self.active_doc_id = active_doc_id # those attributes will be updated by importers self.ignored_files = list(file_uris_to_import) self.imported_files = set() self.new_doc_ids = set() self.upd_doc_ids = set() self.stats = collections.defaultdict(lambda: 0) class BaseFileImporter(object): def __init__(self, core, file_import, single_file_importer_factory): self.core = core self.file_import = file_import self.single_file_importer_factory = single_file_importer_factory self.to_import = list(self._get_importables()) def get_name(self): return self.single_file_importer_factory.get_name() def can_import(self): return len(self.to_import) > 0 def get_required_data(self): """ Possible requirements: - "password": Document is password-protected. We need the password to import it. Returns: {file_uri: {requirement_a, requirement_b, etc}} """ out = {} for (orig_url, file_url) in self.to_import: required = self.single_file_importer_factory.get_required_data( file_url ) if len(required) <= 0: continue out[file_url] = required return out @staticmethod def _upd_file_import(imported, file_import, orig_uri, file_uri): try: file_import.ignored_files.remove(orig_uri) except ValueError: pass if imported: file_import.imported_files.add(file_uri) else: file_import.ignored_files.append(file_uri) def _make_transactions(self, file_import): transactions = [] self.core.call_all( "doc_transaction_start", transactions, len(file_import.new_doc_ids) + len(file_import.upd_doc_ids) ) transactions.sort(key=lambda transaction: -transaction.priority) return transactions def _do_transactions(self, transactions, file_import): for doc_id in file_import.new_doc_ids: for transaction in transactions: transaction.add_doc(doc_id) for doc_id in file_import.upd_doc_ids: for transaction in transactions: transaction.upd_doc(doc_id) for transaction in transactions: transaction.commit() def get_import_promise(self, data=None): """ Return a promise with all the steps required to import files specified in `file_import` (see constructor), transactions included. Must be scheduled with 'transaction_manager.transaction_schedule()'. Arguments: data are extra data that may be required (see `get_required_data()`) """ if data is None: data = {} promise = openpaperwork_core.promise.Promise(self.core) for (orig_uri, file_uri) in self.to_import: promise = promise.then( self.single_file_importer_factory.make_importer( self.file_import, file_uri, data ).get_promise() ) promise = promise.then( self._upd_file_import, self.file_import, orig_uri, file_uri ) promise = promise.then(self._make_transactions, self.file_import) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, self._do_transactions, args=(self.file_import,) ) ) return promise.then( self.core.call_all, "on_import_done", self.file_import ) class DirectFileImporter(BaseFileImporter): """ Designed to import only explicitly selected files """ def _get_importables(self): factory = self.single_file_importer_factory for file_uri in self.file_import.ignored_files: if factory.is_importable(self.core, file_uri): yield (file_uri, file_uri) class RecursiveFileImporter(BaseFileImporter): """ Assume files to import are actually directories. Look inside those directories to find files to import. """ def _get_importables(self): factory = self.single_file_importer_factory for dir_uri in self.file_import.ignored_files: if not self.core.call_success("fs_isdir", dir_uri): continue for file_uri in self.core.call_success("fs_recurse", dir_uri): if factory.is_importable(self.core, file_uri): yield (dir_uri, file_uri) def get_name(self): return self.single_file_importer_factory.get_recursive_name() paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docimport/converted.py000066400000000000000000000112031456262201400277400ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise from . import ( DirectFileImporter, FileImport, RecursiveFileImporter ) from .. import _ LOGGER = logging.getLogger(__name__) class SingleDocImporter(object): def __init__(self, plugin, file_import, src_file_uri): self.plugin = plugin self.core = plugin.core self.file_import = file_import self.src_file_uri = src_file_uri self.doc_id = None self.doc_url = None def _basic_import(self, file_url): file_hash = self.core.call_success("fs_hash", file_url) other_doc_id = self.core.call_success( "index_get_doc_id_by_hash", file_hash ) if other_doc_id is not None: LOGGER.info("%s has already been imported", file_url) self.file_import.stats[_("Already imported")] += 1 return False LOGGER.info("Importing %s", file_url) (self.doc_id, self.doc_url) = self.core.call_success( "doc_convert_and_import", file_url ) self.file_import.new_doc_ids.add(self.doc_id) self.file_import.stats[_("Documents")] += 1 mime = self.core.call_success("fs_get_mime", file_url) if mime is not None: self.file_import.stats[self.plugin.file_types_by_mime[mime]] += 1 elif "." in file_url: file_ext = file_url.rsplit(".", 1)[-1].lower() self.file_import.stats[ self.plugin.file_types_by_ext[file_ext][1] ] += 1 return True def get_promise(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self._basic_import, args=(self.src_file_uri,) ) class SingleDocImporterFactory(object): def __init__(self, plugin): self.plugin = plugin self.core = plugin.core @staticmethod def get_name(): return _("Import office document") @staticmethod def get_recursive_name(): return _("Import office documents recursively") def is_importable(self, core, file_url): mime = core.call_success("fs_get_mime", file_url) if mime is not None: return mime in self.plugin.file_types_by_mime if "." not in file_url: return False file_ext = file_url.rsplit(".", 1)[-1].lower() return file_ext in self.plugin.file_types_by_ext def get_required_data(self, file_uri): return set() def make_importer(self, file_import, file_uri, data): return SingleDocImporter(self.plugin, file_import, file_uri) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.file_types_by_ext = {} self.file_types_by_mime = {} def get_interfaces(self): return ["import"] def get_deps(self): return [ { "interface": "doc_convert_and_import", "defaults": ["paperwork_backend.model.converted"], }, { "interface": "doc_converter", "defaults": ["paperwork_backend.converter.libreoffice"], }, { "interface": "fs", "defaults": ["openpaperwork_gtk.fs.gio"], }, { "interface": "mainloop", "defaults": ["openpaperwork_gtk.mainloop.glib"], }, { "interface": "thread", "defaults": ["openpaperwork_core.thread.simple"], }, ] def init(self, core): super().init(core) file_types = set() self.core.call_all("converter_get_file_types", file_types) self.file_types_by_ext = { file_ext: (mime_type, human_name) for (mime_type, file_ext, human_name) in file_types } self.file_types_by_mime = { mime_type: human_name for (mime_type, file_ext, human_name) in file_types } def get_import_mime_types(self, out: list): for (mime, human_desc) in self.file_types_by_ext.values(): out.add((human_desc, mime)) if len(self.file_types_by_ext) > 0: out.add((_("Office document folder"), "inode/directory")) def get_importer(self, out: list, file_import: FileImport): importer = DirectFileImporter( self.core, file_import, SingleDocImporterFactory(self) ) if importer.can_import(): out.append(importer) importer = RecursiveFileImporter( self.core, file_import, SingleDocImporterFactory(self) ) if importer.can_import(): out.append(importer) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docimport/img.py000066400000000000000000000115621456262201400265330ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise from . import ( DirectFileImporter, FileImport, RecursiveFileImporter ) from .. import _ LOGGER = logging.getLogger(__name__) class SingleImgImporter(object): def __init__(self, factory, file_import, src_file_uri): self.factory = factory self.core = factory.core self.file_import = file_import self.src_file_uri = src_file_uri self.doc_id = None self.doc_url = None def _append_file_to_doc(self, file_url, doc_id=None): if doc_id is None: # new document (doc_id, doc_url) = self.core.call_success("storage_get_new_doc") else: # update existing one doc_url = self.core.call_success("doc_id_to_url", doc_id) nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None: nb_pages = 0 # Makes sure it's actually an image and convert it to the expected # format img = self.core.call_success("url_to_pillow", file_url) if img is None: LOGGER.error("Failed to load image %s", file_url) return (None, None) page_url = self.core.call_success( "page_get_img_url", doc_url, nb_pages, write=True ) self.core.call_success("pillow_to_url", img, page_url) return (doc_id, doc_url) def _basic_import(self, file_uri): (self.doc_id, self.doc_url) = self._append_file_to_doc( file_uri, self.file_import.active_doc_id ) if self.doc_id is None: return False self.file_import.stats[_("Images")] += 1 if self.file_import.active_doc_id is None: self.file_import.new_doc_ids.add(self.doc_id) self.file_import.stats[_("Documents")] += 1 else: self.file_import.upd_doc_ids.add(self.doc_id) self.file_import.stats[_("Pages")] += 1 self.file_import.active_doc_id = self.doc_id return True def get_promise(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self._basic_import, args=(self.src_file_uri,) ) class SingleImgImporterFactory(object): def __init__(self, plugin): self.plugin = plugin self.core = plugin.core @staticmethod def get_name(): return _("Append the image to the current document") @staticmethod def get_recursive_name(): return _( "Find the images recursively and import them to the current" " document" ) def is_importable(self, core, file_uri): mime = core.call_success("fs_get_mime", file_uri) if mime is not None: mimes = [mime[1] for mime in Plugin.IMG_MIME_TYPES] if mime in mimes: return True return False file_ext = file_uri.split(".")[-1].lower() if file_ext in self.plugin.FILE_EXTENSIONS: return True def get_required_data(self, file_uri): return set() def make_importer(self, file_import, file_uri, data): return SingleImgImporter(self, file_import, file_uri) class Plugin(openpaperwork_core.PluginBase): IMG_MIME_TYPES = [ ("BMP", "image/x-ms-bmp"), ("GIF", "image/gif"), ("JPEG", "image/jpeg"), ("PNG", "image/png"), ("TIFF", "image/tiff"), ] FILE_EXTENSIONS = [ "bmp", "gif", "jpeg", "jpg", "png", "tif", "tiff", ] def __init__(self): super().__init__() def get_interfaces(self): return [ "import" ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'page_img', 'defaults': ['paperwork_backend.model.img'], }, { 'interface': 'pillow', 'defaults': ['openpaperwork_core.pillow.img'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def get_import_mime_types(self, out: set): out.update(self.IMG_MIME_TYPES) def get_importer(self, out: list, file_import: FileImport): importer = DirectFileImporter( self.core, file_import, SingleImgImporterFactory(self) ) if importer.can_import(): out.append(importer) importer = RecursiveFileImporter( self.core, file_import, SingleImgImporterFactory(self) ) if importer.can_import(): out.append(importer) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docimport/pdf.py000066400000000000000000000077411456262201400265340ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise from . import ( DirectFileImporter, FileImport, RecursiveFileImporter ) from .. import _ LOGGER = logging.getLogger(__name__) class SinglePdfImporter(object): def __init__(self, core, file_import, src_file_uri, data): self.core = core self.file_import = file_import self.src_file_uri = src_file_uri self.data = data self.doc_id = None self.doc_url = None def _basic_import(self, file_uri): file_hash = self.core.call_success("fs_hash", file_uri) other_doc_id = self.core.call_success( "index_get_doc_id_by_hash", file_hash ) if other_doc_id is not None: LOGGER.info("%s has already been imported", file_uri) self.file_import.stats[_("Already imported")] += 1 return False LOGGER.info("Importing %s", file_uri) (self.doc_id, self.doc_url) = self.core.call_success( "doc_pdf_import", file_uri, password=self.data.get('password'), target_doc_id=self.file_import.active_doc_id ) if self.doc_id is None: return False self.file_import.new_doc_ids.add(self.doc_id) self.file_import.stats[_("PDF")] += 1 self.file_import.stats[_("Documents")] += 1 return True def get_promise(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self._basic_import, args=(self.src_file_uri,) ) class SinglePdfImporterFactory(object): def __init__(self, plugin): self.plugin = plugin self.core = plugin.core @staticmethod def get_name(): return _("Import PDF") @staticmethod def get_recursive_name(): return _("Import PDFs recursively") def is_importable(self, core, file_uri): mime = core.call_success("fs_get_mime", file_uri) if mime is not None: if mime == Plugin.MIME_TYPE: return True return False if file_uri.lower().endswith(self.plugin.FILE_EXTENSION): return True def get_required_data(self, file_uri): try: self.core.call_success("poppler_open", file_uri, password=None) LOGGER.info("%s: not password protected", file_uri) return set() except Exception: # XXX(Jflesch): there is no specific exception type ... :/ LOGGER.info("%s: password protected", file_uri) return {"password"} def make_importer(self, file_import, file_uri, data): return SinglePdfImporter(self.core, file_import, file_uri, data) class Plugin(openpaperwork_core.PluginBase): FILE_EXTENSION = ".pdf" MIME_TYPE = "application/pdf" def get_interfaces(self): return [ "import" ] def get_deps(self): return [ { 'interface': 'doc_pdf_import', 'defaults': ['paperwork_backend.model.pdf'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def get_import_mime_types(self, out: set): out.add(("PDF", self.MIME_TYPE)) out.add((_("PDF folder"), "inode/directory")) def get_importer(self, out: list, file_import: FileImport): importer = DirectFileImporter( self.core, file_import, SinglePdfImporterFactory(self) ) if importer.can_import(): out.append(importer) importer = RecursiveFileImporter( self.core, file_import, SinglePdfImporterFactory(self) ) if importer.can_import(): out.append(importer) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docscan/000077500000000000000000000000001456262201400250125ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docscan/__init__.py000066400000000000000000000000001456262201400271110ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docscan/autoselect_scanner.py000066400000000000000000000067711456262201400312600ustar00rootroot00000000000000""" Select a scanner if none has been selected yet or if the currently selected one doesn't exist anymore. IMPORTANT: This plugin must list the devices only if required. Otherwise it tends to mess up some Sane backend like the Brother one for instance. """ import logging import openpaperwork_core import paperwork_backend.util LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def get_interfaces(self): return [] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, ] def init(self, core): super().init(core) def scan_get_scanner_promise(self, scanner_dev_id=None, autoselect=True): """ Overload the method 'scan_get_scanner_promise' to check whether the device actually exists, and if not find the closest one. """ if not autoselect: return None def get_scanner(scanner_dev_id=None): scanner = None if scanner_dev_id is None: scanner_dev_id = self.core.call_success( "config_get", "scanner_dev_id" ) try: if scanner_dev_id is not None: scanner = self.core.call_success( "scan_get_scanner", scanner_dev_id ) except Exception as exc: # may happen if ID has changed (those containing the USB # bus + ID for instance) LOGGER.warning( "Failed to get scanner '%s'." " Will try to find the closest one", scanner_dev_id, exc_info=exc ) if scanner is not None: return scanner devs = self.core.call_success("scan_list_scanners") scanner_dev_id = self._find_dev_id(devs, scanner_dev_id) if scanner_dev_id is None: return None return self.core.call_success("scan_get_scanner", scanner_dev_id) return openpaperwork_core.promise.ThreadedPromise( self.core, get_scanner, args=(scanner_dev_id,) ) def _find_dev_id(self, devs, current_dev_id=None): devs = [dev[0] for dev in devs] LOGGER.info("Available scanners: %s", devs) if len(devs) <= 0: LOGGER.error("No scanner found !") return None elif current_dev_id is None: # pick a scanner at random. selected = devs[0] else: LOGGER.info("Previously selected scanner: %s", current_dev_id) # look for the closest scanner ID devs = [ ( paperwork_backend.util.levenshtein_distance( dev, current_dev_id ), dev ) for dev in devs ] devs.sort() selected = devs[0][1] LOGGER.info("Selected scanner: %s", selected) # ASSUMPTION(Jflesch): we assume here the requested scanner was # the one selected in the configuration --> we update the configuration # to avoid listing devices every time. self.core.call_success("config_put", "scanner_dev_id", selected) return selected paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docscan/fake.py000066400000000000000000000117521456262201400263000ustar00rootroot00000000000000import itertools import PIL.Image import openpaperwork_core import openpaperwork_core.promise SCAN_ID_GENERATOR = itertools.count() class Source(object): def __init__(self, core, scanner, source_id): self.core = core self.scanner = scanner self.source_id = source_id def __str__(self): return "{}:{}".format(str(self.scanner), self.source_id) def set_as_default(self): raise NotImplementedError() def get_resolutions_promise(self): def get_resolutions(): return [25, 100, 200, 300, 400, 500, 600] return openpaperwork_core.promise.Promise(self.core, get_resolutions) def set_default_resolution(self, resolution): raise NotImplementedError() def scan(self, scan_id=None, resolution=None, max_pages=9999): if scan_id is None: scan_id = next(SCAN_ID_GENERATOR) test_chunk = PIL.Image.new("RGB", (100, 200), (171, 205, 239)) test_page = PIL.Image.new("RGB", (200, 200), (171, 205, 239)) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_feed_start", scan_id ) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_page_start", scan_id, 0, None, # TODO(Jflesch): scan params ) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_chunk", scan_id, None, # TODO(Jflesch): scan_params test_chunk ) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_chunk", scan_id, None, # TODO(Jflesch): scan_params test_chunk ) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_chunk", scan_id, None, # TODO(Jflesch): scan_params test_chunk ) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_page_end", scan_id, 0, test_page ) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_scan_feed_end", scan_id ) return (self, scan_id, [test_page]) def scan_promise(self, *args, scan_id=None, **kwargs): if scan_id is None: scan_id = next(SCAN_ID_GENERATOR) kwargs['scan_id'] = scan_id return (scan_id, openpaperwork_core.promise.ThreadedPromise( self.core, self.scan, args=args, kwargs=kwargs )) def close(self, *args, **kwargs): pass class Scanner(object): def __init__(self, core, scanner_id): self.core = core self.dev_id = scanner_id def __str__(self): return self.dev_id def close(self, *args, **kwargs): pass def get_sources(self): return { "fake_source0": Source(self.core, self, "fake_source0"), "fake_source1": Source(self.core, self, "fake_source1"), } def get_sources_promise(self): return openpaperwork_core.promise.Promise(self.core, self.get_sources) def get_source(self, source_id): return self.get_sources()[source_id] def set_as_default(self): raise NotImplementedError() class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ["scan"] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def scan_list_scanners_promise(self): def list_scanners(): return [ ("fake:scanner0", "Super scanner #0"), ("fake:scanner1", "Super scanner #1"), ] return openpaperwork_core.promise.Promise(self.core, list_scanners) def scan_get_scanner_promise(self, dev_id): def get_scanner(): if dev_id != "fake:scanner0" and dev_id != "fake:scanner1": return None return Scanner(self.core, dev_id) return openpaperwork_core.promise.Promise(self.core, get_scanner) def scan_promise(self, *args, **kwargs): scan_id = next(SCAN_ID_GENERATOR) promise = self.scan_get_scanner_promise("fake:scanner0") promise = promise.then( openpaperwork_core.promise.Promise( self.core, Scanner.get_source, args=("fake_source0",) ) ) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, Source.scan, args=(scan_id,) ) ) def close(args): (source, scan_id, imgs) = args source.close() return (source, scan_id, imgs) promise = promise.then(close) return (scan_id, promise) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docscan/libinsane.py000066400000000000000000000642121456262201400273350ustar00rootroot00000000000000import itertools import json import logging import threading try: import gi gi.require_version('Libinsane', '1.0') from gi.repository import GObject GI_AVAILABLE = True except (ImportError, ValueError): GI_AVAILABLE = False # dummy so chkdeps can still be called class GObject(object): class GObject(object): pass try: from gi.repository import Libinsane LIBINSANE_AVAILABLE = True except (ImportError, ValueError): LIBINSANE_AVAILABLE = False # dummy so chkdeps can still be called class Libinsane(object): class LogLevel(object): DEBUG = 0 INFO = 1 WARNING = 2 ERROR = 3 class Logger(object): pass import PIL import PIL.Image import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise from .. import _ LOGGER = logging.getLogger(__name__) SCAN_ID_GENERATOR = itertools.count() # Prevent closing or other operations on scanner and source instances when # they are being used (scanning) LOCK = threading.RLock() class LibinsaneLogger(GObject.GObject, Libinsane.Logger): LEVELS = { Libinsane.LogLevel.DEBUG: LOGGER.debug, Libinsane.LogLevel.INFO: LOGGER.info, Libinsane.LogLevel.WARNING: LOGGER.warning, Libinsane.LogLevel.ERROR: LOGGER.error, } min_level = Libinsane.LogLevel.DEBUG def do_log(self, lvl, msg): if lvl < self.min_level: return self.LEVELS[lvl]("[LibInsane] " + msg) def raw_to_img(params, img_bytes): fmt = params.get_format() assert fmt == Libinsane.ImgFormat.RAW_RGB_24 w = params.get_width() h = int(len(img_bytes) / 3 / w) LOGGER.info( "raw_to_img(): w=%s, h=%d, len(img_bytes)=%d", w, h, len(img_bytes) ) mode = "RGB" return PIL.Image.frombuffer(mode, (w, h), img_bytes, "raw", mode, 0, 1) class ImageAssembler(object): MIN_CHUNK_SIZE = 64 * 1024 def __init__(self, line_width): # 'Pieces' are pieces of the images that may or may not contain # full lines of pixels (or even partial pixel) # 'chunk': We want to provide the GUI with a preview of the scan. # To keep things simple, we provide chunk of the image and those # chunk must contain only entire lines of pixels. # and then we must also provide the whole image at the end. self.w = line_width # in bytes self.current_piece = [] self.all_chunks = [] def add_piece(self, piece): self.current_piece.append(piece) lcurrent_piece = sum((len(c) for c in self.current_piece)) if lcurrent_piece < self.w or lcurrent_piece < self.MIN_CHUNK_SIZE: return current_piece = b"".join(self.current_piece) chunkable = lcurrent_piece - (lcurrent_piece % self.w) new_chunk = current_piece[:chunkable] new_piece = current_piece[chunkable:] self.all_chunks.append(new_chunk) if len(new_piece) <= 0: self.current_piece = [] else: self.current_piece = [new_piece] def get_last_chunk(self): if len(self.all_chunks) <= 0: return None return self.all_chunks[-1] def get_image(self): return b"".join(self.all_chunks) + b"".join(self.current_piece) class Source(object): def __init__(self, core, scanner, source): self.core = core self.scanner = scanner self.source_id = source.get_name() self.source = source def __str__(self): return "{}:{}".format(str(self.scanner), self.source_id) def set_as_default(self): self.core.call_all( "config_put", "scanner_source_id", self.source_id ) def _get_option(self, name): LOGGER.info( "Looking for possible values for option '%s' on %s" " : %s ...", name, str(self.scanner), self.source_id ) options = self.source.get_options() options = {opt.get_name(): opt for opt in options} return options[name] def _get_opt_constraint(self, name): with LOCK: opt = self._get_option(name) constraint = opt.get_constraint() LOGGER.info( "%s : %s : %s : Possible values: %s", str(self.scanner), self.source_id, name, constraint ) return constraint def get_modes(self): return self._get_opt_constraint('mode') def get_resolutions(self): return self._get_opt_constraint('resolution') def get_resolutions_promise(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self.get_resolutions ) def set_default_resolution(self, resolution): self.core.call_all( "config_put", "scanner_resolution", int(resolution) ) def scan( self, scan_id=None, resolution=None, max_pages=9999, close_on_end=False ): """ Returns the source, the scan ID and an image generator """ with LOCK: if scan_id is None: scan_id = next(SCAN_ID_GENERATOR) LOGGER.info("(id=%s) Setting scan options ...", scan_id) if resolution is None: resolution = self.core.call_success( "config_get", "scanner_resolution" ) mode = self.core.call_success("config_get", "scanner_mode") options = self.source.get_options() opts = {opt.get_name(): opt for opt in options} if 'resolution' in opts: opts['resolution'].set_value(resolution) if 'mode' in opts: try: opts['mode'].set_value(mode) except Exception as exc: LOGGER.warning( "Failed to set scan mode", exc_info=exc ) # will try to scan anyway extrasettings = self.core.call_success( "config_get", "scanner_extra_settings" ) for (setting, value) in extrasettings.items(): if setting in opts: try: opts[setting].set_value(value) except Exception as exc: LOGGER.warning( "Failed to set scan setting %s=%s", setting, value, exc_info=exc ) else: LOGGER.warning("No such scanner setting: " + setting) imgs = self._scan(scan_id, resolution, max_pages, close_on_end) return (self, scan_id, imgs) def _scan(self, scan_id, resolution, max_pages, close_on_end=False): """ Returns an image generator """ # keep in mind that we are in a thread here, but listeners # must be called from the main loop LOGGER.info( "(id=%s) Scanning at resolution %d dpi ...", scan_id, resolution ) has_started = False session = None try: page_nb = 0 self.core.call_one( "mainloop_execute", self.core.call_all, "on_scan_feed_start", scan_id ) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "scan", 0.0, _("Starting scan ...") ) session = self.source.scan_start() while not session.end_of_feed() and page_nb < max_pages: self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "scan", 0.0, _("Scanning page %d ...") % (page_nb + 1) ) scan_params = session.get_scan_parameters() LOGGER.info( "Expected scan parameters: %s ; %dx%d = %d bytes", scan_params.get_format(), scan_params.get_width(), scan_params.get_height(), scan_params.get_image_size() ) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_scan_page_start", scan_id, page_nb, scan_params ) assert ( scan_params.get_format() == Libinsane.ImgFormat.RAW_RGB_24 ) image = ImageAssembler(scan_params.get_width() * 3) last_chunk = None nb_lines = 0 total_lines = scan_params.get_height() buffer_size = (scan_params.get_width() * 3) + 1 LOGGER.info("Scanning page %d/%d ...", page_nb, max_pages) while not session.end_of_page(): new_piece = session.read_bytes(buffer_size).get_data() if not has_started: # Mark the application as busy until we get the first # read(). This is the only reliable time to be # sure scanning is actually started. self.core.call_success( "mainloop_schedule", self.core.call_all, "on_scan_started", scan_id ) has_started = True image.add_piece(new_piece) chunk = image.get_last_chunk() if chunk is not last_chunk: last_chunk = chunk pil = raw_to_img(scan_params, chunk) nb_lines += pil.size[1] progress = nb_lines / total_lines if progress >= 1.0: progress = 0.999 self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "scan", progress, _("Scanning page %d ...") % (page_nb + 1) ) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_scan_chunk", scan_id, scan_params, pil ) LOGGER.info("Page %d/%d scanned", page_nb, max_pages) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "scan", 0.999, _("Scanning page %d ...") % (page_nb + 1) ) img = raw_to_img(scan_params, image.get_image()) yield img self.core.call_success( "mainloop_schedule", self.core.call_all, "on_scan_page_end", scan_id, page_nb, img ) page_nb += 1 LOGGER.info("End of feed") self.core.call_success( "mainloop_schedule", self.core.call_all, "on_scan_feed_end", scan_id ) finally: self.core.call_success( "mainloop_schedule", self.core.call_all, "on_progress", "scan", 1.0 ) if session is not None: session.cancel() if close_on_end: self.close() def scan_promise(self, *args, scan_id=None, **kwargs): if scan_id is None: scan_id = next(SCAN_ID_GENERATOR) kwargs['scan_id'] = scan_id return ( scan_id, openpaperwork_core.promise.ThreadedPromise( self.core, self.scan, args=args, kwargs=kwargs ) ) def close(self, *args, **kwargs): with LOCK: self.scanner.close() # return the args for convience when used with promises if len(args) == 1 and len(kwargs) == 0: return args return (args, kwargs) class Scanner(object): def __init__(self, core, scanner): self.core = core self.dev_id = scanner.get_name() self.dev = scanner self.sources = None # WORKAROUND(Jflesch): just to keep ref on them def __str__(self): return self.dev_id def __del__(self): if self.dev is not None: # Shouldn't happen. LOGGER.warning( "Scanner(%s, %s) is being garbage-collected", self.dev_id, id(self) ) self.close() def close(self, *args, **kwargs): with LOCK: if self.dev is not None: LOGGER.info("Closing device %s (%s)", self.dev_id, id(self)) self.dev.close() self.dev = None # return the args for convenience when used with promises if len(args) == 1 and len(kwargs) == 0: return args return (args, kwargs) def get_sources(self): with LOCK: LOGGER.info("Looking for scan sources on %s ...", self.dev_id) sources = self.dev.get_children() sources = [ Source(self.core, self, source) for source in sources ] self.sources = { source.source_id: source for source in sources } LOGGER.info("%d sources found: %s", len(sources), sources) return self.sources def get_sources_promise(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self.get_sources ) def get_source(self, source_id): sources = self.get_sources() src = sources[source_id] return src def set_as_default(self): self.core.call_all( "config_put", "scanner_dev_id", 'libinsane:' + self.dev_id ) class BugReportCollector(object): def __init__(self, plugin, update_args): self.core = plugin.core self.plugin = plugin self.update_args = update_args def _notify(self, msg): self.core.call_success( "mainloop_schedule", self.core.call_all, "bug_report_update_attachment", "scanner", {"file_url": msg}, *self.update_args ) @staticmethod def _get_error_proof(func): try: r = func() if type(r) is bool or type(r) is int or type(r) is float: return r return str(r) except Exception as exc: return str(exc) def _collect_opt_info(self, opt, out: dict): out['name'] = self._get_error_proof(opt.get_name) out['title'] = self._get_error_proof(opt.get_title) out['description'] = self._get_error_proof(opt.get_desc) out['capabilities'] = self._get_error_proof(opt.get_capabilities) out['unit'] = self._get_error_proof(opt.get_value_unit) out['constraint_type'] = self._get_error_proof(opt.get_constraint_type) out['constraint'] = self._get_error_proof(opt.get_constraint) out['is_readable'] = self._get_error_proof(opt.is_readable) out['is_writable'] = self._get_error_proof(opt.is_writable) out['value'] = self._get_error_proof(opt.get_value) def _collect_item_info(self, item, base_name, out: dict): if item is None or item is False: out['reachable'] = False return out['reachable'] = True try: name = item.get_name() if base_name is not None and base_name != "": name = base_name + "/" + name self._notify(_("Examining %s") % name) out['name'] = item.get_name() out['options'] = {} out['children'] = {} options = item.get_options() for opt in options: out['options'][opt.get_name()] = {} self._collect_opt_info(opt, out['options'][opt.get_name()]) children = item.get_children() for child in children: out['children'][child.get_name()] = {} self._collect_item_info( child, name, out['children'][child.get_name()] ) finally: item.close() def _write_scanners_info_to_tmp_file(self, infos): infos = json.dumps( infos, indent=4, separators=(",", ": "), sort_keys=True ) (file_url, fd) = self.core.call_success( "fs_mktemp", prefix="scanner_", suffix=".json", mode="w", on_disk=True ) with fd: fd.write(infos) return file_url @staticmethod def _collect_get_device(libinsane, dev_id): try: return libinsane.get_device(dev_id) except Exception as exc: LOGGER.error("Failed to get device [%s]", dev_id, exc_info=exc) return False # can't return None or it will be ignored def _collect_all_info(self, scanners): out = {} promise = openpaperwork_core.promise.Promise(self.core) for dev in scanners: dev_id = dev[0] dev_name = dev[1] out[dev_id] = { 'listing_name': dev_name } promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, self._collect_get_device, args=(self.plugin.libinsane, dev_id[len("libinsane:"):],) ) ) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self._collect_item_info, args=("", out[dev_id],) )) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, self._write_scanners_info_to_tmp_file, args=(out,) ) ) promise = promise.then( lambda file_url: self.core.call_all( "bug_report_update_attachment", "scanner", { 'file_url': file_url, 'file_size': self.core.call_success( 'fs_getsize', file_url ), }, *self.update_args ) ) self.core.call_success("scan_schedule", promise) def run(self): promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=( "bug_report_update_attachment", "scanner", {"file_url": _("Getting scanner list ...")}, *self.update_args ) ) promise = promise.then(self.plugin.scan_list_scanners_promise()) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self._collect_all_info )) self.core.call_success("scan_schedule", promise) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() # Looking for devices twice on Linux tends to crash ... self.devices_cache = [] LOGGER.info("Initializing Libinsane ...") self.libinsane_logger = LibinsaneLogger() self.libinsane = None if LIBINSANE_AVAILABLE: Libinsane.register_logger(self.libinsane_logger) self.libinsane = Libinsane.Api.new_safebet() LOGGER.info( "Libinsane %s initialized", self.libinsane.get_version() ) self._last_scanner = None def get_interfaces(self): return [ "bug_report_attachments", "chkdeps", "scan", "stats", ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def init(self, core): super().init(core) self.core.call_all("work_queue_create", "scanner") settings = { 'scanner_dev_id': self.core.call_success( "config_build_simple", "scanner", "dev_id", lambda: None ), 'scanner_source_id': self.core.call_success( "config_build_simple", "scanner", "source", lambda: None ), 'scanner_resolution': self.core.call_success( "config_build_simple", "scanner", "resolution", lambda: 300 ), 'scanner_mode': self.core.call_success( "config_build_simple", "scanner", "mode", lambda: "Color" ), 'scanner_extra_settings': self.core.call_success( "config_build_simple", "scanner", "extrasettings", lambda: {} ), } for (k, setting) in settings.items(): self.core.call_all( "config_register", k, setting ) def chkdeps(self, out: dict): if not GI_AVAILABLE: out['gi'].update(openpaperwork_core.deps.GI) if not LIBINSANE_AVAILABLE: out['libinsane'] = { 'debian': 'gir1.2-libinsane-1.0', 'linuxmint': 'gir1.2-libinsane-1.0', 'raspbian': 'gir1.2-libinsane-1.0', 'ubuntu': 'gir1.2-libinsane-1.0', } def scan_schedule(self, promise): """ Any promise or chain of promises related to scanners must *always* be run sequentially to avoid crashes. Otherwise, 2 threaded promises could run in parrallel. So other plugins using those promises should use scan_schedule() instead of mainloop_schedule() or promise.schedule(). """ self.core.call_success("work_queue_add_promise", "scanner", promise) return True def scan_list_scanners(self, *args, **kwargs): with LOCK: if len(self.devices_cache) > 0: return self.devices_cache LOGGER.info("Looking for scan devices ...") devs = self.libinsane.list_devices( Libinsane.DeviceLocations.ANY ) devs = [ # (id, human readable name) # prefix the IDs with 'libinsane:' so we know it comes from # our plugin and not another scan plugin ( 'libinsane:' + dev.get_dev_id(), "{} {}".format( dev.get_dev_vendor(), dev.get_dev_model() ), dev.get_dev_vendor(), dev.get_dev_model(), ) for dev in devs ] devs.sort(key=lambda s: s[1]) LOGGER.info("%d devices found: %s", len(devs), devs) self.devices_cache = devs return devs def scan_list_scanners_promise(self): """ Return a promise for listing scanners. Must be started with "scan_schedule()", not "promise.schedule()" ! """ return openpaperwork_core.promise.ThreadedPromise( self.core, self.scan_list_scanners ) def scan_get_scanner(self, scanner_dev_id=None): if self._last_scanner is not None: self._last_scanner.close() self._last_scanner = None if scanner_dev_id is None: scanner_dev_id = self.core.call_success( "config_get", "scanner_dev_id" ) if scanner_dev_id is None: return None if not scanner_dev_id.startswith("libinsane:"): return None scanner_dev_id = scanner_dev_id[len("libinsane:"):] with LOCK: LOGGER.info("Accessing scanner '%s' ...", scanner_dev_id) scanner = self.libinsane.get_device(scanner_dev_id) LOGGER.info("Scanner '%s' opened", scanner.get_name()) self._last_scanner = Scanner(self.core, scanner) return self._last_scanner def scan_get_scanner_promise(self, scanner_dev_id=None): """ Return a promise getting a scanner instance. Must be started with "scan_schedule()", not "promise.schedule()" ! """ return openpaperwork_core.promise.ThreadedPromise( self.core, self.scan_get_scanner, args=(scanner_dev_id,) ) def scan_promise(self, *args, source_id=None, **kwargs): """ Return a promise that will run a scan. Must be started with "scan_schedule()", not "promise.schedule()" ! """ scanner_dev_id = self.core.call_success( "config_get", "scanner_dev_id" ) if source_id is None: source_id = self.core.call_success( "config_get", "scanner_source_id" ) if source_id is None: raise Exception("No source defined") scan_id = next(SCAN_ID_GENERATOR) promise = self.core.call_success( "scan_get_scanner_promise", scanner_dev_id ) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, Scanner.get_source, args=(source_id,) ) ) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, Source.scan, args=(scan_id,), kwargs={ 'close_on_end': True } ) ) return (scan_id, promise) def bug_report_get_attachments(self, out: dict): out['scanner'] = { 'include_by_default': False, 'date': None, 'file_type': _("Scanner info."), 'file_url': _("Select to generate"), 'file_size': 0, } def on_bug_report_attachment_selected(self, attachment_id, *args): if attachment_id != 'scanner': return collector = BugReportCollector(self, args) collector.run() def stats_get(self, out: dict): if not LIBINSANE_AVAILABLE: out['libinsane_version'] = "not installed" return out['libinsane_version'] = Libinsane.Api.get_version() paperwork-2.2.2/paperwork-backend/src/paperwork_backend/docscan/scan2doc.py000066400000000000000000000120101456262201400270520ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.scan_id_to_doc_id = {} self.doc_id_to_scan_id = {} def get_interfaces(self): return ['scan2doc'] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { 'interface': 'page_img', 'defaults': ['paperwork_backend.model.img'], }, { 'interface': 'pillow', 'defaults': ['openpaperwork_core.pillow.img'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def scan2doc_scan_id_to_doc_id(self, scan_id): try: return self.scan_id_to_doc_id[scan_id] except KeyError: return None def scan2doc_doc_id_to_scan_id(self, doc_id): try: return self.doc_id_to_scan_id[doc_id] except KeyError: return None def scan2doc_promise(self, *args, doc_id=None, doc_url=None, **kwargs): """ The promise returned by this method should be scheduled with scan_schedule() to avoid any possible conflict with another scan (or scanner lookup). """ if doc_id is not None and doc_url is not None: nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) new = (nb_pages <= 0) if nb_pages is not None else True else: (doc_id, doc_url) = self.core.call_success("storage_get_new_doc") new = True (scan_id, p) = self.core.call_success("scan_promise", *args, **kwargs) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_scan2doc_start", scan_id, doc_id, doc_url) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(p) self.scan_id_to_doc_id[scan_id] = doc_id self.doc_id_to_scan_id[doc_id] = scan_id def add_scans_to_doc(args): (source, scan_id, imgs) = args nb = 0 for img in imgs: nb += 1 nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) if nb_pages is None: nb_pages = 0 page_url = self.core.call_success( "page_get_img_url", doc_url, nb_pages, write=True ) self.core.call_success("pillow_to_url", img, page_url) self.core.call_all( "mainloop_schedule", self.core.call_all, "on_scan2doc_page_scanned", scan_id, doc_id, doc_url, nb_pages ) return nb def drop_scan_id(scan_id, doc_id): self.scan_id_to_doc_id.pop(scan_id, None) self.doc_id_to_scan_id.pop(doc_id, None) def notify_end(scan_id, doc_id): self.core.call_all("on_scan2doc_end", scan_id, doc_id, doc_url) return (doc_id, doc_url) def cancel(exc, scan_id, doc_id): drop_scan_id(scan_id, doc_id) if new: self.core.call_all("storage_delete_doc_id", doc_id) raise exc def run_transactions(nb_imgs, scan_id, doc_id): # start a second promise chain, but scheduled with # "transaction_schedule()" promise = openpaperwork_core.promise.Promise( self.core, drop_scan_id, args=(scan_id, doc_id) ) promise = promise.then(self.core.call_success( "transaction_simple_promise", [("add" if new else "upd", doc_id),] )) promise = promise.then(notify_end, scan_id, doc_id) promise = promise.catch(cancel, scan_id, doc_id) self.core.call_success("transaction_schedule", promise) return (doc_id, doc_url) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, add_scans_to_doc ) ) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, run_transactions, args=(scan_id, doc_id) ) ) promise = promise.catch(cancel, scan_id, doc_id) return promise paperwork-2.2.2/paperwork-backend/src/paperwork_backend/doctracker.py000066400000000000000000000210741456262201400260770ustar00rootroot00000000000000""" This plugin is an helper for other plugins. It provides an easy way to detect deleted, modified or added documents when synchronizing with the work directory. """ import datetime import logging import openpaperwork_core from . import (_, sync) LOGGER = logging.getLogger(__name__) CREATE_TABLES = [ ( "CREATE TABLE IF NOT EXISTS documents (" " doc_id TEXT PRIMARY KEY," " text TEXT NULL," " mtime INTEGER NOT NULL" ")" ), ] ID = "doctracker" class DocTrackerTransaction(sync.BaseTransaction): def __init__(self, plugin, sql, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = -10000 self.sql = self.core.call_one( "sqlite_execute", sql.cursor ) self.core.call_one( "sqlite_execute", self.sql.execute, "BEGIN TRANSACTION" ) def _get_actual_doc_data(self, doc_id, doc_url): if ( doc_url is not None and self.core.call_success("fs_exists", doc_url) is not None ): mtime = self.core.call_success("doc_get_mtime_by_url", doc_url) if mtime is None: mtime = 0 doc_text = [] self.core.call_all("doc_get_text_by_url", doc_text, doc_url) doc_text = "\n\n".join(doc_text) else: mtime = 0 doc_text = None return { 'mtime': mtime, 'text': doc_text, } def add_doc(self, doc_id): self.notify_progress(ID, _("Document %s added") % (doc_id)) self._upd_doc(doc_id) super().add_doc(doc_id) def upd_doc(self, doc_id): self.notify_progress(ID, _("Document %s updated") % (doc_id)) self._upd_doc(doc_id) super().upd_doc(doc_id) def _upd_doc(self, doc_id): doc_url = self.core.call_success("doc_id_to_url", doc_id) actual = self._get_actual_doc_data(doc_id, doc_url) self.core.call_one( "sqlite_execute", self.sql.execute, "INSERT OR REPLACE INTO documents (doc_id, text, mtime)" " VALUES (?, ?, ?)", (doc_id, actual['text'], actual['mtime']) ) def del_doc(self, doc_id): self.notify_progress(ID, _("Document %s deleted") % (doc_id)) self.core.call_one( "sqlite_execute", self.sql.execute, "DELETE FROM documents WHERE doc_id = ?", (doc_id,) ) super().del_doc(doc_id) def unchanged_doc(self, doc_id): self.notify_progress( ID, _("Examining document %s: unchanged") % (doc_id) ) super().unchanged_doc(doc_id) def cancel(self): self.notify_progress(ID, _("Rolling back changes")) self.core.call_one("sqlite_execute", self.sql.execute, "ROLLBACK") self.core.call_one("sqlite_execute", self.sql.close) self.notify_done(ID) def commit(self): self.notify_progress(ID, _("Committing changes")) self.core.call_one("sqlite_execute", self.sql.execute, "COMMIT") self.core.call_one("sqlite_execute", self.sql.close) self.notify_done(ID) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def __init__(self): self.sql = None self.transaction_factories = [] def get_interfaces(self): return [ 'doc_tracking', 'syncable', ] def get_deps(self): return [ { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'] }, { 'interface': 'data_dir_handler', 'defaults': ['paperwork_backend.datadirhandler'], }, { 'interface': 'sqlite', 'defaults': ['openpaperwork_core.sqlite'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def init(self, core): super().init(core) self._init() def _init(self): paperwork_dir = self.core.call_success( "data_dir_handler_get_individual_data_dir" ) sql_file = self.core.call_success( "fs_join", paperwork_dir, 'doc_tracking.db' ) self.sql = self.core.call_one( "sqlite_execute", self.core.call_success, "sqlite_open", sql_file ) for query in CREATE_TABLES: self.core.call_one("sqlite_execute", self.sql.execute, query) def on_quit(self): LOGGER.info("Closing doc tracker db ...") self.core.call_one( "sqlite_execute", self.core.call_success, "sqlite_close", self.sql ) self.sql = None def on_data_dir_changed(self): self.on_quit() self._init() def doc_tracker_register(self, name, transaction_factory): self.transaction_factories.append((name, transaction_factory)) def doc_tracker_get_all_doc_ids(self): doc_ids = self.core.call_one( "sqlite_execute", self.sql.execute, "SELECT doc_id FROM documents" ) doc_ids = self.core.call_one( "sqlite_execute", list, doc_ids ) return {doc_id[0] for doc_id in doc_ids} def doc_tracker_get_doc_text_by_id(self, doc_id): """ Return the text of a document as last-known. This method is useful when a document is deleted: when a plugin is notified that a document has been deleted, it may still need its text. Since the document won't be available anymore, we pull its text from the database (for instance, for label guesser untraining) """ text = self.core.call_one( "sqlite_execute", self.sql.execute, "SELECT text FROM documents WHERE doc_id = ? LIMIT 1", (doc_id,) ) text = self.core.call_one( "sqlite_execute", list, text ) if len(text) <= 0: return None return text[0][0] def doc_transaction_start(self, out: list, total_expected=-1): for (name, transaction_factory) in self.transaction_factories: out.append(transaction_factory( sync=False, total_expected=total_expected )) out.append(DocTrackerTransaction(self, self.sql, total_expected)) def sync(self, promises: list): storage_all_docs = [] names = [t[0] for t in self.transaction_factories] names.append('doc_tracker') promise = openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("storage_get_all_docs", storage_all_docs,) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(storage_all_docs.sort) class DbDoc(object): def __init__(self, result): self.key = result[0] self.extra = datetime.datetime.fromtimestamp(result[1]) promise = promise.then(self.sql.cursor) promise = promise.then(lambda cursor: ( [ sync.StorageDoc(self.core, doc[0], doc[1]) for doc in storage_all_docs ], [ DbDoc(r) for r in cursor.execute("SELECT doc_id, mtime FROM documents") ], )) promise = promise.then(lambda args: ( *args, sorted([ transaction_factory( sync=True, total_expected=max(len(storage_all_docs), len(args[1])) ) for (name, transaction_factory) in self.transaction_factories ] + [ DocTrackerTransaction( self, self.sql, total_expected=max(len(storage_all_docs), len(args[1])) ) ], key=lambda t: -1 * t.priority), )) promise = promise.then(lambda args: sync.Syncer( self.core, names, args[0], args[1], args[2] )) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, lambda syncer: syncer.run() )) promises.append(promise) def tests_cleanup(self): self.sql.close() paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/000077500000000000000000000000001456262201400254315ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/__init__.py000066400000000000000000000000001456262201400275300ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/color/000077500000000000000000000000001456262201400265475ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/color/__init__.py000066400000000000000000000000001456262201400306460ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/color/libpillowfight.py000066400000000000000000000130061456262201400321400ustar00rootroot00000000000000""" Automatic page cropping using libpillowfight.find_scan_borders(). May or may not work. """ import logging import pillowfight import openpaperwork_core from ... import (_, sync) LOGGER = logging.getLogger(__name__) ID = "color" class PillowfightTransaction(sync.BaseTransaction): def __init__(self, plugin, sync, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY self.plugin = plugin self.sync = sync self.core = plugin.core # for each document, we need to track on which pages we have already # adjusted the color and on which page we didn't yet. self.page_tracker = self.core.call_success("page_tracker_get", ID) def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def _adjust_page_colors( self, doc_id, doc_url, page_idx, page_nb, total_pages): paper_size = self.core.call_success( "page_get_paper_size_by_url", doc_url, page_idx ) if paper_size is not None: # probably a PDF --> no need to adjust colors self.notify_progress( ID, _( "Document {doc_id} p{page_idx} already correctly" " colorized" ).format( doc_id=doc_id, page_idx=(page_idx + 1) ), page_nb=page_nb, total_pages=total_pages ) LOGGER.info( "Paper size for new page %d (document %s) is known." " --> Assuming we don't need to adjust colors", doc_id, page_idx ) return self.notify_progress( ID, _("Adjusting colors of document {doc_id} p{page_idx}").format( doc_id=doc_id, page_idx=(page_idx + 1) ), page_nb=page_nb, total_pages=total_pages ) self.plugin.adjust_page_colors_by_url(doc_url, page_idx) def _adjust_new_pages_colors(self, doc_id): doc_url = self.core.call_success("doc_id_to_url", doc_id) need_end_notification = False modified_pages = list(self.page_tracker.find_changes(doc_id, doc_url)) for (page_nb, (change, page_idx)) in enumerate(modified_pages): # Adjust page colors on new pages, but only if we are # not synchronizing with the work directory if not self.sync and change == 'new': self._adjust_page_colors( doc_id, doc_url, page_idx, page_nb, len(modified_pages) ) need_end_notification = True self.page_tracker.ack_page(doc_id, doc_url, page_idx) if need_end_notification: self.notify_progress( ID, _("Adjusting colors of document"), page_nb=len(modified_pages), total_pages=len(modified_pages) ) def add_doc(self, doc_id): self._adjust_new_pages_colors(doc_id) super().add_doc(doc_id) def upd_doc(self, doc_id): self._adjust_new_pages_colors(doc_id) super().upd_doc(doc_id) def del_doc(self, doc_id): self.page_tracker.delete_doc(doc_id) super().del_doc(doc_id) def cancel(self): self.page_tracker.cancel() self.notify_done(ID) def commit(self): self.page_tracker.commit() self.notify_done(ID) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 3000 def get_interfaces(self): return [ "color", "syncable", # actually satisfied by the plugin 'doctracker' ] def get_deps(self): return [ { 'interface': 'doc_tracking', 'defaults': ['paperwork_backend.doctracker'], }, { 'interface': 'page_tracking', 'defaults': ['paperwork_backend.pagetracker'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, ] def init(self, core): super().init(core) self.core.call_all( "doc_tracker_register", ID, lambda sync, total_expected=-1: PillowfightTransaction( self, sync, total_expected ) ) def adjust_page_colors_by_url(self, doc_url, page_idx): LOGGER.info("Adjusting colors of page %d of %s", page_idx, doc_url) doc_id = self.core.call_success("doc_url_to_id", doc_url) if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_start", doc_id, page_idx ) try: page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) img = self.core.call_success("url_to_pillow", page_img_url) img = pillowfight.ace(img, samples=200) page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx, write=True ) self.core.call_success("pillow_to_url", img, page_img_url) finally: if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_end", doc_id, page_idx ) return img paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/cropping/000077500000000000000000000000001456262201400272525ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/cropping/__init__.py000066400000000000000000000000201456262201400313530ustar00rootroot00000000000000ID = "cropping" paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/cropping/calibration.py000066400000000000000000000150151456262201400321150ustar00rootroot00000000000000""" Crop scanned images based on a predefined area. """ import logging import openpaperwork_core from ... import (_, sync) from . import ID LOGGER = logging.getLogger(__name__) class CalibrationTransaction(sync.BaseTransaction): def __init__(self, plugin, sync, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY self.plugin = plugin self.sync = sync # For each document, we need to track on which pages we have already # guessed the page borders and on which page we didn't yet. # We use the same ID for all the cropping plugins so we never crop # twice the same page. self.page_tracker = self.core.call_success("page_tracker_get", ID) def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def _crop_page(self, doc_id, doc_url, page_idx, page_nb, total_pages): paper_size = self.core.call_success( "page_get_paper_size_by_url", doc_url, page_idx ) if paper_size is not None: # We only want to crop scanned pages. self.notify_progress( ID, _("Document {doc_id} p{page_idx} already cropped").format( doc_id=doc_id, page_idx=(page_idx + 1) ), page_nb=page_nb, total_pages=total_pages ) return if self.core.call_success( "page_has_text_by_url", doc_url, page_idx ): self.notify_progress( ID, _( "Document {doc_id} p{page_idx} has already some text." " Not cropping." ).format(doc_id=doc_id, page_idx=(page_idx + 1)), page_nb=page_nb, total_pages=total_pages ) return self.notify_progress( ID, _( "Using calibration to crop page borders of" " document {doc_id} p{page_idx}" ).format(doc_id=doc_id, page_idx=(page_idx + 1)), page_nb=page_nb, total_pages=total_pages ) self.plugin.crop_page_borders_by_url(doc_url, page_idx) def _crop_new_pages(self, doc_id): doc_url = self.core.call_success("doc_id_to_url", doc_id) modified_pages = list(self.page_tracker.find_changes(doc_id, doc_url)) for (page_nb, (change, page_idx)) in enumerate(modified_pages): # Guess page borders on new pages, but only if we are # not currently synchronizing with the work directory # (when syncing we don't modify the documents, ever) if not self.sync and change == 'new': self._crop_page( doc_id, doc_url, page_idx, page_nb, len(modified_pages) ) self.page_tracker.ack_page(doc_id, doc_url, page_idx) def add_doc(self, doc_id): self._crop_new_pages(doc_id) super().add_doc(doc_id) def upd_doc(self, doc_id): self._crop_new_pages(doc_id) super().upd_doc(doc_id) def del_doc(self, doc_id): self.page_tracker.delete_doc(doc_id) super().del_doc(doc_id) def cancel(self): self.page_tracker.cancel() self.notify_done(ID) def commit(self): self.page_tracker.commit() self.notify_done(ID) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 4000 def get_interfaces(self): return [ "cropping", "scanner_calibration", "syncable", # actually satisfied by the plugin 'doctracker' ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'doc_tracking', 'defaults': ['paperwork_backend.doctracker'], }, { 'interface': 'page_tracking', 'defaults': ['paperwork_backend.pagetracker'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ] } ] def init(self, core): super().init(core) self.core.call_all( "config_register", "scanner_calibration", self.core.call_success( "config_build_simple", "scanner", "calibration", lambda: None ) ) self.core.call_all( "doc_tracker_register", ID, lambda sync, total_expected=-1: CalibrationTransaction( self, sync, total_expected ) ) def crop_page_borders_by_url(self, doc_url, page_idx): frame = self.core.call_success( "config_get", "scanner_calibration" ) if frame is None: LOGGER.warning( "No calibration found. Cannot crop page %s p%d", doc_url, page_idx ) return None LOGGER.info( "Cropping page %d of %s (calibration=%s)", page_idx, doc_url, frame ) doc_id = self.core.call_success("doc_url_to_id", doc_url) if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_start", doc_id, page_idx ) try: page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) img = self.core.call_success("url_to_pillow", page_img_url) LOGGER.info( "Cropping page %d of %s at %s", page_idx, doc_url, frame ) # make sure we don't extend the image frame = ( max(0, frame[0]), max(0, frame[1]), min(img.size[0], frame[2]), min(img.size[1], frame[3]), ) img = img.crop(frame) page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx, write=True ) self.core.call_success("pillow_to_url", img, page_img_url) finally: if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_end", doc_id, page_idx ) return frame paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/cropping/libpillowfight.py000066400000000000000000000137511456262201400326520ustar00rootroot00000000000000""" Automatic page cropping using libpillowfight.find_scan_borders(). May or may not work. """ import logging import pillowfight import openpaperwork_core from . import ID from ... import (_, sync) LOGGER = logging.getLogger(__name__) class PillowfightTransaction(sync.BaseTransaction): def __init__(self, plugin, sync, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY self.plugin = plugin self.sync = sync # For each document, we need to track on which pages we have already # guessed the page borders and on which page we didn't yet. # We use the same ID for all the cropping plugins so we never crop # twice the same page. self.page_tracker = self.core.call_success("page_tracker_get", ID) def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def _guess_page_borders( self, doc_id, doc_url, page_idx, page_nb, total_pages): paper_size = self.core.call_success( "page_get_paper_size_by_url", doc_url, page_idx ) if paper_size is not None: # We don't want to guess page borders on PDF files since they # are usually already well-cropped. Also the page borders won't # appear in the document, so libpillowfight algorithm can only # fail. self.notify_progress( ID, _("Document {doc_id} p{page_idx} already cropped").format( doc_id=doc_id, page_idx=(page_idx + 1) ), page_nb=page_nb, total_pages=total_pages ) return self.notify_progress( ID, _( "Guessing page borders of" " document {doc_id} p{page_idx}" ).format(doc_id=doc_id, page_idx=(page_idx + 1)), page_nb=page_nb, total_pages=total_pages ) self.plugin.crop_page_borders_by_url(doc_url, page_idx) def _guess_new_pages_borders(self, doc_id): doc_url = self.core.call_success("doc_id_to_url", doc_id) need_end_notification = False modified_pages = list(self.page_tracker.find_changes(doc_id, doc_url)) for (page_nb, (change, page_idx)) in enumerate(modified_pages): # Guess page borders on new pages, but only if we are # not synchronizing with the work directory # (when syncing we don't modify the documents, ever) if not self.sync and change == 'new': self._guess_page_borders( doc_id, doc_url, page_idx, page_nb, len(modified_pages) ) need_end_notification = True self.page_tracker.ack_page(doc_id, doc_url, page_idx) if need_end_notification: self.notify_progress( ID, _("Guessing page borders"), page_nb=len(modified_pages), total_pages=len(modified_pages) ) def add_doc(self, doc_id): self._guess_new_pages_borders(doc_id) super().add_doc(doc_id) def upd_doc(self, doc_id): self._guess_new_pages_borders(doc_id) super().upd_doc(doc_id) def del_doc(self, doc_id): self.page_tracker.delete_doc(doc_id) super().del_doc(doc_id) def cancel(self): self.page_tracker.cancel() self.notify_done(ID) def commit(self): self.page_tracker.commit() self.notify_done(ID) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 4000 def get_interfaces(self): return [ "cropping", "syncable", # actually satisfied by the plugin 'doctracker' ] def get_deps(self): return [ { 'interface': 'doc_tracking', 'defaults': ['paperwork_backend.doctracker'], }, { 'interface': 'page_tracking', 'defaults': ['paperwork_backend.pagetracker'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ] } ] def init(self, core): super().init(core) self.core.call_all( "doc_tracker_register", ID, lambda sync, total_expected=-1: PillowfightTransaction( self, sync, total_expected ) ) def crop_page_borders_by_url(self, doc_url, page_idx): LOGGER.info("Cropping page %d of %s", page_idx, doc_url) doc_id = self.core.call_success("doc_url_to_id", doc_url) if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_start", doc_id, page_idx ) try: page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) img = self.core.call_success("url_to_pillow", page_img_url) frame = pillowfight.find_scan_borders(img) if frame[0] >= frame[2] or frame[1] >= frame[3]: LOGGER.warning( "Invalid frame found for page %d of %s: %s. Cannot" " crop automatically", page_idx, doc_url, frame ) return None LOGGER.info( "Cropping page %d of %s at %s", page_idx, doc_url, frame ) img = img.crop(frame) page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx, write=True ) self.core.call_success("pillow_to_url", img, page_img_url) finally: if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_end", doc_id, page_idx ) return frame paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/000077500000000000000000000000001456262201400265105ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/__init__.py000066400000000000000000000000001456262201400306070ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/000077500000000000000000000000001456262201400301475ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/__init__.py000066400000000000000000001101111456262201400322530ustar00rootroot00000000000000""" Label guesser guesses label based on document text and bayes filters. It adds the guessed labels on new documents (in other words, freshly added documents). It stores data in 2 ways: - sklearn pickling of TfidVectorizer - sqlite database """ import collections import gc import logging import os import pickle import sqlite3 import threading import time import numpy import scipy.sparse import sklearn.feature_extraction.text import sklearn.naive_bayes import openpaperwork_core import openpaperwork_core.promise from .... import (_, sync) LOGGER = logging.getLogger(__name__) ID = "label_guesser" CREATE_TABLES = [ # we could use the labels file instead, but some people access their work # directory through very slow Internet connections, so we better # keep a copy in the DB. ( "CREATE TABLE IF NOT EXISTS labels (" " doc_id TEXT NOT NULL," " label TEXT NOT NULL," " PRIMARY KEY (doc_id, label)" ")" ), ( # see sklearn.feature_extraction.text.CountVectorizer.vocabulary "CREATE TABLE IF NOT EXISTS vocabulary (" " word TEXT NOT NULL," " feature INTEGER NOT NULL," " PRIMARY KEY (feature)" " UNIQUE (word)" ")" ), ( "CREATE TABLE IF NOT EXISTS features (" " doc_id TEXT NOT NULL," " vector NUMPY_ARRAY NOT NULL," " PRIMARY KEY (doc_id)" ")" ) ] class SqliteNumpyArrayHandler(object): @staticmethod def _to_sqlite(np_array): return np_array.tobytes() @staticmethod def _from_sqlite(raw): return numpy.frombuffer(raw) @classmethod def register(cls): sqlite3.register_adapter(numpy.array, cls._to_sqlite) sqlite3.register_converter("NUMPY_ARRAY", cls._from_sqlite) class PluginConfig(object): SETTINGS = { # settings --> default value 'batch_size': 200, # Limit the number of words used for performance reasons 'max_words': 15000, # Limit the number of documents used for performance reasons # backlog is the number of required documents with and without each # label 'max_doc_backlog': 100, 'max_time': 10, # seconds # if the document contains too few words, the classifiers tend to # put every possible labels on it. --> we ignore documents with too # few words / features. 'min_features': 10, } def __init__(self, core): self.core = core def register(self): class Setting(object): def __init__(s, setting, default_val): s.setting = setting s.default_val = default_val def register(s): setting = self.core.call_success( "config_build_simple", "label_guessing", s.setting, lambda: s.default_val ) self.core.call_all( "config_register", "label_guessing_" + s.setting, setting ) for (setting, default_val) in self.SETTINGS.items(): Setting(setting, default_val).register() def get(self, key): return self.core.call_success("config_get", "label_guessing_" + key) class UpdatableVectorizer(object): """ Vectorizer that we can update over time with new features (word identifiers). Store the word->features in the SQLite database. We only add words to the database, we never remove them, otherwise we wouldn't be able to read the feature vectors correctly anymore. """ def __init__(self, core, db_cursor): self.core = core self.db_cursor = db_cursor vocabulary = self.db_cursor.execute( "SELECT word, feature FROM vocabulary" ) vocabulary = {k.strip(): v for (k, v) in vocabulary} if "" in vocabulary: vocabulary.pop("") self.updatable_vocabulary = vocabulary self.last_feature_id = max(vocabulary.values(), default=-1) def partial_fit_transform(self, corpus): # A bit hackish: We just need the analyzer, so instantiating a full # TfidVectorizer() is probably overkill, but meh. tokenizer = sklearn.feature_extraction.text.TfidfVectorizer( ).build_analyzer() LOGGER.info( "Vocabulary contains %d words before fitting", self.last_feature_id ) for doc_txt in corpus: for word in tokenizer(doc_txt): if word in self.updatable_vocabulary: continue self.last_feature_id += 1 self.db_cursor.execute( "INSERT INTO vocabulary (word, feature)" " SELECT ?, ?" " WHERE NOT EXISTS(" " SELECT 1 FROM vocabulary WHERE word = ?" " )", (word.strip(), self.last_feature_id, word) ) self.updatable_vocabulary[word.strip()] = self.last_feature_id LOGGER.info( "Vocabulary contains %d words after fitting", self.last_feature_id ) return self.transform(corpus) def transform(self, corpus): # IMPORTANT: we must use use_idf=False here because we want the values # in each feature vector to be independant from other vectors. try: vectorizer = sklearn.feature_extraction.text.TfidfVectorizer( use_idf=False, vocabulary=self.updatable_vocabulary ) features = vectorizer.fit_transform(corpus) LOGGER.info("%s features extracted", features.shape) return features except ValueError as exc: LOGGER.warning("Failed to extract features", exc_info=exc) return scipy.sparse.csr_matrix((0, 0)) def _find_unused(self): doc_features = self.db_cursor.execute( "SELECT vector FROM features" ) sum_features = None for (doc_vector,) in doc_features: if doc_vector is None: continue required_padding = ( self.last_feature_id + 1 - doc_vector.shape[0] ) if required_padding > 0: doc_vector = numpy.hstack([ doc_vector, numpy.zeros((required_padding,)) ]) if sum_features is None: sum_features = doc_vector else: sum_features = sum_features + doc_vector if sum_features is None: return ([], 0) return ( [f for (f, v) in enumerate(sum_features) if v == 0.0], len(sum_features) ) def _get_all_doc_ids(self): doc_ids = self.db_cursor.execute("SELECT doc_id FROM features") doc_ids = [doc_id[0] for doc_id in doc_ids] return doc_ids def gc(self): """ Drop features that are unused anymore. IMPORTANT: After this call, the vectorizer must not be used anymore (this method doesn't update the internal state of the vectorizer) """ # we work in the main thread so we don't have to load all the feature # vectors all at once in memory (we just need their sum) LOGGER.info("Garbage collecting unused features ...") (to_drop, total) = self._find_unused() if len(to_drop) <= 0: LOGGER.info("No features to garbage collect (total=%d)", total) return LOGGER.info( "%d/%d features will be removed from the database", len(to_drop), total ) doc_ids = self._get_all_doc_ids() # first we reduce the document feature vectors msg = _( "Label guesser: Garbage-collecting unused document features ..." ) self.core.call_all("on_progress", "label_vector_gc", 0.0, msg) for (idx, doc_id) in enumerate(doc_ids): self.core.call_all( "on_progress", "label_vector_gc", idx / len(doc_ids), msg ) doc_vector = self.db_cursor.execute( "SELECT vector FROM features WHERE doc_id = ? LIMIT 1", (doc_id,) ) doc_vector = list(doc_vector) doc_vector = doc_vector[0][0] if doc_vector is None: # may happen according to bug report #478 doc_vector = numpy.array([]) to_drop_for_this_doc = [f for f in to_drop if f < len(doc_vector)] doc_vector = numpy.delete(doc_vector, to_drop_for_this_doc) self.db_cursor.execute( "UPDATE features SET vector = ? WHERE doc_id = ?", (doc_vector, doc_id) ) self.core.call_all("on_progress", "label_vector_gc", 1.0) # then we reduce the vocabulary accordingly msg = _("Label guesser: Garbage-collecting unused words ...") self.core.call_all("on_progress", "label_vocabulary_gc", 0.0, msg) for (idx, f) in enumerate(to_drop): self.core.call_all( "on_progress", "label_vocabulary_gc", idx / len(to_drop), msg ) self.db_cursor.execute( "DELETE FROM vocabulary WHERE feature = ?", (f,) ) self.db_cursor.execute( "UPDATE vocabulary SET feature = feature - 1" " WHERE feature >= ?", (f,) ) self.core.call_all("on_progress", "label_vocabulary_gc", 1.0, ) def copy(self): r = UpdatableVectorizer(self.core, self.db_cursor) r.updatable_vocabulary = dict(self.updatable_vocabulary) r.last_feature_id = self.last_feature_id return r class BatchIterator(object): def __init__(self, config, features, targets): self.features = features self.targets = targets self.b = 0 self.batch_size = config.get("batch_size") def __iter__(self): self.b = 0 return self def __next__(self): batch_corpus = self.features[self.b:self.b + self.batch_size] if len(batch_corpus) <= 0: raise StopIteration() batch_corpus = scipy.sparse.vstack(batch_corpus).toarray() batch_targets = self.targets[self.b:self.b + self.batch_size] self.b += self.batch_size return (batch_corpus, batch_targets) class FeatureReductor(object): def __init__(self, to_drop): self.features_to_drop = to_drop def reduce_features(self, features): return numpy.delete(features, self.features_to_drop) class DummyFeatureReductor(object): def reduce_features(self, features): return features class Corpus(object): """ Handles doc_ids and their associate feature vectors. Make sure we train the document in the best order possible, so even if the training is interrupted (time limit), we still have some training for most labels. """ def __init__(self, config, doc_ids, features, targets): self.config = config self.doc_ids = doc_ids self.features = features self.targets = targets def standardize_feature_vectors(self, vectorizer): for idx in range(0, len(self.features)): doc_vector = self.features[idx] required_padding = ( vectorizer.last_feature_id + 1 - doc_vector.shape[0] ) assert required_padding >= 0 if required_padding > 0: doc_vector = scipy.sparse.hstack([ scipy.sparse.csr_matrix(doc_vector), numpy.zeros((required_padding,)) ]) else: doc_vector = scipy.sparse.csr_matrix(doc_vector) self.features[idx] = doc_vector def reduce_corpus_words(self): """ We may end up with a lot of different words (about 76000 in my case). But most of them are actually too rare to be useful and they use a lot memory and CPU time. """ max_words = self.config.get("max_words") word_freq_sums = sum(self.features).toarray()[0] word_count = word_freq_sums.shape[0] LOGGER.info("Total word count before reduction: %d", word_count) if word_count <= max_words: LOGGER.info("No reduction to do") return DummyFeatureReductor() threshold = sorted(word_freq_sums, reverse=True)[max_words] LOGGER.info("Word frequency threshold: %f", threshold) features_to_drop = [] for (idx, freq) in enumerate(word_freq_sums): if freq > threshold: continue features_to_drop.append(idx) reductor = FeatureReductor(features_to_drop) for idx in range(0, len(self.features)): self.features[idx] = scipy.sparse.csr_matrix( reductor.reduce_features( self.features[idx].toarray()[0] ) ) LOGGER.info( "Total word count after reduction: %d", word_count - len(reductor.features_to_drop) ) return reductor def get_doc_count(self): return len(self.features) def get_labels(self): return self.targets.keys() def get_batches(self, label): return BatchIterator(self.config, self.features, self.targets[label]) @staticmethod def _add_doc_ids(max_doc_backlog, doc_weights, doc_ids): # Assumes doc_ids are in reverse order (most recent first) # Also assumes most recent documents are the most useful assert len(doc_ids) <= max_doc_backlog weigth = max_doc_backlog + 1 for doc_id in doc_ids: doc_weights[doc_id] += weigth weigth -= 1 @staticmethod def load(config, cursor): start = time.time() # doc_id --> weigth doc_weights = collections.defaultdict(lambda: 0) all_labels = cursor.execute("SELECT DISTINCT label FROM labels") all_labels = {label[0] for label in all_labels} all_docs = cursor.execute( "SELECT doc_id FROM features ORDER BY doc_id DESC" ) all_docs = [doc[0] for doc in all_docs] max_doc_backlog = config.get("max_doc_backlog") for label in all_labels: ds = cursor.execute( "SELECT doc_id FROM labels WHERE label = ?" " ORDER BY doc_id DESC LIMIT {}".format(max_doc_backlog), (label,) ) Corpus._add_doc_ids( max_doc_backlog, doc_weights, [d[0] for d in ds] ) # label --> number of doc without this label no_label_counts = {label: 0 for label in all_labels} no_label_docids = {label: [] for label in all_labels} for doc_id in all_docs: if len(no_label_counts) <= 0: break doc_labels = cursor.execute( "SELECT label FROM labels WHERE doc_id = ?", (doc_id,) ) for label in list(no_label_counts.keys()): if label in doc_labels: continue no_label_docids[label].append(doc_id) no_label_counts[label] += 1 if no_label_counts[label] >= max_doc_backlog: no_label_counts.pop(label) for doc_ids in no_label_docids.values(): doc_ids.sort(reverse=True) Corpus._add_doc_ids(max_doc_backlog, doc_weights, doc_ids) LOGGER.info( "Loading features of %d documents for %d labels", len(doc_weights), len(all_labels) ) all_features = {} for doc_id in doc_weights.keys(): vectors = cursor.execute( "SELECT vector FROM features WHERE doc_id = ? LIMIT 1", (doc_id,) ) for vector in vectors: vector = vector[0] if vector is None: continue all_features[doc_id] = vector all_features = [ [weight, doc_id, all_features[doc_id]] for (doc_id, weight) in doc_weights.items() if doc_id in all_features ] all_features.sort(reverse=True) doc_ids = [ doc_id for (weight, doc_id, features) in all_features ] features = [ features for (weight, doc_id, features) in all_features ] # Load labels targets = collections.defaultdict(list) for (idx, doc_id) in enumerate(doc_ids): doc_labels = cursor.execute( "SELECT label FROM labels WHERE doc_id = ?", (doc_id,) ) doc_labels = [label[0] for label in doc_labels] for label in all_labels: present = label in doc_labels targets[label].append(1 if present else 0) corpus = Corpus( config=config, doc_ids=doc_ids, features=features, targets=targets ) stop = time.time() LOGGER.info( "Took %dms to load features of %d documents", int((stop - start) * 1000), len(doc_ids) ) return corpus class LabelGuesserTransaction(sync.BaseTransaction): def __init__(self, plugin, guess_labels=False, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY self.plugin = plugin self.guess_labels = guess_labels LOGGER.info("Transaction start: Guessing labels: %s", guess_labels) self.cursor = None self.vectorizer = None self.lock_acquired = False self.nb_changes = 0 self.need_gc = False def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def _lazyinit_transaction(self): if self.cursor is not None: return # prevent reload of classifiers during the transaction assert not self.lock_acquired self.plugin.classifiers_cond.acquire() self.lock_acquired = True if not self.plugin.classifiers_loaded and self.guess_labels: # classifiers haven't been loaded at all yet. Now # looks like a good time for it (end of initial sync) self.plugin.reload_label_guessers() if self.plugin.classifiers is None and self.guess_labels: # Before starting the transaction, we wait for the classifiers # to be loaded, because we may need them # (see add_doc() -> _set_guessed_labels()) self.plugin.classifiers_cond.wait() self.cursor = self.plugin.core.call_success( "sqlite_open", self.plugin.sql_url, detect_types=sqlite3.PARSE_DECLTYPES, ) self.cursor.execute("BEGIN TRANSACTION") self.vectorizer = UpdatableVectorizer(self.core, self.cursor) def add_doc(self, doc_id): if self.guess_labels: # we have a higher priority than index plugins, so it is a good # time to update the document labels doc_url = self.core.call_success("doc_id_to_url", doc_id) has_labels = self.core.call_success( "doc_has_labels_by_url", doc_url ) if has_labels is not None: LOGGER.info( "Document %s already has labels. Won't guess labels", doc_url ) return self._lazyinit_transaction() self.plugin._set_guessed_labels(doc_url) else: self._lazyinit_transaction() self.notify_progress( ID, _("Label guesser: added document %s") % doc_id ) self._upd_doc(doc_id) self.nb_changes += 1 super().add_doc(doc_id) def upd_doc(self, doc_id): self._lazyinit_transaction() self.notify_progress( ID, _("Label guesser: updated document %s") % doc_id ) self._upd_doc(doc_id) self.nb_changes += 1 super().upd_doc(doc_id) def _del_doc(self, doc_id): self.cursor.execute("DELETE FROM labels WHERE doc_id = ?", (doc_id,)) self.cursor.execute("DELETE FROM features WHERE doc_id = ?", (doc_id,)) def del_doc(self, doc_id): self._lazyinit_transaction() self.notify_progress( ID, _("Label guesser: deleted document %s") % doc_id ) self.nb_changes += 1 self._del_doc(doc_id) LOGGER.info( "Document %s has been deleted." " Feature garbage-collecting will be run", doc_id ) self.need_gc = True super().del_doc(doc_id) def _upd_doc(self, doc_id): self._del_doc(doc_id) doc_url = self.core.call_success("doc_id_to_url", doc_id) doc_labels = set() if doc_url is not None: self.core.call_all("doc_get_labels_by_url", doc_labels, doc_url) doc_labels = {label[0] for label in doc_labels} for doc_label in doc_labels: self.cursor.execute( "INSERT INTO labels (doc_id, label)" " VALUES (?, ?)", (doc_id, doc_label) ) doc_txt = [] self.core.call_all("doc_get_text_by_url", doc_txt, doc_url) doc_txt = "\n\n".join(doc_txt).strip() vector = self.vectorizer.partial_fit_transform([doc_txt]) if vector.shape[0] <= 0 or vector.shape[1] <= 0: vector = numpy.array([]) else: vector = vector[0].toarray() self.cursor.execute( "INSERT INTO features (doc_id, vector) VALUES (?, ?)", (doc_id, vector) ) def cancel(self): try: self.core.call_success( "mainloop_schedule", self.core.call_all, "on_label_guesser_canceled" ) if self.cursor is not None: self.cursor.execute("ROLLBACK") self.core.call_success( "sqlite_close", self.cursor, optimize=False ) self.cursor = None self.notify_done(ID) if not self.plugin.classifiers_loaded: # classifiers haven't been loaded at all yet. Now # looks like a good time for it (end of initial sync) self.plugin.reload_label_guessers() finally: if self.lock_acquired: self.plugin.classifiers_cond.release() self.lock_acquired = False def commit(self): try: LOGGER.info("Committing") if self.nb_changes > 0 and os.path.exists(self.plugin.model_path): os.unlink(self.plugin.model_path) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_label_guesser_commit_start" ) if self.nb_changes <= 0: assert self.cursor is None self.core.call_success( "mainloop_schedule", self.core.call_all, 'on_label_guesser_commit_end' ) LOGGER.info("Nothing to do. Training left unchanged.") if self.plugin.classifiers is None: # classifiers haven't been loaded at all yet. Now # looks like a good time for it (end of initial sync) self.plugin.reload_label_guessers() return if self.need_gc: self.vectorizer.gc() self.vectorizer = None self.notify_progress( ID, _("Commiting changes for label guessing ...") ) self.cursor.execute("COMMIT") self.core.call_success("sqlite_close", self.cursor) self.core.call_success( "mainloop_schedule", self.core.call_all, 'on_label_guesser_commit_end' ) LOGGER.info("Label guessing updated") self.plugin.reload_label_guessers() finally: self.notify_done(ID) if self.lock_acquired: self.plugin.classifiers_cond.release() self.lock_acquired = False class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def __init__(self): self.bayes = None self.config = None self.sql = None # If we load the classifiers, we keep the vectorizer that goes with # them, because the vectorizer must return vectors that have the size # that the classifiers expect. If we would train the vectorizer with # new documents, the vector sizes could increase # Since loading the classifiers is a fairly long operations, we only # do it when we actually need them. self.word_reductor = None self.classifiers = None self.vectorizer = None # indicates whether the classifiers have been / are # been loaded self.classifiers_loaded = False # Do NOT use an RLock() here: The transaction locks this mutex # until commit() (or cancel()) is called. However, add_doc(), # del_doc(), upd_doc() and commit() may be called from different # threads. self.classifiers_cond = threading.Condition(threading.Lock()) self.bayes_dir = None self.sql_url = None # We pickle the trained model. But pickle and Gio don't work well # together --> therefore we work directly with a path here instead of # an URL and with `os` instead `self.core.call_xxx("fs_xxx")` self.model_path = None SqliteNumpyArrayHandler.register() def get_interfaces(self): return [ 'sync', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'data_dir_handler', 'defaults': ['paperwork_backend.datadirhandler'], }, { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'doc_tracking', 'defaults': ['paperwork_backend.doctracker'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'sqlite', 'defaults': ['openpaperwork_core.sqlite'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def init(self, core): super().init(core) self.config = PluginConfig(core) self.config.register() self.core.call_all( "work_queue_create", "label_sklearn", stop_on_quit=True ) self._init() def _init(self): data_dir = self.core.call_success( "data_dir_handler_get_individual_data_dir" ) if self.bayes_dir is None: # may be set by tests self.bayes_dir = self.core.call_success( "fs_join", data_dir, "bayes" ) self.core.call_success("fs_mkdir_p", self.bayes_dir) self.sql_url = self.core.call_success( "fs_join", self.bayes_dir, 'label_guesser.db' ) self.model_path = self.core.call_success( "fs_unsafe", self.core.call_success( "fs_join", self.bayes_dir, "model.pickle" ) ) LOGGER.info("Opening guesswork.label.sklearn database") self.sql = self.core.call_one( "sqlite_execute", self.core.call_success, "sqlite_open", self.sql_url, detect_types=sqlite3.PARSE_DECLTYPES, timeout=60 ) for query in CREATE_TABLES: self.sql.execute(query) self.core.call_all( "doc_tracker_register", "label_guesser", self._build_transaction ) def _build_transaction(self, sync, total_expected): return LabelGuesserTransaction( self, guess_labels=not sync, total_expected=total_expected ) def on_data_dir_changed(self): self.on_quit() self._init() def on_quit(self): LOGGER.info("Closing guesswork.label.sklearn database") self.core.call_one( "sqlite_execute", self.core.call_success, "sqlite_close", self.sql ) def reload_label_guessers(self): self.classifiers = None self.classifiers_loaded = True promise = openpaperwork_core.promise.ThreadedPromise( self.core, self._reload_label_guessers ) self.core.call_all("work_queue_cancel_all", "label_sklearn") self.core.call_success( "work_queue_add_promise", "label_sklearn", promise ) def _reload_label_guessers(self): with self.classifiers_cond: try: cursor = self.core.call_one( "sqlite_open", self.sql_url, detect_types=sqlite3.PARSE_DECLTYPES, ) try: cursor.execute("BEGIN TRANSACTION") self.vectorizer = UpdatableVectorizer(self.core, cursor) ( self.word_reductor, self.classifiers ) = self._load_classifiers( self.model_path, cursor, self.vectorizer ) finally: cursor.execute("ROLLBACK") self.core.call_one("sqlite_close", cursor, optimize=False) finally: self.classifiers_cond.notify_all() def _load_classifiers(self, model_path, cursor, vectorizer): if os.path.exists(model_path): with open(model_path, "rb") as fd: LOGGER.info("Pre-trained model available. Using it") (reductor, classifiers) = pickle.load(fd) return (reductor, classifiers) LOGGER.info("Pre-trained model not available. Re-training one") # Jflesch> This is a very memory-intensive process. The Glib may try # to allocate memory before the GC runs and AFAIK the Glib # is not aware of Python GC, and so won't trigger it if required # (instead it will abort). # --> free as much memory as possible now # (Remember that there may be 32bits version of Paperwork out there) gc.collect() msg = _("Label guessing: Training ...") try: self.core.call_all("on_progress", "label_classifiers", 0.0, msg) corpus = Corpus.load(self.config, cursor) LOGGER.info("Training classifiers ...") start = time.time() if corpus.get_doc_count() <= 1: return (DummyFeatureReductor(), {}) corpus.standardize_feature_vectors(vectorizer) # no need to train on all the words. Only the most used words reductor = corpus.reduce_corpus_words() # Jflesch> This is a very memory-intensive process. The Glib may # try to allocate memory before the GC runs and AFAIK the Glib # is not aware of Python GC, and so won't trigger it if required # (instead it will abort). # --> free as much memory as possible now gc.collect() classifiers = collections.defaultdict( sklearn.naive_bayes.GaussianNB ) batch_iterators = [ (label, corpus.get_batches(label)) for label in corpus.get_labels() ] done = 0 total = len(batch_iterators) * corpus.get_doc_count() loop_nb = 0 timeout = False max_time = self.config.get("max_time") fit_start = time.time() try: while not timeout: for (label, batch_iterator) in batch_iterators: now = time.time() if loop_nb > 0 and now - fit_start > max_time: timeout = True LOGGER.warning( "Training is taking too long (%dms > %dms)." " Interrupting", (now - fit_start) * 1000, max_time * 1000 ) break (batch_corpus, batch_targets) = next(batch_iterator) self.core.call_all( "on_progress", "label_classifiers", done / total, _("Label guessing: Training ...") ) classifiers[label].partial_fit( batch_corpus, batch_targets, classes=[0, 1] ) done += len(batch_corpus) loop_nb += 1 except StopIteration: pass stop = time.time() LOGGER.info( "Training took %dms (Fitting: %dms) ;" " Training completed at %d%%", (stop - start) * 1000, (stop - fit_start) * 1000, done * 100 / total ) # Jflesch> This is a very memory-intensive process. The Glib may # try to allocate memory before the GC runs and AFAIK the Glib # is not aware of Python GC, and so won't trigger it if required # (instead it will abort). # --> free as much memory as possible now gc.collect() with open(model_path, "wb") as fd: pickle.dump((reductor, classifiers), fd) return (reductor, classifiers) finally: self.core.call_all("on_progress", "label_classifiers", 1.0, msg) def _guess(self, vectorizer, reductor, classifiers, doc_url): LOGGER.info("Guessing labels on %s", doc_url) doc_txt = [] self.core.call_all("doc_get_text_by_url", doc_txt, doc_url) doc_txt = "\n\n".join(doc_txt).strip() if doc_txt == u"": LOGGER.info("Can't guess. Text is empty") return vector = vectorizer.transform([doc_txt]) vector = vector.toarray() if len(vector) <= 0: LOGGER.info( "Failed to vectorize text (text length=%d)", len(doc_txt) ) return vector = vector[0] vector = reductor.reduce_features(vector) min_features = self.config.get("min_features") nb_features = 0 for f in vector: if f > 0: nb_features += 1 if nb_features < min_features: LOGGER.warning( "Document doesn't contain enough different words" " (%d ; min required is %d). Labels won't be guessed", nb_features, min_features ) return LOGGER.info("Documents contains %d features", nb_features) for (label, classifier) in classifiers.items(): predicted = classifier.predict([vector])[0] if predicted: yield label def _set_guessed_labels(self, doc_url): # self.classifiers_cond must locked assert self.classifiers is not None labels = self._guess( self.vectorizer, self.word_reductor, self.classifiers, doc_url ) labels = list(labels) for label in labels: self.core.call_success("doc_add_label_by_url", doc_url, label) def tests_cleanup(self): self.core.call_success("sqlite_close", self.sql) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/compute_backlog.py000066400000000000000000000215541456262201400336660ustar00rootroot00000000000000""" To use it: ```sh paperwork-cli plugins add \ paperwork_backend.guesswork.label.sklearn.compute_backlog paperwork-cli compute_sklearn_label_guessing_backlog ``` """ import functools import itertools import time import sklearn.naive_bayes import sklearn.feature_extraction.text import openpaperwork_core def pairwise(iterable): (a, b) = itertools.tee(iterable) next(b, None) return zip(a, b) class Baye(object): def __init__(self): self.data = [] self.targets = [] self.sklearn_count_vectorizer = None self.sklearn_tfid_transformer = None self.sklearn_classifier = None self.reset() def reset(self): self.sklearn_count_vectorizer = \ sklearn.feature_extraction.text.CountVectorizer() self.sklearn_tfid_transformer = \ sklearn.feature_extraction.text.TfidfTransformer(use_idf=False) self.sklearn_classifier = sklearn.naive_bayes.GaussianNB() def fit(self, category, text): text = text.strip() if len(text) <= 0: return category = (1 if category == 'yes' else 0) self.data.append(text) self.targets.append(category) def seal(self): counts = self.sklearn_count_vectorizer.fit_transform(self.data) tfid = self.sklearn_tfid_transformer.fit_transform(counts) self.sklearn_classifier.fit(tfid.toarray(), self.targets) def score(self, text, label): counts = self.sklearn_count_vectorizer.transform([text]) tfid = self.sklearn_tfid_transformer.transform(counts) predicted = self.sklearn_classifier.predict_proba(tfid.toarray()) r = { "no": predicted[0][0], "yes": predicted[0][1], } return r class Bayes(object): def __init__(self, labels): self.bayes = { label: Baye() for label in labels } def reset(self): for v in self.bayes.values(): v.reset() def fit(self, label, present, text): self.bayes[label].fit("yes" if present else "no", text) def seal(self): for v in self.bayes.values(): v.seal() def score(self, label, text): score = self.bayes[label].score(text, label) return { "yes": score['yes'] if 'yes' in score else 0, "no": score['no'] if 'no' in score else 0, } @functools.total_ordering class Document(object): def __init__(self, core, doc_id, text, labels): self.core = core self.doc_id = doc_id self.text = text self.labels = labels self.scores = {} def __lt__(self, other): return self.doc_id < other.doc_id def __eq__(self, other): return self.doc_id == self.doc_id def __hash__(self): return hash(self.doc_id) def fit(self, bayes, all_labels): for label in all_labels: bayes.fit(label, label in self.labels, self.text) def compute_scores(self, bayes, all_labels): for label in all_labels: self.scores[label] = bayes.score(label, self.text) def compute_accuracy(self, all_labels): success = 0 for label in all_labels: score = self.scores[label] guessed_has_label = (score['yes'] > score['no']) if guessed_has_label == (label in self.labels): success += 1 return success / len(all_labels) class Corpus(object): """ All the texts of all the documents, and their labels. """ def __init__(self, core): self.core = core self.all_documents = [] self.documents = [] self.labels = set() self.bayes = None def reset(self): self.bayes.reset() def load_all(self): self.all_documents = [] docs = [] self.core.call_all("storage_get_all_docs", docs) total = len(docs) for (idx, (doc_id, doc_url)) in enumerate(docs): self.core.call_all( "on_progress", "load_docs", idx / total, "Loading document %s" % doc_id ) text = [] self.core.call_all("doc_get_text_by_url", text, doc_url) text = "\n\n".join(text) labels = set() self.core.call_all("doc_get_labels_by_url", labels, doc_url) labels = [label[0] for label in labels] labels.sort() for label in labels: self.labels.add(label) self.all_documents.append( Document(self.core, doc_id, text, labels) ) self.all_documents.sort() self.all_documents.reverse() self.core.call_all("on_progress", "load_docs", 1.0) self.bayes = Bayes(self.labels) def _get_doc_with_label(self, label, backlog): nb = 0 for doc in self.all_documents: if label in doc.labels: yield doc nb += 1 if nb >= backlog: break def _get_doc_without_label(self, label, backlog): nb = 0 for doc in self.all_documents: if label not in doc.labels: yield doc nb += 1 if nb >= backlog: break def fit(self, backlog): docs = set() for label in self.labels: docs.update(self._get_doc_with_label(label, backlog)) docs.update(self._get_doc_without_label(label, backlog)) self.documents = set(self.all_documents) for doc in docs: self.documents.remove(doc) self.documents = list(self.documents) self.documents.sort() self.documents.reverse() self.documents = self.documents[:200] if len(self.documents) < 200: print("Not enough documents left ({})".format( len(self.documents) )) return False for (idx, doc) in enumerate(docs): self.core.call_all( "on_progress", "training", idx / len(docs), "Extracting features from %d documents" % len(docs) ) doc.fit(self.bayes, self.labels) self.core.call_all("on_progress", "training", 1.0) print("Extracted features from %d documents" % len(docs)) return True def seal(self): print("Training...") self.bayes.seal() print("Training done") def compute_scores(self): total = len(self.documents) for (idx, doc) in enumerate(self.documents): self.core.call_all( "on_progress", "scoring", idx / total, "computing label scores on %s" % doc.doc_id ) doc.compute_scores(self.bayes, self.labels) self.core.call_all("on_progress", "scoring", 1.0) def compute_accuracy(self): accuracy_sum = 0 total = len(self.documents) for doc in self.documents: accuracy_sum += doc.compute_accuracy(self.labels) return accuracy_sum / total class Plugin(openpaperwork_core.PluginBase): """ Add a command to search for the best backlog for paperwork_backend.guesswork.label.sklearn heuristically and based on the user's documents. """ def get_interfaces(self): return [ 'shell', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'doc_text', 'defaults': [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def cmd_complete_argparse(self, parser): parser.add_parser('compute_sklearn_label_guessing_backlog') def cmd_run(self, console, args): if args.command != 'compute_sklearn_label_guessing_backlog': return None corpus = Corpus(self.core) corpus.load_all() for backlog in (1, 10, 25, 50, 75, 100, 150, 200, 250, 300, 500, 2500): console.print("") console.print("Backlog {}:".format(backlog)) corpus.reset() if not corpus.fit(backlog): return {} start = time.time() corpus.seal() stop = time.time() corpus.compute_scores() accuracy = corpus.compute_accuracy() console.print( "Backlog: {} ; Accuracy: {} ; Training time: {}s".format( backlog, accuracy, int(stop - start) ) ) return {} paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/sklearn/compute_threshold.py000066400000000000000000000234141456262201400342550ustar00rootroot00000000000000""" To use it: ```sh paperwork-cli plugins add \ paperwork_backend.guesswork.label.sklearn.compute_threshold paperwork-cli compute_sklearn_label_guessing_threshold ``` """ import functools import itertools import time import sklearn.naive_bayes import sklearn.feature_extraction.text import openpaperwork_core NB_ITERATIONS = 2 # beware complexity will increase exponentionnally def pairwise(iterable): (a, b) = itertools.tee(iterable) next(b, None) return zip(a, b) class Baye(object): samples = 5 def __init__(self): self.data = [] self.targets = [] self.sklearn_count_vectorizer = \ sklearn.feature_extraction.text.CountVectorizer() self.sklearn_tfid_transformer = \ sklearn.feature_extraction.text.TfidfTransformer(use_idf=False) # For reference, always returning "no" gives an accuracy of ~0.9475 # For reference, always returning "yes" gives an accuracy of ~0.0524 # For reference, simplebayes: accuracy=~0.9912 with threshold ~0.162 # Best accuracy: ~0.9991 ; No threshold usable / to use self.sklearn_classifier = sklearn.naive_bayes.GaussianNB() # Best accuracy: ~0.9634 ; Best threshold: ~0.068 # self.sklearn_classifier = sklearn.naive_bayes.MultinomialNB() # Best accuracy: ~0.9642 ; Best threshold: ~0.078 # self.sklearn_classifier = sklearn.naive_bayes.ComplementNB() # Best accuracy: ~0.9687; Best threshold: ~0.9980 # self.sklearn_classifier = sklearn.naive_bayes.BernoulliNB() # Slow as hell. # self.sklearn_classifier = sklearn.naive_bayes.CategoricalNB() def fit(self, category, text): text = text.strip() if len(text) <= 0: return category = (1 if category == 'yes' else 0) self.data.append(text) self.targets.append(category) def seal(self): counts = self.sklearn_count_vectorizer.fit_transform(self.data) tfid = self.sklearn_tfid_transformer.fit_transform(counts) self.sklearn_classifier.fit(tfid.toarray(), self.targets) def score(self, text, label): counts = self.sklearn_count_vectorizer.transform([text]) tfid = self.sklearn_tfid_transformer.transform(counts) predicted = self.sklearn_classifier.predict_proba(tfid.toarray()) r = { "no": predicted[0][0], "yes": predicted[0][1], } if self.samples > 0: self.samples -= 1 print("Prediction sample: {}={}".format(label, r)) return r class Bayes(object): def __init__(self, labels): self.bayes = { label: Baye() for label in labels } def fit(self, label, present, text): self.bayes[label].fit("yes" if present else "no", text) def seal(self): for v in self.bayes.values(): v.seal() def score(self, label, text): score = self.bayes[label].score(text, label) return { "yes": score['yes'] if 'yes' in score else 0, "no": score['no'] if 'no' in score else 0, } @functools.total_ordering class Document(object): def __init__(self, core, doc_id, text, labels): self.core = core self.doc_id = doc_id self.text = text self.labels = labels self.scores = {} def __lt__(self, other): return self.doc_id < other.doc_id def __eq__(self, other): return self.doc_id == self.doc_id def __hash__(self): return hash(self.doc_id) def fit(self, bayes, all_labels): for label in all_labels: bayes.fit(label, label in self.labels, self.text) def compute_scores(self, bayes, all_labels): for label in all_labels: self.scores[label] = bayes.score(label, self.text) def compute_accuracy(self, threshold, all_labels): success = 0 for label in all_labels: score = self.scores[label] total = score['yes'] + score['no'] if total == 0: score = 0 else: score = score['yes'] / total guessed_has_label = score > threshold if guessed_has_label == (label in self.labels): success += 1 return success / len(all_labels) class Corpus(object): """ All the texts of all the documents, and their labels. """ def __init__(self, core): self.core = core self.documents = [] self.labels = set() self.bayes = None def load_all(self): docs = [] self.core.call_all("storage_get_all_docs", docs) total = len(docs) for (idx, (doc_id, doc_url)) in enumerate(docs): self.core.call_all( "on_progress", "load_docs", idx / total, "Loading document %s" % doc_id ) text = [] self.core.call_all("doc_get_text_by_url", text, doc_url) text = "\n\n".join(text) labels = set() self.core.call_all("doc_get_labels_by_url", labels, doc_url) labels = [label[0] for label in labels] labels.sort() for label in labels: self.labels.add(label) self.documents.append(Document(self.core, doc_id, text, labels)) self.documents.sort() self.core.call_all("on_progress", "load_docs", 1.0) self.bayes = Bayes(self.labels) def fit(self): for (idx, doc) in enumerate(self.documents): doc.fit(self.bayes, self.labels) def seal(self): self.bayes.seal() def compute_scores(self): total = len(self.documents) for (idx, doc) in enumerate(self.documents): self.core.call_all( "on_progress", "scoring", idx / total, "computing label scores on %s" % doc.doc_id ) doc.compute_scores(self.bayes, self.labels) self.core.call_all("on_progress", "scoring", 1.0) def compute_accuracy(self, threshold): accuracy_sum = 0 total = len(self.documents) for doc in self.documents: accuracy_sum += doc.compute_accuracy(threshold, self.labels) return accuracy_sum / total class Plugin(openpaperwork_core.PluginBase): """ Add a command to search for the best threshold for paperwork_backend.guesswork.label.simplebayes (see THRESHOLD_YES_NO_RATIO) heuristically and based on the user's documents. OBSOLETE: Now that we are using sklearn.GaussianNB, there is no need for a threshold anymore. """ def get_interfaces(self): return [ 'shell', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'doc_text', 'defaults': [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def cmd_complete_argparse(self, parser): parser.add_parser('compute_sklearn_label_guessing_threshold') @staticmethod def _get_next_thresholds(thresholds): """ Heuristic figuring out the next thresholds to try to estimate """ middles = [] for (threshold, next_threshold) in pairwise(thresholds): middles.append( ( (threshold[0] + next_threshold[0]) / 2, (threshold[1] + next_threshold[1]) / 2, ) ) return [m[0] for m in middles] def cmd_run(self, console, args): if args.command != 'compute_sklearn_label_guessing_threshold': return None corpus = Corpus(self.core) corpus.load_all() corpus.fit() corpus.seal() corpus.compute_scores() iterations = NB_ITERATIONS thresholds = [ (threshold, corpus.compute_accuracy(threshold)) for threshold in (0.0, 1.0) ] for iteration in range(0, iterations): console.print("") best = max(thresholds, key=lambda x: x[1]) console.print( "Iteration {}: best accuracy={}, best threshold={}".format( iteration, best[1], best[0] ) ) start = time.time() next_thresholds = self._get_next_thresholds(thresholds) total = len(next_thresholds) for (idx, next_threshold) in enumerate(next_thresholds): self.core.call_all( "on_progress", "iteration", idx / total, "Iteration %d" % iteration ) thresholds.append( (next_threshold, corpus.compute_accuracy(next_threshold)), ) thresholds.sort() self.core.call_all("on_progress", "iteration", 1.0) stop = time.time() s = int(stop - start) ms = int(((stop - start) * 1000) % 1000) console.print("Iteration took {}s {}ms".format(s, ms)) console.print("") for threshold in thresholds: console.print("Threshold: {}".format(threshold)) console.print("") best = max(thresholds, key=lambda x: x[1]) console.print("RESULT: best accuraccy={}, best threshold={}".format( best[1], best[0] )) return { "all": thresholds, "best": best, } gaussian_with_hashes.py000066400000000000000000000175471456262201400346600ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/label/sklearn""" To use it: ```sh paperwork-cli plugins add \ paperwork_backend.guesswork.label.sklearn.gaussian_with_hashes paperwork-cli test_sklearn_gaussian_with_hashes ``` """ import time import functools import sklearn.naive_bayes import openpaperwork_core samples = 5 class Baye(object): def __init__(self, core, label, n_features): self.core = core self.label = label self.data = [] self.counts = [] self.tfid = [] self.targets = [] self.sklearn_hash_vectorizer = \ sklearn.feature_extraction.text.HashingVectorizer( n_features=n_features ) self.sklearn_tfid_transformer = \ sklearn.feature_extraction.text.TfidfTransformer(use_idf=False) # Best accuracy: ~0.9991 self.sklearn_classifier = sklearn.naive_bayes.GaussianNB() def fit(self, category, text): text = text.strip() if len(text) <= 0: return category = (1 if category == 'yes' else 0) self.data.append(text) self.targets.append(category) def seal(self): r = 0 self.core.call_all( "on_progress", "fitting", 0.0, "Fitting training of label {} ...".format(self.label) ) for pos in range(0, len(self.data), 50): self.core.call_all( "on_progress", "fitting", pos / len(self.data), "Fitting training of label {} ...".format(self.label) ) counts = self.sklearn_hash_vectorizer.fit_transform( self.data[pos:pos + 50] ) tfid = self.sklearn_tfid_transformer.fit_transform( counts ).toarray() start = time.time() self.sklearn_classifier.partial_fit( tfid, self.targets[pos:pos + 50], classes=[0, 1] ) stop = time.time() r += stop - start self.core.call_all("on_progress", "fitting", 1.0) return r def score(self, text, label): global samples counts = self.sklearn_hash_vectorizer.transform([text]) tfid = self.sklearn_tfid_transformer.transform(counts) predicted = self.sklearn_classifier.predict_proba(tfid.toarray()) r = { "no": predicted[0][0], "yes": predicted[0][1], } if samples > 0: samples -= 1 print("Prediction sample: {}={}".format(label, r)) return r class Bayes(object): def __init__(self, core, labels, n_features): self.core = core self.bayes = { label: Baye(core, label, n_features) for label in labels } def fit(self, label, present, text): self.bayes[label].fit("yes" if present else "no", text) def seal(self): r = 0 for (idx, (k, v)) in enumerate(self.bayes.items()): print("Fitting training of label {} ({}/{}) ...".format( k, idx, len(self.bayes) )) r += v.seal() s = int(r) ms = int(((r) * 1000) % 1000) print("Fitting took {}s {}ms for {} labels".format( s, ms, len(self.bayes) )) def score(self, label, text): score = self.bayes[label].score(text, label) return { "yes": score['yes'] if 'yes' in score else 0, "no": score['no'] if 'no' in score else 0, } @functools.total_ordering class Document(object): def __init__(self, core, doc_id, text, labels): self.core = core self.doc_id = doc_id self.text = text self.labels = labels self.scores = {} def __lt__(self, other): return self.doc_id < other.doc_id def __eq__(self, other): return self.doc_id == self.doc_id def __hash__(self): return hash(self.doc_id) def fit(self, bayes, all_labels): for label in all_labels: bayes.fit(label, label in self.labels, self.text) def compute_scores(self, bayes, all_labels): for label in all_labels: self.scores[label] = bayes.score(label, self.text) def compute_accuracy(self, all_labels): success = 0 for label in all_labels: score = self.scores[label] guessed_has_label = score['yes'] > score['no'] if guessed_has_label == (label in self.labels): success += 1 return success / len(all_labels) class Corpus(object): """ All the texts of all the documents, and their labels. """ def __init__(self, core): self.core = core self.documents = [] self.labels = set() self.bayes = None def load_all(self): docs = [] self.core.call_all("storage_get_all_docs", docs) total = len(docs) for (idx, (doc_id, doc_url)) in enumerate(docs): self.core.call_all( "on_progress", "load_docs", idx / total, "Loading document %s" % doc_id ) text = [] self.core.call_all("doc_get_text_by_url", text, doc_url) text = "\n\n".join(text) labels = set() self.core.call_all("doc_get_labels_by_url", labels, doc_url) labels = [label[0] for label in labels] labels.sort() for label in labels: self.labels.add(label) self.documents.append(Document(self.core, doc_id, text, labels)) self.documents.sort() self.core.call_all("on_progress", "load_docs", 1.0) def mk_bayes(self, n_features): self.bayes = Bayes(self.core, self.labels, n_features) def fit(self): for (idx, doc) in enumerate(self.documents): doc.fit(self.bayes, self.labels) def seal(self): self.bayes.seal() def compute_scores(self): total = len(self.documents) for (idx, doc) in enumerate(self.documents): self.core.call_all( "on_progress", "scoring", idx / total, "computing label scores on %s" % doc.doc_id ) doc.compute_scores(self.bayes, self.labels) self.core.call_all("on_progress", "scoring", 1.0) def compute_accuracy(self): accuracy_sum = 0 total = len(self.documents) for doc in self.documents: accuracy_sum += doc.compute_accuracy(self.labels) return accuracy_sum / total class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shell', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'doc_text', 'defaults': [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def cmd_complete_argparse(self, parser): parser.add_parser('test_sklearn_gaussian_with_hashes') def cmd_run(self, console, args): if args.command != 'test_sklearn_gaussian_with_hashes': return None corpus = Corpus(self.core) corpus.load_all() for two_pow in (16, 18, 20,): n_features = 2 ** two_pow corpus.mk_bayes(n_features) corpus.fit() corpus.seal() corpus.compute_scores() accuracy = corpus.compute_accuracy() console.print("n_features=2**{} --> accuracy={}".format( two_pow, accuracy )) return True paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/ocr/000077500000000000000000000000001456262201400262145ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/ocr/__init__.py000066400000000000000000000000001456262201400303130ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/ocr/pyocr.py000066400000000000000000000146651456262201400277360ustar00rootroot00000000000000import logging import pyocr import pyocr.builders import openpaperwork_core from ... import (_, sync) LOGGER = logging.getLogger(__name__) ID = "ocr" class OcrTransaction(sync.BaseTransaction): def __init__(self, plugin, sync, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY self.plugin = plugin self.sync = sync # for each document, we need to track which pages have already been # OCR-ed, which have been modified (cropping, rotation, ...) # and must be re-OCRed, and which have not been changed. self.page_tracker = self.core.call_success("page_tracker_get", ID) def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def _run_ocr_on_page( self, doc_id, doc_url, page_idx, page_nb, total_pages, wordless_only=False): if wordless_only: has_text = self.core.call_success( "page_has_text_by_url", doc_url, page_idx ) if has_text: # there is already some text on this page self.notify_progress( ID, _( "Document {doc_id} p{page_idx} has already some text." " No OCR run" ).format(doc_id=doc_id, page_idx=(page_idx + 1)), page_nb=page_nb, total_pages=total_pages ) return self.notify_progress( ID, _("Running OCR on document {doc_id} p{page_idx}").format( doc_id=doc_id, page_idx=(page_idx + 1) ), page_nb=page_nb, total_pages=total_pages ) self.plugin.ocr_page_by_url(doc_url, page_idx) def _run_ocr_on_modified_pages(self, doc_id, wordless_only=False): doc_url = self.core.call_success("doc_id_to_url", doc_id) need_end_notification = False modified_pages = list(self.page_tracker.find_changes(doc_id, doc_url)) for (page_nb, (change, page_idx)) in enumerate(modified_pages): # Run OCR on modified pages, but only if we are not synchronizing # with the work directory (--> if the user just added or modified # a document) if not self.sync and (change == 'new' or change == 'upd'): self._run_ocr_on_page( doc_id, doc_url, page_idx, page_nb, len(modified_pages), wordless_only ) need_end_notification = True self.page_tracker.ack_page(doc_id, doc_url, page_idx) if need_end_notification: self.notify_progress( ID, _("Running OCR"), page_nb=len(modified_pages), total_pages=len(modified_pages) ) def add_doc(self, doc_id): self._run_ocr_on_modified_pages(doc_id, wordless_only=True) super().add_doc(doc_id) def upd_doc(self, doc_id): self._run_ocr_on_modified_pages(doc_id, wordless_only=True) super().upd_doc(doc_id) def del_doc(self, doc_id): self.page_tracker.delete_doc(doc_id) super().del_doc(doc_id) def cancel(self): self.page_tracker.cancel() self.notify_done(ID) def commit(self): self.page_tracker.commit() self.notify_done(ID) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def get_interfaces(self): return [ "ocr", "syncable", # actually satisfied by the plugin 'doctracker' ] def get_deps(self): return [ { 'interface': 'doc_tracking', 'defaults': ['paperwork_backend.doctracker'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'page_boxes', 'defaults': [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'page_tracking', 'defaults': ['paperwork_backend.pagetracker'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, ] def init(self, core): super().init(core) self.core.call_all( "doc_tracker_register", ID, lambda sync, total_expected=-1: OcrTransaction( self, sync, total_expected ) ) def ocr_page_by_url(self, doc_url, page_idx): if self.core.call_success("ocr_is_enabled") is None: LOGGER.info("OCR is disabled") return LOGGER.info("Running OCR on page %d of %s", page_idx, doc_url) doc_id = self.core.call_success("doc_url_to_id", doc_url) if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_start", doc_id, page_idx ) try: page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) ocr_tool = pyocr.get_available_tools()[0] LOGGER.info( "Will use tool '%s' on %s p%d (%s)", ocr_tool.get_name(), doc_url, page_idx, page_img_url ) ocr_langs = self.core.call_success("ocr_get_active_langs") img = self.core.call_success("url_to_pillow", page_img_url) boxes = ocr_tool.image_to_string( img, lang="+".join(ocr_langs), builder=pyocr.builders.LineBoxBuilder() ) self.core.call_success( "page_set_boxes_by_url", doc_url, page_idx, boxes ) except Exception as exc: LOGGER.error("OCR FAILED", exc_info=exc) finally: if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_end", doc_id, page_idx ) return True paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/orientation/000077500000000000000000000000001456262201400277645ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/orientation/__init__.py000066400000000000000000000000001456262201400320630ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/guesswork/orientation/pyocr.py000066400000000000000000000156171456262201400315040ustar00rootroot00000000000000import logging import PIL import PIL.Image import pyocr import pyocr.builders import openpaperwork_core from ... import (_, sync) LOGGER = logging.getLogger(__name__) ID = "orientation_guesser" class OrientationTransaction(sync.BaseTransaction): def __init__(self, plugin, sync, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY self.plugin = plugin self.sync = sync # for each document, we need to track on which pages we have already # guessed the orientation and on which page we didn't yet. self.page_tracker = self.core.call_success("page_tracker_get", ID) def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def _guess_page_orientation( self, doc_id, doc_url, page_idx, page_nb, total_pages): if self.core.call_success( "page_has_text_by_url", doc_url, page_idx ): self.notify_progress( ID, _( "Document {doc_id} p{page_idx} has already some text." " Not guessing page orientation." ).format(doc_id=doc_id, page_idx=(page_idx + 1)), page_nb=page_nb, total_pages=total_pages ) return self.notify_progress( ID, _( "Guessing orientation of" " document {doc_id} p{page_idx}" ).format(doc_id=doc_id, page_idx=(page_idx + 1)), page_nb=page_nb, total_pages=total_pages ) self.plugin.guess_page_orientation_by_url(doc_url, page_idx) def _guess_new_page_orientations(self, doc_id): doc_url = self.core.call_success("doc_id_to_url", doc_id) need_end_notification = False modified_pages = list(self.page_tracker.find_changes(doc_id, doc_url)) for (page_nb, (change, page_idx)) in enumerate(modified_pages): # Guess page orientation on new pages, but only if we are # not synchronizing with the work directory if not self.sync and change == 'new': self._guess_page_orientation( doc_id, doc_url, page_idx, page_nb, len(modified_pages) ) need_end_notification = True self.page_tracker.ack_page(doc_id, doc_url, page_idx) if need_end_notification: self.notify_progress( ID, _("Guessing page orientation"), page_nb=len(modified_pages), total_pages=len(modified_pages) ) def add_doc(self, doc_id): self._guess_new_page_orientations(doc_id) super().add_doc(doc_id) def upd_doc(self, doc_id): self._guess_new_page_orientations(doc_id) super().upd_doc(doc_id) def del_doc(self, doc_id): self.page_tracker.delete_doc(doc_id) super().del_doc(doc_id) def cancel(self): self.page_tracker.cancel() self.notify_done(ID) def commit(self): self.page_tracker.commit() self.notify_done(ID) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 2000 def get_interfaces(self): return [ "orientation_guesser", "syncable", # actually satisfied by the plugin 'doctracker' ] def get_deps(self): return [ { 'interface': 'doc_tracking', 'defaults': ['paperwork_backend.doctracker'] }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'page_tracking', 'defaults': ['paperwork_backend.pagetracker'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, ] def init(self, core): super().init(core) self.core.call_all( "doc_tracker_register", ID, lambda sync, total_expected=-1: OrientationTransaction( self, sync, total_expected ) ) def guess_page_orientation_by_url(self, doc_url, page_idx): if self.core.call_success("ocr_is_enabled") is None: LOGGER.info("OCR is disabled") return LOGGER.info( "Using OCR to guess orientation of page %d of %s", page_idx, doc_url ) doc_id = self.core.call_success("doc_url_to_id", doc_url) if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_start", doc_id, page_idx ) try: page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) for ocr_tool in pyocr.get_available_tools(): LOGGER.info( "Orientation guessing: Will use tool '%s'", ocr_tool.get_name() ) if ocr_tool.can_detect_orientation(): break LOGGER.warning( "Orientation guessing: Tool '%s' cannot detect" " orientation", ocr_tool.get_name() ) else: LOGGER.warning( "Orientation guessing: No tool found able to detect" " orientation" ) return None ocr_langs = self.core.call_success("ocr_get_active_langs") img = self.core.call_success("url_to_pillow", page_img_url) try: r = ocr_tool.detect_orientation(img, lang="+".join(ocr_langs)) except pyocr.PyocrException as exc: LOGGER.warning( "Orientation guessing: Failed to guess orientation", exc_info=exc ) return None angle = r['angle'] if angle == 0: return 0 transform_enum = getattr(PIL.Image, 'Transpose', PIL.Image) t_angle = { 90: transform_enum.ROTATE_90, 180: transform_enum.ROTATE_180, 270: transform_enum.ROTATE_270, }[angle] img = img.transpose(t_angle) page_img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx, write=True ) self.core.call_success("pillow_to_url", img, page_img_url) finally: if doc_id is not None: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_page_modification_end", doc_id, page_idx ) return angle paperwork-2.2.2/paperwork-backend/src/paperwork_backend/i18n/000077500000000000000000000000001456262201400241575ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/i18n/__init__.py000066400000000000000000000000001456262201400262560ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/i18n/pycountry.py000066400000000000000000000014601456262201400266060ustar00rootroot00000000000000import pycountry import openpaperwork_core from .. import _ LANGUAGES = { "English": _("English"), "French": _("French"), "German": _("German"), } class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['i18n_lang'] def i18n_lang_iso639_3_to_full(self, iso): attrs = [ 'iso639_3_code', 'terminology', 'alpha_3', ] for attr in attrs: try: r = pycountry.pycountry.languages.get(**{attr: iso}) if r is None: continue r = r.name if r in LANGUAGES: return LANGUAGES[r] return r except (KeyError, UnicodeDecodeError): pass return iso paperwork-2.2.2/paperwork-backend/src/paperwork_backend/i18n/scanner.py000066400000000000000000000027141456262201400261660ustar00rootroot00000000000000import logging import re import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): RE_SPLIT_SOURCE_NAME = [ re.compile(r'([()])'), re.compile(r'(\W)'), ] def __init__(self): super().__init__() # Need the l10n plugin to be loaded first before getting the # translations self.keywords = {} def get_interfaces(self): return ['i18n_scanner'] def get_deps(self): return [ { 'interface': 'l10n', 'defaults': ['openpaperwork_core.l10n.python'], }, ] def init(self, core): super().init(core) self.keywords = { "centrally aligned": _("centrally aligned"), "feeder": _("Feeder"), "flatbed": _("Flatbed"), "left aligned": _("left aligned"), "right aligned": _("right aligned"), } def i18n_scanner_source(self, source_name): original = source_name for regex in self.RE_SPLIT_SOURCE_NAME: source_name = regex.split(source_name) for i in range(0, len(source_name)): if source_name[i].lower() in self.keywords: source_name[i] = self.keywords[source_name[i].lower()] source_name = "".join(source_name) LOGGER.debug("I18n: %s --> %s", original, source_name) return source_name paperwork-2.2.2/paperwork-backend/src/paperwork_backend/imgedit/000077500000000000000000000000001456262201400250225ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/imgedit/__init__.py000066400000000000000000000013401456262201400271310ustar00rootroot00000000000000class AbstractImgEditor(object): def transform(self, img, preview=False): """ Apply the transformation operation. Arguments: img -- image to transform preview -- indicates if we intend to use the result as a preview or as final result """ assert False def transform_frame(self, img_size, frame): """ From the frame applied to the original image to the resulting image. """ return frame def untransform_frame(self, img_size, frame): """ From the frame on the resulting image to the original image. """ return frame def __eq__(self, o): return type(self) is type(o) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/imgedit/color.py000066400000000000000000000020571456262201400265160ustar00rootroot00000000000000import pillowfight import openpaperwork_core from . import AbstractImgEditor class ColorImgEditor(AbstractImgEditor): def transform(self, img, preview=False): return pillowfight.ace( img, samples=50 if preview else 200 ) class Plugin(openpaperwork_core.PluginBase): NAME = 'color_equalization' def get_interfaces(self): return ['img_editor'] def img_editor_get_names(self, out: list): out.append(self.NAME) def img_editor_get(self, name, *args, **kwargs): if name != self.NAME: return None return ColorImgEditor() def img_editor_set(self, inout: list, name, *args, **kwargs): if name != self.NAME: return None c = ColorImgEditor() if c in inout: # an ACE editor is already in the list return inout.append(c) def img_editor_unset(self, inout: list, name): if name != self.NAME: return None c = ColorImgEditor() while c in inout: inout.remove(c) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/imgedit/crop.py000066400000000000000000000046301456262201400263420ustar00rootroot00000000000000import logging import PIL import PIL.Image import pillowfight import openpaperwork_core from . import AbstractImgEditor LOGGER = logging.getLogger(__name__) class CropImgEditor(AbstractImgEditor): def __init__(self, frame=None, **kwargs): self.frame = frame def transform(self, img, preview=False): if self.frame is None: # optimize the default frame LOGGER.info("Guessing new default cropping frame ...") # It's actually faster to resize down the image than look # for the scan borders on the full-size image. smaller_img = img.resize( (int(img.size[0] / 2), int(img.size[1] / 2)), getattr(PIL.Image, 'Resampling', PIL.Image).LANCZOS ) frame = pillowfight.find_scan_borders(smaller_img) if frame[0] >= frame[2] or frame[1] >= frame[3]: LOGGER.info("Failed to guess a cropping frame") # defaulting to the whole image self.frame = (0, 0, img.size[0], img.sixe[1]) else: # if we have found a valid frame LOGGER.info("Guessed cropping frame: %s", frame) self.frame = ( frame[0] * 2, frame[1] * 2, frame[2] * 2, frame[3] * 2 ) if preview: # we do not crop the preview. The UI displays a frame on top # of it showing where the cropping will happen. return img img = img.crop(self.frame) return img class Plugin(openpaperwork_core.PluginBase): NAME = 'cropping' def get_interfaces(self): return ['img_editor'] def img_editor_get_names(self, out: list): out.append(self.NAME) def img_editor_get(self, name, *args, **kwargs): if name != self.NAME: return None return CropImgEditor(**kwargs) def img_editor_set(self, inout: list, name, *args, **kwargs): if name != self.NAME: return None c = CropImgEditor(**kwargs) try: # Check if we already have a CropImgEditor in the list. # If so, do nothing inout.index(c) except ValueError: inout.append(c) def img_editor_unset(self, inout: list, name): if name != self.NAME: return None c = CropImgEditor() while c in inout: inout.remove(c) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/imgedit/rotate.py000066400000000000000000000063521456262201400267000ustar00rootroot00000000000000import openpaperwork_core import PIL import PIL.Image from . import AbstractImgEditor class RotationImgEditor(AbstractImgEditor): def __init__(self, angle): self.angle = angle % 360 def transform(self, img, preview=False): # Pillow operates counter-clockwise, we operate clockwise. if self.angle == 0: return img transform_enum = getattr(PIL.Image, 'Transpose', PIL.Image) angle = { 90: transform_enum.ROTATE_90, 180: transform_enum.ROTATE_180, 270: transform_enum.ROTATE_270, }[self.angle] return img.transpose(angle) def _transform_frame(self, img_size, frame, transform_pt): frame = ( transform_pt(img_size, (frame[0], frame[1])), transform_pt(img_size, (frame[2], frame[3])), ) return ( min(frame[0][0], frame[1][0]), min(frame[0][1], frame[1][1]), max(frame[0][0], frame[1][0]), max(frame[0][1], frame[1][1]), ) def transform_frame(self, img_size, frame): return self._transform_frame(img_size, frame, self.transform_point) def untransform_frame(self, img_size, frame): return self._transform_frame(img_size, frame, self.untransform_point) def _transform_pt(self, img_size, pt, angle): r = { 0: pt, 90: (pt[1], img_size[0] - pt[0]), 270: (img_size[1] - pt[1], pt[0]), 180: (img_size[0] - pt[0], img_size[1] - pt[1]), }[angle] return r def transform_point(self, img_size, pt): return self._transform_pt(img_size, pt, self.angle) def untransform_point(self, img_size, pt): # we are given the image size before we apply our transformation # but here we want to go the other way around img_size = { 0: img_size, 90: (img_size[1], img_size[0]), 270: (img_size[1], img_size[0]), 180: img_size, }[self.angle] angle = ((-1 * self.angle) % 360) return self._transform_pt(img_size, pt, angle) class Plugin(openpaperwork_core.PluginBase): NAME = 'rotation' def get_interfaces(self): return ['img_editor'] def img_editor_get_names(self, out: list): out.append(self.NAME) def img_editor_get(self, name, *args, **kwargs): if name != self.NAME: return None angle = kwargs.pop('angle') return RotationImgEditor(angle) def img_editor_set(self, inout: list, name, *args, **kwargs): if name != self.NAME: return None angle = kwargs.pop('angle') c = RotationImgEditor(angle) # Check if we already have a RotationImgEditor in the list. # If so, update it instead of adding another one # Only if its the latest element in the list -> otherwise we may # mess up the cropping frame if len(inout) > 0 and inout[-1] == c: inout[-1].angle += angle inout[-1].angle %= 360 else: inout.append(c) def img_editor_unset(self, inout: list, name): if name != self.NAME: return None c = RotationImgEditor(0) while c in inout: inout.remove(c) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/index/000077500000000000000000000000001456262201400245075ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/index/__init__.py000066400000000000000000000000001456262201400266060ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/index/whoosh.py000066400000000000000000000350061456262201400263740ustar00rootroot00000000000000import datetime import logging import time import whoosh.fields import whoosh.index import whoosh.qparser import whoosh.query import whoosh.sorting import openpaperwork_core from .. import (_, sync) LOGGER = logging.getLogger(__name__) ID = "index" WHOOSH_SCHEMA = whoosh.fields.Schema( docid=whoosh.fields.ID(stored=True, unique=True, sortable=True), docfilehash=whoosh.fields.ID(), content=whoosh.fields.TEXT(spelling=True), label=whoosh.fields.KEYWORD(commas=True, scorable=True), date=whoosh.fields.DATETIME(sortable=True), last_read=whoosh.fields.DATETIME(stored=True), ) class CustomFuzzySearch(whoosh.qparser.query.FuzzyTerm): def __init__( self, fieldname, text, boost=1.0, maxdist=1, prefixlength=0, constantscore=True ): whoosh.qparser.query.FuzzyTerm.__init__( self, fieldname, text, boost, maxdist, prefixlength, constantscore=True ) class WhooshTransaction(sync.BaseTransaction): """ Transaction to apply on the index. Methods may be slow but they are thread-safe. """ def __init__(self, plugin, total_expected=-1): super().__init__(plugin.core, total_expected) self.priority = plugin.PRIORITY LOGGER.debug("Starting Whoosh index transaction") self.core = plugin.core self.writer = None self.modified = 0 self.writer = plugin.index.writer() def __enter__(self): pass def __exit__(self, exc_type, exc_val, exc_tb): self.cancel() def __del__(self): self.cancel() def _update_doc_in_index(self, doc_id): """ Collect infos on the document and add/update a document in the index """ doc_url = self.core.call_success("doc_id_to_url", doc_id) doc_mtime = self.core.call_success("doc_get_mtime_by_url", doc_url) if doc_mtime is None: doc_mtime = 0 doc_mtime = datetime.datetime.fromtimestamp(doc_mtime) doc_hash = self.core.call_success("doc_get_hash_by_url", doc_url) if doc_hash is None: # we get a hash only for PDF documents, not image documents. doc_hash = "undefined" else: doc_hash = ("%X" % doc_hash) doc_text = [] self.core.call_all("doc_get_text_by_url", doc_text, doc_url) doc_text = "\n\n".join(doc_text) doc_text = self.core.call_success("i18n_strip_accents", doc_text) doc_labels = set() self.core.call_all("doc_get_labels_by_url", doc_labels, doc_url) doc_labels = ",".join([label[0] for label in doc_labels]) doc_labels = self.core.call_success("i18n_strip_accents", doc_labels) doc_date = self.core.call_success("doc_get_date_by_id", doc_id) if doc_date is None: doc_date = datetime.datetime(year=1970, month=1, day=1) query = whoosh.query.Term("docid", doc_id) self.writer.delete_by_query(query) self.writer.update_document( docid=doc_id, docfilehash=doc_hash, content=doc_text, label=doc_labels, date=doc_date, last_read=doc_mtime ) def add_doc(self, doc_id): LOGGER.info("Adding document '%s' to index", doc_id) self.notify_progress( ID, _("Indexing new document %s") % doc_id ) self._update_doc_in_index(doc_id) self.modified += 1 super().add_doc(doc_id) def del_doc(self, doc_id): LOGGER.info("Removing document '%s' from index", doc_id) self.notify_progress( ID, _("Removing document %s from index") % doc_id ) query = whoosh.query.Term("docid", doc_id) self.writer.delete_by_query(query) self.modified += 1 super().del_doc(doc_id) def upd_doc(self, doc_id): LOGGER.info("Updating document '%s' in index", doc_id) self.notify_progress( ID, _("Indexing updated document %s") % doc_id ) self._update_doc_in_index(doc_id) self.modified += 1 super().upd_doc(doc_id) def unchanged_doc(self, doc_id): self.notify_progress( ID, _("Examining document %s: unchanged") % (doc_id) ) super().unchanged_doc(doc_id) def cancel(self): if self.writer is None: return self.core.call_one( "mainloop_schedule", self.core.call_all, 'on_index_cancel' ) LOGGER.info("Canceling transaction") self.writer.cancel() self.writer = None self.core.call_one( "mainloop_schedule", self.core.call_all, "on_index_updated" ) self.notify_done(ID) def commit(self): self.notify_progress( ID, _("Committing changes in the index ...") ) self.core.call_one( "mainloop_schedule", self.core.call_all, 'on_index_commit_start' ) if self.modified <= 0: LOGGER.info( "commit() called but nothing to commit." " Cancelling transaction" ) self.writer.cancel() self.writer = None else: LOGGER.info( "Committing %d changes to Whoosh index", self.modified ) self.writer.commit() self.writer = None self.notify_done(ID) self.core.call_success( "mainloop_schedule", self.core.call_all, 'on_index_commit_end' ) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.obs_callbacks = [] self.query_parsers = { 'strict': [], 'fuzzy': [], } self.index = None self.local_dir = None self.index_dir = None def get_interfaces(self): return [ "index", "suggestions", "syncable", ] def get_deps(self): return [ { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'data_dir_handler', 'defaults': ['paperwork_backend.datadirhandler'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, # Optional dependencies: # { # 'interface': 'page_boxes', # 'defaults': [ # 'paperwork_backend.model.hocr', # 'paperwork_backend.model.pdf', # ], # }, # { # 'interface': 'doc_hash', # 'defaults': ['paperwork_backend.model.pdf'], # }, # { # 'interface': 'doc_labels', # 'defaults': ['paperwork_backend.model.labels'], # }, ] def init(self, core): super().init(core) self._init() def _init(self): data_dir = self.core.call_success( "data_dir_handler_get_individual_data_dir" ) self.index_dir = self.core.call_success( "fs_join", data_dir, "index" ) need_index_rewrite = True while need_index_rewrite: try: LOGGER.info( "Opening Whoosh index '%s' ...", self.index_dir ) self.index = whoosh.index.open_dir( self.core.call_success("fs_unsafe", self.index_dir) ) # check that the schema is up-to-date # We use the string representation of the schemas, because # previous versions of whoosh don't always implement __eq__ if str(self.index.schema) != str(WHOOSH_SCHEMA): raise Exception("Index version mismatch") need_index_rewrite = False except Exception as exc: LOGGER.warning( "Failed to open index '%s': %s." " Will rebuild index from scratch", self.index_dir, exc ) if need_index_rewrite: self._destroy() LOGGER.info("Creating a new index") self.core.call_success("fs_mkdir_p", self.index_dir) new_index = whoosh.index.create_in( self.core.call_success("fs_unsafe", self.index_dir), WHOOSH_SCHEMA ) new_index.close() LOGGER.info("Index '%s' created", self.index_dir) self.query_parsers = { 'fuzzy': [ whoosh.qparser.MultifieldParser( ["label", "content"], schema=self.index.schema, termclass=CustomFuzzySearch ), whoosh.qparser.MultifieldParser( ["label", "content"], schema=self.index.schema, termclass=whoosh.qparser.query.Prefix ), ], 'strict': [ whoosh.qparser.MultifieldParser( ["label", "content"], schema=self.index.schema, termclass=whoosh.query.Term ), ], } def on_data_dir_changed(self): self._close() self._init() def _close(self): LOGGER.info("Closing Whoosh index") if self.index is not None: self.index.close() self.index = None def _destroy(self): self._close() if self.core.call_success("fs_exists", self.index_dir) is not None: LOGGER.warning("Destroying the index ...") self.core.call_success("fs_rm_rf", self.index_dir) LOGGER.warning("Index destroyed") def doc_transaction_start(self, out: list, total_expected=-1): out.append(WhooshTransaction(self, total_expected)) def index_search(self, out: list, query, limit=None, search_type='fuzzy'): start = time.time() out_set = set() query = query.strip() query = self.core.call_success("i18n_strip_accents", query) if query == "": queries = [whoosh.query.Every()] else: queries = [] for parser in self.query_parsers[search_type]: queries.append(parser.parse(query)) with self.index.searcher() as searcher: for q in queries: facet = whoosh.sorting.FieldFacet("docid", reverse=True) results = searcher.search(q, limit=limit, sortedby=facet) has_results = False for result in results: has_results = True doc_id = result['docid'] doc_url = self.core.call_success("doc_id_to_url", doc_id) if doc_url is None: continue out_set.add((doc_id, doc_url)) if limit is not None and len(out_set) >= limit: break if has_results: break out += out_set stop = time.time() LOGGER.info( "Search [%s] took %dms (limit=%s, type=%s)", query, (stop - start) * 1000, limit, search_type ) def index_get_doc_id_by_hash(self, doc_hash): doc_hash = "%X" % doc_hash with self.index.searcher() as searcher: results = searcher.search( whoosh.query.Term('docfilehash', doc_hash) ) if len(results) <= 0: return None return results[0] def suggestion_get(self, out: set, sentence): query_parser = self.query_parsers['strict'][0] query = query_parser.parse(sentence) with self.index.searcher() as searcher: corrected = searcher.correct_query( query, sentence, correctors={ 'content': searcher.corrector("content"), 'label': searcher.corrector("label"), } ) if corrected.query != query: out.add(corrected.string) def sync(self, promises: list): """ Requests the document list from the document storage plugin and updates the index accordingly. This call is asynchronous and use the main loop to do its job. """ storage_all_docs = [] promise = openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("storage_get_all_docs", storage_all_docs,) ) promise = promise.then(lambda *args, **kwargs: None) class IndexDoc(object): def __init__(s, index_result): (s.key, s.extra) = index_result def get_index_docs(): with self.index.searcher() as searcher: index_all_docs = searcher.search( whoosh.query.Every(), limit=None ) index_all_docs = [ (result['docid'], result['last_read']) for result in index_all_docs ] index_all_docs = [IndexDoc(r) for r in index_all_docs] return index_all_docs promise = promise.then( lambda: ( [ sync.StorageDoc(self.core, doc[0], doc[1]) for doc in storage_all_docs ], get_index_docs() ) ) promise = promise.then( lambda args: ( args[0], args[1], [WhooshTransaction( self, max(len(storage_all_docs), len(args[1])) )] ) ) promise = promise.then(lambda args: sync.Syncer( self.core, ["whoosh"], args[0], args[1], args[2] )) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, lambda syncer: syncer.run() )) promises.append(promise) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/l10n/000077500000000000000000000000001456262201400241525ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/l10n/__init__.py000066400000000000000000000007351456262201400262700ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['l10n_init'] def get_deps(self): return [ { 'interface': 'l10n', 'defaults': ['openpaperwork_core.l10n.python'], }, ] def init(self, core): super().init(core) self.core.call_all( "l10n_load", "paperwork_backend.l10n", "paperwork_backend" ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/000077500000000000000000000000001456262201400245005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/__init__.py000066400000000000000000000017631456262201400266200ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['nb_pages'] def doc_get_nb_pages_by_url(self, doc_url): out = [] self.core.call_all("doc_internal_get_nb_pages_by_url", out, doc_url) r = max(out, default=0) if r == 0: return None return r def page_get_hash_by_url(self, doc_url, page_idx): out = [] self.core.call_all( "page_internal_get_hash_by_url", out, doc_url, page_idx ) r = 0 for h in out: r ^= h return r def doc_get_mtime_by_url(self, doc_url): out = [] self.core.call_all("doc_internal_get_mtime_by_url", out, doc_url) return max(out, default=None) def page_get_mtime_by_url(self, doc_url, page_idx): out = [] self.core.call_all( "page_internal_get_mtime_by_url", out, doc_url, page_idx ) return max(out, default=None) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/converted.py000066400000000000000000000177151456262201400270560ustar00rootroot00000000000000""" Takes of various document format that are actually converted to PDF files so Paperwork can read them quickly """ import logging import openpaperwork_core import openpaperwork_core.promise from .. import _ LOGGER = logging.Logger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 200 def __init__(self): super().__init__() self.pending_doc_urls = set() self.file_types_by_ext = {} self.file_types_by_mime = {} self.cache_hash = {} def get_interfaces(self): return [ "doc_convert_and_import", "doc_hash", "sync", ] def get_deps(self): return [ { 'interface': 'doc_converter', 'defaults': ['paperwork_backend.converter.libreoffice'], }, { 'interface': 'doc_pdf_import', 'defaults': ['paperwork_backend.model.pdf'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) file_types = set() self.core.call_all("converter_get_file_types", file_types) self.file_types_by_ext = { ext: mime for (mime, ext, human_name) in file_types } self.file_types_by_mime = { mime: ext for (mime, ext, human_name) in file_types } def _is_converted(self, doc_url): if not self.core.call_success("fs_isdir", doc_url): return (None, None) for doc_file_url in self.core.call_success("fs_listdir", doc_url): doc_filename = self.core.call_success("fs_basename", doc_file_url) if "." not in doc_filename: continue (doc_filename, doc_ext) = doc_filename.rsplit(".", 1) doc_filename = doc_filename.lower() doc_ext = doc_ext.lower() if doc_filename == "doc" and doc_ext in self.file_types_by_ext: return (doc_file_url, doc_ext) return (None, None) else: # not a converted document return (None, None) def _update_pdf(self, doc_id, doc_url, doc_file_url, doc_ext): LOGGER.debug( "Document %s: %s (%s)", doc_id, doc_file_url, self.file_types_by_ext[doc_ext] ) doc_mtime = self.core.call_success("fs_get_mtime", doc_file_url) pdf = self.core.call_success( "doc_get_pdf_url_by_url", doc_url, write=True ) if not self.core.call_success("fs_exists", pdf): pdf_mtime = -1 else: pdf_mtime = self.core.call_success("fs_get_mtime", pdf) if pdf_mtime >= doc_mtime: LOGGER.debug("Document %s: PDF is up-to-date") return False LOGGER.info( "Document %s: Updating PDF: %s --> %s", doc_id, doc_file_url, pdf ) self.core.call_all( "on_progress", "converting", 0.0, _("Converting document %s to PDF ...") % self.core.call_success( "fs_basename", doc_file_url ) ) self.core.call_success( "convert_file_to_pdf", doc_file_url, self.file_types_by_ext[doc_ext], pdf ) self.core.call_all("flush_doc_cache", doc_url) LOGGER.info("PDF updated") self.core.call_all("on_progress", "converting", 1.0) return True def page_get_img_url(self, doc_url, page_idx, write=False, **kwargs): if page_idx != 0: return # prevent double conversion if doc_url in self.pending_doc_urls: LOGGER.debug("Doc %s has already been checked", doc_url) return self.pending_doc_urls.add(doc_url) (doc_file_url, doc_ext) = self._is_converted(doc_url) if doc_file_url is None: self.pending_doc_urls.remove(doc_url) return doc_id = self.core.call_success("doc_url_to_id", doc_url) LOGGER.info("Checking conversion of document %s is up-to-date", doc_id) promise = openpaperwork_core.promise.ThreadedPromise( self.core, self._update_pdf, args=( doc_id, doc_url, doc_file_url, doc_ext ) ) def do_transaction(has_changed): if not has_changed: return transactions = [] self.core.call_all("doc_transaction_start", transactions, 1) transactions.sort(key=lambda t: -t.priority) try: for transaction in transactions: transaction.del_doc(doc_id) for transaction in transactions: transaction.commit() except Exception: for transaction in transactions: transaction.cancel() promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, do_transaction )) promise = promise.then(self.pending_doc_urls.remove, doc_url) self.core.call_success("transaction_schedule", promise) return None def _check_all_docs(self): if len(self.file_types_by_ext) <= 0: LOGGER.info("No file converter available") return LOGGER.info("Checking all converted documents ...") all_docs = [] self.core.call_all("storage_get_all_docs", all_docs, only_valid=False) self.pending_doc_urls.update((x[1] for x in all_docs)) msg = _("Checking converted documents") self.core.call_all("on_progress", "converted_check", 0.0, msg) total = len(all_docs) for (idx, (doc_id, doc_url)) in enumerate(all_docs): (doc_file_url, doc_ext) = self._is_converted(doc_url) if doc_file_url is None: continue self._update_pdf(doc_id, doc_url, doc_file_url, doc_ext) self.pending_doc_urls.remove(doc_url) if idx % 100 == 0: self.core.call_all( "on_progress", "converted_check", idx / total, msg ) self.core.call_all("on_progress", "converted_check", 1.0) LOGGER.info("All converted documents have been checked") def sync(self, promises: list): promise = openpaperwork_core.promise.ThreadedPromise( self.core, self._check_all_docs ) promises.insert(0, promise) def doc_convert_and_import(self, file_url): mime = self.core.call_success("fs_get_mime", file_url) if mime is not None: file_ext = self.file_types_by_mime[mime] elif "." in file_url: file_ext = file_url.rsplit(".", 1)[-1].lower() else: LOGGER.error("Failed to figure out file type of '%s'", file_url) return (None, None) file_name = "doc." + file_ext (doc_id, doc_url) = self.core.call_success("storage_get_new_doc") dst_file_url = self.core.call_success("fs_join", doc_url, file_name) self.core.call_success("fs_mkdir_p", doc_url) try: self.core.call_success("fs_copy", file_url, dst_file_url) self._update_pdf(doc_id, doc_url, dst_file_url, file_ext) return (doc_id, doc_url) except Exception: self.core.call_success("fs_rm_rf", doc_url, trash=False) raise def doc_get_hash_by_url(self, doc_url): (doc_file_url, doc_ext) = self._is_converted(doc_url) if doc_file_url is None: return None if doc_url not in self.cache_hash: h = self.core.call_success("fs_hash", doc_file_url) self.cache_hash[doc_url] = h return self.cache_hash[doc_url] paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/extra_text.py000066400000000000000000000033761456262201400272520ustar00rootroot00000000000000#!/usr/bin/python3 import logging import openpaperwork_core EXTRA_TEXT_FILENAME = 'extra.txt' LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ "doc_text", "extra_text", ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, ] def doc_internal_get_mtime_by_url(self, out: list, doc_url): extra_url = self.core.call_success( "fs_join", doc_url, EXTRA_TEXT_FILENAME ) if self.core.call_success("fs_exists", extra_url) is None: return out.append(self.core.call_success("fs_get_mtime", extra_url)) def doc_get_text_by_url(self, out: list, doc_url): self.doc_get_extra_text_by_url(out, doc_url) def doc_get_extra_text_by_url(self, out: list, doc_url): extra_url = self.core.call_success( "fs_join", doc_url, EXTRA_TEXT_FILENAME ) if self.core.call_success("fs_exists", extra_url) is None: return with self.core.call_success("fs_open", extra_url, 'r') as fd: out.append(fd.read()) def doc_set_extra_text_by_url(self, doc_url, text): if not self.core.call_success("fs_isdir", doc_url): # Can happen on integrated documentation PDF files LOGGER.warning( "%s is not a directory. Cannot set extra text", doc_url ) return extra_url = self.core.call_success( "fs_join", doc_url, EXTRA_TEXT_FILENAME ) with self.core.call_success("fs_open", extra_url, 'w') as fd: fd.write(text) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/fake.py000066400000000000000000000205751456262201400257710ustar00rootroot00000000000000import datetime import time import openpaperwork_core from . import workdir class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def __init__(self): super().__init__() # expected in self.docs: # [ # { # 'id': 'some_id', # 'url': 'file:///some_work_dir/some_id', # 'mtime': 12345, # unix timestamp # 'labels': [(label_name, label_color), ...] # 'hash': 12345, # optional # 'text': "pouet", # optional # 'page_boxes: [ # optional # [LineBox, LineBox, ...], # page 0 # [LineBox, LineBox, ...], # page 1 # (...) # ], # 'page_imgs': [ # optional # (img_url, PIL.Image), # page 0 # (img_url, PIL.Image), # page 1 # ], # 'page_mtimes': [ # optional # (img_url, mtime), # page 0 # (img_url, mtime), # page 1 # ], # 'page_hashes': [ # optional # (img_url, hash), # page 0 # (img_url, hash), # page 1 # ], # 'page_paper_sizes': [ # optional # (img_url, hash), # page 0 # (img_url, hash), # page 1 # ], # }, # (...) # ] self.docs = [] self.new_doc_idx = 0 def get_interfaces(self): return [ "doc_hash", "doc_labels", "doc_text", "doc_type", "document_storage", "page_boxes", "page_paper", "pillow", ] def get_deps(self): return [] def storage_get_id(self): return "file:///home/jflesch/papers" def storage_get_all_docs(self, out: list, only_valid=True): out += [ (doc['id'], doc['url']) for doc in self.docs ] def doc_id_to_url(self, doc_id, existing=True): for doc in self.docs: if doc['id'] == doc_id: return doc['url'] return None def doc_url_to_id(self, doc_url): for doc in self.docs: if doc['url'] == doc_url: return doc['id'] return None def is_doc(self, doc_url): return True def doc_get_hash_by_url(self, doc_url): for doc in self.docs: if doc['url'] == doc_url: if 'hash' in doc: return doc['hash'] def doc_get_mtime_by_url(self, doc_url): for doc in self.docs: if doc['url'] == doc_url: return doc['mtime'] def doc_get_nb_pages_by_url(self, doc_url): for doc in self.docs: if doc['url'] == doc_url: l_boxes = len(doc['page_boxes']) if 'page_boxes' in doc else 0 l_imgs = len(doc['page_imgs']) if 'page_imgs' in doc else 0 l_mtimes = ( len(doc['page_mtimes']) if 'page_mtimes' in doc else 0 ) l_hashes = ( len(doc['page_hashes']) if 'page_hashes' in doc else 0 ) l_paper_sizes = ( len(doc['page_paper_sizes']) if 'page_paper_sizes' in doc else 0 ) return max(l_boxes, l_imgs, l_mtimes, l_hashes, l_paper_sizes) return None def doc_get_text_by_url(self, out: list, doc_url): for doc in self.docs: if doc['url'] == doc_url: out.append(doc['text']) def doc_get_labels_by_url(self, out: set, doc_url): for doc in self.docs: if doc['url'] == doc_url: out.update(doc['labels']) def doc_add_label_by_url(self, doc_url, label, color=None): if color is None: all_labels = set() self.labels_get_all(all_labels) for (label_name, c) in all_labels: if label_name == label: color = c break else: raise Exception( "label {} provided without color," " but label is unknown".format(label) ) for doc in self.docs: if doc['url'] == doc_url: doc['labels'].add((label, color)) return True def page_has_text_by_url(self, doc_url, page_idx): for doc in self.docs: if doc['url'] == doc_url: if page_idx >= len(doc['page_boxes']): return None return True return None def page_get_boxes_by_url(self, doc_url, page_idx): for doc in self.docs: if doc['url'] == doc_url: if page_idx >= len(doc['page_boxes']): return None return doc['page_boxes'][page_idx] return None def page_set_boxes_by_url(self, doc_url, page_idx, boxes): for doc in self.docs: if doc['url'] == doc_url: if page_idx >= len(doc['page_boxes']): missing = page_idx + 1 - len(doc['page_boxes']) assert missing >= 1 doc['page_boxes'] += ([None] * missing) doc['page_boxes'][page_idx] = boxes text = "" for page_boxes in doc['page_boxes']: if text != "": text += "\n\n" if page_boxes is None: continue for line_boxes in page_boxes: text += line_boxes.content + "\n" doc['text'] = text return True def page_get_img_url(self, doc_url, page_idx, write=False, **kwargs): for doc in self.docs: if doc['url'] == doc_url: for k in [ 'page_imgs', 'page_mtimes', 'page_hashes', 'page_sizes' ]: if k in doc: if page_idx >= len(doc[k]): return None return doc[k][page_idx][0] if write: return "file:///some_doc/new_page.jpeg" else: return None return None def url_to_pillow(self, img_url): for doc in self.docs: if 'page_imgs' not in doc: continue for (page_img_url, img) in doc['page_imgs']: if page_img_url == img_url: return img return None def labels_get_all(self, out: set): for doc in self.docs: out.update(doc['labels']) def storage_get_new_doc(self): self.new_doc_idx += 1 doc = { 'url': 'file:///some_work_dir/{}'.format(self.new_doc_idx), 'id': str(self.new_doc_idx), 'mtime': time.time(), 'labels': [], } self.docs.append(doc) return (doc['id'], doc['url']) def doc_get_date_by_id(self, doc_id): # Doc id is expected to have this format: # YYYYMMDD_hhmm_ss_NN_something_else doc_id = doc_id.split("_", 3) doc_id = "_".join(doc_id[:3]) try: return datetime.datetime.strptime(doc_id, workdir.DOCNAME_FORMAT) except ValueError: return None def storage_delete_doc_id(self, doc_id): for (idx, doc) in enumerate(self.docs[:]): if doc['id'] == doc_id: self.docs.pop(idx) return True def page_delete(self, doc_url, page_idx): raise NotImplementedError() def page_get_mtime_by_url(self, doc_url, page_idx): for doc in self.docs: if doc['url'] != doc_url: continue if 'page_mtimes' not in doc: continue return doc['page_mtimes'][page_idx][1] def page_get_hash_by_url(self, doc_url, page_idx): for doc in self.docs: if doc['url'] != doc_url: continue if 'page_hashes' not in doc: continue return doc['page_hashes'][page_idx][1] def page_get_paper_size_by_url(self, doc_url, page_idx): for doc in self.docs: if doc['url'] != doc_url: continue if 'page_paper_sizes' not in doc: continue return doc['page_paper_sizes'][page_idx][1] paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/hocr.py000066400000000000000000000146751456262201400260220ustar00rootroot00000000000000import logging import re import xml.etree.cElementTree as etree import pyocr import pyocr.builders import openpaperwork_core from . import util LOGGER = logging.getLogger(__name__) PAGE_FILENAME_FMT = "paper.{}.words" PAGE_FILENAME_REGEX = re.compile(r"paper\.(\d+)\.words") class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def get_interfaces(self): return [ "doc_text", "page_boxes", 'pages', ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, ] def doc_internal_get_mtime_by_url(self, out: list, doc_url): mtime = util.get_doc_mtime(self.core, doc_url, PAGE_FILENAME_REGEX) if mtime is None: return out.append(mtime) def page_internal_get_mtime_by_url(self, out: list, doc_url, page_idx): mtime = util.get_page_mtime( self.core, doc_url, page_idx, PAGE_FILENAME_FMT ) if mtime is None: return out.append(mtime) def page_internal_get_hash_by_url(self, out: list, doc_url, page_idx): h = util.get_page_hash(self.core, doc_url, page_idx, PAGE_FILENAME_FMT) if h is None: return out.append(h) def doc_get_text_by_url(self, out: list, doc_url): doc_nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) if doc_nb_pages is None: return for page_idx in range(0, doc_nb_pages): text = self.page_get_text_by_url(doc_url, page_idx) if text is None: continue out.append(text) def page_reset_by_url(self, doc_url, page_idx): page_url = self.core.call_success( "fs_join", doc_url, PAGE_FILENAME_FMT.format(page_idx + 1) ) if self.core.call_success("fs_exists", page_url) is None: return None self.core.call_all("fs_unlink", page_url, trash=False) def page_has_text_by_url(self, doc_url, page_idx): page_url = self.core.call_success( "fs_join", doc_url, PAGE_FILENAME_FMT.format(page_idx + 1) ) if self.core.call_success("fs_exists", page_url) is None: return None text = self.page_get_text_by_url(doc_url, page_idx) if text is None: return None text = text.strip() # If the file exists and is valid, it takes precedence over text from, # for instance, a PDF file --> we return False instead of None return len(text) > 0 def page_get_text_by_url(self, doc_url, page_idx): task = "hocr_load_page_text({} p{})".format(doc_url, page_idx) self.core.call_all("on_perfcheck_start", task) page_url = self.core.call_success( "fs_join", doc_url, PAGE_FILENAME_FMT.format(page_idx + 1) ) file_desc = self.core.call_success("fs_open", page_url) if file_desc is None: self.core.call_all("on_perfcheck_stop", task) return None with file_desc: txt = file_desc.read().strip() try: tree = etree.XML(txt) for tag in tree.iter(): tag_name = tag.tag.rsplit("}", 1)[-1] # ignore namespace if tag_name != 'body': continue txt = etree.tostring(tag, encoding='utf-8', method='text') break else: # No body ?! LOGGER.warning("No tag 'body' found in %s", page_url) txt = etree.tostring(tree, encoding='utf-8', method='text') if isinstance(txt, bytes): txt = txt.decode('utf-8') return txt except etree.ParseError as exc: LOGGER.warning( "%s contains invalid XML (%s). Will try with HTML parser", page_url, exc ) def line_txt_generator(line): return " ".join( (word_box.content for word_box in line.word_boxes) ) line_boxes = self.page_get_boxes_by_url(doc_url, page_idx) if line_boxes is None: return None return "\n".join( (line_txt_generator(line_box) for line_box in line_boxes) ) def page_get_boxes_by_url(self, doc_url, page_idx): task = "hocr_load_page_boxes({} p{})".format(doc_url, page_idx) self.core.call_all("on_perfcheck_start", task) page_url = self.core.call_success( "fs_join", doc_url, PAGE_FILENAME_FMT.format(page_idx + 1) ) file_desc = self.core.call_success("fs_open", page_url) if file_desc is None: self.core.call_all("on_perfcheck_stop", task) return None with file_desc: box_builder = pyocr.builders.LineBoxBuilder() boxes = box_builder.read_file(file_desc) if len(boxes) > 0: self.core.call_all("on_perfcheck_stop", task) return boxes with self.core.call_success("fs_open", page_url) as file_desc: # fallback: old format: word boxes # shouldn't be used anymore ... box_builder = pyocr.builders.WordBoxBuilder() boxes = box_builder.read_file(file_desc) if len(boxes) > 0: LOGGER.warning( "Doc %s (page %d) uses old box format", doc_url, page_idx ) self.core.call_all("on_perfcheck_stop", task) return boxes self.core.call_all("on_perfcheck_stop", task) def page_set_boxes_by_url(self, doc_url, page_idx, boxes): page_url = self.core.call_success( "fs_join", doc_url, PAGE_FILENAME_FMT.format(page_idx + 1) ) with self.core.call_success("fs_open", page_url, 'w') as file_desc: pyocr.builders.LineBoxBuilder().write_file(file_desc, boxes) return True def page_delete_by_url(self, doc_url, page_idx): return util.delete_page_file( self.core, PAGE_FILENAME_FMT, doc_url, page_idx ) def page_move_by_url( self, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ): return util.move_page_file( self.core, PAGE_FILENAME_FMT, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/img.py000066400000000000000000000101471456262201400256310ustar00rootroot00000000000000import logging import re import openpaperwork_core from . import util LOGGER = logging.getLogger(__name__) PAGE_FILENAME_PNG_FMT = "paper.{}.png" PAGE_FILENAME_JPG_FMT = "paper.{}.jpg" PAGE_FILENAME_FMTS = ( PAGE_FILENAME_PNG_FMT, PAGE_FILENAME_JPG_FMT, ) PAGE_FILENAME_REGEX = re.compile( r"paper\.(\d+)\.(jpg|png)", flags=re.IGNORECASE ) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def get_interfaces(self): return [ "doc_type", "page_img", 'pages', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { # to provide doc_get_nb_pages_by_url() 'interface': 'nb_pages', 'defaults': ['paperwork_backend.model'], }, ] def init(self, core): self.core = core setting = self.core.call_success( "config_build_simple", "model", "img_format", lambda: "PNG" ) self.core.call_all( "config_register", "model_img_format", setting ) def is_doc(self, doc_url): for filename_fmt in PAGE_FILENAME_FMTS: page_url = self.core.call_success( "fs_join", doc_url, filename_fmt.format(1) ) if self.core.call_success("fs_exists", page_url) is not None: return True return None def doc_internal_get_mtime_by_url(self, out: list, doc_url): mtime = util.get_doc_mtime(self.core, doc_url, PAGE_FILENAME_REGEX) if mtime is not None: out.append(mtime) def page_internal_get_mtime_by_url(self, out: list, doc_url, page_idx): for filename_fmt in PAGE_FILENAME_FMTS: mtime = util.get_page_mtime( self.core, doc_url, page_idx, filename_fmt ) if mtime is not None: out.append(mtime) break def page_internal_get_hash_by_url(self, out: list, doc_url, page_idx): for filename_fmt in PAGE_FILENAME_FMTS: h = util.get_page_hash(self.core, doc_url, page_idx, filename_fmt) if h is not None: out.append(h) break def doc_internal_get_nb_pages_by_url(self, out: list, doc_url): nb_pages = util.get_nb_pages(self.core, doc_url, PAGE_FILENAME_REGEX) if nb_pages is None: return out.append(nb_pages) def page_get_img_url(self, doc_url, page_idx, write=False, **kwargs): if write: self.core.call_success("fs_mkdir_p", doc_url) for filename_fmt in PAGE_FILENAME_FMTS: page_url = self.core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) if self.core.call_success("fs_exists", page_url) is not None: return page_url if write: img_fmt = self.core.call_success("config_get", "model_img_format") if img_fmt == "PNG": filename_fmt = PAGE_FILENAME_PNG_FMT else: filename_fmt = PAGE_FILENAME_JPG_FMT return self.core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) return None def page_delete_by_url(self, doc_url, page_idx): r = None for filename_fmt in PAGE_FILENAME_FMTS: r = util.delete_page_file( self.core, filename_fmt, doc_url, page_idx ) or r return r def page_move_by_url( self, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ): r = None for filename_fmt in PAGE_FILENAME_FMTS: r = util.move_page_file( self.core, filename_fmt, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ) or r return r paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/img_overlay.py000066400000000000000000000115761456262201400274010ustar00rootroot00000000000000""" Let other plugins replace a page image without actually smashing the original image. Also provide a method to drop the modified version of a page and revert to the original only. """ import logging import re import openpaperwork_core from . import util LOGGER = logging.getLogger(__name__) PAGE_FILENAME_PNG_FMT = "paper.{}.edited.png" PAGE_FILENAME_JPG_FMT = "paper.{}.edited.jpg" PAGE_FILENAME_FMTS = [ PAGE_FILENAME_PNG_FMT, PAGE_FILENAME_JPG_FMT, ] PAGE_FILENAME_REGEX = re.compile(r"paper\.(\d+)\.edited.(jpg|png)") class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 # must have a higher priority than model.img / model.pdf def get_interfaces(self): return [ "page_img", "page_reset", 'pages', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, ] def init(self, core): self.core = core setting = self.core.call_success( "config_build_simple", "model", "img_overlay_format", lambda: "PNG" ) self.core.call_all( "config_register", "model_img_overlay_format", setting ) def doc_internal_get_mtime_by_url(self, out: list, doc_url): mtime = util.get_doc_mtime(self.core, doc_url, PAGE_FILENAME_REGEX) if mtime is not None: out.append(mtime) def page_internal_get_mtime_by_url(self, out: list, doc_url, page_idx): for filename_fmt in PAGE_FILENAME_FMTS: mtime = util.get_page_mtime( self.core, doc_url, page_idx, filename_fmt ) if mtime is not None: out.append(mtime) break def page_internal_get_hash_by_url(self, out: list, doc_url, page_idx): for filename_fmt in PAGE_FILENAME_FMTS: h = util.get_page_hash( self.core, doc_url, page_idx, filename_fmt) if h is not None: out.append(h) break def page_get_img_url( self, doc_url, page_idx, write=False, original=False, **kwargs ): if original: # caller want the URL of the original image, not the edited one return None for filename_fmt in PAGE_FILENAME_FMTS: page_url = self.core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) if self.core.call_success("fs_exists", page_url) is not None: return page_url if not write: return None # caller wants to modify or create a page # check if we already have an original image. If so, we return our # URL. Otherwise, we let the caller write the original image first. if self.core.call_success( "page_get_img_url", doc_url, page_idx, write=False ) is not None: # has already an original page (or even an edited one) # --> return our URL img_fmt = self.core.call_success( "config_get", "model_img_overlay_format" ) if img_fmt == "PNG": filename_fmt = PAGE_FILENAME_PNG_FMT else: filename_fmt = PAGE_FILENAME_JPG_FMT return self.core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) # let the caller write an original page (see model.img) return None def page_delete_by_url(self, doc_url, page_idx): r = None for filename_fmt in PAGE_FILENAME_FMTS: r = util.delete_page_file( self.core, filename_fmt, doc_url, page_idx ) or r return r def page_move_by_url( self, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ): r = None for filename_fmt in PAGE_FILENAME_FMTS: r = util.move_page_file( self.core, filename_fmt, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ) or r return r def page_reset_by_url(self, doc_url, page_idx): """ Reset a page image to its original content. In other word, we simply delete the edited image so the original one takes over again (see model.img). """ for filename_fmt in PAGE_FILENAME_FMTS: page_url = self.core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) if self.core.call_success("fs_exists", page_url): self.core.call_success("fs_unlink", page_url, trash=False) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/labels.py000066400000000000000000000233111456262201400263140ustar00rootroot00000000000000import logging import random import openpaperwork_core import openpaperwork_core.promise from .. import _ LOGGER = logging.getLogger(__name__) LABELS_FILENAME = "labels" COLOR_NAMES = [ ('aqua', (0, 1, 1)), ('black', (0, 0, 0)), ('blue', (0, 0, 1)), ('fuchsia', (1, 0, 1)), ('gray', (0x80 / 0xFF, 0x80 / 0xFF, 0x80 / 0xFF)), ('green', (0, 0x80 / 0xFF, 0)), ('lime', (0, 1, 0)), ('maroon', (0x80 / 0xFF, 0, 0)), ('navy', (0, 0, 0x80 / 0xFF)), ('olive', (0x80 / 0xFF, 0x80 / 0xFF, 0)), ('purple', (0x80 / 0xFF, 0, 0x80 / 0xFF)), ('red', (1, 0, 0)), ('silver', (0xC0 / 0xFF, 0xC0 / 0xFF, 0xC0 / 0xFF)), ('teal', (0, 0x80 / 0xFF, 0x80 / 0xFF)), ('white', (1, 1, 1)), ('yellow', (1, 1, 0)), ] class LabelLoader(object): """ Go through all the documents to figure out what labels exist. """ def __init__(self, plugin): self.plugin = plugin self.core = plugin.core self.all_docs = [] def get_promise(self): promise = openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("storage_get_all_docs", self.all_docs) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "on_label_loading_start", ) promise = promise.then( openpaperwork_core.promise.ThreadedPromise( self.core, self.load_labels ) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "on_label_loading_end" ) return promise def load_labels(self, *args, **kwargs): nb_docs = len(self.all_docs) LOGGER.info("Loading labels from %d documents", nb_docs) for (doc_idx, (doc_id, doc_url)) in enumerate(self.all_docs): self.core.call_all( "on_progress", "label_loading", doc_idx / nb_docs, _("Loading labels of document {}").format(doc_id) ) labels = set() self.plugin.doc_get_labels_by_url(labels, doc_url) for label in labels: self.plugin.all_labels[label[0]] = label[1] self.core.call_all("on_progress", "label_loading", 1.0) LOGGER.info( "%d labels loaded from %d documents", len(self.plugin.all_labels), nb_docs ) class Plugin(openpaperwork_core.PluginBase): def __init__(self): # {label_name: color, label_name: color, ...} self.all_labels = {} def get_interfaces(self): return [ "doc_labels", "syncable", ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def doc_internal_get_mtime_by_url(self, out: list, doc_url): labels_url = self.core.call_success( "fs_join", doc_url, LABELS_FILENAME ) if self.core.call_success("fs_exists", labels_url) is None: return out.append(self.core.call_success("fs_get_mtime", labels_url)) def doc_has_labels_by_url(self, doc_url): labels_url = self.core.call_success( "fs_join", doc_url, LABELS_FILENAME ) return self.core.call_success("fs_exists", labels_url) def doc_get_labels_by_url(self, out: set, doc_url): labels_url = self.core.call_success( "fs_join", doc_url, LABELS_FILENAME ) if self.core.call_success("fs_exists", labels_url) is None: return with self.core.call_success("fs_open", labels_url, 'r') as file_desc: for line in file_desc.readlines(): line = line.strip() if line == "": continue # Expected: ('label', '#rrrrggggbbbb') out.add(tuple(x.strip() for x in line.split(",", 1))) def doc_get_labels_by_url_promise(self, out: list, doc_url): def get_labels(labels=None): if labels is None: labels = set() self.doc_get_labels_by_url(labels, doc_url) return labels promise = openpaperwork_core.promise.ThreadedPromise( self.core, get_labels ) out.append(promise) def label_generate_color(self): color = ( random.randint(0, 255) / 255, random.randint(0, 255) / 255, random.randint(0, 255) / 255, ) return self.label_color_from_rgb(color) def label_get_foreground_color(self, bg_color): brightness = ( (bg_color[0] * 0.299) + (bg_color[1] * 0.587) + (bg_color[2] * 0.114) ) if brightness > (69 / 255): return (0, 0, 0) # black else: return (1, 1, 1) # white def doc_add_label_by_url(self, doc_url, label, color=None): assert "," not in label current = set() self.doc_get_labels_by_url(current, doc_url) current = {k: v for (k, v) in current} if label in current: LOGGER.warning( "Label '%s' already on document '%s'", label, doc_url ) return if color is not None: self.all_labels[label] = color if label in self.all_labels: color = self.all_labels[label] else: color = self.label_generate_color() LOGGER.info("Adding label '%s' on document '%s'", label, doc_url) labels_url = self.core.call_success( "fs_join", doc_url, LABELS_FILENAME ) with self.core.call_success("fs_open", labels_url, 'a') as file_desc: file_desc.write("{},{}\n".format(label, color)) if label not in self.all_labels: self.all_labels[label] = color return True def doc_remove_label_by_url(self, doc_url, label): LOGGER.info("Removing label '%s' from document '%s'", label, doc_url) labels_url = self.core.call_success( "fs_join", doc_url, LABELS_FILENAME ) if self.core.call_success("fs_exists", labels_url) is None: return with self.core.call_success("fs_open", labels_url, 'r') as file_desc: labels = file_desc.readlines() labels = [lab.strip() for lab in labels] labels = [lab.split(",", 1) for lab in labels if len(lab) > 0] labels = {l: c for (l, c) in labels} try: labels.pop(label) except KeyError: LOGGER.warning( "Tried to remove label '%s' from document '%s', but label" " was not found on the document", label, doc_url ) labels = [(label, color) for (label, color) in labels.items()] labels.sort() with self.core.call_success("fs_open", labels_url, "w") as file_desc: for (label, color) in labels: file_desc.write("{},{}\n".format(label, color)) return True def labels_get_all(self, out: set): for (label, color) in self.all_labels.items(): out.add((label, color)) def label_color_to_rgb(self, color): if color[0] == '#': if len(color) == 13: return ( int(color[1:5], 16) / 0xFFFF, int(color[5:9], 16) / 0xFFFF, int(color[9:13], 16) / 0xFFFF, ) else: return ( int(color[1:3], 16) / 0xFF, int(color[3:5], 16) / 0xFF, int(color[5:7], 16) / 0xFF, ) else: if color.startswith("rgb("): color = color[len("rgb("):-1] elif color.startswith("("): color = color[len("("):-1] color = color.split(",") color = tuple([int(x.strip()) for x in color]) color = (color[0] / 0xFF, color[1] / 0xFF, color[2] / 0xFF) return color def label_color_from_rgb(self, color): return ( "#" + format(int(color[0] * 0xFF), '02x') + "00" + format(int(color[1] * 0xFF), '02x') + "00" + format(int(color[2] * 0xFF), '02x') + "00" ) def label_color_rgb_to_text(self, color): for (name, rgb) in COLOR_NAMES: if color == rgb: break else: def color_distance(a, b): return ( (abs(a[0] - b[0]) ** 2) + (abs(a[1] - b[1]) ** 2) + (abs(a[2] - b[2]) ** 2) ) closest_color = min(( (color_distance(rgb, color), name) for (name, rgb) in COLOR_NAMES )) name = "~" + closest_color[1] return "#{:02X}{:02X}{:02X} ({})".format( int(color[0] * 0xFF), int(color[1] * 0xFF), int(color[2] * 0xFF), name ) def label_load_all(self, promises: list): self.all_labels = {} promise = LabelLoader(self).get_promise() # drop the return value of 'call_all' promise = promise.then(lambda *args, **kwargs: None) promises.append(promise) def sync(self, promises: list): self.label_load_all(promises) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/pdf.py000066400000000000000000001012531456262201400256250ustar00rootroot00000000000000import datetime import itertools import logging import math import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) PDF_FILENAME = 'doc.pdf' PASSWD_FILENAME = 'passwd.txt' MAPPING_FILE = "page_map.csv" PDF_RENDER_FACTOR = 4 def minmax_rects(rects): (mx1, my1, mx2, my2) = (math.inf, math.inf, 0, 0) for rectangle in rects: ((x1, y1), (x2, y2)) = ( (int(rectangle.x1 * PDF_RENDER_FACTOR), int(rectangle.y2 * PDF_RENDER_FACTOR)), (int(rectangle.x2 * PDF_RENDER_FACTOR), int(rectangle.y1 * PDF_RENDER_FACTOR)) ) (x1, x2) = (min(x1, x2), max(x1, x2)) (y1, y2) = (min(y1, y2), max(y1, y2)) mx1 = min(mx1, x1) my1 = min(my1, y1) mx2 = max(mx2, x2) my2 = max(my2, y2) rect = ((mx1, my1), (mx2, my2)) return rect class PdfWordBox(object): def __init__(self, content, position): self.content = content self.position = minmax_rects(position) def __str__(self): return "{{ .position={}, .content={} }}".format( self.position, str(self.content) ) def __lt__(self, o): return self.position < o.position def __repr__(self): return str(self) class PdfLineBox(object): def __init__(self, word_boxes, position): self.word_boxes = word_boxes self.position = minmax_rects(position) def __str__(self): return "{{ .position={}, .word_boxes={} }}".format( self.position, str(self.word_boxes) ) def __repr__(self): return str(self) def _get_content(self): return " ".join([w.content for w in self.word_boxes]) content = property(_get_content) class PdfPageMapping(object): SEPARATOR = "," def __init__(self, plugin, doc_url): self.plugin = plugin self.core = plugin.core self.doc_url = doc_url self.map_url = self.core.call_success( "fs_join", self.doc_url, MAPPING_FILE ) self.mapping = None self.reverse_mapping = None self.page_mtimes = None self.nb_pages = -1 self.real_nb_pages = -1 def set_mapping(self, original_page_idx, target_page_idx): """ Indicates that the page 'original_page_idx' in the actual PDF file is displayed as being the page 'target_page_idx'. If 'target_page_idx' < 0, it means the page is not displayed anymore (--> act if it is deleted) """ if original_page_idx >= self.real_nb_pages: # comes from another set of plugins, no point in tracking it return now = datetime.datetime.now().timestamp() if target_page_idx is not None: old_original = self.reverse_mapping.get(target_page_idx, None) if old_original is not None and old_original in self.mapping: self.mapping.pop(old_original) old_target = self.mapping.get(original_page_idx, None) if old_target is not None and old_target in self.reverse_mapping: self.reverse_mapping.pop(old_target) self.page_mtimes[old_target] = now if target_page_idx is None and original_page_idx in self.mapping: self.mapping.pop(original_page_idx) else: self.mapping[original_page_idx] = target_page_idx if target_page_idx is not None: self.reverse_mapping[target_page_idx] = original_page_idx self.page_mtimes[target_page_idx] = now def update_nb_pages(self): self.nb_pages = 0 if len(self.mapping) <= 0: return for v in self.mapping.values(): if v is None: continue if v >= self.nb_pages: self.nb_pages = v + 1 def load(self): try: self.real_nb_pages = self.plugin._doc_internal_get_nb_pages_by_url( self.doc_url, mapping=False ) self.mapping = {p: p for p in range(0, self.real_nb_pages)} self.reverse_mapping = {p: p for p in range(0, self.real_nb_pages)} now = datetime.datetime.now().timestamp() self.page_mtimes = {p: now for p in range(0, self.real_nb_pages)} if self.core.call_success("fs_exists", self.map_url) is None: self.update_nb_pages() return with self.core.call_success("fs_open", self.map_url, "r") as fd: # drop the first line lines = fd.readlines()[1:] lines = [line.split(",", 1) for line in lines] lines = [ (int(orig_page_idx), int(target_page_idx)) for (orig_page_idx, target_page_idx) in lines ] lines.sort() for (orig_page_idx, target_page_idx) in lines: if target_page_idx < 0: target_page_idx = None self.set_mapping(orig_page_idx, target_page_idx) self.update_nb_pages() except Exception as exc: LOGGER.critical( "Failed to load page mapping for doc %s !", self.doc_url, exc_info=exc ) raise def load_reverse_only(self): """ Load the mapping, but doesn't look at the total number of pages in the document. Avoid opening the PDF file. """ self.mapping = None self.reverse_mapping = {} if self.core.call_success("fs_exists", self.map_url) is None: return with self.core.call_success("fs_open", self.map_url, "r") as fd: # drop the first line lines = fd.readlines()[1:] for line in lines: (orig_page_idx, target_page_idx) = line.split(",", 1) orig_page_idx = int(orig_page_idx) target_page_idx = int(target_page_idx) if target_page_idx < 0: continue self.reverse_mapping[target_page_idx] = orig_page_idx def save(self): if self.core.call_success("fs_isdir", self.doc_url) is None: return nb_maps = 0 for (orig_page_idx, target_page_idx) in self.mapping.items(): if orig_page_idx == target_page_idx: continue nb_maps += 1 if nb_maps <= 0: if self.core.call_success("fs_exists", self.map_url) is not None: self.core.call_success("fs_unlink", self.map_url) return with self.core.call_success("fs_open", self.map_url, "w") as fd: fd.write("original_page_index,target_page_index\n") mapping = list(self.mapping.items()) mapping.sort() for (orig_page_idx, target_page_idx) in mapping: if orig_page_idx == target_page_idx: continue fd.write("{},{}\n".format(orig_page_idx, target_page_idx)) for page_idx in range(0, self.real_nb_pages): if page_idx not in self.mapping: fd.write("{},-1\n".format(page_idx)) def has_original_page_idx(self, original_page_idx): if self.mapping is None: self.load() return original_page_idx in self.mapping def get_original_page_idx(self, target_page_idx, reverse_only=False): if reverse_only: if self.reverse_mapping is None: self.load_reverse_only() else: if self.mapping is None: self.load() # Keep in mind we may have loaded only the mapping --> we don't know # how many pages there are in the PDF, so the mapping may be incomplete original_page_idx = self.reverse_mapping.get(target_page_idx, None) return original_page_idx def get_target_page_mtime(self, target_page_idx): if self.mapping is None: self.load() return self.page_mtimes.get(target_page_idx, None) def get_target_page_hash(self, target_page_idx): if self.mapping is None: self.load() original_page_idx = self.reverse_mapping.get( target_page_idx, None ) if original_page_idx is None: return None return hash(original_page_idx) def _move_pages(self, original_page_idx, target_page_idx, offset): mapping = list(self.mapping.items()) mapping.sort(key=lambda x: x[1], reverse=offset > 0) for (original, target) in mapping: if target >= target_page_idx: LOGGER.info( "Page %d (original) ; target: %d --> %d", original, target, target + offset ) self.set_mapping(original, target + offset) self.update_nb_pages() def delete_target_page(self, target_page_idx): if self.mapping is None: self.load() LOGGER.info( "Deleting page %d from PDF %s", target_page_idx, self.doc_url ) original_page_idx = self.reverse_mapping.pop( target_page_idx, None ) if original_page_idx is not None: self.mapping.pop(original_page_idx, None) else: original_page_idx = target_page_idx self._move_pages(original_page_idx, target_page_idx, offset=-1) def make_room_for_target_page(self, target_page_idx): if self.mapping is None: self.load() original_page_idx = self.reverse_mapping.get( target_page_idx, target_page_idx ) self._move_pages(original_page_idx, target_page_idx, offset=1) def print_mapping(self): if self.mapping is None: self.load() nb_pages = self.plugin._doc_internal_get_nb_pages_by_url( self.doc_url, mapping=False ) print("==== MAPPING OF {} (nb_pages={}|{}) ====".format( self.doc_url, nb_pages, self.nb_pages )) for original_page_idx in range(0, nb_pages): target_page_idx = self.mapping.get(original_page_idx, None) if target_page_idx is None: print("{} --> {}".format(original_page_idx, original_page_idx)) continue print("{} --> {}".format(original_page_idx, target_page_idx)) if target_page_idx < 0: continue if target_page_idx not in self.reverse_mapping: print("WARNING: NO REVERSE") else: if original_page_idx != self.reverse_mapping[target_page_idx]: print("WARNING: REVERSE DOESN'T MATCH: {} <-- {}".format( target_page_idx, original_page_idx )) print("=======================") def get_map_hash(self): if self.core.call_success("fs_exists", self.map_url) is None: return None return self.core.call_success("fs_hash", self.map_url) def get_map_mtime(self): if self.core.call_success("fs_exists", self.map_url) is None: return None return self.core.call_success("fs_get_mtime", self.map_url) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 20 def __init__(self): super().__init__() # we cache the hash of PDF files since they never change self.cache_hash = {} # we cache the number of pages in PDF files since they never change # (real number before mapping) self.cache_nb_pages = {} self.cache_mappings = {} self.cache_passwords = {} def get_interfaces(self): return [ "doc_hash", "doc_pdf", "doc_pdf_import", "doc_pdf_url", "doc_text", "doc_type", "page_boxes", "page_img", "page_paper", 'pages', ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { # to provide doc_get_nb_pages_by_url() 'interface': 'nb_pages', 'defaults': ['paperwork_backend.model'], }, # for page_move_by_url(): { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, { 'interface': 'poppler', 'defaults': ['paperwork_backend.poppler.memory'], }, { 'interface': 'urls', 'defaults': ['openpaperwork_core.urls'], }, ] def _get_pdf_url(self, doc_url): if doc_url.endswith(".pdf"): return doc_url pdf_url = self.core.call_success("fs_join", doc_url, PDF_FILENAME) if self.core.call_success("fs_exists", pdf_url) is None: return None return pdf_url def _get_pdf_password(self, doc_url): password = self.cache_passwords.get(doc_url, None) if password is not None: return password passwd_url = self.core.call_success( "fs_join", doc_url, PASSWD_FILENAME ) if self.core.call_success("fs_exists", passwd_url): with self.core.call_success("fs_open", passwd_url, "r") as fd: password = fd.read().strip() self.cache_passwords[doc_url] = password return password def _get_page_mapping(self, doc_url): if doc_url in self.cache_mappings: return self.cache_mappings[doc_url] mapping = PdfPageMapping(self, doc_url) self.cache_mappings[doc_url] = mapping return mapping def _open_pdf(self, doc_url): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return (None, None) password = self._get_pdf_password(doc_url) LOGGER.info("Opening %s (password=%s)", pdf_url, bool(password)) doc = self.core.call_success( "poppler_open", pdf_url, password=password ) return (pdf_url, doc) def is_doc(self, doc_url): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None return True def doc_get_pdf_url_by_url(self, doc_url, write=False, allow_mapped=False): if write: return self.core.call_success("fs_join", doc_url, PDF_FILENAME) if not allow_mapped: mapping_url = self.core.call_success( "fs_join", doc_url, MAPPING_FILE ) if self.core.call_success("fs_exists", mapping_url): return None return self._get_pdf_url(doc_url) def flush_doc_cache(self, doc_url): self.cache_hash.pop(doc_url, None) self.cache_passwords.pop(doc_url, None) self.cache_mappings.pop(doc_url, None) self.cache_nb_pages.pop(doc_url, None) def doc_get_hash_by_url(self, doc_url): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return # cache the hash of doc.pdf to speed up imports if doc_url not in self.cache_hash: h = self.core.call_success("fs_hash", pdf_url) self.cache_hash[doc_url] = h return self.cache_hash[doc_url] def page_internal_get_hash_by_url(self, out: list, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return mapping = self._get_page_mapping(doc_url) page_hash = mapping.get_target_page_hash(page_idx) if page_hash is None: # deleted page or handled by another plugin return out.append(page_hash) # cache the hash of doc.pdf to speed up imports if doc_url not in self.cache_hash: h = self.core.call_success("fs_hash", pdf_url) self.cache_hash[doc_url] = h out.append(self.cache_hash[doc_url]) def doc_internal_get_mtime_by_url(self, out: list, doc_url): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None mapping = self._get_page_mapping(doc_url) mtime = mapping.get_map_mtime() if mtime is not None: out.append(mtime) mtime = self.core.call_success("fs_get_mtime", pdf_url) if mtime is None: return None out.append(mtime) def page_internal_get_mtime_by_url(self, out: list, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return mapping = self._get_page_mapping(doc_url) mtime = mapping.get_target_page_mtime(page_idx) if mtime is not None: out.append(mtime) mtime = self.core.call_success("fs_get_mtime", pdf_url) if mtime is not None: out.append(mtime) return def _doc_get_real_nb_pages_by_url(self, doc_url): (pdf_url, pdf) = self._open_pdf(doc_url) if pdf is None: return None nb_pages = pdf.get_n_pages() return nb_pages def doc_pdf_get_real_nb_pages_by_url(self, doc_url): # Poppler is not thread-safe return self.core.call_one( "mainloop_execute", self._doc_get_real_nb_pages_by_url, doc_url ) def _doc_internal_get_nb_pages_by_url( self, doc_url, mapping=True): if mapping: pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return 0 mapping = self._get_page_mapping(doc_url) if mapping.nb_pages < 0: mapping.load() return mapping.nb_pages if doc_url in self.cache_nb_pages: r = self.cache_nb_pages[doc_url] else: r = self.doc_pdf_get_real_nb_pages_by_url(doc_url) if r is not None: self.cache_nb_pages[doc_url] = r return r if r is not None else 0 def doc_internal_get_nb_pages_by_url(self, out: list, doc_url): r = self._doc_internal_get_nb_pages_by_url(doc_url) if r == 0: return out.append(r) def page_get_img_url(self, doc_url, page_idx, write=False, **kwargs): if write: return None pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None # The first page is requested much more often than the others, due # to thumbnailing. # ASSUMPTION(Jflesch): If there is a doc.pdf, there is a first page # in it. # We don't want to open the PDF file for each thumbnail (first page) # but at the same time, we still need to check the mapping file. mapping = self._get_page_mapping(doc_url) original_page_idx = mapping.get_original_page_idx( page_idx, reverse_only=(page_idx == 0) ) if original_page_idx is None: if page_idx != 0 and page_idx >= mapping.nb_pages: return None original_page_idx = page_idx password = self._get_pdf_password(doc_url) if password is not None: password = password.encode("utf-8").hex() # same URL used in browsers url = self.core.call_success( "url_args_join", pdf_url, page=str(original_page_idx + 1), password=password ) return url @staticmethod def _custom_split(input_str, input_rects, splitter, log_txt): # turn text and layout from Poppler into boxes # XXX(Jflesch): following assert fails sometimes ? oO # assert len(input_str) == len(input_rects) if len(input_str) != len(input_rects): LOGGER.warning( "%s: Input strings: %d ; Input rects: %d", log_txt, len(input_str), len(input_rects) ) m = min(len(input_str), len(input_rects)) input_str = input_str[:m] input_rects = input_rects[:m] input_el = zip(input_str, input_rects) for (is_split, group) in itertools.groupby( input_el, lambda x: splitter(x[0]) ): if is_split: continue letters = "" rects = [] for (letter, rect) in group: letters += letter rects.append(rect) yield (letters, rects) def _doc_get_text_by_url(self, out: list, doc_url): task = "pdf_get_text_by_url({})".format(doc_url) self.core.call_all("on_perfcheck_start", task) (pdf_url, pdf) = self._open_pdf(doc_url) if pdf is None: self.core.call_all("on_perfcheck_stop", task) return mapping = self._get_page_mapping(doc_url) for page_idx in range(0, pdf.get_n_pages()): if not mapping.has_original_page_idx(page_idx): continue page = pdf.get_page(page_idx) # some PDF are really badly damaged if page is None: continue try: txt = page.get_text() txt = txt.strip() except UnicodeDecodeError as exc: LOGGER.warning( "%s p%d: UnicodeDecodeError: Assuming page has no text", doc_url, page_idx, exc_info=exc ) continue if txt == "": continue out.append(txt) self.core.call_all( "on_perfcheck_stop", task, nb_pages=pdf.get_n_pages() ) return True def doc_get_text_by_url(self, out: list, doc_url): # Poppler is not thread-safe return self.core.call_one( "mainloop_execute", self._doc_get_text_by_url, out, doc_url ) def _page_has_text_by_url(self, doc_url, page_idx): if doc_url in self.cache_nb_pages: if page_idx >= self.cache_nb_pages[doc_url]: return None (pdf_url, pdf) = self._open_pdf(doc_url) if pdf is None: return None page = pdf.get_page(page_idx) if page is None: return None try: return len(page.get_text().strip()) > 0 except UnicodeDecodeError as exc: LOGGER.warning( "%s p%d: UnicodeDecodeError: Assuming page has no text", doc_url, page_idx, exc_info=exc ) return False def page_has_text_by_url(self, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None mapping = self._get_page_mapping(doc_url) page_idx = mapping.get_original_page_idx(page_idx) if page_idx is None: return None # Poppler is not thread-safe return self.core.call_one( "mainloop_execute", self._page_has_text_by_url, doc_url, page_idx ) def _page_get_text_by_url(self, doc_url, page_idx): if doc_url in self.cache_nb_pages: if page_idx >= self.cache_nb_pages[doc_url]: return None (pdf_url, pdf) = self._open_pdf(doc_url) if pdf is None: return None page = pdf.get_page(page_idx) if page is None: return None try: return page.get_text().strip() except UnicodeDecodeError as exc: LOGGER.warning( "%s p%d: UnicodeDecodeError: Assuming page has no text", doc_url, page_idx, exc_info=exc ) return False def page_get_text_by_url(self, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None mapping = self._get_page_mapping(doc_url) page_idx = mapping.get_original_page_idx(page_idx) if page_idx is None: return None # Poppler is not thread-safe return self.core.call_one( "mainloop_execute", self._page_get_text_by_url, doc_url, page_idx ) def _page_get_boxes_by_url(self, doc_url, page_idx): if doc_url in self.cache_nb_pages: if page_idx >= self.cache_nb_pages[doc_url]: return None (pdf_url, pdf) = self._open_pdf(doc_url) if pdf is None: return pdf_page = pdf.get_page(page_idx) if pdf_page is None: return try: txt = pdf_page.get_text() if txt.strip() == "": return None except UnicodeDecodeError as exc: LOGGER.warning( "%s p%d: UnicodeDecodeError: Assuming page has no text", doc_url, page_idx, exc_info=exc ) return None layout = pdf_page.get_text_layout() if not layout[0]: return None layout = layout[1] line_boxes = [] for (line, line_rects) in self._custom_split( txt, layout, lambda x: x == "\n", "lines", ): words = [] for (word, word_rects) in self._custom_split( line, line_rects, lambda x: x.isspace(), "words" ): word_box = PdfWordBox(word, word_rects) words.append(word_box) line_boxes.append(PdfLineBox(words, line_rects)) return line_boxes def page_get_boxes_by_url(self, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None mapping = self._get_page_mapping(doc_url) page_idx = mapping.get_original_page_idx(page_idx) if page_idx is None: return None # Poppler is not thread-safe return self.core.call_one( "mainloop_execute", self._page_get_boxes_by_url, doc_url, page_idx ) def doc_pdf_import(self, src_file_uri, password=None, target_doc_id=None): doc_id = None doc_url = None if target_doc_id is not None: doc_id = target_doc_id doc_url = self.core.call_success( "doc_id_to_url", doc_id, existing=False ) if doc_url is None: doc_id = None elif self.core.call_success("fs_exists", doc_url): doc_id = None if doc_id is None: (doc_id, doc_url) = self.core.call_success("storage_get_new_doc") # just to be safe self.cache_mappings.pop(doc_url, None) pdf_url = self.core.call_success("fs_join", doc_url, PDF_FILENAME) self.core.call_success("fs_mkdir_p", doc_url) self.core.call_success("fs_copy", src_file_uri, pdf_url) if password is not None: passwd_url = self.core.call_success( "fs_join", doc_url, PASSWD_FILENAME ) with self.core.call_success("fs_open", passwd_url, "w") as fd: fd.write(password) try: # check the PDF is readable doc = self.core.call_success( "poppler_open", pdf_url, password=password ) exc_info = None except Exception as exc: doc = None exc_info = exc if doc is None: if exc_info is None: LOGGER.error("Failed to read %s", pdf_url) else: LOGGER.error("Failed to read %s", pdf_url, exc_info=exc_info) self.core.call_success("fs_rm_rf", doc_url, trash=False) return (None, None) return (doc_id, doc_url) def page_delete_by_url(self, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return mapping = self._get_page_mapping(doc_url) mapping.delete_target_page(page_idx) mapping.save() def _page_get_paper_size_by_url(self, doc_url, page_idx): if doc_url in self.cache_nb_pages: if page_idx >= self.cache_nb_pages[doc_url]: return None (pdf_url, pdf) = self._open_pdf(doc_url) if pdf is None: return None page = pdf.get_page(page_idx) if page is None: return size = page.get_size() # points --> inches: / 72 # inches --> millimeters (i18n unit): * 25.4 return ( size[0] / 72.0 * 25.4, size[0] / 72.0 * 25.4, ) def page_get_paper_size_by_url(self, doc_url, page_idx): pdf_url = self._get_pdf_url(doc_url) if pdf_url is None: return None mapping = self._get_page_mapping(doc_url) page_idx = mapping.get_original_page_idx(page_idx) if page_idx is None: return None # Poppler is not thread-safe return self.core.call_one( "mainloop_execute", self._page_get_paper_size_by_url, doc_url, page_idx ) def page_move_by_url( self, source_doc_url, target_source_page_idx, dest_doc_url, target_dest_page_idx ): # 'source' is about the source document. # 'dest' is about the destination document. # 'original' is about the original position of a page in a PDF file. # 'target' is about the position of a page as shown to the end-user. source_pdf_url = self._get_pdf_url(source_doc_url) source_is_pdf = source_pdf_url is not None dest_is_pdf = self._get_pdf_url(dest_doc_url) is not None if not source_is_pdf and not dest_is_pdf: return if source_is_pdf: source_mapping = self._get_page_mapping(source_doc_url) if dest_is_pdf: dest_mapping = self._get_page_mapping(dest_doc_url) LOGGER.info( "%s (%s) p%d --> %s (%s) p%d", source_doc_url, "PDF" if source_is_pdf else "non-PDF", target_source_page_idx, dest_doc_url, "PDF" if dest_is_pdf else "non-PDF", target_dest_page_idx, ) if source_is_pdf: original_source_page_idx = source_mapping.get_original_page_idx( target_source_page_idx ) # if original_source_page_idx is None means # this page is not handled by us ; still, we must shift # all our pages LOGGER.info( "- Removing page (original=%s, target=%d) from %s", original_source_page_idx, target_source_page_idx, source_doc_url ) source_mapping.delete_target_page(target_source_page_idx) if dest_is_pdf: LOGGER.info( "- Making room for a new page (target=%d) in %s", target_dest_page_idx, dest_doc_url ) dest_mapping.make_room_for_target_page(target_dest_page_idx) if source_doc_url == dest_doc_url: assert source_mapping is dest_mapping if original_source_page_idx is not None: LOGGER.info( "New mapping: %s: original=p%d --> target=p%d", source_doc_url, original_source_page_idx, target_dest_page_idx ) source_mapping.set_mapping( original_source_page_idx, target_dest_page_idx ) source_mapping.update_nb_pages() elif source_is_pdf: if original_source_page_idx is not None: # export the PDF page as an image file # it relies on other model plugins (interface 'page_img'), but # they can't be declared as dependencies, as we do provide # 'page_img' too. It would make a dependency loop. # we are a low priority plugin: other plugins should # already have made room for our page if required source_img = "{}#page={}".format( source_pdf_url, str(original_source_page_idx + 1) ) LOGGER.info("Generating image from %s", source_img) source_img = self.core.call_success( "url_to_pillow", source_img ) # since PDF are not writable by themselves, we can call # page_get_img_url(write=True). We are sure that our # implementation of this method won't reply dest_img = self.core.call_success( "page_get_img_url", dest_doc_url, target_dest_page_idx, write=True, original=True ) LOGGER.info("Writting page image back as %s", dest_img) self.core.call_success("pillow_to_url", source_img, dest_img) if source_is_pdf: source_mapping.save() if dest_is_pdf: dest_mapping.save() paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/thumbnail.py000066400000000000000000000134401456262201400270370ustar00rootroot00000000000000#!/usr/bin/python3 import logging import time import PIL.Image import openpaperwork_core import openpaperwork_core.promise from . import util THUMBNAIL_WIDTH = 64 THUMBNAIL_HEIGHT = 80 PAGE_THUMBNAIL_FILENAME = 'paper.{}.thumb.jpg' LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 5000 # see page_get_img_url() def get_interfaces(self): return [ 'pages', 'thumbnail', # thumbnail_get_path() 'thumbnailer', # thumbnail_from_img() ] def get_deps(self): return [ { 'interface': 'page_img', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, { 'interface': 'pillow_util', 'defaults': ['openpaperwork_core.pillow.util'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def thumbnail_get_doc(self, doc_url): return self.thumbnail_get_page(doc_url, page_idx=0) def thumbnail_get_doc_promise(self, doc_url): return openpaperwork_core.promise.ThreadedPromise( self.core, self.thumbnail_get_doc, args=(doc_url,) ) def thumbnail_from_img(self, img): (width, height) = img.size scale = max( float(width) / THUMBNAIL_WIDTH, float(height) / THUMBNAIL_HEIGHT ) width /= scale height /= scale width = max(width, 1) height = max(height, 1) return img.resize( (int(width), int(height)), getattr(PIL.Image, 'Resampling', PIL.Image).LANCZOS ) def thumbnail_get_page(self, doc_url, page_idx): thumbnail_url = self.core.call_success( "fs_join", doc_url, PAGE_THUMBNAIL_FILENAME.format(page_idx + 1) ) page_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) if page_url is None: LOGGER.warning( "Failed to get thumbnail for %s p%d. No page URL", doc_url, page_idx ) return None if self.core.call_success("fs_exists", thumbnail_url) is not None: thumbnail_mtime = self.core.call_success( "fs_get_mtime", thumbnail_url ) if not self.core.call_success("fs_iswritable", thumbnail_url): page_mtime = self.core.call_success("fs_get_mtime", page_url) if thumbnail_mtime < page_mtime: self.core.call_success("fs_unlink", thumbnail_url) if self.core.call_success("fs_exists", thumbnail_url) is not None: LOGGER.debug("Loading thumbnail for %s page %d", doc_url, page_idx) try: thumbnail = self.core.call_success( "url_to_pillow", thumbnail_url ) size = thumbnail.size if size[0] == THUMBNAIL_WIDTH or size[1] == THUMBNAIL_HEIGHT: return thumbnail LOGGER.info( "Thumbnail for %s page %d doesn't have the expected size" " (%s instead of %s). Regenerating.", doc_url, page_idx, size, (THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT) ) except Exception as exc: LOGGER.warning( "Failed to load thumbnail for %s page %d. Regenerating", doc_url, page_idx, exc_info=exc ) LOGGER.info("Generating thumbnail for %s page %d", doc_url, page_idx) start = time.time() try: page = self.core.call_success("url_to_pillow", page_url) except Exception as exc: LOGGER.error("Failed to load page %s", page_url, exc_info=exc) page = self.core.call_success("pillow_get_error", "invalid") thumbnail = self.thumbnail_from_img(page) self.core.call_success( "pillow_to_url", thumbnail, thumbnail_url, format='JPEG', quality=0.85 ) stop = time.time() LOGGER.info( "Thumbnail for %s page %d generated in %f seconds", doc_url, page_idx, stop - start ) return thumbnail def thumbnail_get_page_promise(self, doc_url, page_idx): return openpaperwork_core.promise.ThreadedPromise( self.core, self.thumbnail_get_page, args=(doc_url, page_idx) ) def page_delete_by_url(self, doc_url, page_idx): return util.delete_page_file( self.core, PAGE_THUMBNAIL_FILENAME, doc_url, page_idx, trash=False ) def page_move_by_url( self, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ): return util.move_page_file( self.core, PAGE_THUMBNAIL_FILENAME, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ) def page_reset_by_url(self, doc_url, page_idx): # see model.img_overlay.page_reset_by_url() # We must force a rebuild of the thumbnail self.page_delete_by_url(doc_url, page_idx) def page_get_img_url(self, doc_url, page_idx, write=False, **kwargs): if not write: return None # Image is going to be updated --> We must force a rebuild of the # thumbnail self.page_delete_by_url(doc_url, page_idx) return None paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/util.py000066400000000000000000000115631456262201400260350ustar00rootroot00000000000000import logging LOGGER = logging.getLogger(__name__) def _shift_pages(core, page_filename_fmt, doc_url, start_page_idx, offset): assert offset != 0 total_pages = core.call_success("doc_get_nb_pages_by_url", doc_url) if total_pages is None: total_pages = 0 if offset < 0: rng = range(start_page_idx + 1, total_pages + 1) elif offset > 0: rng = range(total_pages - 1, start_page_idx - 1, -1) for page_idx in rng: old_url = core.call_success( "fs_join", doc_url, page_filename_fmt.format(page_idx + 1) ) if core.call_success("fs_exists", old_url) is None: continue new_url = core.call_success( "fs_join", doc_url, page_filename_fmt.format( page_idx + 1 + offset ) ) LOGGER.info(" - %s --> %s", old_url, new_url) core.call_success("fs_rename", old_url, new_url) def delete_page_file(core, page_filename_fmt, doc_url, page_idx, trash=True): file_url = core.call_success( "fs_join", doc_url, page_filename_fmt.format(page_idx + 1) ) if core.call_success("fs_exists", file_url) is not None: LOGGER.info( "(%s) Deleting %s p%d:", page_filename_fmt, doc_url, page_idx ) core.call_success("fs_unlink", file_url, trash=trash) # move all the other pages 1 level down _shift_pages(core, page_filename_fmt, doc_url, page_idx, -1) return True def move_page_file( core, page_filename_fmt, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ): if core.call_success("fs_exists", dest_doc_url) is None: assert dest_page_idx == 0 core.call_success("fs_mkdir_p", dest_doc_url) LOGGER.info( "(%s) Move %s p%d --> %s p%d:", page_filename_fmt, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ) # source_doc_url and dest_doc_url can be the same document, making # this change a little bit tricky. The simplest way to handle all the cases # is to: # --> move the page out of the source document (we rename it temporarily # page_filename_fmt.format(0)) # --> then to insert it in the destination document # Move the page out of the source document src = core.call_success( "fs_join", source_doc_url, page_filename_fmt.format(source_page_idx + 1) ) dst = core.call_success( "fs_join", dest_doc_url, page_filename_fmt.format(0) ) if core.call_success("fs_exists", src) is not None: LOGGER.info(" - %s --> %s", src, dst) core.call_success("fs_rename", src, dst) _shift_pages(core, page_filename_fmt, source_doc_url, source_page_idx, -1) # Move the page in the destination document src = dst dst = core.call_success( "fs_join", dest_doc_url, page_filename_fmt.format(dest_page_idx + 1) ) _shift_pages(core, page_filename_fmt, dest_doc_url, dest_page_idx, 1) if core.call_success("fs_exists", src) is not None: LOGGER.info(" - %s --> %s", src, dst) core.call_success("fs_rename", src, dst) return True def get_nb_pages(core, doc_url, filename_regex): if core.call_success("fs_exists", doc_url) is None: return None if core.call_success("fs_isdir", doc_url) is None: return None files = core.call_success("fs_listdir", doc_url) if files is None: return None nb_pages = -1 for f in files: f = core.call_success("fs_basename", f) match = filename_regex.match(f) if match is None: continue nb_pages = max(nb_pages, int(match.group(1))) if nb_pages <= 0: return None return nb_pages def get_page_hash(core, doc_url, page_idx, filename_fmt): page_url = core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) if core.call_success("fs_exists", page_url) is None: return None return core.call_success("fs_hash", page_url) def get_page_mtime(core, doc_url, page_idx, filename_fmt): page_url = core.call_success( "fs_join", doc_url, filename_fmt.format(page_idx + 1) ) if core.call_success("fs_exists", page_url) is None: return return core.call_success("fs_get_mtime", page_url) def get_doc_mtime(core, doc_url, filename_regex): r = -1 if core.call_success("fs_exists", doc_url) is None: return if core.call_success("fs_isdir", doc_url) is None: return files = core.call_success("fs_listdir", doc_url) if files is None: return None for f in files: f = core.call_success("fs_basename", f) match = filename_regex.match(f) if match is None: continue page_url = core.call_success("fs_join", doc_url, f) r = max(r, core.call_success("fs_get_mtime", page_url)) if r < 0: return None return r paperwork-2.2.2/paperwork-backend/src/paperwork_backend/model/workdir.py000066400000000000000000000155661456262201400265500ustar00rootroot00000000000000import datetime import logging import os import openpaperwork_core LOGGER = logging.getLogger(__name__) DOCNAME_FORMAT = "%Y%m%d_%H%M_%S" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -1000 # see page_delete_by_url() / page_move_by_url() def get_interfaces(self): return [ "document_storage", "stats" ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, ] def init(self, core): super().init(core) setting = self.core.call_success( "config_build_simple", "Global", "WorkDirectory", lambda: self.core.call_success( "fs_safe", os.path.expanduser("~/papers") ) ) self.core.call_all("config_register", "workdir", setting) self.core.call_all( "config_add_observer", "workdir", self._on_work_dir_changed ) def _on_work_dir_changed(self): LOGGER.info("Work directory has changed") self.core.call_all("on_storage_changed") def storage_get_id(self): """ Returns a string identifying the storage (work directory) currently used. Do not assume it's a valid directory path. For instance, this plugin could be replaced by a MariaDB database someday, and so the string would identify the database instead of a directory. """ return self.core.call_success('config_get', 'workdir') def storage_get_all_docs(self, out: list, only_valid=True): """ Returns all document IDs and URLs in the work directory """ workdir = self.core.call_success('config_get', 'workdir') if self.core.call_success('fs_exists', workdir) is None: # we are not the plugin handling this storage (?) return LOGGER.info("Loading document list from %s", workdir) nb = 0 for doc_url in self.core.call_success('fs_listdir', workdir): doc_id = self.core.call_success("fs_basename", doc_url) if doc_id.startswith("."): continue if only_valid and not self.core.call_success("fs_isdir", doc_url): LOGGER.warning( "Ignoring document '%s': not a directory", doc_url ) continue if ( only_valid and self.core.call_success("is_doc", doc_url) is None): LOGGER.warning( "Ignoring document '%s': not recognized document type", doc_url ) continue out.append((doc_id, doc_url)) nb += 1 LOGGER.info("%d documents found in %s", nb, workdir) def doc_id_to_url(self, doc_id, existing=True): assert doc_id is not None workdir = self.core.call_success('config_get', 'workdir') url = self.core.call_success("fs_join", workdir, doc_id) if existing and self.core.call_success("fs_isdir", url) is None: return None return url def doc_url_to_id(self, doc_url): workdir = self.core.call_success('config_get', 'workdir') if not doc_url.startswith(workdir): return None return self.core.call_success("fs_basename", doc_url) def doc_get_date_by_id(self, doc_id): # Doc id is expected to have this format: # YYYYMMDD_hhmm_ss_NN_something_else doc_id = doc_id.split("_", 3) doc_id = "_".join(doc_id[:3]) try: return datetime.datetime.strptime(doc_id, DOCNAME_FORMAT) except ValueError: return None def doc_get_id_by_date(self, date): return date.strftime(DOCNAME_FORMAT) # datetime.datetime.now cannot be mocked with unittest.mock.patch # (datetime is built-in) --> allow dependency injection here def storage_get_new_doc(self, now_func=datetime.datetime.now): workdir = self.core.call_success('config_get', 'workdir') base_doc_id = now_func().strftime(DOCNAME_FORMAT) base_doc_url = self.core.call_success("fs_join", workdir, base_doc_id) doc_id = base_doc_id doc_url = base_doc_url doc_idx = 0 while self.core.call_success("fs_exists", doc_url) is not None: doc_idx += 1 doc_id = "{}_{}".format(base_doc_id, doc_idx) doc_url = "{}_{}".format(base_doc_url, doc_idx) return (doc_id, doc_url) def storage_delete_doc_id(self, doc_id, trash=True): doc_url = self.doc_id_to_url(doc_id) if doc_url is None: return self.core.call_success("fs_rm_rf", doc_url, trash=trash) def stats_get(self, stats): LOGGER.info("Counting documents for statistics...") all_docs = [] self.storage_get_all_docs(all_docs) stats['nb_documents'] += len(all_docs) def page_delete_by_url(self, doc_url, page_idx): workdir = self.core.call_success('config_get', 'workdir') if not doc_url.startswith(workdir): return None nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is not None and nb_pages > 0: return LOGGER.warning( "All pages of document %s have been removed. Removing document", doc_url ) self.core.call_success("fs_rm_rf", doc_url) def page_move_by_url( self, source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ): workdir = self.core.call_success('config_get', 'workdir') if not source_doc_url.startswith(workdir): return None workdir = self.core.call_success('config_get', 'workdir') if not dest_doc_url.startswith(workdir): return None nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", source_doc_url ) if nb_pages is not None and nb_pages > 0: return LOGGER.warning( "All pages of document %s have been removed. Removing document", source_doc_url ) self.core.call_success("fs_rm_rf", source_doc_url) def doc_rename_by_url(self, src_doc_url, dst_doc_url): if not self.core.call_success("fs_isdir", src_doc_url): # May happen on integrated documentation PDF files LOGGER.warning("Cannot rename non-directory documents") return idx = 0 dst_url = dst_doc_url while self.core.call_success("fs_exists", dst_url) is not None: idx += 1 dst_url = "{}_{}".format(dst_doc_url, idx) self.core.call_success("fs_rename", src_doc_url, dst_url) return dst_url paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pageedit/000077500000000000000000000000001456262201400251625ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pageedit/__init__.py000066400000000000000000000024711456262201400272770ustar00rootroot00000000000000class AbstractPageEditorUI(object): CAPABILITY_SHOW_FRAME = (1 << 0) CAPABILITIES = 0 def can(self, capability): return bool(self.CAPABILITIES & capability) def set_modifier_state(self, modifier_id, enabled): """ Indicates if an modifier must be shown as enabled or disabled. """ pass def show_preview(self, img): """ Indicates the image to display, with all the changes applied from the modifiers already applied on it. Only called when the image changed. """ return def show_frame_selector(self): """ Tells the UI that it must let the user select a frame on the image (image provided by `show_image`). It also specify the current frame to display to the user. Called every time the image changes if we want the frame to be shown. Frame can be obtained by calling PageEditor.frame.get() and can be updated with PageEditor.frame.set(). """ return def hide_frame_selector(self): """ Tells the UI to not let the user select a frame anymore. """ return def on_edit_end(self, doc_url, page_idx): """ Called when the user modifications have been applied or cancelled. """ pass paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pageedit/pageeditor.py000066400000000000000000000207611456262201400276650ustar00rootroot00000000000000""" Plugin providing a controller object for page editing. This controller object uses a paperwork_backend.imgedit.AbstractPageEditorUI object to tells the UI what to do. The UI must reciprocate by transmitting some events to the controller object. """ import logging import openpaperwork_core import openpaperwork_core.promise from .. import _ LOGGER = logging.getLogger(__name__) class Frame(object): def __init__(self, editor, original): # convert the frame coordinates into a more convenient format self.editor = editor self.original = original def get(self): frame = None for (e, img_size) in zip( self.editor.active_modifiers, self.editor.img_sizes ): if hasattr(e, 'frame'): frame = e.frame elif frame is not None: frame = e.transform_frame(img_size, frame) return frame def set(self, frame): for (e, img_size) in zip( reversed(self.editor.active_modifiers), reversed(self.editor.img_sizes) ): if hasattr(e, 'frame'): e.frame = frame else: frame = e.untransform_frame(img_size, frame) class PageEditor(object): def __init__(self, core, doc_url, page_idx, page_editor_ui): self.core = core self.ui = page_editor_ui self.doc_url = doc_url self.page_idx = page_idx if doc_url is not None: page_url = self.core.call_success( "page_get_img_url", doc_url, page_idx, write=False ) self.original_img = self.core.call_success( "url_to_pillow", page_url ) # The frame coordinates we keep here are relative to the original # image (not the resulting image, that can, for instance, be # rotated) # TODO(Jflesch): We should use libpillowfight.scan_border() # to predefined an useful frame. original_frame = ((0, 0), self.original_img.size) else: self.original_img = None original_frame = ((0, 0), (0, 0)) self.frame = Frame(self, original_frame) modifiers = [] self.core.call_all("img_editor_get_names", modifiers) self.modifier_descriptors = {} if 'color_equalization' in modifiers: self.modifier_descriptors['color_equalization'] = { "id": "color_equalization", "name": _("Color equalization"), "modifier": 'color_equalization', "default_kwargs": {}, "need_frame": False, "togglable": True, "enabled": False, "priority": -999, } if ('cropping' in modifiers and self.ui.can(self.ui.CAPABILITY_SHOW_FRAME)): self.modifier_descriptors['crop'] = { "id": "crop", "name": _("Cropping"), "modifier": 'cropping', "default_kwargs": {}, "need_frame": True, "togglable": True, "enabled": False, "priority": 100, } if 'rotation' in modifiers: self.modifier_descriptors['rotate_clockwise'] = { "id": "rotate_clockwise", "name": _("Clockwise Rotation"), "modifier": 'rotation', "default_kwargs": {'angle': 90}, "need_frame": False, "togglable": False, "priority": 50, } self.modifier_descriptors['rotate_counterclockwise'] = { "id": "rotate_counterclockwise", "name": _("Counterclockwise Rotation"), "modifier": 'rotation', "default_kwargs": {'angle': -90}, "need_frame": False, "togglable": False, "priority": 49, } self.active_modifiers = [] # image sizes before transformation of each modifier self.img_sizes = [] if self.ui is not None: self._refresh_preview() self._refresh_frame() def get_modifiers(self): r = list(self.modifier_descriptors.values()) r.sort(key=lambda m: -m['priority']) return r def _needs_frame(self): if not self.ui.can(self.ui.CAPABILITY_SHOW_FRAME): return for e in self.active_modifiers: if hasattr(e, 'frame'): return True return False def _refresh_modifiers(self): for modifier in self.modifier_descriptors.values(): enabled = False if modifier['togglable'] and modifier['enabled']: enabled = True self.ui.set_modifier_state(modifier['id'], enabled) def _refresh_preview(self): img = self.original_img self.img_sizes = [] for e in self.active_modifiers: self.img_sizes.append(img.size) img = e.transform(img, preview=True) self.core.call_one("mainloop_execute", self.ui.show_preview, img) def _refresh_frame(self): if not self._needs_frame(): self.core.call_one("mainloop_execute", self.ui.hide_frame_selector) return self.core.call_one( "mainloop_execute", self.ui.show_frame_selector ) def _on_modifier_selected(self, modifier_id): modifier_descriptor = self.modifier_descriptors[modifier_id] if modifier_descriptor['togglable'] and modifier_descriptor['enabled']: self.core.call_all( "img_editor_unset", self.active_modifiers, modifier_descriptor['modifier'] ) modifier_descriptor['enabled'] = False else: self.core.call_all( "img_editor_set", self.active_modifiers, modifier_descriptor['modifier'], **modifier_descriptor['default_kwargs'] ) modifier_descriptor['enabled'] = True self._refresh_modifiers() self._refresh_preview() self._refresh_frame() def on_modifier_selected(self, modifier_id): return openpaperwork_core.promise.ThreadedPromise( self.core, self._on_modifier_selected, args=(modifier_id,) ) def _on_save(self): img = self.original_img for e in self.active_modifiers: img = e.transform(img, preview=False) # XXX(Jflesch): First go back the doc view. Because when # calling `page_get_img_url` or others, some plugins may do # shady things (see paperwork_gtk.model.help._get_doc_url() # for instance) self.core.call_success( "mainloop_schedule", self.ui.on_edit_end, self.doc_url, self.page_idx ) page_url = self.core.call_success( "page_get_img_url", self.doc_url, self.page_idx, write=True ) self.core.call_success("pillow_to_url", img, page_url) # Drop the text so the OCR will be run again self.core.call_success( "page_set_boxes_by_url", self.doc_url, self.page_idx, [] ) def on_save(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self._on_save ) def on_cancel(self): self.active_modifiers = [] self.ui.on_edit_end(self.doc_url, self.page_idx) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['page_editor'] def get_deps(self): return [ { "interface": "img_editor", 'defaults': [ 'paperwork_backend.imgedit.color', 'paperwork_backend.imgedit.crop', 'paperwork_backend.imgedit.rotate', ], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ] }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def page_editor_get(self, doc_url, page_idx, page_editor_ui): return PageEditor(self.core, doc_url, page_idx, page_editor_ui) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pagetracker.py000066400000000000000000000126721456262201400262520ustar00rootroot00000000000000""" This plugin is an helper for other plugins. It provides an easy way to track pages that have not yet being treated in each document. For instance, when a document is notified as updated (see transactions), the OCR plugin needs to know which pages of this document have already been OCR-ed and which haven't. """ import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) CREATE_TABLES = [ ( "CREATE TABLE IF NOT EXISTS pages (" " doc_id TEXT NOT NULL," " page INTEGER NOT NULL," " hash TEXT NOT NULL," " PRIMARY KEY (doc_id, page)" ")" ), ] class PageTracker(object): def __init__(self, core, sql_url): self.core = core self.sql = self.core.call_one( "sqlite_execute", self.core.call_success, "sqlite_open", sql_url ) for query in CREATE_TABLES: self.core.call_one("sqlite_execute", self.sql.execute, query) self.core.call_one( "sqlite_execute", self.sql.execute, "BEGIN TRANSACTION" ) def _close(self): LOGGER.info("Closing page tracker db ...") self.core.call_one( "sqlite_execute", self.core.call_success, "sqlite_close", self.sql ) self.sql = None def cancel(self): if self.sql is None: return self.core.call_one( "sqlite_execute", self.sql.execute, "ROLLBACK" ) self._close() def commit(self): if self.sql is None: return self.core.call_one("sqlite_execute", self.sql.execute, "COMMIT") self._close() def find_changes(self, doc_id, doc_url): """ Examine a document. Return page that haven't been handled yet or that have been modified since. Don't forget to call ack_page() once you've handled each page. """ out = [] db_pages = self.core.call_one( "sqlite_execute", self.sql.execute, "SELECT page, hash FROM pages" " WHERE doc_id = ?", (doc_id,) ) db_pages = self.core.call_one( "sqlite_execute", lambda pages: {r[0]: int(r[1], 16) for r in pages}, db_pages ) db_hashes = set(db_pages.values()) fs_nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) or 0 fs_pages = {} for page_idx in range(0, fs_nb_pages): fs_pages[page_idx] = self.core.call_success( "page_get_hash_by_url", doc_url, page_idx ) for (page_idx, fs_page_hash) in fs_pages.items(): if page_idx not in db_pages: out.append(('new', page_idx)) else: db_page_hash = db_pages.pop(page_idx) if db_page_hash != fs_page_hash: if fs_page_hash in db_hashes: # this page existed before out.append(('moved', page_idx)) else: out.append(('upd', page_idx)) for (db_page_idx, h) in db_pages.items(): self.core.call_one( "sqlite_execute", self.sql.execute, "DELETE FROM pages" " WHERE doc_id = ? AND page = ?", (doc_id, db_page_idx) ) return out def ack_page(self, doc_id, doc_url, page_idx): """ Mark the page update has handled. """ page_hash = self.core.call_success( "page_get_hash_by_url", doc_url, page_idx ) self.core.call_one( "sqlite_execute", self.sql.execute, "INSERT OR REPLACE" " INTO pages (doc_id, page, hash)" " VALUES (?, ?, ?)", (doc_id, page_idx, format(page_hash, 'x')) ) def delete_doc(self, doc_id): self.core.call_one( "sqlite_execute", self.sql.execute, "DELETE FROM pages WHERE doc_id = ?", (doc_id,) ) class Plugin(openpaperwork_core.PluginBase): def __init__(self): pass def get_interfaces(self): return ['page_tracking'] def get_deps(self): return [ { 'interface': 'data_dir_handler', 'defaults': ['paperwork_backend.datadirhandler'], }, { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'] }, { 'interface': 'page_boxes', 'defaults': ['paperwork_backend.model.hocr'], }, { 'interface': 'page_img', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, { 'interface': 'sqlite', 'defaults': ['openpaperwork_core.sqlite'], }, ] def page_tracker_get(self, tracking_id): paperwork_dir = self.core.call_success( "data_dir_handler_get_individual_data_dir" ) sql_file = self.core.call_success( "fs_join", paperwork_dir, 'page_tracking_{}.db'.format(tracking_id) ) return PageTracker(self.core, sql_file) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pillow/000077500000000000000000000000001456262201400247065ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pillow/__init__.py000066400000000000000000000000001456262201400270050ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pillow/pdf.py000066400000000000000000000101311456262201400260250ustar00rootroot00000000000000import io import logging import PIL import PIL.Image import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) def surface2image(core, surface): """ Convert a cairo surface into a PIL image """ # XXX(Jflesch): Python 3 problem # cairo.ImageSurface.get_data() raises NotImplementedYet ... # import PIL.ImageDraw # # if surface is None: # return None # dimension = (surface.get_width(), surface.get_height()) # img = PIL.Image.frombuffer("RGBA", dimension, # surface.get_data(), "raw", "BGRA", 0, 1) # # background = PIL.Image.new("RGB", img.size, (255, 255, 255)) # background.paste(img, mask=img.split()[3]) # 3 is the alpha channel # return background core.call_all("on_perfcheck_start", "surface2image") img_io = io.BytesIO() surface.surface.write_to_png(img_io) img_io.seek(0) try: img = PIL.Image.open(img_io) except PIL.Image.DecompressionBombError as exc: LOGGER.warning("Cairo surface is too big", exc_info=exc) return core.call_success("pillow_get_error", "too_big") core.call_all("on_objref_track", img) img.load() if "A" not in img.getbands(): core.call_all("on_perfcheck_stop", "surface2image", size=img.size) return img img_no_alpha = PIL.Image.new("RGB", img.size, (255, 255, 255)) core.call_all("on_objref_track", img_no_alpha) img_no_alpha.paste(img, mask=img.split()[3]) # 3 is the alpha channel core.call_all( "on_perfcheck_stop", "surface2image", size=img_no_alpha.size ) return img_no_alpha class Plugin(openpaperwork_core.PluginBase): FILE_EXTENSION = ".pdf" def get_interfaces(self): return [ 'page_img_size', 'pillow', ] def get_deps(self): return [ { 'interface': 'pdf_cairo_url', 'defaults': ['paperwork_backend.cairo.poppler'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'pillow_util', 'defaults': ['openpaperwork_core.pillow.util'], }, { 'interface': 'urls', 'defaults': ['openpaperwork_core.urls'], }, ] def _check_is_pdf(self, file_url): (url, args) = self.core.call_success("url_args_split", file_url) if not url.lower().endswith(self.FILE_EXTENSION): return (None, None, None) page_idx = int(args.get("page", 1)) - 1 password = args.get('password', None) if password is not None: password = bytes.fromhex(password).decode("utf-8") return (file_url, page_idx, password) def url_to_pillow(self, file_url): (file_url, page_idx, password) = self._check_is_pdf(file_url) if file_url is None: return None pillow = self.core.call_one( # Poppler is not really thread safe "mainloop_execute", self._url_to_pillow, file_url, page_idx, password ) return pillow def cairo_surface_to_pillow(self, surface): return surface2image(self.core, surface) def _url_to_pillow(self, file_url, page_idx, password): surface = self.core.call_success( "pdf_page_to_cairo_surface", file_url, page_idx, password ) # WORKAROUND(Jflesch): may occur with corrupted PDFs if surface is None: return None img = surface2image(self.core, surface) surface.surface.finish() img.load() return img def url_to_pillow_promise(self, file_url): (doc_url, page_idx, password) = self._check_is_pdf(file_url) if doc_url is None: return None return openpaperwork_core.promise.Promise( self.core, self.url_to_pillow, args=(file_url,) ) def pillow_to_url(self, *args, **kwargs): # It could be implemented, but there are no known use-cases. return None paperwork-2.2.2/paperwork-backend/src/paperwork_backend/poppler/000077500000000000000000000000001456262201400250615ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/poppler/__init__.py000066400000000000000000000000001456262201400271600ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/src/paperwork_backend/poppler/file.py000066400000000000000000000034251456262201400263560ustar00rootroot00000000000000import os import openpaperwork_core import openpaperwork_core.deps GI_AVAILABLE = False GLIB_AVAILABLE = False POPPLER_AVAILABLE = False try: import gi GI_AVAILABLE = True except (ImportError, ValueError): pass if GI_AVAILABLE: try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): pass try: gi.require_version('Poppler', '0.18') from gi.repository import Poppler POPPLER_AVAILABLE = True except (ImportError, ValueError): pass class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'poppler', ] def get_deps(self): return [ { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, ] def chkdeps(self, out: dict): if not GI_AVAILABLE: out['gi'] = openpaperwork_core.deps.GI if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not POPPLER_AVAILABLE: out['poppler'] = openpaperwork_core.deps.POPPLER def poppler_open(self, url, password=None): if os.name == "nt": # WORKAROUND(Jflesch): # Disabled for now on Windows: There is a file descriptor leak # somewhere. # While it causes little problems on GNU/Linux, on Windows it # prevents deleting documents. return None gio_file = Gio.File.new_for_uri(url) doc = self.core.call_one( "mainloop_execute", Poppler.Document.new_from_gfile, gio_file, password=password ) self.core.call_all("on_objref_track", doc) return doc paperwork-2.2.2/paperwork-backend/src/paperwork_backend/poppler/memory.py000066400000000000000000000042031456262201400267420ustar00rootroot00000000000000import openpaperwork_core import openpaperwork_core.deps GI_AVAILABLE = False GLIB_AVAILABLE = False POPPLER_AVAILABLE = False try: import gi from gi.repository import GLib GI_AVAILABLE = True except (ImportError, ValueError): pass if GI_AVAILABLE: try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): pass try: gi.require_version('Poppler', '0.18') from gi.repository import Poppler POPPLER_AVAILABLE = True except (ImportError, ValueError): pass class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def get_interfaces(self): return [ 'chkdeps', 'poppler', ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, ] def chkdeps(self, out: dict): if not GI_AVAILABLE: out['gi'] = openpaperwork_core.deps.GI if not GLIB_AVAILABLE: out['glib'] = openpaperwork_core.deps.GLIB if not POPPLER_AVAILABLE: out['poppler'] = openpaperwork_core.deps.POPPLER def poppler_open(self, url, password=None): # Poppler.Document.new_from_data() expects .. a string # Poppler.Document.new_from_bytes() only exist starting with 0.82 with self.core.call_success("fs_open", url, "rb") as fd: data = fd.read() ldata = len(data) data = GLib.Bytes.new(data) # Gio.MemoryInputStream.new_from_data() may leak # https://stackoverflow.com/questions/45838863/gio-memoryinputstream # --> use Gio.MemoryInputStream.new_from_bytes() instead data = Gio.MemoryInputStream.new_from_bytes(data) self.core.call_all("on_objref_track", data) doc = self.core.call_one( "mainloop_execute", Poppler.Document.new_from_stream, data, ldata, password=password ) return doc paperwork-2.2.2/paperwork-backend/src/paperwork_backend/pyocr.py000066400000000000000000000157251456262201400251200ustar00rootroot00000000000000import glob import locale import logging import os import pycountry import pyocr import pyocr.builders import openpaperwork_core from . import util LOGGER = logging.getLogger(__name__) DEFAULT_OCR_LANG = "eng" # if really we can't guess anything def init_flatpak(core): """ If we are in Flatpak, we must build a tessdata/ directory using the .traineddata files from each locale directory """ tessdata_files = glob.glob("/app/share/locale/*/*.traineddata") if len(tessdata_files) <= 0: return paperwork_dir = core.call_success("paths_get_data_dir") tessdatadir = core.call_success("fs_join", paperwork_dir, "tessdata") tessdatadir = core.call_success("fs_unsafe", tessdatadir) LOGGER.info("Assuming we are running in Flatpak." " Building tessdata directory %s ...", tessdatadir) util.rm_rf(tessdatadir) os.makedirs(tessdatadir, exist_ok=True) os.symlink("/app/share/tessdata/eng.traineddata", os.path.join(tessdatadir, "eng.traineddata")) os.symlink("/app/share/tessdata/osd.traineddata", os.path.join(tessdatadir, "osd.traineddata")) os.symlink("/app/share/tessdata/configs", os.path.join(tessdatadir, "configs")) os.symlink("/app/share/tessdata/tessconfigs", os.path.join(tessdatadir, "tessconfigs")) for tessdata in tessdata_files: LOGGER.info("%s found", tessdata) os.symlink( tessdata, os.path.join(tessdatadir, os.path.basename(tessdata)) ) os.environ['TESSDATA_PREFIX'] = tessdatadir LOGGER.info("Tessdata directory ready") def find_language(lang_str=None, allow_none=False): if lang_str is None: lang_str = locale.getdefaultlocale()[0] if lang_str == "C": LOGGER.warning("Locale is C. Assuming english !") return find_language(DEFAULT_OCR_LANG) if lang_str is None and not allow_none: LOGGER.warning("Unable to figure out locale. Assuming english !") return find_language(DEFAULT_OCR_LANG) if lang_str is None: LOGGER.warning("Unable to figure out locale !") return None lang_str = lang_str.lower() if "_" in lang_str: lang_str = lang_str.split("_")[0] LOGGER.info("System language: {}".format(lang_str)) attrs = ( 'iso_639_3_code', 'iso639_3_code', 'iso639_2T_code', 'iso639_1_code', 'terminology', 'bibliographic', 'alpha_3', 'alpha_2', 'alpha2', 'name', ) for attr in attrs: try: r = pycountry.pycountry.languages.get(**{attr: lang_str}) if r is not None: LOGGER.info("OCR language: {}".format(r)) return r except (KeyError, UnicodeDecodeError): pass if allow_none: LOGGER.warning("Unknown language [{}]".format(lang_str)) return None if lang_str is not None and lang_str == DEFAULT_OCR_LANG: raise Exception("Unable to find language !") LOGGER.warning("Unknown language [{}]. Switching back to english".format( lang_str )) return find_language(DEFAULT_OCR_LANG) def pycountry_to_tesseract(ocr_langs, possibles=None): attrs = [ 'iso639_3_code', 'terminology', 'alpha_3', ] for attr in attrs: if not hasattr(ocr_langs, attr): continue if possibles is None or getattr(ocr_langs, attr) in possibles: r = getattr(ocr_langs, attr) if r is not None: return r return None def get_default_ocr_langs(allow_none=False): # Try to guess based on the system locale what would be # the best OCR language ocr_tools = pyocr.get_available_tools() if len(ocr_tools) == 0: return None if allow_none else [DEFAULT_OCR_LANG] ocr_langs = ocr_tools[0].get_available_languages() lang = find_language(allow_none=True) if lang is None: return None if allow_none else [DEFAULT_OCR_LANG] lang = pycountry_to_tesseract(lang, ocr_langs) if lang is not None: return [lang] return None if allow_none else [DEFAULT_OCR_LANG] class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return [ "chkdeps", "ocr_settings", ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'paths', 'defaults': ['openpaperwork_core.paths.xdg'], }, { 'interface': 'data_versioning', 'defaults': ['openpaperwork_core.data_versioning'], }, ] def init(self, core): super().init(core) init_flatpak(self.core) ocr_langs = self.core.call_success( "config_build_simple", "OCR", "Lang", get_default_ocr_langs ) self.core.call_all("config_register", "ocr_langs", ocr_langs) def chkdeps(self, out: dict): ocr_tools = pyocr.get_available_tools() if len(ocr_tools) <= 0: out['tesseract']['debian'] = 'tesseract-ocr' out['tesseract']['fedora'] = 'tesseract' out['tesseract']['gentoo'] = 'app-text/tesseract' out['tesseract']['linuxmint'] = 'tesseract-ocr' out['tesseract']['raspbian'] = 'tesseract-ocr' out['tesseract']['ubuntu'] = 'tesseract-ocr' ocr_lang = get_default_ocr_langs(allow_none=True) if ocr_lang is None: ocr_lang = find_language(allow_none=True) if ocr_lang is None: ocr_lang = "UNKNOWN" else: ocr_lang = pycountry_to_tesseract(ocr_lang) if ocr_lang is None: ocr_lang = "" name = 'tesseract-data-{}'.format(ocr_lang) out[name]['debian'] = 'tesseract-ocr-{}'.format(ocr_lang) out[name]['fedora'] = 'tesseract-langpack-{}'.format(ocr_lang) out[name]['linuxmint'] = 'tesseract-ocr-{}'.format(ocr_lang) out[name]['raspbian'] = 'tesseract-ocr-{}'.format(ocr_lang) out[name]['ubuntu'] = 'tesseract-ocr-{}'.format(ocr_lang) def ocr_get_active_langs(self): return self.core.call_success("config_get", "ocr_langs") def ocr_set_active_langs(self, langs): return self.core.call_success("config_put", "ocr_langs", langs) def ocr_is_enabled(self): if len(self.ocr_get_active_langs()) > 0: return True return None def ocr_add_observer_on_enabled(self, callback): self.core.call_all("config_add_observer", "ocr_langs", callback) def ocr_get_available_langs(self): ocr_tools = pyocr.get_available_tools() if len(ocr_tools) <= 0: return [] return ocr_tools[0].get_available_languages() paperwork-2.2.2/paperwork-backend/src/paperwork_backend/sync.py000066400000000000000000000231711456262201400247320ustar00rootroot00000000000000import datetime import logging import time import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class BaseTransaction(object): def __init__(self, core, total_expected): self.core = core self.processed = 0 self.total = total_expected self._current_doc = None self._current_doc_pages = -1 def notify_progress( self, upd_type, description, page_nb=-1, total_pages=-1): if self.total <= self.processed: self.total = self.processed + 1 if self.total <= 0: progression = 0 else: progression = self.processed / self.total if page_nb >= 0 and total_pages > 0: progression += (page_nb / total_pages / self.total) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_progress", upd_type, progression, description ) def notify_done(self, upd_type): self.core.call_one( "mainloop_schedule", self.core.call_all, "on_progress", upd_type, 1.0 ) def add_doc(self, doc_id): self._current_doc = doc_id self._current_doc_pages = -1 self.processed += 1 def upd_doc(self, doc_id): self._current_doc = doc_id self._current_doc_pages = -1 self.processed += 1 def del_doc(self, doc_id): self._current_doc = doc_id self._current_doc_pages = -1 self.processed += 1 def unchanged_doc(self, doc_id): self.processed += 1 def cancel(self): self._current_doc = None self._current_doc_pages = -1 def commit(self): self._current_doc = None def diff_lists(list_old, list_new): """ Returns a dictionary giving the differences between both lists. Objects in the list must have 2 attributes: - `key` - `extra` `key` values identify each object in both lists. Comparisons are done on `key` + `extra`. `list_old` will be unrolled immediately. Arguments: `list_old` -- [a, b, c, ...] `list_new` -- [a, c_modified, d, ...] Returns: [ ('same', a.key), ('del', b.key), ('upd', c.key), ('add', d.key), ] list_old + diff => list_new """ list_old = {obj.key: obj for obj in list_old} examined_new = set() for obj_new in list_new: examined_new.add(obj_new.key) if obj_new.key not in list_old: yield ('added', obj_new.key) continue obj_old = list_old[obj_new.key] if obj_new.extra != obj_old.extra: yield ('updated', obj_new.key) else: yield ('unchanged', obj_new.key) for obj_old in list_old.values(): if obj_old.key not in examined_new: yield ('deleted', obj_old.key) class StorageDoc(object): def __init__(self, core, doc_id, doc_url): self.core = core self.key = doc_id self.doc_url = doc_url def get_mtime(self): mtime = self.core.call_success("doc_get_mtime_by_url", self.doc_url) if mtime is None: mtime = 0 return datetime.datetime.fromtimestamp(mtime) extra = property(get_mtime) class Syncer(object): """ This object allows to compare mtimes progressively. It then calls the methods `add_doc`, `del_doc`, `upd_doc` and `commit` on the given transaction object. Useful to handle calls to 'sync' (see interface 'syncable'). """ def __init__(self, core, names, new_all, old_all, transactions): self.core = core self.names = names self.new_all = new_all self.old_all = old_all self.transactions = transactions self.diff_generator = None self.start = None self.nb_compared = 0 def get_promise(self): return openpaperwork_core.promise.ThreadedPromise( self.core, self.run ) def run(self): self.start = time.time() self.diff_generator = diff_lists(self.old_all, self.new_all) try: for (action, key) in self.diff_generator: self.nb_compared += 1 if action != 'unchanged': LOGGER.info("Sync: %s, %s", action, key) for name in self.names: self.core.call_one( "mainloop_schedule", self.core.call_all, "on_sync", name, action, key ) if action == "added": for transaction in self.transactions: LOGGER.debug( "transaction.add_doc<%s>(%s)", transaction.add_doc, key ) transaction.add_doc(key) elif action == "updated": for transaction in self.transactions: LOGGER.debug( "transaction.upd_doc<%s>(%s)", transaction.upd_doc, key ) transaction.upd_doc(key) elif action == "deleted": for transaction in self.transactions: LOGGER.debug( "transaction.del_doc<%s>(%s)", transaction.del_doc, key ) transaction.del_doc(key) else: for transaction in self.transactions: LOGGER.debug( "transaction.unchanged_doc<%s>(%s)", transaction.unchanged_doc, key ) transaction.unchanged_doc(key) LOGGER.info("Sync: Committing ...") for transaction in self.transactions: transaction.commit() LOGGER.info("Sync: Committed") stop = time.time() LOGGER.info( "%s: Has compared %d objects in %.3fs", self.names, self.nb_compared, stop - self.start ) except Exception as exc: LOGGER.error( "%s: Fail to sync. Cancelling transactions", self.names, exc_info=exc ) for transaction in self.transactions: transaction.cancel() class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['transaction_manager'] def get_deps(self): return [ { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def init(self, core): super().init(core) self.core.call_all("work_queue_create", "transactions") def transaction_schedule(self, promise): """ Transactions should never be run in parrallel (even if on the same thread). Some databases (Sqlite3) don't support that. --> we use a work queue to ensure they are run one after the other. """ return self.core.call_success( "work_queue_add_promise", "transactions", promise ) def _transaction_simple(self, changes): if len(changes) <= 0: LOGGER.info("No change. Nothing to do") return transactions = [] self.core.call_all("doc_transaction_start", transactions, len(changes)) transactions.sort(key=lambda transaction: -transaction.priority) try: for (change, doc_id) in changes: doc_url = self.core.call_success("doc_id_to_url", doc_id) if doc_url is None: change = 'del' elif self.core.call_success("is_doc", doc_url) is None: change = 'del' for transaction in transactions: if change == 'add': transaction.add_doc(doc_id) elif change == 'upd': transaction.upd_doc(doc_id) elif change == 'del': transaction.del_doc(doc_id) else: raise Exception("Unknown change type: %s" % change) for transaction in transactions: transaction.commit() except Exception as exc: LOGGER.error("Transactions have failed", exc_info=exc) for transaction in transactions: transaction.cancel() raise def transaction_simple_promise(self, changes): """ See transaction_simple(). Must be scheduled with 'transaction_schedule()'. """ return openpaperwork_core.promise.ThreadedPromise( self.core, self._transaction_simple, args=(changes,) ) def transaction_simple(self, changes: list): """ Helper method. Schedules a transaction for a bunch of document ids. Changes must be a list: [ ('add', 'some_doc_id'), ('upd', 'some_doc_id_2'), ('upd', 'some_doc_id_3'), ('del', 'some_doc_id_4'), ] """ return self.transaction_schedule( self.core.call_success("transaction_simple_promise", changes) ) def transaction_sync_all(self): """ Make sure all the plugins synchronize their databases with the work directory. """ promises = [] self.core.call_all("sync", promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) self.transaction_schedule(promise) paperwork-2.2.2/paperwork-backend/src/paperwork_backend/util.py000066400000000000000000000044771456262201400247430ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2014 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see import logging import os LOGGER = logging.getLogger(__name__) def rm_rf(path): """ Act as 'rm -rf' in the shell """ if os.path.isfile(path): os.unlink(path) elif os.path.isdir(path): for root, dirs, files in os.walk(path, topdown=False): for filename in files: filepath = os.path.join(root, filename) LOGGER.info("Deleting file %s" % filepath) os.unlink(filepath) for dirname in dirs: dirpath = os.path.join(root, dirname) if os.path.islink(dirpath): LOGGER.info("Deleting link %s" % dirpath) os.unlink(dirpath) else: LOGGER.info("Deleting dir %s" % dirpath) os.rmdir(dirpath) LOGGER.info("Deleting dir %s", path) os.rmdir(path) def levenshtein_distance( str_a: str, str_b: str, str_a_idx: int = 0, str_b_idx: int = 0 ): if str_a_idx == len(str_a) or str_b_idx == len(str_b): return len(str_a) - str_a_idx + len(str_b) - str_b_idx # no change required if str_a[str_a_idx] == str_b[str_b_idx]: return levenshtein_distance(str_a, str_b, str_a_idx + 1, str_b_idx + 1) return 1 + min( # insert character levenshtein_distance(str_a, str_b, str_a_idx, str_b_idx + 1), # delete character levenshtein_distance(str_a, str_b, str_a_idx + 1, str_b_idx), # replace character levenshtein_distance(str_a, str_b, str_a_idx + 1, str_b_idx + 1), ) paperwork-2.2.2/paperwork-backend/tests/000077500000000000000000000000001456262201400202725ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/__init__.py000066400000000000000000000000001456262201400223710ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/beacon/000077500000000000000000000000001456262201400215215ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/beacon/__init__.py000066400000000000000000000000001456262201400236200ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/beacon/tests_update.py000066400000000000000000000070471456262201400246070ustar00rootroot00000000000000import datetime import http import http.server import json import unittest import threading import time import openpaperwork_core class TestUpdate(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.app") self.core.load("paperwork_backend.beacon.update") self.config = self.core.get_by_name("openpaperwork_core.config.fake") self.received = False def test_check_update(self): self.received = False class TestRequestHandler(http.server.BaseHTTPRequestHandler): def do_GET(s): self.assertEqual(s.path, "/beacon/latest") s.send_response(200) s.send_header('Content-type', 'application/json') s.end_headers() s.wfile.write(json.dumps({ "paperwork": { "posix": "999.1.2", "nt": "999.1.2", }, }).encode("utf-8")) self.received = True with http.server.HTTPServer(('', 0), TestRequestHandler) as h: self.config.settings = { "check_for_update": True, "last_update_found": "0.1.3", "update_last_run": datetime.date(1995, 1, 1), "update_protocol": "http", "update_server": "127.0.0.1:{}".format(h.server_port), } threading.Thread(target=h.handle_request).start() time.sleep(0.1) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def on_update_detected(s, current, new): self.assertEqual(new, (999, 1, 2)) self.core.call_all("mainloop_quit_graceful") self.core._load_module( "fake_module", FakeModule() ) self.core.init() self.core.call_one('mainloop') self.assertTrue(self.received) def test_server_down(self): self.received = False self.update_notified = False class TestRequestHandler(http.server.BaseHTTPRequestHandler): def do_GET(s): self.assertEqual(s.path, "/beacon/latest") s.send_response(500) s.send_header('Content-type', 'text/html') s.end_headers() s.wfile.write(b"

KO

") self.received = True with http.server.HTTPServer(('', 0), TestRequestHandler) as h: self.config.settings = { "check_for_update": True, "last_update_found": "0.1.3", "update_last_run": datetime.date(1995, 1, 1), "update_protocol": "http", "update_server": "127.0.0.1:{}".format(h.server_port), } threading.Thread(target=h.handle_request).start() time.sleep(0.1) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def on_update_detected(s, current, new): self.update_notified = True self.core._load_module( "fake_module", FakeModule() ) self.core.init() self.core.call_all("mainloop_quit_graceful") self.core.call_one('mainloop') self.assertTrue(self.received) self.assertFalse(self.update_notified) paperwork-2.2.2/paperwork-backend/tests/chkworkdir/000077500000000000000000000000001456262201400224415ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/chkworkdir/__init__.py000066400000000000000000000000001456262201400245400ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/chkworkdir/tests_empty_doc.py000066400000000000000000000044441456262201400262260ustar00rootroot00000000000000import unittest import openpaperwork_core class TestChkWorkDirEmptyDirectory(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.chkworkdir.empty_doc") self.core.init() self.config = self.core.get_by_name("openpaperwork_core.config.fake") self.config.settings = { "workdir": "file:///some_work_dir" } self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_no_problem(self): self.fs.fs = { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, }, } problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 0) def test_check_fix(self): self.fs.fs = { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "some_doc_empty": {}, }, } problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 1) self.core.call_all("fix_work_dir", problems) self.assertEqual( self.fs.fs, { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, }, } ) paperwork-2.2.2/paperwork-backend/tests/chkworkdir/tests_label_color.py000066400000000000000000000162741456262201400265240ustar00rootroot00000000000000import unittest import openpaperwork_core class TestChkWorkDirEmptyDirectory(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.chkworkdir.label_color") self.core.init() self.config = self.core.get_by_name("openpaperwork_core.config.fake") self.config.settings = { "workdir": "file:///some_work_dir" } self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_no_problem(self): self.fs.fs = { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "coloc,rgb(182,133,45)\n" "facture,rgb(0,177,140)\n" "logement,rgb(246,255,0)\n" ) }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "banque,#702000006e5f\n" "fiche de paie,rgb(0,155,0)\n" ) }, }, } problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 0) def test_check_fix(self): self.fs.fs = { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "coloc,rgb(182,133,45)\n" "facture,#aabbccddeeff\n" "logement,rgb(246,255,0)\n" ) }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "banque,#702000006e5f\n" "fiche de paie,rgb(0,155,0)\n" ) }, "some_doc_zzz_bad_label_color": { "labels": ( "coloc,rgb(182,133,45)\n" "facture,rgb(0,177,140)\n" "logement,rgb(246,255,0)\n" ) }, }, } problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 1) self.core.call_all("fix_work_dir", problems) fs = self.fs.fs self.assertEqual( fs['some_work_dir']['some_doc_zzz_bad_label_color']['labels'], ( "coloc,rgb(182,133,45)\n" "logement,rgb(246,255,0)\n" "facture,#aabbccddeeff\n" # fixed ) ) self.maxDiff = None self.assertEqual( self.fs.fs, { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "coloc,rgb(182,133,45)\n" "facture,#aabbccddeeff\n" "logement,rgb(246,255,0)\n" ) }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "banque,#702000006e5f\n" "fiche de paie,rgb(0,155,0)\n" ) }, "some_doc_zzz_bad_label_color": { "labels": ( "coloc,rgb(182,133,45)\n" "logement,rgb(246,255,0)\n" "facture,#aabbccddeeff\n" # fixed ) }, }, } ) problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 0) def test_check_rgb(self): self.fs.fs = { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "coloc,rgb(182,133,45)\n" "facture,rgb(1,10,20)\n" "logement,rgb(246,255,0)\n" ) }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "banque,#702000006e5f\n" "fiche de paie,rgb(0,155,0)\n" ) }, "some_doc_zzz_bad_label_color": { "labels": ( "coloc,rgb(182,133,45)\n" "facture,rgb(0,177,140)\n" "logement,rgb(246,255,0)\n" ) }, }, } problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 1) self.core.call_all("fix_work_dir", problems) fs = self.fs.fs self.assertEqual( fs['some_work_dir']['some_doc_zzz_bad_label_color']['labels'], ( "coloc,rgb(182,133,45)\n" "logement,rgb(246,255,0)\n" "facture,rgb(1,10,20)\n" # fixed ) ) self.maxDiff = None self.assertEqual( self.fs.fs, { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "coloc,rgb(182,133,45)\n" "facture,rgb(1,10,20)\n" "logement,rgb(246,255,0)\n" ) }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "labels": ( "banque,#702000006e5f\n" "fiche de paie,rgb(0,155,0)\n" ) }, "some_doc_zzz_bad_label_color": { "labels": ( "coloc,rgb(182,133,45)\n" "logement,rgb(246,255,0)\n" "facture,rgb(1,10,20)\n" # fixed ) }, }, } ) problems = [] self.core.call_all("check_work_dir", problems) self.assertEqual(len(problems), 0) paperwork-2.2.2/paperwork-backend/tests/converter/000077500000000000000000000000001456262201400223015ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/converter/__init__.py000066400000000000000000000000001456262201400244000ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/converter/test.docx000066400000000000000000000100731456262201400241400ustar00rootroot00000000000000PKf“0R _rels/.rels­’MKA †ïýCîÝl+ˆÈÎö"Bo"õ„™ìîÐÎ3i­ÿÞA ºPŠ Ç¼yóðÒmÎþ Nœ‹‹AêiAq0Ѻ0jxÛ=/`Ó/ºW>ÔJ™\*ªÞ„¢aIˆÅLì©41q¨›!fORÇWeS.“ICŸð ižÍºWó‚Ñ)ŒíD çŒÞ ¶·^¾dôV°§Nx!1þ_Ä»9±ö»7'd,–Ó¦‰“¼h½p]àÅ5nTQŒ‹æ?PK™]À#þPKf“0RdocProps/core.xmlRËNÃ0¼ó‘ï‰ãT*`%©¨'*!(q3ö65ÄŽe»-ý{œ¤I ôÀmgg<ûr>ûRu´ëd£ D’E y#¤® ô¼œÇW(ržiÁêFCöàЬ¼È¹¡¼±ð`ÖKpQ0ÒŽrS µ÷†bìøsIPè@®«˜ÐVØ0þÉ*ÀYšN±Ïó ·†±ÑÁRðÑÒllÝŽ¡Ú;L‚ZV¹³:æD©¤ß8+ÈQýåä(ÜívÉnÒICÿ¿.Qc©ÛUq@e~h„r ̃ˆ‚íË ÌËäön9Ge–f$NIL¦KrM³)ÍÈ[޽o û¸±eËAˆ8n¥ñá†=ù#pÍtµ /W6ž?v’1Õž²fÎ/ÂÑWÄÍ>xœÉ ©Cîÿ#]R29i0è*[ØÊö+:¶k·yÿîû‘Fb/} }zÿüÇòPK ¬çaÛPKf“0Rword/_rels/document.xml.rels­‘M Â0…÷ž"ÌÞ¦U‘¦nDp+õ1¶Á6 É(z{ŠZ(âÂåü}ï1/__ûŽ]Ðm€,I¡Q¶Ò¦p(·Ó%¬‹I¾ÇNR\ ­vÅ´DnÅyP-ö2$Ö¡‰“Úú^R,}ÃT'Ù Ÿ¥é‚ûO&ÛUü®Ê€•7‡¿°m]k…«Î=‘àn†H”¾Að¨“È>.?û§|m •òØáÛÁ«õÍÄü¯?@¢˜åçž§…IÎáwPKù/0ÀÅPKf“0Rword/settings.xmlEŽKÂ0 D÷œ"ò’²àS‘²ãÀBk RbG±¡Àé +–£73z»ý+EóÄ"#“‡fáÀ õ<Œtóp>æ0¢†™ÐÃöÝl7µ‚ªµ%¦>´“‡»jn­•þŽ)È‚3ReW.)håf'.C.Ü£H¦h—έl #AW/?ÌÉLmÆÒ#iÕiØðQOárTεò ÑÃÚmØþ]º/PKeúÖ"¥ÐPKf“0Rword/fontTable.xml­PANÃ0¼ó Ëwê´„¢¦â„z å[gÓX²×‘×$ô÷¸N+!È¡ ÞìÙ™ÙY®?=6ž*9ŸR i_:Tò}÷rÿ(G ¬'¬äY®WwË¡lÔ]𙓺³jQÊ!y– ×Èø¦1Ÿ½þpHq h!¦ ¸5ËÕ9J—BïŒCÄ›w@™ [Œ'N¶’E!UÞgìñ2 ™žÎDÝ^æ={‹'Hf¿L·G·÷vÒkqk¯§D™¶š<‹ÃüO«W³ÇË[ ¦É®`ã&¡Ÿ}«©dó[—ð=O{º>ΟŠ:?xõPKÁÇÙUPKf“0Rword/document.xml½TÛŽ›0}ïW ¿'†îj•¢%«¶Q«ªê*RÒ0Æ€µ¶Ç²MXúõµƒ½HUÔUûÂ`ÎÌ9gÛ·wR$'f,U l¢„) WM~¿¬6(±Ž¨ŠP¬@³ènûî¶Ï+ dÊ%žAÙ Ô•[Ú2IìJrjÀBíVduÍ)‹Å S Ö9c‹Ö ™òX Fç—¦ÁcÉ.já÷izƒ Äy¿¶åÚNl§?韤˜òúKT{0•6@™µ~RŒº’p5Ódé ž¹B_¢\Ò?‘|nd7‚ £}E9ÛX{qzgÏ—¥/ø-ÑlakÞÆöÕ@§'6I/éVóÐé01íÿhÉwùñÅTvý6W/göw|aÿHškR t-ˆ x‰±À¼ÂúÜm¿³!ø˜<Œ/ŸêÆœ±ú G½Ï“ðî?'·ŒºhgÐ3±bnO6RëæðË#þXgÙ‡°qú¼õï7›«Í”ðƒÿU°Ú…¤«ëcxÓ>Y¶ŒTÌ_HiX8Ð R¸)Á9 Øt.‚Q꾓ÇÑj-=}Å(Ÿ‡6þÞ€›ú¨‰°± ç[ÚqãÛõ×Ú„ s,Œ—Aài«áåþÝþPKØI zðÄPKf“0Rword/styles.xmlÍUmOÛ0þ¾_ù{IAˆ¡j± JÝP7û×ä’Z8¶çs(å×­´)†´}iâç|—çžçì~:(UtޤÑcqx0êÔdRcñãv28yÐ(£q,VHâüìçåˆüJ!Eœ¯i´‹…÷vÇ”.°:05ÇrãJð¼tE¼4.³Î¤HÄåK ‡'q R‹®ÌáñV¡R¦ÎÉýAjÊØä¹L±.Åé‡Ãú­T]2} ‘Ü]e\Ï‚—s©¤_ÕdDT¦£i¡ƒ¹ân™8ã^3“^b•ò–î»k—íª~LŒö-G@©”cq%ç踼ÑÑ :™ -.4í!¿ c13Þ4x”|ùÝ$!œRMÑ%Þƒ†œqøö:Í›îAÅQÑãoà¸CÚÄè¢Ãr7˜\?¥ò¸$³ÍeƼr0…ĸí:ÞÔÂn®Âc)3³LXgT“lÛäõíñ–Ìõ„ñÇýʲì"ð©CÓ,h¶ªÚ$ %v½´pÝãÏIm}¼ŸÑáej”q]PyóÏ-®Å~©!·Ò;Üò£Ak>s ̾é>§4>øOŒ³”¡gwúx‡hgkIÞUíf²Êºñ9òÑÇ Ç0…Ü£ã›îh(^ë<»µÃø6²é{°·±=ºÆ¢RàöÛ¿fêi©§ãÍM7-úl²UtË¡½6µŠý‘XI×U¸0ëymfûñD¬9ðDÿã>ýßÚØ•¤žŽÚÛÌöl­]H}Ãðœeoæ\ Î¶I'`ÃLí5¡ç4Pe­ã?×+V•<ž´ã,„éÅYx~beó›Ð‹/¥·J6eÁ¶kÐwÓ뽦 {£³_PKíÑ-‘†e PKf“0R[Content_Types].xml½T9OÃ0Þû+"¯(qa@%íÀ1B‡0#c¿$†øí–ößóœBUh Æø½ï´œ|ºTm²ç¥Ñ9ÏÆ$ͺ.ÈSyŸ^‘éd”—+ >Á]í Ò„`¯)õ¼Å|f,hœTÆ)ðÓÕÔ2þÆj ãñ%åFÐ! ‘ƒLò[¨Ø¼ ÉÝ׺'ÉÍz/J„YÛJÎŽiœÒ^œƒÖ.´Øs—nœeˆìv|#­?ûZÁêzO@ª˜,ž÷#^-ôCºb±n'$3æÂS¸@Ÿcš8OŸ’0|æŒõ‰³Ã½÷È™ª’c®’AŒ-@¤)Á ÇisãàûâÛ¬}¤â»qbSîÎ4®ÿGÑ´‡ð)ù_7Ù02ï‘l™-T(Z²—ö…yØQšø\þi=ì&ŠI=|aÕÂ_ÜFÇ»‘å´û_N>PKB¿ôS^PKf“0RèÐ#Ù= _rels/.relsPKf“0R™]À#þdocProps/app.xmlPKf“0R ¬çaÛsdocProps/core.xmlPKf“0Rù/0ÀÅword/_rels/document.xml.relsPKf“0ReúÖ"¥Ð"word/settings.xmlPKf“0RÁÇÙUword/fontTable.xmlPKf“0RØI zðÄcword/document.xmlPKf“0RíÑ-‘†e ’ word/styles.xmlPKf“0RB¿ôS^U [Content_Types].xmlPK <é paperwork-2.2.2/paperwork-backend/tests/converter/tests_libreoffice.py000066400000000000000000000021231456262201400263440ustar00rootroot00000000000000import os import unittest import openpaperwork_core class TestLibreOfficePdf(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.converter.libreoffice") self.core.init() self.test_doc = os.path.join( os.path.dirname(os.path.abspath(__file__)), "test.docx" ) def test_convert_pdf(self): (tmp_url, tmp_fd) = self.core.call_success( "fs_mktemp", suffix=".pdf" ) tmp_fd.close() self.core.call_success("fs_unlink", tmp_url, trash=False) self.assertIsNone(self.core.call_success("fs_exists", tmp_url)) self.core.call_success( "convert_file_to_pdf", self.core.call_success("fs_safe", self.test_doc), "application/vnd.openxmlformats-officedocument" ".wordprocessingml.document", tmp_url ) self.assertTrue(self.core.call_success("fs_exists", tmp_url)) self.core.call_success("fs_unlink", tmp_url, trash=False) paperwork-2.2.2/paperwork-backend/tests/docexport/000077500000000000000000000000001456262201400223015ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docexport/__init__.py000066400000000000000000000000001456262201400244000ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docexport/test_img_doc/000077500000000000000000000000001456262201400247415ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docexport/test_img_doc/paper.1.jpg000066400000000000000000000142231456262201400267130ustar00rootroot00000000000000ÿØÿàJFIFvvÿþCreated with GIMPÿÛC       ÿÀ dÈÿÄ ÿÄ> !"1A2 #Q8qu‘³$6B%9Rart´µ¶ÿÚ?ú§JR”¥)JR”¥)JR”¥)QL¥q_–‹%?ŒñÏÏ—#_¢·þ.Œ_¬ì± §ûÊÀ)§Ñ3O¨>®CÜBµJäæ÷+m òÑÆw}%Ë}úà·Ù~©F©ë=@«æM>„0ó ]ïEØûTî_”¹ßá|‰—óW~I -£GQ±ÿ=3’øÈª¨¦©|­’7§ñí1ÙˆnÞMºlÊ ùMnºò ­ï[ ‡eKîã°#`Ÿ[XúJîVZã…t݈¨bÕÊÀš¯Ñ5ƉG¹¶.ƒÜåûÔÖ• Ì7½Á±•Ã|Ú¶ë-ÓÔ4€ƒ™ö(xÓñ¦¡·¡ö!¾ßj— ¡•A5N˜¦c $¹DCí]”¥*·È™‹ä¡‹ñ·Ë¾»õ"BI‡­õž/Aé¨ë¿¡¼½¼}5ØšÞö:ÕY¥a¯K‹å :zíô~¯à‘ޤ}?“Çæð¤e:vÐõß]oC­ý†±8 ~«â‹;'ü'á6A1šô>?¦õ_“©{õï®ÝK½oAö©})JR•©\‘þÝüHÿÕ{ÿõiTŸøŠÿb¬©þÿ-«ùÅ[c`k—>Ã_7Ïêí¡iäo.W†YgMÊ ‚ÔTô¥@âA/„¨£  O¹w$¬Î*Ó ” £ìc¹8Ø w©˜uþuäý™9#È›?%\øˆÖëDaµIfL% ²ÆtwÍãN{žŠ L@‰vª»xÂß 7°]~‚^r3öÑäN&IôÓ¹#\i”ítðÆ]¾€¥0¢} LsƒµF¿ˆ'ö2ÊÿàCþ²uåªþá¸ñÚ÷å·ܘqÇÉÜq–bŽ…ÀHÀ t‹3•ÒÍÀžpK·SÁ¯z™q:;‘Í®8ëtN(Ý/LŒ¥½-1&²± È)휉…v†8ÛúJïÔ®‹ÎN Л—¹ç~ Î=Âïä¼þFS0¨°)ÿ ”»0ãUó+ÎñúÉšÊüª%ÒÎ%YX|’Ù¼Ú±Àtˆ+&»µ_9èv‚!ÙAL_œu_Jq5ä9Y¹HùžßŽ™ê /©lšº×ã÷Ö§ó3Žc+ò—-Ù¿=Úî^`~"íTɤk‡-ÒþR¥éÕc û©‡ìaö®îP§Äì7ŽðV µ¯X«níºTxÊÊõ3Þ€SYÓ´ØeE@YS~û!A.„TˆMBXsWgx›Ë»:ïJuŠÒ+NÂI¹‹˜beŠGi?*ΜíÅ9H)ÊAØƯ~OÙ‘™ØÒ<‰³òUψn´F;Pd–dÂP«,gG|Þ4à籉àè ”Ä(—`:¬ÊøÛŒy‡ù×Çs’7Ž-ÞH‹G׃¥#d USCk«ê[øÔE%ˆhÂm—F â¶ǘ¯ç+:Äø}ïqÙç“”ø£Õ|âåº*®>2%ìr€ý$ kA ö­¶¥)JR¨ì·ƒnË÷’¸72CÈÄ# Œ†âd¬©]/ëÙ}9J™ˆm¢&îrh5®ÃíYŽVâk:qêõÄÖ“ØÖ’÷$Û5ZEElCtÔPÉæÑìQ÷ÕdóÞ9›ÊxöŶû¦-ånKuÜCEžänE•DHS(bÆì}Ä #¯ÀÔg2á;«"c¼qhÂÈE òкí™×Çtª…IFñË‘EÊ•3œÀQ耎¶%¯NTˆå°\*É`ë×|%dÒ)bîèW¦;s€hæ#†‹”LýÀSØ}·¯·.=ak§«z]Ù ìž¼2 Âs*E±38ô šA4›¤cœÚ&9Œ&0ŽÆ½Ü¢Å—mãýíŠmW‘Í%®HÑfÑi›bÈCmC&C˜E±Gû«ŽRƒäŸýœëÞv?LÈwuúp‚ëû(EÛ,š‰û}"S°hw¼¹:ßÉW&pÍ×…»+y\q  ½³³HÆlÛE æ9ÕYA:¦úÎ!  U‹—ñÄ~`Å·V.•|»&·LK˜µ * J(°‰D@t?}jµ¶îÀœàȘ‚â·vdÅí!\À8ˆhö âŸîÆM$ݨ©Î“dŽ~€°¢‘Íã:ˆ€†Æa *Wá{θh¼•«kÅBÕ äf¿²+ûüÄ×, =玥ÜIÆ|yšÎ#ÝÃE[,ŠÀ‰Ê¡@J ¢"~Þû -Ùƒ²ÎqÃÐ,sÓmÚÙ^Ø™ ‚zÉ#•G>Dçç*n„X†HâES8€±€5ì5ûnÀsµy¶Í¯,‘†ZÁ7r¬æÛ‘<ƒ¶å0 ËÕg>Nb‹°w½µYì©Ë`¸U’Á×®0øJɤRÅÝЯLvçÑÌG (˜ û€¦'°ûo_l~ãÌõ­’\e ¹ŒåÏ–Ôú±,L̓p…jT›$sœÚËîsLa÷Æq«ò›–ß÷/Æ–´ q1O¢Ù¿k<©Ñ&‡˜ŠíÀž2›°”w¾ºüÖÃR”¥)JR”¥)JR”¥)JR”¥)JÓÌOš-ÌÀé¬ÍjÙO#­™I÷‡›Lë. Î¸IMºM± R‰Îc”<"%.Š"a8çîl\6‹6y êãE퉬Ù3^Žß2!EÂ¥M'JÇy=JmǹMØàSD6@¦»îîgÏÙ‰#~ÌqÆòKT ­òwÌ‹ãAeJšo;¸¹ÃÜ ÜÀSt==õWTÈwu‘ÁÍ…ˆ§²$Œ‰ÌTÚE;hÕ4HíäYw*„(ì5ØD†b~GÎÝ×éq6ZÃØÂós¤Ä{'ÏÛH³’j‘ÊE…»¶Æ銉‰ˆ`)€ ëÅ‘yC9’äqÂÓYRè·[¶wq¤ÆYœkX„Ü™*áÉ€¢±Èr¤±.‡aøôaR6ÍRòÅ_§²öÄ•æY)UŠPxäÊš™2S)LåY5NE ©D5ªÇÝ\¤¼]sv¦ãÝÅ•>W}ðÙ¹FÓ b£›<.…VÉ,èà+¬˜ÊB覢m€êÀ™¦5@É?i/nÌÛòJÃÏ@ˤTÞF= ™úˆ”å1C‘B”å0à3y?&Y¸v™ÉYX‘°0MýCµÄ;¶)P÷1Îc¥({‰ŒùªŽÎä~n¹æ"ÜHpÒû†´¦lDfME™ÛtÖ0™Äx-æH…Œ&0éØh}{•KâÜß ƒ£q<åá/qÛKMÅ’Ê`ºîHäôÆ" T’LU2ê,R”ê1ŒP)¯˜v°¶›î9ÜrÄڤČœ`èì#’XɦñÛþålŠj 0ö(õ0†ò.Zô½TÅYSNãçáƒ0Ö2Aãwíd”àš‡jñ±…5E3€rSQÖ‡uæ¿s¦r€¹^ÅX\C»nèˆçŠÒãpEÇr”>¥"²ÞUC~Á²“¶‡^ÚÞ çWy7ˆnOÄ8úB}óˆ¹×–ü‹Ä¢žG*˜»â.e{ª6Ò§ûøôQú€j'ÀÌ‘žf±N:´o.8…±cÇÙáxàÉçÄJ›tJ½ e‘òDÿPMuq©¹mÝ®—Á\^»2-–ÕÒÍs#3ƒÀHÂUb‹…GD”Å ÔD¢!¡ª|¨ÄÅãë®IHÈ=µ£ÛªgÈ=l)>jé5E²Qƒ€\<]7î}ht;­oåG&r 2BYSŒ—†>€¸í÷ !¦H²~C.¹: ›´œVf'0@NQ(@ bî·bÎÿ„a?Ã[¤ZÌR”¯œ’_÷HäýõÃÿé—­”çZi‡ òz`Bô-²=K¯`Ñ“×ùj»9”šeáKL¤(¶bÀRëØ4j œ“É3—NƳ9½Î±.xgÎ¥î¶Â‚ ,íPð1+Ç2M{Š(&Ù¼`!T]’ž=…çþc‹¹9‘sW(ÝIIÈÜW1g#ÚŸáFP³pšeH²ê†0€z}õØn÷ÆÙW`>Hg[?5]q6b÷dë+®Nyê,šJ°QŠ( YSDȨÊb€‡`ÖÃzüãžGµ²Ÿ5óeÓdös òµ´Õ¬¡SBT;°3”öU.Ý“é7ˆt"×Ìwñ•¿wdK 9s;0á+®:î•~X†ù ~&Eƒ§'Y³öeU1"€©Mõèânå6À>Õ¶œ<ÇøNÑF÷ÙòäËJOI5øìÔÕŒҀé¤ 9I"‡ÄdÀvcˆHÀ®þuÀÏÌqýÄ¥½o¼ž=¯? r¼Šf@:ïY2|’î!÷›ÆC¯ç®ƒÞ¤vß0¸¹v¡x ódºs<«vì#Ë0¯QeÌR¦µíæ)ÄÇ)z‰@@~õ –L‡þ#¶éŽP&’1Dñ–Á¿òÿ:¥ù5dÛŒ9˜k—.gL—ˆ-;ÆÐdÆèµ®B±UûE–2¬¸17ETÀÝJ?ÌЈûTÓø»(çhK®Ëæµó˜¯8Ùc1µ¸‘nÕbޤ’ì˜oÄ>Ç( ŠMï@]ü÷jå¹+öC‘ó»q ¬ Õ)…o\¬í¥#ضXHÜz¨‘œ:2‰”ªù "òhÛU–àzn¦¸«ÈxH©Ž`~^,cUŸîiUÈv-Ä‚ë¹Japs(&S±J>CŸ`íVDzŽ0ÈœW°ñm›”­w·zñ›-eÐRAš©²"* Êo)Šˆ”Cú…jŸì&ÓÇÚy[ž¹·Þ–°"vÎw”Â#å Z·U= s©ÓÀ%8{ïumßXγøLöO^w&[·¡¯ÆwÔ“ç2ɼ”Òh«"X„L«ëÄ¢‚>âcǰf9¯Ë.>^œF¾aì‰zË\‚“HˆW‰¼x‰L%1œ.N‚h”C™@(¦¾â[…gÂ0Ÿá­¿Ò-f)JTlØ×ÑqÏ`Û†µÝ™C8„¤‚ÆQQUA;~¾3 •8ì¾æ0ûûÖNvÜ·®˜GVÕÍ/ù/¨÷íHá²éÿà:G)‹ìÂû3o@\pŽ­›†>Rê"ÙÌ{ÖÄ]²èˆhS:G)‹¯ùD5]3Ö©uC ¹sÛ3&(°~É' Ä4ã9DºÿʼM±¶:föI¥ƒn îØƒpœRR, pl`.Ðò§é®À°ª³eË®%Z7¶8¹beû}4RY"LÜ1tÑçsvMËeRA3Šp6û½€Gq.F·®»ß2f$¡X]W¿ dÞ aY”K­š‘Q!<‡*©Î`(Ì_`«nè°ì{á$½lÈ+$ H’‘È»*fØ ABއÒ²1Pñ0L‰ Ò=¢_±»T ’eþ┽•c±Ôdú·\mƒn4›\v¬’H&èãïû•)@ã÷¸þk"kbÛ=Æâ{z0Óé24jr¢Ñ1xF†8(dmw„å)„›ê&l+º^àV&z%œ“ÃJ¶xHáý C€€ÿÔ+ÁlX¶M’ÜZY–t Qqèµ ‡÷&P é‘ÇXú^áBî–±-ç³­Cªn"ÐQÚAý ±Š'/Ø>Ãø¯e¿iZ¶˜H…«lÄÃÄ‚ÒÒ?d›Xù]y\­Ðȱú—²†Ù ØŽ«‹q”Ô½õ Ž­ˆû•ÊFAy–± Ò|ªFË”€¡Š""m€WmÇñÝâõ¼Ýa[“nÚÛ¯%ƒ•êC(QÿÒ³­Y3bÔŒ™4E»t‹Ðˆ¤˜…/ô‡°FI‰1JmåÙ§Œ­2¡p¦d¥ÒVÀI÷ÀtÒÀ?>ÀjRŠ(·DÛ¤D’H B…”¥Ð{~+)J­xë™_qDvOùsà^½ì“?Cë=WOHõv½¼ ¾Þúêí­Ž¶6U)T‡%ùyaV4=Ĩ— ù,¼SϘˆÑÒneÄÞeS9?i ìa/Ûî#í^lI—ùMx^­ ò§?OmõQTëNþ ÇKxT)DHOLæìm`: ìjcˆsê¬ÎE‰ùwá ]Î-_'«óúßvëyõо=ú޽6mußaÞ‚Ç¥)UÇ"³èº³Ë¿ùe¡|;Õú_QÙR'×ËÐý?~÷Ð~Ú« |È&·]yÖ÷­…vR”¥)JR”¯Ÿ<1âf;Í\~kså¹[žp£?:X6-®'±íaRNQȤ“US)•2ÞUEEÆúÊ_ÚB…X8bÔÎürÌœ^Éש÷]Ë/bGÜVݸA¤¼{¥Ô6á!U-ß² "";Nò:îŸàô|ƒl±tªLd›A0Dn£¬f._V¼f"î=»h„߸VÏc c«o[©‰cm¨Æñ÷÷1R ¹¿©Œ &üˆkg9ÿQÿRxñúEòßÍÿ8H|/æO?Ã|Ÿ [·ŸÓÿ7¯NúëïÛ¯ãugaoöÔù­ÇûDþ‰üµèôÿ%ü[×zß"};ú¿åøºyw¯«·M{n©[W$Jb kÌŒ™‚JÉ[—ôÓæET½“õ‹cãä q(ˆ~@¨6‡Æ³VÚÇÆ^qÊdÇ <†¾ÛÄHɨ^»tÈô‘ 8쉂]:CB~Þî3žQâÆŸÈvŽB ÄÊP0­>éšh.™„(¦¿Q\¨ªtRÑÌC} >ÁS+Añ*ñ|ÓËÝps¨G(Y JvRiJ”L}I£¤ÏÛØå‚Ä.ƒ¹‹Ûꨎ%–÷1‚îÌœ‚—¸'Ú©vÊD[VûI×Ѭ!XGº;t„j²}ÜÉ™C¨a€j¤<Ò°áñŸðþÉ]¾ö]Ôs°ôæ•’Yû‚ï’?A]sC½º” aÑ@¡ö¨—"8«lcì rçØkæùý]´ <à¥ÊðË,é¹AcZŠž”¨H%ð• t ­Ì¶d•™¶â¦(GÌPrp°é”ïó¬•)JR”¥)Ze†øáÍ?ãÿ”1¶VÆ.I%*þEë+‚5ó´£ »¥Nbº&DÆHR1’U1WÊ q)ƒWßpklµÖŸR៙”wpÜ“ª·" JË:?w2{@¥)}ôR6?z×» ±¸¿ˆEó58wvM‘àºÝÆ  ›Þr,Á¡Ì(hçhù QêuÀt5ºÕQfLCrä<Ÿ‡¯XWш±Ç× ¹i4Ý*¡UYXªJˆ†º€"†·î#íVíQVÎÚ/9ZÙ(c¤ rÝÕ#(D.§rÇ:bݰ‘A1 Ñ`N?@˜e6ý‚'lâîscH¨ì{ef,YpÚу62×TæÓjO¥+éÜÎRh¢ õu؆Äjл­îFü•o£`d«8·kõ0âjÝTñò‡ĉ"¹Tl` þáßÞ¡8ß gI|Åœ¹yYN%í˜w°ðñ6lk–íWgLVUeœ¨e$P)4½bO€ùˆnËžK‹ùÈJÙ¼fžyn^ѯ¥ùqÛ¥Y¬ÙRœ¡¾¿ ƒ¨zØÔ‡5á|Á˜¸táË‚ï¶$/»˜¢i$Ù­Sz¢ªRWT¥*evú„ è&ÙïÍå< {bÛ}Óò·%ºî!¢Ïr7"Ê¢$)”1 cv>â×àjglF/ mDÃ::gYƒ¨dÄD¢b&Rˆ€ˆëaí° ÉÒ”¥)JR”¬EßiÛ÷í©3d]‘þº}‚ñ’-|§KÎÙb jºbS—e0†Ê !¿a¬&*ØÃÛ&â{.:Úˆ…ÂÚv²ÂR”TPæ:‡êR‡c˜GEÞ€*eJR”¥)JR”¥)JR”¥)JR”¥)JR”¥)JR”¯ÿÙpaperwork-2.2.2/paperwork-backend/tests/docexport/test_pdf_doc/000077500000000000000000000000001456262201400247365ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docexport/test_pdf_doc/doc.pdf000066400000000000000000000230121456262201400261740ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xœmŽË Â0E÷ùŠY 3Ió‚2`k»pW¸w>v‚ÝøûæbQ3“››¹%ÁK<%*&©œß’ô–`¹ŠãÕ‘Îr}ÆJÎi|€xíD@ âíÔ!±êP¡Î­å&U³¾X¦Ü\Ö|žëƒãÆd=°ípW¤ž›bê‚}q”/#ŸãAŒQÌÉ,Jú%›¸Õa]Vã>DhH‘Nµâ )nH&ê;z†7NÃD endstream endobj 3 0 obj 181 endobj 5 0 obj <> stream xœåzkxU–à=UzX–l=,•$+’JQœÄñCŽIœ—+~ȱ۴B,Ù’`[B’ÂcãéæÕiÒÀÐ<²Kš… Ý]Ê$ô„^¶cXèž^–f€–fHMÏ4_“!ͤóõ–÷Ô­’b›G;ßþÛ’«êÜóºçžsî½çJΤ¦âÄ@¦ K„¡‰h²oÛ¦ZBÈÿ",C2ü¶.Û„ÏÂüíprdâ‘¿Þw‰ÕB´gFÆ ?ÞòGˆa”ë­£ñhìYûB !ü¨cÃ("öei ñ­ÀöªÑ‰ÌMµ:±-`»<1ý]Ãßb¾‡°]=½)éSu2Øþló“щøÊ&M¶Gˆþ@2‘ÎÄȪBª"=™Š'w=2ø2¶§ a!ð#]5R›aUj¶@W¨7MfK‰ÕFþ?ºÔG‰t¨·#IÒç’‹=EœäaB>’ZWžÙ] Ÿþ¿´¢@~=DN’3ä(y‡\§‚$DÆÈb_/7+]!²—üÌ|…ÚSä,Òe¾¹WÉ—^!ò=ršü|I/!2AnA[ž%ïÀzò L•ù È_—Që'ˆ»úËT1Åø¦àð"ì»äQ湊‘òþa‰Ây‰‡ý¨9ƒã<šñÖ/(½‹Ü†Ï2J L/õ¶Ïÿ7Ñ-ü+Žê6rù&ÙAÆI<±…¿^òúôŠ äˆÚözæÇ 3?6¾KFðŽŽ9Êîø ý__l)‚r¶Œè¾ŒÊÔcöS¦vỊ’¾…‹9ÜB翲Ñì¤j@µB½MõÊ×õ¡ù®j¥ÉÂo³·dcêÝê“­§Ú¯ÝîïëíÙÓêÚ}õ®Î«vv´ÛZ[šwMÛ·mݲ¹qÓÆ ëkÕU•k׬.[å_éó:¬f“±¸H_¨+ÐjÔ*–RÉ‹iÙ2ÞŒúÛüÑŽªJ¾Í1ÚZUÙæFD>Ê‹øR­öwtP”?*ò^\¯è"tDsx§ s yN0ñ[ÉV© ?/¾ÚêçÏÂÞî~„¶úüxÂWSXµš6аáó¡µJ²–oƒFgÚ"h#Ìê [ü-ñªJ2[¨GP¸ÖŸœ…µÛÌڶͳ )(’ºÅ‘¶Ecb¨»¿­Õåó…«*wŠÅþVJ"-T¥¨iµT%?&™NŽð³•s3÷œ5‘ÁH…!æE÷õ‹legض™™»Ds…XîoËoþÀ#‹•þÖ6±BÒÚ¹'ßOç•.AT—™üüÌ Çᣥ˜¨‚Ñ”™þH$PdZDØÓï“.W}=3ôóÁ™ÈLôìÂô Ÿ7ùgf †™dº›„úQÅÙ…Ÿq‰Á{¢)2 ›ÃÊЃ{:Å’îkûE¦,ÈFƒM~ß&—Ïœç }™ [Ð9èaŸOrѳĆ8ÝÝ/·y2èz†аÈD$Ê\Žbë“(Ó9J^<âÇØvöôψª²1züHTœÄìº^ Œß$_vùü33ßS^­ÚãEõjtJ-À¼‘DfL´Q|Y~]pa«Í¾Ñj$=mþ¶ˆòw`Ô xttG…œ½ý¢ÐŠ€U"Ö6[@‰h6ÖJƒ)üIÑêoÎGW2«m¬§ŸŠ(b¢µE$‘!EJ ´ÑyÅ·ÍDZe$]þîþçHÝÂùÙzÞuºŽÔ“p«Ä̵`–­n›é ‹Þˆ+†ón˜ïwùD!Œûûãa)íÐCåç]49Â4Wzû;{üÝ{û7)†ÈIª¬m™¿KVƒ (”ðýŒ‹ #£ |óV|ŠÚ²¼MèpŠ•·y+ß.’ãF3Är¾-ÞªðIí%JÕR:µtä´i¤&êiépùÂ>ùªªdÌ+£DäÔŽ —)$`~¶tP”äK‡”ô|¿?îûGyQõKc“ÜC½¬8ƒú\‰Uï’Ö"g¡›ˆɹ†äL1XáZì\±¶óÍŽeä92?Sàï왑”û…-ß))……Mf] ¤ íǵ—7ᔦzfV¤É<ºYRâß›ñ÷ôo¥Ü¸žÜæºYêËB:¡³·¹ª—¶æY?ÜÝ=+ÀÝ={ûŸ3a]xwoÿ3 0-‘æðì*¤õ?Çã¦A±Œ„•Rƒ—’¦=Ø( ü®çB¦)UE´=tÅäp@†Î22Î$w´šv$)*™"ä¸Uˆ+qÓG¯Y"¹L(T ‚N00EŒk$Ô3ˆù Ö±: § P®Y”ÚCÑgazV'¸dŽiäd ïî»ÒußÞþÓÜ]ô‰5K¦‹cƒÛJ“åÖðèL$,M6ÂahðDðoÇ0ù·£!ƒXè7‹z³„o’ðM2^#ᵘ¢ÀŠOcìC"Hpm¿§$_ú ׌é‚©0.*3¦ßV¡ÇÊðÜðÖ VØ*¼gaôLkã ¤tlAÎÌêØHXÇZ „‰¥‰#ç98ÇÁ½æ`€DòÃE^ãà¥%9èâÀK 2^äà1JJP1ƒÊ@8xŸR§)¾†b¶,Ð~d±{)¡‹Ò.R¼˜ëCà©ÌEªhŽv3M©hZ ×ÇuùëÆÜ•R®ýËð_ H4ÒTa&uú4×9û¯«3[ÀÞh®[_ãkØhö¯4‚ßì3û×TC˜í6ØòVÝüu®ÕñV—çÞ´þ­—ê{Ö7`Köå7´úÏnp5H+Vn¿Å3›üD8D¬VgQq±Î©óxÝ¥¡°›X±aw†Â»­„aÔjóž°Út ç½0瓈±qÌ I/D¼ò‚à…/ð^ðR2’¦sT$½N%E/œX„_ìœTj‰”±ã¨›ê$ ŽºÁ8vù³¾¬ÚíPWËÙpà’7êý+µ ¸¦ÁAmÇ_7Ý|k*{Ãm'÷ëp6vð¨e/V—oýÎ]ó:«ªœÌþSîù R3Ž*œ8XŸZÔ»ˆOKÿQ&ƒÆl¶s¬®'LX0±¬M°YBa›Ñ`6šCa£Íj•/Ùᘘ¤"vÙA°ÃœD;œ MÞ&;;\¤d]̹4G$ P/äÃOJ¦_bð©ÌuÊà5þ•«ê7 Ø+ƒ¾E¨ª„Ê*¡ðûYç‰; Bõ¾Ü>Û,“åÒì]øˆù;öe²–„…zŸÖZZ„)Q¾®ÈÇÚížPØe7±úPXËrÓë ¹"ë ´øuðô:X]ë g/Áð# ÁØÈBó®i¨³suµ õ¨f¨¹v›ÍjÿJÍÊÙ=,ów³ÿ%øƒšªõ7½øp8¾¯öÇF ¬kHu÷]½ûþ½M~(¸ç˜ÛòÏßj=ys½Û×:¼õ^ï«PkãîÒÚê–k¤céXøˆ½‘}¸pu™šÌee*Þ`pªX,ûW®ì;lfó Œ˜Ùkf ¬ÙL 9­ Çh#¶P˜˜¦×ÀÀÖ×aÐùÄAï:Kc@v>i¤9)Ï@³2J%ÿÖà`ÍõÛ¡ êWÓyÙ°´Å`³ÖÕnØo<òÝ©l¶$5û‡':Ú~U¬gå¦Ç|ëÎ{[‡jÙþÃ7çïpVíOcÿ-;XÕýÑ}©WýYJ½Rô:èœÅ˜U©þ‚p¤]XSX\¬-aY»CeÐBaVoÄ9mîî1ˆhr@À!…)•K£º:ÅúFKcm­”CjL ³¿¡ êlu6¿ÙŠqÚh+ظå¶xÓßÿý–šÍ=þÛ­©æþª5o½Õ;xG³i‡ÃK}BŸ1‡ld9*ìuK lF›Ûã$èh§×‰Žv:   [LuwØÀÍy@ôÀ óÀ´’ˆx äâíøòãÁÑ|?»û­ùW;ŸÂGÿö!+>ùù;¹”mv5ànòŸJ²S¿|[òÉÂçê)ô‰ŽØÉ.! ¶’"k‘Ãi· „íªHØÎš¬a“66Yˆš'ðN8ï„NH:邦£¥4”W,DûLÄç7c2Z€'fl”ù©‘ª'²odÿùÌMO^þpþO†áì_e]yêÔ)æ)pÂÊÏn)€•ìËÙg³g²bö¤J¶–îwRüÊÑV;¹$œä,«@£±êY§ÃL"ásÂÌT™ÅîÌŒNm6kt:FV;€¥hTš°ÊrÆ O8á'L;!ㄘTN¸è„œð&Å#2â„^'´:áu'¼ä„¼Èí9¤¢'j¨3¬TCã%ªBæÃöœÑ 7,Ïú%ƒ²Y.4N†ëè|°/Þ)¯k)ú¾uÁSïÏ¿ðØ)ö_šùä›ïÂï¶m^fïüå|¤Ï½S<ÿƉlìqôaN„ª'.Ø üƒ…ãX—Ë^R¨r¯à\NW(ì´k‰5fKŒÚâPX¯—Tn¸ä†ÿæ†ÛÝqCÌ nÃnxÓ /¹áŒ Hî\$ó#Š¿–ÊX)þ•uõº¡5‡ßü{ªè 7[ÔU½VQâæ¢λáu7œpô’nÜÀ»Áä‘6M”oIQ6ZV•|I–l¹Ý0_¶É Q(Á4^²ºAZvih~ýøãOþåÕÍë«VÖ4Õúé+YÕ¶ýšæ×Ï—¼z‹-ùÈñÞÏ/ûªª|‡rŒƒ k7y\Hªõ…: ®ÿ„¨Y5:ßö¦^ÒÃ=<¡‡ôp»2zˆéa•¬zPé1Ý(Ç1=–+zˆè!¤Aszõp‚6Mz z¸H›È·˜m‰”ReIŠ^©YqB¯¯)»Rš$¤Šäƒùz È] ¿Cä-¬·‚žh4†"V÷èµl iRjÔ°¨ÐCmõõmÁººà¾õëë‚AÔÁ,üZûmzžèx£µPmUs6¦ °¨ƒ1ŠŠ¬ÆBµV=6kÙb½þ쟄—¤g¨Jb\Ãdžƒ9x—ƒŸqp’ƒ9¦¤ 8XMÆ.sðO¼ÍÁs|“©ÚGpð&?âàQŽp ²—6ê9XÅ•2¼ÄÁž ò˜®Üñ⋵3Fa`ùqƒ¾°Ž(•[TÔå l<`Ôê/Äj¿ü€±³iuP§“!õþ†ìÙG²­S yë±*Ø5oÀóS^öøç1uQiCCéç]ìãŸïgg%XÉÙ‡°V°’n¡Ê¬Õ‚Á`ã4fºÜ«Í,c5™ŠBa“Qk(Är¦Ð6@‰^ºqÑ'M­º:\â̹2FÞíýkVjUþv<0Ul®ýví÷³Í‚E·õÕ­¸1Lº¸ùæ\ ð,ôk´mîì·‘’‡Þ`Ð:´nÏ <­0–`ƒs MœÍ‚œ¬iO˜5=á<ð’°ÐPy x ã˜z=Ðêz¬ò€‹’±âa×;Xå¼î|)”Ç/ŽÞÀ¿ëD´ô<´zé¨õêÿºY>u÷íÅÑõ7Þ6RÙ˜?õ÷ (ç!zN`¤_Øgp­ÑãIqZè¶hµnbwÛ=ÞR](\Êip'µ²Ýa«ÉˆQ3î¤Ãá1zL<Ÿ;õɧAù(8—ƒyïâå–3Wv+ýBÝâ—•Á)ÍV­´(جŒtÎ`²ÓwnÉ”öNÍÜ:äÛÐÄš{õ×o]óÚn¸xöŒÍ0o7ýƒªÚQ•7ÛýáGóÙ[í¥ñwfƒìŸØSdüFX0J‡ÇÉX HeÑ»%fC1ŽÍVl$Úî0KV`‡=p †ÔŸÐ4xÓ?óÀ=ðmšrAÛìZš˜!Œ^öÀÛxÑÏx³ç>ÜN¹‡iÂ)÷JXhÂ\òÀ?Q~̰38™ãOy`Ð{r ¶Ú\Ž?oÇ™¥ú—ñËÖlºL¹óÖ<Ó.|c±=«¨=Rm޵øyš´²Aä´ÇèXeí—(#§u>Ý»<`ôä+Vi…Z²8-Þb¿Xì,e^ú5ÁWG¤©6¿Ó“¨ô­É•5­d¥r"ÝåÍ%¿ ˜ùùî]Ÿwc}ÿÎÙG"pæìåûaÿ`ö»;"™lÐòJľõÀClç‡k>ÁÜoÛç×>yì*y©ÀóÙ'Ò>DDá&«A£ál…–HØXì-f ÙââÂ5Ψ0ÃÊßcå¿«Z ÀÓ¹ïªç–ø÷!”sëÇt£HЯ™äMãàé×Rô+§¼›–}Å´¤\¬ËŸšpÅ™E=`¶JÇ%É=Òé©9ŨÚóW#Ó]Íž’àº{TÿBWöïüÅ”çÒ{éOåqïÆ5b7®Ÿ‰[Íj=§æìŽc(l(0qVÖŠ³†#Ø.8 Æ¼L¸è€×pÂÓ@üÓp,µ=oéâ © äÍ´„’êX„陕ݽþÔÞìÆß¹ëÄÆŠžLöÒþÑ}ã«Ê῟÷f?=ÈŽ¾ù¬Ðÿ À5íÀÊÌÆ­d¼òïÑÓúú/¯üÚ˜ b5ñ8ÉÿXMÇH´¾lùÆbÌ’‹Ó4â ã7¤LEˆ•i$¬›ô2Òï£GI¶­ø©Òd‹úçd‹ôf~Hš_ŽÍDù¡DòPjld4ï*çkkÖ×ðí‰ÄÈxœoI¤’‰T43–˜¬.lYÎVËïAÑL%¿sr¨zר`\æå{⩱á=ñ‘©ñhjGz(>‹§ø*~9Çòö5ñTZjÔV×ÔT7\¡.gKóQ>“ŠÆâÑÔ |bx©!|*>2–ÎÄSˆ›äûª{ªùP4ŸÌðÑÉß›ìŠSäP<•‰"s"3Ц^?•KÇÆ†¤ÞÒÕù,rGO&~ Î_ÍdâéÄds4}¡e½c“‰t%ptlh”?Mó±xzld‰ƒ‡ø¥2- Y‘æ3£ÑŒ4è‰x&56?„1›H¢Ô éàXf;žˆ§ùÝñƒüžÄDtò‡Õ²)è›at*?6‘L%P«ÒC©x|;‹Æ¢ƒcãcÔ6ME‡Ðcè¶±¡4õ:‚OF'«Ú¦R‰d-ýFû®+Œh ìÍtbüö,qOÆã1©G4û@|…°ãñDâi<ÉËŒV-²|81™AÑÅpàè­ÄÐÔ„'ts&g\t(•@Zr<šA-éêÑL&¹98xð`uT ÍF¦5¾Ž–9”Œ+ñHIZ&Æwaø'¥ÐMÑøJƒèÙ¹‹ïJ¢‚h¯0Tò¹Ô\_½^éÝ8–̤«ÓcãÕ‰ÔH +¸‹´’12‚wï›IœÄwÛQ„†H‚$É!’¢\£ˆåÉZÄ–ã»–Ôõxó¤¹HGyž´ œB)é¥zd’T“BJùzmµíQ¬è Ò•íDù!Ô° 呺X/Oz(f ×YIr„L¡QÄì i”Š#OŒrð¤ ï?§ãÏѯ¡P:O©E»jðSM¾TöÏiC]<õu†R$['¨ý7 .r_çùâ4~i¤Äi+FµJºû£‡r…¨¤ä‹ ím’rõ~I]Øã0ÊÑXæ8‡¨n)'dÍ „G¯^OQ bT.7¶4öüÅ|yvôPëÐ>¯¦x©¦´fl§•qÉ>ë¥V$+ùâ Z"õ;Já(õgŒJKY6©HbÞñ_Û¯ÈF•¸LÒ>(VJ2•Š¿‡é3MûÄ>xjŸå¥}óÔOQêu9ÒHÍPÞ!Äãç2Ï&Ð+r_ƒÊL:Hçå¨2â ª—ÇJ&Ž)+4n“¾•4ÆW¼"çͰ’©<•M"œ £Èù±ŠÆFIœZ*AQ:÷Qbœö-Û6J³#JcWb¡#Èù+¦ŒT²:I1U¤æ…4ããŠO¿+Å®/Õ({pqnJ1§ö¦éž¤ÖÆòc”½-q+=É#§+Ò ùø Ó|“=£Úª¾ÂçÃÔ7¥×µ(†9ârn%PvŠÆCžOr6g¾à¹(õoB‘KÒu)£Ø2AçÇ(ÍÀ$ÙŒµe­“>Õ4Ïš!eÎT+6þÝr’]IêÁÅó#•·emÜ¥ÌþÉü¬›Z4s‘èÁ5h]/’JþÏñË4H³fùª¹û[¿lr6Ža;CíIS_VÓ1Œ ½ {ØEëhz-øÐ¦/¹fu¡ƒ'£0BJˆ"d7 >ØA¶€oiÍønÁ¶ô®†mdù¶!~;¶·"~ .ž^|6áÝ…÷½x«ð–9j#€ï€Ò®Âv%J¼†O ·„mB¬ô¾ ÛønWÞAÄ·á»MiïÄ6¾I´ÒôyTÂi8?¯Í?‡?ƒÐg0ýɱO˜?\,÷>}ñÜE¦ëãŸþ˜­ùŒC¹`ºº¹¼pâ‚¦ÐøÈïÁü›ó›¼ïo{¯ï·ýª¼‡#{¯æ½Ð{Óï‰ï©ß¶ïW,ç5Íñs5sɹé¹×çÎÏ]œ+˜þ鱟2ÿýù€×ø¼÷yÆ{ºëôáÓlä)0>å}Š =y”9vŒÇ½ÇÇÙG®ö>Üîñ~ïÁ5Þó^|9»0wúÁ"sðyè‚]dúp÷ivÁûô\Ã2âÓ‹wï.¼xß‹7ž{Ý‹wv ›Ø¿ý}®û*î»å¾#÷©“wNßyìNvúŽcw0O8w€I‡Ê½‰É ïdû:¯³Îѧ­cû4Ø ö.ì,[Œ Þdºvowo{¹·¤ÎÒ§Æ«ÑÈzÙ&¶‹M°÷²çXmÁžÇÛ÷ùÐÅ#„t† ±ËÛèbÏ.œâ>ÔvUòªé«ØÁroGû&¯±ÝÛh­ýýöÛ5íðþŸž ²B°<‚_pE‡««³õ™ÁØgª3ö1€®#}ã‚‘1Œ‡¬‘4fš5œ…c³½=gµ {:łе"Ü-–õHO¡{¯¨¹[$}{¯íŸøNøŽ£GI³»S¬íé#îp§C@€iLîYŽ4‡ÓéL½ ¢á)|’Š© DîOËX’§“Š4¤qJS!¨ä6à³B¢!B’”ÞŸ&ÒC"VÈB’tZQG…åûÿ¶g– endstream endobj 6 0 obj 7404 endobj 7 0 obj <> endobj 8 0 obj <> stream xœ]’Mnƒ0…÷œÂËt DBH)I$ýQiö"c²àöõÌÐVêëûÍøé™°¬Î•éçðÕª†Yt½Ñ¦ñîˆn½ d,t¯æµ¢U Bß[/Ó Ceº1σðÍŸM³[Äæ¤Ç‚ðÅip½¹‰ÍGYûº¾[û˜YDAQ ŸóÔØçf€º¶•öÇý¼l}ËŸà}± bª%[Q£†É6 \cnäQTˆüz-0úßY¼¶´úlœ—J/¢}RxމÓòŽùˆœg;ä=q!§¬‘ÈkhÎ÷÷ÈGžOúqBšGæ¹d=ñ™¹D¾ð]ä+ÏÉ<ˈÙŠ¹ú§}öŸ¡Éþ“2ûOwΚÆ„ïø¿Pwç|ôôØ”9¦Ýøýìh±‹¾oˆ’œ; endstream endobj 9 0 obj <> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer /CreationDate(D:20190902205629+02'00')>> endobj xref 0 14 0000000000 65535 f 0000008715 00000 n 0000000019 00000 n 0000000271 00000 n 0000008884 00000 n 0000000291 00000 n 0000007780 00000 n 0000007801 00000 n 0000007996 00000 n 0000008384 00000 n 0000008628 00000 n 0000008660 00000 n 0000008983 00000 n 0000009080 00000 n trailer < ] /DocChecksum /72B44A81E5EEF3D98178B73CE31BA672 >> startxref 9255 %%EOF paperwork-2.2.2/paperwork-backend/tests/docexport/tests_export.py000066400000000000000000000162401456262201400254210ustar00rootroot00000000000000import os import unittest import openpaperwork_core import openpaperwork_core.promise import paperwork_backend.docexport class TestAutomaticDocExport(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_gtk.fs.gio") self.core.load("openpaperwork_core.fs.memory") self.core.load("paperwork_backend.docexport.automatic") self.core.init() self.test_doc_pdf_url = self.core.call_success( "fs_safe", "{}/test_pdf_doc".format(os.path.dirname(os.path.abspath(__file__))), ) def test_automatic_pdf_to_pdf(self): pipeline = [ self.core.call_success("export_get_pipe_by_name", "automatic_pdf"), ] result = None def origin(): return paperwork_backend.docexport.ExportData.build_doc( "some_doc_id", self.test_doc_pdf_url ) def set_result(r): nonlocal result result = r promise = openpaperwork_core.promise.Promise(self.core, origin) for pipe in pipeline: promise = promise.then(pipe.get_promise(result='preview')) promise = promise.then(set_result) promise = promise.then(self.core.call_all, "mainloop_quit_graceful") promise = promise.schedule() self.core.call_one("mainloop") self.assertEqual(len(result), 1) self.assertTrue(result[0].startswith("file://")) self.core.call_success("fs_unlink", result[0], trash=False) (tmp_file, fd) = self.core.call_success( "fs_mktemp", prefix="paperwork-test-", suffix=".pdf", on_disk=True, ) fd.close() promise = openpaperwork_core.promise.Promise(self.core, origin) for pipe in pipeline: promise = promise.then( pipe.get_promise(result='final', target_file_url=tmp_file) ) promise = promise.then(set_result) promise = promise.then(self.core.call_all, "mainloop_quit_graceful") promise.schedule() self.core.call_one("mainloop") self.assertEqual(len(result), 1) self.assertEqual(tmp_file, result[0]) self.assertTrue(self.core.call_success("fs_getsize", result[0]) > 0) self.core.call_success("fs_unlink", result[0], trash=False) class TestPageExport(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_gtk.fs.gio") self.core.load("openpaperwork_core.fs.memory") self.core.load("paperwork_backend.docexport.img") self.core.load("paperwork_backend.docexport.pdf") self.core.load("paperwork_backend.docexport.pillowfight") self.core.init() self.test_doc_pdf_url = self.core.call_success( "fs_safe", "{}/test_pdf_doc".format( os.path.dirname(os.path.abspath(__file__)) ) ) self.test_doc_img_url = self.core.call_success( "fs_safe", "{}/test_img_doc".format( os.path.dirname(os.path.abspath(__file__)) ) ) def test_pdf_to_img(self): pipeline = [ self.core.call_success("export_get_pipe_by_name", "img_boxes"), self.core.call_success("export_get_pipe_by_name", "unpaper"), self.core.call_success("export_get_pipe_by_name", "swt_soft"), self.core.call_success("export_get_pipe_by_name", "png"), ] result = None def origin(): return paperwork_backend.docexport.ExportData.build_page( # 1st page of the PDF "some_doc_id", self.test_doc_pdf_url, 0 ) def set_result(r): nonlocal result result = r promise = openpaperwork_core.promise.Promise(self.core, origin) for pipe in pipeline: promise = promise.then(pipe.get_promise(result='preview')) promise = promise.then(set_result) promise = promise.then(self.core.call_all, "mainloop_quit_graceful") promise = promise.schedule() self.core.call_one("mainloop") self.assertEqual(len(result), 1) self.assertTrue(result[0].startswith("memory://")) self.core.call_success("fs_unlink", result[0], trash=False) (tmp_file, fd) = self.core.call_success( "fs_mktemp", prefix="paperwork-test-", suffix=".png", on_disk=True ) fd.close() promise = openpaperwork_core.promise.Promise(self.core, origin) for pipe in pipeline: promise = promise.then( pipe.get_promise(result='final', target_file_url=tmp_file) ) promise = promise.then(set_result) promise = promise.then(self.core.call_all, "mainloop_quit_graceful") promise.schedule() self.core.call_one("mainloop") self.assertEqual(len(result), 1) self.assertEqual(tmp_file, result[0]) self.assertTrue( self.core.call_success("fs_getsize", result[0]) > 0 ) self.core.call_success("fs_unlink", result[0], trash=False) def test_img_to_pdf(self): pipeline = [ self.core.call_success("export_get_pipe_by_name", "img_boxes"), self.core.call_success("export_get_pipe_by_name", "unpaper"), self.core.call_success("export_get_pipe_by_name", "swt_soft"), self.core.call_success("export_get_pipe_by_name", "generated_pdf"), ] result = None def origin(): return paperwork_backend.docexport.ExportData.build_page( # 1st page of the image doc "some_doc_id", self.test_doc_img_url, 0 ) def set_result(r): nonlocal result result = r promise = openpaperwork_core.promise.Promise(self.core, origin) for pipe in pipeline: promise = promise.then(pipe.get_promise(result='preview')) promise = promise.then(set_result) promise = promise.then(self.core.call_all, "mainloop_quit_graceful") promise = promise.schedule() self.core.call_one("mainloop") # required by Poppler self.assertEqual(len(result), 1) self.assertTrue(result[0].startswith("file://")) self.core.call_success("fs_unlink", result[0], trash=False) (tmp_file, fd) = self.core.call_success( "fs_mktemp", prefix="paperwork-test-", suffix=".png", on_disk=True ) fd.close() promise = openpaperwork_core.promise.Promise(self.core, origin) for pipe in pipeline: promise = promise.then( pipe.get_promise(result='final', target_file_url=tmp_file) ) promise = promise.then(set_result) promise = promise.then(self.core.call_all, "mainloop_quit_graceful") promise.schedule() self.core.call_one("mainloop") self.assertEqual(len(result), 1) self.assertEqual(tmp_file, result[0]) self.assertTrue(self.core.call_success("fs_getsize", result[0]) > 0) self.core.call_success("fs_unlink", result[0], trash=False) paperwork-2.2.2/paperwork-backend/tests/docimport/000077500000000000000000000000001456262201400222725ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docimport/__init__.py000066400000000000000000000000001456262201400243710ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docimport/pdfs/000077500000000000000000000000001456262201400232265ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docimport/pdfs/test_doc.pdf000066400000000000000000000230121456262201400255230ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xœmŽË Â0E÷ùŠY 3Ió‚2`k»pW¸w>v‚ÝøûæbQ3“››¹%ÁK<%*&©œß’ô–`¹ŠãÕ‘Îr}ÆJÎi|€xíD@ âíÔ!±êP¡Î­å&U³¾X¦Ü\Ö|žëƒãÆd=°ípW¤ž›bê‚}q”/#ŸãAŒQÌÉ,Jú%›¸Õa]Vã>DhH‘Nµâ )nH&ê;z†7NÃD endstream endobj 3 0 obj 181 endobj 5 0 obj <> stream xœåzkxU–à=UzX–l=,•$+’JQœÄñCŽIœ—+~ȱ۴B,Ù’`[B’ÂcãéæÕiÒÀÐ<²Kš… Ý]Ê$ô„^¶cXèž^–f€–fHMÏ4_“!ͤóõ–÷Ô­’b›G;ßþÛ’«êÜóºçžsî½çJΤ¦âÄ@¦ K„¡‰h²oÛ¦ZBÈÿ",C2ü¶.Û„ÏÂüíprdâ‘¿Þw‰ÕB´gFÆ ?ÞòGˆa”ë­£ñhìYûB !ü¨cÃ("öei ñ­ÀöªÑ‰ÌMµ:±-`»<1ý]Ãßb¾‡°]=½)éSu2Øþló“щøÊ&M¶Gˆþ@2‘ÎÄȪBª"=™Š'w=2ø2¶§ a!ð#]5R›aUj¶@W¨7MfK‰ÕFþ?ºÔG‰t¨·#IÒç’‹=EœäaB>’ZWžÙ] Ÿþ¿´¢@~=DN’3ä(y‡\§‚$DÆÈb_/7+]!²—üÌ|…ÚSä,Òe¾¹WÉ—^!ò=ršü|I/!2AnA[ž%ïÀzò L•ù È_—Që'ˆ»úËT1Åø¦àð"ì»äQ湊‘òþa‰Ây‰‡ý¨9ƒã<šñÖ/(½‹Ü†Ï2J L/õ¶Ïÿ7Ñ-ü+Žê6rù&ÙAÆI<±…¿^òúôŠ äˆÚözæÇ 3?6¾KFðŽŽ9Êîø ý__l)‚r¶Œè¾ŒÊÔcöS¦vỊ’¾…‹9ÜB翲Ñì¤j@µB½MõÊ×õ¡ù®j¥ÉÂo³·dcêÝê“­§Ú¯ÝîïëíÙÓêÚ}õ®Î«vv´ÛZ[šwMÛ·mݲ¹qÓÆ ëkÕU•k׬.[å_éó:¬f“±¸H_¨+ÐjÔ*–RÉ‹iÙ2ÞŒúÛüÑŽªJ¾Í1ÚZUÙæFD>Ê‹øR­öwtP”?*ò^\¯è"tDsx§ s yN0ñ[ÉV© ?/¾ÚêçÏÂÞî~„¶úüxÂWSXµš6аáó¡µJ²–oƒFgÚ"h#Ìê [ü-ñªJ2[¨GP¸ÖŸœ…µÛÌڶͳ )(’ºÅ‘¶Ecb¨»¿­Õåó…«*wŠÅþVJ"-T¥¨iµT%?&™NŽð³•s3÷œ5‘ÁH…!æE÷õ‹legض™™»Ds…XîoËoþÀ#‹•þÖ6±BÒÚ¹'ßOç•.AT—™üüÌ Çᣥ˜¨‚Ñ”™þH$PdZDØÓï“.W}=3ôóÁ™ÈLôìÂô Ÿ7ùgf †™dº›„úQÅÙ…Ÿq‰Á{¢)2 ›ÃÊЃ{:Å’îkûE¦,ÈFƒM~ß&—Ïœç }™ [Ð9èaŸOrѳĆ8ÝÝ/·y2èz†аÈD$Ê\Žbë“(Ó9J^<âÇØvöôψª²1züHTœÄìº^ Œß$_vùü33ßS^­ÚãEõjtJ-À¼‘DfL´Q|Y~]pa«Í¾Ñj$=mþ¶ˆòw`Ô xttG…œ½ý¢ÐŠ€U"Ö6[@‰h6ÖJƒ)üIÑêoÎGW2«m¬§ŸŠ(b¢µE$‘!EJ ´ÑyÅ·ÍDZe$]þîþçHÝÂùÙzÞuºŽÔ“p«Ä̵`–­n›é ‹Þˆ+†ón˜ïwùD!Œûûãa)íÐCåç]49Â4Wzû;{üÝ{û7)†ÈIª¬m™¿KVƒ (”ðýŒ‹ #£ |óV|ŠÚ²¼MèpŠ•·y+ß.’ãF3Är¾-ÞªðIí%JÕR:µtä´i¤&êiépùÂ>ùªªdÌ+£DäÔŽ —)$`~¶tP”äK‡”ô|¿?îûGyQõKc“ÜC½¬8ƒú\‰Uï’Ö"g¡›ˆɹ†äL1XáZì\±¶óÍŽeä92?Sàï왑”û…-ß))……Mf] ¤ íǵ—7ᔦzfV¤É<ºYRâß›ñ÷ôo¥Ü¸žÜæºYêËB:¡³·¹ª—¶æY?ÜÝ=+ÀÝ={ûŸ3a]xwoÿ3 0-‘æðì*¤õ?Çã¦A±Œ„•Rƒ—’¦=Ø( ü®çB¦)UE´=tÅäp@†Î22Î$w´šv$)*™"ä¸Uˆ+qÓG¯Y"¹L(T ‚N00EŒk$Ô3ˆù Ö±: § P®Y”ÚCÑgazV'¸dŽiäd ïî»ÒußÞþÓÜ]ô‰5K¦‹cƒÛJ“åÖðèL$,M6ÂahðDðoÇ0ù·£!ƒXè7‹z³„o’ðM2^#ᵘ¢ÀŠOcìC"Hpm¿§$_ú ׌é‚©0.*3¦ßV¡ÇÊðÜðÖ VØ*¼gaôLkã ¤tlAÎÌêØHXÇZ „‰¥‰#ç98ÇÁ½æ`€DòÃE^ãà¥%9èâÀK 2^äà1JJP1ƒÊ@8xŸR§)¾†b¶,Ð~d±{)¡‹Ò.R¼˜ëCà©ÌEªhŽv3M©hZ ×ÇuùëÆÜ•R®ýËð_ H4ÒTa&uú4×9û¯«3[ÀÞh®[_ãkØhö¯4‚ßì3û×TC˜í6ØòVÝüu®ÕñV—çÞ´þ­—ê{Ö7`Köå7´úÏnp5H+Vn¿Å3›üD8D¬VgQq±Î©óxÝ¥¡°›X±aw†Â»­„aÔjóž°Út ç½0瓈±qÌ I/D¼ò‚à…/ð^ðR2’¦sT$½N%E/œX„_ìœTj‰”±ã¨›ê$ ŽºÁ8vù³¾¬ÚíPWËÙpà’7êý+µ ¸¦ÁAmÇ_7Ý|k*{Ãm'÷ëp6vð¨e/V—oýÎ]ó:«ªœÌþSîù R3Ž*œ8XŸZÔ»ˆOKÿQ&ƒÆl¶s¬®'LX0±¬M°YBa›Ñ`6šCa£Íj•/Ùᘘ¤"vÙA°ÃœD;œ MÞ&;;\¤d]̹4G$ P/äÃOJ¦_bð©ÌuÊà5þ•«ê7 Ø+ƒ¾E¨ª„Ê*¡ðûYç‰; Bõ¾Ü>Û,“åÒì]øˆù;öe²–„…zŸÖZZ„)Q¾®ÈÇÚížPØe7±úPXËrÓë ¹"ë ´øuðô:X]ë g/Áð# ÁØÈBó®i¨³suµ õ¨f¨¹v›ÍjÿJÍÊÙ=,ów³ÿ%øƒšªõ7½øp8¾¯öÇF ¬kHu÷]½ûþ½M~(¸ç˜ÛòÏßj=ys½Û×:¼õ^ï«PkãîÒÚê–k¤céXøˆ½‘}¸pu™šÌee*Þ`pªX,ûW®ì;lfó Œ˜Ùkf ¬ÙL 9­ Çh#¶P˜˜¦×ÀÀÖ×aÐùÄAï:Kc@v>i¤9)Ï@³2J%ÿÖà`ÍõÛ¡ êWÓyÙ°´Å`³ÖÕnØo<òÝ©l¶$5û‡':Ú~U¬gå¦Ç|ëÎ{[‡jÙþÃ7çïpVíOcÿ-;XÕýÑ}©WýYJ½Rô:èœÅ˜U©þ‚p¤]XSX\¬-aY»CeÐBaVoÄ9mîî1ˆhr@À!…)•K£º:ÅúFKcm­”CjL ³¿¡ êlu6¿ÙŠqÚh+ظå¶xÓßÿý–šÍ=þÛ­©æþª5o½Õ;xG³i‡ÃK}BŸ1‡ld9*ìuK lF›Ûã$èh§×‰Žv:   [LuwØÀÍy@ôÀ óÀ´’ˆx äâíøòãÁÑ|?»û­ùW;ŸÂGÿö!+>ùù;¹”mv5ànòŸJ²S¿|[òÉÂçê)ô‰ŽØÉ.! ¶’"k‘Ãi· „íªHØÎš¬a“66Yˆš'ðN8ï„NH:邦£¥4”W,DûLÄç7c2Z€'fl”ù©‘ª'²odÿùÌMO^þpþO†áì_e]yêÔ)æ)pÂÊÏn)€•ìËÙg³g²bö¤J¶–îwRüÊÑV;¹$œä,«@£±êY§ÃL"ásÂÌT™ÅîÌŒNm6kt:FV;€¥hTš°ÊrÆ O8á'L;!ㄘTN¸è„œð&Å#2â„^'´:áu'¼ä„¼Èí9¤¢'j¨3¬TCã%ªBæÃöœÑ 7,Ïú%ƒ²Y.4N†ëè|°/Þ)¯k)ú¾uÁSïÏ¿ðØ)ö_šùä›ïÂï¶m^fïüå|¤Ï½S<ÿƉlìqôaN„ª'.Ø üƒ…ãX—Ë^R¨r¯à\NW(ì´k‰5fKŒÚâPX¯—Tn¸ä†ÿæ†ÛÝqCÌ nÃnxÓ /¹áŒ Hî\$ó#Š¿–ÊX)þ•uõº¡5‡ßü{ªè 7[ÔU½VQâæ¢λáu7œpô’nÜÀ»Áä‘6M”oIQ6ZV•|I–l¹Ý0_¶É Q(Á4^²ºAZvih~ýøãOþåÕÍë«VÖ4Õúé+YÕ¶ýšæ×Ï—¼z‹-ùÈñÞÏ/ûªª|‡rŒƒ k7y\Hªõ…: ®ÿ„¨Y5:ßö¦^ÒÃ=<¡‡ôp»2zˆéa•¬zPé1Ý(Ç1=–+zˆè!¤Aszõp‚6Mz z¸H›È·˜m‰”ReIŠ^©YqB¯¯)»Rš$¤Šäƒùz È] ¿Cä-¬·‚žh4†"V÷èµl iRjÔ°¨ÐCmõõmÁººà¾õëë‚AÔÁ,üZûmzžèx£µPmUs6¦ °¨ƒ1ŠŠ¬ÆBµV=6kÙb½þ쟄—¤g¨Jb\Ãdžƒ9x—ƒŸqp’ƒ9¦¤ 8XMÆ.sðO¼ÍÁs|“©ÚGpð&?âàQŽp ²—6ê9XÅ•2¼ÄÁž ò˜®Üñ⋵3Fa`ùqƒ¾°Ž(•[TÔå l<`Ôê/Äj¿ü€±³iuP§“!õþ†ìÙG²­S yë±*Ø5oÀóS^öøç1uQiCCéç]ìãŸïgg%XÉÙ‡°V°’n¡Ê¬Õ‚Á`ã4fºÜ«Í,c5™ŠBa“Qk(Är¦Ð6@‰^ºqÑ'M­º:\â̹2FÞíýkVjUþv<0Ul®ýví÷³Í‚E·õÕ­¸1Lº¸ùæ\ ð,ôk´mîì·‘’‡Þ`Ð:´nÏ <­0–`ƒs MœÍ‚œ¬iO˜5=á<ð’°ÐPy x ã˜z=Ðêz¬ò€‹’±âa×;Xå¼î|)”Ç/ŽÞÀ¿ëD´ô<´zé¨õêÿºY>u÷íÅÑõ7Þ6RÙ˜?õ÷ (ç!zN`¤_Øgp­ÑãIqZè¶hµnbwÛ=ÞR](\Êip'µ²Ýa«ÉˆQ3î¤Ãá1zL<Ÿ;õɧAù(8—ƒyïâå–3Wv+ýBÝâ—•Á)ÍV­´(جŒtÎ`²ÓwnÉ”öNÍÜ:äÛÐÄš{õ×o]óÚn¸xöŒÍ0o7ýƒªÚQ•7ÛýáGóÙ[í¥ñwfƒìŸØSdüFX0J‡ÇÉX HeÑ»%fC1ŽÍVl$Úî0KV`‡=p †ÔŸÐ4xÓ?óÀ=ðmšrAÛìZš˜!Œ^öÀÛxÑÏx³ç>ÜN¹‡iÂ)÷JXhÂ\òÀ?Q~̰38™ãOy`Ð{r ¶Ú\Ž?oÇ™¥ú—ñËÖlºL¹óÖ<Ó.|c±=«¨=Rm޵øyš´²Aä´ÇèXeí—(#§u>Ý»<`ôä+Vi…Z²8-Þb¿Xì,e^ú5ÁWG¤©6¿Ó“¨ô­É•5­d¥r"ÝåÍ%¿ ˜ùùî]Ÿwc}ÿÎÙG"pæìåûaÿ`ö»;"™lÐòJľõÀClç‡k>ÁÜoÛç×>yì*y©ÀóÙ'Ò>DDá&«A£ál…–HØXì-f ÙââÂ5Ψ0ÃÊßcå¿«Z ÀÓ¹ïªç–ø÷!”sëÇt£HЯ™äMãàé×Rô+§¼›–}Å´¤\¬ËŸšpÅ™E=`¶JÇ%É=Òé©9ŨÚóW#Ó]Íž’àº{TÿBWöïüÅ”çÒ{éOåqïÆ5b7®Ÿ‰[Íj=§æìŽc(l(0qVÖŠ³†#Ø.8 Æ¼L¸è€×pÂÓ@üÓp,µ=oéâ © äÍ´„’êX„陕ݽþÔÞìÆß¹ëÄÆŠžLöÒþÑ}ã«Ê῟÷f?=ÈŽ¾ù¬Ðÿ À5íÀÊÌÆ­d¼òïÑÓúú/¯üÚ˜ b5ñ8ÉÿXMÇH´¾lùÆbÌ’‹Ó4â ã7¤LEˆ•i$¬›ô2Òï£GI¶­ø©Òd‹úçd‹ôf~Hš_ŽÍDù¡DòPjld4ï*çkkÖ×ðí‰ÄÈxœoI¤’‰T43–˜¬.lYÎVËïAÑL%¿sr¨zר`\æå{⩱á=ñ‘©ñhjGz(>‹§ø*~9Çòö5ñTZjÔV×ÔT7\¡.gKóQ>“ŠÆâÑÔ |bx©!|*>2–ÎÄSˆ›äûª{ªùP4ŸÌðÑÉß›ìŠSäP<•‰"s"3Ц^?•KÇÆ†¤ÞÒÕù,rGO&~ Î_ÍdâéÄds4}¡e½c“‰t%ptlh”?Mó±xzld‰ƒ‡ø¥2- Y‘æ3£ÑŒ4è‰x&56?„1›H¢Ô éàXf;žˆ§ùÝñƒüžÄDtò‡Õ²)è›at*?6‘L%P«ÒC©x|;‹Æ¢ƒcãcÔ6ME‡Ðcè¶±¡4õ:‚OF'«Ú¦R‰d-ýFû®+Œh ìÍtbüö,qOÆã1©G4û@|…°ãñDâi<ÉËŒV-²|81™AÑÅpàè­ÄÐÔ„'ts&g\t(•@Zr<šA-éêÑL&¹98xð`uT ÍF¦5¾Ž–9”Œ+ñHIZ&Æwaø'¥ÐMÑøJƒèÙ¹‹ïJ¢‚h¯0Tò¹Ô\_½^éÝ8–̤«ÓcãÕ‰ÔH +¸‹´’12‚wï›IœÄwÛQ„†H‚$É!’¢\£ˆåÉZÄ–ã»–Ôõxó¤¹HGyž´ œB)é¥zd’T“BJùzmµíQ¬è Ò•íDù!Ô° 呺X/Oz(f ×YIr„L¡QÄì i”Š#OŒrð¤ ï?§ãÏѯ¡P:O©E»jðSM¾TöÏiC]<õu†R$['¨ý7 .r_çùâ4~i¤Äi+FµJºû£‡r…¨¤ä‹ ím’rõ~I]Øã0ÊÑXæ8‡¨n)'dÍ „G¯^OQ bT.7¶4öüÅ|yvôPëÐ>¯¦x©¦´fl§•qÉ>ë¥V$+ùâ Z"õ;Já(õgŒJKY6©HbÞñ_Û¯ÈF•¸LÒ>(VJ2•Š¿‡é3MûÄ>xjŸå¥}óÔOQêu9ÒHÍPÞ!Äãç2Ï&Ð+r_ƒÊL:Hçå¨2â ª—ÇJ&Ž)+4n“¾•4ÆW¼"çͰ’©<•M"œ £Èù±ŠÆFIœZ*AQ:÷Qbœö-Û6J³#JcWb¡#Èù+¦ŒT²:I1U¤æ…4ããŠO¿+Å®/Õ({pqnJ1§ö¦éž¤ÖÆòc”½-q+=É#§+Ò ùø Ó|“=£Úª¾ÂçÃÔ7¥×µ(†9ârn%PvŠÆCžOr6g¾à¹(õoB‘KÒu)£Ø2AçÇ(ÍÀ$ÙŒµe­“>Õ4Ïš!eÎT+6þÝr’]IêÁÅó#•·emÜ¥ÌþÉü¬›Z4s‘èÁ5h]/’JþÏñË4H³fùª¹û[¿lr6Ža;CíIS_VÓ1Œ ½ {ØEëhz-øÐ¦/¹fu¡ƒ'£0BJˆ"d7 >ØA¶€oiÍønÁ¶ô®†mdù¶!~;¶·"~ .ž^|6áÝ…÷½x«ð–9j#€ï€Ò®Âv%J¼†O ·„mB¬ô¾ ÛønWÞAÄ·á»MiïÄ6¾I´ÒôyTÂi8?¯Í?‡?ƒÐg0ýɱO˜?\,÷>}ñÜE¦ëãŸþ˜­ùŒC¹`ºº¹¼pâ‚¦ÐøÈïÁü›ó›¼ïo{¯ï·ýª¼‡#{¯æ½Ð{Óï‰ï©ß¶ïW,ç5Íñs5sɹé¹×çÎÏ]œ+˜þ鱟2ÿýù€×ø¼÷yÆ{ºëôáÓlä)0>å}Š =y”9vŒÇ½ÇÇÙG®ö>Üîñ~ïÁ5Þó^|9»0wúÁ"sðyè‚]dúp÷ivÁûô\Ã2âÓ‹wï.¼xß‹7ž{Ý‹wv ›Ø¿ý}®û*î»å¾#÷©“wNßyìNvúŽcw0O8w€I‡Ê½‰É ïdû:¯³Îѧ­cû4Ø ö.ì,[Œ Þdºvowo{¹·¤ÎÒ§Æ«ÑÈzÙ&¶‹M°÷²çXmÁžÇÛ÷ùÐÅ#„t† ±ËÛèbÏ.œâ>ÔvUòªé«ØÁroGû&¯±ÝÛh­ýýöÛ5íðþŸž ²B°<‚_pE‡««³õ™ÁØgª3ö1€®#}ã‚‘1Œ‡¬‘4fš5œ…c³½=gµ {:łе"Ü-–õHO¡{¯¨¹[$}{¯íŸøNøŽ£GI³»S¬íé#îp§C@€iLîYŽ4‡ÓéL½ ¢á)|’Š© DîOËX’§“Š4¤qJS!¨ä6à³B¢!B’”ÞŸ&ÒC"VÈB’tZQG…åûÿ¶g– endstream endobj 6 0 obj 7404 endobj 7 0 obj <> endobj 8 0 obj <> stream xœ]’Mnƒ0…÷œÂËt DBH)I$ýQiö"c²àöõÌÐVêëûÍøé™°¬Î•éçðÕª†Yt½Ñ¦ñîˆn½ d,t¯æµ¢U Bß[/Ó Ceº1σðÍŸM³[Äæ¤Ç‚ðÅip½¹‰ÍGYûº¾[û˜YDAQ ŸóÔØçf€º¶•öÇý¼l}ËŸà}± bª%[Q£†É6 \cnäQTˆüz-0úßY¼¶´úlœ—J/¢}RxމÓòŽùˆœg;ä=q!§¬‘ÈkhÎ÷÷ÈGžOúqBšGæ¹d=ñ™¹D¾ð]ä+ÏÉ<ˈÙŠ¹ú§}öŸ¡Éþ“2ûOwΚÆ„ïø¿Pwç|ôôØ”9¦Ýøýìh±‹¾oˆ’œ; endstream endobj 9 0 obj <> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer /CreationDate(D:20190902205629+02'00')>> endobj xref 0 14 0000000000 65535 f 0000008715 00000 n 0000000019 00000 n 0000000271 00000 n 0000008884 00000 n 0000000291 00000 n 0000007780 00000 n 0000007801 00000 n 0000007996 00000 n 0000008384 00000 n 0000008628 00000 n 0000008660 00000 n 0000008983 00000 n 0000009080 00000 n trailer < ] /DocChecksum /72B44A81E5EEF3D98178B73CE31BA672 >> startxref 9255 %%EOF paperwork-2.2.2/paperwork-backend/tests/docimport/test.docx000066400000000000000000000100731456262201400241310ustar00rootroot00000000000000PKf“0R _rels/.rels­’MKA †ïýCîÝl+ˆÈÎö"Bo"õ„™ìîÐÎ3i­ÿÞA ºPŠ Ç¼yóðÒmÎþ Nœ‹‹AêiAq0Ѻ0jxÛ=/`Ó/ºW>ÔJ™\*ªÞ„¢aIˆÅLì©41q¨›!fORÇWeS.“ICŸð ižÍºWó‚Ñ)ŒíD çŒÞ ¶·^¾dôV°§Nx!1þ_Ä»9±ö»7'd,–Ó¦‰“¼h½p]àÅ5nTQŒ‹æ?PK™]À#þPKf“0RdocProps/core.xmlRËNÃ0¼ó‘ï‰ãT*`%©¨'*!(q3ö65ÄŽe»-ý{œ¤I ôÀmgg<ûr>ûRu´ëd£ D’E y#¤® ô¼œÇW(ržiÁêFCöàЬ¼È¹¡¼±ð`ÖKpQ0ÒŽrS µ÷†bìøsIPè@®«˜ÐVØ0þÉ*ÀYšN±Ïó ·†±ÑÁRðÑÒllÝŽ¡Ú;L‚ZV¹³:æD©¤ß8+ÈQýåä(ÜívÉnÒICÿ¿.Qc©ÛUq@e~h„r ̃ˆ‚íË ÌËäön9Ge–f$NIL¦KrM³)ÍÈ[޽o û¸±eËAˆ8n¥ñá†=ù#pÍtµ /W6ž?v’1Õž²fÎ/ÂÑWÄÍ>xœÉ ©Cîÿ#]R29i0è*[ØÊö+:¶k·yÿîû‘Fb/} }zÿüÇòPK ¬çaÛPKf“0Rword/_rels/document.xml.rels­‘M Â0…÷ž"ÌÞ¦U‘¦nDp+õ1¶Á6 É(z{ŠZ(âÂåü}ï1/__ûŽ]Ðm€,I¡Q¶Ò¦p(·Ó%¬‹I¾ÇNR\ ­vÅ´DnÅyP-ö2$Ö¡‰“Úú^R,}ÃT'Ù Ÿ¥é‚ûO&ÛUü®Ê€•7‡¿°m]k…«Î=‘àn†H”¾Að¨“È>.?û§|m •òØáÛÁ«õÍÄü¯?@¢˜åçž§…IÎáwPKù/0ÀÅPKf“0Rword/settings.xmlEŽKÂ0 D÷œ"ò’²àS‘²ãÀBk RbG±¡Àé +–£73z»ý+EóÄ"#“‡fáÀ õ<Œtóp>æ0¢†™ÐÃöÝl7µ‚ªµ%¦>´“‡»jn­•þŽ)È‚3ReW.)håf'.C.Ü£H¦h—έl #AW/?ÌÉLmÆÒ#iÕiØðQOárTεò ÑÃÚmØþ]º/PKeúÖ"¥ÐPKf“0Rword/fontTable.xml­PANÃ0¼ó Ëwê´„¢¦â„z å[gÓX²×‘×$ô÷¸N+!È¡ ÞìÙ™ÙY®?=6ž*9ŸR i_:Tò}÷rÿ(G ¬'¬äY®WwË¡lÔ]𙓺³jQÊ!y– ×Èø¦1Ÿ½þpHq h!¦ ¸5ËÕ9J—BïŒCÄ›w@™ [Œ'N¶’E!UÞgìñ2 ™žÎDÝ^æ={‹'Hf¿L·G·÷vÒkqk¯§D™¶š<‹ÃüO«W³ÇË[ ¦É®`ã&¡Ÿ}«©dó[—ð=O{º>ΟŠ:?xõPKÁÇÙUPKf“0Rword/document.xml½TÛŽ›0}ïW ¿'†îj•¢%«¶Q«ªê*RÒ0Æ€µ¶Ç²MXúõµƒ½HUÔUûÂ`ÎÌ9gÛ·wR$'f,U l¢„) WM~¿¬6(±Ž¨ŠP¬@³ènûî¶Ï+ dÊ%žAÙ Ô•[Ú2IìJrjÀBíVduÍ)‹Å S Ö9c‹Ö ™òX Fç—¦ÁcÉ.já÷izƒ Äy¿¶åÚNl§?韤˜òúKT{0•6@™µ~RŒº’p5Ódé ž¹B_¢\Ò?‘|nd7‚ £}E9ÛX{qzgÏ—¥/ø-ÑlakÞÆöÕ@§'6I/éVóÐé01íÿhÉwùñÅTvý6W/göw|aÿHškR t-ˆ x‰±À¼ÂúÜm¿³!ø˜<Œ/ŸêÆœ±ú G½Ï“ðî?'·ŒºhgÐ3±bnO6RëæðË#þXgÙ‡°qú¼õï7›«Í”ðƒÿU°Ú…¤«ëcxÓ>Y¶ŒTÌ_HiX8Ð R¸)Á9 Øt.‚Q꾓ÇÑj-=}Å(Ÿ‡6þÞ€›ú¨‰°± ç[ÚqãÛõ×Ú„ s,Œ—Aài«áåþÝþPKØI zðÄPKf“0Rword/styles.xmlÍUmOÛ0þ¾_ù{IAˆ¡j± JÝP7û×ä’Z8¶çs(å×­´)†´}iâç|—çžçì~:(UtޤÑcqx0êÔdRcñãv28yÐ(£q,VHâüìçåˆüJ!Eœ¯i´‹…÷vÇ”.°:05ÇrãJð¼tE¼4.³Î¤HÄåK ‡'q R‹®ÌáñV¡R¦ÎÉýAjÊØä¹L±.Åé‡Ãú­T]2} ‘Ü]e\Ï‚—s©¤_ÕdDT¦£i¡ƒ¹ân™8ã^3“^b•ò–î»k—íª~LŒö-G@©”cq%ç踼ÑÑ :™ -.4í!¿ c13Þ4x”|ùÝ$!œRMÑ%Þƒ†œqøö:Í›îAÅQÑãoà¸CÚÄè¢Ãr7˜\?¥ò¸$³ÍeƼr0…ĸí:ÞÔÂn®Âc)3³LXgT“lÛäõíñ–Ìõ„ñÇýʲì"ð©CÓ,h¶ªÚ$ %v½´pÝãÏIm}¼ŸÑáej”q]PyóÏ-®Å~©!·Ò;Üò£Ak>s ̾é>§4>øOŒ³”¡gwúx‡hgkIÞUíf²Êºñ9òÑÇ Ç0…Ü£ã›îh(^ë<»µÃø6²é{°·±=ºÆ¢RàöÛ¿fêi©§ãÍM7-úl²UtË¡½6µŠý‘XI×U¸0ëymfûñD¬9ðDÿã>ýßÚØ•¤žŽÚÛÌöl­]H}Ãðœeoæ\ Î¶I'`ÃLí5¡ç4Pe­ã?×+V•<ž´ã,„éÅYx~beó›Ð‹/¥·J6eÁ¶kÐwÓ뽦 {£³_PKíÑ-‘†e PKf“0R[Content_Types].xml½T9OÃ0Þû+"¯(qa@%íÀ1B‡0#c¿$†øí–ößóœBUh Æø½ï´œ|ºTm²ç¥Ñ9ÏÆ$ͺ.ÈSyŸ^‘éd”—+ >Á]í Ò„`¯)õ¼Å|f,hœTÆ)ðÓÕÔ2þÆj ãñ%åFÐ! ‘ƒLò[¨Ø¼ ÉÝ׺'ÉÍz/J„YÛJÎŽiœÒ^œƒÖ.´Øs—nœeˆìv|#­?ûZÁêzO@ª˜,ž÷#^-ôCºb±n'$3æÂS¸@Ÿcš8OŸ’0|æŒõ‰³Ã½÷È™ª’c®’AŒ-@¤)Á ÇisãàûâÛ¬}¤â»qbSîÎ4®ÿGÑ´‡ð)ù_7Ù02ï‘l™-T(Z²—ö…yØQšø\þi=ì&ŠI=|aÕÂ_ÜFÇ»‘å´û_N>PKB¿ôS^PKf“0RèÐ#Ù= _rels/.relsPKf“0R™]À#þdocProps/app.xmlPKf“0R ¬çaÛsdocProps/core.xmlPKf“0Rù/0ÀÅword/_rels/document.xml.relsPKf“0ReúÖ"¥Ð"word/settings.xmlPKf“0RÁÇÙUword/fontTable.xmlPKf“0RØI zðÄcword/document.xmlPKf“0RíÑ-‘†e ’ word/styles.xmlPKf“0RB¿ôS^U [Content_Types].xmlPK <é paperwork-2.2.2/paperwork-backend/tests/docimport/test_img.png000066400000000000000000000107061456262201400246170ustar00rootroot00000000000000‰PNG  IHDRÈdÆ bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEã Šv°­tEXtCommentCreated with GIMPW.IDATxÚí{LSgÇ¿U£»ˆó‚,ËØE§Î`Vo+ÃédØéTQ§Sücj†:¶™ÇܘºH¼y™™&ÌBp@ âP§"rS¬N[ÑV Š”~ïïÛ¾@O¡=¥Pô÷Išè9çyžßóœómŸ Ï÷HˆˆÀ0Œ ½¸ †Â0,†a0 „aX Ãað@†Â0 „aˆ^¯‡D"õÑét€°°0H$TWWÛÔ矉DFã´ŠwEÎ`åÊ•H$¨¨¨àXø„a\P ýúõY|êêêÌ×TUU ^ãææÆ­Êð/ˆ3‰ÁÓÓ³G—Áô|útE! …éééP©TÀ¼yóàëë ‰D"8>غu+Ôju«X¯×ãäÉ“ÈÈÈ@^^@&“aܸqðóóÃðáÃíƒ8»ŒG¡¨¨§OŸFqq1òòòðÊ+¯`Ú´ix÷ÝwñÆoØœWAAÆoþÿ‹/¾Øêü‰'0uêÔVÇŠ‹‹¡T*‘ÒÒRL˜0AAAÆóÏ?/8ö´¥îbbé±ÔÕÕ@UUUí^J(%%…<<<ÌéZ~8 ˜ö³Ï>#¤V«ÍÇôz=EDDæcúüûï¿6×¥+ÊøñÇÛÍë÷ß·9¯‹/¶›×‰'Ì× Úµk—Õk‡N………­ò·§îöÄÒÓqº@PLL ©ÕjÒëõT[[K …Â|®²²Ò¦‡7''‡ÐÂ… ©¬¬ŒêëëÉh4’V«¥’’Ú¾}»`^ö¤³Ë8x𠥤¤F£!NGƒ´Z-eee‘T*%tõêU»nØŠ+ݾ}Ûê5‡2×ãܹsT[[Kƒª««é?þ $•JI«Õ:Tw[bat ¨¨(jnn¶8M(''Ǧ‡7!!ÐÙ³g;¥â]QF{œ>}šÐž={:U Z­–<<<ÈÏϯ•„”œœìPÝŸ8}nZi‹L&3φÙÂ!C7oÞtZ¬]Q† ///0÷õ;‹ÂÂBTVVbÉ’%4hà5>>>€3gÎtKÝy«C‡<þÜsÏlÊÇÛÛR©¡¡¡X·n”J%nܸƒÁÐi±:£Œ’’ìÚµ }ôÆŽk^P8p àÒ¥KÚÞ7nÜ„‡‡[]Ì}ùå—[]ÛUí˃t.–µëòòò%$$ØÔý!"R«Õ´qãF‹çŽ;H£Ñ8ÜÅêì2~ýõ×v³¦Ogv±vìØaS™hÖ¬YÕ»X.†§§'¢¢¢ ÓéP\\ …B¹\Ž5kÖÀÇÇjµÚeÊ(//Gxx8<==‘••…ªª*èõz477ƒˆP__ï”6zæ™giii‚ ¹-?Gíòöå.VпxyyaöìÙˆ‹‹Cbb"4Å ïÎ2JJJ[·n…¿¿?ÜÝÝÑ·o_óxìþýû¢âϵĴVqîÜ9§×½£XX .Â믿îô¦½e˜úîO=õ”ày±b6ý)µ±›T*…››¾ùæ:µîÅÂéBâããqäÈ\¿~555hjjBCCT*vîÜ v­L;»ŒaÆ6n܈‚‚|hqÞÝÝ?ÿü3`Á‚ÈÈÈÀ½{÷ÐÔÔ½^êêjaïÞ½øû↑{G±ð ½ é[¶liwÀ¹hÑ"ª­­uhÞ™e Z»v­Õ¼Ž=*j^VVÖáêµÑh¤}ûöu8HÏËËs¨î¶ÄÒÓéÓS„¼jÕ*øûû#??EEEÈÏχ››¦L™‚iÓ¦Á××O?ý´Ë”ѧO|÷Ýw˜4i’’’——‡1cÆÀßßr¹Ü<Õ*¦»SPP€#GŽ ;;¹¹¹×ôîÝË–-ÃÔ©S‘“'OâÂ… 6l¼¼¼ •J!“ÉðÚk¯9Tw[bééHؼšaóA:ð@†Â0,†a0 „aX Ãa†Â0,†é:ôT[ÆqºÓ{W¡P@"‘ ##ƒA†»X ó8 „=l™'™÷ƒXó° ÃáÇQUUN‡ääddff¢®®Ó§OÇ‚ 0zôhÿõ¾JIIÁŸþ‰¢¢"aáÂ…xóÍ7-ÊsÄÏöáÇHKKCrr2 àíí ¹\Žàà`(•JÌ™3ééé˜1c†`z{½lm¡¤¤ÙÙÙæ<}||0qâDbĈ­öu·lÓ 55YYYÈËËCRRÞ~ûmQqÚÛ¦]á õõõ8~ü8’““qáÂx{{ã½÷ÞCpp°ë(D¬=ŽiÇ`RR’Õ]h¤R©H&“ ž?uêT§ùÙjµZš?¾`šùóçÓÞ½{ ¥§§ îþ³×ËÖ–…Õ¥­]N{mzêÔ)ÑqÚÛ¦Îö&"ª©©¡Å‹‹º_.e=Ú‘@P\\ݹs‡©ººšbcc Í;—‚ƒƒé믿¦›7o’^¯§ššÚ¿? É“'“^¯ï?[“•é’%KèÊ•+d0¨¡¡.\¸@þþþæX…\Œ—mG˜¬À¦‰ÈÈHܽ{W°»·oß>H[ÄúÙ¾ôÒKˆŽŽ†N§ÃºuëP^^£Ñ½^K—.áÓO?m·¯+ÆË¶£‰‹Ý»w>øàdee¡¦¦ÍÍÍÐét(//ÇîÝ»qçλ&CÄÄéˆG°³|€===±iÓ&ÀÚµkqåÊóý:þ<>ùä×y(]±æ½»iÓ&@eeeí.¤åæævŠŸ­V«5¯­@`eö§Ÿ~"¤T*-ÒŠñ²µe%=..NÔJºµ6§#mê,`"¢û÷ïÓÂ… ]~%Ý¥¼yñ³4h~ùå„„„ )) ………ÉdËå˜9s&’““@Ð[WŒ—­-u‰ˆˆ€ŸŸŸùo”T*&OžŒñãÇ# @p  =ÄÄéH›:ËØ4ƒµwï^Ì™3Çü·s2™ 3g΄\.‡R©t‰gò‰ñæýâ‹/‹òòrŒ1 Ãù×®]ÃÈ‘#!•JqæÌ«V†qéAº#ܽ{ñññP©TÐétæñéÓ§±téRó,‹ƒ±«Ûÿ¸T¤¹¹¹ÝÕâõë×ãý÷ßç;Î<™],"BII Nœ8ÂÂBäççÃÝÝï¼óàããÓ៽0Ì;Hg˜'z Â0,†a0 „aX óØ $,, ‰Äe6°ÄÄÄXÝÞiú,^¼¸Ušžè/ìjíÎaÆ‚»r–––æZ| ÿ‚0 ÿ‚´ƒJ¥‚B¡€R©Duu5ba©SWW‡‘#GbàÀ¸xñ¢ys[rssáëë‹mÛ¶µ»ëÏÙØë+«×ëqòäIddd˜ý¤d2Æ???ó^í¶ØãÓÛF…Bôôt¨T*`Þ¼yðõõípß8ã ¶ºý%&&ZÝ-vðàA‹tÛ·o·Ø1Ø–Õ«WÛí>¸eË@iii6§±¶+RŒ¯¬^¯§ˆˆˆvwϵuwtħ7%%…<<<Ó8p€˜n¶méûí·ßÒíÛ·Éh4R]]¥¦¦šÏµ}JKK ­^½Z0_“ýäܹs[ùÏv¥@ÄøÊæää˜Ó”••Q}}=FÒjµTRRBÛ·o§ÊÊÊNõ鉉!µZMz½žjkkI¡P˜Ïµ-‹é&Ì;×ÂhºåCÙêxSS“y¸F£±HwàÀ@ÇŽ³+`“@Úû´ÝÓ-$±¾²¦‡ýìÙ³]âÓEÍÍÍVͺsrrø)voÞˆˆôíÛ×âxPP€ÿú¬¶tÚëÕ«—yF۽̃ÁìúazçEW#ÖWvÈ!€›7oÚ\Ž#>½¦õ¶Èd2´9bºaËÚæþ`Ö¬Y,Ýð&Mš777ìÚµËìÏ—/_Fnn.6oÞlÕÔ–i^k.~¶ØVŠõ•õöö†T*Ehh(Ö­[¥R‰7n´ª_Kõé:t¨àq“ͪ5Ï*¦‹b²ÓÂ䟤×ë-nbtt4rssqùòeóñÔÔT€\.ï¶Š‹õ•vìaGîÑ£G#$$6lÀ½{÷ð×_–/_Þ­[`;Ó·ÿþðòòÂìÙ³‡ÄÄDh4šV‚r†O/ã‚i;Ž0azÑ{dd$ `Y@¯^æ—¡äææbÿþý€)S¦tkÅáÉkzßE˼3|zHbb"¶lÙ‚ŠŠ 455A§Óáøñã ³µŽ¦ÁúòåËqøða¬_¿^ô[c; ±¾²ñññ8rä®_¿Žšš455¡¡¡*• ;wî€Vou†O/Ó…tÆJúo¿ýÖá|ò?ü`¾ÞÖ5g/Šñ•íhfÑ¢ET[[ëtŸÞ¼¼<@ ¼Xá Þ¼¾¾¾(//GRR233qïÞ=!$$'Nì0ýŒ3°víZøøø@*•ºÄ—ƒ_ÙU«VÁßßùùù(**B~~>ÜÜÜ0eÊL›6 ¾¾¾þ¿Îðéeº†.³ýÉÌÌÄŒ3€?ü[žy¼Æ Ž`4Íýý©S§r«3=§Ï³644àØ±c8tè¾üòKóëÒæ‰îbUVVZÌT]»vÍ®wl0ÌcßÅ5j"##qùòeÿ ÿ Ãa†Â0,†a0 „aX ÃaÃôhþ›…ý dARIEND®B`‚paperwork-2.2.2/paperwork-backend/tests/docimport/test_password.pdf000066400000000000000000000214351456262201400256730ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream œ¨{àtJ©ÏCžPÊ$Ü N¢$çeFY/ÉJÍÂC†$þÝùÑ_‹ž¢íà§4í¦Jw.ɃÄî%Fðá4sÀÐ$ÞYþpƒ“–qêêYY¼½ònÜlj’í8Ȧë—τڥi†¯ŒÕGˆAåY¸¼‘hàs|_<݈×BÃW‡ß‘ÝûÑ· endstream endobj 3 0 obj 146 endobj 5 0 obj <> stream `fyá ¹”³I£ŒN’ü¼W¥NˆvONœŒô5e»¥î—ᡪ´\&ù ¯a“$ÒÒ?r>’dbRÏL!§lÊ0¸cÄcìó§£ýúéO!–Äçvõƒ¸ú7ý@ìP4;~‘}Ö¡e"òÜò/ŽséíÔ>TÈK„Ä\3÷ ¸šûçÞƒëªî°Åì,kçW0ñ‡G‰?m5\?ùƒå¸±fLÄ5ý=!{UÁ÷œ…ÃŽ^#ðb%“{/‹†¥r\’z™cýû«5¤©§[›ÎÍ/«­K™‹ÉÊuYúáW!<À¨ˆcŠ•šô u¥Ü£šD¯I£°">´8tüÕ•cÄMb[²dq[-óK¤ô%íaJ´…Lü³ MS3Ô¼ŒöaªÞÝ×<Š%†LÌmìç£At5¤ (õÅqñyœ|ˆ%è.åÏloŒ›³ ºõXw*—<ÞSÃb´ ˆx\Wn~Ûå8F'ÎMA9–óšqDx> a!I¯O¬©ù,Úø]‰Ìð}I@ öÎlæ‚#ƒÏ<"æÄ·cf¢¸,ŠýÆ'Á­,vSP>Œ—×jjøÝ’»jÌcõúᘇk«pvñˆõû4f]ž»o`C>í¯_ΉˆÀþ6Ãô° ¾ßãÛüƒ ÞƒÍBÜþ“7 ð†ŒÞ"¿¶Ï‚Ù‘òªdtg£St„©z&[;»÷qr´e\\Ð3Ì¿’§bµõ åÓO¡! üÏZ­È6 ôÛ9³ð³Ù@z9³¢„ñ©èí•Gt¤Ã€CLŠ÷FÆ÷£®¾&C<, ².ýþémÓz4`3üDzï(+æM,Âß“—ÆþGœ/±§}VòÒU¡#ìŸä «§ºþ?„‚où ¶X¸XÍýÌB4ïÌÔcqD§qKCÕÐoS’’ØY8±Ý¤ØZo‡â¹è'Æ¥ÂZP‰!M–øJŸ,ßúíÌF˜Iø+%uÙ1e!dëß¶{x€í.ÍBÑ7àÐ ÉÄe“–.KªC¬A µBð‚îÃDò9K"âýîÕÏ9že®˜1äée0`šH;k™‡ZO†EÖnü;J[Š)DVnÖÍ”* AÙ.ùw¦$¬«¯LfÆ®<ô‡àëö²R‡YŽ—X5Àm‚y÷Wµ$,à^É/þloø‰·ÙÈû6^¸k91¡»d!g–1x‡ ç¾ó€çÁõ@ZÃä§dµ6Y”Ö Vä&”W±EÇQôÙ ' šHüyeb£„½7¥~†=Œ,R©€y‰öqŠ]™KÔÈ1ŸteÁ£È*ÈÐ2_zQBÁñtÕBÚWM"+Æí+Ÿùèž°#à˜„5`5°Éþh #ùÈ[|ffÿôêÓ»31ñ/uô™Ç+ÅĹL Æq O=+Ê@«ó¿$æáõ]ØUHp§¸ˆ x¯;š›DÂ)ñ„ÕUÍ?)·¶¿wÁšåD¨X]•§ l­`ŽÁ–I¦ÏDžÿWã?ð ëºÑTó¬Ü^{‘.v”FGOžÃ>|Sãï`›>ot«2¸8Èê4‹‰Øê¾y¯6,7Nà)埿x4?0Ãu#)Úr¸[*îé¹v†Eª=MƒÞ÷ôú³iÒx»hL7Ü•&ªÛþ´ÒìwÑ6áj·ZuÿBtÐÜØ…/7æ!¤xXÝ“N@YRAÓ¹•òo屮$G£m\ B9Od0K‹6±vAH½_‰½ñnŠ$Þ¼MuèÕl¾M<#~PAöLî ìÇÑZ¡bÇš2yyH{ðñD–Ýìûñßµª{kÅÍuˆØMƒ‚‚ÿÛ0êy' «¬ß}I8¡Oš~ê©cY »N¶X@Ct.—•ÕŒ=·ÛÜg „!ª„ ÿLÄKJW5Güé/&s ê y3Äñ¬ß¥Gö–E¬ åó!’M‚õõ¡0â—äôÄ0è]³ÔÇU¤E±™ôŽ0™Ì͸6¦=äbÔ•c+¹P¶*B³+@c’>pG‚(¾bÒgäM$A›‘tR<³.k?•»w°]ÂX}ö±í›È‹u¥ÒIêeà©IƒSç„m80xµ`ê\kóè¯ë8Øèr¤Küï–ÿöTiáh4¢S}¬ÑBõ9ší ­ÚÓ¼~–—sÁo4ÃPè'i ?ËêóÏtÚ`³R-ºAÀ‘ Û5Í\³ hwf&T‹ªäݼ§jw=¼ppƒ9¯†´X‘/r«îD*\yx&ËtøºÙž}rvm¥´€¢c­3xÚ ˜Ë³ˆ¦“3cÀд[—4›qè´–Ey¦fô=ÚÇø°ãÏÜDjK:yiãO9>?þ²Þe¼îÈʯßseó+[†ûn@„Ž«I'll’Ç“²žu—î—Ñîò§Ç¹3LëK=‘ÿ‰m­h®-¦4Å>'˜•û#Žë¶½bÔ€É$Ôô­{uÒ›¶¹ï{S¢zã4UÍdˆ¸T-Y¸‹IùÕ‡E}M;mÑ}`àIìô¤xùsSfÊœ7EòÞ² ï ô`]>ï(™2®ó’[úWƒGU‹Í„mdz½¨wþø©_hI+¶Qu·GŸDRjB®gœ,ùʨ… •ÖýÝ€Å% ìš~²w÷¸|¿5ƒD­8Qã&"¥M9F ÇîeRö­¬ÎU_8›ü,^äN€±*˜™ðp=¥¾Ÿ¥—fûæà¥6UÎ.¼Ç° Ôí®5ÄÇx9xã 2¨ô’ÍÓuR]7øØñ@“#g Ù÷{ ®kU±ÇÿFÍ ¹v`üÚ¬Dºý‰QY„»î|1<ðesب¶ý+œé8ä66 Ý»P°ÜSWt›ß·wOJÝOÊE{^uijP[ÈF¦g/2go–LF ‚a»`ö™eQr”ÿÞ^.k€·’2·ØÝŒtôÂK:™S^ÑÏ̼èÓl.8é•àáÍ{„¿³œ|y6ÌíP½åµ¬bÀ¹%}y#x“šO%O x”Z Ì0Ñ}ìg ®0ƒÛÇCok;-¯ÍC]¸ø*o¨X Ò8eÜÚRWžWêðø>I v×¼uôO‰ÂÎÔÎÚ/â›o='Ï-æN 'ÿÕ9¡™ä {.lûý?ÚU®Vl²6é¥HœþW…#À¡Ò&Aôª×ÌS xWÿ.æl©^rwؤ£hm!éØI Ñý Å7Ø—8¡ðÐeÔ*¾þ"åzùë£í“E‡íI²jhj“åoÈŽ L”دL2úH £añÆÖÑW†Ó:ùdÐAÉ¢!ù g°ˆÿ×ݽ~mš[7y ”­ÑÌ10MÈ]C§¿ý/òŠíÞ0-¬Î¼Ï,˜ ½ÎÁáTômô2 y’qÏÓ[s´3‹£ìu¤¶4ÿ~^®Â=&–.•ĺðm_˜Ì.H•Pé1Þa°”Ó€k2¿xàÄî7Åa¯ƒ¦§7ô¢±ÅÓ¥uo瀰xfsÅãñ{Š®Gh¿ÍIIìÝ,DÏô˜J«hxZ֕ͧ‰j|ÚÂÌ;6¦Ë;&RL>KMCÃé?AL×Kà'µ”û0CTíÕ‹ŸoÅÙà}”¾¥tc±Ò«|5äõ²´•ÄØ>‘¼Æ­-¸QwÜñw缇(nøÒ:´Ô– ª”ØáSªn«.Z<éZ¿n z`—›`0I–Àà–ÄβÜ* þµ œIY«z{T´ÔŒŠ3PçÂëîî ‘ÖâÄ»˜q —hüÐq"`s;Ãô7#œ8ª@©ïrLsÿ¢”ý”ª™° #]T›<ÿîåÇ(û³ÐºDW€ÕEèšx‘ ®¢S ´™çéGº äG‚ÒX,d5ÝȶÙ&£/ÔÑúE£î¿£Ì&åAÏ,vx QôâF–ï]"1ÓÆ }rMòúâÁ‚4^ŒGKÝ1œ¢¹´ªv«ô´"Ð˺¼[Šb„Ù¼åþåfNVuð) ÒƒoðÏ—DûG¦®ø¹Öep~ϯa,« ¿¬Öª¸+P¬0ò)…¨ ÅöyY5Œš‰¥lû£‹o^‰•TòJnVÑãmšãy@‰Ä)?*´ õf­QMÒŽ¬v’aarG\&å{ïÊ/-æ‡=̶ûOQb7#e×tÐ6cž‡[u†‰jV'/nY·Ô7{qCë9qÝ}R/èä.Ú}ÔMÄé!÷o+rÌ·˜²…G#·JØ‹ãþøG—§çŽG9×»¨ª_”÷âµÓ±mßq¤uô{ÝnD#›f‘|›gäè˜qh’¹·Š|w} ÒÆQ0K! [èkÜ]¯ hM‘T! ŠÏ¿È—FÓ/p²Úž\$Roõ*wÿ¬“å;·†À4ú4k$ÉÓr¥:³\3â5ž#›rzüE•c&¹ÃrÒ"Ķ© MÚvØ÷c—´ï*3Z¾é,_üÅl3ÞdÖpØ÷Tµz6ö'°oCgxy"àû—@”çâì¾hãåÄzdÜôŰ&üd«ªp§=2MÈ9ð‰sÄ[}}§-›)cfÕ‰uÂÓâ F*ãÉç‘Dh»ÿ[†ŒEÛM@*ðÉîšH©PÉÝ9¤L+‰"ehHc¾8‚4Õky‚~ÞÁ:Qæ¸]€¢IæÔ9D8åFÚÈ£>Ö†“ßy} Õ´ÑSùÊ…íØ'³ ú7äµ:;h\4lLa‘¦>ÅÝLH dÇJѰÚ0°Þ…iëˆÃE|]6ºbÖ ©ŒŽ„²‚õ€“pŠ• N%Ú[Õ`ªÜhÀ?þ¦~v„‘oN`Q"æÀÔÝŠwÎÜ&IcKaJ´)eœÖ Û·Õÿn¯sY%0\/ô`r’G,sÿDWíï8üÀÿ}=ç ‘f@”¶Zê“ϳ˜†œ+GÙ¢x6Ÿ¶6Å ó¶GÎÝŒ ç<k\ÑS¤u¨æ!ÛÍâ€PÄO9¾` ßJ8lSgźƒÅ©œûR[úÀW—AÔöG<•ub@žØßð‚‡ë)±òu!›“·A;] ÒæI´Ëg ÝCóÎÊr “ÌÍQ°Ý¤Ä/Ÿ’âZ³N‹l8XñKõ¯µµ´~÷€ûŒü]HØÑr*d=›¯ÂS‚ßwчI¤ÂX š˜Ú”%0†š ¨$'ž®âÿ —då(t'o»@‰%œ° ‹€Õéjcn€Ü}*N..uj•«üŠSô ŠLâ‰ü4Òh¤Õ[´áB#âpÑuòµzpPžÏn可ÊHg';z™_QS"éœoäÔç9Ìf§qxÊý!î`súQi—žÌ/ɲò'©¸õ €Áe³õ”•ÅPu´»ï5pˆŠLD:½…Sk+ëv–ðJò_·ð‚û”Wô¥@Т§èª=êÏ“©VÜâùp$ƒ¡k›‡¦Uò¥± ÌŒF×5¶vJ²™àS¦û«3OŠS6éÊȧˆêk¥P›2C‡`Šj&}%1d$i¦Ññ6<“^뉴L¾ ?Z8àÕœ\ªjt,,ÖSk#X£Ã7ÁßåÛ»šûJØ=®—°¼}ññ(¨Ì<^àiKx¥›âvÃäÛGjg¿”b¯8@·›Á¾³Â¼çf± [,NñÆîczYúvSs»>´ûôÄÎ>£pÀ²Ï„jxѸàx N3)ü‘{4dqñ‹FD {+'(ÃöñÿO®Þ¬mk–M.(UXý8ÞšÔ]jPJH„þúmDÑ£­‚S´ÁžÂÂ]ÿSô¯B=ݳ΃8¦£.æ'µ‰y¡ŽÓ_ãp–9=¸ëêïxãG1éÐ÷ÿÔ¨P“m®¿;Þ;üEXwô»ã¬ïfp‹×ÅÄÙÊ5“ÄÕð‡M´ÈC&"k p~¹éßÓn)ë=£Q^õ|žã ’…øEJDÇû'QvÄ1ùæñ QÉhÏÚ'ñZ+Ê¢+ Šyt¢Ï OxqZRãÛÀt¥ä˜Ý’Ú©QUÄ,—ñ­   4KC™(Ãök ãÖ|‹Ÿíó•¼~bx{jûCÐ[^w¶Pæp2‰â?ò£›ð?ú”yA>’%D3o)²{ö3ôòÅåZ}ÀJë 2VöB’ß*ªlqsË¢¡×g6d,ÞŸ¥®BžnÈ(O ³k†T¨6{ÑLÔuâ0õjaøBîèQQKÓùÙ’ÉÀýÃŒ³V9 xÏ!DμÚôˆ*½¦ŸV¡&(g¶¬Oã³Ô¶Ôõ舮ò§ìά¼*Œ¸ÉÒ"Þ¹!°¯ 'w`>.E7ÿèòÙ‚EUÛÚ1%3>d _YŒ¶~·ì×&»+h ²ësšžˆá±­|KZi‰CUªÉ>Š1ÇÞ¤ÈӚĮPL’ÎÒºª¾È]BÌŒÈìKH±´Ð6bê¾õÉÛ”W©ÁI:´œô•{Üâga}µò þ²~mŒ¶3ÃR5»Û.£ÃÄ‚Ù7À´½,M|9%4oðòòŽªOÂ0°:¦˜A™ùöB‰:Ë˶×ÿÐøíÅU?ïþ†‚©Rd=á}ãí·Á·ŠPW Çû–d7‹éžòç™­}N{ª¤®~}ÍþTÛˆ’¯j²ö™%¬Æ™“Ç­Y}U_ÎèûD"à~¨Jà4RjJƒûιƒáoµš8q¼ßÜ%`,®Ú(2ÌÏþ“ŠûDÕ{k0 ˆŠfyœÛ·xè°ÙZ8ìEäêþêvã!ÖµL B8>n/Øá~º\O4É_yåãšÒþ˜²dD[ñ†’ä©pîXM¼ö•}ˆöu¢g+\;ïWü°„r‡:àr ºýöZ?ö’?%¸Š{‹ŸDÖ©Xð!/OáHŠšv¨0gÒ›?•E´…HU]_×ÛížKv1B§ö‰hN_Ð7Y!?Æ?ï g›‘[úéG‘–¢úÅÔšl=nfàHÃÒ€Æêû# ¯ÏDà!Ç…!ŠªŽ“xåZf8ýÑ·o÷5™¤QLÇE!BžóY¤|­ÞùóEú+kÞëÇ-#®ü¯ÆùGÎueQ,O^GjØû¡¬ßZ…-›á¹ô2ƒ+³1é熕¾¼ì¨>¯I‘H˜=ÆY»03Ø"á´ 1Ã?ÅAÄlb‘ûî…=8¶Ô%eº‡ßÂ\ä¥ZðÖz}a’èË0·þwØÈú’ñÁû$ ™cø46Q)NO—Ûp5d¹zÕRg…ýµŽ²ùrÛ]á´e<5‘¹¦UÚ'sAÙ|=ÚØO¶A$5ñ¥&ÒN$ºáÜ®´õ³úXwƒÉϤ°Y|ÍÅ£«S „X ä·õͳµÊoyw¥&§ÑÍVãjXm,8æ©i”èü|-ßQ4±Sµñ ß9´uþ¥¼aÞ8(ý«ê5K Z ¬ù‰Ë‹_–4jb•ªF8Il‰¶€9‚ðù¥°ù¨z^6ܧ¢À†BX;üÅð9BˆÙá@-pÇçà(i@§ø#©ÍP*R@ø‡„éýÒJyƒÆ?‰å7HN–,¬,²ºe…¡´ì³­o¾=/ ÙU¦ÄÙ"C]ýÁ£FžÖÙM§äÝÛq××(ßµ¶Æ’@¾ŠÓý¸éL nBkAyr·üúd™­j9î<Û ×áË‘‰\î¢N{+ý+\Åg Ó€”ï™eXZxý'Ùnù4_$2»Žµ&é`÷¦Ë"1V9)}qWŽQ¦8Æ•^§xy ŸÔUמ$•@àTüô5²ê›ü„y)6"w™™âžìÎPí´îéG•k“´Æ»³Ý¦>K°æ¢P8Q&j&7ø¨ÃŒÝÓWzí’w`l5Ø¡ÉÙ)ßÀìCŒ¾'€Š%ZÔ½Rp|Ëx1-aFÕfNâšPA òÙF<ŠÔÀk´Ív.c"¦NèÏ­Ô7M…„ÐnVXˆ½ååN‘ ›šS0I’ÒVØÖZº†¾ `o*ÒxRÚîL’’zäµúÓÆL‚¹$æ‹ãËsãÞ-\Œ¤U‹ÑÊp‰G²:üV?Â;7–æ7&ö†X7PµÑGõxßKÅ`âà“ÑW¬ÕËdwÀ{ŽãçÞXYáù?ƒñ@ˆW?~__½¿Íêñhð7«2ÅѤ\?oIíPí§è…ûdw¼¯ù×rl0ò×TÄgÏÒ ITÌÝÞAÏ1/„• ãlçËøó‚!)4á6 ÝÆBq4árwÓ2ŸÂ µßm)6‘{†-ô”V­OèpuœüË$Ž—ïghaMJÏJ âziè*Ÿ'6 .±Y9St‰it>í«¾Ím%xꉾè–Ê"<ºË? endstream endobj 6 0 obj 6557 endobj 7 0 obj <> endobj 8 0 obj <> stream –“´]­U´ÁÿZë¸ ÁOÄûiѼµñô6z ÐÖO]ùÉ"À’ù¶¥+êÈE)hÆòœ RUQè&‘¾QJÒcG$’E6­­yÈr/(Ja2=­S€ÝÃ’ïå[-X(âd,¾ÞÚk"¹½¶¬Ì‡î‹­‹ý/ejpéÒþ‘Bž!•y9}kH²CÐö€dªË:—”œüóµeÁNú• 9»û6Ûª@ëÀ†5|oÁ“.EêóÑ 1%èÈßÛ"÷ ½”-p<›®a ¥ouˆA›ž¾ — ÑT–¦_08gŸßz5bÔ†xV©>^C¨5#c> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer<0F4AD7BD3225496D4174E8D76D12897CC877CEED24DC9DB568A5637A671CE5E2> /CreationDate(µåÁ}y:s5Ú€\\d½"ã!ü£º)>> endobj 14 0 obj <> endobj xref 0 15 0000000000 65535 f 0000007789 00000 n 0000000019 00000 n 0000000236 00000 n 0000007958 00000 n 0000000256 00000 n 0000006898 00000 n 0000006919 00000 n 0000007114 00000 n 0000007478 00000 n 0000007702 00000 n 0000007734 00000 n 0000008057 00000 n 0000008154 00000 n 0000008330 00000 n trailer < <4CC2DA594C5DCB199E0D108A41E1AA2B> ] /DocChecksum /4234D31F6DCF9FDC719B74544277637C >> startxref 8470 %%EOF paperwork-2.2.2/paperwork-backend/tests/docimport/tests_converted.py000066400000000000000000000140531456262201400260620ustar00rootroot00000000000000import os import tempfile import unittest import paperwork_backend.docimport import paperwork_backend.sync import openpaperwork_core class TestConvertedImport(unittest.TestCase): def setUp(self): self.test_doc = os.path.join( os.path.dirname(os.path.abspath(__file__)), "test.docx" ) self.add_docs = set() self.upd_docs = set() self.nb_commits = 0 class TestTransaction(paperwork_backend.sync.BaseTransaction): priority = 0 def add_doc(s, doc_id): super().add_doc(doc_id) self.add_docs.add(doc_id) def upd_doc(s, doc_id): super().upd_doc(doc_id) self.upd_docs.add(doc_id) def commit(s): super().commit() self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999 def doc_transaction_start(s, transactions, expected=-1): transactions.append(TestTransaction( self.core, expected )) def index_get_doc_id_by_hash(s, h): all_docs = [] self.core.call_success("storage_get_all_docs", all_docs) for (doc_id, doc_url) in all_docs: doc_h = self.core.call_success( "doc_get_hash_by_url", doc_url ) if doc_h == h: return doc_id return None self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core._load_module("fake_module", FakeModule()) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.docimport.converted") self.core.init() self.config = self.core.get_by_name("openpaperwork_core.config.fake") def test_import_docx(self): with tempfile.TemporaryDirectory() as tmp_dir: self.config.settings = { "workdir": self.core.call_success("fs_safe", tmp_dir), } file_to_import = self.core.call_success("fs_safe", self.test_doc) file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[file_to_import] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.add_docs), 1) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {file_to_import}) self.assertEqual(len(file_import.new_doc_ids), 1) self.assertEqual(file_import.upd_doc_ids, set()) self.assertEqual(file_import.stats['Microsoft Word (.docx)'], 1) self.assertEqual(file_import.stats['Documents'], 1) self.assertIsNotNone( self.core.call_success( "fs_join", self.core.call_success( "doc_id_to_url", list(file_import.new_doc_ids)[0] ), "doc.pdf" ) ) def test_import_duplicated_docx(self): with tempfile.TemporaryDirectory() as tmp_dir: self.config.settings = { "workdir": self.core.call_success("fs_safe", tmp_dir), } file_to_import = self.core.call_success("fs_safe", self.test_doc) # 1st import file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[file_to_import] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.add_docs), 1) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {file_to_import}) self.assertEqual(len(file_import.new_doc_ids), 1) self.assertEqual(file_import.upd_doc_ids, set()) self.assertEqual(file_import.stats['Microsoft Word (.docx)'], 1) self.assertEqual(file_import.stats['Documents'], 1) self.assertIsNotNone( self.core.call_success( "fs_join", self.core.call_success( "doc_id_to_url", list(file_import.new_doc_ids)[0] ), "doc.pdf" ) ) # 2nd import file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[file_to_import] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.add_docs), 1) self.assertEqual(self.nb_commits, 2) self.assertEqual(file_import.ignored_files, [file_to_import]) self.assertEqual(file_import.imported_files, set()) self.assertEqual(file_import.new_doc_ids, set()) self.assertEqual(file_import.upd_doc_ids, set()) self.assertNotIn('Microsoft Word (.docx)', file_import.stats) self.assertEqual(file_import.stats['Already imported'], 1) paperwork-2.2.2/paperwork-backend/tests/docimport/tests_img.py000066400000000000000000000133431456262201400246460ustar00rootroot00000000000000import os import unittest import openpaperwork_core import openpaperwork_core.fs import paperwork_backend.docimport class TestImgImport(unittest.TestCase): def setUp(self): self.test_img_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_img.png" ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.pillowed = [] self.add_docs = [] self.upd_docs = [] self.nb_commits = 0 class FakeTransaction(object): priority = 0 def add_doc(s, doc_id): self.add_docs.append(doc_id) def del_doc(s, doc_id): pass def upd_doc(s, doc_id): self.upd_docs.append(doc_id) def unchanged_doc(s, doc_id): pass def commit(s): self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999 def fs_isdir(s, dir_uri): return not dir_uri.lower().endswith(".png") def fs_get_mime(s, file_uri): if s.fs_isdir(file_uri): return "inode/directory" return "image/png" def fs_mkdir_p(s, dir_uri): return True def url_to_pillow(s, file_uri): return "non-null value" def pillow_to_url(s, img, dst_uri): self.pillowed.append(dst_uri) return dst_uri def on_import_done(s, file_import): self.core.call_all("mainloop_quit_graceful") def doc_transaction_start(s, transactions, expected=-1): transactions.append(FakeTransaction()) self.core._load_module("fake_module", FakeModule()) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.docimport.img") self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) self.core.init() def test_import_new_doc(self): self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_img_url] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop") # see fake storage behaviour self.assertEqual(self.pillowed, [ 'file:///some_doc/new_page.jpeg' ]) self.assertEqual(self.add_docs, ['1']) self.assertEqual(self.upd_docs, []) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {self.test_img_url}) self.assertEqual(file_import.new_doc_ids, {'1'}) self.assertEqual(file_import.upd_doc_ids, set()) self.assertEqual(file_import.stats['Images'], 1) self.assertEqual(file_import.stats['Documents'], 1) self.assertEqual(file_import.stats['Pages'], 0) def test_import_upd_doc(self): self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, 'page_boxes': [ 'some_content_for_page_1', 'some_content_for_page_2', ] }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_img_url], active_doc_id='test_doc_2' ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop") # see fake storage behaviour self.assertEqual(self.pillowed, [ 'file:///some_doc/new_page.jpeg' ]) self.assertEqual(self.add_docs, []) self.assertEqual(self.upd_docs, ['test_doc_2']) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {self.test_img_url}) self.assertEqual(file_import.new_doc_ids, set()) self.assertEqual(file_import.upd_doc_ids, {'test_doc_2'}) self.assertEqual(file_import.stats['Images'], 1) self.assertEqual(file_import.stats['Documents'], 0) self.assertEqual(file_import.stats['Pages'], 1) paperwork-2.2.2/paperwork-backend/tests/docimport/tests_pdf.py000066400000000000000000000400041456262201400246350ustar00rootroot00000000000000import os import unittest import unittest.mock import openpaperwork_core import openpaperwork_core.fs import paperwork_backend.docimport class TestPdfImport(unittest.TestCase): def setUp(self): self.test_doc_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "pdfs", "test_doc.pdf" ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.copies = [] self.add_docs = [] self.nb_commits = 0 self.hash_to_docid = {} class FakeTransaction(object): priority = 0 def add_doc(s, doc_id): self.add_docs.append(doc_id) def unchanged_doc(s, doc_id): pass def commit(s): self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999 def fs_isdir(s, dir_uri): return not dir_uri.lower().endswith(".pdf") def fs_get_mime(s, file_uri): if s.fs_isdir(file_uri): return "inode/directory" return "application/pdf" def fs_mkdir_p(s, dir_uri): return True def fs_copy(s, src_uri, dst_uri): self.copies.append((src_uri, dst_uri)) return dst_uri def on_import_done(s, file_import): self.core.call_all("mainloop_quit_graceful") def doc_transaction_start(s, transactions, expected=-1): transactions.append(FakeTransaction()) def fs_hash(s, file_url): if file_url == self.test_doc_url: return "DEADBEEF" return "ABCDEF" def index_get_doc_id_by_hash(s, h): if h in self.hash_to_docid: return self.hash_to_docid[h] return None def poppler_open(s, file_url, password=None): self.assertIsNone(password) return "something" self.core._load_module("fake_module", FakeModule()) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.docimport.pdf") self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) self.core.init() def test_import_pdf(self): self.hash_to_docid = {} self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_doc_url] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) self.assertEqual(len(importers[0].get_required_data()), 0) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop") # see fake storage behaviour self.assertEqual(self.copies, [ (self.test_doc_url, 'file:///some_work_dir/1/doc.pdf') ]) self.assertEqual(self.add_docs, ['1']) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {self.test_doc_url}) self.assertEqual(file_import.new_doc_ids, {'1'}) self.assertEqual(file_import.upd_doc_ids, set()) self.assertEqual(file_import.stats['PDF'], 1) self.assertEqual(file_import.stats['Documents'], 1) def test_duplicated_pdf(self): self.hash_to_docid = {"DEADBEEF": "some_doc_id"} self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_doc_url] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop") self.assertEqual(self.copies, []) self.assertEqual(self.add_docs, []) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, [self.test_doc_url]) self.assertEqual(file_import.imported_files, set()) self.assertEqual(file_import.new_doc_ids, set()) self.assertEqual(file_import.upd_doc_ids, set()) self.assertNotIn('PDF', file_import.stats) self.assertEqual(file_import.stats['Already imported'], 1) class TestRecursivePdfImport(unittest.TestCase): def setUp(self): self.test_doc_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "pdfs", "test_doc.pdf" ) ) self.test_dir_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "pdfs", ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.copies = [] self.add_docs = [] self.nb_commits = 0 self.hash_to_docid = {} class FakeTransaction(object): priority = 0 def add_doc(s, doc_id): self.add_docs.append(doc_id) def unchanged_doc(s, doc_id): pass def commit(s): self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999 def fs_isdir(s, dir_uri): return not dir_uri.lower().endswith(".pdf") def fs_get_mime(s, file_uri): if s.fs_isdir(file_uri): return "inode/directory" return "application/pdf" def fs_mkdir_p(self, dir_uri): return True def fs_copy(s, src_uri, dst_uri): self.copies.append((src_uri, dst_uri)) return dst_uri def on_import_done(s, file_import): self.core.call_all("mainloop_quit_graceful") def doc_transaction_start(s, transactions, expected=-1): transactions.append(FakeTransaction()) def fs_hash(s, file_url): if file_url == self.test_doc_url: return "DEADBEEF" return "ABCDEF" def index_get_doc_id_by_hash(s, h): if h in self.hash_to_docid: return self.hash_to_docid[h] return None def poppler_open(s, file_url, password=None): self.assertIsNone(password) return "something" self.core._load_module("fake_module", FakeModule()) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.docimport.pdf") self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) self.core.init() def test_import_pdf(self): self.hash_to_docid = {} self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_dir_url] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop") # see fake storage behaviour self.assertEqual(self.copies, [ (self.test_doc_url, 'file:///some_work_dir/1/doc.pdf') ]) self.assertEqual(self.add_docs, ['1']) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {self.test_doc_url}) self.assertEqual(file_import.new_doc_ids, {'1'}) self.assertEqual(file_import.upd_doc_ids, set()) self.assertEqual(file_import.stats['PDF'], 1) self.assertEqual(file_import.stats['Documents'], 1) def test_duplicated_pdf(self): self.hash_to_docid = {"DEADBEEF": "some_doc_id"} self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_dir_url] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) promise = importers[0].get_import_promise() promise.schedule() self.core.call_all("mainloop") self.assertEqual(self.copies, []) self.assertEqual(self.add_docs, []) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, [self.test_doc_url]) self.assertEqual(file_import.imported_files, set()) self.assertEqual(file_import.new_doc_ids, set()) self.assertEqual(file_import.upd_doc_ids, set()) self.assertNotIn('PDF', file_import.stats) class TestPasswordPdfImport(unittest.TestCase): def setUp(self): self.test_doc_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "pdfs", "test_password.pdf" ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.copies = [] self.add_docs = [] self.nb_commits = 0 self.hash_to_docid = {} class FakeTransaction(object): priority = 0 def add_doc(s, doc_id): self.add_docs.append(doc_id) def unchanged_doc(s, doc_id): pass def commit(s): self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999 def fs_isdir(s, dir_uri): return not dir_uri.lower().endswith(".pdf") def fs_get_mime(s, file_uri): if s.fs_isdir(file_uri): return "inode/directory" return "application/pdf" def fs_mkdir_p(s, dir_uri): return True def fs_copy(s, src_uri, dst_uri): self.copies.append((src_uri, dst_uri)) return dst_uri def on_import_done(s, file_import): self.core.call_all("mainloop_quit_graceful") def doc_transaction_start(s, transactions, expected=-1): transactions.append(FakeTransaction()) def fs_hash(s, file_url): if file_url == self.test_doc_url: return "DEADBEEF" return "ABCDEF" def index_get_doc_id_by_hash(s, h): if h in self.hash_to_docid: return self.hash_to_docid[h] return None def poppler_open(s, file_url, password=None): self.assertIsNotNone(password) return "something" def fs_open(s, file_url, mode): class FsMock(object): def __enter__(se): return se def __exit__(se, *args, **kwargs): return se def write(se, b): pass return FsMock() self.core._load_module("fake_module", FakeModule()) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.docimport.pdf") self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) self.core.init() def test_import_password_pdf(self): self.hash_to_docid = {} self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Simplebayes and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch Simplebayes\nbest', 'labels': {("some_label", "#123412341234")}, }, ] file_import = paperwork_backend.docimport.FileImport( file_uris_to_import=[self.test_doc_url] ) importers = [] self.core.call_all("get_importer", importers, file_import) self.assertEqual(len(importers), 1) self.assertEqual(importers[0].get_required_data(), { self.test_doc_url: {"password"} }) promise = importers[0].get_import_promise({ "password": "test1234", }) promise.schedule() self.core.call_all("mainloop") # see fake storage behaviour self.assertEqual(self.copies, [ (self.test_doc_url, 'file:///some_work_dir/1/doc.pdf') ]) self.assertEqual(self.add_docs, ['1']) self.assertEqual(self.nb_commits, 1) self.assertEqual(file_import.ignored_files, []) self.assertEqual(file_import.imported_files, {self.test_doc_url}) self.assertEqual(file_import.new_doc_ids, {'1'}) self.assertEqual(file_import.upd_doc_ids, set()) self.assertEqual(file_import.stats['PDF'], 1) self.assertEqual(file_import.stats['Documents'], 1) paperwork-2.2.2/paperwork-backend/tests/docscan/000077500000000000000000000000001456262201400217045ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docscan/__init__.py000066400000000000000000000000001456262201400240030ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/docscan/tests_libinsane.py000066400000000000000000000156521456262201400254550ustar00rootroot00000000000000import os import platform import unittest import gi gi.require_version('Libinsane', '1.0') from gi.repository import Libinsane # noqa: E402 import openpaperwork_core # noqa: E402 import paperwork_backend.docscan.libinsane # noqa: E402 class TestImageAssembler(unittest.TestCase): def test_assembler(self): assembler = paperwork_backend.docscan.libinsane.ImageAssembler( line_width=5 ) assembler.MIN_CHUNK_SIZE = 12 self.assertIsNone(assembler.get_last_chunk()) assembler.add_piece(b"abc") self.assertIsNone(assembler.get_last_chunk()) assembler.add_piece(b"def") self.assertIsNone(assembler.get_last_chunk()) assembler.add_piece(b"hij") self.assertIsNone(assembler.get_last_chunk()) assembler.add_piece(b"klmn") self.assertEqual(assembler.get_last_chunk(), b"abcdefhijk") assembler.add_piece(b"abc") self.assertEqual(assembler.get_last_chunk(), b"abcdefhijk") assembler.add_piece(b"def") self.assertEqual(assembler.get_last_chunk(), b"abcdefhijk") assembler.add_piece(b"hij") self.assertEqual(assembler.get_last_chunk(), b"lmnabcdefh") self.assertEqual( assembler.get_image(), b"abcdefhijklmnabcdefhij" ) class TestLibinsane(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.thread.simple") self.core.load("openpaperwork_core.work_queue.default") self.core.load("paperwork_backend.docscan.libinsane") self.called = False self.results = [] # drop warnings logs from Libinsane because they pollute tests output plugin = self.core.get_by_name("paperwork_backend.docscan.libinsane") plugin.libinsane_logger.min_level = Libinsane.LogLevel.ERROR self.config = self.core.get_by_name("openpaperwork_core.config.fake") def test_list_devs(self): self.core.init() def get_devs(devs): # not much else we can test: depends on the system on which we are self.called = True promise = self.core.call_success("scan_list_scanners_promise") promise = promise.then(get_devs) promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertTrue(self.called) # We need Sane test backend for this test @unittest.skipUnless(os.name == 'posix', reason="Linux only") # Test is broken on ARM 32bits for some reason @unittest.skipUnless( platform.machine() != "aarch64" and platform.architecture()[0] != "32bit", reason="not running on ARM64 or 32bits systems", ) @unittest.skipUnless( platform.machine() != "armhf", reason="not running on ARM32", ) def test_scan(self): TEST_DEV_ID = "libinsane:sane:test:0" class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def on_scan_feed_start(s, scan_id): self.results.append("on_scan_feed_start") def on_scan_page_start(s, *args, **kwargs): self.results.append("on_scan_page_start") def on_scan_chunk(s, *args, **kwargs): self.results.append("on_scan_chunk") def on_scan_page_end(s, *args, **kwargs): self.results.append("on_scan_page_end") def on_scan_feed_end(s, scan_id): self.results.append("on_scan_feed_end") self.core._load_module("fake_module", FakeModule()) self.core.init() def scan(sources): source = sources['flatbed'] (scan_id, promise) = source.scan_promise(resolution=150) promise = promise.then( # roll out the image generator lambda args: list(args[2]) ) promise = promise.then(source.close) self.core.call_success("scan_schedule", promise) self.called = True def get_sources_and_scan(scanner): promise = scanner.get_sources_promise() promise = promise.then(scan) self.core.call_success("scan_schedule", promise) promise = self.core.call_success( "scan_get_scanner_promise", TEST_DEV_ID ) promise = promise.then(get_sources_and_scan) promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertTrue(self.called) self.assertIn("on_scan_feed_start", self.results) self.assertIn("on_scan_page_start", self.results) self.assertIn("on_scan_chunk", self.results) self.assertIn("on_scan_page_end", self.results) self.assertIn("on_scan_feed_end", self.results) # We need Sane test backend for this test @unittest.skipUnless(os.name == 'posix', reason="Linux only") # Test is broken on ARM 32bits for some reason @unittest.skipUnless( platform.machine() != "aarch64" and platform.architecture()[0] != "32bit", reason="not running on ARM64 or 32bits systems", ) @unittest.skipUnless( platform.machine() != "armhf", reason="not running on ARM32", ) def test_scan_default(self): TEST_DEV_ID = "libinsane:sane:test:0" self.config.settings = { "scanner_dev_id": TEST_DEV_ID, "scanner_resolution": 150, } class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def on_scan_feed_start(s, scan_id): self.results.append("on_scan_feed_start") def on_scan_page_start(s, *args, **kwargs): self.results.append("on_scan_page_start") def on_scan_chunk(s, *args, **kwargs): self.results.append("on_scan_chunk") def on_scan_page_end(s, *args, **kwargs): self.results.append("on_scan_page_end") def on_scan_feed_end(s, scan_id): self.results.append("on_scan_feed_end") self.core._load_module("fake_module", FakeModule()) self.core.init() (scan_id, promise) = self.core.call_success( "scan_promise", source_id="flatbed" ) promise = promise.then( # roll out the image generator lambda args: list(args[2]) ) self.core.call_success("scan_schedule", promise) self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertIn("on_scan_feed_start", self.results) self.assertIn("on_scan_page_start", self.results) self.assertIn("on_scan_chunk", self.results) self.assertIn("on_scan_page_end", self.results) self.assertIn("on_scan_feed_end", self.results) paperwork-2.2.2/paperwork-backend/tests/docscan/tests_scan2doc.py000066400000000000000000000075561456262201400252110ustar00rootroot00000000000000import unittest import openpaperwork_core class TestScan2Doc(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.docscan.fake") self.core.load("paperwork_backend.docscan.scan2doc") self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") self.results = [] self.pillowed = [] self.transaction_type = None self.nb_commits = 0 class FakeTransaction(object): priority = 0 def add_doc(s, doc_id): self.assertIsNone(self.transaction_type) self.transaction_type = "add" def upd_doc(s, doc_id): self.assertIsNone(self.transaction_type) self.transaction_type = "upd" def del_doc(s, doc_id): pass def unchanged_doc(s, doc_id): pass def commit(s): self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000000000 def on_scan_feed_start(s, scan_id): doc_id = self.core.call_success( "scan2doc_scan_id_to_doc_id", scan_id ) self.assertIsNotNone(doc_id) def doc_transaction_start(self, transactions, nb_expected=-1): transactions.append(FakeTransaction()) def fs_exists(self, file_url): if "paper.10" in file_url: return None if "existing" in file_url: return True return None def fs_isdir(self, file_url): if "." in file_url: return None return True def fs_listdir(self, file_url): if "exist" not in file_url: return None r = [ (file_url + "/paper.{}.png".format(x)) for x in range(1, 10) ] return r def doc_id_to_url(s, doc_id, existing=True): return 'file:///some_existing_doc' def storage_get_new_doc(s, *args, **kwargs): return ('new_doc_id', 'file:///new_doc') def pillow_to_url(s, img, url): self.pillowed.append(url) return url self.core._load_module("fake_module", FakeModule()) self.core.init() def test_scan2doc_new(self): def at_the_end(args): (doc_id, doc_url) = args self.results.append(doc_id) promise = self.core.call_success("scan2doc_promise") promise.then(at_the_end) promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(len(self.results) > 0) self.assertEqual(self.transaction_type, "add") self.assertEqual(self.pillowed, ['file:///new_doc/paper.1.png']) def test_scan2doc_upd(self): def at_the_end(args): (doc_id, doc_url) = args self.results.append(doc_id) promise = self.core.call_success( "scan2doc_promise", doc_id="existing", doc_url="file:///some_existing_doc" ) promise.then(at_the_end) promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(len(self.results) > 0) self.assertEqual(self.transaction_type, "upd") self.assertEqual(self.pillowed, [ 'file:///some_existing_doc/paper.10.png' ]) paperwork-2.2.2/paperwork-backend/tests/guesswork/000077500000000000000000000000001456262201400223235ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/__init__.py000066400000000000000000000000001456262201400244220ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/color/000077500000000000000000000000001456262201400234415ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/color/__init__.py000066400000000000000000000000001456262201400255400ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/color/test_img.jpeg000066400000000000000000015364311456262201400261400ustar00rootroot00000000000000ÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ àÆ"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?÷5Sž9¥ÀéF=J^>”€Lך8sKÀdzÐpqšC´õñ§~ñ‚A üÐG9íïGè[ëJ0z@ ÏåG §` 8õ ñÐõ£õÅ;ŽÝhäžh›XzKƒÔr=©Ø÷£µ7o8÷¥>‡ôï—>”Í¿1?¦iy@ǹ§mïÇáK´G4ܽýq÷Gäiß6=>¢Œæ€É<®(ÚGÓéOÀëš €=9÷múãÚ—+Óuä÷üh9ÇOÎŽaùÒãƒÅ/^ÔÒ299ü(ÀÆ4½(Î:þF˜ 2}3õ¥ç®8õ4`ãü)g¶Ú? 0:ž´í@pz\œŒPü(ü)€dö£­RãÒ€tàQøQøQùŠ'J\zQ­-K·&—·4‡ó@ ´c¥¥/¹¢€…?Z0}qE¥àŽhϱŽ3@ Að(ç¹  !#¿…¥çµ!<ôé@?F1Ûõ¤'Ö×½(úÑž8*sG?ZL‘×½;çÛ4dŽ”…½('¦huúú‘G?‡ÖŒúš(8Î)ªþbåwcéŠvGÿ®‘¶úäúf† êOçF8¥êsFOoÒ€¡Æ1GAÍ.ÞÉÅÛØŸ© £8½ýé2ÙÆÜ{ÑüèséHHô£¾hÁ÷‘ÔQ»=ÿ*Nz~´¸úÐõà}(sÁ¥çô‡=¿&Op)û{â“a@Áàý)GÔ¥!ïÏ>†€žŸäÐO¹Ïµ/,0GåF= úPväŸÎŽ˜ÇJ_Æ‚O çH3žÃÖ—äu÷£sŠN†ãt¥žŸ/N¹4Ñî>œÒóŽW”sõ£#žH yù…LRîôÓŸSõÍ(#< M˜ÿëÒ‘ê3@Ø™SÆ¥Ôî}8õ¦àuÐÇ­TŽsJ¤ çרšLÿê£åõÔìjL£ Ž3ùQB)qíúÒt翽&í@9õ¼9ö4áõ üÞôwëÒŸŽÄRè?Zn;ÑŸSšu7j伎”dç’?­/^?4 8<Ž´œþïlÒƒ@ ËKÈíùR‘ëùRp{  ÀéF}3øRþŠ\’8Q@ Ï<Ž~´¤ÿ³Ç­(ôÅ>´ AÍ(úsAëÈ4œv œv9£9íFi»ÍÖŒûÒ uÛŠOÃP8㟥w&“9íùRî©>Ô½ºP2~´›³F7P îipOÿ®HFOZ\F=¹ uÁ₾ÔdZ3Ÿþµ ã¶)zñœ}(3Ž»©x#ŠC:ãéK@=¨É=¿*LsŠSõ`ŽhÏlG‘AÁ tëF=¤â”§å@ ノ}¹¥çÐ~¤à{ÒÐy¨Ýž7 Òà{ÑšNOqF¿áKÇ­ÔÐtç“’21Ÿz\ûÒ΀ÔžÔ´~tÜ…ã“ùÓ±ÇZ(0¼( úRð;hÀ íÀéFÞ}éÞý( äu™ZPéKJgÊzRñœñýiÜÑ@ üæ—ùûRûi2=è3ìã¦~´¿OåF :Ú”~4gÒ€ gÖŒzf“ŽÆ—“ÇjL‘Ö”Ž˜£ êhã>´˜õ<úS±ž”f“¿S@ ·Ú—QÎ;þtt£¨éŠ\žÇ4Ÿ…ÐIRÑžý(ØQŠL_ÖŒú`Á£(Ï "ÞÔ}úÒsïKÎ)~t<ÑœŽHü¨Èÿ"€ì(8úý ÏRóŽ”Ànr=‡ãKôQÏ¥zþ´ê?Z^Ôqíô¤É¤¨ü)¨ÏÔSqŽƒpúÔ™4núš@;˜÷4€ƒK@)h¤ ¤Å¥ë@ Ó¥&=qŠu&{P`qƒA¿­;õ¤äõèüi3î?:\ñHOµ0 Àæ“è) 6úŒRϵ/^´ß¥&ã@~4„zÒ=éAÈ‟JLÅ8Ñ@ Ç~”})y=¨Çµ'ùëGÖŠ8úÐ{A‘¸¢—?¼j)›ˆï—†îÒœ§ò¤g@nçÀw¨æŽýt¸o¯Ö€~ oÍœñíRdzþ´güæ€3ŽO4¸ïš^ÇçHIþðÅ&@M-ã ““Ô zÐäãÖ“–缎øšNGB*\š1ô£š\ÓŠ\qɤ>ŸŒýï€Ñ€ Œõ”séŠ1î^{S9ÈÀ?8sIþzRàvë@ãKIŸz2?ýt\ÑøÒgš2hçÖ“Ÿ¯áIŸ­Íö¦óïFOp(Øöüi3éMúQž•KžØ&›ÿü©GJ\J:ÓsCJ9 þ_&:RµÍx£ñ¤$ú =裧ZL“F ö£æ¿Z=‡ëG>˜¥éÿÖ£¯oÊ€§|QƒßêNßýjNsF-ߎßáGåA÷4œõÏÖ—ƒÚŽqÈÏ¥õüèâ“Z\ŒýìÑô4™^”¤J ÿ"“>ôcñJ] Qž(ãÚ€óÅö`OŠŠ1ô£ô˜ P ý(æ—ô„sï@8äÑ‘ëFÐzŒÒâ€rhÀã¨Ç½üE/8ëŠLg¸4séùRóëÇÒ“… ÔÆ“ŒôüiÀÒŒýh™&3ÓŸ©§dvvèOµŒž‚—·éKÉíŠN;œ~4wïùROSš^½ÍwæéÒŽ})F=õ Á÷ ïùÑ€xÇ4›@ê—Ö‚9ûÔ¼zþ´}h˜=±J2i ÓŸ¥&1F=1GÌ=OáAÈïŠ&Ú:÷Å;¨çšNØÅ&ëúÑœô=)~£ò¤+ì?\š(Áô£¸ A€hö£ŽÞØ¥éމϵ' {Òàž„ÑÆ=è£Ú—§zLÿUãƒG^F¥#Úÿf—èi{zQHçÒŽ}¨Ç 8Å&.xã§µåG×õ¦r8Éüx£>§—§qô£ð€CŸ­ˆ¥ú PxOó ãÿÕK“ۤϾhàžÙúPÏ·çKÉïùQùÑ’8"€ céIǸ¥&¨4~"Ž}Z>€~4sßšCƒÆAö4qÜŠ\})ÏJOÊ—ð=M!Ûש„‘Ù:\žâŒñ×vÉ<ú@òíIƒžƒëš^½é0;ÿ:CÆ ?­/^ô`ú>”¸úÐíÅ(Ï÷ŽiØ9éAü*NzQŒúÒûi01ŽhëÞŒ´¿Lý(ú PpGCøf—œt£ð çÖ€Ú—Ÿ¥¸>˜ ¯\RàúRsQF3žhÎzþFŒs‘ŒûQÓÔÒôì(2ÏÖ—¨¤ÀÅw($ ? þ4dû ^{‘øRŽà“KþzQ@ Á<ãëŠ^=i3ØÐqÿÖ ɣޔ~4qÞ€ ŸZ;õ£ñ ƒŽÆ€ÿãAé×ò¤üMâ€èqF­ÏÊŽ3Ö€Ò—ñ¤÷ûÑúPøš9ï@#µ9â€íG u¤ëÖ€qØâ€$Q“íFï^)3ÁÁJw>´„Æ“vÅv =>lÑŽi¸Ç§>‚õâ€õ4ïMÎ8þ”œâ€FN94ƒ4´dÒÒdúÒ:бIÍ!àu4Lü…/8ëùSsš÷ fŒZJ1þs@ “F椥 BóIŒw¤ú”6~¾ô ^½(Æ)(úçÛÐ3E/çH:œÐôÁ£Ÿ¥zÑøÒæb(ÏÖŒú昄öÉúQƒØñKþzÑ‘ë@ÄÆ9É£9¥Ï½÷Å&HëK“ŸZ>´gð ž´`ö£ðýhëéùÐb—š?:zCϽõ'qê)6®sÆ}¨{ýî(Ç¿ëH1éKÚ€OñsAÇvü©zçšCõÍ <ýãJÖ“>橦³ù{š8õ™aéFü….8Çj3íFáÜ⌃ü_•ú~tÓRçÜRzœQš2;P3íùSúñ@ãßêi}À£'(;õsÜæ”š8í@ ?ZBqÔŠãHG¸ü©dú~T óM#ëøRd÷&€yúQƒëL qÉÍ)b@Í/Œz‘FáÞÀ3@ÿËF¢ƒÌ­E!‡Jl‘‰nqߊuž?¥1Î;=æ—>ô„çÖ€ úG>”n?Z_®(ǧò¤ÀôïóÅ&G¾}qÅ&}œÑŸzLç·Ö€¾0Ãßµ.Oÿ®“ì8¥ï×4tÿ ?Aàôüèãé@#¸£#ºþ4¹=±øÒdw#ðdç¾;sKõ¤È­&yëœ{Ї>”e³”:oÊ}3G§4ðOCJ¦ v=(Ü}èL`pqI\hcê ;"€ÏcFÑK×ÐÒý 7ÿõQíƒKG˜ë×ó£…/ÐÑí‘ô Æ: 1íúÒñÔâ€E0 ´QŸzinÊyüéìàv&}?Jnrq‘žüQ׿ähÙÏÖ“9ã‡=Hýi{rx¦ éÆçGž(=?Z03Ðçé@ïµÇSÇ¥gÿ¯@ 9 míÇÖåG4‡™4_ÂŒŽ˜j9ì(ÁîhëšL}0þtr8ã€3Ü _ÄÑèF ¥Ç­1­.÷¤#ŒuqÜhëÐó@½¿åKøÐÓéIœv¥öÍ&}¨p;b“ öǽ8æ“÷ µsFßS‘KÛ@„üéy÷>ô„ñœgé@<ô4 ^‚ŒñÈsÛŸqü¨g=3JséGn¤éž(ÀÏlÑ‘ô p:Òö µúš@)Nh™çîÂŒ³GþªúÐ àvÅ.;òi3íK_Ò‰Áìip~´ŠNh8>Ôtõ£'ºþ9¥Ïù~tqÇ4gÓð¤ÓÞ Æx<ÑøóIøš:u'ò bñI@Áèiyõ Ûè? ÒÒ{dæ”tçµö£Ÿ­=²('¶q@OÒŒ{~tQŒë@ ö Z:ô{d~4k£æàfþyÖUpU”iÀ``túÐ0çÒŒžôtç'ó c@¥/áIõ?•ñýhÆCùÐ(éÚŒñÞ ™àøÒãÛ 8=¨ÆzÐzsK@ Œv¥Åp;)1èqK‘ô£õ “Ûmõ掞߅ Rcß….~”cê(ëØ¥ÇAFON£ÖŽç4À=Åuãñ¥Èõ¤¶ü)`ÑŠPhè:S9÷üèíëGz0ýTdç ÇÒ“´¼ñÍ~T€Lcµ.?*íý(Áêi€mÏZLzR‘šLŸ­ =E/Ó­&9ÎJ^sÖ€zLñЊpö&Žh?øÑüérsßñ£ô™ö£v;Rñê3ïF(2{ãñ¥Ç ž´„­>”cÿJZC‘ü4™èI¥À‘úRÊ€ÆÆ—ñ¥æÆ€?ýz)zQÅ'ãE-&}Å>´Ÿ;šLƒë@ ´¦—QGáG4p}iÞx9¥9#·åFx Å'ô4sJ3Žãó ð4}£9£žäâ€ÿÐÑϵ. LóÿÖ Œ{ÑïÈ¢ŽÝhÇÖŒcÔQÏãGJ1Ÿ_ÎŒj\çÚ“'=¨p?É£ÒŽ}¨4¡Ö­=¿ 9õ`vÍ/áM>üÒäö½ûQø¥ 縣?•#ž?±ô£AIø ^Ýhé×&Ž=©?21žhãÖ—ŸAùÑÉ÷ úcó¥ühÇÐ ??3øQÞ‚i>¦€}8úÑÏÿ®Œút ãÖ€çF(Ï­Íõ£R(ö£™çŠ9÷½ºfßìšLqóu÷£¥.IôOÊ€ûÒòi:ÒóÐPù~t ÑøRgÚ€ŸZ:Z3QøQÍ.xèqF}­¼S†ŒP(ÿ=(ÍÝEÿ8£Çô èhÉéGn´cÞ€ R‘Ÿ­'¶?Z(éÐQÏb(úƒŒdñ@=hǶ(Îz)m=è4™Í/CŒS:óš1ž˜¥â“ùÐ=ÏÒŽAæŽz‚}(àu4€=¹£·SGçgñ àu?™£æô§}pi?_Æ€¨ü ¥ã§c×ùÐ`Š9€>´ÇJ9æ€pî?Z7òi2­zœûÓAÏ­)'ãMã·?Ÿ• ÖŸJnìŸëš\ÐçÔ¿ZLû~”;Šq8õ¤üèühãÖ€î?*2= /¤?…&?]¸íGnÔsŠŒ­o ¢ƒþ¹¾”RŽÍ/¨æ›žqÔÒþ"˜…æ“é@>çr~”¿­õ•'>¢ŽÝGå@ 2¯#=)ãd ŠŒ’;WAORŸaLqœcŽ{RdÓSH[AHöÉ£Ÿ\R~&—-ØŒ}(ÀÿëÔ_i€3¯˜2EHI ÐžZOBÔR`ýiBл=3Fipÿª—hõ  èÔÏ>## uÜ£œ”ò¾µ\Â|×+;† nþ” ,¬™PCpiÛÉ E{"Q·ZvÎsŽ}hLÿ³Fð: fÞ:óõ \Æ€¼c9£’ew; äS¸Çô¨§ˆ€›‡¦q@.a|ŒŒrÊŽîáúUu· êZÙ@+‚wŸÖìÛEØDxÛ’9§ ô-ï\Ÿ‚qÍ!u¾`õç¥Sm¹@b»·ýþ §Éf², –g`zRÐZ‰=3ÊŽúôŠ p;õ¥ þÎ(¹?J2:ƒúRmáKƒØÐóéF1MÏáŸO΀ }?*\Žæ“>üPqŽ¢€@þ*3ÉþUCPHÂÓ‰2®b9÷ÅIh±$²„g,1»sd vЫèà œ­/ãÍAt¹·`wcÕA&‰w¡—Ô¿åY°ýœ\p\±äšÑÄÓjÀÕ…ã´n¼ÔRÊ"M冪/¶êé±3l+ŒqÖ„® e€ëΓpõª‘Z"… ÅÊðN1Oû,~[¢ä+uùºQ hZúšNª€E®æÝ·¡9ÍM¾bóØ‘Á¢ÁbRyÅóÏnâãž?:«=”Sɹ™¹ûÀf’Ð`FA¥Î{Š ÚtQ«°’T|ØjŽ3˜‘neã×<Õ$žÃ²4ËFyã5@ÚÎÑ·x;·)ÛÛÐúÕˆá‘&g2î·Å+.â'Î9íô¥ÏÒ›œô4É%H±¿åÜp $ã'žiI¿áYŠ^äΩuÔðFÚ˜ÙæMæáÁ)´Óê)Ø,\ÏÓš7`€?Z¦¶Œ±ª ¦NKÎi#) ¸y2Ù8ãùš,‡böIíHiÃŒƒúÒçéH@N>¾´†E°°ÝŒãÚ©]\#!Ž9„m»Î:u½«½ÕÌþ{²°§ƒŒuÅ;w<‚2Å&qÔU#dá•„íÇQŒ "Ybœù×(F8QÁ¢Ë¸Xº~½é« q”9úS¹4„(úçéE'ÑÈúP!zûÑǃߕ(=1Š(ǹ Œô¤Î=½§$ŠåL`HùXôÍQ”yR.ë•W'#··4Ò¸#Gõ£€VrÅ4žhŽpìõæ¥)t’ƒç ˆ„rOçE¼Çbç4g=ÇáPÇ:2¨Þ éRägµ&„.}èÍ!8íYÌó‰.|˘–>6|ÙÛõ㊸SG=¹üj(ŽøWæVã¨èiýùò %óÀ÷£*z‘P]<¢<Âè,x¦C#;!óãqŒ6ri¤-õïI“ëF})Õq’iìÒgÞ©Èf}â)°Ùù@ü]2·×¡÷§`±d~~ø¥ªköÏ*=Ì çÈüéñÉ2»‰v„^…G'õ¢ÁbÆOµýz@Û€ õ¡Îœîz @;ùRgš¢O$•7oîÝGÖ¤?kßò”Ûôëô§aØ·øQÍRV½RKF‡èÞÕi7à7¦iXVš3H7Lê($´½úÑøÔo (#v2ªÈ÷OcË'<óž>´Ò‹¹£ñªCí»_>Plñô¥i/œR06œqüéX,[Î{þ”§Þ¡ŽS³2mR*\ÇÚ€žß¥ºÂàrN*¼Ò·™²7L‘Ó<ÐÀþ4¸öª‹ç„ºç³QºçÌ|(Úzv ùõâ’ªÛÍ)$JWå<»j×ëI«CúÑFG·áG>ƒñ “éG掾߅¤àÒ~&“æü)sŸþµ)擌õ4~½©€~TœãŠ>´gØÐ×éíGÖŒÐO©¤“Ó™8äÆŒ/×Þ” t4g=¨ ûÑ¶Ž”tèÈúQŒZŒo­{ÑŽ„ã4`úÑ€9Ç4¿Î“ŒÑô£E'¼Òõy£uü¨çÐP ަ–ÝF~”½¸ #¡ÍÏsFN0:ÑŸ@  §­ÊŽ}héÒ€óÅCIøÐhx4`­!÷ò£¢Ž}¿ 8ÏzOÌRýM=h>™üèÀïÂ`(ëè(ú(QŸz1È éÞŒþ4p8Î {P>ž´´¸Å&}À ŒðFi~¸?J:ûÑøPRÒ˜c×ÐÒ€1ҀƎýJ(Èõ æŒsØÑžÝ(ü¨Å_åGÖŽüb€GjL{ÑøÐÆzóF9ëGÓ¯­žô§§9¤ÈÇz9£qëš3ÚŒš?1ÏZÔ~t}(Ø ühäžØ£cÀ1KÅ%/Ö€ÒŠ0;@úŠZ\Rs@=¨ÉôÏãGÒŒŸò(ü(¢”q@ Í/èý)?ïüè Q“Ü~Tdö4RçÖ“ñÅ/ZN½GéGn 3@ ‘š?:Lv ãÿ­@…íŠCF¯éK@Ä£œÒÑôŸAKÖ¨ýh"€GOáF8ÿ^{QÍíGåGÔQõ4v£ñF=( ÐÓÖŒ}~´sF1žiœdpsïF>„ûRñÓ­ö Å&ßqùS³Û“ïIŸsLA´RzŠ\ñÈü©:uâ€=?Z^>´ÞùÝš6ޏ v}¨Í&@ëÊŽ)¹îE‡æ)8õý)z÷zP—>´Ÿ­‡×4¹ôëKÏzn{G#ø¨‡ýkQFs#QHbqÓ'ØRàç­5†HÜÃp;þtÄ;ž (ëÀÐGl8<v{’?*BÞù£úÑÐqŒûÐA–>^}jE^ÇÌ2>Õ*ò$þÀvÑŠL`ÑAIŽ)§LÒu<õ£ÒƒÍvmýj0}½¨#=Ž~”Eߟ/·QK0ŠGÖšÀ,™ Ž:txeÎìûÓúLc±¥©GÐ})i©àÿZ€GÌcŽMY#­B'p99ô¦†L8¥ c°£o=?:B g§ëKÈÎpE<*1ëǵ0ƒ¶*œ‚;'sŒcoåìF}3QâFùבÀÏJ!aEŽ%ThdÿIÛÖš›¼°¯¨æœ8íùPÁ‰·?ãK‚;fÌÑŽ9${P ÎyÇᚊãË1&vž¸É©qž‚¢œ(á2:“@Èá~ìÆÎT ƒV1 òFsŒñU#Y” [ˆä;~öqŸÂ–(ïGæHŒrwvªvî6[Ààtö¥Èõª ]Œåã?7§j³Áãõ©¤}i1îE.áKŽ8#ñ B 9újP}0~”`Ç>ô‡š1K·ŒgÒ€ ¼ÑÁçÒmZB  Ë"D“Œœ;Õ6\½Æn¶nêr?:/à7,F+†±Á¥ŠË/3\le“U+X¢ÂÌ‘ª'˜¤ã‚GZ«3‰›ÌŠé—}({W ­P0àãò¥6Â+B(Þ@sÏzjÛBÄr"€¥'ڧǵRŽ6…1Ds‘Wr) \ù¡?tP6áÔgŒÔkæyøyþÇó§Ý«˜HXV\‘ò·J†&èƒnŠ€¬$š"¹Öœ'?Ý Q‚~•$•§ùf\M³ŒcûvÜŒC†äƒÆ)$W3‚!SÃÍ-²•Sº-¼œ`ç5] èLHœÑÏÖ—ÔQžzçÚ¤‘­ÆÒªDde@‘š¹!m„(RØà•D@Aƒu²dK µQ)×8ëJzõ4ƒ Æ¥Î;ãéÍH„ÀAr³e<¹܃ŽjÆ­T¼hG•¼oçȦ·I>c’ÄŽÃ0-èsU¡\HL1Üô5dàð!C#¶=³UJˆ)œðZ­à qÏóª xåm¥8nvã“ùІ‹“·–Rsü"†rŒw”ô8éõ¦À 'B¤ŸâëR‘ëÍq=Ìö‘ðC|ÌœÎE[¶lXb7’Kc¦j•ݬVñ™£·ÜäÿädÔ©qsæ´bÐyarvI4÷C/`tª²BÆìɱJ„ÀÈç5^] ¤[ §ûÇ©cº2\y~K(ÛÄqBMjcí‡î@Û·¯ÅMÇêi*?RÄòö¥Çµ'¹ ŒÐÛ?…G RãÖ“ñ m.= ¤ã×?J?ÅøPAüj•Üe¥Fò¡|eúÕÜÿתHŸiMÐÈÙãršqÜ-²24ã‰xØ1Ÿ¯­Nñ¬¨QÓ Ô6¤ùŒÇÎMYÇ&‰n  Ðy.¦ HÉžµj‘÷o‹aûÙÍV¹Tgˇ%[*9?X·Qµ¾F<ƒMì>„¹·5H¤†KƒäÎ6îнƒéY“lܲ^Êô¢¿ü‹¹T69ÅIŽ1ŒÔVà,JnŸÅRã4˜™ÒnNa~£Š†Þ0’.Û]™ÎX¶qR^2¬xmã=0E2»ãPd`rCÁªŽÃ[0jµ×š^5[e‘rÄŽ*Ñô¨.Š*.âOÎøBÜ”f¥Æ9¦JU#fb@­I%î#Ë™I±=~•¢:ߥg%ž“Œ,œúëCœAªØÉð`m/‘÷Tòj¤ªÊJA(ÀÁðjÔê<‡ù¶ uôªqËš3tÍ´cDA=LQÛŽ´œtõ£Œ…HŠNÉ*â@Äó€?J·Â’O¿SUÝ€–E cÛÓëSÄ– Ì$t§Ð} :{¥‚/N?Z_Ãð¤ öÍÏZ8”dž€~t¸÷¤ü(ÿ€þ4~GÚ>ôc¿z6ã Å0hç½tëGJ@ü¨ÀÏAš8ôri€tô¥üúÓH=±øÒã#š@üàÑÀúÑ×µ&)€¸£sÒ“žËúÑϦ)¾ÜQþzÒ)A…SÇ¥ôÀ£¯¸¤#Ûó4¹˜£Þ€½¾”œgš(þF€ úfŽEãµúPÛ¨¹Æ“´q‘×ò Žô§¦G_jLAùÐGáí@ Î 4½GR~´`w8¥Àë@ ÁíKIœu4Pø1‘““IÒ“#¨ìÚm£Ž¸/”cœô¥8Î)¸ã¥-/N'O¥ÔtúûP×±¥éô¤À(xÏJ0{t¤úñ@ç׸ô4{b ~4˜ /Ô _lSvLÐ@ ôÆ(äŽ0(Éìp}1š3‘@µúŠ^>”œ‡4}ëJi=(àv ?ç4g׊>”täŠ ¥î(Î(±ü(<iN;ÑÛŒoè:?•.=¨ëØP‘𢂾ŒØP‘ÿ룧~´qÜbŽ1Ó¥íJÿëÑøRg‘Å.(ïG± û`ôÀ£ôqøÒMŠ8¢×ð ažÜÑG>‚Н¿ZNj>}(äõ¸öŸŸà(Ç~”€\{R~F¯J?J`/_ð£·ZoÔñë@ÚyÐ!Fi>˜¥ÆzÐ0ϵ€óŒþ¼v€ÄÑùÑÞÎ8ÿëÑÏ £hö¥íÖˆ1ÜRÒRÐô£ñsIùP±IŠ8ô¥©qI@ÇZ1ïúÑÐûPq@÷ cQ@ÿXÔR ~Œqê)3žÂ—$t˜ƒñúRã=é2}£ÐÒqéKôüèíÖ˜6þpÏV©Fp2pj»J»Œ{'<ìâ¦'ÝäE€}½*1<{AçžœR™Sý®´Y…‰9JNüSUsò“ý)þÿ­ ~†“ŒõÏãA#=¹MÒ G=¸¦Œ[qÂdc§­,`ÎÜUc*úÀøéÚ¥IÔcsÆy(°ìN1Û4qÿë¨ãš9³±óô©?.=)N*‘ú´89Çêf?)ê*u`¤JpOJhe‘’:bžãñ¨Ìñ.íͽMá8ùÈÈÏJ,"N}èãñ¨Öæ'PÊã¡õ¥YUó±Ç‡¸äU6 M)XÀ`8À5o¶@ª­# d;ÛÓnEµ¹Ý! CRp=9ì({‰Š0;QœôZã¡õ£>ãð¤ ÇOÖ—8i9<ÖŽ§ò úÓwÂŽðÒ㎔gÚª\¶×—nîÀ8«dT®™ÄÒätÁÁ4ã¸Öä–œ£a÷pHf¬àÕx³Çå‚ÝêI]‘2 ±Ç‰n6A+?™‘*¨^ÄS@kùÉÏ\ÕdÌÒÆZ2½w/lýjâF‰ªNzÓz {Àõ¬ÿ´±žã÷‰±ÇŠÐéÚ³‹Çæ\0¶rGß?Ò”D‹ñ’PÀ’)ý}ê(J„PÞ8¤Þ¼|ç4=ÁÜ’±–ààt5²™hÉ<œ7ò§Ýò²À*8‚‰“÷-œ68ÖÃ[ùÇ}*9IyPsÞ¥ª÷Xù F_²äŠ”$6/3Î!öàúU¬U-O'å* Î íÅZ =©Èl^=é7/÷¹¥<ƒÇ5Ÿ”g˜ùDc9æ„®$sÎ?F'žù¦B1 dÇLæœßtàþ”˜,™3Fé»û½êÄ¢BPÆ{üÜvªèªT$íÝÜu5wãÓLl« |ҫƈŠzñƒV—HǵAqiÈwc©©RdóV!Œž´· ÉÀ÷&ŒzÆ—€;Rdá¤"»¾.•w ã…Ç4ëVv‹.Tòq´T<#PÙµ¼Í™úÔö®tÈ‘UöGПŽõÜÂß(qŽ„u©3×j¡æä.9æ¤D(ËR°¢|£­tëŸÂ¨F`òÐÆY†Ñ‚OjБÇœ†Èæä·•÷ñÀÅ@žoœ¨W ‘ÇÞ§¹#ìïœôéÞªFN.w.OÍ€zSˆ#@tô£ñ :G5"*HYPsØ-X‹&0Jíã¥Tób3ˉ‰ ò3Ò­¦vŒ`zâ›Ø}ãó£ŸZ)HAIÛžhÜуÜÒ#ýà(ÇÖ|QøPp:f—Ó´¹SÞìhç¥&vöü©ßʶ;þ”{Ð:Q“éG=J0)xõ¤ühüq@ G?äRcèÈÅ@4w Ÿz8îE¸£¯ÿ^“ò)~¤PúÒr¥É¿2{~tœ“ÏåGô?.}èÏ­&=hϦM.~¿J9ô8 éØÑÎ8gߊ^½:PÎ:š8÷?ZO›±/9Á ÊîÆyëŠ\ÐñKŽh<™ ü©;õéNÅ ÏhÆzóõ£>â—ñ ÅŽ ­>Ÿ­­'çG~)r}:6÷¤9Çš0O^M.} '8掼ÒñKÏ üè1F(£ó 4~t¸£ñ ð£¿bcúÐÍ!ç±£ qFqï@=h£>¸£wÒ€ô4sè(ühühíÏJ3ïGâ(Ç4gÓ¥ ?äRàý);ó@ AÅ&¡¥ `zÑŸNh£“@/4ƒ4f€ ÆŒýhÏ®(¦ P8£>ø£=ù¤ÁÿõRÒnÉ⎴uëœÑËÖóÒ •0 zb޼QÏ ¥ Æ(æŒÿúè>Ç4síIøÑF}hǯéGãÍuæŒOÊ€“ѨÆ:“FHìhý>¦€o¦GãI´z³Ràw ïùâ Æs‚)r=q@¨¥ã½0 Í''¿.GJ1@‚“ç4ê(ƒ§z@ß6Ü™ÏjSƒÆhã×ò4QïKøÒP>”´”}MzÆ—Ÿ}( 4›ŽzQ»×¯Ò€‘ÚŽ})/8õ ŸJ3ž1IÓÿ×Køæ€ÔRž´´Ÿ•-˜”¿¥zÒži >¢Ž;ñG4”´QŠ(9ì)9þå;´w4íLؼ œF1Š>£Ž;P6)>´¢5ÎqÏLÓøöü©1Ïj`…ÜF£oJxP3…Æ}éqÈõ£ž”cëøS i“Àç¯iüw?.zS1®>Uã¡%\ôÍH3HG± ˜“'ä=xëKå¯r8u§tà/ähŸ•éúÓY©V”úŠqúÑϵ0ć‚ ŒcíM°îVHÀ*01Ç7ãAú‘@ HB¨òøS‘ÉàÑö8pÀ ç-Ž*Æ{cŠLØŠàõ¡Ïµ.[ÐQÎ9N”£ØQþzÑø~TsIƒïøÒõíF>”˜hÇ¢Ò÷è(ê;cÚ‘¼I&7 $t¡aHÎUqô§ã‚“¥/^x¢ãñÀÔMnŒû˜O¡©qŠ ’sœœóÚ}ž6lì9柳ÔSÈü)p}èȌĜxêL{~t Hüiq@ Ç<ʼÿõéÇžäR`Ù C7¤d*!gW+íëVxÇ"¥ã¼ôæ“ëÒŒž˜" ôýhÆ?ÆŒzQŒt  ¢Å»+0ÜrTÊžÖª@=½ŠŸž¿…§v;•Í”e·`ç§Þ4èàãh ƒ&¦Ç¹;Œæ‹°»=ÿ:\CKŒwü):zñÚËL¡X63ž D,!VÀºí?9«<žM9û£ó¢à@Ö±œ°Ø8ïDpygï–õ??äÐF=M;°¸˜ãÚŽ}Å/áùуëHBc8ýiGÒŽG^}è=:€(#=i=(ǯ4£Ð€>†€ LwïK@é@ eܤ׸ªËf¨"ùÜì$òÙÍ[íIÐdŠiµ°îT‡k¯šà3îãµ<ÛìÛÈÈÀö«9é@Åaq‘£ Nqßì{ñKǦ~´uÿëÒ1­2X¼ØÊƒŒ÷ÍIÁ£Ò€+ý—s†w,G¶([Pªç Y?JOÀÓ» ²»@ì 1‘À `T¨¥I#¿­?­®œz £-ž¿/”Ðf·ffo0õÈ}œî$ÌÙ#cç4¿‡ëNì.VÒƒÎc޹ïO%ûÙJŸ»Æj\‘èj0{ŸÊ•Ââã˜âŒw­/OLPKmÁ#ïf¦íGÒ¥d`àûb¡1È&Þ»1Œt9= ¡YáñøõêCíKϱ¤Î{PJçëëPBÿtçÅZü)9ïBv»BÅV<œƒÍ#Ã!F‡>¤Õž^ióßÚ‹°¹Qí2—€@©xí¥ÁýzO‹€¤dtàÔE$ƒ¶ÑÇAS“ßó£§¢àAäϸŸ8c·¥/—&ì†&§Çµ'áEÂåh’a$‚`…sòàv«#¥ô4tͨã=M-ûPJ:Qü½¨íÖÒŒQÎúÔŸž(éF3íKÉéŠ1ùP`J9õ½{Qa@ ï@'®0>´§éI¸û@aÆhÿ€Òæ“·=(i3ëš0:Ž)yõ ëÐç𥢓€‡4€éùQïÓð¥Ç¿4˜4b–ŒPcžô{qGÍëG8 mü)0OoÒ€<Ðç¨ëIÒÃó éIŒœóFNyQKÈì(üèü(ÉÏ@(Ï ýh2}¿*PhÏ·ëE{ãdt£§&€éKœu£°4dÍõ¤É¥8ô£ºPøÑÁèx£¿j3é€ñ¤ü(À=¨ èFiîÄ})ßýh¸'«qìi@Ç¥Ñþy ã±¢ƒíIÍ/>”¼Ò~t`úš9ÏsF(9í@>´`Š=é ¹ÀéŠOøü©i7QAÆrx¦ãÖzQŒ÷üézqý)v¤íŠ\íIœ÷ãé@¯åF©¥û£–ƘçIŒÿõ©sEš\} =x¥Éô `·4c=©>n˜¥ç¿éH”¼öÒ`æ˜ FM&?Q‘Ò€>¿ÊŒzùQÏÓéG w ýãG#©ý)A>”f ÚëƒI’zcô¾üSÆz~†ŒQÆsF}h"ŽÔ„ûÒqëš;¥9ô¤ÇÖ”Q@  “øÒóíKÈëG4 qFOãI×4£é@ƒ“ÔQÇ­CF\ô 3Ç\ÑϦ ö"Š?:{øŠ^é?*:õÇåG^”pZ\ûP ÍÏlQÛ¯åIÛ­Š;fŽ=q@ƒ4fŠ(sÛŸÆŽ{ÑôÅ'QÈJ8õ?•úÒûcõ ŠCÅü~”gßô¤Å.O§çG41Ç\}(çÖg<‘ô¥úb‹œÑÏ­'=ÏéG^ôsÛõ¥çÖ“ñr:PóIùŠ@FÆ–€ôc;Ñ@A=@¥Ç¡£ñ¤#ÜÐî†Æ—ð4™íÏÒ&ŒcëG=ɤ ËF¢—þZ5† ¥9íùP= ýixõÄNhúdQÁã£?O΀ΘǠ“êiäžÜþ4ÒÆqÅÞ—µ( 8õ ‘›{À^ÇÖžB“÷yõ¨ÑÍl'Ì MŸÎ€±@ÆÞlS$pÚªW¾iÒº¨Úàí=À¦ÆñïòÔi&à:ô¥Ü ã&ŒŠ_§ÔÒ09<Š3\v4£ØšN?¼?@~¹£üô£¿½ºÐÏ¡£¿…'Ûñ£§JwE #ÔT&DŒg RC+#|Üý)`útúÑÅCF7f3g­#dJ@'îí>(¤ÎG4¬\18ÇZ“ñ£wü饕T’O• Œ²>ü·Bz ³Ïùcª¶ëŸ3.ÜrjH”Ã8,(°X›4€ŽÂ”ßšN=hsÆOÔqßùR`ÔÓ_! @7cŒšwÐÔ7.« ÞÌžûIþTÅyÖû¯&à:gëQ²Þ:Håºpp=iØ,\FÜ ®Hõ Šw·õ¨ãF¡#Ò¤íÔŠ@U¸É•@”©àãgqªó³œ÷$`UŒ\Ÿz} U qå¾÷çœcž*×ò¦·Ü<qÞ•Àª¾{³/šp1ÈëVaVH³n#©Æ)–ˆ)=HlÔÙ›clLƒëJ=‰5´«(9Pƒ®})’Ip[t&7B8ÇøÑaX´OµG+~éÎí¸xv¨íZe‹mÄ›Ÿ'œ –^blsÇ®)4vŒa!“#ïÔÄñQÁ¸FéŒ &iU?t}Í7¸2QÁd{š@rìg¾*<¾sm^[mêN"­Å#I¾ ’2AíNÚ\,´óš?*2sÛó£>ôcéJùÅ&p=hÈõ Í‡dçÐÑøRuäsE-'ÔÐ=¥íÖ ‘ýê3žæÇõ£ñ ?ˆúÑ‚zŠLdö c?ýz`-¸ëíIßúÒóH$v U4~dz˜J\w“­÷¤õ¤Ï¿éGãGã@~¼ÒâƒéšLzPÖŒdwJ0O|Qz2{ Lg¡¥ÏmÙö¤À'&€;\ô£·^(ÈÿõÐg­9àQ“Ó4PÏ©Z0¥/Öãx 8þðÅsIǨ&—'°üèÆ;šN{c?J9Ͽ΀šQõ£·#jnnž”¥°£p<(ÆyÝ‘íF3üTqÛ¥­ÏZ£tê?*7 g'ô˜#©£<ýìЃ¸qÏáŠ9Ç8¦õ<R@þÆ€`öýhüi)è?ZSëÒ€ý9¥ãP??­ÿ®hy€óÔ~p ýM(ý(ÀÏÝϹ£éùbŒZ?3íIŸ_åAÿ<Òã=3@ õŒ©þhçÒ“ð$ýhÝŽÔ»¿^qÍ'NÔ~`z@Çù¿™ ðúQ·Ž9úQì3I@ :p´}p(çÛŸ‡ähïÔý(ÀϽ-:œ bž˜"Ž= /âi?:úÑüèÈ÷¥Ï @1êE?ýj3èM(÷lЊ8£·"uí@?QJ:{Rsßå¥Á4œzšQŒqúPi2=E~”„c§&—?—½P çÒŽ=(Èö¥Ïù Oªš^}(ϽsFqÜÑøŠ;PŒö£½&GRx÷£¿£…¤ê:Q×é@ G^†Œþ{Ð úš9÷4vÿ;vÅÃz_¥ Æ3ÅSÜgÐ\þ4™ü(ëéFj;uð£ƒß4¹Ôqí@„õ£qš?FsÏò aÿU(¤â—´séG4œp3ÍZ.(<:Òd~4n aøQž:fŒ ^&N:~sÜQŸj?@ RdwÇàir; 1GNÔsëùÒÐgŠ9>”¿CH~¿•.;R(Ï¡ý(Î{PÑøÒQÍ/ãA¤ç×ò£¥Ñ϶)x£ó ÏRgŽ„})yÇAAü3Hü¨Ï(ÆipGz?;QG>cfŠC r OÊL£Ó¼t €hÏn?:Q×ßÚ€P>´î¾ŸPhàãæüè¤ìÚ3ä(ù‹2°]½¹ÎiêŠ0ŸÎ—Œ¿úÔ™÷ÇÖ€ŸÅøSd—’®iÙÈü©®xùy <Á'ð¥8'­5ÛŒcèi²hÈLf˜RpdzRœzŸ¨¨Q Êzj`}ÿZÀsÏO” w?ÒŒóÏçF[¹¤!{u£$þ¶i3þqHIèZ€7“†e+éŠxÀúTHÄHÊñО•0ϯƘíÅBK™yˆž¹ÅL8è*e2¨%‡„Ôo• €ó‘šÉåAÉäzTWKº1ŸÂ¤VFåLœ°å|r:u Æ>^¼ûÓ¶þ"™ n;ƒäžqRvéCÀàÿ*;ÑÆhàÐ ¦ÈÁ#fôºÓŽçŽ99÷  ¶­¼»‰7nÁéVOáõ¨¡‘™¤åHÕ6 66Qž!5Â+3…éÿê«Q¢ÅEÎr*6wHŠ ©&§ÛøÃ{T#^çk‡ŸwëSÍ%÷ò¸ç5st¸Î3Š–\ùM†PqÆî”1âš-‘·m€ SÄ{æYÆ8é֢ĭ4jƒÇƬÇ*Í’&VSЊllVS×ðªÖŽ„”F•¶âô«}"ª3JìÑÄaO<‘I ¹=Èª× ™ù²GÏUïíD‰}ænWˆ(SÁÏ4¹¹Xd‰ÎyÁéM!“»„ç8FŒØ’9åQ“vŸÈ⯒¸8äûô¨­þác'¥ Ø/̯¾9£>§?…/:ý(ÎzÒ¤’˜*×j¹åF0 #*ý¨Ÿ<¨Èù@0óáA@œçÖ•˜ùØÌX>üÕ2seË>üqSTŒ° غšd¯´€¥wãî’9¢I$…B‚OÌ ¤PßÃ*îÃ&s÷ð?­E=ÄS‘œð•pÚ~j·å£(Ý}G4¤D„îÉçÕ® ÄŠ6B731UäúÕM³L塺  ÁãÎG§jº™1ò¸$tÍ2$`ͼôæ•ÀA÷»u«[ÌÒ*ÊÏŽÌó«„qÁæ¡„îTc©!"+—T‘3# Ú3ƒOŽí#I¹HæŸ.àËò©^嚥mލ¾ƒ+]•PHS9榈m…òØ}i³mùN=·T‘ç`ÎïŠ:  ¹Ò—þG4f øR~4¹¤Ç4¡ þ)zt¤¤ú\çÒŽ;04¸"€ùQŠQ’:Ñ­޽èÀƒñ àñŸÊÔÐ=ˆ4p)hRgÞŒŒv£#±@ƒùý(úÑבFï@ç 9öÇÒŽÒÐ!1ïG^ô¸¢€æŠ9ïŠãøPžzÒçÞ{Rc>´ R{gš2R(è:ÑÔö?…'¡£“Ü3í©¢€ ÜFG~iI“ìMZ9=?•>Ô˜ç«j\æ“ÔÒmúÒóŽ€Pþ&ƒõ&3éF§é@sÎEïÇåIŽ}é@#­ ïúQÏ÷©ßÏz Ïz\þT˜¥Á öúÐ0âx¥íE&¥.}8úÑŸSIÖ ïš?0=EÇ`i€gÞŽðhëëF=Gç@ øŠLç­=©yÿõÒ?*0@ÆGÓg=Å©8ýi€gëGãFqÞ—ò¤G¡¤<žMz`PGrq@ÞÅ:“ñÍèÏN(>çšSŽ™ýi:P8)AÏzL‘ÚŽ;søÐ@Ç< \ÐÒtã©¥È<(ǹãÒ“Ÿ|zÒñÓíIÏsúÐ =8¥úÿ*Lçµz\ :zRtš?\·fúQ’=é9õ£#ñ sÜQš@}èýhΈ~sŽ(üh9þñÅïƒFɤéÎix<äb€ {Ò;æŽ;Q»Ö€­Ôçð¥êh,W®1@ SE7w§”cf€œqFâ=>”˜öüÍÇ Ê€w¿åFO¨üE'>ß½ÁögÞ”þE õéô£ ñº€üñGC“Ö—ûÔmã¾>´¿Z ŸéIÇ^:0M&åÏz?Æ—ÔîhéïøQøþ”¸(Ëg Å8Îi1žÿ¥Æ æŒo΀?È£ƒêhâŠ9= /ãIƒš8¦Ç­/OLRg¶hã¡ +ýáGÐÐGl`{1é@åGJ9èOç@ÿ¦—ó4˜¥Æ(íÒŒý3IŒzÿ:\_Ò€ ÑÛÿ­I‘ž¦—NyãéI»Ž¿N)qÍô˜ç$ÒõïGãG_zP($v4žØÅú¨,?¥.N?úÔœvþt‡ñùгø{âóÜþ“ך^p~^žôtÿõRÊ“<ýà=©zÐ0þtc=±KIš¥¤çÛñ£?…Ž}hÍ{ÐbÆŒt¥Ð}Iüix ÷4cÚ€'ÖŽ½é!F=4˜Z?àT£=èÆ9æ€ýisïEŽh3ô¥÷ü¨ëI“Ó@ CGùéIFç¯Ö€ô¤ä”¸4cŸzAÇ­/nôQÆ;P~#bŽ3Ò—jO§ò¥À¢‰É=h£œðZSÏz@'9£zQùF=Oå@¤ÑÅtÏùhÔRËF¢Ã¿AHñ@=óëFGzbò :Ò`zñô¥÷ó #û¸¨æòÌdK’§µJ3éúÒ2†!HúP1Ȫ"·¥Do—ì«)‰ËáU¼ÉÀúQ€}éw),6Îr:R\Ee‘Ã0Sœjm£ñ¥Àn#ð¢àVût9dœŒŽ8¥7Q¶ÀðÄŒç56Ð@çéKµr2¿] *É>õòâflŸ`qS`ŽôŒ®×Uaô¤"a ÌâF!ÎpÄ“SãÜÒ”v—”ÀhõüéG½.G±4¸È¤sžý(Æ}(íÉ£å=¨(ʉ]CdŽ£.qØ~šjÆ©!p0Ç©ëš~ù™ÿ8¨œ•päŠ90\zÓ&…fBŽÄcŠ` à Øê‡ËŸð¨£[œ®ÿ(°êÛph‚Î8X²¶}˜çJY­#™ƒnu?‰ºš›9èh`ÅQÍzÒÜcÞ†PP†PÊzƒJzuª3ÚÜ|©Ærcõ¡ –Ô`Ë… óq…Û‘øõ«;­gOeu,èËxQTœsšµoÃW™¥nìÔÝØxºU‚˜åóÈ©»u¨LgÍß½€=yâ¦Çz@@›’å1ŒŽ´ù¹…€MçtŽ´Ñý¤Éæ|˜éïROÇÒ€‘‚€lÚ0>´ÕvY¼¡íï”°ÄbS¹÷IÉ$Ñ24ˆ&y&À‘3Uíü¦–\#nÏ;…Yw¨eŠGåÚ9ÊœŒÐ`uÇéQI)ŽXÔG¹\ã#µBö³=²ÆÒÀƒÃŸçRE ¤¡šGlg‚x4Y„®I¸Ï* E‡)“’Iw« ^8 ÔpÆéĶ99⎀MøÒ`ç­zãê)G"ˆeÀB9'$â˜êŸi\D¤“ÉÁÿ G/Ú7–]€tç4’¤¦â"’mAÀw¦P—…ƒ´!°1štá¦øÃpqŠI•›îË·ëR°%Ó–ÇŠB*Īª÷@àT7[shËüÝ»R4W&1¶eWÈúZ|q4k ó‹’Fy4üÆKÄc#އš­hf+Á»ßš–‘" +© v¥„H ™#?(Îx  :ŒsUí•’ád8Ëò? ³Œ’j xdŒÈY²²£9¤„%ÊeR…†?„Õ€¼¼T +¦Øœ¡©°p>j:ØC V8SÒ¦ˆ)pîy¦Î’2~íˆnÜjD(ȻӾ€.1ÒŒgµwÍñǵ ”~Þ3Æsô£Ôþ4^(ùG¦hÆzÑÚ€ŽÔœŽÿ•£Ÿz2sך:÷4gó£žý}¨ixÇãÅ/>”œÐœu£ôŒý>´žœûÐ1øÒ`žÃð¤ÿ9¥Î{ñ@ƒÖŒzœÒûR|½Å.3GÔ R`hí@ÅâΚ=Ú—¨àÐ $zdÑ‘ëŠLàu&”àûÐd{çéF~~¢Àþ4g'€P3×ÊŒçéF 9ìqGÑs@ôþ´O?•½@£ŽƒúÆŒLý(sèiìN~´£éúÒõ c@ì2G½ñøŠvG­×4Ü‘JG {ÑÆr3@xõ?9ÁÇ §u¤Æ=@áG¶)ZN= 'Ð~4c¹>Ô¸'Ö“qøÐ0>­ÀôÅŸz:ô@ ÿü…7ƒÔK¸üú 3ÏZ@%.qÚŽ8þ´džß˜¦ Èôý(È¥ç×4„ôÆ?:C')=¹4síK‚xéô çÿÕK×Þ“qÜqL>ƒ'ò G*°£?…w\“H·OÃ4gŒÑƒž?Z1Í'>œQŒQÓ©4qÓ&€?»G¸À÷ʼn÷Í…/J8=A  8÷úÐÓ®1G§ØRsé@ã ü3@ €(ã¾?*9úRãü怜ô¤Ç=©p}J1œgcÒŽ}¨éÐQÏÜЃëF(#‚ƒÜ~£þº:„Ð`ãåH ÷ÿ w¸Î( #éA_z^=( ãû´½9ÍÿúèçÞ€Í~˜úÐA<HvÏÖ€íúÑÏ¥.)¸9ôühÔŸ€¥ÇèÆ;МúPsnjړñ4½ýé1“Ð~Tq×¥/½Àà“ŽÝ}èÁöÍgž´g4}y¥ç'Š?ÝÁ ÆyÅÊ—ŸlÑǶhü(íþ4sŠ÷ü(ç×ô¤ù±ØýiÔ™¿•aG>ŸzÑß§ë@~I¥éÐ 1IŽzS2J2{KGç@;šN}.(Ç­ üô¤ÇsN¤* 0$tQŠ=ñø P¸¥Þ}(öüérLÒŽ­'>Ôtô£µp>´O—>˜£˜£¼Psü8ÇÒŒcô¥àý)8÷ ÐöÿAÈàQÓ§}J9ÇJ^{ãó£z1@½=~uéÇÖ€íÃ4zgšLÜÆœÞˆ0=…7ƒÇ¢œG©¼ûP!2Ou'Úƒîhþt~4tïGùëA•/” OÂŒcïKŠ1í@„ü©{QÓ©£žØ bgëK‘@ϵ'Ÿë@sÁÁúÒ~T¸ö£€hÉô&“¼Ò‘í@ö¤Áîx£(ã×4@y£Ÿ_ÒÃ>ô€@xþñïK½¿GAGÓŠ`£¥Ž”}üèï×ð£ð ýh$c­c·¼ö¦Œgÿ¯KÏç@ ìsF­7§ÄÑÐpx÷4ìŠOçGÔþ´b€i2OSKƒÞ”‚{qHãŽÔZ\QÈî(Èõü(†(#Ž‚ŒOÊ€#ÿ–E$j) oÿ•(ö"”g¹Fqšbþô¸ÿ9 ~T¼S´dãžµ(Î8Å- ß8£4r;~”cé@GJ2hú€)µ/zNý9úRðj^;sô ãÞ–`EÇ\gÔ PI)1êy£$ô£¯èèy œRcù¥ÇÓé@î8<Ñó{Rí#ž£<ôÍ÷¤QùS±Çݤç1@O½G4séJ íLÁï“F1ß”ã<“Ÿ­Hß­.Îxãé@(ïF8î>†˜ ´g©Ïµ;™ôü¨¼Qϵ'^ÿ… ÔQÏaG8Çz>»IúP!x?ýjNƒÒÃð£è) LŸ­=2iqíKùÓ9éÉúÑ‚=(#y¢€þ*L~4x$Q·Ûõ ´˜¤#=,ÒôúÐÔt¥úQ“éGQ@ƒ§Z>”{i9Î84 :÷ö£§åF=häw Æ=?E£ ÷zÐqÆM/>£žØ #½/9â“ëAúPó@üé3ž;Òç4sœbŒ^E¤úZ)1ô¥â€§LÒóÜ}(籜ŸJ)úÑÓ¹£ò¤àŽ?•ŽÜÑÛ¡£Ÿ­¿•¦—ð¤éÖ}9£¯8üéGµ˜ `=¨Ÿ¥^>´t À?•&OnhüqK@áô çÖŽ=èÈ=?Q@ ϵ.8 GŽ|P´RóÞ“ŸZN=hr=ÿ*ZNhÈõ ü©=Îizô¢€rãŠ^:âŠ1í@ ôéG>œRÑÇzOÒŽ}/ëF1ÛÀ(ç4cÖŒ{š@'ÔqG°¥Ç·¸ àô¸ŸJ\PbŒqGåF=©€ƒØRý  téHåKF)€Üßò¿‰4´@}é2)qGqþt¥Ï½ Í/ùëKIøÐsëF=ép( BqœwúQKÏÒŒvãó¤12;ô÷¾ãô¢Š`húQÁçgë@ ÏbhëØÒþ4dv€=hçãG=ºÑï@'ŠSÓ­ (ô£`úŸÊl怠RþƒéKÓ½&}¨éÿê£#éFhϨ àõ…Ïðš8 ÔcÔQôdúÐÛGAØQÓ×ð£¿4ŸQš0)qG‚7‘Øb—ÔŠR~¿AF=(>oLÑÏcKÏz(üyúQFhÇsúЭçš?8÷&€§0(NhÅûQ€G­Ç¥- âcK×ßð¢€ô暃ҟøQøPcÒŠ?•/ó¤{äÒàÜÒgïzgcQIœÈÔRß~)FÞÔƒ€)w1šbõ˜÷Ñõ$~4:>¸Í93KIÁÿõP¸Çji žp(À>„ÑŽÿÊ€zÑÓëK‚Ü@;f—>‚¤ A Ö ^½èÛßõ}šLc¨Îh}²E{ÆÏÿ^€cŠ0;¥/>Ÿ¥'^„æŒûýhÜûÐ9öúÒ ‘Óõ£#Ò€ ãž/n€ýTuè?:6óžô¹=ÅüñG¾ 0c®)N1†~4ƒ>£ó Ï`ÒŽ½ºQ»ÔRŠ÷sÚ—4ŸÊ€‘ÐÑÏ­4éúÒž=hsA'°£4väþTsøúŠ}? Àÿ‘ýhŒoÎŽ  Aš3ž2Aö¤Î8Á?J7qÞ‹Ï~´sÚŒçµ/?J%qÒ—<{Rd~4½(ïÒô¢€ÊÒ¥ü¨ëÛ4zKÅàPnÇùÍzÒç4qÒ€(J_åG4r=èÇëGáIøQøP“JÒ“èZ1ëÖ€^”uïG4ú >´QíŸÒŒŽ½(i?FŽ1E'æhÏNhsëŠ)2ëƒGá@ øÒg'ž¿ZP(ç}(ýh8êhü(gÛô£š3Iô\ŸJ:ÿõ¨uPs@3Û/çI‘ÞŽ£¨ ÇáF=)0y掽†h¹Å÷Åö¤Æh•µéGüŽ{ÂŒAŠ?@ÂŒû~´sGë@?ýz>¦ŽsÎhçÖ~ÔQE j( AøÒf—𢉀: \ŸA­…LûÂŒç§ÚŽhQEÐ ä÷¢Ž{âŠ(æ€ QGzz@.£ŽIc-±Á^ÕSk}œ*Ylœn$cëWn’7h‹³ ­#?•X p~µIÙúm’áÕíÖ3€K 8?^Z;ð3A'üš–î&Ťç'ŸÂÇzZNO¯áF>ïçKIœtýMúœ{QÛÚŒOÊŽi^ç;Sä'æN*1´q·ØÔSçj•fpéÞ¤C¹;‘êzÓèœúšN¾†Àê\{Rü:3F¥v Ͻ(ö¥¤=zš:ûÒþT˜ãŠ2O­0žô”}y£Š(ǵý)1ë@ œQGåIÓµ QKIÏoÖŒ~uèMc½æ—ó žÔœ÷ÇáKƒïšNhhüi0i ?>†óÖ“éùпNhü©7QϽ£'>´gë@~´g=ÏåGJ3ÏzSIøQü¨Æ9€ 3ùQÇ\ÑÅ'^ôsš8úÑŠ8ÿõÒçð¤ÏlQϦhqïG>Ô˜ö¤úŠ\bŽ/gÚ€ƒÖ—9£4*B;çŠ9Ç&Ž=(Ò€ ûΗ>¦“š1ï@}Æ)i0}¨æ€ëGãIÇ¿ãE/äP ¢“€êhÏÒžôwÅ£#¡ û擟\J_óÍ/ëIÖŽ0àsÞŽ Z@úÒqGâ(ëÞ˜åKÍ'n”qô –’Š)h¤ü(sïš)(â IKIùÐ1OÂŽ´´~4~4`z 0=(3GéG….( =©01ÓìCÓ¦OÖÉúRþtœãŠëh¿QA z~tdL\}Mú~t¹ô¤£¼ÑIô{ÒÐô¤ãÔRóIøP“øÑŸQGJ>”bÇPsí@SG8àÐ2}1Gjã®M=¨ç¥úP~´ã¥÷£ñ z掴w¥Í7ŸJ9ïKÖÖ€´žÙçÚ—ó¥àPyö wZO€{Rsœã&—b€Î’jJ)1ïùRþ´˜Å%.1ÍÐg½E-&=s@ M§b’\àç4¹þ´›{qøÒŽœ~tœâ€¨=IàÒ€=Í/>)8úÐÀö¥â“Ö—¯Bi€:g󣞽¥/#¶);ПZ\gÒŽGqGQÐÐ üJ=ÅÒ€=é~™¤¥é@ÄÉëÉ¥ëØýhÏ|ãñ£>æ ·=EðÖÙïŠLóÎ1ê(sÇLQþx£ŒsÓÜRõ(0§š8¥üè?…&=8¥üè?\})0½úPÖ–zPOÔ{Ðãó¥Í'AëGæhsíIÓ (&€Ùõ£š(À 8öúÑœsü¨ éI… Ôæ€p=M㌚M£üšQÇ?.G½&Fz? :wýhÜ= ÜRÒ*8Ç £Û4ö£=¸ ç­'ùâ—­úþt}h úÐǨÔ{óIøRôæ€éü© =èæ€§RqïFsÜãÒŒc¦iÔ oÐçñ£Ûš^3Ècž'ÿ  QŽÇ4ê1@„Ͻ.hܹÆy£Ú€ ÑÜ ÞÆ€”vçô£ð£ñçé@Ù4¿çšOÂŽž´ ^”œúÑÐsÈ£‘ï@…ô¢ŒúRsKÓ­¿‡éIŸóŠ>jCŠ;u¢ŒJ9ô¥¤ú 9ÿõÐÑšOÆŒÐÒ~´”g´´b“>Æ—š:J_Çô ’ÆÆ_j?•÷£¾y ažqGJLƒúQžù `óŠ1š3è>´ï@NŽÒDTsÍN:ª· ¯$[³ÃvÍYðÓè ^ÜS_vß”‚ݽ)ÜfšÃ*FJûÒ ’éJ#²Àþu5»ÈÊD…I‡9¨ÖÍ@¦‘ŽÉ4°(ŽVˆo` rßãUtÆZä ªLïCl`ß§ãV¶)'µWá`YqÓ$Ô BÄòµÉÜ@P¼®{Õ^*¦é ¬ÞwïK²àã$¶e‘‘øÐÁ•KJþ\S·\,„F#Ø;néPÍÛ¯Fó$µMª£»ï“ÔÀª¸DÎc]åwS –V–U‘T~\ñO†%†0ŠIדPC†»˜âL‚=? @Y‘™P•°.zÓ`‘äˆ4ˆžÁ³K&61< sQÛ(Hð¥¶ûÒèåy ‘î矛¥DÒλÅ»#æ9Æ*Yc>‚«£‰[’á™wÆi DK3Ï"¼xUè٩ذR@údp˜ÎLŒÜc YdØ9¤ü„D$¸!HEÁ¯¿Ö¤‰¦Ëù‹Ÿ–˜òŽXð:…XÛÝ¿ÌÎ$aÿ§¾ˆeê2{Òõ¥Î;~4„&}hãÛð4½i>”€9õ ‘øý(ü(çÒ˜xç4dv#éG>”™=风1IŸAù \zC’:b€ÏéAéů¹£Z9ö£µÀÍü}(éØþ æ€qGo¥-˜PLñÖ—>Ôž´™sü¨Î;^Ý(÷ 4sF§ãGãøPÐýh£ñ£¡ï@Žø£Ÿ¥g€})yõ¤Éô£µ-'ÿ•ûcéEúfŒœñE úПR(ϵ-OÒ€¿Z1š1íÍ/ó £§­'#Óñ ~?%&qÆ)IÇZ?:LöÇëF@áFN8Í.úôuõbŒ`/ Qšn·åKÚ€Ò“·?¥{ÐãÞŽ3H1Ûõ~ÒGåIš8Ïj`¨Ï±£Þ–€š_Ëó¤ÿ=)hïÔÑE'á@ ßFi1Kœ”uìhÚŽ¾£ÚÂQš3í@ý-&häÿú¨Ïµv¢€ QøQGjORM/ QÅ(ü)9ìph;½ ^”QÍ!Ïs@ œñG4œQôÍ·µ¤8õüèëÊ“@Å})9ïŸÂ—éš(éÛ¥'Ò—ùÐÁéúQÒ“¯QKÛ¥Í÷£žãZ\Ÿò(üy£ð4~t9ôü͈¤:1š/z)9Q×Ó4€_¥˜ÅûÐ?`.hÏùQøÐHF{‘øÒÐ~”b“­hÈ=sô ?'4ƒÔgñ¥çÞ€ý¨Éô~4´œÑϽ%/ÔQøÑ‘èh¤G½Ñ“@…'>‚nôü´n(¥Çï[éE‘Ò“Ž§—Óó£$»@ƒ84»½,Rtp=õ?öü(úu£ð?…ö4rqþsÜñA_N(äýhù±‘¥ï€OÓr=}ñJO¦h0UqëúPF{ :PÇJ:žO­/n”‡š^{b‚>”vè3À ÈÎ9ü©GÒŽ}9÷ õ£¯`(ç?*;ôüh~‡4ïøÑÏ®=èëÚ€?{cñ CJÒ˜ Ç çëFóÐŒS³Ž£j^¼Š@ Î;R€i§ŸïIÎ1’}0Ï|RsÜQÓµS@€ý3F =1ô4½( ðžÃð£Ï=($çœQžm”g< BqÔ€}hÝ“ÈúŠ㎦¼u '·>Ô þ‘Ò—”‡ïùRwãñ¥ šhÙ OCKšo#Ú—“Üлž”§ŸcIÛÖŽ?úô}ü)psÇZOÇ4tîhÜç¯éHXÆM!ö"€1ÓŸ¥.OlRõàbšqýÒi1Sí@ÆF8£xüy¤ëÛõ p{š^´`gÅ!ÍÇbh4~…(Æ1ƒEñ€hÿ€ÑÆ(úP“è(üqJ?8 ÀíüèÇ~>´¼{Ð@úÐuïFÑ×4´ç4 væƒÓçIÁÀé@Ͻ!gÚƒøó@åG4‡ž´p:fŠyì)iƒ?þªSÇð“øÐž”™äQÀíøQÎ{Ð ü…/¾&Gÿ®Œã¥/OO¥CIaFI½{Qö¨úÑÿ õ£Ÿ\QøQøPŽ™úÑþzRuíJ>”¼÷¤Ï¦(ÇåF}¨Éî(ÏùÅ&G§4¿…½(çýzLŸÂŒ@Í'ÿÕM¥Éî(r}¢›ÔsŸ¥/nGç@ œÑIJZ:1Isô a׿c¥/áG½'­÷QKô4P0ü)0AéøÑØQßœP}vçô¤#¿J\gÞŽh?/ÊŽ=¿ 6Ñ·ò¤¶$Oœ¨ïBÝEåÜ6úƒÅ6ñdhˆ `‹¥Wû-Г(C·î ÆMZµ†h«PádAøÔ6áÒ®¼úƒœÔŒÁ-œ⥉Œ7neÜ œTc 1+(ÎFWüšGS6Lj&Þ'®*3Ê$'bçø”šz µ1"3ÈŽ) ùáVc@â”aàœu¨­VE ®àl ÍÆE1ÈÊ•ÎjQÏ`ý(ô?‰¥ÀÅ!\í B[ŒŽ¾Õ$ê×/¸úÓ.#Ü‹…RAÈÝR ` ¿€âŽ€:«Æ˜89?tUŒñÖ«üËs• µºúÐ;e/¹íM„¸b8ôS™w‚èj e1³¨áGABØd³hÈCƒØâ«Û¥×˜­,ªWnèsSÎ7Bßw q»¥2Ífáf@¬; cô¦¶±c?LÔ3+…P~a޵0 Æ*¥vÕ8r0 $"Q‚àäu¨X<‚~\Ó­˜ˆ[‚òG>ZT" àr@çñ¦–£,Œñ×ó¥éIÏn=©yíÅHƒ¯Nhç<š¯ZN~ƒë@ ßÞŽ(éÇ?ñÍÔsô¤ät¿…'>”cÒ—ùÐy Ç½½(ã×õ¤#é@=©y£ŠNô´RQŽô¼g­»øRdwqœâ€ÀíKÛœ¥%.(3ïG_J_ÊŒãçL¨ç”‡>ÃëKÏ­ Ð: ­'ÿ­Kœv4tõ¥çáI×Ú€ âƒôëFEp(çÐRgÚ”ãÐ~4PÔQÏáGZ ÅçžhÁ=èŸJ:÷Å'Nÿ­/µ}}©01Æs@ ÏJ8f¯lýhÆ:@>£ÚŽGVý)4½9£˜”dv?\ 7͹ɣ>}ø£¯Z2}¨ “Š_¥ú~´gØ CÏoÖ—ó£“@=†(ýi?ý)zõÀ2}(ϱ j(wZ8¤Ï~~T~¿JJ8?Z>ƒŸz^Ý(ϵ&O¶~´ž(Ϩ£üõ Š9÷£>¹£ó Å˜÷4½{ÑIÏ×ëKÀ)~´gŽ”~tè)€~Ç4dc¥÷ ?ŸÖGãF'#ÖÒŽÝ1G”{bŒŸ@(è9Î(ühRõ¤ü¨ÀÎMQÍ. %P~”g>”gñI‘ÏO¨4¹âŒœu£¥ëF 1KøP íÞ“'ÓbŽÔ ^})1ŸLûÑÚ“9èx÷ œR烜p?ZGñRsõ¢“íŠ^;d}(àQÇãI‘Œ‚qKÇ©¦ÁúÑÐqüé)hCš:Qô4Q­uê?*8Ï^hýhÿ<Òd{ÐÑIø~4´QFhþt€:´võ£ß4uï@çü©ÒŽ” õè?ùhÔRõ‘¨¤1?RÉ£ðüóFpyÅ1µ&HïúP}Šâ—ŸZN?½Ö—œRrzqG>´dç9#ëJO=xö¤ËzäRýO”™þé4dž¤Òàzçñ£cÒ—€y R~4cÞ€øüèÁÏ'õ£ž™üè Ïâ~´™¸¥àQ’;ŠN§ÐÑ|ÒòxÏåH@ö Æ9éIŒž´¡p=>”˜÷¦÷ã­°üh䣎¼ý)Ü)ê@¥ÀÇsô 6=hÉÏZ`c½‚8¥úÐsÓ xþT¼qIƒÜ Q’=1@ ŸZ0(ÎE&ê.284`t¤?‘£­/n´(Ï|FGc@ãÅ&GLÒœö<Ò9É4¹ QŸCÍÅGÞ œÙü¨àŸþ½/§9´~f€Àc–Àôô¥í‚i.yò¥=(@=¸úw ‚=(9=ÿ*^Gÿ^€ŽüzQïÍÏ Ê‚N€?:zÑÏZ?ÎhüM&¯¼R{çò à÷Í/âiy=æ(ÈîJnÐzò=éÀØü(àô9£#¸?/“®?­ØRèOá@ @#·åIÓ§J=ŽM(œ~ŸÏµ.âýt}Iü©>SÕM/Ó4œæÃÜ}iK´'×4¹ÞŽGpMç½/Î:LŸQG>¢Ëñ  sFê?*9ö ÝìÔ¤ùúš9þõ>´cŒŽÙ gÖìhnôÝøQœ÷'ê)Hõ¢n´cÔѦ(çÒ€z1j^ýè84œzÐ3ëùP:ð£>ôr{怽?ýz9ÏZLš\RqëúÒoç@Í÷£_Ö“ŸZ2õ=9?/¦xüi2{ÑŽù ÀïŠ8ô/½=è>‚“8íNüqFq׃£¾ !#©¼~=OÒŽ½¥-&qÚŽ¿ýz_Æš}èy¥íÖ“Ó4õ ëÒ“>ÔúQÛÞ€ çÔ})8Ï|ûšvO½''µ!†;PQŠ?SïLü*? C@üÍ}h ÔÒt>”¥‡®(¥èù@¹Ïtа¹Ø1š¯|àÀPHŸQ‘VP‚‹ƒÆ:ÑÐ}ãÔÓ$‘±óqÓ¥I‚OZŽUÝ«g2ÝLŒt9¤¹Ê$+7û§š-±·n\àZ–é¶Âr@÷4ú¨ô„eqÇCQ[\¦Ü¶G¥K rHÇZŠÕÑšO.Mãw8(î޽NO°Å&Ð{S¾¦ŠB*Þ"4K»`¢äÔèÅ”uÜS.ÀW*Äö8©ü£'ñ : øæ $‹…ò:U‚ÃÞª³#]§Ï†ã?ýzÑ`àƒßÚ UKmYûÝ? œò$ý*½»‡‘È“ÇÊs‘õ D³hˆ`Ä*<³àFcÔ¶jyI’±"¢´‘ž&w¶[¡v…³Brã¯ãQO³È`Å€õSÖ¥È?ãQÌ@Œø=ˆÏ„ Œ¶éØwÉÎ:Ô‘4F5ùØçŸ˜c½Z¶ÞÐ+3c݆*lv=}ª¹¬S`8ëš^£Ò€cøRñïRH€sGNBŠúQúÐ}qFEúŠZ@&hÎ;~´¼Q‘ùS3š^hÏ8$þT™÷ü©˜qÏ®)ßÊ“9õcƒô #׊ãGOÿ]æ€ò¤êhÉì: ÷ü¨J¸Å¹Æ)1Ž>´`zQØÒ÷¥ãß4`úÒcéKùš?Ö€uΗ𣟭)üh(ü?*\{AžÜPŒóÎëA¹£˜#Ò“è§?ZwãúR`ù¤ŸaùÑ‘œ`Òà6怊_Æ“#Ö€ÌRãüš8ÿ&Ž{b€ }(Ç© úÒ“ó ï@¤úRã=h÷ý(Ϩ4sØÑþy Ž™£ŸL =sÅN`;QÆ:QÓµ'ã@ñG>Ù¥ÇZNÞ´:\qÖƒ@ ×ÞŒJ2hÎúÔ¹ãœöçñ¥ÎZLûÐäú 8"0£ñ õ£éüèüé>´;¯4¯Ó4p}ixOóÖ—·J°£>ä@ :t¤8ÇAùRgM(ÀîhAãŒj?@G¯çF}(ԟΓø4¹ÇS@ÅïGNôÜúsFq@ N:Ð?J@Üõo Q’xþ´áõ£§×ëLëÀlýèÈÍ;ƒÿ룑ßô¦ñÛ"©úP¨™4ÞÒ— Žü¨¿N2{LŽ™?•½¸ ü¨ëøzRdOÂŒûÐäzþt˜ÏQGZ\{šúý(•ö9£¾h´”{þ4¸ô9 œtüi3žA4¾æŒû;÷£èÎŒ@ÂÊŽ=©h¸À¥À¨Ï­ôçí@´dc˜\öÍ0§ï~”èh8ôçéJHíúÐÎ>ðœŽàš1‘Ø{Rôí@ ܌ѕõ£#­)äÒ¼}\ŸoÀRj9Å0Ž}iy4dwÅȤ#±4¹ÈfŒç·é@ƒèZ>ozZOnEÇ¥/ü c©ýEžœý(ÜçRrG8ÇjNÇ$j\c° ú7"—’=h9â— cpçOz;rF)Hÿ"“ƒØz/äEö4`c¨¥ÈúÐ1¹o\þ¹~¤ÊŒþ€}M/>¼ý)3õ¼ž˜¤'ýE"Š\\Ðnô‡ðÇÖŽ}J ÀéùÑœöü¨9àd~P:ýáŸJ\dQŠ1ôCHF;þ¹¥äjOn1í@_J6ã°¥Ï{ð ;~4ƒŽüŸJ\Räâ  Áö£éHsïG¸üMÆy~ ÑÁ-“íAϧã@åG=¨íǼRç×8úP`ú‘KžÔ™ã¾>”¸Çj'ãG>Ÿ­;H}Áühœ“‚¸ú]´g=… 8éŠ/NøŒzÒçéIÎzŒPíŸÊŒãÿ×G9ã~„{ÐGjv=©1Š1ïGNù¥ã4˜¶(‡ž§?CF3üT¸ÇLPFGj÷Å Àî)F}¿*2sÈ  Rdc<â—ŸlRmxúÐÁätúRñÔÒtÇÌ÷¥Á'Ö€ ƒØ~4}0(æŠN}@úP õ¥Éöü¨àgÒ€ :Òcތϣ8êM'ÔŠ^èÈÏNhö'4úÑø~4¸£šO¥QÍìE/=¨˜çœþt~4£v9£½ Ò;µûŠ3î3@ÅúRž¿¥ˆ4qÐÐàþ½'>¼ÑÅ÷ý(½Ñu1•Ï\c54yعÀãœT‡÷C#'=Gj°¤`qG@®;Ó$É€ ¥?šFRCÇ€!·c8r½NsúÑpÛ",8ÇçM–"h‘prr}8¦´¦HåÞ™ÁàSßQ“E“ –!Ž3ÓØ7f@Uq»Œ T‰óD8Ç=*”³¥ˆ‘¶ÈìNpœQ»äŒÊQ\šXË2ØÉôc´}ÑÞ…¾ ‡ÊÒ+®Ý¤wËRC¸ä•Aþí22.$ó d'â–Ä’, ž u£a“6í§iù©–ï˜ó…ó´Óå8Œ÷ö¢³UKp#B¹'!Æ П¦M»Ê#äúš~}ÿ*kª²sŒvÒ!!âR8úSf–DáWqÇÕx¯#ŒlÚÅž­øŠ“ÍŠi¶‰|t©­GbÈÇãNçÖ›øñNÔˆ8èÈìEÜP~£>ô€) §ò¥9õ÷Ô™SѱG·4eˆê(ÜG_Ò€ri:ò:zÑŒc8 uàP“A`;PO±úÒƒÛ€’)r}9ëúQŒ÷4œÒöàRçÞ“?çsëúÐûYýhúùQÈ÷úŠ3éÅëŠN{â—<òG¿g#†üé9õýx¥ç¯ô }s@ Ó¾_§ŒžÄ \þ&€žO4¼ç©ü(-è(Æyæ˜p=©r?ɤãñ¥ÏùÅûf“=9ý){u£9€:çŸÎ“)#¹£>‚€—𣸥àzQÅQœÿõéi8>´9ÅãƒøONFhyö££Œu£Œt¦ÒÆŒÒqýê_~i3øÑ‘ž4tæ€ ŸJ;÷ü(ÍúPÇ­v 2=¨êëEN3Gu 9ã4€ã©ý(ÝïúRä@8õ£ó/r)=Á¦ úf“êizš:õÍ\à? RqÇo­'~€ ç¾?1Ÿz^)3ô?@À£¯ÒŽ{2sÎ(d9ü¨Æ£>âÜ‚(ç§4 Ò—>˜ü9 b€ð¥¥ÈîsøQÅ'"Œã¡üéÏJ;P{œ~uérj\óï@ ÀÇó¥Çj2;œÒ€1ŽÔ˜>ÔséFAÿëQ‘@Ã÷ ð{Òäy¤Îyí@}ñŠ_”u&—‘ÿÖ£'¯ó BtíG>Ÿ­/´pGZAìhàÿ/Ôæ¥'>¤Ñ)~´güâ†(¢Œ öÍ!ö4z/*2¢šdE\–;Ò{E7ÍFlSJYAä€hÀŽ™£Ð~TƒAàŠ­:qõ¤¥éÈ8úš7¡ïœzP0Î3G=òEÏ'ð¤ÀäúÐy)Tq×>ô„(\–ß4azîP¶×õ4{sM$) [è3Öœ$ŒƒŽØ 'éH}HR“š9õ Œr1HFFãëKÎ:þ”cÖ Š_ÂŒŽßʃ׃ùÐsø}(ú RçÜQÔóŠBGz@Ô`ãÞŽh¥üM&}zÑùPp:ÒsŸZSG~t Ð~Ÿ¥ÇoÆ—ðƒð ;P?È¥ÎÂ’ŒqÚ‡à ÏjPh Bq×¥ü)3õϵõþT¼ŠLœRçÚ‚}h˜‡ëHsè)Øgµv ú ;t&–‚hªÌ¸Cƒß4õ(^O½;­&x aG>”sG?þºŽT-­´S<§ püöÈâ§Ï­'áš..B€O5‹3L¥BìÇ9ÿ ›`}(ºÇ'š¬vàgÒ¬ ôý(#ÇåG¡°¸c×ùTd1“¶ÜuMH}¿3í@ @vüØ&’Db¸LOãÓ£¿>â€# ûþc‘ì:ÒD²+>òÏÊ*\ÂŽqÀ″Ž?*ŠtˆoLæ¦éÛò `úМ ^})?úÔI’èÈ~XÂ9ÅKs §w`c mjÇ9ëúQ€}h¸\N(ëKjZ@ Zõ¥ô¦­Ð0xÅ/JLzšÇLRdJwh1ôZ?J;õÍ0ÖŽ½©sŽ:RsÒ^ PqŽMçšLœûPþ`úQ“íŠN>”¸ï@Ϩ£Š>nÜûP9éIùùÐzä€?/^”™Ï` ^M/4œÐc·Z}(Å.(£=ù4¿†(#éŠ? ^ŸõüñIÐt¥Éì´›†i ^½©¸öÅ.9æŒòhöþ”cÛŠ1Çò4qõ ¨ô?g§é@_þµ'=©hü1@ Ï~hÎ;f—¿z:ÐgžWéKÏ^”gQòõ"€ óëôíGãùQôgÚ€zúÑŒõ¿‡çIŸQϰ ޏ¤ãÔS³I’{ç@ Ç©£Òâ”S:Qþy¥Í!ÿ&€ê)Hö j9ÏŠ?QIøRŠZoÿZ_óšZ;PQŠ_­ ö ÔQÚ—ÿ•×J3ïKÓ­ö £hôÍ/à9£ 'LGj^½¨Éþí7·A­àS¿ QŠ&3ÈçÞ’:ô¥+“ÓŸSFPd{~—Ž˜£§ðÒ}  “žH”sëKj_Æ€׸¥ûQøfÀÐÈ£ëF\Ÿ¥Ðü§¸¤úQÞ΀8ô¢“¶hüúÐ0r9£š;õÉ © Å÷¤Æ:Q@…ÏÖŽ;sF=hú †)2ÿZBx¥ AŸÂ“ô÷ ý ¥üœpy÷ s¨£µ&Î(´QGn””½èü(ü3@ÓéE&}:ÑÛ  AòhééI¶—° Ͼi? QÈè):v bÑÏ¥&}©F{PƒéEèæ ŠLŽØ¥ÏsIœÿ ¯¥&=hçð£PÀþ”™ã§Ò—‘GZ@…©:t½ýTü´j(ÿ–­ÒŠAÖqš2N´ÿwò sIÉëŠL´¸Ç¨ ÿõR6yüÅ/w¤'ÓšSrüÁHÇn”‰%sèOj`‘Qr€LS¼Ö -ˆ=4Àp\dŒ õÀ¨ÜdíÁ*{zI¼gc/®M6B8-ô G蹬ÝGQ–ÊöÚÒ >[—”gzÆv(÷n‚µÀ$Ži’/vpjC,c×k㑞•Â%;å…Cr2?9°ÐüÃrú tj~UÆy¦0(T¤y>ç¥H¤íàãšlŸêÛrñƒœS-ÂFÕ*PM±,›H '•`Å@À'­2cðÅM‘×õ4 ‘©!ʬaT¹ëR¸ÅCpPlܤ‚ qÛåa†F(Ð<É>xʰÏ?oC˜·wÆimš3"('¿6OPühÈ‹å6ŽÃҤݎµmóÌY³ÐsSg¶ Lf”`öt ë@ ›ýYà°ôœ§å~†¢¸` %¤Ø=qOŒ€ƒ‘ŽJ?…'ËøÒàç¦?1ì( ¡óxóOû'ª¦Õˆ‹ÌPç?9­? ¯&>Ô„JW¨ÀïM-Vß%K==)g Le‘› ÇÅN8ÇRj½Ó(1î•“æàÖ…vé:Ÿ”tþT¼“H¿trzqKžx­ ôì~µZÛ`iv«[¦1S–ôªöÄîpfg ÷íM-dá4mö?'¶N*_ ÏÒo•Üo8‡jd–)-ȸÜËò•Âõ?Ot¬bÈÆsÔSãe( í#ÔsM=T‹NU`Ûܸ'–Á8«1Z¬R¼ŠI/Ö¤Þ àñô¥ÇÔQv+±O¸Í&}MÐ viLç¹Íð4¹¤ã¸ óGûÙ£Ûo`ŽÔc…Rþ­&‘£ð¥ Å'¿?Z_ÊŽÝ?Z'Zç­¥?:N3Û?J@(”€ úýivó‘Iƒè(+ž´¤w9£ŒR{ Pr:â€>‡4zúRc×`OÆ€ r0 ^þÿZLc£ð£¯¥¢—ò¤Ëc;qAúýh¹ÿ9 {sF}G?JNýT¸éFጃGJ=h<öÍ'…/ç@Ýýî=(xúQž)?ÏZ3Ç­.Olj¿4˜=zRç2héÞƒ‘Ò“ï úRàúP“Ó4€äc$ýE/áÅâ€É4›†x”zf—šnâN0\ûRþts@ Û½‰èh#Š2(Ï©¥Çþ´sõ¤ï’(zbŒ~´`Ð10OzÔŠ\g¯ëFsßô BcÜþžùúÑŒ÷¥ú†:õèééGá@Å¢›ŠS@á­{ŸÂŠJZ8£4zs@ ´9£sAК1߯qF)1KŒõ j:ýhü &8äÐçH¤ÈÏ4 ƒJSA@ žßÖ­/ÔPgÖ”Iš3ø~´sÓ™úQ»?Ã@yQŸÊŒñÎhÎ}èúæŒÔ9õÅŸz8>”zRýM.sÿë µ'?Ý?)Áêhg´gÚŠ8=èÈèÎhÀ„z\Z7gŠNâ—z@>Ÿi7RçŽi€hçëF~´dR3Žqǹ¥ýi>™Ï½/^´À3ô žÔsè)ûÔtïùÑ×±£>ÜzÒõ¤gŒg­ûŠ_©£éLÀëš3‘J2(9íH3ª`³ Å*2¸Êôõ¤|ó°ÁìMClÌ‹²G²qÍ;` ’x”ÈçîXmõÅ+Œ£sŽ:úTp“ŒoÝ€8€'ͨ¾Ñ˜P± ;b…¸‰˜0z¢Ì FN´qÜƘ’Ç! ã¨Å<}(ãÖŽôwÎhü@¤N;RðzsE%Aê9úQÀ£Ô¹ '®B·;” ÃŒzÔ®iÛŒãŒÕhàI9t Ù­4¦URIävïNpÍF ŒtEüª@UÞ·JP;äÓLЇ’úÓd“ËBÍŒïdy‘wJ«ŸN¿­M•4"ƹfS‡·JŠubÆFhÞtyûã×­7ípä~õyŽzÑöx™•ŠdŽôÓq¨ÚmÎ(Ðdàʢˆ±Œ<â£2Èsò‘ƒØQmDN²-†àS²=j´@,ŽV0¤žH5`:PÐt ’@´$iǺf¢¹g)…‹Ì„ãõ¥GŽF¥Kæ&B‚2zsNÅAäªÇ…RHè*HÉ(7 Jxühüèü¨ ÑŠ(ö ,›KNiAd=ª´ñ"#IóœOÌjv‘ÇzP=éGJ?*(ü(È£ƒž¸ üh£ÞŽ=h 2x¥â“­#ªO¥.} †pMW[µm€‚Kxæ› Ægm²9|r¤p)Ù…‹y³IÀ¤ÏlóíL•€?… $È#ŽG­¡üª'1¸wIÏlÓ£´dâiBs»¸ü)Ù »ùšL( \ÒœcŽii®á³p'НÎD¬FãÁí@¨¨^u°ØèOZ€ÜÅ0 ’$qÅ4®.þ{ñH8éG”€Z*³še)'ÝÈÀn*9-˜£‚ugùÓ°X»Gò¨`š9ØÎà r;ÔÔ€MÂŒŽôµ^è–£WÑ‘@2=é3ì:~HÁvj¯)Ìs¯ Ǩ°X¶>”vÏëTÍ´¾j"à ÚA¥†eŽD·ùYˆ<‚;{S·`±n“µ2g 1=ª¸‚RrnN ÈRH Ÿ£ð5J%»šo7sðr½Z-´dô¡'áIj¹¸ˆð®9\î©-˜à¾âP1ڂő֎üÒg±6G‡,Üô¤ø õúô ïUDs»"[=:Ò[¢%&ubXãÓ°ì[ãbŠ? B RpxÍEó ŒféúQŸz\ N¯áG·ô£ ô ô£zoÈ<Ñœý(¼wéEsÐÐ1I‡¢Œ{Ñ@ Ç­'Òƒœö¥éHíG¶?_­¥'áF3ÒÆ—¯|Ó/ùhÔQÿ-ŠC×¶G× Ã'ëFÏJ2¯ÖþçëG>¿…7'ëKÿ}PÁ8Úsîi ž€`ÓºÿQÇN€ùŽê~zRàR`c˜©&òÄqŒÓäÔŒóõÅ#e\|§“RzP\¸u íuôÉ‚†_‘Øç·jv3Ý$ã¥,ù`§“ÐTƒÚ¡·Úa ”xj”Ž„ý ÓÌ26H#<`t©°qþ5’Óÿ«~3ÉàTØç PƒŸqõ£?•!>¢—¨Ï8 ¦Vh($út`ùc€;Sn¶w§Zzp£ñ=èÁGsùš8£ßš3ëÄÐ $õê¼›¾Ô€" óбíŽ>µ.£]®r# ¦·&ÆAùÔ7ü˜näõÅOjŠqŸ¯ðšHãÕ~Qƒš6Ÿ„"ý;ŽiHÇ<þ€÷AªðæÌLh>nHëVJ‚9ªð`¼˜VÎpIèhOŠ3ƒÔf€3ëKƒÜÐ{Ã'’6D“È'›p—>Hˆ4eI)?ZšèìˆÅA#•Ô‘å“ןZka•D÷¤ÆMº»Kv««ÈäΓn‡Ÿ­(úQq N:‚isþÉÅ õ¥Ç=i8#  v QþzÐ1OÓõ¤÷4pzͯc@ ÇçF}¨àQž3ÚhÍ!úçñ¤ëÚ€>Ãð£<ô£ó¢€~”}qG>”Pj^¿þºLúæŠ8£­‘F?Æ€ 1íúÑ‚:`QÔrF}¨À'´PGµ ßœR`wÁ¥Ç(8úzsJ@=£ŠB{ P1qF1ÛŠ<‘ùQœŽhüèïÐçÖ—µ&yÆWéÞŽ½éIŽÃ󠌞ƒ>´¼:sŠLQœv;ŒqM£¥/÷õ =±Í.3ÁëI^ B¡†P±øÒm£pb€9ç4 úþtt~´~t¸}9 Ç .yå€úÑÉ£ÐÆ‚¹ê?:\uëF1í@ ƒø{Q€ONi@©qšf<Œ­)ÇÓñ¥Å çØÆ–ŽsÀ£§8ü…íÇçG#ÚŒ“ÛÔ~sGíFaGàh~¿“Óô9 ý)×JpÏSÍöéIŸsøÑN:Ðþ?­'ééIÆ~ïãGtǾ(r(ü)x>”˜é@ô˜çü)Øüi0{ PdŽ(ÉíKÜR`Z.hÅb“Ž” \qëõ£ð4˜¦hçÐ0r9¥ÇãIøb€ {P 4`võæ?LJw”~À@ ÿFß§çK€Oÿ^€=?*:Š\QŠOÂŒQíF)ݾ RÒÑLçÒŒôühǵ`PÍRàý@&@úúQøcéGÕGçGoþ½0 søÒý)?iq@¢‚?1íŠN;ÑõéKøQ×€né‘Kì( QN(ëÛó£˜?-4¨=¨9•vÑg 1ŠªÛãtA¼“…fÅY™ (ÃÁççò¤UV‡œöb9ªNÃCŽYí¤ãîƒL²Xy{qÇZ$«>[{¢ „˜±ÇV4XÆLìæH6ílëO6ñoVÚ2:Ôv±Ä†]¹bNáÊ­àúPݶ* X®J¤ drÃÒ­t[nÉ.pG Vy…&‚zf“ºæ—‚y¤ã=?Z@-­&F=©p^h :p=óFAý);ñõ£ ¸ 8 ÿZ¡‘Û(srHÅhH8?N*µ¬a#–ÊñÒ©[¨Ð¢íLlêCùÔÈÞb+ÁÇ4Œ«´ŒcÖ„8r=»R“ȪȄ¸ã¥Ž5D £zœÕxʳ:‚ųN)ËÞZ‡”3sócÀŸ?{5 ÀFâ:Ž´FûG$ªXŽëNœ¸OqHCÀÈ?…6E[ƒ€¸9¨ñ>å*ËŒx¤Ùsòœ¡îÐ1m¶WceqÆjlo΄ ª0 })rI>”1‘;ª,I>•gt¨“å‚,N*oÀÐÀ¯urE²F d=jq ~µ ÜrI°I;8ëMa1’3•ã¨Ï!“IÄm’xæˆhƒïPl™°ÎØQœ¨õ×ÊŠCçªý([*( c4ülÔpœÂ‡qn:ž œQüé:Ð üÿ9ëKõ£ð bgÔQÔQŒÑ€=("€(çÒ Å&séGùæÄ}s@Ä=pMåAÏÖŽ}?:;sK×µç­R8öúRõì(ãÚÀS¦ø1Þ˜#G3¶ߊ› tÍ&Ïý)@¤D-åï!ˆàS‘ä,M.ÜóøQÎ}vþµ°…O˜ÅˆôñSžGÓÆDbKŸ¥0 ibšQÊÁŽ}ªÒŠsŠb2 ‘ÓŠx;ºPR²yÁÎ8@æÝÄ.¿,2T¥<¯ë@(ÈÐQŸ6Fe•¶«`«åSóÙ¨ «Ñ@ú RðOjTÀܹ*}}Í)”ÃjT©…=x¡X‰RTwÚ ?…$Ù á~¢’;xcmÉWõSÚ0ØÜ3F€69(S fšrÏôjgÙaË6Å;ºÓÎÚ5!Pÿ9£@Ð$I“rŽ•9‰X»‚ ÎGj|p¬Qí‰UsëQ›(L-V ç-ó4c$`gvÖšÓÂ6‚ß{§µ‹äù…éíOòŽÇ#A·Qïˆm!ž”á$a‚4ƒÌ<ž´“³ Wž "ÛD%7gÆx¡X4$2Æ¿y×óéJYÙCœ¯QP8Y%X’Alu©Ö5V%F3ךZï¡üMýh¥ã=¨bŒz~´œÿõ‰ ãÖŽ > Q×®(úu£ò¤Î=(ïÈ Þ—ŸZ9&Ž}J:úÒgÞ—êizО(ǹ téGã@(éKøâŽ”‡ß¥&Gjw´qÖ€QIÎ8ëKìi×…žÔ¸#¿çF})1ëüó@ Š(Z\c@ “ŒÑÁúûŠ_ÀRv ¿ÂŒóÐçëH@è@ÉíKÐtÀúÐ11ƒ“F;–4`JZ>œÑGëíG AGNæ|QøÐ(Æ)~¸üé3ïúPäúQžÔf“§\ÐçœQ×Ö“óü¨È=(qšJZ?J1žÔtô£ÿ­B &qÏ'éG>‡cÒŒý?:0}M/N´fŽhàQŒ÷4~8£ó aïGãøRž”´):žô´gé@ Þ—ô£?äQøŠ;u¤9ÇoÆ—Þ“éÁ ä0}OåAx£ñÅ ëùQŠLûJ~¸úÐ1êhüóG^´b¯t¹ª£6íµw6ìœfœ’’Ê<¶åsÖ€ûCáÇ6j¼EfžC·îžý3V ˜ŸQšQôüsGø¤Ú:çõ¤ñG^(Àõü¨>ô}1øÓzõÈþT½}(úæ€ûѨ¨®!óÕT¹ ;Óæ0‹»r’HúÓJábÁÀ"¢ŒÌ`v¦¼ÑhÎﻟ”|J 3Ž7v Äv$Ï©±èA¨VÜÇqÈÏ4ó2*å¸>Ô1|}£;¶? %ÃÌe€4Äòä»wGmÀ À©þu$Ù8!Šàòë@ cÐS]@Fîõ¦ FGsP½ÜLŒÁê: ,Àž0m^ÀœÔ½øÔQ)XÀc¸ã¯JjΙÁ89Àïš þ¹‰Rx9©ê²1 Îî㦛8vQå¸RNOQH °:Sd FrÒš’£(!€'ÞšeI"Ý«Âäõ¢Áa-@X°µ.6 ÈøÈÁÅ,fAßÔuÄ2K1Ê©ˆ½óO¨§ 2I>´ñÓŽ)˜>ô¸ï¸ÒÃÿëÔ¾Ö8 HHèqPÌ78TŒuôæ„°↠)$ãÞ˜@ûàþ4ãƒÁ~h°gfKïç­HqÞªÂì8‘0 ;RÉ!1Œ«68ÐÁˆ¼ì¢EÂãåÇ"¦$cj´9$»Ä¨ç©S“K<Žv~nrqÅ0²4ó+DãÊ ïVxCŒ¢ƒè9§äŽÔ˜ Ly07wâ»Ú©¤q3,Ðìß)ÏÞÒ¸"xÀ¿˜F7¸9©²OÂñ€X²Œu$ô¥Œ@ #8€‚Wo?j¸ÝŽ03V9ǽW¸E æ¤Aäê`ÊS‘ŽÝiôƒe`;ñƒ×4°6øÃsQÌä2"F\ÁÚz}jU … Àý(èÈ㚆ܓ¸äŸ¼;Ô„¡\ñƒù†UfPlŒf3ïP’ßi?sÿTùµÛbÌ»rHæ€Dø8ëPÜ#”nN@9"œ¨#Œöªò³I,iå’ õÿ­BÜ Ó-Ÿ—>ÜŠãM]ª0½µ.Gã@ ÚŒqI‘íGå@€ 9üM- úcñ¥ü¨b“nOøRуêh1žÔcÚ”~4cŠh\\cÖƒ@úñ@€úIŽ88?J~ 'NÔ OΧތûãñ£©ë@ ·Þ”Ž?ÆÊóÒ€ 6ät¤ã­ó õ­ôRËF¢Ã8íͨ¤Éõ£êx÷ Bå{ ý öÅ&xùM/àsë@ ÁãN´˜÷Íi8ÈÒ€ëš9?ÃŽiqÈ<ÆŠ9ôüè?çH>”¿ë@cÇʽ³Ú€?ƃÁÉŸZ:d~múæ v âÜ{ûÐÆ(ëœf€'ÓŠN£Žü¥÷ÍztúÑ×øAüh#Ôg¶:ö¤9ô€µ&F3Œþ4¿qÔÐÏÒŠ;ÑÓ¸ z~”¿J9¤#>Ô^ý??3Žù¤Î}hãî&È£4b€ÒüÇÓð£§9Z:Ð!qIƒÜÐO<ç4˜>¸ bòO¥ÉVF\#ªœñ‘šZ'¥÷4¼v£ŸJ ''Ûñ§Rg¦x bcÚŽ=?_×ñ£ô¤ÿ ÅìsFHëŠ1L擜ŒÒò(ÎG4œ÷ÏÖ—ñâóÖŒ¶qÆ)gØš2sþý)?\Ñ>¤Ò`ú¨sH=ˆ¥hÀÏR 1 שØ£¯4¸”1íõ¤18ôüi6ç â—ÒóÔ à=E^ÔÀ^ô®hÎh÷`bŽ”zóJ3ÜsHŒÑõÇz½ãƒ@=)žZ‚0 cž”ÿ|géHNrր޸$Ó¹£#qA wÏã@ bdž=4›TŽ9SíOúÓp½G¸ïL·=Ò”ò8ëùÓýûQŽø¤6.zøQ±O=1Oühü0ÔÒˆyÀ8öéOéF9¤ Œr ÐF0¡xÇÿnh¦¸¤Ø§téŠv3×õ£pÒ‹ŒÈ÷æÈî)héé@=±F{gðÍ'üb—#µ/4‡ÈǦ(ýµ7 ‰•EAŠAY$ƹ'$Ô¿û~T€ qÒšÉä2Ϩ§âŽ1ÍFÑFûsùN@éOU 0FsÛô£Ü€Ø$Ò ÙÁ¥ÅÍ!”‚ ¥£Z„ÀžXNvzI-ÒU`Ù†2 MŒöñ£þ@\„[Ä‹ÏNõ!Ž›‡qNëÇO¥üO×¶ˆ²6Éœhû2„Žä ÔüúR`g¶iÝ…ÄëÆF=)©#3&rÝNjOÓñ£ñý)~9£¯¹9ä~”b´) 0ˆ³ó“R°,„Ôu¥£4n>Cl ¼ŒH8¤’vB%`gа@ïIŽ8‘¢áq‹Y7n$cÍ=ºwâŒcÓ¸>¿•U[|9f•Í‘·¥K§s‚sÚ¤ÆhÚ:€3EÂâqëš\·¡úÒñŽÔ¿S@„÷4œÒ`g©ü)~´‡<`ÂŒó@ëÓŠ^(ÏqšOÃ¥š_Ê“o¿Pxë@ÀéKÖ“Šâ(çÞ“'µ;žØ¤úšˆ4QÅ=(ühϨ'ÞŽ(9ÏCA>£Z\ã®:sÞ/úÖú )Ãýk}™õ£9ÿõR`} /Ôþ´ ~½Éü¨ú\@G@J0{šv=H!ÈíúÐ2yÑÏz9'ŒQžÆ€§øQIþzÑÏ?ã@ ßš3Ûu%(<ÐÆ“#¦1Kß¡£>ÔÀ1ÇñH~¤¥/¾E¸üé~$ÑŽxÈ£œõü©0ÝÖ“œt8¥Éôýi3š@LÒcÔñíKøŒý)îHü¨xíŸÂŒþ~Ô€~?Sš^}0 ¸£sܨ£sÖ§>”}Š\®(ã×õ ŒÑþy£Š£ñ  v4~4½zÑõ 㨣>ÿ¥-öj&} Ø4¼úæŽ}?*L}>¸£œ}ê^Ÿ_­ãÒ ƒŽ´cߟ¥û­•ð,ÑÇAG8ÿëQ‘þEž”½G~tœzʹäãð bbƒžý)hJÑœwü…\}(ÆO¥ïÅÏQGãÅ}}(ã׊(ú’~”uì:2}1FqêCø¡£ç?™ ϱ£¨çò¤éœÑ÷}ó@ 8QéŠ3ƒÎE‘@úÐש'ð£ó4c?Ähü¨éØæŒúŸÖ—ØQǵüÒgÖ—ŽÜPGÐ0£>ô˜üÔ¾àÐ ç°4d÷Éúv£ñ£ñ 8ã4~8£pÿ"ƒÏ8æ€ 3ÇLR(üq@ ÇÖŠN:bn)i3G=òhÉöÏ¡ ñ¥Ü¥úÑÞ€”v J\ÐøR{Ò÷èh Üt úþT˜üi{PøþT=h£š3ïFsÿ×£Ÿ¥gš(£š0¼qFOLP~¸£Ôš:Ñ­PøÑŸzLPhsšöÅö¤Ç9 È'ƒŒP=¨þZ9õ `~´qGz3ÍsžØ£šN¿J>´t¥âŒP~4ii:v€ ô¢€ o©ÇÖI‘þEž´w¹¤Ú(Æ:b—Ò`ŽÜ{R‘@€­&~´¸´ Aš_ΓÿU:ö¥üéÇ?•ÔÐ0éÒŠ) OÎü)*8ÒéÒŒö4d{þtÇ"˜Å(Ï¥8é­xš?J2}hÏ­Æ—õ¢“gž„QÖŽÝ*;w ú‘HhgÚ8ô¥Ü1I×±£¿AŠ2=1KÍ'N§4`Ô†}ý8£.'þµ0 N=y¥ ƒØþ”cÞ“ñ"—4„äó@?þ£š\ç<=±ŸÆ“öühdwãë@ô}y÷ÅcÓë@ Ï_éF2s“IŒ^;qHaŠ ÇcFsÿ×¥éLBnä*^ôœ8é‘ôÅ!‹íÍ›¿0?É É÷¤êsÞ—Ò‚í@ ƒ“Ô}ižj-À‡øÙK ÇøÓÇ '>õ Ì *.ÒD;‘‡cÿ×é@ûóI€: †)œ¶Ù`xÛתŸÄZŸŸ¥0~}èÄQÈ=OåKøPLR`ûÒçÖƒõ Íû~t½(€9좌c¡£>ÔÀ?Ï Lý>”u #ÖΓô¸=¸¤Ž(ǘõ4¼})€´Ÿ­/>”€@qÜRþ4Üû΀V€æÏZsÓ4ž”sÖ€ ^}hç½ïL“gsKô:céF>´¹ÇR)=EÅ/>˜¤ÿ”sÖ”çÜ})9õÇÖ$õ£Ô`÷£ÜýhágaŽp(§ËVãµwãHqïJ‘ÔÐýp½Øæ“ŸAŸsKÏ|PóÊG¸¥ü€¦äŽŒMž:Ð=9£‘Þƒ’(üq@éÇëGÐr)2{I’{~”ìŒw‚@à·åIÏBÅ.yëFZ:w à“@ ‚y4‡#µ/ù£úÐuíKÈìãIëÎsÓñÍ8ãô4~'ñ¥àzÆ®hú*=4qGóö éÚŽÝ)>”¹úŠ`AíÆŒ~çr8Å&>¢—žÜQÎ;ÑÈPãÞ­üóIÓÿ®hÎ)r;sI’ K“@ƒ‚:â“n{øRöéFOÿ®†: äÒtRñ@„p_Çò €hÇ  ü.(ë@ `r=èÇÒ“ÔQß½“ÿט¥pëÓÖ—ŸZM˜ç“KŽx ðüé9õ¥¤éÿê ü)8ô4éG^ô0}qô ärsG=†(çóô Óš?1G=ñøRÐ}3F(ϱ£=¨#<þ´cÛ4n#·åF~¿J>œQß¡?úQÉèh9£¯QKž:šLöÇé@=¿*CKn($ã@SG±G<úÒnÇÁ ÈéšQø~“·o©£‘×¥/áH}Å/jC@0iqŠL:9Çë@Åǽ¹¤Âç#wé@…ÿ9Åz~”™ÇSG…/Oz(ühàu4t¥Ï)2£ úÖ“ñ¢ŒÐþtgҌŒzÐóŠ^½¤çÓ4¿&3Ú–Š?ÂŽi1Ï¥þº^ݨ$÷•!¸w Ÿÿ]ü)3ô¥éŠ'pß•.=…ðP ÿ=hǽ SFAê¼ý(xÏlýh¤8>£é@”nô?¥µR.Hî&G®hÎ(÷À AŸoÖ—4”s@ïz3ÇCGÒŽ}h~£ð ŠCSš/ÒŒú“ùR“Kõ púÑŸcõ£¯­£ùP‘FG¡¥£>ù æõ&Žž´œRûf€+ÐRÑü©:q@ ŸÂŒµ&@úQŒúÐóšAøÑùš^{Ö€ @KÍPŸSGj?*:Pô£¥PHzä“G·Z:Pð}h¤"Ž}¨i8ú~Rþ4ÜïKÈíÅúPÐt¤Ü=èÀ¥üésïIŽôsÛ¥ø¦ÿ*N=¿*\Ô„`s’>´€3G>ôqéFqÚ€<ýïù÷Á£'ð£ë@ƒ'Þ€O|QŒ÷ý)xãΉœw/_ÿU'~‚‚p@ÈÉè3@„ÏåFqê? w#Óó¤ç9Å ŸQ@`zGâ~”¸ #§ô£8íKíüé ö4Ÿ…;­7J\zÒ`Z_ÂóÅ÷4`ûÑK@ íš1G~"˜Ð¤c=M/N””cñ¥çÒ€>¸£>§~T¸õ¤!=ñGZ\ÿê ­0š8üiqF¥}èÈ= …-\ÒgßéFõ£€{Ðþ4=h9é@w ¢“ÜfŒPÑFF( ·ó¤• 8çÚ—ñ ÷¥ühÎzÊ;þ&€ŒÿœQƒê3IÏ­}p(üéh Éî8õ£é@÷¥Áì(?ùÐ:tÀ¥éGnz}h0iONhÇå@â‡n(çÒ—ŠL 3è £F>”qí@‚ŒÆÏCš(phç¦(ë@?…~tb€ (ÇáF_“ðÍ- J1Fh õ£=þ¦Ž‡Ú|ЊLcëG½ :õ&Žsí@Áô¥'h¢“Ž”dPçÒŽ=€Í/_Z^ÔœãŠ1øÐøRŽ´¸â“˜ü(ÎyÒóëIZ0=(¿ôëGài7²hséF}Žhà”´gœãÞ—>“ô §Ö޾´dzÐ>§ñ¤ñïI×ëKøŠJJ9Ï^>”}8£$ÿJ`ÿZßAEýk}™æŽ½‡áIÆ{þT{Æ€¯sÜþ´œwúšB#$ÐðqÔ :c‘MÀë×ð§: ^:t÷Å&@êJ\Š7zíÇÒ€=é>ƒó£ð£ëŠ1ëùQ€{cè(J_¥!ÿx¥&Ü÷Í)*:t àñ“Kj1î(0;Ò¦>”¿CÍ(Ï~E&6úcÚpT¯Óš8ÇËŠN3ï@ÇáFqÜQéš¶&HôZ^½E&OÖóÒ˜ ÇáKÇ­'·cנȰ£+ëÍ&qî)r=G42:š>QÎõ£§B)0¹íš;üæÄÓHÏj^¯~4cÜÒð;~”ó‘ùs@…‚Œþt`tþt~€ ?ÏsíøR~8ü(ÏçA$s»éF(çë@W¨4cߊ? Q@˜ãŒRÑÔs@ùéIz1õ£ã4cÕ¹£Žâ— úPqGCÔý(ǧò¥>ôŸZ_§ëI•è•ÏJ©8£Œu sÒŽG§ç@=é0lQ‚zþ”|£ÿÕ@ú~´§=(ÆGZõ §lfŽsÁý)0=ésÇz?ÏZS‚=©8ô£ŽØ Š9õÀ÷£ëŠL õ ühúP(úŠQš1Ó“I×§çJ3Ž´QßúÑz?J1íš0{(éëIôë@ j0£>£ò¢€ Ôp:š3î?*2;Pþ”™¹¤Àã¥ú ô&Ž”sõ£g¸¤É>–Œæ†=ù÷¥Ç~3IE)OÖ“½“@€’;QÓ¿å@õèãð  ú~¹™i3ïùÐ1FqAúÒqÓ9 C³G“óãÚƒÎh´`”tî)j3ëŠ=A£ô ÐøP3F=¨ÅqÖŒ}i;g_ËcŒ}hâ‡ó£9£ŸZ\Ðøbý(àRdqÁ Æ}:ÿ9¤Ü3íëK×Ö€qH? Óõ 4ê)8 `qÍž(ëÖƒï@#ÐÐ!1ÅRf†=I£Ø¥¤ãÒ€ }i~¿¥ph÷¢“4¸QŽ) g¯_z:âŽýihæJ(Å'oj`)Ç~=¨¤À`g4€?^(÷­w¦ŽüQKŸÊóŠ@ô”¸¢˜ Ð÷ ­/áE Š\Æ“΀”¸¤¾¤ÐaøQÍh 3õ£œt£¯jñ@sÁ¥è:céFE'†€RbŒ 3íLŤçüŠ>´€8´™äÒç#¡ …'åF(ïÖ€4˜éGZ8ôuèi9'š^CŠ1Í"°uÈ9š^´¸¤##š?:Qj;qL~=Å• ö^iyî(ëÜQùQ×®(ê:ÐøÑ@àqúцîEúŠ2z?(sIG´döŠ_“ú1ž£õ£ð ´Ÿ\ÒþN}?Z9ïúRŠ8 bcéŠ) ;ÐÁéF1ß4v£Ú}H¢Š9ëŒP0ü© ½úQŠ;ÿZ;sIÍ Bàg¯åEØq@úb‡Î_ï 8=¨ÐPøÒóIÅ BÑšN´ŸNhïÊÞŒù£­¥/´¾íPÑÀ¤£ñ BãÒŠN¦ŒŽ˜ bŠ(£¥•žÃ~}ü¨Áîhãñ¤ühÇc@ Û­&/úQÏz8£Š3ëÍò£€ ?1ùÒcE/ôŸ/éE'ãKÿ4~“ƒé@CŒ‘G¸ŽýèÇ=(~„fÆŠ?O©£´SJN;Œýi8ÆO>ô¤/p;šZhéÓ½6ÆÒ*cåb ç¥"L$b[Ž¥”ŠdèÒÅpsÇzli(ؾPŽ)3ìhÜ}€£¯®=¨äÒ¹ÿ=i3ùÿ»IÏ­.M¯ò£±£?äÑÉõ ¥û LZ^H 8¥ÏùÅ èÏ¿á@IPÁsçnJ±\˜Ÿj¯nåÞLÌ­†#¨¦†Xg¥@3QÃ:Ï‘r3ØÓÛgÿ¯QÛ®")Ït¥Ð Aú~¢ûB}£É îÆzT¬p=j³º¬ÂO5qÓ H³Ï²ÀùXçŽ)üãj)r2žG­ T€Óá Æ0?îœ~tþÞõ\3› ¸9à~TÒ¸sêy¨&œÇ4(Ÿ0IíÅMÎ=*¼í0‘ oNw=([‚,uè ^q÷³õ¤RsÇZíRNsH æî-ò/ÌLcœ rÝFÄm r2>SQFÒÊò²¢ùd|§=‚ÒBñDa~fÏCUaظqßñ£'Û‹Ó (ÍàdsR!̳W 8äTºŠ‚"dHxÛÞ§0dR\G*1;)?Ê¥ÛŽje”ÛŸ—#š•ŽÐX¶¹ E8‘˜À$ëO’DŠ3$¬GVíPÛy¹¥䃜Ӯ†meXí8B2›@ÄÖä¨&XdÖ¤ŽA0ܘ#¥RŒ|ðfÙwíêS…Y´v1¶èš2‘ŒÓ’HmüØô£&ŽúÒþ?…I#{rEúæ”æ”þtޱ!w8½ë ,ŒzƒI6ï)¶ cýÒqšl‚ɳž”t7#±ªí{ ¤ŒÌCƒÅOסýj‰]†]¶ªFï›ïS@‹?j‹r®OÍÓå5( Ž:zÕX·;ïxÂã§°«!ƒŒ© ?Ù44 Im™ºeXËqž*U¸‰ÊmÛÆAŠ£2…žgûf*78î*HN^-°¸¡cŒS²‹üÔo"D ;„¤Ó†Î*Š|ù'1 ºÔ’ ¼·m˜™rÿwš•$Y7þƒT6‹²Ð ¿qjŪ:«–ŒG“œTÒ±M Ë¢•Nå7 ¸£ãózT‘.ÈÀÃ÷ŽjD?þ PX{Ò{bŽ;u CÌY„©…ëÏœ$ˆ êIÀ<šÎ l¯p<“×$6qøT‘¤"x`@ÛN$`}*¬Š±#×…ñœàZ½G0 BxéëRHõelílý)Oµ  J¨úÔÃã› úô£9ìi8Ͻ.O4„)¯*&7°éÏZw#éTu yM2’wapÄsøS[¼øÃóW#Õ±NWWPÀ©qƒšÍ/hbòÉ9ÏñÍhEáH¦ÕÚ]TngÀõ4»“vÝÃ8Î*–¤ð-¾'vHÉê§½@ÂÜH¤¤²ð¤ñZI\4„Š@*Àç¦iÌBÄ঳`ß*rCeKw«wq m]°_Tê(i!4Mæ&vîÆzö¥¬2¤Yj¶©6àò`†'$Uûm¾X œzžh°ìLN9Í0H§Ãó¢@ eX‘ŸCƒT–ën¤HøŒ¾OÐæ„®$ß/$vªÐìóÛk³6ÞTž•cðçHÈN) ¯?0ùzóÒª]¬k*K,ΪйÀ&¡+nLàHù'-œ~”ì YR3žZ^#DyJ|¸ã5'nÔ€_Ê“¿½4wô:sÅÏL~tŽp‡’:Õ"Q$Ϛİàê)¥q¤_íÅ!ãéêj¥£ .âNXTÓ…h1ùqü=hjÀÕ‰AÈNA œuüê+r¾BÊ€0O_Æ’||™þ÷&•€Ÿ"›œ÷1À¨ Ç›.=èÇåFj9”4X'o¾ib Æ9${ÐóïGèÚ:ÿZ>¿Î€;QZRj¸8»Á”r>îhÀRý)®vÛºc­El¤;˃Ð1é@Ñ‘G׫».ÕŒ  úu¤çÒ£˜íˆòGÓ­I‘×GšŽ,í<çšeÆWaóB Þh°çÜcéKùSW…çÞ™pþsÇßÎ1@qèhþ_JŠÜ(bO7¿ –†À£5 ,¬åƒîëÒŸ.|³‚èÿˆ¥¨a8yÏjSŸ\PÀ03ëF9Ï& ·y¸v݆8úTãð¢Öh絆)9üi¼gîçÞ—½&µAqæù_¹Æì¼{f˜þ´b©3\|íæFPAÆiÊó“ .½>u§aØ·Ó¯4¿…4ŒÿZc’ÀœÒ!ç¹b˜„’C‘èjNÔ˜íF1E-'^3I†ìß•/J:÷~'ñ£¯­‚Gz@ô¢Š20ž´Qš ˜£Øõ£ñ£ñ ƒô ‘Aõ£€>”:=¶þT~TsžœzÑj(üh1ó~½Oµ…ÔÀ1GNÔdÑ΀ ;R`údRûPÖŠ(ü(ëÖ“Š×?J;ô´™J ö4œPÇP)hóõúК1IÏBFi~½hÈ£ƒG?ýzNhàPt¥Œó@ƒ>çëGùë@…8£\QG=ø 4géIÆqÖŒÐç”{QÚŒ{ÐG¥¤Åî8 uõü(ëÞŽ(uê)x¢’€ŽÔ”¢r: ÑÏ|PŠ dzóí@ÂŒ{RsíKŠŠCþqE»~4½¨Á4Ÿ§µ c £ŠJ0}h§RgôqÓ‹F3éIA$u Ç¥ö£·J3í@Nø sGáI@ ƒAæ“îizÿ˜ÿ ?*(àzPõ•QÎ(`QŽàÑŒQ@ƒ³IÐ` _ÄÒcÔÐ0ü(Îz \öäšCÓ4~tsžhú:^i¨Ï¯Z;’(Ͻ'à:1ôÅÆø  ËCÓ éE ÿ\ßAE=qAü~”}(s“»ï{Õƒõâ«ÛÇLâ?âbOÖ„$-ÆÐ9éŽEL¨ªBíQÐzUr°ý°¶÷ó0ÜœU®{ÑÐmª§wݬèÎ!“Ë´ ÝO5jê8žYXª§$*qÛ¾;c­ Øh‘SŒØTsŒ¼º2rOj[}«Ù¹<±$Ógd/,à“€z:‡Rq€*¹8»P±¯ äÔà ¸÷¨ˆ]7o ý([‚,~zÖ|¸/6-‰#¡ÆC{ÕÉÕ^Vb ŽH8Å2Ù“ÊÚ’޽H[vݱ]¼t§ÈA° ã¦*8 òùro9ù†s¶¥“iŒƒíCÜ««À¥Pªú.‚´$I ‘}Z[UU·UBYGvëEÂæ,y›÷¸¦÷£ãûƒåÛþÉíMCBÛ•˜c 8§¯*0sèEC,[®c4Œu_Z]C©iÉXÙ ÉÁ=?Æ®ãñ¨.cYbÙ¼¡=Ò¤U¸œw皸ÙâIÊ´|)ëR\*<,‚‘‡™&Õ~TŒ­6àuApcb:m?>Pâ"¡NNsRçëùÒ(žƒ©ïN¤Äʲ:-Ü`³«6Gʬð9ïëŠóö”>býÒ9?J³Š}ì&Hô£?Z8ôý(úR½†JB\=iMS½ØÀFìè}áœRÛˆš]êY™AšôºÙ$¨ÊÙ*¤sŠWŽ_´«¤Š±÷}þ•H¤X ¢ ˆÄ³¼jwÞù‡…X9ÇZ¯n’$²–`UŽ@Ý’*Pû†  E<Ò[Æ‘¡Ù’ dä÷¥ºuH 2Æ~ð4[‚±d.ry4ÖÃèGÆ·NÊ[{ sаx’*¼K ¹‘Œ›”ô¨«ü½?>i1lÂ1QÃáŽx£êN1Œs¥UŸh)»+Œù{xo O­W]ßk;¢¾(@‡Ì°B’>ñ§Å“î!¸ê)³a` AÆî”B¡aPF:b—AhÕ°JƒŽ™íPÇ ù’ïc s÷[œTù=qÇ¥Ao¿Î”¶v“òñÅ‹B¨v¥¤Í(>Ô^)9ÏøÐi 2PÄ ¸ëÏSå-– *9Ü©vn Ø$mã­JU0 cÜæŽƒ ;ÅÁ4\nÀþu4à˜_ ã‚j&ÝÝ>výòp*YcYahßî°ÁÁæ›ØlH2 Mü£$t¢eba$õ›‚­–ê#;~~§Þ'ïeòÊ6Ý({‡RÀ`EC&Iu8<*lôªàîÅù_;$ÒB&”6Ï úXþàéøT7`ö1ÝÜqúÔÈ«QÀ£ Ⓨ©zŸj:õ¨ ÅWPæïq]¸ÈÅXÀ¢ª\¸·•gd•Æ1„ÐXeÛ»Žž´Èàü¡GlRLëår ríEº"F>éèÆ(è2nƒ¡5ÞÎr‘Œr9çñ©%”D›˜ ÆdÔK¸2a†GN´!"t$ -ÝñÒ’Qº2‰ªöŽh‘0‰ÐàŒÕ‡_1 r3íC@ C sÆ 6`Ä.ÄÜCw8Å2ÝÙƒW$sQÊRâc ,ŠPƒ¼ >£ê[Ç#šŽà°ˆ„@äôâ¤Ç^R$FTŽ~òÒB&1*g’éSõíUÑD±üì1ÔÔäëjÙ9Yvˆ°1ÔâŸ8o)‚Ǹã€j+]€¥ØrrÙõ©¦`‘TŸ¥6 !R°¨eÁÇ#Ò–RV2QAaÐ) …H⣹b@„Vppàgº‹¨‘îG' y9ÍXÎ;sU7‰¢ÌÅPrëV”îPGCMŽçÐÑ“ýßÎŒcøhàúÔˆ1P\ä¢|°Ï==ê~>µ^í¶ ýã!,ËÞ˜ û ÞœäåºÓÅœ+Œ)À÷§B# >äÔœzÆØ£‘Š®Án%)"Œ.Ï ÔÌv®Y¸Õ XwÞ²nNÃ!! $7@ŒœnVöªÒ´©"êž„sS†Ü ñƒCß祅®"F*Ò@ÉÐ.b,ªn~@ö¢Ì,MÒŽ}})’J±ýìþ€øb–™çÆ;Áu¥W ¡€$hHÏj?KÏ¥'nŸ• ñÈ…ï@9è>”¹öÅç8¢ŒñšNqÎ)€´QƒHqøÐñÐÑÆ)9íÅ(Z@íFM˜ £Ž””ǽ0ÓŠN”`çè(qíGà)1KÔPøR÷Z\v¤<õ¤ÇJ8¥”ý)€~”u¤ã©Î=1IÀì*@/nhíÅh¦Ÿj^E7€(N:‘©£9Qúš? _Ã4}iy ò¢Žý)?@ƒŽÔu3@ú~t¼ÐœQIŽy¥ÉôqéFùp)1@ Å'áGJ948¢Žôrzq@÷æ—”u%'^œRçèQFhÏÿ*š;pJ(À#Š;QF3Ûš(¤Å/¥é@ÄÀ£ç4séš &®1J:qÒŒú‚)h˜£ð4‡>”¼ö4 (Ïn'à:9ú}hãÒŒzbKÏÓé@‚“?ZR=©9ö bäRqÞŽ©ùâ€í¿J9>⌟N)?h,QÀ罎ÀQ“Šwš? ;ÑŒõ†vëFqKƒÛœã¥/áIøQóg(äwüè3þ¹³×ŠL(™‰( ?çöÍsÐþt¸ÏOÊ€Ó¦=)=³@_^(Àþ4£=F)2O>ÔuíúÑÐf€!Š0$i7–Ü:x©±ŸJdm.÷QÐäT™cï@¨ëvó’1·µM†?áPíœ\åpcÇ<ÓNxàc½AĬÂ}Á‡@:TûO=³ëQÆ;}À;b€0]À6Œ~4Œ Ÿ\ÓÜJdãvÓÂÓ¥ ˆ(¹‘¾Ñ»à ààUœö9掃{¡Cì%6òpZtäy‘(I'†i°² ‚7VÇ$ôëN¹*­ò˶N:ñO¨Ž€gÚ«îï“8=:õ§™[ÍHÊòFI¨‚ ¼Éùðrøè([‚$¹”ª*¨R\í úT‘)Ž%^:vÎß²»`äm$'|JÛvä}ÜçºB-‰ ÇîÊ)“–zÔÍ÷0¸¨f(·QnG݃‚ÇãS²‰©'cŽ `eU¶ç©e%M®™ªÈ–‘¼B)JÅÕ‰Îj´0®r3ÓŠmj BŒ;UT 4äÊ‘|¸'&­dªÀñý¢EE“ï|ňÀúRBDÓAñ”t =úQo¼ÆClàãå§°Ü„ÅCj¨±¥'’([ F . Te‰æ+Ì”ùÁXò`ž”’2A>ó¿sžƒ¢$•äG}¹èqŠh @c€¥ç½&OJ3Æ*DV|‹äSAùÃp>¢¬Ž8ÅU}‚ö0eÚØ'g÷ªÞ>´ÞȘ=éxõ¦I*›älßߴǸ)'qÔ¬¸ÈäS]Š©* :ЉnátÞ•Î3Žôù•^¤s@[îgvtÚsòòzQ^ŸZ®’F’Nw³•ÆG¥Mq!¾@~§±eù•G¦*)OˆA 0ÎjÂ¦ÕÆI£d“ö—ÌJ÷‡Ƨ`H óUÖTIä·Ê:b¥ó’@0Ë(°Ù¨Fî[ø†3Vs늊(ä@Áß~NFGJ—·Ò‡¸™ZA¶e+b[ž§ñ«TB̹“ž€ÕÏj:ÈAÁ8=©bmÑ«+žÇµ$É9ÆM:'ÆH*zG@è?µ&§éKŠ?B ¸*!$îÚ:…§FWÊV\àŽ29¢à7”vº¡ÿhdS£ÈA œrE>ƒè/ðäôª©‰î‰d• r È­6í¤¸ëŠŠ$²´¨Ì¼£ Aq•]ãq#ŒÿUJ’\€F=E$§’=éW~÷׺ïΓŠa™0Þ2½GzS*…ÉÍ.S&PÑžO®=]_€Àjl ìàëše© ޹ÏÞëM@Ûc~N3ž•,Yò”åN{¯Jjÿ®nSŸC“Mî>¢\¾ÄÎ9튕s°rOê;†trcŠ“ÌPB–ˆÍÐQžõÁ+¼ÿ»Ö¥#"¡¹.!&6 þ§¥ $‹Xäò;óPÌ«æ¡ËŽ{)É*¤]øÉÓ\4Œ¥6y¦·RÆxªË'úY/Ó<§XÞ«F\¿˜Ñ“íÁÅ$$M!ýÙúQ ýÒ‚I㩤fÊœ“Ó¶ibßåƒ øäœ~4!úT¸iÔTÄÿœÔQ³y¸ ½¸ 7â õ£<ô¤-øPñëHr;f¸äg§Z7€;ô §f0väö\Ô«½ri’ù˜B’ Ó•€yÇ4ÙüÍÿ.0V¥Ï·çHCŸ¥)éÀ?UµÉ’VóƒýÆ)êËö·¹px¤ƒ*î`’OÔRªƒ9'cviŒ±œ«U ÀbÎ…FÃ޵döàÕ×DÊ Ë»ç!"g¸S à7\O¥YV ¡‡ Ö|m,’1¨vàyúÕè·,JóŠCcÿJ;ô挃ÆEº~´„@ü* Ï!wÏ­XãÖ ›#i#=Eéjƒ¸SNSòƒ¸p)’… ƒŸjz.d ŽyB¥†[¦áÅ:?0Çó•ÝÛß4ʆ2W¨nÙô©ðJ}†r’H¥ý*feQ–`«Qrfè0 :_õg>Ýi0"I>ó»ä@Å4O™‰ ÎØëHÓßêò¾ c4Ôgò×ê>nãUb‹ ç¦>µ[Ì/1dÄmÈ\“øÔçîqøf£„Îvàœdç­JJû]I‘U;–â¦È#ˆ9¨®I )U`{6jD]±€8è( óa¤VlqƒÉ÷©%r#b:㊆ՃuP‡¯<Ÿs±ühcca$Ä¥Ç?\Ò;þùT(ïÏ¥:LJJàúTQŒÎÇÊaÏ?Ó4ú€ù·˜ð0eÚ1‘Áçécn è5 «DÁÌCŒà“Þ—@,Çò£<úÒçcõ¤Í!ùõª÷Nc@@ŒüÃ>aÀ«9ëUîÄ^PóQ™w©€ô•BüΛ€ÉÁÎ*E`êH*k9L*]£·møð9Õ»vÞ™ Tz56†Ñ+}ÓÓñ¨í£1Eµ‚Œ’r£©”9 ²ÈùrOSžô-…Ð’n…V<ðx§FO–»€ Ž@â1µŸ9Pp ”2ˆsž1Ö—@ ”n™±n9'½D¡w#pô©íʼr;ÒÜ”îYˆëœcñ§{ ”}Ñó`ûTýØsO€'’¬yÉl昅Lä†=:­@Œ|¯·ìÛT¡p?*³>ZôtHUcfcòÍ2Ý@\®í¤ dñFè.OŸzBGQš_åIÇj‘ ݓޟš? Èö£éIƒŽM4À?*8ÿõQÁç­=±@qE&@=ó@üi?3Fhè)¿€¤çÿÕFx£ Мu4pzQ‘ÚŒŽôø¥ã¾(ü¿:N§=èϧO¥.AäŒýE'Oz8õÏã@ Ó¥æŒ{~t}i€q@ê(ÈõÅ÷4 Q‘J:ŠLJ3žÙ¥¤çµ”qF¯sŽhfŒûN}is@x¢“¯z9õ È¿çK‘Iøâ“޹ü¨h$ w£ u¥ÈÇŸ­ö/ãI‘Ú€ëŠ\ëKÇzO¡?…”¸¤u?úZ?:OÒ–€ïG“Z({ô¤éG^ø£>ù Í&}h¥ü(œg§ëAÀíKI‘@ƒ?Z3ëKÅ ÐQÒ“uÍ(àqÒ€ޤŽ=é~””Pý£=­'^¸ü襤 aÅúþ”}iq@áIøÒŸ_ëI‘@ã®Mç“F=è㽞äQÀæŽñbŒz3ô4^ô” 9£¨ÖŒŒ÷ BqØÎ—·Z? °Í ¤=:f—#×™=¨àv8£Ò—'Óð¤äP0ÈïÆ—#Ú“Ž¿Î—š@~´cÿ1Iœú¨€ÿ-OÐQGüµ?AE=ÏéGÌxÜh¥ÁÇÞ4sМQéFêhã>¿J2;“ŸjŠ^ùˆ©yô58m§Üf˜ÏŸ§4¹?‡¥ äuð£xVÚHßpÅF:Óc#œÒpHcøÒ&îK0ü)€J¡ À4±‘·€*Y2Éò­ ¸¯Ìû·jŠ4U•ʶI<Œt©$ÉL*Oq@VI}Ãðâ–A¹?6%*¤dõ<Ó# æ7ï ðéO‹;pÌÍÏ^”ˆ6¹÷=©õ'Íê/>¹ {f–¤D vÏËòôô¥ûL[€.2zS˜9—#î㸨J\’Ûv(ƒŠ¥aŠ®rcžÓÐTì \n+ôªËɹL;ˆÈ«@éH ðJˆZusëÉ©ã™$kƒôª…nÈ oꣶjDÞ&è1œŒ~µVL ! ÛIèj¼SˆÞHä™YݱV9õϽUte‘£Š,7lã?Z”¿l‡å@ t§Íf ¸VFkX‘@óŽMhä÷9¦íÐÙlLI©íM„’îÏ­, I !ƒ œf™n!EE^9¡l$Ny5Z!›—mÊ~^Õ`àvÍV"á—ÉTM¹ ´ % BÃy\÷¢" à6â¼ÒÈÆB®óÛ4B6¯ÝU絉·‹ÀyQV9Ç\Õyw}ª1±Xg©8"¬`Þ‡°ÈcY|æ-6å#åQÆ*ÄÕt\\11€1€ÝêÇpE&&ÏlQƒõ£$úb“tϽ2\ùM°àã½UÝpî…]v©ç&­É¸¡=j¶åû<…¡bAäc“M Qà `F )n9ÇãU¬\5¢ ±G95cŸSCVbehflÈdYU°8Æ)óNžKl™CÕ)ãÞ kGb$ÈÃgñö¤Tv•ÙíYS`sïê*¬Š±~×zÀº¹Éù¨c2}®ßdc*‡±ÅKhŽ–à29?(¨aF[ˆ¨ÝÜOÖ—Qu;A1<À?¿š–"ÆDŽŽwj¼(@fd#Ô¶‘˜â`SbI'“Í602Kç°gQžÝqR‰ãhüÀÀ¯®j CåÊÄN:üÇ'éTöÆÑÆÍ »}ŽãÈëBI ±¡n.ZPÙL¼9!·“ÛÞ´Ðf ㎙¦ÕÚ*»]íÊ,m×'¦*ÒÀ{â«c÷.Œ¸=zÔ¶Œ¥0‘:ŽXûPöÀéAbBNzsšàòEI%xdigmðÚ8$óV ªÐó]Fâq×µYç¥66U¹{Œ”[a4d †#¡K›”ò‘­J‘•Áv«ø=qKÉíBvè(ÚÞIs}qؼi en‘Ú¬ÜJÐÄ]c ú —'¿5Zð¢Å¹Ë3ÂŒÐ,#Ž#' y ºXÊƒT¼ØãiÜ4ÛIÂLQnÏ“pÅ9'UÊU)¤ ätU!<¬µ™é¸ûÕnqû†ëøu¢ß˜AÜäŸïu©BbGx‚11ȧ–À$ Ÿ®iÛqÎ3MqòœnâŠÁ÷adµÜò˜R Ý0ÝAù[¿åQ7Ídß½œ›#5=©&Þ3–h᪘ɀãühíÅg®M½êI!„’±1Èp¦ç<‘øU{v $€Hí†èݾ•`gÔÐÆÈ.K-V-ê[æ'µJ‘¬q„B…èCu·zfI“$}ΟXÁ4úAyïÖ“ ¥üM'çHEk¦ùV3uvÔê(QÂŽª÷"• ÌÁKÁ«^ÝéôÉeòSqV>Àf’`¿–›¨¦\àD7; ÝÔUV”JIŽé•P}úô%q¢ÕÔ¾T|ÄXŒb¦Q±>QŽø¬ÌˆÂÌדml çŒV˜945a3=Œo#3@ùqÉÆ9¥Škv–eò1ðIç5¡ôæŒsÀ4ù‡r A“º8„`’HÅ-Ô©‘ );qõ©H=:}*½Þåp•Ww ÒÝ‹©,I¼!c]¨£€;T6ò¬’³yL„Œä÷©×˜Á-Ô}ê­d@R¾x”äž;кŒ|ÌŽæ7G*9ÏAùÔp]G8‰ò~\ƒ)Ҝ݀&`Àô>õkÓ4lƒ ‘ Š0‰œ †âuŒ0hÝ€%EO¯çU™¶Ü’fùBýÎâ…¨‘ZK¸Ëu‚G.vã8þu¢ˆaF*¢8n È`HÂwŠ·ƒÿê¦ÆÅ-±Kb§5GíæFvYQ›åçq÷ §Ö¡‰•Ë#H®SÃÞ’"ˆÅ$Ñ©ó ¨$x«ÜcÚªN\Æþjª…9\c>õd®wv¡ƒeE,x°æ£„«ÊXƒÝÉþ´é¼Ã ylñÁ4Ëwc‰%V›m &ÝÛ{U Ù-òÉ+2àNìu«ùáMdWR¬SÔÖ„/>ÐHêdaÆ 'S[¬¬oܨ0§Ò¦hÑÙY¿tã¥(P ~î;„’*¿¡8É5TÝ[ys:Ì[@þ•i”0ÚÊ÷Ó{HÚ1Œc´ËuRÈ[  z Ÿ'½U·Ü%”»¨ì*ÖF=E6 ¦×ÂrÍqµ”`ÜU˜Ðgz»Ž9â£~û‚¸ÇB*lÛaô,¢$.ç€3ÇQæ·³‡Îfm²°è*ÅÀ>C´’1óT3Äßgˆ1!‡Þ<*!í"|±†åú:Tˈ£Ÿ€:úÔ3†2ÀGÁÍYÇlgÚ‡°2ŠÉƒ‰òÌÝ[ŸÂœ—åL•<ô"¬ùQŽˆ§œÓ|ˆðËå¨ rF84\.:À­«+ †éÒXØ–À­"*ÆQЂ•ÑeBŽ2äR Aíj±ãŒÕ¬ñÚ«DŸ¾lÄ€6°êjÎ}ÿJlZåRFŽ3 VÎ@51l`w¨åßæ¡U\ äçß:C@±Ó4[AЬ²ÌvH0‡æ§Êܪ‚ÝóÒ¢·.K—…çª6sD®Ë<`†õ¢ÚØmGÊ$«¼?”È7Æ=óHnؽ3‘DC8تíÞ€òÇÅ‘°[…½G´³îÈnGµ2á d`ªq“’j)%¹XË$@…ºiÜ'˜›¡§ü‘¦ælí³UVPfÚ4ÞH縫rѰÀôô‚|Ù÷¦…&`CçE,dqÓª»ŠHî-ˆÀá¸Á¥Ô ­Âœ=ê(T亶æÈÛÅFg—'÷%¸dT°€‹÷Jäž1E¬ œRÒg>¿JBÀÅG2y€ÃrœŒÔ¼ö¨^’@ø9=hè r{ç×RÒ¡Wš“Ÿÿ]WwÚ¤0žhv!z°ñBæ9÷ÅCrŠæ<£6‚§©”p:þtt$Á ×Þ”’±ü݇$t¨0>ÔIY3úT“ŒÇŒÀÿw­„1bá†Â§IMG*+£TŒƒM‰v ©^:R€h`Æ*,h*€1ÐS“Ï8Ù°Ç4ùllÇ$Ú¡¶DùÝAˆ<Œv  R#¥"""…LŽ¥ã½.On”¿“#ÔÑ’:‘ùQ“Óš@(éÁ”=qKÎhÇ­¤{RgÞ˜ ÛH~”¹=qF{ñ@ žisIŸò)s@i^éKŸ©¤Î=é¾½(ëÓ”cò¦óŠLzÒ:â—ŸA@ ùQÈï“IÏz9íÒ€µ&FpqŸ¥/4s@ úÑô¥éÿ룟¥&NzÑßÿ¯GãøÒäù´N¥z¥&{`ÒõP0è•!ý(÷4sï@…öÎ=©0}hç½ö€Û’)A÷£ëšOÌГIš:sG__Æ€>¸£8£Ž8 'Óô œw£©âŽ}…ZQÓƒH9…Ï9¥ÁÇjN”`þ4¹Íiqîh1늼Qõ£÷Í.=¨üi0{Òóé@}zÒsíŠ?:9õ aƒë¥ÇSùÐ~Ÿ&Oj:÷§šÿ9£ŸJ`š2{ÒÐãƒF[¸ÀõÍ'#øÎ=)r@ a“ëKÒŒÒf Iœtý(üèÆ{PÖ—ëIÈÿõÑô4 2;rhëëFMuÇsùÐ3ÿë¤íÚ—ƒÔæÖ—=©0@áZ>oQ@ÃÆáG×4ƒ#‚GçKÔq@ƒ# ûQ‘Ó×µçÖŒÐøQ¸g àŽM't œèhϹ¥>´­÷‡ß"—ž”të@ ך\óÖ­æ†N:äRmÚ—ñ óÈ4€NGqøÒàúÒ­(zÐ}%n{ (?ëOÐQ@qÉ ‘š:ž´cÛó ãÒëÅ.=E!ü QL”7RßCŠnNEG&S¸¨ôõ¦˜àsІUùÁŒ{’z¥M’ÀϽA)Uucbp2(bNÓý)‘“–­<à)ÏÈŽKaÒ€PLy ¸ç¡âœ„Њl›¶ú{ŠT*W#Ÿ|ÐSòŸ÷©Î[aùw{ `víßߌçN”‡æÚ}E$º De9èù¦¢·šY—œœ|LY,Íùf™ ”¦IbOÆOœá©sŠc°±'‘QZÑnÒ{°Á„#×@m½sùTû¹äÔRòàÇzþu('©æ€}Mz‘øUPU/]·òä ¦§œ¶9¢ÀWdˆ¸Røþêi°mØYC ÇÚ•ÎÀQÀ»+ßÂsGA¢9@’â0Cü§ ㊱øÆ¡“þ>3mÇðôÍNAÿõóMìHÍ;©È#ÜTüâ žãqÇÓŠŸñ¡‰™·n<â ”‚ò£ ÿ ¹jTÀ0ä®8ÝQ\M29Øñt?xãõ©mÙž=Ïßìš} èK#mBwv¨m¶mo.E`IéëS1ùO'#Ö¢HV܉NitÈXý¥Ð6G¬’}qôªÏæ,ê  CŽø?ýz³Ó¾ ^ ݶ¹`9ÅK'“‚~œÔVäù’>÷QRJ1TSC2ÕÙâÜÛºž¢¢C‹©˜3çÐŽªkvc20'&ªKpÑË)*Ü’qŽ­;j>¤–Îì^V” avàŠšÙ™£ËnÎzÒªÇq1¸ÜÓÄ!8ã¯Ö®A#£äÀ\ò>”± Æ`ÃÔ &æUlŒhˆmAò…€4º~9ÏjFbäôïKøcÖ‘ˆ*{Ð"(hóò€z`RÆJŤOÝQÚ’ÛýVJ†sLo2;€Q«`éT÷(´9íGÔ{ÑÏLþTgŽjI!„åÜ7u^¦¦í×ó‹$…ceËrOsSÐÆÊ÷B­ìÿËCüªÀÏäjµÖL®sÁÎ*ÈÎ3Š} ¼÷£ó£4c=:R^f;ÐVŽŠœÿœUk:¬‘‚;Õ¡íÒŸA\3ˆÁFägwRÇ»‚z•¦Ýüɸg§¥I€ƒj€=¡¨FÕP…sÑÎ*q׌b ¸Tp‘–‘Sóï@ÁëÁúÒã_ÆzçΗéHAÓÛÖ¡º#ÉË pCRóÿת·áM¾28QšÑerPvéUíL‡w›£dü¢¤?,YÚXc€8¨ìÒ0›‘vòG'ÞŸq‘ñ(˜Ëwæ§ëUåe q8â§í×?JÐ\û€j´ža¹"²ËV3Û?˜ªrK_í1¶öLîÝÇ_Jà‡Î«y±$~c j°‘ŸÒ¢¸C§Ñ»Ë'åëŽ*oÄUb‘­Ó?šÛÊò›¸üªÈÇÖÜ*˜2–è'ð¦xî-•X/`x4ë »39P ž)ð2¼*ѶTŽŽ€G2…x€ òôã58üóPLÍf ƒÀóV1ÿ]>ƒ{i9×ò¥>ŸÈÑŒsœf‘"wïø?ÆŽG|Ò{duô -üµšDEÔž†­{äÕkq†e2ïp95cñÇÖ†S+ÎÌ™Èê8ÿõQöXÎ2Ìp=i%\ÜDD¤N@ïVÔÓ»Ar `«$CŽz°â‰š5ž=ä–'MµÙ¾M’ÉÎ éN”¿¥÷ í—¥g©4½¨0qFÓÜ \P}N8£$z}iMc“@ÄþT~´™­¨ ò;RçÔÑüèÇ(Ç©÷ Q¯å@ Ÿ¥/½&8ëJ=Í ú‘G^:RÒc±ü¨‡uïKŠ1ï@:z})Ï4}hÁï@ó¤<šw4q@ îÓ¹4sëÅ'ò÷ ÀÿëÒ€;c󢎵 zŸÊŒ23ÖŽ{£#ÖŽ}hç×ó aÆ9Å'´cÞ— -J'ØRÖŠ@3þ[7ÐQH×·ÐQ@>´sèÒ€¨£Ó4gZ\“Í-'èÃucéQL¬Pá7Lâ¥À=ëHÜŒt  ù™ °TÏ!4øËy‡tªüpæ”Â…ÃbG|Ó–$W.“ß­;Œ“ðªåä Á „SñØà}*m–W Y†cŒÐ$(f(¡Ê’{TŠUG ÙP…ÉbTäÔ¸8 Õ·#½,ö„n÷¦ùKæ‰sîM9×z$ŒŒu ‰bðO®)’VQ±#9SÔà“N†?"%Œd€:“Í#Â0”³8§Ô:‰.²$eKÄ6qÇJ²ˆª Œv\Z¨GA#|ç#æÆ*ÄK寍9¡ØldÀ…Ü©¸ç§JBÒ‰#©j™×rã'ê*n †ó`v4±«L¨ Žœš”ãaÁ¦Gˆ±ó$lúiÿ‰  žtºD–Œc'ïN1­Ã…’<í?Òƒlæeq;ÜíRœËœ’0§t2R£Ú1éUd2Â$ò­†{=J·ùÇš†[q#$u#Ðõ¤„Š­$Óyö„ò 7¥^"€ `vÆ*lT©㟛žµc°sM´ÆÙPÍ9·$À7úàÔ~l–ñ“žI$§ÿ­RÉi¸¶g1Ý)La‚ÎyÎ2)¦‚èž6/±B¤ŽTöªòæY¢†FfäóÁÿ °€¬aYƒÜqQÍ H~Y]s×—Q_Q‹4ÒÆÛ°ªæ¦Š„ƒ9<Õf³•!™°#§ãVÀÅ ®ƒdnˆD®9|p*|j£c*¸r»ÍKšB+ÄO›&a*sÔžµ>?ȨÖ7YšBùSÑqÒ¦çéõ  ÓYÅ8`ê#žjX£X£ Ϧž7z®(ëÇj.1NyéPZØÅ;±'=.Õc>÷½EÎì-Ÿá¦ž€6âfˆ\«Ò¤Œ—Œ1\nv‰ÛHSŸ­,k±–$Žô_@èAo° »œ©Τ™£#fîzb›r©&Yw œ*b>^8ü(`Èíóåp›'Œæ –ÖbžIeŸ;Î¥Y‰4Úy÷éM™ÙJ>Ü{Q}G}J’[[Àc nîÇ*úUÈÕb@§^Ni³$Îcòä ²Þâ¥Æ9'žô7 ›+… s“pxlUŽ~uDZtpç zEMНn2ˆŽ\5:xãuéÊrzXâtc’Jã®î´öÜT…È8ãš.u»ÄiˆðOlñ­치L¥¾LŒsÍI¶]ƒ$îsštBE8!qè)ÝAeû„í'Ž”ËP ·îýsS>ómÀlqÍ6! ŒyŸâ—A\;P¦åläÔŠÀ8¥,¢FŒ…8'¹§*€´t„Ê6o W#Ö–xÑ™$va´ö4äIÅ™ò»p÷ÜP•ëõ¢à$n² t$ŽÙ¦É:FÊòyÀè<Á ‰[ÔS ÌñÀ+üG#Š:‡R’8‰›æù€Hñ9Í@å~ܹo˜)ù@<ÕN;ûÔl³} G–JiêBg [ÓŠ-öˆWnõ§·Ýã¯n(Œ6Á¿ï{Rè±øÒ8qŒu¥üi­¤:CfÈRެ¸àJI@ŠA+³Ä œ– Ê€0è;Rº“·8= ;ê;ê;9â™,é2粂M*Ê ‹ó÷¦L²î_-TŒóž­ "…RÔ»—y7¶O$ãð«jC(#¡ª‚)7ÌJÌI (©àÜ @ã Žp›°ÙÖÀñ³3(?(ëNûd"7q {2i'YãÄa×'9Ç­BcŸÉ ÚÆËõ|u¦­`-%ÌR±³ž:t©¶©bÀÞ †6ŽFÜ¡A=¿¥>sˆX q÷HëI‰•®%tQtŠ`[jRtÝ\㊪Þ`(RÐ̓œp=j[8Äq d“Þ›µ†>áÂFòœõ§'+ž¢’dÞ€ya¹èOJte¶/˜>nø¥Ð].QBÙ“œ¯Z² öÅG0ù©™ÁíI‘ž£4? Ð"´¡šUÝ(`æ§ÊïÙœ63Šdëäí皥,hX¸YòÑýßáëùÓZ•¹n”K.ð6gå#½OÓÒ™1/ÊTcRç=©12¹Y¾ÖI+ålàcœýjlç¡5âäæ'(ùƒp ŸùÐWš V#ˆÿta„j‚@䊊íTÛ±eÜaSEµbQÓŽ”B9w™cà ¹ù7?…G&<ÔÊ’{j_Óñ ÎJ=ÈÍ/åI×¶OÖOÖ“$ƒéšw´‡÷  Ш»‚“üA³šŸŽß­2ÓYóØgƒRÌÁ"%ÏËß4ÞÃn¥S ŸzYK`z’qŠXP&â 9=蔀“·=ñIî.¢ Â´t¨a@·!#Ǻn©£cP·OzŽ=­#€Äàòt d¯œŒƒØS!ÚáBœóÅ=”ûÄÞ™ Fé”}ã=qŠIœp1õ£9êsúS€ÿ&ŒqÐR3è*­ÂFóÅæ)$6AÇÕ¬ ã¨æàd2«™¦ϸü*¼RF÷(F/RG£ 7ÞYÆí§Œ³6 ÄïE†+ýÃ:t¨ÜWÑºÔøÏÒ©HHȳ²úÉ×a"[šI×Sžôû¬w‡#בR);FHÍ/8àþ”›8 L1üYÍCq*‹¸äç<†þ•³$¤¤ì¹q¸ÍI È“l–d|䌯5K{Œ²y^M2¤6ÞyÁÁ©3J¬LË#aÐ.~P‘R$KpBÛ¹<`uÍ,S’F:“š€4ÅUåhömäZ¶=º{PŽ?­ Ëš3Ï·Ö““Ø\Ž™ü©Ù¦ ââ”çµ w4¹Í7,{cÍ`jb>ŸçŒ  4¿…ôÀ£4¿•JGøÑÇLQ‚=hÿ=i >˜£ŽÜøQLëF}¨ÈúÑ‘ïš?9 {P:p(sØŠ0{š8äQŸlÐ0Í(¤Ï¥_åKIÍ&=ñô b‘E÷£§oÖ€ šHäŠ3íøÑ¸w ÐóíIøŠN¨Ï|Š_Çô£§CÍ'ãKϱ A׿åIK×ÔQ:ÿ:Lg¾>”cüæ”`žÏÖø~˜ÇzO|R⎜b€üç4{ä~T¤ã§˜õþtw£ñ£éÍ/çøP}ir}1øÑþy PùRvëùRþŽ}¿*OÄQסÇҗ𚀠^h£ŸJ\f€ fç·ëA±£¹ ã±æ¨ï­PqjB=‰§w£ŸJn(éN?'ç@ Ï­.=ó@}1@{:õ¨çÒŽsÚ€Ëdÿ]/ÔÑÖ€õãÜÑš0{óFE SG8à :âŒô"sÆphzæ—4}h>´¸ô4sIÓ·ë@¦Ÿ¨£ÜÊ üè:gŸÆ—œg4dú>‚CëGáGZLdõ8úйïIŸ¥)h;Ñõ¥Í&Î(dt⑎´ïóÒ’€:ƒKÖŒœtÈ ôéHÏúöú (?ëOÐQ@$œ1KžÙü©>‚—>çñ êMù£ÚŠ=¸£8ïš_~ôœõ Ýë—>ß­FÆBr„cÒ´~_˜Š0qéHáGâ)Z t=hÝëš2sz@{ñFb1Q§˜„…ÏËŽ*N8ÇëLãr)r:çŽù¥Í!ÿ&€ 1ŠPGJc±U%Hϸ¨wÝíâ5ëëÎ( ¸éH=øöÍG³Œ²•>™©8 §ñcÚ‘Þ—Û¨÷d÷"“§8ZPT1øR“ŠLwïG#¸ü¨à}hÝô'é@z`þ´Û#4˜R9ëJ8Ê€ àu£#'ò¤Èî9£¿•;¨£‘ÔsëMãdc¸¿_š0:gò¥Ïn?@3Ï4sš2hÎhdûÒŽ}èÎsõª÷7"ÝPà¶ç Ó¥,žhíË«Ereã1 Ü÷©óƒÚ†¬ÿÀ¨ÚSúTRÊbÇîØƒÕ²8©d|´ìsŽÞ”œãÓéI“Óo>¹¥Ï|P!2}óKÈ9=}¨É=@ü*´·-ÌQùYWÏ Ð•ÆZäš3èqõ¨ ›ÏRBA ƒjn}öÍ XÏlÑ‘ô¤Î:Ñ‘Ô.OcÅ&I£ƒÐƒA$w•÷ýiGÍC þvï—[(=y"€`Iš=9É¥äûŠB­'žÞôvïŠn=èïÔäP³ž‚ÎOçUúf\’‚±ÂŒã“éMEŽÌ»¸ÿ‘Fyêj(fYÓxÎ)&¸ò¤U Ýx4YÞÁbmÃÖŽµ1\vûb§Æ;RjÀtÍtÏç@ôÅh¹£Œpj9gH#ß! ½3PŨ[LI ù¶à©Ó³‹]zøŠqëGnzUIo­ã™âfÔr½;RµÀ·Ï­ð5R¤©¹yôæ Hýhäñך¬/ b ¶ £ëV?,Ð1OÓõ¤ü#F8àíGÔŠ£ñÅép}¨?~dúïKÏzŸ\~T~?…/ï@öÅò£9Ÿ.=ZŒ 7è@úŠúÓ¾”g¶E& c¹¥Æi>¼ûb†sKö¸ 9éFNx >‡éKéŠ9<ž¾”dž˜ AÇNE?äÑÎy4P`~>´¹ôëïF=èãÖ€©ü)0G¿ÖŽsš1žàÐ^ÃØÒ“ôü)Øã¨£zfyëJIõ•.sÛÖŒPr:qFO¿çKøÑÔÿõè9ê9£¼­;É Sy>£úÐ18¹úÒóŽE.>¿…&2O$Ÿz‰£üóKÓÐRäz€ϧëFÑžœûRƒÛ&ŒñŽ£ÜP~¦ŒæŒuàŠ1Þ€ ŒÑÓ$‘Š:Š\ûP1?E9íŠ:ØQ@ ß<þO½&G÷hÏ(íÏJN=iyÀæ—ŸJLQøŠ2¸ü¨#üŠ^½è?¹¥8­74¿çŠ_Ïó¤úœPmîë@ßð¥Å'9 BRÙ*3ëŠP=84›³ßžô x\fŒJ9ïK=(˜÷ýhÂŽ03KœôŒ{þtœŽð¤ÎzœŸjv?J\q@ Æ{Q´GzwôqþE7úR”Èÿ_zLzPaÈÐ9ç>æÀëAÿ8¤ÇAøšEP ù@ì) SùS8žôžô|Ùà }i}áŽi®ªÜÏךv3Fö¦B÷d zñOTTUÆyâŠ0=hÀÇÓLHÿyA>ôïÄê(Èîh0?È €GSNÇùÅçÿ¯@ˆDî'$ç­(<ï4¿Îî?*“ÑŽ:Ð0ä´Ò«ÄdÓ±õ4vèiC¨2?*“=0}©zúÑj`ƒIÁïKÓ·ãFMOÒ“wÍŒàj^äRõÇJ@7æìâiqž:}(;O\Rã#9  Ñ×½/ãIÇLÓ÷£ŽÃ4pŠ)q鯓4½{P~¢˜=@£'Ôþtp~¾ÔRÆ~¾´™¥À£ÔÀLýhÎzdRàQŸj=Í'#½/N½(ÿ¿­/ô4ps@ƒñÍuïš(ÿ=ih£ñ4˜÷Í{Q‘ëŸj\às@ùëIþy£$žœz`гþsAúâ“>¢ëÅÏz^i3GO¥ö¢“ëGô¸Å ö£§ÓÞŒç¥-t¤çg ^;šëM<úþŽ}}ÍIÁïúÒqíJh£š3aGå@ŽôcéE éÿÖ£ó¤ÏµÜPÒ`QA'·4 8£?OÆ”~t b ô¥íÅ BO®(Áõ “Žç@ÏZ/Ò“½Çÿ^—4˜¨/I,§HŽe(v`í;»sõ«üýé3@´óptëSy…ºòWÎPrànýsVIÆÖ–“¯­ úô£¿ÿZŽœRÐHsGáG4sëF½Ž(Ç·4™Æ:QŸCKƒõ ñHüi~†“ó£Û4Ãþ´ý(¤çÍ;ºàQ@ þi@4Íg€F(äu"ÊÓ½(ç×ó ÁëŠ}?KïøR}3Lc $ !yíÖ¥`# Jˆ“nyxôéNYc=$zæ€܃Ü*3К”ôÀ"“ ÑŽý¨yîEE18 ³9ëš—T0k‚<ÆùO@("£„bWµXGÞ€í##ø»RŸºqžj(œ÷•€ã”0à`àÑÉíÇÒ“ƒëFrAüé øÇ*ßU©UFò¨æ·+&Ìzô¡g†|áÇ^E1‚°ûC.Òœpj^iÆÄ•`IïšvqÐÐ Û‘éô¤$*–# Ï­.Aï‘F(’j*ñDÆ'Ûã~*x.VW‘v6Pã8ëMÚ Ê$äëó”Òng”mq·9ÈæžýH·Éå…99ã#:Æ…›€:Ô0³™^D$1Æ88©_OB}é1 ‚tž0ñœ©ôÁ© ÛsD »Û¦Ç¶)½†~¿…#:¢eÎÓ4¼sP͸¶ÐÊ ŽýsHê6¬ŒÊá€àäb¦†á.)ŽzÒˆ"UÊCŽø¨ÑXL@Dã¨ëOAèÝ,¢²ä7zb_Û¼ÞPÜššI£CIòŒðM#È­4eY”g–h PÒI´æ˜n£ÉÉö4É›QæDˆåzÿ:p…T¼I¸‚‹X,HŒ$ó¦Í4P(22p½C3²6ØÕ@=ÏÖ§x–EQ"ÁÈâ‹jO¬Bœ‘Ö¦Ü1Î?P)>{ÔjoÌR`Ê&òÚiHI€œ2÷?Jî¡EèzvÍG,£± ®rçÔÕ2ü*´°ô°¦DT.~èêGj‰/"hј»¶:Tûr>b1éP´ †ÚTv$)hI‘Ý•33ÈÀ4æ8\’?*¯õœ¢Âc£nÎjϨ4&Am ‘oÃKv©ÆHÈ_ÀT͹[lÃ}jr2~ïëCÜ»ˆíŠOÄýh=ˆÅLRŒë–c€sQ ȘFD¸ó>îi$†s–Jw#¸ïJ¶,ÄJtâ©%Ôv v,ÒfPøn0?íQ ü£&犂ٳ$Ÿèâ2'9&Ÿ 7<é´“Žã"††Ñ0ž'PË"NjOÀf«4D Æ¬yìML„” TƒIŠÃñž)¯áJ@ô¤¸¤"ÿ¸'‚MOœãäüø"¨ò¯YÞFã%÷!N[ÙX©û4Ê Ç5V¹MÝ’(˺:⢷g’Fcoº9ÏëRK)‰Ãqœi-¾xŠ…ã éIl$C+H“¨ýÌh[´e `ô ÔW®ªZ2ÛNGµ>˜“ µqÀ£ t$Á9ïF{`þTœr8úQø·ÒŠ“¼’J‰DprÁ8©e/Ï&`NôÅG–×[ü¦RÍÀô«*4d2îäf›( |™ùzzÔ‰$vib\A$ʚʉj¨#r0¬jx?Ô&`…n´ö‘oº¾Ð¹ù~läR]41o±ß# žÔ’ùbî2ÙÝØäâƒfùdòœ¾Þ À Ëo P©Kub§?"‚G¿5fó"WÚFGBiX(C‘‘Ž•ºÄItˆ©Æ9R)n€µ@ؤÈõ£8< DŽúô¦‡V‚0yõª÷m‹d€ÜpqU×LŒChŸä9Ý»ÓIuFˆ9…?:¥¬S´dÊÄž®r*Ktˆ;´y'<óš,,“LR‚OÝÁ¨ä òTzŠ4 7»/9,9¤'ç½.qÔVd7V±'–¯3Æò*Xm#eYViH<€x§aؽÛÛÞŽ‡‘Un<¹Ù”ž…G5öt}æ˜v&‹ Åüç¿uªÖïÆØ NsPˆRæW•.xÛ€(°X¿éÒŒ{Tü…Ë2HSò‚;Õ´mêt4XÏ¡¤Ï¨.zâŒZBïv¥ÇLÑÅůjP0(Ç”(àž”~~t~{`Qž:QÏlPÏÖ“òüèÆ(ÎþT`ö¤9=©O®(úu ÿw>ôqœâ–“޼¥R}x¥ã°?!>¸úb€iîúQÖ¯LAã¿ÐÐòz:1Ç?­º~tOJ1ž {Qƒž8¥äqGá@×õ£ ãŸj1G։צÀÒý1šhcÒ“ð½ '½'á@$ñŒS¾(çÛ˜Çj1žÔ¹>”uïšhôúâ—÷J_¦sAP{@ J1Ÿ¥.?ɥǵ7ðÍ.µ/€Agò bc3HÓò§qïIŸz=¨Èü¨è;~4g=†(Ð~T`RóéG~(>”qK‚}3Fôü(3éŠP 8ïE&ýtgñ¥ã®(ãØPrG^ŸZPÓéG÷ü©qþzRééøÒc>ÔBíŸz`;èsIúP3ÿë£> }hÀéÆhÆ{Pì9úQׯZ FßaHF: C cÒÇ¥ô¥üiˆ8Ϙ¶)p=(Àìq@ סǽâ—Š?!@Ã#§zÇ@3GÓùQíÅ4¸ìqùÑ‚(ãÒ€=iô§}@œÒ=úÐxçõ£ò£8ôÍ&ìÒŒžù£#¹J:ÐþsFïFsßš1êi€„`ã`ö?ì3ùRóŽô…}èÇÿ®—w¤cŠ2B>”¿QAÇ¥0ðâŒb—8íÇÖ€}¨íÏéIǧãFÒŽ1Á BpqKÇ¥/|cõ£µ7“Í/4ÇSÅ)ãš7sFaK‘ïIøš^ŸJ:sHé‘GäzГÅSIÁè)Ò¢Œÿú¨$þÄ/”ùÐÑŠ9£`{Q“ßš1íIÐ÷ ÎhúÑ|Òq@ j?ɤã×ð¥Î{þTrz(éÚ“ñ¢€#Ö–šs@ãž´¹ö¼ÓrA“íGÔPçПÊ×éGãGj\zóIéGŒýqô ¢“#Ö“>øúи£ð¤üsEhÎ(ãÞŒû‘õ BgÖ”ÜRs×4`c¥;'¶(úRœô£èp(éÛQGßãA€}¨ü(húŠO¥'Õ¨½:(éÿ× @h$cš(ù½&W±&—ŽÔ9ô£Ò֓ކ€?…™Þ¥=8 aÍ÷‡Š1׊Qœ` Læž:҇噇| (ÿ–§è( ŸqGLu#Ú—ž™âŽF(w2ü©7äþTRçqùÐvÏ4 þb‚?Î)€„˜~tÆqþ¬uÍ$`g!HúŠ‘ÏÊr? DbTtöÅ8{šŽ‚!´œ{Ðg@Ì¥X•êq@`zâ f•Y¶FïžMJ’,ˆAÛèzÔi+m Üç@!žtªtx-õ T‘Ë„Ôõ§¾Içð¦@ !˜äôj“§CŠ^é ˆŒç8ê$r¤œÇœ}(pßð¨Í¼DcËöâ‰ñ¸\cŠ˜të@Äf5}êQϱ¨P†ðã#)*o¯>ÔI¨§‘ãPP$€:TÜûUk°¦ *Kºqš 6pw1Ì0Ä lh±É±b(3ÕXõªñí¿ÌÙ-ц?ŸZhhXB»¹òB²œnÇZ–@ž[銊²?˜³ÈÀ6œSÚUÞñoÃϽ –»>Î…¨#‚?OÏ¡ÅCjKÛ«e¹îÝzÔØÆ1ÍÜOq=ð¨&T. !n13V8ÿ"ª\2E*¹˜¡Æ0¸¡n²‚iyKß8¥Ï×ëQùŠX¨l°ê:â0K™9#%S‘Î*¹Óà…fe0“ªóÇÒ§·f3MûÖn@ŽŸ¥>ë nêÒu=*®ÐÈ6ƶé”~œÕ¨†"^6ñÓ9¨$ìªÁ0£ 9£É™•BÜaqýÑM‰t#óC›œñÔU¾6ûSbFEùŽöÏҤ䎕,–Wfm¡ÆO9Tçðªñª$?tš³CWœ¡eFä~0ÆsøTS‘•A(F<ö0Î=}è襕!ÁpþŸ(ÍWx3I)–Rqµ±ÅMrT…W”G¸÷ f§+Ã=qFÁ±JX¢!yÚˆç5m†Tç8öªÞOú[2Ë·‘­Zn‡œ{ÐÆÊÖJ¡c9ùÎK¨ÍYÛÅCj¸CûÍÙ$ò©öŒäCÜL?INÚ}©1éšB*¸_´Œ ¸r;ÕŽ¼f¢ræ@"‘A 3S‘îG½7°Ê”Ä‘ç×rã¼ñAwHà¾99«Æc¤ÉÏ=-²„X1ÜqÅ1Œ{˜å-KG Á©¡]±¨ÜXSJÂ#€áHÏáŒ1Jâ×4ÿúÔ¸ô擵!-¶ÙŒ­#7¢à ’UK01ëŠpa»óC’°@8êy d…6› 1Àê;T©€2G½0 ±PÊÎGP0(·'ËÚò#2ðvž•MŒ[¹x“aÁÆiñ©Nw qÖ ¸rÄGB܃“Ò¬DD€€ )tAù ç­ÆzþT™ç¯´„T·®U”àŒmoçSÌ› e2ÈûÉÔTJeŽvyeŒEÑF0sõÍK(f‰‚I¡¦ÆÈWìiš9èH©âÈ…mÜuëš#•lV$I@ûª8f¼Èº!vçúÔŒ%ó—h]£©ïMÌ¢ì³*q÷±Îi+ãËl±“Ú›nŒ©“ u=8?Öœàa¸r9¨àW ÊËòŒ`“ÖóŸj?^=N=©¿‰üi¯t ^DQœ|Õ ¸„³¨‘7'QQݵq·ô˜Íç½/j(~t›i}ˆ?Z(˜Ï×ÖƒôýisíIózq@ÄÏ ýhëÍ8}y¤çÖŒz:1Çz1ÿë4cüæ‚:Œ~T`cÊŒöÅþé>ôcð õèhœ`ñÜÐ0ü?JOþµüñ@ƒ‘ÔRdúÒãœÑŽyþT~TgÐgëA¿4c޼PŸ^>œÑszã½þº\j1íIŽzÐ0ž1@àq@È£žü}(gè~”¹„QøÑøþt 2{ JZ ÇA@u cµ:ƒF;ÑœÑþzP0ÇsGáŠJ_ÄÐwéøÒÑøÑƒë@=¨úâŠOÃ4´œÒóô£Ö€¥(£š1Çz擎ô¸ã®;P18ê( “ÚHϘÇj1G~?_ç@ƒÙ£·OÊ–Žhu¤éô¥úÒtç4™8ÿ _çFsœuúÒóë@ ŠNsÀ§Qƒ@†àöÀ¥Ç¯4¼ÿ“I¯ç@ÀíI€;Œ}){Ñ‘ž†€ QGó¥íÒ€ qØÒbpisþE wýhÀô¿LÒ~´`uÛKüé:öýiyïüè>oj;óùfƒÓ¡4Põ ŒûcÐÑŠ1š`…-ŠNsÒ>Ÿ&ÚvÎ)1Ï@ãG#Ú‚OJN¼f˜O¶=èÆ{QŒvÍ/=ºPcŒ`P1Ž”¸÷Å8ö¤ü?#AZ=‡ LüTm\ç¿ç¥@hcØQG4 ç© Š8ì(À=M/ô™>”sJF}è{~ 8Å' ¥$ÿw?Ð!)yô£äQÏ¥!÷¥ØRóéG= ö£ÔcŽ´ƒë@ W4cÔþTcÞ–€è?:?Z^h怌‚9þT§ò¤úšL㆗>‹Í#§4f€­wÅŠ1ì`ÑžÜþghæŒLŽ£š_óÒ€hü(ü 9ë@ úRóßt9ýhÀëŠûÑGQÈ£'°â Gj_óÖ¦s@ øP=éy¤É ã¾(£ô£žÔ`zRÙíøÑÔâ—¥%Ž:æ—ƒÿê ÿ€Ðz\{Qï@µ&=©{w£4mÏQFÚO§O­œðhOãŠB (éF(9ÿõQÈïj\ý¤Ç¾hïÈ£z`P××ó¤#ÞÏ­> ý&G|QŒò0h÷äP~´ ?G½ãŒÑÏáH õæŒãÒ“<÷ühÁ>”Óþ½¾‚ŠOùlßAE/ÌzŽ)sžüé¹÷¥ÿ=(F(£'¾á@'=)€¸ëÅ&qÓšLdõOøPdVlmlïMòä Ôœõ犓x—ð‸Ô]£Œ£ïbÔ¼ãµÜj+mˆÏµ&$p~\Ôƒ§J2sÀ ãJãváߎsÅIŸcùRñÜþt x+·õ¥‰J.®zš—¼þ4ŸZâààsUÂÜù`œõ«<õÈúÒój ‘G¸’Π1÷©AÏ}):ðE/^Æš@ïÍ/Í'=ù fg| —ž´¨“¥Ê·©569Ï¿¯Ö‹…Èd+þê5ÁzsLDb®ï ¬„`n'ñ«;€‘øÑ‘žGå@\†ÜH#Ã" O7CïGo”~tdtÁ ½TÔrS*ˆÌF§àzQé@Š¢KÃ&(Ãg¦îÕ,[ܳHŠ§Ú¥ÿ8£ŠwÈäR¨Í)úñšª áFÃ{'?ίqÿ꣯\~t&+º³€b Àt?ýjœ”qÏÖ—¼Òð{Rl.&H?v«Ï%È*!'’ǵZÁó4œÐT3†$£Ÿ”îæ¤‰¥$ùª¼zTÝ>´qNáq¬ªØ,ªHö¨žYƒá#cžqSæŽOZ@D¡¤A梖ëQn|É@O•GËØµø^}(¸ÔȲFæ?18¥0bÖì 6:ƒøÕ¬Òþî)ǘe$'n ÷«—xÁ~ØT”cž”\.'#ÿ×G$uü©qëI€JB#1(fp™o\ÓÒïÿVÛG_SS“õ£¯jwÊñÀ©ˆ€IäŒR)1Hñ¤@.20Z±Ÿz\wñ¢ár›f@‹*3ÙùjÖР0=©ø?Ýýi9ô¡°lB{šO§ZwN¼ ùíHE)”[J&Dvfl^”ópÆFŒA&1É#гÀõ¥,;ÄšwÈ!@#Sf„ÔN±ZÎ-X´‡–AÅ[íÇOjè2}©\.TˆG,ï&Ò7R¸íVúúÒóëG_SM°`ÖŒçœñô£æ¸ô8¤"¼Ñ+bR +ØwªÅ–õÔ呹¸éëWñëúÒüÝ7qíNãLnÏ—nx銨ª–“PÙ“¸wùýi1íŠW •íâUy4‡sgrÒqn“ ÜÄ;¸©È¤ÚM;…Ê&æ;˜c(Yöðyr(„1,J\íî{Òùj1„^9t§ãÚ‹ƒb{cõ£ØÒííŒQƒø}i¯sr¦dÎÛ$oós…'×éV±éÞ›å¯P1ÓŽ”î;•íö´òw%[GéD*¶ò̌ێy*Ï¿éFA#'µ ”Þ$™ÌÂGp@– ‹nÛ …ä‘Þ§ «Àí@\p1LQp¹^Õãh¾ILžäU‚N:qB¢ Âªì(ä¤ÁKò2ÈÌáAÎ¥'ÛaÛ»'o®ÓVÚà{PUHàqì)Ýu½¸-bU`OW¤…ÄåI)w<äÿ…ZÆ:¥0ÆŒÙÚ¤ã¸æ‹…ÊòÎ’ (S»zU”]ª£p8…4C ìPG|SÂúcò¢à/çô¤Éî*vaúÑHCwÄ~4p}ip=ãKø fÓœ†8=‰§íøÑÇ÷N}…Ç­.NqƒZpÇ¥07Ôz2}EIøRgi'ßñ¥#ö£ð£üóGã@Ä'Ò”g¿4gÜRs@…ãÒ“‚xÍv9¥çüš&HúRŠ:u„ïõ B䦌öæ“p1@ Ç­&hú^¥ N:qôÍü(ç¿J\zQù擃éŠ^ ±ÍZ)9´¿Î†(ú:1þMN}?Z>¦ŒŒô?p(guÿ _ÆŠLê(üþ”}•-'jÏ~ihçüŠ@GNsî(£ô¿…&¥.íGJ=裧­'ãøR­õèǽ;ñ@ õj^´uô£Ÿj@é~¦LšLcÿ×KE`QŒt£œÐRàâŒ}(ÇÔÐ}3ô¥ ç½ÐúQõÍ÷?•&ßLŠ\}:N‰¥ëÛ€8Æ3F=(úsI“ØóéLŒúþcÜþŽÜÒæ€Ðþ4b—ŸQHséH㸥 ^} 6zœ}(2/áøÒn÷"—'µ1Ó4‡4¼š1ï@Äç4})hü(æŽ3Óš9ö£½'åG¿­-›¡¤À9?‰£½;>üPc¿#ùQƒEÇÆŒRþ4™÷ ¯bhöÀ—“ÚŠnûAKéGùÍ}è=¨Çÿ«4¸cÞ×4˜'Žiyõ£Ö€ 9£Ž‡š:Ô 0GÒŒ}qH>¿…/âhp{Pi Ç$~T 0¸÷Åg©&€ žI¤û«ò §c>Ô˜ÿA9P>œÒð}¾”¿ù4Ñ‘üGéš_lþ4´`{f€oÔý(úÒãÜQ××ò Ò—Ž)À£=¨úÿ:?!F{d}(9þª=ñFìu£?ZNÞ´î Ro—ëúЊ=©>¿ÊŒú@Åü¨Ç9£Ÿ•&>‚ƒ¥ BŒ³cúÐ0ãÖŒc¥.x£·Æ ÑÏ~þÔƒž£Ú“ïùи¤Èô Ž8ïŠ3éÅÎ {Qòž&€ Ð2x¥ÏÖ“ñ õúÑÏÖÃñ£êhärh£J0=h~&ŒQÎhϽáFiqߥ ŒúQJ??õ£>Æ—éIŠéÍÞŠ2h´œú­yïKÍ%æ—#ÔRg:P“éKšLý(çÞ€úQž3Èþ´t¼ÑúQèi’·– ¾Ðzf€ÒŽj°’ébLÂ¥ÏP¥YϨ¢ÀƒŒñÖ–Œþ4€;v¤ÀÿõÒñš)€tî(Z2¯åI}hÀþº>”n÷¥ü¨Ï8Í?ZN¨Éöü©´œösþEf˜'ÿ­@QÓ £ð š\ÜRgØ Lö#4¤ŸoÆÈì((8ô ¥&Xû­/oJ1ÜPÛÖŒv¤#'½/×bŒqÛó¤ä&”öÉúP ç×õ£&Ž?ýT¿…'?þ±KõÆ)?*3ùÐ1x(ÏœÒÐÏ­'â>”¼ôÉ£ùP=(Ïÿ¯´ŸçfŒûñG?þª(g<ÐPŠ>‚J1ïKoΓ¯ÿ®ŒŸoÊ€·½'^œÒóëš}è0}M{ÑÉ=(ǽJ\©¤ÏÖ“ _Ê—ëIÈ=)}ñŠ>¹¤Èõ½{æóÅ'Nôg½( ­žù£Ö—?JO  ‘ÔÒf—œv£èå@ Ï®)p}hÏàh ?õÍ-ú1êi?àTc(ǧò 'ÖŽ½hæŽ=(ÇÖŒ}i{QÛ§âh2\Qü©Î)­ñA NµÀhê8'QÏ©£“ÏJ8Ç´¼Ò`{~ QKϽ'#­/ÐäÒ~4´™ ¤÷ÍúèäóÅ'9äœÑƒK“éH èx ñÏÖ—õ¤îNÑõ£ø “Û¼úÒ`úä{Š\ãÒ‡·4tvô£ß€4¹¦ &áéKõ ˜™ŽqÀ¢ƒþ½þ‚Š@?ŠL9$ hÁãŸÄS½¿¥z)Nìpø£§ÿª“ ç´¹õ&Š2¾¿&Aär)ˆwùâ“<ÑŸaÅ-'n¹úñG^Ô£è)(¸9éIüè?^hi3è8£ŒõæŒús@À7ùnÏB÷£ôúQÀàœš@ÃךRðüQœöZ( ŒQÎŒØ~TŸA@Ú—có£=hÇcÒŒõÏ4Æ:Qœð >ù¥ïIÚŽ=hG×4ƒÓ>Ôgž9¥æ€3ÔRp8À¼êhàô ç´ üM/ê(úŒÐíIì4¼úèàôÚ~”d¿Î“ò4 {~”zô ÁÏ~4¸üý©O—µSøQÅ}híÐ~&ÆŽÝ?Z1é@=Í÷£Žæ—¯jCŽœ~t{QŠ8Ï_†(ã=¨ü)*'aÚcFqKÆh>˜¥úÒtì(ëŽhhüi8>Ÿú9ÇÞÇÒ“ç?8gÒ“žã¿OΓӑG^´ŸCÅ;ñ4=i¹?¦(è2>Ô¿­ˆ¤ðãñ¥ïÐP~"Œzæ”:`}(>Çš=y£¿õ A#Ö€~8¥'Ž”g=¹ô ÁÏ-Å)àsŠ1ïÍÐsF}‰ü(Ǿ? 2sŒP{sùSŽ}¿:8¤àvæ€êi3Ï$þTg4qÿÖŃҦhü(Î;àPŒýisÓ'4Ÿ)ç‚Eÿw~´œwÑG4vë@ äphíIÓ®M.} ¨Í£ð ëÒŒvçð¥£= Èã:ŸÖ—ò£ò(籤ÎzgùQÝH£³~qŽ‚—ŒphÎÿZ“¯§×4¹£”fŽù çûß….1×¥ÏQŠN(Ç¡Z9õÿëQÅú8=iyõÅ'ùéKš?3íF@î(ã=h~4`ŽäÑúÑùP Æx4Ÿ\ ^;b‚¦qí@Ã Ž¹¤ç “Kň AÖŽ}¨Î:Ⓝ@ G·ëF>´`Ô~‡áIž?úÔ¸ÀíFO¶}(šOn)hàwÀ aõæŠAèN}ÍǽêM©¹^ýisï@ šLŸN=sFGBE&GAü¨O^ô`zÆ“Ÿj1Ž„cÞ€ê p)2sÎ)hdQŸcGä(ü*/ÐÑùÒ}Mˆ aøŠ8ü(ëÞ®( ¶~”zÑ׌óí@ÊCþñr;ÒýphgÞ¢•È fç/OJ¯;(‘Alpzö¡ ~èVUô"‰™·³8‚)²‡ÌN'Ø£¯šUÂDòy¬ÙHéOÌd°³4j\Øç$Šà$a†yç¥6ݳrŲ?ŽÔÇæJRBÙnAÁ¢ÀHgu™>^sŽqNŽvwa³ :ÖŸŸ­C+€ëºM½8Ç€{϶EŒ!äšsÈUAžyéPÜH2L¨ä dýiÐ,Š¿½püv§ÐC£›Ìcû¶^q–)Î:Õ;²¾d ¾ìòjúÙ™Õ@xÐÖ€F×%)8§5ÁR?w’Fp4@'·@Ç(¤~4€d3ùˬ£¼)ÎÛŸk6ÐN©¨Ö7³yŸ!þµ1#Ûñ0+›ŸÝ‡ØÀØæ¬qÀüê Èã.žØ©—΀ûÔj_1ãØÀ¯¯z’C„lp@àÓ!a‚p =q@ û^0 7NŸ¾t`”+ÇçOÀì@‹½Þ` ·}éè²N±:.Ö%Ž>^qõ©7 ‚Rû”.ÏÇ­KÛŽ? @6IÄ}Fiû†:ÔR—êö“ïR‚p2A4ß7,ïÛ8\ü¬@F)¬ÿ9 ÀÓ‘>R“îs@·JòlUlc;±Á©I4ÑÚ—v(I#Ò““ÛŠ9£ó éGähúñïG¹ 4p}~”ÂŒúÐÑž{æ“ ô&Þ¹ü¨9îx¤Î{Ð1@>ÿ•ÈïKÇ®~”`çúP!0(Ú;ç4¿•(Q‘E}?•£¨£¥ž¼Ð{QÈêhü(ýhüp}¨9¥ú AÓŸÖ>´sÚÊÆ€ wÎMõ&Ž=hÈõ?•/לu£ð£š:þ¸¥üh£ñ ~ttõúRcÐþ”gOáŠ8/Ö“4èZ_aIœQøþTsë@äæ— éŠJ1@ב@ãלúcÞ—=²(A¡ÏÒŒÑøgñ¤ç¾-Ñü©Í.N9gœqHàixï@ ŸqKšBFqŠ\cµ'nhàŒŒÑÅÏ9 ¯cKüé(Ï×é@ øâ“ëš2úÆÆ€óÍ'Nôd~4‡;NФöÉâ•Km°|t¤Î?ýT¼c9 óÍ-!œ}(ïPÑIŸ­&ÿ®€Þ“v:Òu¥ãë@>ƒ4óÍ!€RmØúâ€z­.­'4¹ìh¥¦’:þ”dõ Áö>ôgüš):LÑŸLÐ~´tî?*>”QÇZ8í@Ú2h ÐGý{ý}¡¹þE ÛŠ:ôÿ 1î~™ Ç¡4`ŠBGphÉ÷üM0—w8éMïÔÒçš@;<õ¨Æ:c4›½ &yëùbÇãE7èM#ÜP1ô„·lcMëÔ {ÐsëùRyïF¤öÏcý®)ˆ\ž´œžß•.f8£$uaa@ÄϧZ\œtÇÒ“9¸9 A–ïŠ>Ÿ­/AHGz_Ë?J?('µühïÇëGâ)3ÈÍ/ÔÐóš;u£ŸJ1ÎsЉ£Ÿ_Ê“æìqïF@èrh£$zQÓ½'â:9äüèÀŸ\ÒÓsÇøÑ»Ž´¼QøRg#ƒFO¯ëŠ_N¢ÄÒnìš3ês@ Å{RR‚ üóE÷£9ï@8¤ÏÖ—?J1ŠLûRóž´~4`ö 9íÈ£Ÿ@)¸\÷ü)vç¨yÏZLsÉ¥éÇó4( c§4g=ÿJOóÖ€ÑϵçÛëGÐǵ #Óò¥àw£Œ÷ À=hÀïÎ’€3ÐQÓ°üèè2H£¯qøPŒ{Ñé@ëÁ£õü(ãéE.=¨ü(Íÿwõ£ƒÜSÖ‰Š?*3ןҌƒÅ~”RäÔ™”mî@ü¨£?çûÆ€Z?)8íJ(2}8£òü©séE¨Í&=€¹÷¤çÞ€ŽÔ~”™'µúŒ}(p='”dwj\ŽÜý(°£¢ð} Z0a@9 gÓ4¹¤ÇnÔ`þn>™£'¸…'>Ÿ­™úÐóGãIÏù4¹üè÷Å/4Üê)r\PœšçF~¦–€œv¤ëØRñèhí@8¤Àp)qíùОü :ÒQ’>”¿—çGãIŒv Pr;þt¿üÑ‘ë@ ×¾i;ô£å>ôŸüèFÔd 03ÐP0v?.@ëÖ`Rþ2(ÏNhâŠ'z9Å.sE ô£èiqéIùP çò}¨àu#ñ4}3F=E—ŸjLqþEG~OÖ€ð¤ã¹£ðÅzâ€8þ”bL\æGҌԧ4œP0ü(¥ýi842M&E/·ó¤"€ž”qéÍÏSKí@ŠCÁéG>Ø AžÙ£¯aF[²Òþ lÑ’;R{ÿJ21@ Oµ?‡°¤à}hÈ#Ö“ŸlQÁôæn”8ìEW¤&ÅV9$ò*Ç>‚«NA•#*ß0<ƒMn4OÉ8?…6N#8§BzÓ•FÑì)$FÙ]ÜtïHÂr€jd·É•8ÎG"Ÿ F#*1ÐŒTp¾\¨_›\Sc>Æ¢—ïSpÈæ¦¨&î¡àƒœÒBCn¹cW`3S¯Ý8è* ÕyÜåAàµ:œ¨##"Ÿ@+Ý3«ÂQüÜîV ¸8 õªµÑA,!×vXޏ«$€¹=µ¡eÖGQªŽ˜ïKçJ< N >)–RøþƒRûñŠ@EŽà‰† æ¥üª´h«vò9#qÅYÎz`ýh`È.9 •×¼ç52ñúzT>[.É”ÕsüÅL˜ ÎsÖŽ€$¤¬LBäÀ¨<æH•„$dŒ÷þU4Ì« l.95¹R„£—síMl}¥Øœ@؃žôØœÉ0sBË’H9ÍZÈô¨Ä§Îòöݨ¸Ä”âD; {ƒÒ¥>¢¢‘?xW ïOg„ž€f†È«¼1\œb¤¨$ ®Òo êûr9欈¢ÀÈ Q?–$õ§çV¯Jƒxa¤žOÁô }1š_­õÅ.)™€yâ–ÀSÆ{QøÑÅŽi˜=±š9îJQר£Àn8÷¥þµÿÎŽ{Š9'§Ò—˜¹÷¤âŒŠ_­¢Š9¤÷4£ëšN?(ê8ÇçGãúÑž(Ç4}¤Ï§?/Qí@qKÛ'™ö£J8ìE.~”ÜÒóÅuÇ4sëG=hÐ ü¨ÉÏQŠÑÔQ‘Ó4´~"“ƒÒ—§nh9öÅ/oj9¤í@^Ä~4}¥ÇÒŽ}ZLSFE-'|ð(xì1IϨ£Œõæ–€®9úÒÒ~sŸþ½稣>ÿ˜£œuÍþðÅ&G9 ÒäQ‘ô Ð¸zŠ3ïúQÇ^(úhë×ùQôÍ)úÒâ äQŠL{š9ö ãÒqÁ¥¼ú¨?¹æŒŽ´g#Ž”`RâŽ=GáIÇ|Pœ†Ž4£8 }hŸ…è3G$÷üé{Ð!¹·åJ=hü¨ 9î 9ê(íɤ;»b€Ú“w¦(üEþ¡@Ï­zÑøÑÏ@JNýÿZ9õ£œzÐÒŠ\þœvÅ÷}(÷àÑùP0ÏLõ£žý(ú(ëØqG=…&=È¥é@Ëvú (ÿ—†ÿtQH}@üi@ÏaŠ:öüŇœ}q@p: 3Û£'¥ø^h{tÍ'áFßoÖ—ŒS?_j^Ý);qGÐP Ç¡ÅfŒŸÎŒóÍ!‰òç¨Ï½.}èÈ<`QߦhgüâŽG~=(£‘éŠ`§‡ëHç#ŽhÉ#†#õ ´¸÷ÍœÒg4¼úRsž£ó¥ü(÷Î(ÁôÅ éJsÛ¹ÏP(:(æŒöÏåGJ™ö£'=áFhç½=phÜ© ûŠ> }  Û›…ã‘F=³@ƒv{çéF~´`¥€j9Í-~4sëŸÊŽÜÒg¨ÏÒ€Bh=:f“8ì)G<í'Ô¹üi9?Â?Kj;PôÇLÒnÀ"€ó¥À=©§ÿ‡z\{þ´`ø£“ÞŒš;ô4½:š Î)9=©3Ï<}hÙ_Z¥&{bŒžØ #Þ“#ûߥp–hÉíJ2{Òr?¥-‰ óÁ¥™íŠ:bŒ{QúÑÈ´‡Ð±¥çÞŒ’x÷¤çø¹÷Í/#¿áG~i9õÍ} .1Ó§×`÷?JNÿ{õ£†Ž¸ãó£œö¥Àö âŒg‘úÑÓ¡éF?å@ÞsüèÁÇZ8©Iè1Š\Òdž‚ŒAŠ\QÏcŸcI–ï‚~´nö ÎN)1Š\ñÎ(ü(gëF=I4cÔdQÛ¥ôc=zÒÒgÜ~tdúÑõëFGb)sž†€#ÜÑKþzÒî@Àê /Lãõ¤{~4`¼Ðâ8˜÷üÇúÐàúÐp=!Áïøf€@ãùÐ1zgó£ŸQ@=¨Æ{Ð À©¥íÖ“¯z0h0£¾){qAãœþ”›ë@ øR;\‚;þ™â€æì3IÎ:ô£¯RisõüMÓ©£ŸJ1èhÁ=¿Lgœ~´J?J:ŠèǾ)qì(ý(”t¥éÖÄ~t OÄŠ½ê(Ï?w§z>‚£‘Yñ°…8=FqRc¾?J9ï@2ÉÉ”Œ ^O­.ÚŽ5*¸,M6D.@ß"¥çýšÇ¥UŠÞXí¼¿8ÚÞƒµN¡Ë8"ž=ŽhÅ ‘H’3«,¸\`‚*QÇZ>ƒ4tô ä±·óÇJxÈP Î;Ò“EBÉ1o’]£9 (9m[ÌämëStèM'w в±ÉRM+ï*|¼nÇJ\×4¼qž WÙ8ÆæVãÒžC–Cœ×ê^ùäRðxõ¢áq„#¯­@‹:¼€l ühýJK`É€:6zÐ .ö¨%9Í>Þ9fe±ÝêqŸ\PíNár9¢c®TäsMýñdWgñæ§#ŠL{ÒVTÄh§ÃRŒàdsÞøñAúš‰V_0—Û´—žõ0üi9ÏoÆ—üñ@SKIúQƒë@éõ¹ÿ8¤úÐö Í'¡"ŒŽôP3ëG?…­bŒQE£gò£ Ð(üx£¯z0=híÇOjLKÆ}è úPxëF}húP^hÇ?:3ÇJ0:ãš=Í nhÆ{ÐŽ=}…èhéÞ€ ÿõP š^½©3@ç4;Ñô£?äÒÐcéGà>”¿…Ôœþ´=é (Èõ¤ü(>˜ ÍR}(ç=?\ûP>”œÑŒõë@ ÐuRQ“éúÐýM?ýTÓŸAøR‚}(ç½/Ó•&~”sè(r}(Àô¤ç²Òc ;éIïÅ>Äýiyö bqþM¥ç¸¼Ð! ¾´¸£ñúÐ1{óïKIÎ: _å@ƒó¤ëÞ—éúQÍÓš?EãÞ î(äõÔ žØö¥Á ã¹£üõ£z~tsé@ ǽïG׃@üèÔ´}E祽³G¶Z3î)2;~”Qõ ô¤ü3G¦(i9¢ŒúPÀëF:w4¼ …œvŒ¼PówâŽÜu£ðdúPÏÒŽ=sGÖŠ„ÿ®cì(¥oõÍž¸R?¦ŽJÈ£¿€ƒÎM½?1Îp3õ äsŠ^ßãF8¤Éô£œö"€ñüèÏÒ“ƒÁŽhÉÇ_—ŽÜR}Ez~T¸ïG†)NpMúš\ñÔQÆr:ÑQš9ö ÈÎ2sG4rzþ´r(?p£¯aKƒþy ¶;s@=E=€¤ÈÏ<_ ãÞ€“Ô 3ÛõëAëü©ph>´cñ£ŸLþ4~ f—ŸÊ“¯cøš0­³Ü}1KÖ›Ž;þ¾™Í/Nœ~œžø£sÚ€ ‘ïJ3Óôœ÷Å-)úãñ¤çèÛó£ò 8“Ÿz2>´g@ÖŽ PŸ^(9ìhϨ£8ñøÐG4g4sé@ œt¥Î{ÎŽ}©¡ë@ žÙÇáG$|Ä\ö­㥜ÿõ¨ùŒw üy¤Ž¢ŒŸîÑÆyS@yÆ:=ø4…€ìqAÇ 4¹£ž´œã’? >o€:v¤ÏûT}GähãÒ€NN½x£íF3Ò€½…7æ¬ÇëKÆ:šO§çE {~9 }M÷æÄPϵw4˜õÅ;Ð àt£>ôœz~T´~5 ÄæR#gËڥϥSÔ¤’;`P€Û†7P·%k–ÜÀBå@Î@ÎhYœ²«Fr{ŠˆÅtó#$Á#ÙÊã½Å:È­$ª@ôš­¡qœ*–çAH²èj9‹[/xž6Ø“Ë#U¤RgÄ'×¥{Pf¿T“kE.3Û{ÔŸhQœ£ç•Ù_ L Îy§ÕÆd=2i·%„Dª)~Áª"eÊs׿ãùRH jÁ†A¥ãÖ£FÚ¡Höæ–I— D×±)aÉÇ¡԰ʳÆ$SÁ÷ª¤LKlDÆ\þµKŒWYU©¥a“I,q ¹ õ§g# Ô¹0j@ÄŸ•H…Å{Švü œ(÷ªêqpÙ+ÏA»š‘øC€3@n¢ ¸ž3€E;ÎBÛw`ÕpdhÀ¦ÂOÝ=)ÅNàvò½;ÄÈèü#äŽÂŸŸòjŽá’› ê*_Ëñ¤!{w¤ïÔqG½/N€phÉ“Ÿj2qÔÆ€Ÿ\Òþ4™£uÒ¨£9ô¥g¯4Lc§J\}h£œPxç?˜Ížù¤£ê?*\Ž™çÞ—Šn}ÿ Ð8=hÔw¤ÔP~Tu£¿Jÿ^€ ãüô£Á4øQÅ>´d÷þTwëùQ@_þ½J8îZÀÆ?Z?*2(í×g¿Z\fŠnhÈõ9 c¿:?Iôť޿—ŒbϽ&=¨ãßJQŠO€){ÑŸóŠO¯ó üé2}éA÷ úÒãŠ>”˜ o¹¥¤4€óÔвȤÏ=qF=3ùÑŽ88 ñü¨'Üþ zæŒûÐ0Èõ£8ô4~TdÔ8¥ü1I“éÅZ3þMÑŽhä÷ ç˜´hàô9úQÎh£'¿ .(ü)¿ð,Ñõ&€¯4sëIžxÏåJHr(&¿n{ (lyíôRO|QøÿZL`’*w>ô~?•öÁ du9ü)zvü©ˆ?Ÿz^=i9Çõ¥éÔ“qÒ“8ëšQÇ_çKÍ7ƒÿꥣò£#´Ýßò4cŽŸz:?^zP  uíF;ÒãÔÑ‘Ü@ Èœõþ”Òcœä¥&¼u&ŽüþfŒç¡ý(`ZZ?A Btõ£Œõ¥úŠN{ 1ïFsøÒäâŽIí@ òã’hÈ4½ñƒGÖˆaü©zô'éKËÖ“Ÿ_Ê€rûŠ]ÞŸ­/ãŸj03Ò Î{þT¥)Æx8ü(ãñ €:QhÔ˜#¸ ÿú¨G¸4™íƒKÖŒg¿4oÖÃò£§Z8÷ ã¸ýhÎxä~4¿SùÒqôüh}³IÏpGãK€zôgÜÐ¥ÿ9¥ü¨¼“è);d·Jv=¨ÇzN=þ¹¥ç±÷ `÷ÒœcœÐcÜbÎŒqÁÅ=? ¸ühü±GÓŠ^=3@ ÏaF3ê?1ïK@ Çù4qKŸzN¾´uõ£ÿ…êhÏ´cÞÄQƒ_­'Ì= >”t)Óõ¥¤ÐÈ£"ÀÑô"€ 9”¿ç4™ìOã@3ÖŒgš½ôŸ6F8¹é0G#4g=q@ Æ(Å78?áFF{Ðàž8¤sÁéK×ø3GÍè1@üé2ÆÓŠA4£Ÿc@ Ž=)6Š1Žÿü(1èiqÏZ2æƒþq@JPGjL 0;f‚3ߟj_l~4q@ Èõ¥ã­&~´§æè >Ù£ uƒ» #ñ™úÐûõúRgŽ?1Îr*:÷ãÞR9Í>â—ÑhÍ'?Þ9÷¹õ<ûR ö'ñ£8ëÆhIŽ>”œ2>”¸œQÁ •ÿ9¤íš\äý(x£ÐÑŸcFG¡ühÇ= ºRñéŠN½h¥ü8úRqëùRçñ _Ê”cdP1Žhçµ w4ž(\ÑیЂhÅޏ4qŽ:PϵœÐF~ö*NÐHzÑŸZ>_z8í’(zRvÿëÑž8ÉúÒþPsèjµá)oªÇ<«¢€!‰¤Ý‰F;Š—ç57;Õ1ãÖ§ëC¸þº‹“!<`ðAëSnZ€2´Í·vAäBS’1·5¦Z>a1ãŒcùb¬66ÜqPZlh·¡bšÃRÂæ5Ø=ñV:ôV!î£GF.ÀãÖ­ðÀcƒMì„B« ²ÓèsDãåR#ó9è[‘„>Òsži·l€D²å¸ Ras°0}:Ó`ÂóëOSòŒ Ô.§ÏÍÆ‡oZàXÇÿª“ éFz qKô Bgó¥çÒÎŒ@'×5Š¿hBcbGñc"¬c𪓼iu2ÇŒ´ÖãE¬ŽùªÑ¤kw T ‘’ÄžjÎ{Å@›>Ðà:îã# à÷ëëKOçIƒÜÒô=x¤7êóå–Çl‘O‹˜Ôão:Ó' èC1Qê)Ñ`F €8$Sè>„s3yŠ6=EI')Ó5 Ç–]C9Ó$¥Uy;Aô4°± ¯Ü<0OmÔøÿÕŽ­F§ý#‰#î“ý)õ.6–PÈä°#*jq”Ž)“©xJ†ÚOzh*-È2`å¿úôt«´]6"ëÎê™ÇÈNÒ~”ËsˆÀ]{OvžÞô˜ „(RU óÔ÷©A9ÆMGàó»žç5'9èGµ L^~”wéHæihOùÍ'åš8£óõ ­ºRÑÚ€aKÛ …PE'~søPûJ?ÏZBGcƒô¥ü(8îF)sþsKÏ¥&}¨ÈÿõP9Ç&–“Žù éG>€Ñj:v }(æŒÿœQ;£"óÖ˜ÿ…&}x4dž1øš^{ÐvÉ sÿÖ¥Îi¿¨¥Îhxõü(íIÛšLóÔ~ìÒf“8)>´ L/¥/Ö“‚0(ãëô B‘èi0>´¸ö£ô *;þ£’8ÅFsê Ð _Æ€úQ@ƒ?äŠ9£§j9 `½/4™ü)G#Ö€hãÖŠ(ühü©2z\ÿœP ¢ƒÓž)n¿…ŸjJ1éK@>´sžô§ãFqêE 7­­cÆp(sHM-ƒ>”sëøRþ‚xõ bdw~4u£óüèàöüèi8éKò)8éÒ€{bŒŒú:uæ€h?Lg·>ôqÐ @…LQÏ¥-WtSpKg;Gz)Ì?~ßAExÁ¤zóH4¿B 9=£Ô¡?Z0{ñLBíî.=i¸÷4‡§ÊNqߥ;ýj1Ž•[¤¶€zÐ|÷†ü’/j,;{{ÑìE@C0c +Žÿ•N0;PŽ~íÐb‚Ê0Ö¢æódWQ³?)ö  °O`hÇ rpA5žo˜ Ÿ—ýh@MœvÅ!#¸ÍG™´ïÚ[5'N   1ÔG#¦?*NýE.= tŠ9ô¤éþs@…äŽF(Æ{Ôù òϨ˜MÒ²a#+žNþ•;żsGN™51dàžõRO·,ÌT©NÀqÜQ`±9˜9ëÅTY.òAˆŒƒ»‚}:RÇ5Ã*‰TžªJÓå vã¹æŽýé@8¥ü ©¹$Ð3Ø~tqœqô¥ö buê(÷ûTMAÉÁª%¸¼*ÄÛr§îîì.Î?Z\{~UV9® ÉY" ÐAÏz°Ìu=)5`AüjÚ®•€6¤®yaÏóu1È€†þ3šv Èö£µ5•Æ{Ó¿*@&íš\dJB;ÑÏ÷hqê)}ê9YÄyUÕV¸ºEŒ rÇ¿Ì)¥qؼGzLçÖ¨›ÙÔöW$ub d‘ˆt*1‘š,&À£ñÇáKP\LaŒ2©bX @N:u¤äžÔ‹ÐsJqž”9íŠ^OóÅöýhqíF(ϯZ­$ò¥ÀUMÑy4®4‹<úP:ôª_É5¸‘`ûHe šž)¦{‡W‹l`§<ý(i ±b‚ÀhÈò´1XËéHCñÔsøŠ^©ʃÈÏçKþzГG'¥œŸjB=Tкv£ÔƒéC£8 À téŠÍVV„HÑ8Êœ‚;ÔÒj †uòd&!ž_¥7‡f\Å…G¾| &Ò›†v·QRÒ1Çz9¨Ä ÊcÁ•-&O~FŽ3Æ)h˜ô£éGÐqGN¦€þx£>§?AG=±ô£žÿ¡ É4~B—ð£ŸZNÿJ=hÀ=qŸz6úPúÒ+ÁàŽ´î}hÇ9ï@þ˜Å{QK“éIùf€ž ÊÞô ŸjZ2qÅúQíŠ8Î?JNsZZ(Èï€h9éÇÖ—J)9>ß… -%-& c𣞄PG¨£'Ö€ {~T€Üþ4¾æqŠ3ï‘ô£ðóŠ1@ Œû~óAÇBÜÑ’8þ”¹ô™=?AKZB=²=(ÀÏSGCëJ?È£è ÁõgŽŸ;yëHIõRO>”êühÁü(Ç¥cÿ:\ú~”˜$ôýhíÔÂéHriy=1õ`úóí@ ´õÜÔdÿ¥G^”»Oc@ ÏzQœdãðྼÒíöÐ1žæ— æŸH8ô ñÜóô¥ñî}hüh?B=é>” OÇô£9ô?…(ïÍ%zÒœúQÖ€ž„ÒŽ¥ÁÅ&>”}Z“Œä)p}Eë@Ö‚Twö¤À⌯p(À#‚ix“Š2¾¼ÐçŽ ‡Öœ»Š8õ8wàþ}4zwéUîÈ1®eÙ–À'?•XÎ;Ô7¬ªªø 0#Ô"ôlŸ_Zv Wó‰à `g­HŒYrF=‰¢ÁaeÜc`+cƒM…HŒ`Oµ, 4.C.9_Zmº"Ä6 @F@£ íúÒž9âb(Ç R(÷“»zGðŒT¾ùÇÒ Ç’r¨éNY~`„ œò:S°ìJŸµD“»å'§¥J2;¢`–“Þ<äð(&?ɦÇP‚A9;F2i3Œ‹>¤ž¢¥F. ‘´žÄÐiŸ7Q¢²‡ ãrÕžqÇæ C*40.Ëó`ŸÖ‡° #=ÍCr²2 Cüc?J°O®j ÀÂaIÃu…¸"^j'LÜ+í­;ÌmåB¶Í0âIUÎàG¦†O’xÀ£ž”cÐÐG©§óIŒ8úQߨ£óLwäÔô˜À ß’9üêÇáUänW!Ëc¨éBÜ?ëøT\±ÚUq×#šŸuª¨w’äîÚ„µøÐ}ÏéQ™~”üxÍb9÷íB‘žr)é»býÞ•Äa£ îÇ}½ÿ HÝR06²Àãü¨²©,¬#çø¹Å>LíèáLòüÇæ0öÍ,ê®™bpx BÆHA•×£\ùä”@½ˆÓá*c3`Žõ1­ÎÍÍ»®3ÒŸQ…ÛÊ"ÄhÎO`Gõ¨Õ®6ˆ)?7N8úÓ®“G)r¡Èçž*?'æ*Ó¾e9R§¦¶±<-&â¥v¨éŽõ3ggsíš­¤LѤ®YNöÍYeÊžzw¤ÄÄvßœcž*Lžõ¹XKž šx•yn‚† ~´¿‰¤àtçñ£’y8¤!~§ô Z1G|Púôd÷àRã®(íÖ‰Ÿ¨÷¥ØÑÏ\ÒmÏ4¹nÏ<ŠLàš\dc¥ÿ&Œã©£ÖŒ}(du¤õ8¥ÇáIøš\ŸÂ®E'>´´ž”sëÅRãÞ€Žô}dzÑ‘ë@qÁÍ&zý)xõ¢€<ã´sÐÑù~tŸ‰ü(ç¥'~)s“ŽôR{Š\ÞŒzš:v£&Ž=hŤݞ1ŸÂÏ­'^œþ4dã‘ǵ=æ)ÏZLÐ~t¿Z9õ¤éÚ–€”õ '¸g×ô¥ÿ<Ò~8 >ÔqéFV—§jLö¥ýi9õæ—ó íÒ—4QS@aÊ—ê 'ÐÑ’;ó@ F? CÏ^>”g·4P?0}hÈ=M(¥ïÖŽGa­'~—ø£òüèÿ QŸÂ”Ÿj9÷ DZ4¹Ç­!úš_΀wåGáÅ/ÖŽh&ÿ\ßAEoœs׊@Š“Ÿz6äò1ïKôë@9î(œî?•@#ŸZgš[„`Ç8ùOJ“êsìh¦¨ ç,}¸§ ǰ¦ ?\ÔH[{nEœj›'ЃQDÇ{wç½D ŸJc»*ª ˆ§ð{þUìlñÓë@¤‘röÌ1ÐÍ?í2æ2!`¬pO9>ŽõÿêÛs`cœu&%ëßzNÇ™Anž[n\pÆžH#9&€#·pÛ çº‘SžÁö¨-˜ÿ1?7â§ ã±Ø1F}sF9û¸¤éíFv÷„œÒ;aI Ÿjv{ñQÌ»£a¸©õ‘@ˆÒ4‚6R29nµ3*² x"£ƒ¡ùÃáˆúTÞôØ2G˜‘ ¢ô©ýj¼.­s ’Èô©ñƒC2i<¥ rqÀÎ)ÂVf”LÅX”Å9âf%”à㑱·EI]2N a“þ4‘F=ñK‘Ž¢‘"Rc#îÓ¸= üó@¤W-÷†ó“Ïh:Kp)3´…^ìæ 3è)Ò ÄÒ}ºb’aö˜ˆ³ƒØ‘ü©Ò!h€ ‚:šc q¶XqК‘*À±Ž¾•U/ Ž$2Ιc€zTÆæ oÆÞ9¦Ó¸4Gi·÷€3·ÍÎàZúT0«ÌH!ŽF*jOq0úŽhDZ£r?úÔ„!Ä}) üiݺŠq#@ë !)="2ÇpÆ Î ·÷}*x×b[>õQVü:þ,q“Vуç{⩌lÒˆ"iÎ=:Ó-£DB˸î99áL™åiUa1‘È9'­L’ÆÈ˜‡¶AïK gž}ii‚EfÚ ³Í?ò¤HsŠOÆŒàQžqƒõ f gJÈ,nUL¤‘¹pµ^ïÅQI^ ġ$¨ãü*ÑpŒó“ïP8 pG˜ü`ã·~”ñunT²ÎŒÇZl›Œ€+.2>´’:xæ“i†P˜<äg5—4QŸ6à9ìBsW9¯çQÏ¿Ëáý‰À¡0¹"¶PqŠ]ÞÔÔRp?žØ¤œ­cG=Úsÿëª×͈?×¹3UœÏó¨.ŒÂÜ„c‘Þ” •db}óAÀRNqQ¤èцó#$ppÝêMÁŽ2 õ¡^ØîšR$ýžxü $–÷%÷$ã®FGoJ}»;<›Ð.;Žõcôïf ‚6e›ËiQ›#ÕßLÕeíl|±¿xjÇ40aG9¿•=³F8¤ ãÒŠO›±sÜþT¸¢ÔÑžü 3í@ϯéE'^¿žhzP@?ZAõÏÒ–€ QÓ¨ü¨ÿ¹4sÜÐצGáùQøþT}(3Ç-KGCïGÒ€FLRG#ðÍ.Aã@ùâã¾qK€G§Ò“ î(ŠSÓÿ­IŸÂŒœ÷ühÂõÆ úƒKÍ'$ÿJ2 úQÏLŠL‚qΗðühçð y sÅ:ŒRö bgŽhã§4QÓ¾hpGZ2j? 23@ÄÈÀ£AJ( Bf–ŒzŠ0{(#=i)qïI@4¹>ôR`uÇ?Z8oZ8ÇCGSÓ¥î(>€Ñ’8~T§=©>oQ@èiqëHz (Ú;óõ ã=O¥/=±A b Ÿz\gµ'4=pJO¥{çØRûŒ~4 LzþuRðDŒÈÈXàâ­÷õ¨n2vr g¿_„,ÑP(iO¾qüªÊ€£=iü£={œÓ‹wŸ¥6ÛÈç]ñ09ǵ,Grà©ã‘M]¢`®#'¡'¥~\oVaÁ¤™ôÆi à“Š\c¾)ÿ£o:îŠY0{f§ŠßÊ“z–Æ1ƒƒEºI3Èè0O¯áM¶6ÃqÇ5^êîâÛ#=ZŸ>ôבQ•¾vé‘HEX­<²Jͽ„÷xéV"l ÄT‡9Àõ5  ÃÌ.01N÷Üw¸ÛœMÌW 5a}wéPÏæ›_o<’qÅO¸`gÆ—A9ÈÔ Ëåâ¦Þ¥önùNy¦º¶AÜB£Ymd1>ۖÜŽ9¢(•¦‘ËG× ùÕÌ2}êGÊT†Æxî;–1ì:1G>Ÿ­/"‘Æ8£äRãëI´Ž‹’}é€c#¥A8o—l›yôÍMÄ€ypsІá¶e•Fî¤ãš"l·®j“« I]fU0S«¼úê2¯æ«ò㜨æšÜ [È›÷K’Ç9 в ‚sZ^¾¸úRž¸¥p¹RòbùŠ¡› ëôª¤8¢ûB°ISõ«—HÎñDU[«ž IQüàâ%nŸ05IؤË#éÚ«ÜŒáCí8ÈgŸÿUC:Èqµ€=³InJÜ”g . òÑç=É©»cUàIÓo(Fï— Šmá¼ Ò`îÎÓÞ:34l$eØuÂJY °Qžx4K9\犌Éö•Cã;Oó©Øá -ŒÀUyQ¼Õ ÇÞ'šœ®ä .sïCØ^%vSº\ó•À5*¤¾yvÇ”±Q´ R=ê^ÇãC`ØïΗ>ÔÐ?‘œw‰Š\ã¯éIž8 g¯J…)°Ž‚€zö btïKÎzâ“êqøÐ:PºŽ”™ú{ÒcÔ~4­{Rñš)yõ C}ñŸj_¡8 ÑôqGOaô¤ÁëÅ.=q@ãHOoçFÜúšv8í@ ãŒã4î´ŸOåF3ê(Ï¥/^¸4œö¤Å/˜¤Ç¦1ïKƒÿꣿ#"€½?…ôÍž‚—7“ÔÒþ9£4~4r;þtdúŠ9ì8£¸ ujzÑÔs@$÷…?þªôý(æ€õçéF3ÞŒŸ¥&N:P…ÇÖŽ=i:ÿúéhàñIÓ¦E/ëGµ-!£ç4sœP(Ï…4c”dÿ‘Gj2}E>ÔgëKÏj1Š(=qFO¥/Oþ½ž¢€l~T™ühàŽqùÑìs@}±øQÏ­/AÁ¤ç½8ê 3ùúâíKÛŠ&}¨ã=*3ïKžù @ô£ÿUÐhQõý)?ùÑùf€}OåG¾xô¤úš2z>ŸÎ–›ÀïŠQH‰ýó}¤fb}…¸ž(ÊžôÐ@õ§uê¼P1ÑxúÓ@>ñÝ2)ýhÀ4sëIÔóô4¹ã§æ1Fqü$S™#¹ØØ±c@=?Áž¹ÅG¬,ˆÆ ägµ,–ÐäÈûÜŸ˜Ô•òSa,ÆN)îB¡' 4ÛÔȈÁ j]Ý€5^ß?9ß•ÏÕŒP÷zÑǵǯåF)9ÍS%•aPÌ­‚qÀÍ82°Êó@ÃþµAn†õ‹a#±ÍN@#ÓÞ«ÛŒ«–\cÅ4468‘®%c=}j(ô»x£hж î=*X›‡o0b­uì:wh ¾LPKçÌÏÜÕ¬Õ^ä!òÁ”!ÝŸ­N“ØC²{Òtè:^}?*N=3HBg¶*&·çC¨ ÄqSg¡Æ(àýhºZÇaCc9ëšhÍpC¨ó#¯z–f ˜,=?Ò–GûÆ }j®÷&=ê½ß—å~ð€=sV*æ,#*±õŸÎ¥${|µÁcŽÔíÜãŠh esôâ”ô¡ˆwÇò£è)2G`ûŸÊ€”Œ)'¶ãKÀ  ‰apˆ×;AÏLæœñÅ=ÁÏNœU޾¢ •äyat*÷Š})ݾ£¸–ÑB»¥„“æ MYÀö¡GÚ>‚Œúi0día÷Åq¶¬~U]U¾Ö_øvãïV?J`Â÷°(æƒøR½i?ÂŒŽô¸”Ÿ/NÜÒÍç(rhãÿ×H}ºÑŸJ^x¤ÉxúŠLñÒŒž§§­;9¢š=¸÷¥çé@^â—>ÿ­&O £>Ô¸ÿ9£™íŠ9ôÍ-&OÿZŒã¯åG~´vëúÒóÔÒc€3Iϯ>Ô¹÷æÍ&IíF~¢€È¿2{âqGj\QÛ¥'nM/ã@ øQÏcAöŽzð(ëÞŽƒ­üh ñ£µ=ÍÔ¿ç¥ÜÒQÍ{RcÔ~4½zŸÌRcÐPÑ׵擭/§"“=ºÑÈ£“Ö€éüè'Ö“hÏz_Ã? û Lf—Ô‡×& áKô ~4~4}(éÿפüèç× (ÉœQõÀP ëÔÐ8àRûQϵŸqG>£ð¤ {P!qïE#½ãÐ0æ©4`zþ´gÒ€ wqÜQõ¤àŸZ^ ãûÒ2=@¥÷‾zý ô¿@)0:ÐRãð?J_Æ“?äP2zÒÓHÏ·ãA€äqÎ) õéõ£žÔ`ÿúÅg< 0?»F9ç?\PìOã@¨n•Fy¸öÅVº$ØK³ “ÏÞ”-Á ùã°§ö¤G¡—†ÅAp ÂÆ$lp§½,`ì†ÓŽG¥:åö@ÌoG4Cƒa“žNhè€#¾h=)ߥ!Áw  öûÕò‚ µcŸ_Ò¡µeÙµX¸­OŸR)½Á‰õ¨ 8ƒ9?6qбš©+Ä.ãY$!‰ùT $²zc­W€8™ÃE±@aÞ¬FqU­›çtóË•ÀÆ8 ¥RцEuÏ!…YÉøUk—ºXî!AQ’?:µòþ4tU6½Ác)=?*|ËœŒG±Å ÜnÉÈÎ3O•ÕFðüõ¦— £P[÷8`_Âpº›v Œ}j$,._2ðpÒ0‰£QF÷¥ê:@9<ñM`Ž@§`ž¿©¦± „çOj­kK,“"1ñ¸âŸr›¶|®yíšX,ìf08¢áÝJ…n§Ž*º©0é׊©$aµÉ ¹Îx«`’9?•Twa~±¬çså•¡¡n rá{Rw•'@?.=:})¥{å<°£¤ód­-ãùP. Œ°)æŸv%&5‰Ù!j±Õy#ëO Æ¯Ü{Ô7Ràv*HLý™ÜqJdÁ„ŒÛS©uRqÐtéU Oô™›a\·R¥[P{Н7(!¹ œþ4!‰t˜Õ£wº¯« € øb£œ‚sƒÜqR‚Òè"¬ûVà>×?.QœóVCFAA®Ë8o4lÇLw©Ÿ&6ÚØlpqO =ˆí— ’@þ#š›'=E;çù»Þ¦ÎzzOpa·4 éíG9ô£‚xoÖ€ŒàÑô£Ž„çð£þ˜H4§·œRsêh¿ŸLcéF>´`úOΗ·J=é=¹ÍÄÒŽi0 úRðG€ó͇áIŒzÒû ÆãG|qK‘Hp{þT¹ì)1Øgñ£ðÇéG=ùô œsŠ08ü….3ÔsGåšL\ 1Û9úÒçÔÐ(qJ9éÒŽ”c'<ŸÆ€¾”`QבøP p­/4v µ QÏ­´cÞŠB2y­уõ£G†€ Qj8íúRr(sì~´¹4¹>¿¥ç¥£#§4qŠÒ€žô¼úŠJZAŸQKŠ3G³@ÂŒqÀ¤Î{‘øRó@ ŒtÍúR’EŽ™  íŠAŸaKϵ˜´~?…öçé@€IøRàzQ@Ä w£éùt£Æ¨ Ÿ@?ZLwÇéN¤üh cÒ“€yã=óKÀô'ëH?J£ñ£õ ?_ÂŒÒgž‡ëFÉ ù§>”Qÿ-OÐQ@?Ù?•ƒÒŒ{Òàc¦Gµüèç=:µg¥0x$ô¦+“À(=0sOÀ`A¥/}(}9¨’6W$±95)ÍÏjO›µ2@ÍpqÁªOÚi°ý(Wʹ€O’$Ž´óåÐù (<ŒOãš°îsøRàÿÖ¢áq0{š¨ñß Æ9c''R8üêÙö?éFÑß4\G:ÌT& $w4ø«9c“ך›ÛuÿEÂáÓœQÉ8 Ð2{KùÐ Á&3ëKÀíEC2JßêˆSÜžÔÁ‡WõÎGøÕœâ€)ÜwlTHàS."‘Ôy.ªÀääT߉£ñ¥p¹VHçg`ÃÍ9"v”™eìsÿÖ«v£×šw €^8Î(À÷¤È=éOãøR¼RbŒzcñ¤ú~^t§M¡Dc;‰¦ª]oä¨PxçµZÇpHúRçÛñ4î;•‚\ùdewgןË£4sF~´{~´}I '°Í~”}hü¿:1žôvõcÐq@1F(öÁ£¹ Ž¼ÑøQù 3ŸZ:öÅ÷¤ìN(Í/ôtÿNO|}(ü(r}?CGNâŽ}*L}3G4´~4„dÒÐÓ¿:Cަ€ žÜ~ ¤ó@æŽÝÍ-'~ 8éFyç4sž£Jü~´púâ“§z6ûb¦1G> Rþ4˜Çz9¹Ç­'Zühç~x£¾1@ ŸÎŽ{ŸÒŽé1ôühØÏCGáÅ7OÂ“é“øÐ1ÙÁëŠ3õ£'¡g“ŠâŠ>™4 ý?i{vÇåIù~T} ÿg¹ü©2 SÀîh ß•&1Ò¯dÿ‘@O¨ ŒõæŒÐOµ&ÐÅ/>ÔgÛô£žæ€ ç¡ Ô3 Ý›zü۹⦤tWa@ÈQ´¤ŸòhT¡TJ\P2î1\gý¡ÅDpw–7zv«L¡”†ÔÏ!7ƒ‘ïBn7®$@ ò1×õ«%s¸RùkÏh ÛÆ(l yºª¬‘nR7qÔS‰¹ó˯—³o Oz”YÄ 0$ç©§yKænêq޼S¸î |äöæ›9 r;štp¬(T‚IÉ4Ü(RÝ·U`oJ…" }9õ«n× ÈúÓRgSšBBDX‚NÌ稢MåH]™ìM=cØ09ç½¹Ëu íÁ>¸¦(̬Lj=ûš”ŒS|¼1lœýhØô ç¾(Æ=)yíš@&Ol~T„0@§~tÞIÏoLSæFdÛ#/ÍÖœˆeL±€ÃœqJð‡`IeÇ÷N)R1vä’y$õ }@ûÅÊ‘·xžEXÏ¡Ãóž v¡!ógÉý×Ë’2¯ÍJ#1Ü¡FxïšD‚8Ãæ99§¬j¬NO°ÏJm !¸ŒFïrJ犛—=©=ä̸ô=iøÇj@Accˆ¨îÍ>d.œÇÐñG•ûÿ3žF1ž)eÌ]¥˜ºq@Z{µV {¹Û—ÀþU< €_3òØõ£ìà8lŽ)è7ÎNx¦Ú„W ͳ ’9ÏJœ}ÜÿJd°¤Ûw í9úT˜—Aœ“xÄ lÎâ;ç¥LìÛI1îôÍ$±yÃir9ÀëOö4U]£*VÝÃ9ùº~µ!šBå<“…ÆXž¿…(‡°ç“Ç)R‡†l÷'©§ Â Œ¨£GÏBj_Ãô¦¢\š9¤ çÖŒã­úŠ?—Ö—¿¥&9¥æŒRcñÅ/?O‚ ÷¤úÿ*⌟OÖ—ê?RqÛ?•}hüizô¢€4¿_åE€ ëÓ4séKHzr*:u4­ãŽ(Ü;š_Æ“ÍùâóÒ€ ZN~”§>ÔdŽÔ™8èÖŠ1jZ?C‘ÎhÁÇ-@úþt\Ð^¿J\úуI×½Ïz/>†’=h¢€r:þtgÅKÁèJ1ß›½9¥Ø~Rqø}(ìÒqÿ룯oÆŒŸlP0ïÖŒ{Òž”œRÇ8㟅'>¤~q½š0Hêx¥Á÷£¯ñQøÐ`7ÚîíÚ1ž´QÉ™¹ì( }(Ç ü¨ëÚ—ò›É¥Çž>”„ý)xëÖ€ géQ<›[iSÀÏN*LžüS˜«ÛÁµËÕ„]}ø¥ûH²l œç“S3À£<×\4 ‚e-´¯8Á©1ïIÀè5ÝPÝIÀÍ?tÿ g›}…Æ@É¥GI ÊÅN¥;ƒÛó£éŠF` –Úêi©$rr®{s@ç­&ryëHΊÀɧc˜>¿…( ô£¿ š/4‡å£¨åj)`Àá±Àõ It‹¼.ÖeDZším€Ç÷…:5V]ï ÜÓ'G·À`>^ƒúSЭ ;‡Ö ‘¸—¦r)ÐÌ$ÈÊ–NÐÐaFB¥ÓÔQ¶âدà^Y€À$Ži#Ô!–Q1ÝÆFGz{G‚ Ĥô Æi–ñ:9fT\Œaz*zBÖ~Ÿˆ tàÿ…'QÈüip¹Ç©nê¿=ŠâŽ•îRdÛ8Ío Ë ã!¶õïNûLþñAÇ?0¦G eK2._–§¬ƒ‘Ž1MÙ °N—Z6Žie”B¹nþõ`Oµv…ç*)²±yÖÚb#½» ßÁǘ¤ã×4õ¾¶g æÇ·zx·ˆtGÐTw QU£Ú0Ã'Úž¡g+F5X2‚>â‚*Dö“üæŽ;䟥/4§E}ŒØãw=1M6ûreP ãÄЮi8Çj_®ÚBž¡sFr:wïMùOpip(xÔ;ÂùŠI$ mÃÈ‘¨±R{T)coþH }úSVê4Y1`$S´dóK‹*îFÈéš®,­8ˆ|Üf–ÝLgbF‰Ï ÞBÏê}©’L±‚ýi¬Ó«¶2ÿ­U‘¥xcy-·?u<‘BW‹äñœÂŒg 4~£·zBhúR`âÄÒÐqŽFhgU3`QÛ½Tº&Ib‹Ë®ì—NÔÒ¸ÑdÍ Þ¤’7r)LÑo ¼nn€UCc˜_æ]¤dóI$I #ǘå¹É´gc¹pOsNÁb|¯cG·zŠÊá˜3dçªlûRhqéÅ ñ×ÚŒf€ŒtÅôTSdÄBýâ8  ¸£¨¨•Bï  c5?^ÔX§QIÖ¢/"Îwm`c×5.á@÷äzQùcÞ¢¹2$ÃŒûš~çòò1œw wì(R9.‘¿tSp^yÍ)7{™€@20íNÁbÝ{TùÊXJÀòqHÒÈ.6•ÂcƒÚ‹‰óÎ6æ”}) ÿ]2Rà˜©Ï¥ &ǯJO¡20·ß>´ô'h'Ÿz,;ôü)—µ!ob=ÍAKÏœTœž”X ó·µ`*³É(·N>´«$Ç Td¯Zv :œãKüª¡–ì»*ÅQ˜œU¡¼õïJÖÚŽ½¸¥àzÑzךN9Ç8÷£p=¨Ü½sùÔFYFÊü™Àã“@ý@£?çQ.æ%VKw ÄÇTÍ#JRH°\óNÌ,OÓŽiE2FeL€ úâ InCI¾,Œü Ô¬ª:rx÷ª±Ív\î¶P›¸;¹ÇÒ¥·wx÷:m$ôìe 4 “šB¾Âª=Üé 7ÙØ0Æ\óRCtÒÊÈcd+Ž¢˜XŸŸÂŽ}ª9$(U-“Î*»_0ÉkwP?0ïE‚ÅÌ· ÍûsUüöÜ„ÆB¶3Ç­X#‚H¤4dç€*ç2JSËuã95?= ëƒíFO¥@ól‘Æÿ7p*a‚3Š:óKøT3ÌaˆËdóŠX¥ó; àô4X,IÏÒŽsŒ ´gš‰f&wŒ¯ 2h^öô¥ÁïΓè( BÒ~Qœtçé@ ‘éÏ¥ZC@>”¼cŸÊ“'Óõ¥ç½'àhqëGÒcý‘š3ØŠ2sÇëK’JáIÇQ@ É<GùⓌr(úPñë@Í7Ø þ4sŽ8ÒtçŠLžâ—Z2=(ü)2>”c‰ zqF'\qùÑ“ÿꠤϸúfƒ“×"“žà\ç¶>´dã‘ø 2{ 3“@N{ 2O§çMïŒd{RãëøP‘‘Ïó¤íŽ?:1ŽÆŒŽâ€½?•;~”¹ô͈‡¦Hüiqè&?8ôæˆWסsÛó£'ÐRu õ§è( ÿ­?AE ø3ŽßFdÛ*)û­À>õ&áé@ãƒI´uïúÒçŽx:þ´m>¦£}âUÀùqÉ©zŽA¨\Çæ…,C0éM% üèÚ ëÏÖ¡kTuUg“ƒŸ½Ööt3‰C?sÅ¡&?ÙÅ2HÒA‡ÈïOÆ:æ¡r²ÈPHT¯$ <ˆ‹î+Î1É¢5Ù!Xã çš<’>kdw¦Æ%m²3yÖ˜ÉÏ# ‚=ê½¹ØÆN¤Çš³Û¥S»ˆ£yþdƒjãjšñ!’ëcÛ}Ó€øÈ«=;T±˜ãf2;‡;†îÞÕcÛµ cÚŒRdZ\{Òž¸5^]¢áÂÇÍYàwªó:,èÈ$p5¸Ñ>=©B uüh?t‚{R½¢…iO’P–É>µgŽ þu }É<ñSu¦÷TvI¥bñ01güjÄl$‰_iúŒSñïÍW*Ï2¸é…Ï^ú ³Ž(éF_Ö—þ”„&}r=é+)<ûÒþy£ñý(ĉ#ÎÑÔääÓñž”˜zŠ«sºî?*ÞèFÊCd.xüh¹‹í`yM¿¦â¦’gQx‰±‹ëíV8œûÔ ~äɱÈÈÅRzŽå qÜŠ¯vÉåñ3©8"¡k9Ÿ#íN3ÝTqMhžÙ’G¹vÁG4Y…ØQR »@:SñíH§ Þž:àT±0çÐѓӟZLÔÐõ4§Œuüê‰Ö]Ã;Ž3ž•/Ò€zÐKs ¼†/—%Žy«žãš†U&2ö68m¢–&- Ù#‚@Å6ï¨÷"’YDR@̽r:V‡Ž•V¬<ÖaŽqP­Œ¢àN·o¤ËëOM˜9ÏÂŽ=ªÖ­±ž'”É 9Ô }hÇ¥úþtuê¹£ŽÂ—'Óõ£¯c@ ŸN´`ú“KùÐcêi3ž”½zQz:zÒc×–Ž1@ ôÍ/ó¢“'¶1@J? 94uJNüF3F8þ™¥Ç(„zõ¥ü)G=°)?ø÷4s@ϵ/Ö€ƨ¥ÏÖŒÐƾ”g#Å?_Æ€ NøÆG­ñ•{Ðzçð ü9¤<ö4¸·çG„P×ÿ×H¥Á>ßZ0(ú~´œûÓ»Ò‘Ç>§>âŽ}Í_­b€ ŸJOzu!ñ@?äÑϵ}sŠ8ôÅ'lPù½¸£žâ€=E&ßj8÷ühàœsš6‚?Âb('½-7ŠP}Í…úŠ Î)8Ç­žâ—¯ZN{ô4¸ÒŒ¯µ†{QƒëúQ¸z^½¿ZO­sŒQ:œQÆ=¨:cÅŽiØãšN(3õüiy4wâ‚>‚€‚@äœ~4œw ß•.Aä3éƒIÇl8íŠ.;Ô70°Øœ~µ.îqš‚ì+Û2³0tdõ  #ùQC§Ó4âÀ6 žƒ5Qmcsæݸ >ÌbŒe™È$€)è= ½9äÑŸCQÄÅ¢RF9'éšB#IìMCgXž!‡¨ëMâæPrÈbsÆ3š·Odõªó"Í"»‚¶rJ’Y(Ëc>ÔËxÊo1ˆcjpD£hÆ3M—˜ØÝÇOZ‚#y¸““œ•o“+ˆ•vl ÍIŒRð¢–tˆ ©$œp(ÜDVÈQäÌJ™br;Õ¬:š†(ž2ÆYL¹$Œ¨œTØqC`Ä ŒšZ=ø£Ž¸„ñÇ5Uç•dtteÈàñ×Ò§”îŒüáG­6ÝÃÂÜž£è@‚hRUÆqÈçDÛ÷e6í8àæ¥ú«îä!gRIãdÝS/ÞÏZ±U¤`÷"Ì1ƒÀ>µjŽ€Vº_ôf7žÀ柷1ÇJ.Ÿe»‘!C¼qB•[ufv#nKÉ£ ÆZ¢$(a’OÌ9©ð=‡ÖªÃq‰ ƒÞ>ïãR‹¨y98ìqÁ¦Ó‰ÏZ}Ò;Æb%6ç5o ÕGæô.8û¸ÏëBÜH’ß&2 mÛÇ­!p£hažyÅ!Ê\›;»RK‡$ò1ŸÆÙмÀžƒå\äqÒ›…K` ¸ëOˆaÆ}é¼\{TËdõïV8\ñНm!™Kî$dÿ)¡!ÛÉ`cOÖ§Ç©ü1P>Á4 ü¸äý*At™cJ- ÉvûQÀïMI™ãv§ö¤ ÇzNO| \z:ö#ë@ ÀïÍV¼U!2\ãFMZÈÿ­QNH ¼·ñJà@è:T«£‘õÅEs'—!ö·®3GPáÖø9ÎA2°c5 Ž|€|Ó›h4è爂¾j–_½Ú˜ÉHœRQGq­ˆÜ;zTßç¶Ÿéš2}(Àö¦<Š‹Ëc>Ôü‘ÔSd#o8öÍT·”G"Âòg”ã©§9qî´…¤†U øõÅ,M#0,P®;uÍ61b•dܪNTàæš@yÕ²ù\Ž:RÄTÌáXœ)¬Íö„@^AïBÜ:“óPܹU_˜›°ÍXíÞ«Ý3*©Pœ°w¥$$:V ±î,ù ‰7ûÓfmˆ½‰8úÒ%ÄC³€ê¹#ÚŸA’¶B“¸ô¨mX°rdÝó˜©LˆX(n{qM„Éóùƒ?(ïŠ:…î1(s!U¡d:²y¨fܘMØ8£IgaDÜ1•hýÛ ñM(”$þT¹õèç<(èj–o5Ć< `ÍO»·zªþ]¼»„|¹äŒP±ØòjS朷LÓ~Ò¦2ûhüéùd4P3çƒÎ€°@ëUdYÞà4L†=¤ml}êË1 »ié’VµHß÷Â-ŒÀõÐ[¬Êd26[å : žªlŠÚBV7flœõÅZ:wôÅ  ŸL{PsøQ=(ã¸ބȨ$ó…ÂmŽ39by§8*9cYbhÎ@aÔv¡ x#AöÍ2YR(‹»„ûÍÐUxnbG{eÜZ2i¯<h•Â09#4ì&·I‘¤ †9R"§WF2“ìh*€3Àª€Çi9ÊÈWnsœÑ¸n\ÏÒ«ïÝ´gÊØ*w|ÝûS?´bÞŠÈv#8éLŽê ‹é`Q:ÉåSô8§f‡bþ8ëGÔšnqëøÒ–\g¥H…Î}(ãZ@Ù?¥1äTRÍœAšc´¢l*£GÇ$óO0@EQUb¸LºR èPË4æÔ!X|À€?«1–óž‡J«$no@«€¸É§ý®#t¶çvöMÂ’àˆ|ÌøQ£¡¤®˜¹¨§?0<œT/H‰‰2ëB’6[„”Çó‘‹`§)ò°±jþRù˜ÜOÈ#M 6¨³z\ä{ûT±0ÎãÜRþ“·N(#×?Ò€˜z«9d•egÄJ9•/­Þ]ŠXÿÀ:g­;‰&£*6’{7"–1ò”aU¤¾¬šVw¸‡5b1Œ¨rÊÞ£Ö‹Y lÈ[!G ZŸŽçR7ŠÙŒ{œàunM$z„…ÇÎx=©Ù½‚×$Daw#lR6yüªÆ@õúbª[l–i'IK´ƒÅ[ÏÖ“§ÚŒqÔÑ–íŠ=©^1Øþ4{cÚ“>´×&3÷MEu3" X„›ÛkARA [DZ>UÎqQG‰3Êgi¾êœajÀ<õɧÐaëóñU®•IPé½}Ž*W¹Ž99Á#9ôª×SA4j<ÖEÜ9 œÓI‚EÐ@íŠSêj²ê˜Y÷à.G5ù›¨Ü )3I“ïùP¾¢“ŽÄü½.@=¨Í'׊;ÿõ¨ëþ8 ޢ޾ÔQõ <õÅ.Où4sGô ØäŸÆŒsšN:â—ë@¨ }hϽÏJ§“<ÑÅ/AIGFúQ×¾(ÈM(Ç|ÑøâŽ½(ïÔ 0;ÎŒŒP3HÀcŸå@ ÔÑšCÏSš0;@ 8¥Íð*L{š_~) ö4`{ý(É'­Ž„œûÒöö÷¤Ç¹£ß­c ñIvüéHúŠ1ï@ ×µ'Lõ£­.}h? Àõ¥ãÞ“õ™¹üiA”½zRsë@CÓô£ëG|QŠ'9ôüi Ÿ¥Åž(ü(Ï Í.£ÿ•¸óhÜ= .î{þ4nã'?LP13Š3õ¼ãï(¹ê(ÉôüiséF}hü(ëÿë¥#=hät bc(#Žp(Å/Šd•ãÄRÛ#æ+¸cÒŸ€;dý)pÖ¢šWB4Ëqüè/áúSdÿVpH÷î½ÿZdÇl,q»Ž3šXÉØ7šlä¬Gn7™8¢-…r9\t¨„²„11¹$qO¨u$·l>`’*›ñ¤03KÏ©¤†ÞeÚ{1©7¨‘׆…_—ÉöÍ1­blpFx£@K$‡{&pMMžÈ þ5Uc؃ägÓü*ÄQ¬1„BvSšlíÃ8à·¦j(üÓ#îÆÏáç<Ôgɸ¸d„‰Ü•h(ì)˜ç½/N3úRýhæ€ÚŽ}©qIùÐ_•8ª¨n)(9ùTZ³.<³ÇýÞ´Ø ùCûÜhYžèGæ(}ı°1ëS†q0SÈ?¥MøT ©˜eyÏ.;‹26ÌÇÃú€ =+ž qN c½TYíágTI~1I+ˆ|!›hRñ•ä`uÍLÅ‚éÐÔ6ñDOŸ8 :gŠžM¾Y-œb† ¯oÚwŠA;p0j-;¨üª+2¾@å†O$äÕMî :úÕw..8ˆÇ ŸéSà_Ρÿ—¢è=i A;81Æ$lô'¤fo)C"î<¥OÏ®>•X†Agb䑸çÐÑ(,!ÀA:S£bTnJd ,%€õ"chÆiv}*KÝ* žTõ©ûwªÖèŠä«79È=:Ó@‡ºæP @®9$NXb`Фp8ÅGòý¨c;°zUŽ:õ¤* äc'©¸Ç¥/_ÿU`çŠOlRm\÷¥úPÐTW ¬«•'#Œâ¥çÒ¡Ÿ C󢄑Ú5ÆDD¨ô#5*œ¨<ãò¨d’7“Éó ã¨ê!o³å†n>SÐS–(ÈÜQ7°çŠIÉHrY†åjTÀ@9?Z4Bƒ‘× ~E{¦(ãð Bäã€)7}3éKõ¤À ñü©’@È'éOëÚ£”£ TÈõ ˆî„¸ëy¥Ž$;h=…:6€©Í:˜2¤WQ.$Ž´Ù­Êb%9'š’2 Œ7fš\$ê¥ÏÍž([{ZŠër–ç×/QÒ ¸U`™WæÈÜzÒBBÌSbîÉÉâ˜-`1´ÃœqOŸWqÁÝǹ§ÇŸ-rI§Ðd¬M cIéVxô¨¥ ¬z¨ÈäÔŠê˸QCa œ/>¸§,¬ÆP 9È¢/™÷«eHô©yö¡ƒ ›`–=Ëóàçé„m÷{ñšI3æ Ü ûŽieóJa)úR‹:Ǹ0*‰€=éM‘µÑ€cœ`ÓÑ2ÁKÉÇZq è2:(Ðm‚¬ Å*2 ܆îqK0H özSԱ佩½Æ?J0}N)r{ÒýiN3É¿JLJ3è žÔ`ÿxþtcè=èõ4sè(äÒöàâŒP11õ¥üqIϯué@…ÉH¢“íHHÖ€J;Rn¥'æ€éG¾J3ùÑÛÓë@Ãñ¥úâ“·j°_ÊZNOj>¿¥úQŸjOÓÞŽ=MšO¡—ñ4võ Aϵè'Oj1Ï49íGåG'øix bQøÒÒ~t8(üZ\ÒçùÒ|£?J^ÝqIÐu€?ZN¿Ö—·J3Ú˜œy§éEæSô¢ Œ÷¥Æ>´ÏB~”{dý1@1ïõdwÍÀëÂŽ§­/n¤ÿ×Fêx¥Ç¦:B¥Æ{RóØŸÆ“±¦!ômöüÍ/'¨¤Ç~¿­&Ñè°¥È'¶}):÷4‘‘œ}i:`CŒäÿ,ÒçŒÅcÛÚ—üŠÇC‘G_Q@B7 Í@àRŽ{š0MÐþ„óýiy9çÿ­K© Ž2UW'©Æ3@ ½Ú—ïúQÐgÇšL‚:'€0OZ÷$Rô(É”gëH[Ú€{ÏŠ\óŽiÏBhyôühïÞ“§QF}Iǰ r)9õ qëG|b€ -ÐqÜþt¼ÑnhÆ;šZNhéGá@(ëÚŠ_Ò€”™ÇP9¥8£œñ@áA¢ŒP`zþTt¥Çµö ß‡ 9£=?\zsõ ëƒô ŽäŸÎ”Ò`g$gð  ž}h ‚)¼¯@qõé@ëùѸ׿ ÷#ó£ó¤¼gÒÏ­çèíFÖŽþôB@¿/éøÑ“éúÑÏz\äÑÓ¥''œñéGÔñ@Ú9 û*Ló×ôé@…ÏК:÷¤êAÇãF=søÐÓ­vÒôäRn8é;Ôq޹£#ƒG¸ûÐŽÔgñ¤çåF Å žÿ¥($ôéGJ?^”uéG õ•&;zÐíÍ>”€ät¥ã½uÉüé® .°}©ÜõéF(»@唤̃9 sš”Ù\J@§­KžsÅh¸\L{ŸÂ™e K9úT¼Òdú~´´RyÅ/é@ÐÑÎŒÑ:P{ÌÜ_OZsd¡ÁúS¾”dúš‹cçvî{Ó 2ç"^§=ú~ucëŠOÆ€#Š7Bw6GãRÒ}1K@>´Ÿ•úÐ0%xlHÁTÛ-ëŒS³žâŽœ1@ øþ Ôe˜qÀ*LñÔ~TdP¿E"»cË+Ž‘S}(¤UB  Ô2œq×éÔt¦hã˜.Tœ…éOu›»p§<äv©³E ‘m3;þLr)?z.‰;|½¼z榣4™¦ºî\¨‡LÓòqFh±†òÀ|nÇ8éQì›s`ŒgŒšóÅFVLðÃõëDQ•@»‘RQEÂã\·Ë·§\R*É€ Τä÷ý(Ç´YÖG;”¯aÍL¿0ç…/>”}x ŒQš(¨d ]qåÏ~Õ5T=ÆT€9ù»Tˆ®e%ÂcºÔÔ~&Âã$ÐŒ= 1<áÁzñJ—Ÿï^qHÚËÔç>•$~`_Ÿšw"ŽOµ ‹œúRd Š3ô4gê(ÏãL—~Ô Ï<ãÿ¡g¶h«÷FF¥8~£Ö© ãÞƒ*ž1I*Ÿ¼ˆ¦N~lt©ã®GÒÊ€+´³•`©ÈÔÐSÎ}³G¸ ú±øš?.*‚™ »o X›tJJlÈû¾”ì¼ý)yÅ2H’EÚч 6,œ¨Lv/nN)¥Cuæ€""R¡ EKÆ}éqÇþPR/ï„ù‡JYq³%KڤϹ¤Î;ñ@­ò ËŽ>ï¥8€FsùRÇŒs“ŒÐqî r£ocži›‚Hî!'ýÓÍNãGãÍr4–B 1žƒ4Øçgq OcÅMÏ¥ûÑpsü84¿7õÅ.@ï@ƒAš\qÓ𣷸õ ô£"ƒï~{qŸ­ý)}Í'3Ï¥'~â€øbñëøQÏsøÑ‚:PñéIœs‚húâ—ñ cw³Í:ÆŒú*&­ãý(ÎE÷ü¨®? :r¥Éõ óÓ4øÑÿ ŠN3ï@ F(ç¶hç >¦—>ß­&}9£Ò Iõý 'z3@Éô¤É?Â:2>´qïõ ‘ØÒdŽçšwùæ“ñÅ ñÜÑø~tSp:òM Hé3žÂ tRþf€#?ëOâŠG?¼äöõ¢€ùÒôã#ñ£ô¼P*0Ê&Ø2N2G¥99Î[é’(T 0£­1ÍQŽ0 £ŸZ/ãIÀïÍÀîGµ&}Èühpy­w8"—®IúQÓÿ¯@ ׿4¸É¤Ï­§ƒÁý)2 Ï?Z_`húP1×4qê(ïžhüç@== sé@Æ}þ”¹>”œû~œdæ”ò= N8ü(Ï)~cßð£u‰ƒŒƒAÈä:© ŠNOA@ƒùÐFy4œúþt óÉ…1žiqè §õ¥Ï(Æ;š?*NqÒŽžßJ8õ¥£$ôÏâ(ÚsÁ8ô ð?Z\ñGÒŽzÐóÜ‘KÐSyÇqI“Š~i:&O ç­.ÓQ@>ÿN{ÑŒc½¸úPG~);ÿ€£8ëÍ/ãšç4¤Rt¥ÍŸJ1FGµϵ cž´{âøÐÓ½ôÝÏ­Z2GBOÒ€ÙìO½/ÒŽh¸ç Q×’?Zq±Å68 óÛ#ëF1õ§dûSqÏPh8êhÇ?z—éÒ“ŸP â—æŽHêhçÔš8éK¶›¶1HG9-ŠïF (üh#ŽÿZ1Ç­&29oÊ—¿@izö ö£§Ö—Ÿ_Ô{qšîN (ç­~>´{ž=͘x4po€žâŠ9?ÅGnôŽ˜¤ü­/áøÒdúf€ ç§4¾àPA>ÇÚ“´½úsõ£9£¶3G>ß\Pm$w£äqKÏPhÈõü( ê3Fp1íA£ŸZ0)2:`þ4¸Í¸?G_ÒŠ1ëF9 ÈÏ¥/ôqéG=€Å~_J^”G?Ê“§n~”¸ç8£8ëJ>´Ÿ•/áIÏp(8Ç8 ¢“¯CKøÐÍsëŠ(ü±AúÒc=hãןj^?'׸¤úÐÒcœ÷¥Åì1@Ä£>ô}ð¥íÖh##¥-&;äÐô¼Òc½Z8£§­.=0)8Ïjƒñ¦ä©Á¥;tü©¬=óގϨ£?=±KŸq@ƒ4~gÜÒdZ/áIÅ鎔gë@‚Œzõ¥æ“_Îú QÛ¥dy?J!ÇáJ9õ4g¡ÁZ?àF€qëFNzQŸfúÒÐ1¸oZ^}(Å;ÐŽ8&­!8ÁÝŠ\ñÉâÀhÏqõ£#=hüÅZ3èi7 ã­žý)80>¢Â”ŠLóÏçQÜ<‚ò/Ž8ÍHsïô¨nW’ãÝN(3<áÕL-½}ýé¾mчîÙþïQùÕ¤@2ǽ)xÓ¸î(lôQï&Ê©nîp:gñ¥·!d(¥úÓ`eûL£/»w>(°XAytò(ûªÎâGÒ¤I®6ñ–ì;UëœQøÊ‹ùÄy ÆH°è=jœwÓ1$Ú¶Ð#½X•FKc§­H¤•=hš_Iˆ·@Q±ßWúŠŽP|¦ù¶Œr})–¨‰nЧpÇÞ9æ‡fÿ©ö£>ÔdzÑŸ@i:ŒÔRÌbe‚zœT½ú ­tÌ$„e‡Íü4-ÁCqžÔùR™äÒþ_§J¬×,# !$çg¥NX`õÇ­C+C30ã$sB7ímæH¦'FFGZé\DFFóÓjÆ[¾ãFïZ.f›Ê‰Ÿib; ‹í‹æ„ÄíÝÒŸ+`ÆLµ'P @/ }¤vóVÈÍC c@úð)¶îí,ÊÜž”ÀŸ¿ZZLœQŸJ@)Î{S]ÄhYº àåEC9<`€¿\PcQˆòòz|ž/“r‚GLŠ”c‚@'·0;/½ x´’å§ B Ê‚[¨ÏJrÞÆX‚àúÔˆܤúŠpUéŒSvƒpòyx!±ž¢¦úŠbª‚X}qJÅQIfÀõ&ˆf¼HeºžA ‚*Xä.GÔÈòÿ3q÷[­1KGpC:ª¹ùFy4À›j“Žƒµ6)–T ìi[;<ã½Gld1ì öéH ¿/ΘdýðLg=M?5³ •ÐØõ¡$y;š~GzŽVp ¢ï9õ§!b¼€Øæ€I’ »ˆŽ{šxéíUd/5Ï’ÑnˆÁ½ [:P~4f—­úP ühäÑøÑŸzÒgØ ZBhRrzœRÎŽ{ Lô¿…ú­úPt ä{š_§Z1@=qŠ}©qéF !Ô{Rãèǽ%—ÒŒã¯åFG½ãúfŒçƒGQÇJ9ÿ"€ôgœf“oµ/Ö€ zäÒqŠ9¥ Rv¥¤>ǼÑH(ú\1ë@#Ò—ŠLKN)3ïš?*^ÜÑõ4:@ßJ\ÒþsHaÏ­•&Iî=©rÝ3LßýgáE#pÿ…€~ïF3‚:AïKÎzçð çÚ“ëÇÖŽ>¿…ðæ)€F:þT`täý(ɃÇÒ Ž:fŠ@3ÜÑœz~TcœçF=y£¨¤$ú@ ùÑÉ4™ü¾˜¥É#îþ4cŽôtïIϧáŠÓó íGNÔÑŒP0:dýE.3ÞŒ}?:2~Ÿ….N9þTœw8 Ž2üér@)äçŠ:?LóËsô ãµ(Î8çߥöü)0OÞ ýiv÷šLœz{Rá®)*AŽà~`Íéqì?>”t£>ÆŠLÃé@ ÔuÅÿ­HqŽp 2:@ Ï`?à4›¿ÏJ^OJ\þtíIÏ­ŽÔêLzóõ4‡>œzÒöÈ µ!$vÍ/^½(Ï  On”¿çšN½©G”?΃õÍ'è(ãÐPœÑÈ=hÁô£§\þT¼öÅ/?½'áF=¨ç9ö£ Š;ñÍ ëÞ€ŸNh>ŸÎ“ì?:^ëš8úP÷4¿…&8öúPŽxŽ}*]½;j1éÀ 9“I{ v(ÀãùP0{~4cƒÿë¤à÷Ràc®(8)qGn¹¤úž(wsŒ(Í!ý~”¼Òc=èæŽ}?*_®(éÒ“ éFsÖ€ð Ö“\PóØ~´sß4éÅzœÐ‘ž˜£ñ¤À=Z0éǵ/4d}hÀúÐ=;P úRóïGb€Èš_ÊšqŽG  pÿ8£‘Ð ?#G4qÖ— ôæ“§8¤ëØP÷Îxô j?2;*^”Ÿ†(#Šx£¯qŸ¥'=úRõì(8î)F)8ïKŒ÷ €zŠ\úsMÚ÷hϸü .hãcã4gÚ€ 1@ç½=2=èqž´Ÿ•.µ'sŽÔ¸>ÂŒý1G^€Püèͤ £š¤Å/CGz0AG=±ùPϵûQÐÒ€ŠAõÍèÏ=ÿ*3ïŠ2‡Ón_šãžÂŒ1Ç!G°ëNätQŠŒcÿ®i2Þ”væ øÑÍ &ƒÓž´dwÍ ?CøÑŸjR}hÎ;qIjQz2=hÈõ4`Óc°úÐ ô£§¥ÿúÔ~΂>”~M̦y# ü ·5kžß¨ª sÝÈ%0 %¸>ÙåÇ=À§¤‘Ê2„78Ȩ–Ú F3ÇlÓãbP6=ØÐíÐ4(m¿'ÍH³" ÝŒàšvp2A…@m!iL…FãÎI¤„J9W†VÐæœª#PÝôÍVX`µß$`/ëRÛÍöˆVLc=³‘G dŽyü©Ò“ëH9÷^=søT µâáH-Þ§ÀÇlUk€ždE˜Œ¶­h²<ÈÐ8í@Æ8þTrGÊ€œö{š‚ 3»…@zƒÅNÄsŸÔUía•?w½FìõïŸJhxÈ# `dóNA#Ú 6êKe˜îäÓ¢`‰c\=éh6C.ØÃõÎiá“fK.^hçµ@ÖÊT†-‚s×49Úß.rzâ„Up¼sК„D"c(ä㎕$r‰qǧ/>´ri>ŸÊ޽M Š‚qž {ÅL@?þª‚à ¼†ã€qÆi 'ÇJc¥4Àç¥;>ÔÔEˆ£9<Ó¸=úqHG¯ò ¡TF}±m$äœõ©¿Um‚+ɲV|“Ô“Š³»Û40bÿž•ê/È[žÇ6ïóŠ‚åRE]ÎW ‘‚y¡2ò¼Â’M¾YIZp ŽÔÙX$,IÚ£¾(!'Ê0cR~Xª«›ƒ,ÀŽ ÿëÓü¦,y¸ÇZnÃ'Éô¨gSå:eXsš™OȨ%1‹„Üøl Kq"uT*Œ:TR¢Y ndû¾ÔÖ»s—L޵!¸†UÂJ¿QO]À•X¼YaÛ¥$òþUÛè)—‡›§ZKa¶-»‹c¹£¸ÉÀ=Í@øóÔ†¥ÀëÞ¡dr‘ \€i!"c‚$ò;UE’+i ]Ø.NrxúÕ²8ÅWšL6UF\ã”Q×µ•LúRóÔÒsêhÆE.}Å&~”þqF3Þ€ “FOz3Ú—Ÿ¥&(Æ;QÏ®iy ŸJ?Ö€hühÇ­˜¤8<KÆ:ÐúQœzÑšô ð£ò š3‘@=ÅgØÒ´¹ô þ™¹”…¹àPcŸÂ—>œQŸÃë@^œÐ=;úÑüè#¹ê(çš8îi(àžÔ¿­˜¤ü)y §J;w£§ÿª“¯CúP0úž´rz ÐzúþsôúP ÇAš?š2(è8ý(-íŠN¾£ëKøsGà1@AÔQŸCGÐ~”™Àéš)Ï·åGùé@Ï­&}¿J@DêL¹Î8éEO›ÁÈÇ¥þG|Š\š€ .G/é@sJ~Ÿ­''Ž(‚˜ ž:QÏ¥ü(úÒ lQþM&AèTÒíúPcüŠLdÿPiø=¸úSsŽôcØŸzB¯áFIî)Aç {ÑùŠ^B(ÀÍ'âMíš]¦ŒS@2OÞ¥Áô4„sœQƒž8 aøbÇŠ\{œÒý(1G9à~”dzПˆ¥ü¾”¹¿"hãÖ“žØ =:^ÿ®—"“žÃó4¸?J;õ£ù{Š8>§ÜÑŸ\b€˜ú}i3ìhÎ{üèyúþf“þø\:PŸJLß4`À¥Ç~ô™ÇLÑŸj\Ÿz(}…ž PqŒ\(1ß‚{‘Nç½&;ö #=GëJ?ýt3Û4½z 1Fj1š(ãñ¢ŒíGã@N¢ŒŒu£ñ ÐdúÒûóš1è(ôÍúP>”`P~‡ë@ò£Š:}=¨àŽæ€žØüérhÀô£ñ\Ð9÷~4gëAýhþtqF)qÍ'½£>½);~‚€¿AFxéG=À xÏ>”t£8è>´˜ö¥Çá@­&=éxÅùš>ŸÊ“Ÿj\ö£h‘ÔÑǽõÍ'çKíýhÀ4˜(Æ“¡éF1ÐÒsí@ Ï\P±¦ÿê äõ8âO®(Ͻ4ë“ëKϵduü¨àŽ™úÑŸaùÑ·<÷ §N(8ìH Ž;Ñ@ ZN½¨#ßô¤çüš\qÈÍ{~´›ˆëƒGƒóÅ®;Ð:ñùšQŠCøš9Íç8~(ç·å@µsF÷hú 7g±Œ÷£<ž>´`zÐì Žü})p?ýt™'µ.h-Ž´˜ö#ñ Ó 3žAü¨÷Ï׊ÇjLÿ× C‡= ý)¿ðʃÀô ÈÇjnõ£þš2?ºWë@'©8 3Í/~9 ýM!±ÁúÒ}M.8£ôý(6œò?©{°[’ìÀI5l€z΢I„…‰ì§ T;£NQ\ eFrpôþ½*eBP} Í+"²áÔ0÷u±¸•w)}AªÐ-ËŸ9œ!ÀéíÅK2Îû†#ÇÊ5–U”´Q¢óÏûTúŒ³ôÎh ÇÆ«¹ÆLx>€Ó‚8U³†ÏSš,!n x|•î3Ö¥MÞíŠk¢:á€'Þ¡ó'U?ºR3€=¨i±å6aÇ ÜR[¾ûtÉÝÇR0MBÍ!7)ëžµb4 Ut4l€“¨ÍÎi ô§cšBÏZ­rM œžÞÕcý¬ÕkˆÕ¥‰ž6vV%HâšÜh³:òi:®g›6GáA’\‚#lút¬'lm98÷¨-‚ªmW,:äštO,€îŒÆs“šŒù±F/˜Aç­0,ö£Žµ_uÁ–Aå€1òûS“lY'¯¬l(¡ ô"( 9çÔžM6UVÛ’:T{ÜJ£ËÈÇZ™ÉÚH#?Jl!„x/»“QyÄÄKÄØÝ€M+ @ÎqL ?ùÑzM¿ìóF=qHAÈôüê)³ÆÖ½væ¥ÇÐÔr¨áöäŽ8 dŸ0ÆJ°¤ž•X\>Ï»“ŸCü©~ÒZ2þKmÎ1´äÑ`°ûºÄÈìzTß…Gª/Ê„g’)+,¡B1žõ£vÂ;î*yã5PŽUVb!`Û9ÎjÒJYŠì`G¨â›Cd¿J†˜(ÝßóüêOÃJ‚ëýX%7a‡ZHDùã‘HùhØ)ýêðÒ›,k,lŒ¤ƒ@ vób)àzUt”*…DÀ­=¦Áiü©´%íU§¥]®»w©DÈdÙŒ6;Ó%ÍFòÉ#>¸¡nD€”s׎´ÖE p£'ÐiàdgúÒI…RHȤ#?“‚qÓSm¤8s“’x¢)7ÕRúœšŽ¶äĘõùºŠc-Œž•‡3©ž)‚è4nÛ '…šr¤RK¼R(ZÄä‚Ò?†(Ë“$‘¨r0}égÚÁCFæ¤Q…9÷&ˆ­U“1íUxÍXǽV’Oæ–|·ñV@ãŠl#ך@= që­üiPxæ“?Z1íF¦(yü(Ï ¤üh¿Z\ýi?O­.}(ϘàRäúQG>¿¥'?Ö—žôqéÍ~4g4t£ð4}üi2ÖŽj^ýEJ8æ“ð¤?¥;>âŒæ“·LÑõ4£ëG>´ŸCF=Í/úÑôýi1íKùPÒcè(ã°£J?G·“¸ü©qÇ\PÒŒš?F\P3íF(È£Ž ÐÈô£˜¤Å.ö*1ïIŽüÒþ´‡>”îi}ˆü©£éKŒöǽ#=y£Rcš1Z/ô›Fsƒš2I£œsÍtýiqõ£íøQÓµ& Žô}8£ŸjO+z^ŸO­&=È£¨ Ò»Ìã¦(¦¿úÎ=( ÛÍ/OLÒýÞ)Nà:sï@^ÂŽsþ`ã £zSgýœQž™&”LQÜJ^Gn('o$Ô3²ìÁp„ôlÓ-&Cþ¹e`O"‹ÅœÒ§¨¨gó Aíç4ÃÓ<„L6‘òñE€´p;æ“ñ .U»îuá°y¨w\7›å¸Îx Þ‚ÅÌzQƒUHºã¸/~TTñ‡Ûóã9íCAaü§—è(Z9ìçH@3ô£ð'éTå{Ÿ´GTR)ˆ5‹.ê®/qëÍ;ƇnçIÆ}Ò«À&BVW,1×Q3»ÈzQ`±gô£ðªÈ%Y¿y(o—¥OŽ:œÒh,.}¨Ü=ÅV¹iŒ‘6“¸oÒ¬vã¾:⋤Œr? P8銢P]ß¼V³ÓœR¬Óª“>–ÀÇ¥>QؽÏsøR~Šr)Äb„¢—ñžØ'Þ “ô¦Œ­.3Í€Ëð4n÷ÏáG·}(Î(àzÔSÊÑÄYv–ì P2êjŠ0çœ&0?:i\v5 ÈéIŒõöªÐO#ç ¹Àæ’fºiåòˆç+œQmBűKõÅf‰ïNÝ᳕GÓ5nV“Èm„ù˜ãüšl;àöÅ'â*ˆ7­,-WoÌ:ýjx]Â3a³À$Pâ, š9î*…ÝÍÔRªÃåbj1s~T~ãzî^¼SåÒácOÿJ;ýÚ©·'>r¨ÎH“Í»*¸rO>Ô¬+2=($úf©¬÷y}Ѓ·¦23V!ghÃH›Xöô¡«‰?ùQÓži¤!søûQÇ¥Py/c31@ë»å ÉÅ8ÜÝ ”–W©ãš|£±w#üš8úÔÒM$Yš=’g ^Nîœt«aóÓ€vI¥ÇsMÏçõ ü£<Ÿ Í! Æ;QÓéF~µÒÈ€I“‚7t  rsÚ–“=Ȫ×W2ÂÑ,p™76Ý¢Ã-KÍT73€@·Éõa•Zv°XwçHsUL·ë-Ñm<†â›ÍÓG™-Jà|ÀñG(X¹ÔcŠsÎ3AàvÏ¥&æéŠB g¨Á¥ÇùÍã¡?…A,ҥªCº2H'9  ©zÖy¼¹ò‘¾ |7\ëSÜLÂ2W'¡ìÇbÆNzRvëùUOµ\Uî2¹'Œ zÍ!a˜œ§Z,,:š\šª×R Þ1l.àwc5ßJÑÄÆÝ—Ìl`‚qG+ab÷4`ú⡊Gw ©w©sùúR° ŒûÒ`tÚhëÜþ4së@…ØQ‘Þª½Ü‰$‰öwmƒ!¿½SC1–}Œ¤Œí=E;ÄŸ…ø&£™Ý"fDfaÐ ‰.%y¶4%S±¥`±g>Ô;qFxÆ*Œ·²Å4Êm™‘ ŽùÍ \ ¼t¥ãÓ󨢔I¶ÈÎ*Qõ @=¨úfŠ2 ó£OÒ“<MŽRûƒ!R=MÇlQÒœš Ú‹6Û9í^i¤ÞÁkš¸£€Uh.üçeò œÃcô¤Õ€^GlÑŸò'ãÍ/âhg=3Ÿz):{Ñîp(y¤'>´c=èçÐf€ Ûò¥Á¤=¨ã± 9èqG=Îi9õö£š^sÏJ8 {Ö‚M(üýé0#ô œõ¤#Ö€ŒPE&1G¶1@ãéKÿUöÅ'Nx4¾Ø¤Ú8£¯^(Àê /ùàRdJZ3@qGãG§øÑžÇ” £>ô¹ÿ9 #Ö¹èEçš1Žô¡{ÑÍ'â?J3íùPgµ/&ŒžÿÊ“¯|ý(çñ÷ª9 Ôcž&Aõæ—QרÚŽsÊãñ §|QÓƒ’)NqÒšvŽàPàZOÄÑ‘ëǽ(úŒûP1¾ùý)qëš1øRöõLZAõý)Ø2 1ši\úÑŽ;Ÿ¨¥éÔÆ‚÷F(0O¥&)ÛG¦)1ÏúPsé‘Aã¨æ—c·ó4˜ôü©Óò¥ÀÏgÞ—hö ñßqúÒñ_”­ Á÷ü(ÚG¥:¥(§4”ñÚ^´uïÈõ Ï©ý1F è8¥Æ¥9ç¥ã‘F>¢—ðý(ÆyÁ oåI€zQþM{1îh8ú{Ñ‚F3‘èi 0&Œwãë@È=GÒ—ëÏáL"”g¥ t£ó¤ûŠâir'õ£Œôüi€ÜsëK´Òóø{Ò`žô€9ü¨Æ}¾”c>”rJMª~¾â—”dúfŒ­0 ri`gïÊŒéùP éØšÜ:åJV“(ÁÆ9ʼnÇÒ€¿Z]¾¹ ½}ép;f“çt;ˆíÍ.=Í@ì>”~…wýhÛŽµy' Ð:3ŽOé@ ·Ûõ¥ ø~4g>ÿJ8Ç"€o9ÏçAéIÇB/CÀ€ • Á?…8;KÉê?J>”FÏQF8Æ8õ Š0£8Æhǽt£Ÿsõ£#´uìhÅ.8¢ŒÁý(ühǹ4~ŒŠ1G~ôuëÍô ó¤ÀúþgÖÏJ=ºÑƒìw£ôm© 9£Ú€ ´”½¨íÓó ¥Å(çÀ †—ÞQõ íF¥&){PEõ£¥)2OðŠ\ú::Ð ~ê‚^ôþ}(¤4`ýiz LqGn”bŽIëAèçð ½ߥã¦(ç¡4Ø\QÆŒ“Ôf¶:žhHïF=y£4`æ€ qÞ^´¸Ç#¥&G¥A@Èì1Gʧ֎1Ûð çÐQÏz9ö4cŒã4dQG^Ô˜èp8iqÆhã?JÐPu ÚŽ}³K“ß…E'2äzQI.|Áô¢ôâŒÞ7°Ï½;Ó@éJ8ÿëÒt=qFF}éˆ\wΛÓÖÛ·ãHßtägé@’Îø*¥zäö¤ed“r¢ŒõãëfI"ܪñœÒ\mŒõ4 YC¥Ww<ûTœƒŸÂ«I‡XÈiWæèH.T3®ÖÊûõ§aˆ¬ÌÊx8ÈÏJ!ÿ].c Ï¢–$˜Ì8ÝÔ¬—QÂ÷.ňSÀ$Ðüç¥|Ô1ÜÅ2ÆÈ§ç¦Ãv?¥&šÜV$÷'ð¤?;¨£ë@ v­åÜàîþ•9Ú9-ùš¯"ÄnÔû±Æ:W´ üD~ZXe†Ê©+õ Å4®€žØHò¼Ò®  ðE[<ƒÇµB#híˆc¸ã’ ¥¶âûÀãøºÒz)ÿdœÕK£¹•<¦uêpqÏÖ­³RÄŽ:š­nâgwYIPH#.âE„T ãêißJL{Ñ‘Ž´€\zŠÖŽ£üjº†9„,À1ZàO¥zЬo` I”|§8©#$b öÍ;0±&4õà‘íNâ“ð¤"µÚrÁu¶Ôøãúæ ¼Ùåeä9oð¨Î§l±†màƒò=ê’mhPí‹ö¦/É<N Y#+ÀüÍ2+„™™S?/ZyéÉ4ö^Ö6D9aÉà±4û˜üÈ@,qÓ$ ŽÓ ¹‹ÌÜœ©§>\.ÁˆãÓ4=ÆÆÛ®ËdVxè Gt›ð2ÍŽ3šHîR$‰$fgqœâ´·hLnbÚØ!€9ýj¬ïqõ$(>Ó÷NÐGV=jÇN„Õ‰;ŸÞLÛçô ÔbaßÄŸì—ŒóK•´+¾´Ù·yL8ÁCN7*E6S¶&9èAR"+@<…¸$wlþµcõüj­‹ù°Þäÿ´¸5hž}©Ëpbþt})rsÏJB)BG¡?J©|¥^)bÁêN3SÎ’´.±0G#†#¥@±M#É0 œ‘Ö©X¤O!ò¢ùccÛŠm´^Zc,}Žj6¹‰íˬ¥W~ÜóÖ¦„mŒÙ9ëœÑªAЄ«Au¹7:Èz1á~”éÖO´ÂÀ| óŒÒ]m2D†FF'å dRÏÍ4-ÀEC—gp£°p=êOüX ÷¥[”%²ÁÀ8ëB³Y§=$„‰ÇJ2{QžœÑ×­!j¦Öâ%p^I7ý*ß^êMˆ* ìǦ†‹ît8ª¥×í{Ha‚AÈ« £w§jSÏp(½˜_PÈ=j¹dóðdpãyÿëU™$H”¼’^™&¡·Y„²4’nB~\zPž6¸Pãæþ#RÊsÃ$õÍ?or1PÜH¨ E$ç-Fì7$‹„ÆâNNI©*8„0î½qÚŸÏsC)'5VÙcó3“’Üãó5kêx¤ã?ýj@Eq·È`Û°zíëUöF–Ñli@Pqž¿Os2ÅÍ*ÆXíRÝÍC"ʶ¨e§'ý¯j¥ Ñj2 jAlc­;‚xäU[°¤™Ž£if V9 /Œç5Ø"\ @®ÙË×?-Zçÿ­I€sϯJŽY‚»€vû¹¥¸†@ÊóÉó± à~5g¨ä~UºÉå™TI˜Š›ó¡î Nj)åHSæ,7p Œâ¤È÷¨nKÁO_Î!`Bˆ»;Œ‘LùSlfäàd TѶä~…̪Š£?CO¨úf/.з$eGó똌ÐmÞËîu1ZE»ey”†?(=½ªÉ ßjÍ®ï*Q–ÙØ­Kn  !ËëÅ3tÞY.Ñ›½NŸps“ê)°e`ÂÚãl’2Ÿ”Õo#Óòª×.H•„g-ÆïéVAŽi=„Ãëüèü©*:u¤" aó%I2ANG4Û}¥ä!˜’y\c9Î3ý*8˱rÅH=6œâŸA‰pÁcäºò>e±Ññœg½KÛG½R¥ÃySÆ|Ö]çT Zªó<¢dÂ’!<äão½ZëMìdŠ;RóÍÀÉÿBŸÿ]ö†€ëÖŠLúÒŒPÍ'=ÿ•)×}(03È?‰¥àQþy£üšMÀŽœQŸJ1ïG=ÿ•ºQõ£Š1þq@p:;t4QšQF)3Ÿþ±£€‚(üyúR~¥…&=I4cžMôûf—$víGà?:A–ŸÃ`wþt¸Ïz?F 1“ÈýhçÐcëF=hã©â€:Ñž8™¥ï@ƒ=³zNG|þ¹ÏAGãùP1:ÑŽhÇéy>”R`ÿ]àџʰëõ d”¸ô4˜>ß•ùÒ~ñ£ÖÄŸ­ ß_Ê““ÇÍZw×¥'_Z…&¦isŽ£ô¥ïÞ Áô¸ã¥/ãùQ‘ê(˜¤Ç­;éGó Bž´„S±ŽÔdúжE/>œÓ©>´OÒŒ{Òœ{fƒÈê? CG\þd÷ÅÀõúRg#¥1ÉöJ3š\fŒRzøÒçßõ¦‚;þFŽø¦½ÁâŒûSqßµx Í&O¨úÒòzGZ@&yûû.ÒzóG#·ÜPµ&l~t£üâŽ{Š3íLBöëšCǨ£ßùRôèh2}ÿ;w¥ühã³PõüèÁ÷¥ü‡ãF=Çá@ Í.sKÁõ ð;š=)rƒFzo°0 ÷§m…!^Ç÷ èüqô /¿áAã³PÚŽ(íÍo|Òe}ÿ Z?:úþ4£§Œ‘Øš:ÿ ϸ c¶húŒÒg¶Oü ”Š:öæŽG¥£#ë@çA’9Î)sžô”~4§"Ãñ úšQŸJNGÿªƒÓ9<ÐýsIøQBhõÍ£ŸRh÷Ïé@ö"€ÆŒRôíG'®>”œôÏéGÔÒâŽhöcüŠ0{QÛ± üè¤{ÐJ^zcõ¤àQÇj>´vëKÒŠ1íGáIøæ—?JÒŽΓ8ÿõѓߥ_ÐÒãëIÏ^þ”¼ûP~tvõ¥çÖŒ€OΗô£˜ç·å@Óš9£# ¥üh /áGãG#ž¿J0häM/âi??N{¯å@Ûê?\dP|â—ŽÔ˜nø£ôP½"“éKÎ?úÔcÞqØšMºþTcë@ÃðÍú~TvÀê;S{w CJ@ÔÜÿúñNÉÇZ†_õsŲýñÏj)¹ç4¸„ûÓàCéIÆNq@Ü=yô£'4žÜþT¿ŸãLàÒ7Ý<í?J¨`vô϶h´²D$RÝ3Ò£e¹V¤]ž¤ã>Õ<8Ø>@§Ó9¤˜”mÜ7síNåÒ ªw''Œžµ(AÉÀõ÷¨ƒ××¥JGÞÍ&&P8ééU )$ó©¹düêÏAEšm¨Êr2IÈ 8E ¸&)ßðPG~Mö¸õ­ãšLþ4¹>Ôß-Yƒ=©vãü*˜‹•fTç'uLXyv¢ÀUŒJÛþdéü'Þ¤€î Ï>Õ  ÝÙ¨#ã©§Âûf1*¶;’sН!ޏWÂùd(Ý–úS]ÉXÊ*0aÁ Ê–âF¢Øå‡Ì;Q-œ2”2(bƒ‘B·P$.68ÜxçšH  )`â¡û(€\©Ü ê*XQe ‡#œõ£K<…0¨¡‰íÞ¥ŒasÉÖ«$k5É••ƒFxÈâ­ô¤ÀN)p:Ž”`Rc¿ZaKÀÈöÍ?Œ{zÒ`b€#ñª±ª‚sȧ ’  §mÈÅb€d’("—éE#“f6¸\0Õ¶‡ÝŽ:qÒ›v”# ÷ÎjÏâqèM1•²\4i„|ÀŒÔüã<“UÀŒ^9\«ÿÀ欑Æy¡Œ¯jåՊƪ2~íI)ÌGqÇFéQZme%AÀ$sRÏ´BÅù’1CZƒ+”“ìÈÉ,˜þ LÕˆˆdà¨?Ä\þì{eNÒ>†£‚TÑ_9ߟқìrÅ·EZ‘›Ú¬%´J¸XÆß­FñÆnƒ;n«[OZO` Æ8¤bõr)Üú™&ß)·œ®9¤!¶î¯°R ôέMƒPZ쯗¸ãžjlçÐ}i½Á‹ùц÷ Ù9÷¤ö9¤ Æ~¿Zk‚PŒ})‘ÜG$¯çrNÂDÅŽ¨ dIþ¨'jîé¸~u2) ‚? ®¶ñR›Ÿfwj[ib–1å–o÷‡5LllÁüÄ-ËŸZŸŒýj»íšãb³+DrxëV})t¶žÜSP˜„ƒóÅ-Ì©'q<ô Ö‹hŒHwH\±ÎHéBØ?4`ž§güâŠB^jŒ2íd ŸZ˜ŒŽECtʱbËŽàsB%Ú8ž˜Ï½ü£$ãê¬äÍ*Ä’e °Å;j¬ÓM43G˜‡Ý$g5aUT`p"ŠpqJä*–+œ”€l„¢ ±ì=j=‰r ÉÈã *(<»™üèäp#$ŒÕÌgßëO`ØÇNê(縂3ßšBxÇó¤9ç®{`õ£ p~•UšådV#fF9ÿì&Øï2BÃËl‚ÇÔ²B’Œ0Ï¿¥<(ãöÅ2Ic‰ÑY¹nƒ­0ªŽ‚«ÈÈnÑ `±_¼MZ‘Î}ê¼ËÌqFÇP pDÀûš†fQ*‰‰ ŽjÇZŒ^9G%ÈÉ E‘Ï9â—ð£¾(Áî)Aþy¨.FcnîEOžpj9CºŒœ÷ z}ÁŒíU¦ÏÚù%Îáóga$G\©zƒQf¸$ço“­5¸u«Ü3<`Ç9üji“17ÊO3Ö£*_3Înça=jIQ’vû憀¶ Qù8ÚXáTL€;ŸçL(å]ÙÉ?Ö‚XÆnAëŠll†ä¡žþaÃq·üjߦMU‘~Ñ*yrœFß0Áþ5hÔžÂ{ Ó¹¤RôîhãüŠBýÓÎxüjUœ¨n}I©‰bü÷ë@Ñ&<ÔsËä $g'K*Åd}£ cI ¾ÌÈþa=úPÇF,Ž{À©3ÏZ^Gµ¦ ô¹ã½³Ú–€bŒ0ퟭcë@ ÉëKžÆŒúâŒQ@ N7øRäö}hã¦?J1õ 'OAN¤Ï¹úb€”p}hàQš2}ñIþqJ_­Q@“Ö—'Óõ£>´œô¿OåJ9 þ”œã­Û8£í>¿¥Ô{sKøQ@GZ=³GJùæ€ Ÿ­-&M•óÒ—óÍ'ãIõ BõŠ:qͨt™'±üisëÅ?J^}¨<ûþ4ŸZ?QÈç#ñ £šN˜¥çÖ€ÌÑŠLÑŸò(ÛëŠ(Îzgó :( ö4¼uçùÑ‘Z=è8ÇRæ—ðÍ'3@ ŽAïKŒt…úæŒwé@NÔ´Î“Ž£RçÚŠZN½¨£šLŽ™æ€ÐäÓŽ)9õ  2~¼Ðþ4b“òÏC@ F(£&€Œš;ÒýhÈí@ ü¨éþ&Š9¤!ipÔ~4S›N“OCøRô44œw?•.=>ôgޏ cÔдŒ€z®ir=(éœæ¾søÑõ þ#ÜQë@Ã擯RGãKŸc@އñ¤ íAç‘øÒàQŽØÍ1ˆŒúÐE/4@ ÉÏ_Ηžÿ¥)Çz2 7·_Εx*SGàhtíIß‚iF;Q@HÔcæ€ ûô£Ÿz29¥â€ó£·Z3í|Òðh1õ£¯ÿª—$z­!=ºP0£œt¥í×ò¤ü ?Q@ އëKœRryï@nØ?Z\ýh¤ïÅ/=óùQÁã?¥'¾)sè  ?_ÂŽ .r3@ ϽÏÿ®— ðOáIŽ:çë@N3H3ØbÓ©¤Í?þº\zþ‚{f”qÜæ€ñÏÖŽ}©r~´}4˜÷9úÒãŒq×4b€Kõ¤úçó£?J_Æ“Ÿz Àäñ@ w ƒKŸZnGLRæ‹Ó© œô?¥ Ϧ(Ï¿ç@…£¶ ¦óõ¥üEÚ(ϵ… ÑŒQF}hü(Ϩ¥¤äw £4€Š\úŠ(Í&sü§ \àRpyÍõ£§lÐ íüé)=óøQ¸õ?¥óÆ(ÎOJ1“œ~´? ^}GåG4™Àÿ2s÷…ç¯ëG¸£9Þâ‹Ó½'çF@hÈ÷ ÒÌ{Q‘ÿë¤È< qH'ŸÖ‚}N(Ǩà0G­žÔ€ƒÐÒ–÷ dûãéE}ñô¢Áõ¥éÞgÐRöíõ¦ ühÁÎsG4~?•Œ=)xÇzQÓ­2(ü¸Âî rÞWéOϯ>ô¿+ùG¬§ä={šŸoNsõ`ÖŽ‡æé@1U>Ïq¶açÞ6G*ßùphÉÃ/˜Œ&#jààu©cW Ù> S±žüÑøŸÊ‹…Ã>„æ“'ð÷¥ÎFFMè ë$‘íÂ’zäÔfÞV”¿Ÿ·çùÕ¡‘ØQǨühLw ¢UgÜG|u¦OÌ›RBŸN*l_Γï΋…È㈤ÌìÄä*aIôæ“óüèq• ZlQÔ†rÙ9äô§óÜ‚>”§ð  ŸgœÙrà“ÆF@§¬w ˜ó|Œf§£¤Ó» ‚î óŸaNÆi¼ sKÛüitîOÖõ£?SF}Å ÚŒ{Q“އê)3ÇZ^ÔŸçŠ\÷ɤ84Öš¨°Ý,@ ”°9ö«¿N~´ŸZiØw"‰3;°%½$‰)ä!q¦¦;sô£_ÈÒ¸"¶–4Ùæœg#e”´eO'§4ìp2hÇù4Û¸65±Ç¥#«çä#èiçÐñFÐ{R •¥ŽQ2´)ÉùËuÇõ§l¸ÜÇ*@û¼õ©ÇJëý)Ü.1@FæôéÈS‚G—ôöÍ.½ #…]c øÜ=9©0O\ÂŽ=y¢€¹ã‡å¥À=(ãû¹ö D$…ò¥W=HÒ2\20ªœñòƒV8íGœãéNã¸Ð0 Ÿ^*ºÇ,rÈP"£·Š³õ¥4®"‚6PKÞz•©NqA^rhÇ¥Eå´ŠË:«&x©{pqô¥ü3G#ëï@ƒ¨õ£§cEÇÆ€#›~ñ°{T.’¼É¹“o ôÍYâŒö}Í4ì;•±rë‚B6ìävI 3™†=N:լט'°Í ‘)›+ÇN¼ÒÇæeËãñÍIØôúQÇ<Ñp¹T%Â'îÊ);B€ <µØ>W¾3Sþ¿‰4\."äG>Ô§Ÿþ½£èy¤ ü*ƒ÷ª]‘9ïÞ¬tëGzBEÁní댜Ҫ3B»YÇ|b¤Ûô£§ÎÂäcÏ— $m¿{ ,:óRÑü¨¸\3õ¨_Ï|®ô Ôãž3G™üiÄã(éô¥tî Ö]ÊF2jwçŠ8ǵT$¼¨¡ ®A'©§Á¨ó {$aÈÍNhê:åNã¹ÑyŠHP_Ÿ­0À²af]@þ.jÁô4˜úQp¸m\`/áPmhü¨•ATý¨ÿ8¤6ñ„]Þ^×n[½O–ÇjLqÏà3õ¡€)zQÀ掜Ð"3 UÎzt¤U‘(Š3÷¸ëSåzä 8÷ÅÈâ!Á<äQ+Ýo?»]˜àt5kèÄþ4r{Ó¸\®r"tcqo›ž‚¬Ž¸£Žôb†ÂáGoð£èçG'­!áAуJx ã ¤ç¾i~”s×#ó G¥ÄP:rsFá@}xǵsí@E-'SŠ1Žô¼Ô™ÀéúRÒvë@ ô¤çÖ—ÔSJ«w ïGŒcÿ¯K@ J1Ú“©£ž(H¤üèæÂ€éIùÑøÑŸÖ€}M-~´™÷ůRhü¿:^ÔRdzŒÑqGåš;zÑÒ–ŽÔtíIïš=…úŠJ\úšN}hàw\ïQøšo¸úRãß¼uÍïùRcßñ¥üs@ÄÏùÅ/ÖŠ0(£éG'‘GJ:´¼S~´¸Î(úbÂz_€ LŸZ?!õ£“@=¿:ZOÄÑÆq@4ž”wíKÛµ'½-'×”¹÷£ñ €h3ŒóF;äÒïF=ÿ LƒA#½.=3F}(¤ÿœPN})ÜúÒqê ‚x#éH=8œ’)2;þ4„sA¥ü ÷ LšwÐÔK*ÇäÏåà±Øpî=¾µ?ËôúPEzš1Û'?Z4ÜÒÆŠLœúZ8íIŸjN½i*2=èϧ_J7zOÐ{P1sëŽýhÏ© ‘Ú¯{Ñ:š\ŸZ?Ê“#×ó4{çó ôgd{4›‡\Ðä÷?£I•Ïz:w BçHã'´¸ô4 Lö$~—ôm÷üé01ÉÅ)üi ÇñGËÓŠ>_Zö&ÃŽà;rhÏ9çñ£9£¯âŽ:µ\ÐqïŠ_ÄŠ\s@=…&ÿõRðz‘H6ôð Œu4¹Í&÷OÒ—ñ£¥"€ÿ×Kœw¤ïœÐ=á@ ÁíIßb—†õÐxëJzf“<ã4pzó@ ƒëF?8£#š8ÇZN¾¿/ÐÐ}Ï (âŒÇŠLƒÐƒü¨p:ŒÒƒŸQIÀç®=)sž„š?Lz8ŽC@ ?*8¤ÈǯãGÔâ€w?ýj3íFG¯4~tdzÊŒûRdûRäÖäzÑŸcA¹£¶(p{QG¯j>§Š3Ú×½ Ç®ih “èØö"Œ 1Žô§Ž¹¤Ï±¤ã§z\`u"€Ô¿^i2=hãŽh϶(Éê3I€=þ´wëÅ/ÍêhéÏZ?)3ß4 _ÓØÒcÍ)ü??hÜ®y<û v=¸£·zL§ãHaÆ9¥þ^ÔcüŠ8Ïj`C'úÁ×¥I÷ÇÒŠ@;¿AKót$éH)qé@3F} ö£¯P1LBçŽÿ5ä ˪Iô§ ö5 …y4jÀŽrho`B¿30n‘V:ô"£"ª‹µzqÒ¡G‘®pÒ!\œ0q@5Äq¾Æ‘CuÆy¦ Û}ˆþraÎúš#äc Š·ËБO1GŒëŒÓÐ4$àò /O­Eb¿0ýjNý Aê9õ¦y¨aq»Å8œµ–ñ?/_úP€³ÉäRÿwõ¤ÜGðƒõ4žØ>”ÃT= ƒïô4sØb.œP2GÝ5"Ÿ^´ƒ?JLgÒŒóÉ4Sõ¥ÝïúRr})/·¾(ú8¥Í B=@ö¥ÀÇ4Å'?þª2zRÿž”Þ€€xžùü(qŸÒÆ€ ñFµú ;g4cß>ÔcÕ¨Ðþ´cØÐôÍ÷4ŸËéJ? ^£Ž1ë@ü(<{P‚;΃ŽÔýO­/&€׊^ý*1‘Ö“ñü(K´})¼ž”mÇãšPèGçIŸlQÛ®~¢Ž{‽ÇåJÏ\þ4‡ñd‘Ò€SAu RgÔ \àtýh9ÆA‰£:æ”y¢€#®y €zþ´ìlR`÷4zÑÀíŠ9éF1@:_ÎŒûЊ^)? ¹â€¼Ž”œ{þtsŽÂ€Ù£'×ðtÿõÑ‘@}(éÎ:3éÍ&O÷@úГKœàæŒþ4¾”™£'ŒPzsFGz(#šN3ÿ×¥Ïa@G­¦9¥é@Í'©¥ú:9ÿõRpOLÐÛ“š\Š)Ò€ ú~Y ŸRqéGà öýhz÷£‘ÔñH}†ip=3ëÍ'Gæ)G¹üèÍ{æ€ý3G^ô‡Ûð¥Ç½ëÍçµâÏáIÎ}¨sFO¯çGnMy õ£¥'èÉú}hÏáõ¥ã>”ÝÞ„~tdú wçšJ2MçÒ€ œôâƒõ£š;÷ 4tõ£ƒ×õ£œqÍñ ž?Â’–Fx£¯Z3è(çÚ€4„QÐu#ëKøþtÜÛ½»Ñž(úŸÖ€Ãõ¤v"—ù b€x¥æ“Œõæ“-}J8ÿëП|Qøš?•¿…§$ÑÛÚ“ƒëGç@…ÇåI´g4žÄþ´¼Š­‡QøyÅ/çI‚hÈéÖ€‘ÜQÒŽ3@ÃŒðhÎ:š8£ƒë@€Î— ÖzC3åÛ• cÓò§Ço0e-;0ñÈÍ;ÅÜóŠO¦)¥¶Œôª¿½ËG3GƒÈÆsI!qÎ{ÑTÖ Ã†3¹;6œã¯­:ewW˜HÄôÃE‚Ū*)dULÛ¸µI ¨ŽAçš,ž{ÖÖªC˜HI¥ÞîN3V³ÇJxôæ–«iY–)GqÔSq"mw—åQóQ`-ÒsLG"²œ©¨çbSËV*ÍÆAé@ãž”sè SHn,ü( ñ×ñ§Û» X¤}Òc¨éNÁbÎ(ü):r4séHAÛ £'ÒŒýhúP0ÏùÍ&G­DîÞp]Ê=jjLg¥ƒšZ} NzÒóš©2Üy¥‘‚Ç·œž†’'•˜ºJ²#( ÜS°X¶Gµ=ˆÈ••HvÉÉ5öûY_4cÙŠVÇ4lÒqžôc=Eœài;óŠ‚åÚ(ÆÇUËÏ5:çhè/󣞸æŒwþT›ùÍ=ÆM(¸ýj«¼Þcì(Øš?Ò·ƒòm=½(°Xµþx Ó¯Ö¨…¿1mi7<ÕÅ`²@怓íI×½&¹¥#Û4×#ÖÖ“>ÄSô `qÜÐ:ñK“ô¤É zdQøÎŒdtüi}Žhݽ{P1ØÒ÷ëF=p(võöpF1Ç¥¤Á4\ûQÖ“z_ÇIŽ=}©pi03@N˜úQ…84¸?O¥cŠ?hÛßš1ë@ £Œqø89ÎiG¡Çµ79 óØRž½†ŒñùÑŸ_ÎŒAšZCŸzÇZ8¥Å7=sÀíÍ/^ùcÞŽŸþº1ùQœwüèçšLø4gŠP;“Í&8ãm!s×Ú€#ÔFsÜLaõmÉ ú‘ô àyö çÿ®hŸóŠéIócÚ—áAé“@ ŸR?^Üó@ϯwëúPõÿëQŽ9£>ôuäPÀ}£‘éZ3Ü‘@ ÇLšQõ¢ƒŒsÇÖ€F=ø£ïG?Z(ÈëÍ÷Å'œÐ¥RqëÍ.N:ÐÍ&=@¥Æ}h9ÿ&€GéFOµžØ ÇøúQH=)sŽÔ½Î“pÏå@ ‘éG´íý)yìqô¦!2j&#Ï\äœpG6}FOÖ«M°Î\ynGšhh°N;õªèYîL8^yÀ¦˜ÖFTirèA'kÿUÅkuQ,›aumÜ–~•d€À®8ïUíÁi$Ä¥Ô7AÚ¬ò(`È¢…aRc“üF¥Ï=1FG­àÒû¾µˆžfîCcµOùþ5 ¯ïƒù…F1ŒÐ{PxêJO”ŽÔ zÆ€#™s1žG·zlH ÝI9§Ê¬c!+dsŒ÷¤ƒˆñ¹=Í>ÐŽ}‹4D«“ÏÝéøÔá²CUç öˆw6Ö c­YÁÇJÃè±ÔUdX…Ð9eb85a›bäœÔ櫤g훌ŒÜ—'—J"×·‘\ œRã1L—ˆ˜î+œŽÔ„Eh`xéÖ¬}F(¤f­ÛÇúŠšÞ9¢-æI¸€ž•RCeŽhÏ‚€ sGçR ÷þt¹úSx¹¥ì3@üþ”qþE(ÓJ8Ï?Î Ç©¼ÿõ¨£:KƒïùÑÏ®(Ç€~”qG8íG¶('°\Ð}Í&GPi~¤R÷ aœöühÀø¥ëëF=…7©ë“ô¥Ïb)ydÔŸ‡ëF}éqíùÑß§4uíùRdŒ0¥œdQÉè zN½F)HæŒPq“’¦E ÿœÑϵ&¥á£'Š^þÿJ9èéGáF}¨ã)9÷>ÔgÚ—§\þtdã Í&qÇòc¸â—žù ü?1FO¥/=)8=x"Ž=Mã½'çøPæ—&dtÈ ±ÏJ^£ÿ­HG¶EÏÂï@ =…ž´P~”}i9çœRã=èéÚ€ùÐI¿*^4Pn?ýj\œQõ™äPÏ®}³J3ž‚“Ž˜¥Ïµ9ÍúQÔcmQŒñ@O·çGn”´sé@uô õéG¶(£µ>”g×ô ŸAG#µ&qÎ8ïJ:dŠ9ô¤ç¶ /åI»¶s@ õ¥ÇåíI¸ÿw4džÂ€ cµ/¯?Zn}©zM/4‡žôväÎŽÝ((hÆ(çÖ€‚OLÎŽGÿ^Ê€ ïF?Î(Ç=¨ÀôýhÉ)ýT¼úqëš:t “èhþtgù£ßÆ€ ç½çA>¤~ŸŸã@ëùRãêi3ø~´½¨3Ç¢—¯½œÔg=ñGëøÐ~´cÕ¨Àô æŽM¥Ï­'4ÀZ9íF=qKÏ|Rc€ c°£ž˜?Z^I”h1ê(¥ÅØ ÁÏQG zþ¼QïÖ€O¨¥ü1FxõöÅhcÞŒZ\R}ö£šZ9ü((æ—Ÿj(˜÷£RⓚÅ4bŽM'N†ŽëAö ^hOáQL¢`AÁ䊓ð¨n `qÁ „ü )uâœ&MÛCŒç{Õh-ã’$‘“k•ät§In‘¨e‹qS»ïTíqérwݰ•å½úTp.Õ?uFz)§¡óbVt#péÖª6ÌÂ+f|±ÉÀÍ%Ø Þœþ•«-Ë·É‚„sL†æG‘Û´jË“»¨§†ÅÃ/‘ÈïE¬ ´ÞY W榶1P¶ß´±³¼Šœôýh{†x·m`AeÎ=¨fZðq.94—J…W1»x+ô¤aþ‰þ¯·+š:¡$Q…°·Þlõ© …X†éMî8}iùã§žâd0îV+ŒFŠ`W’Sæ*á_*wQ~Ðÿ»p00KdRFTÜ8òÜÝHâ˜Ë9öÍA7˜¯¾8òÄc;±SýAtXFH\œqÍ$$LŒÛáµ½Í?>¦£ŒŸ-s‘ÇB)ø8 ?Z;qKŽ;Rvíô D,™ºV ž;¿¥OÛ½V“jQ¼†#…êÎ)ôgŠ^>†—¥!4€B89ÍW·BŽÃË   Üš²sèj¼2oÀ߅Ǧ(@‹ü‘U•1zò`ä¨ÏZ³õ5Wo[ Á€ÈâšZ£ó£ŸSGOþ½!\ ’0»IÈ8ÅJ2Td~¡º)å Ç=52TuÞ‹†=8¤ãÿ¯Jq‚rÇ”õ jÏ”0‡=jlzfª4è·LæÊ®pÚiÿn!Jȹ8^OÒ†XéØþ&”×ò¨­îÄ[À`3ÐÔÜ÷„(ãÞ“?äPçÖŒ{~´rFzP:úPÍþ4¼æŒc¹ ÁÿëRÑGå@×4ƒÀíKü¨ üÖ–Œ =ùdç­ñǽtê(ÇáI“K‘ÚŽ(Þâ—¸çŠ9ï@ ¯çF­/áE&\þT˜ãÖ”’;RñøPsÚ—ëIÉéŒ{Ñõ•(¢F}á@ KÍüi;Pר¥üi:ÿúèéÚ€“HA£äQíÏ×4ê9££é͵æŒ`qIž3Ê”þ?øæ“íKƒG>¦€ zÒcÜýisÓ­&?ÎhàvÉ éš^i?PŸ¡¥ý(Ç4}1@N¹£'8ÁǽëGë@O§ëGÓ“þúÒ×ë@çE¥׌Ðh÷àýE>€ÑǠϥÐO½'N¤fЉâ“õZËöU ØÜ[š`I”ÊÞbÆ©žj~@㪴‘Ú¹/$¬H$ ¹¤7𲌬‹¸ãt¢Íì2Â;²“ sÀSšxÈ=ê;x„1ãy`NA'5/æ) ‰Ï½Wq’€½H5`ãÔT:ù¥X°Ž”Ð"p|f”Õ95R3!Y:‘µ$Wi4ͤ ¯RË0±$¤8PÞÕ¯0åÓkdðÉn£É2ò=ê;{ÈÌ`âFbÞŸýzi; ’àÊ'ˆÆªcçq#8«# Æ? ¡v`MFÜH½ÁÚCc8íŽôåÔb/2såpN8vÐ:‰ê´{¾Ðq˃“ŒsQÁª[ÎȪ{c¼sNóH¼do0({ji‚-g=‡ÔTsî>ÄqÑ ñѺ¹ŒŽ)¿i†îÒbÊP/ÊÙ ÿ*\¬V&µy ”Ù4™úÐl“øPéùÑoÖ”­ô ·@(ü?J1êçGnôRc¡çéGøM.=á@?…×ò£Žàþtq@Ni?õ¥Çµ&¡üèr=0)7qŠ>¼ŠNÔ£ëùÑŽzóõ¤¶sF Çrhߥ!8éÇá@ ôëí@ ùÒŠhú樠bÅ Àþõ.F8é@ÅÍ\~™ëFGOÓ4¼Åô€ƒÓ4d} Ži3ß§áG?…-(öâ›Û¡ {Š<1Kô¤Ï8È£‚(Ͻ>Ÿç¥&2yÏ·4 u&}©1þs@÷ Ï4˜øA4¸¤Áô ëÚŒñéIõ£ŸJQKøþtÜÜš_Â{IøàÒöæ†<âŽhàÒg= A@ ZO ¤ä¿™¨äyDª ˜%_ë@ŸSÇÖ£•”FrÀ{Ó³À?ýjd¤ì$ôõ ‡0A-ÇSNϰ¦E»`Ü¥O¥?w”=Á’DE%Èò¨ YAÈÀ©9O¥ e˜Æc¹-ß50P 0j: ˆô D€a~è9Ï¥VŸd_¿3È8úÔèxi C'm©ÄcžZŒ¾û ÊøÈêË“K;?›¬{£bCô©(Ú//iÛéž)ôa'Ëò}iäúóíPÀ_,¥¨8æŸ)uˆ”||¢“27ß3÷@¦•/p¬$;UŽG•$h£ç)µÈù5 ˆb™!€Íó3Ÿð¦·k žj)ÎÔ$0¶jLäg Þ«³g1´$Ç·ïÒB,.v [Ô v}©£€ãéKÈî*_ÂŒŸj?iÿgò¤O¿ÏR àTÙ8éUÝsv§(^x©÷2xüi€¹¥ïþ™ÉÈPÆ9梦q´c­HH9ñÒ¡…wPŒqœš±Þ«ßj<ƒn©¸ªã‹·;8Àçš"Öyã4=?JNøÏ=¨Ïn¦€#¸ cžyÁ§®vŒŸjŠå<ÄUÇ|â¤S…J8þ˜¤>”dJ( în6‚¡@çÖ¦àò8õ_hûY"&Î>þ8©øëÁ {fΓpÛžÞ¦”P!r{~f—ñÅ'=ò~”P1sî3F8æ“üóKøPô¤ïÚŒZ\æ€ RÒ~PG°£#¦E'¯ ?•'¿J_ÄÒd9 Bþ_•;Z…QÍýqAϽQš? ÑøQõ£é@ ùfŒç£h$úF:b€©ÑϨ4t=(üèíïGÖ—¥ŸSŠ??z?*>” ž”™÷¥çÔþ~4cžßJM Ð:b€üñA#½%}hnö'ØQþzÐzûý(ëÓ§µ £Ÿò(2;g4»²8þT}i Ï€~” öÎ~´½}3H îhÏ8&€?È£?äQß­/íøÐ}(àÒóíMØwî,~ƒ¥/zQGãGàhsGÖƒHÖ€—Þ‚=¸ö þ4dP8£ž¼çÞŒÒãÞ€¾hÅ# üÍj2{`ûÐsØQõëF>ŸŸ@($÷•'^héÚŽÆ{ÑÐuÏÖ“žüŠ:ûPþt~ŒÀÑŠBazš>ï4G&€ ÐQÓ¦3G^ÆŒA@É÷ÇN”Q6|Áô¢ 3ïŠiFIëô¥÷æ˜ëœÒð:ƒG¦iGã@„£ð¥üéxô Èî ‚€F8úš «Î€ ¿Ö˜bBNUsœò)Þ‡"—S@ÄÇëKœðEÆM/¶ÚCŸ\ûcDŒyLýEIjN犈[B§"$ÏAJ¨ˆÌÊŠ$u5'áIÆpF(žTdçË\ŸaH°Â­¸D úŠ`^ä(6Ž3M*“µ×úÓŽ}½écœÓšO-CØ ‘Ô k[Ç' ¡‡½?ǾhëŒÿ*O(&6€éM*« (ÝËÍ<`t¸4A”-’‡+ÇCJaSÁPsØŠ~ `~TŠ˜P88¥uïô£z\÷=(Ï¥/ÖŽÝ( ñF1ØÑÛµÙ @A=¿:_ÀR|£žŸZv(ß»Ûò¢—ŒðÖŽ &=zÒã§1ßó£Z&=qGvúRãð£ó bvéGƒ4¿¯áG>´NsŽ(ëéš?Ò—·J%£>Æ—9õ ÀÒc=©q_¥¥§z?;Ñ@íGzNž´{sù u&n ôb€zÇ®hǵ/NÔœ}(y¢Ž{R¼Ðô£úÒ`šwc~4™ö¥úКCއ¯µ.=3Š·ë@ €=iM!üis@ ùþ~&—#Úô íëøP=€Åôþtž¼ÐsÛÚ—Ÿj@è1Jç?!ô'Š0@¥÷È£øö éô¤Ï<ôôÅ;ñ¤ç½{~4uïKŽzQÈêh1þE(àõü &(ØÐÑIÏ¿áK×ü(~4tíŠNOÿZ—hë@ZÓSKøš2=¨Áõ4{æ“*{~t£„P öþT¸ü(ãŽh÷€ cžôcžF}èý( P`ÜÑôÇåKFx†qÁ™8õúPGr)qÞ€#×—=é¸\õÅ/^Ùühúþ4s޼þt¸ø:LØÐþzQþzÒçÚ€Çð¥½;QøPíüèÈÎåGŽhÎGJ83GÒ““ßÄ{Š^qÉŤ$dd3ƒŠ)qÇó£ŸJN{IÀ§zRuíÇÒ€zQϰö£>¼Q‘Üâ€çF© Z3O΀'°ÍÒdþ4*3އ½)=¹£·½{Ñõ¤úKŸq@Ô´™Éã4‡ŽÃñ 9ÿõQƒÜRué‘K^hc~”qFG­CIŒÒ÷þ”gž††(÷æ“Ó“FqÆ “ÒŒ~4{ö£¨ûÔczLwÉ&—ŸQùQýT NGj2}é:N”‡ýãL•<È™7ÈÆA§ôèÏp(wýx ¶ æG tÉ¡-¶.®NsV)3Ò‹°¸`úÊšêYÜrGP)Ø£ÜäPQPIÇ'ÖŸ­ÿJLŒp1@öâ¢11lù„ äŒTÙü)1í@Eˆ¶Ilžç¥KŽ™¤éA#'Šd‘³²ØÇ^´ÁÊ’ãpàu©Æ¥ß• Š8i1R¼ŒŽ´`;Òç¯ç@­¹\|ÄáqÍ:(Ù eÉñíRgñ¥ÉíEÂâcŽI4¸î?::çÃõ BàÑÏsM8ëÈ£ñüè7Gi1°¯Ò-ŠàôúÔ¹÷£ô ew†W™qÈ+Ò¦_•@ÎHïN¥ÀïEÀ®ñ»J\>08 BÛ‰ó'­OôdÒ‹…ÈâF6»–=Î)­1o8ˆø!Áüê|ÚŒ} ®ÐÈοsïJ!“pc/ÍŒ M·''4c¾(» ˆÀ‘€Øü*/)ðSïSûR{PF,ªý:àÑ e3–vÉþ#š˜Î•¢‹…ȼ£çÞzc¤>~ñëÚ¦ú~”¼ôçëEÀ®ÐHb*]CzààsS¨ù@ààQùÑÆ;â€Ó•¥Њ>™¤ã4\ýhéÚ“óúÒƒÛ½…ú =ù£#Ö€ÓŒQë×4{üÔ½»þ4f“ŒQK@Æç4¹ì0(¢ãKIG·j_ΊN:õ£4gš\Òdz? \Š>œ~Ÿ-w4p;~”ƒ¿_ÆóÖ€ çžGáF­Óš1׃Š2}?Z3Ï&Œã¦¦(ïÚÆÆŽ}h¢Ž(úq@3ÖŽNhüóEȤ'ÿ S±IÓ± çÐ~Ž1ÔQŸcJztÍ7#ÔíK×±ü(éž¿J2Oo΀˜zÒõé:zÒþtŸZÐR÷ÇZL{PæŽýtœc¡ü â€üð(äzþ4™÷üé{ã‘@Ô~”u£¶3Íj:QøÑGáš>¤âŒŒõ£§jºÐŽôP?9Ï^(ÆsšLgøG¿…´žÝ½h>Ëš^Ý3KŽ=¨¤Ûšv ô aÏaI€9?;së@„ {Ñô£ñ¥ÉÿJ&000(Å-ºÐRñI­.\@Mþ·ð¢‰±æ~RÏElzí4õÁÇ¥8`ž¦Ž}(Å{ÑøŠ?:bŽ„šG]é€HÏFE8~nô4LÁåF¥bAûÌ3šU·Ü€‡ÆzœJžS¹6ç>”Ø<Ï%wíÝêUÝŠ¸ÉT4± vR;p0ßY;UIÖF™6º© ŽOôïVFóëIì(#ûS>㸌`Ž*K‰„Q ûm5ù¿ib\ñ€0:Ó%y$R9c*̸íE€KG‹®K9ÉSÔqÒ®vïùUY•â @ˆ¹{ê´r Ç$zÐûƒ´Œ0:r?¥!$ý(ç®9¤IŸ2¼Ó•ŽçkŒ€¥sýi?³æ8ÿHc•5d äðA=9&§Ç çÖªí"®UºZ2K(,F7Ò K9 Pbå[`Á!HÏÐf¯Ë¹£egŽÖ7ŠÝU˜1Â…&"‹ý@³L\ÉÂ’=z¶<Ô3ç|xˆ9çãÎ¥]ÛA'žüu¤û‰ŽÏà?*k6ÀXœ(äÓº”Ž2Œ1œŽ‡¥ 3š)îd‘ã™+•§²=¹Y¥“äæ ãšž áZÁsIz’5«¾ÿlÕó[AÜsݤq«ív Ójf¢hîRÑÌV6^29éDë)µR"èn‡õ«J>EÉÇ8RÛ`Ø…eKuÙ4£y•º¿–TÆ©Ïj‘ ¡0'8ÏÌzT÷b¶URÝ ¦Ü£´`óŒúÓ 2C¬pcžãå_ª FÀ}ì¯Z³– Öe88©1ƒUí‚”¬%ó“ëE“éFãþEúÑœÿúêI+ª!%±ÅQ_<yª„¾àÁ‰Èý*kü~`ó†FEXˆâ5Âí鎕IÙ ×Ίbò͹éÏò¢]ïrJ^ôû€Í´ˆÃÛÙD8 ‚ÇÚšÜev‹PĤJ¬Iù㊳w ó&Üòvã5gÓ§­#g$t—0®Q vÌ©ö¥ rxÁ¤•os\à ¸ïV-Év24^[c]°KV-”>Qõ¢öÉ`$F|Ø© _|ý*(IÙ€…G`H©A4žâaŽù ÒÖ“·ÿ^€~&—ð£"û“Š^¿ýz);t g¦hqA£ŸSAÏ­Z^ŸÊ“>´ }h?ÏJSŒtÍ-'9ë@ Ç÷@£ôü)yé;õ?•Ù  q‚(äý(éë@ 2hÆx#ó™÷£æÇZ\uÁð¤£9Ñ“ÜЇ×ô¦äŽÙ¢Ž=(síG>´fŒPþy¢ƒÀëIzÐñéGùéIÀîiIèzÐøQÓ§4™îsKî9 Žù£ñ¤úÒä{P~8£´ph<ÐÒƒô¤÷éIߎhÜ{Ò{– Þ—Ú€qíAäsIßîÒàý(8íKG#¾i9üèÅ>‚­çƒ@:rÏŽµ¡ Ûò£êh¥Á#¥ ã®{Ð:`…O|ŠQ×­'~Ÿ>¦ŒsÔ“ë@áKø :vÍ'j?•_åG§4~¤ÀëŽiO¾hã×ó ô})~œÑGБ@ žÇ û~”tõ£ë@Ã=¹ü¨Î?Z3ê?Z:õÇÖʃמi2AäP!ÜÑÚ›õÈ¥ühvçŸÂŒ˜£ŸSEîþ´RçŒæ“8š1ø~bŽ{Òþ4œƒíA œw¤ú} öâ—tÅ4˜Çÿ®€î3ì(ëô£ÿ…ò 9Çô£?AKÉïš9 Èõü@£'׊3ƒÒÿžô\ú?#I­(öü) 'Ó4¢“ß½òMƒÓã¯åKÉÿõÑøsLǽëù 1Ÿ¼x£oÖÚGó¸ïŒ~˜œñGáš`.}hätŸðRNi (õÍÀëKÏLSœvý/ùéHµ/ï@úãê(Àõ£“Ø~t~ :ú©8ÏCùR‚G\j:÷ ¿µ'â?*^½©{PÞçð¥ÿ8¥úŽ)Ò€ 1Eö £8àG©h;ô£ð£ñ¥üh1IíšZSœt&€¦“Ö—4PøÒ`úŸÂ—4®h1š_åE&yï@…¢“>´{PŒzæÃžø£óÍZ?ÏGz>¤P Ü=:?Ï·QÞŒ RsýãùQŸZ8~4:ñI“ëŠ?΀ü½©?š2}E{Ð1xÇJ))h`~4Ÿ†)i3@GA×éH=²~´¹}hê8&Ÿ\þgÐñGãúP×ÿÕKIõ4dzþ”¿…ÿõR}?:1žô¿^)=ñúRçÖŸÄúPd\RäŸÿU'ÔP0ü?úô˜ü=©sÚŠzfŒzÑ“žJïQùPö¤ý &ÓëKÐu ·o§çGnMp;Qž)3ýÓK“í@úÑF=èüOá@ Óø¸ö£_Η|ё߭ {fŠ ©4PFOµÑõ @Lâ—Ÿ¸ö¤ú`Röõ¤<ôýhÏ­.*2褜ò8ö§}i0:ÒþTcZ1íGOÿU'nXŸÂ€<ðHõâ§&ŒûÑõãé@Ãñ£>‚“4Oá@ øÑÏ\Ò}?Z_Æ€ ›ý`úQDßë )üg¾i~¹ü¨ã¯?Z;w J”r?Î(Ȧ ?Z9õ`u£§h9AØ=Ži!%â Wo?ÅK1 œc®ZHe„2ç׃O úÏ´]F78RwÇÿ®­ cª×>b2ͼùhåMJ’+E¿ 3ŒsG@è@©þ˜t c;¹Í, ¦â@a(àrÜÓ£fw.ŽJc¦0sP,“ºÁ6ÁÁÇ4ÆZ¸¸l!cŽÇÓ¡g¯±ª€^G03œU¸›rpäãŒâ•´\qIî[ð4œã¿åFyäÒBk…Žì ’<þ•"Þ¼‡jÛ•=‰'§åOfp¡ûœŒU޽óU}È®[dÅIÀè S·ºŽxv«|ý˜àþU~N#lvP d´R±eç…ØõÅÌÁ€cû­×«C ×éÅVµ•dhÎT ¤ùÕœcµ)vúôc·J{/~T„'¸ª—RåþÌòëÀp*g™\4q0ó:`ž3NEn …Ü:cšhàXj#vb&!áÞÆ[çڃל|Ñ~ár‡ž—®REãœ`оÿ&ª‰ƒ\˜’L3€¸þ•kƒM‹ŸAøKúL w?gøjDWšÎ)çY[‡ ·#¸¨ÆË‘‚X;qÒ®`Ž¢«^D@H#;²2N 4ú ÝJxWsüÌ⮃’*´ÒîãqÆ æ¬CØR¢åÄdÄ’:m?6iž¨î%Ÿ{íjxò&e2nÜIÒ§ c w£_Dd’%WÜ«¸¼ÔÖÅZ`IϨ¢gTó]‡Ë¸õ§@dò†ý»¿ÙéG@ùÒþ™&—Ôˆ #œä{UH¤F»”o!³÷IÍZǵCŒÓH¤‚Ç"šMÆ8#géGœÔláƒ"Hzgš@E;«:Æw)ÏÊÀu©Ñ6 RÛ°:žôØÖ%œ°ïR¤ïMö“J¶ð´‡$(ÎEnŸ3J$fs†çJH敎U­ÿ‡sõ«ö£aì(9ãó¥ãÔC´Ž”}1H‘y>‚Ži ©5VY¥–Ö˜,0ëE†4–º“t‘èF0i·£Ìž ù°ÛN?:¸ÀàQŒ‘÷IªNÌw*)‰m·8` ¹íõ©¢¸Ä‹ yŒq÷ÊñÅO“ßš…$"}¥“'´cc L:þT `u4¿¤ãѨgè$zPrElБץ&Ga@ùô¥Ï_›4€û~”¼Í'^:ûÒŽ”sü8Å'>´£…/á@ È c×#Þ—è(ü1@Àt#œpM‚—9ÇyæúsùÐp{f—Œc‘@„úŸÒŒÿê¥ÉíFêh7}HúRþ4g×"Ž´d”cÔ}(ÇÖˆqÔŠ\çµ&GcK“ë@ƒ&ŒÒÒ{Jç™íü©p{~´cŠ1øÒ`ßãF=I£ô&€éœ}i>”mõéFõ ÷?Ê—ô8 ŽsŽ}͇™Áô¥æŒ{Ð õ4gÓõ£´xéHažýi:ö'Ú”ŸcøQŸ®)ˆ1Ûh`{š?Î(Á>¸ óéFqÇO­.=¨ät üQøQj:vÍ PFGAGJ1ï@¥è;Ñô4b€ ýi3ôÅ;˜ÏjBú“þº\~˜4Æ.3éü¨úh;½:N½GZQìhç¹ÍÙ4cÞŒP:C·ÐÐâŒc½ÚŒ÷æ€ AF¦hÏp ÏzOð£ð£?_ÊŒŒ}ïÒ€QÏáIŸz>§Š_ÄQIïG4~‡šv½%”~gêhéÿê AŸoέõ£=¿™ ñ£„Q×ÖÎ…%/J ¥Éõ£ ñ“ôÅyÆ(Z(â”{@„擵.qßõ£ñÍÎ(Æ(…Œ÷ ƒÒ—sIõð —ŠN}(üñ@^‡ô¥ãµ'4½ºP0ühïGáE Š(ééGÖ€)9íŸÆ‚}.} "“ߥ=@ð¥íÒ€ý¨í×?…QÓµõÆhöëõ£°Å…یʪYˆÔš^üÓe&’T©¡\ƒùRóëH0  ¥'ŒÐà{ResÔgÚŠ;P~´`gÞŒûÑŸÆ€ =i ¯z\ÑøÐ:qKøSyôZ_óÍ/J3î)84c”¤‘ÚŽÜÐ=ÓŠ^;žh;q‚}i8õü)y£>†‡~ƒð£­/>”œúþT=hßÊŽ{šæ€üQÆ9ÅÉÅŽüÐý !?Ÿ­'|ñõ¥üMMŽ}h÷ɤ0Î(íÔP1G&˜áFsßš\{Òs@Ëþ°nëŠ)dûãéE sF@èM}(éÜ`/ãǽÑÉ 5ò P!Ü}iiqÉ¥ôï@M¹Uv×æÏ¥>0¡.Ð;`ÐಕØ0i°À°Ä±€0;fŽt)VÃJ¢“ܘʈB>ïºO;séWÁÿgš‡ìÿé&o5ÆF6ÓL"®Ô€*(³ç¹lg5c¯LT)qLò JWgȈåU‡£ÒÆ¡TáBŒö§2‡R3IloÜI'šwâG½½H§dÒdç·Ö€*üÆä|ªÊrwzUŒŽ˜ü©¦2e¸Œvò:Ó`ÆJvß/ïQÛ6ÊÒ鎵+¨dd'¨ÇØbò¢ f…°t!€•Ñ Hã¨F*ÐÇáPÏJ›C…È#îæ¦É?JÇbi²;,lPàp1Nç§4A<Ò!T0®O'ަʀOçÍS6rªL|y‡ŒŽ”¿ao—$`rF2OZ>¥h[àÿúé®vÆp >”±¡D \·¾)ŸgÅÏ›½±Œm©ÐC-Ó?¼’=’œŒôãó5cñëøÒØQÇJGÖ¢˜¸…Œ*Lƒ =êoÃõ¤úPQ–d˦ÞzQ\¦í€"¾Wv)OG“y’N9µ:3 ¾vÁÏ@;Õi¸ôe ¡Ò-î*F•ÖåN@û´ãÜUf³2‰wº•s‘ÇJB k¹¤h‚±c‚=ê|€2@ÇÖ€6¨ç£ž:¨$ü­ž´ „žè¶æ>VR?•ZÆ8þT cœRŠ@Ã<ž)3ߥ;—Ö›ÓŸÒ€ ëíU¢!ç—12”ld޾ô·Í,Èc”F£¨<Ôkg"K#ù ‰­5a¢ÙÎ8äúf¢ƒ~ñ“iéÍ6(YT«99ïL{2êŠe?#îæž¡l‘è=ÅBîLÂ-™ÝšoÙ“÷¸Àó:àÒK´1¤r²íàžø¤¬v€Osš^=GÒªiÌÊë;_án•%´3DÒ[s0{QeÜEŽ)3Üþ4wïŠ\¼bˆn¥h gXZL žiaUXò±”’ZKˆÌ‘2¦ç¥Wû¿mY|Åò–=¸ç­5a—ÊG·5 ³´s*ùnA8ÈŸf@#ílç8âŸKá7 t¨íbDV*¥wA©É8àŒýqQ[G2YÌxU9ô¥Ð ±íKÀí@ã×êhϾi2{Qϵ$qÀ¤öã4¿…ÿ&—œÐ=1øÑƒëøPb—§aG>˜üh?îæ€ >˜Å&ri@´QœÑœQþy 8£'h#éKϵ7óÅÓ©?ýj1ïGãúQG~3@>´r})i>¦€žäQùRvæŠ\ú3‘G4‡×ñ 9èEÿjlQí@EÏJLÓ&—§JLúÒñÛ4dþ4r{P~"—·j?Ò“‚€‘E~cµ'§z1žM('§4úš_Ê“ëúQ‚zþ” OÊ€'=hüsG4„c€¹ aÎzP¿éFô¥üèœߥ/h?Bhf“‚;â—“éAö(úÑ€{0Åj}iJOç@ãíÅúš3Š_Ò€ÏùÅ(tçñ£§ãGã@"Ž£­éÍzPô9üh QŽÔŸ…/åIž:ãÞ—ÔÑ@õçÖ—$ñÇçFFxü©yÇ@(ë@õ¥=±Iøó@„¹£§cHyÍ×¾i;ð?*N½…)÷ð A’|Q“êhÁêãIŽs@Åú΀xëIÆsG>¸úÐûÒöÿo©¥ÎEb”zRg‚ãAú Æy£Œöüi~¸£ô @N(üh…&{PúŠ\ñži0:ƒš?,Ð0ÝKzu¤é@Âö4§?_jNù£·R(éÕ±@ƒèM/jNÍ.áýîhÏÒŽÔg4pGZ9ö ¥çÖŒÐ=¨¥íF}±@ Ǧ(4céùÒŽ;@ 'ñK×­ZN3Œ“@À`óš_”wüè$t?• #Ð~t»†y¤õ¥£š(Ç|QÖŽhqš9õ͘ô?˜ 'ñúR \j0 úF~”œQþy `ÑøQ‘ÓÂt Èõ橤çփÀôýhϵ'áGN3@ Ï÷hëíIžÔtèhÚ”óIÏãGÌ}(z”dã(Çz1ÇÐøñô£‘éAÍ…Ÿ§çKÔqF@é@çÚý)y¦ñÒ úÐþ¢ŒíFH= Ø~Ts@ ö4væ€ý¨À¤?5-''¾ x<þ wãŠLú~†“Çð Lç¡ãéFãïAúàÐF}°i9¥?•C/ßô¢‰sæ{QHdãµ($ûjN\ŠR=²( Žÿ­¿# ýhç=)€¸úQø~´tÿ‰™üý¤áqùÐÜcœ~t˜ÇNž‚ŒéU¡viä *”ÏÊQøP,õ”qÏ&“ w¥êh¼üÑè '#Ðþ÷H ã©Œçû¿7>ÕIJ(Q «6~oP(He‘žøJ1íTg¸»RÞTÀ€øþubHó"…lô4ì&Èü(çØþ5Mî.ÖVQl»C˜·QV‘Ë 8žÃš,À):ð¨nLâò_Кj½É•CD›1Ëæ„‚ÅŽsÚ€3õ£§JLç¥ §áIǯ”¼ú vÁüiqíIŽ9¥ èqô c±õ¤ëÔŠã8ÍAm;Oç@½F3ž†‹>=Çå@éÀ¥ãHúRuç40Ol 0sÛó£óŒê„ ,} —ÒŒ ¦·M#£>Rp 4ëI.J0»Un;@ÇO΂ŬJ=sš‚áå ¿g »<†8ÍC×~qÀ ƒBW síúÒcœâ“¯ùT[9TˆÛÃdu¤X³Ž8Žj­¬’˜À¸@²x,3¬äc'{ÐÕ€>¦ŒT-3‰B‚¬x57áŠ,Ž0hàv¨f–h¤!óŽÇœÔF{¿#?f!óíÓó§`±l€i?ýTXwúR;H¶.X=iá·Û4¹üj(ZGOÞ¦Þ¡™îÕbHòOÈ}±NÚØ ~œPOÖª$÷<«AóñƒÇÖcq%ͲÉ*„cÕGJ9BÅœzÉ㯽6F)0ˆè:f› "dÛíš@Iþx}ÇÒŒôcP Ç|‘ô¥ÇùÍÙÍ&Üs@ ƒõ™(ÉëýhÉ$|Ø ñ„qÐQÈÎsøRŒ @¹è?^”£¯ZLñŸéKÉÞôc®i~†ŒqH}È4n<ð?:\I¥.'^KÛÞÀQa@{´?ýt˜£Ú€#µ#ú­.GN¦€ z\Ruõ£½Ñõ£ñ£§S@>”½úÔ”søPG½ Çn>”£ïKøÐŸÿU¥¤üè£ÞŠ=¨àv4§4;ŸÒŽJ9£ŸB?B@ç>€^´gý‘ùÒñíHxô£Îç@È£"“8óô£ð Ž }é9u‚€ŠCA#ØÐXP öÅô4qG JNxõ¥çÓò ýqô¤ê:Ÿ­ŽãŠ0?Ö€;ŸÎ—ô p=¿OÇó£¯z8#ùPù ?*Çz3ƒÒ€?ýT{ÒqéÖ€ƒG_Z3žÔd?:8õ?Çj9ö ò4~4dt¤'ßô >٣߭üézŽ ”½i¼Ñ“ëúP!xühÉôühϽ $ô9½hã½7-ßÞ€Çé@ãÞŠ? 9=¨ã½ ç4êo=è¸ö¤Ç<:^´œúñï@…Æ; úR`gÖ—ë@ÀaG=ÿCGò¢€ f“è?Zw4}MšLóÏéJ@õ4p:RsøRcÛ4¼zÎŒŸCŠ`ô£üô¤ÝìE/j;ôýi~¤ÒgëH8gñ¤ÿ*ZAžÿΗñ¦séFhú‘Gò ü &(Í=:@õ4u£õ¤ïÓŠ`¥/j9ÿõÑúPP(Á=¨ëß4~€:ú¨çëõ£'Óõ£'ÔŠ 9è(Ü{RdýhíȦäžø£8ëIýT¢€½(ÀïA>ÔŸ¤ñGz?i:Žü¨ph¤úœQøŸÊ€ Rãñ¦çž¼ý(üèHÏ#ƒê !üãA£8ö4Aç…ç £8õ½¨+IÀëKÏ¥ô Bp}@£ )A'4qÞ˜lãÚÄã±ü(Ë{~TgÛ4gýšMÞ£¹ÏCÇҀNJ7v8Ôdc4~¢—¾E&}(ϪÐûš=Æ?:Lö4dw8úPç“J?ãM LÒç=(¼R| oáM8ãŒúP”Þ=y£#?*2»Í/¶?*?ÏZN{ÒŒÐØþ´~›©Aâ§4½}i3ê1øÑš:RóIŸJ3ÏB  w¤Ç±8fœ ç üh##ãéJIö£p1@ÄdÒàŽ§4}M'~ô´P{QÛ€hßp¤ëÞŒûQ–?ýj?"hçüš^})0GLPÂŽ{ÎËò£žÔ ÑŽÜP3ßö¥Í'çøQÇ|ƒéGéøÑÏlþTc>Ÿˆ£  ~¹>Ÿ˜£šM¾´¿•ÚŒj0=Gâhàu”¹Ç¤ Ÿz9÷?Z^qÞ›ï¸ã½ó¥ã¹¤Ü=sG4€ŠO¾>”Q'ßJ(Àö£=é ûqNçó ÷ó£9ì?>”pz=ù¦!=?Uæ]Œ^5%ñÓ<~Ugq=¿:©p¯$ûV@¤§B3Škq¢Ê±uŒUxÑ–òCå àçšm´±¬†}ÌU /©´Þ7,9ð vÔcä¸d¹H¼¢7wgô¨¾Þw:yD•8ùr>)ÖŒ¹}®Íósž*Ë>Ôbxà’hÑt‹Ä¬TŒöÍ?mV³}ð†ó³ÐŽ?J±Iî&{øÕG"+’øvÝ€GaVÇOZ¯!q8ù)Ç­ pDøÈî?§j#ÌlOS!"®qéKÓ×ñ¥p!ÂǬw>SN·bCK3Aóì9Ǩ4Øy3““žNiôAn%h¢gTÞGaP‹© ±¨‡åaÉÏÝ«8Ç<ÕwnCyØ qŽ(@‹Yã<Õk«Áj”g…c9è:¬ŒÆè0…„$FÚXË®1´Õ™eu·2"’q§Šq€väGoz¬ò²ZÉ ¸A·63ŽièÆL×`ll÷ZŽ É&™‘­Œj1µËõü;R„¶00?{>”—¨Q 4ì†-åÓ[“=Jž•Z¤·MË… |Îç‘Í_^#øäÕ{0†2Šñ²äôúК°ø¯wÎјNNÓÉ~\U®ÜŠh µ(Çn*xÅU¼s–ÁXå€ùN*ÙÁò‚Árp8ëMn r^=*ší|Ç %Ž2I]8éAäŒÐ†RhÞæå +F"nÄ|Õ5Ô&XÿÖH¥áµ°MCh_Λ|Ë"ï8 G±«R9HÙÆsCCõ¨”ÆIÏ#4ZÄ1æ*¸ÝÙÈ5 ¼’=Žó6㻃ŸëV Ï•ÎOPsTô¸È%ŒCp²ªHÌsÀlÒ¬Iž‚»‡8ëQÝ2¢d¸^Ö¥˜“ÙÍ'°ŠÆ5Kˆ—÷ß/‘ƒW1ǵW”±¸@@ôjÆ=¿:ÀʰÉ»’5fÞ£MX|ymŒôíKõÇåL™ÂDX¶Öè3ëKqÚ•Ãí×Ô³0vã={RB^(Ù¦e žÉ¢ØLÒJd ¦ì¦jo{Œš41Æ©¸¶;±É5i ¬ƒœ‚>馢0¼’O9™[øIÈc¥ Æä ñÇÕ]=ÂHB­žw6ZuäÒ"ªÁ´ÈOÝ5+?•ùÙF:žÔlƒ¡ÉV•">b‚~òœsVcMˆ,À§©ª¶âgžF”+ ?»=x§Œµæ ‹¸/ÜïŠ~@YÆ=iFOcŠAéÍ&Þ™cRH¼ÿwõ£8ô}) óèhsž8üèÈ=çIó‘Ë ¥ç¡Å}iqŽM÷ñ ×4pýtz® £ê(ÏÒàÒuéü¨Ûé­»~t`žôs“A §'Š\gž´ƒÜQ@ õëéGnŸŸÿU!÷•.~”¿•'ÓšLûb€¢Â“Ÿz9÷ühsÎ(=)y4¼vÿëÐýtwà ÑŒž”`t ž”{gó4cëKÉžù4~4¹úÑ@ Û¥x£ð¥ Ûõüéõþtê(9¥!²ŠSøþsé@ Ú”z9ô{Póì>”nÿõQÓµ'ן€ÜQžÜgó¥Çz2=h3ÛŠ_­Ð©úÑôëG4}hä{ÑGùÆ(íŒPǵÀãcÚŽ}¨ÉôÍŒÑGá@|à}hæŒ{Rs@áFFM)éÉãÞŒ{šN÷¥>ô˜4cÜÐÐu£ÇÖŒcÿÕKj?•!ãÒ—éúŽ”í@ ×°¤8ÿ"Š1@ ã×õ¥Æ{š\z6û hüRãüŠNŸ…ãʇg°ŽÔg·ó AÈê?*9êOëF´žvš\ÇëFìwö¤=zRóŽÔg'½ûþtu£ëŠ3Û"ŒžôQþzP0ëÞ“ð4¸‚Ž¿Z&~”sÒ—4cŠ!ÈíúÐ}ñKIŸLPø ûRõýjCƒGó È£#µ!ZZ3ÇZLóŒþ´¹çÐÑÎ#ô Á£¡äQÏn)Ï4€3ô¤,FsŒzæŒLÑ€: S0ãš^}©2{ŸÈP@n´€_óš>¦€¤àúSÃvàRp4½¸'Ô†/^ß­ >€RÈRâ˜9ç{ÑÏùséù8 “ïô¤ÉÍ/9éøÐõ┊o=Øý)h~´sŽ”sëIõ<úÐ1ßËëI’=1õ¤Ï=þ¦—'Ûò <{POµ&PMsÔŸÂ úþ4sG#ߥê?LBè(vÁ£ñçÞçØÐ1xèy´˜\q“FÜ’y¥Ç·ã@ƒíïAóG>â—…&)Ö—Ñ“êOµ ãÿ­G¹íü©q@ $QÏáNäö¥äP1;cƒõ¤úN4ƒÖy#ƒïKõŽÿw¹ôÅ&G¯>”™çîóNïÉ\Rý4{QÛ§4£¾T N€¨éš\ñéøÑ×®(zP0çÞŽž§ñ£ðü¨=:P ã¥w? Î;¥/nX怞Խ{QÓ £ùQžxçœÑÏçF 8´d÷§8¤Ï ¥Ú€ M¾˜¥Ç9Ç4´˜Å=0(ÆJ0¨9Ç_Z¥/Ósï@ Èì(íž”¤{P:ô ëFsÓô4¥''‚£¼ú©£°ÍZ>\ô4pô£?OéKõ¤ö€ŽÔcc©2ïq@ã¡ñ£æëL–xâ(ó!€3“RzqŠNaG©â—¯µãÒ‰×øÇµ(÷Åqýh BqëKž‚Œã£9éš9¢—:q@'à?:_óÅvé@O`•&~˜¥â€ 9ô¥Å!Ö€v{Q’{Rÿžh ûb‰Ð{ûÑŸò)p1Aǽ'^(ǾԼv£'Ž(>øúQDßx}(¤±ßŠM úÒƒžqK“ïøPr8QƒŒäâ”’8çó¤ÉÏ¥0'§_Æ oõÜFäãïTýGª²*}¬øè:Ó@‡L%FÑ*òNöa»ž”ØK²Uç€ ,ê d;_PqMµ! Ê¹uÏÞ=éô/ä€j·ÏÆsžj±Û‚*«’ä-”n3œDw,åLUGs…£¶ßÇUÆjÞxªÑ,Qܲ¬¼‚pphi¹”±F¶9`HçŒR/‘öi|¸?‰I#5pªI=*½ÄÉk&dØ£‰íÍðn)’›<¼S.Ð2¡1yŸ7M¹§ÀTÇò° w¨o|°±ïvP_ª6)ý êZRvv_j†Üî¼aHÁ)ÀŒåñª¶EH »mû¤äGp.…#¡¥çÖ›ÇçF8"ñª÷G?vd%€Æqzœã¹úÕk¤FØXÔÏ#9¦·YäsŸÊŒ°õ"€>•IL?mù3î9º ¸ulXM(0´@¹ÛŸâ÷«(0¸u 0rœÕ`ÞàwfrJƒÐf§šUw »€hhd6›>ƾTH‰ýÑÈ©í×`¼ô¦C-B,¤®2­2ÅâCÀdò*ŸPp„º6̜Մ`ÂÇJ§rc¸•m‰t$’ªÚ.Ô€1šO`èWœ´ÂE¹f ÷û ´¯_Z­6ÁwY#8æ­}qIì€3€yª°Î—Ñ’Q€¾E,Šd”ßk/\Š±Û¯åFÀV¾…å¶Ù«r2­SĬ# b›:¼‘°Þõ^K7r¡d*!€èh@IÅÌŸ#)$r{Õƒ¥g _4ˆÍß-ÇqÒ´x(hZvŠUü¼»8ïEìjö®¯”à4°‘ö™1#0ê uÔ/5»Gùlz7¥: <°þÎ:TÛIò#mûçb’KYÝÕE„~Ni‰óí¼ÔÆxÇÒ«Nã40}hÀÿ"“¯ûšpÿz ‘6ƒßò£ô¥<ƒ‘ìhíÅ=è}zÑøšôý(íÔŸÆŽ½…q@{…Å··ÒŒ u£·Z0ßþª õ­š>‡š2½)õⓟò(ÿ<ÐãÜf“t£§ñ~cÜš:}iyÿõRsì~´cw^” uÀ¤÷âŒhrZ2=è4s@åGÔQÒ“?•.©sIü¨éÔÐà§¥×8¤öâ—§oÆ€ùëF=ÏÓ4QÓé@z>†ƒÏ\QÏ1@?AGO­\Ñ@ ÒŽi}isÏQ@ KùÒw ýq@áKÒ“=³ŸÂŽž´=2iqíI“ÞŽùæ€ dQÒŽ84¸ ¥ºfŒdÒÎr~™ ŸÿU.)3ìhç¿ò z9éKŠ1@ аü¨ qÍcëùÒpI¿!£Ï4c4¸ô™ÁëÅ™£>ŸÊƒÏZ_j1è÷¤ g¸:ÆŒsÞ—…'ãŸÆ€ÔÒâ ö£~4™ø³F)søÐwäóíF9êGã@âŒ}3ô §CG>´OÒŒûŸ¥¸¥íë@ãÚç@ IŽsŽ~´ç¥'SÈ b‘Ÿþ±£iÿ=èïÐRmö ¦)ÙÀëMÆyé@æ žø4ÏÝ4ŸˆÍ{޵­ãñ¥ÁõcÒ€§oÊŒcµ/ëF=&Ò”hüi¤‚9íKøÓGÔÓ¹Å0†Ï£ŸÎŒ³GÓ"€ lÒzŠ>¸&“Œó×ÚÿõèÁæÇó4qÛ…-'àM.GJLöê~”»{Q·†i½{~}(§8ô÷£·8&“¸ühäté@ š^ý '='>Ÿ•(<÷4cÚêhã¯Z`/ò£öýi? })p:ÐÃñ£ð`{RãÞ€ðúÒóíIíGë@ÅúÒtôÜÐ@4`Rƒ‘õ ŒÑš^=ZoN3úÒÿž´d@☃çŒP@êJ1š^øçë@ ôc¾ ¯ÍÏjC?‡ãMÀëKzZM£ß4˜$sÍ(úbÃõ¦cé~´¸=¸£´˜>‡ôbŒÆ—Ïé@„Ú?8M.sêhϦ0z(ܹê(àŸº(0{œQëKG^hôÅš>€Rã¿õ b`wëF&—˜¢€cŸJ1G¿1ø1Gví@ ÁïHì?3Níèi3ï@NÃó£§µ·4§Ž˜ çÖŒã¾iN{Fx÷ö4„ûÒzZ^3éG¯?…ŽÜÒ㎟­&=qIÓ'­)éØQÛ­ð¥ïÓñ éÞ—9è*@éKøq@xGÒ€ è)}¹ü(÷'úÒ`úÒñë@­.?8ö¤#ÜP1~ƒ™”sŽHÅ ™ÇÖ—§<þcÓ|Þô½;ÒÑþx aïš_®(ÏÖŽs@ƒÿZ;w¤ u4~¿Z/^)1éKøQÅ ÜÒ~t`RóØÐŒu>ôž)hüM!ùüèÁô½¹æ“"€ c¢Š9ïÅ <õ?J_¥/ÔÒ;ÑÞ“é@ ‘ïGnhéÞ’‹×ÖŒZ2}Í'^Ô¸ô&Ò“sGldþ€ZLàrÔsïKÍC'ßJ(“ï¥áB)H8ê)¼“K¸pò BŽ(ëÒ“>Øühàõ¦ô¨JJe?0ÛÆ8©2ã?…;'çÔ N­F±°œ9Áþt©•'O\P²‰—fx;¾µŠé’Aæ/ÞÊñW>„céE;…ÆÆ¬#PÇ,$Sù¢‚~´„'9ïP\ )‰`y'аqH@=hC*¯ÛÄ»•·o ŒsI WÒ@΢峇 ÏoZ¶@À£íNárƒG¨âh÷«üpG~Ô¦;Âr²"§ ]*¹ô¥ÇûD~s1ܯ4S0]²éßÖ£T¿ÜwMãåíW@†´&+ ¸óÜÈÁ¢ `ƒM™%4 Éäºö«=óF>´®F[̱”¹…rᕼð·p¸©ºs·d_Ê€ÿëÒН¿;T Ô¸=é KÇ\Ð0¬¢I ›vòíô©ò?½H}P(<ŽJÆí·mòqÇËÎj|gš0΀ }:\~?&>€RíÀüh`ÿvŽ3Å&ô—‚}èH3ŸZSøIz怩rhäv çüŠ)> Q@ ÏN1HqÜQÛÒ‘Ü~4¤î(ü¨ ÑÇ|gÒ€GcÍ/?äS 1žvóêhzz 3ޤJ1ž¢¯åî(z÷/¿›ÏÒ—9 æ€E'áAõ\ýhNG~=(ê8¤ «Ñ@úQÆ}ý¨G®Z8uëGNÔ˜ÏÓÚ—ÇJ2zâœr8 ?'ÐÐ?1ž¼P>´túÑéIÀ ïÖŠ9=©1Ç4¹ÈõúÑœôæ“>ÂŽ=¿:3Ž)rZ?9Ïa@-&i2¿¾(híIÏ®(Ï=?Pô£“ëIœw ò8 ÷Åð9#ñޏöîùâ’“ úcÞÞ˜&€ŸCAÏs›“ŽŸ/ Pàz~T`zÒg=¿*\æ€ëIëÅf€}:0}htÍ>£`u¥éA>½(ÎG( £¨ ¥÷Íih8#½§ò¥¢‡n2);bŽ{Rôë@€}):sø \f’‡CÚ“ ô£ç½/ZúŸÊŽ}J ö Û4`u4sŽqIŸVô È”wæ“ñ c¸Þ“èqíK׎)8õý(sÍ}?ƒÐþtœzÐ0àv4¼Rgò¥ “<Òþ´œöÅ9¤ÍcÒ€Òpz~"Ä8ô"‹ëøÐ}³IŠÓÚ€ëKøÓsþµ.xäÒ÷çò¤íéKŸCùÒOÿ^˜ ÏlcÔPyçò¤žsŠÿ9¤ãßò£¿_ÎÇ£öý)€­qA´@=éh¥çÛò ÉôÍ#“F1ØbŒs@ÀsÐÒ‘Û“IŒñ×ëKÀàþ”îsF}åHG×”£Ò‹ŒÑïIGJ\zÑIžØý(ï@âihüèü QFhï@AíAúQGJJZ1œ‘Iøs@J?JZL;Ð ÁÈ£ð£vÉ¥ü1@Äàö c§£­… ¤;G Í(ï@÷†}(ëØþT¸ã¥&;f€ñúRàõ-‘ô£‘ƤÀF hç¥y¥Ø?&>”¸Î(ã<Ò~tcž€ÐçÚŒâŒÔãÚ“þº^´~4˜Qÿ×¥ãÿ­@çGJ? LŸZZÇ\QƒÞšqÐg?J;׊8íIŽØ&—ð A‘ÿÖ î(Ǧ(Çq@©{R~`b€¡¥ç½'çH  bŒŽô™õýihÏÖŒR~4phFG^”dûSI=‡4¹?äPæ“<Ñœô¥üèëÖŽM})8¨£ëGZ9ïŒ}(£ê Ïj=ñ@}xüi8=izö4Š}èïÓó¤ÈÖ‹ùÒdõÇáKŒç®@ 8 “ß4uô£¥ÜÑÁéGƒŒr?3î(ÏçMù‡i¥?CHåáÀ祒}ñô¢€Ǧ)hüèã¸4¸ÀàQŸóе/?Zb8¨éD¦3»röÚj~GJ6÷˜ e¶/ÙÌÀîQžTksåù@;6öÎd^@=†JÊ낪¼äb§ `Ê«A‹ÇjF8 qÐf’I$.Ýz«<ì^9"*cçùºRJâHž ÄËqíR3íç>ÀS<è¸!מ=iü·øÒ`T·½2>ÆP“Ê‚GZ·œÿªÒ]F« ÊVi»ïü©xè¦ü¤¿J\׈¤ûUVÔ"Ie‰ƒƒ Àë×ü*wm¨~p§Ó5"LrŒ{`P¬­îÌBEÈSÓ5'ГíTåyb¹ÜÛ{H5gz„ÞÛŒÓ~@6îà[[¼»w À§Ç"˸èÃ95Z‹¼…åI#,~M§úš´0¸vÀ¡è1ßéA´ÿúÔ¸ZD‘É2Â7Žz¬u'‘ƒRAÈ©.ˤJWiùÆrqRªG"gj2ž¤Í5k@·±³F1!÷NÊSt¿¼Ê:8$Šu¸æA³øTŽ”ÈH72 cЮÒža°êpÊwž='Ú¦µ¹1–Ù·sRð§¦)sùPÚè…tzRä{géGâhϦ=êD!uD.zI¨ì,P)$¿N8¢mßh‹m^w u©vGÇÊ:qON£$ú lޱ!f P@ͼ«:ägQšíj,1ÞãœÑaØš9D‹‘Ó8§ñïPZ´»˽Æj±Éÿ*âbdzŠ=3E/=ÏçH ÓßAlá%|7°& Í‘PÂF*I¶ñÅ]òãÎvË5‹£F‹r PTuªVo`¸šH‘‹2uÀ"¬dÄÔ0FÈ€º&ó÷ŠŒQ4Š‘Ÿœ! …Ï­'kè Š+ä–þ[_*E(3¸Ž [ÍAnŽ©—`séSŠ˜¹È¤æŽ; >¿¥!dÔmá¤f œg9£ûJÔ—¹_QÖ§1ÄÃk*zäU[˜üÉ#hc†@¯µóŽCT¹YZmî#¹%CÁíŠIîRPU¹ç;I§"ùq„@ˆà*ñTŸí«lApd'~´hØ!à ŠQL]Áqù±Î(Ç^¿…H‡gÞ“ƒI‘ê*^¾”2½Γ$uÇåJ>´søÐ¥ÿ=(Žãsÿê£ñü(ã± ÐwäŸÊƒõ4¼‘@Çù”´RõÎ=Å.p;þTnÿ8£#¨Àúџ΀?\Ò=úRg=qì ÷Ïá@ {~4i3ž•úþTɧH#ß!8Ï¥Bú²Ìœ;mß­K>íƒj†óžÔc#æ~@<ÓVw©-É…AÎ2:ÕÇÒ ™?tì˜WÆb–Ü‚‡çF ó·µ6Î*9¥X•r~ñÀÍhˆ>hzóÒ«E;=ÃLb&ÁƒŸz‹qÈ$@ÀðzSóïQÇ2J¹Bt§gŽ úb“³J°¦öÉÃ4‹´dûQþzQ(éÒŽ{šMǵ/=úzЂ>ž”‡=úPXÄÑ´}(Ƕ)yõ¤à\ŸzLÁÎ}(Pz>¹4duÍ'=ÉÅ.>´ ûFE'åG§J8?þª?š\ŽôgÒŽÔ„}(I4™>”vööcŠ?J^¿*LGü€z1ŽôŸJ\Ô~tfœôäÒÿ: ÍOΟOΓéúŠÔÐçíI»Ž”dúqô äõ¥¤Ï·ëFx ŽØ£éIùÂŒzãò ÑŸÿU.)0(8Îy£ðÈ ñÞŽägñ ü)pi1ë@Z9£ð¥íßó£4n)9Ï RõÿëQÞ€>Ôdã­Z^È až94ŸúÑÉÿõP ü(úžh wqéùP0Å'^qô¥Ïµ}E$d R÷ÇÒ9Çå@qÔŒý)0sŸÒ—ž ãð¥ëHb`õ£šQŸSIƒÒ˜…úŠ? sG>¼Òž´~Tsßf˜~”vëGÔPqH¯4™úŠ\ûÒgØÓÒv–m¹ÏãDO# gsÚ”ØÅ/é¤úàP:vüé:vâÖ˜Åâ§ó¤'Ûô  Ð’ÃÒ“ÿ¥0ÜΗæ g¿Z0~”€CêE£¯­;¤?Š`'4¿•} (£Ÿç@ Ç ¥¥£>”€OÖŽ)NqÖŽ}©€ƒ¢Žæ A) 88568âª-¼r)-€1èqŸÊ„­s !c"à{ÓüèÆÑ¼eú{Ô_c„ç)Ôc­8Aã ÈéO@Б¤TûÇôd8õ5êÐT“ƒÒ›öHØ–`ÛŽ3Ï•O¸ »“ÐRàç¾*…w vîtÓá”Ë}¤g±¤œúñMÞƒ–eç§5Ä®Ø÷†l7=F`Š4Ü" G8Ú(ÐÇcA`½HZb6ô? ŠéP¦æŒ¾;PŠBÛzœSRBË»}‰¤“FáÜp9 ,<Œ‚1KךŽ˜‡ÊÚ¤ÀëŽh`Z?OëKŸöhsFh£ñþ´ýýiyõü¨£ñ Î=hÏ¡ý)phÇÒ€$ûуKƒžÔ JNhçÒ—#ÚÒ€šLzSˆÈè)2{ ÷£­Ñ¥&yÆ3G~”¹Çp?=úPŸCÍ'ÔRàG¶h?•=3G4¼ÐÛ§u¢Š1Ž‚|~4{QïÅ{Æ“žÀRçëF3ô ê?Z:ô¥ö¤?å@ ŸÆŒš^:3ß4¹æŒŠQþE…&@#ÔþT´qŽE˜éÉüirµ˜÷4£¿ž´™ÁèO¾isøQGá@ ‘ëFx£4Ÿç¥·Z: OÃô£ð AÀÿëÑÉíÅgµö#Þ€ ÿU!Æyü©hü1@ žx‚isž„Qøf€qG÷¥àŠCí@à sšLc¾)qžôŸLš†_¼>”RÊ~qÆ8¢ã4¸šs@~´‡ó£Ÿ\Rã=©ˆn}F>”|¼qÏjw?äÓNG§ã@JÀ\G˜•³ü^•?Ì9Ú?:­(ˆ]Æ]Hr89ëV@öÀ¦öB¬ÞcNT02=iâÎÙC€ÝqPNÑCvÓÈŽX&r3ƒR}¾<¦!QƒŠvmh1²[¥¨V‚Ø;d ç§çWFH\©4–ó®×vAéšµÆ8ú‰ÈÚ#*ˆG9cÖ§…T˜À·†$;g$f­dtŸÂ‡°ÈîáIoÖ”ŽÔ‡=Í!\/îŽ1ôëNŒ|ƒ=qL¸ [±bÀ¥{S¡ÃD¥°Ç§Ð}¸+äàýxÉ%Hí‹3F¼qš.ö-³y„…öëQÌÐýdƒÜP†‰-› ; XéÔUìU£”ù²—?»SÛ¸‰D‘¶»‰Î}Í6“Øhr)3Ú“¯b(Èö©$d¤À 0<ÓÂ…(À¥,#ŸaUï bÚC+2GŽH4 l`ËpûàÛ°å_Ö™"º<¼o&{ž¦¦·t’1HJãŠrÄ¡Ù÷[ßMèÆUYoEâ+B«RY³Þ®+«®åù½Å 2¤dš†ÏËòØF$PñóM» Ü°FqFê(ú’ {z’JÓ:­Ìj ,[?>Ëõ« ÊÙÁÎ=(8e#wQÚ«<+,€¯R7}iè1Ñ’Ò±h¶ãŒÔΡ”‚…‡¥Wã–fdvã ©\sššdI"tf c¤æ†62Ü|ˆÂüÕ6?†ßnNRÕ>=({‰†qŽ úš\ö4€ÍÅzsõ¤Hõý+4»ÈæámÉ’2Êž¿¥“ýÚBO÷±ô¦‚â!܊θlr:â ÃHªm¼ÅÏÞ8À¤‰P\Hf,ÇOJ[M›¥)ærÜîn)ùŒtÞb"}à ©þ£š©x°emÝxÃb­¨Gn8¥Ð:׊1î¿;ÒŽüR$‚âao;ýÑ×NÚâ?=DV³¨å¤eÀic9¨æPb`ÇŽ ÓLiŽÈa‘ÈõÍAtfý˜tïEš¤vʈå±ß4ÛÔŒ ™Ñا@­Š6cêYŒ| ã3Nú€i‘•xÕ‡qÐÓ€Àëǵ&&;ð ö8ȤÏ<~F“'?wñÍÉì1IŸ§ãKÎ8æŽ} ÝþÃíKœ÷Åö£>ôhëëGCÐfŒ çcØP~”gÐQœu8  äö£¯ÿ^ƒî1ô óìi!õ¥ôè~”¿‡ë@ Ç —㥜ÑõÅé>lw¥ÇåIÓ4 ÖÏ+çVaè½jE8@@Ú=ê+¥i"Ú$ŒçqíP=´Œ7ý¤€§v@Ϧ¬2ÔÄùM´nlgnzÔVêÉ“Œ“9⢴U•ÅÆæ/½x"­¶1'ÞšbŸÙ"»‰…Ä\ºá°zŠS¥Ù‘0çÊÆÜž˜¦[ÜÁo!‘œ0,i­Hu+e‘‘Ÿ¡#¾iµ.€îð%œ†(b|1,NîŸ[veLªäýj‰’ÙõXJ|ÒÐE^ÇNæ“]ÄʆT{µVæ#98¢]GÉ6³¸Ü*Ƥ‘GÚÔ™q÷{UëGD1AÈ{QŒú :RþU$‡CŒƒôæýE(ãŒ@åùÑœð úQô Òóë@sÛKéÏéIõÒýhü(RnßÖŽz_ÀbÀÒ~?…ãâ€}! Þ—ŒQŸ  qÇJ@GN§ëKøÑÍ….~˜£Û4~TcÐQA£ŸQ@{`ÑÐóGã@ç½ãŠ8úÑÓÒŽ £®yçëIŸ΃@~¢—šLŽç¸÷ ŸÊ“ñ “Æ?:?(Æ{Rãð¤ü~4dtÎiÝ©¹'¥Ò‡ïøRƒìߟL{Š:zP Ï”tö ŒÒ}H üsGJ:Ðóõ õ£ÒŽœdý)2@俀 ãÒŒ¨áG½CŠ^))>¹ö ö ãÖžøÇµéj>‡õ úQ‘ïGÔŠ3Î3@ÔQïü¨dvÁ 8ëKùÒg>ÔzŒÐò}i:ûÒqǯ¥/ã@Ã?(Ï®~”™_Æ“7!H äqÏÖŽÜõ£$v¥üs@„ü±GåEhpi9÷Þ^¾ô¾Äþ4î}3IÈ£#×4™Íó¤ÝëÇÖ—¿j(›½èϵÍ탊@/^ÔŸÄS͸£ž†˜ ì(ÿ†ŒŽôqí@­zÒqéKÛ’(>¸£>Çêhú`ÑÁÿëÒ¿AIŒ?ZQŒqÒÚ˜…úA£jS@Æç׊QìEAJQùQø?JNŸýz_ÂéÇå@0=)sõ£ÚŽÿ:3íE!8è? \{U{mŸ7–Iæ§?OΪ•¸òÊÇ “’qÀö¦€µÏz^*°IðTº°ÀÃg½L‚ Ì ö¤e AíŠzœ¨<ôïL— dvìiŸ¾-òýÓÜÿJ™ŽŸOjФRÇwbzSGšd]¬ƒ† ÍNQÀÀúSØp1eîÏ#wJœôëP§Èî\ŒÇjº ¹CÀÏ4€ŽB71ßSnˆ f?ÂiÌ œr˜Ç´Oœ ¸üN)ŒlXÊ–c“éOš0ê2ì0AùN)³‰6«D>`yÏ¥:FrŸ» ÜC`t’<¡lŽj_ΣŒåÝJ?Þ¤ÄÅÜ?º~´QFjbÆŽ{P1zRqÔÒÓ$Rè(çÒΓ“íKÓ° úKøQÍ&29 Bœ}iN„{PÅ;f‡G4véGà)hŸ§áGO¥.)9é\Пj9÷£ž8ýhç¸\ÐŒö¤ÀF=±øÒô ëG} -% wïAÏá@ Š@(ý("€~4Þxçó§sí@÷Š(é@áF~´rh ü /é3Ú€ (Çz3þM/?J9¤?J9î´ ûš>´» 2{ãð ÎhÏlsô¤6æ–€´óÍ& Å#Ú€ŸJ(¤éÆh÷ ýÜRñþE'?A@ƒÒSô§uî '8ëŠN¼óKŸJ zÐu=(þtž)p=¨ƒñ4uæ‚=ZŒú†o¼¿J)fûÃéE >¿''µ/0 žØÍ’?*1š1ÿ]ø÷¤àóƒõ¥úGNß•V‘ÝÆÊë€sV1‘ÔþU^M«t­ä±m¿}TUœû~´ÞÃèS™w]®dûŸY(­Œ $2:TW1Œy‰ùAœf£ûd›$v·‘s÷†•=ÐÉÝ€¬£“Њ“qœU#,Sù%­ÜñÀëÏéV.%1F !~zc4š°¬#™>Иd+èG?…L=úûÖk^“]W2@½Xµº’à.ûw9û⛋°ì[ýhâÓñ£§\~5$Ü™|†òv´˜à0È©"å/™·v9ÛJT2OÒ¨…ŠÆf(…ŒÇ“ŸJhe›¥gˆª_¨â¡ºó²åXFi O:àÎÞj°\rp¦¬K w ¶EÜ:ç8£aì=AÚ9ÜqÍWTatÌ'Ÿ\{Ó^óËŽBñ•çœpÖ–Þ(¤ÛrÎÿ7'¡§æž2î´q¸®rjµÚÅû¹$BÆ2HÀ'µAfmÍì¯N$`7n< I Æj½Á‘Ùc&F!ÇZ³ž:fª]mYlHX mCŠà·,¨!UpéJs†{ÒŒ€8ÈúÕyBþbBí¸ó·ü(v©Ã`ö8¨m•ÕöC“Õ*'¼!˜C+sŒméV-áÇ…f!Ž~n¢¬‡°ö‘W›žÙ4 ïälz­8Ž)D¬Žäáp™õ¦Ø€‹´˜žâ•´ 8ïMpæ3åãbiOáP2}¨šDÚ„‘Ÿ­!·lËìÜ»ÐÔŒNÓ´Þô¡v €ÅT’è›Vuˆ’~Ÿ=ǹbÁNâ½xÛRÔU/5m¾EWwlœZµ ´‘dhÛ¸4Ú{ƒC·ÐŽ:ñJ#=qTn(¥ £mJGµXµdhh|…ºšVÒám ¸-€{Qœw?…R¹‡Ë¸BI8R£¡#Þ •Sqù”¶1–ü¨µö A'Ÿ#0ÂÁ¨ ŒŽ€ù‡<Šu¨/$¯–å¸ 1Š·‚jw°\ËÛp·oæò¶€ˆäûµvÔH°(Ãä÷ÍG{´yY†Iþ6Ÿ_j´¬xã†ô è#:Æ2XcëO ž+1áï&/ £nTjí»‡X!Eç4­ X”yÈ?JdÛü—òÀ,Õ>,®A.ì'nê}¨7ñH’†V ¬Ta³š|½‚Å‹Q"Àªø€1It²˜òŒ£›‘M\ÛZ¦ÀÏ’>õE4<ɆD]»³)îéys´dsß)Ã>ÕUn%T[3 íÜN8õ«<ïRՄǯ4}óIøâŽOzBõ¤ã©£§½>ÿ€ >¤Òä㥠lއñ£#Ú€µ&9Ço­ûŒ{Š1ùPÒŽÔ½¸çëF|Æ€ž:9ê /8æÆ€t£‚;ÐWßõ£ñާ𠍥ú‘HG¡  }>´c¸cñ£ó“@o”ÉnWúf¬(@ÛÆ:T7aL ¶ìtÔê22>´ú¡\)†s„ÙÜç‡Þõ£ž”„-ŠN3Ðçé@ ÒöéMã¸æ—ßñ ¥/~i3Æ?­8 éíH3éKô„{PøP¨¥£€Z\^i9ôý(ôý£>ãó£ç4~"€õ£¨ëGÒ€ “G¶(-ŽÔ~ 4ž¢ŽLÑÆ€åFO¡c˜öÍ/ùéGµ&8ãŸÆŒ}…éG>ÆŽsÓtê1Iϵ.:~fŽ}ÿ*8õ£¿OΓžÔa‡µ/$ú ^i2zQž3@ Œö£ô¤äÑÏs¥;ŠLcŸÐÑ’úôcð4 :ñŠNqÏó§j? Ob?*NE;§z(ÓƒIŽø§àú~´„ óÖ€Àç“øÑôâj9ëšoZ]¤wâŠAÅ(éÒ¯Z=ûÑÈí@Ç­¯\Š=:QþzÐ×ëA£¯R ŽÂ€zÐ>´r?:9Åt¤çÒ”@ÎhëëG>¿­…&{Òò:`}hç¶(Å''¡…)÷£ŽÄRw8 >œ}iyÆKgð£ëIß§4 ^1ëô£äQ‚{уž€P!1õ¥Œ“@œÒÿwó9 ïK|S{zQ‘ê?:\Qô€Aíš3íúÐ1*OÄ L0qÅ.(çÒgÔRzãRy£?C@âËñ4 v9ÿëÒ`Žçð£¿_—‡cŽsKǦiN¹¥ü(éGéG>Ôtô Š3ÍsKøÓyö ÐýM¤•.OzLöÍ¢Œÿ‘@óªöÃ!‹)VÏ~j|ý*(rwîôÅ4Ø÷£ñ£ð–M¼çð§¨;É#é’à.K1ÎiÊ2 äŽÔ¯‘8X×!ÎXñÅXã=i’Pí ÄŽ”‘pŠŒáœO­ 8¥ÉŒ’­×vqøSä´ŽYÛ‚ÅHŸxŒ†çÓ¥Hè?•;°¹Ubò¶®çvQŒ‘Ö–è  …ÝÈ©XMŸ0»K&x!öš.1änB@5QZ±£/ó;ÕÀN3ý*97åJŒó“I-ÑR?—qÉÉÝÖ¥´¿'½{þt½{QŸ­!ã¿éFìq@NzRóþ½%b(Ç¡£õ£ŸÂ Hp{~”¸Ç|Ÿz9éÆ(=ésíù0sÁüÅ&|~¦’–ŒPcÞ¦)qëIŠ3žôcÞ—Š(3F3Ú‚=¨Áì(Éǵ&G§éNçÛs@ /N””~?¥/_Z(ëEwÅzRt=hÇÿ®€ ç§ò£ŸAG>£ð¼Ðë@éG>´¼ö çŸð£š3ìiyúPŒâñÚŽ=Z?þ4uíŠ^”RdŽÔ¿çŠ;RsŽi Lzš1ޤbŠ?=¨£èhçÚ€ QƒGCÞŽ3Ûð b|ØëG8éùÑÛ¿àhçÐÐ úÎŒÿú©=ÆE)éÈ‘J~qÆ8¢’o¼>”RLþ'ÚŒŸJLžÿ…v~ó}(ô`Ï^Ô¼ N12:~´1ù8õ£Ž:¡ ó4¸=¸ýhæ“hö4F(Ç·¼qúQ×¶(0:àRãž”¸oîþ4ܽ3@9Ǹ£ñ£Ÿ^=Í÷Îhö8?Ǧ=©0=(O>ÔÞÿu~¦”bŒúPŽ1š0GÏÖŽ½±@ ž?F>èÇ¿4`g§¸#½ަ‰ïƒøb€£ÐgØR‚)sØÖWó .zŒþ4¸ãŒR~(ŽqK’zt¤ÁIüéG>ßS@„úš_Ãñ¥ÿ9ÅžÙZi®J\qè)O¸"“'ÓŠ\f“¿J:ö¹>€èi äsNÈúŸAGÊ{cë@ ë@ §dvæŽÝ1@ uÛÏ®)Ý¿úÔQ@Täd{Óvs}{Óût£ŠNE¼zŽhàu n3KÀêqøRöÈP>oî~´Lw¤õãÚÏ¥û i^zgëIŽ{}1Oäqœý)0}(1Çj1“Î=©F»úÑõ íä)ÃëúQÇoåJµ'©Ç¥.rzÒcØP’=1G8ç¥.=i8”~$ÒóØ 3ôúbŒúÿ:9ê@£ŸL3ÇoÎŒäñ@ÍÜäûR}ÖŒàö)ü¿N)qš0Ô}zÐÓ¾(çEÇZ3ÇAŠ:÷ BhäôQ‚?ýtu4{ÿZ>«G¸úÐYÆìE;·4tëA9ïí@pzæ“¥/ùæ”}7ê(ÇNìqFyé@ …)éGºÒóê 7 œàf—ŽÝixô£·ÿ^€^}hÁÇ\ýiÜÿú³ŠJ1Fih? 0zãò¥ç'^2hä”g×…N~´¿¥'=±ùRŒ@眊? ^{Q@x¤àõcùÓ¿Ï`zPLýip sí@ùéIÉæ‘þM&hÇùÍŠ8 éAæ”ò:ãéGÐçÞ€ ñF9èiy=ÿZùÅ7Ü{RœÒàŽ™£šCŸ\¦hÁîIú SùRsë@=ºûÑÏ|RóëKÊ€ëIǽ:“#µñÒŽj;tü¨çßó ­ ”`cŠ'½¹4{Râ€OJB£Ò—÷£ŠCqýiAÓ·9ïê(ϧ4~ELSsè)y böâçIKŸOå@ I·ÓùÑŸjç óõ¦ŠZ?*8´}:RÒgŠ1íGCÒŽÔcÿ×@O¦iŠ¡8P=)ù=…˜úP!3Š:ö¿ç4~€$k,e|§­9@Px` Z1ž” :‚ 5cHÉØ _Æ—>´ÕP’¹Ëu9¥+íùRçüŠAŠ3ÉC'˜FN1K$I*€ã ñOÈïÅ&W±4 0:â‚ šŒŠO½ Q©8õ&Å'ùÆ)xíL½i9¥ü(ŸOÖøRÒuôÍüGµ£Šùæ€ûÑKÐqG¾H ?ô—ùÐväþTd_Ê­¼Pž;Ñ‘î)}è ÈÍ÷¿•4cßš>´;~´½(¢Œú‘ùÑ@áGéE»ÐÇ­Q@ ÓÖ—'ÞÈÑþx ¤ãÔRŽ;QÚ€ÓƒE£4}hǽö£?JL æ— Ñš1ISšu%'OZ)hÅ'^æŒ~&—š(8âŠ\Ñš3ØÑ{QIŽæ€{€)NÔgêÖŽ½ÿ*Bqô£òh÷Î~´df€j1õ`g8ýhãüš9Î;P=©I⛓ë@ý(Ï¡£?ZÈï@Ãêô4˜?Þü)÷üè¤J(—;Æ}(¤1À.r(ǵëÁüèç®(Aô¥ëüB“99úÑÆ9¦!sJ?(ǸüèÇ¥sÖ“éŸÂ€(sÇ_Ã¥'d3Š;òhÚ:Ž)Gò÷¤Èþð “Ò”ýhï@> ~œ}M.8äPnG° ½è#˜QÇN”¼÷ÏçIÞŽÝhϧ?Z0}H££¯§r(§#×ÂŽM;Ó±¤8 ã¹9öïÇ4zÒàÿú¨ç±£Ž´cëG9 …!óÏàixõÅÅ~¿.=é¼Ó4¼ñÏÖ€×£QŠ@}±F}M/"ŒgÞ“Û¨£¯ÿ®€jO¯Z2ëI‘ÞŽúš3Iôâ—ŸòhRtÿëÐ@“GJÇãéF{bƒÁì(& ﲎýâhÈ=(ãßð bäãÊŽ­'¤Q© £Ÿ|R~gŽhqÒ–“#·Z2\@)yì)2¾§4{q@ ’=hÈëGùëHON .Gj £ŽÂ“§aøó@xÇéG¾ ç§çK»ó ·LÑõ‡ûÒþ~TtìE…Š^Üô£ñ¦ä{þ§­.h&“··½Á >¹£å4 ýh#4téÎŽyâŽ(à”t àÑ»=㥟֗曟oÌÒu>£Ò€ŒíçëKœñƒMÀ(õýhØö¤Çµ'æÛ@?µ'?þª\ŸJ2x‛ړ‘×zÙ sß4§ëIõÍQøþ´¿…'Ó4{~”uê(çÒ—j;Rb€žÔ|ÞÔQ‘Ó¿SGЊn}(æ€óźþTtãdPœö£½…ƒ@4½)(zÐwQÛ¥q@?ýlÑǽ&ÕÈ%A>¸¥ÇÒ€íš1ì:3Ï_“¿€dQÉ£Ÿj:ÿõ¨Á¸£w÷F~´O&—¯J:v cüš3Ž1IÏ·å@ Îh9õϵâôÇá@>âŒ\RûñIÀ=¨äQžýèϨüIühsëÒŽzL÷ÀühÍ/ùéIÏCϧqïJ=4ìúQÓµÿÊ€ zãò tãš:ãƒF9é@†Ž{â—ð¤Ï­&—éHõÍ-~TQš8bŠL{Psíß4¿JN‡°~TsAÆ:ñG×f€yR(ÉìE)nÇaùÐ`æ€z^½qAúq@ Œ{ÐAÏZ9î¤ç=søP1qïIì8÷§Rþs@ƒŸQFOr?*9€£ð aïJÖŽ?ýtœf€šLñÜQéGRÀ}ã¾ÔÄôü¨÷£8ëÁ£·_Æ€ zG×ò¤ã¾)wJ1E“G'§?JNüñŠ\Œu挟N)0Gz.}G4sëŠ0G~)9ëÖ 3ïõ ÷©2}GçG8éùSP8¦ƒGçš/N‚Œ‚zÑŒ{~4¼ ?Z3íIŸ¦}©r{ãó ØÑœæŒæ“@ Œgš9õ¤ü…/LñÎ~´“ß4u=#F ^=(Éô¤àöçÚ–€OJ:š?F3èhëÞŒQÀíùQÓµý žž”¤ûãëIß­éKÍ'n™úÒçÚ€Ó¥'éFFy£#·?/QÔÑô¤?äQÛ¥/áKjhÔž¢—ð Š3íš?( >¢ý)zsIùþ4qš^sIŒv¢€“?þºZ? ?ÏQÇù4t Ó4´œc‘@(h£P:Ò}ixÆ 'nÔ£ÞŽ>”€b¥/N˜ü© oLÐxëšN=¨~´cŠLÐIÓë@ G4b”bŠLqÒŽ1ȧcރךNœsKŒu<ýhÆMàs@z1îiqŠ8ëÖˆxíŸZ^£Å¯ÎŒ{Ð}ñô¢‰þøãµ€^=é@Íc(94À_Çð `Ð3ÞŽÖlþ4¡O÷¿ ‘ÏãA® úP0Æ"‚ô4dcâŒsÁ È­tþ´ŽvÒuì!¸’XÙ|½„ƒ¹¹¦î¹RÇGnNi·*<Ä%Œ˜>*סú ¯þ’\0*£oÝ÷¨ñv6ð£shïšN;dФ*¤Sí|¶6zÒ„¹;CÀµYü©H=N>´\.Te¹R sp)^)a¸mÆFæç?•[Ç<óFqƒŸ­>aܪ¦èˆ²ªGñ|ÜÒ3_ùncHÉÝÀ$ô«gô½yäRæÊø¼.ùU/|ŒþT€Ý…ƒ„Ïü´æ­éGN´sÊö¼7ʤoF{Rÿ¦yŽ]˜Èç¡öâ­þ~• •Tݪä®ìö$SŠÎ^2ª¡GÞùªÆ0r £=¹üióåW[·F]Á n0ÀñùPV÷q!Ó¦'ƒV¸î(ÏãK˜W(¯öŠ®Í°œ/ÊÅ'ߊzµßî÷¢üXn•lJ)óÊr=á…Ìq¨pÀ Çí÷BffÎ=êν(Å+…Ê~eÞmñÏ™ßBdԂ͈”áþ^y"´xõ4cÚŸ7\¦fºóvˆÿƒ$öúÓ<ûæ„„ñ«ØâŒqÿ×£›È.SY/HŒÁÎ[ÒœÏy ™Tl?òÌäsVðqÔÒc=1C—\¬­yÀdÏÕ{åp¡nÜ—-“š·Àþ!KÁêy£›Èw(<Ú–!)€[ê­<\]‘6aÁSòÿµW0=1Gó£›È.VÜùªi\“»¡¨Lš…Ê û¾`r*þ=E….o!\ g½i>Ï´(1 ƒíMgÔ¼·Ù{ ö¯ZÐ#ßlö§Íä(#ê;”>À6sŒu÷æ‘QÛ—L†Ë7SZÿd}sA¸£›Èw(5 ²ä.íÿ! Ûßš”½áœü¡cÙÁ<Õ±ÛœRcž¹4_ÈW(·ˆ“,·d…ÀãÒ€ú÷T=ñ•«Øõ_ÂŒgŠ9¼‚å´Þ²Ú2ppG>õ&ëÏ4€˜@X޾ÕoîhØ9È4syåEšñhòXÄ‘ÇÖ›ç_m}Ñ`«ñ·¸«Û}(ǽÞB¹E¦¸7!L´¯GJj\ßm¸ÁäB¹^8üêàïúÒà§ó¥ ¹\É?šË8 œÆj0o6FâÝÔçVÈ¡ãëGNù¢ár¯›z…‰Œ8'm3í7¬¤ Vê*ïáG|ƒšwò •¼Û“ÉŒ¯}¤ƒšA-Û„"=€žry«\úþ”mç'š9¼‚å6¹¼D”˜rC˜î=iÞ}á¸Úmðž^A,95g··½ôÁ¥p¹]gº>Ih6îûØ=)’Ý\¬lÂ&È|`/QVøïÖ—‹ùÊr\ÞþøG)å-Í5n/LñæT¡-š½€{“øRvëEü‚åe¸º+÷A$7Šk¯++»'·­YÀN)Øô}h¿\«ö‹Ò€£Œñšpšçr$+–9èjÇ8'ÄÑŒö¢þArª\NcBÑÄá‡\Pד8[y2‡åãï}*× uÀ¦ç?ÅúÑp¹Ë1”~è…+“ìj?:ûÊFX¹|Ÿáõ«Yçqê(¸\¨ó^¯™²,àänÁü8¦5ÍþаݎOaúÖ‡Ðþ4™Çñ ýh¿\¨.®X€mp1ÔœÔ^v¥¶" /ó¸8ÏÖ´9<äfƒ€z~´_È.Q‘µ "¹UU‰óˆ›ãó©•®ARÀ0 óqŒš±€{RíEÂåT’ëÊL¯ÍŸ˜…íùÒy×…dÝ”ƒò“‚üêáǵ&;ðh¿\¦d»2 îG&—Ï»?ÑØƒ×§­\úÒqëúÓæò ”âð$Œ±K| ¯AJf¾Yf`ãÛ”P¼çëÞ¯q×ùQJþArŒs^…â'åä*Ž¿=..Œ|Û8'Ô¯5oðMÔ_È.SSü¹¶uƒß¿j¸ÃâÙ‰^€Í[Ç~ôséEü‚åq5À‘G“€W$ûúQÅâ3Û•bpÃwJ±ôëFÜsÒ‹ù[Ϻ !ò*xù³šqž5WÉù çw`jniqŽô\.Tk‹¼XW ×4åšëdyK½“ŒUŒcÔ}y¥ æ‹ùʦ[œÈ<²~\r~´†[¼ãÊlè9ýjßü ô¤üh¸\­çÜùŒ¿g;qÜsúÒEstD~e¹ùÏ#åýjÞ¥!çÿ×Eü‚åF»¸Hçg¾_»ÔSÖâf* Y ¹túÕž{P}è¸\«ö™·çg އ4y·eF`\ç¨=ªÖO`qF(¿\­,—ŠdHÃ(ÿëæ‘f¹Yò2 üÃsVFCJO­ ”•ïÛ†HÁÏ'¥=¥ºùÀˆ>R­Z'Ö€ÃÓš.)´·£€àw¯ëR np¹}Î NǃÔqÚ ´ÈŒå‹OVÍ;è1iÖ9XFƒòŽi —"`Â?“ËέZÏÎ>´œryïJâ¹R›—‚2be“?0eÇÒœf¹Þ@ˆ?tÓõ«]zÒm_È.S{›‘å‡çÝŽGšpžs,ª UÈ$pMZÅìF. <Åc- ùó½/>åÛÚ3žy©±ìGÒ”yÏëE×`¹šs>V=¥IÄ’a|¼MXüI£ŸSEÀ¨%º"ÃËœçJd¹Ù&îÝÀÀéùÕ¬zóH0Iäu_È.Wón Ÿê›…î&…’à(ßÎ}ªÁcþº.+µÄë´ f<òAéQ½Ôê³%²¿wŽ?úõnŽGsEÂåežã͇1¬™cŽôßµ\ya„¶ð3Ó5sŸ^(ì8j.»ÊÒ\βám™†9 Ôfúácg{V]§ ç5tuïK~hºì*}¹þÓå}žB6o܃íNûwîÑŒ2 çqÈ«\æ“¿½]€­ö³—ù:àCxà¶î[°Çjµ“E]€®n$Yòh\ç=O¥7íNDEb|3`¹ÅZçéFcŠ.‚åCs8Ÿ³“°ü¸êiþ|Æh‡’ÛYr}OøÑÓ¶h¸\«ö‹‘ï)Ió1Ç¥:K©ŸîÛFF*Éýi:R¸EäÆ8Ø[>æê´«u+>Í"“×uYëßéF{Në°ÊŸi›o6ÒEÅDuPójÛw`ŸJÑÛøU{·h Èg# ¡5ØC>Öþc¨¶sµ7ëíL7·,‘²Ú¶:¾sÓÚ­©;‚qK–=ÉúÑuØeQ•F6òçé@¿ d7:üµkœdb›¥BЪ·Û” üà Ò}¹Ä1ýšL>w7÷N*Þ æŽGoÖ‹®Ãº)hH±;›s•} g­J×n²åe6äyþUcŒ´`EB)¥ó³2=»d ‚Æ)«}&ØIƒï±¨éWpqÖŒqÇj.»è¬×Ž<Ñöv;ï@¼o1¡]Ü•gõ4p~´®"‹j`FE!Ëíû¹Í<ê–Eò¶ÑžÖ­öêhÆxÇà)ÝvU¯±s‘ŽF:R ÿÞ òN¹Í[ÀmÅ€úQuØ4* C|JñÂü¶ ñRí¹ýÌŸ÷ÉëSáðŒ{Q½¨ºìþÛµ 0ɸ ¨yúPo‡š±ˆÜ’3œ`UŒûqF3Ô~”]v Âý|µf…Ô³mÁÅ?혒@b`sœŽjbCJëÆ•ÐŠßnº>Q;Ç­"_V&Þ@ÀãmYçû¹÷ “׎)Ýv ¢¶qŸ)ñëŒÑ%ÑB@…ØLR[d‡Üêù$Œ•`zcò¡ØzÒôœƒo g§Z_¶ƒ9†ãŒzTø÷£åéŽh¿´!7#tƒaùFj5¿2b|œU®¾”œæ;ÑTjK±Ya”ägiEúºFDK™Uœ9lœQuØ4![Äó¤Ë*úÒ-ò3Û e?.XÈÆ9£êy£@Ыý£…$Jw6+Oûb«à£ØúÔݱÅÈÁÅA¡Þ#îP¬zƒL7觘äÛŒîíV0>†‘—óùŠWA¡Yu(Œa»i8ì¥mJ“i,GrO­-®e„—_â<ïS•FÎåSëMÙB½Ž7TÃ’Ã# š_¶ d[.qÎ8©Hކ(ìŠG±£Ah'Úc ÊI~´Ï¶¦ÒJ¶@åqÍK°uÚ)Øã ¥ ­â»¨Û@ÎãÞ˜/ãò÷8*Np§©«AÇ€ péO@+®¡#8ÜBœ7)PWivÄÄ ÈÁ5YÚ €Aö¥ .€®·‘[ 3ÔqNkØ‘ÜáIÆO­M€z­7b`)AŒÑtEs©À©ÎïN*SyÊ#'ŒŽjB©ýÑùQ±;…ÏÒˆ^)ÈÅ#sJn£›æÂýìsRm_AHsÀ篽„)~!Q¸©^(£ÊW(À·AS„QÎ9éÀ¥Ú|QtKwMÀ1*?·ÇµÛcü¹ì9«ÐŸNô¡G<zŠ4 £P‹b³ +Á#ò§BŠß1VéS_î¨íÒ…@ € .»…dÔàx·€ÙÏÝã8õ©~ÛN Ø:·j—bÿu* .*¸=x¢è4!–ö8ÁêN8éHoã0AùºžÂ§!xÎ8ö¥Ú„ŽžÔhú gxÛê xŠì˜s´gŒsS£a‚Š{ã»ví£v1œsF¡ ÞÄämÏÔsMûz”íoÝœr:Õ…E_ºª>‚ gzñEÐhCöØÂ©Ãœžp:Rý¶•ŽÓß.ÕÏAøÐ€J4 ÇPO)ÝQÎÓŠPŽ6@UÎáÐ/J±´cÚ—h''A¡_ûB.2® ôܽiÂñHBREÜ{Ž•.Á€0?*<µ€>˜¢è¡ ¶Ó»=¸ëQ¾©û¹7ýÞ1ŸZ·°d£ò¥Úlþ]…v¿@ê¢9=H(käBÀ¤œtÈëB1l/•bHÍO€GÍÈô£Aè@סLY†OŸ¿/Öž.£'ø¿I´ N)€  qF‚Ðk\¢ç‡,p­7íkæÆ›\—àp*^3¹÷Å.9¢è4"Ct¹GPƒ9=é¦ù<•”+0cŒÍLW$ ëÏZ¯6èÊùaBôÆhVÐ>ÆŒ“ÑM éÔ~t{‘HBóïøQœQŠÆMÏÿ®—ŸLÒqœÑô4§¨äRcÛó¥èú“š?(Î:Ñô aŸÿUGÒŽÍ&}3KÎ=ÒŽÊ—õ¤y¾òý(¢¾>”Pîî¦ip;(Ïuúýh挳øÒá»b“$zSc'óéAu͹Å(=¹4ƒweǽ/ƒšSQô¤Àß#¡§sïHqô AøÒmÏ ~´¹ÀïŠ1žß­'Ö¿Z]£Üý Ž>´ƒé@äð1øS¾¹?JCœûPã=8?JP=é™'ÐÒäãÒ€(ëH¥ç¨ü(yéÚŒãÞŸQô >(Æ{QÇRi wPñÓŠ:ÿõèçûÔ CŠ1ÇcKœuéIÁê(íÉÇãIƒKÓÒŒgš&3ÔâƒÀäñKßÿ¯AëÖ€û“hnp v)Ïs@?€¼ôý(ÇÖŒžãå@ÓùQQÉ÷¥ÂŒc üè˜ÏZR1ÉÎ=¨Ï®GÒ“§¯ã@ƒèx oÇqê(Ç PùÑõÍ/áúÓzž­@ ÆzQœ&N?•G9Å/=Á­ÏÿZšGuûRƒž‡Æ€ ¨4£§qøf“”Ày àóùQŽæ—'Óõ¤Ç|gë@è9#ü)vçšà}>”Þ;ÒŽœ`{â—ƒÏCG¿?&I=´ß¼çŒRàúÐu£ð4c©@‟ £ŒòM.õcµ&ïz^CøÒgQÆzPœðIü©héÚŽ=3@ š_›×¿AŠ=»{PcÜÑKÓ Í íÆipiN1Fx ç׊Lôý)Üã§áš:qŽ(i"œáF()2sÅ;b€¸¤úb—=?Z1ï@'OJP3ïF(£§AŠ0)=ÿ:\óA÷£ îhÀëÏÐP‘F}ÿ:1è´sð ü?ÑÁïKô ûÐO9ÅEoŸ,äî9îjnjEEŒasøœÐ1xë“õ RçÓzs@„Àõ9£§½:âA@zŠ(É&€s@¥'CKìGÓ4r{бõ£üóMéúÓ±@ ÇJiPNyŸùÑõ yKœœ“ëšÁÚÙϨ§õéŠFÆ;PXãõ¥éØÓW­;§AúÐïš^@ëIõ¤ÛÏs@ ×§gêhϯ4‘Ò€õühÅŽ(wÁ£·ŒŽœgëF~”dt9üiÐ9$RçÞŽ½³@ƒ9úPqÚŒúQ@Äç¨Í'<õ¥þt¿ ?äÑ“Ž”´”csùÔ[¼£±ŽG Sçܟ‘×Ì\r(¨Ñž¸çšvÜõíJ£R“Ú€G=éE;ŸZ0{*Bžç¥ãƒKƒŽ”‡ŽpI¦wä}(>äŠ_Á¾”cØÐqýãHqÓ“øÓ³ÅöÍ'ù£¯jSú{RuîhæƒÏ\âŒÔsè?:M Ž‡ôp>ž´ïÇô¤ÆzÐa}hAã"ŠNGz{1¦àg½;ƒŒdÏŠ4wÆGÖŽ;’M8õëI“ØÐ Æ9äQÛ½/^”œú†µ-ûÀÈW {b¬dô¨ãŒ©b\œö5(üècdu Œö¥ü¨ÏùÍÁéŠ9=¹ qÁ&—ùPsøzQÔÑŸj3ž:P:ýÞhÇû4gëFIïŠ@ÇP(âŒzŸÌÒŽ½¿:` >Øüi ?ZviÈ ~t †Ý0‡äeäðNj~¾£ðÅG ãöãë“OÄÆ†N:ÿ*ȧt´™ãÍ&=éyïúP2FZ8zÐ ÿ=)? þ4¿C@o΀ ¼æŽœsG'âŒtüèÅ/4œúRð;Ðt=8¤8ö¥ÉéüèN(9õü©:Lc½zÐãГEô£#¥õŸ§sŽÔŸú~t{óFsÒŽ}(ëÛš?*?ZNÙÝ@ Ï­'ùéGùëKøPž;Ò|Ø£#¹ cs@ †ùÑŸóšLsÏ4¸˜ Í&%þT¼Ð3@ÏaAç·4Žü©¥ühé@ Kz( úP/ÎÄ¡'“SS6(–8c¥IÎ)±† ò¤úÒþ´„÷4sF~´qï@ÓÀ,B•%}¸ïSã¦GZŽd2®Õ8äP2P8à1õ£ö÷£·(KÒ“·ŒŸJ3ŸJ\f“œõ£ùP‘þE=3Ÿ­ÑŒÐàÑøÒ`Ÿ_ÎÀP1N1Ö“>çò£Ø¨£’:b€ 9ŽsGè()yj)%?¼J)¼{¥/§"uãõ¥Áÿ&€¨¥äzQþx¤öb§N”sÇ4RŽ{P€}qô¤Ç<þtcÔ~rðÐϦE…7sHí±Iràп*=±ùT6û¶·Ìnàâ¦Éyühc2}¨éЌўßÎcÛ?J.IïúRàõ¤Í'Íž¿­/åK–ä{Õò!SvÇ’GÊ?”ÚÎÊÞ¿ Ÿº:c¥;.ã±p¸ëž=…&rz‘ˆKÃHœÞ§ÉÏ8¤Õ€ ¯¸£êj).bùÊÈGÒA‘ï+>NFà8ü©Ø ³Ûjpeö¦óPÜ\¥¼a¤b7ªzòzRÎp:Š:÷³Ö;Ç´ ׳îÎvàc5|gŽqM«…£éI»ÔsM–e‰79À¤!üû9ϘªÖåäc8”´RQOoÒ¬ŒúPÐÚLž…©sŸJ=E žÝh£ŽœÑʈ}1Ç­:“Š^E6;Pc ôÇëAéÈæ€0:P öÎ(ã·Z3Ó"“&€o—ò£¥ºP(7qÏüœsïF}¿:BsÓ4 1èåKß­4ŸoÖ”qŒŠ?—¡¥éБøRgÐ~t¹ @@Ï-ùÒ3ÉéKõ4|Ç¡Ïá@ È'½î)G^Fµ.}•/zoã”g×"”ÒPœPXöüèã­÷ êyõ£Œ÷'Ú“ñ›&ÿ)‚mߎ7(ÿˆ¤ÿdÖtm¨¼å­„^_[æÝùt¥"ý$y“ËBw9Èüª¹|ʱ¢~´{f£ŠQ,aÔåHãŽiø?Ý?H…ú‚i9¨ÝòY!€ïÒ’0VóŠ±ÝÆßJv óýâ)9õÖŽGjB'¿ó¥Ï¿áGnÔ~gÜÒaQ\ü¯ôrªùþ1Ú£O¶ ‰‘£h‰àÒšC±kžÇŸqGåIÛ§ëKƒÖ€äZ94cœ1Æ:Pœö¤Áö O›¾?*03Î £ñüézÐp:õ éŠ_Çò£9£$ŸJ:w£<ôüi:ôþÔîqÃb“æïƒî)­¸)=ýê8V@\¡ã¶h0ÏcFxô£Þ“ 9úP!r=){zV|‰¨1“ 7 ¡IÎ*ò–Ú3×Ú‡aÙö£··¥7œõ?;ž¸ãÞƒ<Ñœvü¨úQúšNOz^hç±âÌz?ð Ž9Å_Ï4u¤Æ9À¥ç° ñü¨ëМÑÍ ôvÎ=é2¯ã@ uð£<ú ^:ÒgŠ_Ò“Ñ|þ4~ó Ç4p8É£§jCøÐ 9àŠ1îiq@ ÏCÖŒg¡ü©p}hãÞ€Ž?/° ƒÛ˜ß…Ç­2w) 8À zQ/f#ŸÂ’žÿ&AŠ;uÅ(QKøþTŸBh2}1GÍÜ †ãÏ* #$ŽÔзaÜ3¦Óœãô§aر‚yÇ4g±?¥VT¹]$€…S¸/sVAÜ þ”4Æ”~´ÉIÄ0HÈØ7ù æïŽJŒ @MGâi2sÓŠZö"”ô÷¦1 É ¾Ò[ ÀWŽs@ÉW9ÎÜqÉ4ãôÍzQϨü(uqG4zRp€>äQÉö÷¤üèÏ©Å$u4¹ã#Óשþtg€u©8=ãNÀJ?Ï4½ñÍÿ&€ (Á¤ãµú€E'~2öæ—”~ ÑÏsF{RÈì(ç=i:ôǵA4²¤ñ*íØs»'ši\?=ÏÖ–ŠdÌÁB£žs@ýhç5@Éx[1˜6žäÔ®‰LªžO^ôì-àûR~i£ØS²zt€LzqFÓ׊ñøÑœŒf€ƒHO°¤àsKŸj'ä(Î;óNü):sŠB~Ÿ þ¼ö¨ƒM¼‚€ úö d™íÓñ ûœÑó{ÑÎqÆhÞä~&”{d¦A·Ë9ç'S—”€Ï~s@ÅàçŠC°ù€=ði,уŒç?…l :wü¨Ÿá¥¥!÷¼}i Žbé(››Ó4 ~=èÅ"G9Í:õ¥íIÍÖ€z1ëF¥.;cõ ×4žØ8úÒ÷íGqý(ÑžÌ>˜§~<ÑœôÇÓ4ž¤~=GëIÏ ¥Ç¨ÍJw¨Åx£Ÿcô¨æi?t¡›= ÅI·4ŸQMRXs€~´âp¹'?J0;þ¢—=óUšiÀâ,å€ätß´O½“ÉÇ÷ýiØ,[ãÔÒ­VŠKÀI¨ÆsïùÕŽ£¶i4ÑŸoÊ›Ÿz9ïš;ô¤üé0xÏ4ûŸlнÎ(Èõ s3»©BœT¿‡ R}ésÉü©ôñ¥üy AŠ1íøP}óAn8öÍLÑÉîEE®åÃDWiàç9©sÇJ"ŒsÖsØþ4`ö\Þ¯Z€Ë »XÆÃ\ç<æ¦Èï@ÅïëG=Ži2GLcéFp;Ð!y>ÔcëøRdÿ“F}E(<õ4§ëUî%hÀ›‰žà´Š` € Àçð§aØ»€>´v÷ª‹5Áq‹|.z椷iÊ~õpõ ç= ¤|~ 2HãçP09ç½MœŒu˜yÏ×4£ëP³¾õPÜòI¢GuqŽF bm£=húU¶Oóm¶rïŽ~œÔ¶×Ìó ahÂ6áÔ{S°X³øsIž”=ǵ/¶~”„QΡY›sÜT SùP1r(àw8£Ÿz‰¥a0AÆ9nÔ/J21ÅÔÐ2{š'¦ŒÒÿÀj™šá£h˜(Ý@Éÿ:\œôüi¹¾)G± BÑסœg¡Íö ê)i;ñÅ/Ö€'^E/__ÊÄš9Í'#µúcŠ1Èãõ¥íF=‰ â—“8ìiN}( þøúQI?ßJ)ïÄQÞ”g=(Ç`E1Î=>”¸ÏlÑÍèè}¨Ï¸ Ž¿•(ôÉ óG=6¨£hëFO|~tHà}~ZF¡AÖ—‚:ñïHê 2À@ \ ‹ŒúÔ zU­pw…ÝprMYïÖ›ÜlA£éš0L挟­!N:~£Ÿ@(üp(ÇP«Ã*“Ω‡§òªM4q+Α9eãõñ‚¿'ÛÒ©¦Êhry¢öBÌ»01Í%ãÏ´%±A/Rv¥Žž_´ìefãô¦³@u eüÀ½1ÁÝE™X¬€yÿ¯OŒÜG&n$ˆ (õ«˜îúÔ(ǘ™ˆl£8¡0¹0çü桜oŒ #r0sS'͸ã¡ãV[h"c,Žà’Ë JÂ%…X (Fô…= ’vØêjâWd™‚€A\u©!·Xwbwœ’y¦ì6,Îâ#å….GÊ êj³}­Ä[ Ÿ¼:õ§Þ—6íÊ&¬FÀÄ„dd1BÑ\6)«^ÆTyQÆÕÐÛ€#¡¦LvÄK@ôË9–áÆäÉèÄúPõA¸Å’éÎhy¨ºŠÍµ¢7Îq”úóK,1Ý3@7DÇëÁ«±¡HÕ –Ú1“Öžˆ6"¶–vÞ³ÆWi´I<“†B£sÉoJ³Ðz ­nûî$;XÀ'½Nú€Ç’óÈD™ëÖ%ÇÚ‹1anÉ+þ5p®;U;×H–gý‘šiÝ<ÒH!fŒ øã=)ci cpRþƒ¡¨î£åvúàÔ)œºJØC’»ºþ4$ÓÝ£û>åcƒÎ6ÕÄmÈéHÇäbIÆ¥VÓŠýŸ²A'‚hÝ·²O¾ûeC&G éP™/üð¢(ðc<äí ïRÝKr)‘œÆñVúŒç?Z/dD3êê‡Ï·‰?q¸ýkP6É9ö¢HÌ‘²·>”Õ‰ ”dñÉÍ ¦)\]_$ù‚Ý^>3º‘®µwŬl„¸'p«vd˜IÞg‚NjsÉ‹¥¥ÚÉ+Û¯Ÿ´MŒ1éÅN9íTm$ŠKéùlŒpW§ãWøÇ˜˜›ÙüM/o¼´œöR÷Á¤ ã¹;þ• ÷1[i ÁGÖÞB³ˆI HÈÈÆiٱ؟‘Ú€Otô¨îœH§œpÔ±ÝÅ<…ƒœƒÅabn{ RcÛð¿U ñŠBÄŠoíøŠq'Ÿ—Znî2®(¥º…œâ_“®yëéVІR0î*¼!^íå [)÷qÀ÷«G¯QM•áó–fF ±6ñK4“$ѬQ‡VÎIê*(5ôÛcqò–n?Dn†ñÃwËÎAàSê29æ7EK(Æ]À9X†[—‰V5ãåãSü¤äƒUn™~Ѿüg#^ì7-9ÂòŸlÕa5Ê0W!›…è?:/š/³4mOp XŒ(‰Bçt–€P’æüoD‡$`‡ÙÆ?:¾ŽÅ@ÝŽ@év‚8ÏßgiXÈÎ]³ÈQt!óÈé dÌaü5š<+Â6±á³ÐU¬ÕZl”Ä…˜È4 EœdçúR×ýhúOÖ ¼ EÕ”ä`®Z@1fºr7[ª©=Ûš ÷D°[q€p aSAHUAȦÝùB &p‹ž¹Ç5M«ì2U,P_¸¨â’LŸ7o”øÈ1¹#Þª¼1Ý9cä~”uòKr²6ĸùG¯ãSDìËó.Òzth¨Šƒ°Ç½TµŒCs*}¢G,Å€c3ý(òî}1õ\=ÎùAUÚÉô©É ¥˜àµU5f}»ðwcšI7°‹5Éò·}ÜäŒqWqÇOj oažÝ˜¹Qœ.jÕ°ÃqÔõ4Úq$ªñ¬q†V$7¥C ó%ºì·~ü7×ëW\ ‡¨ã¯J«aþ  Êzôç<ж°è'îeI"Ú‹÷XÕœã¸uéFíRÄRšæx‹2ñ‚{Õ´}Ê &ÓéLœ~è0§#•8¥‰ ¦ ÜIÍ>€IŸR*–a)Uzâ¦"ªÀ?} ÉÏñc…$jKxmƒÁg©ëùS¡¸º7L“‘Ǵ`îÎMYïïUnv ƒÄñ…^½j¯qîY‘œcoçAc°íûØè*9™B€ÙùºÅ$P²¿˜Ò“Æ6äâ‡df=£<“S~&«ÜÇæDr€Ä©ëRBèñF,§¹ :gž QÞ€)pi;g8¤Z\b@qGÖ—‘ÒŠCŽÀÆŽ}ýizhwâ€hÎ{Ñϵçµ Á÷¥úQÏ·ãF(ãÓô£éKE'áFh¢€ J\ÿœÑü¨ÂݶÆd8û ã4è÷ÀÙŽ:Ò›p@…¹TÞÍ:>×Þu ~4ž†ƒúÐ üEã­.­4ýh±'íû®ýâO5døªÎË%Ç–$;—®jÏN”ÞÃdsdBÛWq=‰§& à{SgÛä?ÏŽ:úRÃÌKµ³Ç\u¤$ÞË"”ܤpJ‚ÜÈ–‘í‰Î8Í[•‚#3ÀºÔVÇ1Þ\……5°Ñ$nÍÁB1ß⣸1ˆÍ`«ÜÓ¿îJ:gô Q[¯îøvlôÎ8©¹Æi1 Ÿ­.rzR`žüRÐ ü©½GSŠ^@4dŽÀ}h¸Ú;ãÜÓ¾lu£¯cIŒÍ Ÿz9Í:g4J\ŸO΀HíG´¿NhgØÒÓyÏlûй¤Ï½ ëŒþT¹>¿… Ñ‚8φ—9î):P@ïU§8ž\à“žNg8à“U®lˆ7¨Îzõ¦·XŒçò¨ç|G$tâž àgµEsòÅ•m„¦r¹M¾Õ!ªqÞD‘eä-œŒ ÔË:4q¸<8¦ÓBÂ0_å<žâ”Jßh1”ÀÆAïIIíì'jE$Üœ8 W40\µÈÍ6ß)±ÏÌzTøÅVùd½ÌÎÑÈ’-ý1AúŸÊ›ÇMÔ´}ÿ:0~”dœQÔgwα!fÕ[,.‚4£’ŠHHF»p 06¡§EqæÜ:¨&§ÀÿxT3Ç3*ˆX/#98§ 1õ¨§8‰°¬ÃÐT£8þ´ÉIT9`¹èM *x#ýê—=ª(UÀb︓Ç*Sžæ‡¸1{fŽzN}èÀ>ô^Ÿýj2?ýb“ôúÒöë@ãF;õ¤Áõ£>‥;QÏ­'ãÏ©¤ç#Š9îE&yê1Gz`=‚þ5É—*ØÀ5''±4ÉTéŠ$"=™B[“ÉëOÆ{Tp,«1É'¸©vœqÏãŠ0ǽUBÎÇs’IíÅXØ;à~9ªÁH»tn¸ÁÅ4´(c…,8íF;ІàÈ0’ääÖ K’ûp€2~n”Ù.¶+~ïœàsŒÔê£hxüè(ä zSÐ4G©÷¨ä”)Ú«“ùS-‹ìí[Œœ•'§4lÀ¨“GîK1`늚 ‘6p® á‚i±9Ü¥Iè§ùÔÀQùÐì68ç=OãF8è)1Ž”`úR$^œæ“#ø£ÿ­!éÇZ­d¼Ë™ÞS»«1R=ÆÇ Eœ žj¸{ÐÇËTu/ÉÜ8tgn÷ªk©LU}ê¬23Ú‚v©9'³Uí̆I2C À7`äT±2¹ØHêêÀ!Öœ·û¢ßäÉ‘ŒƒÒŸ"±¸rì ŽOô©Â€8ÇåUt;ŽÀö£§sIÈè}¨ÛZ’E$wü±Iz\{IÎz@îv€2åXƒŒu52 ¢ú⣸“Ê~SNGß-ÉÆH©ôAøòqKÛŒŸ­&à09éJG×ó¤"´ .ws·¡ýjÏê1P§›çã °£Ö¦Áõ›*±E¹tƒqôÈþTùH( Ã# Æ ´‚U å•ÏvéI19]öÉ eÀÆj„Ü–qµ²6dÓ’hÉÁ$™#¤•œ¡0åNõ¢ÖèX4K†~ŸÄ0jNqÆ?Žæ d]®G#9Å?©ê?­& ‚'O3`v-Ï^•c Ž¿¥C˜[çÇóSðG½6 k`.{Už?´,ÞlNT!ÁçéWŠäBþbʨ„ÇNÔ CZî$@øl8Ç?•YÊ‘×?…3b•ÁU {S†G@)gߊ¯Û3/žìÝÁ\UŒöý*4y­»~¼Ó@‰±è*?0@õ£ŸjB¯z1î)½éݨï͇‡=èÁÏ&€¨=)8RýGåIÎ3@ééJ>´œ’hÈ<þ´d{1ÎsGלzPçé@sŒ~œŽƒôqýìC7ßJ)eÎñŸJ)¿‡J\’0E(ÚŒALAÁÒŒ{Š\ t£@8ëŠ1ïGS‘ÏãKÞ€Û÷ÍÇaõ¥=8¤ þdãŠGÉV䎥/"îÇ© -[w˜ )!» ³žÙ<ÕkU;\¼J„·PÛ³VFJoq°ãÛëG9à­4O9! ów O¡£ó£é@È"pïÄŠàg€E6æGŒ£ï›°Ù¥… IÄjˆrI<Ô²®øØm qÀ'§³¨Áã ¤2ž†¡‘˜ÊUCíàSlŒ¦Y¢H¤”VÎ9 Œ^(¡výò;ýiÛPê7˼Þ2ÈëφŽójm ç•[ Ë|šŠ_7ry8#wÌ:ñB“ ’®ð£,ãšI[jd£¹cŠQ?‡ð¨®9EX‘w|Ùì=jD:2D²’ºr*CÇBj8 ¨0=ŽjBqMî ¯s)„æF£;Ü Œ}©Ë:H» ¼äb–ì”<ÅÁÉ=ªÂ•ؽ@ÀÍ>ƒ*!¿Ñöm`1øU‹f™¢ÍÆÁ&Oݲ3¢æ5Ür8ÏjXd2F©?Âh½ÐÁ.éÙDŠýx 8« U[dÚç÷B3Éàö«YÏB &&'ÓŸÇš¦ÿjäBP܇9ü±W:Œg¥U¶f”,E1ÐîûÃéB;Ÿ;š Ç~ Fa»PíxÉ%ƒ¶~•w8ëQK+¤¡7dœô¦›Øwv)lÅ@Ü¥, Í–ëJmÐÍ«eûíV*M:Cä*= f—@Ù Œ‘ÇR*v}˜gV#ÐsR?Ü=N5 ª0LìÚÄs–Í `Aw,¨ÊaÇÞõ«;‰êxö5Rê5ެѱÆ>aV²¹Æp}(èn×á  ïQMp’<9c=é|ÂöÅž22¼¯_ÿ]+¬éãMŠOrFZhmAäù„VÇÎöëïSÙ°ò¨£ ŸÈÕ‚W©~^*›³eku».Óªch”ç?…[$ÿ3PC7™+¨O•z1Sœw¤ÄÅëîhö£Š3ž¢†²dVÏ4…çríÍ?­ „àb$NG)Ê¡@POÐS§J0‹ $v£#ÔRŒgŽ´´ƒÛn_¼Àý ëJ1ê(¬#÷ÌÀ(ÊôR1VA vÇ­U·Ûö†uˆ€ËÖ§‘¶ÆJÍØ l¦E»®ž=êpÁ¦3É$Œ"–2Àš}¼c`‘£°ù”œâ¢‰c’äŸ%†Ö<·9÷ɧÔ)Ô‚1(…Êð[š _«G˜Ô†o˜îÎÑùV‡Nÿ­A=Ä‘I¬%öž”'®ÁrG£!OnJ¨VùäR䢫q´ŽGåV.%0¦V|õµJ§pãúRZÏwÔY•v8x?N3W-¥Æ>îõá€ÏžÍ„,0ØŽ* c¸ÈJ°$ó‘ŠwºBÏ=Å@ù3€yÏByÅMœw?UvŒÞØÛaži-Ä‹˜ÆsŠŠ|•7mǧîÏ?ˆ ääiÈÛåU‘“Ì=@oéLË¡H]C« Ý8¨SM¶B î-’rO?JuÄ[c,ˆ]ò8Î*´…¡£„‡îœrjc!‹2 7¡3”‚OJ­bÊñUaÔsõ÷¡l$YÇáô£tæœ=©2qÞˆ§É$Fú1¥;9›rÊ` ï ‘÷:Ô‰ÌcïO ÅçÓ E„ò)húäŒäÔÇ8íz­Õº›å`NîÇéBZúUk†Úû‹FcïŒàæ§ÞÈ9V}ò]Úð‘ÝyúP·O#™M™ì½,eÄcÌÛ»¾)“ýшšCÎ0@©!º\®Þ:g8£ ÜohÔ"©¹ {T«€ƒüê+¼ùC·Ì*HÑV0= £ t¡¢”{ RôíHBcÙ¥Èïš8ÿõš1Iǧ4wÈï€dõÅ!Ò—·J?*>S@öRuì?:_ÀQùRdQž8¤û9ú}hÇ·çGÐ õÅèù±@àPH@Îr?*wãIšŽe%‚}â8&–0Bi'#Ên >€óK1Œ‚>´ q íGN´ {Q“éÅÐ~G==1K•íŠ 4 ªí/Úv¤hÃñÈ«¨Ë`õôûIP¹pNjRxÀ8Í0dr3<¢œ|¤S‘›jï 69¦8ù<½¬ÊÝNjU¨Px©Â’#µ2Ü»&æU\ôç÷'a8Ç Ž, (`¾‡­—ÛT7,Œ”²ØÛ.@ýMCqäæ?17|ß/ ›®B°=íøf“|äymo—%ŽO¦*ÈÇ`qHÇj“ÖÀH÷ÄŠ öQÍ;p c¾N)îíô¥üi0¸ü(ÀëÞ“ñ4qž™ Bð8£€:þ”ŸZ?hÈþy£Ô 3õúRõ(1Ço­w}´r:ÒãÖ€¾„Rsíš1è¿­.=Eè(çÐRž½?*NýT 2Hèõ4"ÓëFM(ÿ8掃©üèÍÇ¥ c¡üÍA6Ñ2Œ_MOϦj¼¡|øÉê T·L q×®i“ïòÀŒ)lóŸJ?­2còp¥½… 4GŒ‚FÓöŽ>PqÓ¥6-¾RðWކŸéCÜ¼Ž˜úPÆí”©ÆÞMMŸj¬ª>ØÎD™##Š"׿ çíC ‘ޤZYîK‚qÀéQ#Æ×\;+0û¥¿¥4†‹˜8ã¦ñÓ½=©8ô£ñ¥ÎzRgÚ~ÿ•@Ÿ4­ò€AÇÖ§9ô¨Sæv$žÐ"n‡}hÁ÷4tïHyêZŠ~€ye—<Ó¡Ê\)AŽ•ÌžXAóÍŽ*HÆy$Sèžœæ PËpH0IÇ­Oß9ªê#k‚KÊÇö¤áKÛ3Iøþ¦<¢2䚆õýi’`FIäz¦øTW<–ÜÁGr4èÉ9Âã#­<­CnᔄÎã'½MšàÅÅ&<ŠLúâ—#èh}ãŠ?Ð:f“Á ãÖŠN}sJ}Í/OZ;ÓF:ƒšQœòh~aÜ}(ü):úQA@=±L”.ÿ‘Oú棘)C¸œž(‘( ÂÉïRcŠÙÌ‘–?10Çz—hõý(`ÃÃð9ª‹MvD7.FïCW0{UU*÷yôÈ)´S@‹?_åP\<¦rzŽÕ>qÆ*Â’˜ŽzzзJ£ 8=( `÷ö¡WxÇÖ”Ž9Ç>Ô€­iµƒ•“æ=xÍYǹªÖ¬Ì;Ÿ!ˆÃåVyƒMî ‚U/µËwjÆ=•W·UÝ!Í“œg¥Xã0aŠN=9£J0qÔR~T„Œc¯ÔÒœúÒrGj­kŒÉû·O›’z²FF3‘P[gçS ßµNG¡íÚ›Ül‚E‘ÂÄý¡Þ¬úÔ1ß{ñ7=åCU–5« …‰Ù÷ù8öô«xõçðªÏ ûj¦NJçhn¿…Yë­`è'­&Üúâ”qÜþ4§è)B£û¿õQÓÞŒŸL}( €†2\¾)±ÛBT¿–G˜*OJuÁù2ÎqÉ5*ਠöëŠ}ЈZ[ïä‚ëÈ'µLyÔb—ô¤"´Jbo\ÕŒ;Uh¤ÞPw?.~cš³ÏáM•Ù"[…& ’~þ8§J©¼1…˜ã¨QLvGºTóвSÖ r7äýéŒl–ñGºÁ¸ã;G_‹;hb,q²4­¹ƒrAþ•g9ÍWS¼ìŽé› RMì+–vŠö A¤"¼{ ż²®2¹ëÅXÀôÍ@¥ŒŸë8çåÀ©¿ ll\g?:®Ø*66Jçvx« °û@Bç8È\ZH6ÖŽGµ!ôçó£ŽÔ¤ñÔŸÆ«¤q}¡œ) F2j~zwöªèÚß2uQòzPJûƒõ£ÚmíKÏù1ÞŒdpx¥ç¿ò¤Çwèp{â—8ïHy<óGÿ…;ñœg¨ ŒôŽ{ñ@ÆŒcÓ}qF9È ŽyJL=(ÅsÈ  t8¥çÚ“'ÒŒóÎ()¾øéÓµÙ¾øúQHd˜ô¥ÀïIßîÐô¦!ØÇ¥'üô¥ôÎ=(Ç< PŒàšáš Š8é@ Íü)8éüèϵúf“û— ”`Ù m­–ÝW',NMOƒž‚“û{R•¡ê0ǯó¤ÀÇOÒ—€}þ”œd×é@…Á1ÎŒ§ãIǧ?\PF==¨(­–&Èv#°fÍKß üèÀì=hÇ ãÖ­°[‡›s|À|¾”\@nbòËëš›¯ni0¾”\.Q:T'ïK1ãó,VQÇ.ô’Lç8g'úÕž;=(ÇsíNì.ÅéÛšc¯˜…r{Ó¹=1A¿ ¤!± Š0qÞŸÀôÅ&9¤ d=h²Æ²ÄÈqµ†+U$Ó’G…„®¢"œ:»×ÿ­K·Ð~´ÓkaܧöÝ‘q 9Ï Š¶Î õ ã¸“¿ØQvÂäIl©1”9$Œ`óRã·SAô?QH¡GvŠ@;üñUç¶ó™xÑ•=TàŸÆ¬}8¤9îhNÀT{x„fW#ÜÓþÆ‚äLq¹FýMXôãùÑ´c…§ÌÂìk¦ô#¦G\RE”¸,['©)û¥Ÿîñõ€ äc${ŠŽ(|¼þõß?Þè*L“ü<}hÆÞpG${Щb=Ôb K%K)¸•†Ý¥Y‰þµsæÇ\Rr#4&Ð\Ïm5'E×s:Uÿø¥$ã £žÃó¦Û{…Ê73KqçGtÑp>Q‘Ÿ¯<Ðö°.ˆà‚XOëW‚ç¨Å‰£™…ÆCÅ ¡}Äu#½I·Ö€¤t¡Å+Üv"“±Íä1ô¥zþT;vü¨ÉÄ&;çƒÔŒP¹õüÅ&/¥&G®}©zõèÎi9=HöÇpNzÑéŶ}éw!¶’8§`õéFRs@VÊa*³\äÇÝ ç?ZrÚH2Løù²_þ½\µOÒ«™Žìjð sÅ2XÙÝH} }êLgßëKÇN†¤ ofÌÇuÃm8À1OŠØÇ+HÓ³ä’>ïµXÈSõö£ð ;°¸›IUgµ•vÜ2Ù`Z²@=OëG?QJàT–ÕÝ›•R¸ÀêÔj5\çõ¥¤Æ{w ‘ÍÉ÷f(qŽ€Ômo),EÉÁ=Çõ«<sAÇnh¸\ª ˜\Ç'Ú›ÊU!“xýj×OSøÑ‚:P8ÏcH ó[Í#ïŽvå#wõëI´ŠÀ´åºgŒgõ«?Cš7œZwapúLHʾâÌF1‚x©3ž3úRséŸz@/N è*YK´ŒÜð3Ò¥ éü©qÇ#Ö”€J’8=qUͬ˜éRnÜ 'ÿ×V±Ž)qÅ Ø.VŠÝâ2›prHùqÖŸo 0egúô©z{Qß­;°¸¼zІXägÜ“\`…¥éÛ>ô™?ݤ!£FŸ<¦CêF)Î7ÆÊ2¤‚ô¥Ï½( ea¢%QrÃÊu¨ÚÖæF$Ý7§ÿ ½Žôœã¯éO™…ƨ€Çq’F*7·f”:Ë´cîâ§ÇŒÒ|¿JW ”ÒÊeˆ£]±%‰,š;r’î3» »v’H©þ„þ4r;Šm¶"–6®S¨iꬪàq݇Zp¥è?Ú@G*3¦ÐûNzKf8ÂÜGz~}ÿJ;uý(ÈôÍï‘F[®q@÷zôô½»R_”í@ ÆzcÜR“íúÑÒŒžäPŽ{ÑGÐóGÔŒPøçéEÔ~´WŽ´œdÿ….sGuü(>´´pqšZO—Š¡ý);Ðøþt8÷ýhçÒ€êÅÂv8Í*tÁ'=ø£<ãó£ñüq@Åãéõ àZhÆ:ŸÆ—Ÿ  @@=1ô¤Àî§¥¨£.˜ålŽqA‰ËÜT¤ž(êhF=¬ù>§ŠU?<ÿºi2qþ"€®y9¨ÚF,vU*F2O?XÉ'ÓëG·4qùqª“’3Í;ŒE;RhÆzñøÐ&à„ËœŒò þºA¡ÿH>aï³#ùÕ ŽAüM`vü(» ˆ>P2ǧ4¼cŠ_ÂŽ=(c¿4qêsKǧ4f€žæÒ—?!ðhãÖŒc“š>€Qžzãñ õ  £öÍ/J&>´mÉëKô¦ž{~T¼ôÇçAÒmúû_çíHÇ?tÆý1î){àŠ8Ž}… Ï¿åKƒÿÖ ã"ŒŽ¼ÐŽr E"±‘H+°}áSRgôÀA·r=Í S—éGðiݽiÔR¨ ;¸ü©1øÐýj`.3Lxذ(اîôÇC@GråH'€Ï«ÜrÄsRp}qëKÆyÏÖ€œsÇáKŽ:ÑíŠGbi`úf¡4´;Ss× }jBÊb*9Ë|¸ÍM»=ÐÑøP24Y’äc*L} ÇcK€h¤d`¨¨rùeKÎp@éV>”¸ã¥7õúÔÆÆThÔpyçþº³×¶(?…Vuœ+•#~8æ„I„¥Ÿn:UŒ ñš1Š.ŸL c†e!XƒúTœQœv4 Ný½{ SùíÖŒž¸&Œû~t{àÒc‚—¯Z1ÏP!:ú~4bŒsÐRã~”céG#ØR}E/'׸z}(¤ã4¹ô §j1õ£'×ô£?äPCùÓdRS Ö—†þ\{P#F óìÎOݧcÒ€1ÐRõ(cëP‘/œ1/>¹©¹ôü(ù½4g8Í»‡ :g±¥ë@úb¶]@2¢¾:ŸÖ’Uº ùnGlU ö jwÆF‹ÆIäíɧçÜþT¼÷gðúR Y|ô)R}i`€“ïdÔŸÔî;‹ÍîhïŠ^¤!;ãúRvÇô§r>”nú€+À®¯&ôU¾RZŸŸþµ.~˜÷£ó?J‰ƒ±c×¥?æÏaÅö dr!ûʪ_ ÏøÒ!˜¸ T.=sRÀx£:PøóFIíϱ¥ïÒ“ÓùP!}¨àw¤Ø£'¾Ô¡ÈÂ"¶zäÓ#7Ý^$€6í57^Ô»}M¹]äõeBŸ\Š–4e\;–>´þ;^{ÎÂä3,¤ÊHÆìsL+?”ƒ«dgžÕcžýhŽñ¢ár5VÉ2ÎxÀ¤}æDÀ9É#š—w¤çûÔ€_—ÖUl °û¤Ž”à=‡çK  C"ó!½…9ŽsÿÖ¥ÅÇ¥WT‘nQŒƒ¸àäš±ØsúQ†ÇÞ͑Ɇ=ê)ãrýáÓ#5.;b¨“#vàbž=?•/lŠ:ð íõ5 #‹‡Ê ¸áóÉ©ñïùÑƒëÆ€¶9¤éßõ£¨êh zôöëFxëŠ3ìiŠNü(þñ¿€ ÇcÜýhãðúRãòhçÓŠB=(üÿKùþ4œš1ïF1Æ*0}h;¿ýtcê3ëI‚8þ”£éGOjA7ßJ)fûã¿Rçj^üŸÊ€s@ÇcL@EÐJ1èh ±Š:vÅœQŽ94sØþ”´œgž´à}ÿ1GÍíùP3õ¥ç?ýz\¹£ŸJ‚i%HÖ<îÏÍž•2çqæ¡”¨•7/0É_QO ú Ó½!$w?.{gžÔ|ÝÎ)MÄõŽÏÐÒõ÷4˜Îpy÷ Œÿõ¨Ú3Í/±£äÐp9Á4c¹4ï½IÞ€´˜Çùâ‚FzÏcyúP~Ñǽ;§¥zPzõæŽùàS©9=ô¤ã¶)qïÓµžhü(ü?:\wÎOÏò Ëz~T›½Aü¨ãÓò¥ã¶h×>ÂŽéõÀ÷Å#¸ü( Á翵&G¦=Í?}áŸAFÓÿë òFr1ìhÀ>äS¶ú₤ô È1#ÐfŒûîhRŒÿ] ã§Ô»xàÒr)x=ÏÖ€}/áÆŒýqFGlþT„z€)G±ö4¸ô4˜äÐ0‘Ô$ó“ô4»Aç9Z=°M üGéš8Çÿ*L¨=?J8ö;ŠP1ÜâŽCùQƒžhëß4pJLz8=r~´¹#±4dwÏãI޽¾”t<ç¼zçñ Ï õ¤9<Œ‘@9éœÐàãµÇÿZŒ´›yÏ#ñ ÆGz0=èÈI͇¡ )8#¹¹¥Ç|A>Ô›xè:0>¾Ãš\sÀæ‚;ƒ@ À?*8=£u£¿·° è:Rcއ¼{ƒG”lÇj0}hêr¤Ç'¼õçð Œuñ4ŸŸåK·Ú€>”`j0:`Ð1Øæ€CýhÓ9ô4mïŒ}(ÛŸS@8ä L¥A¥Æ9Á£ ­øÍ&jv@=èϠϵ&ÿ^—èi9ïF¥OJN{RãüæŽ( š1íøš¤Ûõ Áèï֌٥üy çך^žÔ˜¾)qÛ­û~TŽÙ£ß­Aìh=öÒü½G_aFb€‘Ú–€¦( ÖŒ‘E…ã sØ(àu4~TQèsIøÐþP´¢“€z^OjLPhÏ×ð Œû(ÎzQŽ1@åùPÇZ=ÎhíÓ4gŸz(ëÿë£#ÐÐ\•F d)Êò®vìö<Ó¤lFÄd5¹,™'$š}‰È>´cו tü(Å! Ö›Kר¢€vè(8ÀQŸΗ#°•ö Bd÷ÛGÕ³ô4£¯Å>äP10@£Ÿþ½}©p1œ~=Î3ô£ëŽhô¥æúS$sÈ$ãҤǵG1eQµ‚œúg"€0Ïñ¥ëÐŒ{|¾´½{Æ€è3Z^N=©ßP(Á Bphàvý)zQ€{þ´ Ný1FiF(ã<š?Ï™ézŠ9ô4dú©?Ó±Åb€ö¤ÀÅKŸoέ÷£ð¥£ŠAŸj? 23ŒRóÚ€üô£õúÑÎ2I£4‡éF–{PËÞ㸧S[€hȦICydœ1RqÉÅU´`ÄŸŽüU¬zôô¦ô qIóš\ÔR˜÷£ŸÃÚ—ÚŒP=hÆ{QF=:OÀQÆy¥ÿ=(ïÇ4¿ç4­&ßL­/N¤ÐŸj3“Å÷?•#ýÂvçŽôØäYWp^ôñƒëš‚Ї‹#“Âô©ñ‘×?Zƒì‘IJ\qEê-ëGã@ Áê(ê8£§¿ãG^Æ€ ?G>ôŽâ€·4ŸAKA怎ÜKÇÿ^ŽJN™âŒÒàöüèäw4˜°£=(ÀëÎ}èïÇ4b´¼úcëJ?ÏÜqí@ì:u'~s@sÛgÜ\OÒû®~‚€ŒŠLd÷§}h§§\Q…=qùRŒR’£¯ë@ ôÀh÷ííKÁ΀oà 1þsKéŽ~‚ÀÐcç`uçëKŸJ^h¸ÏjP8¥àúÑϰ Ç·ëG=†?ZN{ŸÒ€#IŽê+Á§óéŸÆ¢Š7Ydc­ÐŠŸ?ZÄü(SKùÒcŽô1IƒŸñ¥Çf€Jk ßڟ׵A?˜?.0Üòr8!’{cõ¥ÁíNÉŒR`zP Á=£r1A¨Èé@NyühúàRäRd÷àPóŽ1šLg¨Å/Z1Š Ñߥ–~”QÒŽ{Š1Çz>ô}(ü3KøÐyøuã±¢’çï¯ÐÑH GáŠ2=¿nìõþT¡‰÷¦óýê8êO4OÒŽG9 Aõ£òÅê)x€óÅç®Ö—îOÖ¿äP õüé6üÙàš_Çò£ç ©™ä}©7(³ {ÒÍvm‹–&– †òÙK:ü½yÎ([˜I@eúgŠQmç=O­8@¿.O+Ó=¨Ð4"kÈ ŽÀ(m¹÷§‹˜ ù{Æìgž5­"pA@AmÇ©¥{XÜ䧦œfˆ2ƒ2)aÀ'­Bl 1ù{ÜzóMu°h˜º<ãž¿Z=ÐМ\Bs‹” G5Ä*¥¼áùÔ aå²Ç9'8¡´ÛgtŽÜ=ÐМÎÊy 3íŠOµÅòfEÎÔK§ÛÇ3H†#x§ 8•#Vy¡È=ÏåGºˆ@|ȹ^¸æÞ[‡g]äd.y4ϱÁûÜ«'\ÓNŸk¹XÄ7(ÀëBåê}ª,n2 {ž”5Ô!¶³€}3Qÿg[ǗǦiVÆ ì Ž›¹Åèh<^C‚DŠ@=šœnbÜTȪG<šì6Û…c’6õ4}Šß ùc `Qî‹B_>Äy¨X à0éQ­õ›íÛ:6ï»ój!§[«Ãn=I=iÿa‡}ÑÍèhLת–2"…8944ð‰6™6ÜãpéPý†˜„“’E;ìù…ö¶Jí4´ -Õ»(q:0'œÐ×Vë»2 ÛךˆéðlT)ÎëGölrüýriû¡¡0¸‰Â‘ ù†G4‚æÝ—wš„gÏzˆX[©\oÂŒôÃi Å@ÇZ¸!Äi¸s‘Gº’BÌ„CÒŸæ&â¥Æà2Fj¹°€«…R…Îã´à敬‘¥2FWi½-Bs$xæDé’9¦ ˜Hÿ^„g{Ô §[ˆâGÜÞYÊ–<Òµ„G~ÆîN)û¡¡1¹…FLè0qËSŒ± ºä žj/²E³ ’=é†Âß– C‚ihùñæ0Nÿ»Žô<± $ȃš…lâ_/ŽÁŒzÒ(Ê:3³9äŽ=ºSv üØËìó¶2@=©{l›N€¹Âü£6vù$ŒpzR›8YÙ^Aõ¥ hLgˆ¾>´ï11ãâ«}’µ¶¸ÚrqMû F"A}ù “š4 FxÀ$ÈŸ/^hó¢;pà†èzÕo±Ä%y0ĺààâexØäÆšz…„ž& ï\“€)|Ⱥù‹ÿ}U&Ó!1÷Èýù È4å°…d2)nh÷CBÛKjÌî¡Te‰#ŠA<_(¡-ÈäT"Ò ¥Ib`ç½4XZ‚Œ!\¯CŠZ…q ‰dà|ÓCÜB…ƒÌ€¨ÉŠ€ÙBP&Á€Û¸¤:|,aÀ~¢BÀž,ª‡_˜d Ò ˜JäH¤gj!c(ÛIdšwÙ£*²@”-”jc¤>XÆIäÒÐ4-oL€]yé“Lk˜YÞd §i%»Ô?cŒ+ducüG¥a‡nߘ~4h<èÕÞ2qúRˆ¾\È¿7L7Zƒìhgiw6æ]´ñj«·%ŽÞžôh}¦"¥„‹µN ¦ÛpûL£$g=¿:,bÌÆÿœääçJy´„à2g&Ÿº­Äd 63íN2ÆËŒ“Ç5[ì0–Oœ:Œ`1¡tø/ÈNÖÜîô{¡¡cÏ‹‰ Çæ& Þ¤§=*“i¶Î% ®¢^¸n”ãa ÀÜåq¤æ–¡kÎŒœyŠN3€Ôž|{Cy‹‚pjºYD™F Ç&c¢&NÔ9 ~èhNnbÃÃå88çÿ5åÔqžµPØÀÞa>c99nŸJSdŒå²ßwn)h~Ñ DˆCýÒZ<øùùÇj¨°„,`_N ÓÐ+#É#!lãò§îBßò¾bä ãwjP錇=j¨±·W.ªÀôëÒŸöH¸ùÇzZ Bfš02X¡¦ý¢á<Á»ÅFÖñmÁ-ŽæZ@N@#>æBQüÑötÜŒCe:4 ý¢›¼ÅÆqœ÷§ïLãxÏÖ û:í g“šF·VûÁãF¡0–2ÛCŒÒ‰SsÀªßdCŸ¿ÈÇÞ¦-„K1ì" ƒŸJ4 Fâßæýôy^¼Ž)D°œí‘xëƒUÚÎcžFj²U@gNF8Å)´Ìg.ÿ0ÆàQ hK©÷YÑ\ •ÝÈã*Sæ ÝÓ-Öª¥„*¬$°ÁcÖŸö(B(`~^ôh= "T'×>™¡Ì£ÉéUšÍLj¢F\å3Köe3´…›æv‹!hX¤gx#¯ZpÚÝ0¦,!U—ÛÓ¸¥h>ì’ßThðé‘F@€µHYˆÆ²0%³Ö•ì¼ÆæsŽœÑd2?Ù£ôØl„ív Œm$àRÐ ¤ØÏ'µ&õäîyªifÂu•¥v*äö¤ŽÄ$DdÈfÏSšv]ÃBöõ¨üèÜ9ûÕF³VódQè f¬8’@q½F¡l°ßÞ“pÎÞþ•Cû0=¼Q¼®J6àjgµÝ#:ÊêqÆJ4î²=¨ÏëØUSiÃ,€0ägŠs@Ìc>aP:Ñ hLYˆ ^¸=)xúU°biLÃyäŠYŸùï!\p3Š,‚ȵ‘ëHpAã" [eYw‚ÛŠàŸZi´ï#œRÐ4k€$"=€±ÎFÚ±¸w#5PZ1Rvc“ŽqÅ"ÙˆÑÔM&[¦[8§ ô.ƒÒ°Î8ª¦Õš(Ñ¥?(üé¦Ðí¿¶y Ñd- ‡Žr?3Û"¨¶ŸÃ6æ äƒO’Ñ÷,¤c¥…¿ÄPMRK6ŠE)&«.;úÑöF,KÌ[ •ã¥]ÃBï##>”c>˜ªIi¶Yd±ó ñM‚ÀÄNg,¤}Üt>ÔYw àvâ“ u#mR[IÄ` ˜¼WµõOìÓ‡¾ÐX†Æi>Ç&ýßh?{8 (²îEÜÜqJ Qk7“ç2ò:u©ÞTvýïîöàÏ4¬»‹BÎG¨£xìj¢[J0|îqƒšE³q€g,3’ Ó²îEÚ}j¢Cp‰ ŸºM4[M· prz½iYw r1ëI‘Žj™³b¿ëÛÛ ÓéM’ÎG· ÉÜœâ—pмX —>˜¨}Žo4±¹;HÀjCÙÂ\¸î¹4Yw "Þ>§ð £Ò¨YŒ‘°¹?)Ë ½i‘ÌÛ¦$I÷r +.ádh gތԊ££‰<Ƹ%Ší8\S¾È[hwÈSœÅ]ÂȹŸzNüÿ:£ö#äµWÉ0ÄŸ'9R)¿g,©›/œƒéJÈZóþsFj«E1uý÷ËŒ?šÙÔ(2d/L”Yw "ÎáP\m/c sÁÏJ e2y‡‘€1Òš–ò+‚ÓIäP€²Ç–iAÏOÐÒz:H?•! òŸþ½>œ}i8?:7~T§ê ÒsÿÖ¥È#œÐO¡£ð`c=©h3ê(Ï¿áKƒI@Ç­§ÿ^Š9ãš÷4~´{â— w D}~†ŠIÈÞ¸ô4RñÉãùÒ1Í;'8ýhÏ8ïLAÉc<‘©£>üÑÔö éK’;ŠÐ8ÁÎ3ÚŸÏjvxëI’?ýt ú23èhqïϵ=i3Ç4gßò ‘ëšZ'‚3F9ëƒõ Î:œsI´zÓ³Øã™ãÒ€Æ(ú/ëKŸ|~4`ýhŸ¤Ç<NÆ =³@ÞÔ˜ÁêhÁ’¥S@xäóøÐ>€ vJN}? Ð0ÇåIŽ Œ{ÒýM:“øP!µGÝ¥þTÓ‚yæ‹>žÔ‡ëŠBþΗéÍ€8Î)O>¿… Ï|géF}I nip;àÑž:š^=Oó ÎL})¤œä`~âGù⎠šN£$š\‘ÇsýìýEõbh£tÇÒ~£ÒŒûøP0=?ÿwó¥úŠ3éšBxäKÁäQž(Æýt:Qa@úPHÇøPϨ¤èisíô£JCÏsF?:_ÒŽýs@ ÆhéÏ;=(äPw`ü¨ùºqNüO4r=Å0†ÏQøŠP3Ü¥;ëœzQœw ô#êsHA8æ‚;ñAç¹ü(þÆŽ½1š_Äþ4Ÿˆ4¼ŒŠLúc>”p¾ƒð£ƒ@ÔQ´g;I£žÙ£šLuùFir@õüi~nä~‡Ó9g®i:-/Ð NqIœuÏ¥'ÿ×FyÆhϯJCì>¼u§`zœÒõ çÔ‡>¹`‟Ph<ó‘ùf—8#éGáùÐ12{\¶: úAg8úQÏlÒÇ~”qëKó{Š^}©€Üú L{ÓÏÓšNzçÔ˜ühÇzZ0:ŒPŠOÄÒãéøQœñÖ€>ÿ™¤Ï¾iØý(ëÖ€…ÎsÍüR•Ž1éŠáψ¤îOæhÏÏÒŒ{Qø~9 ?J^£¨#Úš3ØŠ\ŸP `ÏSùÒàv¤Á4cñ @sëŧ޺RŒÁǵãÊ—?—½#œþt~T€3ïIÆyëëJI£“Á ¨£ŽÄQ×¾)OÔÓ½.@ëIJQ‘H8ÇZ\ŽìhèsŠ3ôÀOÈÒà£õ£½Êâi1zwçôÍ''µ7Ùý(Ú=)Ø<Ðzw¦qôÇçFQJ =óõ£¿Q@„ãÛ4)p}èÀîOå@Ã;QלRp)qíŸzö£¸Í§4„úŽ}¨äöñÍäŠv;àþt™#Ò€†Ã"—š3‘ßð Àõ"€¹¥ãñF{ÿ#@ÓÐRûqHOMã­zRñI–ìx¤ ~´^;~”›ˆþÖ‚iAô<ûPF{ÀÑ‚?ÆzÿJ1þν. £ëŸÀPéh´c¸ãÞ—£ì:CŸ¯½qã¥/N¤Ò|§¡ àñŸÊŒ{ÎŽ=8£?äÐøÑïKƒÞ“ P~žôpGQŸ\Òç=E;@Áâ‚îi2;’h 1À†åqõ4d‘ÓjNò¥ëŠ¿éA#Ö—4r;Ð:ç£ñ¤>çúRôôqÿףŽsŽßΓƀ·j´‡ŽE.8ëš8ì>ßQ@>àÔm P0È¥ê:Óu‹Ø(cQÛpûLñ‚z Ñf'ïÔRäýiÜ29ô¨Þx¡8‘ÕOÖ€%8Ç4} 29RD ©¸9§ç×4~bƒ‘ëLó¾ÐA=8=)NTn%@I gß4§çLÖP>”þHühïF~´×u73`})¢d*[x+@'=1øŠL})¢x˜.×=¨yQ Û@ÉìÂöœgúQÓ¿åUVúÖM¥ežpMZÔ4Öá`çýª=³ùÓ$‘cÚ'Šz°#+‚=sH8?Ö—¿ZŠkˆàPÒ62qÒš.íñ‘*`Ó³ ãÓ­7±¨Ì±ˆ¼Íãf3žÔ¨é"–FÜ=iXãßÿhRe^ÙGÔbâ(üj5ž‘0{ÓÖDrB°'ÐQf; =±KŸcL’D‰7HÊÞ˜.íþoßG…ë†éE€›üóGN晩4{ÑSéIÑ9eGœQfœ‘G’¤q–,=ñQI{o±FòÒTrsM&ö x£ðFzþ~t„ÇQúÑøŸÎŒñÒŒŒô ýZOÄÒóØ Rt”gŽhcµI8ÀîiîWoJýà÷÷—ƒÛz8÷Å.ÿëÒ~ŸZLŒŠ;žÜQ¸¿Ê¢ûDl’3j—?LQa‡ãFGzk:)²‚zdõ¤Iâ“$V=p4áŽÆŒŸöisA¼P9<·çNéÉ4œŸCô •SÉÆi½}¾´}i¡Ñ²ÁÅ/j`)ôÍ!'ûÔ¸ÀÅíŠJQõ¤g2HÅÔœdn=³@ ×Ú—‘ïE1eC®Óƒ@úÒgç4+]ç½;Q@ ÖŒÅ.=ÇãIÓ©Åöü¨£9‘F8ãšÿ“FOqøQŸZA*‘žÞ´ ^Iô£}(­¬:àÒ1Uä¶1ï@>´sÐ jÌ…€W‘‘Í8ò{†QÀ #¥f€ |§…'Ô Ú;b“Ì]ÁK®ãÛ4ãõ"z2ȤÜ3÷€Ï­ôÀ¥ÇbÔŠÁÁèpqK\f€ ¸üèÁëš0}úP äi9÷üM(tÈ£œòxúPj0zRàLýh9é·wÒ€ tü³KÎ=(ÉÇ¥cõ ´ŸE#ñÅq×ô¥ú{Rõh¹Å'á@`OOºÓŽ(;u£â—MWVS‘ô4¸õþtcÓ?!*XÐ3·#ž´¤c¯ëF8 °zQC@ žØüÎirqÓ?œv¥Ï™>” žœ~”dçÅùühÁ>”Ÿ5)Ò½3úÐø~”tõ¥Çµ(¹ê9÷éK·ÿÖ)Ý}Eö&€ë×é@ÿëÒnû­K’;P€=(öüI úñ@ ñÇàhç§Ë@ëÁxǹ>”cŽŸ•‡çAòAüϽ'ÊlÑÁM/J;q@ Ÿj^i;öü¨íÅ:“óZ2:RgÓõâ€ÄR`½~”¹õÎ=E(éÔÐ1?ÂŒ} _¥¤;ΔýhéFGµ0+Ü}åät4Qq÷—èh¤»âŽ zÑÐzSAöÍÐzsÖsØf E.=©6ŸþµØ 8Ç"“Ž S±ÇZOÏó ã¡¿@µãÚŒPd˜Ï¥—õZå£ܳ6O?/ Œù¬wL¨HB*ÌndXŒ9\ô¤Š‰HDàó“UÒ8­'b¨ÇÍ9®Z{è=Ç·ïæhesNx! ì!Œ¶ÓÛ­8B‚c&X1ŒñR1ù[©Àþ´®+‘Ã#É‘BÓ«ª­ÅÛù°FPµSB,*“¾éW<¶ìÔö¥M¸ØîÊ;¸æ«ÌdhM¼»>T pÀŒT³´€Ü~µÚÆv´›Øtqвàâ€(Úº½ÓƒhÃrÝ3ïWÛvÓ´|Øà•LHz6ùªÊqÏJ¸Äl!†xäÍAd%X6¼j¼äm9gžÃñª¶^^Ö„`ó¸VÈÿ9¥-Ä÷"š• ºäCQ­¬jÚ#â¬{Ò3‰ãÖ•À©,qÃåì·ÜrTv¥½‹ro[q3–Y&k…‘Š0Á_z}Ò+¢ä¶C1UwqŒ’%Š$VÑï^B¨Ÿ´‘åÔè >2†yõëTíü˜ZR‰ 9,Ù£¸¼óv,(Ì~éa*kbÞB†R¬+QZ*—yxùº1ëHQ-®a’e ØSò!^15ÙŽTÜ›r=)òYBð²ùsÎïQ ê.»_ÌÀ=ñWñì)6Ò@Ê‘nh$F…WozR[‡ IŒ ìJë” ’;TVȨWvMÔ^÷sùŽw‘"Ü‘y‡8ÛÒ¤=: †â>=»Êœƒ‘R"(ìãò°Ñ€ÌrNrE ·–1 k¹‡j°ˆUî$SQ\”R›Ù€äaj®î;‰3K¾4[pêßx–Æ)ÂÞÿ–(3Ö™5¢Îð>ö.@­Y8žžô7¦€Ê¶þds¼"HT ¸§FW4„Fr§­6#Û¤UÜ[ê1EÑŽÜý¡óÔ zÐ܆–eíÖKfya‘I2Dñ¶À|¿UúS Awt¡w·9íRÜG¤’œø’æ4xL‰Î[=)^ÎÕáhºn«Œg)Ìì·ˆ¬NñVºsMìQFÕœ¤¨ð” p¡²NÕ%ˆo ‰Pò8>õ<€4m¹˜9Áæ¡¶P#R¡”cæ‹èš^sÀROÒ“¹?"EéÚ“p’1êM.):p?J©º½ko†çw#ÔŸ¥Tºmì‹æˆÙ[<Ž£ó© •g(I ªkBº <Öf„+‘‚Ø÷5`1Æ*¤Aé°Òä¯+Ø{Õ­Çi11Ù ÑœRdã¯ã@ϱ¤!Ý}i2=M'èiF0Æ€ ú ûŠqš8éÖ—Ò€¡4~¿…(çž(ãÖ‰ŸsøQŸsKÓéFh9ÈÅç¥þ?J2;u éFsÛó œw¤Îî´¿OÒ“'ÿ×FÛ?Z\úPdúŒRæŽ}3F}å@Äú9õü.A>ôŸZï“ô¥È=¿:: N;š/2?:L{“FF?úÔžù#ð  ·3˜æ ´”*K§šu£«Ä¬ˆP‘VsË|¸æ¡·¬Ab}ËŽ1ÒՇД‘üTd¥/פíÓ"QLH^9¯z—ÐíUgÂÝB|ÂxÏZkpCv"Ú‰Œ9!~é¬Å ’0ÀmúqÈÇ_¯¥Wˆ¯ óCò?»N÷Ë‚²\ÃÄ]ry?….Ø­®P$$§‘’:Ô¡±FãžjY”4ŒYF:Ñ{ÉrOn(ï“ÍG5òq×Ö¤äv˜…Î9£9¤Š Ÿ¥/ëIô`~˜£§j$ÐG­¨üé8ÿõPŽsÏáH@ÿ*\“ÐQøæ€ŒRôéšõÍ&HþlŽ#‰œ€2iäÒqî !”šh§Y‘Š6 à½Ö«]6–“=“š±ï×ëTÁ‰+”ŒyôÅB#YÙd`C)Èã­m9”!ÇqŠ˜”uúæ¨[$àt¨Uà 9#¦qš|ÏBÍ#rõ6Ý­R8'½,Ih^EÜÞcs¹‰ÅZROÍÐzŠR6òvóÚ–,ùc¿Þ€%ÝøÒgÑGÒŽ}û @U¹uÞ‘29ÉÚ)$†;yR\×ÜS¢%¥ÞïàŒt©_hCÉÕ^Ã1†aÛÍ6TÜßëYy/J ©¹ ]Éî‚qùQê1[Gæ,e˜ ’GZ´¯¹AÆ2)î21ÔSanÁõ^â%¤Ï*]¸!÷Àüi^êâ8QDƒ*ÇnFÐG,£;—¦Ü æ¤á¦8szv©Ž}iÞÛÃc”ɸïPÌË4‹$2°9¨f>i,GÜþ´°)ÎòÙ=Û¥#Ýœ¨£'Ín¤ÕÜúj†A˜Èè·P"P|qžhz¡nKœ÷É nìEO|Š]§×ò¤!áN»ò)?)xÿõÐéŠÔQ“ÚŒzО}iHu˜÷4ùê¸úPCAÏ­©Í¸úPmüiÀýhç¹£ŸÿUçüi8éýiyô?4dp9¨fadR¤î8©½³ùÑŠ¯oµÏ™m¤cŒU­@˜Y¶ï'¾6ÿZ›Jll¥ŽO1 ?)ê8Å6ƵR¬[“Ø­O(&27í÷ô¦[s ï9ûÔtƒ¤Mãjm<ÈÙK¸ÈÇgéùÕyçU%Ês‚E EX3ݼ9pðí9óZ]zæ€IÁ÷¥íÆG½6î O­ÂŒäw&šà•8ù[±4„VB—_½G*0WÞ– JÑ£3Hݸš–Æ<³=ÊŠlà˜ÎPtû¹§äQ0öÆ*³,rÝà±Ý³Ž*IeŽ$]ÎîÏZH”ÃéYIùÉ횉Çû&ƒ×üi•†àÀcN$˜¤} 'ך_Äf—œP!>j1“éF¾iqèh)]cÆ{úÔ0l2ÈVg%\‚¬:U¢0=?¯3²ºœ±È4ÐÑ``ã–Í/N3IŒv¥ö! Ç\FÞùïÄR‚€ }hÇá@ÁèÅúÑø“F9£¦húš2PGùÍ`u£ëIŒq“øRõí@ÂŒúFÜ{Q‘ë@<ã4¢“ñÍC?Þ_¡¢‰¾òç® €vF:QzL‚y£ƒéLBçŽæŽ¢Ž1ÖŽlÐŽzóGÀ¤ÀÏjS€2Oâ.Aÿ O¡çéKÉí­†):ú~T½øÐO#Þ ”?œ Ⱥ@5däu5ZàȬ[ŒsMn4?ímf&ï{T¼2K4ñ€HØ7c5(¶„#¯’НËc¹¨Ì “ÇåÅÑÀçÕ®5bà⫼("ÞPu .^áP `†Lò¥HÕy ž¸¤!’#3 ÄuÀ¥·Ü!]ì¬@ê)Ò‚blÜÎi¶¹È‡UQý(è1—K±“jáÆy« ʃ’G½ArЬc'®ÜàÔüç𣠺Í8+"ìÉw©[NÓŽ§µE‰>Ð6¢ÉÜÙäTÎ@SœcúPÆElĦÖucþÏ?­OÏN?:§c»Ë;ÑE[àwKq1ON•^_5åTˆÆT­R2}ªgmˆ[®OZ«o ù3BQØäûл‚,¢Ð"¨P;(¨î<ͨRDæçpê*qÓÚ ¸RQv¨s¸uÅ p$Œ†@À†÷V5tŠ@'ËHb:U¤ÂD3€\Ut˜¦ ©’NÎ84ûŒrH1+ÞÊd³.èœH¡ Æ ç?Jz[¬ˆ¾r!eì½?*dÑùoÈãÁlO4Õ®\“æ7ïÀÇM¿Ö‡ŠvZ96ÆHç4™ÍÛXò1’œUƒ‚:çJö­°¹Û(žDvÝòàýÑR[]ë»qÎN)–é"G()wmÍK@bTOcšž;RæŽi1ÇÔ’#²Æ»˜€rj²¬Í>X£DI##‘Ó¥fî2³ÆÃ‚9iP*€8 §±[*)eDýÞõWnwÍ>gdO‘w?eÎ3L‹çE’H‚JzŽ¿­$ ·Ò1æ‚ÏÜœJK¹( 9Q’ÈÏ56O~*¼‚I. ºo޾§ó§»-¬xgWsÏËI:ÿ¤D|͸ä=NzRùfaŽ=§9Æ>”\Ç#K¢ƒ·9'Ò«wqõ,ƒòŽJZE$(Î:v¥ÈÎ3P!iö4~fŽOãÞ÷ŠLqŽŸÊ—üñ@åJ'ùæŒÓ4´„{~´uêh=EhèzQGç@íÍø£§¯4~•õ˜àS¹ô¨åUxÙ]7/q@,RI1iÕSòâ§|í<¨÷=*+V ò2 Ä|Õ3Œ©ÂƒM‘Û+,3«{©ÍKœŒsPÛDcŒ†N{Ñ3Ì’F«°«g%Žà(z°{Œ‘\\e% 8Ü1Î9§ý¦ÌÊlÓY§?ºB0>mÙ'ê1N[(îÜœ±Í=-¨Èí·% ë'?)R3zF·ºYÝ¢‘60sO†7I%+*žœu4ëW¢xUnáhó@AåÝÂP¼‘”—l*iYe…Y$ *iA16Õ qО V ‹XÃZ§|¤ð(½Àž2J óî;Ó$Ò R¼˜lò\$ äÀ “Øð)³ùæXv¢·ÍóðhKPê ÍöІDnvãš°ë•S·å>™ eOÝÈ=­=×÷gÃÖ£µP#lB±Çî¶sK †Ý3¤ Ѳ)ÜdT±Ñƒ•ä GtX[¹TG>Žx©#$"’0qÎt„RåÀRÍ!sçí,›1ÐŽifÉš2"Vë’OJFgûHa^´ÐÐ<‡mò"¡û™b’ÎI¤Wóž6*Øi×0,Ê ·áã?­:Þ-ˆÇÉD% G@èKŠ9=þ”ï|qíIÇÿZ¤’©‘Åâ¦ø¶x?z–XîÎÉ‚¡€*V\Ü®` × ž‚§ÀÁÁçÓÆRµy_í $»Ýä Tö¯¾ÊÀ¦*8/p6D ž6õn;Ó¬¢Ä ¾Êr)ŒµŽ>”c?ýjLßžÔ¸õÀ©$OóÖžÀS±ŽÏãFÿZ€*º“r ‰Jã³ÏåH¡›j¤iý)&\Ü£$a¾o½»8ÿ ’â-û$U˦p3ÁªèŠs4…Ú2‡óVF;t¨m‘J *ŒG ŸŸlzÒbaŠ=(÷ÆhïïHBç°"—ÜãÞ¼€?*6Œäþ´§¯JLQG§òëKDZ È=(ÏfÏ×ì§áIÅSF®)r}(ü'×Ö”ÚŽüõô£“í@ÃŽã˜^ÂŒôü¨ÆoÆ ÆzQŸjN}hÿ¾E=éy?J1ž¤Få@Àœ{ÑEw Aøæ€3Ú©Í&3Ôçé@ÅÀíF)2FßóŠk(ÚpqÇ¥E 1œã½Lã(A äTvñ,iµ}:ÐzM˸ŒóŒâ´UiÁäî*§Þ€DÙ 2ªï¿í*2›錚–ݳ °df™7úø–¬3ËŒSKQõ&Æ;ÔQ‚@Ì鎵1#  UXA[©‰L)Án9¤„>݃†ý >`|–”SPÙ†_7(ï=nÆ¥ž=𺼎˜Ípd‘çbòGJwÍQÀ…AR§©8õ… cÔΗ>‚”wæŒÐ{óG>ƒó£åÍ/åŠôÅ&b?_Ç“î§ð aÏqÅüQߨÇåG㥠“éHG?ýz0^´cÖ€¯4¸ 4‡QÁöüh½ÔbCÞU>õcZ­rcvQH ô&¬œqŽEЯ)}ÌVn¡XÓ¼É2€¨ø¨ý%Ž8þï#dƒœŸlP0VIÚÊG±¦²0Ûåœcµ6Ø œFê3ѪnqÖ„@Þs#n‰žp*X×dav…öíM‘¸ÚÊØõèÐGÐXã»Ð²›¶äg®3Í 硪rí,ÌÑáNoõ«Qn1®î8ïNÚ†D›dc…äóµ³R9ù ÀéÞ ŽÒwdŒå›$ã½NøØr§§j@DIçb‘Ÿ^*UÁЬå~Éó$¤uÀ?5Y@ ƒÈã¡¡ßiÁXñŒƒŸš¬{ãóª³ûAA„—ÙÃÓÛoŸ­6 äõ­/>”`þ„7ýzQÇaGåF@ ü) y8>ô¤Œdâ«ÆÆå e(A#4Xaå´²"Fõ¥*¦u$ËÓ6ßpMW#̸Ë)P§©šNÀí8çëL‰p„d{RÊBÂåWv@3L€.Ýû0[®W€“*.~b24 œsΪL„Ìv©ËÑOÛŽniÛ@¶‚0&le}}êA×Ͻ@J½ÎÑ ™R>fXÀ?xHU\;·c Ó¡W —Jˆ/ïžSæ³îóš–ßqòØÓ­1pÞY ¹Í:$)p}é~ësÇ4°®ØðÙ¤!øÏcùÐ>†—¥(úf ÛFÐ=þ¦ùR} ~u¥çÒ€ð£îúRóIÞ€ ÷éFISž”qØ~4gŽh¸>ôŸQùRíúÐGµ&;Ràq͘‡§CF)Ô™ˆ #ˆyÌæ<c;Éý*lqÇÅæSÝ? “Œ‘3 ûÓ-”F÷zSäF‹ñ¦[d ~iô\{äTmmb¿¨©};QÇlR#Ž!·ýꛨgŠü™äg$Ç1*ÍŽÀã4Æ;!‡=©’‚3ŸSU‚G Ä© 0-ž}ýê܃1°9Æ:c44"M±€8úlÊÅ@à÷l~´è©€)—+À’2ëôÈÍC©ÿ4‘#ÇFORüƒíRN…à(€Ó Hê¦e%íéƒÅG4¾m¸ýÛ’{ïE†Y ¯#ÚœëœÔpHv„`W¨5)ø¡î& J_ÂŽGj9Ç€ŒŽâ“éÍ)´u=&qúÔQG¶Vm€n95?áU¡@’¾Ôa¹‰;h±‚(‚Œsš=E‡ç@ ëÍ}hÍ/áúP`(äv£-è??Ýæ€ wÆ)y¢›@ “èqøRwû´qž¿˜£Žø až)*;p¤Ï!@ ~´síIõÁ 9 êK©ö4RÊrËÏcE “Ú—Ö—9<Š)ˆ{b”ÞŽ1è=hOOÌPûb’1þgÿ×KÈíš^zRc'ùÒöÇLÑŽzšNqÀ¤ÀèO?Z^žôÎ1­!t{šŠ`7s׊ž˜Ê¬FTsÍC¶Œg¨& ç¦G&§ïÀ?…!ëÏ_Z"¦Ø¡ºyBï€y4õ½ˆ¸F$3÷ O·'$އ»9Âç×èŠÞæ;•fLáN9UWòl¯w–r÷çUÕEŒaNN)J+J‚Aà‘Òši1_R¬)®]”ÈY@Èbv󞟕>[Èà›c©.sS„äÉëŽô»AÿõR¸\ËŽòØÜ Qå*X–ùN=*Üw0Ü=ÄyùcàOJ°Pq•_Êš‘Ech…ŽXªà“ïM´ÐÝÛÀ‰µ_Aþµ!¿‹íMoüaC`úg?•m §+‘Òƒ {‰ò×'©ÇZAtW’X®¬Ì¡˜'ûËoÞDdö;EB)X<þùÆîpQN[´3IÆIÛÁ©ŠA*¼t¥ p g¯hº$ž9v… K ýÚ…–õ³…Uã€jÐ §¡TgjõîB¹Vé0DäýÏ@ó¦ÎÁÞ!ÇõÀíW äFAìE€Uqô¡Hw+-Ú+Ã0|št7‘Í'”mÜF:T¾L{‰¦ï\ Ñˬh¬ÝH&‹¡h?$t¤ùsŠ^Glþ4œžô¤!yJ}8£AøÒt=3@>¦Ï4¼žØ£ê´qGâM†>¦ƒõü¨úQϽ5ó´íäŠHË‘óð}?8ïù÷¥¦çÔõ¥çÖ€ƒÞ ¸mçÊIÌruãÇãSã×ô¦yqùžfÑ¿ÜG4 xœŸSÞ‚ ÜRÿ*0{P" -#),…›¯<æ£wŠâîM†\¡O?](ŒrÁsŽ´mÏ€ªO¨îTžHmfFbÁ¤`€}®ã"›µIjäwÅ>•Á•a@L©™:àäÓc l| å˜1ÔV¶¨$Éô¤Ú¹ÏB{Ñp¹ËѲ‚Hä¡í÷[¬{ÛŒ~51 nHéÏJu •MÜin\³pqÀ$ÔCmœ›÷ó˜rGJ»åǺ¸íÅ)E8ÈÏÖ‹ŽåfQáÄ’’)â4²G“•Ç#Þ­2©ëƒõI!@Ï\´] åXÑÑñ4X¿¸úSc¹H¢ˆ4ÅÃ`#“WJ)]¤=)6.Õè=)Üw+}¶ äàgš²¤2©óÍ.ÜõA‘Þ—Ø Z ˆO§ëF[£üô£©îi­#pÂAû³ÈÙdIö²w]Ã#Š˜Á;Œk¸õ>´¢b‚ôªº*è~A¹‰Ç|b’G‹)÷;TÝ:søÒÀàb•År´‰Oæ°cÐu㯥YǦE!U8Ê®{f”cñ¥p*Z¬q–E³'šµƒëùRì³…Ï®)yîJmÜÇPÈAÎZŽÝSa(7犜ã¥5QT`p>´„G4fHÙs‚GÅ4:Ƙ$’03ÅOÅ0ÅuU<ç‘Ld%‘åPì1Ö‘š?¶ËïÙœ`â§3aJcƒ 3Š.£­Amå±,»aˆ$çôÍYÁÏ_Ò€»z gÒ ŸÂ—J÷4¸Oë@ŠòáÌÝ€àM1¯c—k ¢­Éï¥!Ž2NUrzäS¸È#…#YÄŸ1Ééô¦DñAT³(ËU¼qŽÔÝŠn=⋅ƈ9p1ŒÓÔ« ­0ÃG¸¥ ÛŠ@¦H¤Ï`âiØúQƒ×ŠU¤©ÞÃ' üRcÛ4cþª^?ºOãGSüCñ£åF09üÀ Æ&Ž:æsÐæc@ ×Ò“žhÇ=¨ã?ýz9ö¥úŠ:ö4˜öÏÖ€ÇéFG¦hÂŽ¼s@Åü)})i?@”|¸ä¥'áKÏ¥/zÒqŸz1ƒFGµFÒ)VU`zãð¨­ÈH•o1ÀÉ$úTÆ(ÉÎÄ9àu£ËŒ6v¨8Å0_z’4ÇÜĨî1zSÂ…è })@H${@2(Ù#ÎæÇ&›,fE[ç¯.=¿* (¸÷!‡Ëg^W©QvFªrp:ÑäǸ§· À¡±•ž5IüÇf! ïCâIÐ åsV5|nPØ94yhvÕÝ^ÔÓE€ü)Gáù掽ä)0}çGzN?ZQþéZn}¹¥ëÚÊ‚h˜Ïo¦hçÛò£-ÓåÇãG#  ½}hÀïŠA×§áKöp(g=…úQÅ……5Û•ÚÔtÅ5€# 2?:Vºgt §c Çj°$^€®}é<” HP ü)D ÇÊ89t£@¾I<Æ`OëNóóÍ8€Àƒ‚­4¤g#¥21¦ÜÏ9¥y‘)à‘žjO©Í1áI)Ÿ­E•e»†‹?(©Áë@ØZ? ŠBÏØoÁÅ>0ë‡?694T9pìc4í¤zP,ÅÕ’@£# Ž´K#¼¨‘É·ƒ¸c­Jèa†i©JFezri¦1ÁIiÁ㨢.¡ÕäÜAã ©ø¤*ðÒ²›ƒdÔý}E"¢¢áFéK´h`4m÷?>”˜Áõ Bãc=¨Æ{QÇOé@O¸¢í óžô#‚ öíN’4ÀsÒš`F9äàc©£A‹½Iàb™:±ÚÂ@¡NN})ÂÇðôõç!Lðvàö"@+HVt (è©ÔmAÉÒ…‚$ÆØÐ08§ãèi܇‚ añÁ#Š +ýÈó.ŽGNiø€¯p“2$€Aç'SØd~¸©ÏQMX•ÏrMpDd@¼`IDåšLÇŽ OƒíMt0ý=1@°.ØÏCô©F})…Á§uì*ÇSš0£ä õ#ò BûÎŒûP=sF3Áü¨f¥¸¢3@t£h'ÒŒf€94tíK@ ß“@¥¢€@ÏÒ—òÅ LŽæ‚ÀgÞ—ð¦°}£"€¤îùˆö#4ðÀçæéÖÄ»Ãó1Ôб"–*€9>ôÉIä ÙÆz∘,d<Šõ4¢Þ wÐäàc&[Æ¡€@3šzHI ë&#iÆTXÃ3 zШ«–ËŒt¤ò#Ù³hÅ„1ìn8©•³p(XœŒÒ‘‘ƒH_Ì.­Iù¾•7nâ‘P ã4¿†(·©Úï“לP¢S;}Ó?Ô…ÄsÒ” Pÿ:Švd…˜>Ò;ã8©yö¤`=(#Ï–2Û¸ëNÒp:RóßQøñFh t÷£½ŽUXàzÔJJHÁØá4ç…ü†ê"ÅÀÀ9õæ„ä0#Ú—¥1QcåvŒõ8§`ØûÐç×d÷£ð¤Éí@…àv¤äúÒóô¤ÿ9 ¯õ¥ÇåIŽz ? 6J3À?•…#½w¥Í4àu4}h¿…éã4tíùÐn\ãš\Œã Éq@M÷×èh¢o¾¿CE $íԟ—ŸP)1ÿUôÄõ£äRŽ”¿Ê€œsGäE/¾(Ï×ò ãÓš8îH¥ÈîM/ÐÐÇJ>¬EóÎhéÓ"€·RhäšNi;ŒÐœ‘ùRð;Ô'1l Sw‡j[wFPªÛ¶NÚĹ_J\ÐTSKµ ‡Ä¨9÷«4êTg…\B@‘o¿þt½¾éªQL‘Êby|Çf8ÀéIæ ®E&ÖŒ2ç¸ô4rŽÅÞ£¸£ìsTÝ'HÁ3 ÁÉ=*e™0þràu#‹ ÄÃŽ1Š>æªIr’Œ3. ïÎjÂpƒ%Kc¨¢ÁbNqý(ãÒ³.h^Fž^ó¹w&p?¦Š)£;È_¼ >]/qØ»ü¨?•T7X BÉ×ÝÀ¨"Kö ùðmöúÿõ¨åî4ÇN9 çMgýžçÊQû¶;²zÖ¤º,0Vu†: þ”­æ-Ҍ֑{ÎË•$‘ÎÃÅXŽP«å¼¤\qÔÐÐX³øÑƒõª2 åIY'„’~PèpçH†æWȸB `…ƒE…bþqIòç§?J†%•b!¤Îp}*£›Èá‹|‘y›þc‚£šÔv4²:`ÐMWÏóä21œmÅ2hîšeòÝ?^ôXV.zP~•šZæGeE Ÿ—ûßMo±®—{{ Sjñkð.z§4ò<é,)ùò{Q ¯äòÇ—9E&•…bæ>´t¨f›dg†<;ÕañHs2‚­—Ò„‡bþõN'x¦uš]ûÛå}Ú$”ÛOæHä£`Çz,-ñïGN*9¦X£Ë6Üô5™:[³´ÈÛ˜le¥aX¸1ÚŽüÊ™âŸ3|Þ S³ØŸÎ€?ÏUÇÖ“$zfŒŸLš.Ð;QŸJLç¾($g½.}IúP 'éG^´½‡?Z=ð)¾hÍ.}¿Z3žÜÒ|ÝÿJ3ë“õ n{Rþ’—>‡ŸJ1ùQÏjLÚŠQëKÏù4ÇuD.î¨äš‚0Èïæ#ÆÇ+ŽÂ–½hªÖæG,ÎÑji3±°pqÁÅ?"Š£3É&žÛ$ýqŽô¡nZT+"ˆ¶cŽ Ó°X»Ç¥“Ò¨¤WabÝ vSógü¨¾‘Ê"+ç¿*à¯z,.íKÍQÅáœnu %GSô©b”°1™Ë‚r;~X,YçÒŒVy·›=Ò*(èþ5,+1Œ–•H' Ž˜¢ÞabßNØü(ªw1uH$=ÁÍ" áC‘Ó h°X¹ôúÔyã>i “Ðvý*|ƒÐPÕ€9ïK‘ÜÒuïùTs LdB@~ÙïHD¿ˆ¤Éô?Ui%I’D F1ïJ¢àí,ÉŒœÎiØv-~Ð@ª÷"g€¤,¨ÙêFxª®nZæ1¡pØnŸQBW/¥'Ó­Am‘£‰IÜH#ÓÞ¢cxa²Içå¢Ábç4½;UE3ºÈÉ lýÞjÊîØ7u¡ ° ýij¤Ó™BHŸ»?8'‘VUèeäE´ £ðªèq)÷dž=*r~_OsH¥/çUíÚ!¸‚G¡Î±õþtÚ° ϽŠ^;TWˆÓ•Kp2qHDŸ‰£ ïøU%ŽìD€2«gžsRÀí½ÖB»²:wâ›C±c¿¥'éU³,·¢e€FO\ý)6ܤhòÌ£hùöŒæ‹‹tvïUg”½¦ødÁÆF&‘b‘[Î9¦Ži2}Í)Å_Z? ~™>€ÐÁêizw£'Ï s@ŤâŽO@(Ž€P!qé“Iߎ¿J:Rÿ*L{‘øÒàzš;ôeOR>”qêi8ë“Kød}(Ç= &^{Ñ’;f¨ Œr(ÀÇ¥>ÔcŸzL¢Ž=)ÕOÌÀÓ=ê8ÉpÒ+ ü¸ô  y÷ühϹ¥<÷™ÁûÃ9¥úò(àç&šÄ*“Æ\ÓÜÔsëTØ\ÊàE2óó`r*h¤Vw‡4X,MÇ­µE#íR8V=3Q•0îËåãëB ¹èh#œãõ¦‚r)x÷ ñýi9ô¥(Ǩ ØÑ‘ŽôÆ(Å ÑFG÷y£¯jLŸÆ—ð£çgÚ€š(¢€óÅzþ´cœóM}ÁÖí@Ç:u£ŽãU¾Õû¼‘ÉÁëQï¸Y Ãç'nqǵ;‹ÇúQÜUYe$Z«ñÊçß­ n€@Ó‘È¢ÁbÞPzg^"Âw,ÃéNv¬"a¼p3JÁb\z=¿ €™¼ôÎBm玦¥IÁ*sÎ(°XvãAÔdj2}h}xüh>ôÉËRÇðõªè.9ÜùVç$Ž(Hv.tïŠLÐ~´ŠÃ¿J¯+ÌnDFÑ÷óB@Zçþ”{Ukw;¬äd±Ùô«=hjÀæ–“‘ÿë£>”Ïlš;t£¯#öc8¥/lÎæ‚H튭›’ä]„ðK`Ð2Ï¿­'~˜úÔQ4áØI´.~R JÇû P1ìi^£ôªê× ÊUÉ9"­.r=©µ`°ƒ×·¥8fŒ~tcSHAùÑŸJ0>•WuÛ³…m òŸQ@Ë\QøTq34`¶ÒÙéD’BTe½3@bŒlÕU–ádQ"þì‚Kqõ欃‘‘ƒžã¥6¬Ëó£9¥ÈÏÿZç·ZBž;ÒóIGáš8ÇRi(¢€ ÒÒq@úŠ:ú袎ÜК? Lâ—¯4PqEbŒ{ÒsÞ£š]«…#qè   hª¨×GAéÞ¤†G1yoCÅ;ÄԄɪ‹-ËBt7Ô8à}iþmÏ'ÉtÑ`±2Ê®Hñê)ÿ•BK¬{’ \õµ0K>HòÁ p1ýi‹4gÒ«¤“˜Ã4cè:ÕŒ§µ`ͤíëAt ÿ<Ñôª~eÎHŽ¢¥ß7š~\®8ç½;‰ñøQõ¦DÌWæ9îiB'TÁ4¬$â¯éG¢ŒÐŸc@&—ð¤ AF}ø¢ŠLQǧëA8Ρ2Iö¥§”GãB0Æ:P@ô¥¤cÚŽƒ­.>”˜ÇOç@ƒŠ0;~”`ÿ“K@ÄïÔÑš1KøŠ?ùÒfŽÿ^‚=ñ@N†Ž}(Ç©4˜ãŒŠLú94¿ZN4œg“Fx知.(Àh OÎ>†ŠY~òóØÑH #¹£>ÜÒd1ŠQŽÀæ˜6¥ŸoÄÒöèi0sÍ ã¾irh·ò£ëÒ€Øê‡ÂÛºùRàûãÚ“p鑟­.Hê3íFOL­§^)2ã€üæ‚qFxþ˜¦Èv£ØÐ2Þ<ÜídÏñv¦¹’+€TFõç¯éO·pêXgiþ÷Z.Bù`±|» «f1'Å6 ‘yíÈ©ùA ¯±Ø 4(Sqq»­<ñž8©}„ÊÌÄ_.ÕˆƒœÿzŸ—ÍÉ /<M€,²´Šý1гӸ¹ªza’±°ñü]*dÿGb"±ÎBò)÷l<~bÃcè£.Õf=òÇ4º[*òHL„pjÊ– 7`sНt±–y#-Æ:TèAŒïš:B ²ê¢‚Àñ‘šœä§@*ާ$vè“I#.ù¤þÒ†U ”†vÒ©Eµ [Bd-X4j¯žƒ5-¸c@N0ÀÕh‘dre<“ûÒA¥ÒŦ‰Ëg9ïÐ`sN×½†iáúœb«\,¥†ØÃ õùÓí®’åm+þðÇz†øG”䃞¡sR“NÂê]ú7>€æª;í­º4 Ž´Ñ¨Å¹n¸ÉŠ|Q”N%bÑ[8ùZÕhäŽZ¯n&Ý'™(Ýò”êjv©ÉÀõéUìö•rÈÜ~÷ô©[±ŽxÇãUï…FTîî*ϣ𪷮ª‰—nX !æ…¸-ËYǽ!9 t6}È¥éš@U‹>q=˜'Ò§rDlS Ø8¥V‰£k£µ› ¶CVŸåFnpðõªÙZÑ2<Ùc 1cž¿…>ä6Ñ*E¾D.Jm“,‘oVrûý•IrvÛ·Îë¸=ÆLÎöñ“÷à•銲¿tdsLGÙÐvêç$Ôœ×JO°2³‰ Ò~ï)œ†ÝƒIx’:(EÓHû]Àpò¯–y\•ÍY’1,e¶Óèpií` ¸bñª®× ×=©Ò ¶ ×§éUíHÅUÛä=êÕˈ—bƒÔv¡é 2HÕ|±·éOéPÀÁ¡Rp=ïRaÆ“ÜLv}i8ì úR`úÒà÷„!ç=?QŒûÑÓÞŽå@ùæÃñ¤?(ϯé@ 8õ4™æ—œýáùRsÜŒúš3è´¹=Æ(ëÔRqôö £ò¤8ÇZ21å@ š2;Ò}M;Ð&¢pAÆ;h–àÈŽö³%b„cÇéSÄHr¡N:ÕUš8ôòC2Œz’E:+¸ð±îwm¹ÉV¾Ã-äú©0c{Ðà˜¶ü*k{:3e qó fªêBËvÒˆ1³'’Vz‰n^äúf«À ‘˜Å´÷#ŒÓEò³ çnå#54 qô¢Í mÚÈö̱ƒ»ŽŠz• òÔ2àãÒ¡¼(m˜0sŒ}ÒEKÄJzÉ¥Ð]¥ &‘x'géTnåKiÖI.m$âžšŒJñ©$¡Ãc àëN͡عz:÷¦‚BãK×ÅI!óŠóŠ8OçFh½éF<¡&HSU@¹¨nÈX×èK”ÍL¼(Ã~=éôAÕWélD|’7ÜU¬ÕnÓ0•¾bÜð([‚,óM“&6àž:S³õ¦ÊÃÊl¶=¤@1 ‚¸#Ûç,¨Ä Ç d ¢Ã¤æ™uµ‘P».O[›Ü:‰bHŒ’Û„wûËœæ’×ÌVx˜Oɬ¨ÀNµ Ó’0Þ´ü†1ÖE¸ýÊÇó –=sVNJœc>†ª²,í"~ñ?ÛÅI @ ¡'¾ìhèÛy›>xÕ=6ÿ…OïU,@)¿Í•#ç?Ò­æ”·1Ó5Zí7ÆG¼dUŸ¥W»? ™Xž(@‰‡O»M¢¾ð«¸÷¢Ic…A‘ñž3ëMŽu“søÑf)@êsŠtêZT?1 ÔVÜÜüÄóš’à!÷r6ô0d;&h»p_˜7¬F¥b\ísŽ•SåþÎQ‡E+ÕrÄS¡œGÆ¢LŒ²m\d™spÁlÇÊW¯ãDA…Ä›®qódsNÙç İõÆEWK„[™˜ÌN06Ò‹{ŸÂ€=±Q „fPeºsÖ¤,O­M„('= VkØDhêw+6µÇ¸¯!º€Tôü©ò°³'È5 þÔŒm Ö¦W¡àûUinÔ³zðh[‚Ü·IÏj÷¥ëÜRgÜfàûŠ\ Lí@FG8ö4¼÷£üõ£õö ëÔRàÒŸ­&6žœÐ²})2OZ9ÿõšã'¡ a“øRp;õíK¸öéô¤Í3œàzR=#@$÷çëFIÆ(ÆM/>‚þ4œg¯>ô¹#éí@ç¦EÁþÐFh£“GNsKÔv ŒúÑÁ¤À bŸ§ëG^”˜†ihcèh#”œ÷úQøÐ1’Ä’íÝÕNEEoIJ,(ƒŽµ9ã§ëQFIf;‰ð Mœp}©ztSsê@ö4¿ð!a@áŸQì*†eO‘9àTÜöýj ˜Ë¨ŠƒœíïÅETÈwry¨Â4s‘â2:ç½M vOZ¾{²¤>ç9ã?J}F9„0V‹!O M>HÖHʰ ¾†£E_µ;äœpr©ØàN>‚™»¶Ãæ*©Œã6}ªµ¡fWmìAc€Ã*Æ}²(`Åý(ÏùúQ’3Š)#ó£ð£òi3ǧã@ÅÉìx÷gM'åK@ƒ9íŠ?GáG¾(9>Ÿ…žœQŽý 3Ž¿•&3õ£œv¥'†)3Ÿ­G)dMÈ»±Ôw¦Æ¡‚ˆV<óÚ bA Tw´ÄýÎC?Ð c#eo·äÇ”+÷ûÕ¡íKלT2¬qíb>n Kö©K‘·š|„’O‘S'<Í:Ê ‚1Æ)œ[o’B “Øt¦2v8SQÛà)Ú¥y<O´D[`cœgM%ªaXù…òÄóÚ‹hŒÿœQ’zâ“§z:öÍ"Jó³4ÑÇå³#g$ŸJÑ«G°ä/aQÌ7MÍŒàTüc“Ç­>ƒèBDF+ p3In„1ÆÙ’£)j«m—$g&¤‡˜—çϾ(×dmf>‚¦ •‚¥C.õe"O”g Ôã8wãHBóéIÏÿªŽ}¨äžÃñ Bã¹ÍwŽÏ×4½} !¸Â@Í´œº:šX¶¬K…`85(£  Ò†ócÀÊç“Ö–}ŒN²m~2¤åJÍæJlææœÌÂuÆb:Ó“Èò~m¸ÆsÍ“’¸8^‡=j^~•;²Û›w>˜¤"QÏj\àR~4¥G8-]¤†àÒA•©K"ð$zr ÆäbŽÐ¯®"¸êz~6Ùn60~Pö¦˜€:¨ 6n1»€:S³"ˆ9îõ4°H®Ÿ*2…ãæ§±ùNÈ7a·0ëÆ Kô¤íßò¥ }sHBr>”sô¥ÑÇ­ÒÒQÍçîÑ“éF3ÞÇô ŸJLžôwëGêhqê:8ïIŸÿ_Z\óÉ >ô¸ç­'ü~{О*´¥Léò1oQSöïA#üŠ'­@±(›ié×',ލ…Øð:⡉œÈeQsMm¬H#“ŠŸŸz¥ < Ë!-œ ‚;Ô»ž2 È¡;“ëC,TrʰıÇÒ‚È ûÓ0æFù†Üp3ÿÖ¤!ÉÇ-“ÏlÔ¿ç­Aº€²°zsS Ð ?BóøRæð;Ð"¼LŒÃxû­V?“ ñºƒÏ­QEC7>†Š%ûËÏcÞŠ—pM!'¦E ]¦—À0ÄcwåK´ŽÔÖŒ qBŒzŸÆ ŒQŽp)zzуë@ ÀüèýqG '¾ãKó“G~HúRãœã­1ÉİM<Ÿ|S$Ë!+dp3@ÊÑý©ˆÃ@W¹H.|Æ5ëÖ¦†=«,/û´Ë ÍÕ…_×qÅUõɪB rõóQ7›-ÄM ‹å©"AžieшÌÈWÇ#ÿ¯RGq©ØF~m¾´¶Ô qÏjc°E;T{Óùœ~«IßÛ§‚Ø9æ’ëuœ#yåXî8Ç¥MƒØRîã¤ÎGQjŠQ&ä*Á@<çÓ×AÈ ŽµÌbChVDÎNy©”*…BñÇz}T»Tß’ ú:÷Ï^jË ! ÅCx¥¶ªÛÇ(ÈÎîÜԮʀ„’¼(=hè"ß%©s"¹ÉÆ2Im»ÈÎO<Žj¢D²ÛösS±›<ûÔÖ›–Ý@Œ/û#ЧÔl˜ £…¨®RÈ#!Náœãš—zŽX“ŠŽxƒ:n…_ƒŒ‘R·1g Z1#9aJíG·"™PØnÕ&N{~URðtA˜Á=ð3BZ‰ ê&Ý3D{’jiþk|‚<òp)·glùƒÐ”Ù•¥´+‘Âö§¸Ë1ƒåŠ“§_ÔÔ0ÿ«À#·z`ñi=ÄÇfóÆ?ÔœÐêE.O^ÞÔ„õþT c4܃ß𣿭/ŒzóG&”æ€J1ì?:1íG ò1@á@çÚŒ}(}(ôæ“§r?\ÿ‘IŠ4BžqÜÐsøTS3ªŒ&üžyè(„³ïåçPäTŸ/P梊EÊ!\úÔ¸¦ÆWå2Ü|Ÿ279ǸÒòÇ`Z,6:v«å¡8Ý·°¦](û3)xÇ@Ø4øW"íÛÀ4tE—šû òÝîpž´üñÀã×5ZAþ”„ÄÞ%v$M±CgË]ØÆqQB\ÌÄ´{ÆÕìj|¨;z¶3Š‚C±0Ǩ9&„îl Ù£"¤MÛà:v¨®¾x$bB{*DcPWiÇcš:B)̃÷q²q÷‡z›dd¢œõâ«J‹-ÆÖˆ;ŽqVºQÐô£v:šN:Ñž9ãñ¤!AÍ.G­3×¥/qŠlÅö|O?ÅOãžµ^é7Æ•æ ôÈâ§PB÷}…>ƒè/NÆ Ì‚èï ¡û£98ëTÀŠ[Ö- „mny¡n»CL—"'Æ3´àžiØÔÙî˜ p~_ZBlY­Ð¾ ãœqM¸iB$¨lÿÏës˜T”Ǫæ’u ŒóÁÍ7¸ú‘m»ó%ù—n>N;Óc¡ ñ–ÿ–œäÕÌ UwBgR`ˆŒýæëM1Ü|e÷ò+|Ǫ9~гa<¡Ka³DH Ìæ ¤1'õ©¥g@d ´yy.{)È©óÇcô¨mÛ1åù`Z˜~=ÄÀ ¯w$‰Øpwµc »Ƹ‰d9GJH6=xü*Ïö†ÛåíîAçò©² ŒøTHß¿`#äw=é 'ºänöî)Ò¶ØœîÛ€y#4ËpNâð¬dsRHsáXÐ÷¡ƒ+¾ç°æP _¼8¤;ã†&7Ch$ãšy ö`j2:ŸçRyjÑu»Nã$ ‚#Ö«Çó\ɸ¼cåøKímÈž>”È¿ãâlÄaÞ‹öÆ=(##dPÚ¢†,Q  ©€:zRíê}}©ÙϦ>´gÞ€`p?•A+È.‘C(R2r*ÄþU€gLªž:“Mn4KG—µ„JCõý(ÿ<šLúâ€Í'Z\tÁ"Žs@3Þ“Üý)—ÒŽ}h8ïIÁ9ÇéK“Ûó4p{ŸÂ‡ô¤üép(ç×40äP1Œ1G~i{ô4™ÿ8 `óÒ—Ž´™Þ怎Ԝ“È¥Í #=MÜý)2>”¿ŽG¥çÒ†IcÎŽýy¥ïÚ“ùûP úÒð;OΗ8~†ƒÇP 3éFO½ û 38(ÁëS}I¨b+æ8óžsÈ  ±þMCq'”¡÷…Υǹ¨å‚9GÖ„b'Ì(ÎIÆ{Q8#8NwgéM€(rdzô©'Mñ7°M7¸Ç¨äЉŽé‚¾¥†Ìl*Šl.]‹:l2;Qm@TgpÁvƒÁÏ5)h¨\ˆe ±ÈpJñO–Cd+·°íHDv¬ÏæE1SÖ¬ vÍ64 ¹€y9æžÈ¡€g´té@µèŸ….@õ£'ÖŠLŸZ^¼*NM&qßô ÛŸZ2@À?>¦ŒžëŸs@}zûуŽî1Hp9'ö ·ÒƒôÏÒ±ø¤w¥ºñ@Åæ¢¾õã#Œ Xdó¢Y0ËžÝ)²¦fG*sEµ\Œw¨.—fÔ–Áç¥N9è* “s‚€€>öM p%@vŒõïJÃpÁSÔfúÑô£ýã¸ɤ·»üÆ$Ê䕯ɤX[“œVB€ô£  ”°<}hŒ¹ÎîÔÉáIæ$ØR[mä+zî4úAeb²Ç’OzŸ~• ùJ¡bO¯JY&ò 2:±=ÀëG@Cª>ò^Ô¶¬ÝØ "‰R3‚Ä~cšm¼›· €N2M)1@Œ=Oz—}*a$žQ ;•(@P[‡bŒäQ‘‘KŠ  ò)izõŸ1Üàùk½‡n”HþTeÊäÎ)!!ã À7?1æŽ@B‚P<*'ÞÓBžpj~qÿת÷6òW'4-ÀŸ ëLï0ÇåI毒$ €Fpx"ˆ‚‘½I!»&’XÙ6G½NwsÈô¢'•Ë#1ŽÃ94M Ì uÇt85° $Š ‡nÌäÓè|ÊÌWjPyÏj™GÊ8ÅE*Ä„°ÙÏÊzÓ¡Iº†ÚG¨è2·™£œsšhgûN̓n3»9¤…Òw/‚®:Œço†€¥Èw€Iæ“>B€qíM„|¤íÆ}±D®¨„’{’qD µI߸7#éHD)G#¡™£ð AþsGëGN¿ÛfŒÑF~”sžEÇ@1FÎ(Ï¡ ¨ã NÿwñÍ÷‘ äzš8?þº?*LPŠJ_ÂŽ”sHO­&G¨¨¥ •L6 ꥤóÙ¹ ëíR »FûR*ìE]Ý8Í.@‚5AÀ’CˆÎ'¤ŽT•w&qK+팒=¨c? $m4î*»Ì!H΃uTÀäƒÍ ×¾Ò„Ž¹Ç'?äUyš6 }¯ŒŒ Ÿ“é@¬“|Û€äœØTÕäÕ_ Bx–$ñÚ¬¯ÜúÓvQTä/'©¤}ÁÕûÓu’FEÝ•çšt‡äåˆÿv…Œ\·Zl„,ƒä'ßDÂ3“ËÓe(.™0tt"ŸQõ, 3éIè¥ü±HAϨ¥¦óíKÎ?úô í@ãÛêhÏlÑŸ¥õªÅŸíxò~\}üÿJ±Û­V.¿mQÎìüS[‚,qÓù \R>Ÿ/§4€^´”¸ã“IϨ AïFBÿAGnÔg¾Mç­zÑ‘ëš4sÞŒŸAI“þM­'©y¤?ï~4 1Åéô¤úþ9£`‘HŽÀÿJ8#½½½(Ïá@Íㆊ%?8ç[K+qŒ–&žlÃ/$Œt'­Zç¹J@HŠ.ÂåW²StgÊ \c#Øtõ„ü³N{Ïš¹Ÿö`ö¢ì.ƺîÁªâÈÕÓ)’˜ý*Öõ£’1»CI;Êm§îeas>AÉ?¥Xxƒy<Ÿ)ÎàýjP§y›ëK\gÐÓ» ˆ9íô¨Ö Oæï÷Aâ¦Ü~cÛZ@ŒÔPCä¡Ù¹ÏÒ¥ïj˜ôëJi=òh  óž7ÜT¡=3Í@`$b¤Ÿ—5>9âlþ”îí`¹ áŸhIJrF5¶˜«9Ž~ï'"­àŽ3H}Ûð¥p+ˆ$ÝiŸå€~÷Öœ!Ûróoo˜cn:TÄzRàþ]…ÆçÅP, 岿låj|Òƒš.T³(ĉØä`nÇZU¶‘V eû¤–ã­YÜxiyÍ>f`«ééG>¤ŸZLŒòIÍ(9þ"? B}1J RcÚÀÆ€ƒß{)8r(ÂqÉǽ/“$tÀJÀÿëQÍ)'ÐQÏqš8Ï ƒô¤Žs@ ôÏáIÇ©ÏÒ¼ýãFqï@$t¨ž'i,¥p:T¹íŽi}Î3@ “ê>”¤{þ¥êy?¥Â€ç œñMŠ1 íË2Ž™5/¶sA#ÔP74öí¹BzP‹W \9! ’y«|}iqÇOÀSNùN5Ž‹~í§;SSÏš#b¤ŒgŠ“ëÅ8À46Ø\®¶§ÌVó U]»jH#x£͸j~;ž´¼tïEØ\Žâ34L€íÏ|R ¡y¨ØaòP(lÓŠ“ŸAIôýirqÒ‰ÈéHA#ü(ÉõÎ}) _5²ZzFÊìÅ÷g ô©}çµ;Žã;óƒùÓD92ë´ç¨æ¥úŽh8îáJáq’G½ äŒÓÔmPéIÆ;â—† ÙóïÉÎ:gŠnÆÞÇÌ#Ž*N½2(Ƕ~´ ¡•Èq zŒsùÔʬ3œiÜú 9õ¢áq0)qŽôvçô£• ¢Ý mÄc·­Iƒ×4PÖ“#×§ÛgŽÔ{ñùQE=h;õü)r1×:L3øf€O¥&ô¸c×€^p(àwc¾9¤EÇÖ€1ž)CL@>”}Gã@ M'~4r8Ïd÷ Ï88 Û#ØRìL÷?Jv}EϨ¤É#JAç#Š^~i7µù A»ÐbÏ~´sùQžqIÉì1ïM8ç$Æ€œu8ü)qß?4gу@ÅÀëžh4ßÁE/9ë@²;nÃŽzS<¦!xAqÀ5>ÐOQš1ùúf‹i*»–“*~èô¢HÝØmp|æ¤Æ;S°}Íq9ãIÓ¿4¸£ƒ@<Û&R£žëR ¦<Ã¥?´pz>´\.1ˆd  ïQˆÛ)‰HÇPWïU€ ô¤Ç¢à¿¼GáKžÜG?… ?J@/à(ÏÒ“#=³Þ—$zb˜ ŸJ ùü©bx ±ôü¨ìçÔ}Eˆü)§'Š2G\­ Ÿj2 7è@4„Pi€ãŒô›z ý)qÇJ=é 9#ž){ŸÎ—¯pE.H)ˆƒcîoŸ G 6o-2yl n«CGŒÆ‹Žà}OÒ˜U¼ÌœíÇ­IÆ;F;րʙ*—B”>:šöœmÉö§~€¬aY8æœ2)9íG4À–V—pp€T›ˆêh<õäуÛÎqÖ£0bA£þ¼äjxé×?JAõ棒7f1ûÔ™íA âËÜy99ëš›· ¤ŽÆ—sŽhþ_J\QÏÒŽ½MÉÅ&¥.?É Ð!Ž7)‚G\TOÄD¸Ú~l¼=*ÏÒ’˜Ø’w`öã¥Hs޹?Jv{çŠ\Žæ€+ùr³gz‘ž˜éSz^:Ñžz Ô¶6¾ßž£hõ r{š\ŸAA$ú¨1žÕG.~rtÅMž=(úP a‹ô¢@ÅNÕ»n§Ý8£'¾(†D$ |Ã5>O@)^”}hÍ™ühÉö Bçž´™õ ip{š;PÓ¥Ò/ÔÐ߃I×ÖŒþTd´sÐcñtïùR vçñ£pq@ ÒŒœð(Î; ?*3Ï fŽ}¨âŽ1ßJ;â¡‘db¡:gœžÕ6=0hÁÎ2h³BÎÀ’0§"ž«*ÊI`PŽ¡©°}=sEÇr LeÏʽir–˰ÆxÕ>3Ï!ÇMÆ€¸‘Q0›jàô÷0ì~´`zP7™ l{`Óò=¿?*OÂǼ3ùŒ¡sÅK»ŸÌRQŒz 2A!Á€ç¸¤+)^ núT¸Å´ÈæóE»À/Ž­W’;§‘P…ÁdWw`ãÒdtÚOÒšv ‘'Ú7‚Ì„gžÅOœúS{ð>¢ŽOj@8þ´œcœP_ÌÑƒŽ´„×8¦nÆS˜gi<±qÏÖ8›ÍÊmÙÅ!ŠB„oB*c‘íKÐà }(¸îF¢`ë»wíRõ韥 #=éIàŒý(pGE¢“>Ôwé@ÉîGáIOŒ¥o€½&}¤êy&Ãñ @HôçÜQœôŒªûþ4nãH`@ÎN(Èp(ëÉQFG`(ÿ<ÑôéG­!Çpö üi;u4›‡¥/xþt §æJ)'•$†Š˜`÷üé{iÏŠ_óÍ1=( sÕ¹ö£¿"€z0z`bŽqÈ€9é@Ö“œ÷§cÛõ¤ü'?)?JR3ÜÒ{có ‡Ð缎⢺™b˜ƒøP|Ùüò<¼Å؃ÍKÛƒƒïU>΢!2ž7m ׎•-»ù©òŒc y4Ú(l×Çr‘Y•”’Ê8]Ê°ÈæJ’2£4¶Î å~|ŒñÁš¶ÿqŽCÂõ¦ô!q)²$ÉŒˆÏYn¯šXÓì ¤³ÐÕ‹aÀú·ùÅ>y I»anzFÌ ¢úïi&Ô¬ANH©.næ€'•m¼¸à9§,LeùÎxûS.ˆÄ£Î<éúÓV¸‹û··…©ŽRpà‚qϧZ±ky%ÀfxŠ$`Œwõ«89ëAèi]v·Úgª›pA'抒 ¥›x–Óך-·‚û†>n9Í:reƒñÎWŠNÀH1ô¨d’A(Hâ'¡'·ó§ÆßèáÂ?L€Ýj°Sq"I¢=}#ŽhH ¸ïPܼѨ1 P*;Ĩ\(è\óÖ›(Û¨£3v;}Úik`¶£úåf[G%0óôõ«6²I5¬rË•# •ô©¹ òj’mgß){ž”hÖÀ,·³G?––®ëÝRÇ{3\,oo"©ï+À§Ú:½²•,ãûÇ­6좨wópû‡éODí`spñÌq76…WKû§šXþÁ TPUÉëO‘À’Û/ÍÓ üêÙ9Ry#)l€ŠÎyn-’Ic1±þsUå¾™%!meuX`Še¤Ë!—lÍ•Ã`cñÅK`dû6$vfòÃ4“¸Xr]Ì×"3jëg'úU¼ñÓ5Nü7Ù‹냜£`Šdó"Ú"Èd+"ãrçpãÔsE¯°núr÷(,ؾáb@Ò¬[NÓÛ¤Œ¥\ŽW*;HL1&yäo'#ó¨¤aks湑üÌ(QÚ6Ìó4(&ñœU.5ˆdtK?0…Ü¿6?> >Y^ùY™p ð8«|zãÝhØíî<ô.ј¹ Ö¦qÔâ¨Úº-Ô¨%‘˜¹1àUïóõ¤Á€>ü}*9æòŸ-Ü3cå*Lœò>µVö]‘)ÞUw‘“B-HvÜö¥ý~”ÈÜ2îOÓëH¦ŒäÒŒö Ò`œ3@ƒç?Z9Ï­þ½€ïϽO4qž¸ü(;»¥ôãÚ€f“=A£<à _© ##‘‘@ÀöúÒœtüé:u$ýhsFp:šN~hÎE/QÒ“ýáùQ‘×4dP3¤ž‚ ³¹71+¶Á‘ü'ŠmëùPï22.{ÍE'–úp •ëM-.¡!VL™ÜW!:T–ײMq$MИù°Fi,ßtM»9Ü~÷oÖ<&CIš=­’Î}©»^Ã-gŽAò¼Ž¯U …oQLº˜CnÎÊøÇ%q‘Pù-ä¬ßl›oP6¨ã:P’_%±À9¨a™¥Ý¼m*ÄQ ËqȤàúžjr#žD˱-Îåòõ¥nbIJ2FJ©céQ´Ó¤ ¶xP)nHòå¿ÍgaË3dÿZ:«§3\´jÁ•dÜÔ¶·“ÌBË LçæÁÑ~á<¼ŠK€1ŽjÈ(ç'éUum†IÀïùnŽ=ù£žœ~t¼{T!*ò¦Å"ÈÂ2çÔ`Ó˜eH Ç¥A À8ƒqfçæQ€1øÓ&‘Ù*…ùÇ&‘™ÄLË÷Ààc5ZâHæ˜Ú•Xaƒ¨ãó«pÎ}ÍUûDäÆ<®£-Øý*kyšubÑ”ÁÆ*9ÿw/š¾c!@õ« gšm«AÞÿΓ¾OZ;súÑŸJ‘ –EŽä…ð:ÕQ¨ƒ²Ã6 ”<æŸzÛm]·•Ú ;FOëO…Ä#«ç#?0¦¶A;ÈXI')®ã.\$l­‚¹-Ž*rFÜõ΢¸!cù²8<ƒÒ£uó!‡ýaÚAëÏãŠ7ï´¸‘WÊ“æœqš|3I&á$L„{ç5"Êæ¡r‚cËî p3ŠHòleã õ¨ÚáÆæXÉPæ™Ä7' 3yÈÏz²GŽs@ †H•в3µ‡JÖ¡‡3CÚ¦Ç4˜0Çsõ£üŠ\R`úÐ!~”‡8ïš?_lÑŠžùü©GáF}E'^ß­®(”jNž´œçŒŠ^}Gâ(çŠ1@?Ș¼öéïF}h>Z9Ï—ƒÜQÓž(:úfŒc¦h$ãÛÔ?•{­}) ?(=ÿúôgÔÒàÒdÐpGN)xôÍ>§ò z‘øÐ`À¥qÜ}1KŒôëI·³í@ ”•‰™Wq8M$2MÍO¯ZŠxœ;L²mÂ`¤RÚî)—,ï’M;h>…Žzä~Tcß?}èÇn)žÔ@Îܑڌs×õÅVšT3Ç‘ƒ“Æ9ϘD3{VF⯵DÊÆ‹'ͽÆiÏ’ñí|§V#ƒLd²3¨!aßÖ‘ÚB àc95¸e: È1”ëøÒ^3Äžh’CŽ6(â‹s'4¿_åMFÞ¡€Æ}izôíHBàwÍ7•?•;´˜œšB†?J^@þ!Kqô¤ÁÇ?΀©£éGÝ&€G¦(˜?O—· ÒŒú~4€@h™Ç_ÀQ·¸ûÒôãލ9ÿ"ŒSšOÃZ!ô9v먥ü¿:OÇúÐu6ÖÆìàw¦%ê—ThÎâ3‘È«·ú¬ûíªîD£bã €8¦­Ø¢X®Rê£i$œÆêz-4¡mi¶9lrh¶}ј’ qÒ‹°\<À‰Óê*p ãgâj¥ì¦;rÊì„t*jxÎb@Î\àuÿëRó!ÐgëHqÔÑøŠLœsHÊþR Íœ(ÍEox'!v:±Ã)¦¸–iÁŽEóü©n<À‰6€¹ÍVƒEÏ©A-ËÂÇ÷O ÿahûByhpùn OJÇÛ­+‰Ë.pÖøñT‘Ú‡Y$f FÑ·¥[üÅ wÐÐ>™¤=8 ð}èOç@Û˜¦ôÿëQ»ÐГœ‘P‹µ#$œö¤ÊìÚW–Ç'©x (¶÷h@ÀuéKq3ÃuBÜŽdõ¨‹¹T c;qD„Ë)HåØËÔb‡aÂ匊»zâ¬uìj½Â–T"}›['©ðÊ%L®KŽ;ÑÛ©üi?ÏZ?@2YšFÉ 3Q›´ ‡¦âCÍ2u2̈•#ƒV  ¼t§§Q žŸÊ¢šo(Q™O¥2 ƒ1gäçµ66ynæ>XåeþF‹‰!œL_ ­ŽjaН2¹hÜ>ÕS’z™X:ýhhC¤öⓞ…¥Å&O üèÏ·ë@ øR9ÏJ2):Lç¡£Ûò£,3À£Z\R}hÏ¥(Ú€ñ¼fŒ9 Ï®sEôÅ~cÚŽ1Ç?Z0O8úÒ}…ÉÅg¶i ýOãHê@ÎÐMt£w ‘šUºä«q’3Ò’!º<†WëŠmÃ4q‡rÊ)èV…ŒŽ¹?€¦É ‘ÐR…Ï^*$í’ÀǺzæ•…bt:†‚3ÁÍ;ƒÛ4Ðè)sèh¹ö?JLŸqFìp@¦¼ˆ‰ ë@›¥YZ>¥qŸÆñÜ!hÙƒƒœTPgwfF ŒlëøÔd›yÕpªŒÇ  U[¡V.ÈÁP·§aQ}©FÑÉÎ:sQ3æõÊWîæ¬¡z.z[nßJ_«ÛÈîdÝØàb§8ÿ"“V¢€N9?¥=¸£êOå@ƒ#ÔÐ6öÉ£€{J>Ÿ­'§ó¦E4rUçk`z$ó°6mëI˶sž@¡ ˜zQÓ‘ü©>¤f~? /¿#Úœu8¥ÿ=i3Øÿ(#ñŒþT™íHG¿ë@çÞ›‘Ó"“9<5/¶½qéA4cÞ“ë­úþ¿….2:æŒ:qìi˜qúуƒŽ(#ÐPH<h¸>Çð§Qœujw>¹  ×¥z‘Í\YrA84Püúqõ£Ô\.UBmÁ¶wƒ¸Ôw&GhÄ3Ï?6NjÄÃ%SË-œòFqC[£„ÝÝéíTŸQܪ_ý›k\;=pqŒÕ•™Iòùb–ÛÅMŠXù…Byæ‹Ü£#”+•y2Xªx4÷:í†@¸?8 ò)’<˲yÈ€íÏz}ºžaŒFòrØõ MH£A"Æ3އ𰋅’Oµ2p¿.äw9þ‚kÉbGU¶‘ŠãîÓÚZò>.Ö%sžÝj2²ÿh']ƒø6ž)ZáMÔHa³.wcŠ{îûjbÝŠãïŒQµ†YçõúÒ0bŒ€ÄRà¼Rm$•¢¸DRySÌSÈÏOÎ¥ÀòÄŠÌÃ;Cg¥1¬àg.ñ«Ä3QKȲ­¶çPpÀr*´lcçm·ìe’EX,SŠ«pÛÞ–p~\¶1VÁÏ9úÐö5ˆE-úÕ{w…‹Ê·ºÙa°ÊARÃ=j½ž<’b?˜ü½([0CîŸÊ¤Þ©·œšŠY›ìѸ¸@[¸^½ªK ­1oªçÉ6 `í àd. Å `Eˆ_1!ݸ‘ɨn§òÊp r3RDKĬA\Ž˜ÅGt¥¶f0ëž~lb´K³Ÿr)$aeÜáçÚØ1ÁôÍU–}×bÝ ÆË÷¶œ~cŠI\Aæ¼ò7˜­ï—náVN}ª8ãŽ5;/9⤎¡±6SøÕ{¶•Q|©d,3»ÓéV2}?*‚ìªÂ£ó>a…Í pD±’Tdäû “æÏALB6 aÙÏJw^¹Èô¤Á‹œõÇçG÷úQÖŽ}xô @}°>´ :wÅúÐïÁ¢¯Z1þq@ áHO~¿….=hÆ>”¾ñͽÍNŸZ<åHühr}8£ž¼RnÈïM'зã@?\n=èjdÒ¬Q3²’ÉÅA,²´Š tu ‡¨¥¹Àµ`¤GØqÅË w–5µ:è÷+Ž‹Éªzh1I"Á#LA I㜠GÔ A.ÆBI#ëéKlÈñÈÜG­G´~tqëøQŸoÊ€œôüÍ/8çùÒÇÒò(>ïAKÔsÁ£ŒœŠAŽÄcë@áÓ½ÔþtsŽi03ÿÖ AœúÒvéN#¿ò¤>äãÒÆ²¶O·R%¹Ê³( È9늻­!ã­4Á1·îUo˜G¥E ˜T«ìÎO 0)c)æ0 ówâ¤xÕ$;u¦2‘lÍ¡?íÓñ©¢bУ8䎃š­w nÍ,[”{ãj¦$*r»x掃è?'ÒŒœÔvÚÅ lƒ€ z6ô ˰žÇšVaÍÃ|JžM>PD/µW§GéQBQ§ªÈq–šR¢Þ“¨æ€djH·Sò~XüªÂð£'ŸZªÂ?³¯îh# N§utÅ665ÖV› UzdûUŒc·çT¤`Ó„ò÷AÜsÅZŽäÒãÏ ŒzQœp è1I•îMþ)Lz \ûàÐYU€ ãÖ—åÆ=(ëÔÔSL‘”Wî8âˆ]Ìãl`ÇŽ[pÅ5YÓ|¿&:ƒœþè Ž.v= FÛNò98¦2Én8}EEkæ,DK‚Ù?tÓÜ „0$Ù¨­D[Dl Æ?Æ…°ºF>”t÷¨%c$sœ ‘2eC\ŠV —í`õ[};Ôù>™üj± ^(±È9mǬ߭7°Gæ|ÁÂ÷Á°ï‡u$zu¨âe&L¡\ÍœŠ[r§%WŽh$ÜFI®h€(G`)&£*À{Ò[:4 僴qÉ£ º~zqúÑÎ:P{R¼8ô;:súPÑøRnH4nï@ KÈŠMÞÜQô üô£öühϾ(ê:Š3øÑÈ£·CGç@O¥u¤õëGOÿU'éÍÑß9ý)sØŸz?)? ^OáI“Ùh/cQ\–ò¾T r8cN‘ÂFÌG 9ɨã)0¡àúP†? €Ì8âˆÈQµØnÖ£œÆ n݉ÀÇjAk8VÞ4À³ÇQFj¸˜$ÂŽp9$Tç dþ´XäqŠŽ\˜› ô5^DåT¸ÞxÚ)ó2¬,]N¥ 4=Æ1œÜTS³+D«â[®K‰HRõëPܪy‘3(ûÝX‘GQõÌ‚í6¢ˆöüÍÇ8%¾éô‡•ÀÏ>•@T36GpÄ*:åŸrmë‘ÍOøþ•RÔ"´ˆža*yÞI«##§ó¡ƒ“ŽzÑž94Ÿ{ëG¿ô¤ 'Ž?Z6â—üâŒPqž˜4ÄÜ$a´('¨5&cPFÑùî;‰ç“B'çŒóøÑÓ¸ü(úÿ:9Æ{{Pç'¯ãFOáG…ž8ühg4››8ã¹¥ÚOýiBàP1œž)@?ýz~phê8ݧ±Ïµ(vãÔÒâŒ~4˜Éè)Hè'ÚŽ;Ðdp)2:wúRœã?9Ãǵ ‘ߟ¥.z9?Z^}?*­p~eú)n¾òý 0£Ó})½{SI?äQÏlQ’õ»‡|çé@aþE& 3’9ü ÁéG_LÑÏr)9 ¿‡c#¦>”¹ãAÁÇ"€íŒýi“q@TœæªÎóˆd‹1•Î@9ü D!UåÏLv¢äfÌ|u©@UP `APGLçÖ›z¹_(€K('šŠñ!/ <›?#ŸÎœ±ÜÄ®±,@‘ó`*UŠiMȈ…9çúUu¸ÈØF/Ó÷ß>ßõxýsVÏß­FáüÐÑ…ÏL±è*nG|Ô½„Êì’Ü4±ÜB+“€A ñRÚ€L>ì±àv§¢Ì&u)ÇŽ6ÒÀ%ËîHÀÜqØšc"½MÑdI°ƒÃdŠš7YT²pqøÓÝ\®‚OcÒ›:! ·ãº‚ô+ÇÌÀïÅ[ÀÉæ¡Â…Tl0$?ô©y¹úQÐ: lÒ|§¾)HãÖƒšB~ïT¤´e™‰'ô«eH?^õ¸1ò,gû´ÖÃDw,|Ÿ¿"ò>ç^µ,K¶0>=ÎiÍÓå½i 0‹ñ×µA3Dóù-#tÎ9ÇZ´=qPŸ ¹cÞ?ˆ XàïûB ÁÂìêEŸè*CÇOñ£*{šP?»ÂŠ×»šÒEV –$÷ †åûá§ËÉ+¨u#¡ïP*ÄqÁ8¦¶“8eŠõìi¥—û@|ÿ6Ü`ÔéæïýâGŽÅzŠ›öŸº†=½qÍ;Œ~×ðªöÁU˜+nŸQVˆ8è3Q¯’]Pzc“I áŒDTzŽÔÛ~cÛæo ã8Å#¤­'Y<ç9¦*º2ªF‘§9P¶ó•P§. a÷MHŠ >ýhxÕ× àäQþûn\úã¥6tS"n‘€ÜëŒÐF.Ô´üã þT›iYgv!qš’HA‘dTRÀc&€%8Ç9ªq¤ o"+®ÌŸá<Ôû¥áAÎ(0Ÿ!ãB›Ðq@Ç@ÊrŒToåÅ8,Çq 52‘éHÂO0˜î9£¨ºŽ¿9¥íÏò¢—ò¤"9‚˜ˆ,PxqŠeºª#*³6$â¦``ƒƒØÔdC„P:hd“ªùdî+ÇUàÔR˜ÄQ‰ó‘‚:“OĵdU*WæãŒÓü´Øj•ì¸â ˜U 7có¦¶ ˜,ÃŽ”Ô2©ÚW Ÿ@1úЫ™ø×Ãw¦•yŽ$?)Î*nOµE$gr²Î~bGQN%ðNÁì O1º3É57=À¨ÑAò¨r9©0=8 gž¼QŒö4¼t擾  c·çFGãFThÉ :Röã"Œþ€Àû¿¥'>”÷lRòEúÑAçQùŠ3Ç_Ò—¶ri:÷£çñ aØ~”´z( r;Rþt™íÍ àô4uìizwÇ4 nAè}èÝÇøÓ±IR(€ç§_¥.O®hÇÒŠã½½(üMöëï@ ~‰àcžj8ÛÆâ:‚i„ÊÑ2<{‰Â(Pñ‹QϘ’QÆ¡’"KHŒ ÔˆdÁܤsÆMqlOQŠ@2Ü8…|Ù¶9À¨î7,ˆáßÀ °ª¨»UvØ GEqó)nâ‹êd3#aT œÓ"Ã1•[*ÃŽsLe§–"È9q2FUB¨J`C,/å4¥‰#ŽinHdòI °ÎpqøÔ’!?:"— ¦ª3%Ç^¼Ð2DVUƒŠv=¨Ç=)qïHB ƒÚŒ€zŠ^G~(ëÚ ã®ïÊ”` f£® .¥&GN¥Î4cÒŒlý)ˆN ÏSHr‚qŸÂ”×ü) N§”Nô„~tïÌ}iE"ܬåAÉ‘ž”ì`ñ¦:¤ßD³·ÍHòIÎ"'Œâ€DŽw‡ÎÁéRœozHÐcw—°ž£Ò¸p˰.]ݨ«Hf¹òÒ_“oÌ6duõ«]8ôÅ ©ÏÉ»@Å;Ÿ_Ç0+¼nI&b¸<`T‘œÄ¤0lŽÂšÉç0Y#RŠr2;úÔ˜ LfŽ€@¤A+´²píò‚Õ$ì¥ [ö4M 8 ȃ‘šg–&!%„°#;» c%Ì šxÆ5$l3»=‰§ÕWj¨Ú1P0xAX¡8 (&›Ìr±Ê ©ôÍOœ÷¨`€FÍ)\Jàn8©²OðçéC(lz})r;*MÄžTŠ1õÅôþT ’;R~¥à÷ ‘ö.w€Oâ™63>ç*qÒ‰âYPR@9æ3tòÜJ‰³ÛŸÊ«´­Æ$•V28$² Ç×¾yéâ¤ùJ켌¨&žÌ6<ÑÇÞûœŒäÒ@’¬xy7Ÿ\TSDgX’HQ—p$0Èh*Ž ”øʉSŒîô¨<Ÿ´É›‹e;,¿Ëš·É£ @£$úQÒŒ“éšB sÔQÓÒ—ëŠNg×­¿Ö”{*9è1ùPôþTnÏBi2}¿ ÷çé@Oj^}¨ÏdcÖ€h}(üè9©3è?:1ëF@f€xÿëP2ð£¯ÿªŽÜPÏ­!>§ô¥éüFô#­@ŠÅØî„œäÔ¡v¨ ¸‚¡Ft˜ÌÝ@è*Gvä*@ëŠl¡³òž9ÍKƒŽß¦SϸÍ65 @Œ)ÎûPíRO¦(`@¡ã’%Bй;€4¡š& ·$wÿ ŒD&+!G §ÜTÅN=èllŽÅ,¤ÿ²8¦J’<ÈÑË€‡HÍ9Q"cµ?ÝÅæÉ ˆ«à·J/­À²IúÔ +Fc†P’c b¬v<‚GaPˆ•ØJÈñƒÅ$!ñ®Õ÷=MIÇLóõ wþ”{Ê€ ÿU'<`R‚1ÔœúRò(ÞþþÔqžW“OÿÀb“×ñâ“·ó ÀÿdÑ‘Ó LRôÿ \²hſƎ8Òí=ÉÅ'ä·zƒò ¯áøæŒ䓟ZLÓùRŒriASÓš;ç˜ö¥ÇùúãÜQùÐtîOµÆ>´½GqG9ÆAö À¤'Ø}iØÀ£'µ7žáAíþàëÏÖÃZhü}(ãûÔî{3ôÍ&¡úÑ´{Róê? 1@ ÿë£ìiG=úPÆ(Èèhú (08èhÚ= /áGå@ Ú=qõ¥Àõü…/áŠ0Híõ  ò£ëK¥(Ï©ÔsœOΗ ëŠœPdŸo¥.=èéGטÇAøš_ÄÿJ0;Ö—ØŸ¥ Òý 'áKœÐcÞŽ{\äÑ@ Ç~¿Z1Ž‚œO4Ÿ€ èè8æŽüfŒ€z·Ö€ÔŽÄÐ ?ãŠ\PÇ®(ÇŒQÀP‘ÿë£#4¹©£#×QùÒÒb€Ô˜÷¥íëI:ÐÂÎŒÒõ™úŸ¥zæŽÇZ?:8£ÑrhçÞ—ñ ãÿÔhéߊ ÅÏ…ðühâ“ÔÆŒŸZ\sF)?ÒñÜÐ éF~´~t™ôæ‹×®(úRRþ˜¨nÙ¥ÏÖŒûŸÂ€  v¤Ç`ãÅ/'ÖŒŸ­&<žhíÂñAÛè3KRhÇ¥4œgŒÑÍñ¤Å=/>ô 84m€ÑÏaùÒPãŒö£ç4zŸAG^9ÍsßòïGÒ€ïšãùQŸ­‰ ¯­ QלýiqïG¹ ñ"‚qØŸ¥(9éšBO¡ nN@?‰ ¹ò¤ç<æ”z( ã¹¥Ç¥Qþx¤?çŠ1鑸PÛ4}çF©˜=AZ0?úôÜÔ})ÿ‰ü¨éëùPqÇ þ94`÷Z^}H£wâ øŠ6ÒòhÇÔPvxýhúS¹ïIÇ®h: `÷à8éõ Œtæ€v¤Å(ÇcG'Œ€ b“Øú \QúÐcŽ†Žƒ¦iqð¤ç¨â€ g¶>”¼×? ÇZ;ûÐ0„zxÁçò `“ɧcŽZoÖ—§cKÏQAÝé@ לsïGNÔ˜õSøÒôìhO RòJ7zfŽz… ÁÆ?¥r?•. ô4~`P­ð4=)ÔÞ=EÊ”þ”ƒð ‚>”vû´¥=ÇåAÇqKü½¨Ï Í&A= 'דéùQÏ~”˜öÏÒŒz R=©ÇÖ€ ÑÀ<ï“@ã¹¥ã9 cÚŽ¯ÖŽœhúP‘G3GN¹£ ö ôº23Èü¨È9àÐÏ¥/¹ýi2M=Å.!Qž†Œû\dq@ù ŒÑ‚=(¦Oã@ Ïÿ¨QZ^ëGnüP1IŒwüiÙÓ4|ÙéÅ&3Û"“h±KÏ@ipGÅ'~E'Ò”L}(úƒùP`‘J=9¥íÞ“§ZÔÑ“þE.qÅô»ÑÇcÍã©ü¨£4 ã 4ì(Ç|š;u ¤ïKœqÉ£“ØPœóõíNüE7ŸJQœP1{óŠ1è)=ÉãÚ—‘Üâ IøQŸËéAÏù LœÒqëÏÖ”’:ÑšN@àþ”´Z8Àý(ê3Ö—µûÑŸÇé@îq½9쥗y9= €—¿LÒóØdP2:ÒïÏ ì/Nߥ.Ȥæ”dSd½~”dR`ÿõèëÖ€§­¤éFpphp}ý±Kú~˜íGz.O ¥ç·ZLÒdÏ4§woåIÇÖ”ç×8¤çé@ǾLö8üiç’Aõ¥Ë¸ cØ~”¿†G±¤Ëu ?Fæö wn˜´˜©£wsFNzƒ@ƒÇÖ®OáFG°úÒrzš\úgò£ð¥Çphæ€Ç^Ÿ…³ÇOzqãšLý(Þ§åFG®AKÔuý(<{Ð È÷çñ£éÖ“9Ê€x Ϩ¢ŒÎx£pì:2}?J8÷ü¨É>ô|Ô|¹õ£ôRçê(ëÁ­&=zÒ84§IŽ(9dqG….ýj:÷4œ”¼uÁ¥ãsë@1êOáAǽ{æ—óü¨3ž†—<ô¤Æ{Râ€:`ÑÀéÒŒzQÍ/¡Î(¤ÿ8£§@GÒ€Š:w¤Ç¾hǽ)i9£?Z1ëGäÒäÿ‘HhÈéÐRqêN¤ç4~qž¿…R(ëßô ÈíKøš\c¨¤àúÐŒšN=¥${ýhàÍ ç8â—ôP~™ ×õ¤ÆúÆŒL}(#Ž”8Æ>”}8÷4`õ@ôÀ£#¹ý(çÖŒg¯ò¥Íö OÒŒ{~´})¹ÇÒ€ £½{E/Nôœ{ó °ÏÖŽ{çó£AFAúúŠ9Çü¨9$þ4¾Àу؊? N=(Áõ£­QøÒãÓ?•>怊1×gÞŒCúQŽ9SùÐϧáG>‡4¼ã­}h9õâŽ{L —õ§cÖ€ñÍ¥æçÖ€ óÛ?Z_lRc=¨ý(ý(Çz>olRóé@ Qš2=9£‘Kƒ×¥ZL­7~h9ïš8ïš9£š9"€ ~?ã>ôtêqIôгïIÇãõ “ô4f€GçùQÖ€3ØŸ­ÏJM§ßó¥úŠ9£¯QùQlR~t½OJ9좃ƒëHqœüÔ¿ç­¹Æ(ÁÏJ0Ob(éÀ£üçqî)0>´¹îizŸj?ZLƒÇ4 ^(¤öÁ£ð BñØR/qG4|Þ”½¹Å%''Ö—ŸJ:vý)i2sÐÒóÒ€¥!þ/—>Ôb‰õ¥ç×ô£ëFÐh=?¥úÒ‘Gá@ Í.F3ž(üèç=(Ï¥'æiM/Ö€€F(Rž( ¥.(Å7¯^hëJIùÐ9ïIÏÖõ¤ÏlP çÒŒõþtìzOå@Ê2=iqøRcšMØéŸÂ—p£æïŠNhgßò£p´œtÉ¥Çó :óÈ¥è:“I“éÍ.} 8¢ŽsÔÑ@éGjZ3@ ŒfŒðO>ÔìÒgž¤~u¤äÔ¿öæ€Hç…ëFIê1FsÖ€=h÷Íqõ¥â Å!úqJ:3ê8úÐ1¹¢þ4»¿Ù£ ðüèü(9ëÓÚuàipG©£'°ý(sIœó“J\ŸÇÚŽhãÞ“"”ý(ɨ;ñÅ.x£'ÚŽh1KúÑ“íF}èü:L§ÒŸ¥'>¢€?ï;pqïJyïFÐ:çzMÞüQ‘ž?:^ýéHõÞžædsŠn)9þñ #'Óñ£üõÍ)äQŒôÿ OÌRóSFÒ—É ç¿éFAîhêhÛš6Š1íGNIâ—éšo#·¹”§ô‡ó Žø zŠLZ9í@ zÿJNÜœRúõ£·µ3@ hëô£¾9 åìyúRàc‘IÈëš9ühÀëΗƒØÓsÎ9¥ {ÐóŠL})p=èýhö¤ùsïõ¥?BOµ&=¿Zö¥ü& ã¦)qé@ z8"š÷¥Ï®@ £Ÿò({š ãÿ¯@þ:Rý 'ƒIŽ”¼£ŠO©£ØR¯æ)Áã4tãœý(϶MÁïKÆ94€g¶(Çߥ4`>¢œ3îhdÑŽý©y¤'ÜþtqšLûàûQÔôj3ž´€\LóŒÊ“·ÿ^”;çLëÓŽlRu= ;§c@î9túéE?}2Np¥€”óŽ>´sAíH:ô¹³øPöãšLý)=ñùš nÄ)$ð1õ¥úóIéš0}0(sì?:0GOçF21ŠLÖ€¯\~Tqí@#ÚŽzâ€ð!>ÂŒQï@=…'â£ê)séI“í@ > ý(É=0~¼ÐG<ÑõäPsØ~¹?Ò“+ëš7‚_¥=ÏëKÓ½G|QŒh÷À }F(Â÷¼v›½Á£> Rsì)ï‚hÝyô£ß&›·<š9ùqŸqÖ€“Ó¡£žô v§tí@ Àú 6sœæ”úš?OzM¾Â“t´szNI⟣¼zRçé@ 玟•(Ï­/Qž)2;sô ïÞ—¨â—#¥;f€ŸZ3êE. ¤1š\ûEQøPÇcùQžÙ¢“ðǸ Æzq@Ï­!Î2>´™Éû¹4ê?*B9ëúÑÏaúÐóI“@üi >”¤úQÛü žçð¤±9 ç±Å¥-œñ@9èÔ„P \öþ´¸ úb“ ž´ìN{Š0héÿꣀ9£vsŸÆ€=?¨¥Ïlþsôö4¼úñ@ õ ð{céGÒƒŒr(ÉÏ4 ŸQGôÔsõ ÛM#Ð~Tcž‚”Š1Ç@°¤ü¨ÛŽsŠZNÆ—>—Ÿ¥'>”gÞ  –ö@ PO©¥ý>´€ëõ ÿˆ8£ñ&ŒþdöZ8£èOçG8¥éßô éÖŽ}x£Ž¹4~?¥ú zÑž£4¹Àüi?Z8éF¨§ëIúÐߥ\Qü©z´˜÷ÏãAôqëÍzÐdûÑKøçñ¤Á”gžM)Ò“þhéÿ× š1ôÅò §®(âŽ;P}Áj\sÓ4‡#qô£ ã ús@ Ó¯ó cÓƒ>ÔmÈäиt''Ò—ówïǵ™ Áõ#éKŸóš=Á4{óš3Ï~tdŽÇð£ô£¯z9>¢“Ÿz^ôcë@9Ç­/·?úþ4¼ÐwïI·œ÷§sIŒõÁ úùRczRÑÓßé@Ä㢯çJ3éŠO›è(Ǧsï@ 3ÜçéGáFON”gßô éÐb“žâÞ€æ‚Op?*4¼ú~´™¦–‰Û§ähÆCùÒÑÓÚ €{~tcØ?\P0íÂÐ3éHG|ÑÍÇ`>´´œŽ‡ŸZ\žÿÊ€šN=isõ£#Þ€Ô`óÜP=¨ÐõqŽÿZ1ÍSøÐÑjh`E Ð!xõ£'¯ZAôüéqži :öQÇzMªyÁühG°ý(ëÿê¤Ï±¥ü(23ïEzPžz~´¹¤çÿÕKŽ9 Í/>”˜úQØ ( tâ—ó¤Çµ0 îÊ—ÿÖ¤æŽ})¹ è1IÓ€hë×~tÀR=©1ÏAF?Æûó@Éì¿•.x Œõgð)Ÿç­&1ÔŸ¥;‚zfŽsÚöþt„€y`b—ñ☠ö£>¸£úQè(¸ÇAIÇ|}h#ÿÔhãšì)h£™ÐÑî9¥ {Rcž¦€}û})qŠL{ 2yéKž8Å Ý)JLûÒçÿ:=úÒýE'~ÔgèhÀô {/ã@ OÎŒRã¿ÑŽhöÁ¤Ç½.j1ߘ?J>ƒ4¹ÇcFsÚ€xô¤ÆýT¿˜£“Ô~´sëùÑüé:õð¥íÛ𠞔܎¿Ê^ Oønö¥Ëz¥üŠ0 éúÐ`÷þy£é—cŠ9¤í×óâŒf” LŒò3ô£õ¥Ø£ò Àé(Ç= /=ñHÎhÆ;Rc=ÏáJ3ëKŒõ í>¦Ž{“JxëIïü¨SJ> Ñ“ÛúQÉA jÒqŽhÆz€h==Eà{QÓ“H1Š^3Æ3@…ϵç®i1ëKƒíŠ)?*0)qô ü/~ÔRÐñÅ Š9ÃAüá@Ú€ÛŠ1þsFÑIï@…Æ8RbŒ­PcòúQÈ÷¥ëHOû¢€ s×úÑ“í@ç© c¾´„c·åGlRÇOÊ€2{ŠŽ¥Í BiqïŠL©ëÒŽÜ \´€ýOã@ÿ….Gz¯qþµ>‡úQEÈùÓè¥ðqìisÇZL|Üô¥v?­Ó³þM'¡ýi Ærsè3LC¸ÅŽ‹GN¹üy£€^ JLöÛúRäÔƒ®vâŒàž¢—œñFHô€óÔ ^ùÐN£q8ÉÇÒ€ðü¨ÁéŠ^üRcÞ€ ÿUc¯¼z“œÐ9€ýsKóg–ÀôcŸçÅçš:™üip¥/ë@ Ú9ãJ\sKj8À üè¥üh?Z8úÒpúô½(ëÔPõƒâŽ1×½{Ðpúôuÿ 3ÇøPrzþb€vÇáF=›ëI‘Ž¿íùb€§zÇ|Òn8¥É=¸ ™£> :3ïš3ë×µ³Ô w¶)9ü(ßéÅŽ1ŠR}E&=ÏçGâhÿ<ÒäÑøÒwâ€Ä A‚z“ô¥ÈíFhúbŽ;ŒRñIøÐþ­Ý œàæo›ë@ òúhúÒ{h ÇÒ€ +õ¨öÁô¹ü>´™õoÊ€òhÎ}é0:“@ )qø{RgéIJ_lbŒcIœô¹ø ŸJ:zý(÷£tãñ AKžÇŠN½…†}èϵúÑGÿ^€ ûQÏn?3éG=q@œÑ´g }©O¯O|Syþ÷é@ ŒŒÍ/Oá¦çчЊw^´qéIøsAúþTc:P:â—4€ã¾}….sÚ€cÒŽº1MëÛñ£§jv{‘úÑúR~u?täP3íùÐ{Rç¶ ôsIž™£>ßôÆ(y¤çû Òý „g¯4sýÚ9=…&Ð:”àúÐÛ‘FF:ÊŽ}Åÿz€ Š2; N^h?Züñ£4ÇJ1ÇZ6÷4}9¤àvüèÀ=ü(ç¾(ÉïÀô žqFÞyäÐ~âZCíÍ7ùë@ ØdÑži0z`bŽ}8 ÈîEsÚ“žüÒóè>¢€sGNœn íJ<þB€ô ät™ïÆ(Èõâ€Øþ´vãšLúþtî~”gÖÏAŠSŸÃéIÏj\zÑÏj1ž¸ü)qì(9ê@¥#ŸÒ“¯^1G?ÃÓÜPäçÓð¤ÁõÅ-& ^i?ÌQKõÁ b~4síKùQ@‚“ŸJ_§ó£>ÜýhŸZ0}¾´síŠ9ÍëHr(Áâ—?þª3Ï4œŠ8öÍƆOµ.}ÇáIŠ(úf—ŸZ9úÒsÛùP¾´˜hü³F(1J˜¥ IœŒçéHN:š =ñùRÃ'ƒùÑŽÔÜç±¥ü8 ŒòÆŒz3žã} 0sIÅ&H?{4¹oZ@/¨âŒúâŒçÿÕLÎ)hÉî1I“íH¤Ï¡Í.HêE'>´gØRÿ:N{ž>”¿J`%(?ô£>ãG¥'К\úÂÆ€½(éÐÒäã±£9í@}èÿ=hþTP À ­?Z3JblGSŸéG>Ô€N~‚—'¦?^}i1èi€`QÆqÎ}(ü¨4€1ðgÅ-Îiˆ@Àž£>”¥)öÁ£'ډϧqÒ–“‘Ó‘@}¿:ö¥ëG4NÀ¢ÄQÏ­\fŽ;Š3Øšr(ÇcÖŠ(çJ3ZN½p~”¿J7z3Î3š9ÇZ3­ƒFN?ÂŽ?ú٣Р=‡éJ¤Éî@Ô½zО(â—éŠ3õ÷â€ð4vÍ/çI@ ø @â“Ö—œûRÑÇ­„óŠ\qÖŽ}i9ÇZ:çŠ\QÏ­'~”~t~`ç·åF© ŒÒã4€Q͘nÇ¿SGâ(éF(Ç·4b€ R=)~¹~&€Œß….?­.>”mÍÅ'^1šã€>´HëùP:ãúRŸÂŒ”}x ¸Æ? 9ǯ֎=i:t8 Çn)pi½ö R~Ñn(ÿlÓ¿Ö“o¥7Ÿ`~´¿•(°Å/=0(3íGN@=h¼(Ùã§™>Ô õÆ=© =†;pèqFG¨¤öÇÖ‚q@ œuÅ&A4„¯®)rz7Ö–“ôí@â(ϵ'¦1íI“Ž1øŠ\ÔæŽ¼sI–ù Q“Ö€{b‚Fy¢”g½!>‡ó£×œÒþ4˜èÇ|PGÔ¿Ž}èè=¨¼{õ¥çÚŽOÒ—™ãƒùQøþ´wïùQ‘ë@ Î{POÒ}1F;ç9ûƒøQÒŒ’zP“ëùP(ç>ô˜=Èÿ^”„qÇò£o°¥üh8sGÏ_sGÒŽ~”¹Ï½&ñÍv0Oë@ß•¨çÚË›‡LÒã¾@ ‘ÜP1ïGâ(Áô ƒø~4˜=©zúè䕸¤üI4õ?¦isèh{SIã¡?(ÑÈ ¦‡Ó´¼ž£4˜zP»#Ž~´›½)Ü擌t 'ïKI“ëNç·ê(;’(<ŠLóK“ÿ× §SI‘Û­.hüq@#×ò£ƒÛühúäþ`z L~ip?ÂÃÖ”{â€p?9õñ£ wdzëë@¨üEížhüéqõ&ri3ïúPãëGAÞ“ƒß4´™ÿ¯FO¾)(8ïFp?íÁÈ?þ4{óH^)p >´Ÿ˜¤ÀÉ9¥éÔ~”¸Èé@ v?•z‘Nö¤Ï<М gô£ ~ŸJ3žÄ~täïš3ÇÑœv¥ç­7‘G¹ëK»Øš3õüx Ü;Š_ÃdcŸÒàw4ê3øÒmãåáê3GòúP çizv?•ö£œwdŽ ÂŒŸJ9ÛéF?É ÏùžhÁöŇë@ö ã:ùâŒþæ‡QG8ìhçµ/± úçð¥÷£­}¨Éì õŒQÇn(Ÿ£Ž¹/¹£¯ÿZ‰Å€¥#<õ¤'Ô†qÍéG>Ù¤ÆIçò BñéŠNM'ãIÁ8ù¨î´`ƒž´˜=‰£uíš^úÔœã¥(>Ô™>”sžÔ½¨9 B¡£ßJZ0O\QŒsF(éÞ€¦(£'ÚŒÐÀ<‘G^†ŒŸCйüè8ÎsŸÆ—ŸcøÐ)0=(ç°KÆy£Ò€éKÏsIÒ—žß­úÔÇëIÏ֌ƀu¤ QŸ~hüh£Z?–€¿½ý(¥Å&F2ߥc¶>´`çµS@(Áÿ&IøPw"¦:_šŽ(=sGãF=y¥#>ÇÚý@÷ ýÓùÒŒã­$rh¿¢‚(úq@ÅüóF}³Múçj^”2¦‘ïøP}¨üèuç!¸Í_ΓŒuÉ Bò:`­ rqHOc?ýjOcKIŒõ¤ÈèyúQÇ<‘H~ Rö怭 _BiqŠã4¿Z;u£ŸQ@æŽ}J¯pq"P¥—÷‰ô?ÒŠ9=Aü)p:søÒƒŸjp‹h?/ÎþzÑÎiFG­OÔRœzRuÿëÑŒS¸Ï­!ù¥‡#§ZM¹ÇãFÃ×ùÓ†}ç?÷Å&¿çNàûÑŽ{ŠN}(ÁïŒÑƒØš6æ† ùÐqœhŽ;d~@9û¢_çIõ¥Ï¥ïùÑô“€úÔsøýirsÓõ¤#ëŠLŒc“@=zÎqÿ× ëAúÐþ£½&}¿J\çÖ€韭t¥£C@ Ï¡¥ÇvéúQÇPhÅ=Å.}Í'ZP?ýtbŒûbŠ)sI×üi1õ?/áF8ëF?/­!Ó4¿™£ŠJ3ïúPÇ@(úbŒÒäzÐÖŠ:÷4ß4=hÉ?tâ—§CF3Þ€-ŽßJ^}¨ééGzO—ñKÏ­'J1íGàhÏsœàÐŽ:RcÚ”æÆ€Ÿþµö£§RiNJ;ð(ϱÍ'¶(Ü1Ó4~@ûÑÜÑŠ9ïŠ?Qô£žØühÎ:g  çÐQ@éÆhëíKŠš\PQÛŠ\ÒP`ðÍ?Ý¥ü(  PW?þª^;Q­&¯`úÒàŽÙ ŠCíA>Ô½(ü(9úP@ïKÅ''  †öùixëŽ}¨ç¸ ¦îÇïÈÒsè(F;RtãŒR;ŒÓ¹÷ _ÎŽhÅ'½©qÇJN}3øÒc¿Z^{ 9£ð¢€ÖŽ´d¼QŠOÀ~tsŠ\Z?Ni1ëüép=¨ýh0(¼ûR~€{RýhÏ­ÿœPKøSwz(Î{~&€'µNi? CÁë@ ƒßô4t¥ü(ã¦(1ß?…\QŒsÆ)Q@?&p  uÆ(ú ^G¦(úcƒÚŽOp(sþq@9èhç´gŠZ3×8œQõ€éÓõ¥íÍ÷¤íÅOÖ”{ŠLŸOÄÑ‚{ ÏQõ£§CŠ3êF}…ö<ý(¹'Ò“üõ£ŸN}qG>Ô}?ZLûÒôö£ñ`R ž)r|ý(Æ;QšN=)s@Ã9ïùÑ×ÿ×Hsõ£Ãñ ÍÏoΓÔdáü¨´dwþT™ÈéGâh¿L~t™õ8ö¥¸9üh£¨£ë΀ÂŒÿœÑŸCùsI’hqÅ…'ïKøÐGsÖŽ:`ÒsžéKƒ@ ÞŒ¹¤öëF}±@ ùŠZnh=èØúÒg4˜ôçñ£´€1êsøÐO±£Š:b˜ “F=ÿZN( ¼PãœÑœu¤¢€>”~Þž¦Ž1žÔî{RþÈ›€íÅÇs@'éH0{æ“ô¹úÐõ£#ð þ4t ãÓŠ? ZN}(„‘Ò”dÿõèäv£¯¯ã@ƒò9úÑÛ¥÷Æ(?¥#¾&{Rペ?@ÃŒqÿ×£?­ö AƒIŒ‘šZO|Ð0p{ŸÎ“$ðQK‚J:úb޽¨ÉóøRgžz~´SŸAÎŒ{QÉõ£¶q@1ÿë¤ã×ò¥ü:{Pµ!õýhéÚŽ¾´›}‰ bç£'ÚŒ§µ'៭8sGQŽ8éH1ØRAúÒ–ÇQIíŠ? PsF?2=?JBq@\|ξÀÑI7ßzQ@Ü sòLÓºsLŠw#ó@íÞÿ&dýiyî?:b´žG>´¹2OÒ“(8$ \àðxúPãÖšT‘×ñ¥ãÔÒþ LNhØ æÇŠ_¡ aØF~´~_•gÐÐ!sƒŠB´¹¤JQÓÚŒ{Ð îiyiqè1øPïúÒ`õÍ.É£<ôüh1ßnOÖ‚1Èâ‚?¼Jô~´sõ£ŸS@„àuÏãKGéøÒgÿJZ_¡¤çv üM%©y ixô£Ÿj(£Ÿÿ]>Ôsé@CÔÐI<úRsÞŽ;žhyÇZ>”zsGnŸ¥!Í/>ß(&€ëŠt½GZ(9£îŽƒZ\RqíšL÷Ízš^üfŽs×ô ?­÷¥¤ç¾ >¤ÑúRóÞŠNüdQŒ[š_ÎŒC@(ü1FAïÍühúç4} çŠ(8ô£žùÍ9 ǵ/4Öù}sí@Pæ9>ã¥"òìÄ ƒŠ½çŠ?1FHôÅü(íÔÑÏáGúýiN´¿u õ£š(ÅóKùÒcŽ´}sùÐEÊÊ€{SqêM;J2­'AÜÑŠ^)3õÅ:ñGãš`úК1ïR g­gµ/AÞgÞ—Š(Ï­Ž=0}hÈõ 8æŒÒgÓ4«P×wéIÏ®hÏ­/éGphüèç­'ïJ?3F3Πñü¨ÁÇ­{÷ ƒž}©E'ËëF}hÅ.E4>” qÅó@Á¤ÇáKžÙ QšN¯åG^héÒ€ åF}¥ç¿IùP>†“¯øRàz ¿Ö€ ûQ¸w"ŒÇŠ=  Ý£û”´(ÛþEÆ—#¥&qÖ”QúQÜPøQÅvÅë@=ÿAF1ÖŒQ€;ñï@À~4}?Lg¦ .(dÿwm¥úÒcÜÐÀÿëÒ;Rñš:LŸAG>Ÿ9£=hhǵ%$Ð1xö¤ýhÁÏ?•皥{æJ1ëúÐ0íÚŽzp}³FGn´ú€(q´t¤<ÑùRûq@ #4½}(íKÁí@ Ç¡¤àÿ?Zwühíš@7Ù¤ã9þ´¹>™¥É4ÜŽ”u ä:9'éøSwàcñ¥ÛÏQÍ&®=©ÁÅ 8ïKÅ7¯µÀ¦±žß­&1Üþ&“Ž˜ü©ÙQÖ€uõ¥"޽(ÐR˜ôü¨$wühÀíúš\~4Ä ùº~†“ÿ…8ëG”†Ã4Ÿ˜¥àôÅ=üè6ŸRiy¥tþt`v€=(¤éÚ˜ üþ´uéEbŒý)8íGùÍ/ÖŒ}h£Š@úÑEÀ:ö4¿…&=hÀ ¥.}é8¥À 4sE õÇ>´£¥êE Ðdc®}èÇz_®(÷ Æ“Š1éÖ€ 1GœÒñ@ ÅíF~˜¥ýhhãÿÕF3éùQŠ8£ò¥ÇÒŽŸJCÇR(Ü=Ev¥Í&iOãõ£ð ŒÐdzóE/åG´‡ëŠNMJ^Ô©iÖŽ3Å>”bŒŽÙü¨Ï¶(:œŒÒâŽ;Òñ@ §Óõ£c¾q@Nø£Ö—éIŽ9 ¤4`hü¨ÇQøÑš\~T˜ô£œQž3œÑ@ ƒëG=:ÑøfŽ®~” ÷¤Ï§ëKøÒçÚ úQŸqK×ø:9 bvã8£ó£=é~¹ Bdõ޽)sÎ?•”™ï@­/ÉÎ(à÷ ßOZô4¼Ðmüé1ŽŸÎ”ŒõäzQùÐÈÿõÑœŽ¤}(ïÜQz5!ê1š?KùŸÂŠOø &qÔ)Z?@{€1K’zñIÇZ2{Hbçô¿ ü©>¢”g>ßZ:ÑÆÆŒJLÀRóè(£œbØcëKF=³@4cÚÒŽŸþº>”˜¥ëÞŒsï@ øP(¤Ï¸ü¨qì(g¥gÔŸ7lqJsž !8ëš>oïQß=(Îz~t¼ÐøÑœI&ŠB2¤@ ;y'ž´ìsÁ4€0œQžh*: _jNjZ9îiÎx4dö´Ÿ…ãž´´u æŠ(ç°£ŸZ? (ç½(Ͻ¨¤üE/ãGJ{âÂŽ=èúÐõ?•}hϵ/Zm;gÞMÇÒ€¨£>ôqßš3í@ ø~”:cò šolŠ\þdúæcŽ (ƒg¹Í'CÎi~¢€½9¢ßZ>¼ÐíFqÞŒž½½Å&î=¨sÇ,(,qI׌ÒçphŸz¦ Œï€œçñ£ÔŸLçÚ—"šAõ£Ú€þx¤ãÒŽGÑ’:Ð1~¹¤Ï¿~´~Ÿ…è0héÖŽ£š2;ùP0£“G4„Ûsï@ƒv:Ð{¨£½9ÏJ)8Ô€iÉôÒ}Ižù“‚9#̰ôÅ'ÍÉÁÅ?üŠM™õ '<~Gš\Fs“LBc<ãñ¥ÀþäÒÏ=¨÷ÛúÐñß“FFzsIÉþ"){ýïÎöëéKÎ3IœŒn?…!8î*`;¯PHõ£ƒØƒQ—ç¡¥Lœw¤1þÙ9úÒö擜sŸj:óŽ(ç±4¿—çG=™£òþ´À1ÿê¥ç×ð¤üM(Ç­ ;ŠZLޏ4pyÀp>œÐN?™:ÒÇ_Ö€œö£ŸaIš:ôçéHçÖŽ´Þ)xA4À\â€ÙíH}8£ ûPþtgÚšXRo¦€ž(ÇznîäšMÜöIùQLܽúѸã9 æÆ™»žM€çš~hÍ3w\uúRîö€vG¨¢›¸úèÜÍ0Î(úÊ“4gŠ_€=?Jh#±Í/¹¤phϵ&}9£"€”AíGãúP!i8ô£#Ö—?Râ“>´f€ Rþt™£Š/éGjnZ8gš\Š\LñÍJZN}¨£ò ŸZ8i*(cÚ€)(Åñ¤Ç¼{ÑŠO—ð¤Ï`¥¨ý(ǰ£Ô¹ôPcÖ—Rõ¥ü œúQÈôüèi(Ç´Ÿá ‚{ ûÒŸlQÚ€ƃê)xéÍóƒ@Qòhúž~´c† è£ò4M£üš2¥/µ @oÒ§_z^{RÃñ ê (çÔQŸphéØþïKÍ!Ï¥7v=hÏ=Ni~§Ø£ŸZNOLÒpzÓ¾¿ £ë@ýz(ävýhúÒÎ4`ã’(ܾ߆€ ëÅRñÔ3ÏZ`U›ýoáE>f@3ÚŠ@H tæ”5'>¹¥äzP“Ô 3žÀ~4séúÑŽûFiˆ\ŸJ7„b“'¹£#µ.IíÇÖÍÛšJ\žä 7ÂŒ“ÎhÉH¤=s“øP¾†“¿¯ÖŒžØÏ½.Or?*LçÒ“ÿê¥ÏûX ŒŽh:”sŒóJ>ƒëGà(r{ƒš®3ô¦Ž¼\úäPäͽ'´güâ€4uíF}Å&{‎}hÏííGJ?:LãŠ3@ÇsKøRsŽ¿¥/#¹ aøÑš?1GâOÒ³ýáFɤ=èA£>” 8ï@}ùö¤$Ž™?…/OjByûÃùГëGÓ­ äuÏáKŽ:ÐF@£Ž3FWÖ€9œÐOCšZ8sIA÷þT¹Åõ¦ätâ”ë@ œúbŽôŸ÷ úQIùÑ‘ï@ øÒÓr1ÔRçæ€ ÑÛҌ籠P3ß…­¤ühi8g¿ˆ£>ÿ­c­&ðFúŠ=¸£ z~T¿‰£?Z8õÇҌГïKùÒfŽÖ—üõ£šç@MhÏn(ÏÔsýÜQŸòi7g¿ä(~¼ÑÓ©4žhÏá@>ù÷¥ëПʟ\¥&ï¥;êJ2)¹¥Ðþ”âqM, '^ôP(Ç9Í œdàPùÑÜš;rÔ~4c§8£õ£#Ö­Œ{ÎŒƒõ zhÀëƒJO¤üZ7}?:SïIÀï¥ÿëÐ>”~?£§niô¹ö9ÉÏçKÉžý)Gç@ ÎE£ó£8 4u£4gÞ€9Î)x=©2OaI’¹È4¿/Ôšh`yÁúÒ‚}ç@ ÀèE£ðÏáFzqŠ3Æ)>¿€9Qž¤zÑíH®sGç@ “ÓbŽ}N(öô >ßüóG'·éIϯàhÝ(Ï=)>aÿë£>ô£éGãIŸqF}Oé@ÅëïKI϶(çÿÕ@çAät4gÒŒŸc@„')>€f—$v{š7Z2})3ž„þT|ßäÐÐôâ€}3FON§ÐÑ–'î{s@sØš=ÇçA<õèÏlcñ çØQš\þ4gߊ0?ýT˜ô.}©8ÿõŠPݸœi„ã­Žw}hüQFxëM ?È¥Ï×ò¤ñHOãøQôæŽ}qøPÏJ\ûŠn}9 0#ŒSÜÑÏ­ Å ç€\c“IŒóJ3ÜÐxïLÛH@÷.}GãA9ô¤ŽÔ=)Ø3IÀç€sž‡ð ð2)Ù=&9Ïé@ ïÔRl¹ü)ØÏP?*ÏlÐ9^™Å8}hػ֔§¯…'=†iqǧµ.ÑNÍšB;óK»HüèÉëLcA9à}és“ÔgÓ4oâ“9íúP³ïIœ¦ô íKü©§ŽzÒp?\Ø~TdÿU0>‡Ú€yÈcøÐwzõ£;b Ÿz=Àüéʘ†ð=)rHèiOáF{õ ÁúQõëGQGNÿ¥'±ý)irGqF 'áøÒþ4¼ÎE'^A “Þ“hìâ)ÌÒdg¡ Æ=©{qA>ߥŽÿÊ€{š;uÍ!ç×òÍú~´àO­.OsL?Z>§Ô'âiÖ›“ŽÔ “À4¹Ç§ãJ9ÍÞ¤~t¹_ïP‰#¶i{ RïùRæ€áE4KÎ{гÅÜŸJ\ç½/áFx¦äŠ8 f“>Çð¤Ýî(ç» \àf— v¦î_^}©hãéKšo"ŒûP³KŸjh$ÑŸ¥:’›œ÷¥Í:þ4™Ï§çGÒ‹FG¸¤Ï­vüè¹¥æ“>ônö?•zQF~”œã½/jN=(üM.hÇ¡Å;Fyìhϱü(yïIJ0(Î(cÚ“§­/>´s@„Çz^”†ŽÍ.qÛŠL{ 9ëüèÏcŠ}JLQG/Z3øQE)Zn=¨ÿ€ÒþgëG^ŸÊ ž:b“'Óõ£ÿ¥>´ ÓñÍ®3šN‡µûåHÀÂ(÷íéŠBp;šLžùü(úš_›°¦ŸP!F=Z€"‘@”årHÎh¢R|Χ¥88&Œ³ùÐ8íÅ.(1žß…OcNíÆi8#Ó˜ÇN(ç©ÆhãÛó¥8ôÅO¨üj7üÄ(~_â5'NÈúQôçëÅ0:“øÒãüæcÒ—ð4„g½ûRœc¥ûP´ô¤È<ƒJz{R.qÈæ€9r=qG>¹£ëGùë@}é3Ž˜£$z­)=Í=ð>”}iOojN¼s@éÓ›©3Ž2(ϵ/SAÿ8¤üé3èhÙ”`})7zJ4½:þ´€œã€O×Úà ­.O÷iõý(Ú€Iès@ÏR“'¿ZLû~´î{óFM& µþ4r{“p=ù÷£w¨ÏÐÐóÜœÑøÒn¢ÒçÐøP:õ§}i'£~(ÏbÀÐóØQÈæ“8´œPϯåF{3Ï8÷£ƒÿÖ ¨9¤Û“0}iqé‘KózŠLœÒž½(Ç­ÔœúÒƒêhèy#4dö"€ ŸÃéGJ Í4°?ã@$gŽ´™?_šG° 1öÇ¥;š2p7cê)¿B1ô£ úŠ]Ã3ôü©=)8ÏjvãÔý(ϦóÓ•ïš\ý)sÏ­4óØ­/?þ¡@ »=(ϸ¤ÏáI‘Ôs@ãè(üOáMÞ;Œ 3žpGµ?v8Áü¨ÎyÆ)›ˆéõdâýhøÇ© :äjn{Òòý.RO>ôdu?­0·?2õö¥Ï Å;púÑ»4ß|äûÒýqøPž?ÆŽG|Ò zþtw ޤ¥.G|Šnqÿë¤Ü=Aú~AôϽ&i‡ñ ryJv}¨Éõ4”f€4g>¿•&AÿõÑœŽ?S@ š?€üé8õÀ ~8¤·Z^¼â€ SKÈèi2}J>Ù ÝïùÓd£ rHâ”s×óÆ('=1õ4ÔR¨§vÆ(öÅ(8ïJ@>¦‚IþzPÇ­/QÚŽ Lý:“vz~”„çŒóê(ç½.}M.}ÿ:fGb}ñKÐpGã@Ȥ9Ï š9ÇRcÓô >”™Áÿ =Eÿj€8ïšLç<“w° :àP¹î϶hÉïÁúÓ}ð> Rã×ë@ ŸSô£œRcqøRpxÍ;·sô4„‘íøÒcœçŸj>¦€pïü³GçùRdvgŽ1@ ǹ¥çÖ›žôdtÝøPãÔbŒžÜý)¹Çz\çµ('· ÿúé1Óµï@ KŽàçÚ›‘èisá/Z?*Lçµ'?ýaHbûÑIÇõ£¥1 žÜQÇ`1MÎJPÙñøÒ¿1oÐRm´>”döÍ11ÐRöæ sßµ÷…(ǽôÈ£8ã#4vïŠ\ŸZBXäãéGÊ}ZÅÉú}(È=qšnF>î)Ã>ÿZ9=ˆ¤üOÒŽGÿ^ŽœñùPŽ>¹£Ÿ¯ãIœÿ{4¿\þt¹lô¤É=ÿ Rqô´n^{þ4þ~”dÓA'Ð 2?ýTÀ]ÄW4 žÔ›‡zNEÏé@Ϩþ´uà~¢“>§Þ‚:RäE(úsIŸ®)3ŸcéšvAïKïšfhÉôÅ?&˜úŠnO¥î üèݺš3Ø}i™=¨>ý(w1èEÇ~) Ÿ'¹ g4˜ÁÎJ>‹Áõ4œJp$öÁ£¿znÁèÖŒPðE&·Öš0?ˆsêiIï@ Æ}iyìH¦sëøQÓÖ€Žù¤g úIÜàqíG §ëƒG=©;~”gž‚ »Ý‰ö£'¿“põô4=ã@ÅÉìE.3Í7Ûüi03Ò˜‡=Ž? ã’M7híÉ¥íœP±š:vüÅ4AÆ3ïJIÆHJ0{ 0ÙÿëÒ|¾ÆŒ{ @|ß…/j;ýßÇ4ÀOÀýhëÐsïKE7â—ŸoΗê1MÂúô¤÷ùh9ÇÍAÈì1õ¤À€úSç·ë@-ŽHü(Ù¥ç¶Ö€îÈù¸úRðA¤ê9Å}zÐîÏj^qÔÓsëͯ–hù$qG׊iB~´sÐô÷ å{Ê›ôoÆ“ŸÊ›–ÆhÏ?•;=‰¥Ü¿Z`Ç®}©ÏJvàxJ3Û<ÓON0iCÆ€'ØRäÿ“IœôÍÐæŽi¹rFhš;‘F}饇z2{::Ó­3­.{ÿZ;>§tïMÏ®1õ£À }i=èúfŒöþ”gÐþ”˜è3ùÒäúRÒ€zfŽ{Hyã£Ò€>§„w£&“w<ãó Bþ4œúÒî¸üi;õ aÓ¡¤ ZSšB)ÜKF}©Ã×€+ÍãžÔRܬcŠ((ocHÃëP†ô™£sqíLE|ÒQîHÏ¡4»ñßšHðü(ÝžÜ{Ó'ßêiÜã9‹‘ŽŸ­)\ÿ±¦‚ýFާø© 1œZP}?Zo>ÿÅ.î9ÇçLGÀR¿tÑŸÃèi3î.OaÆ“zBOjO˜u9úв3§ëGCÈ4ÞGCF[Ó?;?ìæŒã©¦€}ÿ:\ŒÐäZ>ƒŠBÜw4›¹ï@Îz‘øR} 7Š@éùP÷cµhÁÿõÐX3úP»qúR`?ZMÄÿ#ÒŽIé@ÆG#"— v"™À8'ìM±Æqõ4üëKøf¢ éNÜNsüèçéIÓ±ôÞÝ*\ú·ç@îØ£$ô'˜£ù™¤ÀéÎ~”Ÿá¤ëÒ—ŸLÒç±8>ÔuH>Ô˜ÈõúÒü½élPOO_­;žôÞ¾”~8÷  1èx¤Àî&8ê\: P=èäÿõé=ésøPŒrMVˆ¤ÈÇãÍñí@ÀÇ#Ú“ŽÜSs’ÇÔG4þ=F) ã=¾µn}©¬ÙÿëPËäqÇÖŒöïô¨øÉÀ?\Ñ»óèNhOp0i7ø¤±Á4GR~¢€åïéÅ>Ÿ¥4{æƒí@'<“ŸÂŒñŠfX4oaÈ4'=óøÒdŽOsLÝØõôÍ.{ôühüÐO=j-ÙÈ<{攟J“ MÙí˜ϿҌž9Í?“À+IŽyÒìÄ}isÇñ PGl©£ß›ú ÃúÒ¯&€×Ô~4‡ÜÆ™ßýj3Žs@ =1Kžy5cœøÒäúÐÉãžG¥'ˆô¨Ëz¶~¦—#¸õ –úš2Ç¡â£Ýþñút¤ÞXò j‘NÞý(  ­0?xŠ \cô€$=†=hʃß>ÔÀÁ»qÎ:÷ dtý)sïM8}h#î~¾Ô~ñ¦çßnÐÐýÅ/J;NyJ2O#?‰ ä´džÿ…3¯\Æ—ò:v=@4nÿõŠŒŽäŸÄÒä.lPÏ<õúÑŸ@)™Sü$‘ßRçŽ?9£ša#®x žhØ×ð¥õÆ~µ-Û|Òrz¨?H7{Ò|ùâdö¥ÁÏ<}MÇQ@ìsè)0E¨Ï·ZvONGÒ“$zâž”úñ@ ÔñKÏCŸÀSHÎ3ǽyzšQœ÷ü¨ÎOÊÇ?LRuî3KÁãÆ€ëÏÖ{~b”ž3žh~nù¤ÜAíôëMãëFOoÖ€žÄqü¨t¦ä7|} #9éÛŠ\{âƒë“I’~¿\RëùPò¼qíÍ&ïΛÛÒàûPç”ÇÊpi1ê(éÆqì(rßÞ&¨ÑÇsŠ8èÏ¥.N:â›Ó¯OQIœŠyn„øQ‘êi¹ôo¯4™ÀÐ2N™ŒÁ•G“Ó?Z^ß{­8°õ4d§ô¤œ`ŸÏŠ7{h¹ÇéFxà`úÒc׊\àtëï@Åê>òþtœ‘É\ûRpz ÑÇ­`÷¾÷ãI€{âŒAøš.}òi2hüGáMÏ4vâ£îþTg>¢Ï4œç98 ç×ð§dqØýiýttëÅ ¹zMã®OÔÓ>ñäqNç·>Ô \æŽ;š ¾>”dgƒ@}sŸ¥.QÓÖ“píÍ!`}*`?sI’o¥4'à{P[ý¯Ö€ÇÒ“¿\Ówœö#¿4¹ôïï@…ÈìØ °Ä~†™Ç\švᎠ?…!‹œ÷ÀúQ“èG¸£yõý(#ƒLAœt$Òõé;u¤Ú½qÏÒ‹ù­Ïp>”˜Âìs@…,½>j\Œd.)1Ç_ÖŒàãŸÂ€éÆŒžÙ¤Ç§_j\`Ö€õêsIž3ƒNéÛšLñÔÐ{ƒNÎ:äÒóŠ_ÄÒ3éúÐ=È£œzP2{Š`ˆ'ëGüþt¼ú­uú‘@=¹Í.^Ïa@ ÇLœû ?NüèÚz怃“Á§sÒŒg®i=ñ@Ê;óùёӥçŠ3žý(;þbƒß¿µ/µÇêhÞ‡¿à(,Td“ïžiH#×Ôˆ23Î= Í!Šÿ¯¹ÇSF̽Nu9 üù£4»@ìip éÍ1 õ&ŒŽ€1¥Ú)OJ)2izö¥éÿë ôþ½i2ANÇáIôÁ÷Í ÁíŠ>^ã'ëFïKŒv ù}¿:2;c4˜<• ~4‹Ï'“ë@ íŠ$sÒŽÄQÆy>”dt#éI´p:8ÇÞ…&~n4g”Õݽ•¬·Ws¤6ñ.é%‘¶ªRh·¹†îÖ›yH&@ñȇ!”òü)ÒÅð´3Å‘H0é"†V„´EPBAqG…HãBÐ: xf'8ãÖŒ“ÖŒcžÝù£O΀ Ÿ_Ò—&“­/¹Å(†€9"Ž£ÔzQŽz~4¥ˆéÊ“qõ#éFãŽi;úþ4d眚 Æ>´`{ÑŸn(GáNúôÜç8¤ÿ=hNÝ)2s‘ÏãLǹ¥à{зzõö ÿU7è(‚€ÀëFïjoJ7zçó úÿZ9íùÓr3ƒIŸLþ4ìŸZ7c®I¦Ž Ç8ýhû½ñ@oR?:f{çò£¿J; ô9£p÷¦õ)1Çÿ^,3ÔQ»ÿ*aàR|£ëùÐÉõ4g©ÝÉŒþt¹½(¹ëNÚ˜ <0ôüh^õƒžÔQprëô¢‘D`09#n”ìyÎ=jDRG Òìç¡Ç§JE´=qJ=>•.ÁßùÒÁïùÐy烃èiÃ9ùе?hÛœRl×ò 8íúÒöüzQ°÷ÜP"$õ ûPŒÿõ©uÃ{p*E’yçÜÓŒ~äþ4?áNÈ"—ËÁÈcôíJ=E3ø?J1þM?€Ô›î3ÕEE“ÏîȦ€N~ñÜT¦5#æ^qØÒyHF1ý bè?LŸ@~´ð„w'¦—h=iÐ}iN}ÅHð£Ëäç4ÀŒ:T¾Zúb”ªÿ]"*qÈ£kÿש2Ü‘À_Ö€#ç¹R#¿ªCÏ~)»G “@Æ|ùéƒîirß¼}qMû<`çhÏ©¥ç'{g¿Ìq@ö<ƒõȤ$⤪õûßÞÉæœb`ª°÷  ã ":ÔR‹`rGãš7rŽ7ÔæŽzT¡` Q?2éÎi _~}é6ñœzV ‘H#¥1¯b~´ “ÿ׫:QåŒwÒyä­&ßSô59‰{ y{}N:¯µºŸ©àÐí“øñSù` nlýsHccŒ0ëÎî´®)3ƒÐŸ «O¯ãA^ø¤|ÏJÅOåÿ]_ÀƒÊ1è(ÆF0N? ›Êÿ<Ò˜Í ¯lý Œ×š²#ÔQä¦s´ëL Û{‚Oµ.ÜŽ™öÍYؽZ ~”X«€þt Ôâ¬ǧ>´ó×ùP}¼ã<цã?…Oå¨ÿ <±ýßÊ€ Áæ”c¹#Û9©Â sÛÞ€Ž9 1Ï ­qØ~u>ÎÄ“I寧#¹ qëŠ\wÇåR”çùÒlSØ~t~ð¤$ŽÞ§ÙÛyc_¨ÁçëFǵOåJ<¡ýÞh-¸óF®0=ê_+lç8€!a’qH0ÆÝô51¶Ñøš<=Gû¼R;t£ËÈà ߕJ#㥠ž§jŒ¿Þü©ØÏniþYìJ]§Ò˜†`‘Ïó v§cœO§JP¥h‡Iù¸>”¸íßÞ•W öcýâ?¥(] ‚w~¤Òí¿¥†ëK·=søP y9ÆM[ÒŸ´ú‘@Èí@ hò¸Áüé»01Æ=1Sõç¤ÅEŒtÀ£5&lÑŽŸ˜ ð 4ƒÿë©°sÆ?* ç·4‡æõý)wgœŸÊ¤*½ñ@ Ø~TÁïKœž#®)Y3È|ÿ.iÞe-îW ]¤ûÒmlã½;hÇZ>nÄ~ÀnÓõ4ìâ—ñ4£žÔ€n8ïF8è:P½ñK‚~4ͧÿ×K´ö§ôþT›O`&µG­8éùÑÐŒûÐ1Žÿ…sÛš~<ò}©Nz0©ëŠCÜvÑž˜4»MÅJ?O­séFÜsŠр:*]½ñK¶ŒÇ^ (àӿŸ€9?á@QÛ¿¥ P“×#ßµ&ÁÛŸz—œÑ†ö¦{1Ûò¤ØjM™9¥Û@ô¤ÁõÅMj Ð8ÿ8¦OAúÔÅ ù¿@ŒŽ2:ƒi)v1ëÍOåcõ¤õÎ:@A´õìàe€ëRùgx½þS@Å+뺛ïùT‹ƒ’ÀŸP)v¹ÖãÞŒcŽjL8ÿ–gñj\8ä"ý  d[O¥rzfŸ™·©@=wõ©G›»î¡_¯4Ч<ãéKƒôúÓÆz˜ñøÐHÇðþ&€*\ýõÏ'Š.0dc§cE'ǵ:“p›‰Æ(ì{fŒzŠO›Ü/Aó@1ü4}.xâ“v;cñ¦óøQéšMÀõ4¼Ô~¦ùQ“ØRnÏÿ®€í“F9è&r8ÉühCùÒ Ñß £>™úQÁ¦ÛÒƒùÑš_΀sùÒ“íIŸcKŸ®h1í—¯4gÚŒó@B)0/4P!1ëŸÂŒ}ihÍÔŽÔ¹>”™=èÀ£RgÓ4~ @Œô¥Ç€w gÖ—&€…/¦õ£žÃó bðzŠ ôÜ“ÁÅN('ÔQØcéG^GZ1×·½­'ùæŽ}(Ç­)œzRôí@(ÆzcÞ®hÅ”tþÊŒöâ— {P0â”Ú“&ŒPÑF? N(¸cüš(`cš1GÒ–€ 8¤çµ>Ô¸¢“'ÒŒJ.1íKIÛ¥'=¨ì}hÀíMÉÍÏc@ÅÅ~œRÐ Å})s@Äõ¥¤È?þª3í@ƒbŒÑõ4 \RcÚÂŽ}1@)qIôŠ\QÅ'áG?äÐþ4ŸÒ—ôœÑš\QŠAŠ\ûP0ǧ&“~@¥ëG=¨1KE% `QùÑŸj3øÐŠ1E'áùÑÏ®ii1øPÑH^=)ÜÐ1¢—ð ÑÏÿª ׊L ç­/Z7b—ô€qÎIö AGãKŽsýh4 NƒÒäSI?¥p4~tƒ¿•‡­ŒzÐqIŸ^”}(sGŠ(ÇQFhÅf“üó@ Š0)1KøÐ>´c4væŽÔp)1ÍíF(Ç"ŒcµzQ@){sE(µ¥ÏùÍ&¥£Þ€´R1ùÑF?ÎhÀô ŸJ>‚Ž˜â—$PcŠ0($ÑœúÒÅ&Ð{Rÿ*Z`G°{¥ç&ŸG½&=©6Š&Šf=ŠLR:vâ´ÒþtsL‚b€=èÅ-zs@ ³üæ‚£ßðâŒRûf€mihüè1îE&ÜäàúÓ¨w¤bŒ{ v1ëGÜ}hÛŸZZ?`&Ú6Šu€LQŒRÑLü(úbŠ1@çF=-u¤cÚŒ{RôíE0ÔŽixÍ% ;ÑÁ¥¤ ãÒ—íFh¦Ç÷h¤À¥À€1GNÔ›NâIàŽ”½)€rzŠ:QŸóš¨¤ÑIGùëLqIIÍæ€ôQž´s@ jL ?F}£J3š(¥â’Ž´`QGçF=%/åEÇz2qIŠ2}¨ ¥4~u ÍñÒ›Ó¶isJ;¨äRQš^=(˜öc…-&¥Ÿ4¼Š1@ “ô£ƒÛ4¸¤ µ/˜¥üèâŠ:v¢€ QøÑŠLPçgŠNÔ~Š3Gj@(¹¢“‚ŒzÐÒgüâ—ô‡¯søÐ0ÈÇÿZŽ´œúsìi{gfŒûÒ~Òqè(Ôf›Š9àÔf›“޹u C¹õ£½ ÏlÑów bæÇšLÑÏÔP³G4Îý)FhüÒIÒŒÐ1sõ¤Í!ühú \ûÒgѳFãŽ0i^ƒò¤“ëHFìeGóÅ;ùRqН(Ã;QEÆ )èh  ”ûãÚ”Šo#©¥Ç{?…1 éŠ"ŒqëF=ÿZ÷Å.} 7ÓAúP¿ÎŒŸ\Ògž”Û"€ ú“KœõþTgŽß…&îyoÒ€”¹úRuõ>ôcž” :ô½ûÒdqÚŒ“ü9îßÖŒ^i£èGµ)ÇsŠæ—µ ÿzƒŽ¹ ÏÖÞÆŒñÐÒ3@ =…祟JNhÔu¤ý( >ÔsëúQœô“ŸÂ€p;Ñ»=·ZCž¹ ÏÖΓ>´¼u £Jwpi23ïH:õãKøS:(f#§†hÄ÷æŒÒnšMÞ‚€žä~t›½ÇáIÏ=A£#ךv7{S~™4~tìÑŸ­7ô¤Àõ'èhû…ǽ4`ÿ— Ïå@Ýè(í’hJLãÖ€=ù4dÒn÷ý(ÉÇP³Ç9£Šnp:ÑÁÿõвZOåH=‡çHhù£4ßÈRn÷ ç4gñ¦u4¹>‡ë@Éú{Rd÷ý)£êir?^j?JO­zÐäz~” bÃÞ“¿Jv3íŠoµ/ç@ š3Å7#=yúRæ€4g4”ghrh擟jL怚23Ú›ùRóÒ€>¢¥&}hã¹£ùÒ~4qõú\úÐOÿ Lö£&€´À\ýhÿ<ÒdzÑÁé@ Iþx¢“§¯áHȥϽ7>ƒ4¹ ÏoåE'4¼SäQœñœQø~4f€ÆŒšNýhühhÍ&hÍ-¤Í/åI‘ê)0iy Fi9£‘@ü)i }}©wg¶h?ÊŒúÒ~´~Y BÒgÐRäzÑ@Þ¹¥ÈõÍ4zæ‚p:“џznAdzгÅÑŒqŠ? P¨Í7p¥Ï  BçÞŒZLûŠ2:ÐçÞ’Œû(É-7'¾/JZ?H9÷¥ ašOÆŽ=húP ç§?…/ãIŸoΖ€ Þô¹¦Ð>´ìQ­4çÖŒûÐ1Ôf“ó¤â€šLÿœR} &hìÒt÷¤ãÖ·±&€ŸÆŠnqKœPÑÐsIŸZ(qߊNhü(ü(àÿõÅ(úQ@ Å'zô ®}h<ûû0:÷£ß­-!¤ü©iq@ ÈÆ¥.}¨zçëG?…'”RŒÑõ óÞQøQǵ.xéG# â“ñâ“ŽÔ q¤ëÜþŸOçF{“ô BóFO§éH1”ð{ÑŸz\J?2=©2=h#Ž¿‰¤ dRü½ 2(½ºÒïIר¥Pk¯¾¼ö4RÜýôúéE ;ñÅ4þý/§Æ€ æ—>Ôƒ4 žŸ0‘ÒŒ‘Ûó óš^Ø A’:ŸÎŽ;ÑŽZNðñê ã*?J@$“‚{S°?ÖŒB?9Æs@9êECA\óÏàh~„Q×Óó¤ ß§¨£Óò Î'ò£?ûRuÿõÐæŽ{`¥&0isÛ½=Ï?J^}):õ Rsž ;#µçñ¤çÿÔ)½GC@ žÄÒ~#¥Æ—éÅ7Ò€M'=Oó¥Ï|ñ@ 4tíŸÂŽÝN(ÏÐç=é);Q’:дõϸõ<Ò~”§?þª:QÀ£_ÎŒ\{ \Ž) 1Û ¥é@4~<ö£êhÎh£4‡Ú—¯C­Í&AïA÷?•èqêhúbŽM!ìÐ ÈéKÅ'¾ÑùÒñÔP žùúÑÐôü¨#¿Z=¨ÏûT ý(ã<:rOÒ€ÝhÉô?•'~ÿ.HíúÐ}øúÑÿý)3íKƒ×¥íɤ>ÿ•/ùëIÍ&=OáKÏj2:ä­‡Š2;ãJ\žÜÒ{‚9 }?*^G&Œ“ßò¤ù¿ ÇR?:_Çó¤ ‘Étçòæ“9#ú P1ž”`âñI‘Ô=(ÂÑ”Ç^=…ÈæŒ÷&€Açâ—wN)>€š>´¹ï@8íMÎzŠwâÖ€ ç½úþ´qК21ž? \zQȤϥçµ/^ø£¶)84¼Pô£¨äçéG<`Ñ‚O^”¸>¿…íM94£ØÐîÀäQ’zp=é1F0(r(úçðÅ%/'¥-&~´˜Çn}©(ÝÏ?…/ó¦äãµçPþ94v擎™Òäv"€lÑÅ£¯qš9gÞŒœÑÈúP»Óš3í@ ÷âŒï@ ïIžzF=èÏèü¨<â y¤üh}@œf“Ÿlzš1ïŸÆ€ ÐÑŸz9GåGnôQ×±£?燮 \àÒäSzôRcô¹õ fŒÒt¤È ïFG­4qÓó¥Ýî3@ š3þM7w¯_j\怽è£4gŽ”¿…}¿oÏõ¥È=èx=©#‘FG­&Gs@ü)23ŒRcÐqIóãŒZvIëš?nqØÑŸjvN(Éôüé¹÷ ûƒõ C±IïÆi3þs@é׋ϡ£>¿¥'ÔgÒ‚ÍÓ€ØQÒ™“×­/=@ýiâqÍ&}(Î:ƒGÐSÜMœrhã·Z9î(í×õ£žÔ}h÷ AÉìhçÔÓpëKÏ­4½O4œŽ£š9 }(Éö¤íÎLP¹£&›Œûþ4¦(Ý{ÑùÒpxÁüè?OÖ‹œzÒuîs@'ÒéÒ€s×ñ¥¤9õâŽ@õ B掣¿áIš\o­&>¿.@àÑc­ >ô}(Æ}ãF0?úô´œã¥ú~´güŠ^¾´{Rsè?ùæ€4uÒg¶Ö“' ^œã4ž)3ô£oÎt£JniGã@qÇõ¥Éô¤ühÎ{怌ôæ“>Ô™õ£'µ/ãFsÐÑÆ94„ÿ‘@ “þE=åHüi3Ç^hÙ?äP=©9õýhõâ€üñFɤɣ¯j\þ¹>Ÿ­4~´¼ÐæŠ1IÇjQIýhýir=EôêŽô~PG¥ ç¡¢“aøÑŸAš\Q×ÔRtèMcéýhOÔOÇõ£§ÿ^“ž¼{PäwýhéÒŽzQ×½ýO׊MÃûÜÑ·Ô.híÒ€ sÔdð #¯JNèÜv¤£ŽÜþrGoƀƌäzŠ1ëÍ&§\Qy8£¶A úÐ1Àc·ìûÓG½/ÏßN{éE%ßÞO¡¢`wæÞŸÊš¹õÏÔÓ¿*?JQIÖŒ{ãð¦!{Rsë‘õ¥Àõüè=»ÐdƒÏJ\áçÞ‚p9SHOë@ã’Ø¥ëëõ¤É# RãÚ€ ÙúÐ}óKFh3žØ£#ûÔ¸ühÀêé@Àt94½úR~'°"ãéô£è À­Ðž{RcŽŸ­)g'ƒ@4½¤{ýiNi2G|БH[Ûò4tõÏÒŒ{PtíGåôÅ.ÿ¨Ñ×®MºRqŽ”áŽÙü¨8h9#­»b—Œô"ŒŸA@ Æzq@ãø—4î1Î)9ìx 9íF2~í(äQ¥&þŸz_ÚÇøfŽGLþ4¸ïÁ ô¤ÇùÍ/>”¹çéÒ—Š0:ô£“ÐçÚ€ؤÆ8Á£žàÑŸz1ŽÔ¹£·J8îy öÀ uåF}…¿ç¿å@ ù}(ã¶>‚Ž½ÖŒúŒP¶ñÔÒñþqé@ Çj03œ ÒþwéšOnsëGçGáùÑø~TžÔnÇoÒ–ŽxP»=@áAúŸÆŒqÎEŸJ9=ZNHöæ—$z M¼däÑòúP >”§þªnÑœhöÚ]ÀqšO=E'~˜ü)O_aG9=?*>´KøŠL w´|½zþ½z°˜íÇçFñïùRäãµ&3Üš°£¯Η¯§‡éŸÆŽP(*:ivûb€w ?•Ðr= LÔþtïÃúQÀ¦ût¥éÛš]ÃÒŒŒRr{cÚ—·4¹Í\þTzQÆxæ€>ôŸ¥qG~‡Š^;ÒqéHqžŸ­(õÆ=N(wzR~¾´½=è ž¢Œ}(#ò£ŽÇŠE'¸þT¼ŒâŽ ã¯Ò€ÃZ2§<ʨ„z~¦€ ‚03ùQôñ£ê?!KÇr(Ç®?*?ÏJ¢Œç½'çK’=>”}hÏ¥'ŒøÒóIÖ‚8ÆM:ÑÔñÒŽŸýzN3@ Ÿòi2I¥ÇýjLsÉdžÿ‡JLµúÑG˜ =Fáô£9íùÑŸÊ“ ô ôÁ¤ëÿêÅsÆ?:\Çñ ø£Ö—Ó&“'Ó¿JO\š^?úôg¯4œcŒÑלQŒò(ïÔš\ާŠ?ÏZM w£ûÀÐz ýhãÔzB3Œþ¿…/â?*9#‚)>†Ž=~¸=?Z\úŠMÀ÷?•(ÆhþT~_/ëI@=º}(ÍÿëQ“ƒ€ þïó¤>œ~4½²?Z(œ r9ô£qIé1KCùPÓ¸£Ó?AF?:\zPÏNi2{RÿžhëÐÐ!9õž´£>”tí@ ƒéG?¥æ­úŠ_~¿…!õÛŸÆ“Ž1Å¿ æŒûÑù{fŒœ¿Z.{;vëïA€g×ô£œðߥ'ÍÙ¨çë@éÞŽÝi½;Rãè) 3ëK= ): bùûÐ}ñšL÷Æ}qAg4½³ïHOçIõÈô£ÿ]œhÏlþT™ÀÿëRäÚÏ~o=±KÆ:f—¯C@ Ç^*3ÇZv)vZh9ýzNøò§ŽzýhÁ=M0sž3Å3Ž}éØí“KŽsÖ Çr>Ç4¤‘ëùSŠŠLõüéˆLät g×ó òyÆ)@Çñ~t† ÏcKÔûÒäôd¥è£#™ô¦1èEB(þñ£ðühwz:N¿þª8ôÍ&r=¨øÑ}i2 ûÔcý¬ÐoÖ—ž´˜ô4` @§4pG¨£AF}©€|¤`øÑŒt~4œóF}±@ š2}8úÒpGsGâ?\_ÊŽônãåHI¢€ŸÒ“púÒ}.N98Ô»×= €;þ4¸˜£Šk&Y[-Ç¡ëNÈ÷ ü(ǯ4™¹¤,=Aú \jO”ƒêhÀôçÚŒ84î=¨ã7ôgŽžôãÇbGµ!ÁíøfsÔR÷Æ3ùý(ü4˜Oë@ƒò47J8÷¤Áýz^(Å#½/¨Å&:ô£­㓊9í@ Ê“#Ö¡çÞŒŸj>”¹öÈö¤çÒŸz? Rã"ŒûÒzâ€ÔÑ‘õúQŽ3À¤ïÈïÂŽ{ãó¤Íõ ç âŒc’hÿ=hühhúSséÍ/8è(¿ZN=Eº AÏðЦ(àõý)zûRp;=©hëëH¥)#3MÈï¶—æ=x”`÷éõ EÆ—·øQƒÜ(ÀÏC@ Ç¥™¥ïÒŽÝhüZNir=yúP@Å!4tµ9ëšLç·éA=¾”¸ãŒ~4t¨ŠOÒ¤íL\Ð xúÐ{ŽY9쥷?z?¡þ”Rz`QøÂŒúæ—=)€e±Ö—æži3êhö'é@…äö¤ç¥äÒö隌©£½.=4PuïG>Ô¸ïüéGÓš@sŸÆ—#8'4‡ƒŒÒõàƒšOaÓéF9Æ Pj÷Å&Ð?ˆÑŠ^p9úÒsžhät£ïqúRŒg¥gøA÷ hëH@Ï^~´`{~TqÛ¨ hÏhÇE-&\ Ð0短.GcùRIÿ 2} ž´g“$ãŒýhß £ŠNG9zRç4m稣#Ô8î3øÒä}(>ŸÊƒ•ÏÊãG^r½/>‚€£œ~½©M'^”˜Õ~´gþ½('=sAÎ}}¨7pã@9{?J1É~({÷4™ÀäFAퟭ.(2O` ÿõPir(öÇãKŽ9ý(ç®ìLQS@~¹£Û8¥æ“ð ?‡ãKz)xè€sœŸÏŠv;Z3ÇB)*n?*1ßõÍ;4dzÐHõæŒ}OãKô£ŠM¾ Rm_Æ—OÆŽÜ þ4…Aô Ýi@öüè9îGá@ àv£ƒž3NÏÓñⓃÐþF€Ÿ\}hù€ì~´¸Çqõ£Ž§ùÐ~oQKÎ~õ/Ê:ŠBt~4g¿Qê9£ëJÆ;z 1øPc'=¨Ï`@úRŽ>¾Ô¸Çÿª€øþ´¼õþ´c=³ô£t•zsÚ“o4¤cœãñ }ր޴c üéqíK€;Æ€Œ¤{ŠÔÒçœ3íG'¡ýhãÐ~&Œú ;àçó àu†©õ…ÆhÝõAÖã·ô½ÿúÔ˜ïü©rOSùQŒt Ú1þ4p:`QœzRýN(?Ï—¿øÑŒsš(ühéíïG¿Ëîi21÷‡ÔPŸ|ûç¼gßÒŽ§¯áIž¾¾ç¹ü?7 wüi¤gû \c¨&€ŸÎŒÿx ýiöÇÖ€=q@ ‘ëGnh?çšNž”½{‘íIÛFxç—ƒê SAÏÒ“õühpÈ£‘Î?ZN‡¥g(F:àÐOlRuçKÅ~tCÍ/ãIøæ€AùRöï­.~‚“êÙmëÅ'=¨Ú¹£Æ€ ßð&—9øQöM¹  ÒóŠo^”£Þ€Wüš:öö ã=E Ý×ážÄRcÔÒuêÖžÜÐtàõ£9íKŸlQü½¨(8ëœý lþTpL8ëœ{RŽzc™½ö ÿ<Ñ‚)9Î@Å(ühÇ=©1èiHöýhíÓ… Qõ4˜?äÑÈí@ƒ†‹ŸJLŸAGãϵ/8 B~TœñœÞ—§aŠ1Ç`hHíŠN;Ò€{ÒàúP!¤g½'Óõ§ãÛšByê( px¥ÁöúbÇÓñ£¼“Ï¿ëMüÒ€ƒŒöõ¤à BrÑ@aè(zôr)2ñÖ—‘Ó¥!÷£ç ô ^=¨úG=J2=¿:1ÜfŒûFìzšL~—#¶1íKœÑÎ=h<ñKÛµ'>”¹oE èGô ¯þ´€“èhëš\j0Qù LžÆ®(~¦Ž1Ôb€séF|b€ÇšLÿœR€?úô¸~™})yô¤4¼ŸJ8#šLãÒ”ôÿëÐ`ûiqØœûRnÇ$S³éúÐt?ýz2=yúP>˜£óü¨<š1‘Èæ—9”f€ >”‡‡ð¥Æ=hqÝA÷¥¦ƒÎ sKÎx AøŠqÓõ£Ÿ_À \} M½ñKAõÍ&ãê(Çû9¥ü1G^ žç¯Öާ’)zw4‡é@9ãv~¦Œ öuì•õÀ Ž´…zdñKÏ|~1Çò L{R~9£'ýÚ^¾´püé2G^žæŽ‚ŽÈ œ}=Íãÿ¯FHô¤Ï?á@ î@ü(ϵ!ìþ4¹çùÐ0§Œãš`'×ò¥ý®(¼nN{(¸ 2“ÔƒE 1 ¹¨¥éIÛµ1 :ùѸ²)ã¶ir=}H ÎGj>¸üé:vÍ.r3°qï@àzŠ\qœ~"“ê1íF1Ð~´e}?JN:g4¼“œQ“ÛB=è?UüèÉ?ýz9ÿdÐüØÍ=ˆ¤<™¤ÈÃ@$wÅgØP;΀ ôÅ/~†€8Ü>”™?ýj2}qNÀõ4Ÿç­!÷£€;cëGÝà㣀?# ëKϵû~"ŒÐ íÆ?LûRÏZ6ÐpGbŒOÖ­}(Èãô¥ÁÇQz9î):v žœPIô£'(ç¶ />¼}(ç4uíG>”£-ŠZOÌQÈúP²LÒŸJOZ? ~4™ížž”¿çš>´=(>ZPFxëïG'©ö4‡ÜPíéI·O@ .8éŸjOÈŽÔ¸=ÀçÚãºÒûã4 Qô/QÓ}q@ “íøQÎ:Rûæ“¿\ûPƒß™ÇoÊ—µ“ÛgÔâÇó¤ãŠLçµRàÑ@ ǯ"—ñÓÞ—>Ôuô Çâ)2¯åNÏÐQÎ=¨¼wúÑ€}Nÿ“F\΀Ó°üizÓð¥Ïµ…&3Ô“ìhÆz v=("€qøÐ28À§ N¼ B êÀ ;ãƒüép1éF­ã½'ÛëKƒ×?†ir4³ô£“Ú—¯ÿZŒŒë@7zƒF|~dcŒç×ñ 9îi2£¨9÷§ëIƒõ =é Ïz^}±KÍ7ëùÑŒ÷¥Àú}h‡|ýhN§ò íïŠ\äQŽüPíGJ_Ä}1Gò #¾iy>†“§CA'¿ç@ Ÿ@>™¥Îx¦`ö<{Q:P¹ñI‘øÒ ž­Ï°§`÷ Ï¡sëǵÒpN(߈£ ñ‘Ÿ­&ëü¨ÀÇ¥úLz ]Ø lcî .3ØþtŸáG^ƒš3Îü©y'=E'AÀÀïFAÎþ´ìúÒgüâ€dÒãÓ£Ÿ_ÈQ“@ “è¿Z\dqïKHvžTŠN=¿:Lãø*p :ùQŒPuö£œõñ¥¤úÐ`zf—Ð~tgž”g’vàÐF3ßš_Ç𢀸4NAJvbà ü(3ÇðŠƒ¹Ï\jÒ€·4½{QëøQv ëIíAPÝFMëÆ€ÜÐ:z~=¨Ó4}H£ð4sGùÅŒûQCF1ÔäП­¸ïEöüè$~Ô}2(çØPsô 8Í7‘ÔÑÔzþ wŸ/¥'ø¥àœó‘ÞQÆEG~h⎣®(ÇùÅð£“Å.Gã@ÆÀ}(Ͻ.)3Ú€ ÃÔ~Tž„~dú~T§ç4€=±Gæ(Æ}h仸Ó;PqŽqKò÷&—ŽÜšovüèÉôüÍ.? 1žÔÜ™ü3Kj_¢ž)@>´ AŸN)ÀQíÒŽ=FhÏn(#ØÓsÆ0hçÜPç¶ßÎŽ‡Â“×4Rx¤ú \Ô™×>â€ðýhÿ~´úsKÎ}zš3ïA£ŸA@Ï4¼ÿ“FOµ˜ÔÑ‘ÞçFqØPŸlQõ þ4gÔÂc>Ÿ cÒ¥ôéõ¤Ï¿â)ˆ1íGéúÑ퓚9=ÇL~t½GJnFpWš8ôü¨~\ûûÒwíG”p(t :2AçIÏÖŒÐç=0~´väQôäÑ»¨ÔQòç€x£õÏài{}ÓŠCëúÒ`qíOú LÐàPc €´dw£Ÿ\ûÑôûÓ¹ö 8  ö£o±üèÀÇZ3Úß4£8Èçð ÈïúÑÇ^(éÚÀý}(úRý1ùÒ~tß?Z?*͇4¸â€i8=9£ß4½ºÐÇ÷±IŸN}÷Q´ÿ¥/µw¥ÔŸ†ÖŒÿ‘@öühàt£ðæŒzæ€=ÿ•Ô¿^húÊ€ô¥Ç¦ 7~ŸZ1í@ “éGãi¥ãÒƒŽôgýj(Ϲü¨"€ ÿ³GŸ1èÆFM.G§4gÓŠ@ù4£¥Ò;€=éqGN”¼PHïŠ\úL}Gã@8ë@ÁúÑÓ€hÇÒ€;ÒÒsõ¥ïÀâ€29ÇãFxⓟJ\ Lôçš9öüixŸüh>älÒqþM/ £Ðd}ixëKŠNÎh>n£õ4`ç­ç·ëGÓë@ œwü©QFXv£“Ú€îZ^½h<ú©â€íbŽ8éøÒ’@ÿ 0Ièh¨ü©ÀÒ`ž„QüéŸ4Ÿ{ (¢EËezQ@ qAaÛômö#éGaŽŸJPIçƒFãÓÑéó`ý)~o^žœS€œc9£ŸîãÞ—9¤Ç9ýhEõ_×4dÿ• =3õ4ìÿœÑøÒcÛ—¹ çŽáKϽ bŒ\Гÿë4nÏô4‡ônöý(Û…‡AIžô^zšÎëI÷ºÍuÍ8œRsÜ~T™$tý)9ú¥?ƒëMÆ G'¡£…䑞™Å 8êM;“ßõ£ŸSŠLß΀žô½xÇëG±Í'¦MñÍ !½ùæ—'·Z7qÎ~´ ¦H£ðÍ®ixÇZïFG|QƒØš@=Ö€¯AøÒsž¹¥üæ—€<`ŠNÉ¥Æ1Å&}@ ëKɵ'Zü2{Š2=(ð ž(qžÀ}hqMÀ RóØÐž™9ü)Gÿ®Œõ挜~¦€>ù£¿¥'#¨£#=èyü)sÇ4dúÑšwÿ7<ôÇãG×4˜ç½)t£Óð¦óÜÎÞÆ€§ÌÒóïŸÒ“ßš8 ôŸñ£?SJséŠL7OæisŽ”uéš=¶š?@ǶiG4të@ï‘úÒm8¥ühÿ<Ð`´`‚þx¤é@ †ì?J0{ã>´¸÷£Ÿ^(»sõö4»qÔâ—èzæ€×4téK­{šN½ÇÓ4cÜÆ—PlO§?Z^hçÒŒæ€ fÌÑøâ“ñ4ÀM/×ñ¤Î:“GLu4cüæŽ{þ”¸üé9=¨ãšn9Ï8ôìsÉ£“üF€ó sÛñÍ)Òm€§©ö¤Ü8#õ£¯LRóÜÐs׌Q?”AIøãé@ ŸlRñéG9ô4sÓ#ÜÐôéG¢Žž€QÓÞ€¯¥ 8ço4ïsÇãF=(2Ç¡ü1FO¦hÇ©?Ö€ îÑ“éÅ(?QF>¿>”„lûÒàgÇÜô¥æ€žß­!QßÒíéÅ.Ð1@ ŸLR`žÀ~4ìiúÐ:óKŒ÷ŽÏýõ@;nsëKéIz9ôÅCGâÅ‘ÐQƒëj2~¿QG¼Ð0{ôúÒãëHxë@niyïI‘èqGî(7(ãëKž®i=y?J^qÖ€ gŽ)ã¸Ô Ž´¼ÿúèã¦(÷8Å4ݧ9#ñÎhÙÝ&9íŠ1Œv¥ç¸‡#¢‚>´`žÂ—üõ¤ù½q@Ô~´uñG9âŒÿQ ïAãéô sÞŽø ä~4wëIžxÏåFsÕHúÐõêH4xÅïÅQ@^Ø£hõâŒdphÎ=ÿ 6û`ý(Å.=±GçùЃè1IƒŽ@qþM.tÆ>”œš1ž¥Úqíí@„>çuô û 3ÇlÐ0ÿ<ÑÏa@ú’hÇ~M¼fŽÔ¹öü©9$hæŽýÅ4`Ðyô£'¹Å.1Æhüè9úÑ×±¸âŽ”˜=¿:^G­`P0ÏÒ—Œö¤ÇåG¿£'üŠ?•!P 8ìGÒ”3ÏçMÿ=(â#<ÑœŠL絇æh£4`ç­&x£¯ALÎjL“@Ààu¥ BdÿU&Xœî¥¹ÅàûÒ_¦3H@Ï|ûS‡OZ¡Ä7ë)~ƒ⌎™o¥úýEçÖÏéA”þE&)vŸoÊŒŸCGažÖ€ýM $ñ‘G>¸ô¿JN(ãÚ¦(*=ÿ­'áGN¸ £8=)¿/nM.‰þøš2OP? 1žÔtô PA¥çëAÏÿZ€ Çó£¹ ÞŒ{ÐLQŒõ£u¢€ÀbŽsÆ>¦Œúš^”œôëAÓ?úñG>¢€øÑÍúš9 žI¥ç×ô£&“ƒÇç@ëëùÒühü9 ÃëKõ¤j1îhÆ{qJÔ›E±Š^N 3ëü©ך2{~TqŸá¥#§åIϦ(ç?(8ãm/>´˜8ëIŸoÆ€އõ£ƒÐf‚3Ú‚8 œ{_ ýi¹>ß•.=sHA÷ǽ‚y£+þE=†MzÐgÔœý('= 8£¶7FIþ2 CÏùëKœö£×4§4­†Qìh¤“—ã QHd»¨£'søRqÛ4¸õçÞ˜3МRìíšQ‘ô¤Ã{P ÀéÅöÇãGnqš8úPúgñ¤8#<QÈ¥À¨¸ú=ry£ÜQ“@F2qK‘Ç4™ÿ&Œ.zPäzŸÎŽO|ý)? ^}(ÿõR‘íšLû~´{怚3êhùàÆŒœõ½:Ÿz_¡ŒsŽ(<ñŸz:zÒaGl}iAâ€{p}èü(úÑÏn>´sÒÎŽ(ÀúPQJ#ÐÐr·Ö“×ñ§síøR@}òh÷ÇëKÐt?…õí@^G_zNƒ8¥ØÒcž zcJZN{Ñž=¾”¸ v¤É=1I{œ{Ò:+bTäv怃éùR…ã·åFN:ŒÑŸR(ÿ<Ðî@õ£+ŒQŸC@þTŒ‘Gü Z>nÄ€Z2½ˆüè<ŽGãIŽqÅ/C×ò£è(ÅW9ï@ Ï8$~¹ãþ½:b“@(çÔPsïGÿZ9èÝéÍBM=†(AÏ_åGÐçëÍÄR~ãþq@àsŸÆæ—òÅrisÇJ3êGÐRgÐPýEð£ð4s@ íŠ9ïGãI×Ò€Ç4tÍô éš?FO¥íƒ@)h£ô £ó£>ôPIœzÒç= gÞ“ó£4gßš8ÿõšSÓúŠLw£·ÐøâŽOoÖŒûQ@ ôþt™ÍxÈ£žÆ€þ &IÏ©#éKœX~4dž ÅÇN)?FFsœÐàž¤ÑžØ4g×¥!nÌ2>”uô£õü¨8éïKœúŠ01Ó4ƒ§ ~sÛ4¸'Ò€ qFîØ£Žù zLärç@_Δ­&(Ïb=qK•ô¤Àõj>Ÿ…Å(9çcÜÒà÷lýh9ê3ùQŸ^¾ÔcœãŸ\Ræ€3÷QøþtqëF}9 Ú“ퟭ.A €{ПÿVh£èE'SÒ€¯PhàcŸÎ“Œã&—w 'Û4 ¥ãÞ“ó ù½…}1FGMÜÒqžG4Ž£qÚ—¯|ÐvÆ?ZLãµ.GsJ=3@ ï’9úÒãÚ—­úÐdqŠ=ésÇsIùÐùÒqÛùÒŒc¹ ý ''ééKùPqš3œÐÇb?:ÒŒCIœÐãÛ4céG4™ÿ@ÐF`)sHA=Wõ 8tõ£hì´ t Îzϵ/áF}óïFOb(1ê?:^ƒ‘AæÆ€ƒšB=Í/±æ€“ u£ê)zŽ>ô 8ô õíIÏð4¿Ž(Ç4˜9é—ÔÒc¯&Éõüé1ïFÓÛõ¤ÁïÖŽÇÓñ¤õâŒ0ic§ühÉ£¸¥Ïáõ¦ Áô`ÑøÑòÐRñØ~4Ru aú~4gÞŒ8¨8£Ž´¹£¯Ö€ ñÒ0ô4cÚ—ùÒÇ·ë@üRŒŽÔrzŠNô½hϨ ã§éLB~¼š9¥ Ò9ÍzÐ}ÅS›Frhô¥çÿ×Gå@ƒoµ&=sKøþt~T€qÔŠLýM.1Î÷£çµž„}iz ãó¥ ÇAô¢˜„ÿ<Òí8íFM­#µ&Þùý)*?àT ¤äó×ðÅ.@£pÏÿZ€ ç­&Ù¥ëÓ4gÜÐsõ£š2}A¥ù±Æ?*oÔRñô£,=(ùº6?*Ûš7OÖŽh}(éŸÂ“ñæ—$z© #¸ sØb“éÂŽ;ñ@ ŸcIÆzïF{f”ãéõ Èõ£8éùÑøÑùPHî3ë@Ûü"Ä{Š}¨r{þ”œö#éŠ1ïKÎ:gë@4séŠO¯ ßô ŸR(¦ŒsÉ£?LP³IÈö¤ö&ŒjvÎhÏâ)9ë‘GSÓš\Œö¤ÏÒŽ”sŽ¢€ÔœõcÙO½»f€séøQõ4fŒãµ~b“ðüèÈí@ ÐqF3Hë‘K“øPÒ—ñsíKøÐ{æÆŒú>´gœgš3Çcô¥ÏjLÔÑÓŠ^ýîçIÛ­úþ¼Òsô£¨ëϵ.@>¿…/†Ž}J9ŸCKFqÔÒg¡Íð}zQú­)ÿ×G=ñ@ Œã“øRgà‘ëK×­Gã@ ´™Èô£ðÍ.=sIþzPóÛ?J>§›‘KŸïP29€RïE$¤ïã­€“8 Í)#Ѩ ϧ§4¿­1lóïFyÆsì(9Ñלœ}(Îz Qþx¥\ÐN:h8ôÅ'¿•/çHqœæ€3š¼v“ðÅ1ù{ÒãÚ—§A@ àÑëúRà÷Òuþ#@ ·±õ£?{ð¥qÆ”·¢æ€ž)O?þªL¶zøRîõÎ}¨HäŠ1߀z~´ žÙ›OpGãK€Nr~”`”€sœÓN 'Ny£Üô —ê1I‘ïJê…Ã4j^Ýxö àu#4´c¸¤ãêhéØQŽãsÛŒc¿?J9ÇÌEéùPíG?…P}zRg×ô4¹ëŠCƒÓ¯­&1ԜӉÐýhÁÇJnyqÚ” ŽOàipJoRäuà~4¤c®hü(àô ãéõâŒPzvÅ7óŠ6ÒôÀÍó@ Ïÿ^ŽýM.}'|ø3Žÿ­¹Î8æŽzb€z1žiphǾ 7çò¥Ò—ôlï@ ÇLPJ÷?/>¦Ž}I 9Ç€Ùî ¥+íùнö#ñ¥Èõ¤ÜOËš_ÌP»sIÀ鿉Z^3ך^=(ëéGáAÅzSÏ·½'¹~tpˆæ—¥&sÜþT½;Ð zPiGÐ3êhÿ8£ð¢€:LâŽ(*B}¨£§A@ ô¥þ´qž´™ö4{M/ašLœQÏ  À<ã'Ö“#<æ—‚Æ“#ð Žô£Çô¥ÈàP`ú©¥ôûf®?01œ(£‘ü#ó¥ö€žç#éGNô¹Í ÉÍ'çJ3éAÍ "—|Þ‚Ž~Ÿ&1þ4u¥çëI»=öJÇÓڌ砣œõ ¤êi^¿.GRhzõþ4dzÆšv‘ÆM(är1õ ŽÔt$~4¹ö úPøQõÅúR ýP)9÷¥Æ}¨É~´dôÅ'Nâ—ôϽ–({SA¥Åúñ@!õ#ñ£8= .}1@ã‘IŒuÀö¥ã®EÇJâãÔÒó×J0zb€þ¤ÈÇ_Öô¤Ï=…&“G·z\ïN£ ÜbŒŸjZJNsßgœR‘Iž?€õð>÷¢ôäÑíŸÊ€#×?Z3žß¥. £óü) O­/à? >„ N{:b ÑÏ\‘ô¥æ‚}Àüh2=³Aèp} .OPi(ãÔRžZ ¤ãhÿ=h94gñJ< N~ŸZ9¥éíGJ@=áG¥ dfŒP1=€¤Ïàixõ¥àÐ!¾Ù'ñ¥äZ\ûñGNA cp3ÁÇãKõ£#¹£¨ã48éŸÖ—Ç<ÓNh$÷9¤±ø})1ßšMÇ·"—'±À7_΂Ã=hÉhëÞ€ ç½=©2Z0(~”™9äš8ôgŽ´d~4‡ØÒ矽Š1ùÐ*PAÿõÒƒF@RR§ÞˆzéxúRÐH÷¤Æ=:~9ïI€M ÀéE- €ix÷£ñ ç=h1×­AøflK‘þ½õÆ)>ocFpx”Ðq@g4¼ã­&1Ïó˜Ò”c×¼†€ ŒsGNÙ¥úô£ó #½÷æ—ŒpsIÇ|К8ÆOëK€;Ð0àt<Ñ­8ã4cóúP!Þ§4}ßoz2}2}è†õp….=3KƒÜþß®(Àô¥ÇaȤã¾hãÞ“=1J3êM>œPõÅ.p:Rv£8ï@ ’}3ô¥ŽZ8oz\0ã  ÏZ>¼æŒsÿÖ£‘Ûó cÿ­KjAºŽ;œPíÈö (ô£§NhÉ‘@jQMÉþíõ­;n:Rd)3Ÿj_­.1Gâµ&G­-'€¥Ç|Š8úÑ@ œÒsØÒh ëHHÇ84´ŸZQŽ¢Œþ“êMç#4¹öéF1Û­ Ï­Þ”sïŠ3Žô`ãƒ@GzPAn^sê/ùé@ Aü):qŠ:ú©p=(>olRãŒQüèëÛõ >½(ëIÖ—ñ jC·Û4î{â“§AÅQÆ2IüèǸ˜Éëϵ¯úRñG9ê'¶h0}ãIŒ ÒŸŒrp)>œ{Ð¥ð{Ròzþ”™©?J'8Ÿ¯J=FisÆp'$vüè}(äw¥Àô¤éØÐ2ù+ô4Q1ùÆ¢€%‚ŒOÆ{gÓ¹÷¤#ƒô¥êhú“­Ä>´gµQøš8?þªR2=(Å}  ÆaGø³F©J\Ÿ¯á@ õæ“Óõ¥çÒ—¿JNAçõ4déGŸ†(Î9äP€9ŒLþ4óš8?þª1ëÅ. “þ4c=ù ô¤Ç×4½½hÎ;PgÓ÷¥ûQü¨ãÔŸ­¤8ǯãKz8õý(?QøÑŽxý)Z:ÿé@Àx£Œ{Põ£ç4œ÷úþTcÜÐcšP)0}J&Ûëš^ý¿:Lœôý)N=å@±š­&}Î)}èþTgèhíÓ"–@cÎ3úÒð(àû҃ǀ°þ”dv£¾>¸¥ç=xúPp}*9é“ô ƒœŽ´gŽ„ý(çµ7­?þº=È ¥Æ;KIƒ@ œzŸ¥ ÉéÒ—ŸR? :ûûŠ2=J2= ú 8õÅqÜÐÿ{éAç4˜ÿ9£ÿë ^{Š3ŽÄÒsëGüþ¹Çl~4nõȤÇ×ð4dа1Ï“›ƒëšpÇp(Âj2¾¸úQJ€ÂŽqÈ£ƒÎHý(ü?@xÿ\g×sôühÇzZ9ê3üé>¤ÐI´¹¤?B\çÖ‚@õ ¿ â}0:Ñì4´}i¹=ÿZ?@ ŸÂóÖ“'ûÔ~4¹Ïlý(ät¤r1Å=ÏMÔŸ/\gš9¥Ïµ6Œñ@ÉýzLçµvãëA'ë@ Ó·ëF@÷ýiíš¿­.ïÊ—9)3FxäŸÂ€B)ri¤únüE-úÒeº*\úŒÑ‘Пç@rh÷äûQÇlQ€{š:ô'ñ¥úœšo:^1Óð ÎOLR(üqK‘šC‘ïô£ðãÞŽÜp=…ÿ•ô4c=…¥Ú:‘@sIŒvý):9ÏNhü?:Cžÿ¥:Æ€œvŒñïKEO֌ⓠž†—hÏN}sÍzŠLñÉ'Ó¸ÇsøÑŠ8£(úñõ¤#Ò€ ÔcëJ1ØÎŒŸL}h ŸjO¨Í.~‚“¿4»½2}±HNzÒñÐùQœzÐsëG8¥Çj1ß þM.=F)§n0EÙ séIIïý)Où4´ƒ”уê 2;Œš> þt»qIÆ:PŽÔ ¶(ÿ=ixúQŽùzsGà)qÀ¤ëí@ƒ£ô4`ö4¼ú~”` ZOÊŽ(Ãñ£ò¤ü^N)?Z1íGá@ÃùRâ“ò ÒqØæŒIøÑŒÓsëF}(Å'±þT€wÔŠLÒ`vsžƒð¦Ÿl~4~†“ÿ…ÅIGé@GOåK‘ëùÒdëøRô” ? {Ò~?­žM(4˜£Š^;sHN9€ Žù¤üM.2{ÑÓ¨Þ¥&x Ž­ºLBÑŸ]ÔœQŽû¿¥!Š1õ¥äô¦ñëøRŒzÐýGåK;šJ(sš8ëÆ}hÀô£­0;šNü0¥¤ã­¨æŽžÔ}@£ƒÿ× ãµô»h㵡ⓧz\Z({ã?zŒP~¸ óŠ;Qß–'Ú“Œt£ÿÕ@ ŒQšNÖƒøÆ€ SJxëHÅýéFïjN1ž¤Ð1yÿëÑ׸4˜ÇsK€hÜc¦1F=¥GÿZ€¼Ñ¥.8£#¿JLcduþTp{Q×ÿÕ@ç¡£ðüèÀúQê(ýhþ4mç·ãIŒPǽôcŸz?ϵ9ÎxúRägž}èÁ¤Æ:ãò ÀÏ{ÑšO”z~T¼zq@iyÿõÒe}¿Z^| 1ì?:8õÍ{ÑÆ9ÅÜÑÀã4qŠ?2zš2;sG°i~‚€”„Žù£ðæŒÿœPýãIÆ=hà÷£”£ rFhsÒ—œw\ѸJ.HÔûš^:ŒÒa~T\ûdÑ’hÇn*1ëúÐþzP~´`Ù£¯ b€qÔÑJ\cž)2=hÏ¿éG>Ô¿&Oá@=çIóv#gÛò :cÚ€Þõ“ÿõérj3ëŠO×ñ¥ ž‡Š3éŒP3ë‘Awð¤$cü)3Œ#ñ `ö8£Û’}(<Ž”q·ü(ëÜýhëÐ~9£'Œ“Ô~ëÏÒŽ4˜ÀãƒKž9ü¨÷Z\æ“<ð1Cg(_Æ€M.N{SpHíKžÆ€“>ù¸œRcØPß¿áF}ÎiHÞ€'®Ü¨¤ÜGcô4ã‘ÿê¦õ=(ïÓgŽ”¸>ôtìh8£ÐsG¯ vãj9=F .;gó¤'yõ£•ûRöÎ7ƒÆï‘é@Nhü?#LÉ<úRœö?¥/Sœ©¥É©¹#§éÚ€N2pOµ;ŒQŸlR`d’´f€'¶?:´Þ; 3އô nã¡Í&OsIŽÔf€ ÷ü;Ÿ¥3 ö4è:v}I£œð)?Ï4‡óü(ÇüæŽz`RdÁ"“Ú€˜žô`âŽ}qô¥é@¯çI{Š_óÒŒñžOÒ€¡âŒ{FGÒŒýhö<ý(ã± 8Íz1ƒF=pŸzS× ¤š1øQz³PŸ ¥g¾~´uŠF(xìE/?ýzo^ò£Ž™Í.9õ£ùJ:ÿõ¨ ǾhÀíÏáG?…÷ §lþ4~T¼ú¨ü•/֒΀~”sëG¿z8Ç<ПzOÆ—¥ÿ&€Ô}°üèý>”sê?K׸¤Š=¨ÇãFAãŽ:çõ àŽMçŠ9íGчåF3ïøÐãÒ“ÿ…íG© z1×&Ž€:üǘ Ú;c?J^Ýÿ*OÄÑö¿Z\J9ìGÒŒqþ4b‡°'ó£ sIéž>”gÔó@…È=9£&ŽqÍü(ê)8¥/^˜£Ÿj'__Η¥ÏR3ô£µ&}ÿJ_­½(úФÆ)qþEÇ­&áKÛ8¤'=¨àö4^4pzÒ ZRc@Ã#i0¹íŸ­=Š?(àö4žý)r}hséš1žÔ:?:9éÅ£=»Òõô bqÔÊŒŽàþT|~JP£ ûj3“Ó)sÚgÐQÁæŒJbÁãޏ£ŽØ™÷ c¿>”˜¾Ø~#éŠBÛ»==ér}E#-ô¿7’1Èüiz×ñ 4g¶?*AïŠ^Ôm4…@íGƒÏãKÆ:b˜ƒ§ÿª“>¿Ê—?äQÇã@ÆàQÇù4¸Çz1Hðêhôü…ãüèàÓ!øQø~T™ÿ"Œg·âhq@úR3Àü©~½hgž”¹¤ç¸™ÇQϵ(ø¥çSsŸ­/=M/=ñøQ“GÑ@Àžhþt}qKš?*1E&@ BÒ}qGçF´t ŸJ;ÿõ¨gÐÑ‘øÑù~Tôü¨üi:úš3èEw€½?ÝÅ/¨í@Ï¥/ëMèx#éN Ÿ¥.Üúé1ÏAF=)yö ëÓ4|Ãÿ­Kœý)0?»@âzŠ(ã𣞙â€êh¤éÐgè(Ï=8 SGáIÇ^´¹=p(9öÒŽG|R€ ÿ"€Ÿ_Z3ŠLc¹—¶y žÔú N:ðhü¨séÖŽ{ñïŠLc¿Ô ~J2}isÁ¤æ—éÏá@×§½- 8ïŠ:Pþ?>Ô™ôú Z?Z:rx£"€ ç¡£±£?ÝÅQÏ­÷ÇáKŸ­}(Í'Å.{R}EŒqGN€PϦEóÖ“å‘ÏÒ—#¾(ïœÐè &>^)~½(Îz:Rqš^P0þt~4‡ž¸Å÷€ zš^”™ô¥ÉÇj‚¼¿CE2Œv4RãéKÉö>ôÑ‘N'ñúÐ\þ¼ŽÜRg"”céLAÏ¡£éœÑŒ¥&€žÙ¥ÅÈÿëÑôÉúš>¸£>†úñKíŠ^žô¿…3ÜÒçÖ€ óȤÆ;Rç¶÷ r8éF~˜ô£cÓ€<ýßÒ—z­Çs@çÐÜB2pzRàzçñ£=¹üh0;Ö—žß©£¯ðÑøÐÇ¡üèÅv£þʉ·Ó—“Œ}ãøQÆzƒõ Èî '¥ü?*3Ž¥ ñÐÑõ£9gÐf€ Œ{RŒýi¼ŽÔƒŽKõ cŠûRg=áÚŒ/Ö—>ÔN{ QKQFOÓÒóÖ€ {QŒRŒýi}h1ëϵ(ã•/áÍ'Œb€::?:8õ9¥É ÈèzÑÇLâŒsKŸAúPuéGz\óKùPQÁÿëÒçž´wï@Æ)Ï\“KÞŽG@Oã@ ´Ríö ò:~T˜ôÈ `ì(Àýz>  2}¨1íAéÓŠ_Ò×48ãuþiÄŽÝihÁô ñÁ£·Z?N½š9ïÍ/ëFryü¨öǽ£j:º(ϰüèàsŽ”d”z1øRçÔÐe½? 2=(è8Æ(?†~´€Žàý)~ƒŠ3þsAÏ×êhçû þ4¸ö¦÷ÿ ^¨àv¥È¤Ï¸¥Ç@qÚý?:?2~”r:â€ýh<öüèèizô,hÆ8Æ(Z?—Ö—¿·Ö€éGÍÓrO>´§Ó€iÍG¥tF èIp?Š“ƒ¸‘NéÔqô ã€“ÔâŒ{þ”ž´¸€g~isŽãò c=?>_AùPñÐÒqØãÚ—¯½&Üú:ô&—õö£'ЊNÖ€œRdã¯~'ëKƒØÐ =ø¤ï÷x¥Ç¯4~T`uÅÑßÖ”{õ Á£ñ¸?Z9ì &OÒ—ŸN(ëÐÒb€4~4Š?Ï4œ÷giÏZNyŸÎ€ zQŠ_ÒŽ(Áì?Z@=€¥Í äzš9ïKøf“Ú€ {fŒw¢–€ÏaúуýÁNíIL~ NsÐ~`ý)pqÃgñ£J7$~t¼ö'è1KŒR}?Z1ÞŒqÉsG=èÇÐ¥/>Æ“=Mw bæƒÍã¥''µ.Î(ÈéžhúQ“þÉ ÝFO¨ühçÓô þŒg&Ž´GáúÐÎ9ÇáIÁ¥öÀ£jÿõQG^ß­ý?N½(ϵÍ(9ö¢”ŒúQƒ@¥£œQÍqõŸþµ.p:þ9¤>ôsŽ /ÔRsÿÖ£ŸJ@)÷æ“ð¸ãÓè(Î8Í1 ÇL‚isÛò£8ÿõQ×¹¤0ú⎼(£žâ˜ƒ8ëA x÷4güŠ\ÿ’(›³÷M=èÎøRó@ ò)y4™4uô?Q@ƒ>‚“gŠ2M‘Ø}i \ŸQн&æôý(É™÷¦ óßò£­‡ë@„ žàûÒ÷¨Í‘@M=Í»“Åçï }(ŸZQÏaGÍ'qÞ€ïKÍ'¸ëK@ƒêsIŸ|¥zf—¯` '4|Þ£ô½(Èõë@~´g©£ŸZ9³@ýTn9Çð£'éKŸ§á@ øþ´d穥ɤ'ÔÐò}0}i3ž‡Z9 æŽÔsK@ÄãÓŸjïKÏ¥'?AøÒÀ/9惟LP!3ÇCKšN:d~t¸Ô \Òt£ô¢{sF(íÜÑÏs@8ëI·Š^}(éÐPßµ}? Oµ úPűڗñ¢€§zLóNǵ'^äP(99ãéF)0~”džù£'·J0)? çŒýsFP3õ£·ŒsŸÒ€< \\RrG˜Èí\Ðþ9£8ê)3ì~´£¸ Ÿ@(þt¹éü¨Ï©uëF>”¼ð0?NO¥w¶(Ï#­=ýèÈíŠ_­ô£ëGùé@GPM/9ëMÛïF;ùПÄRàßœþœþ´c½.\þ”˜\äãëK€N{ÐAä‚ wט?þº0=³@ 8ïFO¥Ž>´´™ãühüè÷ aŽôd?¥'~Ÿ(Ï­FxéGò¤Æ:“ôÍ./­õ©0½iß'xüh>_Z^óö£ô ž¹È¤Ç§ò ƒÖŽÉ qF}¿*NqÜÒõþC!Ÿ‚¿CE$Õú(@HïKÉçµ ü?:Z`ކާ#š0{Rãד@ƒ·9£ò(˜"—s‚~”uäP~£>™£¨£ õ P(þts×¥}(ú`Ñõý(ã±æŒþŠ2O¡dOÄÒ:ð?_Æ“>ÿç­ëøPçž¿­yÍêhïØPôü»ÑŸoƃz1þE¸£”cŽ(æ‰ógÓéFìvâ—8ëÅwÇã@ƒ<à`Rdôç4¸ÒŽÝÅ ÷ãñ§c®hÎZ;p&Þ8c=óA>ÃëFsÒ€Ô¹îGÒŽzÑôÍ(É”Qšo^´¼Ž(ÝFx£ž3F>”¹ÏNi9õæ—·ZN{ÐþyúRõ£žØ¥ü3@}ÓŽÞßJσ@ ô4f“#=©IÇ_ç@yõ4qÒ—tñ¤çé@ ÇcÏ­'=ˆü©ÎŽ}¨¡¼u£8î(É ¶~™¤9©sš½&yêiyÍcñ@=qøSI^àþTî½£Ÿ  Æ}GéIƒéš\gÐþ4p(1žÿ˜£Á"ƒî3Gr?­!ÅœýÿÊ€áGʽhÇ«õ£‘ÐRã=“qøPÉëÅ& ÷¼„Pphz`éJãü3@#Ô}~tm>”¸'¡"ŒPs›¥£89Î}©qžøö äïô¥Ï=)O¶ £$Œ•ühÿgÚP?:_ É£§·Ö€¯Ÿ¥ÁúŠ?JLâ—Û4¸¿4c>”ÞýHZ_—ÔQÛúš=²nH<Ö‚}ýóFÒxâ€Û¿rhùI篵¶iqÛŠ>”™ö /NØ¥ì Éã$~4»» 0>¿žÆ“žëÅ.>‚œu žÙÍéš\ûÑŸ|šLq÷M#¢ÄÐA¥Îhç×qŸº~´`PÍ)8õ£'ÿ®)3ž‡s@=Ogßõ£ñçëKÚ€}h¤ÿã4}/8¤ÅzPÏù4`cœþtdõóF~ŸŽƒó£ÔsŸ_¥© ú­.=¿Z:QøÐþzÒqØgñ¥Ï½zPp:àŠ_Ãõ£žãjNGE?…/áG>”„çøN}è‡ñ ŸNip}(Ýô gÐQúÑJ\ã°¤ëÒ€”bàöÍã¶(~”u£ð zPéIKŽsŠ>ƒ4bƒô£é@„Àô£ÚŽzfŒã ŒsŒþpG<ýhúC JLNihǵ1#ëGÍ׿‡™…ΓڌŸJ8ôühséE.hÉéŒP0çÒ“}~´¿…… “¿$þTáš9ôü(¼Ä}ix=ér3éIüéˆ1Ç_z99ÍÈèhÉÇJLRóŽh͆hcžÿ!üéN;€~´~4Çݤ9éŠ?h?Qô¤ SK†õ`z 6Žz `''¯"ƒéƒKÓÓJ1ì9ïŠ>”tê)1ÏAøÒçØfqë@ä÷ͨç¿éLæƒÇ\ÓyÇõ£Ú€޽© Š9=©1ëÖ€v=ã½:QùP×·¿••'N€PŒÑIÏp(ç°¸è~´œú>‚Œû _Àþt`ã£ñ4œ{ÐÛ‚(ýhÈôýh#=GøP1yÿ&އ­'”¸ôQ@ƒ'ë@‚Œj\{ÑÓ’ &± x éF})2¥8ã?-ã4™ÀäÒçž(úPG¯½&yéøÑø q<ã4™§Š@@èGÐQúŠRGÒŒRhǰ4ƒ®0ã@}3IÏn};ò£ŽÔœžqúæŒqFHõÅϽ.)1އbŒ~4„g¡4` ãš1@ Ç¥íÍ(Ö¯Ð³ŽØ¤ÏRZ\Q@±$~~?/â( b€ Ô`zÒ`ô¸çÿ9¤Ç ?/J?:0~”qëšL“éô£ö Ç×ó gך8Ç4cŽÔsF=ÍÒãé@ ·<àÒããš@=@Í(㸠Å)8ïŸÂƒ‘Ðdzç¥{æ—9£æô_­ˆ Èç­(ôæÄR ÍïAÏlŸ¥÷£#¡ ëÍ!ö?…ôü(í@ Ž9Ÿ>Ô¼ÿú¨3Ž™£?Z3IÍ/ãIƒ×&Œ_ÖƒƒÏzC7UïÁ¢‰±•õÁ¢ß½;қɔuïǵø¥ç°¤ÆGëFO§4 _b '~†—?'Ï4Z3ëš2{sIòŽ´p~”¹=zQ‘@9ÈÆhüNi:úèÃõ ž¸ýhÀúQÛ¥·gñ£'ÞŠ^?úô˜ÏZ9õ4¸¤Á¨çéGO¥qëÅ.(3ƒíGêhÉéŒÑŽ>í/?ZOøcœQŸJ1íF¡¥ÿ<ÐAì3õ4ŸAøQƒéŠ1íùqKŒ÷éÚ€E'ÔÆ—å¿J\~&1ïK“ÜRc°£ÈÑ·ðúQºŒ“@ Ïùc>´™ÿ&Àà€ŽsŒqëIÏ~iyü(Áõ¤¥Çå@ãŠ0{Rs‘Ï>ô¿…&çPyôúP=ò¹¥ë×?€¤æ€Ã v$š_ÂŒõ Á=GëJ:RñŽ”g=¨¿ôsŽŸ•Ç8掼¡ Ž&zv=³õ¤ŸÎ€Aš\?ÀÒõëƒG>”ŸPM ÷¥Æ}ãKÇC@ †Ç`hüy£žÆ—·ŸQ@ç¥)ÈäšL縠㥣ZN}s@ð"(ç¸ü¨Ç#½ÍzþqЊP8 9ëžù¥è®h AÏcùQÇ\QŸQ@ŒSô4êMþº®8£·øÑŽàPc?ÃGןҗÓ$f¨…&½#Ö”.(?çš9£“Ûñ£t4`väÐøÐzsGO὆€”}hàw£{PïF2:ÒqŠ?*\Ù¤ú  ÅÏ_Ò€šCŽÿ/áúÑ@ }i: cЊ8íÅ'ïK»ž´½}i1ïúГéF~¿•!ÿ{”s@ãGdÑj3éÖ€ÆåG§ñ¤Èô£#é@ Ó¥¤ôqë¡ ŒRãŠÅ!hRçÓôÍ&^3ô ù}héôö {GËŒ`í@ “ïI×±¥Íõ ïÎhëКSÓš9ÇtìhÎxëG>”Ÿ…/ãøQùþsíùQŸ§å@‚=h?îþ4`Ð ã=MSA£ï@Å4˜4¿çšú擟zSþy¢€~&—ŸOÖŒzq@&=?•ö4`úПÿ]/N”Ò;ôÅ(°ãé@ œÒ Z1@ƒ£´P1}(çµ-'ã@‚‚*OçíKŽ) 8îhïÞŒQøãõ¦!i8÷4œû–‰œö"”f޽è ¢=hæŒö4vë@ ÎyLâ–ŽÜR3ëGæip}hÅ1‰ÇLàÑϽ…'^Ô¸é8íKÇz9ì(uëšN3×&”çéô¤êzÊ€OQKIÏ^i{ÐAôôþ”¼ç½=(3ÇCH}0iØÏcGu¤pQœRã='¥¦Š^ßÒ€ÞƒÃñ —ð¤ÇÔQŒÿ± œŸoJ0N;ûæ—ò bþ™´p;QÇÒ Ç=hàÿõèàž¹¥ÆøÐmü(Às@Íÿž(ã¥)i>Ÿ©£Û õÉ¥çÓðÍ&(úÐçµ'®hǽS@·çKz2}OåIƒí@ Û¦hÏb ëG9ë@µ¸£#ûÔgüæ€ J?3IŸö©sïÍ£ ðhäô4rhÀáGøsIŠ?Ïp0sG>ô¿ ãœþtgiyô4~´˜ôÍJ2O­õqô ÀÏ ÑŽàQ‘.Îh6÷ç‚€8â—Ž¼Ð=¨ÖŒc 4~g´rGS@>Ô™¥Ü{çð >Ôuìi®”{`ÐŽ)qMžœýiÜÐcÚJ^ƒ“­&AÿõÐqÓê(Mã§ëKõý '8é¥/8¤Ïù"”zÐ`÷4¸8ôúÒdzþmqÏÒ€·J9£žÔ›}ÍGJ:Î)pøQ@ þ”¼úRsFNx?•/ni1õ£8ëÏáA>Ô¤zäÒ`zbŒŽýhïœPÏCŒRJS‚9•'ŒP18ôâ—ŸÃëA 8ô…!Ÿ;— Æ ²ãpú) “üš);RçÛ4À¦i}±ùRf—¿_ÖsÀ}hÏÖ—üñF1@E…ãÚŽ(ãÖ“ŽØúÒ€=(àq@>¼Z_×ÜRgÐñß4¿LПΓ4¼úâ“§z^Hãõ¤#š1Ü1'ëG¼Ðô&—éúÒg=¿\ÇŠÓñ¤Æ{`ÑŒÿJ8<Ð3GOjLûŠ1@ “éGZN;šÓé@­.3ÿÖ¢“'° Àüi{t¤ÉÇ"€N(çÒŽ~”qŠZ&O¹¢—#§?•&} ?: äg"ƒÉé@ øPÊ1ÈÏÖ—þªÐPŒtÐsߥ¤Ø¤ýÑKÁê*8õ ¶0(À?Z? Ñ–G×4sëKÎ9æ“´^hÀ8âƒîþT™ÿ&€sÏò4´„sNü£è¸=¨äRŒ™£?•ü¨ü1Iô ^i2{šv>”p8ûÒwâ—šÔÐש¤ïÀǽ/ëG4ýýhëØROÊŽq@ Ñy4 °8Ò” ÷¨ÄX£dÈÈÈ"€·ëF=¸¦ ä#0õ Ésùƒ@Ç~K×¶*%ùßw!GL‚*LŸo΀ À㯽7+K€: ^M'×Z\ä}3K@ Ú1F1ÎsNãÖ¥7ñ4`vÈ¥#ÔÑøæ€ zQõ¥ëëIŠ?•-”c° Á )ÔQ@ ·'¥.=è£ÔŸ¥ü) Rgœ`БŠ3éúÑ€=Z_ÊšGÖ—ò£Q@ àqÍ.)h QùQÅ'Ò—žàQÅ€À èÈÇJNq÷E(R ^ýÅ>ÔsÞŒœÑŠ0zÑŠ1Š8 “ñÖ—ù}hçë@;QF=õ4™ÀéùQÔ}ßÏŠ\ûRdú~T`_ÎŒ}OÖ€Z2=@úдæ“o­(ã4¼@=èÇ4¿†i;‘ô4dûÐAÇ€AùQ´Çó 9ìE÷çéKùâŒw äÿv—ðÍ.Þà~F“'ÿ×@<9£=é8îhç­isÇZ3š1éš)1FrqÅÒŽ£ÒŒã¶Mz`}hdRäúS¾:;ŽM7¿¥:ÐóíKõœf“åä(r3×ð¤?^(<ŽZ\{þ {Ñ‘GëG´g4sÜÑz9ühç·J(#Öc~”¹üèÏ=Ni9¥.=Å œðir=i91IÇ`)€êO®hϵ´u£­''­.=)? ™Å.}i?@éÒŒJB'ÒÞ ŠZ(™õ?•(ÇcIŒRŒSqEcƒŠ2(sG4u?:7zÐß £>ÔÇjLŽÙ Éô¤úšNýhÁÏ_Ê Û­÷Í热²y ÎzÖóÒ“ßÑ“@£·9ü¨Î?úô 3žÄÑß4px£ŸcHAÏ©¥éI­/¿z`%.hçÚƒŸÿU'æ(M/#¹üM!Ç_é@ Hÿ"ŒRlâ—ŸJ>¦Žýÿ9ô£‘Û#ë@Ã'Ò“ŸZ\Ÿz_ Íö£¯Ö—œrh9£ùûŠZ1ô æüi¸—è)? :v¥üM7h€i@öÇրʌúÎŽ(wo΀z¾(Éõ⃆þTtî>´qëGŠ\s@ ŸÒŽ4{w£žœŸÆ€Ÿ¥LÑÓ½¨Ésž´} £¥žhãMqøPœw£èhÿ€ŠZLýOÒ“v{Æ—¾:Òâ€Ç_ÖŒ Àæ¡ÍvþT)ô£·Pgý£ùQŸz>§4eGèä÷"ŒZ\wÉ£ñ ϱ4½G§ãAÈ´œæ€8ïHOµ/Q@ úÒà™Í>Ôœuþf— £’8"ŒŽ˜çÚ€ úæŒÎü¨àž (9ö£>™4ŸJ3þµ/_ÿ] >ÜÑœÿúèy÷u÷¤ïØP}{P×±¥ü 'Z¿3ÏCÅ{\sžGãIŒÐò”¼uÅ'ã@'Ö“ð¥8¥ú oÐb–Œ~t çgŽ”ŽÔ¹ïš‚pNÓŒuïE,üí?Z) “òhÎ=©£‘Þœÿ¨Ðõ£ƒÞŒ½¨àžü{Ó{w£éš9ì(ù»þT¸ôÅ&W ëéFAsKô4OÂÆ—éGã@ ‘ëKüèà÷£ñ4œ÷'”~4¹ôÍÏ4˜”`ÿU(çÒŽÔŸ6z~4ê*3Ú—ŸÂ€ŸJ^¼ÒàÒcš?*9£ð¤Èè4½O4téŠ3ž84sØPjOn”¹Ç\~tqè(¥íÒýq@ ê(äž?…'½/8 ý?Z\ÓIÁöõÅôæ‹× 4g¶?ZLñÈ£8ö Bõ죜ғ>˜Ï½.M.sÞ“>ÿ•>”dûPŸ¯åFE&O°üih'Š(ÍØâ€ 8âÂŽGj:ÿ… 9úûÑîM{ò(i23œŠ01žÞô Ô¤ñ÷…&}H½úŸ¥!>ä~4¹äуAúÐ1ê3@ÚN¢Œg½~4¢“4síA>Ù ”}EûÒtæ€4¿™£'R‡œþg·J>§4dúâƒîs@@ö£=‡9àqF}1ùÐøš?>¼ÒÐxéF=isÛŠ€`Òä”`çµ'©~T¢“×4 ç#­'>”´~4PsGãKœzQÖ€ µFz……&}.}¨Í'ãøP1ŽÔ¹÷ʤÀyÎ(ãM.F;Òcæ¡çé@ ßühéÞƒ‘Û&€M'ã@ÍyíK‘Š?1FíE/ŸÎŒñÛé@sÿÖ£ñ¤É÷£=hxõ£ð¤Æ{ÑÓ§é@ F=(ãÒ@â–’Š9¥çÖ“4´RRÒt ŒýhÉíùRc'¯á@ Í'^ô½úRPÑøÒgñ¥ qÒŒÒGùæ€ã¡84*NEc=E.Ð:Rr{æ”zdÐÓ¾(ëÓ¥&qÞŽHïøPž w•=À£¯CÍ&Þx&޽NáKÞŒžÂ€ÖŒŽi}³úQÐS@Ö“z\“×éFz&?É¥ïïFÐýtcߊ^{ N;ŒQÓ½ô怜ÒqÜRôäŒNsÖ øqF}JB¤ÿ#¾h¸ôœQÍ)8õ4œÔ¸÷Í cqÞ—§^(ÝF{å@ À¤#<æƒõÍ÷4€:åAëœþ´sAÈÇZ0Üc\R`÷ÇåF9ÎJ^½  ðâ€ÙìÃëFê3ïHpýt¸ïõÍ-&i2ßAéLÎ(È÷¤üqG?Z\ûÑGáG'§sëøbŒžæ“þKÏsH9úûÑG4`v4À>´d{Ñ:š?Q@ƒð4‡#^£ƒšNAÎzúPóš1ž´~t˜úŸÆ‹Ò‚ßZ(ãµqßð£§ô c'ž})8<h =(£ò£ŒÑÓÖ“> J\õ£è)2ÞÔ~ bÿ:1þsIÓ¿é@ëÅn=@/=åIŸcFx bóIÞŽ½iqŠLýF)hÆhÆ9Æ ôÜsKF)7ŸAF=M/çš@=¨àô4¿OÇ4Ò ï¥ÜæŽü& …OQ‘Kô Bmç4b—ð¤íÇqÎéG>”gÒ€ :÷ÅýN ô?J\{Ð2=Å!ühéÚ€#éGçøšLŸO¨£ð tZ^}( ëÅö¸ü©sïL#ëFáØ 2=yúR;° qŠ2:ç? äc¤ûb€=èùAè?@9éGâ?0hÇ9ÑÏ·áGùë@ ŸÂŠAÏJ9ÿë Z3øÒb—fŽýé89r?úÔ wNô™ü)?:^hf¯{àÒPçßc޹£žÙ£¿'>Ôƒ¸£éGZ83F=èüsK@ ÇçF¿Ö@üh=³F8Æhç½/ã@Ä OÊÇcüæŽü@^ù Ñš\gÚ ‚?ã £ùÒÐ`Pp{~tbŒc½ºRãðü)3Ÿ­ú΀ gµ¿•çŸåFqׯ†1Fyãó¥ëGNIâ Àúýhý)iÔÐ×·çIôþTr94¸ ¿ÊŒø þ&›Ž08 qéÇÒŠN}Eãü(FÞƒޏ£ áMGõ #ÒÏ{ð}ÅõS@¸Í'Ö—=;~4gµ&F1‘ô£ðüé~ƒ?/ÐPzöÿú©y£ŸÿUôdûÒý(Å&F9ÍöãòÅ.p)1žÂ€ ŽœbŒ®>ð¥Ç “˜ü(qHpzŠ1þÎipGµã¥&sÐ3ƒÜÒãÜþtsíG=ñG>”c”ïGãIÅ/J9õ¢IŽ;P’LÒäRg?ýj3õ ŠN”´s@Í!旤т{šLô Òð:ñõ¤É '=J3“Š2sŠ1í@ Ÿ~= (?J^‘@ :Ñ׌~´}M/áúÐcž˜¥Ç½'NÔPâ§™ü~”´F(£4sGáG=±GÓœöâ—§Z?:>¤Pš9£éÍ'9û¤{Эœc‘úÒƒéŠ =ºR¥.H=£$u•'4`‘÷±KÍ~£=©? ÒsœÐñíGZNqÎ(çÅ.qÇ'ÚŒž:~4uëüèúŠ(Î{QÁ÷£ðâ€qÿÖ£žæ“§oÆ—'Ò€G¯ã@úæŽ}(ÎE}i0{cò£§ £#Ö ƒê?*P9ÿëbƒ×‚i8Ç\}hç9ö"œôaùÐ1I"“9ï@<õ¥éé@„ïÛéKøRg¡4é@áKƒGã­Ÿ\Њ1Š;ÐMÆ“>´íš }Ö€‘ô£sMÈú{ÒšÅ{уÿ뢉ô"ƒ×"ødRP!÷ ŸRE;ñ™öüi ç“ÏÒŒÿ¶(Î8ãgÐ Ð Èu÷£'?t}sFO £9ÃLaø _Ã"“éG>”„.}ù£Û'ëH ÆEÈîc¿SFNqÒš8þè>”½øÆ}(sêE&OcŠiyõ BsëúR瓊2:gš(üèúhÁÏSG>‡ñ ×ô¥ úÓFï\þ¿0ï@çR(ãÏZ9ÇPiAö BÖÇô¥÷Ÿ§ã@Ä?S@úçð¥ç¾(ž*À£;QøKÓ­ sÐçéGâhÀ£ëLaô¥Ï¨¤è(çP!{w4˜ÇÂÇô¥ÇãøPG^üÒvëùÑ׸ àzÑIóJ^htþ ? 3ïG#½úP ëF8õ¥ô£"‰Î;Ð2;Òç=é;ö Î}~¸£óü©1õúQƒØ@…ö'4`úÒœw=ñ@ÄÆ;Ð1Ö–n>”´œúÑÍÐmŸ¥. £'<Ž(Éì(r(JNM.3Áæ€ ‘H:gƒKøŠCŒuü¨ 1Iך^ž´cßô¤íéF{G>Æ€ Çó¤ÁM.}H¢€zu£i=hÆ:®(ý¢Ep(ÀÔQœvüèÇsJ~´‡ÐÒsØ\s÷…ÄþTsôúQÇOÔPÅÞŒ¨ €G­&çÅêhÀô¥éÖ€ qÒ‚Sš=ép(ëÒ‚(8íKHx‘é@úšQ‘žô¿‰ Ú“?QF2:š8ëó~4gçó c=hãû´~­/)?J?*=±š^é8¤ÇÒŒqÏZ^üïKŸzn;Òàú~´¹ü¾”™÷È¡ã4p=…ÏQF@8É Ÿ@häwæ€ ‚88˜ã§¿SúQù‘ëšOΔýM&}qš8öô Š~vñŽ´Q?ðóž´RÃòúSº´ÕçðëJ=BŒPñÔãr:qG^ÜR~TÀQž¿Î—ØÍ ÉôÅ)ü‡­¡ÆìJP1ÏSìi#¨?… Þ€'©éì(ëô÷™ 19êhØ4sž”ŸŸçGùÅ)zÑ“ëúQ@ Ž9¤ Ô=?::ÐǦ? ?F=.yàó@O¥õÅúÒg“Å(㠥Ͻ78ê£$ô$¥;tÅ'áGÎ(öÝø > ~tgŽ´qèMðü¨Ï­&{mýhù{š(Ÿ•/¿vÏZL7 £¾:7RþÒsÚŒ‘@ó¥üi9È£ôdzâ—ã4™I÷¥ÇÜwãò¥ïEõ ?äÑÞƒÓ9£Ü“Š3éŠ1î1FÎhÇå@ ø A‘Ô)0{óõ¥ç¦?*®8 qÞçõ¤èz^{9ìô$R`ޤ{äPã=@?…&=1KžÙ÷£¾?•ûуêhç°ýhù‡P>¹ óâƒ_ÌæŒy4wé@úç𥤥=;ÐŒv}4€ûÑš3‚=}hëïî(ãæÆ=…Î08 §©ÅúÒý(ü(01ƒŒRâŽGZ=è£éÒŠLœPâ“ÞÖ—?…žh8ühëÒË4˜ôéKÀÿëÑE‡ëIZ^{QŸB(9ÏÞm¥Ç¥'#¯4mO?éÅóÒŽ½1øÐJŽ´g#¦>†ïŠ^Gz>™¤ƒÓ´Ÿ(=³@ øÑŠN¾ô}(Ïô£‚84E.}9¢“ò£# #ð çÛò£§J£ð ŠáøÑž=裟SŠLæ—šLÿœQŽsKì) 9í@¦‘ÏvÍ&}ð(ÀŽÄÖ“tï@ãG'·ãGoJCÆ3@ Æ=M=èëŒf“ó ž¦Ž¦—¥PÓµ“FE&GÖ€ :ÎÓÒ”ô¤Ç®MÍÜQÓØzRq@ è1GáÏÒ“8äŠ7qÖ€ñü(Ç~´d{Ð8é@`:ÖŽ)O¿*LŒg4Ž:ÑÏp(àuÅ€’; RüÞƒ4 ŠLP12qÈ£éFqF?Ÿ¥çœÒ“ßµ €hÏj3@ÃóÍ–hí‘IÎ8?¥ ÒäzQÈœÑÏS@í&O ÷£ƒÔcñ àzÐ Î{Q“éIÇLA b÷Å'NÔQùÐ!qßð£9íÍ(ö£qHb ã’(Çãô¥À£¡à~´Ä&=¹¥ü¤Ïµ=AÈúÐŒŽMw"ŒƒÐ­x Žç­qF=rhqê ”}E!ú~´½qƒô §§ã@túÑ‘Œžžôuè§N úbŽÉ¥íÿ× ç°"—“ÛŸz=…ÇZ\bŒg§ãHÏz1ê #°£ëšN¼€\CÉæ—ðü¨éõ úâ€ŸîÆ€J:ÑÏÈ”(ÀŒö£òüèééGNp½¸çèhã<Žh:çñ£Û¼zPGµ'$v4cž0qFsÚ”}y ¿1 ôô£§$š?§€øÏÒœ8î1H7¸¥ü(Ù£ð¦ý1Fqÿë Ýž€þU²2!*¹#°òxä‘K€GJ1 °ËŽiø=èÁìŽ}¨Ç½ÿ£ŸÂŒJ…(¤çÿ*ãŠu&ëMÎ;S‡=(ÈýsG=±F}Í…úQžÜRgö¥?îæ€( b“ƒÿ뢀ÀR‚}‡˜õ}hi ëÍ{qKËÚ€:ç”К\ךLz@ Ϩ¤úÒ:‘øÑ‘ë@üé§$rGâ)y#4¸õ ö àõþT`Å!Ïù4 ñÚŽ}78ÎF)r=0= /à.M7¿^Ô½{ŠA“ØPŠ?*01Íí@â(ǽ)›E÷£¯¡¥úb“>¤~|ÇÒ \óÅ>”:fŒw¥Çl zRtéùP‚}¨Æ(Ýõ£9é@åFÞzþ”d÷8¤=1@À`v€£ŸQIŸöŽ})r{Ð3õ^Gz(˜Ÿ—>ôRØ>ÔðyéÏçQ€2?ÆŽ1@ÿ€þt£éÆ›‚=hãÓ&˜ @?×qØŠ9ïÅ?ÝýhéÖŒ‚ KŸ¥—ã@„çöüh>çò¢Ž8üh½ù9£üñG‡ë@~Ÿ‰¤ÿ=)p=0i3Óñ ééùPI?*=ŽqG=ˆüèsÏ ¥Àî '>¼{Qƒéùš-ˆüE1â“õ ãÈ dtÅ}'~àûÐçð£¿Nhàñú\b€qÖ“žÃ?ÿdÑ“èq@Ã8âŠ0G®(È? w¥çÞ“J? /×4gñüi<@úb ž:~´gê(âŽj Ò}ô¹>£c<Òdc¯?LÒ‘Žß•(éЊNN23Jµ&xé@ç§Z.8è1IŽ;QÎ})qí@ÓLÑÛÛÒ—¨ŸZ>¸ü¨ã4`æ€QÇ¥¶( aœö¤ëÐbŒw¥éë@ƒñ¤Ç~iIÇz:vü¨>”¿•&( 0è W¸¸hbGy«89£é@ÆÆY£VuÚÄt4£=ÇáIÆ{“JO± AÇj=PnÆ€Þ—Ÿ­'ÐÑÓ½÷?JQŸ\ýi1ëƒGNÔ§Þ“<ð?ZCÈ ôéE&Þ‡4PçÜPO©1íF9ô ϵÏj(éÚ€hÅJ(Àõüèú~´>´cҀƓ‘Å{PþzÑŠNG¥G4`¼š8¤=~bi ^‡gßõ¤Ž >‚€"Ž´bŒJN1Å ^=é1ž¢€;c´c”cò÷¥Å&¥ü)?:\f€j\ð¥'=ÿJ8éš3Fxÿ_“‡>Ô\ç¥'J:÷¥é@ ü)GûÍôŽèÏá@Ì󟭑š?ÎhÈôÍ ýOÖŽ}sA8û¸Z9#­!Š3ÐRp:žhã°ýhÆ})ˆL‘ÆÓGáŠ\céG¢Ã'¾)9Ç<ÒƒØR}H¦ Î;Ñ“Gçš_ÄÆ€Rñž½=häÑùÐøQŸQF9ëÏ­zþ4G¯ÔbŒâŒûGÌЊ:RⓞÙcš3þqF1ëùÑÇ© ’;fÈéŠ9h×9÷ ŽØ¥ÀÇ¥4cë@ Z=¨ÇoëK¥õñ£ŸJÒ“>Ä}hÉíŠ_z3š9 Àõ¤À?áIƒŽzÑ·Þ€øÑ‘øÓsŽ¿ ¥ “Ç4¸ö£´cëIlþ4QøP0: Róé@ ר£$v¥éÚŒäPw³×Ò—ðâ–“¿ñ éA¡\š_¨4€dðEç¥.=…'àhÆyæ€Ö—QúÒ`g¡ ç×¥'Z6ã¡ Š8íƒî öc:PsèhàzQ×¶hÏj=è1Û¥ïÆiGOZCøþTõþT>ß•RnôгžÔqGà~”žÔ¹¤={ïGáK×§4Þzm§QŒ QÛCôÏÐÑøb”ý(ÛÇJLzÎ| G^hǧó 烟¥/ÖŠ:Š^;JÇlQï@dQß§ëKÐPuíGåIÔô¥Á=ü¨ã¸ÑøQžÝèïÊþ4 2}©3ïùŠR*¿4nN9ÀÍ=w¡¥Æ:Ö“ó a‘ׯµ!ÛŽxúÒ÷ïA<ò´Ç%z KÛŠ)à;â—ß(zÒçéøP`õÍŽâ—ðqíKÅ1 Ï„síŠ~J0(7 s‘G¹¥üM±ü¨:Ž¢Ž\Rðúâ€â€ïGñâ£?Ö€<ôÅ.;ð:w8¤½@ÏÖ€qÛÓŸ‰î(Ç¿é@ ÏLÐÒ—cÚƒÏQÅ!êyõ£z2;( ŒuüqFïNü)7öhã¶¥z~9£9ÿëRóõúÐ{⌜ðh*4qï¥ zŽi@?AIÛùуØ^}3õ4²G`j8=é@ƒéh£>Ô™Ï@ÀûŠ^?É£ð£¾x ÎzÆ‚}A¥ÁïúPx€ÛúRçŽÄÑ’GQùQÏ® ö£¯P(éÚŒŸLP0ÏOð£õ4ê(ÇÖ>œRûRûQÎ;Pþ´™÷¥Ïµ'~zÐã=©8qøš8ëÞŽý¨Hµ&=©r=i>”`Óô c°£&Ž=hÏ©4`c¦iqIŠ1ÏLQsJ=³øÐ~”žÃšP§åG= ¢€(Èè•ôÍ(ãQŸzLRò;PIϽ.HÒrzŒ~4¸£ƒKE7hÏNiqêsô£Šèâ—Ÿ•QÇJ8íGá@ E'N@¢€õ¤üOåKFhÆÆŠ^;õ ü)zv¢©ü(ãéíGò ãÛëE'°4£éŠ? (úÑŽzfÇu÷cŽhÏåF8Ř`zQô£=(?Ê“>ÔväšZAôý(çÒŒ (ü(¢‚~¿…çI€N(È÷¥â€ ã¦(£ó£Þ€ð¥éÅ{Ò~'ò ǵ%-'´éKÞŽÔb€‘ØÐ÷£ð?ZZN;bŽGj>¹ÅcØQÓµ.ÔqIŒsŠ\ßÊãÞ€œc4v¥äý=)? 3ê(æŒ{š? 1G¾(£žüþ”©ii;æ€})3ôühÀïÍ¿é@QŠ;u ýM d÷Ž;äÑŸE ê)zv¤ãÒ“ÏJ\{ñKùf›»Øþnç¡Í)Í'?QJ8æ—§Ö€·?J7gŽþ†”ŒöÍ.1Èü(éÎ3ì³ÎŒc¥úÐ0ãÒŒ‚:bŒ}iqéüè9?â)1Î6õõ4¸úÑÈî ÇQŠ?,QÀõ£è?:1ŸåG^†Ž©1ž1j0}¨ÁúÑn>´qþM ƒÿ×£¯LÑÈôÇÖŽOÿZ˜ òö?J0Ïj{ÑÛ  Bc?ýj>QÚ–—§A@ ‘ž™ü(ÿ€àú÷¥ÁìH£üúÐvæƒíÏÖ—= ¥!‰O"—éŠ;`dÒò=i€œú0GQGQÒ€1@ KIŽã4q@çùPGz)3íùPòE&3ÔRý(Áü(ÀÇZ=¨Ç ŽhÆ:bŒP8íKÆq@ ôæŠ\J8" Ó·ä($ç þ”¸ú1í@ÄÇÐÒâŠ1@ Ðvühúÿ*1í@úP çÞŽýt£ŸJ0(Ÿ^(êy—wé@ ŠN½.§çJ=¨Ÿ¥&3èqíNÅÞÈ¥B  Ð:Ö—ñ äwÀ¤ê9 ^{š?ÏÚ\Jö`ú›Ãvzóô w4p{šn0:~¥>î(Ø£ëƒIÓ°Åô éßúÒÇzZAëÚ€Óð¤íÉý)zÐ>ï8Ôwëš\{Ò`vwû´¼RaO@ ~ ØRŸz3Ú“?‡½)úAéŒP'ƒKž9ý(=éqŽô™{Q‘Ç€ÿ])sÍ'qGPŽØ£ó£4 ÀPÇ¡qëKÇ üè :u£>Ù¥zþdPgÛ¥.?j>†ƒÐþt¤ßò¤$ã¾=èÜ=?Ïr(sŽ´¿€ Z1‘ÐÐqžùúñ@ÉÿëRô €ýtœúbŽ=èÀô¥ÈÅ >†“¾M.(ãÐÐdw4§§NhÈíÏáIß©£>´R}húæ“ Ç¤JLú©¥äçðÅÏ?…  Ÿj8#§™ÇOÒ€ ÿ³úÒþúQÉäf€hcŠCÓ¦=Íz~tqŒq@ùⓎGJ þ?úôì2¸¢–l Z) 88ÛJI¤çÞ—#Ö˜aÓgJ>˜ü(ËP íÒN =ýiO?ÂhǨ`g±úÒsß»A ô˜§»AþÖŒ}hÉö4u8ÀÅ.ÿëPxõ>Ô}1IŒž(ü1A®ÔÐÿw#Ô5¾î(1@2ÇÖ—'¥/^Ô~ó àR㞟­4„ ó@2zšSþy¤ÓwãKÎ:~T 0cëF3Ú¤tÅtûRgžôqøQZ.}i?~”qGlPócîþ´£>”±Åâ Ç¥¤À=i~„b€þ´cÓŠ2}(Éé@±£§j1ÍÅ׌QÎ(í@Ãð£ëG½ô£ôsF?;Qóg üésÎ(ǰ BëE@(-í@Îh'¸£ðýiqõ >Ù£Ÿ­(ÿ<Òs@lQJsŠ?@ $í%@>œõ¦@òH„º…ç¥KøRúRdŽß­Èàfލçñ¦!N}i1GNß­€úŠ?2}xúRçè( —¥'éGCí@ ŽzRtúÐ~†ƒÇjáKô¤9ëKŠLtÍN(ü) ?Z(Àì( €ôœ´¸ãŒQÇJCÅ'ûÓ¹¢€J0=)xô¢€)(úQ͹Åc¥Œô è? )y©9õâ€hã®(ÈöÍ Œô¤Ýÿê¥çÚŽ}¿:?:(ü?Z=ºPp½.pqEúÊ€ ŸAGãøfŒjJZOÒŒýhϹ4qíF:PIõ"Œƒé@=¨Ç|R‚h ÉéùÒôõ¢“?­) u£4œ?J8¿Z^(ü(Îhü3@ãEœûP‘õüé9£'¯?…¥õ£¯jZ>¤N=¨ëKœúRP =èèz~4~´sí@_OÆ—ñ¤ÁŒRóë@jLûu¥¤Ç¥~9¤Ï­÷¹£&ŒœPŠ0>´œ_Ηù J;{zÑÛ¨ü¨çÔ~T˜pÖ—·Žž´ :ÑŒŽi3Ç'󥿀–ŽÜ 3Aüh:phÆz Ñøš3Ïj8ϽsšLûQŸ¯á@ƒ<{{RœÉüÍï@ÛéŠ{ÑÏrMv Ç9Éü¨8“Š\žÔ™#Þ€`t¥ÉïI–ÿ#Š\ç¹ Bdß…/f–‰‘é­RóÛ•÷ Bu´ 8ô£"ަ“¯¦hy£')9õÏáKϽôQš2{Ñ“Ø@…ëF)>ÿŽß•3ï@Àã¥&iEµÞ“žÔrh¸4gÔQùÑ@áFGµPŠ(¢€ 9ÏQÐ÷ü(ë@i3ŽôûÐ3 bÔôý)Œ¸9àÒãžzP!Ø÷4~˜Çj3Ÿ¥ž½(Áõ¤$sßÚ=Ò€¿?ZCƒÇ&”1ŒR}(qíIžÄ¼t4ƒÒ •&ŸaíŠLçjÓñ ÇãG·£¸Í ¡çp(Çù4ê(öÈ?…ÿg“Ú€;æ€>€ÑœvÏáIש¥üÿ1“š^ž¿'áŸz3õ ?þº^})ö4gØÐþ”„}(Î}£§s@SG~0(ÆOÝ£=€J^3Ó NqA?äÐçÒŠLúRçÔ† sFG­d :v¤Ç·4¿çƒF=>´˜=À£Ð~4p:u¥çÖ€ƒëGnßZ\zš;óŸ¥ #ÔRð†ÃÒ€'4£8è(ÝFAíüè?_ΛÔ~zÑøš)sIϯáGë@qŽ? ^|QéÆhÇ´\vÇ´œô¼ûÿ*L‘ÏOÇ4 ýhÏ8 Ñ‘@3GãGãG~ôdz‘øÒqØœûÒí'‘GÍÓ9 Çc»ð4¼öãëFéÅ ÉêOã@ÅÏn¾ô¸¤ú“ô£ qš/QF}ñI’{­#Ö€“I“œœÆ—'§4€žãõ a“ž„ÑþzÒç¶?ZN{q@…üéÏÌŸZ3ë@Çz1ŸZ2(ëÛó AÓ½ÇJO›¾(€è:2{‘G¶hö ¤Èõ£Ñòh8õâ”ÚŽG=½yÉ aß§ãJHúÒÆ“8éÖ ô 0´qêi:LƒÇó¥ ëþcÚŒgëKøæ€FÉ¥ þT~”c!½œf€­Ÿ†hÈúPÑ×µ&}ø¥ü()zRsÓô ŒPçÖ—?…7üóG=1ùг‘E&qÖŒäu ¤éëùÑ‘Ó4ï@úRÐ3ÖŽÝèÏ¥sA4b“ñý)Ï™úÐ`Žiyõ£ñÅ.(<`š;tÅsšô}E‡ñ£<ô¥ë@ ǦhÈÖŒQ|Ð×­zQ€:Q×§ã@1ÚŠ:zÑšҌџqIŸö±@ ôzÊ—põüèú“@ Æ—êhüqõ£×8 J;Rg4´QøQøÒ~¼ûQÏ¥&OqJ:Pô£ð¤üÿ:2}(yïIÍ{Qß®(ühǿԽ©?:1íAúþtp;QïŠ03Ç_¥öëA8¤?0êE8ý?:Lÿtgé@w?‰£ŸJ9úQž}¨Éü(Éõ#ØÐ’z/çG'# ‘øRqQ@ j°¤ÎJ\û3øQÍ&})qëÓÒ€ÒŽÔƒ8ãð£ZF`¨XôªAPGB2(Ï~h稠í4¹€ B}…J^Åÿ"ŽZ3ØPƒÞ—‘ÿפúàQô€ äô õ Òqž” ?ÒìGã@ÉíÆƒ“J>´­/>†Š%'ç§¥/ ÷¤ï@Ã4£4)sìh¤Éõ “Ùsõ¤É³@ “øzÒdœŸj>£ò¥9í@ õãñ£üõ£“ÔqIì ÎQô£wnãFù4ÀE $RdõÈ£ñF þ#Š;“ïNÏß`ãJG¨ãÖ˜ ÁÿõP>”œôŸ¥.ãG=OéIÈô£8ëü¨wJ8ôÅ&{G9ÇëšC§ÿ^Ž?@qÆsK×½0ƒZJ1ùPñÓ84`úœ}i0:ã„Æè9j9íúÓFOlýi}³Í.sÁÅzæ“¿¥1¿£¿j9=qš(´Rgœfç@ øÒqGù£¦Oj3KIÛ¥\Pçð£¡æ“zÒdý(ê3Ú“ âŸZ/JCùÑÍ.(8ôÅ¢–“Þùâ©âŽÜQÏAŠ8Å-'ãG=Ïé@ÅÎzQþzÑÎ)9ï@^ô}H óÖŠ&¯Óšpæ›ÇãFÐzó@ x¤Ü:g¼Q@lš_ÏëšLÿœÑÀë@=èçž´£ëKŒÐc½bŒu4`Rc®\zNž´sÚ€[89£'¾iy=Í!Çz\{ LŽ„æ—‘÷Oàh~1KŽ9Í&{“ùP{ŸÆ€ÑŽÜÑÏLÑ“Ûó4œƒ4¤Š9þð£ñ?JAÍ;Ú“ï2húóKŒÒ~8£åÇÞ~™Ö—$÷ü¨Ï…8—ëúÒ~˜ôâ€äâŽ:fŒÔÐzp1øÐÓ¨Í>”`úÑŒúèâŒg¨£¥.OzCô¥üñG4ž(?,Rþn£4sÅ%~t¹÷¤ÿ=hϱ¤ÝÏ­.(£&ŒñÍæ—Ÿ ê=©½=~”¼úóAϽ&¥À¿Z¸4øúPÀŸZ@£Ö—&|Ѐ(£éKƒë@È.Ý¢’ã/'½€“Û¼úP>†—ÜÓŸŽ(ǽu¥û 1LÒöïGn´™úŠ\Z>¸£&ŒŸÿ]ãü)M >”sžô ?,ÑÀÿ \QŽzš'ûÒóÓŠ1îi?(À÷4½zñFxêqFEÿ&Œú±GàóGãùP0Ú=i:ZLÍ ú‘KÐQzLñÈ 3íFG¯õ£$ú¥-'>Çð¥Á4r}Ǹ¤Ç9Í/1IŒj\bŠbŽ3ÒŽœñŠ9ô ù{ÑÓ½ãÖŽ”dž‚““ßð¥úÒÐpGA‘K“éGãŠ>­@^¢Ã?CG_J1ÇZCÓ•¹ã¥Ê€G| ;bΊ0>”p:æŽ}éh1Fqþ4|ÞßÏZ8ïŠ? \Rmõ ÂŒb—­&x£’i:(:b—éüèÁ£Ú€¿ýjLvïõ¥¶(Ç¡ “¿!ü*1ø~4¼wæ“ùRñ@ЊNýsKÚÆ€&ŽihïÅ'ÔRöãQùP>¦ŽÝé0;Ð@ qô£4˜ö¥é@áFz :õ£4wâ—ÇëHhíÒ€ãüš>”Ÿ…>´~4´Ÿ.(¤Ï ¢ŽhÉìHühýhÉÏlÐ:sŒýh£>Ô½ºóG4{QIG>´t£?…/ãI@úÐ1G4s@>âŽÝíHΪ>fµüâ—}( ·cGü “ÔŠ^}hühüèúâøÐøRÆŽz3î?9îr(ÇrhÏl~”ž´´QŸÆ€ôqÛÇ™¼}~´uô£OÂŒPÒÃó£ñüé~´™ç¥ü(Ȩë@8럭&1Þ—ŸQEgc"ŽÝÿ3ïùÒ~RóéGü €G|ÑþzÑIz\ý(Í'ðÜûRñë@ ßÒ—Ò—Ÿj?Ï4 N}hüihã½7Ž”¼c“š_¡¤â ŽqŠ\ƒžÔ(çëøP0ÏãF}(ç<øQÖ9¤üèç "—4 o>¿§cÜÑÓÒ€ŒqJ0;âŠö ýE'ÐQÐt4 ~4sž‚–“8õü(É A‘ÞŒŽÀÑÖŒàòOá@ÄÏ·éJ2N0(SøÑŸ|þt¤ã·~´¹ßéI‘êhÅôEÿiã@}sI•ëÐúKÇáJqïùPZ8Ï&—ŸPhÇOš¥)±ü(8õ£ÿU!´`ÑϦhê{ñL@Aö£I£íQøÐ08ÿëQÚŒÇÚ—#ŠJç½/¤ühQÏ~)r=éO½ÏÖ—¨ ÑÈ Í/µ æ€1Ð~¢—µ4˜§RŸO¥'Ðþtqé@ÁéKÛ9 .~¦“ñ4`ÿxÐÿ:¸¤è¼œâÈæ€IÅàÑšæŽ}±G4dŽÔ1GáIšQœÿõè:´ ÑÍQÍçŠ@q@ Aÿ<ÑŸZ8õ4œý}èÏÓó¥üx£=xüh);qÏáNϧJúŠhÿvÍž:Ò;ò~´¸õ‡ŒßΔ_Ò€?ˆ£"ÎŽqÆEú~´tà~´{ÑÇj23Ú—@ÎhçÚ€ñÅÿ&Ó½'ZN{Rœö£ùPsÛë@8ì)9îI¥ô$þtõ ‘íKJNÞ‚Ç4Q‚zQŸ­÷æ€ Ö“‘ØSîhé@}Eô¥÷£P úÑøP(äPâ“ðæ—­‰ £>ô¿­ç¹ Ï© ðsøÒÑü¨ü¨È¥9ìGãIϵ@ë@#ŒcÖŠ29 A‘íAüúÑþzP{QùRæÆ€;Ê–ƒÛŸÊ€Â޽úPsíGâhíHsëϵ.A´zP×ÞŽ}(Î'Š?àDŠ9õ¤ÀÏøRãÞŽ !÷cð¥Ïµ{P#îóëE,ýSŸ_éE!Žã¦H¥éH2< 2;t Fz~tëǽ.E1 ÈíúÒóÓ¯ãIŸCœûQ¸J^‚ŒÞŒžýi:ÿõ¨vƒØfjLRô=H ü¿^sGQIŸ|Ðä{Òžhý(ïÖ€ ç­.):Ñ×¾>”cÒ—©íIKÖ€ÿ:OÀRóõ:ô Áô~”¸ÔŸçdö£ùÑõ ã¾('ÎFsÞŽzŠNýh@ü(=1ÛÞ“¦;ûÒãŠ8õ£¡ãùÑlÑ|Päzb€{b“ŽÂŽzcñ Áú}(¦à~zâŽü(ã)£?Þ§~_!8ãKÔ :¤ûRr;Ð!zw£Ÿ­ãÒŽC@4`öv£z-™ëšL‚:~twáIÓ©4œ>Ô¹éЊ\ŠL¼R}x f“ŒãŸÊ§æ(íë@ @Å'^ƒò£_€#¹ ëQº3ãOŽ:ûÐñH}¸¥Ïù4™Ï¨ "åõ¥ç·ò£>´ƒœþT¼zóF}©?z\ŽôRRõ Aõèüèé@(õâŒzf€Ê“p*Qš(£Ú­'Q@ Ï¥?úÂŒzÑë@Àõ£4~_•…ˆüèç¶)2;®(EJ2=è<Ðú:sEh£ñæŒûQŸnh9¥Ž”:õ ð£¦h çÛð£·?Κ úRõPæ“ò¤Á÷Å/J;t¤ ÷G\óG#¥ÐÒïš>¼Ð×ò ?‡ãIŸn(ÈÛéF~‚€hÎ;þtc=ÆhÇ·ë@ £œRžhéÒ€ŠLàsÅã¦/>ß'áF=Í;P2}E&[=?J^=)y ï×Ô½i1G>ø Ǧ(ü©3ëF}hü¨çÛrzOҀ𣽭¨ Œö£äQoÎŒöÅ'_QKøŠCŸqéŠ\ÇÐÐìM'Þ—½`öŒÆ£#“F­££…-!ǵô£€?&y¤Éö£“ü?­/ÿ3èyúR ã€1K@ ϵÏ_θç€=q@ÞŽ=)@c#¥'¶(É‚—i¤Å.OsMï×4î}F(äP19={{ÑÉè _ÐzÐ:L öò£w¥Æy¤Ç­ç“ì(=9<{уëGÌJ§_¥_ʃ¸û}(Üþ4™Ó4¹  {Qz£4cæŽ(uô£ZOÀQŒŽ‚€>”F)j9öÇÖ“žâ—ò¦uúûRõïG>ô¹ ñÐQ‚:ŸÎ—’9ð¥Ç¯ó ä~?J_òM£éš3K»ØÐAö?Z;r1@ï` !Í.)0@àÆ€þ{IƒÚŒs@…ëþqíHN=1Fq@Ãò¥ô據9?ãšSÖ“œÑÈ÷£¹ >ã4sïŠ}&zþ^=hãÞŒG>Ÿ­:æHlKÀô AÇ­.y¤éFr:ÐøfŒ´¼LœÐøÑœuëFO½är¼P¬‘Í)'µ4.8{S°{Ðdw (ÉõÐóFi9ë“JG¯>ôŸçKŸR?:LŒb€?Æ€ ûŠA€xð¥ÏÀúÑÆ3ŒÐpz€hü(ì1K¦h?^}ͨúŒP×Ö“Ò‚PZ^Þþ”˜>Ô¹ÿ8¤¹ü©yõ4dúÐN:óG¿…&3ØÒŽp .9éÍ ûûP襥æŠLzŠ1ÏjÎGz8~TcèhùqŘühÇ¡ û(ÛHÁ‚ä.â: â€Òéš1ßÓÐÇÖÀþt¿…Ð×µ{QÎ(C@ÓŒæŠZOø £Ôqêh 4bŠ3í@>”séFG©ü¨é@!Œg`zRý(;pqŸj^ýi2qÎ3Gnx ëØQÅ úþTýtÉ£JLÛŠ01þî)9¤ÿ=hÍ(ã­ÓúÑõo΀œô QøfƒëÎ(Ç­G\RuíGÔ~T ?#Kø~´›¸íF/¥ArxNúQEÏðçÞŠ@J3Ž¿¥/Þ¦ã=Á  vsF^´œ÷Räõç}? _jJ8>ÿJb ;Ñóc­‡Nôa³×ò  =èÁíŠNsÉ4¸=€ ‘Õ?Z2@äRОhèiJB ô Ç<â”çÖŠ0{@:÷¥ïÚŽsKŽôƒ89&ŽŸÅÍ/n´n éÔœúšL:gØÓ³Î9¤Éö —ÖŽ(÷¥Èè?9>Ôdúf—žý(9Ç|QøâŒã¿à(º@ aס£×&ŒägŒž˜ Û©¤ÇûGÔ¹ã¶iGAùPF;çFô¥úÐr;þt}Gå@ ÷ê(ç¾(ÁõeG擞ÃjRxõúÐH^Ið£ ôæÈQùÿJ3Ç úæ”ûRg׊úzQŸz3þsFs@N;Ñ‘ïŠ\û‘ô¢€ÜKŠLãÿÕ@Îzq@°ü©FqÎGãGOñ£Ö€äw?…/¹£‘Ó£ ž¢€qéϽ/>”˜¢€gÐþt„6zÑ{ÑÉãŠ9Ïj7zô£ ÿëRäu ÏÖ€sÞŒÿ“FON(OÔ ?iÇ¥{þt´˜8÷úQÎ9Å=8Å=Nir}p) Å&áÓw4¹£­½h$c½Q’}¨£¯søPÈúQøÒcן­.=¨?‡çF}?(Èö žæŠ3øÑíÅf޾™£vÐýhJO¡"—ŸZ3î(çÖÂŽ@ ŽÆŒûæŠ(Íç­ ÷dcŠ_ÒŠJN?•/¥íšhÉŠ_¯ò Ͼh?ç4sèEë@ ÞŒŽy¥Áõüè þ¿)>Ô§#Ö“'Ôþ"€'Ðb–”dRéրʣj0Opë@÷4¹´rO©£ôdÑÍzÑÆŠ9÷ ·ÿ^Œj>§Š;ðh;g‘øÑ»ß?J_ÖŽ(üÿÖŒ{ãéIŽ:“õ aÇ¥/ÔvëM'h'Óš/Úƒõ#ð 6{þTg¶O×~Tcð£ñ£9èQGoð  ò(QŸ ¥Ç¿˜ö aÅsÇJ:h¿•&{ÑŸjšLqÚ—98Îh<Ð!:úÆŒc·äixèè{Ð1=ò:9þíŒu¥íÁ ó£ÔsK@~ƒñ äöüsKõÉúRqÔ }h}¥¤äv aǿҎ¿3A&ŒŸp( P=y£wáõ£>ÿ‰ ëGáA"HŸZAœú~4¤Ñ×µ0-ßN”SKŽØ£h hœuaKÀ£¤12J@Fx4ï¨Å!#84À2;âŒ{Ñøš1øûÒÛÚŽsŒRóëIÏ­1 ZôýhÇsš??ÆÁÏz\g®i}¨Ï©€1ÇOÖŒj:ô?­¹ÇÒ˜¿ZLÿ‘J=¨ç¾)H9î:u'J`&j:¤š\úƒF=3øPcJ?/ÆŒ}~¦–€€Qz\ZLj.=!u4¸¥'Ž´œsGJ ÁÇ„‘Øb€¯z3J:ö£ñ˜'ÿ×IÈéüéÇ‚~‚Ž}(ÜãÞŒ vüiqëF=¨>‡j_p)xÅ4àŸ½@ רæŒ}(À£ŽŸÎ ~´Ÿ•/¿éF2(2zf—òhöȤ?J€¿QŠLžøü(÷8 AAFù4œùÑ€lÑø LÀS±èh´rzsøÓ¿ NýT ÷¤ëéNSG”Þ{šSÏsKŽô`“@ çÖ—è¥À£RgéŠ] t£ó “Þ“‘ÜRðzÐ3íŠJ^=hÉH gµ=ÿJ÷£ñ¥ Å/ni2(ê(È>´gŠ=E ûÑ×¹£ñ~´?1F Š;Qž(Éõ¢€ΓÒ—Q@4Ÿ†)h :ÑøQœw ŒýM™ Í!£#µ( aÖ“=©hâ Íÿ"—É4Psô¤#Üý)ÔœÔþsF}¿3ߥñ@ œ¢—ÔÒsÓŠUéŠwçI(Ç·ôŸA@&—ñýi8Ï¥)é@ãšB(Ï¡£4 1žÔ}N(æŠWºþýh¤¹êŸCÚŠC&Á¿1éü©¹ÇN}éwÆÖ˜ È?t‘õ£pÈàþ™éíK}1@…ã°£9<Æ“µöÏá@ü'Ûñ¤Ç¦iqõ ô ÔŠ?Ï4™9ô F:03“Jyç­'OJ^¨äžƒó¤'ÔŸÊŽq@ ϧãGùÍ&G8£#Ò€š9£<ôgÔ~”cÖŽ}?ZN£¯á@ ƒGNÆŽ=)3¥ ØÀÇ´~¿Ç@E(9 AÔu¤ÀéÖ”ÒgÚŠc¡Å!÷?ôÍ.hÀÎGéAÀö¤í×'ÞŒû€w½=Áü 4äöý(#¹ë@Ïb?N:G>™ö£$ö ë׃ŽqA=ÿJ¾£®9õ¤úÇg2h¸ôêi þ…ãÓJ)>ÀÑ“éùÒnøM(ã±úP0ü©sÛŠn¥.8é@…ç°Å!${ûf“hàq@Çdàv£õúÒ~”gñ´¿7 ¤ãÛ>Ôdg £ƒ¸ã£ {Ò`”wýhsëÅ'tÍôÇÖŒú“š\I“õ÷£=ÀÏãFüúcÞ€ “Ž@£'­Ôt 8èhÏ|äÒ‘Å)ÿ8 rr2}/^ â›úÒþ€—ûԿΛøK‚=(y=@¤ü(ô¹=1IžyëF1ÏçKŽ9#?Z?JLš^F)9ìá@ ͸ëIÀ£#ÐPóŸâü)@=鹄Òçý“@ jN}i ùö ¯6~™ ïÆ  äs@àp(ýŸÎ€ŽqÆ)9œý(Ïá@ ƒG>Ô˜=sÅ-œ õúRÑGô @~”wíô£>Ô~‡n(çÒŒŸN)2s@…ü9 óïGÖ‚h£ÑÅ=h»0IP}©1 ygž¾ÔìòhÎ{@=)~oZ3Ž´Ÿ—á@ Í'=¨ÉíG8öö éÔÒ~AGN¸ —¿ãÔÑßîÐ>Ÿ­£9 û~ (Å'nHü©xÿ"€G^hÇùÍübŽz/åGà(£#Ö‡>”cž”fŠ1GãIžœÐ=3úÐþœõ袀~´gÖÞÔPšZo)zPFs×~4¿…‡SGNÔr{†ŸJ(¿Ëé@ ïG4¹÷¤ãÚ€zâGãϵ.h:ö¤Ç§¤R(ÏÒ(ä âlæŽ3Û4œú wŸ‰ü(Áôâ˜}¿:3þÍõ˜÷Í àÿõ¨£?1è@¦×¶?ö4qŠ "€ Z0~´c=ép;`ÐcÔsF½(ã¥ü©Ÿ(sGãúSÅÒ˜&޽¨ÉÿõQÔwüi&zRÐ3HcüŠ:ÑLÇ×ñ¥À>´fý G¹úÑŽ=) QÇ¥&Ñè3Kj@}©r3Ò€ }(£ŒÑœõťΎ; L§ÐPø ÑÇz^)>”p=(Àô ‚zhçè(ã­ J=ùAޏ?(Ï Å×ùPE-¨¤ãëøÒñèsA ŠLãµ/S@'¼g½ ð£žÂŒ{~”mÚ€œ03ëøÑŒqý(ǹü¨çÒŽhÇN¿­ >€š8ô£·Z/ùéG8¢“š^”QùRb€ŠLÑùPÏaùÒÒQøPàÒsõ£ëš(}(çÒŠ? š1íGcÚ€ 0hç¾(Å t¢Â€œ_®qFN:Rc=E-ÔmÔd çîóGáŠO×ñ£ŽäPô¦žz\Ôc³@ È¥Î;2{õ&ŽÝ³@sÜšZ1Gç@ÂŒQÏ Z aƒÚ“ÛŸLÐ[Ž1øQƒèµ;·4”™ü~”gð BþIŸÇéK× ‚ãïÇô?ÒŠ'4Cý(¤†;øRçëMëžqFGMÄ`;8£ê B)hcÚ†ÉC‚sõ¤9ãâ”c=¿.h˜7»#ç?1 ;ã4ò×?¼Êñèò«9©Í.}J®o!ܪ’Üy‘-ù^I­0Kx%˜çûÀUÀÍÐàQG?Z9¼‚å1-ïš3Ôž†—}ጂ>müpoñÅ®?ÞAr«Kx$p±pàƒúÓVKÒ¨¾^9bòÍ\úÖŒ£¥Íä*ù×jÅZƒüCP&»ÆL@sÃ5gÒ‘ëÈ¢þAr¡šä<‰±N*Bâ’9îJØOÍÝ8«›r)zzSæòÊFêèE![bYN$sJ’]+ÿ6FvñÇÒ®vçR~—7®QWŽy ¹ìÀ ~µ žä2/‘ݱÿ×â­ðsÊš?*/ä*y÷j­”mÅð0ãó§I-Ú8Ûn8ÉÝ‚>•gw8Æ~¢Œú`J/ä*‹‹ d_';FA ŒÒ}¢ìª:Û ¬9ò \äŽhÉ•üh¿\ n/‰cL/^:Ó^æú8$o'.…^NÚ¿^ ô¸£cð£›Èw* / À8O,§#ÐÓ<ëí°â%vtãó«¸=0? õv4ù¼…r‘šø¤ÀÆòmôüékÐñ…·frÌX Uí£»}9§mÿ"Žo!Ü¢&»Ø„†ïœ7í·`‚-$ œJ¿…úÐIü»G7\Î7ZˆIH´ù”ü£wQþ4õ¸¿k¢† ±íÎx#5{,Ý@þ´dc ÄQÍä+”Òêèù;íH ~b*¹ÕDS쵌“ä žWñ­`üßáJ/5qåýjÝ»9Áô«ýº~9£'Žó£›È.RKë¦òƒXÈ œ1¥4ÜßÉ͹_3˜{Uÿ›ÐО§Žo!\Ë™{¥00À7$cè*Qwz†x3¹IlzÖ‡åŸÎ׌{ÑÍä;™†þí`F6ÎÌdÛŒœ×ÉæfÜmÁÿëV–Gÿ^“œðI£›È.Siï·I¶Ô`—œÔ/w¨æ–x|ã5£úRƒžŒhR·A\Ëûv¢ `lnÀmÃÖ¦Šâøæ@G<ããW½ÉÏáA<ÿõ¨æò •<ûµ2 lt¦µõÈY85w¯Z1ƒÀÞ•ü‚åHîîeÁŽ£¹$u¦Iw|ˆ¬–EÉm¬»‡=jÿÌz“ùÑŽãNë°\¤n®•¦&…\ªƒßëNKÉ™¡ÝÆñÉ5o¨à~tvçš9—`¹KíW>DŽm[z¶úÒµÍÚÊãìÙ@™O9ô«‡éFæö¯ä3Eåïú8kgË“»çéJ÷w‰„Y³<:Ö‰9ïš0zÒŸ7\Í{ûÆuŽ+•É$”Òý§QW;­Ë&Î0£%¿ös·$~&¯gwc>eØ.fÉu{%¾è#da&PœóÞ¦{›±<ê!RŠ¿'$Õ¾}¨È¢þAr“ÝÜFc&Ù›+ó*úЗW2ÆOÙÊØò«¹'¹gÐóG2ì*´—`’"}:ôõ¨þÕw16ìå9¦3úÕíÞ¸ü©r{ R¿\¦÷,bòà 2r:JA}>ÈØäÛ /½\ÆxÍ.:Ó¿\¦÷ò(˜ýÈC·¿½H/Ïåùd~ïvOsô«üèÀÏ©úRºì3—R¹h#“ì¯Ì› ‘ƒõ© íÖçAhw.îÆ®àsœ~Tqýî=)ßÈ.gËôc¾Ûä#ª‚H4‹©]0ìÒÏ3Z@cøÙcG2ì(-åá… ƒçßÈÚzgüóNûEÛ›€°íÛ÷2jàÏr*Ür+ùÊBæð_¨4 Fè3fÅ‚†# ç#Ö´:r 'Í˰]ÍíÞü­›‘Ž™Å(½¹* Y8Ïðƒ’jÖO@>¼â”/ Áõ¥uØ.T7wEãT´$ï9oç֕3öBNüuíëV³ž óùуÇ_Ê.»È>Ó9y[T|¤ž 7í“*ÃæC‚çqV¸ÇCGùÁ¢ë°\ÎÑ´bcl;þ•/ÚnÚB«n lÎwµo ˆãÓ4}~´]v ”㻸Ù›ÌÇœgü)EÝÈY¿pX¡GLÕÜ’=>”„qÎqM¿ ¹[íÁ·8Û“ÉÎ})ævT?f ÿÏj´¦hÿ8¥uØ.T7³cå´ç¦H}hK›–Lµ«)Î>ðÿµÏµú~”]v ”ÕêD]¬òsÊîííëNKË‚6¤z ÕÏrZÏ;E]‚åQw9û1Æ=E!º¹hƒGjēБW}?*B}¨ºì*‹›’pm}ò)ßh5SÊ~Ч'<àAÁꢋùÊŸk˜Gÿ3íb4ÞÝyd­¬™ó6㎞µt¶;SpÏì;æ‹®Árq>é³ÂýÑ‘Í(¸—Í·`…sž:Ôàc¥à`Ò¸\®¥·˜àò8 ÜKƒûƒ»<Ýjp[?&ßL~Tî [‡2XØ3õ¨ÅÍÓ$cìä3u'øÆ®mÎ8ü¨Ûõ¢þAr“^]"HÍjçk`Èõ© ÔÂr‚ÝÊìÜoôg {Žj×Ì; LŽô_ÈW+ ©°£ìîÌzŽ8¥73ðE³œöàúÕž;Ñ‚9äŽÔ_È.U7* ›vÎyÆ?ZAy(æÝ²£å3W)>aß>Ô®*­ÕÑ‘ÙFÆBKoè}1PµíâÀ­öVÜdÁÇaWñê(”€=©Ýv •öo3[2©èr8úÓþØÌ­¶'ܽx«Ÿò(Ž´\.UþÐ*9¶›8È8?­8^å,26á×άwÈ4ž¹¥t+5éÙŸ+ø°~`iÆè‰‰ ¹Îj| tü…(Æ‹H_ÊÑFßdpY°AaÀõ§ý¶L·ú3œ)'­YÇãF>Ÿˆ¢ë°Êßm`[06ïb¤DíCüà ԤQFÞø…B¹PÝÝ ¥©.6ç÷¹•G6ìÇÀÿëñV0É£·¯ãEü‚åqw+n+m&äÓô§}­ÿr $—뎋S÷¥ÇbsNë°\«ö»æïµ8Sòlæž×Œ‰¹àl“ƒš›îi ©{Š.»Æ}©<õ‹ce—9ÇߪČTÏ·åg¯×éAÀþ®‡r¿Û“{¯”ùN¼ ôª’±H}gƒØsE=¡X^8|y ¹ääÓ¾ÔÙ‹10Þ2sÚ¬c<àRRz .»\^¬|—8lqŠñIJ ·mª™ ‘϶*ÆÕô£ã»&(Ùã`íÔÔ Æó § ÓŸÖ¬t4wPM»n6ÂçûÝ8 Ý0(‰°Ã"§àzRõ]OûC£eÏÞ#‘R}µv;èx÷©ùì)89ÈÛ4Û]‚è€_ÆCûß)ý)Zþ%‘c ä¸ÊñÖ¦Àµ!ÁëƒøRQ—¿h ûT?b‡¸¨N§Fr¯°îœÿ*³´uÚ2zñKÁ éŠ4 ßÚVÿjŽÜ±ÞêXcÒœ·Ñ¸`åIÅLQI ±r8*'—T9äíçò4]€/bÝŒ>sƒ‘ŒSEôFvˆîOP85$,%ŒIåểëOÚ§? ç¯h}¹ ²ˆØ•#Ô‰poÊFGOJ~Ð?„PI žÄ .ƒA‹uð 8Áã<{I8ëÍ+" U$t8æ¼äÌRо×P|Ãpàí4Ó}‰äÜtëVaǵZ`«ƒÔbž€*0u fÖš1Š=)ïŠN£Ž( Bý*N=) J1F;bÎsü4¸öüé2?È¥ÆGøÒvÅϸÇAIŸz?úAöÏÐQ׌Ñõ :zÑÛÿ¯F1ÀÅ ‚ãï§N‡§áE~?¡þ”RÜŽœQ‘è(Þœ2>”Ĺ>™¤â—Z·4¤úñô¤”˜´=Oá@úŒÑ‚{þB”dô¤Ás@z?JQ“Ûó ú 4ipj^z)ô'Ú†9Îìýi;ãùš\±øŠ9Ç¥sŸZ=y§uìOÖ›‚8ÇÒ‡=:RÒm98õâ”~(˜nøþTCN#îæ“>ÜzæéÊñG¸4gŽƒó£;‡ÝÅ)ÿsñ¤ ƒÐRŒã‚hÆ:Œ~Lz~=iØÏÿªŽ§ã@ Ûùs@ÿ$RðG@ W ““é@ 8ëK†úN´¸>ƃ×€¹þT=©sŸ­‘ÐP`c=}¨ Þ—=:w£o~”„Ðþt‡pÎ>´ü8äQŠGß©ü)qê üiߎ? \z’hÀ=)§Zv?Î)0Ç ŒÐ`uê(Ú>´¼ç¸£4‡…ƒzQ»¶(9î@ ãµúÒãØP3ØLg°üiyÔ`Ñ·hÇãIéÅ.ç£ò`wc¶9¥úñI´w éíN< AƒèE/â ƒIƒØþBŒÑI¥,E ŽçëIZ'Ò“þ*n0 ëõ£è1Nç=?*: 7m. /ãŠã½&=³Aç€)p=? ^ÿëPqj9úÓ±ô£t žF(àu¥ÿzŽ;? nTŽ´3ÁÏÔÓ®EÒ€¯z?ÊŒ`Òãè(8@£9è)y) o«KCA íùRmÂx ÁìÀ{Q†îÇó¥Ç®i6çœ~4qÖ“9è0~”ïóÍ/Ìh˜cÁÅ.õ8îq×ô¤íØý(Ç Lò)) ã>æŸòh¸÷ý)yéÍ(Qéǽ.84Ïv"”Ž){ã9¥Î:Ð{tÅìûŠ2h£_Æ—ð¥Æhüx öÅZ\ú*o€èsíIÓ±úR޾ôÒ3Óò£î÷üér:æŒg©ãé@'Úøϱ¤üèÀö >‡'©&—© .zãè)>o|R€}I£=‰ Àô£#ÓŸ­é@Ç]Ùô Œ÷£8ëF9íFqžhAöü¨ýM'Nÿ¥²~”dçü)yü}èÎx?­&=ÅÇb2qǸö 2pG± ü š\gÿ­HO­u#ñŒ“Œ:úQס?•g®1G#ƒÍ{þTgñ  éF úý)Aõ PvƒÔ}(sjvGµ ÛíùóF½=1Åž:1ïj1ަ‚xÉ&€Aïš.1Í}E½i:ûýhsŽ:ýhÎz~†“§=¨ÇqŠNƒî“ïš\wÇëIŸCÏÒ—¾ri¹?äRQÏ]ߥ/¶J:Ò|¤÷Í-OÊ€Þ—?•&Fs“ôÅ)çÓÚ˜}Z:žG4cÖ‚=Ž}E>”ëŸÎ”dúþ4Ÿ­ ¹è(ǵ&xà{\c¿>ôcÞ“…/Z\zãò à{ÑÈ1õ¥ãÖŒþ&€ïͧwÎE&€Éç¥/>”¤¸¥ã´ß›Ûñ£éKÏLŠ1@=I¤Ç ¥À~_0ö¥Å&G÷h¤·ð¥àuý(Ç­'NôÀ>_BM.@õü(üMÍ ÎŽñFsêi8ôçÞ€LÑžÔ}OëFrq@£ŸN¾”QÓ½0˜ã¯ëIŒu}@ o=E.aIžÝ(ü)¼{Ñ׊MËПsKiˆ8õæŽüu£Ôr;PO¯qëKIß·å@ñü-{R`Ž”¿CÅ>Ô ;t¤Ç¨½{šÔ~­RâÌÐ!1ïGN1KøQƒÚ‰Ï¯åKƒ@Ï¥üèç<âŠ_­.s@ƒð¤ëÓ4¿AE7=¹ühëן¥;žÃ4zãð Æ(úøRðhé@ FÔ~T¿ð9˜?ZO¦iÃüóHNOqÅ–ißJLg¦h8üh K´F=Í!ã¹£Ž¸4½¸¤é@ øRcÒ—š:u ëéøŠ1Çõ¥£'˜£ò)ih¼ÐFzÒâŽ}¨ãµ}M/8ç“KŠn8êhé»4¸£ùPÒ ŽqFqÓùÑ÷»P0ö4£¹üè£ÄÐ!xõ¤êx4€ú©sè(Ç|Ò`}~”¹?Ý8¢€<Š>ƒ?…;ò£ô çÔZ;ÑÚ€ŸZN}EºQøš:ÑÏ­ÐG© bÐ SÀûÀ{ÑÛÖ€GáKøQº€!Ÿýb}ô¢’ãï§Ð÷úQHüsJ{qMÞ—êsôÄ8gÖ‚Nylýi8ZPAé@Óñ£¥ø¥ÁúÐJ\wŽ@£ƒŒþTa½p(ã·&Ÿj:sÇç@Ù£8=Å@ÍFñ³tl{šKÓ©¤õÍ"áF ÝøS²{~L{Ràc‘ùÒg?ýz7~}(p₤ö7m¦—œñšÀçéG׎y8?J;w1ê? ñÀÏãKœ÷¤üùö aÈíŠ1ŽA õÍ.€ÏcÆŽ½qŸqK…ô£ sØ~\qŽhÈ´zRŽ7séJ@>¢›Àq@ €EcÔý)}ûRqÿê AÉ£ŸQGH QÀè3šLg°Ô¤c½/NÔ=¾´¼úÒg°9úÑžÙÅ/AþŸ‰ÞO®iIù‡o|Róëý(=8 g8Å.{dQ׎” 0MÐAîMé@„ǽ/ôœ{ÑÏf Èñé‘@Á爣#½ ®(üÍ=Å>‡é@ õ4¼žƒ"“v½ùQÿ?/#±€ã©üèãÐgÖŽ; \àñFOÿ^”b“>˜­:sJw¶8ÆiœÀPð})Hã £·Cô¦äc§é@ ÓŽhút£žÀÑ“Ÿ»Æ€ ’(äô­.3ÐQÏjM§±¥ÚØè1@ééô uéϱ n.=(ô¢€ Rœš ƒØ~T`Žçð 'ÒóŠsÓ4¸=I ÿ€óëFOÖ–Ž=è3žÃð£Œ1¥Æ;Qר ¹£æõ¥È½zó@ ÈëK‚zf“8ÿõQõ4mïž)729§?ýTtëšÏPi1î~”¸þº1ëÏÐP ôÅqëF}?•úPvëÒ—=‹ÂŽ1þ4¸ôàPdÒŒçµ?ýzLqŒÐœðVŒëJ?3FAö>”˜ô(9Î Çlæ—ŽÝ»Ny¥8õ¤äñÓè(Ç­/AIIÇSøÐ÷â—ëF}éûÔ{óGcÞŠL޹ÇáIžùÇãFqÁÉü)p3Ú€wÖÇô¥à'Z8<ŒýhÁÇ´qœ÷£Œt?3ŽO×4Eî¥Ï©çÚ ×(éÅ-'nhsëIô tþ4c¨Å&°ú ^Þ´¹ô­zõ íqKøŸÊŽÝ¨àžÿ{ä{Òcþ€Rò8À£¿~4 ãŒãéH=¿•/ç@ƒæŒ^(ü³KõÅ'>´Ÿ—ãNãµë@ ÇçG 攓J>¹ Œz~t¹Ï§ÐPqø})0; ÐçÐÓr ê ;¨ìhã¡€Óð£>¤RàqúRàc¥4ëúQß®? wà(Å7*?ˆz{Òâ—?Z>ŸÊ†­ >§"ŽžŸ•.GÖ€ Ÿþ·™¥ÀÇŒŸJ''œý)<ý(ëÞ—Žh¼úP ïü©¬Ä)+‚} U7Sî8¶|$€M \ ™>´~uH^\b@Öü‚BóÖ¦ŠiX¨hÈÊóÆ4ì'ç=E/Ö“ñ Ú;ð(ÁI4`Qš@þZ?*ŽfuPTwúTŠxåyô¦õ4~&–“'ÐùþTwïG^ÔgÜþTPHö>ÔÉY„dª†aØÒ£; ,¸$Pž{KÀãŠ2GZ$”ÊË&ÂM Ðø9ãqíU¥{ä"Œà‘Ö¡K›ÜFd…FW-ž¹¦•ÂÅÿlþ´;ÕA%×Ï•P7 ¤qVÁàdR°@õ9¥íÍØ cØRÈõÅŸJ\ÿ‘Iœõ¥ÇLŠ3ê:ûQøŸÎùÐý1G>´Æ“hìq@Ó×q££ É£qí@ÇlQœô?¥õ4À0ÿªŒ}~”QŸj@!Uaó(4m^ƒ#îiùÀn\t\þ” œá—ëÒ” 1ߊ8îhÀ=åAñÏáJ:u Ç©4ï¥'>´}s@ G½'J^(¢ÀQa@¨£ TSJcd 8$ оۨÅU72Œnäã9¥6;¹ ®lêªÎØñNÁbíZÖy%Fi#)† d‘št“2¹UŒ·ÊH"•‚Äô~$Õ&¼ac ªwABjD¸f—g’Ê9å©Ù…‹¿RiŒÛA8éUEëçþ=ÜŒã"„®ßΓñÍRKÙo³¸`HñV£¼jÌ¥XŒ•ô¡«‡þ4tíFhȤz@_ÊŒóïFsë@ƒÐQMsµI'I—PHÇ|P1ÙúÒäcåG^ß…ûP!¹S‘KƒÛŠd²ð6“Ô ÓÈh¼÷ñ£§¥ Ÿc@„æ—êhÉõ⎟ã@nMª¤·R¦B[»ŒñÒœ.$,ÃÉ8ì;sFýFªý¢l û; ·9èÖ¥–q( Aä tôbš¬¨#­#¹En~”€4dž¢£I7Æk ŒàŒ€ÝIæm–ÆGjvabßnZN½¹ª¿i"ÞI7ùsÕz~<2‰aFÁRÃ8#‹‡ç¶i{RQ•Ï!Z1ß&Œö£>ô})~”ÝÃ8æ—>ô¨£šZCÓ¦h͘ü(†ûÑŸ×ÚŒŒÑÁcÚ“ƒÐŒÒaA'Ö† £Œô¢Z·ø£ùÅqÓðÍÃó¤0Î9ü)sèM >€Q“ÜcÚ€!¸ûéô?ÒŠeÉå2;(AK:œRq럨¥ã°Ä(ÛÇ#ó¥Êäpi0¥/NŸ5.G®hÏLRž”¸â€Œ“’}©r1À¢ŽCƒ@?8å÷RcœäŸlЂ{Ñßh'8 øûRÿÀ¨?(äz~t½{~9£ÿõÐ1 ÜPO£RãÓˆ£Œt€ ÑœñÖ“#¾úR|ŰTmìhüŸJnNy"“÷`O­;?íIøÐÒ”gØÐdçŠ\“Пʎ¸È Ûj9Ç_Γqúý)sþqHO8}(ëÇ$QÓOáH#ÚY·3n9ßJ\`uýhÇ©§{ÓF1÷wÅ)8=iyíÅ&=ø£ ퟯ4œöcš\þ½£ø wÍFqî}hç­$uaF?RqIÖ€=hϽÉëF?É ‘Ž´œzÒíµ=(ätþtvçŠ>ŸÎ‚=è¶hÏøÒýiGå@ Ÿ|}(üM/>¦“ž?:Þ”ãÞŒc½àÐd÷?¥/>¹£ñ£ŽôŸ­{ãð¥ã¥ç=h0\~4wý)G>¢‚­'éG·$ÒãžÔc¨ô˜>¼Q“èhê3œÑŽzК9õ4tþ/ÎŽüšCש¥ãÿ×G¢Š_ÊŒR~"‚G­)Rc<äÑœÒäPp'Š ¢Ä è©àýM÷£¬h3øÒgÞ—ƒí@ î(¥=“ŒñÎ(ß4¹8û´ÜóÖŒsœŸÎ€ŠNçùQõ¥üE7§¸ö£ÔR`g’h'ë@'ßñ4´@}èÉíÆ“©ïš^O§áKõ äþ½éF@ïI¸{ZZ:Sy'Œ}iØÁ4‡ž†ŒgÔR†ìqÔÐ`~?J\qÔG³Fqߥ!Z\ïRdñÏçGJ_­îÑŒu4f€(Å/¢€¥&sõ¥À¹õ 䎴žÂ”ò8⃎怃í@vÈühÁ<çô£õ¤ÆxÜ8¥Àÿ"€ ~cÞã#úŠ¥-&|~tqí@ 'éKDZ¤àv})qFG¨£>ÔbŒœQŸaH0zPŒQÏz_Ïó¢‰×Ž´cÞ— מ”qÖ—š?:!?\~TgÒŒzIƒØï@…Ïù4™£ò£žàQŒu ûŠ3ôÏÖ“#{cŠwNJOÓÚî?3G…1š3ŸZ8^ Q•9À þŽ=?Z:ÿ ñü¨ÇûÔuìG½&8èhöçó¤E»K³sÕŽM;À{š_Ö€ð¢—Aô îÅ'ãKŠN{Š6ƒÚ†=1H:ç;Fhú`PX>iXá†<jÐÕ^=ÒM¿Ìb#iâ¬`wPÁg+ŒO~*¬·³!b¶ŽÊ9Ïz–Yn#MÇsÙ5` u§°Êëq'ɺ&!±Û«¾^¹?J¯tWb6ûŽù©€š¢*\îB˜¤Ê°9R­Óß¹q·ÔRÜp~lôêUû½A£ Â9ˆdwâ})0{Œþ4¹ôÇãHBg×½ôíGÔRñÛšŠp&\œûS¢Ï”½Oæ›3…È!O©8¨-î¢ai78-ËΚ@\üqQF˜IR¹â£kØ–"à1Æx yª¶ÏÅô²+¾à9B¤ùГ.;Š©:1ºÐ0Nx㨫\c®~•Rè³L±†erOãDw-ŽzÒœúÒ ÁÀ¥ú @/j9õ¤Ñh,?É £8êÔ€ÿµš°€‰®ãGe!°½À©RO1w`ЦÉtò8Þª¹½G¥Y‹z¯ÎA?•Vƒ%Ï­'ãÇÒŒ·r1õ¤Ï=jD/^ÿ#¡”½Qš7{Š2^”p:ž>”}1õ¦Ç­ÇR)0(žß(æ—§­7þªQœðg‘Ó½/ÆŽ?Ï4gŽ´fŽ=¨ãÛ4f—ñ¤ö9÷ÅÔ~T´dRŽ)3ø\ñÖ‚G©£ŸïséŠ(È=èçÔQ§åG>´BØä‘U$ÿKCr„IÆr=*{„‘íÝc >8$TQÅ2ª—p0xÅ44Y êsU¡9œãÌït©¢™&ŒT™.@w0N6І‹GŽyª·Äw²õéÐÔuc,F7c4ÙŸ2F¢EäCBZ‚éÂÛ»§x ‘S'1©ç§SNÛ”ÃaŽ}(éÀúRÇûó•ã¨íQZþùä8°©ð c€i,¿1”ƒœc¥5°t&éKøƒHÜ—¤ úùÐN8?…&­E;á@íbxŒÐ28¥ûL‹*»*Œ‚„{Õ¿§Z)(YYD€H§›ˆ@È£'’9¦Ð2nh'ŠN=T3ÈJ”‰ÔËŽiÐÍ,Ä,¬»O̸«˜»–<œïI gRX‚3Ûš`I“ëùŠ9=èÅ&åõ„ñ¥üè;HëMÎÞ=è¼.æ1É?wά㩪þn×%Þ=¸ì95'݉íêéMÎRj¼øYã˜ÈÃh?(ÍM©2oŠUaÓ*A¨§ßÊà(14-ÁÈÔS%*¨rH¸¥B6›”„/äR`R⎽ñô (ïÍ÷ J3F}èü¾¢€èM.{´güŠ2qÒ€ zLd`ƒøÑž´wã¼Òsýâ.=OçF=±@2MÓcéGN˜úP0À¤Ü£>Ôg#Ó4­ކ“ÑÀþ/Ê€!¹9+øÑIrF<h¤™>”¿…hÈþö>”Ä.xÉ¥“#Ô8÷ ~“Î?:Z:wü(sŸZ3ÏJ2 ó@Ú8 óIž:qõ£¤RgÐqK‘Ór­n™¹¤úQǽ. £ƒïùÑÆx Ç˜ÇOÊ—>ôþïã@9qKIKøPdÿwñ¥ã½ü)7z@ š(£Þ€>”dûãîÑÏ  Æy£¥úÐGNá@|Š9Ï_ÂŽÝ(Î;b€ ÑN9Í¢€ÏøÑIúÒâ€ÂŒ¥š9=èã§ OÊ€ ã¯J21Ø~¼{QÀ=&~Ÿ•-ö¤ÿß…~4sÛ4zóõŽÃ¸4˜Æ(hæ€EœúPÀâŒPdsŸÎ€½&On”ÀØ—ËÚÀc9ê)ühÏ>ôqéFqÖŒûÐWלúþ”£Û}q@ ëŽhÉëÏÒ—õ¢€gû¢Œcœb—¯¥Ç~(çÐÑ“žô`}hã¨é@ ŸoÆ—#ÛëG†Ò€ ŸOÆΗñ¥üè0$Š1Ÿ¥{QŸN>´aÇÒ€MÎ:gëGóúÐ>¸¥æùQ‘ë@Îx :Ñ»ŸN(pGŽ@£ô®hçÞŒçŽ*1øRþ4Ü ûÒãñ¥ÿ9¦û*#­(RgŽZ9êë@ E&I})qϽúҸŠ\sÞ–™ŸqŠÔãÖ€<ÿõ¨Èô¼ž”>†ŒúŸ¥'Ó'êi*'~3AÇsJFz“€ œÎWÉÚƒ?6jÇãPG°9ÚIËýjlûb†2ûB‹Œ˜õ?ÔŸÀUy6}¥2NãÐv©óÛ½`"¸gXÔ¢3œóŒqR&íƒvsPÝmìÀnt‘üªDudÏ=3G@è2ã„˃Üt©;AéQܰH·ËÏQŠ‘~èäýM(޹¥àw£>€Ÿjn êhÀ÷¥ÎN9—æ=øúP"‰7ÊúmÍ28Ñ‘XƪqÓn*IŽ"q¹“ޫ֒l³ñÕˆÍ á@ø¨Ñ¤7N<¿§Õ’3è°ª¨ ^¹%þèÆO!¢Î1Ð`zÕy¤+2¯–åÎsÏQV½pØüj¥Ê¤’ª7™¹ùzu-Ä‹@d c»i íõ¥ÎxÉüèqÆq@ã­ôg<ÐÉúRmÖ—è$gÞ€žœuâìIú ¦ãdó?žFìgiéV-ŠˆFÙL€Ÿ¼Nh°X“?ìóJq/Öc=Ͻ ÄÑŒõ¥ã¿éAÉû¹ÀLcK|Rcž´¸ÿ"€ù}(Ï ¤ ŠLöàPºõœô£Ö”ã½ùþTŸç4`{þt¹Z}³F=(Ïù˜äÐö£‘ØŸÆŽ{Š8úP0Å~>Ô›Aîi@ÇZ0GsïE@ƒš0É£'ÓŠŽI– aϽÿÍ1†Tü´õ!”89db›#BÄæ¬Ý3²2 sÜÔï9Ë&OLÔvª8–ùÞíSôô¦÷!6°íÇ–:梑£yãŠX[©ÚÃ8<²¤j Ë·'æ›l’"ò™$Ž: q“ã"•™UI8âšX'°ëPD Ìì’g$=8¤ … ºo=2H8â¬óÚ€1ÞŽ¢€–ü¤ñëU¾ÚLa’&f=¿Z²À#¥T*Qм¿0ÉÚ=)«.` âª]YaV…d,ÜíVÈÏõ¨. ²äœÞ…¸"WŽ79dŽõ·…Ÿ/§h}Ç g¥1K (Ëlä—;¹Å\†$‚%G’ÅæDÊN2Ï¥2Õ£Xo3©9ͺBÅ&}E&sÒ—Ÿoƃð8úÒãÛ4˜÷£ðéKœñ£?LÒuí@ ~”œúb—òhëÓõ Ç4c4}qGn4½úÆŒÓzñš?P±Çœt£ éGáúÐsë—Ù¤ÚQÍ„Ô ^Ò“ß­¥ý(Ïù4„`õ d7?ÃøÑMºê¿€—äøÒõäÑô⎽iˆ0iqõœt{RäûPƒëG…”c/Oÿ]§ñ£C’G¼­!Æy¥Ç°~#ñ ·z:ö£?J\ó@ ÇjC·3Nç¹™”Ÿt­>ÿ”u4a{Öˆ gb—>¢—4œ{þTœzb”cÞŒŽÔ™É C³Ï­&y£>”dú1š óÇëGø³K‚zPãü(Ïi=é:zÐqß?Z]Üw#éGÒŽ}q@ñ@ã ýhü*þº=¸¥£·J9ëš?h϶)?J>Ÿ­/>”~4œ^´QÖ“ zÑŒŽh{wÅ!é@Ç­çšNÝÍ/à:9ïÇãG&€ÄÑž)1ïŠ £ð4~ð¤þ¦Œzb€·r(КCžøÍ'_SøP®*N¿OJ1íF;ZÓŸ­§4pJ8ÏzB. è š1Ï^(ÆG9úÀÀ¹¤ÉíÍ/$P8ö r9¤ÿ=hr{súQø@I¥üMéFO§åI’GcK‘øý( :v¤ëÚŒ{€AíG™£ߥ.¥'áŠ0{Rã…'à()£8íúÒç4QFh “§oÖ–ŒŒÐzŠOÃõ§{Rqè@}£?Z:u£ƒéùÐnÏCKÆ—>ÔtìMâ“ëIÇÒ—88úÐÖ—8÷¦î=—óø w¿JN}8¤Çp?­.(Î;QÍ-! '½ú~T„ô“ô¥Æ€{ 2hÍ/$ph£“J3îMúP~BÄb”ñÖŒû~ Puô£ûÒæŠ(Æhü(àv ÛØ€hÆ;Ñ€†—{P1ž¢—>Æ’€QךLqÐÒl^  _Ã4`wsŽ{õúÐhü¨àup;~”sߊ0}¿G^”cÜÐóéšLfŒqHG9ï@ ÓÓó£9ô£=©@ Ͻ¥äö⓯a@à QG”Ò€  óý)8öÅ/áF(È=qE³G?ÝP!O¥&?É¥Áu Å/ÐbŒ})(éÁ&ÎŒþTg= Z: _©¤ï@>”u£=hïÖzѓӭ•J>hÇÿ®—Ÿj9ô B9ô¥ÁúQq@Ɵ—?ˆ£èq@æiqõ¤=ºš1þM…;ÑôÁüiëœ~4ÈÂrûÁ9éR¡¤…pèãµ6@Ì>\n3P˜îÈ+Žz±Ï­'4ÉþO8<äTùã¯cØPzrúQp†åÇêjÒàgÌ•HÏ^‚¬ã¸¤Èëž>”sÁÏéJOçô£è(üè3J:õ~—ô ¾v¤g¶i±‡… Ü-?ñ¥ éÓY|æ%‡—Žžõ5'Ú¡š)æ7Uã­OëÍ'#¯?… ž}É¥ëØQÏáKŠoÐb”1ßqê(„zsŠöJRH÷„í@ýž#Iå.ælŒäTˆª«µFÒózf—ŸLP1:{ÑÁÿ \sÔNzÇj^:ŠLx#éKq@ëF{rhãÛ4u=9 §AÍ£ŸzQ@ ŸR(ühéFN:ÐàŽ„Ñϵ Rîø ½#×éš2)¹Áãõ éœ J3êiG<ô ž8æ€éG>ôdéõdÿ¥/?JNã­úþt¿^”:fšÜƒÏlÓ¸Í'>¢€+pJÝŒÁ9¦7ÛÎð¢ 7 däÞ­rNpÖŒÛô§qÜŽ÷Å)”j2=i‡cÊJÌ©°¯¯ëSý1jN=èϹÅ(sòÀ-éPÇ ÑnØA9ÇcVsÇüh>à~t\.WÝv (‰Xs¹‰éRDe#÷‹¶Ÿ“Û4uà“ô§p¸¦¡XÞF0‡M¦¦Ç(üéøS$@ëaÓÚ¤ühëØÐ"² ¨®§Ì{æœæ+ìŽÕ6)qõ§qÜj¨UÇCß”qÐÒý(úR…Olæ¡·Ò29=ʧÁîhÅZ3ëŸÄRŒŽâ‚×ë@„útúP:sÅ/N¢—ùÐR³,­²1·o\Žiéæçç ­MŽœ“õ¤ÇšwÊßéaQRÝÈ$±‡ÃìÜë¼â¥£Ž¹ÇÒ‹…ÊÑ›¯-wFméèi[íTyhr~`Oj±Ç÷¨ãÞ‹…ÄUUM«¸Æ)‘†RÀ QØç­IŒú©yR¸ÏÿZ¢U1°HâP˜ûÕ6{b”dŒùP Ï”3ì~”`{ÐõÍõ©qF?:(ϱ  Ns×ò ~”™õÐ=³FW8ïï@Ç¡ ß4cØ­p(é@Ç÷qGã@ IcFE¥&3Á¥À(&ŒÐ1}éyÇ4¸ô£Žÿ΀·ÿ^ƌۊ8Çø‚ã—C“ÐÿJ).º'NôRS¯Ò€qž¾˜§;~´‡< sLÇcKÓßñ¥íÈ£¿¥ ñŒGQŽ>´piÏZO˜>”zîɧžØ¤u až9£ÿ]ïÍõãE&à¥.=¿*\ð1@ Àp½ýêwÔΓ>”{çŠ0¾”~u¸_j:t¦€¥Ç9 bóÏ}sHG·ëGç@€ŸaøÒdûf—Ô˜öýhëש¤#'¨Ó4¸¥ãÒ€ qG°)1õüi~Q×€®(ÏÖ—ß?¥€ ïFOp(Î /=Å&pzё߭)t¤Ç¶(r=OåHqëF=ù£Ÿïgë@úÒ©yö¥'Þ€—õæ€ÆŽhÁúŠ(ù³Ûñ¥æ›õ&”=Gã@#Þ“9 ãÐÑLPàŽ™úRà㨣-íùP{ðçKÿ¥ù½¨ÁúÐaš^})9þé`ç“@ç¨9ö4˜Ç­/‡4cß(Î99£'8Å ô½(ëÿê£ñøR}?ï \~þ4`PZQJ1À£ŒÐ­ÀÇó£ùQ×øs@ËØRÒ}(Æ;~´`uÍ€÷ {f–€ çµ! N(Ç®:C·Ò€·š94KŽ:Pqž4˜Ç·ãKøQøPÈêhÉ=é*;v ÀëA÷qGQÔŠ3Åö¥ç½'_þ° úwíGO­±ü©q@ ïÒ—žÔqïGÿNz€?:3ꦗµ&@£8S¹#ŠN½h3Ó©£éÅzbާøæ€'ô™8õü(ÉÅ} ? }(õ¥÷íô£õ dÿ•Œã± §ÎާŸÐÐ>”¹ÇPE'–Š"€z_ÎŒI‘õ Érhü üŠ3ž¹ 'µ&yÿëRþPpyïGÓŠZ> PsFzÆ—9ÿëRPš1ŽÔ}:ýiù4½:ŸÂŒŠ?(ãð #ÖƒÀèOÒŽ¡¥ãÜP`wó£OÊÆ–‡ó¢“ÿ­c¾(ÈìOf€Aã­/é@„Ïlþ¼õëIÇ\ÐOµ.hô¤Ï½' ØÐ1yôüèÎ)?KÉ1ž´p=i ÀÎßÊ£Iƒ“û·_v.}¿J;ÑŸ­&ÿZÏqøÒäúQGç@|ÑÉ£ŒP}Å +ü4¼çÞŒ“Ôb ÈëF}ixúQŸÆ‰‘ÙisíGÖÃ4Ÿðš;ò´¹4cZOåUšöls×;ÕåUgÜáUvœîçùSVKöÈ‹”9 ýjXäYP:çÖªDÏ;yª vÉ«èéÖÆsÛ¥6•†Ò%4Ÿ•8éGN•$çÜÓ\ìBÄ?(ɧ󞙦ÈFázwé@ÄF(a»žpE;9=±L€f0~P;m< “èh`ïøQÒ”gÓœž1øP!9¤gXгtìc¾)’#m Ç dbî7dP>ð'ŽÕßF±;¬Lå[iS¸³Â3Î_múÐc˜ÄûaŒÜÍïUd;"öxÎ?:¯0ÆU*ýjPÜ䊪a“Ëa’A$óšJÂ,}¢"Á@bǰõ}Ã#¡ªŠe’bñÈ#§‡xˆy™ ôÿ C°­2$ ‘žø¦=Ü1 bF `{šIÌ€¨@¬Üõ<Ô- òFHã'9àñM$.ŽyÁ¥8úS"AÐý IŒ{T± Ӡ擉¥Ç×RÉÏAŠJ_¦húŠb—òüix):Ÿ¥:t£ Qž¦†ãGjJ^½·J9ô£š_·AÒŽÖ€1Íú 'Ó R`gßÖ—¿?¥sÇ4qïHzgë@¶}éGéøRmã¦iyÇBh;9£ÚŒÔPgžù£ z攌u=ñŠLû~´¼õ LûÂC@ @'‘ŸÂŽhÅzsí@„äñŠiuiâŸÁúûÔ1¹ÿR¤cýfFh'íG'¨séGNÀP!ŒápÎiÀŒÌAcp3’[¥J»¶@ŽÔ :öñ¨¼å\ƒÁ‘©KÆæPMgÝ­7¨?Â7wëŠi/ƒž•;$jbmÀƒéš~=)ŸÊŽ;‘KøRqÞ ïÅœúæúc'Ó4‰2Ë»k ?ñöªöùÿpcËrsÔÔýhPHÞ£K˜\9÷¥¸'Ë &ò„T"‰›}€sM$ 3Æ3ô¤éëKoÖŒBBpÎ7 ûÒþŽ(ïŒ~”~ó <«»œHn"Sx Ô7ŽcI‹Ìù‡àŠ«q3¶ìÍŽ>cÈíÒ©$ÊHÐYÑÈ ÙÏ ¥y,lgÖª¦~Й€…üÙúT·!?v­Î9=(²‘8`FAàÓ|Ä,SÌ:JƒÔ•R.™ˆL;sRÍ"ª’ÇMYã`Jºœu¦Ü'™ &7ÐU*12‚3ÉÒ¸$] ;H8ô£5^߃ òv ßYàJLsè(ü…Ç­/å@€dz0{ô¥ã(Ûñ çÚ—&”@( Á';Fhö4¸öüé1ì(Ûò£"Ž}ÿKŽ9€ò"ŒéF Ï½/#¾(Ç·›G¥.O§ëA'=¿:nßOÖŒc©Ó=©1@ÃþúÐi6ƒÎ(ØPçØÒŽi°£·J¯uü·_ÁÇ­€“žäÒä hÇpy§`qÖ€Có_ÌQï“IÁìiˆ\QG>Øüé;`géÖŽ{hüÖÁ<1¤Ï¯ó¤èhØôÈ¢“ŽCF9ÿëÐ’qþœŽÿ;æŒóƒ@ Ç|óíGàÖ”ãÔƒõ£Ž½M$r1íF £sIò÷ÏøP0Çû Òà)1Sõ4u Bã¿7¹§~¦“¿¯ã@E(ç R`ç<þt qÒ‚ œú“Eâ€3KØÑ×¶h¤õ¥éØ~¸Ç½=¨ñ‚8¥ÇùÍ'^€Ñj9ö4nõ¥üh†џSF}¿J0hÏÒ“=×¥…!äuü¨OÒŒRtîiGNÔ>´¿&|QŽ€ëŠ2;`ÐWÿ×F>´¿&)7vQ¸£ò sïKÏqÅ&Gz3“ÔÐÆ~àühÈ¥íÛñ¤Ç=9 ÏáGQÞŽ$òOç@qéKøQÀÿëQžØ"€‘Fq×¥)'·ëHÕyôqØÑÐuÀö£w¨ØÑž3ŠO§'ÔŠ:uÅ)>àþ4´ƒž†—ñæ“J:tý(p}F(çëMÎ=©Ù>†€…¹ RcÔœíîhr7c<â–}x£Œg€“Ö“×ð zu÷¥ ÀÏNiqš=ÇZ:ФÇ9¥çÖŽh0)qÏŸ…!#=Å)ÇsúÒ|¹È—zb–€¯j3ÏSùPµtÏë@îÃ÷½==i#¡qèh}Á£ÆM&})Ï$‘øÐôêqA=‰âŒß­Sí@éøÑÏ¥/ÖŽBh\õ÷£^~´ïÊ“>àPc>†—Ÿj3øÒqßò ¿Í/=ðM£½(ÁÎ{ÑGNØgÞ€ ¾ôcÒŽ?ɤÈúPýh£"Š9ì:LàÒþ¾ý裧m¥ü(C@Ãñ£üñEŽ ÷£ëFpúÔRqïøÒçdÐøRb—ê):ôcñ¢Ž£Ôdôgñ£úQùŠ(£¿š9 >Ôdv£“Ò© ŸÃð£'¸£üõ£Ö€§ó¤üáJ=ºÑÓ¯Z:ö£œph¤ü¨Ií‘I{óK‘Þƒô <ç?†(üihç=¨8ÍwÏåF P0ëÓ¥ûŠ:tÅ {Qš>´~4gñúQø“@yëúRÒúôg·4z2=hÏlÐõ ôsê):1@ úèãñ£§Òç@ Žs͆M.O­5¾éÉ8Ç4«+ÆÊOÖ§9õ5VËÊ0ƒò§=~µg·ÞãaÀ9Ï>ô,Šz8?J¯xeÙOÚqßÖ ›ì¡ÂÈ8# ëœP•Á"þ} çÒ›!"6È'Ž™ëI(BÐõª×-oæ€YÃñžqEµ [0x”ùe(nµ`Èã¯5™þŒ®ŒgeÇ ƒÖ¦³Ø m¥Ë§¥6†Ñp{þ´Î L’iqÛ&¤Bpz8î:1Ž®ir:nÍU½ m˜:3ÁFMM|”àŽ)—AL38¨y©" ĸ$àc=èè~ZFû¤ 7µ8þ?•#…Øsœ{q@@c*Jp3ëRô¨à*•Œ÷ç=j\çŒÐÁ(S);Tðp*cÈ<ñÞ¡FF˜ƒ#;T¬)ùŽ1é@Y„ŠT#‰«BªXì1’Á9à ¶ ïN[ƒó¥ö¢‚qëHA´ÑÀ÷¤Î{¬È«3“;üãsÀ e®½h5 ˆ”o-Žæ¤ ÔqFçGàqõ Ž{ƒG¦Ž´2(£·s@ÐÐd}hÀ¥ã§f€·þ4¿‡4›¾¹¥çÜÐÀM/SÚŽ£½{þt Lz > û^)6ŽÙgÿÖi8÷4¸äÑúPv£¯?.­ôLúRÑþy¤>çò n;\AøÒ~t™ÏaøÐýàAý* r‘Ÿ.5lÔô§KÌxÞS<ß4°'— ¡•¤ÛÕ˜äšhd½{fšà*W ŽÔî1I¨®1ýâ£×4„W°â_/Œ1éW0}ÿ:j`  õîZw_SM»Ü"°MèÇ ‘Š˜ŒóŸ­Csµv” Ï\ÔÀ sG@èVo(](!‹œãh«C§«ckºUι«=è{Ø1šJ^”{šBhÏZUˆ]#6L |¼U“œUhW÷¤´­#.q‘ŒSCE(ÇçG”œRNëÉ]X¾F>lúÓï^!™¸†1ëIx¹‘þÐϸ}ÆíV×uô§r‚3¹í {Ó¾‹Ÿz†Ü(N%ó®*|Ð÷ëüèàôÒõê´qèE!îc£Q*îúÔÀ £ü*+¨–DPÓÆ{6*Uû£>ôú cëPÜ,MåùŠsžŠŸœr3QÌ 7”=© B¢ü«ŒŸ­C€·gl çnõeؼä㯭F3朷ÝÏJkps %7`ð3Š’=»8ÈJq‘Çnhˆ ™·½.€$¡vŒð=©a*Ѥ°÷¢\˜þWÛïŠ"¹\¶}ÔbŽ€Iø~´p;QïKOÖ ïœ ]¤õéGàE~cëJ( 8Æ:QÆ1Ú€{`ý(ÎOLP>Ÿvý('¶Mºš0s@à÷ÍŸçFhü¨úùÒœúfóÚ€šN}é:?ÏZ):u¥4™Å -&GãF~¦€ ºþÆŠ.Üà÷¢÷ü(ç&œ ŽhÊœô…€å…;¹?Jk®å#¨#¥1ê8¤'Ûõ¤åPzK:(¹ç‡Ðt£'­(#×hU¹§dÑ‘íAàP€zÑŒpFGjL`u9¥üE‰è:zŠ?ݥ籤<ýãù9ô"Œ¶9çÞ8¥äzPqKúRu<Ðs×üâ”c¤ù¿¥&GsúPœ7 ƒô4séùÐ=?J:÷ aÎyý)r}):wüh÷ AÿÍgøMÐíøÐÓªþT£¤äõ=èúÐ3ïK×¹¢€¿þª0z3Çj}? N{9ôãÞ—'<Ò{Ðú{ÑúÑøq@ ñ‚? \z2=)0¼hàõ?¥^ ^Ô˜=‰ Œs@õ @_|ÒqœqKÓÞ€?áGçF{ Š#ÔPcš\R`vÍ.?Îh0;ŸZP½˜9êhr=åE÷4‡ÜÐÒ“Ÿz\ûÒþ´ÜtÈϽ/éy=ÏåIùÐ0:phàœâ€N­ÉÍsÒŽ}1Aϯ4ž”c`b“ƒÆ .=y÷dzÐõ£­æ‘ØôëÅ.1÷Z0)õ4§§=(@qÍg¡Í4`öýiqžô¼ÿUúRdø¥éÐÐÉÿëŠ3ô£ÒëÏá@ 4}Eãš?_aG=Å&)p}h=x£ó¥çµ'^ÇùPFz‚cÔQ´g¥Ž(ãµ.:Rzñùš88ÏÒ€~#ð£§|ÑŸcIÓé@ ‘ÚßáH{Psë@ ×°"Ž{b޽÷ ´˜vóî)qîMúŸÆ€ ú~”nüÒ“8?Åý(ÏûT½èã3ô£ŸJ õ÷ üô£ðô{Òã4˜µ.2: RmØÑ´uÅ(ôÅ”} !>Ü}hxõ£°ïIž@¹4`wÍbŠ(ãÒóÍÿúèü(>”}4œ9 ǵ7OÆ—ÐQë@ LÑÛ¥&¿çF@ 9íÅZ\úSsï@ >”™"ƒÏ^”qÜPôÈ¥Éô¤ÿ>”pM/4Szv${_Äš^})0?J1íŠ8ÇzZL{gëFO Ç©¥Áõ ðgÕ³I‘F~´¼úÒdúR‘ïIõ4¤g¯4tÇjBp{þqø÷ ÀÎ¥úþ”Ÿ/`sJ3ŽŸé)sŠ:ö Ƕ)sŽÆŠN>´£šáGáGN€~4sŽi3ê)r(Î}èÞŸýcKÎ:àzb“`'8õ¥éÛš'nŸžÆ—ð?J\{O®)~‚޽A˜ZRsƒÒ—𦶠œúsÅ"·»ÛÏÝ>õ8Ȫֈ#‹j£’r~µgŸlûÓ{‘LÙ,8ì)íŸ-¶œz‡j‹€B·¥LÇ*~\œt¤ÀŽÇvé`ÆÕóÖ¥aš„’€ªIcÉÈ©ù *ª §gÛ~9¥ Bw£œõ?•ð.(8÷4c>‡ð¨Ydó‚„c€Gó©»Ô^PÞÌY¾nÀñBè7ùK¼ nû'ãLjçê œ¢“>”¿¥Ç­ ŸzB3K‘Ú“é@qÛ¹éIœuÉ c9 çüŠ6û~”;9ÏphGùâŒZN}E;ÐïŸÊƒŒòir:fÏ Nÿ:_ÂlRãé@„ö£§p QŒPõ?•9ïGÓŸÆŽÜàþ4~"Ž1É£Š:í"€ -qG×ùÐ2|À6©ò ÒÈZ8± ç½5ŠÌå72•<ž™§M€ –eõ^ô ”@'¢¹Ç’Ä.â;S×G'ñ¨geÜ{+‘ŽôÐGþ­xÛÇ¥; Ž5œ‘³‘ÜŽµ2á”ÄPÁ‘J­ÆÐ§æç#5/Ëôü*9aó°ÁÏš÷Iì>™£pêÆñÑ´g4òÐ.Iǽ. =úQ‘K@„àqÒóÒŽ{Q|P0ô&އ¥ô4¿çŠ?ýTGÿZŽAïF(9Ç\QÛÖŒwÆisŽÔŸ£4rOQŠ? 3ŽÇéFO§éKÛ)9õý(gó£4qØÒ(¸ÇlÒýi8£ ç'ùÐ0⌌ô¤ãä SÓ>”ÏUüh¥Ÿï'N‡úQHŒûQ’;QÏBi*DâW'ŒÐ€ã £qíÇá@Ã9£n8þF˜¸¤+ÜRçð ŸÇñ ü)xõ£òüé?@ õü¨ú ÑIÇç@ ~†ŽÙé@ö?Ö—­'4¸ü r?ýTcÞŠ3GÒ€õý(>Ý}éNi9öÅ&=©{qúQÇsG´dzøRçµöÇã@ Ío¥Æ—ýj3ïøÒtêqKü©{P~9£ñ£Žý¨àwÅϽˆ¤ÅþªZ9ÇLRäzÐdcühÎzRÒ~žhÇ¿åF(ǯ4güâ“Rõõ£ŸJ1Žô´›FzŸÆ€ŽÔG¥ÁíG4œþ¸£9¥4PqF¥.E'àhǨëF3Iz^(ãýª?øRÐu£·Z(Æ:PìH£ñ£·øÑŒPŒw£ÖŒsÖŒzšL{ÒýéA÷ ŸQ@ Ÿ¯åKÖŽqéIŒŽ†€;š?:1Z\{šŠN; \Š3š~•/åŠ9õ&8ïøÑ·Š}qG4)8õÏáKƒÚ”ë@1ŠLÚ”ý)yúPQ‘KƒI@qØRãÞŠ!擟ÿ].hÍú⌓HAö£Ô¸¤éÿë¥Àïüèǽýi)r:u¤&€–ŒCA'éI×Ö†Gn¿J†ãÉ { Ÿë“QÌ7BË»nGZlWœŒw©H£·B€¾ì¸©9=è{ƒ ÝþG˜Ýô©ˆÈ#4ÆÎþXô©1ÇZ‚ °ÜíÏñ |Ê G.W=é æCÏðv©N÷íšÛ¯îW'8sR…#¥6<ªç-ŽHþ=  v£ëšQô¢ThÏjN3ÔþT¹4^æU@™&[¿z™ (_§"£¸Vt_‘XÏÍR&퀞? }Ð\ûŸÀT|ÚÈ…©ÃÒ§ÁÇ\ÔW!ͼ‚0¥ñò†éš@,Dùcsn8ê)û°~òý 6 BüÛAîÍ?ŠàÈ",flÈcSàO FiuÌ{ñž8©˜…˜â€c±îhã×ò¦ƒžAý)s޽(¼zÑõþTg·4PG”nÀÎx àÑǦ3žâŠ3Ž‚‚ê);÷úP1¾ŸQKÈíH4>¢ŒâŽ;f€9êhg׊N½ãKÓ¾Mǯå@öÍŽßöÏãGç šØü(ÁÏAEÔc=… f޽ñ@ À¤QŠ(íÿ֤ϯ¼öŒŸz2jLŸJ8Ï|Òþ™íŒ})ˆCƒƒëŠ^=)àð?‚Ô, _¹Å-—À´"–ؘtT<à/JIÜlT-êÔú•Ô›<j¨æc3ìy/z¶9PjGE¸Û·‚¡c¹ÚDòøãZWW”© Ò0ܤ`þ5 ªºÆÁÓoÌqžsFàLÀ• ý*˜Žàm\)Y¿ýUpOåGÌJ°\¯jf2Je`7É·®*ÖyäU[õ²bNz–ÎjÇýj0ÞœsŠwqú¡0le­‘Á~üb®*áFíÖ†‚Ã.w²¬Púã5.·¶Ý›3Çj–â2éÉÏÖ¤@vŒŒ{QpDÒN‘F·e|Óœã¥Y<©Áõ5^â"Î $0{Ô¸;x\PÀlŽìȯƒÔ .¬Eƒ*Î[¥2Þ6FrUA'œ1©&VhʪÏbqCܰc ]I<ä “#Û?JŽ DaYB‘Æ:Ôœôô¡ƒØÅ™£§^¿J^OzB*Êò „U*ƒœžÿJhK¶Hñqü4ù# uCÌGOƬ`ÒªöEŒüª9KnP¥G±©;p?*†eË£ˆ‹‘ïŒRBDË÷{ùTJÌflȽz ”Æ B…ÁeQµÌsÒ’>còg~1ëUžFüÉíù^j{„fˆª “ äŠdŠå (WoBzhh’*¬YÃn9Õ7ozjç·îE&&-'ÒŽž™£üô þ?•…£ŸÿU­ûf~t¹ô€ ç¥úà}i3A#¸ ÝïIŸ|Ñ{Róí@ÄàžÔd}h wæŒpx B€1KøQIþy £ñ¦ãÛ\Ñ@Åãך3íùQÈö¢€»ëK×Óó¥£é@î+øÑNŸ;£Î:éE ÈíÍ8è)¡G¦)rÒ€·@>´½=? nIç¹¥ãÜSuïŠ\tæ“ ö¤È½;×ó¤<qøÒçñ40hÝž£>Ãó¤—ñ èœt¥ãQøPdƒ@cÏ~”™ô Î{QÆ9üóHOµö ö ’;~”™ç©Å;Œõ bvô zñùRò=?:Ný§_åG#©¤þZ3þM/9£§l}(Î>”œ_ÀБÛ?…/ãGéFzf‰ÐqK{Š('¡ A‘Ž£éFsÓõ¥íÖ€êEºÑÆ9 èh>ôt¤8'½/áúÐq×®)rFyãéA£‚h2}risÇ”êJLû€}èüEÏoΑœ½.r8e4¿•7Ž£š^"€ ŽäQŽã§Ò—¿JNô¿‘¤ÎúÆ—ëKšh±Kl~4dzQÓ¦hú~tgi0:â”p(Éì(ç¯éFE{Ð×ÞŽ=hÇ(ý~”™ö´síFáœ`ÐøQFsíE•{QŠ;Ðþ4vëùÑŨ(þt:2=hÏ®ix¤üi3ÏOƀǥñÚ“>ÔgÚ€ ÑŸjåGã@FhÁÿ"ŠNŸ•—åGähÜ>”g=A ÇÒ—ò£Œu£#4Ÿ7µ4¹3I׊ç?ÎŒãÒ—PpzÑÓÓó£=èã¹sø{Pxë­÷ñ£í@E8ÿëQšZLúcëGZ3íÅsÔc>ô~4~tvíš(ÏœŽ”¹ü(Ï¡âŠ{‘I…Æzý -R !Ú;}9£#¥/¨Æ{ LØûRãë@qÖŽON)3Ž¢—©é@ö?…÷”¢“ ÷ÑÏÿZ—¨é@ßQG¶y¦àsš] ú /ÐÑϯäi0{š(*3ÛšnÔ‡µ.@éÒŒú3ÛPÎzŒÔ7JÆÚ@£$Œb¦ÿø¨­ò`BÄFsRã({ƒëüéyô£ŸjLØ "“<õ¥Ï8¢€+Ü„!K?7`MJœ Á8=jŠè¾ÄÚû~a×½J„ì–úAø÷ª÷‡ýòãÔç‘ÀÅG;ì…›zÒ P©À y©3ǵE*¤Èåòr;â¦ïP÷T„o»yö©.ß˶'c¹'.¥$aÉ}àŒt¦™¶F[ ½MƒÄc ‚{m"¥õ¨¡Ý´çØ5'ÑN}©0bþ<{Ñǯä( ûRq@?)$ÏfˆŸ,¤ß>{c x'Š¥$ŽŠ#k…Ë“‚¤gÐÑqXÕG `Ó¿ ÓPáø¸ëKŸ¯áHBàwQņhÏá@€qúQŸ­‡åGæhg<ŸÂ—ëùRsê:0({zQ;ÒQïÚ þx¤ÉÏOÖŽ†Ž(ï×uïG$Ró@­c4cýª2i2hÉ£9 $úÑ¿ýz3íIǶ}èsžô™÷£§ÿZŠ:ô"™#dcµ<çÓõ¤äúP`tÇ#,§ŒAjs͵etYŒ ¸ÚGâjþÁÀ ŠdÎb\«sèMUîUÅ·¹\gžpjE7ÎĶ@ãæ«#sI¨|ÆûYr2<Ò¾¡Ô•‰ œöªÖ+”fã–="­cƒÀ¨ 2í n;@ô£ ‰¾£5 ×ü{¶ /W­K‘ê1PÜ4‹îÊû–¤!ðÑóøJ~b "ð=)yèúæ†6P‘£ù‹—P[ŒäÕÔ"ã;ÓeL¨á3œœñO\•Éý)Ünñäà–?ÂjT@>l}i—A0ߥ:=û$gڎЭr"‰Ö]’;€'Š´(01Ò¡¹i£ÁC^ûªÀ/\ÑÐ:[€CaHç½-ÐO³å±þÎi Ê—3Æ‚ öâ ¸eB®X†è1ÉüXê9ÅE(“r”Û׊à‰Ӹ¨@™ˆ-‚OÆ*pxÔQù¾|…›(OÊ8¡å­Ù8`AÀ¦ºÄ¶E[pLuš–`æ"# 7jXÔ˜€|Žhƒ`)åü¥ˆ÷5(´ cë@‚—qàoÒ†¤ nÎ;w sÅ(÷ ˜ öÈ4Ä;ñâŽ=©£ƒÐÓ»zPÛ°£ÿ:8ÆAÞŒƒÒ€tÆhÇZ_ÄQϨ Ç¥Ž€Q‚{Òàñý(Ï©ƒëN4ÒêEަŽhàŽ¿¥&TªÖ€üõ¥Æ{~t™”`ã‘@ ´z ÑJN}¿_Æ€ðþ”¢Ž>ŸZ0q@GÒ§?…Ô~?­ç­'â~”¼ã€3F¯•{¥Ü~Tc”~€hëÛô¤â—=³@(ÅÈëš(è1ÍÑŸLÐÇ­›ŽJ?*1AüÑÇz_  £¯½i>‡ô §túý(ÏÖ” AíF? 1øQ‘ëšN¹É4cßšZ\sÖ€|Ñ‚}…;ñ¤#ž´síGâ(éÖŒJ0OCF·áAæŽ}¨¿(< f–—¯q@怩?`zÑÿêdù£¤Rqë@ùâ“×ùRàu¢€ó£ÿ/ãIŸz:t R?8î(Î=÷¨ {?J8ü>´qØ‚~´­r>´œú ^)qïIƀƎ½óøÒþT˜´dÿ“Iß¼ÐþsGáEÊ€õÀ£=(Î=)~´sF ïGoJ7z 84 \}(8¥ÿØ£õ  tgØÑøQõ£òÅ~t`þôb€Ì)•ûš(玔~´QÅÊ?G´d{£pGÖz1ž¹ ÁïKƒïøÑÓ½'èsë@ }È™ÇZHýhÔ¢¨Í'ãŠC@ ר¥çéH9Š2p(ühÝŽ¼ÒŒv¤Éì?J3žÔQÉ£œsÊ€ lÑŒzb‚\fŒPž:ÒdS¨ ühϵJ3ŸOÀÐIî)8ö¥éïG^¢€žÞôœéFì(öë@1éG#Þ€qž(ÝéùPÉïùÑKßš01Þ€ÏJQÇðŸÎ—‘ÿê£Û8 žâŽ}¨¤ééÏ­/>Ô÷üiϧҌcÛé@Ã>™4Gñ4r;ñïFHïúP ù±Ïó£>ô¹½w Ç¿ëF9éøæ—­'>”sïG1øRsêiÿgŽ}³IÇBÔp)^{sFEÜQ)ŒOËóÅG8"?)ãø¹) óœûbšè²!VÎ |¥àtíÒŸ’}¿EPªv¾Ô1N<²$Dɹ8¦4·a³!†9ÉÀ« uîDZÅDÖÊÜ.:n¦2H£TBDH¥¹`½Í<àŒàÓQv(PN­;¨¤b÷ $Ѝ6cä©mZv·C:…õ†‹qÉfJtiå \±Çr9§} ü‘ÐøÐO­'âƒ=¸£èE0Ç‚q@Ê÷y‡`c¼uÅL¿w $ˆ]@—µ9N?S@çPÝäÚI¶1'Ê~RØÏãSõçÉ£ó"+’  „7”o7gó‘ØQ[.IÇz^zãe?-ã¾2ª ž^8óQ´ÓÈþSÛf&—cßÒ­ËJIbØ#¥1­Cå´Œ?Â*“]GrdP  :Sþ´B¨QÀRãëRÄ&:áT}ixö}y â@Æ Œ…-!C¹É9ÅMÖŽý?*(Q‚{QÛM®héëIÉ¥Ûí@ ô84cœfŠL; iy>ŸJoÐ ^žÔ¿ç­!ú惞À~4œ‘@ >´½1IøRÿ*3Í&}2ixìqEõ£ò£µLs@ Æy"—ð£Ÿz2=èÀôÍ…éùÑ@ “Û4¹j;dŒRpzƒøÐÎ}}ÅŽß•ã­&>¦€ ÿ{µE(ù†"fr*\:~u±¬¸t9ûÄP4?9Œ~5 ØŒ4ÑÄ^LcÔçhëŸË4Ùz©õP"²ÜÈòùo(àdÜU„‰c\(8Ïv&£òr²Îã,89>1M±±²«0\àtjU¸ʸ8õ"¬cëMDe-óäƒÒ =©{ýáš\gð£z@q34oŸ¼O¦ééMT!ŽÁíŠvOÊãÞ0@ÇÖ¡fxÜ(Šç°©ðGALò›~ï9ÀÏÝÀÅ4hT™C4x=>n K@)"B‹‚Äýiç׊2­Âé'“½È#Tjæpï‰ _¼8Û=j̰™J•r…Nxï@Œ‰·ïÈÛ¤PžrLJ1Žÿ­§JQô¤ çÔQ×µŠN´V|,àˆ]ßi ƒ…üiEÑò•ŒL¿Ôƒ©ìE!…Îq+dþ•WV(X§óKƒ.ÓŒžô²…ǘrJƒÀ¡Ë$ޤ÷§º–R:)z¬·„ÈBvmÈ9çò§Â3>Ò =ûR¬.Š©æ6­HªËÌ[ž=©¶ºã'`# £0 ƒŒñNˆ€¸àSK)Ç@î u©BXÂùHË–=º °¾Ø÷¨äFl#ƒÒ¤ ÇݦŸOéIÈéJ3ØQ“ÇzB9ôÍöó£¢Ê€9£ôÏ\Py=â)23Šv>´PsŽçKœ QÍúPÜ:9ô.qÅ&yäPŒúþtt¢Œ“ÆÑßÖƒÇjLžÂ€ÞŽ1œb“'ð¥þt N=F)pzñF=)0=(ŽdN{éE,ùÜ¿CE ÇÔÒ‚;ãò£#ÓŠ_Oð (ɤ7•ÚA¥ëõ÷¥Ààãšb>ŸZ0}¿9=GëQÈÒymå`68Ï4 —P:¨’\åw¨Ã›â•„î ¬Ê<àf‚ŬcÛñ¥é֪ķ^i2òùúÕœûŠLÏÆiM7¿­ö_­'SŒRŸÆ¢ÝcÊ€N{и=†?N@ç?ΔÂŒÐÒ“Œä^€Pø~TŸL~t§Ò£—&6À6:š–“Z¨ÆðJžR)n cƒŸÊ“máv!Î~ñÇZ«yŽÅÎ}3KLF.A{\Ó5"Ú“éŠ1ÞŽ{0{ ;t`c¥{Pqß9¥Ò޼8õ4QùÓ$gT&4ÜÞ•R]0PÑ*yçµ4®;°Z:w¢—ñæ„ëÐÐxêi{Ðsô Ÿ­8â“íŠ\ÅöæÂ“ñ£ùP‘ÅÚNßãKŽ(:{P:õ¥âŠ0GNi?OÆ †IžFÞ.8ÛëSíE†/4Qš=¨síIÈíŸÆ˜Yüð»FÌu©:P1(Êç¶iOÖÄÐ!(ÁëKIÆsÈühGáIhäñõ¥9 ü³Gà(9úQœs@:~”v£"ÀÐÏÿ®Ž}üóK@ üèüè&ƒš3Žô¼vëMÉçƒKϽ/lÒn§åHq× Ÿ­/8äb€ðÅÞ“ðgé@?ç½-&÷¥ $ŽÙ¥ÎG#fŽÜPíš3íIßµÇa@}?Z^})9íŠ2}@4 QŸj\f“ŸZ(i:PÖŽ~”9ÿ&¡¹’Hàc †“(-ŒÕ®5·ŒÉlË!^™^~¾”Ôn;¹ö4µI&¹.wÂQAÀ,G?­[Î(jÁazQšÌ7W¬$há_/¢¤ûã4õ¹½VaÈÇÏÇÿ^Ÿ(XÐü?3øý*(]ÝrãiÉÀÍIǵH Éì?:??ΓŒqÒ¡çÚ ëG¨ô¦îäN¢€×®)¬À äÔQ¼ŒÛdŒ/\ õ÷©AÀǰ b©Ü€’E;'ÀÅG4¾TlÈ›˜v—J1õ¦«dr0i{v ò ôÿëQF¥=hϵ÷£€>Ԝ֎(ì(ã·4™4¸Ç|}i2:怓éGn´*(ü ù掴c¶hü?*8£q@ II\f—ŸQš;QÐt¤$Òã<÷ üàÒqߌwþt¹ Ûš]£ÒŽxȤÇ=(HÏ­J0?úÙ¤ÏÊ€ }(ϦÒäý(ϯ4}ÏtëøÐõ¦’8Å/ËïKÛŒ CÔ‘õ£ÏZ^; ÑŸA@áF=é1è@4¿•&H÷g׊Z0h2=ir;š3ÚŒqÒ€õ¥ãÿ:Nžß/~ß•!`=)r}ñGN”‡`(ëÅ?‹š4cÛë@À“ô¤Áõ¥üiÏ|Ð ÇûT€ñƒ‚}©GOCíGÍ@=ó@ÏáJ=Íù àw4¼ûQÅ! ûÒ`R‘ž”¸ PmïÞ”çÓðƒ¥NEg1_¡4›‡©úQÎxÎi \äñAÆzûÒ~$QÏJbþRsG?…Z6’zò=(çØÐÏ¥S@ÅÁéÞŒSIþµ.éùP ã’i=öŸÎŒaFÞsÅÏðš^}¨Àô£+Ð~”O¨4qïùÒ“éÖ“éÖ€r03øÑÔž´dôæ—ZLñIþsšwÿ¯FOnE&=¿Z1žHühïÈQ’Oñ4¹õúQÇ~?>j>nãZ21ÐâŽ:bŽ(ãÖ€Ãõ¢—§ÖŒûPG„ÑŸq@^1úÒòΓ&ÄГéJ3éI‘Ó4£žØö éÍZ^~´`Pcœãš_­…¨3ÓñÍ'ËéùÓ¾¦{Pלcñ¦óß÷§`惚1ÐP0Fx {¨óÞ€ñùbŒ{ŒÐï± N;U…üd ’^le =hÇ¡ªÂõ]]£Vm†« Ù@Ý>´ìnzуéP” Êò§“S#‡PÀ‚JVyîqFb¡¸»ŽÛ@yïŽ*ÔÑçX„.2OÌÊi6.‘ÜŠ1Þ€O^*»ßDŒ“¸œ` V¸X°÷£ÔQº—& ž8É£“FsÚ‘Ü"'§¥/¿J:÷üj¼—Ĺ#wlS£nd* Ž¡Z|¬ve¿ÄRóPÍ:ÅJQ˜(ÎÑÔÔfþ5ò¾Y3&0çZ,ÂÅž=h+‘ßóªâö.rN*À`G"‹0°`c¦öãÜÐ~¸úŠd²Ç m$Œ0£4„<ýi?Z¬u+U º@»º´èï`žFDlíêpiò±Ù“÷¥ç¿TßÂ#. Çl÷§¥Ôo8‰wnÆzQfdø£¾)’È#‰œžF÷JžXËúœRJábÁ÷ý)3éÍCç¡™£?Â3Éþ”è¥I—rž3E€nJ^ gÆŒg¥ÇQŠ;~fŽ=(éOj8'ƒš1Š;u4½=èÏÖ€Ã4qÅëÍqIÛ £$ñÒ”t šL}i~´qÒ€ J0{óAÓšN{Æ€@<Š:óœÒöèN}© :ý>´¼u¤‚¦")¾òý ²ýôúéE!€Éæ”qïH?Nc˜ ÏÒ“þþ4¹ãÖ“žù\qÓ4“Üþ4óÅ)b¢‹˜AÏ­=±‚O㊆ßäe0-Û¨¦†‰Æ=yô¤•ž5Ê¡cž€Ó±éŸÊªI‡ºÙö‡^ÛÒ’W=.¤uba‘}/Z ÄÛâ3†ûăÅXÈõ?EpT'Íœ}3M —'ÅTiÙáv’'Pn°~µb¦$ØN1ÇÔ‰`ÈÛ{Œæ…¸¹"m‹„c9Ô°ËçG» ¼ã 1N` ¼zŽ)N¿áÚ‹¡Æ:ŒLûƒHžvñKÇcHA“Ó¨.ƒˆ XúTùþ/Ê¡¹G‘é@ÇD–»²úÔ„ sÏÖ«$ñ„DgÝòòÅ…4ÞÄpF'8psÏZm1Ø}²m,<¥EíÉ4Ù¦¹I•b·˜ùŽâ?*|Iw>ñÛ#´¥çyå€8Û·§Ô%ÝØ‹sÛåú.x•Oò4ì¯ÕÆAÅMžÝj­Ë2N‡Îu ´(?þª.Ÿ@б4­‚°ïLŠàÉ‚c*Lõ¦Ü±]„’<àS.dU²Ý溩 £&„´ ×íä³$$°l`äcëÅ\VÜ3‚*8˜ù#œŒç5„Žðngwäò†€µ#RUKÚ †êW Ý“É$b¬d¤Õ@ä]>.’Ð:u¤„‹‚‘¾PNÌãÒŒûfªß:¬j<ÿ+9çŸéI+€Ï풬ČôSŠÞ±8H$=¹éš™#@°ÀÁ<æœsƒƒƒôªºì=J‚x=ÅVšðÂäy;…ÎimÒhãÄÒ‰×n)¶ÒwPîÛx9iXo×÷{âu2t⤂é'y€àŠ“8ª·¢â$ó|“œã€Zš³ w4‡ÖÎÅI!Ÿ­.xäþ´Rž¸üh´í‰€QÙQ-àŠá"(ÇvyT*%šWT¹^@ Gÿ®®F¬¨Íݪ½Jo9™Š2aˆÃqŸqN¸”ÛÀÒ.W òj+yg,$€‘Óš²ûþ4˜™DJZ壙7.vîÊœ/†9<§ù›i”ö-öµA0UÇ)·9üjÀUcô¢êÛ \ñßò£:Ñø~´¸4‰Ôd÷£¯cGãÆ€5NEÀËb6ä°Ÿù¥ÎsÁœã¹ ‘Jsê)2}0)}±Å'ãÏÖ‚)p}…(½? £sîiÞø4PAã$Ò’ih?•ÑGO_­± ïÒ–ŽÔp:ÐÏ­&G·çG—"€§<ý/&N}½hç±?•.ßj>”‡#ž :Š >¼ÑÔqÅ&NpÐK•Ifˆ6àU²6“Í[ÇëU®LÁãt`¨§æÈ¤mBݶâÀ÷\UfÖƒè:÷k[Ë+åŸZ{€°–×½2yckmù7BFiå Ú†õ"ÂÛo»Ëî?Â¥$«ÅS‚å#ÖY2cë…#ÿ×S­Ô-³>a‘ž3M§phe¸BÅÃÈpHÁbEYëëUàc'Î “÷;ÔùÆ3ŸÊ“ôqëúÒgëK¯4„&?ÚÍS:jgóåÜ{“WzRqBvNÚ(üíømÉ•n£Žj÷oJ© ™³(` •kŒb›!l)=p3ÖªZ«K+\yµÀÄg §Ü9ù1ÊRA‚p;P. O’I88=¨H OΗüñPÇu ’©"±ddTÙu¥aüGN9ZB>¤Rãüâ€}ER? ?_¦ '§§¹¤üZ\¥õ4ž™£$öÅ;ŠJ0OP(ééùÑR 0;PÉôüèíF§çF}ýÍi:öýiԘǠÔsê?:1ø} &ÿ®‚Q@ óšO ¥ÅúÐÉëF¥Å}>´Þiy£ã`zþTc¹}(ãµ{P×Ú“ŸZ\JôÍžâ téõ¥#4PƒíFÿªŒ 3ØùÐþzÑ×ÿ×G^ßÖ“'°üM¿ˆÅ1Æ(ã§'ð úIÏ®>”cëF=Oç@çÔÒb”ÑÛŒ}hsŠ1î3Iœõæ—4;óüèéÓ“9ãp:sô 4œç¨£ð£¨äs@ÅÏ¿ëG_J})9úûÐ!*LÒþÒH c¹ê)9öüé=ÿ•ŸÿU¿øPsê3Iì=Á¤Ç³@ ózñFqÔŠ1è(Æ=á@hϧÔQLR@ÎV€v;Rtô¥Áöü)@úŸ­‘Žô¼žÈ÷ëK€JÞ(œâš—ùühÛí@ ?¥ãµ.=±Fÿª‡åGÒ€=Î ózÑÉôüéqKŒúÒ¼úš_¥çŠw¦øf€Gr?:N:sKϽç¤Ç¥/4¸=ñ@ Ô¼žâ—ñ½/AƒIžx­ç•£¯L ?Öß­cÜÆ€sÿë¤À¤üirÇÒ€ Qœú~tgèh={PÎ:âÇCKƒÜšLž”`÷Æhüÿ :ô£é@Ó4~tqŒrhú΀?ýt}z}h'ñFGlP×Ûñ¥üi:ž´¸8Å÷ýhÈ÷üé0}9hÈ#±üsFGLÎN}èÎ=èzûRr£¯­.;PqžüzSʉw ARóíQI»~ B;ô$­:4n‚üàw§Ë*Ę)Ç÷>¢«Ê<éULLÈwÒ­…¦ö0ëϽG:î…”íä"¥ãx¦JŠb`T‘ŽqHDQ[¯’ŠËJ¨aZlòÔmdô ÔÔ™søScd&ýÛŠ°ö,„ª’1ŸzŽ¡ØÛÚ3~í°‚L»C6mßfcò“ŽçŠTdŠ3"#‘Êž¸¤—ÑØ¡¹ `OùÍ%-Ÿå@ ÉöúÒàúþ´˜õzÒazþ´§ÔQŒQŠŽÝJ†ãnåÏ\(›’¿CE 0NïéF;æíŒ ^xì(@ã¥&=?Z8õ'ð û☀`žqšR?ɤÉþð¤çGç@Å,zc­C bI*j—qÛÏ5^ÝG™3,eAn§½c z“ù‘Q™™T(#¯5?w5Nb È »ddƒÀ÷¦·\éß…E0|¥p>ðnõ/=ê –;ULEÕ¸”¹>ô€)xÇÿ^“žÄÑÎrIü¨sǨn û;ì ¸âéRäúš†à%ŽÂøíŠTU1¡*¶»PÆ“$¤Ê#öÚ1ô«1“å®T©#¡ëU¯UYZ'vÈ\ '½Rz©o¿™¬ý·`Íå3»§ùñW"c$JXÏlb µŠ4–_,0Ëdî¡h?Ó·¨ÝÜrzlkx[÷±ÆàtÉ«Øã5]îDw>W“!È8\Š9¯Ð.,æ@Bç’‹ƒ¶ÐýÌ:ŒŠmÏ—˜ÑÔ’Ä€Å,‹V ¶ÐÛœ]•1©éÔt¨íX4YWSÏ;F=òÇÞÅGjP¦P¿R>ni÷ÇQëUþdœ—*7·8«U5òÍÛ ó1üi!"àÇcQÍ’&žÛ†jLóPÜL`PBç>Äÿ*H3|Ò(تƒþ½¼XNY]÷}8«Šr ö#½6BDlv“ì9ÍW0îÈ+=›5L›Ï?÷Q[ñ÷˜7ÌGåRYykkû¥ls÷—–×cå×r¹0ÏJ{0Øhkì͹8ùù4£í `,#ïf­cÔ¶>µ ³ˆæŠ0¬K’3RžºÉùõ?÷£œu4¹>”„Rz^ôzó@ŠÐãÏqû¼àd‚~µcœsš¯Ó36Æ ·“Ú§ÝïM•í¤”»#À±OÜlÕƒžõVÙ£iNÅ#$ç'§J·C@w•Ä F>ù#"¬}¾µP¼FõTÊwàá­Zõ¡ì \œsFy¤$ö¼Ò€“éš3žrÂŽñKÈ £3Æ“™Æò2<⟓ÏOʪK$Fð!Ì œ{SJìh´²,ƒr‘øÓ³U¬¼£l , r0•X ÛŠŒ¹?'n .1F}zÒ„ûgè(ÐäÒóØÒóÜÊ€ç4wíùÑ×­së@ Øò)GLQøš^hëÅ&1ÒŽ¨éü4¹>”yÉüèê©¥ü?Nhçüš_ÆŽ½èüh£ñ¤ÀPþTqIúÑÈé¥ : 3‘Óò¤© Ç¡Å.;f—è3KÏjo=8ü Ÿð4ìú*#¦(’F²)YH=F3P›C´}š/—§È*Æ@ã5ÄË +oeQÈQ“Nìd22}¡mÖÜ4XÉ  Õ‡;c$(éÇlT6¡UK¤ŽCpÔë¦D·räà‚3šÄ‚åæHÀvûÄcšq¶‰˜1@HéL³U[TÚFÜzæ¬gÞ›nâ{ÀxòÕÐç5>}?V· ¸˜˜ã'>™«<÷aøR`Êí,Ë#™ÂiÐ;ȧÌP„qÃTw6ñffl¯<–Ü&ÍÉÆîO½X:cúæ—“ØR sŒ“Iyɤ"¬ Í1r@È8ü*ÏJ§Ç,Û‘\¨ÏÍFxô«|㩪cd]óÝ·!Ž2jF·‰É-6}TŽFC:¡,_¼ ³ŠW¬±¥¸$n,r­®qÈÅU»ò¾A&OÌ#=êÐ'í@OQ@ ޤýhÝþqKœö4„téK‘IÞ€ tëšZCé“G~y ü(¤üè÷dfŒçÚ—­…&j9ÅÇ© d÷â€héÓ4½:šLæ€G\š\Š:Q@Ö`)3Û"Œq@ 8œ{š\;怑Ü~td÷â—èh:j^}çIß%Ò€ýÇÖ“œÿõ©N÷üÍ'lOã@ú~f—8õ£éœP_ÀÑÚHG|f€ÐQøþ´p)8ìh¸>´¸4Üç§J;pOÖŠO±¤üy¥'§éFN9Î(„zµ¥Œ}E&õ4;â”géï@ ÇÿZŒÆ)yϵ&:Ð’;~tqêi:Þ—'8? gž´˜÷4¹ç£~TO$cêh™ÿëPF{S¿JNhcÚÇŠ_ÄþTŸêx¥ç¨Æ>”gÒ—>ü}(˜£°¥üèǽ&=è+ǧÔÒãëI·ÜР挑J4qßš1éŸÆóš0; 3ï@àhÇ®M¥ b~œÒœö¤ŽÙúPsÐS³ž‡Š>aß@'Ê{Räû~t(üHÀ=…¯#õ¥çÖ“µ3õ£­õm¥ü):ÐŒt çÓõ£Š\c±üè(çÒƒîM'qÍ·4lö•.O¡£œzP!Žãô£Ž”`Qߊ:qŒ~4`§¥Š8ýjLãŒóéKÔtýhÇ¿á@:œS±á4cÚŒN. ÏZLc¹4£Æ1I;~B‚xû´~Ïcõ4¼ö{uö¤uçèhúÓ¿ N©Éäþ´§è £ Çò 8ÏáF1È Óüh4œãœP=ð(ǵûRI"D¥°=éWd( <–fˆÈWÁ¦— [¢á‡#®*Yrˆ}§Ö¢9hca?ÊY±ŒŠhhPl( Ž•­æBbB¿xLŒ» ¸ûÙÍF¹y¼Å“¨@ˆê) }ƒ9'¡Æ1RM¢yŸ¼%;)ëNŒ2Ês&ì’qš|åÌ-±ü¶Ç {Qp!vWHd)&IìZªêd1DUÃ|ÌÝêu9QógÞ†6CÃrÄ£‡n= NΪ2MAé. ‹(1‚«ƒÍI*Êc>[ÝŽ3@€\F[nyìz~sÆ*¿ïZd+€ïñV©¡ƒ`€~5 Ø á‰Ï8ÅOÔu¨n?Õñ ÷4€|j¡ÜóêÙ¢LÛv@ÁÎ)W,¹Î쎣½2Q(Û±öŒòÏËO,Æ0ÁO@FåSœ­65]ƒjŒS¹Æi°aÏ üj ­m ‘Ê®:®xüª|qƒM”-•[i#ƒÖþȳ¤mçÌ ¬FjÜq˜ãYÛØäÒÇ•@ %€çŠvr9È4Ø2—–¬X$Ž¸äœšu«¬äÊ¢E=0ýýêXL€íwSŽã“AÞ·šU‘2iŒK‘¶ÞXQÖ‘ ŽhámÏû¾™ïRK“ÀÈõ¥ˆ1‰CãHBˆgiC6Hû½ªNE søÒäRphþt˜ü¨ÆOJ8=Åö ÛhÆ{þT9ôüèÏ=Z=ˆúRmõ ~4˜>”cb€óÖ“óš8ŒŸÆ“;{е'N3“éKŸSIœŒPíKŠL{âŽG®=CGãG¿?J9 ¸£ZNºhÈ<â€"œò¿CEòËô4Rî;çéM<ò“øÓ¹ÃøÓºwâ€?.Nxý)GLŽsÞŽ;f©Í1}FhÈü=èÈÇøRÀhNê*8–D,d—~Ot'HÏáG¾Ó@sÛó5ñÉ,DG'–Ç£/5.©›Î(ªÚÜ,hxîGV`9ý*Q—÷Ĩê1Š—w<ÒÓæc¸£>Ô‡q\}h÷<ÑÇÊŠ±%Ø^x?ÂJ·ƒŽ™úR ¸ÆÏlQÉã‘ô¢ã¸¸ç84tìhÆ:æ¦MØTr§›&ìn§õ }Eç¯?Jlk±g8¥ cJGŽ~´ÀÎ( ²îÞåò1ƒI,Rù¡’mŠÝÛScÖÂÂå1krcíïݽjhâ™gwi÷) ·§ãSsïøRñøÑv ¹ŽY£Är`8<ðiÅdû2§š € ±îj^ƒ¹ühÁô¤C;Ž}=©–ñ¼QívVúSñÜ~”}0G½ Œ™f.†'Ú üÃÖ¢)rÌùeÈ?'µYü(úþî!†)П6}Ã=1Sv;XK“ß…½A¤ÝÀ¨mïLn¿i ÌÙ ;Gâ)Þ]Örg GðëVH$t£tâÂà ª€q‘éPKæBÑNá* Oø 8ôÍ *47†hȸPŠy\uý*x„ÂI Œ¥sòã­?ê3N qÓNiÝ…ÅÝÅöüé3ퟭ„ÿ³Š:ôÅ-¦pMB‘È'wgÊ‘€£µJsGàhsƒ@A¨pÎrN1SàƒŒñF¥ãÒ‹ŒŠXÙ˜2÷ôÜG8¦D“¬Ÿ¼teÀç¹59ÀëF{Zw@4cž†šx è?)viÒf“>ÿ¥;·&››=iyõÍ÷Šª \@)zô"‚~¢ŒœPŸoÊÀb–“€ñ£·_¥!õc4´~Ž1Š &:Ñǵ/Ò“ž¹ ŸSK“IôþTóÅ/>ƒñ¤'=ÇÖ¦(9ö }sGÒƒèhÀíŠ\¯ÒŽ:€)¹ÉãdçúгéŠ)9'¿O­/åF=ÍüPâçÐ~&Ç'Ú€E'¥&OÒIŸ\P}j¼‰pgB¾P‡û³œUŒIœöj]§Û“—8íúQÅV\(-ƒ÷6±ýx¥Ùt |èp>f5`9ôî;Á$x“$Ÿ—¥L1ÚŒãµ&yû´˜•œÍÉA==GåRãhjС¥ã¡ C}Wjªâð |µLÿÍ×ü*áö~t›}å@Ê‘ÇpŽ9PyP:ŸÊ¤S>TîB?‹$ñSm?ˆ¥òýéóÆ8vLëP7Û±Ç霑VB©”vöúQ@ Ï¥ŸÊŽ=E)Ïz@oÒŒ 3@Àý(Í&sÐâ—žæ€9éF=/ãšN(˜?ÞÇÒ€8?.qÛ?r=èãÚ“8è!KÇ·à)3ÔÏz\ôã4½i¼žß‘£Ž˜÷ qG=ˆ¤…9àš?_ëGãFè(3Û‘KKŠ(ÜsÆEÿdf—ƒ@ ƒß €zŒÑÍ/ãøP~R`ÿt~&G=è8<3íF¯¹>Æ“'üŠ9é9õ4§ê)Æphg× ÷Îi¹ÉäÒþ€4½i7 Q¸Î >ôQ‘ÚŒœu AG?JLžÔ@ Š;R~T¹4 NhëKùÑÎ(ý(íÉüé9î2)>lô Bþtdzйüir}(häQš2Ýñ@ ÛÒŒzæŒÒóè(2sÉ¥¤üç¥-ZLzŸÊ—éšCß­˜£Ÿ_ÒŽ}M=I£¯lQÁÑš>´›E/ùâŽzPc<î4¼úK¥'ãŠ1þÉúŠ@>¿ô§9 søÑZ2{挜ãšôÍŸL¥¹4}i1G=ø£ŸQ@¥æŒc¦(çÖ€óNÒ~bŽ(8÷ éùÒóGÖ€j?)?_Äþ4Qøý(Í'~ ü(¡VÖ¡zG‚0rz÷«÷4˜ühåȧ¯\þtö#Œ©#Ú­ w # y1FÛW¦Oj|Jä.>¦¤ÁÇz9õ4\.Vd19hbR[ŽÔ²4Žv”š±ƒíIóù§p¸Ï- >V b«…kh|›x ¦æàÕ¾sŸéKži\.G B$Ú òIäÿ…°Ž2û èj\ÑϵAK¸¸ äÕ# ÊT‚>”óÓ‘HsÓ&€++˜‰ŒC#þ.9¡ŸÎeŒÆÃ#aüXJ^sùS¸\hqÓÞ£™Ý89È=*m£¯ëFÞ88úRÄQ°Ð†œ;ô~F‰ŠŽe ¹r©9úQÏZG ‰p»F:T„QÉíŠ9=¨ aC‡~œS¤‰\†l’;u©Ç®h=}( H7Û¾èIÀáOz|C0¯É·Žž•!_CŠN@ëùPqKŠo_SGNô^1Þ—üóMÀêICKÏ~E/âh9íH?>”¸ç¯áHqßš2 3@ Áf—Œg$ýhÈõ£¯z(ç 8îqH~¢€§RãH@·åG0áFp8ãë@3A÷? óEqëõ¤8îixïÖ— ìhœçqÚÄþqŽôçæ_¡¢–~«ŸCE!Ž sŽ@¥Ï¹4|ð—ñü…'±úS¸£ýÞ~´Ÿ† Cß¹ QƒÔþ”c§#ñÄúÑŸ­ëŸlP3ëƒô  —Š1þsKŒûšLR(vžÆ“œöÏ­&ÑKìPÜØ£ôçÚ‘ê?*LïPŒQÉãô¸ÇÒŽzgô Ï¥Ï¨ýhçÔQõ9ü(÷£$Š\c½'~s@ ïÏéFà9Ë p,ÒŒ~?JMÞ½}©}ù?Z^{Òmõü À~sëKŒ gÞ¨ býÞÄ})ùÒàã¯æ(ÁõÍ žØüé3K·oSÇ¥(Æ;ÑÇ®hÒí‘@íQÇ¿ãF}zQ‘ê?O¯ó¥ÇpH£#ëAõÀ ØJhÏ¿ä(ç±ý(0{øQøæŽ½sš\ôÇZLö;¿\qžhçÐ(=;Òq×Ñœqü…/^ôœzQÆ})xúÑ×µ'|âŽzàS¸E&=¨ëF=¿Z>„Š{ŠOÀÒƒžŸ•Î(ë@ ÏçKjJQÏ¥Ôcßt¤àôýE;ó¤ÉéŠLã®qíJ¦híF 3õü¨Ýê(gžôd罇¿å@ò ñëKAãé@ Î:“KøÒãéŠ1@ Û¡£qÍïÍ`>”cМPxõ4v£Žß΀9ëF=÷ÇáF= )´;ÐsÐô¤ät¤­&Räÿ‘@ç­>Ôõãñ¤úþ´¼ÿU&ÿ…;ð¤Ï¡4q×úPÁíF1Çò£‡ô£Ÿ­ÑœÑaF{Lûš=y¥Áõü(<´~Ÿ¯ãJ{Š^1Ö€Ç\`ÐØ­/ãKÍ&sÚŒF?Æ–€Ž¢øþt½9ý1Iùb€ƒ¡?&A¸ô­F9€ Z:Qô£ÿ¥~”pzIŒõ¥éÜ~4c¦(ü  sÈ£sG'½.>´PÆŽ{ÒÒgžô ö£ð ôÍ~ŒŸCG“GÓŠ9£'ÒÄ~t`{ÐG¿ZNý¨éGôp?ýT¹ÏNOΊ(úÐHæŒý*µ'âhÁïúRóíGáG×ùP‘éECÇ¥&>”ïŠ3K×µzb€$÷ÏÒš_ÆŒûæ€^hǵ/éGÔ 1ïIŒõ4 v—ñ BtÇõ4cÚ–ŒÐ{‘G_zRqÿ× ž:~” L‘ÛjlŽÈ…—ŸaNöÅGq´BÙ㎠PfåË…¹ç“Š|2´ˆ×aÎ0i! ´ãž{®)&:>HÛž§ä2À£"¢y„pù› ã &˜÷hŒ‹‚wt´3`sQý¢0>õ%ϵ&síMI¨*rëCº ;ó£ v5»‹Ì([nîjD•\¼ààÑfºö4¼úSU•ºךI%Ž.Ä:š~IíGáM»¸ÅD/`,”IÑfŒûLûÔk*9°?CJî©À{Pÿ 3éQ™‘_i8$Q‹*†VÈúQ`O=¨Ï¸üéx¤ÀúP ÈëüÍ÷£ŽØ&šîInëÅåëÞ—ŸN*¼ìLa’UQîp*Mø*SéE€Í/QÇéIœ™úTK8’eܧž«ƒùPÝ=>´TK˜å›#ž9üª`w{¥ X î—ŸJk8Lîp8¨gvYR5‘°<šÁ=¨Ý“Š`‘<Á7Ï·8§à )FãÒ££—@êzŒô¦Æêw–p@=ûP&çüŠ¥GÑJÆÀàpzs:&3Ò€ð¥ÎzT߯CqƒÞž%S'–Xn§`±&hÎ}iqÖ›æ«+m`qÖÐPMW‚`Ñ3±Cóò¶qS#+€ÊÀ¯b  Å&9á#2 Ž>µÁÌÑpÃ84$žE/áQ™HVp¦iY€\’1ë@†5Äk#!ÎUri«yp˜a“€HàÑšÃ2m ôÀ§H›£àƒ‘ÚžFKG>•2 üáˆ$“ ôsžß•/?äQøóô B¨ªÂþ?6T`ë°’89ô©fm¨U]UÈ8ÝÅ/îòÁ7¤w cö7‘c ùl€qÅXÍE*¯UïÒˆdYÊ~†ž€:YH\‚qéLk•PWpº3NrÇý^ô#4í£ÓJ².äÎ=Å8óèEWf1L€2,mœäùUŽÏQ@ùâŠ?*9ô*¼·±E»!þV ~SÞ¬dŽpV |öY`Ž3Ž}¨C_FÒÆ œtÅ } °uÆJÔåÄ.@àžÔ»F;cÜSº yUqn;{ÒÆÁÐ:çf£˜; ÚBàòO9èñ°´ŸURäàu¦G2J¥’ ñŠq8î>¦«Zh˜²®w¶0zó@ûRÝóÆzR-ô »çÀSƒ‘M‰ ’ªcw­M±rpˆ3׎´Ý‡ N—ïLã8©EUs(š0c¯l~g·41 A£šëÓêir3ê}©1ŽÔ£9ëŸjLÒþ"€Ÿò)ïÖ€O§{“úÐÏ®) =.G·âhܽÈœúÐsŽ•.áÿꣶAüÅ&{þ¿Ê“ŸP}€¥î1@r:âÇ4½ºS}ñÍ.i=éyö£‘é@8š8?ÅúRçZLJ;QùÑþzQŽ) †n«×¡¢’o¼¿J(@qÁéíJ9ëHìE.Òpq@ÜÒàŽ´L~FŽ¿ÂGÖ˜ ͶúÔí¸qŒ(9¤çýšvc˜ì(LGCÛñ¤*8'éNÚ;Šç°üé:õÆ}¨ÂñéKÀíÍ>£ñ þ4¸>ô˜ LQõm÷c#ô aŠ9ÿ&€1ÇRþPguì(#ý‘Ÿ\RÜãò C¿=)0Oÿ®“où4cÛðÅèZ:úRcéKÇ×ð A¥/â)¿(úÒŒ„b€Ðþ4`Òþ¿SG×·½ ÿ”`Ðõõ£ô¤ç¥c§ë@ Ï\ÑõÆ(¤Ú€Ç4˜‚‚¦({ô£·z?/ΓŸlÐý:џŠLz‘n´´™=¹úÐ)q@éI‘õ¥Çµ-%&\})hé@ Ç®iqÜh?JLîŠ9î?G^œPN?ˆj\ÐsŽ þ{çzQŸþ°£ÿ ã®? 0:ƒFÑÓµ.1Ø`PgÚŽ1š\¸£Ô”Û ¥<í}@ è9¥äzQœ{R ^{ÿ:7œQÓ©ãÒŒzt ?SøQZ;“GxQ@}>ÿ•ìE/å@8íGáG>ßZ^}¿ LÎ `úÑJ>ƒó£pÆFxõrz€}èé×¥)÷¤éÛ4øQÓc>ÞÔ`úÑzNòs@Áþõ&­&2zÊ”xÅÿœQÍ.3F¨ äô¢ŠLçŠ(üM—ÖŒôÿ 1ëG?Z9ìØü(úœÐGJ0(é×…±ÐfqÖ—·ZNhéÚŽOµ&1@Åëè(çÚ“>âÄPõ£w±Ç­/ãG^‚'·cŽi;úRÐGqF öœPéGOj;ô¥ü8 br;ÑŽi{Rg=³@fŒÑŸjJ7zð~´¹¤úŸÒ€ŒdÒ{ŒRþ4˜{g™1Û·þÒŸÞ™*ÆÑ2¾Ý½ø #€¿;¨Éã‡ffCÎjØ©¿~lqÉ©íáX" ¹ÆIæ©Øa'š\`¨æ¥Àãå•A.à WSŒg¥ñ¶´n2ÛTúÒ° ƒË‘bE œž)l׬€ùd`÷¨ÃDnÃq#.F@ R´±ÛÍÂÎ@nÞ´ìòFª…‚—$`Sac$@¸8#ŒŒgð¨þØ» …8ƒøTèþb+ƒÀ”¬Ò)K‰QV0ÀžI#Rˆã-p=ª „Bê&v!³ÀÛÅZëG@+Ì$yT.ÝÀ–8©|”,NÁÓß•A)Dœ¼çžôïµ(ˆ;’¹çf‹;±oóJmA÷HéSýU^Ý¢gÆÌNrAÅYçÔ LLNýé’—U<ðygŠâ›×?)›‹’êD.ÂÜúúU¨di# é´‘Ó5¼ˆÛ¾QœŸLSb0µÛ•RHóùU?B‹œç¶(çÖ“¥/qÍHˆ®¤yU,sýÜÓR(ÙUš?›‘ÏZ’bg%‡û½i°ªˆÀ Äzž¿­l„À£Ë#¦3S`2àqU®Š,y”¸QéÍ:[”Ò2³ôÀ¢ÀHb˜œrË Šß¼ N)Æ2Aß p7S`1Åu(ów= *•†‡äÃ2G@+’IÍ-ÓÈ"Â]Hç—2Fï$ƒ'…PH¦É0¹eŠ9YI\ôã %™Þ(¤cÐzõ¨¡u#„*>•+céQÂŒd°ëšj07 ¢>½SÔ WÏ`]³èjz@Ȧ®„‚8àTŠ *€: Ž`S» Ûšp£œÐãÚŠ1KøÐ!>¹U3zê";€ÎãV¸¬û˜ ̲EãDü‘y5¸Ñ¡ŸöphϪªÛNÜçƒòõ©¢£SºO0žø‹ ^S‘žz "ÁQ´|¿•$ ù|6ÞzÒĸŒ áˆïK `pF2*½««‰FÊÈÅNÃÈÏ®*|…pÒ;ðãÖÀ„G\0=0MO‚{b«yM. Ü?Ni“‹y{—±ÈÇéCZŽÂÜp‚ŠÍÎ 8«7÷OãPÁ— 3ž»Z›þ¹¡öƒÜsGOá¦óÜdvÁ¥^™ù‡ÖÙîO¦)¸÷mõ `J>‹‘ëH1éKÆÆáùQßœ~4qÔu£¿OÖ€ ÃÚŽ=?::tü¨ê(ÉúQœuÅç¥üh ûbŒQƒëH0z*^)§dtÁϦ(¿ŸÖ—'ýj_“>Ì(Æ=(£•'#ŒPSýåéÐÑI?Þ_¡¢ƒÜ¯Óš]Çû´€{Kô"€ nŽ(¥ãŽyö£œòÔÀ:sÍ{Ð?Î(àtϽÆhçÐÂŒÄÑ‚Š€Œw¤)0}Z”ýÔš^½ÿ!I€4‡wm¿‰¥Æ;PÔöÇÒ‚¯sØŒz1þE ÞŽ¼ÿ:>„ÑŸN~¦€úþ˜É¹ÃÞŽ;h™`z;ãó¥ëÚŽ­Ï@*OÇ­.;çŠ1ùPõ ØÒñ–ŒûRqéúÐàQÅ'î(Êžÿ¥/ãG_zNÁüiÏÊ€Ç~?M£Ú—ŽüRp?º?J_Ïð ÆŒŠLŒã'ùPò;~´ ŽØö£Ÿz¿Z9úP}©8£êÔgœ惑Û?ëKÇnh8ôÁúÑùÐz(Îhy>´`RsÜQ‘Ï_¦(zvÍž”ƒÔš ƒ÷€4§ëøQƒøR vð¥Ç4cšô4gÖ΀ 9ÎN)9#ëKlPGù4{sG…J^sÖŒûÒbŒb€ŸzN¯çG=èÉ Ï3Iü¨Å~´g¶qF}4Aç¡ü( ž9SF½ºþ”c9ùhÀ¨à÷'ð£+ë@ G©8# f޽ˆúÐý(9Å£ìƒ@>Ôzð(éEzPzc¥~_•=þ”{1õ£§èhþtc>ßJ0{Q~}hé@ö£CïGn(Ç¿>ôsÿ꣞˜¥çÓó ‘îhã¦GåNçÖŒ}(?ÑŒŠ\Rb€å_LÑŠ\ÿU {RãÖŒgéE”`ÔRÒ€Žô¸ïIŠN}hÁî)hç>Ôô¥Åó ^”b“¥GJ0=Oç@=(çÛò þMéšN=(Å=€üéÏJáŠ9ö¤ÇåéFs@ õ¤Ï¥q~”¼ûÐqÚn /טö€ j1Kþx¤ RdúþTzRþ} ÇLQøÊŽ}*3Î(çð£õ¤Èÿ"€ŸZ@=(#?áš1ÜøÐþ9¤Ç=èÀú}(!sÏZ.=M'¨ÀöÅ.;š>”dúþ”u£q@‚Œg®i0ÝÍÇ=踨£ó¢€ LûŠ\úu£¨ä >†©£Ž´cj>´}1GÒ®(?Ê™2@ã©©3L~Pñšdy*@ ÓŽ”È\ÆDrÊ®ü㟭¹sÇ=i³!ûñ¢—‚G"ŸQ‰3îsŸaÕ æò¼²Çœ÷©³ž¢“Ï¿çUç‘–HÂÉŒœ޵céƒøÔR@’²;¢³!Êû!Dqªí(»OlTq±7,¾`Ú£î…þ´Ù$¸þî0Íâ§G#l‡ï0ic$óΔ“è)£éG<E #™Õ#%˜(÷¨V;¢ïcÛƒü85<«º2¥CJl÷| ^OÐ!ѫʓŽqQÌOÞ ÜóSã>ÿJcÇ`Ì¿2ô4®øüj¬HËs+3†Ï@1NYea“Ü„Óaÿ©?vÜ÷=? v;óÎ:TprªÌUœ¼9ýiK;Fà.O¸4ÆdebH+éÞ„Á2,H³ª2Ʀ’Ÿ(ØŽ´ì OçHÂIŒ|ª¾Ãµ9›`ÉÚ*¸!“8ÇLÓehä  Ãv§`±%º²oÊËò㚘“Ž4ÔO-p‘œóNÈÁæ“Ttƒû• àsúÕ±øæª¿—x D2²Iô«X¦Á].øNcY0:0ëSFsá@è;Pë½Jä€x8ªÉ"B]0HLrzІeQó0¦Bž^F8<ç4ŽÊêªÇ=A©PàPj§í J*úrj|zóUçA"cs.?º)|â1òçœs@ (VÆ9ïR®v‚WŒÔ+¶VÞ€¦x56=é¼Qô¤—‚ ®ûSœcŽ»³ŸÂ¬`ÿ“UÙ„r±UùQB'ÈÀ9¥â¢2‘·ŒúQý¬ÞQ‚qÛš,%•°™Ù»ž™¥…JÆàR:‰Px9¨ì* èQ‰8Rõ4³ÐõªöÇå“!Tî9ÁÍ5îÏΦ>ŠI$Qª) ýãœq@ ‹ å†Üc¯½1³&åŒHëЭ…ÜvŒTüƇ¸Ù;Œy ÞݪN=*¢,6³;$ÊÃŽ*Ø Ž¤ÄÃJjã$ÆŸÇcÍ!#9ü ´p;s@éÐþ4¼zÐdsŠ_ÆŽ1ƒFô4c×4QÏ®E&G­#ñ£êqH1Û¿-©ê\ŸN)0(=xë@ÅÈÇÑœwæ“ Ñœãš^1ÞŽ£ÿ¯Kš8õ cǵ/Óõ àÑõϵðæŒûŸ¥ÏCK¶€ Ÿï)ç¡ëEg+ô4Rà‘×&—wÖš=ˆþT¼ðÅ/©AýznN†—åqLg< Cœú­'n˜¦Ë*Cwè(@1Њ3Î* ¿€àrN3…ùéRÛÜ¥Ä{‘…>V&Î}i3ø ^~” þô„'8ùŽ)qOÆî1GSÐæ€“=i O¦(ãñúÒ’=?Ò ãæ ý)xô†}sAIÇRhÇ£sõ¥ú‘š9ëÍ $Á>ôÙ$ÆÏÔÐT_kˆÈŠÌa‘ž)¤ØX±Ôõü(ϽS[ôdfI·‡¯Z±$Â2£®[Y…‰9õr>”j(.R|íÈÁ#X›'ëIÎiÕ»ÔÐŒ$@ÃFs@ ÀÑŒçñ¥Ç½õë@=×õͽ¹Á£üñ@„ù»? 2~žô½ºÑº€uQÞ›,É osëN `äf‡ÓùQ¯ãGéøÑÏsš/µ;(ý(Ϧ~´¸ãšŠIÒ&EpÄ·L-H¼€Gz\Ôc4É%² ,p1ÚžëÇÖØ6Œc&ŽâàrXïUÞþÙc;K``´Y°,phý>´dp9¥éڔĻŠGEGS¸da…;6'öëFÜÓ%™`Œ¼„éš/¡vIcœ|ªM 6-àúÒž¼ÔOq ,ˆÏµœü¢–Yã…ÈÁ÷'•‚Ãð}M.MÃ.AÈ=1G>ô;bŒb—"“ó Š=±F;ÿZ_΀ëF1ÿë¥ãÖ“hÇøÐÓ©8úPqŽip?É£o€Š\NhúPÎzñHFyÏà)zu¤'¸ éÞŠO¯ëQùñ ÄÈ0½}¨Z*#s$ Îçôuu „h°Åü)sÍB÷pÇ.ÇlR8§E(•K™Ç­;0°üw£·ÀWÌ.ã…ÏzbßÚºYÔªõ9éE˜X°¤0È$Š\{Òš惚(æ™$‰Ü.NM9H”äô´b–££Hцù”dŠJ(ϱ4uí@?ZoáúTownQçE|d«078ëŠCÓ=EAöËq³÷ñç –š”JŽÅUÁ#¨‹þ‡–““Já@ƒZ;QøÓw¦ý›†î¸ Áõ  v¥£4˜½~4¹ÿ8£Ž¸üh1ÞŽ;KIõ qGOoÆóÍ!àô⌃ÎxúRÇ¥ ð}iyõ£ŽÜRò(½O4£Ž™úQíÒŒ (óŒRý)84c?Z;àñøÑŸN”gÖ€ Ziä÷¦É*D »àdЙ¥ýjq. ¯Ê2y¡gGÆÖ'=ñE†MIÿ¥çM2 `¥€cÑIäÐàž¢—ã4˜è(¹>”~•t¤bI9Àô bš1š‡íQeî[ ïRþtb—CG´ÈÝe]ËÈíÍ?£“@Š1íÅÇ@hÍFeO.Ôâ€$£ГQ-Ì,2²)çiÆEY› ’h°ϱ£”Õ`ë¹sƒC6ÎXà{Ðã´cÚ˜eN7uàÒùˆÀÀç§8 < BHÿõRãž4¸4܃Ç?ˆ£‘ßéKôýhÎ9¤Jç©&ŒÀÓ¸ãŸÖ­0ùÑ€}iÔOÝ Æx$þt›3ÐS±ÇCGOaõ Bm#Ô~cý®){õ'Û”éúÑ–ÏJ^Ü 1Ž˜£œÐ1Ú—ŠLRõ4½zGæ~”ÓÇ$QŽøÍ/^Çñ£ŽÂ€'8À¥ÛqïF}¨0=)phüÇLÐsҌ◟ÿ]'á@är´}E/jnÇËÒ—ŒQKÚ‘"cÒ™#ã$¶ àz}U›t· ‚»vi¥q¡ð¦øÔÉóžÄÔÇ…;zãB¨U.yéCas9Íȉü½¥º–ïŸaZÏ5 ÉÀO·=—52œ¨8Å6î‡Ð…šO´ª‡@˜å{Ó¼˜úUç=;Ôs 7Ÿ+'<°YÛÒ—A¡2µË—’6oÊóùUœŠ§ »}±cå÷â® 0ϱ¤g $KÇÒ¢¸ `T‘è)Øüé7yÂ=™ùps‘RãðúS#u1ØPM<àúãëMƒ*ÎòK*¤k‘çe»})·@A–(ÑY2xÀúâ ¹ˆJ>ö0ãÞ§)³ÈÇJwZâMÖjÈ뜌’2µ2Ù˜K¹š2˜ê¥J!Yâd–0<zÒ 8!lxr3Öši ß$¥ˆ‰£*ELʲ.× Àö+‘PÚÑ|¨Á@þ.?J±Ïÿª¥é ™U¤–œ»¢ÀFô5kþPÜÛGp˜tc´çå<ÒÛÈe‰[`ˆ<ÑÐ Ö5ÜìÉ HŒv†ã8 ¼uH?{:dd äT6Æ9.ƒ])-‘Ž;P•ÂÆ‡áúÒ`w£ëÅR}héKϵ'?‡¥AøÒãüâà{}(ãÞ€ z_÷qH·ëK@᥎}h ¡{h È1µùoz—šŠâc »¸ŒÈº VtMë%ª+öã¦jyÉEòÊ¢ƒÎêŽÝϘb(Œ2zõ©.ÕZ,4e‡·j¦­¡Bˆ¡˜ 4v#¨j9 Á*ù~JÃŒ`ñÍMQ`.Þ8 Ê8Ýñ޽³G[QÒ†’`岃߭Hm¢lþé2zñA…L›ùÎsR)_A@_ "€x jJ¯o">à¡ø8;†1Sã:PÁ‡J ÀYÏOn´;tï1I÷¥Ï±B)‘cí å²*ÿnhjÀÃ>œÑš9£?ýzB#®9¢—zR`w aéGÓŠRsŠCלP!~´œ(ǹ4~”¹£õ¤úAÆ(HG­äÐøQøRàŽÔ™#° ÇÔ7!Œ*†ç¡8©ÿZŠX„ƒ ^ Ð1«{Œ…˜Ã šU–r‚%¸ÛëVz.0j©ÄÓíE+É9 hh±#0Œ”Ã7aÓ&›EöI"í@5É\DÌŒX—YJ:? _­&qÿë£#Ö…È#ž•[Î-t!ãfܑެdU5x?´JÄ›:O¥44Y1"¯Êª1Ȥ†IȹN|9\ІÜ*!6çÈö£ 2ÌnUV8Ì$Í¿~˜©!†8¤c9úU{f‰¦•Q21ÉaŽ}ªÞxéCi=ùZ3ï@aØŠ@)<ô?Z©ä´®ÂddãœU¬Õd1™° –ÉäóM`ò†)%‹¿•·y\ Ã"§ëŒb›"îƒF:R»;` 0qØæ’äçáNáÜÑiź¨MžÄóK ]ê ÁçÒ›Ü}HLl.—¥0Ïž*’;8âŒ"îÀ;¹9þt×uK´ •«'‘×6ì ‰%‘äehÊ({56{~¦«C…˜¨wlŒŒž? ³†ü)10Á=i>„þT½Mý(Öóš^~¿“@ úÑÏáKŒv£>´nõ?.)xõ£ã LúëG_áâ—þGùë@„ÈäÑZ\RtíHçÔbŽ˜ü© u c°¦Ÿ¡¥àQþy£éøÐÇáGáúÒdgµÀ bþ£Š8=ÇáFéùÐ!r:QI‚øRçŠ&=(ä}=)~˜4Pϵ&sKQGó Ô`uÅ>´˜9ÎiìiH£ð£¯z`¤Ç­ç§ãJµ&?*LÔ¸ö£ðȤ!8ÇR =éxúQ~h›}¿Z0§ãKÓ®3îiú~4À8õ£üõ£(ÁôÇÒâ PãšLÛõ£žÔ w'ÚŽ©2=Å.E w£õüi>´´~˜÷¥ýh9Ï8¢—žø£é@oð£·zN´ž´(¥ÏÑÅ›Tö£Ÿ¨£·q@;sIíÎ)Ù9ëÅÐcŽãñ þt:? NœÒþ•/N´”~tÚŒqÉ£ñ ëF@ìh£>¤Pòž3IíÍ.G÷©(ü(àñƒqK‘ëFh:qÅ/á@éÇJ;õ ëùQÍÿ9 bQÀõúÒç4gð B}9£žÇ?….OÒ“üæ€ ⓵/âi3@qIzùÒóëEH4qØgñ£n=Oã@° ƒëùÑò)p`i0G9ü(À÷cüèúžhõý(Å/nÔ”zÐÒƒõüi9ôÍoÆ€ Aî(Èé‘ïF@?xj\{fŒãŽ¿…Èãš;t~Tƒo©¥úcò£œPš1ÅZ>¢€8âŽM/Ú“@hÏŸ‰ æ’“ß‘øÒ玴 1ÏOÖŒ{QÛühí@Í÷—éEŒ2ý €x+בKÆ1Å>Š ¯…Ç|PX{ý@ sÒŒ}*bpsïHp;Qéš㜠SDWÀ‘×+ÈÇ?'Ù£‡ËÝ<¹ÈúÒ¥ŒJ.ßäãŽ;ûsO˜1ÛŒc<ñT›:§—Î<ÀqLû'ÊËæ¸ sÛü)X0D 6>µ`esš€ô Ug 3“ŽNx¦‡ŽÞbŽÌY²Ãå=)ÁäûS ªx š•‘K‚Àgi\–õXÇò¸2g…6ûËÄlï(ç¤]þ´Û¨—ì߹خ¼©ÛÓÖ‰š_. ¢¹,Hü©ÙtAsrH„6c\–=èR²JŽ—'hÁ¥[udmñŒÈ>|rà :ü 8¢è †3œš3Û9ü(éÓ—µH„ü*¥ 8ÎSƒV3íP]†û;mTcèü tgåO¹ëP]ˆ”£É¼`õQš±vŒo]è $ªv#‘š{1õ0ÀtöÅTŽ(#‘‚“óîär­K²›}ÌJ+º™oæ˜äy!A $ 7Þ¦´M ½¸"V”nÛ’FAý*y]_(æª hL¶ê³Àƒkd.íÜÓ¤‚8É ½¸b7k‡RÌ|D‡,p:âœtéïLˆ·”¥†;qOëß5,L9<†4¿¨ëÚ€ßp=híÈ£žÆ€+Ü®èö‡un£jT$ªä¶i—9ò‹ÕÈéž•$g1©û¹)ôìÒeyëKÉ£¼ÒpG>•X¨k¶ )•Ïg9éU®« 2Îx%E44Yü ¦DÌbRêU»Œô§þ´€†à±‹àÓÖ¥\mâ«Ý)fˆyq²çý¾•`¥>ÐG®â2:ŽÕLZN±€&-µò;qWI¯ÙY–6hÆæ­ ´­nT\ÈWd-¼»UsE°“x߯ËÎ8çéOœ6øÊ¦piìô¤Kb¨$ß·téVÔ0Œ6H;SÆp À5]C‹¶, ‚=G®ÞàÈÑÈH<í'¥Nø(Ûºc«@ÄÜÊZ4EèsV$`Q—ä9dñI‰‘Z…T`¡€ÝÞ¢ºXîgHìÎB©9©mŒžY¡H=¸‹'ÛšD¶V!$Ç=øÍSø‡Ô¿;œÑŸ^*Š]\»!h ÁùºUÕ<9ïRÓBhG#oÍÓÖ¡³)ä-Ì€“óQw$ˆ«å.âO uÅ>–(‚"íp >З´½}hÏa×Þ“­/å@?aE&~ŸJ^hühç< 9¤ÈçÈ÷ î74EC”ÏñS-N!Íi<“Krà`c;Oµ­ºÝHŒ =…5°ú¦³¸’ïÌóÿt  må…S0»qÎjöp2MVØò϶XFÐ2ëT¤öe¬â¢2Ç1xã‘ )ÁphžY# ±nãéK(ŒeÚGåþµ6è“ËR¥‹sÈ¡äŽ%ÙWœdÓÁíÅS¼óXÄ"îçhÝa'G‘£V—¨ª÷°™™žÑÉÚqúÔçΓ1xùÍ àl@ÍïGPê0Á3Iþ´ìÇ·4èGî|ÝΜ6zÕ€9ëUÆárÛc8'“ž ;ßA‹n»K¯šî=ùÛ˜„¥7I€ƒÞ«¬óÄ%v³ÚwàG#=iò\1¸Thˆ :QmnáŒpsKùÔpJ%…[ϧj€Æ¥ˆ) éKE+„?igó>\qS3mRĵV\›É?tTŒ|Ùê*Ë_Ö›+Û(ß!ówrzT“"c¼.;x¨mY<É‚* ­Ž3ššá|ÈcwNè`Â%aÜûý*$IíÉ”ùdgn49Ù’¤väÔhÚŸ#Œâ?ÊŽ Nì3J¦>” žô×fJä‘ÐR¿7µˆªÑÜLÑ£4X$ò3Ò­g"›Vƒ?çg·…{Ñþx¤!>ƒó ž´¹ÏQFh8ÐÎM.}(>”œôéG®sŸ\Rþ?¥ÿ8 ÅZ8>ÿ…늲Ñô àõ Ñ×Ö€søQÏ·ãNüÏãI‘é@ ßóG>”¼ØÇJNÜÿ:Ž`PÅsÜSmC¬ ƒ0þ,c4\;©l‘Ðô©4ÀàSè>…%[¦’|Ê Ýû¼&L©r­1ãoέ–ieÌ  ÷‹pÞõ4‰º6g# ïN㸩"¾BžGZC*o(Yw““ÐTV|ÆÄÄÑåÊNi“q#nÒqÏ`E+kau,«£Œ«+U9¤yˆB’LŽ)¶Ëû…ýÙA»šƒÆŽôž€Êdp‘ægRœ’3lÆËÆgeÂ’GÊqô«r€¨v®ãõªÒD ›%C0˦ª÷C½ÐxKJŒaÎsSX¬ñÄÂäåãRB¦6íõ¨ï@hA!¾ðèho ‡^¸¥üÍ1xP0zS¸ô©ÞµQ¼ÖŸå‘vó‘‘“øU¿b*ª+}«"5 ÎN{Ó@†Å ʦEÙœñׯJµ -pqÁ¥Æ;ãéI/19lƒ½& PÒaÔŠK0åH‡ªæ–Ýq8Æ{DÄmݰœzqMî>¤lÓ …RãaNxïM?jUVDÝ»Ã9¤p€Ç!ܾ¼ W[Ïç;¿Í…< `YPªIzÑ€NyüèÜz\“ØTˆÓŠO©ýiyÍ$v ûR`óš_N(
¤ÈÏšqÅÐ3íš >˜÷£½.? @&OqFO½-&qü$}9¦ ïÎhüMaǽF?…- ÇlþT¼{Âþ#Þ†iÏZOÆ–€—‘Iœš^ž´ŸEýizzÑ@ýh`zâŒûQG´†ûþtÅ4~tÀ1KIƒì(Ï(¥¤Îhëë@Í!Æ;þdÒþ{Rã=èü }h3Ž´`gšZC€}èÍ'¿•/¯Z^¾´ÆÜÚ>nÜR©%A#žôïçM9ühr(£ëIœñ·õ ) ¿çGzBE¯|ÑŸJLƒÐhïÈ e½E/^¦™s@$s@È£¯Jnüõ—9íúÐ1~¿Ê“4 \ûÑš9#¥%.E8è(£šN{Rýi3í@#¸æE.h£#¾1@çE”ŸÎ€éIž:Rþ™ òühí×ò£9éÏÖ“ñ4¼RgºãëŠ?Z1þs@?Z>”J?Z(ühÏã@Ç¥­¯R? #Žhù¨äQéGÒ€ sž(?•÷œg¥¿…# üé÷ µÐ~™ ¹£èOç@ú~´cÔ~t˜Çv&—¯'õ¤û½€£$ôæ€ Øÿ 2qÖ—cž1@ øÒóÜÑ´zQÛ¨ÅúÒŠ?Ï&ô ?Z>´dzÒÐQŸ¥üóGz3ÏRhÍ-&¥ïøQס¢ŽÜ 0}qF^ôÀhü?*9"œu¥úÑÇJÒr}©h ç×ô£Ÿz^qMç¹PãÞçÿ×KÓ¿çIÏ×ñ fûËô¢)ù—èh¤±êM.p3Í7'ß”¼‚8üI¦’xÈ8£>ØúÒdÿú©qÏÝýhŽW1ÆÍ‚Ä àMIŠ0~´ŸªÈn<‰7É€9T£ý$íš=»y'ô«XÇ¥;Žä>Båf¯ÖÎVM‚7é×*p8¤Çrsô¥p¹®ìÀ9fàç§áMr-09\“ž;U¯ÀQõæÂåIgI•’HYöþÓîaŒD®àþëæf§§­.¢ár¼WHëÐ@aÇ…6KrÓ+8Áâ­.00£ŽžÔpNEÐ\pã¦)IíKßßÒ€Ÿz¯:®Ìíb}@«Üg¨"çã4ñÍ}i6|ÐmNÉæL­6OÞÎ>œUÖ@c+×NiÅry"‚¦Ø\¯jD#ùŽ9ùªYŠˆÉ>Ž)Àü#>Ô¾Ûsz ‹Jc¦;œÓúŒÐ¾GÒŽ)04œúPiy BdÉÇÒ‘ÛdlÝp3Í;ŸJCéŽ(§Ú’QNÝÙéJ—Ñù[à>ÞMYÆqÇJ6¯÷ö4î»qIÏÓëF@ccÑGçKŒtýiÇRѲò gÒŸõÅ'9Ço¥UR,aQ$¥†>ó°QRÉsp d`©Œç¨©q‘‚â  qM»î;”$º·˜Dû»åqÏô©–í8œuÉöÍXØ8ÂƒŽœt£`ô§uØw6Fjž"ÔcWVdØÝ½ªÞ1é@UQ…Ê®"¡¸¸òW;763Àgó©±êOçAôÛŸzB"‰9WÃŒŽ„ƒÖœñy޹†Ãдÿ›Ö—žæÇr¿Úg8ŠU„y¾w<ކ§ãd •n+‹†r»ƒþ4ÉŠ\”…™×xÏËÅ\* ®G¥ à:P˜\ŠFX¢ôÆÞ¸5´*–ÎL®û8Î=ªáÁà¨"£ÓŠ/ \ÍO(˜ÕþNAÈÉ«òJ"ˆ;çÝ©ûTc* œR•yŠmÜ XwÜyâVÚF6ã=ãëKÅHˆ¦¤L$õlpl7˜Ì@Ç&¦úqKÓÒ‹Žáž:@$ÿü(éÔÒäg­úÑKFsé@>´~tQͨϥGJ(çÖŽÔ®hǵªª‰ìKóÛŠµ“éIוáfƒ 2Í·Œšµ@ “Žæª{Þ”‚{ãñ¦ØLRR`óvÜE>ü¨öù¬ÿí1ɧíÉÜ@'×ÒðzÑp)Í,pL ’–ùTŠTÔ-ä™cRY²G­F • GLŠAŠIàSºê‰(;Npzb‰eX‚î$qÀ§$k!T œð)J+crƒƒ‘šZP²Ë#–S¿œþ<Ó剜|®Tý*bëŠNG‚ä&uY ü«œš!ŒiD„‰0qžªlOôG`S¸\i ÙÃ=ºÔr»H‘“žyëSc½5£V#r)ÁÈȤ‡N:RÒŠ^h”íKz0{P5sö·VvÆGà´rÀŠO,,Üz¶9¥ç¿JW -¤Øòƒ»î©â™q,sFcó¶r>aõo`$#¦i6)þøŠw ‚ä/\Z‡a‰ÞS+2ãî8üj|{~´È#ŒZ@D·¶a[3ÛŠ{¯˜˜ Ê=TбF»p«òôÇjy¿¥WŠÝÓçg>â¬që@úÒþt6Žý~”¼~4ŸëKúÐ úF}áF(É åFhϵ(íG~Ÿ­PùÐp9Í/áI@´gÓš(çÖ€ Rcß4´NcøQÛš\ý(ϽW¸Ù„Ëíù¸ù±šœdóFê.8 d;DLîÒpNp{PdŽÅ|1©YA#¥4Æ»ƒ]áÇJd1ˆÃa‰ÉÏÒ‘åC˜÷üÇŒ›ñ¤Ú3’h±®Ä ÁÀê+¶Å,G“NÇåGn™ôQQnü»˜æe쑃SOI"JPž„OÀ1éF3M°¹BË6xÎqL25̺!Ýõã5>>`p2;Ј¨Рgµ €ÊŠv}qJ>´u¤cŽ2VÁIÔo}¼þugŒç"šU nà°ïéBF·1•';yÆÇzvô‘Jê3‘Nؘä.(UQ÷úw£@ Ià„̤•àîþ”Ö‘æ=“ðÀü¾µggåî£hÎBàŠw ³âì.ó¿wTÒPàÇqFÅ/¹±šwÐgß4€†ÙŸÉPò«È:œb§÷¨Äh®Ì0¬ÝO­<J E>¸£Rh8úÑ׿… ŒóÒã9"Ž;ŸÊ€“Ðþ”9ü©q‘‚ÄŠŽ£ùМô?˜£$u£RóÜÒg<ÑÐûR`úΔŽ(ÒŽi1êOçFG½0{š9ÿõÑŸRhè:Ð 8ïŠ8ÿõQùâŒÒQùÒö¤ã×õ AŸ\þT˜çÿ­KÏ­ãŒÐ0SIJ2G^´dÓE‘È¢ÄОôdv¤úQŸoÒ…ÝïHpzÐOÖÃ4ÆŽçð£9õÅå‡Ó4gÜRg4½)3øRtïLëÞŽœ*LŒsKô ñ£Ÿ­õ¢€$täú3ÇqAÇ©£zÏ|þdzQÆxÏÓphš1õ4˜ÏCǨ4¸÷4™ÁÆ "—ë@Í&i{qÏÖŽhëÛóë@µ÷ÀúÒ‡å?…/ãî(½;“@&“¥÷ Bç=(ãµ&O¯g¶ '± }(Ï|џ€>€ÑÍ&F:âŽ=Z_ÐÑÉíøÒw&ŒûPÑœN)? QúPH£ëG&‘ÜgqŸz8híí@Z3ôüè£ñ£ õ ñÏÒŽúÔ~ úš@pzñKœô?¥_j84 úæ®h=:IŸc@ »ÿ×FhçÔÐO¡4™úÑž(üI£¯ÿ®€AéF8­íÐQÞ€ œp(‘ÍîAö ôÏã@ôéFI{œR“êÖ€MGÞ RçÚ€èIúšP9£š1ß4bŽ¿þª>iNƒ#4´‡ŽüÑ–é¶€ϵ% ÷—'Ò€­'"Ž~”PIî(Ç|QŸc@ Àß•(Çÿ®€=iGÔQ¥çšLŸz1Ï84¿SAÆy ËzbŽ}©q‘ÔÒs@ ‚OJ?šLó›´Æ?úô´{õ£ Žôóš3ŸZ;ô£èiF|Ð=(ÇÖŒúÐzûÐG”g=hý(ü(ÓœøRc#ž´Í.>¿…'âiqÏs@Ð~tgè) Cï@ žÙ¤ÿ=)AϵsIŸAKô£ÔgÖ“§ ¥¢€;QóŠ3Ï8£Ÿ^("Œ{QúÑøP‘E'àhã=(ü(úÑíŠ(¥Ç)2}sEýj8íKGé@ ŒÒtõ¥>ôP>”Qóš1ï@éGáE:怟j_ÎŒçµ ­ûÒ·Ò‚)ç=èüi~(Óò¢€£ñ—4PéIŠP¥÷üè9ôÍúQÒŒûPïÞŽhçÔÑœõ ŒûÑš3š?Z1E€ý)(üé>‚€#8æ—ð¤'Ú“Žè 'ÒŒÁÉü(yõ¤õÍæ—¯Q@&}qŠZ;t ü©:žÿ;šNGj'éϽ/ùàQÓµqHséš\ã¿ëFÙ&€O¥÷Åãð£ùP“õü(ÆzŒPI¤çµ;Jn1Ò‚çPOã@Á>´£Ž&=(Áë“ùPšN?È£ôúѸg¯é@ Áê>´¾Ô~Ê—J!÷“æõúS¸<€h$¹oÌ>ŸJw>”™ëÉ þ…};ô¦ðGN(üÿ:/ãG·}(ëÖ9¥â“õ⃟­-&}r(àõ`zP´á4óÞ\Òý8¤sýî~”¹=èÀÅB~”ÀCŸ\Rþ4R怞ǥÔ}•æ€ {QúÑŸcGáH½.~”Þ½.¦ 0øü)zw¤Ç·4|Þ‚€ 1Ûµ÷ÅzP08¥ÏlÒn=¿ÏQ@ ŠÖ“#¦ 8Ͻ¸£œõ£ëŠ\ñ@ ÇÖŽ;â¥öÅý¨çÐQ’;Rò{PG'×…ï@ƒžÔ¦9õâ›Ô}q@À`r(çÚ“§\â—Ö€ ò(Å&9äš\šÇš1ïF}&O®(ãÖ—Žç'éIŸaGNÔqï@9=E¤M§Ö—µ ‡ÐÒó@ õÅçŒ Ï¥/Ò€ÏcúQÏ Í(9HúÐ}ò tÈöÅ;ðÇãMÁÏSKƒŽ¹ 8ëÁ£ðý){sÍ'ùäÐÇ]ß•Žhü(ü ö ~)H$v¤üǵ.>¿‰ ¡Ž=ô¨£¶8£¯jq@úÑ‘‘ŒHIúP  úQïšZ;t È>´´œv ûŠÇ©¤ ÷ßǸ£€Q†Çµ(÷ǵ&OcšSžøÅ'ñIМb€øRd NÁÁ¥ÀÇPçñúR}Z3ŸcùQÈt „R`óži{r´qÓÐÓ¿‚““ŽHü)rÀ?:^{Ši¿J9îçñ¥9즎OB(;w¥ z1Žƒz:QsG=v­¦3ï@ Û§4˜ïŠ:uúQôÈúP€{PAè >”rGµFsJ3܃MÉþè¼ÁÍ=Fhê{Ò|øÉþ])qž¿­ÇÒg¨¾À P9ã4œÀ£½#¥ æþõ! zóFAï@9Í&Iã­>Ø£Z_­'9ëÅg‚iqì(ØýH£Š û1éÇÒ×ëGåKÎ{Pc#œRãÚƒõÅ'â /ùâŽ}hã°£¯nhëÚŠ0x£ñýh ã½ô4‡ñ æã<‘F >ƒõ èi{uü¨úÒ`gŠ2G©¹¤À=G4`úæ€ÄÑÁí@ùG<Òç<ƒ@=(éØRRãêhi2E…úÐæ’Š1@8æŒ~}(ÐP×¾hÅG R~€üQøƒF3Úzm àŒÖŽ(úñGG4˜ÿ¯K:âŽ=p}è ühǽ.GNôPùÑG½çÖ€ QÒ€G¨ ð£ð£8ëE¤ 8¤À8ZSúÐE&yþ”¹ ŒzfŽ=i:÷ Çó¥#Ž”QÅ8 }hÅ{ÐzŽi8£ñ£>ô¸Ïÿ®Ž”QÇ­~4Þ{FE.1Óò éúÑŽ=µdúQŸ¡£­ö4gŽ ö¥ü©? 2Eõ£> îi:tæ€=ii2Gzñ@â8úþgÞ”}M'÷¤Éî)pÞŽ± Ò€8È¥èy'8éÏÖ€’?….8õúÑóšMÜ㟮hqì)>^Çš^ùíF}å@ ÁëœÒçŽF(ëÞŸSøÐ1hã¯?!Ïz^œçj1ùQô£‚3ŸÆƒH¯½‚ŽMù¦ ëÚŒc¦/µ 1Üb|sIŸP :zБޔô¦çž¼úf—Ÿo /M4‚;gëJ3è(;~”¿çšJ3Š_Ä~cן­'Nß•žÿ•.=8¤Ç­&ÑéKÐPhÇ£RóIøP×£dÒcØÓ¨Ç®:n~`§®:â—¯ãJ½J@'åF=ÍZ>˜¦zzQoÖ”{R~t¸¤Úl~}E…-v4˜ãGâi¹ÿ8¤ÿ=)~†‘ÜŠ`-!ãµ–€ôü)@ÇJ8üi?) =…/ýÞ}é>¢€ÀQ‚:t£íŠ\`õ{RgØþt§è::õ­'>‡ò¥íÒ¢—xüèÞOÖ—ÿtŨÏQFù½{äRtãP ÚLQ´ŽÀQžœÒñÜb€}Gò {âŽX‘íFWÖ€ÖŒûãõ¥Ç¡¤Éô žôc=¨çüš ö ÈéÅ•4ãÞŽî(ÇëH@¤È¥Ï¹ 8î1FÚ£j3Žƒ4~cÚƒ“ÿÖ£š\}3Ió{bƒô÷£?J0GJ2sGëô£ŸB(õçšL/RGâ)y¥Æ(=Eù¥ëü$}iyí@ Å t¥#=E.=(¸â“=¿*v=¨ ÀÿõQõ¥æÂ€âÂ—Ž†€J;QAF>´u)0qéGО)hçŽ*\g‚(Ç`)q@?:ÑøÑøÐ(>Ç4¸éš¦~”œzqïGüŒgøh9ì(Ž”~Tt Ž(æÔÐ0;~Q€2qŠLí@ h¢“Œð(8´£8Æ(É=Ž>´mïƒøq@Ãü<ý(ùÓÜP1KŸ¯ç@„ü(Áÿ&–ŠO¨üºÒ~úÒäÑÇ©ü¨ ÷F~´œ7ÿª” €úÐIÇJ!㯿J^zâg'Œ{KÏÿZ€Ý=Aæ“*=¨Ï¶áí@Ûò£œõ©3ô¥ÈÇÏÖ‡^qÍ)¢’—$ðA A…ìsøÐr;QÇ¥#¯€ žœýi0¿4dq‚.)—Ò€·¯éG“J0::íÁ ÇÒ“ ÔÐ#”aþõÙÇÒŽ;õ£¶y£Žã4¿CHFzþY£ÓÑŸbÒ€‚“Þ—Ž¸4œ€ÐrHà \zóõ¥Ïj:qÉýh1ÇOÄP1è(Úƒô?ˆ ¨ûŠ Àé­' .}˜PïG~ŸŽizöü耧>¦Œäñ‚(#i9íj_óÒƒAIÉèH qÜÐÇN>´qÚŽ¼óŠ8éŠ8Î9Í&çý)O¦8£žÄÐ1ž—uð£ úæ‚ç9 Æ:ÒF=(èhÇ|æÅžÿ…§S@ Ú“ÒŽsÓç¡&€ À)N:ãõ£¸¤ïß4½}ÇÖŒOÒ“ŽsÅzPñÛ¸Å&J\~4=híßò¥Áõ4`úÐiߣ‘Û4:(úgëKøLŸJ  ûƒFµ£?äPôqž˜£ëK@zsIÇ­´~™ÏøÑ‘ëÏÖ€ð£§ÿ^“4½³Í'_J8ô4gëG=ò~”sÛò¥ëÎ9£œw¤Ç° žGËš\úÒqõúQÉí@ úQ‘ŠN¨Î{Pº€sF sÔPõfƒô¥ÉÇj3Gà …P×­Œ 8íG¨ÅÿõRgò¥üèü)9ôâ—¤ïÖ€wlRgéKŸcš>¸ äãœQÈéÒ–Ž}ÍqGN´g=qøÒsØQ’}h PN(çÜRcÓ€ Œôõ£×¥8éIÇ\Pàz L:\ú;õçë@§éGN(ú€i>ƒõ =Å• >Ä~4~/ £·¯Ö޽‰¢€žØö¥üÉ£¼P ?çm#ž?AÆ?ÆËÐÐ0ôÅ´c46ŠA‚zsïKŒQ@ ZzvúQžÄQ=¨þZN¼ŸåFHã·Ö—Ø BÁ¢—8ëGãzL{þ”¾ÔŽ˜?’ô àïãëNïÇéHæÎM/O­ MoÂp3øÒ㊙¤úGN¼ÑÇLSJ2qžÞÔ¾ÜæŽM =Aühé×ô¤Ç°?7®=…0þt™=úQƒÞŒŒu 2ž”¹4g°£žôw£#К1Å!>ßö¥È¤ÈíÒ”g=(g4¿ZJ?Ö‡ö4piÞ¸½©¸¤éÿ꣯½ºÓ Î)ßJMÔ“ÔP!;ô¥ê8£‚ŒJ!¼Ñò“ïNçÐÒb€sÓô£·§ãFÿª€yç­¤úÊœi9ôü©qG¹£”sØäÓïÔý(8ô¥âã¹Çã@Ñhÿ”½Oh8 84¸ g'#õ¥æ€4£ÖŽ?? (Çÿ®ŒÑ’{P¸ö¤çž´ ÐøQø ÷£ƒ×­4cßš^½)0:ŠOlQ‘ÿê¥Æ?úô@ ïÐÒãÔÒÒb€ Q‘ïG9 ý ŒäqGáIŠ_¨£ éIŽôdúõ aÓÿ¯H@=8¥çÖŽq@ȸaŸCÚŠIÎ>†Š@< w¥Ààš@ÝúÑœñ~”à þµ/ÊÿZ›‚=¿3Ï>´¿€¤À?þºv}óFsÁÇá@#µGSך^ÔŽÔÄ÷¤ÏÔj9êzzRîô8>„P0๠phÏÒŽ{ô ÒrBߎ‚ŒC@…ç°£$zŠ9ìy÷¤ã®E&âN9ü©yèÏÖŒžô ìÐÒ Ý°?w_qHG>¾ôO—׎¡ü)yì:3ߊŸò¥öýhî?#AçøGã@€‘ýüQ‘×&Ž>¾ô{ýhÏ¡£ëGQÿÖ¥ç½ qÅ'Ö—Ÿ\Z\ûÐsŽÆŽÝéyõsé@„ü¨#=qøÑøs@ö ÿÖ–“?…zл»þ#âxæƒëŠ:wÍ ûqFáëÅ/ó¤ÉîJ!*Øä~4mÇ9Í)ÇçIÀÆAüèù{dP=˜Ÿ|挜ûöÉ£¯$`ûPÏ`h9=Múþb—õ ãtúš_ΗÐ :ñžh1ìhÏ·áKÍ@M7¯BE8ù ƒH=(xõ"“Žü{ÒõïG´™ô9¥ç9…/Ó4œwýMäpsøQ“ÐQøþ”øÐÏcI’zÖ—o½Pdâüésïš0{Ò݈¾E8qÜþtqíIϵuýh}yň¤ëßð§}häw£>ôp(ü(úâã×õ¥ü…'ø²(ìhÀÍ/ô†Äþ4g=3KŽh?•¿•?:tⓚ^ýZMÞôqМýE/¼Òf”PGéEPùþT˜ç§ãJ[¶yúRОzþT¿LRtö£ùPŸSúQ×½/ãúQÏ¥'…/ãGëFs@Nô~$~”QÍ&f4¸Ïz2~¢ŽÈ  Æ—çIÓš>”¹¸£¯F?…ñÒ€Aõü¨ç=OÒƒFsØÑž;ÐF;óùÑšNsé@ ‘ëùQø‘F ÿ8 óÏ­&r{þx¥Ï©?•óÒ€”œ­'^2qô è{ÒåO|Ò~'ñ£°Å/ãGZLc¹£9÷úPýõ¤Á>Ô ûb“ü怵÷4™9àþ”ž´uàRã´qêhüèç¾ii8íÖ€ {š1îhÆhä{Š ? ?=èÇÓJN‡€i~£4tõüO­{Òã¦ÌŠ8=©)ÌÑŸjL 䃚1Ÿâ4rLÐA=•9 dûû‘FsÓÚŽ(:^ɦ•¨Í/œ{Ð 9ô4~Ÿ…ç“AÈì(™‡çJúRP9 Œt4 ã¯JÍ/± Bg_­ôdÒ—¯­|:ÒqF~´\íô4½óMÉúRî¤1CØÑ•Ï¥öÍ!ç ñÅ1 ÀëøQž:SqŽƒ—·QùP1sŽÿ¥”‡ð¥üéAíúÒþ&×9¥È÷¦dtÍã¥Ï@M'>´ïÊŒûŠ@?8õ¹÷}MúÒ~tïÀÒ:fŽ1ÆhJ?Îhè>õžœQøP0ÏùÅw4~4uë“øP È=çI׌äÒõõúPxíš!ÈI¥úñ@>Ô ÿúÅzþ´d“GäÑøP Ïtì)>”½8õ aœõÈ£­zš?:0iy¤ühÏ¿ZCžß­'>§¼ôÁ §`)~´Ÿ…ìEHßJ23ÞŠ=±@}94?­&8ã4p\þî½é>nÔdcÂŒCùPsŽ¢ŽH¥4f€š8¥úÑí@„Á _çF8àLC@ ǽÑÓ¥Pw¥çÖŒ×4tõ çÛéGhÀŠ^;P~T™é R;Ðî”aO¯çIÓ¶>”¿…&(ÃzŠ]Ã8Á£è9 ÀõýhÏlΞ@*O½/Nq@ËœÿJ8Î{Ñš7˜ Eß•žh/ÒŒâŽ;~”{P‘×"ŒûfŒÖŽ(ϯcÞÂŒg¨ àv&Œ´ìvâ@ þzÑÖ—š(Å÷"Œ{Q@ÂŽM{š3@ƒZJ(Æ(£>ÿ¥s@}補õý( ŸóŠZ)µ¹úÑ@ÏqFAã#ÔPþqG=€£¿CG×ô Ç­7KÛ¡Å&}3øÐÐði>¹¥äÑŸóŠ&G\ Bsô§} 'oj>ôqßõdtæ©ü(¿y~‡µM÷‡ÒŠ@/áJÒÇ89ö¥ËPŽúÑÇ ÇÒŒ‚Mç®i€„ƒŠw>”œ÷dwoÊ€&ŒCAã’JL.ì÷úÐÏ Ï| _§ëFÙϸ£¿ š€ ûâ—ž˜ãÞŒsÖ‰ÏNÔdž¿¥/Ÿ¥'#F(ŸAÿŽÒçÔfŽIÈlŽôcÔ ;ùP}—>àÑÿüÅ(ÅFsÇZ\1ÛéJGûGJnB2(ÜGnGåMãÓÞ€}³@ÔŸÄS±ôÍ'QÁé×½é@_z0}.Þ:Q·Þçæ?8`ŽÔ~mõ BgŒ ­ô4vÆÜ}(ÂŽÄP9ŸÒ€@þ´@êM°A#ëGÞüèϨýh<úZ=ð1ìi8 dŽ¿§4œùö¤uü¨Àôæ€ïýhÎ{Rmö¥Ú;b€¸àçK‚;ÑóJ8Ç^h9=…ë•LPsôüiG¹4 A€1ŒÔ¸÷¤ïÔ¤{~\P âŽ=hç”c=MqØÒþT˜ £Û4¼R~tqßùPN:ŸZ>”`ú­ÏøÑÀõúƒ@Ï¥ð£$Q¸ÈýhïíIǵ/½!'¾(nà@ ÀÔuÿëÐäQŒv4céøQƒF íGN¸ Ç=©zúQÍžôp1Hrj\c§åF¯ŸJ?OÆ—Z:Š3ŸÿUé3Ž ãÛò£ù4½¨O‚=åJ@ïI€:΀ ŸL{š>‡Š\žØ4sŽh9?Z0ØéùQó²(#µ.x ×¥=E 8íŠMÃ<Šw^1H>” “ÇOLÑœ….ëIƒÐf€ÉïG§j3ØÐcÛŠ1ì(ü _Ê€—¯ÒŽG¦(æ€(ë×ò¤ëÛõ£ÿ8öJ^=i½)qÚ€ ŒqFEwëKjC‚zøPGáA^Üb—ð bR`žÂœG§Z1èhß›ÿÕFM.}è4cüâ“è?J1Ç_ÖƒŽçñ  à~Tg=• ç$QÛ©4QŸaF{có ûøP1@8à‘ôwç“ïI•ÏßæÇÆN¼~~™`p2~†”ñÜæ€<{})yÿ"“­&Ñž¼Ð!ßç4Sp>§ëKÁêØ4´ž”€ŽÇ4¼úþT õsëG^Æ€sÐÑœŠýt”€wçIøI çÀ(çëH9þ!K‘޼}h9Í{Qž8"€}ùö @~´œŽÔ»sÎ?1øÐ{qG^Æ·<ÒqÓ?ô£>”¼ 2~”LñÀÅ'ÅŒý)ßR);PŸ¯áF}èÆ:ô£>üPž(ý)qõ }M9¤Ï¯åJ8ïGá@Äãÿ¯@n}qíKŒžzÒýH AÇSÅ“ïIßšQ×ü©}†)9#©sÛ?ã¥/>´œþ4£Üó@(úŠ(íͤàuçéFG½/ ÇÔpyþ4ò &sÛ4¸ø@£ç4Ÿ@Æ€ðÀúRgÓ?÷?J?Z>¢Œ‘@ÉéúŠ1ë@ øGnåK‘œ03ëô  è?:2ǰÅðô£<ô?Z:»ÇzLã°ÇÒ”`ò§?Z3“Ó?A@ëèhvRž~™ çן¥è~¦›“ÐóK“ž¿…;ç ñÒ“ŸJ8Ï?Ê€ó£üô£\Q@ƒôü¨À P€; ÑϦE´™öýh4vÏ4pOS@ÄíÿÖ¥Íc4qïF0:FG® 3ì1E( >˜£ð¤ëÞŽ”¦(çÐQ{þ”d =¨÷=hÈ4ì Ÿj9÷£>Ä\ž›³@ƒÒp)Iê nF1Þ€ûu£õ¤¤<ŠSœtôÅ&:`ý(Ž ¥ãë@ Èô4 LRŒÇë@ÈeûÃééE6o¾¸ô4Ràôâœ09ÜOÖ“åìsøPÏõ àžs@ÔÞ˜ù(Áé»ëÒ˜ Û¸¤À8äþtciç“õ¥ç·œƒÙöÅwÏáš\·^~˜£9ö =©9=ãëKÁê2}èçÐ .Iêy£§ øRm¥Æ=@úPsëIžr)@?ÞÍô'ñ ÈéÈÑ’;ñKÎ9&€IàùP0úŒý(÷¨Çlõ ä÷ žäÑúQŽ:f“žÙÐÐ!G§êhçñ÷¤ëÔþ }Oç@Å œd~F”òi¿7BßìHÅá}žŸ­qŽ Bëš_mù`täP7×z:ŒdÐ1ÜŽ3ùÒuàÒ`c±J:a‰'é@…ýxúQÁïJ=3@ Èé‚(ÈïGçõ£ñü…ÉÉQõ£ÈŒw ú怨<#߸îGåIóõñK‚{Ð:v¥ãÐÑϨ4œzБê(ÀÔŽ3ØûRç=0h{ÑœûPÀ(óG=ÿúÔ¹¾=¨ÏcI–ÇŽGPhš;öÏÖ“ß4žÃò È?ç4gĤÚqÖŒc˜š2=iFOpÖŒŽÇZNSÍ/¿4cÔñG¹ü(ÈìqøPä <ñMç±4¿˜ ü9úÑ“èsí@ú °'Ú€ çÿ¯IǶisžœ}hæ€ý Ñô£“ÜbŒf€Ÿ\Ñ×Ô} sëHn4ìRAÎGo“æ2hx”s×µÏlç¡ÍÉÎúš…äfŽG ®húã~޽h ‘FN{ÑŽxÀ¤ç?Ö€Ž)9÷¥?Z&zsùPqëùRã>ôdÑŸ¥öýhŸZ{@ô-KÏsš:phôÎ}iqŸñ¤ÏJ2Oj]¢ŽØ£¿\Ptô¤íÈ—ëGA׊;õ¤äõZ\û:öÅ ÔÓ¹¤PF{Òtþ,ÒÑô ϵ³‘KÍç‡å@â)1޼ûRüÝ?¥'#±4nôVŽq@É$~¹¥ÀõÍ'nGëJqô¤À?JP>´ 0j0GAG×4c¡Á?hãµÅ/#ÚŒs@ÆÎqGáNëÓŸ†M§¥/8Ïr;bà 9ÏÝýi8'Nôì}i;ÿ* ‚ô4tôÖŒÿ £PhǨŸ† P=8 þ~—ßzš3ëÖ>ÔœŽÔ¹?ÃÇÒŽ}¿@ “ýí)Î:3ìáIŒãs×½š0;uúQŒñ@ñÅ'ýÚ]£=9£×ó†çš0;¨¥üJ:u LÀß"Œš;ò?* ŒÑFG\:Ð11ƒž(¦x´›FzRíZÆŽ gëKØGZGj3è? 1ì µ'¿œdtçÚëGé@ ÈíøÒŽ}©qE'ך3íGãúÒÿž(3éüèàÒã4`Ð~Ÿ(úÑøŠ9 bfŽsÔQÉúRýh`ÑùÑ×½´p:Ñÿü(ã¶(>˜"ŒÛò£J?(Èõ£v!Áê:R¯>˜ >¸¤Éö¥ühçÞ€¯Ö©¥ëÞ“'·Z:ñøÑGZ^hëÚ€J?Ù§w¤#ð Á£`{æ—ñ Ï ?•ÇqøÒõïÍ/á@ çÔ~T¸8ëù\}(Àö ñÜóGn£ðê9ÿõ n8ç‘Híšqó×ëHF=1@ Ïû8¥Ééô¥ŽåI~hG .Gri?äRó@ {ÒŽ´géõ¥ÉÇQ@ øâÎ):÷£ñ ŸZ3íGãK­'ãÏÖ—>ô˜Ç­.1@Ä£œq֌џzö ð; ãŠO§ò >âƒÇÓéGùÅ÷"€þqAúâŒw£¿Z2}E&M)Íë@8äçð¤íÖ”Íyë@~¤Rgަ—?ã$PxÏ\Ñ»µ;ŽÄþ“šN=¿*)ÜúÑœõ© NHãð¥çÖŒƒëùRqëÇÒ˜Ѱi~¬)0 = g?:ý ³ýõú”RFIÏOj}06}ÐÒç¾1@ùG%‡âi3ž‘ô p9õn<|Ãð¦àë@'ÖŒ’Nø¤ç¯Z;wåõ£ œf“‘ÞƒŽ¿¥ ÉãŠ>˜£ôgHÇÒ€ ŸAKß’sHsŒî£pï@$úéyõÇÒšH¤©àuëÍ;ÃzÈþ”cý}èÉíŠLàö 1¥?_j~¿JCŽ ~9£?PiØ'‘Å&öü(Éš:uâ”íH1ØPò?ýt›€íÍ.;ŠNsÈ ëÛCIÎ{R|PÞ‰ÓÓ4´Ÿ0ú}(äõæ N=½é9ZŒx’=1FÕÆ?•/nqHr{þBŒg üiÝ:зáG'¿uêi:wâ€ÿ•öúÐ2G8ϵSùÐwzÒrzãüÑ@ éÁÏÔR©¥æŸ\Pz¿­úуéùBGlþ¹„}ipÙéŠ1@ Áî3ÚÀwŒ~4¼ûPÝüèã=iy¢€€O+KŒt£œqÓÞŒç½!RzšP1ØþtbŒ}hÇ”˜lpA¥Àëü¨ãÔÐ=Î~”và~tnÿõÑùPߥÁ¤#ÔŠAìH ühϵ&qïG^¸ ççð£4hèh ÷ÏåI}isÉ~”dúPtçúÑ׊^”˜nøÇ¡þÕ¸Í/^ô™ôÅôsØÑÏ©4¾ã•& úÑózƒKƒþM'¿4~4¤g¸£Ö€ý8£Ô½ºæ“¯úPA§õ¤ÆzdÒñÇ"€1ž¼Ó¨ïŽ”d3@N9$Rç< àÐTûLc© ~´¹= ý(Á#– ¨ö£`Ñ?‹ó ¥&Õ÷üép¥Î(ϧë@=MŽãœõÆ—'Þ€ wÇähÎ{Γ{ 7vÅäÓºæ“8E&N;gÚ€žÇ…>´g¶áFO®hävÈúÑÉ=Å÷"Œûñë@ ;ÑùÓx×ëKœŽ™ ¿Z:ñÇÓ4cüô¤<œÐóïIßœÐ[Óõ£§΀Øf“=y¤Ç¡þ´¤ûþ”½=i_ç@ zš\ÜPÓ×dt oþº\j_ÔÒrz֌㩠ò(àÑŽ¥.}MýhÇoëIÓ=OãKÏ~)2Ýé@QÐQÓ çÞ݉ Ò‚Ö€ß&F{æßµ!8î?*Q×£ê)¸Ü4¸=J\Ž ÑÁãƒG$u ~4p(Ï¡"Œ}i?:\äƒùÑóQœQøÐj)8ô¥ãg­78Î ;¯J3ï@Àò)>„þT|æŽqþ40[ÔÑ‚?ýt§ž£"Œ€åÏhã®E/ã‘AŽ‚€®hÀ÷úÒþTsë@ÄïŽGÒŒ0÷¹¥ÏbOâ(úqøP!1Ï'õ¥ ÿ]84@´`wͤã¿4¡pzš(ý)1õúP1 1Ï\QÿU'éõ AÔÿZ8ÏoÀÒñØÑÎ8t Ði¸ã©Ç½(c4„v9ü(ÀèsøÒŽô~'4˜ôÍ}*\óÒŽ=IöÍ'»­.Ž‚ÇÔcŽ”cÌÑøóIùÐ’§ƒFqÓ?J9¯áIߦ?.O÷qøÑß¿çF8çñ£'þ”Ÿ¥ç”}ISEsÖƒšAǵA?Z(#±£#ëïI׿åK·?J&qFyéKôæƒé@¥Ç1øÒdtæ“|Їù4uéIzgéHyõ c¸Ç½{RQמE#½ô£µ}h£¡ëúÑǽ  dQøÒ~t ;qGÖŽqÍ(Ïÿª€ dw£èOçFsŽhéÖ€×4¿•L^(çœÑŠAþy bã'¯åH}9ëØÒðE4ð9É>ÔÉçëO ãÿ¯MÈéÍ<Ù¤¾¹¢ŽÔÜa³œJbøR~ž´¼v¢€q“J(>¸¢€ Ðhüi ö #Ôqõ£Q@1Ûõ£“ó¥Ç° ð£ŸJN}¨Àï@èhÁÇZô¥ à1ì^}@ö ûã?J? :õ4 c¿ãIŸoÒŒy~½úÑÇãG>´œPü½ J\ãéH2:ô¥üJ:ú~4}qøRsïøÒçþº3Û4bŒã§çHNE/4sE¥Ž(ç½g¯4@Hãi"ŒûRÏ\~T¼ŠAëœÒóF)8îå@ Ϩ¢ŒÒ>¦€ gi2=h=zþ™çîñõëAúþtdöëë@ Ó·åHxühùÏñ ö™‘J0=éN}úÒ{àÆ€qÚ—ñ£=ð(íœ=¨OcJö?ZLÚ—¨ëH óãzôèzQKq÷—>†Šp÷ߥ(ü ¤ÉÂiÄA<~4œž¸úRüØéǵ.3ÆãF9'ó¦>†ŒNhÀúÒðF lR`ç©ü)ÞÀÒsÚ€ FïQšúQšÏ;iHö¤-í—wµJ1Ïó ã9çð›‡`ÄÐþ¯Z1þÈ}F?Z0 ãšOÃðÆ)qßúÒÐH À>øíGËÛ?ûÑÞ€¥zu£ó¥ü(? _ÀÒ}G>Æ ÿúèÊ÷ãñ¥ÏÒ“`çŠ1ì?*}@ {â—Œq@ úÊŒŸîÎŽ{‚ \t Š:})> Š\c  tè? R3ÞŒŽi0QÅz1íFaúRç×4œQ׿åFG@y¥Í'¹£>ÜRõ£”™ôýi{zRþ&€·Óò¥ç×ó4cò÷4¼Pv÷£"Œ³š9ì´ :žŸ.}é1ŸájQÍ{b“ éÖ—“æÏAj^iîÄQǯæip}¨?Z23ØôÏNhËt~t`ÿt 3ž ÑŽ9cÒƒÁäŠ3ØÎÁíô >” N{óõ¤È"€ôýiA'µ(Î)\¥7÷¨ëÞŽsŠ:Ž9ühïÆ &;J:zþ4œž£ò4e½¿*:sŠ\Žœýh÷Í=‡çHO æ£ÔñJqŽh8ëÎŽùþ´¼¢ŒÞ€{àQÜ~Tr;óô “Û•.=óøÒQÏùsއó ÔÆŒØP ô¥÷Í&EQKÏ­o¶(Ûõ§~­&9 gãó¤*lÒò:~”ÆpE'N8¿\bŒúã4|¤æ€ØQôüiG°ýi3žÜÐã¿ó¤ã<—>ÆŽ£§ë@O¡¤Éî¤Pp:þ¦—¶x4wÿ õçëG'µ&N:Ѐaí@ô]¢Œ}qíAŽŸúþ´;`}ixëƒH9ìh~†“×Ö—ŸJCϨ41@ úŠ\ŸJ>ŸÎ€çG>£=é6ûçêip=s@¿•'~àhÈéüÇÒ€À}(Ç¡Å/n”‡§$ÐŒž†‚9éùÒu4¸ÿd (ç׊ÇJ1Í%çÛð¥ÆSùÑ×ÿ×@ œçõ¥Ï·ãG#ßñ£û¹4}hí@µ{^{Gµ&)1žä} :“¾i0?N3@ ƒŸ­÷{ÒÇËúЃG¶áF=@ü(ÇP~”uëÅ'¡æ—ñ ð¤Ï©Ú—Ö—‘@ ŸlQGœQÛ¡üèÎ1Íã¨Ï½×—>Ô™ÿ ÐI¥Í'>˜ b挟QI“íIŸCŸc@…$úŠ0 ëÈ£·8ü(í€ã@^3Í'^CK’?ýtd÷4 N}üiy£Š=ñ@\QøQÇlPÐp)3ô?¥.qK“ÿë ç=£4¹úP =…4AøÐ@ïKÞƒÇoƇåíIŽy<Ð}ÁJ\{æðâ“éüéqÇ4;þ”qF1Ó§ £‘ÐP1LÂŒŸj\ûP!8íKùPq׊1íøÒÆ{I׌þ8£¿i aו1Šã×§ëM ‘Á•)?þº/â?:=ÿúôœŸJçM¡¤ žô¸Ç;h?C@„Ç®?::ð£#¿Æ—ŽÂ€Ol~4síKŽ)1ÍöÇäh%‡cøÒžœb“ŽÆ€›ÓsKƒëŠO›µ÷{ÐÁ÷úRûÒÝÈ?†)yõü(ÏåëFï¥&zKƒéšîI£<ÑÿU…Oµ.i1Í•.GÒ“¨ëš\QþzP1>´½:~4”té@… œRdú~”¼÷Çá@ÄÜ;Òü§Ò“§aùP >ŸÖ“ ôÀ¥ü±IœtÆ?*CÆ2p}éÃŽÂŒ÷r9?¥ñ#ñ£ŸJLûRäçÿ­@„Èþö? PAr=E÷Í 8ãF=ø£éGAÅ£”Q@1Gwõ¥üh:w£SGNô@E!Çÿ¬Òþ´}1@ Ïc¥=xüér &vÐÈ÷ ôéúÑœŽsô¤ÁƒùÐ})zö¤ûàj2q@ íšã­&ãÓ´sè(íÆ½ÇSFGzPÞ„cé@F=~´œö}isíGå@÷Å/½&M>´oÖŒñÍ >­ŸÂ—œPæ“9éÏãIߊ^}(Ééš?Ö“è(ïë@ ÀÇsA=Í ô£‘@ͦœý)6çœÐ1ÙÏjBáÇÖŒüÒ8Çç@ƒ#?ýz8ÆqšLƒÎ?hÎ:t÷ gŒšLdt£,O&—Ø ÉÃÇ¥ø¥çÔQÏr(íÜý(í“ÓÒ—çó£Z'F¥ÀìhÀ¸>¢€+Üãzóž ³ýåú)¼ôúÑžìÆ—†”Û Ý‘×óâ®ÜûSÆ3ÏëAێ߉¦ÏlƒùQÏP¥ùºñ@ 8Ú~¹¥Ü;gÛš\qÔ¥!Èèh'ŽÙ÷4‡=°=èÈö¥Ï?v^¼ûÒóêqIœöü1F^ŸZP} & 0zŽ”™ÇÞ?L p9õ¢ŒúIœö ¡Á4¹õ4FÙü¨~ǵ½qô¤Ýžƒò Bî=³øÒn=Î(É~&—œä1úPgŽip1ÎhÎGOj ÇoÒ€qE&sÈ>´êqøQÁcñpx?…)=ÿ:BJƒÁ?Jã‘zPÿF{uü(üEŽôtÿëQùš2£Ú—éŠoÍïG¾ )_ΓúR€{bŽÜÐï€?\{þ´œv¼öÅ&9 Kô4{qõ¤÷+ø Z2SGùéFh2;hxQõïKš2{ÐF{dRúóŸz^£×ëF~‚€ß$ÑŒõ¸Ï” ÿ‘@GsH[ß­.GNhçÓ"€$ôÀüiö£ð Çÿ®Ž}(ç° 控”nö?…¡"€žý(ÆzÒô£·4ݾƒõ¥Á4}. %Ҍގ:Pzt£9éùfŒÙ'Ú‚>´s鯂 'ü4`wÅ;bƒ…£ò¥ééš@Aõ¥Ï¥=i9úŠ1»×ñ£­'Áãð£w=¿.pzþT½}i2$Ê“ œÔP‰ÇJ9=ëIÏj>§J^}é2qÆ '~r}©Ýyçñ4núý(Éô¤-OΗ“Ïò äŽGåGáGÍJ9õ4têGçJ9õ¦îÇðŸÒ—ƒë@ ´ûÒbí'©¥è99 ü©>˜÷ žàfŽ£Óñ ¿ Ñš?õé@sÓ­·ÿ®Œz(Å÷Å׊AlÑÓ8þt£¿/4ƒ>£4qÞ€ c¶O¹ }à‘A¨úcc=:уŸ­.u Æ=3APz‚}³J1ž!ÀÿëP‘Ó¡¥¤Î:hÏ=2=hçüš^Ý(ÍZ>†›¹Å&=zQŒPϵè)x£Çë@ úÑǧéKÈÿ 3í@>„Rð €úô½œuÁühüE“ÞŽ¨çڌڗšOÊ€ RqKŒŽ”P0ù»RsGéh™ÿ9£ÜŠ^=)3ZÏùÍôg?þº_΀§LRuâ—"—µ&ÈÍ. íIÈ<ŠúçëG=†(ü3KÏÿ® ÏsGAŽqFxÅ&Õ‡nØ£ŒRpOñCùÐ!?(=:P[F) ÈÀÏ4 \ö£æõt£ŸîÐ ÉPHïE㚀 è}è#wP¤}h¼÷À£éI€; ^ Ï@=ù ÚŒ{ŒQƒ×ŠwÅç­éG>”0G¥~Ÿ…):tãÜsKŸJ3ëÅ4àýþM8Güé3Žô»G¦8ôçó£¿ÎöâlcéHc²sÒŽ?ɤ dŸ­”À^j1IEgטúP?Î(q@4Žó£4§ßó¤ü¿:3Ç\ÑøPÏû?w|~{ŠQŒt‡Ûñ¥ü¨öÆi3è1@IÆ)s“Öš2O ~Tï®(£8íGÔÒqÔP~€Ð ëéKƒíIQš@8áOâhÜ÷"ŒŸj@qÁ4sŠR}ÅŸ•-J7œÒmæŽM.isMæŒzгïŠNÙÀôœ”™çŠ\æŽ=?L­7©ãìûþ¸¤%ñ”>¸tç4g= ÉÏ-šPFzfƒõ½³Ò€-ÜqGOoj'€>´vôúšQŸP ;àâ“úPëÅ/µíÊŽ{cr= -€£š?:ñÇçHzsÒŒ{R¯ZLñÆ?Iéž½³NÇ¥7ðü¨÷ãð¥•&3Ò“Ÿ¨ 8£èhμ)Çj>˜úв{~´ÝÃ9ëøÐAôçÖŒàsúŠ(#±dý}é2OpÖ— BsÐùRŒúÒã·SF=€ äôȸ= LSºuý)1Ç È¡”Ž~”¸ôŽ~” @OPF>”}zÐqÜŠ;{zP üþ™£qùI˜ÎÞ=Í8}E ¸å—Œph¢¾0sÁ¢õ4`ýi¾ýéÃè*PÓµ@êx£“éFíšb#=Hô¥çÆGçKÛ°£¡ë@3è½Ç^1I‘Ü~´¼Ž˜#ß­ çŒøÒãÜb“õ @ͯzL{œ}h æ—88 ÐvŸÄÐ=?8Œ÷¦àgœæ€{“Š8Æ7dÓ°1Ç?J1í@Äã84gœw£Ù¥ú¯ç@ ŸL­÷OÖ—ã˜'Óñ BñÉ£·RGÒ¿ýlRmÝÔ@ÅÎ:ñKŸ­&£Ö‚qõ4~-J0:šB?*0qÁÈô4qÑhÇ¡®ã@ íš:úR`ÂҀƓ·j:÷£‘êhéÖ—ßΓ8ÇøÒuÇ4½hÇ|sH[üh<ÿ*SŸZ0qëA>Çð¤ã΀{€)sþÜã•.=ÿ:_×ñ¤ÀöÅõëK@1FQùÑÀÿõQš1ëIÏ·ãFoÔÒÐdÓð¥ãèhéÜ~4s@8È£uâŒ{š1¯¹ ägŒz\“ÓRüÞØ£­'9ÿëÒã>´ŸLQÏZ\ 1éH3×úÒ“‚Å.îsJ3êOÆŒPã=¨Å'lþ´vÏZ?:1ž¹£Ÿ_Ö—ë@ ÓÔÒžƒ­)㨣ƒÁ Àäv£ 8 †9|½¨ùŒ{Ó©:rGëK@~£ñ úçz B©CKÆhÎ:ñ@ ×·>ô½Fr)9ü(Áëüèsõ£>ô`QøÂ€Ò–’ ~c4 šLýh¤êGˆ¥Ï=ç4sîiN¤Rþ~&©£½cŽ)?øRçÚŒçÓó ühÁô p(Á 8îqô£¾N(Éô4‡# c¿4wë@ÆsœÑ?ˆPÎ9?¯Ÿ/féAç8úQ…<äf€¬9ÞO¶(÷Å' ÷?Ç'?(ÁìOáFö™û¤SNãØÐrGÞ4mç= çï`úRóøPƒØøR`g“Kô 1É 9£žÔ¼÷£¥"“Žß¥.x†\ÒcáAÇz:f€c×õ c§Z3íF:r(DZ¤éÒŒc8¥ÉP~—…vãŠN¢”j9õ£¹ ì8íŒÑøÑ@Å⓽qÖŽÄPŒÑŒuf€(œ{})@£4{ !À÷ö~•-.EÖŒ{ÑøþT~t£·­ü( š1F3ÖŠBMç¼ç­'ã@ƒãEé@¢–“4sï@ÄÇ=)sŠ;õýhüh„úçëE÷ÁúÑÎ=h¼ÒqëÍz©¢ søSwcµ.=éh™nÌ);õÍ;š>´€zPÜŽA£JZonœRŒúœÑïÞŽ~ŸJ÷?…ºÑÉíš_Àþtß”O ƒÈ'´¸â“çùú\du¤ÀíAÿ\ÐãëGó¤àó×éFr:P÷ïH@=èÿ8¤ã¨P(þTgžYqõæ‚zu#Ú†>¿ühü@¥ãÖ õâŒ{ÑÍ)üh™÷£¿8?{þT JŽÙ£§8£8ëŠnyù_w¨ P¥ÀëɤÝíùÒ‚3Ö Œ÷Å}çNçµ'ã@8ãÚ“¥üéxíüè1Å'^£ŸzLŒdÐ1j3žŸ•.O¡?Z1í@ ×°£8=±GŽ}8õ äRõïMØS°hõéK:ŸÂŒQ’:P ã°üé3ŠZN{ŸÒ€¼Ñ޹þtuìh…sŽOçJ94wÒqé@ ùþŒÙüèÎ:Rdž¤nôïÆ’Z?>´}ãŠãK“ìhùˆì(ëëGn8ü(É=…`Ò“>§ò¹ô ¥(¤Î(Ü(þt~$Òn¡ÏãGÅþ4èi .¦E ö €L~~Ž(úiH=Èœ :ô8ü){u?jNLÒ`Ù??¯sŸz2@æ€h#Óð£jžÙ¥Á4gëùP`Jî)¸úñFHô4`g Í!?\ûRäžF)p1’(£#ÔýM.~´˜ù£å ” õè›~¿>´¸ö¥üÖ€ó3AÏ©ÇÒ—ñÏãKøšn=Í&>´üzóI@ ÛîhÇçNç¶ÔQÓ© Ó4¸ÿ9£ëFE&Þ)qøýh'Ôãñ£ƒß4 1íÍÒŒzÒí÷4L~˜=ºS¶ûQ@ ÒŒzdRä{ÑøPsÜÒ(£ð ò=~”¼ÆŒPpqÎ \~i>¿Î€ t?…4móKŽýèíIÀì \{ÑŠLc§äi~”qÚŽ>´ŸÎ—ŽôQúPÍ& §QÍ'#¦&=©ÔP:Z)¹Å/áI­ÿõéyîh¸üè£ßµ…ïG#Ö“ó öó údQùÒg¸9¥Î{PøÒ`ç¯éF(Å/N9Ϧ(ÇçMà þ—nzòh}r(àÒy£h`zdPHZ0NOÒ”t J_ÀÑøqGÒ€ gÖŒÿ]g°£¥÷£ð(Æyňü(ühç×ô NM¼zÐz?J(?äf€“o·ëE…Ζ“ñ u4´˜¢€ Ð9¥âŽ %JZ1@ F3ÚŽôc='>£ùQô&—Ô { P>jN9ãšž”¸Ç@(,SKÏqïR~™ôÎ}@£¹•?ð¤Ç=&?úÔ˜=Ž)Hõ8üipqÜÐcÐуýãFê)Hõ üõ¤Ç­.LRí@ ŠB9ê§~t`uþ”˜ô?•&Þù4î=(÷Å&?É¥Á¤æƒÛŒþ4´€z0?É¥ ziOŠM´QÅ-'8éKùÑÅÔgÛšAøQìhëÚ€aF? OlQ‘Ú€ƒŽ3úÒ~”‹ùQÓÿ×IǵÐ!iý?:“š1F8ö ¿z8ïKŽ(Åô¤ÅðùÑúPâÆ’Š_Ö“~´vû´Nœf—ñ¢ŒP0£ô¥Àö¤À žÆ‚ ïùQz)€c¹üih´ÀN½èÆyÇëKøQ“ÿê Z3õ¿QI@ sK´çï{Ñ“éGQÒ€ñ£ñ4ïÊ>¦ þx£§~(Ï¥¸ aÏl>´b–€Ç¥õãÞHp:Ð <ŽhÀ=¨ã± Phc>´c—·ÿZŠLOÎŒSô£˜÷£”¸£ð £š\{QŒÐwëøQÅ.=ý '>¸JB£ê)ÔóÒˆÏéW¯Zyú~4ÌóŠ`>ŒP( ŽÔ´œcµQëúÑÇLÐF=èÇÖƒôâ‰øŠ1ïKÇr1GZL}sIÈíúÒãJ0;P ž£î)¸ö¥ü(¿(âŽ=¨Ÿç4síùQÅ/ã@ÄÆzÒc×ùRõä Ö€~´¼ã±£š8ôZ^)?/4N;ÒmÏj^M.(¸Å…;ñ¤ÆzPϵ&)pGR?*1ï@ ôÅž”¸mäPQÏ|PV£Ó4qG^ô`úñô£´ÈÁ¤ÚsKŠ(ÇãGNÔgþªJ3Z3õúš?/ÎÊ€½øúQÞ—ŠO¨ Ç˜9ÿëQךpÅ4æŽ{? v8àãð¤Àõ ÇcGùéKž) _ZN}Oà)G=óõ ;þ™£’9Å'>”m?J\wÍÞG4£'µ/CÐÑõ Á⃚P¸ü(0Þ¼RsÜñëNÛžhÀÇJg^‡?…#¥8íéÈü(Àô ý3Nô™²>”¸ ãÖŒG‚ŒØ €OCF©¥Å˜±¥£ð P0£üõ£#Ö¥A>|ÄúéE>‡úQH÷¿­.qÔ€~†Ãñ §­æŒï RãÖ˜ Žùü*6¸ Ã+Œâ¤öÈ-ç²²¼aŽ4 Bý¶6™cRNA#¨¥Šá$žX×CƒÜÔ›@ÇÝöâ˜êW-„mÀ±r(Ð ×ò£“ßJŽ#F …w±Ò¤Ï8ÈÒ€ä Ë>6)e%X 1^f•ÄžP‹<òjTxóµ1ôZp£üô œuâ“z‚rz Ðþy¥ã8Ï5–6m—qìöÇé@½ÌQ»#Ȫ@Ï4øäI:œƒÐÐ@9!FqÖ’-ÛFáøš“ƒß4cÓŠNÝ? Cò©%ð£­;‘ߊ7xù~qÏOzMëó“Æ(øç®=¨æŒcµ0ȃ‚ê>¦€À¤üé­,hÁZUV# nšD²‚AÎ(Ü/Ö€ÀûRTÁ$xäâšfA»÷Š6õç¥IG›ñš…ÏlŒÓ™Õ³ª:“Ò€G>¦:”Üõ¤Þ€¸sÒüÏãGNôžiÉÛS@ÄÞ»¶†úÓ¸ôª±¥Ùáí'“Óµ`0 ÞÔXãGçIž8¥ Aùj:ž ¤8ëÇÖŒZ Ê£%€¤Ô_k„n̪võÁ ÎÙeHŒ{Ôõ tü{Q…¤cä‚1Æ * ?Zvcsîoœàqš›5U¡†"ˆ`Œ)RÀ$òGšAoP:Ñ f—>””cÞ…ëÖ£ó¢˸n^´îyFêÖ# qÈÀ9<ñíMj4ZŽî8Y=Å=%IQÃQU“O¶ƒÀ c¯jC¶mbUVÉ%@ÆiÚ=¡sñ¢€xè)yôýjI &Hì(•-&9ëøRãÖÆ€Ò“ëGáF2y  êhÀ=éhü(1ïÅ¥ÅzŠLÿú©=ù§c½ ç¹4sÓ<Ñ)h;òM)ã¿ãGó¤ëÜš?SëÏçGÒŒ0 g¸>Ô¿Ž=é9£ØŸz^ êsGãG_LÑŒz@ãEZ0=(£žÔt4„û~T¦~”áùSsG^ùúPþ4™õ¥Î?úô™ÿ R~´~géøQŽâ€ œÑEûb€:õ¤ý)phÈéš3ïúP~¦Æ—ñÏÒ€ϵú 3ëŠ=J¹4dz挌q@ãš\Œw¦ñèhäzÐæ—õ¤ëIÒ€z030i3ÏÝ&—>çé@Z;QFE žÔÏz2s׊\ŸJ1ëúš:(#¦)0:PòG½&ß~}¨Æ<ÑÏj?:: ?J_Ö€ôïøQúŸ¥…2s@×4½;Rcßó£ó üé ÍG;ìŒüŒùãf›m¤#jy|tÇJMŽ){sMãÖ‘Ž#$ö4¨®ª\ÜNêz ­Bm³K¤ã#ÿ­Vqèh`5ˆQ’ÛEן›¥Cp O(°ÈäœÓ´elñ@FÛpÙÝÒ¤íU$·ŽóQ² 9Ï5ePö¦íÐbŒ´…/J0; @.=¨üèüÿ:;ú~9õ 6ìàôëPK.ÇQ™Hä‘N†Ý!.PcyÉ dÝ}i¬È£sîM)ô8¨$B£WBprhÆê”Ê»Îw ‘:FܤdÄUi- òp#8\àþ•,I 8)€iéÐ ³E7Z1èOáH?! “ëKÏ­G7ú²v–öQ"œm#¦zPeEbG8ªñ[¤ˆ¬Êê@#óNûoÈ2§ƒÎi´ŠÐŸzîÚ:ѼnÛÆ~´Á «nQ·ùT7!‘]±Èõ#­µŸÂ‚À šãÚ¢¹ÿRxÝì:ÒPÀÒ7rj$*`8V1Н¼3å>h ÷‰ëM!Ø·ç&æŽTâ¤æ©¶Ÿ‚y|ÇŒT«/ïLeƒ€Hãó¢Ý„Oøþ})lRçž)QZ3Gç@æhã4}hü¿Ç­~f€KM¥ÇùÅô¥ç¸¤ÇùÅÅ/ZN¾´ôgÐPŒ¦²Ž ô¨…ÊyŽ„“­@×HñÈ@8pi¤ØXº:P}éh#ëHóP7®@çšv} g´I4òFHÈî§kU‘‰2KŽãv?•;g‚)yíüª!ñ,jXÜœš”ç¯4€S׊BÁFO—¢ªHË<æ1•“äïõ¡sŒÒMG#ˆPN*»ÝG"n=:Ñ`±tr8¤þu*]Ü’y©xÿ"†ŽOdgëÚ ¹dÚŒƒ$r´Å´ÑÌÒ6Ðzž¹¦—p-Œt¿Êª@ÐÇ;Ä…Œ˜²*Í Gò¦ý2?Fp«“;#§™ÁÆj |8/–<œn¦±IgÚ£­E€³žý¨ÈÍT[@ŠBÈø$ûÒ¶ÓûÌíNÈv.pOj2:S mRH8jªÇÊ™P°<€M+¹7c¿4¿ð#T ¨É l.Ý¡põ«ŠrÀûQ`FFqUâoUU-œò¥29U¯ ÿwîš|¬,]9Çô£ŸSøRgÒ’IQ³±áFM 9ïÍ¥TˆyêfIN$ŒsŠR#™ù©Ø,[ÔóKMV Ž”§>ô€ -'ÔŒzQí@…ãÖ’€=(úÐ@Æ8&ŠNq×£>”sôúPJ1š3õ¤Ç¸Å/ÐQÚ€éŸÒŠCî){P×üsGÔРûŸÖ€ÆÆŒQŠ?ZLæ“Ó4½¹Q‘ëI޼;t ~4ºÑô¤ë@ Ï­{ÑÓµ'ò çØQ×Ò“ß­)Áê3øP׎1F¯ ÆqG´ ùŘÍ;ŽÔCFOµˆ£­ ŸaøÑϯçI·ê(Â÷Çã@ƒŸj8&“h§åKŒw?!ëœG<ò@¥ÇÔRèO\ŸÆ—çó£tÇåFÑ@Þæ“ ѰŸ­.00Š^½('±ãñ¦œ d^£¥.\Òî¦óØQÈäóô q÷£ñ¤ïÀǶ(Ç®3HF \`tý)2éL.~òý \ýåú)(ãži*@O`3íGׯҀðÉ£ (ã têi€„ûÆ¡ù|ö;X6FOjŸ?äÕYN]×w¡þT!¢Ë0äsL•‘‘¨|uPyª³@[o’yPË:–Ú0¦Çyà)ÙëP²ŒtšbGÄÂo˜0qÒ­gŒg«G'–ŒòÌ[£¦ŸPìø –ØÙ'' hòÖ #sN7”Ü =š.-§¹ÜŽCíÁÈþ´% Ôµ1Ê…(ΧjbÚĶÖî4M°\#4¸!xO_zœŽô¶¬PAo'—dg5lgõ7w08Î1ÅOùÐõ¹FjHY&PùCR± ó1Ö™©ÈW GSH sì?:­t«?ú<ŠÆ7^qV¿Tœbàfb¹_º5¸!EŒcL|¨0?ΘÖ0¬<½ÁzsŠÝB™ÝëŒã4-Ìec“2p1Šwõ™#ÈB£¦ S·‚¨ˆe*à ¤cŸzžÝQmX,­ çæš,ÎbÌw÷aÏéOkØżw«É<¨oQO„¬wF±0É=±Š-B«:‡vÉ'œÿZ·]H¬ÁHùO Q~€:ä#SnF=©Æ92ŸiÚÔr„‚àÊÓH»ˆÊçŠÞÂP6Až§Å%{h5”6®³$r³)$IûU™ BΠñ½*¼‚hŽÉ×¾53|ö£çê>÷­7{jIr‘á19YNß”OZ‘¬­£Œ„”ääÔñ = $Ã|DodÇñRo°\m¬ÿh€Ho$b–æÝ.P,ƒ€sÖ’Ôæù·]¸©±OΓÑè'¹LEÆå>a•jrXÉB’G©öÅKóùù08+Ò¥Ëcÿ¯Nìw žÔgÔRçé@©$@sÀ_ÄÒà )3ÓÐ2à\Æ~rH=:Tý¹ZEss6r¸5`âŸBžÂ2+®žE$qˆ—hä}iÜ÷æ—$v¤ ÈÿõQœœàRdzs@#ÓôÅôéUnÕ$ò÷ç»*ÉúïUoq‹çTùùÈëúÓ[yìª÷aTenä6üjµÕ¥ôö¥bš4“vAÉÆ3íRÉÇ(šI£ ‚˜Á?5kî2Ú¸*sNÏ|qH:1ƒÛw銑šóM9îhSžŸÊϪÑI“íøÑÏãô RRa»‘Ÿ¥. 4nÇcKíH=ii2Eç§ë@9͸£êI¤ÈêhyÇ@h÷£éFí@@ ÊŽƒ¶(yÏdúQõëG'®(3þqKŸòhü¨öÅã‚?1ÏZ3Ç4 J3ŸJ3éFOc@){P=Å-&}¨æ—4™¡ ŽèéÔÑœŽ(séIõÅh '4P õ£ñ äÑ“éŠ?•ôýhϽ4g×wçsÓ¥/?…•!`:ÐÒ«Þ²,¤¢ dŽOZ±ŸZk q† ÃЊT³––CÍ!$g9«¹¤Æ:.(Éö¦õ;¯ZLQÏphŸþ½!{ 9÷ü(籥怟QŠ9éÖŒßJ;{ÐÒŽ4dúÎŒÐõ£Ÿò)9õ¤äôoÒ€žÔsÞŠ(ô£…>ô\ŒR}(ü(äw žôQÛ­1Ë;ÇŽ( '¹P%!ð@¡©„Ëæy\ä ô¦B¯´4» ¸ê´Ÿ7Ú‰.œ¯½=6(Ÿ?Jªî“ΨY•ãnËÖ¬œ•=G½V„e#;9éB-õéšNsŽjŸ•r]@*€}ÏëSC¹d²ï]¸Í ÜÉ.¬Æ@Ì@ù2{Õ®Õ¡™FÆ ÙêW5ŽànÅœƒÕ:QÐ nX-³“¸ýÓÏZX n矘Ô(’ÅgåÉ(yñ{ÔñTœê ’ÄRnõ¤ó8 3éŠBñ'ëHÎK;(P2Nir¼1ô¨.C…,¾[¦„AûÉLé.ceÀP?\ÕŠ¬±É …#HáG#šŒ­êäù±Ÿ<§oΛ°ËŒµ ®ÁT•ŸýîÕ(,GZŽeB¬Á˜ZB&üMTC¾eËíÉÉãò«\û~5 ³ –F”Œ…ÇJ"|LRô¤éÛ4sÅ.j9FcaíÚž}é“1¶×ÚqÅCd?ÑÀäà‘úÕ‘šÎˆ^´©&ø¶ìÃHÉÏ\b¦ò®ÈËw@ÏJ©-wE£ÎG5Zà*0vg=8Þ¬äã¯ôªÓ‰wîß‹Ž{Ô¡"ÈÉóøTW+˜Xo)î1SeŽ:Ts™|£åíÝÛ=(‘ðŸÞ3vÉÛAˆ€ÞÍï xba?w=ðxªÈ'-žYŒœ7ýz¥Ôeî=jºYöù¼–?/LÔR‹¼ü²D€°0ëVÕz ¼w–Á°þhç¿å@>ÿ¥é-&O§ãFÿõQŒwÍ!Í’2‘“œcšŒÅ,i¾K¶Îp£­%Î@UN稤srÄec ·æÈȪb9Ð2¶à{úÔ$,w;Œ–=; }¸ÄÜc€JhÜ'ùäR ùAëGP'íßí7-–b@‚§çÞ«®ÿ´¾V5\Œy?ZHH°z`ò)x¤Ï¾E/lÐÐp(ÏŽ)¯4~$ÐŒ½{Õy¶ÄÂF›bx>µcõ¨.¿ ˜ç'Þ„™HeAisÛš ¥>ÔM8î¤-78Tëè"«ýÛ¢w»ŽœþudŸlûÕq¸Ý±1€6ýð¥6rx QΧÊû@둜þ/?ýqQO¿fУi$¶(cUX×hQÇðŒ v7®0¿ DƒS¹ÆO0!´I"ˆFò@ëV“úÕ{TtŒ^qøÕ޼t¦÷-ëHAŠ9þïë@úÑõþtŸ)y d )3è)r Å'¹þœú‘õÅ.}©3žÔ¼÷Æ>´¿7£Ž¿Ê€ð£ð4v£‹øRgØÐhüèö j>£Š(uïš9£½ïŠ2h<ñFO¥žø `N)3êhàzRçüâ šPsßô£4™Q@ “FO¥=†hÉô aøQj4¸æ ÀíG^¢—èö Å/‡9éøÐHèzPøÐqÖŠ1@½&}Å/ù¤Àô œtæ“>‚—ÂŒ(2ÙÅõ © {çñ gëIŒÑþzÑ@§4óÅÇ Ñ@Åè;QœðqšOËò¥ü(8¥÷Å£æM̈}ô¢‰¿Ö'ÐÿJ(@Î)Ozýi3ô¿J0;±F@ï@J>´ÀL¯|Ô$3£!ù¸?SÀV‘¡K¸Ð©ÞüäŠkpE‚21• úН¹IßÍtØXìP;v«9ã­U½±ý¡Ùñ,Tr) E£Ó°5Z8w–ó=„tÇ©`™g$@ʬ8Èæ«$ñCvmÞGf  ÓIì4[òc Ÿ,g׆(Œªp¾bŽ=EUMR6‰˜Å.UˆÛ´žé°ËÍó8Iª¼"Ÿ+ %RWrª³™¨‘®Kɽ |»IÍY.Pj˜Ô ;²®b£å<â’¸ØEÞP¼0îîwš¿ùU{›yîŸnD›FAâ®g;õ –B\qL„lÎåE'©­Bob¼…\ªœ)¨MüP7ËÒ:ar±ØÑÈõ¨%V2©U^œÖ âhòÓèsTï• s|ÎÙTÙòýhµž¢Ø¸m¡$“$œŸ­ÞX„#vª¯ªF“@¡’Q÷±Èü:ÓXåh„s}à¡¶€éš|²™ycHc+€9<šeºá8T þÏ¥&ß*؇%—i$ž¸¤´hZ,E uTs2à!CÁ Þœ¶¶éb@ ä g¢¹’$®ìp ¡5\í1¸m»°hÖÚ3A S˜ƒê¢’d¨èÎRKô½ž8£Â²“æ€ÕÛ… ñëŠN-nG€w³I6ÿ%ŠÝŽŒx¦ZÏñnŒ’ ã8¥¹O2ÞE˨#ªœâ{…±o!rŠ¿îœÔ™¸¨,T-¢ÜÀq’0MXù½@ö¡îr,‹ÃÅOÏZªó­½ÀGüÙo»ÀüjHnÒye@LMƒ¸`,ìüHÅ'²isøÑ×ÛéHBqØPsïKþzÒgßš­*±¹R#,õÝÒ¬ãŒúU[ɸ729F¿2ªn?…5õ;hößë+Û5VmhQn@Å>RúÓ-·ù æ2³ãï)Îj¯Û#š8†Ò»Î$qþ5n$ò£8¹¤Õ–¢±/ùëIÃråUî†è‡ïH ‚•VÚt{¼‘°¼ôÆ ¸$iq늆â=þ^c.sÓŠ›?çJîTó,BIæ…¸"؎ƪÞ`Ì_÷‚œÓ&Ôím¬¾Ó<Œ‘÷I?¥>9…õ¾`“Ë9êFiòµ¨ìYS…)àyïGN7dûš^jI#µ(÷£>Ùü(Ï­”rzÐÓ¥>Ÿ`QþzÕSi!Ôc»³¬IClìcýãÆsøÕž§9 ǹ£·#Š1ïŠ3øÐÇsG…öÅ/ÔR~¼ûRÔ~ ~4{w Cõ¥íÎ1@ úûR‚cqŽ‚Þ€ Û4´ƒo@(4´{QÚ—4ŸÏcGëíKÍ'Ö—E7žÀRãØQHGùÍ(ÿäÇ,@Ī °89Í[8¢·ˆÃRFqÎ*ZlLG”À®î:zÕguca ùˆœU¶`£%°­Bûå`Ñã y Æh@‰ÿ «s†eR¬N •j£˜6Ü©Æz!è  Æzw¡Êxü*$ž#€d±ÜÓEÔ3\Û,ÀtEŒGz…$ž¤µP±ªäð3ýjD'oÍŽµ§cù¯#lPrNOJ®ŠÛ“¦iZâ'…¶Iµ±ùf¥‰JÆ2Ù4lûcš? >ôgž”€3ÇzdŸêÎFF)ýi’ÿ«nqÇ_JŽÕ·Û«cnîÙÈ©ÀïU`•"·MΘõêS8p;fœ–£dÜU[¥-µZ-˸r*Q2—:‘‘ŽôÉÕŽÒ$(ÉÅ$"a´zTSœEþ¬·# R¥ÄL™W Ï’IÔD eMÇw­` ÂÀ õ8¦Yÿ©\¡SŒò1Š‘7Žâ¹ç¥$& ϯqNãq—I6¹`Àðxõ=Cˆå€äõÀ©ÕÇÊÁ‡±¦Á)Eº`¡‹1ç¥Y¨d.¤mÛ‚psOp2úÒ+¶býá dt©”|£ T¼’åÑŠ´ —9;WŒ©â€!•Õßìûñ!JFéíQBYÀwÛ’?„æ¥À=hr~´ÒØ=©j)¸ífesŒ `T¹hå;Œœ`õ«ôÕ(Uy‰°>á´ô9ÅGr¹UùÙ0ßÂG?J ޹ÏlÔp¹UÛ#ýqš•ÎÔ$œP[Ì„¾Nî˜éN”–;c?0냊”tä ûPý* (×Ìw±e\l#­Y2 BÄà’j¹.Y%b{FäþTÐ"Ör{Ô3í’Ã#¨©©ÛÈùºsCŒ¡Àçµ Oîç ¯¦)IÈàÊ™ aˆÜ£§zGvÀòðNy€"±'ËÁÉÆy«Y¿éLˆ¿–¥Ô+c*LúÓnìsG>ß…Z>¢ƒ½”™”½hÏ®híÀýhãÖŒq@}¨ÉÍ­rzœÐ9ãž)>¹Å¶i8>Ÿ/}}¨÷ô4ßÒŒŸP(ÔRd{ÑŸ­Š8¤ÁíÊ IøÒÒd7C@(íþ¼zÑÛ4Þ}³K|}(Ï(Èõ z(Î:Ñš?\籤ϥ-&hÏp(¥üh;s@4´b‰=½¨Í.=(í@„æŒRÒ{Ðô¤÷Àúâ–zJ?*^):MdQz8Ç )8úRÑ×ë@„Àõ¥À£üóE? 8ãÎŽü¨8©hÎ(È"€"›ï§ÐÿJ)³ýåú)ð?*^£Î ž´šQþqKíüé8÷£>Çò …ynHîiÝGLRvÿëÓgÔ BŽ=J^}¿ý(ƒǰ›Ä.ïZRTrsniN:øt B…úqK·ž§ñ£9ì£Ô¥!‡·4Á Áž¼ ¿ëÅÿ]0(°@OsŒfŸlRcïî)Iú~4›=}èÚ§ÓCK‘Ð}¨À#îÐ +Ó4Ò*ô4îƒH=ÇJaE,j–‚­$ àäɤ㠓¦(÷#éŠN·”p9ÇÖŽ¾‡ñ B|¹,1žçÐ1ž9>—r.=…T0Å1m£qqɧ`‘Ø @=0 @мcØ¥ÚÆ>”£Ú“#>¿*¨ÀaAU Œ)sÛi4gБ@ÄUÚ¡@ÂŽƒ¦)Ø=‰ ÜÒÃó CJîÁ8Èÿg¥"¤jXª€[©èM.WûÇð¥Îh¼ÿUû 9õ9ô£?AúÐ9ÿõÑÇÒ€$bT(à=AïIä¦åo-7 ½<Ñžô M€UáN'ÿJN}¨ÏûB zô4‚4RUœ~£>ÔcÔ~´gÜSJ#gpÝž Šx?OÊŒžy ,"ª¬JýÞ:Sñèi)8ù aÔRõíÍô}T~t?Ï&ΓéÒ”cµöcüæŽ>´=?Z8èH¢—ð™ö ¥ú‘øQÇj ­Z\ý)(Æ=>”¹#°¤Í/”~4¸ü):RûÐqÙ¹¥Ç­!ïùQ‘ëÒ€ SùRŸj(ê(ÅŸ…J8îM.9àš3ž¢ŒZ;u?´mïGN£(ú`(ãßð öÍ(”ž´sí@&G¸¥£'Ñ(Í%Ÿç@ÔŠ=¹£üŠ6ñÜ}(ǵZ c4~~4¾œÑÿ4Q‘õ §oÆŒŸ_ÒŒãÿ×I‘×?­/áŠLc½Œÿ‘@õ9¥íÖ“9ÿëÑÍ/>´ŸSK@9Ç\ÐG¶@G­/×?•ϵº‘@çGSF3ÜÆþy ýqF3ÖŽÄQïÆ}¨ºÒþ4d8~´™¥ühϵ͉¤ã×ô¥íßð ­'êhǽ.8î~¦“u÷ö¦í\’F ;¹£ ëϽ&8íŠiEb #¡Å?§z2=h3Ñ88éJªª0¡GÐbœAëüé3Î>šQK* €iÙÏÝj1ô?åKéI×µ(àP1ÈÆ2(à *^zBð*iPÀ« ø"Ó§åFlŸÆ‹xU·“?J<˜ûÆ¿{wãRwäQõQq†ß@i ÷"øR}Maˆç(zäS‚…à=;ó¤ÈÎ94 _ÒŽ|})ºøÒš8ïH@+‚84½³Î€"0Ű!@TtâœQAç4îaF=(6®ì½Œ~Ž»†Tƒ×"ŸŠLP"Ö€ÀÆx­nŒª§¢œŒš— z œÑvmÈÁéÜS#†8Aò×<â¤çÖŠQžù¦í@Û¶Œúãš\ž:~4PñGàiE'à(£µõ£ v D~Rç$ž´¾Zï Ž@À4ÿÆŠ5QA,^´¥ºÎ–‱*¾FœQœuæ‹ÚB¯#¨9s’sSªª(Px(ƒZ^ý(¸˜c,_1ëJbF9+NéôúҌ֋€ÔB Ú¥$/¿o>´§gž(¸ Îii3J3ë@T7£ª– }îµ/‡ M´G9§GqdF¸'©©8õçÚŒçÿ¯EÀB3ÁÍ0D ç$ŸzÔÒçÅGK1E ·\œÓÙw)`\ç¡£8ëŠDE/AïKøRdpOÒŒç¦,Põ¨ü¡æÁÜzúT™úPqí@ÞÎ'eg+œ`žô©m @XïSg¶(ÍapS ÄœžF85'éGoojˆ@ƒçàzÔŸJ×õ£#Ö€"h†Ë:äcƒIödäóÈÁ9©…rx¢árkÉË §#¯Ö§Îhü©zQp#1ŲÜö¨ÒÕ£n•Ï$õÍXÈÅ&iÞÁqyÎA4”£®8„­-&}¿*_€ô£ó¢ŒÐŸZ2: ? 8 íÞŒþ4œRÐE&>´v è)'éG=òiO×?'=8£'=?:zÐqŽ”¹íŠZnxãò£'° f–™»×”@ FO÷hÈëI¸P“Š2H ~Ÿá@'á‘ô¥íéI»=¨Ïµ)Ÿ…¥(ÏÿZÒŒ :PŸa@£<Í-%¨Èô4sKH=Æ?ZNh¿…v¤4úR~­/P}èÇ éùÒôëG;ÐEâãÓšçF 稥Éöüè~4ž´™ƒŠÀÎN>”´ÐG¥/×ùÐ2þòý MË¡¢Ö—Ð3Ôþ¼~4Àw4sžŸ­'8èisìE}E'¹£êE/߆(˜ü~´¸öÅ}hÈÏúPsè>´}:\ý*NHáhd2hè{ 8ÇøRóéøæ€#ŽŸ•'¡…'ž1îhõsŽ´™'†äRàc$ÊtÁÍsÒ‘Û&”qÕ³GËÓ4ãÐÒ ž™Í.ÑIß ÆWîñïJ}>”ƒ9êhÆGÝ `88Æ(õÍ.ÑŽ˜`z°ÅÛ4Ï'š:ôäQõÎ=(ÇÔÞ:àŠ_Àýizö ǽúÒŸ§åIøPGâhãÿ×KõÅJN?É¥ Ž:dfcIÛÍ/áF}¹¤àô£ð4´„ã©â—ð¢€ÆŒ{ 8ïF(þTbŒâÀÐqïš(àw¤Ïá@ F! q´â€ç…Ž˜¥£ŸJLúš^}±G>˜£œã­=ÏãJWÍ&Xw÷ ôò(ã¶ÒŽ1Ö€9¤Æ}? Z(úþ´wê3@vï@NxÁ¢”ƒþE7±€ŽÜÐ8íŠ1ô¤àpp .qGjL€0>€ÐQŸJ©ý(uR?6ã¥`cƒÏhü¨÷É 8£ñ¥úQŠB[ëKõ£žÔ¼ý(œÐ:ÒŠŸÿUÇaô£ó¥é@ÄÉÇNi8éšSô£îÐcœ@Rý(;þ4gó£“F­G€ ýh£©ÿ ?ßïŠ>§¥=ó@™ sÎ \уޓڀ½Å¥¢† '4¿…ÿ“@„Ç| Ð:R`“×Ö—¾ ÖŽúÔzŠ\{Š22}'¿ýhr=ÿ:7IŸ\Òþt Lûâ—Ÿ­¨¥$P!izRgÞ”gÒ€ õ8¤ÏÐý(ú`ÐŒõ&Ž{~t¿QKÇ¥'ùéF­÷ ÚŽ:õ£Ž™¥ãÒ€Ÿ¥'#¾ \z(9ÇÆÎ—éh:÷ü(íFhúPž?úÔu¥çÖ“w QÇ®hÈìGç@¦Ž|cILÐçŒõü)0{°ÒŒ}sI´w4¼üÒp}éyÆ6ÑjAÇAKžÿÊ›z^=Í8z\Ž™¨ò^)F; wåFxëIøRóØ ýhúRóIøÑ“@ ùQŠCŠ1šZ0GjNÇcÓŠ?]““èi~ Ð‘Û4PIÏN(Å/çùÑIŽ;Ð=hQE…ø¥¤Çµ£·z:úQÖ€(ãÒŽ½èÅ=¨ü¨Í'Ðß½gœŸÎ‚h8ë‚~” LzGNÃð¥ãÜ{f“ƒÞ€ úþT~bŽ{‘@ÉÃ/ÐÑK!Úà·B8¢€&—'ÔmÇL~4£¯4€NN9"—óüEí“ô4¹¦ éÒ‚q×ò¤ÀºúQ¸ë@Ó¯4¼‘œœzbÇ3ô4›‰ôü¨rqòþ´›½Éö£±Çµ.?ýtŸð" .= ôbŒ6ry °~ñ÷¤ú’iFOQù1Üõ£>¦“ñ—'­ú­'ÚŒòhǹüèõéøR|ÿÞ }:Òý1øÑÏ×é@âM äþ"œsש¤äö ã’9ÏqÞííK:ÒŒƒ@É<}#¯J1‘×sš·ã@Ü:šá¨Æ{ó@ÝçšLœðsøQßž£$ýh¹#¶(Ƽ>”e½hí÷‰ÿv€ úÌQ»¿Z9¥Î9 äþ4vûÆŽsÔþ4g=èI>ôƒò¥9õ¤Îzu ¿©A3IÿÅ.N1ëšOÌûbŒÿ´E/µ'þº‚ ¥ÇÔÒ}(Ï© ê=>†”{MúPO?ã@‡`ý>”™ÇœÒqøÑsô ØQ¸ÑÏ&Œ~tdÁþqF(ïÖ€ ƒÿ×£?_Ê­F{šNoÒÄÒùQ@äÑùÑî?*\ûs@é@÷£ÿÖ£9è Ï|ÒqØš2~ŸQKŸB 4„¶:Òz?@ Û‘Š\}i8=Í)éŒP8è0(ÇrZL:Kõ 9ïÂŽƒ©£¯JC×¾hsFi;õæ—š?(ïÎ*CÏZ_å@ :qIß§4œzÒŽ(ç×𣞽èÉô£ž™ ñ£SKƒßšL†RhÀõâóš;÷ \š8냚\ü_ÒŽs×™ÿ"ŽOP)qîi¹Í/×QÓÔÒ|PñêhÎ=i3Ï´™sGùéE 8õ gÒ“qÅ÷&€$w?u=hÁ~¦‚qÖ€ z樤ÏÖŽ½èx)i9ô¥ç­¤ö4qëGò ð£ŒsKj3ž†€`tâ—¥Å'>ô£êiõþt}hÐPG9èhÇÖ—ŸZ2héIÞ—ò¤vÍtÅLRÒgë@£ó¤=ðH>ô¸ÀÒ`zPè &dûb€8è /ÖgÐïH1ž;`ri1ïϱ¥ÿ8õ¤Ç~iqŠ9úPv.ìíäõ8§íG¶Mf€ØP:`=èÇùÅúÐÓŒ~tc½¢— =(Æ= ÷¤éë@…ã4gdqFAêhÈ=Qôsß ?•Âõ÷¥Æhƒÿ/К8úQ|Ðù 3šN½Ž}¥Å ûQ“èE%õü¨ztizQ‘@„ã9ç>Ô¸(æŽGz/çIß‘øÑ€{Ð?3Š0×ëIózÑÐtüh ƒGcÒŠÑž3Γæî—¯Ôz@ÏjhäÑþy¦I>ô^´¼Z0?ýTZCÒŽ1F?:_Γ¿½úþb€Àõ¥æ’—?Z8 }M&=Hüi~€>”sÛ'„‘KŸ|P`ן­´sßéEü¨Èô£Ñô¤ À(ü(Æ>´}?c 㨣îšLŒõÉö Ø4¹ã‘ǹ¥ç:AÈÏ'ñ£9 }hi9ô?…-!$uÀühÈôæÂ“ ÷ýiF;PcÓ"Œ`ääÑÚŒ``($üéqô¤ü*8èr{c~F“#×ò£“ïé@ rxÎ(:Ò`çPAë@…Ï×ð¹8èi¿Lþt§ž:7~´gëõÅ8àâ€O|ÐÐQÀéIǾiy=¸ ƒKŠCØÑžœÐß©4¦’@ ŸjLñ“ùÑǽŠ3éùÑœö4p: ÑŒö4r{â©•.=¿::vâ€4½}(ü1HsÚ€œâñØÑ“ŽhÈÁô ó¤"Œ{ÑŸJ2:rÒ”âŽHäñHIÅÇj8ÿëQzN@î?Zpÿ8£ò¦ój^ÙPð?ýT¼úÒ}qAú­-7ž¹¥Æ?úÆ€¯C‘G>”€CG½>´d†ÀöâŽ1Çë@…íF{Ò~4gÜPÉ¥¤ãÖ€}/\QÎzRzRóí@ÇsE'ùëGë@Où´œÔqŠw4 v£ñ cÚ ÅRg=¨¹öâŒÒž´~”qéFxëÇÒŽ(ÍÄRgñ£ŸJŽO¼>”RIãéE 9ô¤ ÙìG§z\Æ1øPñОhì*Ïj8öÏ¥1xêA>ÿ¥Ži{ô ÈõÏáFæ?wùRí'©ýiH>Ÿ•7qM.Iì)poÆŽ£žh:Žx£ß¥'hÈ= ƒÇ“ }ìKœÔÿõèÏ Í>¹†Œû~T™`9¯4wÈ´™ô ·#Úǵ99úÒp=H ~4síI“Oz9ÿõÐàö¤Çj>oQj\zÐqÿë¥È[ðÍ'ƒúÐ:ðá@ Å'ÛëGÞ ­(޹3ÉÍüiGR)w à@ ×§çI‚=>´ÝÆG­&}Gé@ ƒÆâhàv挓ØRíã  ïš^}¨ã£'áIø¥;‘ÓšOrå@ ¹Aêsô£v}sô¥äôéFÙ&€ž™ ò:P{g¥ q@  ñÍG4¹'éî(ãJùÍ?ÝÏÐÒgØŠ^Ô›–—ÅÜgé@F8é@"—µ'áŠ=óG9ã§µ:{QŒõÍ{ÑùÒcßó§sŽ1@ ÉïGO¯Ò—Ÿj@{@ÑÜs@‚Œãµ‡®(ÈíÏãHI=À§{IŽ8 óøRóô£ Ž?€ã@ ì>´dËcð ã€A—£žù÷›‡B?­QïÚ€ 9ô£'ßgó Ƕ)x„ö¥æ€ÂŽZ@ûÔgÔ~T§ž”èGãFqÛñ£#¶hÎhϽ'ù4¼PíÅéøQŸJ9<ó@ šsIÁ£ù}hGãIÇù4uï‘@úPÇf¥Í&<ãò£4 \úÑIš?J/zOÆŽEÐÉÿëŠ3õÏÒL“Js@ Èþ/Ò“éK“GozNOéJ¦*9£4Ÿ‰£‘ÐÒõïúRgßòæ€J3ŽØ÷£Ûƒ@ã€1@J=;Rý)9ô4 \`u }M'^¹úP=½?••˜£§½ ú~¢ŒÖŒç±{u÷ o°úŠ1í@?LÑ“ë@ ߎ? 9ïJ2hɵûÒR8ÿëÑÀ¤Ç›½A£‚sŸÆŒú2=èÈ=åKFM0ã®áFqÐRûÑÎ:Rç±£ñ¤ü(=xÇÖ€>´dô¤äûQ“Óõ4¿1ëŒzRbLþ4¡³Ãc>ÔÄ{Ñôü(ÁÇ_ÊÅçÞŒúŸÂ›Ó»y\Œôæ—8Ç?­4 ž´{d ;žü}(çÒ“ó4™çÐС£­7>üzR·ôúÓr=M¿7vz7é@oÀа 1ïMëØ}izsŒÐ÷éF;Ònϵú­ ëFqÖžô@ö ê(¤8õçéA?çÀ^A zh9=y “ÁÍ ‘ÜþT˜úš>œQÏz:Qôü¨ã¦M!ã’(ÏZ2~”œÿ¥z˜…>§¥.)¹÷£#¾sí@ ƒØæŒRnúѸúþ”b”ûÑœRn# &€ zfŒùü¨$ãÊ€Üÿh=ò>”sŽ„S»ûÒî3@ϧ~t‡¦70ýi?ü¨îGÊŒûµ'QÑ¨ÈÆ ÇS_ÎÇCMÆÓÅ8tçóÍŒàK|Òíz0î>”¿çš8ï­&O© ã¹ãé@ ÇlþTéÅ&s÷sK­úÑÐt£>øúÒþtœúþTr}q@9ïG^ô½)0=x£sEvj;õ4~4Û4séøÐ0;`}hæŽ â€ùQØâ§JS@ Ðp3ïIùQ:ÿ*3š0:>´`uš0zƒF=s@ ¨¤Ç½/sœQøb€4œ{çéKž:ⓃÎsô è ç½ÈäRöè~¸ ôœu¥È=*CžÔ£ò£'F}‡å@ Œö͘£¯R(úÐÓ©£?…‡é@£¿"“=iOÖ€ZL{âŠ(£œö£ŒsG˜4P¸üèü¨¸â“u?´psÍ zP(ÇÖŠC ÿ]Z1Üu£ô ¯AF?ýTpqžiqþM0+¿ÞÿëÑN—ï/ÒŠ@ >Ä\RƒŽR`Ö”<Ïá@ ’zdÐ7gŠ0N~”¹#Œ`NiNqô¥úü´cØÐ!1ôJ:voΗ¢—_Ê€ô‡ofæŽqÇ4¼÷¤éÓ"ŒÇO¥3@Çp1ŸaGü ó4˜Ïñ@…ü)Iƒ×4qØh2=i}úÐ}ÚŽøÍsG^3ùÑŒóÒ“œdš/NâŒÿœÒgþª03Ö€3Îséš^´¸éFOeǾy 'Ú“—Ÿzô€J1ǼŠL|ÐrOÄšwåI»œqŸ¥—å@ })»TsÐÒŽƒ aKϽ&3×¥àƒô£­žÀb€pMõÁüèÉà(Ç® /ÍÛƒô£½ûÑ×½¸úQ‘Œu¤irHÈñ  ¤À<ÿ:0{ÒŸz9=BŠ^O\RgØŠ1@¤öÈ¥úдwcÓ"“ñ4¸Ïÿ®€žøÅ)÷4€}ãFù4£ê(íØÒqïš2†€¾Ô˜ Î(Áö4¹Ï­;þB€èiGN6ÑœúþT½(9Ç_ÒŽ´f—“ߊLb–“4gÚ€ð¤£>´PG{ŠZN(Ï®(ÏùíEühúÑϨ4~´ ? 3F=¨ãÜP êzQôëGé@ׯ¡£К0}ã@ÐÒd{RàûQƒÜБøÐ1þM?ZúÐKIƒF ‡çG½ö9£óÍ'çøÒâŒgšL\`wüèãñ qÐQžøÿLsÓqžúu¥4œtç?J1êGçF=…/?þº þt”½=hÇùÍé@Ã#4cž‚Žô˜ö ¤ãÖŒ.sŒŸZ3õ @FGÎŽžŸ•/^h bbŽiIüý(æ€þ€(ç°¥úŠ@<_ÈÒgž”gÛdgŒRô¤>”{qô µý)GáùÑz¸œÑØRÒ9ïKF}hú bÆþE⎼š@úþtc'îþ4g‚ŒgÛéLœ 2}F(t ýZN¹Íõ ÒäƒÐP ö bqÓŠ1ÀëK“ì=¨Æ}3í@ƒ8© =úô¸Í&Nqšßdü)yÎ1ùQ‘ßõ QšB£Ðf”=èù¿ ã­%.ßòhúƒõ aôzCô¥ÆyÅóƒ@„Î{ÑœðzRþ4qÜP0À¿*N`hÇ¡ÇåKÈì? 'úÑÏ­)'¦ úLžÊA ni=¸Í.O ¥äŽÔ˜Ç¥É“ŠC‘Û4t Î;çÜÑŸCGæ)h””ïÊ“œô B`ÐsÖ”ŽÜ N{µ'8à~´£w¯´Ÿ…&TOà)7)çwæ)üãP3ïùÐq‘“G‚—§ 挟j 8QëFH¥ ýT‡Š2;K“ÜcÛ4œ÷ 9#Òå‡ÿ®“ õëJ1Û“@ ßšZ\QƒêÔd{})8öÅvÆ= lý(Ï®)ÏvçQÍù4gÒ€ÀÀ÷£9À£ºþT¸ Æ:ÑJsü'Üf“æ[?…G\RóØQøPFMGjOÇ`ûQü¨Æ}(úš;ÑjzqIŽÜ0:AÆ;QéÇJ^ÜPcÚ“9Á?;sA"€øÊ—¯9¼úÒ(çžiy…'ŽhÇ¡ü.xÍÁéIÆ}½.}hÆc¶’hàt$}(Ͻ<{R} 4`öâêE.=ÇáI’;~"ƒíùPàÑíÍýz1ï@1Í¢Šn}(„…9'”y^iÁéK‘ë@ƒ#ÚŒûÒþžý¥}é:ÿõ©Êäúþû¿.p=) ¿Î—9 aÏ\ 9Ç$Rdtþ´½û@¹Üä`qEò¶}h¤3ùÐp:šj¢'AõëJ1@éÎïΗ\ý) c¦.÷³LBãÝ)à$} &Aè~´sŽIݨéßòæŽÔvíš=i~SÛ…'|t÷¥Ç|œP‚sƒùÒ|ßÞ \Ÿz8ôæ€êÔœvþT¿QG½‘Ð~)pqœŠL‘ØPO'´sÓ¨ö¤Àé@ Ó¿>ô›µ=MGÐ?u¾¹|´f‚}ühÈÿg>´së““Á9¥ÇxÐÀÆN=³ŠP}Å'©‚8àГÁœž¬á@À£©é@ ê ƒÁ4ŸˆüéF{q@p8èÇoæ)wôö£>ÙúÐxî Òàtê)çAùÒ¡ Œòhé‘Fê3ž›h>œþ ôÏçIƒ½Å/>™ ñ?…'z^OJã×¥s÷²(ïÖ”qÆi 9ü¨<ð[ð£ø£Ãó£<ýïÊ€ŽäLûÑ×¥ìEìzQÇj\Rwíô ÈúšLŒvúRçÔF>”„Óƒô£p?Ä(ã§rc@ ¹Ohút¤öÇ_z^:Pu8Èúb”à(ãÓòvëÁõÅv4ö9¤Û‚)qŽ´ŸSKødÐOj9õ ¯½ÿ9¥ÈèHÍ'N‟P½.3ýÚ9ü>”wýhÁǧғžÄ}iC}(È4¯çF=È£¯­t&€¯?(>ÿ¥/çIÆzÐŽ{Ò}•;&‚qÎh ŽÍ»ñ¥8=E8£#ØPŽø£ð¤ÎzΗ Ðg× ûþBžh$Ðä äÑÆ1ÅCFG¨>ô˜ç4cÓ?÷£jZ9¤É4¼ãúГhÎì Ž3KÞŒzÐsïKŸö¨£§®(ÿ×HÄ» ÜÑ’{ñíF‘@ ƒëøÑÓ¹4™úãÚŒûÐç°jCÎA£®>´}4ZR=Í&?ÎhÁíÍ)Ù£=±Iøš;vÅ/ãúQŽrçGãM9þ÷é@ÎxÅ'?JOçKøÐ0ê>ð£ŒqŒ{P>´cë@‚“Ò—¯µëùÐèhÇà)xéIß° Rp~´½;Ñœ÷ ½!úþt§ëF}è˜õ掼þJA“Æ1@ƒúfŒíÇÒŒc§J8õ ¢Žz>†€ ŒäÑÆ0I Žý(»àÐ!CŠ^¾ôz&8£ŠSAúÐ~^Ô£>¿?SíKÍ'ãIï“NúÒPŽ˜4‡_¥™£'üš@/Ð~”f“ÞŒzS½hãÖŒL~œŽô 1Ï­/×ùÒdÑŸSŠéÐQÏr1ô£8ïš2V4€^qI‘ž¦”sÐñM-‡UÁ;»À¦!{úÑéz0Oz8õ¤1: ºš^‡4žœÓ爣ŒÑ’x¥ @…ÆGoÆ—ƒßšiÈÿëPA#¡ÅűÑM€ïš2O|Ð1wf“ž™ÉúÑœvü($úP éÁÅ(ç“I“Ú—¯9 bŸÊÀÐHOçG=y A’{Iz9þõ($úb‡ãIÆ{þ¿J0{“@ B)xèzÒãÓš1ë“@„Àô¤ëÐ~”¸ £>ÿ­äRñþM4ŠPs@G_éFOn(õ ö8¥ã×ÇZ8ìhôãõ£¿ÝýisþsIøó@1Ûò£?…­-'lÿ*1þsK~i0(ÀQGnÔ´‡ž‡ô b ª? >”½GøÑŸj&=Ö—ÅïÖŽ?º3í@uéF=:ÑŸz^Eö¤ôçõ¥ëÿÖ ó£ÐÑïš9#ü(ž´½¸#ñ½è ÇÒ—š8£¥&=h¥Ï×JLûš(éÿÖ£·z\Ð`Psê1FaÍú~4~9 úGÓ4:NéJFM.LqH@ÇJLü4m'‘KÚŒz L8Ç”ô£ñ à⥗zÒ~‡ðǽ(öÆ(À¡ü¨Î:ŠLS­)éÁÅŽÂŒgªâ€0éÇã@ Rãþµ&28ò #>ô賓ÛÇCH~s@Àí“þ*_Æ—€“éI^iG=¿J1ÏNh>ÔgŽ´ïÆšO<þ¢€ŽÀ~qýÑôÍã¦( ŸLR ¤éÚ^8úП^´‡r?::Ž„})x¨~"Ž:ðhü)2Î 4¼õÀ£#oQý)y'J:Ž¥ëÓ‘Gé@¸;ÎævŠà‘Ž(¤†;àRýúÓFÒp[ô§tãô¦ Áþè 3Ã4 _ÎŒx8úPàc“ŸjCž.>´žÇð Aüž)0}N>´ õ ÎÛÒ—f;RgŒ£u Ú9‚è ýMô…sÛñ€ýÜ})0{?1Û­(ÿõèÆz•¥ Œ`þT€ wÀ¤Ú3žO¾hÙltýsHBŽHç×xÏçKõ8>”ÏëF3Ój2=ñF短ºb”sØ~¸?ÞÍ&1ï@ZM‡<øRóšÍÅxû£ùÒmôZ\ÀŸÆ—¿ ÷ü= >¢Œg¥(¤ÉÆ6ãñ£o¾)vúŠNÜþ”£hE'=±­I #Óõ£íùRƒœsõ¥Ë?Z8ô¤ãÒ—ØœÑøþã¤ÛÀãô§c=3ŸjN}ÏÐМm¥Ï¡üÍ™¥ç°Í& ¥÷æý4ƒÓ“ïš.ÑØïF;qGÓ?….sÛó B}3A$zûšQôÅg¡ ÁëœÑÓ’åKþzÒàö&€q÷:N=9îi3ÿ×É À€÷£?CIÇ@g© ÎFqõÈ¥¤ù½iq@ £>üÑ´{Òs@ yúÑÓ ¤Àïš;qš>nÿΗ=°i8ô4`žÜPÍÏj1ßÑ‚{PžØæŽƒ84c=Æ}èç¹çÚ€Ú”œv£m&?Ù Ï×ò£P=†? 1ëš:ú©2:€>¸§~´Ò¹êá@ Ÿjçš;ñGZ9þ÷J1íE&GÐÐÿÀy£ò£Ÿ_ÒŒ“ÜPÏQGN84žœŠ8Ú€ wÀ b—·v >”{~\QïF}(qÚŽÝ)?:^} 1FÑéIÀ=Çc@ÔQÆŽ}(Ç®(0})qïF=(#¦M>´qíùQ‘ïùPG¡Å¤Ú;àÑ€;šPZB¥>¿¥/éKŸ¥I´u£­…Ôc¸cô¥'ÚŠCš0G?ÊŒz ? 3IÐÒäú(úž>”™Ÿ/CéG´QלQŒw¤äv8  9Ç^ô¼}(äôýh ÞŒçÒŒŽ™£Ž´c¿œvÅéK‘í@à >”cØRgŒ@Ã?.p=? N}hüÿ.süYúR`fŽ:df”}(œ{Qø€ip)1“Öñ 1ŽÙ¢ŠLzI’;sìißJ;tÍ&IÿõQϨ£×¸úPÍüèçéFjð|}(¤ç¸ÏÒ€~t¸ôÀ¤Æ‡ó¥Ç·ë@„ç¹½©pqÚ“é@Ãüõ£4u ã׊3Ç RŽ˜£>˜éKÖ€ RñÓŠJ8 ‘ßéGÐRõô£ñ4~TbŽôœöýhÆÀš1ƒK‘GéHQPáF 4Ä&G £#Ø9ì(è8€9=éG?Þ´qéùÓŸŽ=hÈ>þô lÑø€i˜ï“G^Ãó¥÷£j`4‚z(Á=Nip?É¥ÇN³ô£-è¥Ç±£Žô†c=? OÊ—ŽÄ~t˜´¸ÀíIƒÛçE>¹ Bêé@ÇQK§Ö“'ØÓ}sÆÄ~T™õ£ŸAùÐä~>Ôp‡~)G>´¸Í.3G4˜ úÐmöýiO¿áÍ-ö d÷ý(\Ñœÿõèæ€õü(ÀíÀ¥Ç©£šLj0:J=i~§õ ú?Z;öÅç4cÔŠQŽ™œgžipOZ1é@j2;QÈï@'Ò€“ßô£êy¥üè=è9ÏSùÑÏÔRçÐf€;‘KÇcúÒ~´¼P{ñõÍ&Gÿ\ w^ÿ…'© œÑþsFè)y î‚À¥ƒÐóJN;~t`@ Œr(ÉÇLš\~Tuï@ $ëøRŽœbŽ:ÑQ@qÍ.Fy}£ó@ n(Àôç֌㸥ÉìE Û„{~–Ž~´™íƒGãKøÒÐgÞŽ½(úš3ô Éô¥ü3@t£îh8=Æix¤üé:8íŒRqŠ9õ4`zÐÀô—çG©PÆ:QŽ”¼÷¤èy Ûèh£ò£¥÷ÇÖ€ zŽhÆMœýhäûPPáGùⓞôìÐïŧZ=9J7{þT½ºÒ ö¥æúš?KÇb(ÏÒ“ñ ¿ÿZŒÿœQ“Ûõ¥ç¦*8ë‘IÁ=AúÓ¿ NëšO|Ò‚}Gå@>ô˜¦~¹ b玣߭&ÑŽMzœ})¿÷çÞ–“ u4À†L3è(¥”å‡ÒŠ@úÆŽýJwN¸£žÀSv¤ç©çÚ—wúQ“Ü~4P1Ç|çéKÆFzЃøRàç­&ßLуҀ½zz Žô£§-ÅçƒÅ4¨¤ÀÎ3ϵ?¹£ô ã·›}éàæŠ@v${ÑŒÿ¹¥—ò¤##žL{’}éݹ zw¤÷ÉüèãƒGÍݱA?ìœÑ“ëô à÷É£= '£þ€ùzЩ=³Íý(ãßëšO—×?Z3éüéx#ÿ¯F=?€ zÎŽ} ë@Æ2 '^æ€;uúÒ“SGoo¥¤á‡qŠRG­ôRޤRsœÒçŽüésøPsïGÊG_ÒŽOAFxÿëP@Ž¥ 短 ž‚—éƒFOÓë@ Ó¡Å=Í.M'#¨?Z6œó“KƒßßΔêh+íF9ç4gØÑÏ©üh@Çpi0)vûâŽ3Ó4˜'Š1êsKþqF{q@ ì?zŒRÑz?O—óGn4œH9£CøÒþbŒžØ >Ùüèüqô4¹4qž84™ô8ô`v—'þ”gë@GçA÷§Q@ Éô?…/J9Çj_Æ€Ÿþµãœþtã¶}¨Ô\fŒç  {ûÐHï@xèhëÜÒÒr{‘@GLÒÿŸJN}híÁ àÿúé??ÎŒg®M_€:m£G¸Í/âh1F=ÿZ?(ÇÒ€zÒwéF=E?þ³@ ô£“ÿÖ¥üHüi>”:Qøš1횎(æ¦i(Ï©'ë@ Àè3Kj;qš?Ðp:cùQØdÏ4£ÙMzPÓ¡üÍ&O§åF=)yíš)3èhü1A-Ú€Ÿÿ]…½Hü(ýhqþµ})ë@  ôëGƒžÇ¹õ ç4˜=¨ëÐ (#Ÿ‰£Ä~4tìhúP:úÒdõÁ¥>´¸úÑÅ&;qG~„Ð0Ç4cÔÑ×½ö AùÑŽ{QGëõ SF>”sØÑõÈ §ÿZ޾ôdúQøb€ Rp:æ—ñ£“Þ€ñ¥ÈèMý(Å/áH>”¿‡ž¢Œ{~´dzŸÊ­'Oþµ¨¥üJ?2(>ôqÛò |Š1Ÿ_ÀÐ1 ?Z?J@=ÿZM£ûÔ2;gó£?äš0½)µ&a@9àÑÏ¥zÿ:/ü)8^ƒ@)xõ4zšLŒñŸ¥/éI‘ïKœÐz1Š?Is@ è)8í@äÒçœP`g¯ëKƒGOjOÌÐKƒõ£Œsš3@?LQùb”ò)?LŽägéKÇ­'æirqÐÐ!6Œÿõ©qíFG©£ ž´cž´1FFzÐHè çE!ö£¦:ûPõèsF=sô£õ£ AøÒuŒÑÇ¥úqí@ÃÐ~¸õ¤ã<ŸÒ޼‱Hr;ŒQŸoÂŽ=?:&?ÎiyÏÝüsG”aϵ cßëF\þ”hǶi€1žyüésŽŠhÇÔPŠ1ÿ]qÖ€ÜRþ4¿……&=MGoÒóÍ…õ4¼c¡üè<ý}(Á=±@€`ŽëFµQÍ!äuýi,QFyé@Äç<ÒŠ>„P~´^i1ÅRûÐt _Ú(≞9¢—èhüh1íŸÆŒZ\œQOÒ Ö€=©r})8îEzçqF@þG”¸ôý(÷4œ^?ýT}(ãÑzRjoøi@ÀàRâ›øó@áG”cÿ×@=³ŸÆ€ _ÈÑïÒ“æõ ÏùÍiEö  Š^…'n™£·¥.(ǵ'â:1ÎhÏ ¥ ÉúÑëŠZ?ýzLv4cÞƒÏaE'×4|¤úÒýELPÃñ¤Àúš^ý¨'Ö€:RsŽ3ùæ—œsAÇù™Ï§ãG=©p)8ßJ))ß…!Æhá@ÏãG2)pÀÅ'ÔRçÞ€=ih˜>Ÿ.üh>¾”JAÓŠQÇ­{zLPè8¥ÇÒ“Œò3@?Ÿ­/n)1Ç&€‘ÔÀQÏ­'åš¿Nô _ÊŒúš(ëÐþ€(ȤãßéK@I÷ÇÒŠ%2ý ¡±Øþ “È8 }(#>ôÀç >´øþt¸Çr? \`rÖ ‚zùÐêix>´p:.h#ÔqGàO¹ ±Ç8JZN½F õäÒôíGçøP8¤ N)xÎ9̓Î(9= ž¿¥çØ}æ€ ŽÙ£Lý)²Y@n=F)Çò ´¸ã‘ýhsœpi9ä`­#¶>´§=€ Ç~þÔ¼úcëGÓ­wëõ úQøæ›èGÐÓ¸Mdc“ô4c`P1@Ä{Ó¹íI‘õ júŠ9ÏZLŸBi:0}hëIƒëùÒäç¥ó€yïGz ½E'>†”ûýhâŒzPùQF}•´tÏaëF3È£§AúÓy'îïšwn´p)x#“8ãsÅ/4˜>”}(sëIŸZ(ÿ&€œòGáM'špüOÖƒÓ¥7ŽœÒç×8¥äŽx4¯é@ Á çÒ—AIŸE ú’)xÆzý(ÇûÔ}HÔsÚÄôÁúÑcKÆ€ Äô£“ÜP~”sÜ 1ޏÍ>”˜Ç8æŒúPÿœQœð¤= íéJÇ_΀ Òäbš;þ”¹çŒþ"€þTŸˆµ~”cë@x¥Çµ7°¥ÁÇoÊ€ RŽõ£ñ¤Ú€ߊO›qéŽÔ¿§ÐRvêhqG~'âE/ZOl 1ê?;P׿ւqíïGçøQŸzN½y£)}ñŸz:ösØbÃ8Ï?J1ÍŽ(à÷4~t½yâ›Ó©? ©éǹ¥ GñRn\àO¥/^”}qFhÆ;ÑÖ€ 1KùR`Ô¼R\þtŸL­éùÐÓ …/8êsIÁúzQŽø ëG8àÑÏ÷G×4vê(8ì(Ç=iÝúÊçÒ€Çz?LûÐ¥=¿/CF=¹ g}Z8õÅž€­'NÃë@ Å@äÒd~>Ô\QÒƒGáKŠLç½»Ò÷ëøRc¨„ñéKÍ÷{ÒgÐf ƒŽHϵ!¯&“úRêh:âƒ×¸£ÆE§P}ÅŸlQü¨ ç¨ÇÒŒ{æ€åIŒŒŒRô¤ã=9 Bþ?•.=é9ô¥ÍtÍü(ÉÖ“'Žæ‹À£µ'¿}9 ñæ—ŸN)})>ƒõ¤³þE&©£>ôP)€p9ÆhÈ£8êE§o€ëG~?éIa@…úž(ÇNZL{QÏÐP1sÛ½÷æŒCÅBEŽG¯×49'ŠL·n?•>¹£zLñÍ/ã@ó½ÿ^—œt" Åg¨–“ íùP1xõü©??\G4€>¼Ò`g¯æir=èɳ@ Ϩ£Ÿï~F—…~?J`õ&ƒŠN>žÔ´(ãÔþtg'¦hÏá@ÅúRgž´rM>´sš^J)?ɿީúQÛühÈIuïÅ.ãI¸væ—pô ý(ÐæÂŒ s@ ÀïŠ^H£è1F9Î(ÇsF9¥ÇÖŒzÐcž”`zb–óÅñüé2?ýTuç©£€ð£óÆ“'Ò€Š2:gš>”PŠ(ÏÔÑÏl€8ëš^J9[óPÇ­ãŠ)0ÿª€Ø~´cÚŒJ_ÎŽÿ3F=ÿJ8=èüèÇÅ÷ ÷£ò¥Å&>´Å¸Íö€õé0=iÀ~4~˜síJ0)úÑ€{ûÐñÞ“¿LQaùRö8ü(vŒçŸÎ‚ÐúÑŸ\Ñœã"€ £¿zp´{sFsëøÐz Òu”£‡ò 8ô£h#îÒçëA¾h„`ug“GAòÒƒÀã9¤tœúRö¦dvÚ|Š^Ïá@ ~£éE#pÃæÏPóŸJ:õ<úfŒŠ=±úSáœàùÑß§àM7’:}1F0FA?Zy'ÖŽ¼àf›Í.zf€‚ðy{Š2èizw có¥Ïl}sIõ.ãÒ€ ÿ‘K–1ŠCÈÀ8 ¨'¥>¿ˆ£¯p:Ñœu<{ÐÁã&—éŠLúùÒçéøP úr=¨Éë¥çš9ìM/æi¹ìE.{(1è?Z_ÂŽ!hÎ(9öœz¯çJ§ëKø n1F§ëN žÜ© 8ô"€=/|g4›ŽzŸ¦(Áõ4 žô¼„ÐpzÐzt8£ùRtïÅô?¥/>™£?…&8çùR(:÷?•ÇëKŸCF{f€ {cñ£4‡'¹Í)rq@ `š2;sGOSIÓ¹üh<Žãñ£¯­/4Psë@RZ2Çõ¥ ñÏÖ€Fxíõ¥Ç4Ò”gÒ€Ãîi3ï@‚Œr)i3í@Ÿ­.{bÓÒ€Í'àS³Ž¦“êsïŠö¤ÉéÚ”ãÐÑœöÅ'çKŒõÏçA÷É÷qÞ€Œ÷¥ÉëÍ‭çOOÆ“Œ{Qô ¤üÿ:\ŸJ9ïšBàÑò°ã4t3K×µ v¥ü)7{^Ý zf‚~´véFxõ #ÐÑ€ýtQÇL~´c¶ à 1õ4cë@4˜æ—ŸZ2=ÿZýtóŠ9£¹ ¥Ç\Ñ“è~¹£ð õ£¦3Ö—’rF)¿ Qõ¤À_¥öÍ.yà3MÆx#J]½†~´¿AIß•£‘×4`õÁüè;t¥Î=¨ÉôÍ 9ïùÑ»ò£žÿ­êIöuéGbIüqG~ôcƒÍuŽßáAÀçý(ëÎ ‰£Ž¤æô?•Ïb(üçG#®hÇ~hãè6(9 Ï­.{b޽õ?'y£ó¥úQøûPsëŠ^}iqêi;óœÐÔv?JLÜ\úÖŒãÿ­@8¤£<ôæ‚O\ÐGéKǦhà{Psõ>ôc©~œP1ïøÐø1è ÇSŠ8úÐÎ9÷Í&½¯AKõŧ֊8) ö&€ ÿúÅ΀sÔcèhÊý? õ4{çñÍéúQj=?õÎŒL} “Å®hÆGj\ŽÂÃ4cüæ‚(ãÐçÒ€N:b€ ¡£?J(v£t~?J9¥úsIÜe'>”c'Þ—ð?\ÑÏ© 9¨ÀôÅ÷¥çë@ ´÷Ôdÿ‘@þrh#ØÑ•ïš3@ƒ°âŒƌְǨúPá»óF¦);)p:s@Qëõ äö4œgޖ÷\QŽy4uê)zS˜×wëúRÒŸÃñ4 LzQƒëGÔ 23€N~”tî3F}p~”¡¥í@„£ŸZ\Ñ@ÄëÖ—Pr>”€è(Ï(ϱh?LÐÒt£Z=úÐõ¤éÚ—>´~u¤ žœÑõÍéAëÞ P¸wàÐ4¸ö4c¶Oá@„Á8ö£œRã×ùPh?à8 éK”P~ŒóF=ÍõÏå@¦H¥Î:HOõ4r}3í@ ùQ“ÚŽ'=Ž.^húHç“KÏ®(÷Í>ƒëFI£ðÅ/¾)?ÏZCŸSùRò9Çë@æ€1Ú€IúR怯ðóKÎŒ{Ògµ/â(ÁÍÙ£4QõÇçK×½'èú~tQÚ—µ6Žž˜§tíE'¨à÷… >ôuõü(ã4˜úÐÇ­.)1Š?:_ÇŠN´`QøP=¨9ö£#š>”™=Í(#ÿ×GnhÅ·çGáǵ4`žô~TtïF1Gq@qG9à‘øRgŽóߟ¥/9àþ”ÒúŸ¥C@ žô8íKÇj(: ^i9¥Å&>´½)NhíÞ—­'oJ:æ€ 9>ÔQÇsÍúLSJOoéIŸ^ 3׊\ô<ÑúÑ@ ÷Ép:š_ÆŒc½‘GçŠ=:Ðqžô™ zjLÀÓ±éIíœB}ñô£ ÷,=…;rh#<C =½¨ù½xô ;Rÿž”À†N«Œô4Q/ ¹$ðzÑHŒuÀÇ©£'±æŽN0)søSg±ãÜÒÞÔ€ôÎáKô€ ½ó@ÏcÅ.}E'­899üi0z\})Ê€¯z?KþzQÅã·Š‚yÆÒ}éN~”™´nJ>ƒÚ—žäþT™ã“ùQǯëKÍ'4 \Òr}©pO^h&“žüR€}é??2{\ûÒgó ¯ð“ô£œPG¹ŽlПSFA8Áü¨íKŽ1ë@ Î1š7 u ñÆh÷€Ï ùšPr(ËŠ>´s@ǽ/Oÿ]š@1Ö€©ëF­!?_Ê“§¡´ã×½!#½ŒcéA wüèsޏ¤'ÐþBŽ£Œ~t£=è:sš^Oµ:þ”qýÜýh äÒþ”¹öŒf€øä{Òã¹¥>™çéF3ØPpzsEè)së@ ÿ9£ÔS²zN(ú÷cÜQǯ4¹¤ëÜQù9 ‘éïFsÈ#ò¤Ç§êhç9Ý@ 8ö¤ÉïG>¿¥ãßñ r8È£‘êh#?Z;gŠ7œÒàuæ›Á<ÐTPäzâŒú⎜cñ£éÀ É¿Iž0O4c¾hë@~¿€£$ö¥1Gù†žý)1Žœ}izý=(íþ™>¢¡éKŒóÅØüh9ìGâiFOQGCè>”cÜÐG<“F(éÅ)äP:g"€IôÅ/ɦà•4¹£éKž9ÇáIÐðGÒŽO¥;ŸÆ€G¿åJ8îhúœÐסsŽqF}Í'~Oá@ Ÿ§åF?*:ŠOÆ€;Ñœv½¾´­.qÖ“ ô4c¼ö#ò ÏbÔ§‘ÀQ’)¼ƒØ{ÐŽaí@Àíj2|ý)I¾(¸ÜzRöÿëÑÞŒ~tgñH["—Û4dPFFzæŒûþTgÞ€ýZ\â€ÙéÖçû€:ã4¿…' QÎ:Ðôÿ8¤ü  |Òÿ*LçÐR;þt¼Rté@Iãcž¢—>¼þ4p=½è1KG^†Ž£­Ê“Þ§éF1ÜÐäò?! uÏà)y=³õ£¥ÿ‘G=qš¸ ŸÆ‚9ëF}Oä)u mú‘GçKŸZ)SKøþp=¾´qF@âcF}è3“…üx£|ýiwµI“Óµ(£ëŸÎ“Ÿ½Å(縠;zw¥íÖ“>ü}(ÎG dc­'E'áGãë@ÃþúÒçÖ“Ø€hÏ\þ¸ ã×õ¤=éKšLÒ¨œž¸cßô bçØþgÐb›Œô#™¥Ç¿ãŠ:àþŽâŽ}hÁÇ^hÎ:ùQ»ž£§SK×½&s×ò£w±dtÝÍ(éƒ×Û;ä¥&G÷…û“ï@ J2? 0;QÓÞàhÉÅô¥æ€Z2?È g×ó£#Ö€ŒRw÷¥Î=¿ :ôæ†3ÒƒŽ›N(ç¡ãé@Ç©  ¥ÏÒ“ ô È£­'>™ü(ÿ_S@ øš=±Fh BóHsÒ—ó¤ÍÒŒã½ih?1èOåGÔgP Àš>˜úRŠJ/×­&}¨Àÿ"Œ‘@ƒ¨¤Æzš^Ïz9=¨íÁ¤ÛÇJvhí@ÄÀŽ/?…Û4Ns×>Ô¼}½ LÊkʉÃ7>€dþBsHŠ8÷'½dGŒzpiüûb*©b–äÒ€=(qïGàh^J?@…ëÚÊ“µ/ò àzFI£w< f€ ÃÖ¦?:2{fŒñÏ´„€{š8ê(Ï·ë@Z>‚“¯Z\öô bd gŠ^}©2:åKÔt AùQIß©úR絎(úc4 AFE–’–€Z?Ö^´é@(?ÏZ  éíK׊P=)Ö€Òð=(¥ ÉÖŒƒE-'áEPùQŸÏëA¤Ïû8ühù‡aG9ëøbŽÝ¨úÐñIù~TgÞŒûP:ÒþTQÍ&ix4r)(£¿8£ŸÂ—ðqIÇù4´xæ€æï­)Ïÿ_4~¼P ëKÁhã·Z;ÒdÔŠ8£Û<Ðóÿê¤éÏ'éF1ßð¤ã< þ4¼_­úRdô¼74QÏÖ“9ãò¥#gõ¤ãë@ ‘j1Þ“§~)r;ý ß­/à iÛÖ— w4té×Þ‚3×4n¢Œó×ðŨà ôúÑš7­úÑÏ®iIÇ­{þt˜¤Ï¶~´¼¤ÑøP’jO§éJ9éÅ.éÖ€‚zóFsN'hÇÖ€·LRèH§tÿ<ÒgКQŸCFN)¹ã#4§Ž¦€ÿ]AMÀÀÚ2)y>¸ ;R~R Žœ{Rõ ÎG…w¨?…/7ŒÒc‚hÆGAG¥ëКN=h#œóIƒß—èi?/Ê€Š:÷"“œp(Ç¿4v$Ò€{túÒcÓmÈèhyÍ&>”dñÎ=¨qƒÀ£=£#7?Z?Ÿ± ö)ùR€=¥íÁ ÔqŒòixü)2ýT½úf€ @(ÁïÍ&Ú1þs@;àÑϰúRþtcÒ€îM/>™£ÛëIÓ ǯåšB=üir1Ô“·PJ\g¥=~¹¤Ç· LPr£ŸJ=±F=³@)=Î*Sèh8 uó¥Ï4cÖŽœå…'^Ç'Þ—”qŒãô¤ÇßZ\c¯_­¥ çùQ­-'_Z^;foé@ ·¿4 ý)8=? ^;b€íF8ä~TuïG_Z0;þ´|¼`‚i?½Çµ.AèhÂÐ1Û~TPÞ©£Ÿ_ÒŒŽ€“@KwÀö |ûHséÍ.O×é@ øPuÁÍ'_á9¥üèNWóÁ¥úšN1×ñ Ç¡üéØúÑœZOÌPy9£œþ4¼ûуë@ Ï ¤úwNÔ¿7ômÏsKŸoÊ΀ÇcG=ˆ¥ëÚ“=¨9ÇÝ4{äRþtzu “éGÓò£ß4cÜŠ9¤ÇÒ—éùÑþzPÍ&p \O“wüèGÍ úQÇû8 óÔqô ÏýjN?3žis@3ïGNGáHp}3G´¼ãŽé8mëé@Ã'ÚžGëKÃêhô @ì (<õÍüh2Ëš:ûû)x£ÔOÊ—õ£ tÅÏ|Ð08=sGG4J3ÎE¾ ­ïF}ó@ øÆœ½'^EÇ9æ õ"ŒÝ)}¨ç Ç҇׿‡}(ÀëÖ€oÇ4r;ÑÈé@Èè õ¸ gÛð£š3îM¹…ºÑÞ ‘ž´§ëŠL}(Ç:@/Z:»øÒc= (Èîi€ úQ’(ã¯ZMËÐwô z‚sF?ÎhÉö¿Z!ÿ.?¦ 2=M c¥â“9ÿ _€=©>´¸¢‰úÒÒdö4{ãñ\ôä­&OµúýM/_OΈ@=sHzÒô£é@„ {ÑÀîivæŒPaIÉè(ÇûX£“ÜÐÍ/×õ¤¤Ï^x¤1Üú~fŒzÒ`v¤ÉÏA­0Û¥ Î1ÀúQŠQ@„ç¥ÇÖ—ïF®(È£>ô}hü(qëFhühϽqܿ޽…ñ A|ÑøfŽzRqÞ‹ŒŒfŽ}h£Œs@4d:t 럨 Š9¤úP!xõÇÒŽ3ÔÑŒú~˜Èüèi1ŸSG'§hç±â—¼Ò õ sÊŠMÜõŒþ4¼ŽâŒsÖ“ðüèçÖ€GAùÒóß“MÆ:1¥çûÇñ ü '·õ£Ÿ\Ñ׸ Fr8$RàœQÏÿ^€ )2yéGÒ€Š3GÓgŠ(ϸ4{ô <çÜÑøÑϯJOl‘ôcÜÒîÁëE÷ ¥ô4dÐŽô~`Òg=ÅÓ"€§\šLžÂ—¸ Ï £>=é: QÈ ñæ‚TrN)?•ß#·dv4g'ž”¼ÿõ©1“œ°ühéÒ—4tïùš?@ –<` 0ý)8êhçðô4œŽã4§ƒÚŒ `{RŽ84ÎzîúRã=çG ÇÖŽ:æ€Sߊ_SAÁêGµ.1Ð΀Ž3=èú0ü(Æ:·çKÓÒ€ñüiqžA€£¶qøRaO8ÇãŠI¥íÔŠ3Ô3Ÿð ñ ŸÒÏ_ÖŽqÀ ޹&Œ÷ÆO ¢ƒõ “ØÑƒë@ÿ94½½h6ñŒóëŠM¾ù¥ÆG¼Ð㘣ÿ.hÆÆ€Çj_^(üIüi2G¥–(ÁÇJ2}Ïó s@ÁõúRãßÿ¥Æ©¥éë@ü~´™°h?\RÑÎ94zsF=©O½&zóõ ý(£ŸZ?ÐSI·®)qG¶ô£Ÿ|P=(9ï@}w¤šQ‘Üb|ÐryŒœôgÖÈŠ?ÊŒúƒG¥ îÀ4g4î}( üMSKúÒqé@ ~h ÿõ³KøP'·4wíKŽ9£€:þœž˜ü(*z”¦í~h lRàç¥;©éøÒ~ƒƒŒŸÊ”ΔŽß…ŸŸÒ“€{ý)NqÐÒsôJµžiû¹£¥.ìñŠLó‚Ù£¹¥öÈ žÔ¿ç˜ÈíŠ2: f€ {Rööö¤çÔ :{ÐÞŒzQøQ€hÇà>´cži+М{ÒãÓŠ.)2{RuþùÒçÖON´ƒŽ€þTàG§çF¯ N{@'ÞŽ{KïŽh~•úІÃó üóG8ä~T½(Ï=s@zfŒŽäQÇ©¥Å7÷£ ö;”˜Ï úRö£¨æŒúÐsž§ri3éA>¼ÐógÔ}hàš1è1ô¤Ü:çÓ ^{š1žsŠ3ØŸÆŒžÜÐ|ÑéGáK@„éÒ—ð£ôgžA b'¯éF)p{(ÀêqŸzLŽÙÏÒ—è¤à”1ïúÒŸlQ×±£׊@ß•çš?ÏJ\ñҘĥÁõ£?…&­·õ¥úÑÏNE aÏlÑŽsF=È¢€}(£ŸÿY£Ô~X¥¤£¯zZOl8¤éžOá@ GáIôž¿Î ÅgÚŠ3ŠO—>ÔdúP~?¥‡çKœôý(çÒ€>‚—>ÔQÅ'Z1ÇZZ?ÇAIaG=‡ëE(£ŠB3ÔKߎ(8ö¥úâŽ\Q¥/q@ øQqKIŒú~tRcëKGç@) `t\QQúP3ØÑƒÞŽn~”qþµ/ãF?Ú¤ýhãüŠ\ÆŒbŽ´}•v£žÆ€ø Š>†“žp1@0(à(ç·J^q@ EŽ ÇA@}4sì!<|ÊQì?:8 û \{RpqøÐŸòM <ýïΗÆ@çŸÎ€ 8õ ÔPùÑøÆŒÝhÉô èhü ±ëI’E.9Î hëØÐr}èÁö¥íIÈãô£ñü(dRJ>˜£ŽÆ€"—ï/=“grçž €pëKÏ÷sô¤äöé@ÿ<ÓàOÒÄö¤àŽW`qÁ gÞŒçøi?à8£‘ëÏ¥/×9£Ÿz2ÿZ“\P“ߊLœÒ’;Fáœm"€ ^~”¼úcÞŽƒ­ÿúÔ˜õcŠ9ìEúÊ?ýhzu$šSÒšÒ—Œõ  vâ—çµ&~Ÿ/áš?Ö®3GãMã<€O¸ |Ç¢­&úÂŽ;qí@#Ò€ëš\ZPjOlPÀëšLzøÐ¨üÍQøÐ㎃4œ÷ Š;Η‚8ý(3ßéJ3žõ"Žÿ:\ŸAGOJLŽÝ~´£Š}‰£ŸZLûÑŸQ@ Ïzùæ“ wãÒ—§oÊ€i0ßJ^É£¨í@ Áu÷¥çûØ4réJq@ ϯJ3KŽœqAÿ8 Üz`gó¥Í'21J¨ çØRóÛŸçš^(íèhïëAõ¤Ç?á@ Ï|QŸJL{Ÿ¥ÿg4¼ç®}©=»R`Å.ÞýMö<})y?Z¸£üõ 9©?\ÚŽ(ëÇ=/AH‡Z^=)?>”GlûƒJ Psž1G?ZN}E&yì~”ìzÒcžôsè¥9ÿ­@:ÑIœŽhOÒ€>¤šO§4qëK×·é@ Ö—ó4™Çj8<„ŒšLã¾(ãÐf€ŸAF)·¸õýhäv¤Íý?Z_Ãò í×ó|fŒû  vÅðcj1Æ:þ4‡w­aל÷ cøhàöü3@=hÈõ£ŒP×Ú”QHNzÅ÷ Èõüi9Åö£ =²AúQŒõÅÇðŽi{tûj3““GéAŒt ŸQš>˜¤ÆÞÀÒóýÜPùQÎ:QÍŞؠdzRÑÉÿh'è(üh£ðÍ&Iì1KŠN}¨úŠZ3G=¤ç= ÷Å'z\Ò;ãñ £Š:÷8úQŽøÒ€óÒ—ÔRgž¢Ž:‘@ G>´™î,Ñ‘@ ŸlÒg=qŸj2=Eç®>´ :ôæ–Š?*OÈÒçRsê>”^¼ŠNqÍøÅ/jNz`QcøÒŒ„QøÐŠ>”qíIŸjÒò=)3ß­!ÛùPŽzQùÒcÒŒúþ”Z)21ÀÏÒŒš=(ü8£üô£?çsÜÑÒƒë€ 3Ø*?*Nz ÒãéG^ÔiRO_ÒŒZ:vÉ ‘Ú“'4¸ã £¥Aj9ëGZNžŸZ\c·ëG?äRRà÷Çå@ ŸAøÑÏÒ—¯CG^Š úÔg¶qFIàŒQ‘ŽM4dÒçÔbŒÐ×ëG4}?Z3ï@}1FOp?:>˜üé Ðýi1øýhü 3ùP?Ê—éü¨Ç?QÍ!‡ó£€QÖ˜ƒò£ŸoÎŒ@ 1ÇZC úâ“èÔ½;ãëE0qÔ­þ4sìhç¾?*ç­(¤Ï©¥… úÑžzi>´¹ÍûšN§·çKŸóšBÆŒþt9Å> SsÜqG Å'¸ÇÒŒÞài232isôsêqL¨ïøQÆ:š0z?þ4~¦“ {þt¹÷ ïGçF{gŸ­÷ ó4:B QÓ­ç‘GjM¢—§µRdúÑøþ”¹ö£ó¢ŒýhÎ}¨¤úf—¿4töö£J(úPd ò*^¢ŒÐ~´uèhçÞ“4¹÷ š0i;Òò(Æ:šÇJ?8 üihØü¨÷ aGãI“è)yõü¨ŸSG^(Èõ¥ïͧ֓ô½©2?úô ^´(Æi u BçüŠ^½©8õ£â€9ïøPN;®hëßއ®huäsøÒÒdÅúþ”9õ¥çêi3þµ¾ñ úâ“ùÑϵˆ üM(Ï­&A çÖ“<Òæ“4 3A¥Í&áÐÏRhíG^´~8¤RãpçµJ2Ê}£éùRãð¥ÏÒ—'ýœS˜ïƒšíƒøÑ•$r3KÇlPg×#ëGëJÇB(Èÿ&€ß™ c™£(#¶OãI‚:Ðà_¥ûÐ×ñ¥çßèh1ž½}h±ëKŽÄQ€=hÇ¥#¨âŒöÒätï@èáš?øÑèFqïFåÐ\Rtè(8È<}sFG\þ´r{Rõ⎣š?h?Z^})>QÁ`?J:öP‘ÇLýi>¼Qô¥ÏÔP{`‘KŒ})2OŠ8è21Ò—‘ÈúP 8ô€üóIÁ£ éš?Ê€Ç`(È'¶i:9ÿõPuþ”qØGÒ”8þB€gëN¤â€ 9gšLx?­)úsIöM.VŽ;øÐc¦OëF;â”g°Z0;@ ×± ûŠZ(îÔ›OaNü(Ç­'8õ¤ã®HüiÄ9éG¨ ŽÙ4½ú~´¸÷Í€ŸASA>ÙúQÀëŠ\ûPc#¡{~4œuüñK¨`ŽÔsF;`ýi0hiû¿îƒÐ¥}……§LRóëšLÏ?|½éré@ ŽyÚŽý;ó¤àzPcñ¥ííKŽ:QL~™”zf”ã®)h9£è(¥ äzÒt4¼bŽz):sƒKÓµ€>Ø£óg#ÖÈ鯀ž´QF  }hü¨Ï¶Eç­Ͻô`ÜÒqÜþ´¾ÄQÛšL{qõ ŽÿÒ€“ü8£šCøQÀã¡ ÎOÝühÀô¤¿­ÇbhqþÎ)zŠNƒÚ~hHõ8 GÓùQïùÐ11þÍAŠ^žæ—ÜÐ!>cýßÊŒvÅ⃎â€= &=E.G¿áFG§é@:c‘£'ÐÒñGQžzQòhëé@}&yàqKÐQ‘ë@~œzÑÛ¥J1éüè¼úRPT0äf€ŒtdúPµ&qÍ8 N=GãAéœf—š(9ôü)x¿¥'>Ô}h£´;P!0qÆ?GÖ—éHG°Å `w4vôÍQÓøh0GAøš_Àf“ àbŒg¨ õçñ£êG§çA*:ƒ@ƒ§RãA=8ü¾^¾ôqÏ¥£?ΓòÍ;è)sÓG¥—åG^ôtõü¨Ëw¾øü©2}èᅫ(÷äÒòFHˆ¤ÁôîA4€>”mú~T {RcÐ)Œ_ÂŒzRŽyÁ¤Ç×ó BcžI¥:΂qØÑ×ÿ×@=¨è=i~”Ÿ…LÑŒvÉõ ñþy£ß AOOÆ—¯lÒ~¸£“Îh¼ÿúé =úŠÓš ü>´ ç×ñ¤Ï®i:öýiGÓõ ·øRÒsè?:6ƒØ~4dÂFx—ßnh1íFG¡4¹ö¤Ïû?Iùsìh ŒŽ˜¤ü3ôSê>ôuéúP08ÇJ8ôüèsÜPéŒ \}1Ií‘@ ׃ғ”g#¡Í;~´¢ƒIߥð\Ÿz)3K@'^ÔsŸj^= 'áF}©{Rgêh¹üi9úуޚ9£qï“ïFqK@ ç9äÒŒúQj(ÏáF­zQŒÐƒëG?äQGÒ€—ð¤ã=)qí@ žùÇÖ“žÅqKÎ;1@}qùT_iAsäpøÈ$p~†¥Èö`góÚ€>Ø£šJ9=Gå@ÍßuïÅ¥/à(çÒŠLsG>ÿ.Oÿ®Ž‡Ú“'¾ÒƒÇEþ”¼ÑÏzL³Š_Äþt¸æ—ŸLRdß-ÏjL·r)y£¥Ÿ‡åG¹ŽßçŠ9³KÏ¥&{c?ø ýhü 'áøQŽäb€ {ƒKÛ§åHp9ÍzPš9íŠNühÆ:Ðþvà AÏ8£z~4¡¥üãH:‘ô£ò æ“‘ÿ×¥ÇÖŒ 2z*N{ÒñGÐb€?…hü( <ãF;Ñ‘ÐãéGÑq@åF}qøQÏ|~&Ž{>”™öý)y"“m gÓØéùQÜRâ€!å‡ÒŠY~fSíEH<î¤8ã½0ü!E;wû94ÀRp(Éì1IéG>ƒñ4^O4r:çð£p;­ÖŽÜP9ã?J0{P1Ù¹ô¥Çù͹ýhèy€§z\ôæ—'ØQÉ Ÿ]£4 äõü(ÉÇlÑŒõ4¸âšv÷­(^:œ{Ò½.2z°¤È=y´¹Ï~h09£sŠ^@éšs@ ƒIÓÖƒŸò)h8=(íÓò¥Ï¸¤ÇqŒÐöäÑžÙ¤ÿÔ2ØKøQ@4¹9£ðdg¹ ñ¤Ç¦iGÒÒ€Þ¾Ô:æ—Z:u4œ­¸â‚A sßÔøPF=M/ãIϯé@_Z?: QÏl}(ã¶hÍ;Ñš9£ñ¤úƒõ¥Í8ãõ£ê(æŽOlÐqÎN(ϧ4€:çëKŽ8 $}(÷¥ç~gëŠ(ïGä(2(Î=-–(;õ4¿ä)3Ó§Ö—_€ õ4sè(Ç)9ì/ÖŒûI×µÎ>Z_ÄþtsØÒÛhÅ(t ~4fÂŒš3Ç^(ü(ú}(ü¿3ƒ×gß4¹™í@4§4gñ¢€§sG½¸4€ÄÑF­.(½?úô ƒÒŽ3GN(?:C/ÔgŽ¢€yÅ/4£4œ0sÅŽ´rzRcš=À£¡êixp:ô ¥çÚ€=¤ç=hMƒÜ¥þª9ÍAGµ>œQõ4¼úþ”œQïÛëK@}ñGâ &3î(À‚€{ñô£§c@ãÒŒàõ ÀéÍ/áùÐbÃò£ø£Ÿ­/çH1ê*^¾”˜>” 2=E/åIùQÀäÿ*QÅúÒg?Óž´gž´½}hÍ…œrhǹ¤'ŸúÆ‹ŠçIø~´¼ÐcÐÐ~™£Üþ”´~bŽ}hcèæŒÑøÐ1õ£§z(˜yüèéߊ\{;ã€éM^:¥;Ò—Ž€Š7wãøRõ?Z^?N­79ÁìñÆs@w&Œzÿ:\ñÐþ4d÷&“òüiqì)˜úÑŒwÀ£€=?Zb½3Š2QŠ>¦ƒÀé@ ǸúÒõ£ñü( ¯9¥¤÷£§ƒÆ N¦—‘×4¹>¿¥ôsõ´}(ÜwQÓµ/éFGr(sïIÇ¥/8ãõ¥ü BuÿëQùÑGë@ÄçüŠ3KÎ3Š\P!¹çž)A÷£o¶h#·4qßš;QÈî 3“ÇëHaøš1Û}x¥¦vàQùÒä}? MÃÖ€ }qKÓ±¤ã4~8 A׊^Ô™ö½:Ð0Æ9Å÷Å'áš\ûq@ühã>´™â—#К:{Q×Þ—ó¤ÈÏ€óŠ1G·4c>£é@tÿõÒ~?….h8©=èíÖÌP Í/^Æ“åϽzæ€4tæ’@ øŸ¥q@n´Ÿ‰ü©søRg·4d÷þtpixüh Î:æŒû ÇQF}èëÚŒ{PNzcñ¤ÿ…;ð¤ëØÑ‘ïG^æ€;ƒKI‘ïFGqùÐô¤àŽôdb€ Î(íéKí‘IíŠ ÿ…{~´p=*8Ï\f€ zÖŒcŒ~&“ÚŒÿwõ»Eí“GáFx Ç Å/>¸£éŒQõ èsF{ OÌÒö÷ 9õô¤{f’€éKÛŠCGç@Æi¸úÑïÖ—ð 8êhü?:ZLw ŠLŽ;Rþ9 >‚“æ—ð¤Î;~” ;cð Ž;ÑÛ¥/˜ö£þÅ÷c@Z/åG'Ž´˜Ç8¤>»s@ P(ïIǽ/Ê{Ð0ãÐÑÓ×ñ¤éÚ—‚2zRëIŒs“F1Àb( ä9aÇj(“ï¥ì’9üèÀ8£Þ“'§ozb /ãúSAuÍ=y }zP}i×¹ížhä¿Î”tÿëQÒ€m?Zü©qïŠ@\çð G'·wɤv]¹bF=(îýJ0éŒÒn\œ ÁäÐ!yèÜ}3ô¦ôèsý(ÉíÅÏp:L¨ëÀ ×9£<|Ãë@ƒ#®(ÝîhuüMÏJ_À¥'~3ŸJ7.pr QƒŸÆ€½!õ"“ƒ÷ˆ¥ü(^ŸÈRç4pF2OáG|1AâŒt¥Éôýhü©?ÏJ\óŒLû2=èÞ—#§zLçµ/4ÞüdûRãŒRðhœúL7|NÆ(9ôýh=èÎ;Q´QŽ8 AGnhÀ™¥ã¡4˜ö4¿çšCŸ^)xü>”œû¡¥Ç®MéÍ!Àëš©y=À¤çÚ—¯Z:Ðd9=èã¦OáIïøÐ©1ÿê¤Ï­è‘ È£ výi3ž‚€¥.xÍRdzbŒƒ@ Ͻ¤9¥ýh,zLžÜRþ”PgŽir:æŒ`#¯è(?7 ÷?….@ôüi8ïÓë@}/àhà{ÑíÏ3ÏçK‘ÿꣃïE¤Çî"—ÊŒQõ"ƒìZ>ƒZ1ÏgÓzQøPQù Lz98ǧ4\æ“î _ÌÒp;þ”¿ ƒÞ›ßïΗך\z0@õ>ô˜ïÉ¥üúÐú­ÿ8£×b€ dw Šs@äq@?(¢€“ w¥ç{Põ÷£Æ“8íGâhy¸¤æ`täÒç×'ð ñ£!ôg×4cñ£…!4¹´œuÝšQúÒr;sG'¨¼~Ô€ŽÆ”{sFH8 †qÚóÅ +ž8úÒõï@•¸ÅϽ # •¥ãÔRpO >€ÑŸz\û}i3Ô*_ÆŽ}i¼õþ´džØ´ïÆ“ñ¤¥ç”¹ZN9â“ò3AÀä@ ôÀü)3œâ—tü¨ÆGøQÇ­&3þ"J:R`{ÑqÅÏ ñ@ÜŽOåFOáKøf“q@ƒ#·4dûÑŠL uü¨¹4™óFÛdî=ŸÂsFy—$õ#uûÐÏLåKÈêi? ÑøP0Èõ£ÑŸLQÎzñ@1Ò–(#ž´\Ñž;QFzÐ0£;‡jZNÝþ´À‰¤Ï?ýz\ÐwíK‘ëFAéGë@ã×éG4ýþ´d_¥£>ànæ€(àQœv£'?ýj\ç±ühïÉ£­'ã@ÒŽžÂŽ>”¤u†zsE'¿­/Oÿ] : LÿœÒçÐPÇ¥úÑH2zÐqÿꥤÈ÷£4 8¡¥ü©1ž¼Q´bù悽zÑÞŽ‚€ïKþzÒcÒ©ÅÑרÑô4c“@ ŒšR=Í.@úRqÚ€ }EïÏãK×¥8ô£¦—ðý(Å0 j_ÊjLÿ³ŠZ1I=¨÷ÍúŠLÛŸ­.x£ô &Ê—>Ô„ çŒúÐzZN3A'± ëÞŽÝ©(ï@ GÖ€sÜQŸz8íEAEgÿ­EÔ~OaÏáKIøRçŽ uIøšÉ Œç·åG4f€Ô~d\ö ÈÎ2húš9£p;þTvéKøR:ô ŒûÐO<Òc=ÿJ6ûþ”gÞ“ŸzPô¥ÇÒ€ŸÆ”(úš9I•õçÞ—#¦hã¡ÅⓞäbŒwÅE.=ÍüèÀ4~¿J?:3ïI€yþ´½¨çÚŒgØÒÜâP(ØÇ|QÇsI´zŒýiztæ€ ç¥(’óÖ€ c©Ågò£ô aŽ=(È 8â. ëÊõ£íQõ"€:gŸz(ö ®z‘ø 2ç§ã@ôRô btÉ…§ßÅLâŒ{Ðwê)sކ–ŒzŸZ'£ÔQŽx"Æ€¡?•ß­/ãIÇ®h§ò Œõý)0=N=Å/N cëŠ_Ç~T‡>”î¼E ÈêI÷ ŽzÑ“è3ô¥ú þ4`õä~´œŽ¿¥öãõ Ó?¥=ÿ:\œtüé·ŽjS‘Íã¯éIÇsùRŒú ÑÐ(àŽ¼Q׿éFA㥱 `3Ó4~¦—éGÍÛð BvëG#¡Í/ךCŒuÀ aÉhíÔšSÓµ'AÀ AÏ­/ãIÇãKϵœŽâƒÇRixõ ã¹QùÒqžFµ/™üÍ! u¥”} (>†Lz ýiyõÏÖÄÐ`?/~œÑr~´sߊ3ICF{:\ŸJLqœãÞõühÜ~”¼ú~4ƒž”~b–ŒPqéŸÂ—ê¦Çõ£õ “#iØÿ&Ê€w×ð¼õæjLJôâ—ùÒxçð£pH ßéKøf“ëAÆ9¿¤éFGcŠ_Ï4ži3êJ3ô¥üh?:? ?QÇã@‡…&sÔœR‘î(çŸÒ“qÓð¥ÑŸ­¿†“’AÏ”¹>”žh‡ð£Û<ÑÔô£# Í=ºûиüþ4ë@ƒê?­î8£>‡ô¥çÒ†?Î(ÀcÖ“œPÑÛ¤Ï<ÒçØÐŽ=©0¸áA˜¥âŽ=(+‘É£où4bŽ{j:Ñùš>´gÞ€ {1FA>ôdv Ö“à:1Ïõ¥ ü(úir}©;ôý(hü©2=þ‚—Ÿ¥ ø£¿QKøÒqLý8£§CøRÑŽ9ýiŸQFyàRô¤úcò AžzQ€iyÅ'éL Ÿ­³FE Þô½EÍ&ÜôëHöÅ!¦—×'Š?J`qIZ_®sIøP Æ:`~´`ú‘E LœRöëFG¯4)ÿ&Œ{QŽãŠ ö¥Ç¿ëIŒ÷?…ô€\QŠLñš^œúÓE&©£ò ¤úRãÛš(úÒbއ§^ô£ u ñè*QœëKIzÐ!i;úÒ­…œQœàgéJ>„QøÐgüŠ^} )1ùPǵühÛŽ?Bhïþ3íÇÒ¡£žÔ¸ ÀÅ.8ëÅ Œ@ I×ÔRíõæÇ‚—zQ××éIÇ¥-ÞéIŠ_ÄÑõ¤£ÐƒþM'¸Z\gÒŒš(ý>´¼cŸçI‘@4 ú~t´uíúÐg­™£ðÅ>‡ë@n€Š; 3ôÍ/ÔŠCƒÔd*N}8¥Åh9>ÿJSš\g½&FyÀô $Òó×4Ÿ—çK@ õ94Röæ­'ùé@úæ—·CF=¨1ëÍ&û#ð§güš2h÷ÅúR~t`ÔcÚ—Š9&=¨ëFõ¥éÞ“¯#4¤â\P¹ Æ€ ‚:ÑÇn´†“Ó­;ê(ÀíIÏ¿çHhø˜úR½ÿ:Z8ô£j3ÏBhÉr:t¥äúR~‡ºÐóž£ò£¸£ŸAG#Ò€ ÑŸÎŒžø ý ï†ãÓó¥ žØ£ÛùÐm÷‡ÒŠGÎñô¢­Ü&à[³”Œ„uÆG±èjÆÛñ ãŒŽ3Ú—9è?:b Øü)qßÐ1íõ£ ôžäR÷£#×~B€¯çIJ^¿ãIÏ¥/ …'§æiyõÅ&yûÔ|Þ߀ÍÏZ>œRa²0¿4}@ÿ?>”¹äŠ?3éùÐKc £$téKŸj%/·áAÏëJ튧¨÷¤ïè}©zQ‚j:wü¨ýhÈïÅhÀ‰çyœîÆÞ§•8׌ö4¼‘Æ)=qůqGNô™ÇQKŸjc‚i>aÈÅç®hàP!wäPOòâŒÑÇa@ G4Æ‘|Çõ °Ù»w ~}):õ¤ÎFCgëKͼ_ÊçIÒ€ŽÔ´Ÿ—çHŽ$\©â¤éÒ—ŠLû~T£>˜¤,d)7¯MÀš;Tm4h>yP{“Š~áŒä~tgëGzhpÝåNÇç@…ɤúšN{óô ½èxúQ@$ö µQÇ·åI»Œôõ 0àqÏLw ϸ¥ç¯JilßÔàäsèhà >”ŸÊŒžÙ BhüèÉ÷ äv ­-4:“€A>Ô¹ô <ÑŸj ¨`¤ÄtÍÀûØ çÖŽ½é›¾m¥†qš7¡înœõ óE%ã©À ~¹?JLŽœRo\dF}hÔ~TÓ"…-¸:ѽN>aÈÈ cºú~y¤ãÒ™æ Û–^xÓýxZCI¸r28ëÍ.yÆhdã×𢖛Ô÷Í}óJOµöýhÏ¡ Èö¥È¢Žèëß®i22y޼ÐyÜ(ÌQÇNŸJBÃÖŒûÐæŠNGµ.M¥¢“#Ö€ ŽÿÊ–“pÇoΔ 4uïGNœÓw ·CÍ;ñé@Ÿ&}Å.@$q@ E/QÅ7ß#cÍ)÷éô¦— 2Oä)7‚JžhØÎE!'=ˆ¦““‚FZ3èhIõn(ã¶) ƒüYü)AϦG½/éøŠùâ““Ô ^(þ¼ÑÆx#òÍ'ËøÒ†¡ 2{·éŠ3ÿë¤ÜsÀOZ c©ý(¤óÏJ8ëý)~‚“ŸS@ ŠL’;cÒ—ñ£×ò ?çÈÒŒ¥'”¹'øE÷¢Œ}M ŸJ_ΓŒpH¥íÔ&}zûQÎ:Róړߥ qÓj0}Å¢“S@ ©'ðéGãùÑŸAGÖ€v)2z1Ž‚Ë4Z?(‡8äçð£ Qõ楛@ä \óÖŒ“ÿ× ŽEsê(ü?ZZLÑÏj9Í=ÿ•ÑÈ€=ÇZNœ÷£“ÐþtôÍ0έ ;ÑGùäÑÏ\PJ?})÷£Š`íúÑÛ¯åGJZ@'þº8=³Kžù˜úR~t{*:‚x šZLŸÿ]/(ÏçGN´Å~Ÿõ?¥€`v4¿•1¾s€åqלF) .äàóÍ*¶Ts“ëŠwoJCÂð@¦)OÞÈ4ìc¥! ÷ü¨àr(Éü)dw4¿Ê“>Ø´À3íJ>´œúQŸÂ€ÄQÏ|~fŽÝh¤ÈéÁüi}óIówzÒsIFyê)hÍgÞŒZ`&¿áFëKŠ?1è);÷¥úÑÏ¥h£Ž=hçÖ©Ív¢€Ž9¥ü¿*Lš8±P3×9Žÿ¥sÎM/ù怂(ǹ¥üEºÐ~tdÒÒsí@ƒŒP=¿•ð¥ ã< Z)×4¿ÇhÁê GZŸJ3Û4~4~4OóÍçŠZ?JL籥Ϩ¤ÎŠŒc¸ ðÅ/ëIŸ¥.hý(íÖ“põg¾1@^üQÁhéèMÍ-ÇÒ“ê(ö€Ïð¥þtcÞQ@8äÒõïúRQüéqì(™Ç8£9¥£· AþzQÍöŇ4„Q“žœRóÛÐIÛ‘ŸÂŒ±<ñGãúP=:})~‚““È?¥ûÐI?Ί Qž(üsFh?J:õ€ïÏáMÝK·¿ZB¹ä0üMÏBhéFÞäÂŒcœÐ‚~£ÚÎ“ŽÆŒ ô4à{J2;šo^AÅ/>¦€u÷Í'9ÁÁ£ zçé@ GÐæ—­'¹úP0üMÖÓëEéI‘î)hÇÔÐ!7ÄçéKœŽôsëF3ï@ÈŸïŽâŠ%ûËô¢×éHAöê1øÒçßuÅÔþ´½lS>”ôÔ¤ÑÔgQŽÑ‚>¿ãV±ì(ã¡àÑÌÂâŒvÅŽ´~T„žø„)Æ1M!z9â—ßu# ©3Æh¬-åÝÉVÆFÒ{õ«{°·¡¬ï/Ì.Ïu!HÎ@ÛÓüi÷Mä3¡$®AãÖ©«”ÐAw7_k_1Y \0­KrêÄÀñ—R{Ôj¡/P‘¸ÙŽj[…Þë¹ÊãG“èq¤[ <Ìa±”ŠY,¢†“æ>V[‘œÕìŸZd¿,LwÀê9§Ï.â»Ye± :Öª.™ÄѬ’¨ct«nüÎ]SŒTØÿdRÕÆZÙ¤—„ï¸È^3!Ç_Jµ ŠÁ3H&‘·áŽpicn³å1¤sŸ­YÎ)¶ÆÙZêMÛa)!ßüH3ŠF²Fpç9 ·'©%b%O™±è½*oçJöEí¢¶\™_Êù‡9ÉúU˜îµ2²årA#ð¤¹ÈŠZ!fkE%—vÞHéNí­CrŒv w’ ç_4䃌 "¦þÍQ)“ÌrÅ6å€5bÕ™­Ô³n÷õ©»tÍM1¶U³u ÖáOîûíÆsVÿ †5™e}í•þý*nÞÔ›¸˜QÆ?úôqØÑSšB†F1׎9¬¥ÓâóR Óe2ŶaMk`ãŠ>Yöï9ÆH#?­T[[ ý†4w;¨#¢Ôöî…6!ÎÑüB¥'ëU•³rPN¤ŽJcµl7M¿jŒ–“qéƒÅYÎ*»ïCç]„tÛÈüjÆáЊO`èU»DÂX•ÚümÍHÒÇ Û!=Å%Æ~Fù`7 ƒCe­ó'#¯@hè ¯eö‹i#Éó°`Û‰ã=95)²ýào´J0›@ V"SåŒã>ÇŠ~¦h»Ar¥œÈÛ†,Ê2XƒÏãM™Þ)óŠàà­J‰r.Y˜¯”Wîã½íö•ØèpãÓ¾£êTm2-Â_0c&á‘zc5goÙ¦’EÙŒtçùÕ°=ª)ÕšØÛ[Õ….f+°[¨ÚßÎ' ·w>•I-"»O§÷Ø=iwO•”¶ß½Šu¶ð˜wV8ì0)ì2`æRþpÆÍ¿wŸ¯Z’ج`³'"¬çÖ«Ã5òèÇ<…¥vÐ\†ì›‚-£‘ãqóeAäSÎs,¬n0®¯5d« ¼‘ݼâüên?¹ùÑ{§³ìòùŒK ¡r \ÈǯáP\€T/üàTãvßSõ¡ê 1ßèizóƒøÒp9ZÓõ¤!MAt­ÙÂ>öqÿ멸ÇLTs¬ ãqè[šlxû>Ðrc#ƒM³ƒ· œÙ©P 7 éL¶YÿZOÇò¥Æ).@íÅžœ LÑÉæ€?ç:⫤²´åX¨PHÀïSŽ=¨¼gÒ‚=EAs$‘Ź^FI©w`dœ`uÏî(Õ@÷ «Æs÷p)çí;×çLcWúÓ°X±L}(ç¦*^R¥eÛ¿?ÃéFé–\áJŽ[¥`%Íïƒõ¥Àúýj η;w ¤p½è~ÞÿJ? i,ÀÇ5TKzIÌHžÇ9¡+…‹™ú~4uèj™šìc1FrßÞÆ[F  ‚0} 6¬ÑúûRçµ&}©¹Ïÿ^“üóF/Ι;H‘«?`Ô éÀsШúÔAä1îdýqPy×F$>OÎO##¢ÁbïJ8¨by[!Ð:æ›3LqåŸsNÀOÁ÷¥ªb{”˜ÊäãgùTŠó0È»=A拉þ¸£ð¨gwD 3‘œŽÔ‹#™NåÂ×4€Ÿ9ÅžÃ5Y¤¸ËŠTtùºþ•2È¥€Ð”ãêzÑø~u’È’±n\psÞ¢ŠîàùBKlnûÌqúSJábç8è(梊I˜IÜ0iÎì«•RÇÐRþæŒóÁ>Õ’Qç_›Ó¥D·G0‘ž0M Ï'š?ŠŠ»H=j)n$K•D„º$·¿¥Ô tqT#¿w‰]­ÙrÛqèsŠž)$‘™Z=¸¢Ö ýqTö]ùʼn]‡²ÿ:¸>‚«ùÒ8 È¡%ˆ?–˜/ߊ#·áMF%Apî;ÔRp{þ”{c4€_ÂzN1ŒQŸÆ€Œàt³Gß0ýãÁëMQù­È`3ÈàÑ`'ͪG¨C!Àbê"­dãž(jÀ-%VÑ'ˆÎ*E+_À $û¼u§f,`zÒóéQC/Ȫ@#¡¤ûByâ€ØÏZVoçG>ÕÜElvÁú!' ³<Ñ`%¦ÈÛ#f$ƒ½)>ÕVñŠì;FàQBÔŠðHŠÂ6éVx=¨è8Æ)sC9æ[xR8Qš¯öô>Qï‘SÏ1ÚŽœUg½‚6*3œVsž˜4sÞŠ‚[¸!š8äl;ýÜHo Ý·ÌÁ÷â˜X°3éùÑõÆ*(çŽ_¸Àþ5'=…! ø>´QùRÎ(J2Þ¢šŽiÔœÿ•.;çõ¤Ï4}@ ÀÇJO¡qŽ˜ö¥?A@ ÈçŠã4qþ½ÏJ;çŒQǩ̀ÄQ¥/NÔ˜q@>ÔmtÿõÑÚ€À£?J9£¯­}(ú(ä1øÑÍž”QÉì ç¯ë@À>˜÷ŸÅã¦($÷>ô‘Í9éÅ/äPN0ãéEcxúQ@ Í8ž ãG=ÀüéìûâÄf€0;QõÆ)€¹8æ›ïÔÑ…éüé~„Ð Ï¿åG>Ÿ‘¤Ç#ŸsG^ô p'½ûþ”Ч®iO¯?….I¤üA÷÷©NOs@„ǾOÖŽizœgšNhqޏ¥ÇÓ4gœfŽ}hÅ&=è瑜(ùü¨¸Çq@ãÞ‚8£Ÿ@hqŽi=Å.z1úÐ11ïGCKŽy£ zÐ!8õý(ü¥ür{ LKøþ”t íÿÖ sÅ/qE&AïúÒäv挟^(úñ@xçŽ}E祅LÑŸÊŽqIÏn( ààŒãŒÔÞ`ˆ JïòPã“ïU¬Õ¶ëška–‡î n—ëHAzsô¨®sä¥Ïñ —ùTS®øŽ‰ë…ÆZ>2Å~r¤ÿ³ÒœHÅG —&6Nq‚)ì@ROLt¡ƒ!„H·0Úz*|{“õª–² ÈV1œéV‡^´Ø1E2³:ýÒ=úÔ¼â«OµeC±˜žãµc0 &I8 ô£ 9§sì? B"˜¹Â[iÆzf©!¿R¡m¡ÁûØ~Ÿ¥^œâ;KqÐRC1M; Ä·®„ù*§¦ÝÙýjÄO!|Ðãžõ-ÇAùÑp¸øQÓ¸¥É=¹¤úŠB’:ÊçÒ”ç±Å!é÷³ì Av,‹ þÿZŠÚÚEvóR;vÇ‚?Z}¯%ÿvW’NjÇS×4ïb› ;Åà;Wê8§OÈT(r3P·ü„†àp«Á zýi÷X,ŸºÝ“É9ãò§Ø \úÔsò[_Ž„ãõ©°¨ç ä¸qÆHëR! Ü#åU}6œÔ¹îG㊊Ý÷©ù0£€}j\~ÞàÊñ«›¢î¸ÕŒzÕTÚ׿u·*àõ«X'Ò† †MÿhQ¶2„wƒSg±?¥C)Úê6;èp*|œuü(Í¡\0àÒ¡•Pã•QÅò€XÆ)±¶¡ðA ¤çõ£ t]á‘cŠcoâzjÜÝ• öáF윟­O¾tjø*OcRqÛò§~èŸCéKUàÚ®È dV3ïùTƒ#ÞŽ(Ï×4™Ï± AþzÔ·ÚpÑ(àáÃJ› îj²˜þÛÑ÷…î8ÐÑkð«¤Gí,æ-§×vx«ù©£@—²Þ(õ¡$‘Ý#r|ÝjÇnƒóªÏ"”\œõÀ¬çü⇰2½È‘¼µX•зϒx“«%¦ÈcVÆRxÅ%ä›L+µÈgåçó§ÌÙNÝÀc·õ£ É"â%è8éœâŸüé‘ ûÜqŽ*O“ŒŸÊ©ÊÒ%ìa ܬ~fªevˆGZŠ]«wæL“ž:UGpD {~D‡ìx &ÐI<¯®*ÂÌóÜI °°Œž²Ë• ž VµÌy…˜¹_â#®ŸA’²ˆ "4bN4–Ê<í*ObIþté†!|–ÆÓÐd¥6Û8,zrÝhè"lûT(_ÏlÄ'ïnÍMÏÖ Ufr3–<äR@„Áûqmœü¬u<‘øªÁRûÌf9*nÞ¼žõn˜2½ÎX±˜gøzÔÀ tÅG;mçÛ“Þ¦Š] Ü{Òó×4¸¤ ôLŸ^>”œgüiÄ”`÷þtŸç¥çê)F4cœõP)y£õ¤ ‘@G\G\´¹ÿ&‚AëùPH™pNÙWæ<15k$zÔR²¶"ŽW±©R@ɸOZc+j"F‚T‘‘˜“#÷ÅKp@€áøè*8÷Mv'ŽL÷Ïý*Yʬd–ÀïÍ:ˆ”*1÷Oj~'80© c¨jLätȤéZ _1£eq3éHã}Ï̧‚1‘~”øŸÌ“p8ÆFÖ$Ek…À#ü©­ÆOj®pnÏîœ>öx«AUJGý¡¿xß·GZ‘%Æ $`œŽÀÓ @ªŒð:x©3ØUo&}îD€†=Éâ ,0Ü…9})°C䩹›ÍBérª$QޤúTñ01œ1Ç-ëFÃ$ïŠ(Í­! Ï`1QÌþ\eŠ·ü¤ú d± `zÐTµÇþ¾C–ÏøUÐ0;ÔVûÌd»n$ñÆ1RåAÁ<ÐÁé÷OçU Às‘ '<6H«'>õUwÈ„,ßÄy8¦sïÏÒªÜ3Äø—µMǘÌ&S•ÀÈ8…+Œ(gýý¤Ê„1÷?ê€ÚíÈû§šYû;ñÐK‚âåɱ²9#4÷â,ØÀäŠ@2eAØ“ùÓ¢iqŽ9Í5 k\ïnGÞ4èX@lã¯4ØÛ¤q±T '¾5d~*¿ïó¶7u994à“|åœå‡¯†[a¼.˜àÔÒ¶Ô=LTpË—cƒÍHÝ8ýi1Ò’È™†?7ÍÅ]ô㚊ݥhó#äö*\šmƒ‘ÔÕhda\’I8ÍY>íUá‘Ì…e‘wdíÔ DýpsÅ2HÝÙHvP w©qïGz@'Ö£•¶®Kú÷©}ª9¯OZl L*wg?HÇä8ÏOÆ›ŒG4óœgŸ0ek=[æ?ÁŒUœç±ªŠ×²¦#N@lšR×!XÔóóø8ö¦ÕÆÇFÙº“ ãÂOè*Ç'°ÇÒ«ÂÓ؆†&ÿ"Ž=hÇÿ®Ži®±ÆX¶Ò£€†wnã‘Ò¤`9<“^)óî9çò£ 0Ïà3PÚò¥ÌÎý¹•NNµCÞ™!vú/j º`ÒÄ‚f·€:ûUœûþb¢”3:m\€yéÅ4ùÙ—¹û£Ž)ô,¬3“Bi°KI>˜¨÷\ ¿!lz`Ô‘‡ØÅ€W'×X ˆ÷—õ¦®B€ÄŽHâ—%b7Jƒx<|Ù⛽’åQ6l–æ¦Ç®j!nPyd–ÏÍéBÜDÍ»iÛÉíT¤’í‚«åIÝÅ^Ú:ÕKÑ^&ŽqDX!ìn·¨ ÿx·ô©×v>aÍ/ùæ—"‹€ÖЫ Àöªïµ%H͸(ÚO@jÖj¬æ2,€ä0Ûîh[‚,ç'ý)zõþtsL–O.2ÅY±ü*2ikI¹^Q~â/1¢+½ù<“Í iÈKÀ¸cÈ4²ZB¡!Ãü?áOB…µ3ÿzT¯JTs,Âà›t‡Ì8ÜY¹ÇÒ¥¶$B ‚0:¿7+ö†![=\SêG"´‘âáWw  nIT" C×±©ýñUÎÓr¹»œ`p)-Á”É´@àõÒ›ºyjL@t,[³Bä°ç¨§¦Ñ•Œ掂aU c‰7‘Œã­>2ûIe r{æŸÖŒŒv¤1î’BeF>ëSþÏAòÆ~•]gHš@PŽp¼ç4ÿ¶Ç’˜f‘FJŒgìÆ8©Ir±‘÷²OõDÜ[\l.Œ¿7¸çó«ß—çC û~´œú Z^Ô„&}HÏÖ—ñ£ŸÂ€õ£ýz_ñ¥ ÁÇL~4`ûýihéÍ&(ãÔŠ^½V“#ÿóAäv¥ãPc´­-'Ò€ QïÍÉäQŒóŠ3ϽžÔœwâ—è1@>”ŸZ3GÐP0ühÍû8íš2h${Qǹ÷¢€#ýª8ÇqIœtÍŸþ¸ H~qô¢‰Î>”RÀäñKùR/ÖùÐÍ!8çnhÉÏ¿ˆ¦uçoëK’E&Õ6ÎGCŠ\äÒG¡¥Ô;“G=hÀÎHühÍŸ­ìEïIŽ~´ƒŽƒ4¿PhcŒM¾œÑéKÖ€ùûRGN¤ý1GÓ4›yÎ)ÞÔÜœã4¿\ÐõÑŸlÑî9 â€ ûb€?Ȥç·NÜÒ÷èh{sFMãÞ“ŸÎ Óµô¤Ç¥ÐçÚŒã®1E®hr?ýF›žù¥è:QÏjNœóFyëKƒëI¸gŽ}1@ ÇJ3ÏaíIBhëëõ ?…$t™íG_þµ5×1°û¹}*¼SÇ j@sÀ$òjÉ\Ž€qPµ¥¹*Í$ƒÜSCíQop_„'µ™ÍH‹±Œœ dži†Þ6bÅNsž´À²Ž¸CQB²yŽÎ>Rx9íJ-£ ·kc©ù4ôŒ&qž}h/œ^9òÊ€>µ6ñ–ºu¦MTà ©¦5š8pwüýpzQ  q$ªWÉ@ç8#=L9¦¬[\°$gŒSérzPsìh£žß¥ž˜¤¿!ÏNþôgÐþséKþx¤ öäQͲ ?€ œŠ1žqHHr}¨`¬0T0ô=êœsÜÜý”† Œžµsóüj(·‡n˜Æx¡ •jà(\v¦Ë»Ë#hn:c­?kuÀ¤ úPa?ºÛ•àŒô©?ÏZ®-P4„ >ñÀ§˜Pã<1œPAs>U@Ls‘×ñ¦¾ï=s@9ßÅKb(ö.p)Ï• žôîr҈¥˜ô¡_5îw¼AF:ãšš8– I8éAZo0ƒ»Ó4'`WdŒ²©8œÒÄKÆ¥”†#¡§õìj¯Ù\‰\Hw6@= '”þåʨcƒÅ6Õ·[!(‘ÈÆ)ŸcùUD´‘Ç5`) p)€dçŸÒŠ^1é@u¤!2{’G¥2Qº" î·­Hsž1Mtܸ)õ cbÙ³…Ú=*^?úÔÄB å³ÏÒóšj9;@ùlTØ#Ö˜ÈYÞ@ö¡ü~TÉ$*ê»ø½)‚¤#nÔ«VË>àž ³nòþæÿjIp 9MØtŠt± Si8œTì*Î:Ò(›ýÓ¹Kv“åíö4õ]¨ìŸZH¢1î9''4Àe¾J¦ÂIã56yïPÉ;®W#&…†TTQ'¨#4nË·˜8=i\ü´‘FËϸÓ?ãN`Åpaõ4€ŽßýWž‚¥ù»ÓcB‹†mÇ×§þ40bcUíü’\¤{㓊±øT2Å$”™‘qÑ@þ¢„ø#©¨ÞeFE$Ç û4ÁQVla²ÃoQS*¸‘‹8+ž1O@%ÎGQQM†Q¹U†jB¥”QÞ«}žà"(•r,Jöö¤€ž<,cŽÂ†?)8ç‡øÓ<¶ Nòj“È$P †Ô"ÆÛbN@?…OÏÓèj6Y7eXúT~TÛÉ cŠ7é0yž ru8©º†£‰Jçsǯ9©1Í'"—µ9XÈÃr[<ÔǧÿZ x$iU•®9óBr;TP ”WÞšb“9cÛS¡£ŒmÇ>´ÑŒIö9/Ç5hC‘õ¦ÈŒc`ƒ’85IFÎGžhS…\äÿ:dR œ‚E0¤Ûdr}ju03Þ€QŸz1ÏAF=¨sÔRx,)ÇžÙ¤ü )Ç%½´Í¿!w0,x4;2FA ïšY³¨lüŇj‘~Q´/Ôî;••"fb08¦ÛªªeKÜòMH@ ƒúÔ;nqÏ=¿*‰Ç|~µ°ÝdÁéOýñ|q·hŒ½ f0N(\ƪ«Â.ßk|äá‡jµ¥E"·XÀŸ˜àP€“4„à…F‚MÇ~íRõ¤H ý¦\999 žÅ[Éö¨”L%}Ê»3Á“õ©i° ÙéÍSy`–çÊó€xÈ%IÁl†ôâ¡™&,Å9ùÉ^qB`IÿFuR70ϱ¨ \ï|…ÚÈëõÍ$bfØÒÆÏs÷J,GPsNÆ9'ð¤Èÿ¯F3Ûš3Ž˜Å.(ÁÅ&Ì¢¶yíBLÇ#éKÇzAÏÒ—¿*!úUYÃ<芰$f¬³202Ùî*´Ÿ4¹{r0FÖšÜh¶* ¯ø÷aæÿÚ&‘%‘® ì`»x'¥K$i*l~G×€#(ä7½$ìVmÁ@^¤ãÅ2(8Œíà0£÷ŽØxÁC×$t¦jH·@Ò rG9¦¨?ksçHPq³Ÿº6Õ@t′yí˜ã ÆM@—ÀÕr¯%Ò•”l\†çò«'>•Yý¥H…yÎ[Ö’I.hÞ·=éÑ«$j¬å©¦Ëä$.X—'½D’N±F<‚ç"˜Y‚©'w&0e8`~† “Î.À"ñüF¦EUL{t¤"ݹ¾p@<1Š“¿lúÔLs¯–™ ÌFhMó‡#wËŽ8¦Ħv¹¥ãÞ«ª$³ð|ÊÌ@?•Yý)„ílJ¬­Ðƒô¨î@±ò÷ã Æiˆ§Ìd’zSÇÓµ.Oãì)?*\ZB­'Ó4~4¼ÐsÛ~ù¥ï×õ ûœPu£>âz\ޏ äç¥ôýi (˜õ£·'ò¥Ï×ò¤ëÒ ÿ9¥üy¥£¥Í/4}†2E'^´¼9¤8¥ç Í "“ïŽ;QD¿xqŽ( àö¥qÇÖ_ÌQ“ïŠ^1Êô¥íŠLz1LBçüæ—çðÜzõúÑ·¸ SÏ|QƒžO™£Š@.ÿ^Œc¦(íÖΘƒ'ºŠ9Í}hÇÖ€4‡‚22(ç§õ£‘Ú€GAŠ?õ 9ëFOsÅôÅŽqG>¿•&@îhsí@´iÆ®ipG®)q‘ëFÓžh£>ô`ƒÉ zf€íü¨ëÆîihÆhÁÇÞ£'¦i2?\Q¸zäPŸ@*?~¦ŒSùЮhÝØƒùQ‘Ÿ½ÍÿúéqŠNƒ¹£9àŸÊ|š1õë@ZB©4¡³œgŠSޏ4ƒñ£>´wÏ4¹¨þT„Œw¥ú~´žû¹ j;r?JLc×4¿LÐCÇÒŽz0}épE'>™÷c#Š1íKÓ®Gã@ ø^1š2:üß•u Ýèsô£¯QúÒôô~4cëFG÷I£¾(Î=MÉéF1Ûõ£>ÆÜãš1F;ãš3ìhçÜP’;~´™'°¥Áõ£üñ@pEJ?ÖŒ}hqž(Å!Ï­>Ù šSIzAè .8£Üš?ÐzuÅ/áš3š@}‰£ŽÔqKŠ)8öÍ.qÔRdzséKïÍc>Ô˜ü~´´b€u£ þ´ }hÇ­'SHr:óNǽ'¹ àçæ—m.Biƒó¥Ç¯Z@8Æ)JƒÛ­&3KŒv4€0ÿ®ŒQõÈ£=退J\w£z? ¸ÍQÏÖøšO¨£?J^Mô€N>ŸJ =³GëøQøPž¼Ð=wAœ Cך@AìiGQŒQÐcÀ^©=ÀýhÇ|¥/áŠhÁð4˜õ9úÓž=i1ÿê¤cÔÑÀ<š\ô`{Óƒ=qKÔr¹£§®)~_JN‡ý)h “é@ÄÎG–)qî3IƒéŠZ&1@v4¸ü(ü?#@ WFr ‚èô§m¨Ò“¼™'w@J”;}h€ôsNã½zæ >§¥.)N:úQùþT˜ô£íúÑÇ¡>Ô`v`õâ“èGÓ4¼ÏZ0;Ž(8ç=þ†£=)zt {G>ßÍö äÒqõ£óŽiyïŠLœÑ·Ž /ã@ ÁïšZ?Â¥JLuÇó¥zb‚~h1z;J\vàQÇaŸ¥&1ÓŒdô4¿\Röãô ÇnhÆzâ‚ýTtïH[Aôí´sÚ€ëš{õ£œóÏÒ—ð ÛGOJ8"Ž;ãó ŒÒp: q¤Í!>ø£ñüéxÇ­'áÒ€sÑ~´¹€{bƒõ Œ~dzþ´nÿdæ€ g°üèéIéÏzA·§×4´cèhÇ©£ P0Ϩê84gŠNhN{cñ¢Žhúæ€=?J?:CÈéý){t4€Nøþ´`zPùÍ/´¿y~”Q)‡ÒŠQÇ €zþ}qøS¹éÚ€¨ÆGáAÜÐ?_sKÐô4Ä'lŒþ4œ ñõ¥ 3ÊžiÒ€ÛŸÊ—‘GNsIúP€HäŠ8íƒHë—Ä~4¼Ÿ@(ëëMÚG@iyÏ$b€ ƒÆ(àw£=Oj ÍôuëŠ2{þ”˜Ï$â€OÊŒ÷£§oÖ¡ 9³ï@ëHO¦ £$ž˜Z^}1G^ø?ZCŸÿQ¤È=ñøP»ç©ôÍ9 }M&1ÎM.=q@ ô Phàôæ¾€QÏs@ ÓëKïŠ:÷£ äj1þsKŸ¥ûQó¢€sIõ<{Òäö£8怶?:?ï’~”£žA?úPÏ­&÷©zv¤;»cñ éïøÒtê1AéÓò¤äJ8뺗Œõçé@‡4sé¥RöäÓHSü4 aô #ŒdçÚ—ŸOÆŽÔŸ†2qÔ8<çõ œº(ïÈ 'Û4gðús@í@ö 'Ö“>æ”jLHÏá@}óG<óFÞzœÒp3lPöÆy gûÙ£ÜQòhxõ¤÷8 mê ƒŸ^ô¹¸£9ì):wÎzsŠLÿõù `cÒŽŸþº@sÓùÒç¶ “ÒŒQüéqì(8ì(”cÖŽhý)~”/­€Ñ“ìhJ4™¥Îz^=sE%}¨ü(?™÷4dzŠMÞ”¢Œz)$t¥õ4ÅÏ4œÒó@©£ñ bŒÐtä⎴séš2Þ”`÷'ð¤à­ÇµoJ^ýx  gŸñ¥ý(çÛò bqÜÒþ4˜ãš8­¶sI>ž´~Ïz_ ýhÈõ¤, ã?¥æ“>‡ô '×éJ3ŽhÉõ¤Î{çð àÑŠ)9ný(cœfŒ1ïš^{àÑŸB>”NØ'õ£=J8÷4gÐ`ý(ï×ð¤ÈÏ\¥.séJ~ P1:žE.>”™8äŒúRóíŠ0hÅ1ÏSG'¿E zœ~”~4uõÍãéGJ^Z9õ 'ëFqÇ~ÔœûRœ@ß­& ŸLQƒÚ€÷—¦9æ‚}©œÜ\P)yÏ¥/=ñLCp= z¥/>´g?ýj'üRƒžã4dÑ϶i3øÑŒr Òã¥1‰Í-&Ežø zRqž£ó£õ¥Ï1@ Á£=º}h<úÑÁéŸÊ€“ŸOÖŽG¨É¤ï“FqG¿z^xéLðxÇ4dg¸ü)}²3J3í@ Ô…séùу륣ñ£=héߊ@'=Ô}E/¾ 1éüèü3@ ׿éGNçÒ—>‚ŒÐsÁÍ(àòi§“Û4sýê\Žçô¥À4Üœ}ê2qÉõ€•N)23ÔóF æ—ôÀB|“J8õ &M è(çÚŒöäQø“LÔÑŸÿP¤#ý¢?_ÆyëGáE=3@ HOÖŒš3@áKøÒgüšQõ ëØÑÇ\ÑøŠúPÓ¿æh<ÿõ©qïGåšL zÑ»œ~”¹÷›³Æy 8ëF8¥£ñ Ç¥8ëùQϯçIϨü(r}3øÒnçÔÒàúñG=¨É=?QKÏ|~™=Å…{~9 þ4r>”f€hçþT{ƒFGz( py¢Œ{š:ŒsF1ÚŒv Ð÷ýip½¸£ŸAùÑŽùŇ4qØRãÐþtcþºA··åA_ÏwéJ(?F~¤ý)NÜóüèÆhã×sF¥sÿ룧ŠB3ë@)>¦“¦¢€ ñœÑœö œu¤Øü¨ÃüâŒ}hæ“>´½z?LûŠ3ê?Z\ޔֹ4¿cŠL{šP?/z1þsF=Íõçè(ÁõZ^):1ß‘¥ã­'>¤Ñš­¶(â“'±”síHO­7µE3 àÁÁâŠdѤ²ÀRPr>÷çKŽ:“@æ—ÀMÀô<Òóš2qŒæj/ãŸÆ›Ïn)xÈ÷£#=sï@Lœ/Ò—>¦šO¿Nô wÎhùsÔçêiA=Æ?N~¾ÔdÃǯåK“šLžÇÉë@ OznIÎN´¹?Þ#ò¤<ý(.AÒäã8"—~“©È Ÿj\÷#õ¤ÉœýhÉíùГ‘ÀϽ'ÔŠ9?þª3@^3@>‡ð cèÈϯáŠQÏ<þT¸=¿&ì㵎ãô £ óI¸z2}(sÇOÆ’“qè?J^Hû´¿‰¤Éì?i° Òžq@ÏlQÏ|~TŸð#øÑÏc@Ï üé;týh=ZŒŒðI>€‚qœš3êx£š7€; }),ûÒgÓ4»‰ÿëÐôÇá@úqM9Ï'ò¥ôïŠ_ÄP})2F(,=F~” 88çÖ—w¶)7wïFîÇŠ.OaůJnG©£Œ{P‰Çj;ñÇÖ›½ #ëFF=½Å;'¿Nç4…‡r£8Æ6š9îGå@{Qœt¤ÀëÏãJÿ#zŠ\ÿU…çtÏ?ãŠ\Sr Ðÿß$ý)1ùPGŠ_lÊ€—Ôœ{f—ŸZ2{ã#µúšo¸¥çéï@ žüQ“Šn}è9ì@”¿ˆ4`Òa½EÉ4¹#ÞŽŸÂ(ü(éÎ(yôüéñIŸJS@G½Î(ëïGCÈý(Áü(ãéô4uæŒ|P@ì9úÑÀÒç“óühäu œt›×ò£×ó ÏÀ ãΗܚ7€ c­OÆØcëJ3@â -'éô tàñ@£¿^(Í“@äRô™8ô¤Ü; ^ON”r;bŒ“ÜlQÓ®:P28úR~ŸžÃ4tí@ E'ãG3Í.qÖ“ëG9Ådrp>´¿¥&G­ÄS¨9ôbhàt–€4;ò=éhÉí‚(6Ð ^i8£ŒÐsz}h&ŒŽ§­ojRO±úÒžù Ÿj2¥•/ãIŸA@ •õÁúQǽ-/àh¹Çf”þµ.­&4˜'¡¥Áõ£ð€÷M&M/=ºR`}>”¼ûb›†í€)ØÇVúRcé@¡Èü)3Î2¶i@¸¹Ç@ '¨íÉÍ.}zѻڀ{ 2{FA£·ÿZ‡'¡£Žçô£4r(céG±•¥Ç±úP1:÷ü¨ïAÇqùÑŸj;t¥â“'°ãÞŽ£Óé@ E&=2(ÀêE-&Gcš8¨Î{Pþ4Ÿ•}OëF3KŠ0qÆ(9üi0sïëKFG­ ÀÒrzŸÂ—4˜Ãð¦ótâŒA#¸£Ò€Ÿb=(£§jCôüð¥íÒ; RŠ;ŸjLÖŽ(Ôdž†Ž¾”RÐ!¸>£¼ûQßßÖ—>´ LÑô¥íIƒŠ2{ÿ:3ÿê£ò äc 'ÓtêE.i:v ñ ãéïFqü_˜£pö͈£tÅŽi3éŠ\ýÚ“ôúQÏ­€Àþ4½>´™Íx Ÿj7sŒŠ8ÿëâÖsœc4tëÅLQ’{þtg°"ŒœÒvà¦(Î{®}.r3FsÜ9ÿõPéÉúÓçµ÷¤£w®/=r? ^}¿:hþt¸ÅŸZ^Æi;“@J@µ;µ7'Ô~¹ÿÕLçM(ƒg·zQ@„?ZN”ïŠnïjw8ô¤£Š1éÅÏsI€yë@çúPô¤ÏÓñ¥íÈü¨úPÏ 2}¨Î½{‚>”têhäRž)x=?•{QÎ:bñÉj?_Ë4¢{;ò*\ã’x£ôcŽ .¨Í!Çl^ƒ¨¤ú‘FIt~y£·LPóÚŒHG=:~´¹Ú0A¤$yäQØÎ>”rZ IúQ¹@ïKŸqøPF‹šníøÒóøÑøœÒwè:2xû¹ö£>´¼÷\~´½;b€ ¤#ž¤Ÿ¥>¤j9ìç@àÆŒŒó×·`‘GÍœgðÅ.\P¡¤Ú3÷yúÒòº=Žixö¤ ½ñøQ:PIÈéqGOþµj1不>ÔtçœÒmϽ/ pT}hÈ##"—>ÍõÅûcÚŽ§¶h÷üéqž”ŸQ‘Hyë“@ ·¹þtp£¯éF;äýhØ=èÜG¥6:ÑéƒGщ>”ãüi:8¿Ž~´=¨ç~´`ã¦)1“Óš6ã¿Ôž´¼õÝÅÁ£¿8ü¨3Ü~˜¥œà7ãGÍê?* çê(9>”lÉÎI¥çÚàõ#ò w"—'×ñ¤Ç¸ü)xúÐݶŸcF}G>Ô¤f“@ü(üx¥äñI¸v¥ê9€ECGN˜…·¨ <ÒesÁ?LRŒôçñ£?úPÈ~4¿LýM'^¿/~A =¸Ïµ!SK×ÿ¯J8Pp{ãñ£ŽØ4œzî÷¥ÜsŒb€·LRtì½/>§=h4`öÏÓ;QÆ0sùPùÐ9í@éÇ„zµ/J=ó@ ÿœPr:ELQǵô"€ jò)i0}hü³GÖ—¯z9ìh2AŸÂ—üô¥ëH~´~ó£§ÿZƒÇµûÐŒÒ~gÚ—¯nhã4œLmÍ.)>¬~”›¾„û7™½{0qé@ œu}:{Ð@Mob(#èhÃFOfÈ÷¼ŸOÊ€ z“G>¿­‰4nÇ 9?OjCZ2:äRœc“ÇÒ€§Z8ÿ"“ƒÆâ)xH AÏ^”˜ó‚{Rã?•ã“ùÐ0çÞŒ{ÒÑžhÀ£J9¤Ï§ò Æ&¡¥Í{ÐÇj9ö çµ'§ð ó×j3íŠ_¥S@Xg’(ú:RíI:ñ@Ò—üóAÛò ÅøŒcÓò ã¿ò Aß­4téGn´†ÑG”qÚ˜„êqGÌAùRäö8õ¤0£\QÀëŠ\Š`&(ǵ-÷ š\LŒõ v ð¥ÇzN(Í>´cØ~tgÐ~tcéH‘ÐgÚ¾Ô¼JLÐSǵ.n)3šNc¦? 1þqGOZ8õ¤ŒzRc¸Í/áøÑÏ­0ëG>´qŸz_Æ€= !8íKFy¤rzÿ»ÂŽ{µöêh1žß(ëÀôŽ  3î=¿J1޹ ·¸üh?ÄOáLñâ€AqÔÿ*8í@ÿwŠ;ðqøR瞢Œœöü¨9¥Å`æ€p=hÏ v4dÐ=Àhý)GN¿&GÒŽO§åK;ÑÉïš'N1KÍ ÏaK“ýÓ@ ׃úQÅ)úÒŽ1@ ô¥Ï½/zCô `öý(Ǧ( ¼µ/l}hÛÍýhÎ;qKÅ'NÂô¥Ç½!úf€=¨Ç·ëG xò£>ôb“r0y¥Ü;ÐPù~´ö#âŒq@ ŒœÐ=©Z2}  š9MºR=?*\ŽæŒQš:õ~›AçŸÎŒAùRaùPjLqÛ~˜¥ü(cÚ‚}¨Ã`RõÿëR}h?Z0hÍ9£Š' Rò<ÑÇoåGn´9#ühäu?•'®(Æ(ÏéFM&9Í/ò ž¸ûQÅg­ÑõQøPN(ëëGáEÀPÐÑøRwÎqŠ/,:QÏsG^½hǰ OΗš=Ž>”Ý£98'ÔÒÉÏ^=)zsÀϵ4ŽŸ.} &1Î~´¿{hÉö#ÚšqþM;æÅFçsƒíE÷ÿ (¿ ŽÃ&€;ìÉ¥ãÐ~4À9ëŽ}ÍsŸÎŒÎÔQòž8ö @3ÓƒJsOÐÑÓš03é@@èh9ÇÊ23ëKÀè 1ާñÅúfŒõé zgß Bœ}hÜzQŽ€dúf›‘Àúu¥$g§_nhÛpy¦‘êxö4}×9¥ÁîOå@ö ýh?7°õëF=q@=úôdñÁü¨â“ñ ÷¦Ÿj\g·äi:ô >ÄÒg##ó§vï@úcèhÚO_θ''Ò¤ôQøÒíÁàþ²r=óGò\wÑß¿ã@éÅ/oñ¦þ?•ç'õ nö£?ìšLdsŸÎ€>éüó@ sòõ4 vçéFçò¥ü3@}èíÍ' üé23Ïò #ó4m´ŒªÝE(P£h}(9ÿ*^qÀÏãIÓ×ò£èÛÇÝýhë×èhÁÎsÇÖ—‘ô Çl N;žiÇ8Íc?¥'OAG8ëŠ1Û8úRÈéùМwëÖ“8=hÆ}áKýãô ®îŸlPŽ£Z\ u£ yÀ Æ8ç×4¼úŒ}ip1÷hÛÜqøP`gÖŒóÍ)uâ“p(ÆqøÑÐð?´gu>ôdŽß…ôÍ-¤Ûò Àÿ&£üš)8ê1@ ÀíF2£‘ÞŽœäŠ9ëüéyõæç¹â—¦ÐP|þ {AÏ~´¼Ž0(Å'­ÏCšR3Çô¤Çáô ÇøR;Ñ‚Hê=Å;·&€+Œ”qØRàQÓÐPs@Í/ãKøÐyúÑì¥ãÜšSƒÛŸ¥&>”r;Gj@ v4¸üi3íùRâŽ{Š@IãùÑÖ—sÿê z1Ç"|RcÞ€¯CF}¾´~c×ùÐ`ÿ{>Ø¥ÆøPTÔ⌮q’OÒ€Ž:œzÒàéJ!ÒI?|lPF=éØ'ÞŽV•7sKÍ.?ýtsßõ 1žiG¦sïIƒŽåKÒ€ãû—Œwü)0¾™ü)vŽÔ‡>´ â>¿Z\Óž þ¸íÆ)9=ðiyö ÀìG {4wíøQLPàzŒ{ÑIøbŽhqéE=:3õ Ÿj3ïš1EúQÞ“­/å@Nø 6x£ð£ŒPœÑƒëKI“é@ÍŽ?Z(éÓš3šO¨£ŸOÖ”}1F= &1ÏêhÀîiqÛ¯ãIÓ¥Rmã½Å&OùcŒñùÑ‘þE'$ô£>´¹ ž):QQúf€xô™÷æ›Àä ÿJ\úøÐÏrisïIÏP/¾(2sß~´¸õ¤ Ls@À`÷é׸ÇLÑŸZ9„}(~4gëøQÍP0ã¯?….xôséúÒc¹ íži¶E/×ÆÆ€ 9îh<õ£Š(öþ´~´dÿv€ ÔQj3ŽâŽ(0=ép;š8£@ ~(àt4g=èüè?2õ¥æŒ¼@At¤Ü:óõ¥8ÏQšN;f€ äpÔ~$~4qž‡?JÓó1ž£4 jOÄçÔP§4 \ŒñÍ#·ëIø}hÀì1@…Ç4~t~ÀP1*NOJZ1@ ר£·qÚ‚?ýTsßš^”œöÏâ(Î{R~´cHN=(çð¦žhÏùg¨Ï±¤Ï˜=¨Ýîhç·ëLr9ÝF(úœQü©täÑÇ¡4r;þ”qߊ8íGnH£ŠôÅ1@ÿë ¹£9 ð#@LÑÓ®ivŽ´mÎOç@ÄÝìhÏ­/ãŠLQŠ\ñÈ?•-&£Ÿj1è [ô£òü(Ï¿é@Ó¥zRóÜæÆ øñK‘ŒÎ޽Æ)0?½@ ÿ^i:P¡â€=8ü(Œûâ—¼Ñ@ ‘Þ—?JLzš?ùГè)Ê“ëŠ0SŸ­ûÐ9íŠ?ÊÌPøÑÇ­CFFqùPF3ךZ8´˜ÇPW#ŒŠ\ô˜t¥ëE'é@ FiqF{f€ƒKÇJ23ÓŸ¥&@ö4¼Q€}éüDþ¼ôd‘Gô™Ç…)=Ïó éŸÆ—ëIÀõ¤â€œ÷â“ñ£ÂŽh£¯ÿ®¯ZB(íÇ?Z\Í!úQÆ8À ÆhÇû4~Tdö?¥±F¹üh9èühÇl~´t£³ùÐN’zP1r;ÒdzÐ9Ò– FG£"—4”™ïùRäfŠ{FqÖŽ½7=GJ;œSIôÁ§Q‘þE7i)vàç?‡j_ÄŸ £§ô¤·=¨Ç "Œ{“NçÖ€!—!‡ÒŠ&ûÃéE4(ÏýZ—iàãõ£  FûØ íœP#¡¡zdš]‡×ð¦!¼c)xõþ´ìqëôwPp=~€QNúQn}7o¹üñF=¿Zv½ …A?¡£Û4î{ÆÂ€yëŸÂ‚¹ì~¹§õ>Ô˜ü=¨@ëŒzÐJž2OÒ”€zŒýhþ_Jm/·4¸ÿ8£n}h6ç¡ÁúPÏÞÏáK´ã¥Op(8Çz:c»~¿Z&W¦z÷Å@Î:Ó¾nÄéI“ëúÐvƒ×ÆíœÐFG?¥Oáõ bvö£±¥üE6?ÂOþ½ã©þT„ sœPç¡ö `s׃ô þ×åNÉõúŠ0Ê I¥Ó4`ŽŸç§æzPäž”`ŸSúRdöÇçÒ“ÜÐF:ãó¥Ç þ4c×ó ¯N¿&<ÿ/SÆhÈÓÚŽHíŠ9ô™ã§¹ã8âŒä÷4€8$z9þè;êsG>ÔÜ{‘KŒsŠ2=ÿ*sЃ@=¹¥ç°É£§­!Ûß?• õÅg§4½1èh:zRÿÀ*0@éGèA÷ óþtô4:9î*0AâŒg¯ ŠLCŸ­AéÖŒדéš:ÿëG=Çë@Îi9ÏlúÒò;Röé@ Î8Á¤Ç®?*pϯJBqÜ \ƒHxèGãH1ÔO­/×ùP€}…cüŠ8î?:;{ýhüE.}A¤ÈÅÎçÓŸzv?Îi >ô¼ ÞýisÎ;ÐwëøR~”¸õ: Núôc=I¥ãÿ­Gµ€QøÐ~”=1@ Çj>½(úQÀ ŽÔsß•FM'ùÍ.GùqïIŸp3ëKÛž~”Ÿ¥/\w´˜úŸ­&ÐsœŠ\sÒ”}1øÒÆ?Z0=(Hÿ"“#ÜR‘œÇÒ“9è 4ž0¡‡pN)K“Øv§gÛš3ì*=ÇQKÈëŠN¼ŒâŒÆ€ {`Q€„Q:ƒõÅzý(Ï=(çÐ~tsÓzÒcØf€;Qõý(Æúô½¨Çô£Æ—ƒ?.}E'ÐÐÒ”ÜRè(ç¸Çã@ Œõ¥ãÖ™ž™¥Ïµ/LRþÜúRŸÆ€hÀëŠ1éIß‘@\⃎àÐx=­‰ÏçKœO­&;i8ô"ŽëȤȤã¦2~”tÇ\dñF=M'nœRnÇ@h¸çÛÒŒàŠNO¨ .Ý\ç¡Í?‡µJ1ŸÿU Ö›ÉíúS±Îpó£>ÃLÍ/>ÙúÑø;¨üG©úÑ‚zR‚ ö˜=Í(íÈÅ{Ð ãñ¥u¤Å.8úPõŒúQŽ1Ò—§RMüõ¥ÇÒqíô¿…7 ¼>”ìûŠN\})qøPuÿqÒ—Z0:â€$uý£¹ÇÖ—ñ4€ç¥gJhƒéH}‡4ïø ºR9ÿëP>”cÓŠ6Ó2:gô¥À=ÿ ^žôg#¿ã@„éýãô zÒ“MàõPàS8¤tò£{P0Å¥.=óFzÐsGéKÒŽ½è¤ü¿:\ÜRþT€LäóIÅ-)€~4„ÑéƒF?è)øÎ~´¹ãšB®(Aàs@ ô"Œ{š9>ô™‰c×?Ÿ™ëòš^O¥.­'Ê9£wlþ”p:@rEÿ"ÇS“éJGdPƒëF?ýTcÜQ¯ç@µ.(¨ÆGAùPŠ^>´`ú M¿J`íJíGJB}Í(ú9Í `FqJ>´™ÏSš8ì)sG_ZN; 0£¹£ÖŒH>ô~9¥äv£¨¦!ü~‚—SI€yïKÅ!îOµê?^´~”˜=úRþ&qKÖ€’:ôúQÏÿ®—¥»ÐQÏ`1õ¥ãÍö4˜ã‘Gt£¯QŠ>^˜4¿€£ô¤Æ;^ÿ B3ÞŒQ‘é­/JN}ô sKøPcGÐQœv4ÇLPžÌ9ö¤-Û¼tí@Å'øhÅŒ 1ž qš?J> ýi?øÒZ_ÀÐ1¼c¯ëKô£ 9ÀÍ¢€ÿ }E.E!>¢ ƒñ¥Èô AAë@ÃpéƒùQ“@ä}ãùÑŒñ@ FAèNi:u¥ @;QG‚ŒŸoÊ€úŠ0P(P!hýh¤ aÓ¥4 Rh9úQÇÿ®—èhü(¾)0>Ÿ/?þºOÀPõ£ÚŒúc4ô¤Œu"€2?¦h;ýh#ýš3Žâ—dúOÃô fûãœñE:\n¨ ämÏÒ—Êã `œ€ /ÍÅ'ËèhéÓŽ?»Ï°¥çÓRiˆ>lÑÏNiv瞟“úP`tÐa¤}M;·øÓpä.}Í!‹Ð`‚óÞ€*>ðíøS`ž”a³Î? N:àÑ€ÝüçÓéAÇ·ãK‘éøfÓñ ÏpåKÏ¥J3ìhÅ/=ÿ%ôÆhyö¤äv¥íþ4›}‡Ö€ þT¹'¦)0æÐ(#>ÿJ·ýisøÓ@ö<ö£Àï@…ëÛó¥+ê(ÆG#Ÿ-&9ëÏÖ‚H&>FshsÛó£ŸlQœŽ´›ryÐàýE'—ÎyÅTg­(ç­Ÿ­/@8 zâ§ë@O^1F}³F9ãgÚ€ sÛZ?1Hqê?*9ÇLÐÒŽœ‚ö¥Êž?¥îÏ'j\ç½õ~4£¥c¯gÖŽ:ž>´¸Æ€>ô™‚yô¥Àô£ò Æ:gñ£ŸN>´¸úQ´zP“ž8¤ÝÎ2~”QÆúRãЊoÍÛ—¿9—ûQŽß΀žÙ&€=½éqÏlѧá@ ôaFx PyïŸÒ€‚x$¥/AËQ’;œQ“Óñ êH~t¾øúcÔP`uÍ{ǽ.}F(çÐR1Ò–ŒÐrGÿZj?3âý({Ñõ¤ãµZ^ýé=èãÒŒÜГÜRþð gÖŸN(ç¿…Η>ôq@ øQÉéÅ)úQžh?>j\Ñ‘ï@ ϽÁ¥ëI‘œdPÇÒ—põ CFGb(ê:šOÃõ¥ü>´½è§Ž£ñ£ ñKŠ8 çéKjZ;PqƒÆizÑÓ¿çFG­‰ü(DZüè݃Í ô…sÔš^=i9þöh c§J@ õ`uäÒý Ü:óøQœu8¥çÖ“ŸÇÚ€ OÆŽž¤zÒã†=ºÑŠ4‘êOÖ—'®x¥éÒŒí@ÄÉö£8Áúš8쀷á@~™£-ÿ×¥£L“Gµ.=MPp}MÎ:uÿú©ÌûÐFúæžsIúþÀn3ÇCõ£ žXý8¥<ñƒŠ6œp }h1êÜÑ‚Š”c=H4@Wé@ ­'"“â—èhrGøQÏcz_ÆŒc¾½÷¤ÇçíAç£}©A9䓸P íÓ?Z?  dñŸÃ >¢`(¥ë@ùⓃñ¥¤Îx âŒRg¿Z:÷ ¤ cš0;Š8Ï\}h Ný 8¥¤øÑô£ò´ÀL}(Åv sF(ÅõÅb“9¥Å}hÀì(#êhëÇO¥¹4˜×éGoA@£Žâ‚}ÆhÉ8ã4€(úFîØêi8÷ü(~nÔ‡ÞŒçš^}hÆ{Æþx¤çÜýhÏ6ÔÐõÿëRcéKÇ_éIžàÐуëùÑ‘G×é@Ž?ýTIŒv ÚG¥úé:f‚}ñõ zçëGåõÍ&rxÈ4zçÀ^­;Qž:ãéFH=  ÚOqNÍ&sÚ—ŸOÊ€hÇ>ô}AžÝ½©ÊŒ­¼Ù Æ9æ—ŸCIŒtÈúQש¦œñ‚)zú~4{v£¾ ãÒŒ{RýhúПZ9ï“ïš^Mï@4QÍ çµNhþT‡ÜŠ??Ê€¿c½&îÄ8ÏŠZ1éüéN):Žãñ <÷4ryäRçÜÒqŽ´{sKÏaF)p(œÑ×±¤ÀëÍÄÐ!'>¢—•ü(îr&—õ£§s@”*ÿ9£¦3úн /òö4?ɤ8=¨Ï­.sÓŠN)s@ õ¤àzÓ³žÔv ÿ€Î€?Ù½ýtqí@=©9>´§¨£ŒŒPòj?*nÕõ§vàP1áŠ0qÅp*Z'J\{ÎŽž´›sÎ9úÐÇÿª—ó¤Ç1øÒ_þµÛ¹¤8Ï#?ÒŒ{âÆ øÑIG~”~´ zRtïF;äþt 9Ï|Qœô£éAQׯã@O®(ÎG¯ãJ< \‚;PrGAIϧëNÀô¤'ëøRúÖ—µ&=phè8Ïã@ F Æ>”™÷úÑÉè}è9Î>”Q.w úQ@éÖŸjQFîÇëš`.ãÁ#dõÆhÜbŒ©?xP!>÷U”Ù£ƒüCð4¸ÇnhÝÊzfÃ?t“N8Ç?¥zgZ'^Ù¤†œ-&) \éGùë@ úRò:FAè*:ó@ƒ~t„ñÒ—œP8ö£ñ£ð4s‚¤~4`ZoË»hó§óIóg§cÛõ£ŠoV Ù÷§¡>ôsž‚—ŠB}ÅÀ}&=?ž)@Ïj3HWæÎM“êƒÀÎM½‰ AÏ`)?JvG¿åG4œã­îh “éš\à“š^?ɤ8õ£ u&\qúÐsÛŒúŽ(íÒ€ŸJBxëùÐOÿZŒŽâ€ Àö¤éKéùÒŸ^~”œzKÏaÇÖý)0?»úPõëü©qéHé‚hÈÇ"€ ÐçRöà~´œ“ÈÀúÐÇrhç<J?Ï4P“íK“œqšNSIÁ8 sžÔ™ÇRÖ“§ðãéK’_Ò€ ƒÜ0£±ü(4b€3ÀæŒçµžÔaOñ 1è(ç=ñõ£h#©ü å@ ÏqÅ/ Í&Nxñ¥ž0 ã<Œ~4to@hã±æŽ}¨Àöü©N„ýh翸öÍ Ç÷@£éÅ.(Á {š1õ4„ÜŠN{µ8Ãñ é@ Î:gõ4¹4”ŸRhw}iyÏZLžÃ4˜ñ·îÝè¤çÓò4¸ #"”Ú“Œóü¨ÈOç@Å âŽh£'¸æõ4€u4¹ç¨£ñ y£'EÆ©g§Z(Çz8ïü¨9ìhúœÒäv¤>´Çó¥éÐÒv£ñ&€KÏ­'QIj\óFHÿëQÏ¥/>Ÿ­z)Óõ¤Ç~v=é3î Ç¥ïÒ€­¾ðÅ'´cŽ ⌃ޓð¥â€ NsÖ—P0üM 9õühíŒÑ‘Ðh¿Ç­&@õ¥ãhnôf“ñÍ/ÓCÇz/n´du šN?½ŒÑœðúÑ»ÔÀP0ÈXRäQœÂǸõýhÇ¡o¥‡LøÑ¸güM/nzÒRç4g€AÓ½ã¹dzÒñŽ´ÀMØéJ3øPp;øÒãÛõÍ!ÒŽqAsG”sš^Í%cÞçFGâ(Éÿ"€O·µ-?äQH Q€(üè `ÇcF=é3è?:L€z€ô4uïúÒgê>´½ñ»š(ãÒîrh ¿Œ{ÒPúPöëFG®i2?¼3õ£#üš\ LcÖóÖ‚}h¢“œðhçiqëF/Ôœzhǹ¤ÎiÃêãG¿ëLÀ>ø£<õ?LRã<†£ŸzOÇš^zóùRsíG~Hüéuõ£'Þ—>ãó£'?{ò‚Œûþt¹#ÒÊ€¯z\{óGáFGù4`ú~4qŽôß'ó£Ÿz8”P’>žô~´œ}iF1šÔûÒgÔÒäcÐ{ÑÇÖ€ š3F}¨ÉõQǽ´qÿë Ò޽ vÅ?Cô?¥(ÈìAúPøN½©sÞŽqÅ£#ÞŠ(ôÝøÐïK‘ëFhïÞÄÑœt 8 üéqš? ÑÏj1FaKƒøÒcާó ?J_Ç4cßõ£ëÅ(ãÖŽ( ëǵv¤ävýh8<îçë@ šLŽ˜?±š8îI ¥ç©£ñ4mdžß.}¿#A÷”˜í¥/àE'4p8éKÁã?­’9Áü)9ÀýiqŽüQÛ†Ïã@ƒ$u“#ŒŽhç±¥ǧր ýhü Ž}qí@£Ôuà(ëÞ€Žô„Ôãê(ãÖŒë@O·ÖÎŽ=hÇàh…‡¿á@#ÔÑÆ¡£#¶h'#¯éF@î~”¸éç¾=hx÷£ùRu>Þ¹¥ätÍ òi:úÐ}r?*\çØÓ8îiræ€yíE 'ßJ)²˜sÚŠ{œŸj_zAÓ»¹ê3é@'¡¿€™÷™õ4ÀRBòHuÇqí@ç©æËò éÇ4˜õ4¸âŒý3é@qŠ9íŠPÀqšLŽx çhÈâŒÀRœŽÙüh~´r?ýTsíKƒß N½ù¦¸ù‚:`Ó±íúÓI‘‚M(9­/9ëH Ó¥ç×sIŽyÐAîOáKϵ œqIËëKÐöÍ 9ç€~¹ qŸÒ—<òM1ïøQƒé@ Ó¸ü©ßÎ’ŒPÑ“I‘ëKøæ€Ï§Ò“ëúRãëùÑÒhè=(¤ü¨Ï”r9ÏtÿõÑ@âM9¥äw£#Gç@ ǯåKúÒv£ƒß{(ú‚(qƒFsÔŠJ;RÑšLãµ.Fi1G?‡­/ZOÇ~£ëF §®)sŠLƒÒ—´gÚŽqE!éÜ}(zzÑ×Ö“óG>Ÿ…ûÑõÍ:ÑŽ?ÄÐÅ”¿\QÉíúÐvé¥ãŠ1Ž3I€OÞü3@Îx<ÒcÐ~´qØR‚}?ZL_ÖŽ”r{Qí€~´dc½.sëIózÊ“ñÅ;èüi?hú:rEÍÞ—QÅ£<õgž”gÐQÍ{š>´qIƒô ãÔRQQùQÏj4¼ú>oïRd÷ý(héÜÒîE.r:МuÍCI‘ê4¹÷üͤ,?^3ÓŸ­ǧåF}çFAèH£¥-'zOÌýh9ìhOÔÒ}sG<oo΀ ôþ´duþ´¹?ýlRqßd{Òð;1‘ÏëF(¢“>üö¥ü…öcšO Z1“Îhz&W ddô¥ü:kÆ©$‚§#ìR`úÒö£?Q@ ŽsÎhúcó¥$tÍ&j9ïŠ3j3ŽÜQøP“ëŠ1ôüii1îhúŒý/çøÑÏ­'å@ÅéÐ~´éGÔ~t894QŠB=hÈÏZ:v¿AE&isžy `:t4Qš3‘@„ã¾iE 8=y Ç=M/?_Æ“rqí@ö4¿‰¤Rö£ó aÏ ¤Å.>”œt4 £¿CŸ­ë@üýèr‡õ£·4Rdw _¨¤ÂúŠ\¥&á@€“øzâŽHõ g­-~†­&Mžÿ¥)ÿⓟj(úRñIš3Î;П@)r{ÒgéF}ùúÒÏ4RgüŽhÈü(yÿõÒphÆhÇ×ó¦þ8¤Ü)qÇOÎŽ;Š2?ýtsÜQG_J@'àii3ZR~¿0ŸJ^½©3ô£4`Ô¼vd÷›½¨ÈëKMËÙ£“Öü)3Š0=?*> ~4ÀLƒA?CF{ƒKŸSHõþÒäö_Ö—“ÓŸ­zPÀh#ކ”ñÐ~´ßÀPäj0}….}áIŸP\ކ’Ž{G~•/ZãšNƒå"“-ê1L8rhÁ?Z÷È£§j0zÿJ3éKŸ¯ç@ÏqúæOaŸ©£éœÑÚʆO½íŽhëÔb‚l~T›°~í/~ôdúþ”|݆~¦ =(úƒšLŸLRàž¦>¸¤ú QŠ9õ¿7z2{Ò~4ž çš8hçÔ~s@áIÅ;·ZJA·=y¥Í…-'ÒŽExŽGÿ®€ ™^çðëKž8&€¨éÅ(Ð~tsIù~4¸ö?úQÏ PøQFGù4óš(ÿ8Rr:(zu£õ¢Œóýh9î)y>”sè?:1@ †õÇãEö¥Ç½úQô¤Ï¨ÍöÇã@ Í4€;RçÚŽÝh¼?8}ZLQŒ÷€ŸOÆŽ LçN)6c«~´¤ûþƒ?Þü©ØíÅsíF=¨éÞŽzö aÆŽ”sK“è(~òý(¥—ï/ÒŠ@;þðÇ|Š\“ïMíKïƒô ëü84´€“Žö¢˜ Àç©Å'?þªM£©¥(efÀÜ}éÙÀç¥7pÇ'qÖ€#gò¥Å&Iä~T`ç§ìRcéG#ÖŠÔÒ~4 tÏ4~tDXŸÞÈ3éŽ?J(^J2qGä~”ŤÆ{RŒú~f‚(ý)8õ¥üJ3è2iy÷¦lçÞ‹ž}(ÀÿõQ‚}(”{>¦Œö<{Òg·_¥/4œö—·Z^½ó@ Ç<©¥íÀCGAíI“ZQÇÿZŒ_Γ#®hÈõ È=ÿ*^=i¹ç¦ipOµÆŒûšL2yÆ(I=óJ:RE/qš;ÑøÑò(é@ÿ­IÚìhxì(ôŸŽ),Ð!3ž”¿Z?*NhsÉ£>‡ô¤ã®GçG×óg×£>¦ŽsÞŽz@+ž¼ÑF`)*LûÐ:ÒâÊ€<ö¤nNd{Š_j9ÅåGN‡ó¤Ç§4~4¼p#ßgOç@ëÖé@9ê?*9#­/8â“ÉÆh÷£éŒRÐHOzBp:QÁ"ŽŒ}÷£íP3è(çEiIô4ƒßš^È üi@>¦­PÓŒ“GÐQÓÿ­G>¿'Ðb—ð£'ÖŠ8¤ëøÑƒõúÒþ”gñ¤çéô¥öÏëKŽ3΀Þ“èH§cÜR~˜8⓵;9ê:Nœb€cIØÿ])'¶(ç¯Z@xÇ'ð¥éAçúQéþgß?…ûL´¼w8 ñ4¹÷ü…'oñ¥þT™çÒÿ:@G@ÔgÚ€Aî(íëF:3ë΀7sé@aíFáï@}¨é@Á~Tw 'œÒäZ? (1øŠ\fÄRê(†h–a‘|Â2žqRö£é?=(üh£9í@PM.:уïIŒs“ùÐÐ#9 šB29çë@ ߥöý):qŠ3ŸZ_ÆŒq×z÷âŒÐ18õý)sê(íIóc®(¤ýhÎ{ŸÊg±¥(:øÑŸAJGËÈ S@ƒ'½&GÖ–Œdæ€éùÒõ÷¢ÇŠ%ÿõÑ’GcÜÑ©£š èÀ>¹úRcdg®(ã¹ AÔúÑ×¾hÉíÒ‚OÒ‹øÒuïFhÈþõ!¤Ÿ¥.HéøRûâŠC“ïøRG#ùRöëFsšNsè~”sê)pG½1ùPóëùR(éÛ 8Ïõ¥è:Ñ‘ßp})c½=©x£Š`&½}hãüš2=¨Ï±¥Ï±£ô™Ç…ù4c¿4¹õ£­ Ôg׊N3Gå@ øÑùþ™éŸåKLàÐ8ã§NœQŸ¨¥ÿô¿Z=hüi=ÿ*?I@ÆM0¯nEZLg¸¥þ~Ô ûÒcÞŒúŠ 4¸ö¤ä÷ǵ?… sžþ¦‚¯åKŽ)>„S££OÒŽhìM.~´€“Áȥϩ4˜ÇLÑóÚÃõ£é@áF3ÖåG¨ AŒæŒÑ‘íô£ŽôsêihÁþºõ cÜÑœu8 ã¯z3ÚŽÔQŸjc­¥;qÒôêizö¥ý(/JCþE&G¥)úP3ïFéG^Ô`ÑÔu4ƒÉ"ŒçÓó ýhÉ¢ŒzP0 ïGnÔdP!z÷#éIsF~´PçŠOÌ~ ? Lz@Ç©4¿N( Š:u4@ ÓŸÖ‚Gz^zL|PÑ“Ø CÈÿëÒŽzÐøÑÚ—§zqëF>¿/læŠ °É£©èáKùÒgØþ4rhÁúÒÒdÔcsíI‘ÝM-èúŠB}E˜Á éþ“ƒÞ”sØRtõ ÀíÍCF1GOO‡OZ(úQÇpLŽùü©sõ£œRÒ)yaô¢’_¼¿J(￵;ñ¦Œãÿ¯KŸRãÒ€éúÒûž~”€ý1õ£Ÿz^þ”`ö&“'×Ôg逧‘IŠ=hîJ9Š0yãò c×4½9c×4˜éGNø¥ŸOÂŽ¾ôg4™ü)xÏJ8€sÎhäõÇá@=z~T¾Ù Bcð¥Œ*JOÀÐ1ßN)ÇSš?:Lzb€“ÜbŽ{ RqíøR ‡­/׊1÷¨Ï¦hç° úf_Γ‡éI¸gï}(I#Þ›žxLSºúQÛÿ¯@nÿSF;æŽÝZ@W·_¥#¦9£ŸJ:QÀëü¨çë@P=3GNŸ¥ö üH¤ÉóFÇ`>†€ò9À¥¡Ž=)3Ï@=É Œó@ –ƒñ¥ žOÞ8=~´¼gP‘ÇSFO¯éMÆ:K“Ó½¯z?Î) õ¥È#ŸlÐ!2Gj\ŸJL/ù挀{þTêL}hâŽ{`Ð~”güš9ö£œPþx£ðÅEõ ã½üšNôp;Pÿ®Š;Bi=ó@ GZLƒÞÏjC´ŽNô½ÝýiqíúÒ~t{š1ƒš^1È#ëIŽzþ´‡óúQÁã¥.@ëùQôæ€ïF}4œyü3KÇ­­/JN(ëÒ€Ÿ@1Ž‚—ƃÁ ï׿‰“ê)~”™÷ü¨ÏlRãÜQô Ï=1øÑ‚zãZ^{ŒRcÖ€Š;ÒK@“ߢ—æ€ öÔ tãó¥Á¤ ëŠ2z(Ç?w?ŽÔcÂ(Çr1F>¿…c¦:´tÑøŠ1Š1õ£˜£óü)síúÐõëF3Û4gÖ΀{QÏÖ“üõ£æ>Ôd÷ü³KøRcê>´¸ åôŠ)7Hqë@ sKÛšo~Çñ¥Ïl~´r8£ÖóÖŒÐIFsGÒ€œzRg=èãÓñÍ/Ò€ qIÍ;ÒsÛ.}N~´väÒäQ@úÑHG½ ÇúÐ:õ¥ Éÿ&—>âŒQŽ:PúQÍ&>´¸Å'½ú SŽôÜÔ¹£4`ûRç@‡gM&}óHýi{vŤ$ŽÙúP~” ŸB=… þ“$÷sýÜ}Mq‘¥AG=ˆqéÅ.ì?:9ÇŸzOÇò¥#=qïIZ/çIHg©ÏÖÒ(Æ:cÞ—ŠLã·=hÛ}àhÆG"€þ”£ØŠ>¸ü)x4 LæGŽAúÐ Ü;Ò—>ù¤ç9 ã8ï@ã²3G±Å"€ sÿ×¥éÞ“õý(ú~T»‡§4zQõ£¯A@ ŽzRóíMÎN7tíK@…ÉõÅ&sÓ¯Ö€1Ïu bäö£&ÖŽµ/4„àóFyè?*=ñš8úŠ\úR~óÖ€ÞŒw¤'hü(æŒp9 ýhͺÑÐu&ލï@Íÿ룿4piF;PÀRzŒfÅ!>Ô€9õ&“žô}E†€ÈQŠ\aõ â€>€~&~)G=¤Á¦äf‚}ÿ NÜÒgØ© ë׊? ûÑAKÛ‘@ ‘žƒ4´˜qøæ—ß­ˆ`ç·Ö·µúÐϵ©£ñ£¸4vÇéG …§J>‚€ žçò¥Ï½'Íÿë£=¸ üi9£µ/Z&qÍ/4Ÿ‡ãJ9€z9íÍÊŽ(yõæƒùÑÏaùÒséƒ@öâ–Ži:u"€$}(¤àñKøPŸ|ÑŸz;óIÇ^”¿úÒ‘Ï4 {Ð>´`ÑõþT˜Ïÿ®€ zRÒRЊ1ì(J1@4qŸzNԹ†ûÑŸZLúQ@äð=iG±£tâŽ;PÍþ™ö£ó £§\RqéF~”¼úæ“ò£ðýiAì/ãŠNè þ4½¿­& ÜЂ:bŒþJ3Ø 8ü~´ 3ß#ò£9i ÷ñ¥ëßô Aô£ñ£ÒŽüÐ0àÒãßœc¶(íÅÆŽ=hã¦3FqÅ'~”¾æŠ?Z=9£ñÍÆŽ= !,8g׿çŠÐP0È>”g˜£ÿÕG>´gßò4sýâ}©>_Æ”PRrãéE,½GâŠ@(ǧéKÔS3Žyü)Aúf€=È¥éÞ öéÍàà.=é€îÔœ§ÖAê 3Ûi ÉöϦ(ç©4}p(ÀëŠ2qÒÍßô wÆ:7s@€ûŒÒõê?JLŸ¯ãGÌzÐð{ÑÁ¤Î;€~”dö/éõ£jOóɤäÔ vA<ÒñLç®?#J ô Bäöu£“IÀ?ýz\yœgÐѧõ£žÿ­.Aü}x£<õÀ¤Î?¯4{ùf€ƒè1IÁíùÑq@|b‚¾œQÈqë@=H?…/ÓŽÜô¤Æ{ГéA£¨¨ÈéŠZ9ôg=&AÇ4œò)sF}ó@>”˜'ÐþÞÔg׊1õ£—ž´søPÆ—¯©£(#"€ÛKÖŒ“F=hÅùëGµ ¨èM{Ru<:6çŒtõ4¼úQÎ}(àu8ühÍ.lRgšN´§>´{ÑNh 8=±êMz‘GãG_J\f“~Y£'¸)i:ö£Ž˜?/^Ôgžx£ð£è?*9õ£ñ£þµàu ò£š(Ãc½¨ü©úf—˜Ÿç­§Òö£Ø÷ ðæÆŽI£'¡ #ÖŽOÒŠ0O¨úPðøÑIÈéÍâ€lÑIŒv¥æ€}J9íE{ÐøÒcÔRçbŒPb—œRsêE.hçÿÕIŽ´sóÅöÍ.(Æ)9=p(ÝØ‘ùPóŽM}hú):RóHN?ýt½úQøNIÎçFO¥)ühçÒ“r Š1ëKÍ&py>´¸œ{þT`ÛsþM.Ñé@ î)y¢ŒÜÐsô£Ú—ñæ“Ú€ ûG£¹?…'¹ëí@ GùàRc¾çJG­¢“s@ IŸLÑŠ>”g>”¹ã¶)? Q@ ŸqŠ:÷£óGô˜÷4tïG>¦ôÅuÇãšã§ë@î::uÍöüÅ&}i}ðizõ úP(ýj1@v çÚõè:0Î/ÒŽ{ŸÈRu4¢€¯Ò”:/åI×¶>†ÀÐþ“¯j\~güšo–ŒQŸò(÷$ÐËëGåF©£÷4 ;ÑœvæŒö Ž1š3ßÇ­!xäûš^}(ž)2}åFlÑŠ†M†?9hç=F=h„úÓ~îq’3O#¸q~"×mm¹ô a\Ð>‡ð4lÒæ ŒóKƒè)pi>‚€íF1ÿÖ£ð ã¾(£Ÿ­dÓ1ž RàAG?þº­zÎ’OΗ'Ó?…!>Æ€Ãò¥LRgßó¥÷4s@æŽ}èçÒ€O4~”Ài@ øš1KE%/åE&Ií@…ç¹¢“ó¥éÏé@ “ýÓùÑÏaF =ø ¿Þ?J9Í/ãŠ?@ ÁôÍ>߀¥üÿ*1ùÐ{qùQÐv¥Ïn £ŠO—žøÍúRq@ ŸóŠCôÅ/ÒŒ@ Ï¥Ý4¿…Z?*(ãÒŠ9>Ôƒ>Ô¸úQ@Ïp>´sEsG^”Q@sŠ?!Ezw£ëE…~TQÐûP§åGœQŸz(üèühéÖ“‡AGÇô `zÑzdb}(#=O”sŽ”`ç&€ð┞ÃùPsÚŒ{PÈô£Ž´Žß ô£"Œ‚8ŸÊƒžã.iöñ£äQø Бž zŠ9Ï4ìá@Åɤàÿõ¨Ç°£ð AƒíŠ9£… 0>´g´˜ö£FA?J^´ Ÿ|}(¥”|ÃéE qýÞ*RB)ztö§qÊþt„AøŠpÇgð£ŸJN¿Å@ ÝüéHúþtœÂÓ¨ }I½úR;äQžÀPŒžip:ç4…‰f“Ü`;Ò`g?J~´ryÈ !GŒúñJN;þTv sIéFx<ŸÂ”6zf ‘ÐQôý(Ïj4 RoçH3é@ãÿ­FF¡ Bç#œgëFN: 1M9…Ížê)r ¦ +ËsÛ°¥ëÈéï@…ü3H8êá@#¶? 2=Í“Kô¤Ç£§Ê€éG”gI£ ñ‘@ƒõ£Û¥ÇSAüh9÷"—ƒÔbŒßò£gÓšLã¨Å/f€ žøü¨Ï¦êLуž£éšPx掾ôŸ‡?Z:vüèéKI¸c“FîzÐÇ¥-—Òã±ÁúÐŒqš8íúSHõÏçJ(ONsIõÍ/dç€?:NAN¤æŒ{~´=¿Lç®) BßLP}Í.GJ:Žs@Z? 3éÍ…?…;Qž1Š1@ Ú“êÛÛò£'Þ€©ö£8íIÍ-öý(éÚ“š9ï@ Á'ÒŽ¹¤ëÜÑŽ:b€(àQØQ@ÇsAÛþEŸ_Æ“ßúÐñŠqÒŠ8=¨£¥ú >‚ùÑÏ¥èÏ@)i(Å/åIKj9 æÂŒQ@'^¥£·C@âŒþt{RŒzb€šGaKùQøPgÛ½ºâ“éŠ2}(sFi2{Ê€'ÒŒûšN¾”¼ÐïIÐô4sÞ—¨ô Š>”cÚŠ1øÑúR ßäÒæ€ QéGZ(ëEhͼ{RvéI€3øPþQùPÍö àÑŒv£ò “€f”ý)1ùÐÒ ù€¥äzR~€ ®âÁúQŸÆ—{dÐpyÅæ–“ŸÃÒ‡ó gÐ^ü擟ÿ]/¦i9' Å1Ú—žàšúqëGn)3FïöM ŸQùRÒŸQF .}Å™Ç_Η¯J!´¸â€ÝŽ)sèMëGùÍsÿ×£Ÿj7QŸa@ö4¼ÑúÐ~c½;RdãÚ‹ÀëG¤ã?áJ1@ :RN½éy Š1Çj9ô£ò Bc×£Š9ü(ô þ4có£Š9ü( ŒZLzu ëE%-sŽ¢“#ÖÀA@>¼QÓÐzÑœô4c<К9ô£•>Ô~´fŒ`p9¥ J_Γš¹ Éô¤Ž˜£;PþNhç4r:RÑ“ÜQ@ZN1Ò”fŽÈ £š\?NGåG¸Å.(Àô 1ü©?ΊCÅ9Ï£ŸQŠ1@9ëFy¥úÒ`Pô£QÇLÑŽyÍÆhäzŸÆŒz 2z`Ðã¾9¤À_¥ò Q;Ñ“õ£žøÅÏÒåô£ðÅÐ0뎆—¤£ŸA@ Eü( ð£°¤9£¯S@ Íx¤ãÞŒûñ@Ê>aô¢‡ûÔR3GÞ<Òîy§ ãùæ€ óŸ­.3Úž™…ñ“@ÒŽý(£<àÓGE'”¹çE; ϯéKÈêsõg<óùQùP¸z~t¤ûâ“êEvÁ4döÁ‡h$œ~ŽüqG½8ôÅ&3×RqÛŠMøÀw¯œRn\ÿõ¨Ï´‡Ù àœÐ§ò£žçò£> þt´™ÿõÒýý(¤Ç4tëÍóš_Ò“8÷£ ÷ü(Î}hÏø ^qÆi8ÿõÑøf€ùç4~†ŽýhN(ü¨:2qÞŽh£¨æ€Æ“‘Îh8í€hþt}£ÿ×KŸóŠ &)>¼ý)}±Åñš1ß4”¸Ï¨¥ü '=ÆE/éHW=ÈúQÆ€ š3ïAúQÓ¹ ø¥ö&“¿Z\c΀(ú ?'¾M/^(ÅÚŒQ@¤âŽ}søQ@Ö—Ô}1šJ\RuëŠ:Ð}ÏÖ€ŠLïIøN aøþ~4gÚ“?ZZ?Gni8íÅ…/¯¤ü 1Åãc?JZ&8ö£Ô¿&|ÐÏqIòç¡'ÞôºæÖ€·åK‚;ŸÊ“ƒ×4}½ÿúÔ„?ïª:úþ4:súÑh£J:zbŒû ?:>” ZOÊŒƒõ£#=phÏl@6öüéyïúQùŠNMQÈí@âhÿ<Òsÿë¥Àõ 㸥üM'ãùÒûf€üÿ*L 8ïš6‚:P Ç®iF; QÒóØŠ)ü©=±“G~†“>ߤäý9þ´r{Rãñ ´Ü㸠ûŠ2:‘ëš@QKŸÇð£Š;óÖ€“Á—íGïFzbsÈ£>ÆŒ (gðúÑŒösëFyÿ@@)hϵ&y §9ü1F3ÿê¥ü)>”Ä>ÔéFGqKœÐ11Ç4tö¥?þº:ug¹Áú N)ߣz@Î)>¹Ç­/^ÔRÔwíš1ê3øÑôÆ)€dúþ¼ÑœzRu ŸoÊ—Ô¨üèÇ?J=€¥ü(ü(JQGj;P12OCKƒAŸ…Í%&ÑœãšZ>˜sG^ôt Œ`õ¨ü1IÇ\ZQíI‘ÚŒý(¸Í…'Ò—ÐjN£¡¥ôtí@ Kš3ïŠ;t šB>´~”½¨8ô£=±ùÑÏ\cúÑõþtpzÐ@=©hüh? ^i9õâqüèÁÇoʃÓÿ­G>”´˜õæŒQÛ½.>¦€ÔttèçF}x &—ë×Ú’Œz/jAG>¸ }E 1íGãúÐ}轺R~¥é@ã© gÐRcÀ¥ô9£=¨è3IßœRà\ÑìZLþTÇÒ“ëùÐ Á¢Œ{QŽhfŽ‚–“ñqÿë£ô}zP  ·ÔÑŠüh™ãš;g?¥.=)zŸj@C'%~”SŸï¥€ñ×êEÏb)¡ÆxcùR’‘@Ûž½)pjh e©xÅ;Ž™ˆ¤ä ?h8Áæ—ðçëLƽ&Nq¹séžiA‡ùÑ×üid‘ŸéIÔuÅ&rIÏ֗ר4tâ“sv#éJÇ'>ô¸ô¦!¿?¨?Z1Éî){óœÑŸrEÛ¿•&{f“œôýh¼wý.<)9ÿëÒgÔšvHÎqI”==è#ŒÒm™üh¤€is¦)@c~B‹’{šCõÎ; 1Ü*8Ç<ý  Ží­.i3Û·Ò”Û§Ò€}9 ÿ]V£Œu™öÅ.­'ßÚŽEØ¥Ç~¾ÀÒêqô /SÔЂÇÿÕFpqŠNOÏÖ—‘ÁRôô¦œzÇCŠ]£ÐRçÓg?ZN”¸>´Ö“¹Ç¥.úÐdtÎÖ—#½&íúRŒvÍ Ê^´dú5ü(ù½qG>¼ÑôÅÐ üiyìhÏ©Å&Fzãð ’;QÃéK×i3ê(ýhÎ:tô¥Ï¾>´˜ÿõБøÒâ粃øÑ“ô Å! ÜѸŸJ^ýtqŽ(ýhÆOCF(è(úÒâ“ &Œœ÷£=)qí@ ×Ö—mµ&¥÷Å•.=±A÷ öfsŠ0cGÓ?| ä°õ¥Å&Ð{PÏb1G__ÊŽ;ƒKØPsëùQŸÂ—ð£é@ ߎ(Áíš_Ä~T˜ ŒûþtsF3@ GŸ®i0hÁôüh*9¢“ó 8âŒJ^~”„úƒøPÔô?ZùÍq@=€üép@ëIÆ:~”¸ü(éߟz?1ëIþs@ ×ÿ¯@úÒ~4`úñ@yëAôâ›Põ çð ñÅïŠ3ïš:LzqF1Žô¼Òöæ“üñ@€:sE}izôé@>ôŸ­£v{Æ€#¥úÑšOóÒ€ w¢ŽÈ£§¯å@qFFhã<ç4gÆŽýtsô£Š0s×ÒŠ>œš?ÈÐ!yõ?SGJLž˜ýh#=蹤ÝÓ¡õ£ð ;­Ÿ_¥÷?F: >† øŸÂ—Œu&—ñ¤Á bÿ*>œÑ‚;þb€:ÐûQùæ—Œc¥'dû ^”b ïš_¥zQÏs@Äãýª_ÆŽ¼g4˜Éé@ ‚8Å(Î;_Ò‚=Çá@} &éNÅ÷ çð¤ ûÓ°{Q‚=踮(ÁŒRž~¾´dö  w¤ÇÒ”œv¤9íŠ?ÂŒÑÒŽqé@ ß½{ÒüÞÔ˜ô ëÇãGãGN½hÈ<OÖ€1×ó¤—$vɇ@3‚yãÚž´gÓ4™Ïô£žÙ4ŠCžçj3õ¤ž(£þF=Éüi2=OÒ—·JÇΔZNSEœôŒ÷Í&Ol~&“ úP1à_íßÚÆŽž§ñ æŽ}híÆ(ÿs@#¶GÖƒÓ¸£ŒzÑž üéqØò=(ä æŽ¿ã@¹¦ÈéA͘£üâ€ý(£¡êGëF3êh÷£=M(íG'¿åH´gŽ)>´¿0“ô£¥éHE!ÇB?ZpíÅLÑÆ9Pz3õ£#±£ÍŸj2{æ`á@ïøPÉÅ=óF9ÇãF󥿓§J\úÐÏÒ€}Í%(É >擌w¥üé9ô)i3ìih‡céKóšN(cëKzJ3Ít4½(æŽ}x ÏùÅúšZ(;ÒÑøÑJ:Ò~tõ¥úÐ;QôÆ~´fŒúŠ\“Gäi8÷¥üy ã=è#Ú—š((ÆiiÔÐéúQòƒŽsô£ëüèæ€ g¿4¼úŠNOÿ^—¯n}hŽŸãIϯ¸ãÖ€ Òg¥Çæ“´gëF=ù£§^>”dœÐ×¾~”~uàäÒã(?\qëG>”ŸŸç@ ùуؚN}hÿx–š_¥P1=¿J1ìE§CGNô^?LqGçùÑ­ÎŒà÷ âqÀRrqŠ_ÎþsÅØ?J\Ò~TQÏ­Ž)ihÆ>´ 0{â—( “¿Z=híÎOµE/Þ_¡¢–Có¥€Ïûk&|Äb;¼Ô‰wÇQžÍÚ§äö÷¦›HÛ Ç¥V`ßuÁõíNó9>Õ µ=UØcÐñF%\n!¿h}Ì})wc©ö¨A$}=é23·®:Sg̾~”n_©ô_°ÏqëNÝžÌ>‡ ŸxE&ÿ¥D0Š^Ë@‰3Ã}….GcQç#Š\ú2ŸÂ€ŸVJ2CúÓwc¶}Å&ìôòÅsþµÏ|{ƒMÜÎŽ; ЃƒÉ4¹?…0g9qNÁþ÷>¨¹çü . 4ÂÁFIzâ—€rçÚã ¤ÈóIŒñ×ñ£ôühsÏAŽô¹¦)¿)Ïb?*\à÷ü('ßZNOZ4£ð4¸ô*=r)28Ég#±ìŸ_ƌπ‘ÇéFOÖ€‘ߤÀ'#.}hÇ(ë럥&­8FïÊ€íGO§Ö—&Œœp?ýj^1Œþ”¼Ò~TLãÞž¹4½)yõ aÏ¥&=èúŒÒ€8ëGÒŽ{ Òõö ç©N}?Z0=(ü1øP æŽô¿éIÐýãšúô¼Ò~<ÐA aϦ~”~tŸð*QŒõüè~”£Ö“ŸZ^þ´sè)?hüM/å@¿>ÔgëIϵ/Ò€ qÍ-'>¸£ç¸ô} „ç×ð çÒŽÔ(çÚ‡nôïGéGç@€gãð£ëFÐŒÔ9£ñ èi#®)hëÎ !?úÿ:Z(1žçñ£٥⒀›ð£ó4qŽ´¿­'8ãƒïGQ÷¿*^>”Øš=¢ø4˜úš.3E&¦ úŠ\úQÏJ9õý)9úP!¢Š1ÇjL.hÀëŠ^Ü8£ó£óPp;~”¼È£š>¦€”~dÑŸò(úÐ1? ^ZOÄÒþ48õ¢ŒQÇ©ü¨üi6ÎŒ{š0=Z?ô¤Ç4ìR}E]´´cÚŒsšN}(ü)qÏ4~#ñ ÍŸ¨¥Ï4g?þª7¯cKÆx¥è(ýh½9掸ëKõ£ç(ÀÁâŽ:h bŽ{RdzÑÇsøP!~™4Üûf—=ðM-b>´rGÿZ—Ÿò)ç¡ ~´gÞ—¥'¾3ô4sž‡ñ£O®(ëF?:.);ãù8_¨ bpOz^): 2:ã?….sô¤ç¥hý(çÒ—§l}(¤éÔÐþfŽ?: 9ô ¯Š0E'çKÏ®ºQ‘ÎsKÚ€~(£9¢ F)hÍ&9éF=¿Z\ ?M¼R÷;ø£1° ¶8öÍ1Pä»ãq»{TØÉåi0=(Þž´„ñ‘úS±­zÐ1¾ŸÖŽÝ…;ÒÏ^¾´ƒÐã?LRöîhÅ&Ó‘ÈǦ(8íŠ\ÒãüŠ1ìhÈô£Š1F=ÿ 8ôgë¥/J>”›¾Ÿ•ôcøSÞ°Ç·Ò€KÁíFE# éwhhÆ{ÑŸ^”©¦þ4‡¯Aš>QÓµ2ýtQÔõ¥Å {Q€hÆy¤'ž„ÐâŽ1Òg=8¥8ïü©€t£è¡£¿\Ðס¢ŒPµç­Ÿþ½ ^E {b—œÒ}/ã@^ÔQùQÍ0KôÅ4~u¤ü?*R>”£†LôãëJhúŠ9ôuíŠ>”j1éG4|Òìh¿•‡ãE=…ÆŒsš1ŸJ?/€ƒ×?;~´¥Aëüèǽ&A:=ÍŒú~´Z^i½úRК9õ4¿•'á@ÂŽ}…ýt~4Q@ƒQŠ(Æ(Ï¥Ò‰Î9¥sê(úc41I·½/'¸ÇµŸëKšZ?~4QŠOÀP1r(͘=øúPãÜÑŸcIÉ¥~¿QF}? Ö“ñ AžqGãKÆ( aŸ­ž?:0OÿZ€šLŠ)0}s@‚Ž=*1F8 >ôtõü .3Gã@‚Š2=³FOáô É }1IŸÆ–ˆX§ô£ƒ5a‘¨Ó¦(±;GáHPt °Tô ÓHé@íÚ=Gµü~µ7` 0sÐs@ä eÂŽÀÒü¹ÎåÏ­KƒèGãAöüq@ã¿Zv3Ó¥Ø×ëFÆ‚>”mò*6ÒœtïHôþt»àb,vÅ/=ù¥ã=9 ÙžãéKåŠwÖ”ûŸziŒ €Àö4žZôÆ)á@è)zP<±K´ÐSñF>”ͽÇçFÏ¥?Š)€Í£(Ú|SóE3hÿ"ž¸§ÑøPv¥G|S»f“'üŠM¾”›=yôÿ“… €;KŽx4î”S¸4cÖGå@ #ëF;Í8šLf€oçïIƒNÀ¥ ãŒP)y=Æ(Àî(õ}qš\J?*LqŒŠ03KÇzL ò(¢—ê)(sŒâ˜¥öÆ~´˜ôQ@ƒ<ÐO©RœúÑøPwsŒƒøÒð{Š^´˜õ àsK‘ÜþtcÓŠCèhJƒÏZM¾ÃÛŠ1í“J3@ ¸v9 Š^{*LØf‹Íý)9èOä(äqœÐýy¤Ï°öæ—ð£ð Aœvhæ®zŒÐ1hïé@éÖŒ}?*:ô Š?*Lwüiq‘Î(àð~c’sþcÔ´ÒGcúÒóèh'”~f€'¯QŸ¥(úQžzP~¼Ž£éGó BQùRóEõui{ÑÍ'J\úÒz3ž€ÐäÑ‘éGè ¯oÎÊ“š1@ Áî? 2(éÚŒûñ@ãùÑòŸñ£>ŸÎ“'=Gå@ǾizvüèçÒŒz}(Èö¤üi*2hŠÒp9 AÇcGâii? Qǵõ¥üh8é@ÏlbŠ9ÍZ8ÏZ\ô”c¸¤Å.®iph)1øšwPqIì)ÝhúšJ>¦–ƒÍž¹43“Í€ µûý(#ŽiyõÅ'ùëIÏb)Ü~4(1ß4ÿúéÞôŸCÅ âŒúš?>†€ Ñš\(2=x£#Ö—4~TÀq×ñ£JAŽÃŠu œ˜¥ÍJ…_çF3ׯ€­ (Èõuî(ýh8úý(íŠLã­_Η·QÍw£ŸþµÐŸËÚŒŽ¸üMúRÐqÚ¥/4gŸZ\â¥÷ÍúR{æ–“þsëGjZ(:QŠQE&1ëIÆ=©Ôqí@ ÈÍ&G¯úOÇÂp>ö? ÀàÓøRcë@ Çn¾´;óïJW=é ûŠ:rMö¸J1õ Œuš_çKŒúÐ}¨ôŽÝ(J0húàÐ~¿¥/ÖãÜPŽzóG¿4c=©E&(ÆiqA óÎI¥Ç­/=èþt„LÑú Qõ£8î()ON™£9éK“ëLæÒ”QHú;ÑŸQKøP}i}¨ühǾh¢“ZZO­ΗéE  )zŽ´S??iNhÅ'4sêqíKIÇ·ã@hàö4éÀQŒ÷&€ cµŽE.M úÑŒóŸÈÑ“í@ö éG¶(ϵ/=hïGNÔ}(õ£¿j=¨Íçš9£8ãµ/=¨£§j>j>¼PfŽi :Ð}h¥¤ïÀ ŒQj_Ò€ò4cŽ‚Œý(À÷  >˜4Qj1FGãF>´¸ ¤Ï°§RdúPøŠ?,}h£€ˆ£ðÅA@=¨çQ@Ù£¿hüèÆh¤?‡çKF=¨p84Qœ¿ ô¸¤Éü(0óÖŽ:ÑÊŒRü³A⎨•Š:zÑÍQz@´´À†o¾>†Š&ûãèh¤Á¥Í6—4†;u87½2š`J„n¢™š\Ñq cô´íâ‌QNÜ(ÊÒ8¢Œ­… 7J7 `&>´¿£p£p¤IÛMgs€ŠsܰàSò2?J]€CóO°À¥£p£p š……0ÆŠ2¾”e}(¢ŒŠ2)QÅei€QFG½\w â“§z\Š]€ÛŠ)r´¹Z@7b—å£+@ ?J\úb—+ïFV€š?\­”séNÊÒ|¾ô‡?äÒž´ìŠ2)€Ú?ýtï–—Þ€ÞŠ_–“åõ4ºGÔ~FòûÑ‘@ ¥¥ÊûÑòûÐ~&Žir´eh1IŒv§|´|´€hç·ëF)Ü{ÑÇ­0Ž)qíKÇ©£å÷¤~˜÷§qëFG½7¶(§dzš>_z`7ԿΗå÷£å¤xõ£ëÍ;ŽÆ—½0Ç £ëNùhùh´~tï–—#Ö€j;t¥ãÞ—S@ ç`ûÓþZ8 cÚŒÔî)~Z@3z8úÓþZO–˜ ¥ü)~Z>_z@7>ß.8éKÅzšf>n¿….?ȧ|¾ô¿-0Š9§qGË@ À¢Å/Ë@ ü)qNãÞ–€øÐG°§|´œR¸È£ï–—zf1ÿ륥ùhÊÐb“švÞ—"€Óÿ×GãNÊÒ|´ÀN;ÑÅ;å¤ÊÐQŠ\¯½-'Nôb—"ŒŠ@7¿Z0=qNÈ£"€Rp)Ùq@ ÷ÅÓ¸£#Þ€Š\Š2(¤ô†Ÿ‘FE6ŒS²=(ùh´uã4¿-/”uqK‘@ ǽ…;"ŒŠCE.E”Ÿ…'׊vE&GÔRî”nŸަ—pô£#Ò€óš]ÃÒÃÒ€}sF1Kº“pô ¿ZASNÝíI‘é@»‡¥”œQùRäzQ»Ú€·£ð»‡¥&G¥''¨Å-.áéI‘é@ËË/ÐÑR6 Î( ÿÙpaperwork-2.2.2/paperwork-backend/tests/guesswork/color/tests_libpillowfight.py000066400000000000000000000104501456262201400302540ustar00rootroot00000000000000import os import shutil import tempfile import unittest import PIL import PIL.Image import openpaperwork_core import openpaperwork_core.fs class TestAce(unittest.TestCase): def setUp(self): self.tmp_paperwork_dir = tempfile.mkdtemp( prefix="paperwork_backend_tests" ) self.test_img = PIL.Image.open( "{}/test_img.jpeg".format( os.path.dirname(os.path.abspath(__file__)) ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.doctracker") self.core.load("paperwork_backend.pagetracker") self.core.load("paperwork_backend.guesswork.color.libpillowfight") self.core.get_by_name( "paperwork_backend.pagetracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.core.get_by_name( "paperwork_backend.doctracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.pillowed = [] class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000000000 def pillow_to_url(s, img, url): average_color = self._compute_average_color(img) self.pillowed.append((url, average_color)) return url self.core._load_module("fake_module", FakeModule()) self.core.init() self.model = self.core.get_by_name("paperwork_backend.model.fake") def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_paperwork_dir) def _compute_average_color(self, img): img = img.resize( (1, 1), getattr(PIL.Image, 'Resampling', PIL.Image).LANCZOS ) return img.getpixel((0, 0)) def test_transaction(self): self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ], }, ] promises = [] self.core.call_all("sync", promises) for promise in promises: promise.schedule() self.core.call_success( "mainloop_schedule", self.core.call_all, "mainloop_quit_graceful" ) self.core.call_one("mainloop") self.assertEqual(self.pillowed, []) self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ("file:///paper.2.jpeg", self.test_img), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ("file:///paper.2.jpeg", 2), ], }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) transactions.sort(key=lambda transaction: -transaction.priority) self.assertNotEqual(transactions, []) for t in transactions: t.upd_doc('some_doc_with_text') for t in transactions: t.commit() self.assertEqual(len(self.pillowed), 1) self.assertEqual(self.pillowed[0][0], "file:///paper.2.jpeg") # algorithm may make the results vary if it changes later, but we can # still check that it actually changed the average color of the # document self.assertNotEqual( self._compute_average_color(self.test_img), self.pillowed[0][1] ) paperwork-2.2.2/paperwork-backend/tests/guesswork/cropping/000077500000000000000000000000001456262201400241445ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/cropping/__init__.py000066400000000000000000000000001456262201400262430ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/cropping/test_img.jpeg000066400000000000000000002422011456262201400266270ustar00rootroot00000000000000ÿØÿàJFIFÿáëExifMM*>F(‡iNxHH0210 0100 ÿÿÆÎ(Ö HHÿØÿàJFIFÿÛC  $ #," '.0,)7(44418=9'.<2432ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ p"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?÷ê(¢€ (¤ ¢Š(¢Š(¤Í-%£4bŠ3KIK@Q@ (¢Š(¢Š(¢Š(¢Š(¢Š(ÍŸÊ–€ «v×+$& ÅFæ`½ñŽ?Z¢€3gšúgTû3‹|†r1Ÿ—œc=øh#Ub¥IÁê)ÔS«­ùšB®D*¨Ç#dþ#=» š#)Rd;p*J)^D»,å$!NÐsÉéþ5}_ÊÝåF$?Üãæü6ûõ«ÔS©¿hÞFîø§QE (¢€(¢Š*¼ªÂâL˜Œ+&Üà}¥X®Oƾ >/þÎÅûÚý’Gbä0l{ŽF8<Òm¥¡­SE’å]íÀë(¦¢ìU\“€OSŠç¼KâEšËO½»ò.oy_!`9Æ[Û4î–æ2’Š»::l…‚1Q– p=M:°üW¢^ëúp³µº6Î&Y ç x8üÿ ¨$ä“v&¤¥7wØÙ‡Íò£óNdÚ7}iõ[N¶–ÊÊÖÖYŒÏ )HÝXŒÕšOr“m]…QHaE%-Rn_Z¡ ¢“"–€ ËÔü9áífæÎïP³Iç³mлgåç=ˆÈúæµ3E _q4žŒ(¢ŒÐ0¢ŒŠ(¢Š(¢Š bŠ(À£Š(À£Š(ÅQ@¥QE&¥.¥PÅPh¢~´´QEQEQEQEQEQE„wiAÍ9 ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢g>Ô´8íKE%-Q@Q@Q@Q@Š(™1ïN4´PHih Z( Š( Š( Š( ƒE€?ÿÙÿá fhttp://ns.adobe.com/xap/1.0/ ÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀòp"ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?÷ê(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (ïŠB@ë@ EŠÁ×*r(h¤ÈÎ;ÒÐE7-éNïŠ(¢“"€Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Žø¢âÍ)2)[š4P¼Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@1?Ö¹§Óï½>Š( Š( Š( Š( ¾(£ø³@ädPEPEPEPüY¦°'¥:ŠO_zn Ç…Óè àïÏjuPGñfŠ(¦àÓ¨ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( àçê?‹4PßQüY¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ b}÷§Óï@¢Š(¢Š(¢Š(¢Š(¤^–Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š( ñ@æ€Å74PdsíJ9Ïï{Ó—îÐÑE„ÖëëHÀž”Ì“"”r2)¸4«ÂàÐÑE(¡¹¢€ (¢€"–›ƒN Š( Š( ¾(¤ÈÝšQÍQEh¤^”´QHHhG4™)˜4ê(¤È ¤È FGJL\ŠZn :€ (¢€ (ÌüÞ˜§/Ö@Nìs@¢Š(¢“"–€:Ñ‘HÀž”`ÐäRÓpiÔQEPx¢†æ€NR& 4ê(¢€ Š(< š)ÉÀëOÔ{‡·<ДÖPù‡ÌÓ­M@2ŸMÁ ^ŸMÁ§PdRÓpiÔQH=)hniªëN¢€ &“"†åp(È¥¦àÓ¨¢Š(¢“"–€ (¢€ (¢€ š( È¥ni¸4ê(¤$´JZ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ j‘½©ÔÅ{Ð袊(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š4P¼Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@zûQ@Q@Q@Q@ ‘KMÁ§PI‘œw¥¦€I‘K@h Š( Š(€"ŒŠiã­ž”æ Ó{ã½{P¥*ñL^:Ó²(i¤N¤n”£š)K@Q@sE„Ö€Š( ™O¦àÐäRŽi¸4å†(¢€ (¢€ (¢€ (¢€ (¢€ b}÷§Óï½>Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ŠLŠZ(£¾) ­-Q@wÅQEQEQEQI‘K@™´QEQEQEQEQEQE&E-Q@RdPÑI‘úâ–€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ n :Š(¢ŠcsÒŠ\0h‚ïO¦ŸJ}QE&FqÞ“æ÷£~{S¨ŸòÒŸMÁßN È¥¦Sè ­(æ˜Üô§)´QEPx¢€"–™Û=©ÀƒÒ€˜Üô§ÓphŽ´RàÐ4ên :Š)¸4ê(¢ƒÅQEÜ0iÔPDŠzÒH 2(Ȧ¯h¥Á QEÖô§QE5=)Ž´ún %ãŠ\0ñìЃINȦŽzPÇ474/PpiÔQ@Q@1éô×€9¢‘H¥ “#8ïKM ‡Ïju&E-7€EPEPEPEPEPLPw½>š¤ojuQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ Á§QEÅšcsÒŸMÁ RdgéiŸòÒ€üY¢ŠLŒã½-Q@Q@Q@ §Ó)ôÜuPEPA⊚(¢Š(¢“"€ƒÅÒ€ ŠLJ}QEÜuÒÿ¾³N¡¹¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ( s@&E-7€@æŠEãŠZ(¢€ƒN¢Š(¢Š)2)i¸8Í;ø³E&E(怃K‘KM ŠAÏJŽ´ªëF :ƒÅ7474MÊñ@ ¦ZUu¡AiÔQEP¼RdRÐEŠ@Aé@ EPÜÒdRž)”àCt¥™üyíO †æŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¦(!ÞŸH>óPÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ@æŠ(¢“#8ï@ MÁßžÔê(¦àïÏjw|Q@ )ÎOju4½éÔ(¡¹ ñ@Q@ ížÔúpÚ<š’€ ( ñ@šB@ëJ¼PA⊚(¦nmÝ8§ÐL§dRM:‘ˆ4´Ê\uPdRÓ)ôQEQHH£š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)Ž)i27gð Š;f:ÐÄçM£ÿ‰Å. !áòzR¸40'¥+r(«ÀÉéNȦÿË:hý³AâF;Ò·4ÜÖEQEQEÜùíN¢€ š( ñI‘JÜÓph)ãšn 9x Š( Š( Š( àÓ¨¢€ ( s@Q@Q@Q@Q@Q@Q@ ûÍKH>óPÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE/QEÜùíN s@Q@ñfŠ( àÓ¨¢€ š( Š( ìô§QE74Q@ `OJuPEPpiÔQ@ Á§/Q@7EQE7EQEÖ¶iËÅPEPEPEPEPEPEPEPEPEPEPEPEPEPEPx¢†æŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)¸?øöiÔPEP¼QEQEQEQE ô ¨fã÷c<ç­MßPEPEPEPEPpiÔQ@"ð¸4´PE&E´…£"ŒŠZnÍïN¢€áÅ5=)ÇŠLŠLu&E-(¢€ƒ³è`OJuÕ6iÔQ@Q@Q@Q@Q@™´QE&FqÞ€ŠLŠZ(¤È£"€Š( Š( Š( …âŠ(¢Š(¢ƒÅš(¢Š(¢Š(¢Š(¢Š)ÞjZA÷š€Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(ÐEPEPEPEPBñEQEQEQEQEQEÒy[}Î*Zk }¹ìsN Š( Š( Š( Š( Š( Š( Š( Š( sE ÅQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQER}©iªÝï@¢ŠB@ë@ EPßQüY ñ@ ‘FF3Ú“Œ˜ï@¦¨ àÒädZ_â͆ͳCsGð†) ùRÐI‘KMÁ ÈÎ;ÒÓ?å¥>€ MÃ8¥¦'×4úPÜÐEPphÁ¥È¥ QEŽ´ìŠZe>€æ˜9éO¦/h§Ó)ôQE)¥+sMPGZuQ@Q@=)iªëN Š( ñE ÍÜu! u¥ ˜9|Ž”úbñ×ë@ ƒN¤È¥€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ PÜÐEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPLÿ–ÿð}3þ[gýš}Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñEÅšh@­:Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¸Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@QÛ4QH=){†(¢€ (¢€ (®úg…­‹y·Óƒ0õ5t œ¤aØyúÂ(d.ÇSÖ_æ'ï3ÌpGà+Ò|=¦.‘¡ÚYÚcŒnŒzרõãû 6›-.?2XÀÀG¿á^Š8­+=,(‹EVQ@Q@Q@Q@Q@Q@Q@Q@Q@8®3Çþ1O éiä0kÙîã<?§ã[^"½ŸLðõäö»ZtŒìÞá~cÓ’@¯qsâÝkziïõ+¨m!ÀÀHƒáœÜ×N’¨îö"L÷ý>Y%Ó­¥”bG‰K}jÝ24đ€;pÆyü«˜±h œQ@ÅÄV¶ò\Ná"‰K»@É?•$W0ÍK‘IR}84ì÷Z+.oh–ùóµ[8ñýé”ZšßYÓ.ñömBÖ|ÿÏ)U¿‘£•öõŠÁÆTäRÒ¢ŒÓK¨Ý“÷y>Ôê*®íç b™$ ÓiÍK¸d õéNÌ¢Š)QEQEQEQE„I½vîçâ¨ê¶××6ر¹ò$Ïq\]LJþ#Ïpg_iñüÙˆN1ùUF ¸†>¿•&áÿë¯<ÿ„[ÇSœÉâ¥Ø)¥—Á¾2˜|þ0dÿuÿŠªå]É=K)»©K…8!¿MpÉàß`Þ6Ô¶ö&ÿâª3à¯[ô_Þ’{I¸ÿìÔr®äó³½) yŽTŠ}r>×®ÝM‹q¶Ë÷Ns6Gn‹ŽµÝøÚDÁz³1Àû3 ûÖwÃ[t‹ÀÚ{ˆÀ3«JØìKt®˜»P~¤ý¢…—Ä{W½šÒëK›O‚8ò%”޾˜Ö߇m×P\Ox„G‘ÊGÛ”¾%ð}—‰tÉ­çQË® ×9à_ÙêrxS_`·Ð‚ —H£Ó…¬ZAöG¢ŒÑX”QEQEQE!ÆøÏÆoáÕ‚+h|Û‰0võÀ=9é]sN‰ JÄ„PXðs׎µãÞYüuñúÿ šE”ù(ýÜt_ÊքÄö&G°Àd0Fdr>njZ@B§'Z ëíY!`9àf¼ÛIÔWPñf½âyÔ kû£òœ}æöükÇúãèÞšH3²Å÷fcÓÛñ®#C±}jßOðŃÒ-ÐI¨Ì83¹êyº¨Ò´žÄËS´ð>žñÚͪܡûUãnÉë³Öºú"Ñ6ªðéŠx®j“nW¡h¢ŠEQ@Q@Q@Q@Q@Q@Q@Q@Rdb€<³ã=ò¾c¢F$’æúáUBpHõ­­ Jµ¶Ôíô¯%vYÚF›}±üëÍo|l!âó,ô{rXuøýN}+WIñ.—eãèÞÅo4.™)ëƒÒ»öpå]Œ­ï…½yçq^yãˆÉá颷±UžqóJã•Qè}ýºÕMKÆWÞ,º'ƒÒHU›çÔJíU_`pk'Åþµµ}Ãù—·ßi»‘›æ“hå¹è=«:TÕÒeÈö(dY!GÎA©)ˆTŸ\å>5“Êð6¼øÉ|àRPŠà<=àGÄšk_êšÞ¡u#ͤ»7$‚OnµØüA¹ á´³,ßÜÅhï½€#=ãW|†?h‘‘ó‹7 ç °d~u²v§ó'íöŸ |/f2;’çé‹Õû_èVj¿eÓaµ#þ}òµ¿KYó°«±0:ŠiuÉêqÒ¤¡DH÷³½Éí\»¬j*‚mÃBE ¿> 8QùàÒjw÷/×nt]*g‚ÆÔâútÞ}×ð®ÏOÓ-´«Tµ²…b„uëNU©68¿|/Óì4(-5(7^!%®-n¥_æEwV–¦ÖÎ;mìûWÏZ³ED¦Ê (¢Q@Q@Q@Q@Q@ Í&EÔdf€ÃvÞýzWã½VòÖÎ=#JS&«©t81'w­íw]‡EÓÌÌ •ÛË…6Ÿ½+;ÚDÉ$šæ§}Rã+ÉÏ•xAçZA[VLµ.x_Ãñxo@´ÓÑ÷4IûÙ;Èç«ܤ íÅ-Cww(*?‘w1èO%bx•oÖÊ ½:3,ö²ùÂÁ|ß•†Ü’z"ÄýWû/À׈©æOu¶Ö$'—ÝÔZÞ Ñ%Ð<%§iòçÍŠ $RAÓȮOÁðÅã;Ö×µiÍÍÍœ„Å`AÜöÎx&½4Œ/Ê+Z•{2b:‘OQÜRÕMGQ¶Ól'»¹—ÊŠ$ÞîAà~’WvE+ñ5¿…´s¨Ü2Va1rî{ñ®GI°ñ‰£ú‰hÎR6Ç"¨øVÖçâ‰î¼Kª—U«ùVv-ÈCýïCøW­ªà8 z VüÞÏmÉ34}t{hí¢bÑ(ÉÏ­kR ZÁ»»”GœMžqŒtïU¯õ,-ÚI¤10KÀsT|Iâ+_é^NàòÄ0IwôÀæ²|1¦]Þ'öÞ³ºKû¥a8Ûl=:àþQ…•ÞÀmiž ÓõU¡ºW,»†T¯ˆ­jç¦ðÍŒV.-¢(êÍ*€qÏ÷~•'„õVÕ¼?ò¶gRc”u✢šº$Þ¡¹£9¦—Q×ùVe1kÖÓxôxÝZX£Üç<ƒÛñâÍ¥ëVn¹¸™ÂÉB¹“Àâ¹=KkOøËƬÎöð·‘“€ÎAò©¼£Íªøš v陥 %ÜêpC´œ*L ëT’Õö&ç®·4)3Å1§™›j¨$’0+“wbŠ×·öÚu¬“\IåÇüÌTÿ“øW3ḮõÍE¼E{¾!óGgoÙxýjŒ3Íã²F¥t-=Ìlz ŸÓž£ô®ö8–Ö(*(À¥híN6[’ICsE™ACsEQEQE74QEQEQEQEQEQEQEQEQEQEQEQEQEQE7EQE/QEQEQEQEQEŸÇøRÒá@ EPEPEPEPEPEPEPEPEPE™´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE`dŸZ( Š( 7â}È·ðEÊ“:Hâúî`*×ÃÕ#ÀZ>Gü°õ®kã=Ó&‡¦Ú/ßšì6ßP£?λ@m|#¥BÃ[¨ÇášèzP^¤}£r¼ß⥉³±ÓüMf»o4¹”«Ž}kÒ p¿G€¯£ÏÎï¨õ;º ŠÄC‘Øi÷Ky§ÛÜ!ܲÆ8ÇUª§¥[µ¦•i.ÖŽF„jÞ@¬¥®ÅGõ¥5Êë><д{Óe<=Ì}#‰›oÔ€EZÑ<]£øÉ •Óã$2Ç\n?…W$­{ÐQE7xÛžqô©ÜQßÏ:=û<ÄÝýÝÃ5Êx§Å¿Ù†-3MÿIÖg»·Psøž‹ø‘N1l ïˆÞ.]ÄivYº! Fsž¹=ãŠÒðþ•oàoF·§{ÚEæÜH«’íøu¯?ðï†ç¾ø« Ô%iî,"Iï%biDúŽ+Ùg¶ŽâÙíå]ñÈ»\Jè«û´©­‰Üó؇ÃÚ`¶wK!Ýq'üô~í\×à /N“]Ô×ÌÕµÞÍ#àùcÛÿ­]ìW0λ¡•d#(r2:ÕÕ¨ù}šÙ$´QHXÏ>½+-™ëí@ E1$W@뜑E>€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ¡¬_G§i7—r6Ä‚±Ž*ýy×Å‹ù$Òl¼;lÄ\ê·Iòcþ#íøÕA^H.Að†ÊVÑõ ~å O©Ý4ÈÇ©SÐ{~5×ê^Ñu‰Dº–•m<ªAß´ÿ_þ½]Ò´¸´*ÛO·Eb0ó«ý©Ê£rl’Ž¥XéV~E²[Ä;(港ØsÇš‰nµ½¦ëKQØÿy±ÔWUâ}Déž¾ºVÃ,gi÷ÅVð^™&—á{8åB.%Q,à ᛓU5MÍîéÑÑE‘G™|Jšþ]{ÃZVÜ]5çÛR9˜Î@>Õ~ËIñ½å¤Mk¤ÛFV(t˜Œ‘Æiš¡Ýñ›A‰²â;˜g±¯@+i¿u"L«=ìâa{&>i+ZŠ+ÃüAÖç°ÓáÒtì¶©ª7޽c_ï×nÄ($ö¯0ðn|IãmkÄ—%¤r›KHúŒ­íÒ´§Ü‰§…ü?†´;}:Ünt_ÞLÜ™Ô÷­¼RwôéJ+9I¹(把(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(^›Y‚Óþ$ö_i—Ž<Å_ýŠã.,ü{ ”—zŽ¿§ÚÇË1‰Ž?!ÏÒ½0Šåžñ.®ÂyLš}› IñéíZSv$ä4Oj êZæ·¨H±ü¶‘îûƒûÇÞ½ËI0¬kww Þ’¯"lZ&Ô*JU*6AETÇPùFN$}«—ñWŠ—G¶K[@gÕ.F-àU$“ïÙàX§·°džÛ{7c1茯Jõ? éÑYéBHÇ‘"ãû½…ršÝ‚é馸NÌfóZ”5샃å/Þ`zqéÖ½HmÖ4*Ç8úVÕêÞ6FQ^ñ Ã5çž.ÔîõýA¼-£†À‘VîáN<±ß9­ßkwP@–:T~v£;a" ǹöy/õ5šjœyÖã5T``õ®cÆþ$>ÐÌ.ûˆòm¢—sØJÖÕµ›-'O–êêàF¨E,Çè \ž‰¥^x‹ÄCÅÄ-B6XZ9OöϽL!mXI¼%á´m h »Õ'>uÌî.Þœô‘¡[_â}Þ§g‘¦é@WK!êqßë]½©ºÜ.‹dXßÝ©- àDž¿ýjÑÑôØt2Uëm2“'ûG|îÎý@Ô®wž"Ч½Päá"‰¿‰Ïlôþ•ÐŽkÌüh|Mã#Ãï»Á%ÌŽ£œ¯O­E(§-BH‰¼K¨¶ZLv×~"º#í¢–ùëÎ1ùê<-áÐCÝÝ9¼Ö.GúMëw>€•Äi> ÔþêwšäZ¿™£ÍÅ«©f“éé^º’,±«¡Ê²î«JÖÁ°Xó¯M_üU¶×x¢uR9e ‚Ez9` ’ps^yã=îÇÄ6^1ÒíäšêÛ qnœy‘ýkFÓÅíâ=1×Ãé$C·ð¸þu5•šì-x³Åð襥±óµ[Œ‹{uRIúàaàX¯/_ÞêÞ8Ólu) ê7Iö½L—Gï–1Ï_¥zvƒá8´O´j—î.µYƒ4÷OÈØv®3š͵¦±ã+Ëv7º¥ÙKHOÌÛG  q[R|Š\š“$ÎËÅsO%¼Zu‰)$˜P«è?÷5“ðÇü"×Q vT½•UݲHÏç]…§Oåͪ_Æ~Ùt¤Kå'÷2?ãüªÙxZãQðÞ©p¶wFéäŠi¾U‘OB ãõ¨M{6—‘V÷P®k^ñ ÙÞǤéÈ.5y¢2G œd“ÀçÔ×F²#ǽ]Y¼Ep~ ´Š÷[×uÇ™gš[§·‚u9 ‹×oãYS‚³a!>ßk³\ëVúä¯#ZȪ7!8ù±ëøWW­ëphzt×sýÔQ‚w{9'ØT÷wÖúu«Ý]H‘ªu'åÞqÒ¹=. ŸjñkwÑ•p’W&HߢŠ* 8¿‰³˜|Ç¢½Ü7ÐÈþ†»Gƽ>•â|E¡Íbä‚Jºýå9­k[‰E´^bâM£pÏJÒM{4¼Ù?hšŠ(¬Ê8O°ø‹á­Q²›ì #»ýßλˆ™^$d`ÊTøõªwšM¥ðµ[ˆw‹Y’x‰<«©È5jÞí­¢‚%ÛHЀ*äÓH’Z(¢ ¡’ÈÀwä>ÖáðV³©hÖmL· ,R¸$6sÜdzu¯a¬MoÂúN¿ÝJÉn1éÁüêá$“L™"ñn“öÙQõ+!U(ÂáOqÖ˜Þ7Ðö[jvéˆ"y?ôj·Ã? Û6³þ®ÿüUnéú%Ž˜ج--I<ù1NÑ ³Ö ãf)Oûß/óÅkSB±rÐS«9QEQEQEQEQEQEgëo¤Ü4Î˲!êç ¦èºhÒ´Ø­°Y2?½^š™U\d øŽ• §},ER¤,«œœ2Iô¥ª—öy§OhÈ…CZåõ_Ü^jØÞC-ÈÿYpÈ¿‰àÖ†áX´‰¤¾º“íz¬ÿë®[úÕkÃþ·ðö––6 •þ'c–?kj§>_„›¢Š*J ñÿ>7'MÕBHÉ 1ÌÈ¥Š¡9è95ëõFJ2)OF®GNWDÉ1Ý]j6:†™¬[ɧ´–¿*ͧ†Qî§ ùŠõk µÏê6²ºI§höl¬á×›£ôê?ì¡ð¶‹m?Ú Ò­a÷NÎk lÚãµmR·6ÁaëÅQ\ź¿†tlí>9ÜŒøæ—KðÆ£Ö:U¥³ÓÅlÑUÌÀhÈRª›@t§QEHZ/‡îõ,V‹´“žÜkøeáÛùüW«JÏss¼¢8çocí^›, ÒI[’Z0r*¾nÜV²’dÅQŠã|aáÍNãP°×´7Î¥§©!b•[¨$+³¢²ŒÚ‘GŸ%‡Š|WwÕíÿ²´è%Y%·óO´ÿ³•cõ®ù"xJxF¢œ¦Àc+à*m Žr3MX‘IýÒ„ –Š¥¨Yµö™se¹—͉8>£Àx+á­Î=½î³zng¶M–ñ \çw¡5邎8¦ªJœZˆ@U ÌÔ´M;XòΡ¦ÚÝy|Çç %?kR’’`T·°‚ QQ˜¡Æ<¼×Ÿéº/Œ|ºn‹eg}§ZHIuCæÉÎâ3^—Š1MTz’yþŸà­_T½ûw‹uy9†Å8}Hà×x¨è à€>TQŠ–ŠR›(àntÿiºÕãh–¶Þîew™°6ã¡9®£IÓ¯m WÔ/>Ñv ùVµ%S›d‹ETQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEâU'û¦¤¦0%×èhôQEQEQEQE™ÇzZnüö QEh¤^”´h< šE#‘ÜPÿv€ Š21žÔ˜4Ÿò΀x¦†Rœs ÔJŒPΰ†ÉÆNj@AéP23ýáS 4¤€qFGëŠB lŠ0ñìÐäRÓpiÔ™dSiphÔQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEš(^( Š( Š(ïŠR7JZ==è¤=WÚ–€ (¢€ B@ëJx¦°'¥:Š#"Š;âŠ?‹4PEŠ(¢Š(¢Š(¢Oz(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¤‘Ò–˜ „æ€EPG|QGñf€"–›ƒN Š( ¾(£ø³EP9¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ C÷––‘¾òÐÑEQEQEQEQEQE/QE5AÄ÷¥nW–Š)¸;1ÞEG—Î1úÔ”h àÓ—Š( x¢Š(¢Š(¸4ê( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( âÍPÜÑEQEQE74QE"ð¸4´Q@'øÒÑ@sEPEPEP«íKEQEQEQEQEQEQEQEQü8¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠŠ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ C÷––‘¾úÐÑEQEQEQEQE€ƒÒ–š€Ó¨¤ÈÎ;ÒÓ“Ò€I‘FE6€‘A ž”˜4Œ &8zQ‘œw¦§ÿZ—~{PädJZnæ>´ê(¢Š(¢ŠLŠZn :€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ 4P¼PEPEPEPEPEPHßyiiÞZZ(¢€ (¤ÈÆ{PÑEQEh¡x¢€â“"–›ƒ@ =)ŒAéJ¼ ž”Ò=(Ô€‚p)G=)ª~h@ÊN¡H¨ÔüÒ«2O«Ççšq u¤šÒ€EP9¢…âŠ(¢Š(¢Š)2)iñÞ€EPEPEñEQEQEQEQEQEQEQEQEQEQEQEQEQEŠ(nhÐEPEPx¢†æŠ(¢“ûÔ´QEQEQEQEQEQEQEQEQEQEQEQE&E-7@Q@Q@( Š( Í/QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQÛ4(þP9¢…âƒÅQEQEQEQEQEQEƒKLÚVLÅ>Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š;âŠ(¢Š(¢Š)ÞZZC÷–€Š( ¾)¸;1ÞüY¢€ (¢€ (¢€"–›ƒNÐEÑ"ž‡ô f;Ò7)O¦zûP”¸;óÚš¬SßüŠoñçµ(U+Š0iËÅ ÅQ@Q@Q@Q@Q@7~{S¨ Š( Š( ø³EPEPG|QGñf€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ Š( Š( Š( Š( u4´PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPÜÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEPx¢†æ€Í/PEPEPEPEPEPEPÜÑEPÜÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÅš(¢€ (¢€ (¢€ C÷––ýå ¢Š(¢Š(¢Š(¢Š(¡x¢Š)KE³L†#¡§ÿ)ªL6×4`Ó¨ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( M-PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEš(¢ƒÅš(¢Š(¢Š(¢Š(¢Š)¬Fõ§Sï¥>Š( Š( Š( Š( Š( “"–›ƒ@¢Š(¢Š(£¹”T3»¦ÇQòÿô  ¨¨ÒxäFÏàiË"¿Ý9ü(ÔQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEš(^( x¢Š(nh^(¢€ (¢€ (¢€ (¢€ (¢€ cýô§Óé@¢Š(¢Š(¢Š( ñE#sŃŸn)iƒåÝžç4»×ÌÙŸ›Å;¾(¤ÈÝšC"ƒ‚Ju™Ïj2(h¢Š( 0ÁPx s@ H‘R„ ÷iÔPEPEPEPEPEPEPEPEPEh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Žø¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (TjY‡ÔqU´/‰Z&±y k<Ç’£ ŸÊ«’]€í(¤ij@(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š?‹4QEQEQEQEQEQEQEQEQEQQËæc÷c?I@把(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠšFåp)h Š( Š( ƒÅ74QEQßQüY Š)=}èh^(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ š( Š( Š( Š( âÍPEPEPEPBñEQEQEQER7ßZZFûë@ GñfŠ(¢Š(£¾(£ø³@Q@ùc~üsÍIG|Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ Ž+•¸ñƳy¥K!K›x‹²:‘È]ØÎ1ÓÞººù×âÖ™ykãÙn\—Р„«»¢7~:޵¶š©+2&uß 4Hµùµj¶¦kFM±+Uz ñ]OŠ|¥ßé˨ŠöËÅpœEløoI'‡l4õM­ ºFÊà÷5.¹xš~‹tìÙc*ç¹Æ*G*¾èþÉWÁZŒš¯„ôûɹ‘Óæü+z°|föÓíÙ6²¡$}Z·«šÍÛ¹QŠ(©¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š( ñERÕ5[-&×í²˜âÜpFnO²‚hæG¨â–¹k_xrâèÁöµŽOúh…üX]4sG*†Ã©ä2òÐÕ8Én€}QREPEPEPEPEPEPEPEPEPEPx4R7+K@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@#}õ¥¤o¾´´QEQEQA†(Ñ@ñfŠ( Š( Š( r2(¤^–€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ Më¿f~lg´˜Ýß ¢Š(5âÿѵˆ°€o›ËÎΟÆSÇE5íå×¶ƒQøëÈ2¶¶ ãØüßã[á´“o³"gY­ø…ô-:À²nžr# {‘Ôf³bÓ5?j0Üj±µ­±ÌVûó‡©Áþu'Ĉü#it«Í¤èùôòk§Ó®ÖûO‚â%ÂH”úÑü:j¤wÔeƒËØ£` zS袰((¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠGeD,Ç :š­<0ÞÛªK’3µÆ{Õ/]ý‹Bž|à(äÕ½1™´»g~ IÍRÓP¹Ÿá]V„ǧZÉþÒ¦ÓX–â÷Á+$S6ƒ ¬À˜}ˆê]¢¸# ä{WñGSµ·ðuÅ»\F—3"ŽÒ®œ¥7fIÙØÞ[êPÞZÉæ[Ì¡ãpܱæ¬VƒtÙ´Ÿ ivw$ùÐÛª8$·«7¾…QHŠ( Š( ÈÈ¢‘x\Z(¢€ (¢€ (¢€ ;fŠL¸ ¢Š(¢Š(¢Š(¢Š( sE ÅQEQEQEvÍ(¢Š(¢Š(¢Š(¢Š( ñE ÍQEQEQEQEQEQEñEÅš(£¶h£øq@Q@Q@Q@Q@Q@Q@Q@Q@Q@#}奤?yhh¢Š(¢Š(nh¢€âŠ( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( 5æú,©wñ—Z“9h-Ò#ÇC^‘^}à˜RoxQ>c¨ ùÿ…oK១[O‰íEï†5]s˜þ dU/Ü›ŸiŽÇ,#Ú~¢º ˆ¼ûybaÄŠTý®#áµÄG¬iü’XÝ × i'z-yííQX”QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQErÞ5—u•˜äÝ\¬xõ½qiæYcb¸B«¦+œñn|S ÚŽ@s.=‡zë{V³Ò1!|Lò½Ož6Ñíå»Ó<@n‘N~ÊF8úž*xWJÖRß_¾¹—U¾L«¥ß>[ûƒÓò¯J ÛÀŽs\GØFñ][HRÛSšê鿱p¨ÜZC;¥@P8´Q\åQ@Q@Q@Q@Q@Q@Q@7EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÖ#zÓ©Œô4ú(¢€ (¤$´´™´ÜuQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ahC’éãbÆgÝÏãþ5¹ÞŒQ»4šóéhŸ#˜ê¶ä•þóë^ƒ\OÄ;YaÒíukxËMap&$u ÜUÑiK^ÄÈí¨ª¶‰yco:6å–0á€ê Z¨eQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@”ÇÎø•g‘‘eä×[\ƒþçâr4„(šÈùy?{œWU%Ì0¡y\"¬üÖµ©­­ØˆŠò$HÌìTe‰è+Í4ÛÉüqã£tŠWDÒIXÜ&lÿ…G¬ë·þ>½:‡H´Òø»¾ÆÝËíœô#GµÐ´Ètý>/*G»ýM ÷qÓqšTQEdPQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEñ@Q@Q@Q@Q@Q@Q@P9 Š;âŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)¬@+õ§SÉþõ>Š( šÀž”¹´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQET70¥Ì±ï×õ5á{y´Ý=´É•ˆ·‘‘9Êv5¿Låy É<ÓéÉÝÜŠ(¤EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEP½á´Ö–)DÍ õ»·¸QÌyíî+ž‡÷º‚˜µïßßÚÿÏ$}Ÿ­wÔµq›D”tý6ÓL´Ö6Ëou^µz’–¥”QE (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ?‹4Q@Q@Q@Q@Q@Q@Q@ ‘œw¡HéIƒ¿=¨PCf€#vii¸4ê(¢Š(¢Š(¢“põ ¢Š(û-É©àáÏ[Þ‘wËo ö²hØ‹÷U½z÷§QXÄi"hšhdY!¸’9‡ü´ •z„¾'^i޶ZÃùöÃþ[à’?µç[­&sZ£G.//Â×…œO«¬¯!¼„M ‡B2µlŒŠñ?…Þ0xn“C½“1°Ûjä}ÃèkÚÏLŠíƒOcóÜ~ á«:mh:Š(«8ŠP?§ëRQE#ŒÒÓX˜ê(¢Š(ïŠ(þ,ÐßQüY¢€ (¢€ (¢€ (¢€ (¢€ (¦»ªY‚€2Ià G‘#]Îê«êNf·‰tE¸6­f$=œ¿Ï8®þMGâ¹%•¤ÒC A&É&Œ··¯Ôq[²ü,ð¼–b§&ñÿ-2sZòEnÉ;U`ÀrÈ4êç|-§ê:eŒ–çÚÊ6Nûk¢¬ÙAEÉ#ÒŠ@Åš(¢€ (¢€ 4P¼PEPEPEPEPEPEPEPšBvŠLã­rþ+ñl:\DIvzGƒÓëÒªœ%'h«˜Ö­q¼Û½NÒÆ#%ÄÉSÏå\ÅßÄ].F¹>Ѳÿ1^U©O¨ÜµÝãÉ,øã …üª›_9¯Vzêxsy=Vâ–˜_ gv«ýìƒýknÃÆz%ㄎý ÌŒ¿Ì ðü§­5–*ÒfÝ8­e–á”sŠ«t}!ÄS xÝ]OB§5(eÉÇ=+À´Ojz$ë-¬ŒÖýíXçõé^Íáýzß^ÓVâ#óc¸<ó1yQè{x\tk{­êlÑH4µÌw…Q@Q@Q@Q@Q@Q@Q@Q@Q@Px Š( Š( Š( øè£ø³EQEQEQEvÍ(¤°íN¡¹¢€ ;âŠ?‹4RZZkN:“#8ïKM—Ïju ÍPEPEPEPEPGðâŠ(eýãG' O§¦yc~ÿâ§ÐAâŠFé@ EPEPüY rÙ¢…†(¢€síKMPFïzuQEQEQEQE½Sýê’£—’˜þõIEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPñ¿Œš¤Ÿi²Ó#<2Ê=é^ÆkçÿŠs´ž:™¢@¡~•Ž#à=¾¤ªãc~Ìá袊á?A (¢€ (¢€&·º–Þê+¨ŽÉ#pF+êøj=¥Ò6ä•Í|´1´×Ѿ‘ŸÁzcùâµ×‡>W‰é¯g ½N®ŠŽ/3ÌçÖ¤®“ãA¹¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(®âÜú„–~²‘£ŸT'Í™N Qަ»ã^w£îÖþ(j׌»¢Ó£û$gОI­(îßbdvš>—o£iÖöQùVð.ÀrkBPXßò¨z²„س(ù:š]TdœNȤôÃ1õ¥¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÉ×u$Ó4›‹—}›Wå8'æ=x]íä·— <Óú×£|O¿xí,í#Þœ”¡…¢Š*MŠ( Š( Š( Š( Š( Š( Š( Š( †æŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(£ø³EP¼QEQEQEQEQEQEQEQE74Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@1ʽO¦¹_÷¨ÔQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE'Q^ñzÓÊñE½Ð\,öùñ:×»q^{ñ?ókº(žI–׌œ¬«¦ãdz™=u‡ÅÆMÙE9Q˜Zi5矤7ʹžÁEP0¢ŠP¥#py žd.Öʨ¸Èµô÷†lNŸá»f]­*¬= x_€´ uß@|ö·›#äaO÷M}Š#Œ(è+¯ÔøÞ%ÄÆs»Ø–Š(®£å‚Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( =k€øv jÞ-™ÇÍý¢Gà»þµçžè¿üC¦\Ÿ)5 ú×?òÐíÃŽ˜÷­iü2^Ÿ™'¡Šã¼aoâãymsá¹Õ¢D–äªóë’@®¼:ã<óíÍqÞ8ñ-Ï…N™t–ÓL»nHt™¨¦Ÿ=‡#ž¸ø£¡I%¾¹¢J%B¹AëÀ鑨צYOö›(&‰6}xïŒu˜µ¯:iåg4á4„!à‚võâ½WÃÓ¿ØÈAF0/ÅmZšŒUɉ­EW9aEPEPEPEPEPEPEPEPEPEP”üRf½šãäò‡×5ç½…zŸÅ 2ö¶·Š¹J1ô¼³}\:>71Mb§~âàÒSé•Òp EP1G4õ8¦'58R­“Ò2^ŽÇ¬|1v: ÀÇÈ'm¦»ŽõÍø*Á´ÿ @¬›dÏ­t•óx–¥VMw>ãO²Š(¬ ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Žø¢€ ( ñ@Q@Q@Q@Q@Q@Q@1ʽO¤~«õ ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¨ÙC!“r6AúT”P†øÿÀSi×rjzTO-Ë~ö÷>ãÿ­^tâA8aÔw¯¬6tdUO¨Íq"ø_£ë;嵄Ù\Ÿùhá\“¡}©ÊóéRJž+Tx#  ’ËèÀÒ)Üp3ùW?ÁÿÅ# ymeSÜ€?WO…~*ó5·”?ëªäÕ‡³Ÿcè–k…zûE÷£Œ ¤€¿1=—š¿¢øzïÄé¼NÀœ»€}zW¤é?_ƒ«]ŒƒŸôO’½+KÐìtkE·±µXã ­¡C¹å㸎ŒcjJìÏð·†m¼9¦ hK8ýû‘̇Ñc"Ï#ŠSœq]q>*­iU›©-ÇQEÉ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ â~ øvãSµ¶Õ´ýË©iæÆæ/uÍvÔŸ&ÌoƒŸJtæÔ® â<7ñÎþÇþ&¤Z] ;÷¡}xâ¤ñW‹ü0¾¹[Û«kø^3þÜÒžÀc§ãUõŸ‡1]Ý=æœþL’†Çqó‰?.••£|¶‹VþÒÖ~Ï3޲•Lþ5Ójvç¾½‰Ô‹àÿ†¥‡FŸTÔ¡.× "Œ¾ hÇ·Qø×ªÆ‹B4Mˆ¿(Ò› o¤1„E¼ š°©QÔwa¢Š* (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€2õÝ5u=6[v]ÄŒ¯Ö¼#P²–ÊôÛJ…% §üzWÑGšä|Uáס2${.qÁ®ü+‘û9lxÙ¦ Ô^Ò*ìñŒâ‚*ýæ›qgp`¸…ãvaÇçÒªÙºsô¯mJ2ÙŸ,ý×fGƒF L!œ Bçû¿‹ .…̈¢ŽH:ó]'…¼8ú¶©°- È{ñªº/‡.uÙãFâ?ãn€~uìš‹‡§­´+–ÇÌç©®V&4ãh½OW/ÁKRóZÄ‘ ¨ÀÕ%W†}pQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE(¡¹¢€ PÜÐüY¢Š(¡¹¢Š4P¼Q@Q@Q@Q@Q@Q@#õ_­-#õ_­-Q@Q@Q@把(¢Š(¢Š(¢Š;†(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (ïŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢:šO1CŸ¥ºC¨ªRêút?ë/ _«Š|z•”ßꮡ÷\WDûHw-QL+~¸ãó¥. ‘“‘íLµ®Ã¨¢Š( sEQEQEQEQEQEQEQEQEQEQEQEeßéVZ¬M Õ¸e?ÅÞ¹k߆¶SǬ¦ßõ®èîP7÷´13¥ð³’®VW”6á{Ëj}+VÇᾑn£í;®zœ íqíFßj¹bê>¤G-Â/²V¶´ŠÚ‘B¨ƒøVqšhçÏ)3²Tãd:Š(¤PQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEš(¢Š(¢Š(¢Š(¢Š(£¾( Š( Š( Š( Š( Š@A)h¢Š(¢Š(¢Š4QEQEQER?UúÒÒ?UúÐÑEQEQEQEQEQE êhÈ¥þ,ÓpiÔQEQEQEQEQEQEQEh Š( Š( “#8ïKMÁßžÔáÈÈ¢‘x\Z(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢“×Þ€Š( ¾(£ø³EQEQE™Ç~´dgÉøïÅÑøc@3Dss1ÙrÇú~4›KqJJ*ì‹Åž9Ó|-nR\ÜÝv„u5âÚ÷Ä/ë²²›Óekÿ<¬ò§ó5Íß]\ê7mswtÒ\ŸùjsÊ¡}kŽuYãÕÄ·°÷æ|É-Çý÷O¶¼žÙók-Ä#ÞLÔ)½G´fÑÖ‡ñK_ÓdÅÛ‹ËùçÐþf½ŸÃ>,²ñ>ž²ZH©2ŒI•?C_1†NÆ´t]nïDÕúÖfó˜üç·åZ«:hâåõRÈC9Èç¥MX¾×a×ôk{ØúH››¥läWRiìzÉÝ]!zÒÓXÒLaßQüY¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ( s@Q@Q@Q@Q@Q@Q@Q@Q@æ}ãJ¼QüY Š( Š( Š( sE ÅQEQEQEQEvÍ( ñBñCsEh¡x Š( ,SKAÑ@Q@ñfŠ( ƒÅÒ€Š( Š( s@æ…â…†„Á§QEFEÕ`Â~oJuRzûÐмQEQEQEQE×#+þõ:˜Àå?Þ ÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQERdgéi¸;ó@##Þ¾mø—®>³â»¡¼‹{\ÛÆ‰îÕôUÜ œÒt(ŒE|—wp÷—Ï'ß‘‹­sâ lÚŠEsÇZf)íÏJes`bŒQE=NM9HiÊ× rj:zßÁÍi’êëG23B=Ùö¯i¾løkpöÞ7²Ûü{•¾˜Í}&9We„öp“n˜ê(¢µ:‚ŠPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPBñEQMWWû§4ê(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(nh¢€ (¢€ (¢€ (¢€ (¢€ 07gÑEQEQEQEQEQEÕ~´´×#+þõ:Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(  ·cͱ,ñ²êH¯’%á•â‘vº1V„u¯¯™AR|ÛñFm#Å—Hb1ÅpÂXe?{éø×=tݬyøôì™ÇS1R' ¦"¹1 4ê( ‡Ýû´zQOŽ'`HtëI»n ì¾[›Ùasµ]ϰ ŠúAx¯ ø; È¦çV–! rG õã¨ükØ+¶‚j:žÎ5OP¢Š+S¨š(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€(^ž¹¥¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ÑBñ@Q@Q@Q@Q@wÅQ@æŠ(¢Š(¢Š4P¼Q@Q@Q@Q@Q@lÑGðâŠ( sEQEQEPx¢€ )23Žô´QEQEQESª½O¦09O÷¨ôQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE%r<ðšøŸGhR?ô¨ÿydO÷s]x˜'­L—ºg:j¤lÏ’om%±˜Ã,f9ÚU¸9ªr¹$8é_Ix·À‰ã2”^c‰W×Þ¼wXð½¤ÎØ…¤Œœ‚¸oäkŠp—cÇ­†9{ªçœRg5n[9ÐÖó:þí¿Â¦·Ò/ndV’»g SÊÌy%ØÏ·@*èü1á™üC«A hÞQ9vãÒº |,Ôu |Ûö0CêqŸË5ìÚ>c¡Ø­¦ŸÃüOçZÓ£Ï¬Žª8yOâV%Ñô»}"Á--×¢´;R(Å-v´U£`¢Š(((¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)=}éh ø³EP¼QEQEQEQEQEQEQEQEQE/QEQEQE ÍQ@ ÁßžÔê( Š( Š( Š( šä¹þõ:™($¦?½@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(5·‘òª­>Š”›M´rKZÂsþÀ¤·Ó-­y··Ž#žËW>j>j\ˆcY2=©ôQL°¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¦¹_÷©ÔÆ)þõ>Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( šäeÞ§S§ûÔú(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ k‘•ÿzL~ gûÔú(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ Ž^©þõIQËÕ?Þ  (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š( sEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE½Sýê’£—øO`Ô%Q@Q@Q@Q@Q@Q@Q@ñEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPQË÷?àU%G' ½@QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQES“ýê}2@Jqë@¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¦¹yõ§TrýÏø  (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š*9A+Ç÷…IMr6þ4ê(¢€ (¤È ¢“"–€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ øOøIQË÷?’Š( ȦÑE. :“"ŒŠZ)2(È ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(€ (¢€9éO¦¨#­:€"šÜô¥Á£€žÔ`ñïR¯Ü—Ú€"VòMOLòÅ>€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ nÌw§Q@½)h^( Š( Š( Š( ƒÅ74QEQERdRÓhôQEQEQEQEQEQEQEQERdRÐEPLnzSé¸4`îcëN¢Šn :Š(2(ȦdQ‘@QEQEQEQEñ@Q@Q@h Š( Š( Š@A)h¢ŠŽO0}ÁŸÆ€$¢Š(¢Š(¢Š(¢Š(¢Š(£øè£ø³@h Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š;âŠLŠZn 7çôýhäÖ”r2*º;;e‡:ð¸4´QE&E˜4`Ш¨Z ÿ¤klÿËC@ÑP-¶?å¡§yíµ?Ì__ÒI±ih¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¨çå?àB¤¨äå?àT%Q@=(Þ¾µ î þ4íé@ %BpéHÛ÷ð)V0ŸüY cŸõƒ9‘ACy‡ ¤ò?Ûjiš8¾ûcð4¢êÒAOx‘úŠˆYÛùc@ûU¸ÿ—ˆ¿ï±QÿiZÏCÿ|7øS¹ÿ—h?ï‘þ/•÷ò }ªùè)ZD•0ŽãLû¿üñýiÂÚû±~TP_É~òYKëwW$¸¦Ào¼ŸGʃéŠhž3üXú‚??rÿx~u®¸”yŸ†)Ÿbƒû§ó µ¾[;Í<ižGûmR¯’Ü/܃?ð!H.­8ü3Vša‰¨ÍW{ˆ¶b2IÿtÕ7¾Ôe­p>¢µ€ÜÅ,>dü(2=YÛáaëòšº·Iœï“Sé•gîþ4žbúþ•Úbþñÿ¾MK±ixþíWûu¿÷Ïýð·[ÿ|ÿßü*m‰ýÁùQ±?¸?*gÚaÿž‚—Ïûß¡¦}’ßþxŠ“ÊOJQ"‘xúS©ª€.)Ôß1}J<ÅÎ3ÏÒ—bѰnÍ'˜¾¿¥U–ø"ÿ«9úU½‹I€ßy?:¨Ú€å‰ÈÿtÕÏéN%ÆW×¥%"ùƒ¨§äRÓ@&€I‘KMÁ QQüþŸ­?§ë@È£"“Œ<Åõý)r(Ø´˜4»×Ö‚ê:šfÆô¤dcÐPÙÕzš]ʈ~u£7ßÅŽ1ÿ,üúôb:Ó>OÖœÀž”ê*IýßÖŒIýßÖ€%Þ¾´dc=©›Òƒ³èw¯÷‡çFáëPy)ÿ>çþúãFÙ»úÐû—ûÃó¥ÈÅAå'üð?˜ÿkZÿ- Y¤Þ¾µÙ¿é¡§ìoJ’“zã9â¢ó ;clÆ9  )7¯­E‰?»úÓ¶7¥?zã9â‚Àu4ͳæ£e”ô_Ö€&izšO:?ïΡ_›ïÓþÏüò ûL?óÐSüÄ?Æ¿EöKùâ)£O¶Â:²=hªÆÔ§ú‡òÿZ“Èÿm¨@A(ÈÆ{R(!0hÁÙŽôê*?ŸÓõ¦ù†€%$´´Æç¥~ý=%Gû§?…)‘@É<})a~í+ +ŠÔþtàAèA¨|ˆ¿çùüê Œÿ£Ècã4v0= A½½)ª\ugzúÒoLgrþuDXÿSúÿõèñüÑät4ú‡'Ê«òýiËæ¢€$¢£ùý?Z’€ (ïŠ(¢¡ógÿžøð§|þŸ­IEB²Ö¤ËzP¨¢Š(¤Ü=i<Åõý(Ô™´ÜU=ijƒvÁœûÓIBàŽhÍ_{zT€¹íúДT?§ëGÏéúДT?§ëQ˜çn—øíO¸zÈÒ÷ÅC¶çþz'åF$ßœqõ  ©7Ê–£2H?å‰ÿ¾…IEGóú~µyðݧ›õ PƒÀ£¥C„¦ƒQ´JWiü¨Õ&~¿•SŽÖKfÌldã𔋠¿}3ô  TBaþûå?HAúPÑE4PÃ4PE(¡TqÞF>lÓdqHí?>Š@Aý)h¢zRÐEÓ"ާô Q@ Žh Š( Š( Š( Š( Š( Š( Š( Š( £~þRTrýÏÆ€$¢Š(¢Š(þ,ÑE&E´ÃÇZvEdShïŽôú(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (£¾(¢“"–€ (¢€ (¤È ¢Š(¢zRÐEPƒ¸ôÆ)†TPäžïqÒ¥Æåà ŠH·)}ï½@ ÞÞ•*J‡8=:S¶-28ÂîÈês@QEQEQEQEQE‘‘@7EQEwÅh¢Š(¢Š(¢Š(¢Š(6--PEPEPlZZ( Š( Š( Š( “bÒÑ@ Á¥^–Š)¸4ê(^(¢Š(¢Šš(¢€ (¢€ (¢€ ‡b{Ó¨¢€ (¢€ (¢€ (¢€ (¢€ 0(¢€ (¢€ (¢€ (¢€ (™7úº}Q@™dP‘M¢—€¹éE. 4`Ò{Sé¸4ê(¢€ (¢€ (¢€ 4P¼PEPEPEPGñfŠ(¸4ê( sE"ñÅ-ÜuQEÕu§QEŠ¥ùÆ;ô©Ûšg–7)ô ÑEQEQEQEQEQER/ ƒKEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE ÍQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñEÅš(¢Š(¢Š(¢Š(¢Š)²‚SŠu#ýÊZ(¢€EPN”˜4(#­:Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ø³EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPE™Ö€Š( Š( Š( Š( Š( Š( Š( Š( ƒÀÉ¢‘¹\ Z(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ I>ᥤ»@ EP)pi)ôQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQESpw)ô§Q@Q@Ù |»yæ@( ò(ÑBñEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE÷ii€œÐÑEÜuPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPx¢†æŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š=}¨¤[Þ–€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (ïŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¦Mþ®ŸL—ýYö ÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠPÜÑ@Q@Q@Q@Q@Q@Q@Q@Q@2_õOO¦Mþ¥èôP9¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ dßê_éO¦Mþ¡ÿÝ /JZEéK@&E-7€EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPL”~åÇû4úI?Õ·Ò€éKH½)h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¦È@‰éŠu2oõþí9zRÒ/JZ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)’‚ap:í§Ò?Üo¥ ÷ii¥-QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE’«o¥-#ýÆúP½)i¥-&áœgšZ03š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¹mÝ8§QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQG|PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPI'ú¶úRÒ?Üo¥ Ò–…âŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(þ,ÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEñEÅš(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¤¸ßJZGûô ¢Š(¢“"ŒŠ2)i¸4ê(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(£8 zÑ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@#ýÆúRÒ?Üo¥-Q@ Á¤§ÓphÔQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE!e>”´Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@HQ“Ò–› ,˜i¤¸íúДP9PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPHÿq¾”´÷é@ EPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPCsE‹ÂàÒÑEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE÷ -#ýÚZ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ( ñ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@#ýÚZGû´´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE74Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@#ýÃKHÿpÐÑ@æŠ(¤È¥ Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ‘þí-#ýÚUâŠ( Sé”ìŠZ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ PÜÐEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPHÿv–‘þá ÑH½3ëK@‚ÈéKL^œ##¥H9¢‘H´QEQEwÅh Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( _j)V÷ ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¤¸iiîПpRÒ'Ý¥ h^—“¶{U슒¡©C©èj@Z(Ñ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@#ýÚZGû´'Ý¥ïŠDû‚—ø³@ Á¦`ìÇz–™@ ¡xëJAi;ã½PFêÚuC÷>íJ=*@Z(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ PÜÐEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPHÿv–‘þí ÷–‘>ॠ›ƒN¢€Àž”Ì2¥¦àïÏjf (!zÒž:ÓXÒ€$çKQÆAééŠs@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñEÅš(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)îÒÒ7+@}ÁKHŸpRÐEPEPXÒ’ŸMÁ 0+÷)êÀw¤¦z}(aÍŠF3K@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@“E#r¸'Ý´‰÷éK@Q@Q@Q@ Á¦(#¯÷³RÓphʘ=iÀƒÒšÜô¤/_\P”P9¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ ( ð2hî--"}Å¥ Š( Š( Š( Š( àÓÓûÙ©i”ªÃÖP—­J=(h sEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE÷–‘þá >âÒÒ'ÜZZ(¢Š(¢Š(¢Š(¢Š)¸4ê(&ô¥RÁëNÁ¨ÿ=¨U"–£RZx ô ¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(ïŠ(þ,Ñ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@#r¸´P'ÜZZDû‹K@Q@Q@Q@Q@Q@EƒRÓph˜4ª@ëKÛ=©‡Žµ@MEÍ QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQßPEPEPEPEPEPEPEPEPEPEPEP'ÜZZDû‹K@Q@Q@Q@Q@Q@Q@ ÁÙŽôÇ¥¦°'¥B®ÀàÔáÕ†Aâ¡ØÛóŽ)cùS®qTÔRJZ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€âÍQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Ÿqiiî--Q@æ€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€xëQäãÕ+zTEuóTÔÖž##¥DxÎ{S˜ïR”QEQEQEQEQEQEQEwÅh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(î ZDû‚–€ j°äÓª,Ê}(Z(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ kzS¨ ˜»é¨EJA ‚:Õ8u= -@„g=HQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ŸpRÒ'Ü´SpiÔPEPEPEPEPEPEPEPÜÔ{Ò¤¢€+¨!òj`@¦GZ\Цƒ‘‘E"·µ QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE"}Å¥¤O¸´´QEQEQEQEQEQEQEQEQEÖô¦`Ô´ÜjOJ“9¨°vc½43¯Qß4=Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Š(nh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(#ÿV´´ØÈ1©ê(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šn 1ÁÆ{T´Æå0(¨íýjQÍB¼¸ÅH¬zuh Š( Š( Š( Š( Š( ƒÅ74QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÈÕ%>™"5ö§ÐEPEPEPEPEPEPEPEPEPEPMÁ§Q@Cäô¤Ô´Ïï{Óè^( sEÒ–†æ€æ/¯éM$1ÀëOصœ1+Û­*ýjLŠbFGLb€AÎ;P7>ü㊛zàœô¨‡##¥(«Þ€%Š5—  ŽGZ•x Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ˜xëO¦°'¥.E-2œ=(h¢Š(¢Š(¢Š(¢Š(¢Í³EÊ(¢Š(¢Š( rÙ¢…†(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€¹\ Z( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(ïŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š)‘KGð†(¢€pÆsÅ/ð⌠bŠŠ(¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ø£¾(þ,ÑüY Š( Š( šÀ–Í:Š)¥- ÅQEQEQEQE"÷úÒÒ/­-DÀ”À¥RZ^àzÓå4ñÈÈéNȦ¯ ƒE=x¢Š(ÑH¤RÐQ:Ÿ›Žµ- ÍE*˜=hPA`zšqã­ ¾GJEF ‚)êë@‘OCúRäP`Ó‡#"ŠEáphh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Šaã­":ÐÌCLÈ  è¤.£©¥ÐEPEPEPBñEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQüY¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠEïõ¥¦©ýiÔÏâSéLO>jyà⚀ì RZZkzP€ƒÒ–š Ž´êbSé‰O Š;âŠcÓTÖžàÒP»3ÖÏJb}üÓ׎´ú)23Žô´QEQEQEQEQEQEQEQEQEQEQEQEŠ(¢Š(¢Š(¢Š(¢Š(¢ŠM‹FÅ¥¢€"pjE R0'¥%>Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( ¶h£øqEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQ@æ€ø¢âÍQEQEš;âŠ?‹4PEPEPEPEPEPEPEPEPEPE&FqÞ–€ (¢€ÅÒ–€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€½ýšŸL_â÷j}1¹9íBð˜4;ÒàÐQAã­. :ŠLŠZbS²)©Kƒ@þ,ÑE74Ê}3¾;ÐŽ´ñÏJn =Ah?å¥>›ƒ¿=©ÔQEQEQEQEQEQEQEQEQEQEQEPÜÑEQEQEQEQEQEQEÊ}7€E™´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE/Q@Q@Q@ ÅPEPEPEPEPEPEPEPEPEPEPpwçµ:Š(¢Š(nh¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(< š)îd0È麤¨­È1ñëRÐpiÔ™dqï@ nzS²)´PO´æÀДQE7~{S¨¢€ˆS¨¨òøÎ?Z’Š4PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEš(¢Š(¢Š(¢Š(¬ L c)A•-#r¸.ì÷éSTX4)}Ç#Ö€%¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(^(¢Š(¢Š(¢Š&ŠFåp)h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ÈÈ¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€,ÿïSê8º¿ûÕ%2Š( Š( @iÔŠE-QEÅšn :Šgð¨ô§Ópiw ÛsÍ-Q@Q@ÊLŠSÅ ÅQ@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@ñEPEPEPEPEPphÁù½éÔP@把(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠEápih¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€#‹«ÿ½RTqu÷ªJe¤I@¸4`Ð/iôÊ}QI‘@ x¤È¡ˆ¦Éé@ȦÿµüT¸9Å4OJ“¶h£øhÐEPpiXƒJx¦E:ŠLŠ23Žô´QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQHHhÈ¥¦í4ê(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ƒÅQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEGóýê’˜½_ýê}#ŒÓO¬ L Få³@¢Š(¸4ê(ïŠLŠm‘‘Ò°M+ÓX˜æç8íAã­G¹÷çRà¼`¯9æƒÇZ¼Å•B.3š“Ì>QnÂ¥R*¹à:Ÿ¹R¡Ïn´%Q@sP7˜z ž˜xë@ ‘J9mÃ¥0rH©ÈFÂ=(äÖ¢óyÇzszQ±wf€‘KMÁ§PI‘KMÁ È¥¦S袊(€ j‚:Òäc=¨È ¢Š(¤$´´Öô ížÔ¸]Ù£f;у@A*;Ó袀 ˆ½jZkzPg“Òš˜dt§²1LMSs@ ü[»TªEGƒ°朼u Ñ@ädQ@ éQ*0ê*Å7€#ïŽô/'¥;coÎ8£clÆ9ª¸ u¥ô¦²1è)êëRƒœP Ž´ïâÍQEQEQEQEQE„Ö–šÀž”ê(¢Š(¢Š(¢Š(¢Š(¢ŠLŠZn :€Å74PEPEPEPEPEPÈúÓ»íB© ƒéŠ\Fç¥&ÅÛŠv 4Ò@ëOR*6F=9xë@ÑBñEQE Í7EQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQE1:¿ûÔúb}÷ÿzŸ@ þ w¥Á£—"€Š( Š( Š( Š( Š( ˜xëO¦=§Óš\H\ÛêEá@=ºÒÒzûÒÐEPE™´RdRÐEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPMÁ§Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@R$ô´R+S‘K@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@™ÇzZ(¢Š(¢Š(¢Žø Š( Š4PEPEPEPEPEPEPEPEPEPEŠ(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Íš(¢Š(¢ÍQEQEQEQE1>ûÿ½O¦'ß÷©ô™Ú( ÑI‘K@Q@Q@Q@Q@5=)ÔP{ŸÒ¤¦:Ó²(h¤È¥ÐEPMÁ§Q@ Á§QEP9PEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPEPUçi ÄqÆ2ßúUŠL îïŒP€` (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ (¢€ƒ¾GñfŠ(¢Š(¢Š(þ,ÑEQE"ô¥¡x¢€ (¢€ 4P¼PEPEPGlÑGð†(¢€Å74PEPEPÜÑßQüY Š( Í/QEQEQEvÍ( Š( Žø¢âÍvÍ(íš(nh¢Š(¢Š(¢Š(¢Š( sE Å"ô¥^(^( Š( …âŠ(ÑBñEQEQE(¤n”Ôûïþõ>˜Ÿ}ÿÞ§Ð(¢ÏJ=)ôÅã­>€ (¢€ (¢€ (¢€ (¢€ (¢€Àž””ún 'lö§)Í&Ìw¤O¹Žô¦Eþ”êiEcšuQEQE"ð¸4´Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@Q@vÍQEQEQEQG|Q@Q@Q@Q@Q@Q@Q@P9 Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š( Š(ïŠ(¢ŽÙ Š)23Žô´QEQEQEQEQEQEQEQEQEQEQE74Q@ O¾ÿïSé‰÷ßýê}2…ã­PàÓ¨Ñ@Q@Q@Q@Q@Q@Q@1x=)ýñMÁÙŽô«Ò”ñBñHÝ(h¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÏJ);ÑÍ-QEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEQEÁEÊ(¢Š(¢Š(¢Š(þ,ÑEQEQEQEvÍ( Š( sE Å(^(nh Š( Š( Š( ŽÙ¢áÅQEQEQIëï@ EPEPEPEPEPEPx4#r¸¿Åš) Í-#r¸´Üô¾žÔ¿Åš(¢Š( no cropping should happen # automatically self.assertEqual(self.pillowed, []) def test_transaction_with_paper_sizes_2(self): self.core.call_all( "config_put", "scanner_calibration", None ) self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ], "page_boxes": [ [], [], ], }, ] promises = [] self.core.call_all("sync", promises) for promise in promises: promise.schedule() self.core.call_success( "mainloop_schedule", self.core.call_all, "mainloop_quit_graceful" ) self.core.call_one("mainloop") self.assertEqual(self.pillowed, []) self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ("file:///paper.2.jpeg", self.test_img), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ("file:///paper.2.jpeg", 2), ], "page_boxes": [ [], [], ], }, ] self.assertEqual(self.pillowed, []) transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertNotEqual(transactions, []) for t in transactions: t.upd_doc('some_doc_with_text') for t in transactions: t.commit() # No calibration defined in the config --> no cropping self.assertEqual(self.pillowed, []) paperwork-2.2.2/paperwork-backend/tests/guesswork/cropping/tests_libpillowfight.py000066400000000000000000000144441456262201400307660ustar00rootroot00000000000000import os import shutil import tempfile import unittest import PIL import PIL.Image import openpaperwork_core class TestBorder(unittest.TestCase): def setUp(self): self.tmp_paperwork_dir = tempfile.mkdtemp( prefix="paperwork_backend_tests" ) self.test_img = PIL.Image.open( "{}/test_img.jpeg".format( os.path.dirname(os.path.abspath(__file__)) ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.doctracker") self.core.load("paperwork_backend.pagetracker") self.core.load("paperwork_backend.guesswork.cropping.libpillowfight") self.core.get_by_name( "paperwork_backend.pagetracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.core.get_by_name( "paperwork_backend.doctracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.pillowed = [] class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000000000 def pillow_to_url(s, img, url): self.pillowed.append((url, img.size)) return url self.core._load_module("fake_module", FakeModule()) self.core.init() self.model = self.core.get_by_name("paperwork_backend.model.fake") def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_paperwork_dir) def test_transaction(self): self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ], }, ] promises = [] self.core.call_all("sync", promises) for promise in promises: promise.schedule() self.core.call_success( "mainloop_schedule", self.core.call_all, "mainloop_quit_graceful" ) self.core.call_one("mainloop") self.assertEqual(self.pillowed, []) self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ("file:///paper.2.jpeg", self.test_img), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ("file:///paper.2.jpeg", 2), ], }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) transactions.sort(key=lambda transaction: -transaction.priority) self.assertNotEqual(transactions, []) for t in transactions: t.upd_doc('some_doc_with_text') for t in transactions: t.commit() self.assertEqual(len(self.pillowed), 1) self.assertEqual(self.pillowed[0][0], "file:///paper.2.jpeg") # algorithm may make the results vary if it changes later, but we can # still check that it actually cropped something self.assertNotEqual(self.test_img.size, self.pillowed[0][1]) def test_transaction_with_paper_sizes(self): self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ], "page_paper_sizes": [ ("file:///paper.0.jpeg", (256, 256)), ("file:///paper.1.jpeg", (256, 256)), ] }, ] promises = [] self.core.call_all("sync", promises) for promise in promises: promise.schedule() self.core.call_success( "mainloop_schedule", self.core.call_all, "mainloop_quit_graceful" ) self.core.call_one("mainloop") self.assertEqual(self.pillowed, []) self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", None), ("file:///paper.1.jpeg", None), ("file:///paper.2.jpeg", self.test_img), ], "page_hashes": [ ("file:///paper.0.jpeg", 0), ("file:///paper.1.jpeg", 1), ("file:///paper.2.jpeg", 2), ], "page_paper_sizes": [ ("file:///paper.0.jpeg", (256, 256)), ("file:///paper.1.jpeg", (256, 256)), ("file:///paper.2.jpeg", (256, 256)), ] }, ] self.assertEqual(self.pillowed, []) transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertNotEqual(transactions, []) for t in transactions: t.upd_doc('some_doc_with_text') for t in transactions: t.commit() # those pages have paper size defined --> no cropping should happen # automatically self.assertEqual(self.pillowed, []) paperwork-2.2.2/paperwork-backend/tests/guesswork/label/000077500000000000000000000000001456262201400234025ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/label/__init__.py000066400000000000000000000000001456262201400255010ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/label/tests_sklearn.py000066400000000000000000000477411456262201400266520ustar00rootroot00000000000000import shutil import tempfile import unittest import openpaperwork_core import openpaperwork_core.fs class TestLabelGuesser(unittest.TestCase): def setUp(self): self.tmp_bayes_dir = tempfile.mkdtemp( prefix="paperwork_backend_labels" ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.doctracker") self.core.load("paperwork_backend.guesswork.label.sklearn") self.core.get_by_name( "paperwork_backend.doctracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_bayes_dir ) self.core.get_by_name( "paperwork_backend.guesswork.label.sklearn" ).bayes_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_bayes_dir ) self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = -9999999 def fs_exists(s, url): for doc in self.fake_storage.docs: if doc['url'] == url: return True return None self.core._load_module("fake_module", FakeModule()) self.core.init() self.core.call_all("reload_label_guessers") self.core.call_all("config_put", "label_guessing_min_features", 1) def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_bayes_dir) def test_training(self): # ## First training self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch sklearn\nbest', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': 'something else', 'labels': set(), }, { 'id': 'some_other_old_doc', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'something something niet', 'labels': set(), }, ] # make a transaction to indicate that those documents are now in # the storage --> it will update the training of bayesian filters. transactions = [] self.core.call_all("doc_transaction_start", transactions) transactions.sort(key=lambda transaction: -transaction.priority) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") # XXX(Jflesch): use upd_doc() so it doesn't try to guess labels for transaction in transactions: transaction.upd_doc("test_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("test_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("test_doc_3") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("some_other_old_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.fake_storage.docs[2]['labels']), 0) self.assertEqual(len(self.fake_storage.docs[3]['labels']), 0) # ## New docs self.fake_storage.docs = [ { # old doc 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch sklearn\nbest', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': 'something else', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc', 'url': 'file:///somewhere/new_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\ncamiön', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc_2', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'else something', 'labels': set(), }, { 'id': 'some_other_old_doc', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'something something niet', 'labels': set(), }, ] # make a transaction to make the plugin label_guesser add labels # on them. transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.add_doc("new_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.add_doc("new_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.fake_storage.docs[4]['labels']), 0) self.assertEqual(len(self.fake_storage.docs[3]['labels']), 1) self.assertEqual( list(self.fake_storage.docs[3]['labels'])[0], ("some_label", "#123412341234") ) # ## Upd docs self.fake_storage.docs = [ { # old doc 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch sklearn\nbest', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': 'something else', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc', 'url': 'file:///somewhere/new_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\ncamiön', 'labels': {("some_label", "#123412341234")}, }, { # new doc on which we will guess the labels 'id': 'new_doc_2', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'camion camion camion', # accents shouldn't matter 'labels': set(), }, { 'id': 'some_other_old_doc', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'something something niet', 'labels': set(), }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("new_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.fake_storage.docs[4]['labels']), 0) self.assertEqual(len(self.fake_storage.docs[3]['labels']), 1) self.assertEqual( list(self.fake_storage.docs[3]['labels'])[0], ("some_label", "#123412341234") ) # ### del docs self.fake_storage.docs = [ { # old doc 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch sklearn\nbest', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': 'something else', 'labels': set(), }, { 'id': 'some_other_old_doc', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'something something niet', 'labels': set(), }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.del_doc("new_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.del_doc("new_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") def test_sync(self): self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch sklearn\nbest', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': 'something else', 'labels': set(), }, ] promises = [] self.core.call_all('sync', promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.fake_storage.docs = [ { # old doc 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\nthe best', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': 'Flesch sklearn\nbest', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': 'something else', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc', 'url': 'file:///somewhere/new_doc', 'mtime': 123, 'text': 'sklearn and Flesch are\ncamiön', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc_2', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': 'something something something', 'labels': set(), } ] # make a transaction to make the plugin label_guesser add labels # on them. transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.add_doc("new_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.add_doc("new_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.fake_storage.docs[4]['labels']), 0) self.assertEqual(len(self.fake_storage.docs[3]['labels']), 1) self.assertEqual( list(self.fake_storage.docs[3]['labels'])[0], ("some_label", "#123412341234") ) def test_training_no_text_at_all(self): # ## First training self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': '', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': '', 'labels': {("some_label", "#123412341234")}, }, { 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': '', 'labels': set(), }, { 'id': 'some_other_old_doc', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': '', 'labels': set(), }, ] # make a transaction to indicate that those documents are now in # the storage --> it will update the training of bayesian filters. transactions = [] self.core.call_all("doc_transaction_start", transactions) transactions.sort(key=lambda transaction: -transaction.priority) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") # XXX(Jflesch): use upd_doc() so it doesn't try to guess labels for transaction in transactions: transaction.upd_doc("test_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("test_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("test_doc_3") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.upd_doc("some_other_old_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(len(self.fake_storage.docs[2]['labels']), 0) self.assertEqual(len(self.fake_storage.docs[3]['labels']), 0) # ## New docs self.fake_storage.docs = [ { # old doc 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': '', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'mtime': 123, 'text': '', 'labels': {("some_label", "#123412341234")}, }, { # old doc 'id': 'test_doc_3', 'url': 'file:///somewhere/test_doc_3', 'mtime': 123, 'text': '', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc', 'url': 'file:///somewhere/new_doc', 'mtime': 123, 'text': '', 'labels': set(), }, { # new doc on which we will guess the labels 'id': 'new_doc_2', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': '', 'labels': set(), }, { 'id': 'some_other_old_doc', 'url': 'file:///somewhere/new_doc_2', 'mtime': 123, 'text': '', 'labels': set(), }, ] # make a transaction to make the plugin label_guesser add labels # on them. transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertGreater(len(transactions), 0) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.add_doc("new_doc") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.add_doc("new_doc_2") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") for transaction in transactions: transaction.commit() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") # guessed labels don't actually matter, it must just not crash paperwork-2.2.2/paperwork-backend/tests/guesswork/ocr/000077500000000000000000000000001456262201400231065ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/ocr/__init__.py000066400000000000000000000000001456262201400252050ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/ocr/test_img.png000066400000000000000000000107061456262201400254330ustar00rootroot00000000000000‰PNG  IHDRÈdÆ bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEã Šv°­tEXtCommentCreated with GIMPW.IDATxÚí{LSgÇ¿U£»ˆó‚,ËØE§Î`Vo+ÃédØéTQ§Sücj†:¶™ÇܘºH¼y™™&ÌBp@ âP§"rS¬N[ÑV Š”~ïïÛ¾@O¡=¥Pô÷Išè9çyžßóœómŸ Ï÷HˆˆÀ0Œ ½¸ †Â0,†a0 „aX Ãað@†Â0 „aˆ^¯‡D"õÑét€°°0H$TWWÛÔ矉DFã´ŠwEÎ`åÊ•H$¨¨¨àXø„a\P ýúõY|êêêÌ×TUU ^ãææÆ­Êð/ˆ3‰ÁÓÓ³G—Áô|útE! …éééP©TÀ¼yóàëë ‰D"8>غu+Ôju«X¯×ãäÉ“ÈÈÈ@^^@&“aܸqðóóÃðáÃíƒ8»ŒG¡¨¨§OŸFqq1òòòðÊ+¯`Ú´ix÷ÝwñÆoØœWAAÆoþÿ‹/¾Øêü‰'0uêÔVÇŠ‹‹¡T*‘ÒÒRL˜0AAAÆóÏ?/8ö´¥îbbé±ÔÕÕ@UUUí^J(%%…<<<ÌéZ~8 ˜ö³Ï>#¤V«ÍÇôz=EDDæcúüûï¿6×¥+ÊøñÇÛÍë÷ß·9¯‹/¶›×‰'Ì× Úµk—Õk‡N………­ò·§îöÄÒÓqº@PLL ©ÕjÒëõT[[K …Â|®²²Ò¦‡7''‡ÐÂ… ©¬¬ŒêëëÉh4’V«¥’’Ú¾}»`^ö¤³Ë8x𠥤¤F£!NGƒ´Z-eee‘T*%tõêU»nØŠ+ݾ}Ûê5‡2×ãܹsT[[Kƒª««é?þ $•JI«Õ:Tw[bat ¨¨(jnn¶8M(''Ǧ‡7!!ÐÙ³g;¥â]QF{œ>}šÐž={:U Z­–<<<ÈÏϯ•„”œœìPÝŸ8}nZi‹L&3φÙÂ!C7oÞtZ¬]Q† ///0÷õ;‹ÂÂBTVVbÉ’%4hà5>>>€3gÎtKÝy«C‡<þÜsÏlÊÇÛÛR©¡¡¡X·n”J%nܸƒÁÐi±:£Œ’’ìÚµ }ôÆŽk^P8p àÒ¥KÚÞ7nÜ„‡‡[]Ì}ùå—[]ÛUí˃t.–µëòòò%$$ØÔý!"R«Õ´qãF‹çŽ;H£Ñ8ÜÅêì2~ýõ×v³¦Ogv±vìØaS™hÖ¬YÕ»X.†§§'¢¢¢ ÓéP\\ …B¹\Ž5kÖÀÇÇjµÚeÊ(//Gxx8<==‘••…ªª*èõz477ƒˆP__ï”6zæ™giii‚ ¹-?Gíòöå.VпxyyaöìÙˆ‹‹Cbb"4Å ïÎ2JJJ[·n…¿¿?ÜÝÝÑ·o_óxìþýû¢âϵĴVqîÜ9§×½£XX .Â믿îô¦½e˜úîO=õ”ày±b6ý)µ±›T*…››¾ùæ:µîÅÂéBâããqäÈ\¿~555hjjBCCT*vîÜ v­L;»ŒaÆ6n܈‚‚|hqÞÝÝ?ÿü3`Á‚ÈÈÈÀ½{÷ÐÔÔ½^êêjaïÞ½øû↑{G±ð ½ é[¶liwÀ¹hÑ"ª­­uhÞ™e Z»v­Õ¼Ž=*j^VVÖáêµÑh¤}ûöu8HÏËËs¨î¶ÄÒÓéÓS„¼jÕ*øûû#??EEEÈÏχ››¦L™‚iÓ¦Á××O?ý´Ë”ѧO|÷Ýw˜4i’’’——‡1cÆÀßßr¹Ü<Õ*¦»SPP€#GŽ ;;¹¹¹×ôîÝË–-ÃÔ©S‘“'OâÂ… 6l¼¼¼ •J!“ÉðÚk¯9Tw[bééHؼšaóA:ð@†Â0,†a0 „aX Ãa†Â0,†é:ôT[ÆqºÓ{W¡P@"‘ ##ƒA†»X ó8 „=l™'™÷ƒXó° ÃáÇQUUN‡ääddff¢®®Ó§OÇ‚ 0zôhÿõ¾JIIÁŸþ‰¢¢"aáÂ…xóÍ7-ÊsÄÏöáÇHKKCrr2 àíí ¹\Žàà`(•JÌ™3ééé˜1c†`z{½lm¡¤¤ÙÙÙæ<}||0qâDbĈ­öu·lÓ 55YYYÈËËCRRÞ~ûmQqÚÛ¦]á õõõ8~ü8’““qáÂx{{ã½÷ÞCpp°ë(D¬=ŽiÇ`RR’Õ]h¤R©H&“ ž?uêT§ùÙjµZš?¾`šùóçÓÞ½{ ¥§§ îþ³×ËÖ–…Õ¥­]N{mzêÔ)ÑqÚÛ¦Îö&"ª©©¡Å‹‹º_.e=Ú‘@P\\ݹs‡©ººšbcc Í;—‚ƒƒé믿¦›7o’^¯§ššÚ¿? É“'“^¯ï?[“•é’%KèÊ•+d0¨¡¡.\¸@þþþæX…\Œ—mG˜¬À¦‰ÈÈHܽ{W°»·oß>H[ÄúÙ¾ôÒKˆŽŽ†N§ÃºuëP^^£Ñ½^K—.áÓO?m·¯+ÆË¶£‰‹Ý»w>øàdee¡¦¦ÍÍÍÐét(//ÇîÝ»qçλ&CÄÄéˆG°³|€===±iÓ&ÀÚµkqåÊóý:þ<>ùä×y(]±æ½»iÓ&@eeeí.¤åæævŠŸ­V«5¯­@`eö§Ÿ~"¤T*-ÒŠñ²µe%=..NÔJºµ6§#mê,`"¢û÷ïÓÂ… ]~%Ý¥¼yñ³4h~ùå„„„ )) ………ÉdËå˜9s&’““@Ð[WŒ—­-u‰ˆˆ€ŸŸŸùo”T*&OžŒñãÇ# @p  =ÄÄéH›:ËØ4ƒµwï^Ì™3Çü·s2™ 3g΄\.‡R©t‰gò‰ñæýâ‹/‹òòrŒ1 Ãù×®]ÃÈ‘#!•JqæÌ«V†qéAº#ܽ{ñññP©TÐétæñéÓ§±téRó,‹ƒ±«Ûÿ¸T¤¹¹¹ÝÕâõë×ãý÷ßç;Î<™],"BII Nœ8ÂÂBäççÃÝÝï¼óàããÓ៽0Ì;Hg˜'z Â0,†a0 „aX óØ $,, ‰Äe6°ÄÄÄXÝÞiú,^¼¸Ušžè/ìjíÎaÆ‚»r–––æZ| ÿ‚0 ÿ‚´ƒJ¥‚B¡€R©Duu5ba©SWW‡‘#GbàÀ¸xñ¢ys[rssáëë‹mÛ¶µ»ëÏÙØë+«×ëqòäIddd˜ý¤d2Æ???ó^í¶ØãÓÛF…Bôôt¨T*`Þ¼yðõõípß8ã ¶ºý%&&ZÝ-vðàA‹tÛ·o·Ø1Ø–Õ«WÛí>¸eË@iii6§±¶+RŒ¯¬^¯§ˆˆˆvwϵuwtħ7%%…<<<Ó8p€˜n¶méûí·ßÒíÛ·Éh4R]]¥¦¦šÏµ}JKK ­^½Z0_“ýäܹs[ùÏv¥@ÄøÊæää˜Ó”••Q}}=FÒjµTRRBÛ·o§ÊÊÊNõ鉉!µZMz½žjkkI¡P˜Ïµ-‹é&Ì;×ÂhºåCÙêxSS“y¸F£±HwàÀ@ÇŽ³+`“@Úû´ÝÓ-$±¾²¦‡ýìÙ³]âÓEÍÍÍVͺsrrø)voÞˆˆôíÛ×âxPP€ÿú¬¶tÚëÕ«—yF۽̃ÁìúazçEW#ÖWvÈ!€›7oÚ\Ž#>½¦õ¶Èd2´9bºaËÚæþ`Ö¬Y,Ýð&Mš777ìÚµËìÏ—/_Fnn.6oÞlÕÔ–i^k.~¶ØVŠõ•õöö†T*Ehh(Ö­[¥R‰7n´ª_Kõé:t¨àq“ͪ5Ï*¦‹b²ÓÂ䟤×ë-nbtt4rssqùòeóñÔÔT€\.ï¶Š‹õ•vìaGîÑ£G#$$6lÀ½{÷ð×_–/_Þ­[`;Ó·ÿþðòòÂìÙ³‡ÄÄDh4šV‚r†O/ã‚i;Ž0azÑ{dd$ `Y@¯^æ—¡äææbÿþý€)S¦tkÅáÉkzßE˼3|zHbb"¶lÙ‚ŠŠ 455A§Óáøñã ³µŽ¦ÁúòåËqøða¬_¿^ô[c; ±¾²ñññ8rä®_¿Žšš455¡¡¡*• ;wî€Vou†O/Ó…tÆJúo¿ýÖá|ò?ü`¾ÞÖ5g/Šñ•íhfÑ¢ET[[ëtŸÞ¼¼<@ ¼Xá Þ¼¾¾¾(//GRR233qïÞ=!$$'Nì0ýŒ3°víZøøø@*•ºÄ—ƒ_ÙU«VÁßßùùù(**B~~>ÜÜÜ0eÊL›6 ¾¾¾þ¿Îðéeº†.³ýÉÌÌÄŒ3€?ü[žy¼Æ Ž`4Íýý©S§r«3=§Ï³644àØ±c8tè¾üòKóëÒæ‰îbUVVZÌT]»vÍ®wl0ÌcßÅ5j"##qùòeÿ ÿ Ãa†Â0,†a0 „aX ÃaÃôhþ›…ý dARIEND®B`‚paperwork-2.2.2/paperwork-backend/tests/guesswork/ocr/tests_pyocr.py000066400000000000000000000161341456262201400260430ustar00rootroot00000000000000import os import shutil import tempfile import unittest import PIL import PIL.Image import openpaperwork_core import openpaperwork_core.fs class TestPyocr(unittest.TestCase): def setUp(self): self.tmp_paperwork_dir = tempfile.mkdtemp( prefix="paperwork_backend_tests" ) self.test_img = PIL.Image.open( os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_img.png" ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999999 def data_dir_handler_get_individual_data_dir(s): return openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.core._load_module("fake_module", FakeModule) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.doctracker") self.core.load("paperwork_backend.pagetracker") self.core.load("paperwork_backend.guesswork.ocr.pyocr") self.core.init() self.model = self.core.get_by_name("paperwork_backend.model.fake") self.core.call_all("config_put", "ocr_langs", ["eng"]) def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_paperwork_dir) def test_ocr(self): self.model.docs = [ { "id": 'some_id', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_boxes": [], "page_imgs": [ ("file:///some_image.png", self.test_img) ], "page_hashes": [ ("file:///some_image.png", 0), ] }, ] self.core.call_all( "ocr_page_by_url", "file:///some_work_dir/some_doc_id", page_idx=0 ) self.assertNotEqual(len(self.model.docs[0]['page_boxes']), 0) self.assertEqual( self.model.docs[0]['text'], "This is a test\n" "image created\n" "by Flesch\n" ) def test_transaction(self): self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_boxes": [ # Should be list of LineBoxes, but meh. "putsomething", "here" ], "page_imgs": [ ("file:///paper.0.png", None), ("file:///paper.1.png", None), ], "page_hashes": [ ("file:///paper.0.png", 0), ("file:///paper.1.png", 1), ], }, { "id": 'some_doc', "url": 'file:///some_work_dir/some_2', "mtime": 12345, "labels": [], "page_boxes": [], "page_imgs": [ ("file:///some_image.png", self.test_img) ], "page_hashes": [ ("file:///some_image.png", 3), ], }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) transactions.sort(key=lambda transaction: -transaction.priority) self.assertNotEqual(transactions, []) for t in transactions: t.add_doc('some_doc_with_text') for t in transactions: t.add_doc('some_doc') for t in transactions: t.commit() # first doc already had boxes --> no boxes or text added self.assertNotIn('text', self.model.docs[0]) self.assertEqual(self.model.docs[0]['page_boxes'], [ "putsomething", "here" # unchanged ]) # but OCR should be run on the other doc self.assertNotEqual(len(self.model.docs[1]['page_boxes']), 0) self.assertEqual( self.model.docs[1]['text'], "This is a test\n" "image created\n" "by Flesch\n" ) def test_tricky(self): self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_boxes": [ # Should be list of LineBoxes, but meh. "putsomething", "here" ], "page_imgs": [ ("file:///paper.0.png", self.test_img), ("file:///paper.1.png", self.test_img), ], "page_hashes": [ ("file:///paper.0.png", 0), ("file:///paper.1.png", 1), ], }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertNotEqual(transactions, []) for t in transactions: t.add_doc('some_doc_with_text') for t in transactions: t.commit() # first doc already had boxes --> no boxes or text added self.assertNotIn('text', self.model.docs[0]) self.assertEqual(self.model.docs[0]['page_boxes'], [ "putsomething", "here" # unchanged ]) self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12346, "labels": [], "page_boxes": [], "page_imgs": [ ("file:///paper.0.png", self.test_img), # new page ("file:///paper.1.png", self.test_img), ("file:///paper.2.png", self.test_img), # modified ], "page_hashes": [ ("file:///paper.0.png", 0xDEADBEEF), # new page ("file:///paper.1.png", 0), ("file:///paper.2.png", 0xBEEFDEAD), # modified ], }, ] transactions = [] self.core.call_all("doc_transaction_start", transactions) self.assertNotEqual(transactions, []) for t in transactions: t.upd_doc('some_doc_with_text') for t in transactions: t.commit() self.assertNotEqual(len(self.model.docs[0]['page_boxes']), 0) self.assertEqual( self.model.docs[0]['text'], "This is a test\n" # new page "image created\n" # new page "by Flesch\n" # new page "\n\n" # unchanged page --> no OCR "\n\n" "This is a test\n" # modified page "image created\n" # modified page "by Flesch\n" # modified page ) paperwork-2.2.2/paperwork-backend/tests/guesswork/orientation/000077500000000000000000000000001456262201400246565ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/orientation/__init__.py000066400000000000000000000000001456262201400267550ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/guesswork/orientation/test_img.png000066400000000000000000000710021456262201400271770ustar00rootroot00000000000000‰PNG  IHDRà€a£ôŽ hiTXtXML:com.adobe.xmp ¬tä¤gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDþðˆü) pHYs.#.#x¥?vtIMEã /Ùfëg6IDATxÚí}y`Õ¹þ#”°F1U@KPF¨Ò( 6?"Wq)ˆ¤JÕ¢‚hnUD/D@D‹@d©4¸Pʾˆ4V”öU°Á¬d9üþø–ÌdÎÌ3gæËÇ$7Ï? óœYÞ™3ïyÏû>Ï5¨Î¨u¹O •‹WsÔ¸š£ÆÀÕ5®æ¨1p5G«9j \ÍQcàjŽWsÔ¸š£ÆÀÕ5®æ¨1p5G«9j \ÍQcàjŽWsÔ¸š£ÆÀÕ5®æ¨1pÕGa¡ÅWÔ¤ÍVyÔ‚…q¹ÏN‹ü£g‹ê]scC“ŸKŽ^Ýì Ë.9]Ôà—7ÔqÞ º!\Þ Ûyîg网Q#û]#k½ë¥5ÀБM­e†.^1: â^½/Bz¤A…“¼Ø ?ÉåúÏQÒk{¥CÐT!Â~ì½±Áý±û$=d·ô¿(„£’y ö04W8h`<½ 'Iï½JÕCر‘eƒp½Á±¬ÁOIYñÃokZ§äÌö77öûü*Cƒ•ٽǵ86xîà8 +vµ0v1}bää®×7lñíÎ7S¯~ý õ±lÏãþ~2èW;4÷ÞwðŒ“•þx¿©Wû6Ï ^–dhðè¢ÌXà‹î“žN5{óUCƒÃ­#¿êÔjqg“ÖeuPo`ù{RoÒØ¸_`£ö6Ôîp­Àjp3û“ªàd­Æk~û¢Ék V ¼­´Åwá°±‡¯0#`³kRÖmè ÞÀ>Þ1cØð÷êöß,ÝTùÃ|µÞ<3þ­ƒÛm±ÝØàר à*ìP[Œ 6"P  ¾tÐ@õŸû`ƒ»"ÒËæž1ðšÁäøµ±A<~-òÐÔØ`¢‚ÛWÊÚ@ -±ÒüÇÒÀƥʾo á¢É,¶Ç''n lG¢±Á}ØÔ ðy6‡p»±A¡ÿÇBqƒƒJ¨‹oÌ<äF@º„ø>.2ìémÕ‹UC›6•}ÂßC²^EcaÃTž;é!pü÷Ïæržýýq÷×®7˜Îb²Cs _“!’§²ó‚!@¬ ÚmDö(Y4ÍF,ÌFÚ‰å!ŠžËh;æŽk#ŠOo}5ã¹t£·°\Ö—yÀ$\N–v¤H˜.{Îx}®æÆÓ*yoxÅ]B­Ú`¾ÿßKyÛ§"j«ñýzbÎ…Hµ"/;nKe< ØÑC¬Oè9ëzßæÉ'Ö¬3†c¤c®¹þ\Øâ±îñ²õÓ½·!ñ®+ÍŸýâNé:ÃÛk£Ú@»F™ðždü¤±0°£‡ÈÀ(¿}qý˜5Æc(†JÂe`:‹]¶­ç»·X mŸcià´±Öª÷@ óÿ[;²Ù-·Ö—4 ±0švBñ5Ê}óö²UÑà T| µÍ3ÜÓVŽ›Tzc‡uƒ.È·ÞÐh  ³ØÙD J‚Ûň±l[ðüKE¬?ϬïA[ë;Pße´EËôÀðùäʲù4M;¡è„ÓÁíÓèdÙ¶Þ³ïҴϘ.›æºîÁýÊlÄc½ çlÁ‡÷I£a4í„¢6/ýÝ­·Ä2ÖŸg üȤ/!Áì?v{  ì¢éÕf±NšvRºj½o#û»ÒŠ“î2Ó÷,ÿüÁPt³>‘Ú<ñ(\Ó$:{+=ÂÝòíÁý!(¾¿iI/ø£Ãßv~ùCƒCmR‡(J}ˆ›y«¤‹O¢Å3mêîOÍÁœÖ‡;ps¯%ì”\ºvÁ}&yÔ1wÇ =¸?ÅÚ¨Láóó’°Ôøû¿ðµBüˆ¢e~ZÉ‚àýYPb}°£IxŸP¸Þàþ(›t‹ÊÉФŒkÃãP0u8R¯©‚öàæ6ãG{ðÍŸÇwi|+²N~¸0~¹qÂ?zôñëÂNûÓ+xë­ùʺ=õÅ—»cºÅw½^ö+ •è¶Ä÷óïï~¡}# o×{·¹Êø{gÀxZ¹€R‚¨Po`¿s;‡ìþ4÷B$°ëÖèõqàæ¡“ÍŽWfú-Ñâ=Z¶®@G~r£Y  QÜG/½˜ÚÀÐà#ÖCcfÚm`@üH2Ia°ÛŒöaP} ¹E^¦yç4T¢G¸Þà¥ï NB÷µ[ê ›°V8RÔØ8(;0 ØÝ³± 0|üê@YNßVú‡kš´-ƒÛÑXá ‡™3g†é\Í‘Ÿ|jV\#â>Ê~±ÀØ ¡uÍ"¢wà4?­ÈòûCp Ñ_C{Éß8èá©0©>ÿdoàãÒ0¹Ý#Æ¡»¦,rÅÚܸä"ÚØÀ}â´á2pÛ¬#ÁÚ£#•žŽá¥ŸÕõ­ÞdçDÜ$û¼U‡ÈÝ—¥t|~S“©x¡€½²äûP'N‡ËÀ‰ Sßöß²‚É¸ÏØ€–¾SX÷0úîvtþÈý©÷Â* ¡6µ‘˜çú=Ó¤^ÑEj¦%ÈŠ7*\NÖ©Ž9'ÇÔ wNJʼÎÐÀ8‡Qõª¬{¸k3z¶Ã»–=,}øëßøôˆÙèÍÆHcß…ûƒãЛû,ô¡I;éµ0¦ìßx¡ÍomäÓ™• +Þ¨°Íƒ·$佚žYD®ëlü½£þ¿™@G SåÖ=ä-OÎaO B|ô—¡ÁqhØ´YOð´+•” +Þ¨ðUøÿ0e’o#ù…_…ë˜:œN[ë’^… ãÐÚû i'káûÚ­Mpþ×>„“Âáøáœ‚Q­š»ï©’pËþ’ÚÀ?û¼õ PÐ(n“±‡^™ K;‘ß\ÛiÏë'O¤™“ÅÁ/;šî/© |ƒNê¢XÒ¢óö)“|k°òqè+ü.ÖPH{®ëh>©‡gHX¼€ä)Gn@~³Üƒ­€ÜÆO~(md95ÎÕÜOé|¼F`³Û\öÄת:Ó$ÀÆÐD˜îè,–‚F!2Ñ´šö dÕˬäõÑrœ›î« ˆš~NÞàtª¿AêiG8€T!„(x@Üv'=DÒàS!„X‡Ïô`ö?Ö¡çñÀѱNÖGÑ"‘AÜ¿¤uŠ—6ë|¦ºIWÝÓ_K§XI¹B1¢Ë™Ê¸ #°9¸½#$-X ²âe†ËÀ¡í¼ƒ /œ‡ Œ ÎvBüŠì¢²¢ì]Ð霃C¼ŽãBˆü¶H+ýùUÌwtš{g¿·<×üç¥z88@‚&ù7‰’9û`>Züøù½H)s}™á20šÒÐï¬óL_¤98D\Bì@t¾û0´2®Âýç¦=Dd–-„8€,×—.'‹VdP¦;JÃjw-ÝÜŠ;í> HÓži ²âe†o¹TdP¦;Y¢î•â³X;°$”&‘™Š»ί«þ,»¥-~Ö¿)O{¦%ÈŠ—6%”"pÌØàŽÝ„éŽâާop»–N§ý0㪤d²Ý1¤vR$üü©4í™– +^f¸ L‡&ÊtWNÂÚNBÈ ›³Xk¤øCƒ›:Îz:^ÿ¹v½âL¶§ÕœÏŒ ¦=·2öKKU/³2| >ÄÔÀfY*fœMH)öo^‘xΪ/““VœÅÊ&™ÌƒÕ¢ÉNnK{ˆ BH!Äv¤¸¾Ìpø 0ÃÇnu~pPÒâè€áË„e^hžnöT*ÌbË|ÜYv’ă՟Fg·âDúàÄ N?.ý5'×øS2Ü]¦_â;­È˜ˆŸÇ Àtw¥ç_¥]™Fhí®¥Ÿù&-]¶P;÷OiIð±$aC×iÏX÷â&Plžö¼°ïÖ_¨…}‡&¯8Cæ Ø½La\l([Ü7°¹àÉå)0¸ Án_>@Ÿþ½ ?=ûÁÑjEÎ7IJ³î(ò›¬H‚Tûo™1(p;¼ëžo*l‹ µûœ°¬È°Éwçe2&í:?{ÏM’-5Bi¹•I*À>Ÿ=„y¹°,Õ}Žßà“›>^DþOBùèöm%µáçX)l˜¸ÊЀ'¼)­ZÀŸ „™„¥2«7iFqòC~û•f=PBiÇ «6ô£Ø¥ã³ψr¸Í(ž‚ûÿ|g3‹(‰cl\â#AªÙ*þ‰%]t…•9ŠzÈÀ„BLH¶už™ ~¡Â‹¥°%ÑÉd{hȽ’U’Œ¸Lþ’šF!&s³å'_ràƒëKÆá—ÿàÉG;_ ¸÷`{¬Ë&Y4’|ÅCp£Ôp9˜î ³Ì‰;³ ÿ¬:À»2 1ûŠS.L”d³ü¸yî"¯÷Œ•;0Å‹ø{°v—ÇŽÒˆ˜•p£®!š.´Q 1•êÞˆA­ìiÜýË8ô唬ѣcžÿmÉñ ǹKCîvoTè8ÿ…Ûœ#÷›þc’ìwO!¦ÅE 6û©ð›1ðТʸ:rW¸„CÇwF—!mV^‘qËþ¼ÀÉææyWš¤¬ÚFQƒÎ›Í=¿eÞÇŽF?ú<Ü3«ƒq°•´»Æ&ETÆsL°k;û¡D‘ÎBˆbĺ<ÄFÎ7ز"ƒrþÓ0áüÿ–æ¬,k/³/Ö`d´¹~sp#¾³4°ÉLÌóé} c³M¦=Z¸þŠÛq.´ç”pÀݡʾˆ”¥B¯¼Âõ·Ežâ8!~Ɠֱ˜‰YàiBD !Î!ÉØ …Qœ¯Ø½a{ƒm;fb ¸">­Ûá–†Ýt øõ~2à2GlÁtÉ9»|Óá‡F°˜9”ó_ ÷`ÙPÃÎL¶GÉ“ÏÄmÆt¢L“&é‡F®Ç{PËgsôqðW‡°DRß¼lѲøäòh,6î§7—&M–ÃäCS¼Â_østk–<\o°}ç"$8#þŠjPÓ™(Ó%çr˜|h(דá20­È PYG»ø1œÈ>ROž~ ©$ ]rÖBú¡Ù…ÎðÏW³{óÛYH(|ò²*ùl2ЄgÊ¥¢ìô5ø½±ZO5¨í ÍÔcc±ÕWmr30`<áóˆÄ—FoÃ Ç í±‚·Þú÷£Ö]„ÍÀÔ¹ /(ýtRÛ‹ï06°?¸™yò哿G7t^ÖV¨÷l»Dã0¢”4)ýÐF#‡÷G?\«ÑÀ·6xÅÀ4Ÿ¾ ¶¡";Þ/K½¢ƒ›‚'oòÔBª«²ä,ÿÐx´|”:öºÍF?t¥ƒ›R®ºô©…•$Šù—“~hJ Ç/‡|ô£PܤH-äê± ôC£X>.BðXlõmÜü_k¬‹:1οRhÝ› A( BKÀfbrõXÛˆŒONÏ~HòÃ]Xr öËGÃõ«8–q|£Ÿe]Ph(ü õ’(P_’~h(ã´á2°R>›t¡[ “ÑÔÑÁ »Ð$UuÏ÷M§õó‚¿½L Ç7ý‚uA9ÏΗÕÑÚx*ìB?T%I“‰{ƒå£cÆÐÖªl(‡4ŽOG?Z¤8¸YÀt&ö6ûKUõ_Úªˆ¨†+£Ã>ÃbéÙo‡~¿Øè^PA(*ŽŽ5=$Íl eýÒ&†ßg…Uú£hxÄXFMëá20eÔÇñß4>*uÓÑ/eìæ ƒó–¸²ÑK©6¾Ò±¯ÝgN"æj×M£H4ŽOG?JÅ¥8¸U:¤¡®P#\¦Q$÷ Ý”Š+ PÊiµ¡þëá20"©Äñåp_DAí§”Óê,Ô¥ˆpX!ŠdÇ¿xôtaý¦¿ª+ý‘²ºµMûÒÀe¨Ë&Âe`¥(’IÿâŠ1Y3êÙNY݃Ú/ÓРÂ:Ù 5ÂåEÛ’C ¬ŽLs*ox‰çéñ²ˆ“Š8úå‚¢ú¯{„ë VbX”Æñ/Ÿ†Yñ×EŸúbÐQ£$+¶´.ÈPTÿup½Á'oÉMj2Ÿö°>Ázþw1uØðq†½;c£>÷?ñ;rvÆÈþÒZ½JÀ½†£a«MbQ$}ÿcœwúEÁ×rÑ£3MCN!¡âº|°!MHØjô_ñ‰"é.L©Äæ΂N50'\ç]–Ú?Ëe;•ˆT:êÿ›i¬-c5®zxF+``Ó8~‡ÝÅA‡¡¤nÄÑ¥8;ï ߊäÈ~×X\…Ú[ì^܉²Õèá™Õ$ú Ý´[h_'oD¥µÜ1…bß,ßFÎÐÿ·ñ÷ÇQ6è•“aÂ5£˜¶.e«©xc« †áÇàö&kB¥µ¨8—Bÿðí¾üî‡bÉO\ûçܘ~›~Bü¼©ï²ßÝ‹;)²ÕT/ÀÖàöVÌ“´ ÒZTœKql†ß?™alBµr Î l>ýçÆø ;€¬5}Ý•jdàà‡àö÷H76xܧX#„â876ƒïô;¶V4Óþ9…Ç·ä !ò7'!ꄱU=¢~¸öí´ÁVS†èž ³Gø/§ä£DÉøI3²*ª­ ö3Ƞ嘷Ú?ó%ª?×-KHKC¯¦g–‘Ë$Ñš¶þù'{5 “Û=bæ´ÇVã™Pe=¢ÙSÑW—Ï<ý†$ñ2…Þô}‰þ«WV'@ùl[õç‡)“|É/üJz–$&ÿÌÌ¢`jYq½§§äûÿµÉVSùv· .­E2J#¯4êµÄ·5CvD9ÅñÃ9 ¢Z9”\é˜u1HC[\Ï}Ƚò lûÙWZst kq®Ò)/akÝ®7¿4¾²ïOô]X~n–e¶¨¡ò¿Á6½ÅU0 ¸´–%ShñÄ×€Uú\°Uúj¤p qaêÛþa¤`2îsßaè½Y9˜÷Ÿí[éQ1ÞÇ÷WI(‘ïL6jw}³Óc(AýpE„ËÉÊÒh¼ß;Ì©8µ¡ Ók¥ Ö&L{Kî |KV>‚éO«vSvè`Naà¦qp[rðÃ×uvÐá2ðÒ‡÷ËFöµ“°?º(3ø¢û¤çSÍÞ|UÚ ]îuZ_Þ‚ÁŸ ç·DÕCQÎÞYk0xBÅ5yf¿^Ÿ«ùŸ£›Kýp%„kL£ð;Ð@[| Ëú Ù.±åv Áä&“V•‹|±¢}õö3øtïmH¼ëJWt›-'¾èÊ×#\þÚ‹–T6p¦W–MAaMŸp;4ßkR€þ#é™»+:æÔ~˶õ|÷×lªÍCbZÂe`…§«`?%eÅ¿­i’3ÛßÜØïó«ÔÏÁ}Â/ºw=røÄϵ_׺¹ÑÙ§ö[…ñíÂq;í#\¦Þ?Õl Ë½öèj·jeڵ߸-PuŸ•Wžñþ×Fe ß2g^’<‚,÷Ú‡cÍ©Ír¯O±*„ïˆÛî²3!D¸x²®[™Ö¹áCO>Ô0.]…ßÓüŽïnÜìül`ºŒé•.÷Ú‡*.)º°à¸Ë¥©”Çæ‡ÏÖ‡±þ·Ø@¼]UÖtÉGzà'åyÑ¥g»;›Ã­¥LMd´ôaÂOY08z„eeåÉ=úøõ@a§ýi¼õÖ|BÇÇÅÐùšd…ØlìÓ?þ̦8þ˜»s)©;ø}ã^6‹¥öù±W=iåSqÑ?ͽ ìº5zg}¸yèdI§²ó2È=°@ÌÎõ`KïŸ2½Òå^%H©¸è,¨ÁıoZÚoŒõP‡€sôš¡uôh¥|É{õÿíëxJZf˽JjNÍ~ŠÌ‚Æ¡`¬ìg_ý׌sõžõ€áãW÷ÊêH– ×ÞÄ8Ö!ÀZ‹S§íªnVD ›B·ÜûWIC»q`3*®Gí°.ɦöûXÿß?[u&×N£•ò¯LXÚ#˜à¥opñŠÑY÷ê}Šô_vW”Ù”RquØ}ÑúéS±‡ÔÑ›Ÿ4eÈ‹{Çý§p¢ÅXã qÏFMV7°÷„±Œà ½l|A)W—Ýä.-ZRÎUÊ·¸JácÑœ›-4ŽH©¸˜u¼e¸îL=š•—˺Õ#\C´…ê¦íœú-Ç¥ Ȩ¸ø,ˆA)Ð(uôhV^­OÕÃÒÁÂgà¹JK‚ÏÀØÐušö¥ìïÿW—Ó3Wýô ªÅòe! 6‹ˆ«H)9ƒ0sôB cùmyþý~/´oäíz¯ý«‚~AµRqÑY,u)%§¢Šµ{„ë ¾gcQ€ZQ§ñ‹@¶±4§Ç}Q×—ŒŠ‹Ïbƒ®" ui Ñ½Š5 4áôŒ0ÏègÙ þnÿ *¥âúˆþÓP¥”œ68Wél^iÂéa,šÓã>ލ\RƒÎ‚¿ùU¸¶{lÒ˜>F‰Mh䜫ì9VœpzF‹æôÐYý‚RI ª¡ª@Éi¹ʳºØ(Rî—”mÁϰì[™ˆ‘÷>ØÜÞ'SÿíÖ‡ ¦ûy±p*Ðþ<Ž‘‰ƒBˆ Œ@ã&wÎBÏ]eV¥¨Ä®7˜ªnÒœš ÿ ~˜RqQP U%JN©vÍ RTböŒ0ÖýQ©ç’cê…;'¥Gý—±û8"0PžHê** »H=ú+*1{F‹VÖ†!ŽHù¾©«¨¢Z%wôès¬¨Äìa¬ÎÛ§LòIÊsz”fAÎ@ù¾¹@;S­¢Ž}Žé(¢‡§ü­+kY1ä §F,ì»õ×jaß¡ÉkÎp zD9Wi<ü‰9"ÔŠ¼ì¸-e9 §(š»Ê†¡44áBI Ý¦ŽÍóQD‡p½Áîo.#.}øëßøôˆÙhIØ~>Š7èåëȆ@»3Ь ÅQ$\¶us-C¬4›‚ÆËVþ„7 V~œ±¥¡ZI7jÿ-3Ú x—2Ý…kˆögŠ“fþ,ÄÊãˆ, aHv5TÎæU”˜qœ¬ü=©7i,ù-ÔPܲ¿¤6ðÏ>o½4ŠÛdÕ6<Â&pš|¨ƒÝQ$\¥+A4¼cÆÉáE’¦OŒœ}0-~üüÞÔ —ôÜ%°+ÍTïÙwà +'Eñâ¸[âÿßÝ­».u¥AÞôj›_ '!Y—؃µŽB¬d³Ó*Å ñüe¸r!D^y¾ïÐÜ0/ìo0€–XiÜ© ±V v=Ø&ö†ä3pè€ä¿ K.Án8,Â2¸¨JW­÷md·ÓFÝå˜ו­Ò뉞ÙRÏϪ,–‰Q(ÅÃ" )]Q¦óIUÕ‡Ë1LÉŽÚEBøWâJeT°3Ñ{_þÞ{±Iñ5VIº]I¹B1¢ËË38š„÷/Ç•‹¿û„ÐBñL“ÝbEÕ‡ËÉ’¥öÒëŒlƒ¶#×oŽnÄw’ê3ƒ0$ —ÒŠV§Q%f=.‹e“ ºPcƒ†‡|kYÞ«”!šŽŸt-(8Y7«N£Ó}=*ßÀ6ÉHiˆ•Óð0„A’¦ÍÚ_ ª3!åIuš‚3K‡Bcx¥üÊuM^3ðN㟨ŠQñ6kà>`NÇO:Pi1¨õƒÆâ%%%f‘‘Ò…JÃãžFÐÏ’µ 9?•Ö‚¤Õiª2T¾m.Ð+£  § 6x–ˆ 9?é@¥…´:M)í+|NV~r£Y  QÜG/½()\ 9={š¿Óq|—ÆÀΓ.”Ñ𸧤N¹ ùî¾Rr:~*­(gâ6ãN¥é>Â6¦’`Ú“–ŠQЄÓÿèáÛcÒ¶hØÓùƽe#€Yû.^Ø7)9 —¥ûUðäJ©öZÅ'—GK“{¦û"|ª+ƒPž ]„§ô´n‹—KÅd$N[<à+Šb !D¢ÇÈŠÂNc®šãCÎY3ë¶ð# ’óeMöÎ~o¹í0¶gÈH)( M8¥9uZHœ/1=P‚Üaê£2óvÇOóI¥! Ó}=œ‚Jf|áx —ì>Ö-xãºÉ¦1(n_D'cƒ]»>Æø ;€¬5}/]4 -Âe`)ÈÓ’)Æ@\ÂoàíHqpt©‡:8¡í¼ƒ /œ‡$'ÙK³hVˆžÆÚwKºèj„ËÀ4X imK Nøî?%!ÃÁ9DÒàS!„X‡Ï$7C ÙRì:ô<è,ëŒ †áÇàöfq³EÏPÃd¤F´ÄJ£÷ ”ì"…í¥S'£ÊÒ×Y“aL©¢¡.ºèj„ËÀJ.’´¶%ô ,3ž:8_£|vÖ^¶ž‡uA«®Õ8\ATŠ2®\#< Ù ¯±i%h;@¸ÊGoD>»Ü0 ÍG2Û…Ï•nXؼôOt¿|'bázƒ©‹DSvlÁ;=‡îR;)~þt(º…éÞ¹B¸ü)7Œû”7ÒLvÏá“hñL›ú…ûSs0g€±÷Å/¡F¸ L¦:êÿ› tÔ'Åñ{çšÆ…žÊ÷ l.xDPuOÅj„™eÇÿw{9¸`¼>…3e;é/¾ÌØÓ-¾ëõ²_ýT\ˆºC*®ü£g‹ê]c²ž¡ø-óW¥%è½³f 1ÊxnŸ)[ÇÙyoøÖ3Fö“9âŠß²Ëb`žÍk³{g!Ít9P8¬ô='£Õþ¾YÍØÿmcü½£þ¿™Æïˆ—ÅÀ<›×ò{÷ìG[À¯Üs¾IRÚe¸0öµ[Ë—k ø)a[üðÛšÖ)9³ýÍ>¿ÊíY„oÁŸfóÚÎGýçÚõ6Þ;÷ Æ¡…4¢®ƒl$[½­ßÔ«D4k7xÁª$¸D¸ Ìu«íg„›Ü;[ÑPKÿ…:êJ³ º´«d$[×®öo6ymÁê*c`šÍKi°´Þ;ÑPâ¿Ð´![åØ(ÛIF²o¬áBÛŒCá2ðçÐéVSM”2Â¥÷޳#ý—œ¡ÊüZáoƒ@YDŽdwì.7É/8CE¸ L³y9 4‘HÙ½£ÑП’²Êý—~ÿ…ò «Ë~§#YON*hp’Û , —Ý8Ws ™}Ëþ¼ÀÉææyWJ´ëi$’FCÓ÷ù/Î ^fùy£|Ãò4 ñÊÝHf¼?=Öe„ÿ­+ycKúU†ŠÁ²ð1¾ÿa^Im °açÍ@iDl¦± ‰¤ÑÐ?Í-~duìÿwËÞ×î³ß©7 Qˆ{6æ××´–ÜýìÍžŠ¾¸txæé7$µ мõá¢i6/§Áb¥+tÁXÉi‰e¿So@‹`w€0°MDË1ow»;2÷« ¤ÈÿªiÀ™bôGâ—‚ŸD±/¸/] Éi-Æ@ëÆÅ²¤W¥R€ž¨IΣ‡gduhF¸ZéŠ,†@ý-(ß°3Bb:’MSèLN…§‡g Li°ÔJWd1„ž ³ƒþËG‰ÖΗ ä u J!t)SŒá‹EžA­{’0]²AEâu1„X Ã+Âü=ßðÖê ÂŒ¢7“&a3°žgÐxÔ [<Ö=^RX‹Û·•Ô†_Ò­°aâ*CÊm0?AÀ x'ZÿE÷½×ÞpÞÀB¢ºÀ„)Fp Ñ”gf„ÓH$!¼€`Z´ÖÀ”o˜6°Ál#¯È²€13¦=Âe`*ÐNSlh$’FC©ÿBIUhÎ̪,i£ž)¦;£p˜ [SÐH$††!àqÆšLgó8Þ?÷‘óìü¹GÁžáúwØ}Ñå7‡F"i448ÿþîkò­2ÖdšWT”´¤í˜;®(>½õÕïJ70 -ÍYY6ÒF¥†ƒÉº<…‹.{ <­4†àÅ+ü…G·fIC ¹ç6Ÿþsž±­²¤Œå(û"’Y†kˆ¦ÂÖt‘„F"¹ $ KTsãóOö*¨&·{Äxt6O ËaJ…§EØbÑŒgÐîZºyA!PûU N@Wý™P"¦•hÜŽÆ £i^-`Ô_eŠ —©°µÚZº#PûÑ¥ª¹AY“i^-`Ô”)¦á20å ™¸¯9¨ý2 *ì¡DL”5™Îæy£&L1Z„ËÀ#`É’À_3oÑ~ÒðÑ’µtëôè»ÛÑŒÌL{¬A‰˜¦Y“'ã>c:›ï–¶øYÿ&-`”Sáé.SžA ê=Û.ÑxâÖéգѳÞ­ä« DL”5™Îæic@øúRQvúüž²'KW.Ö~’a§u&CÞòäœÊ/öJžrää7Ë=Ø Èm,Ë+b¬Ét6O uI#‹¢ç\ÓE·°^K/Ú1h‚„mölj]ºTö‰ÙÐÜ8œx¾—žps¯%V¿ÓŒ89(_4‹Ÿ¼%7©ÉT|ÚÀú“¤­ã‡s Dµ²¤Öµ¬²´.`TEe?ôAv ¸¸ïË勿·FM³ÈJÜwáCØÞ`V™¢´–.ýHS,}øëßøôˆÙhI˜ÂFÂ"ÕÜðÂåEÓÊ%qßÚøÒÁ9Ð0…„EDL¡[Ï7ý*=„ÏÀ´2EIÜ×Y›}¾h3í^°ZÏ·3YçP©Ò ŸieŠŠ‚‰Ã„7¾hó„EëÔr=ßÎd}ƒl§6`®T¥N*CûZrè?Ò:èA‰/Ú$a‘%ÜX®ç¶zéÅÔ†4a1 Ê/J‰ï6.7¦),ÌK)T²4/Î5Øal@ ‡¨v¯•©‡d+ñ=ïØÙ¢z×ÜÐÈFž¢i˜—R¨Ü´»ü¸ÎØ€`*mGaƒgäcØH|?ýiJ.D¾ñšS§V3gδnÀÕ+~°LQvàå² "†ŒÕ”°9b¹BˆÂ}>Û°·Pþ#¿¹; ÍBˆû$ŽðA`†Oµòü4à ö§ ï¦ !ÄÎòp\ÌzºázƒŸb h˜—RÀQaHZ8dWŒÉ€˜QÈ>ô„Žæc´š3ð™±ÁÄ÷VÚŸ¶¾´ÀÙ¾ûïvë5uJÎf½“ñØú&ìŒ>Ç!GŸò.¢„¥ˆ¡/‡ñìàíàö81öð!†ª¶óc–“³üypðÐO[ªÃšdç‹™è½/ï½Ø$„ø«$-ÌßßÁQ!Ä\ôègŸ{ÿ`gì™o0 óR * I ‡(.Ÿ†Yñ×EŸúbÐQ£,ÞÌJèx>Fí>'Lß 1€•P$¹ê•´5 §ì™Ê†'æ\ˆ„ŸkÇm)£*ã¬pˆ²µíŒõÅRìLÈÙ+Héhm°&ûND2¾Çm)­tØ]\K)j £åÕÁ3op(Öa:oŸ2 Ë ù…_ÉèÙÚŒ¶ˆ¥!¥£µ›!û~×BQàŽÝå¿Ù „÷ŒÝ |”B¬åÄ­ ‡([¥h!ÍÎw“›Öqó‘v@â''ƒ°“ ÎM÷­ÇGM?çèïg¡ç.Ë~Œ†ø"›híC/ãNÊšlàåb!Î&Œ ø^Åcβ?òÌl#ÌK>”BŒ‚²µÑXŠòì|ša*éŽ õþÒâêÙ#F?ÑÀ¥#³²g_ Ï8Y~XÔU2:SJ!FAÙÚ†ÿ18Õ>ýËaÆDOZB·ßüy|—Æ·"ëä‡ ã—ãóV’ +zvŽÌƒ{ïŠÌÝ´)Wê"2xÍÀæ8}Ÿîù‚¡Áú„ž³ü‹“O¬Y'óÓÈ0h1ð¾[ƒ^ÍwwÌëkh ÆW+cM¶ÔàüöíEÛ3ûyfˆ.egBéL9…s’)[[Ö ¼Vãpa?;ß,#x†2 ÎÛçät^‰ÂmõÎüÊ0m"ÝvcYÁ£‹vX4÷XW.hRÐHB(MÇ€‚ÁÑÖlm8sEð,Ï^r²¨”ïÿ×”5Y§ú¥:xÆÀµâ¦_Ž’ùŒ§E?v—­S!¡„ŸýpnìUO:ñÎ* ÎôKõðÌÝ{ÑýÁ¢ùñ YX²ËnÒ]I¥N2ekÓª »“I†ýRp4a¬äý x*[!¾ŠA I²Ù¿dy¬Z|ˆ©Í²TÙZB c¼U»5îPÀ„7¨pï—Ÿ}uЯg†hàË¿ìþ¸káœ!0VRJ?‡[cF€Bl0¶24 NòÇúÿþYÒ„é~ð*õrÖk¢¸}ÈBˆãƒ€w¦ÉNÏ$:fù÷s€cç/ÿF0Gò;(.¾Mîm ÄéT¸-õ4=^®lÅ1¯|ê;4—vá¡7(N{ˆ!DCÁ8X~ Ë'¦ ‘¼ìÜIfX{ŸA÷c­Zƒr‰[ V&qËñ·—ƒÉkëS^§Î¸Ëg:¤8ÿ&€{wÊ´sÞ'ÒÇ fpúqyt `xK˳Ýeç@œí„øÙEeEÙ+º Ó9ç (ñç¥7xï‹«0uñ:¤÷–ùö6>ä+©>ð1€j‡Ò*·rÌýSZ|ªØÐu«1÷ŽKÿÕÝ&ßzaò($¿z­ûþŒ Ê»4'’ê~ÐJ·R<ûÁÑð+Ào’”Fš{ÆÀgÞùFþ÷U€X;0§ÓôßTÂ!è@Ÿª‚LtØ] NÙÈÇÀ†ÄŸž tÜ¿%òÓžµÔºïë׿ÝYÏÝŸYšIu?hZŸA¡H"àoéóv`æÚò£»^pЃ¢¸½”Êê~ÐJ·R(’xfˆžüm­ÐWwPû©‰Û“8bqÊgT†?=Ö%XŸñÆ–ô«Ô{5æÄuðÿ§gt%Í=c` j?5q{&v¸õ 'T†Lâ–¿&] ûM^3p‹eyfˆ¦ Hº-š8"°VúY© YN­Ï ¬åª$®&þ—wwÞºIÁó/IÊïmÄ5] ³d/ îoÝ=µe-W$¨:op6¸~åº-T`X gT†4ñ–ÖgPq5ÕåP¾[aÃA¬°nPˆç;i1ˆâ“Ë£±Xv\&¤‰·¯ã¸"¿-ÒJ~ó]ߪZ¶ž¯á¬°n M:§Ã7úq]Äõ|O© eÔΫ0¾;Êok¹œ=Z Upˆ†ׯRJø ÷T†{`CÑ×*¬åvP5 ,ÿ@–CžtžËºuOeHóŠ((k9g;Ñ¡ ØŒë—RÂÓ8¢{*CšxKAYË9Û‰UÇÀ”ë—RÂÓ8b9L´—i˜Ê$S(±–Û@Õ10ý@º§„ו!•I¦ ¬å3Õúó”-³ÑèÒ%¼‚âT{™Ö¸ª%ÞÊ@YË)Û‰ŠEÛ` öáÒ†–±»*ŠCg¯í¼Ù°“j‡ª-xÈZq5ï¼ÁÁl´œ¡Zg£™| )T‡RªÈ$›Á†¸š<óÿ”°­œ-¸“Œ-XƒóM&ÇO¦Ÿ5¨÷¸Ç¯ß|sç*ãDJOeø)ÕÝ™J¤2 9\ÇÂBʬ…”ë—†é{#SñoLBœÀ›Æº#‰TVExfˆ¦lÁZH¹~i˜Þ¶â=*C×¥GRTNÞlÐKÛ)Â3¦lÁÈ?T\”2ܨ}®Ú¨µ·É:_Á{@WWÒõž10ÍF£\¿T\Ô½úM°È+’ª--kc Ýïëïþ[oú¥Õ§Z ÑUŒuž:êöó±/»¥Ï}í[ÑJy˜±»îÁV})©-s’?L™äÛ³ÎSGÝ7èÿ»öÑTpð’[°ûl¤[°Ú2÷' à¸ë¼ üOïèÆ° Ï|ƒiUûh}"ÕOt’ÐÜ*NGs{¼ù]/òåÕàr/HྪÇ~f¢Fb"gÌG‹?¿)’¾ÜŸ¤{ì_1¦-Ü;9ãX)oî™!𲇴‡¢áQ£Ã­#¿êàc(:›´.˨Ÿèþ$C‚Òã2ÿw €¸G;¶if‡íS¶`ê"Ñ´ŠQ *¥C8» »(;uhû’õb“~ݦ¥y;Ï|ƒiUÅR«Í´ŠÑÚ2÷¥Gô*ì¢vóæ]ŸË9¼cÕ’¬ªÉ¢U=ÔERª ’Ö—ÒÚ2÷¥G Æê¸â—¿¼óá?¾‘eÙÆ+C´}¦P3 %®Ñ7÷ZbØyû¶’ÚðËë6”ˆ¸§3 ÂlÁXe§íX¾@·õæšjÚùá™7X RÉ=Š7è –…~¢}˜8 ZØÌÈ©øGx¤g‡Vlh JXî"… !ª-“: :äCöŽ“"æÛ·zÞ{Ó/mp$USÉk: ¬ˆ¹ìÄÌù¾º›øG:¶¾žLÛztQf,ðE÷Iϧš½ùªå1.ýxhû¿ÖUXtÑsAyçŒçœÈ;Ó*¼Ÿ’²ÊIúÉH˜þ,%#¥\]™lí"f¸âºëî~6ç°U0Ú3o° yg· ’6T–.»wþ0¯¤6Pذóf 4‰j‡žyƒ¹¼3ܲ­SªA­##]·Áh`÷\]¡(bÖÂ3þå·«½œkTM”ÑJ"@õg邱 ®.ZĬÈñàŸ@¹Ñ"pLÒ‚eÄQPÊKŒÝƒ1+rè¨XÂ×,² 1WË÷ÿ뼈Yï˜É;SQF¢¡.š°AÉHUÔ›C!®Æ9¼c`àÔ_fìŽéßõzÙ¯4#î–ýy €“ÍÌò®”°Ìu«êЄ º`L#!úÆ&âjöÁW”=ó pÝcYÐMP¶uJdÇ´”yÂÕ,¢Ž‚&âjJ^20˜áË@÷1 ª?ë‡yß4¢ÕŽ‘‚’±éá5›ƒ²­»'²s¥HˆT;†N”•ôÛª’iFœ-";Ëœ÷° 1ÓŽ¡µ-v84ð†GßÝŽJ)P¶u¢9ôõ¢ŽÕŽ¡eªß¦‡7¼è»6£g;¼k§©yF'²c9î5¨i꼦¹vLfe%26¯8oyrŽ+VdßÅúa*JZÌ)øþ!INݼö@é˜1¯FBkA¥9+ËF’¥ ùD™r<èá §ÓºUb¤1 šS@íW~,“Ò1 †vŒt¢¬FÆæ‡)c7y‹¶ÄcÞÒF韼tL)u~ùƒD;¦¤îà÷Ý^ôÿ%÷XWNAUÐH Ó€—þY•ŽÙK—jÇhQÔ ófÞ5ª¦~0Ç¡CÆ}<§ õŸû€|1Zb¥éoM¯¶“4)«°Ò‚‰¬Ú7¦I¡‡L1ƒçh åŠÕÂYé˜Rí˜ Ì&Ê6Å=¨V&AÚni‹Ÿõo^ú'º[÷eÃ~å»/=]X¿é¯ê²?—kÇЉ²MqªÑ7˜ñnœ‚Á8ØÊº;:‘—Ž]\1& bF= ¦©¸(W(AöÁÜá¯F^{Ÿ!H[aÁr tÛ!oxßüéñ’ɸÎçY,á¶?Q¶S‚\­ Ì3XN{\z},fÅ_Q|ê‹A9Ê8!؆¸Ÿ(Û(A®N¶£˜aSà^VnglÔçþz† 9;cÜ](óäêd`»AZóœZúG1}È¢GÛ‹©(æ\t¢l£¹êxÑtz`W1Ã|lv/+÷%î nß . ,U!×_Ê—¬ªc`:=°CÄkL{¬‘¥Éö¸;\^²õDÀ÷ D5p±Ñw  ¥ŠŠ•‚›v—?rר|æåe ²G!^4ð¥Ã¦c°J E— í–]ª(üŒ[ heY¥%ÈzxÏÀg¾IK·lÑ~ÒðÑtzpypŽ |LVßF?óTdU[õšð^U¢ ·/ OËVõžm—(¼Ü+fØ€erÖ­ºVãp‘ic‹‰²b ²—¦Ie2&í:?{ÏM$AK>=p¡˜a;‚Ïj”Ï\dw9{É}ù¶{xÇÀ'7}¼ˆüŸ„|ô•2Q ØÈT añ<3D'O0ä÷·_i§±tz@ ,`SžÛF²×à™7¸îÿóÍ쵕3…@1ãüû»òÜ·Ê乕J¤(ý¬®/,;'â&³/¨;*=<ó…K­~¦ÓJÀ@‘ŸÜhVh÷ÑK/J乕J¤8r꽊R_âfÞ*kâ–Š¤Üׇ/À“«Ïš6ОtÂIƒ§pQ\ù^Y; •èáÓT‡Ð¸Hî@¥aB‘|OfÒ]#ŸßÔd*^¨`/_ððŒíÏß]Q¡»Ó.´! ãt&MC%zx&'kéÃ_ÿÀ§DÌnDKæï¡ Bw«]ØawI0¯4ÂD2Ð]F/cÇþ`¨Ä<óÓù{’TƒÚ…9C?”k’W܋ی*3é¶*¹gž1°âü]:‹åÚ…ìç4.®ÅÜϤ+ÀÁªL¥ -J„ ñ–"qz0^X…ËKC¿@Nß™¾H“t±·|Z»OòûA`Æ!„ç§%-& röÁ|´øñó{‘"Y¼¦kA‘ÚS63OÞ®/×~¹ËVJžg ÜBˆaX-„(‘åCÑ[«‡o¶AMŠS&ú{8Û ñ+²‹ÊвWtA§s’cÌZŒ¿tþQÀÉï4£êR…¢àqÛ%=€øÜt_ê_ÔtÙ)VìÏ-*4ÕÞŠ”¯á ÖØ€¿â% ‚¯øY†ßß}…Bˆÿ`š±M›MH0ûOǺ•2ŽÑ‹öLÒÝ]Xr VówÍ26?|ÆÁ!îÐxRíB<)VKº¨ÝçDúàÄ N?ÞGVÛR!£ÊØ Ü—ÌúùÕïÿml°v­Ùü(z.£í¼ƒ /œñ\½j'¯Be€¦:¼ŽãBˆü¶H+ýùUÌwpˆà‡àö÷H76 ¯¸æÙ¹4£Š¦ÍR¬CÏã{–ˆu¬¹gÞàë }ªÕü]çf;Ê'í™0;"*ù(Q’1@_q?Ìi\hF•âZºh2Xsω{g¿·|¦/ÕaC“ʸ5WÏþ!åð%—È–iöÀ‰àöqN!MœnŠ˜¯^wü;„b4Í3ó`:§ËdTqa"ZŽy; ]¨eÓjöL˜=ÂCä¯8 ˜ÓŒ*ëµ Õ£¹v… )2ào0u³é…ñë?:`øÁ2!DÙ—ÊTêÉÓÄétL)‹wQ‘±~ýùÓ(j’ÇQž°}³Ûæ¡7˜€.“Qž¥i  ¯8Mx£UÖkAúý.m!9I%RdT¡7˜ºÙAí4ÁQá%½AÔ“ç‰Ó« )W!Ft9ãà$y4MϬ&q¬é ifC)ë—6±jj‡†U*Oú§¹"]·Fï¬7lÖ‘•fƒÒZ J¤ÈÞY.´…[cƒ†Õ nÙ_RøgŸ·^ Åmrߣ¨‘"Wo°Ò2YK,« +&¼Uj÷9aIЬGU2°ÊM… s—™>Š o•k¡e=ª©¥Z”U¡”÷ü—ÆO C~5ÊA‰­r©d.}´°#îda¼R°6*Sørùó’d\ÍYˆ ÐHgEa§ƒÜç´ª hØÓVDfwwÞêï‹O.ÆbvϼÁî ø¿Äô@øªÃÔG7:PþtŸ¸©â"Õ‰™òÊD£«G%ÂõðŒÝ𻆠ór/s‘äO@vù¦\"\Ï8ÇüTrá]„Å.Ì˽ÔE’>ÿñÿ[𳲬=Ÿ,xÆÀ”㈂ CöÅÐßßÞÈ¢E~GŽÔE’>åË—nèL$Âá¡HVC?ê:&hh‡ Ám©0$Ú½õ¤æÚ.]#ŸÿãÐÞ¶ùMÚ´±ø±ôÇ•ã~ëÈpE|Z·ØIxæ ¶Ë@†<¹åÓy9Eâ]L†jE~)GŽ}©ôì·CÙp–Y+H{h5ÉH êدÞ(³àí׎ȸ´/ý°±?ó¡ÚmNkŽ b¨B3bÊ]$ýð¦õ²gY> `*dà`  ªl CÖBÊQÃn©„Ñ‹rä–´KsV–”e‰Ò'@‹³×vÞlÝÂ;C4Áò@•ƦV$I£’¿[’j9T;åÈ¡.’Š“L%Âá¡7˜&*ìŒúÜÈØ™³ÓAÃàÔÖôtCbJÄ{6æ—ªµH$yùƒ‡[Zü|iò'@/þͰ†g L¦YôH`{Ñ£3åq K2gåwýÒÑM³×…<¡±q®¦CfàóM&[»HÒ'@÷&,~ˆ‘g†è E‹¤¶yFb!*Bæ¬Ã¿º²ñÑý¡¾ ¥|€H|im`K'ÙT"¼Âuzå Ö@^:Öawqði,©+ˆ.'sºÍ5û¼ú_«üí«Çxd‘Ò™IÔÒ Kßì¡ýìö t¤ÔE²á$Sxæ Ö Þ³íÎ TQ2ç Šw¯Ÿ´ýïî­ÕÎL=ѽ!*l³ÜE:¯‘Ús /X^:ÖnÙ…`C¨¢dÎ~ìûrú6Ã{u¼ ¹µzé÷–mí8Éž4°´tŒª(™3œÚxäOwFÁ öTø;cK¶Ù»µÿY,qm= „¶ž4°´t,ë‚V]«q¸‚àô3…;V‚ohvƒ¿™5°É6kê"Ñ'@•ж’ÓœàhÞ—ìÎ9Ü<-“ÎŽA9AY±Œ„lj[þ• A8oWÅ=®õ»ƒO@|rz¶´…Ú!<óëKÇ”´`*Jæ<„ Í4m¶­q^U!ÜèZ¿›Ïjáøi1´ç”°ÃIbj`³,³Œ ÚNßk--NY’îG¡~G!Òý?ÔúÝ(Â3op`!ȲtÌ2PÕCj'EÀÏŸE7cƒmÌk¦i³ÍQ _ª,¨0_Óéw¯ÛС‡â!é4éüû»_hßÈÛõÞ­C®2þ>û©žïÞâ\aþrÀ3^Ÿà[Kpò‰5ëܺùIxš•ž?¤Ñx!ÿ¥âÔ†.ÚᄦXƒ1¾Û…g œ2vsçÀö–¸c BJ(ÇÒ‡÷çÁûÚ-5¢Ãî‹vRU-À9ÇC ÏxÑt-!´$€R¬DËàv4V{è²ÛíeÒõàP?Çž10Õ\  e6Ì×Ð~_% þÌ:ÞÒÝef²=JT†”çÅC¦k ´üÐF¨’dôÍ:,V:"»u þ>®܉C(Q¢MÕa|§k å:³Pey6 ͆ùè/CßöÏ” †M“ù±W=i5… ¡eöë"ê>W1Á¢Ïøpk̬% ÆÁV–™rÜ:ò«@­Gq6i]–$£xKB.Ыé™e@äºÎÆßéŠdGý3¥ª9ùGÏÕ»æFNæ#}Ž#êžùÓ¤W-¤å‡Z´ÄJ£yÊxçíS&a$¿ð+I·±‹Èä{ÎÎ{ÑÙïÒ›´Œ–ò¼èá78e[sñÀͽ–X·…*Ÿýàh µ¢Nç›$¥Iÿðøáœ‚Q­BοÀþ¾YÍØÿmcݶ4BBd Äóâ¥7XAsÑŽrÝFã.[)ãÍ+Í´€Ÿ’²â‡ßÖ´NÉ™íonì÷ùU–¥e´;x…†^20`¥¹È˵±¡(¦ŒW Voë7õj͚Š^°*ɪ­ü9VÔ}ñšÍ¡½ ï1]%™£š2^X×ÕMM^[°Úh`ú'˜þGŠªc`å‡d5žfÃÐŒ8:Í¥ÆoQÎûÒVö™ Ï± Ï … Bˆ$”³ge¡¿äÏÎ$:fÕ-¿rF"÷/|-„ÿb€h«â\{‚¼Œ¥Eš366è‚"!üÄ¥¼NÚ{o°QNf;Ø®‰µ–ŀơÁ¨QV«ñ<§‡ñcPž%EaA ¾Âï¬ç>ªuY¥ …Q¬£“ŒCžbŠƒ{Š1ÐØƒý Ëý¦ÿØŸ$û)?•'Õ?nQ“û ]wÆqA!)„ØŽÖŸgÞ` ÍÅŽ›´?9|\OBòrÐÕø Þ1cØpINõ_(Ï’ Í0§‹EŠõ¥ž1°Å­‰ÿ`Λ¿À} s_ñ«¥Oùþ¬p4yù!õ_(ÏdsºX¤HÂâ[Üšî˜Pï/-®ž=bô-\:2+{öÕŠÝW„4§‡f(È“^ŸÖM¢™Bæt±H±¾Ô3¶¸5×/à7zvŽl9fì½wEænZ”,ÄPW6ÀRÿEIžTª™²l›Ûò5Už'Ž@eã&ëwléòóvä¿ØáY ¢}Œ;{ÃU²9gíùp|ƒ%‚B·ÏÿþÈé¼³ö¶ëó593ÔQ’'•j¦ì¡y±›:_¥IXŒ·¦ÖMV58Ò-Y˜·äháÕÍ|¤l†û/‰{ƒýçÿ×ûë¸ {Ô«Æi ûs@^ßMãázTÓ­ÏŸ÷SS [äÉâ0ð¼Ø˜ÆT×£êxÆ·³l¸05XŸ?÷܇M½ÕO‡p»±›Ül'ÁhÊŽB<ðéÛCc@÷G¥ž+¯Ïÿ/cƒèµ\ëŸTLD¼±?†¶ƒ-4eG)î!Ó·‡Æ€®[––¨Ï_&QÞÓüŽã»4vžüpaüo (Ï‹ì[@òúh}w×Èç75™ŠêØËKè<è • K–¬¾éñÔI¾ y}¾6 ‘0Ýšˆð¼˜‚[h^¯ï^Ó@Ò̆RÖ/mkxÆÀå7Àäí±²¬Ï¸ÅcÝã#IO&1˜p“:á’ñw/ÈBèQu Ü2= ¶óäʲy¤û·çêÙ?¤¾àÒ¡Ù³®268üräW[Õ®í>?aÌ.cƒÛPܾ\²zxhˆ&ë rLc@îßž‰h9æí×o`ýRËöB¿Š$V®Q…ÔGé:¨æ1 êfÓ≗ #$hИúPŠ$V¨ÕGqõQϘ®ƒRз‡OPÆ_úP$±’ÀF}TÕÌÉrO EßJFJg5ô+`±Xd³:ÖGUÕœ,Zœ)…]Jæ((T§êÄLHyE¢]QUÕGC¶jOTE*0L±°ïÖ_¨…}‡&¯8ƒ|c¥..¯N+Gí ÕG=c`Ń¡ÄÅúÉ ;érM¸ÑAv÷yušd=|°Q¦…g êuP™À0]n²A¤E4S–>¼7ø)Ú×n©õ,¨¨AçÍ’“¬š9Y &Ž}3”ë aºÜDƒ-ÔÅ]‰–Áíh¬°6pYªjNV¨×Aòá$ß‚aí}WïuÌ*w5ŠëI ƒ(=ûíÐïedyjðÌêuP÷æ•ùPÔÅ¥Õiîe=ôðŒC½*]¦^›… iÙ­N³Ð®(GUT ¨eć¢.9—W§e«—OaiÎʲ‘òÐ@W­Pñá.î–„\ªÓÖu¶:ÝKÊzT}õÑË’øN}( „ H‹åÊbÕ@}ô²!˜øÄÊß_™ ó¡Þ;K* -Î7™l”õ¨ªê£aà‰¤ø))«<ñ½Ÿ$ñÝ}…*4·;Ý7hWøÎ¡jªºá‰,‡»Ê†ÕÛ|‰ï͚Š^°Ê˜ø† U-¤²Љ›ž1°žÈ”ÜK Vãµ€àV“׬6˜êÎÑÄ#ÀþS(×®PL=óŒé:(Ëi¥wŸ&¾ó0!O<"O!•õPL=óŒƒ0[å`• ôîÓÄwª;ÇØSx·ö?‹%Ú$¼ÂCïˆÔúÁžêF+èÝç‰ï <ñˆ>…~˜jW¨&nºåZ« \Ä`EIäf¡ç.KšÊ³ )â‹#ÏÉîýò³¯^”ÿH•ë¨D1ÅlB`ßÊD ,bÍ=™ø^æHPV6¬Âøv–oM|ŠÇÝÿÿînÝu©”LŸ&é&9ØuÐ =¼8DË×A)¨{Iï>M|§_PÊZî¾:­Ê«Ÿ\íH«J„ðk‡æ#ÑØà)\´îß Fü/¶>DŸö¢„¥ˆq~›ªœú¨ûuPê^Rú šøNý¸„·N< YuZ•Sµµj ê^Ò»OL&¤‰GŠ“ JÕLæÿ'pþ9+ËÚ;†¤• îÓ¾è”*×¹¯NûŸaÚu®íÌ[ñàj’Ù:(ÍiuŸöE‰`Œ9 –Y-C­¸©ÁLÉüU&mV ù:(Íi¥w bJó±þ¿Ær}µÌj]„þà[“þñiU'mV‹{°l¨ú_ÑœVi_$PL¿ ”€Au’cÄß»¼øä¦QÍlúËîsh{çŽzå¡}.ÏóÊ'½Cs%¿§à„>¥„Ÿ’áü@.$Š…ø¢-¢3DþT`ÀQÚØ“‘,é:h8À(8:à„oãÀê~éŽê»ýhzµ£·×‡øú¾Û„AC0mF ÚØ‹ßà‹©Ã†sò‡DµŠ‚fÃÐ/hégu}žqvNÄM•—Pœö$;ÃÎæ™o0]åØõÒ`èȦ‰Ö M§¹ô zäþÔ{¥¾Äͼµ²nVÑ)Mm-š{ÆÀt”âDÏl©çgÕËT«hÚæR?n:À?_AÌîÍo6¾ã!I=Ûûâ*L]¼®Czoæ«l¿Å.矜ží¨ªZE¯Ü} øuBä·EZéϯb¾ƒsà(^tÛ.~$ÿH[{æ vï PÕ*ÊÑá>P|Þýp­FßÚð¨ú9PœyçoùßW¡ñˆß œôÅôßæž1°{PÕ*ÊÑá>P¼ ìàú@s|ãà(îßùiÏZjÝ÷õkóg ªUA˜qtÐ@1ý‚6Ý_RøÔ…4'€œÅ–>o·òo¶üè®h{GŸ;Ob*r„%€âîµn¼k;i6 ½wÏ㈹‘8(„¸€'œÅ{yÚÿ}ÉšW£7˜«ViÐ+i¯”ˆ‰~Aïš²dÈksãn‹hç@¡gïfÍ«‘m¨V•£®ìI§¹ô Ú5òùMM¦â…:ö²¯¸ôÔÀ¹*½Ér5Õ*‹Ò1[DL…ÃJe_Ð5=$Íl eýÒ&ŽÏÁ&ªËŽ{hÃê ÓMžìàj kަ­ý/´ù­y×¹@ù“çðHºÕÑÀæªUn‹—´2mÙ9I—wœ¡ëQ œïÿ×\µÊµ¨‘2¦-þG® L‹Ðõ¨FN·˜Ý²›Øèàofº¾ÌªÊU„Xý°r˜¶(¹*=¹à_Ip_6¢CÃËb_Õ"ôj4DS¸/ñÏ„"t-ª‘éÝw/Ëž wP䪬F¦wßýj`(x&Ü‚¡ëQ Lï¾ûÕÀ`¨²ø@j›g.Ï7XÕÈÀ”å#„¢Fí' =6”J•ŽêèE׉™pþ•Bãþ%½@½gßu¢žç£×¿¤öÕè Ö@Îòá^ÔH‹–Xö;—]¨cõhôl‡wþ¢š:¤j6ùPaEç]IÈ[žœ£æ½WÏ7XÎòA“^•ð=xYAÈѨßïÒ*ýE55°ˇ“’>#²G9âYrk““•ÚWG—žýv(žÄ,—ò¶OEÔƒ®ú ªÑ7XÏòñfeTér Þk¹¯Øª‘5wß!ËE`©½vd³[n +ñ¬cT#ÛP;ø?ˆjdàr8eù¨Ž¨–vÊòQQ½h8eù°…‚#ç ë7¹±J¬4 zÆ¢D¢’Åç?hÕ>¾G|û›>8¹¯Ñªé}öZ‰ngp¼F`³ÛÜpJi:Fõ|ƒåjîQô\FÛy/^88/:ã¹¢Ë}™vPÞ`=ËÇ7NX Ö'ôœu½oóäkÖ¹ZRª‘“åžåƒ"£üöÅõcÖdÔø²ÀTíÀ=¾Fy2u{G´ôaG52p>6'Pž&c—ûŠí z:Y•…N8Ü>N—ûtì ÆÀ*è†ÅÍKÿD÷Ë}:vP†è0 ;†ÔNŠ€Ÿ?Šn—ûtì M“ÂO¢Å3mêîOÍÁœ—ûlì ÆÀJ([Ü7°¹à‘ËTÚ †+âÔ_fìŽéßõz÷}…5v€²*ñîúPcàjŽšiR5G«9j \ÍQcàjŽWsÔ¸š£ÆÀÕ5®æ¨1p5G«9j \ÍQcàjŽWsÔ¸š£ÆÀÕ5®æ¨1p5G«9j \ÍQcàjŽWsÔ¸š£ÆÀÕ5®æ¨1p5G«9j \ÍQcàjŽWsÔ¸šãÿ²hÌG…œ–eXIfII*½0tEXtCommentCreated with GIMPW%tEXtdate:create2019-10-16T22:47:22+02:00ÉÆC,%tEXtdate:modify2019-10-16T22:47:22+02:00¸›ûIEND®B`‚paperwork-2.2.2/paperwork-backend/tests/guesswork/orientation/test_img2.png000066400000000000000000000022141456262201400272600ustar00rootroot00000000000000‰PNG  IHDRÈdÆ  zTXtRaw profile type exifxÚí–[Ž+ †ßYÅY¶16Ë¡¸HÙA–~hª3=‰F%/‘º(Úå2ÆŸMwß¿ÍðiL!©y.9G´TR኉ÇG«{¤˜ö¸[»ŸÑ«<ät0D‚»<¾z>ò9CŸ¼;r}c¨Œóàz}P!ö³À‘ß =ˆÇp¨ÇðYùxx=¶sq{ÙÚÑŸçù®°†$ÆY3Y˜8šå‚¹sL†¸õåèl\Ö{zCヌ[•á!‰}y(p_ŠÔ%Ûc^:èU½bVž‚‡h˜—;®·<·ëù Òçìê;Þ’; ·Š¼#”Ÿ÷_Ê‘ˆOyx‹ts{³rÎgƯr“˜^ö|S[לÝçÝÕ”±å|6uoqÏ w­hí·2ºáÒè+Ø«tGI4äQG’]è 1MJÔ©Ò¤±ï\L<Øpgn,Ô„…ÛÆV§Éð]ˆÒA å§/´—-{¹FŽ…;y@öŒÑÎ?èá3Js®‚"Z±ôG¬à¯Jƒ‹Qˆ50 y‚ª;Àwß×ÅLw˜¬ñZ€ÿRú‘\²A qXÈdý@ˆàˆ™D)S4æ`D¤P…ë,‰/`!Uîp’“ ÄŒQXïmUV~ˆq„Jb`ƒÒ¬”ùcÉ‘Cu™T5«©kÑš%¯ ËÙò:Q«‰%SËfæV¬O®žÝܽx-\'®ÔcñRJ­X´ÂrÅÛ µ^|É•.½òe—_åªC“–š¶Ü¬y+­vîÒQÇ=wëÞK¯ƒRi¤¡#>ʨ©6e¦©3O›>K˜õIí`ý©ÿ5:Ôx“ZŠö¤©Ùm‚Öq¢‹ˆq"·E€$0/fÑ)%^ä³XU¡ 'uÁé´ˆ`Ä:éÉî9 ’ÿ·ü7È……îä~æö+j½î:Ù„V® FAõM•üb~|ñ“Š_†¾ }úG ÉÄi¿Šá,ºÕÌ+E:bKGDùC» pHYs.#.#x¥?vtIMEã 77ŠItEXtCommentCreated with GIMPWÞIDATxÚíÓ± 0±ýg~X€–Îᤫ$ý€Õ— ƒ€AÀ `0  ƒ€AÀ `0  ƒ€AÀ `00 ƒ€AÀ `00 ƒ€AÀ `0`0 ƒ€AÀ `0`0 ƒ€AÀ `À `0 ƒ€AÀ `À `0 ƒ€AÀ ` À `0 ƒ€AÀ €AÀ `¸4¹ÒÁ_ýù8IEND®B`‚paperwork-2.2.2/paperwork-backend/tests/guesswork/orientation/tests_pyocr.py000066400000000000000000000063751456262201400276210ustar00rootroot00000000000000import os import shutil import tempfile import unittest import PIL import PIL.Image import openpaperwork_core import openpaperwork_core.fs class TestPyocr(unittest.TestCase): def setUp(self): self.tmp_paperwork_dir = tempfile.mkdtemp( prefix="paperwork_backend_tests" ) self.test_img = PIL.Image.open( "{}/test_img.png".format( os.path.dirname(os.path.abspath(__file__)) ) ) self.test_empty_img = PIL.Image.open( "{}/test_img2.png".format( os.path.dirname(os.path.abspath(__file__)) ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.doctracker") self.core.load("paperwork_backend.pagetracker") self.core.load("paperwork_backend.guesswork.orientation.pyocr") self.core.get_by_name( "paperwork_backend.pagetracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.core.get_by_name( "paperwork_backend.doctracker" ).paperwork_dir = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.pillowed = [] class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000000000 def pillow_to_url(s, img, url): self.pillowed.append(url) return url self.core._load_module("fake_module", FakeModule()) self.core.init() self.model = self.core.get_by_name("paperwork_backend.model.fake") self.core.call_all("config_put", "ocr_langs", ["eng"]) def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_paperwork_dir) def test_guess_orientation(self): self.model.docs = [ { "id": 'some_id', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_boxes": [], "page_imgs": [ ("file:///some_image.png", self.test_img) ], }, ] angle = self.core.call_success( "guess_page_orientation_by_url", 'file:///some_work_dir/some_doc_id', 0 ) self.assertEqual(angle, 90) self.assertEqual(self.pillowed, ['file:///some_image.png']) def test_impossible_guess(self): self.model.docs = [ { "id": 'some_id', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_boxes": [], "page_imgs": [ ("file:///some_image.png", self.test_empty_img) ], }, ] angle = self.core.call_success( "guess_page_orientation_by_url", 'file:///some_work_dir/some_doc_id', 0 ) self.assertEqual(angle, None) self.assertEqual(self.pillowed, []) paperwork-2.2.2/paperwork-backend/tests/i18n/000077500000000000000000000000001456262201400210515ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/i18n/__init__.py000066400000000000000000000000001456262201400231500ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/i18n/tests_scanner.py000066400000000000000000000030021456262201400242710ustar00rootroot00000000000000import unittest import openpaperwork_core class TestScannerI18n(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.i18n.scanner") self.core.init() plugin = self.core.get_by_name("paperwork_backend.i18n.scanner") plugin.keywords = { "centrally": "CENTRALLY", "feeder": "FEEDER", "flatbed": "FLATBED", "left aligned": "LEFT ALIGNED", } def test_i18n_source(self): self.assertEqual( self.core.call_success("i18n_scanner_source", "flatbed"), "FLATBED" ) self.assertEqual( self.core.call_success("i18n_scanner_source", "fEEder"), "FEEDER" ) self.assertEqual( self.core.call_success("i18n_scanner_source", "feeder toto"), "FEEDER toto" ) self.assertEqual( self.core.call_success("i18n_scanner_source", "toto feeder"), "toto FEEDER" ) self.assertEqual( self.core.call_success( # Brother MFC-7360N + Linux (Sane) "i18n_scanner_source", "feeder(centrally aligned)" ), "FEEDER(CENTRALLY aligned)" ) self.assertEqual( self.core.call_success( # Brother MFC-7360N + Linux (Sane) "i18n_scanner_source", "feeder(left aligned)" ), "FEEDER(LEFT ALIGNED)" ) paperwork-2.2.2/paperwork-backend/tests/imgedit/000077500000000000000000000000001456262201400217145ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/imgedit/__init__.py000066400000000000000000000000001456262201400240130ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/imgedit/test_img.png000066400000000000000000000107061456262201400242410ustar00rootroot00000000000000‰PNG  IHDRÈdÆ bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEã Šv°­tEXtCommentCreated with GIMPW.IDATxÚí{LSgÇ¿U£»ˆó‚,ËØE§Î`Vo+ÃédØéTQ§Sücj†:¶™ÇܘºH¼y™™&ÌBp@ âP§"rS¬N[ÑV Š”~ïïÛ¾@O¡=¥Pô÷Išè9çyžßóœómŸ Ï÷HˆˆÀ0Œ ½¸ †Â0,†a0 „aX Ãað@†Â0 „aˆ^¯‡D"õÑét€°°0H$TWWÛÔ矉DFã´ŠwEÎ`åÊ•H$¨¨¨àXø„a\P ýúõY|êêêÌ×TUU ^ãææÆ­Êð/ˆ3‰ÁÓÓ³G—Áô|útE! …éééP©TÀ¼yóàëë ‰D"8>غu+Ôju«X¯×ãäÉ“ÈÈÈ@^^@&“aܸqðóóÃðáÃíƒ8»ŒG¡¨¨§OŸFqq1òòòðÊ+¯`Ú´ix÷ÝwñÆoØœWAAÆoþÿ‹/¾Øêü‰'0uêÔVÇŠ‹‹¡T*‘ÒÒRL˜0AAAÆóÏ?/8ö´¥îbbé±ÔÕÕ@UUUí^J(%%…<<<ÌéZ~8 ˜ö³Ï>#¤V«ÍÇôz=EDDæcúüûï¿6×¥+ÊøñÇÛÍë÷ß·9¯‹/¶›×‰'Ì× Úµk—Õk‡N………­ò·§îöÄÒÓqº@PLL ©ÕjÒëõT[[K …Â|®²²Ò¦‡7''‡ÐÂ… ©¬¬ŒêëëÉh4’V«¥’’Ú¾}»`^ö¤³Ë8x𠥤¤F£!NGƒ´Z-eee‘T*%tõêU»nØŠ+ݾ}Ûê5‡2×ãܹsT[[Kƒª««é?þ $•JI«Õ:Tw[bat ¨¨(jnn¶8M(''Ǧ‡7!!ÐÙ³g;¥â]QF{œ>}šÐž={:U Z­–<<<ÈÏϯ•„”œœìPÝŸ8}nZi‹L&3φÙÂ!C7oÞtZ¬]Q† ///0÷õ;‹ÂÂBTVVbÉ’%4hà5>>>€3gÎtKÝy«C‡<þÜsÏlÊÇÛÛR©¡¡¡X·n”J%nܸƒÁÐi±:£Œ’’ìÚµ }ôÆŽk^P8p àÒ¥KÚÞ7nÜ„‡‡[]Ì}ùå—[]ÛUí˃t.–µëòòò%$$ØÔý!"R«Õ´qãF‹çŽ;H£Ñ8ÜÅêì2~ýõ×v³¦Ogv±vìØaS™hÖ¬YÕ»X.†§§'¢¢¢ ÓéP\\ …B¹\Ž5kÖÀÇÇjµÚeÊ(//Gxx8<==‘••…ªª*èõz477ƒˆP__ï”6zæ™giii‚ ¹-?Gíòöå.VпxyyaöìÙˆ‹‹Cbb"4Å ïÎ2JJJ[·n…¿¿?ÜÝÝÑ·o_óxìþýû¢âϵĴVqîÜ9§×½£XX .Â믿îô¦½e˜úîO=õ”ày±b6ý)µ±›T*…››¾ùæ:µîÅÂéBâããqäÈ\¿~555hjjBCCT*vîÜ v­L;»ŒaÆ6n܈‚‚|hqÞÝÝ?ÿü3`Á‚ÈÈÈÀ½{÷ÐÔÔ½^êêjaïÞ½øû↑{G±ð ½ é[¶liwÀ¹hÑ"ª­­uhÞ™e Z»v­Õ¼Ž=*j^VVÖáêµÑh¤}ûöu8HÏËËs¨î¶ÄÒÓéÓS„¼jÕ*øûû#??EEEÈÏχ››¦L™‚iÓ¦Á××O?ý´Ë”ѧO|÷Ýw˜4i’’’——‡1cÆÀßßr¹Ü<Õ*¦»SPP€#GŽ ;;¹¹¹×ôîÝË–-ÃÔ©S‘“'OâÂ… 6l¼¼¼ •J!“ÉðÚk¯9Tw[bééHؼšaóA:ð@†Â0,†a0 „aX Ãa†Â0,†é:ôT[ÆqºÓ{W¡P@"‘ ##ƒA†»X ó8 „=l™'™÷ƒXó° ÃáÇQUUN‡ääddff¢®®Ó§OÇ‚ 0zôhÿõ¾JIIÁŸþ‰¢¢"aáÂ…xóÍ7-ÊsÄÏöáÇHKKCrr2 àíí ¹\Žàà`(•JÌ™3ééé˜1c†`z{½lm¡¤¤ÙÙÙæ<}||0qâDbĈ­öu·lÓ 55YYYÈËËCRRÞ~ûmQqÚÛ¦]á õõõ8~ü8’““qáÂx{{ã½÷ÞCpp°ë(D¬=ŽiÇ`RR’Õ]h¤R©H&“ ž?uêT§ùÙjµZš?¾`šùóçÓÞ½{ ¥§§ îþ³×ËÖ–…Õ¥­]N{mzêÔ)ÑqÚÛ¦Îö&"ª©©¡Å‹‹º_.e=Ú‘@P\\ݹs‡©ººšbcc Í;—‚ƒƒé믿¦›7o’^¯§ššÚ¿? É“'“^¯ï?[“•é’%KèÊ•+d0¨¡¡.\¸@þþþæX…\Œ—mG˜¬À¦‰ÈÈHܽ{W°»·oß>H[ÄúÙ¾ôÒKˆŽŽ†N§ÃºuëP^^£Ñ½^K—.áÓO?m·¯+ÆË¶£‰‹Ý»w>øàdee¡¦¦ÍÍÍÐét(//ÇîÝ»qçλ&CÄÄéˆG°³|€===±iÓ&ÀÚµkqåÊóý:þ<>ùä×y(]±æ½»iÓ&@eeeí.¤åæævŠŸ­V«5¯­@`eö§Ÿ~"¤T*-ÒŠñ²µe%=..NÔJºµ6§#mê,`"¢û÷ïÓÂ… ]~%Ý¥¼yñ³4h~ùå„„„ )) ………ÉdËå˜9s&’““@Ð[WŒ—­-u‰ˆˆ€ŸŸŸùo”T*&OžŒñãÇ# @p  =ÄÄéH›:ËØ4ƒµwï^Ì™3Çü·s2™ 3g΄\.‡R©t‰gò‰ñæýâ‹/‹òòrŒ1 Ãù×®]ÃÈ‘#!•JqæÌ«V†qéAº#ܽ{ñññP©TÐétæñéÓ§±téRó,‹ƒ±«Ûÿ¸T¤¹¹¹ÝÕâõë×ãý÷ßç;Î<™],"BII Nœ8ÂÂBäççÃÝÝï¼óàããÓ៽0Ì;Hg˜'z Â0,†a0 „aX óØ $,, ‰Äe6°ÄÄÄXÝÞiú,^¼¸Ušžè/ìjíÎaÆ‚»r–––æZ| ÿ‚0 ÿ‚´ƒJ¥‚B¡€R©Duu5ba©SWW‡‘#GbàÀ¸xñ¢ys[rssáëë‹mÛ¶µ»ëÏÙØë+«×ëqòäIddd˜ý¤d2Æ???ó^í¶ØãÓÛF…Bôôt¨T*`Þ¼yðõõípß8ã ¶ºý%&&ZÝ-vðàA‹tÛ·o·Ø1Ø–Õ«WÛí>¸eË@iii6§±¶+RŒ¯¬^¯§ˆˆˆvwϵuwtħ7%%…<<<Ó8p€˜n¶méûí·ßÒíÛ·Éh4R]]¥¦¦šÏµ}JKK ­^½Z0_“ýäܹs[ùÏv¥@ÄøÊæää˜Ó”••Q}}=FÒjµTRRBÛ·o§ÊÊÊNõ鉉!µZMz½žjkkI¡P˜Ïµ-‹é&Ì;×ÂhºåCÙêxSS“y¸F£±HwàÀ@ÇŽ³+`“@Úû´ÝÓ-$±¾²¦‡ýìÙ³]âÓEÍÍÍVͺsrrø)voÞˆˆôíÛ×âxPP€ÿú¬¶tÚëÕ«—yF۽̃ÁìúazçEW#ÖWvÈ!€›7oÚ\Ž#>½¦õ¶Èd2´9bºaËÚæþ`Ö¬Y,Ýð&Mš777ìÚµËìÏ—/_Fnn.6oÞlÕÔ–i^k.~¶ØVŠõ•õöö†T*Ehh(Ö­[¥R‰7n´ª_Kõé:t¨àq“ͪ5Ï*¦‹b²ÓÂ䟤×ë-nbtt4rssqùòeóñÔÔT€\.ï¶Š‹õ•vìaGîÑ£G#$$6lÀ½{÷ð×_–/_Þ­[`;Ó·ÿþðòòÂìÙ³‡ÄÄDh4šV‚r†O/ã‚i;Ž0azÑ{dd$ `Y@¯^æ—¡äææbÿþý€)S¦tkÅáÉkzßE˼3|zHbb"¶lÙ‚ŠŠ 455A§Óáøñã ³µŽ¦ÁúòåËqøða¬_¿^ô[c; ±¾²ñññ8rä®_¿Žšš455¡¡¡*• ;wî€Vou†O/Ó…tÆJúo¿ýÖá|ò?ü`¾ÞÖ5g/Šñ•íhfÑ¢ET[[ëtŸÞ¼¼<@ ¼Xá Þ¼¾¾¾(//GRR233qïÞ=!$$'Nì0ýŒ3°víZøøø@*•ºÄ—ƒ_ÙU«VÁßßùùù(**B~~>ÜÜÜ0eÊL›6 ¾¾¾þ¿Îðéeº†.³ýÉÌÌÄŒ3€?ü[žy¼Æ Ž`4Íýý©S§r«3=§Ï³644àØ±c8tè¾üòKóëÒæ‰îbUVVZÌT]»vÍ®wl0ÌcßÅ5j"##qùòeÿ ÿ Ãa†Â0,†a0 „aX ÃaÃôhþ›…ý dARIEND®B`‚paperwork-2.2.2/paperwork-backend/tests/imgedit/tests_all.py000066400000000000000000000026021456262201400242600ustar00rootroot00000000000000import os import unittest import PIL.Image import openpaperwork_core class TestImgEdit(unittest.TestCase): def setUp(self): self.test_img = PIL.Image.open( os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_img.png" ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.imgedit.color") self.core.load("paperwork_backend.imgedit.crop") self.core.load("paperwork_backend.imgedit.rotate") self.core.init() def test_get_names(self): out = [] self.core.call_success("img_editor_get_names", out) out.sort() self.assertEqual(out, ['color_equalization', 'cropping', 'rotation']) def test_all(self): editors = [ self.core.call_success("img_editor_get", "rotation", angle=90), self.core.call_success("img_editor_get", "color_equalization"), ] # the input image is 200x100 frame = (50, 25, 150, 75) for e in editors: frame = e.transform_frame(self.test_img.size, frame) editors.append( self.core.call_success("img_editor_get", "cropping", frame=frame) ) img = self.test_img for e in editors: img = e.transform(img) self.assertEqual(img.size, (50, 100)) paperwork-2.2.2/paperwork-backend/tests/index/000077500000000000000000000000001456262201400214015ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/index/__init__.py000066400000000000000000000000001456262201400235000ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/index/tests_whoosh.py000066400000000000000000000076151456262201400245150ustar00rootroot00000000000000import shutil import tempfile import unittest import openpaperwork_core class TestIndex(unittest.TestCase): def setUp(self): self.tmp_index_dir = tempfile.mkdtemp(prefix="paperwork_backend_index") self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.index.whoosh") self.core.get_by_name("paperwork_backend.index.whoosh").index_dir = ( 'file://' + self.tmp_index_dir ) self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) self.core.init() def tearDown(self): shutil.rmtree(self.tmp_index_dir) def test_transaction(self): results = [] self.core.call_all("index_search", results, "flesch") self.assertEqual(results, []) self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Whoosh and Flesch are\nthe best', 'labels': set(), } ] transactions = [] self.core.call_all('doc_transaction_start', transactions) transactions.sort(key=lambda transaction: -transaction.priority) for transaction in transactions: transaction.add_doc('test_doc') for transaction in transactions: transaction.commit() results = [] self.core.call_all("index_search", results, "flesch") self.assertEqual( results, [ ('test_doc', 'file:///somewhere/test_doc') ] ) def test_sync(self): results = [] self.core.call_all("index_search", results, "flesch") self.assertEqual(results, []) self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Whoosh and Flesch are\nthe best', 'labels': set(), } ] core = self.core class FakeModuleToStopMainLoop(object): class Plugin(openpaperwork_core.PluginBase): def on_index_commit_end(self): core.call_all("mainloop_quit_graceful") self.core._load_module( "mainloop_stopper", FakeModuleToStopMainLoop() ) self.core.init() promises = [] self.core.call_all('sync', promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) promise.schedule() self.core.call_one('mainloop') results = [] self.core.call_all("index_search", results, "flesch") self.assertEqual( results, [ ('test_doc', 'file:///somewhere/test_doc') ] ) def test_suggestion(self): results = [] self.core.call_all("suggestion_get", results, "flesch") self.assertEqual(results, []) self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'mtime': 123, 'text': 'Whoosh and Flesch are\nthe best', 'labels': set(), } ] transactions = [] self.core.call_all('doc_transaction_start', transactions) transactions.sort(key=lambda transaction: -transaction.priority) for transaction in transactions: transaction.add_doc('test_doc') for transaction in transactions: transaction.commit() results = set() self.core.call_all("suggestion_get", results, "Whoosh flech best") results = list(results) results.sort() self.assertEqual( results, [ "Whoosh flesch best", ] ) paperwork-2.2.2/paperwork-backend/tests/model/000077500000000000000000000000001456262201400213725ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/model/__init__.py000066400000000000000000000000001456262201400234710ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/model/doc.pdf000066400000000000000000021522241456262201400226420ustar00rootroot00000000000000%PDF-1.5 %ÐÔÅØ 5 0 obj << /Length 809 /Filter /FlateDecode >> stream xÚuUKÛ6¾ûW¨§PÀZ+Jeµ‡A[`- ‚¢í+q-ÅéRt ï¯Ï ‡Zy‹>h曇曇üa¿¹ÿ•W ¯³‚W"Ù?'çYS%RYєɾKþd_ÒzÇôØÚI§Û2/˜·øäìcZH¦NéÚ]P³îH>?¤ï7¿ì7<ÉáÇ^ˆl—‰àE&ó*i§Í?›LÖu#ƒÇLU^¥uV-ðýÃÄ“Ÿíæü–ÄÛ%óö&õ¤¶K𬑅Db¼l²ZȤlŠlW7Älßë+”Ûp¦œ&á`s@1Ò¨sÿi- õв=“Ò:õrMw%ËÒ­ä;öÊöìÈzê­‰QÛ9œòÖÝ¥[‘W˜©^Ÿ”9®†]0@ŸÈ!à‰£©¨òN=zyíÞÍÅ%›[z^dGÌUÊ5WðéR(å°D-H1åebˆ^èrfбúO’‡Ï"|ðñÕZO3AãpDZš45ŽäaŸ™<ÒDÃ÷zö²Ž’yw¥ &ÏÎY,àbÈ%ö”³é´[ÜÍL ¼- 'µ´}†UBàÎîØŠ’Û:RPz…ÚëÄ_ËÌiÕݽ¡§ÑŽjž‡ç°ÐÃR”L™…‚Mz²nxÁT‚³¯çÙ>BZ5kBÖ*0,Tq%ÅhÝ‘wl`£‚¹)!ö»¥¬œˆƒübÀWû’×—•‚]‚bÞy,¾,Ù¥h—È> stream xÚìÝwXTÇû?ü*‚X{£bï½[,(–Ø£1öh$FK4` ŠŠŠ1ÑøÑD0"JèÒ¤H‘.½÷Þ^÷ûÜ—sýöâQ\—aËûõ‡×²;gΜ™ÙõÜçÌ™ù¿ÿ QSSãáá¡««»mÛ¶)S¦ 0 sçΟ}ö™¼¼¼²²²ªªêÂ… wïÞ}íÚ5//¯ŠŠ Ô@›«««³µµÝ°aƒ’’Ògkß¾½ººú­[·222P‡­¯ªªêöíÛƒ âEëÊÊÊk×®=w©©··wDDDâ[AAA...÷îÝûå—_–-[FÉx›ÈÊÊΚ5ëÏ?ÿ,))A•´,ŠÅV¯^}çÎT¼ÃÊÊjðàÁ¼pþ»ï¾£@¾®®Nm¹\ndd¤®®îäÉ“y~çÎ)“ððpÔ-@óyxx,X°€\ô<gýúõ¬oôêÕK__¿¼¼\èÜ’’’.]º¤ªªÊ ð544‚ƒƒQÏÂyõêÕ’%KxA–ŒŒÌ‹/P-À2„:†œœÜ?üÐRƒçëëëíìì(¢—••e½nݺu‘‘‘¨p€&…l+W®|g~³]»v¡f€±µµUTT¤^1hÐ __ßO±‹ðððõë×S\ÏæÖ;yòdsH‰ÐÐÐ5kÖ°`JVVvãÆôºOŸ>………¨ ?¦@›zÅÂ… óóó?é¾^¿~ýå—_²+KªªªŽŽŽ¨€FEFFRÏüLÑ=Åøñññ:t wLLLPEðoïÔ·k׎ºõÊÊÊÖÙ©µµõ€XÏÔÒÒª©©ACð$''ïÛ·ONNŽÝ]¼xq@@ûhõêÕôÎìÙ³¹\.* üüüØðû7 8ã}K)..Þ½{7ë¢sæÌIOOGs¤¦¦RDÏn¿²pÉÝÝ÷é‹/Øh|^˜Ò,77—Ý4_´hQuuu›”áÑ£GJJJT†¾}û†„„ Q@j¥¥¥iiiÉËËó"ú÷纟6m¦Ë¦¾¾žÂyêÆ kÛ™bbbÔÔÔ¨$]»vussCÓ€´ÉÊÊ:|ø0/¢Ÿ={¶‹‹ËûÉèÓ:¤¥¥¡ÒàæÍ›ÔDá.yAAÁÌ™3©<ÔíííÑ: %rss=J¡‹è§M›Æ'&bëÜíÙ³õ :u¢þpýúu)RYYÙòåË©HŠŠŠ>>>h#l'Ožd¡™0a‚••Ÿ©ð222Ø4zÁÁÁ¨=`Ó'Ι3§¾¾^tJUUUµpáB*X÷îÝ#""ÐL ©œœœºtéÂ"ú1cƘ››trû[·nQâ‰'¢öÀÅÅ…:ƒœœ\hh¨¨•­¤¤dêÔ©T¼Áƒs84H$ö$òˆ#Œ¼ßºbÅ ÚDGGµ'å¸\îäÉ“©38p@4K˜››;pà@*¡¦¦&VcÉãááA!Oûöí›4ý]Ïž=i+Ú(嬭­ÙtyÙÙÙ"[HêáTÎk×®¡É@°éïvìØÁ?YEEïunn.´Í0cÆ ê ?üðƒˆ—óÆìúCBBZ $Fdd¤Ì[aaa|’egg;::VUU±?ÃÃÃ)DêÔ©*PʽzõŠ öÈÈÈñ¢r¹ÜyóæQi/^ŒÑø 1Ž;F‘Î’%K>” ¶¶6--ÍÊÊ*??Ÿ÷¦¯¯/mÕ«W/T ”Ûºu+õ„Í›7‹Ei£¢¢äåå©À?FÛ€ ˜½OŸ>|œ’’’°°°×¯_:88ÔÕÕ±÷ÙýúŽ;â¾§4ãp8:t žàíí-.e>}ú4øóÏ?§ÎqgeeE1N·nÝ>;ÏE±|jjjrr²‹‹KÃÖæ³çëóòòPRëöíÛÔF%Fe...îÞ½;ûþýûhAw_ý58ûöí{ç}.—ëççB±|xx¸³³suuõ;i @ÛZYY¡¥Öœ9s¨èêêŠW±/]ºÄ–³Ç-{kõõõl­:;;»†ïçää¼|ù2,,ŒÃᘙ™ÅÇÇ7ºùŽ;hÛƒ¢&¥S^^ž¬¬,õ¤¤$ñ*yYY™²²2•ü¿ÿþC;€øbsß)((4„`ccSPPð¡Í-,,hó®]»–––¢2¥Ð£G¨¨©©‰cá9B…_ºt)ÚÄ×Å‹)´Y¾|9û³¼¼ÜÇLJ‚}záàààééÉ”2}:hÐ ÊáÆ¨L)Älˆþ²õŠŽŽfË;b-{_7n¤¸LGG‡ýYXX󖇇‡Ã$‡ëׯSÊÊʹ¹¹¨O©ÂårÙJ ÏŸ?ÓC˜;w.•_OO­ bjäÈ‘×XXXðÞquuuss«©©0J9jÔ(ÊdëÖ­¨O©Ì:,//ÓC¸qãÂôéÓÑš Žêêêäää(®‰å½)à¢uUUUeee¼Klò´Û·o£V¥Ç•+WÄýùôÔÔT6?== b§  €-@_TTÔ¤ lllrrrxïhkkS>òòò/_¾DÅJ‰Í›7S£Ÿ={V¬bâĉtFFFhP;qqqÑ´k׎Ëå ¸III‰——WHHõ §Ð¯¯¯ÿòË/)·.]ºøûû£n¥ššµ¸¥¥¥X…––ÅÞ½{Ñ  vbbb(¢éСƒ ‰ËËËÙúw©©© ùùùï„ü3fÌ  »wïˆê•lì!Ž””±>333ñ]ª¤\vv6‡_YYÉ?err²OLL ‡Ã±´´¤Ðž÷p}CÅÅÅS¦L¡ ;uêdccƒ–`~~~ÔÐݺu|°‡hÊÈÈ ‘‘‘yóæ šÄ …ól¾»¤¤¤¥)(( Î××—bv//¯†Ãïß—ŸŸ?{öl6¼ÿÞ½{¨dIõ×_Q+«««KÀ±tïÞŽ…ú9šÄ[¢ÎÜÜüýjkkCCCCBBâã㜜RSSÉ“¶|žœœîJªÃ‡SkiiIÀ±Ì™3‡ŽÅÐÐÍ bgÇŽÑ|ÿý÷ï¼_TTD|tt4½pvvpEûÚÚÚ°áý{öìA Kª5kÖPHÀ±ìÞ½›ŽåäÉ“hV;æææѨ¨¨TWW7|?77744ÔÕÕ5""‚ÿÀû†JKK544ØÓÊ:::âþä5ð1mÚ4jh333 8–³gÏÒ±|óÍ7hV;UUUìáâû÷ï¿ó‘‡‡GzzºàYeffNš4‰M°ÿðáCÔ­dëß¿?µµ———Ë;wèX–/_ŽfqtîÜ9 júöí[RR"t&¡¡¡¤|”••]]]Q«’­¾¾¾]»vüg\#t,“'OFË€8*//0`Å56lnä¼££c—.](‡!C†DEE¡J%[!QFFæ£+$Š777:œaÆ¡e@L¹¸¸ÈÉÉQhó믿6uÛû÷ï·oßž¶6mZNN*SS‹wïÞ]2ÇÛÛ›gàÀhY_—/_f“ØŸuƒ%K–HÆá°ËsçÎEË€(--íÕ«âÞ¸qƒ½SXXHþ† :uêÄ ð•••)À733+++C¥I¶ŒŒ ~ýúñZÿ‹/¾(**BÍH³¿þú‹zÂòåË%ãp®^½J‡óÕW_¡e@2\¿~Nq)Ž{ç¦<…ü¦¦¦›6mêܹ3/Ä£×ô½OŸ¢ê$ussó+V>|¸ºº"匌Œè믮®.‡sôèQ:---´,H†ŠŠŠîÝ»ÓYîÓ§OMPUUåììLçÀ½{÷æø;v\¼x±ANNê@²={öŒ¾õS§N•ŒÃÙ¼y3Ž®®.Z$Æ?ü@g¹§óOVWWçééI~ÿþýy¾œœÜœ9s(ÀÏÈÈ@MH$¶~ý¨Q£$ãp&OžL‡cjjŠ–‰-óVll¬€›DDDèèè°åÏYYÙ)S¦Ð›111¨RIâååEßñJÀ±p¹\¶Hhh(Z$‰ºº:è;v¬©†„„hkk;ö³&MštáŠýQ±€¾ælþL 8–ôôtv’­ä 1ØÂOªªªBç§§§7}út^€?räÈS§Np¹\T2€˜JHH ¯sûöí%àXìíí›ù[ š8Žœœî6}ZZÚÝ»w544( àøÜ·oŸµµumm-j@ì~ع¸¸XÜåܹst 6l@³€ä™5kVÃ…ì[$022¢_^^ž૨¨lß¾|¬ž FØ3éáááâ~ +W®¤¹zõ*Ú$ÏùóçétwéÒ¥-žsyy9òÎwîÜ™àwêÔ‰B~ üKJJPù"NMM¾¶öööb}\.—­×éêêŠ6ÉÀ¦¯©©yÿÓôôôæï¢¢¢Â‚ünݺñ|EEÅuëÖÙÙÙ¡ DÖÒ¥KéÛú×_‰õQDDDÐQtèС¬¬ m ’‡Ây6`þýyìÓÒÒ’““ÃÃÃëêêš¿¯êêj‡}ûö±{gDNN.%%­ švïÞMßÓÓ§O‹õQܼy“ŽbþüùhPT&L “^“wÞçp8¡¡¡nnn>>>ׯ_§Ÿ^ÐûÍB_WW÷òåË#FÐ~ÿøã4€h:{ö,}IwìØ!ÖG±zõj:ŠsçΡA@RmÛ¶NzÏœ9óÎûé[XXdffÒëøøøWW×ôôt›   ´´´f.c§££CûýòË/Ñ¢éï¿ÿ¦/©ºººøBUU›âÃÛÛ ’êÒ¥KtÒ«©©ùÎûnnnîîîþþþfffyyyôfaa¡¥¥¥­­íÇ#""¬¬¬’’’ØÉsS÷Hû•——/--E+ˆ OOO¶ž…øýXÑ!ôêÕ«E&M¶Óyï”)SÞÿˆ¢õôôtggçgÏžåççÓ‹¬¬,ú('''44ÔÑÑ1888&&†‚ý°°°´´4Á÷ËårûõëG»¶°°@+ˆ ’’YYYú’fddˆé!ìÝ»—Ê¿{÷n´&H0 Õé¼WUU•Ošúúz:ÃOII‰ˆˆ°µµ¥HÜÁÁB~ ükkk)œ§ßÌÌÌÔÔÔßß? €6ä.<;åÞµkZ@4}þùçô%Ó¥+êêêúôéCå·¶¶FS€cKÝ)++ ˜žÍ§÷ôéS+++__ßääd.—ûæÍ ü)®ÏÌÌôôôôððprrª®®®¯¯ÿPV´9íšN¼Ñ ¢iýúõô%ÕÕÕÇÂ;::Rá»téRQQ¦ –@§¾²²²|ðFQ GgÎ×®]£ÞÒÒ2::šÞ/**Š{+$$$<<ÜÐÐ>ÍÉÉ©««£0ÿØ(ßÄÄD4„ôÈÍÍuwwgK(ÖÔÔ BDÙ… èºqãFq,ü×_Aø %A[M^èùë(ZOII±µµµ²² 655ˆˆ`égeeùûûÇÆÆÞ»wÏÞÞÞÑÑñmÇŒC»~üø1BâUTTŒ7î³TTT¾ÿþ{ê0¨ÑdccCÍ4bı+yYY™’’ÞÝÝí’-==EX-rç4''ÇÇÇÇÒÒ’|ŠèŸ?^RRRXXXYY™””ôþ}ù]»vÑ®øá4„«¯¯¿}û6{Ò™¡×C‡•——gÊÊÊnß¾=77u%š¿Ô@ÅÅÅâUr¶HßàÁƒ›: @ìÄÅÅÑÙ¯œœ\Ëf[WWI§Ö666<ÈÎÎn4ÙÝ»wiï3gÎDCHªØØØyóæ±ø½oß¾úúúl,Çÿ½éñìÙ³¥K—ò>õññA‰ ©ulmmÅ«ØS¦L¡b_¸p-/44”Î~•””Zt+–í]^^¾ªª m!a²³³<ؾ}{jâŽ;^¼xñCÓ—¹»»6Œ’uíÚõõëר:‘²cÇjšcÇŽ‰Q™}||¨ÌÔ÷x‘$˜¯¯/÷ìÙ³MöN±§N¨AAAh ‰ñæÍ›3gΰ–%óæÍ‹ŠŠâ¿IqqñŒ3(ñ¸qã0™žHù矨]&Ož,Fef3æmÚ´ ÍÒàÙ³gtEʈ#¨]=z$¥=|ø0fí©rèÐ!:ÖÒÒj«=z” pàÀ´…ø²µµå-`§¢¢ríÚµ†ñ{UUUZZšMjj*ÿ|œ)‡ JEÊ‘#G¨]¶mÛ&úE-((`€ˆÝDB[±b߸q£­ pëÖ-*ÀÒ¥KÑâÈ××W]]EôŠŠŠ'Nœ(**â}Z[[‘ô–‹‹ ÿ £¢¢(T¬HqrrbWlÀMlÈÇøñã¹\.¤Ä!Cè4ØÆÆ¦­ `kkK>|8ÚB¼DFF²g(ØÄãÈÊÊj˜ ¢¢ÂÚÚ:000--ÍËË+66¶¼¼œžlV|T¯H©ªªêܹ35«««(—333SQQ‘ÊinnŽV)‘ÍⲜœœ¶*CHH€¢4‡¸HOOß·o_»ví¨áddd6lØÇû´®®ŽÃáøùùççç¿xñ‚š˜Þi4ŸwÞ166¦<§M›†J5Û¶m£¦Ù¿¿(’ŠG…œ2e nÖ€ô°´´¤Óà¡C‡òOfccãååU__ÿ)Ê@e••Å©¸è£ðüçŸVPP`—ƒ-ZÐ0AmmmTTÅò)))¡¡¡®®®ïï$++ËÚÚÚÃÃã÷Ïœ9#.ÏqKj/¶ &5±h–0..ŽMƒïèèˆöéqêÔ): Þ²e ÿdæææOŸ>533£¿epÞ˜ŠŠ ´ˆÈ*//¿té[‡Ž­fþNôT__O±¼½½}ZZZrr² ýùþµ ¼¼¼ÌÌL“¤¤¤÷שŸ>}:e~óæMT¸¨©®®f­ÿüùsÑ,áªU«¨x_|ñ ¤Êüùó™4"zÞëÄÄÄ'o…††¶HJJJX¨HZDÕÖÖþïÿëß¿ÿgÿÏÀ)ô¦°ý”aaaqqqVVVYYYN°Æápœ£¢¢ üüü~J[ÉÈÈPþÔÇPí"hïÞ½Ô:k×®Á²ÙÛÛSÙäääBBBÐR =(ÈbHGFFòIVSSC‘ÚûïStÆüØØØæ£¾¾žEsÉÉÉh‘ÂårŸ>}ª¦¦öYcdee—/_Þ°õsssƒƒƒKJJÞÏŠbv;;;Šè‹ŠŠèý™––Ö0ÍŸþIÙŽ;5/š^¿~Íbç÷/é´­êêê‘#GRÙ:„f©Âæ(ûèÃõ!!!ñññüÏö)º777zò=yyy*ITTEtdff.^¼˜…ð]ºt9}úôÝ»w¯]»vñâÅLœ8‘}Ô±cÇÿþûÿÅŠ÷>|Z^^îîîNé322 ßI9iÒ$ÊðÂ… ¨|‘5cÆ j#mmm‘*Õùóç©TÝ»wÏÏÏG€TÙ´i ÿðÃü“QÌ.Hnõõõ>>>fffµ•–– ^ Þýú¤¤$ñª@ W{ö,""âÍ›7ÁÁÁ=¢ÐþCY±g·555ñÝñßÁƒSK]½zUÊS__?wî\*ºº:ÔiC¹J'ê|’åææ¾¿™€8Ž ›BŸO²¼¼<6é.ª««;{ö¬œœ+¶€ãÄÅñãÇÙqíÙ³‡Ï T 7oÞìÒ¥ ïqû†Ï\999QDŸ““Ã¥÷ööæs‘§¤¤¤sçΔ ¥ÄwSÄݾ}[tnÙPaÐ4 m455™fÊÂÂâýÅÈš*&&¦Ñ™÷˜ääd*‰ŒŒL£3¨‹š¼¼¼/¿ü²áôqïLþ&ÖØÌuDGG‡O2ŠÙÙ³ðdâĉǧ†††ôQ~~>Åæ/^¼(,,¤ ÞÅÅåÙ³g]éàîÝ»”àAƒÄ¢H¹ªª*j)j/]]ݶ-IXXXÇŽ©$ׯ_G»€´¡8«}ûöt>üÎBcïkê üFUVVÚÛÛó99gwÜD¿Þ(\íÓ§•V^^~íÚµô¢ÿþÓ+;tèÀV4uuuÑ+))éëë×ÖÖnÛ¶þ¬¦¦Æ?™¯¯o‹Ìe———÷òåË}jggG…>|¸(×—ËÕÓÓccïL5sæÌz½aÉé .¤#Z¶lY£QEë«V­b}»víöìÙËÙ:Do=zôÿÞŽÏ·´´|ñâ…——WUUÿ=򯯬ªª²<çÎËápðÝ ÔCfΜI­¦¡¡ÑVe8|ø0@EE%##-Ò†BÔQ£FÑ)1ªüSš˜˜´Èƒƒƒ?ô){\wñâÅ"[cÙÙÙ,æ%7n|óæ ½¹téRúóÚµk’Ñ+|||XÀÞp=z&**jóæÍ²²²lÍúM›6½“f×®]ôÑéÓ§ÙŸ¹¹¹üw—œœ¼zõjV¥={öüçŸ0é™x ¡ÞBÍgnnÞú{§Ÿ&Öy,,,Ð …ž?Nçà ü×z¦O]\\ZdÎÎÎEEEú”MÔ¶gÏѬ.7776ï½¼¼¼ï}¶Ä}*½âÈ‘#t8ëÖ­køfddä–-[XDOV®\ÙèôøË—/§OVUUU.\ îÇ®8pàý…ìA,üôÓOԈݺuKLLlÍýR·TRR¢]ÿøãhNË–-£Sâ½{÷òOfbbÒR“˜ñ¿£·iÓ&*Åz¢VQ\.WWW—EµÃ‡o8ä ;;›…º3tœ=ªüðáCögDDµ /¢_¼x±··÷‡¶1b¥á35"££#›dL›6- ßGñUYY9eÊjÊI“&ÑëÖÙiqq±šš{p£ùSzˆ£˜˜™·ø¬$ÎBÚ§OŸ¶ÔNùgÅfV766©Š*++Û°a‹@)ÂecïƧôþÀ%£WTUU±1ÕÔ=¢££7nÜÈ‹è—.]ʙ¢¢"–˜ÿjiii_}õ˳{÷îýõæ:“ÔèÔšÔ¦ß~ûm+ùòË/}||>º-»ÄAqÖ‡ÔÔÔ\¾|¹S§Nl»víâÿˆ;;;vaçÈ‘#Ÿz_¤uìØQž ‘RSSÙBfÎÎÎn’””dbbbddäààðÑéÍ•ø¡O}}}ÙŠi¢s÷–*GEE…ÝV¦ µÑ4ìòÈñãÇ%£cØÚÚ~ÖÀÂ… _½z%à¶çΣMÖ¬YÓè§®®®£GfÙNš4 á˜Dºuëkâ3gÎÐ9%%…ÚýÞ½{:::û÷ï×ÔÔœ5kÖçŸÞ·o_eeeÞª ôgŸ>}Æ¿|ùòo¾ùFOO~g²³³Ý˵kר¥!SSSÔ9H­ЉñÌ™3…Ø–ÃáXZZ>yòÄÉÉ©ººZð i>tÿøã*Ò‚ D¤Šîß¿ÏÆ¨©©ÅÄÄ|(˜Òܽ{W2:ÆŸþÉB­ &~͇Y¼x1mxùòåwÞÏÊÊÚºu+˶k×®¿ÿþ{KM×¢&<<|ÆŒ¬­ÙZͤªªª¥¥E]‘÷SchhÈ.üöÛo¨pZéééòòòtblggל|(À·°° hÝÅÅ¥¶¶–b åø Â'ß~û­ˆÌk]__Ïfæ'k×®---å“xàÀ”¬¥Ö hsÑÑÑêêêׯ_ÿhƒ¾£¢¢¢cÇŽT gÀ£LnܸѥKvwuûöíº b-33SGG‡Íb׬¬ìàÁƒ.\¸sçÎS§N<~ü˜‚tê$aaa‰‰‰)))‰oEDDøøøXZZÞ¾}û×_]³fÍ!CfÕ§OŸ .<|ø=òÝwß¡Ú@š±GS§NÚRæåå™››S€Ogæº#okkËg…;ÂNãÛd ì†*++y³ä;vŒÿC”X™â¤ƒƒÕƒŠŠ ¯Æüýý©±š9rdSïþƒXˆŽŽþúë¯ÙC=lDý_|ñË/¿\¿~=$$¤IãyÞÇápèW…ògÃðlÞ¼s-€4‹‹‹cÃË)ÐnñÌSSSMMMéTœNé¾O§÷ô&Ÿ cbbØÀݶ]Á>>”¾W¯^èWlÕ€{÷îõèуÅ_ˆ¿$}µy­üÑ[Ðùóçi§ÊÊÊ-¸þ&€ñóóckÖ7:yBBBYYYËî100ðÉ“'¾¾¾ü“-_¾œÎÕÏž=ÛV5Þ”ïÛ·¯à+úYYYÑ&cÆŒ‘ò~•ͦ2cuÈ&”˜9 ¡ââ⯾úŠ×ÊÏŸ?oåDGGOœ8‘`ß¾}åååh*óçϧ“a:-oôSGGG i_½zÕ"KÕ îÍ›7 T°†ÿŸHPPPÏž=©C‡MHH|Ãû÷ïÓVêêêRÞ¯>|È{ö¹S§N—.]ÂÀ{‰2|øpöýÉ“'ùÂùtªªª~øáv)iܸqIIIhffftÜ¡C66þˆ¹ººÒ2¹/^¼ ˆõåË—ÑÑÑôŸÅéZ„¡¡!lðàÁŸzG¢ÃìÚµ+`Ô¨QéééMÚ–=>°jÕ*)ïZû÷ïç-€÷’ÊÉÉIII‰Z¹ÿþžžžm^[[[v9Žþ¥o1$^EE›pþرc&ðööŽˆˆ°±±IKK«««£èŒÂüçÏŸ×ÖÖR˜ÿI§³[ºt)ìäÉ“­_-...l¨À´iÓ„˜òëÊ•+|Æ?Hê*öööø¢IªÇ³IïçÍ›—››+"¥JIIa;PÙþþûo4H¶³gϲÞŠ‹‹M@QmRR’µµµ££ãÓ§OJKK+**èÌÙØØØÖÖ–ÿ¬¬¬_^Šb6¥vhhh+×ÉË—/;uêÄÒ—””‘Ã… hómÛ¶¡ƒ»uë[Ý`õêÕô› Re£Ÿ©5kÖð·¯­­E{€DJKKcì½{÷>š8==^Šâ}||âââ³³³322\]]ÿþûo++«Œî¯]»Ö&SÏÑÑuîÜ™Ýz¶ÀsçÎQ_ý5úHžÊÊJ ‹uëÖ±¨yïÞ½¢¹ž#ý8q‚RSS³­žúø¤Ö®]Kg¼“'OnR<^ZZcccC±|xx8ÅøÕÕÕ ÎÎÎUUU–––t MÉ„.—Ë1b•M__¿5+äõë×ÊÊÊ´ß™3gò¹SÿÑ9ô®^½J™Pàƒ>’„zþºté›ñÌ™3"^f###yyy*êâÅ‹[|]€¶eooO纲²²®m÷QöRüÏ?ÿ˜˜˜ØÙÙ¥¤¤ÔÕÕQ\ommíâârïÞ½W¯^q8áÊæääDeSPP:!„††vïÞ=Sÿ¡§¸\®×[ü³ºsç[¿Ý $CXXØæÍ›åääX8ß§OŸï¿ÿ¾­ªh*¶ºýœ9s>ôÕ;åååC‡¥ÝC‡53«äääððpSSÓ—/_Rt_QQQPPM±ù¿ÿþ›——\TTÔ¤ÇoÙ@‚;w¶Z…¤¥¥õë×v:qâÄMÈ‚z pèèøOÑÿøñcÊjêÔ©èi îrrröîÝË‹èÕÕÕíííEsà=l˜Á”)S„˜ @;vŒNqûöíÛRw¯ÊËË)~×ÓÓ³³³{öì[2¯²²’Þ·±±yøðaTTÔGÃaÞ…6c^«Ý ¤J;v,íqذayyy¦¡cquuMMMÍÍÍ¥¸¦¨¨ˆO†þ³e¶ÐÓ@|ÕÔÔ\¹r…7ê^CCC\nÐ7ÊÏÏ È¡/û‡¾æâ"$$„Φ¦¦-žyZZ…½< (žò§(˜"âøøxú×ÜÜÜØØØÍÍP|øðaö„{ëÔFuuõ¢E‹h=zôˆ‹‹k4Mmm­··wpp0Åõ³çääðÏ3##ƒ…BxžÄTXXØÔ©SY75j”Tdd$–3aÂþ¿B¢¬¾¾~Ö¬Ytfûå—_~ÒQlëîîþßÿYZZr¹ÜÂÂBŠôÓÓÓƒ‚‚îß¿ïèèøâÅ‹÷·*((`SôÓV­PT°íÛ·³gù)ro4MMM HRREý‚ â¥Jf“ê 7w@ª®®ÖÑÑiß¾=uà®]»Þ¹sGìFÝóÎæÆ\´hQUUšÄÑŸþÉÂØÄÄÄVØ]jj*øfff‘‘‘tRM1offfDDEÊï§?sæ OMM­—Ìãƒ-H'++ûôéÓFTTT¼|ùÒÏÏ/%%ÅÖÖöCÞ¿¸víºˆ‘äää™3g²ÛôË–-KKK“¼côõõe׬Y#I—,@JdggwëÖNh/^¼Øšû­­­¥ÐÞØØØÝÝÝÜÜüCÉŠŠŠXñûTTT>LÑ«(”ÃátíÚµunÖWUU±9ÁÆÇgj»ÂÂB???ggçÚÚÚ¦î‚Ëå<˜vqÿþ}t<e ôE`¤œ:uJˆÞ.¦._¾LG-''Gßqt»èþàÁƒlÉ'f̘1W®\ÉÌÌlÃRýòË/T’#F´BX±ÿ~6ØøCàóP\/ô¨†³gÏÒ^FŽÙ:sÁÎÎŽÍ#×£G'''©:v.—»yófv…³Ñé>D\UU•¹¹¹††[óŽÝ·Z¶l™‰‰IEEE+&33“ÍdõèÑ£O½/ Ú‘ŒŒÌÿý't&ùùùxÃá())á–=ˆ,]]]6ÅÄäÉ“SRR¤°ÊËË'L˜ÀV¾Ãª” ¾(ü¼{÷î”)Sx·ï»víº}ûvggg.—Û:eصk;µn…[Û—.]¢}ihhCNNÎÿýçææöÑÒ²ùö•••322ÐÓ@tÔÔÔ|ûí·ìûþÍ7ßTVVJmU$%%©¨¨ðŸj@\DDDœ8q¢wïÞ¼РAôΧ^/**ŠhaÀ,®ß´i“ÛVWW§§§[[[‡‡‡~ô‘J?vìXv?´©3ï|"EEE .dÔc)Fâìì,''G"Ù«€ô¨««£³ÜíÛ·+**²èžNþçÌ™s÷îÝ’’’O±ÇåË—Ó^èßÖ9@===ÚÝÆ…Ø655ÕÊÊ*++«¢¢ÂÃÃÃÏÏDFF²ÅûæÍ›ÇápÐÁ m%%%=š:dÇŽŸMu¢¤¤Ú‰QTTD±cÆ ªúÅkÁß7­££3dÈÞøüþýûŸ8q⣓É—ËeÏõïÚµ«ÕG__Ÿö¸víÚ&meiiùôéÓ¬¬¬„„Šñ›4O~@@ERì Æ7ß|û‰ŽîÍ›7‘‘‘ŽŽŽ<¸xñâO?ý´{÷n:XuuõóçÏ£3K³gÏž±A8cÆŒ‘†ê›*>>žMt©««‹Ú‰T__ïéé¹oß>v뙡¨ÜÀÀ   @¸<ÿý÷_ÊDAA!--­ÕäîÝ»´ÓE‹ ˜¾¶¶–Âäððp:L???ooïèèhAâëwÞÉÍÍݰaïц üõ×_ ú­ªªJHHpss322¢h}ï޽˖-=z4‹J>dàÀèÆRëêÕ«lêûÅ‹£BuçΪ¢öíÛ‡……¡6@‚QÄJá$E¼ñùòòòfffMZz¾²²rðàÁ´ùéÓ§[³üOž<¡N›6MÀúåË—ÕÕÕÉÉÉtŒŽ^¶²²ÊÉÉyÿ} Æ¿øâ‹†áv¯^½-Z´gÏž“'OêëëÿóÏ?fo=xðàîÝ»ûëêê=ztÇŽ+W®¤b÷íÛ÷3¾:tè0dȹsç®_¿~ß¾}]»veoº¸¸ ÷J!.—Ký‡õ]»v øðˆÔÖ›îcΜ9­¶@JKKÓÓÓ6l/¢¤SKKKÀ'å/_¾L›ôìÙóý[ÛŸ”½½=íwäÈ‘MYVVfaaAé‹ŠŠ¼¼¼è… ãç)pvv â“&::úôéÓS¦La·P…@öë×oöìÙ›6múé§ŸnÞ¼iiiI;ÍÎÎn¸£ü‘%655E•Bµµµ;wîd}¦¥Äðññùã?ZaIÊ6‘””ÄžV¸wïúHÀÀÀ}ûöuîÜ™uŽ=šBþÜÜÜmRXXؽ{wJIB+—Ö××—öK{çŸ,==ýÑ£GYYY)»»»SÔœ™™)HþÞÞÞqqq‚L‘WTTäêêzëÖ­'N°áçÏŸ?å-z±ø­ 6~ü866¶¬¬Ìë-AÎð)Œ JKKËÉɱ²²¢mÛ°9þý÷_ö „¶¶6:§¢î·dÉö†‰‰IKeËårååå)Û˜˜I­:ú`K~ûí·èH 222 ÆÏ»}¯¬¬¼oß>OOO– ))‰…­_¼úúzŠthïQQQ&(//wwwOHHÈÎζ´´¤è^À©ïãââèKJJìììÞßRªªªIfccî®Pµ£CJ¡üüü©S§RPTT|þüy æÌ.‹ÉÈÈÐ×D‚+~dÞòõõEwiæããsàÀnݺñüqãÆéëë¯Y³†^Ïž=»­f¦RUU¥ð‰w¨`nnnöööæZ\\œššêìì,à ªŸFçÖû¼¼4-Àÿ½ëÅtãÆ+,,D—“6QQQýúõcqw\\\‹çƆ‚HC\O´´´è`GÕ¤<¤Eµm»ˆ¶™™;]o~VEEE‰‰‰¡ÛÙÙñ_ÛŽ' €ðøøxgg犊 AváààPVVfbbB¯?”,??Ÿ¾VUUÍÊÊB7“6ÔýzôèÁV£ø ..®oß¾l¼ÍÁƒÅ¥Z¸\î¥K—Œ…Ø6//¯K—.t¼<@)©©©ìY€&=Þþ¾ââb¶º½¿¿¿€ók•””¸»»SØ•œœœ––öÑôÎS<•žžÎY±ÒÒÒéÓ§³ŸãããÑÄÒ†º›ÈbâĉŸbu6úÊ <˜òWRR¢oÞ¼).5Cß2*°‚‚‚p¥\¸pOhÛK‘ð¾#FÐéºpwñxº““Svv6õ‚ §¯¯¯OJJ¢ðŸânvÿý£›”——;;;¸ººòy²ž"ŽåË—ÓátîÜYÀ1 I<<<¨é©LŸ>ýS<Aý–õô­a Àý÷ßâR9\.—Í8áåå%Äæ¥¥¥***´¹‘‘z€H9tè«ýõ×ÂmÎáp^¼xçââBQÅìÝ$66–Âó´´´ääd祥››'$$X[[óy¦žv½mÛ6:yyy* ZVÚ¸¹¹±{èsçÎ}óæM‹ç?pà@ÊèСÔ{»víJ¯ƒƒƒÅ¨Š™'“Ú\MMM¯9´GGG6¨Xûæï¨­­¥ÇÓÓ3$$ÄÊÊJM¸\®¥¥%Eôööö‚ þ¯ªªòõõ-))yþüyvv6Ÿ”GŽ¡‘••533C³J;;»Ž;²å¨·´xþ±±±ýû÷gÑ“’’Þ¼yÞ¯çp8bTK¿ýö•yÍš5ÂmNˆC<{ö ]@tÔ××0€ÎÕ>|ØÔm­­­SSS###}||IŸ––æîî^YYIqA~~þGÓ×ÔÔx{{gffRþÉÉÉ|R²ELjÚTÚ˜››³…ØV¬Xñ)Ö4ŒŽŽf³ë1"##ãÿÞ.ýÀ®†‰WE½|ù’ŠÝ­[7¡§µ?vìå0uêTô:‘râĉ¦ž«×××ÛÚÚ†‡‡SPOѺ Á‡Ãqvv.**rttäçÔ»»»S8ïââ’žžÎ'åßÿ-##C‡ ­­Ö”6ÆÆÆíÚµ£Ö_·n]uuu‹çïïïß³gO¶lov}zg̘1âUWγÇ<==…Ë!33S^^žrpuuEß5³su;;;7¡ˆþõë×t?þ\ù±SRRœœœ(½¥¥¥ wê % óöö¦ù$£‹…uû÷ïGSJ›ÈÉÉQëoÙ²åS,­îèèÈžÙ?~|ÃÇFþøãzsùòåbWck×®¥’Ÿ9sFèvîÜI9¬_¿Ý@¤8p€ÎÕ'L˜ Hž””äåååççGÿ 2ñ]aaa|||tt4EIà RžW¯^Ñ&´#þKàyzz*((°(£®®í(Uþ÷¿ÿÉÊÊRëoݺõSõÆÆÆlxÿÌ™3ßY…áøñãô>}kÄ®Ò~ùå*y¿~ý„Î!88˜rh×®ÿQ4ÐÊ222ºtéB§ë—.]$}rr²Ÿ%çxŠ‹‹mllJKK_¿~]TT$HæAAA~~~‰‰‰|’…‡‡+++S™ÕÕÕ?ÅSÕ ÊîܹÂú={ö|ŠéÙ¯_¿ÎîX»víû½kÓ¦M‚YD [†ž¤¦¦ ÉŒ3šyÓ>6´X^^þÕ«W‚¤¯ªª$¨·µµåp8Ú ÔgeeùúúRhOÿòI–’’Âæ'Ÿ8q"íÍ'UôõõYpºÿþêkkkÙŒdçÎŽ˜9s&}jll,vU§§§ÇíÚµkBgòðáCÊ¡gÏž‚ü@«¡øhÉ’%tºÞ·oßæÜËã),, ŒuttŒ|CJÀår?” ??äÈ‘TÔaÆ 2H]]]™=z”O'‡ÃY´he.##söìÙ%cÓã{yy‰]íýú믬öfΜ)t&γ¹Ÿ|8®4¨I‘ø‡dddXYYeff¶`!ËËËgÍšÅnÆÆÆ¢Õ¤Š¶¶6 KOž<Ùâ™ÇÅÅ©©©Qæ;vü÷ß?”¬ººš= Ž˜ÿøã¬eddœì¢Q?ÿü3e²lÙ2ôIQCáüàÁƒéŒ½W¯^ÍÏÃá´`ñ(¤Zºt)¯K—.ÁÁÁh/éÁårÙâéäĉ-ž¿­­-[nÀ€|R&$$P²öíÛ‹ãTûöí£Â³gX®\¹"t>”ƒ¬¬,fÏA©©©£Fbwô8 à²t­ ¾¾~Ë–-l€/^ ¥¤5=[²èééµlæ555:::ìü¤I“ø/Á@¨ïQÊ¡C‡ŠcMnݺ• ¿jÕ*úWMM­9YM™2¥™àÓ)--ݾ}; £ºuëvòäÉOwWŽöãééùìÙ³?þøC[[ûĉûöíÛ¹sç† Ö­[GÿÒŸ‡fKoËÉÉ™››£¤G]][3]FFæÆ-›9õ=ŠåYWß»w¯ +Râ ˆcejjjRá/_¾ÌˆlÎ7oÞ¤F. ²lmmÙôt,šž?þõëׄX+¼¼¼<**ÊÙÙ™b¢óçÏSœ¾bÅŠ1cưÅõšäöíÛhéQ]]½~ýzÖÿù矖ÍÜÈÈHII‰2ïÚµëãÇÜŠMÜ·uëVq¬O6+ Õ$úòí·ß U~~~ûöí)þ-@Ûª©©yôèÑ´iÓFÖ &LX·n…çǧ0çÖ­[wïÞ¥¨_OOÂö'Nì߿͚5sæÌ9r${l™ Ùúôé3~üøeË–íØ±ƒ¶¥´µµ)·«W¯Ò¿ôç‘#Ghw†††héQQQ±|ùrö0{ËN½ž˜˜¸råJÖýæÎÛ¤ä¾ÿþ{Úê§Ÿ~Ç*e+ô™ššº¸¸Ð‹N:½yóFèÜØx~ú@_}ÑÑÑ¿/X°@QQñ3¡Ph6hÐ Šô7mÚtìØ1 ÿ¬¬¬_‚$@ii©ºº:›ÞÚÚº¥²­¬¬,,Lˆ‚±e·/RTUU©ðnnnôúúõël@¡'ö/..–——§L‚‚‚Ðc ! 555LϦUüÐcïžžžìÑrÒ½{wÊ\è MC† á…Æb‡ÞÃÃ^—””tëÖþ|úô©ÐjhhP§NB€†Øïùóç ˜> @FFFVV¶á]øÊÊJCCCÞíÛ·ÿî»ï8ŽÐ¥âr¹;v¤¬bccűVL…ùò%ûó§Ÿ~¢?©~„ÎÐÈȈrøüóÏÑc ![[[ Ç'ø&l*¼ 6¤¥¥™˜˜lÙ²¥sçμˆ~×®]‰‰‰Í,UAA˰¤¤Dâzª(6§½···p±¢¢¢Ði€‡"MŠû÷ï/ø&222ïLØØ¯_?ÌÌÌ)Uxx8{ê_Lkõ¸žlÛ¶ÞYºt©Ðy.X°€r¸~ý::-ðDGG³E›´Õ_|A[Qt?vìX---www¡'…k”““å?|øp1­Uö|=U ïØØØvíÚ5gÆ€‹/6óÊHžÜÜ\vý²²Rð­ذp[[ÛOQ*CCÃ&=õ/jÔÔÔ¨üŽŽŽ ßüöÛoéÍ9sæ—çëׯÙr„åååè·ÀÔÖÖ²AõYYYMÚPKK‹¶¢¶¦¦¦ÅKuåÊö¿˜Öêĉ©ü––– ßLIIaËÕÙÛÛ ‘'—Ëíׯmngg‡~ <***-4i«‚‚eeeÚðÎ;-^¤ãÇSÎÓ*5k•ßÄÄä÷¿ÿþ{zÒ¤IÂ-ÿÇîøS&è´À3cÆ Š›º¡¾¾>mØ»w~×®]”³¶¶¶˜VéÂ… ©üÿüóÏ;ïggg+))ÑG·oß"Û'OžÐ¶ªªªè´À³}ûvŠuttšºauuõ°aÃhÛ3gδl‘455)Û›7oŠi•²ò¼ÿ{Ä k×®M}ð²É÷âããÑo€9þ<…Š[·nbÛdzéôÓÒÒZ°HsçÎ¥l=z$¦UÊÌ7z©¤¶¶v„ ôéŽ;„ÈyöìÙ´í­[·Ðo€a£»§N*Ķ\.wÚ´i´ù®]»Z°Hl>y1­Ò£GRùµ´´ýÔÓÓSæ­/^45gvfåÊ•è·À°Ôºté"Üæ´¹¬¬lpppK©gÏžBLå':.\¸@åÿúë¯?”€ÝÐ9rdYYY“rö÷÷§ «ªªÐu€”–– ·ÔϪU«hóeË–µHy¸\.{Š<99YL«ôÎ;ü+$??¿wïÞBŒs¨¯¯ïÞ½;mèé鉮 Œªª*…ŠVVVÂmÅ"q—æ†Ãá|öV‹O³ßj¨&©ücÇŽå“ÆÑÑQVVVˆ•ØU]]]ô[‰TPPpûöí‹/>þ<''‚`Sâ?~\èöîÝK9|ñÅÍ/L\\eÕ¡Cñ­Ïàà`:„nݺñOöóÏ?S2%%%:dÁ3g3ê/_¾ý@’ÔÕÕÙÛÛoذA^^þ³ú÷ﯡ¡¡­­MŸ¾yóº{÷.ýbÌž=[èÙ-{ŸfÆÏÏòéÓ§øÖg^^ž Cjjjجƒ3f̨¯¯0óW¯^±ùè—]@ÄÇÇÿòË/¿óbù‘#GR,?`À€Ïþÿäää&NœxøðaSSS:çDÕOdd$»E^^^.t&›7o¦LÖ­[×̸¸¸P>#FŒßúär¹;v¤£ Šå“,**j̘1¬æ‹ŠŠ̼¦¦¦S§N´UPPº.€ø*++344œ?>›íŠtîÜy×®]^^^¼4¼;::^ºtiýúõ}úôiãËÊÊN›6í×_õööÆ 8”MAïîî.t&¯_¿¦_$úy‰mNa,--©$“&Më*=z4ˇ±ð¼GÏŸ?oRæ‹-¢ oܸ® Ž(rß½{7Eñ,B§³èyóæ=xð ´´”ÿ†qqq”ŒbÿÏ?ÿ¼aŒ¯¢¢²gÏgggøÒLSS“~~ûí·æd²xñâf>§OŒ)úeëú\»v-Å•+WÞÿ¨¬¬Œ­sGæÎ›žžÞÔÌÏ;×"C# 5eeeééé9²á³ó§NjÒlK<ñññ·nÝZ¹r¥¢¢"/Ã^½z]µj•œœÛœkkks8´€”`s³7ó©íƒ63*?þ<åðÍ7߈ue°5ìØD÷ ã³_WMMÍæO^:kÖ,Êêîݻ跢¦¨¨èöíÛììš_:t(00°u ––väȑ޽{ó¦ã;~üxAAš@â±…Ñ›9ßßߟ2‘——zÌω'(‡ƒŠueVWW³[êQQQ}³1Q Íϼ¼¼|ÆŒ”áÞ½{ÑoDD}}½§§ç¾}ûØôÈlÊú9sæÐÙ`s–âDÔÇÇçõë×FFFjjj¼k zzzô)Z @‚%%%± 텘ɇËåöëׯ9Cñ:ÔüÉ÷DÁ¤I“è@† Æ~Hé']¸QÞÁápØÍzyyyô[€6—œœ|öìÙ!C†ðnЫªªž?¾9¸ w*ž••@'ö/_¾dêêê?~<|øpV°±cÇRÔ&`l°¾¾~s2a“½>|X¸ÍwîÜI›Ÿ;wN¬k²¢¢‚Åõl4þ­[·Ø€üfJOOg+èuéÒÅÕÕ= Í:uJVV¶áªs½zõÚ½{·¶¶öÝ»wÝÝÝ[g|NN΋/’““#""bbbÞ=[]]}åÊ:‡¤âµk׎ÊÖœ™®@”ýþûïìêbsfæ|òä e2|øpá6ߺu+m~éÒ%ñ­Fkkë¡C‡²_õÉ“'§¤¤´H¶QQQƒ b+£»ˆ‚U«V}ö1}úôùòË/ûí7OOÏ Offfz{{‡†††„„dgg(%}Ä–·&3gΤ­Ð|R¥¦¦fÉ’%Ô±®–d+))éÚµ+}Í-,,„Τ°°ÍÀ™ mq=…Þ‹/f?•}ûöý÷ß[*g6“ê!CZd>>ÇŽk8ÉÞøñã>|(øtL”2**Ê××—byŠÊ…(INN[b©K—.Í9óqÁV$'–––¨ i°~ýzjî-[¶Ã_ýE9|ñÅBlûõ×_Ó¶ººº¢_QùùùÚÚÚ¼‹®S§NmÙ êkkkyß¾mÛ¶UVV¢sH.—K>úÊË˳ó½qãÆY[[ ’‡……ùûûÓ¿ÍyPº¤¤„³UQQîZQQQì^!/+¤„¯¯/[ðNè w¯^½bKd ñ;#q}bb¢––ïý¨Q£ÌÌÌZvö ú¹VWW§Ì©-Î;‡©-$õ>}š=ðNV®\)ȪÓnnnyyyÍß;‡Ã7n›í¹ªª Í!©V¯^Í:ØÎ;QÒcãÆÍyÊž~(¥Ö­[7}út ðGŽyàÀKKËNѰ}ûvÚð·ß~Áj¡àÚÝÝ}Íš5¼¥LègðÑ£G-²†]C^^^ýúõ£üŸc?vìØAÉ.\¸ R’‘‘¡§§÷ùçŸódΜ9ÖÖÖ-~½®®îòåˬ‡†Þ %ÇÏÎ6÷îÝÛj7П>}J{”••Åbʉw³¾gÏž‚¬˜’䨱cÔô#FŒd„W¯^}õÕWì#Ó­[7%%¥Ã‡ûúúš™™íß¿ŸMÀȲ‰‰i4«o¾ù†œ;wN*!??ßÈÈhÉ’%¼ôŠŠŠTÂO´ HBBœ9sØŽÖ¬YƒYò¤ {Ÿ8q‚Ý]5kVAAAËæŸ––ú¡ÐoÞ¼yh Ì»YðàATˆ´),,da¸¶¶6ŸdÙÙÙçòºÊôéÓÿý÷èèèFWUUöéÓ‡Rªªªæææ¾Ÿ†ÍG¿fmx쉉‰‹/n8ð`Ê”)ô&‡Ãù{¬¯¯ÿóÏ?ÙsU:u¢×x @j=}ú”Ž?¾Ñsf!P>®®®111ïß¡CÚ£ÐëîhÒÔÔäE4h\éD18µ~»ví|}}MàèèØ½{w6·ÛÖ­[É6//oøðáº^D}ë_J ¿téÒöíÛçÌ™Ã~ÐxÔÔÔN:õ¡+-‚êmæÌ™lw3fÌøÐHtŠÈî²=º™wí³³³cccCCCSSS½½½?”›¿zýúõ¨|‰Á»Û¿ÿŸ ÄÅš5kXlûþe½k×®ÉÉɱ¹ã<==›”­µµ5m8dÈ÷?úí·ßè#úUi…£ËÊÊ:yòä°aÃÞŸ@]]]__?..î“ 33s÷îÝl¿’’ÒÕ«WëêêÐë€P$Þ«W/6uuuµ9p¹\77·àààøøx__ß´´4>‰)»©×âƒÿ¡­°9É™£G¢B¤Vnn.û1ygzÌË—/³îAx£#yø‹ŠŠb‘ìûýùçŸlOz\)))ß}÷]ÇŽÙQtèÐaÉ’%çÏŸgW:wîü©+6;;ûÈ‘# ¬›7oÎÈÈ@€†üýýÙÚÊ»wïnÒ†tŠ—””dii™žž.Èý#vÃËØØ5/ÒÒÒ>VL} u"Íèw€´711aïÜ¿ŸõS§N —çÿýG›þùçïôìÙ3¶€æ':œÚÚÚË—/óêiÓ¦Ño†:v•²oß¾Ÿô’ÂÑ£GÙï3™:uª««+º4êéÓ§l(µ©©© éß¼yC±¼““Sddä«W¯‚ƒƒŸ]KK«Õ†Î§vøða^P¯ªªŠù»àûï¿§Î@±°¿¿¿[¯99Ö®]K9P¶ïÄ"ëÞ½{Š ™4iëÛ³gÏvtt|' }4f̘ß5}è×USS“=¼À®]|Š•ò@Â9r„λwï΄geeeDD„§§g~þÿÇÞy‡Uq|}üMÔXc7öKì±ÅÞƒ5hŒ½EJ,QLÔ`‹5*v±#ŠŠt¤#R¥ˆ€ô^Íû}8Ïï>÷¹eY.6à|þà¹wwfvîìì2ß™3ç¤>ž¼üµk×îùóçb²¤§§7iÒY8èäätûöí3gÎlÛ¶mÖ¬Y½zõ¢Ò´jÕjÉ’%¨ÞË—/…Ëûå—_6jÔ¨~ýúuëÖmß¾ýwß}7yòäeË–8pÀÌÌ,44Tå ò:::(êÔ©Ü‘†a†a•quu¥Q«²qé³gϼ¼¼ Ð1ä )S ûÐê·sEäðáø}Í›7ÏÍÍ¥…ÎS§Nq³02@¡Óvž‡ ¤‘즇–s!Ÿ˜˜˜‘‘ìïïíÚµ˜˜˜GEGG+óÚ!£ñ׬YÓ³gOß¡C‡¥K—^½z5""â§Ÿ~Âsñ±9ÂÃѹ¶nÝ*öÍ›7OžzôhÉnz¨`™¼öööFFF<ÀÛ&;;R]ÎÖÖöéÓ§666±±±ÐÑ¥V#99ùöíÛk×®•qD/1•‡ ù‹ ȡĠAƒäç<‹‹‹gÏž­Ì&¿víÚçÏŸy!üF ·'fƒa†a†a”¡¦¦†¥ŽŽŽÂ³999yyyª•<þ|”ü×_q#W8~þùgÜ»îÝ»CÔÐf &p³0 yõêÕ¸qãHÕ¶mÛVOOú}ß¾}½{÷¦ƒ5jÔX³fÀnzÈùèèèÌÌÌ;w™¡ÀÐÐP|…À÷ôôtuuµ²²rqq †xS¥””“éÓ§ãÒTè}ñ¿hݺuÈÒ°aè¨(ù³+W®¤FíÛ·'× øŒGæäÉ“díŽ;&æB¹¹¹4Á“f Ã0 Ã0LyX¿~=F•+V¬xç%“+uŒÒ¹‘+ÞÞÞUÜÆÆ_)Ø÷¥K—¸eexxxÈ»…§°t³gÏ¿¥=¿„ÈÈHÈù[·nݽ{7888'''555&&ߨØÚ?...--MÀˆ§´´´¨Ó6‘Ñç……ií›7oÊŸµ´´$¿ׯ_¿xñ"}¾qã-..¦7*ŠŒý×¼ys¤wssã^Ä0 Ã0 è M‡þn‹ÅHžŒ·1üæF®@¼yóæ»ï¾Ã½›9s&é5²aNOOçÆaÒ´iS²Z‡ª2dHÏž='M𤣣“””$“ ]L™EEEèŠvvvæææNNN>>>OŸ>MHHÈÎζ¶¶6+!<<\ÆKž··7y„D½WSSù[BCCi ~Íš5ògß¾}K%khh’o“$¤Yºt)ŽõÕWò?_4Kf†a†aFîß¿O>¦Þm±" ã|náŠÅ?ÿüC{„)À7->N›6[†QH\\\ûöíÑI åKÄ+((°°°°±±±´´LII¿†Ÿœœ ]ooo± 9Ÿ••7˜«««d6`Ïž=d{ߤI##£3fàóîÝ»Å\U"ë”(4°³³ÃÙ:uê ¥““Ùê¿zõJ&Ynnn×®]ÉI`©¥ýJûöíã¾Ä0 Ã0 è 9n‚Ž{·ÅŽ5 Åjkks W <==Iäþ¿Ô’srrhw|Û¶m_¾|©0¦¦&,Z´è¿ÿŒ˜4i’” ¤ZµjÂ×]»v­˜@ Ã0 Ã0 #@RR„1Ø~We>þœ6¨ŠßWË|t kºté‚»6yòdòÎíèèH«“8ÅíÃ$$$ØÛÛëèè¬X±bذaJƒÖ¬K}Ò333!–?~ìàà• -ž‘‘njjzýúuüõòòR¦©•‹¿zzzTŸÚµk£†÷ò_}õ•˜Ýë¨Ã˜1c²AƒOžîþ+1ö(ÙÛÛ?))ÉÎÎÎÕÕê>777&&&""ÂÖÖöÆÖÖÖaaab&”âãã'OžL•Á;çÙ³gÒgkÕª…ãÁÁÁÂï@Zè¯S§ÎÇR6lØÉ<==ñyñâÅø¼sçNe‰QÅž©8pà’Í›7ûÃ0 Ã0 £2ÙÙÙ4$NIIyWevëÖ ž>}š›·¢pèÐ! ×EGŠŠŠh­ÓÔÔ”Û§ê=îææö×_õéÓG^Å·nÝzèСÿã?JfÈ><<üÁƒPúVVVPåYYY—£%{{{{ccc2ȇ´G™´¸É#~~~æòqäÁíÛ·Ée_õêÕµ´´äÓ´mÛg•U ,,ŒÞW_~ù¥£££@Uß¾}K¿š\O,Y²¤Ô­FéOxï<éú pßc†a†aT&33“«"ýT— FãäAý]ȼo ©("Ø®]»$mllp¤~ýúÑĘÊÔ44æ×_--äÛ·o?þ|‡¤¤$$À£M¶÷ºººÒ³wîÜ–‡®§ tñññÞÞÞÖÖÖ¦¦¦é8.°Ó§¨¨è¿Wù^^^x Cš››# ÞN(*44ôþýû†††(Mâj§hÅtïÞ×RX2m™?~ü¸Â³fff 4@‚-Zøúú ·*I—{ñâÅÿ³Ã_¿~½@–cÇŽ‘>4{÷îEš%K–pd†a†aT&66–«ª•@cr ¿þú+-äqÛV ß)òø¼yó$»’ÅêÂ_n¢Jõºuë$èk×®­®®ÙN[׉ÀÀ@Ú]&Nœ(}Šxõê„¿§§çÝ»wœœœ‚‚‚222òòò‚ƒƒ-,,nݺeooïç燼2/ y7;;ÛÈÈÈÊÊÊÝÝÝßßìâðàA»ví(L¼¦¦¦¼GzeݹsçÌÌL™Ú"#¹éß¿?-Á— Ùá{yyý÷¿ÝF³fÍHýY 4 -[¶ œÕ«Ws?d†a†aTCnŒ*1¤/S.Àüüü777éu®øøxRP‹Ü¶Ÿ>–––´yÊ”)ÒAÇ hªŠ[©}}äÈŠØzôèqâÄ  üæÍz®ëׯ½/=ÿ£ôôthðˆˆ¼ ¼½½CCC“““¡ñ¡ë!ùïܹ¥) ɉœœ2Å÷ðð@mñÚÙ°a™—´mÛÖÞÞ^8{ZZZ‹-¸W¯^¦¦¦d3€ú|óÍ74-°víZñSšdWO;Snݺ…Ï}ûöÎÒ¯_?$;uꔲ‰w{#Ã0 Ã0 £2¿¾]»vb¿~ýãð„„[[Û¨¨¨ÀÀ@™àVZZZ(­OŸ>¥Žü™ÎåË—)ªšššŒ±=” Ž7mÚTá¦f¦r€yôèѤè¡s¥ÝßI€ô¦˜•`øðááááe½Jjj*Þ÷îÝ‹µ±±ÁK#:::²777433{ôè„¿pH¨oŸž={Re,X ÒÕ§¯¯/­³“»&MšÐ2}óæÍ---Ëô[ÈAYõS„Ð/¾øBx£ÊŽ;hÞLáÙâââ6mÚ ……wH†a†aFe.^¼ˆQåÈ‘#Kœc4nggçè蘖–†:¾:888;;KV÷²³³iü|ãÆ nØO¨õ7’Ò™1c†üšéܹsqjåÊ•ÜV•'''ZÈ®]»6„ªüÎÛ·ouuuëÖ­Ki8 ìâ^äLBXXTÞ$999)))AAA...Ž%(Ó¿ÿüóMC5nÜØÐÐP>M||üöíÛ÷ìÙ#*99YSS“~/1pàÀ¤¤¤²ÖݺuÈ»|ùòÿJÌȦ?G ‹»»;5 BËÚ¤Ff/ Ã0 Ã0Ly èÉ‹-RxRÝÇÇÀÃÃÃàððp býüü>|˜žžž——'øðáÃäh«ÔͳÌG$::šœ‰Qômy±–››KjNØ=8Sq100 ÷w]ºtñ÷÷WØIÆ' ún+ðöí[hí/^@à_¹råéÓ§ö^^^ Ûáµ#é±'N”—••E?jÔ(sssa “gÏžµjÕJåB7nÜ Ý ôUMM­Tz<_WBÆ6 ¸¸ø÷ß—84(u?Ã0 Ã0 Ã0uêT ,÷ïß/9‚qJJ „üƒž?ìîîngg‡ƒ8¢pÙ®°° Jutt¸U?Mpãtuu¿üòK’/^/-[¶¤ÈeL%O(íOŸ2eŠÌVzBOO:I5´µµßw7À«#"""&&Fa”yT¦^½z6&&&ƒ 200¹÷§yóæ(ÍÍÍM…ªâíG»òÓÓÓñuûöíø:{ölá\‹-B²5kÖHŽ$''K¦MêÔ©ƒ¿ÊF†a†a†Åw¶¶¶–‰õ÷÷ŠŠ‚¢‹‹ƒœ÷òòÂ@TxØ|üøq”Ó¤IáM²ÌÇÂÁÁaàÀ$%ú÷,å´iÓæ÷ßçF«dà†N§>±)¿´@wŸÍÙÛÛGJñ´|HKKûë˨Ì?ü@•]VVÖßÿ-S8•œ––¦ZK♢ðôuìØ±2û˜B«üD­Zµ¶nÝ*mc°xñbŸ3gwT†a†aFhýnõêÕå)$!!6Àb_5›ñÍ›7sçÎ?>†÷÷îÝSy)ð])8 ‹E‹ÑiP½zuTO¤áñ„ ºƒŸŽJCFFÆÈ‘#%±êºté"ј͛7‡¨lffXêÚby€þrqq9xð ššZ­Zµ$ÕhÑ¢:´ŒÈr’’’È`X¡t¦"òòåK<›2ý³^½zË—/wss“¶Ê@W‘q+(ÒÕÞÞþôéÓ+V¬0`ùÞ—æ›o¾Á…nݺ•ššJ¹òóó7nÜHýÚ´icgg'SlrròôéÓµ´´ÄHr›ÁƒË;‘&mdd„§R¡ÛÀRéß¿? 9{ö,>ûùùQ{á=þ+DâpO†GU«V &OžÌ=–a†a†)LÒ:Zy<Ý………ÑV\r$U„¡•qˆŽ©S§vèÐA¡Y2KûöíG½hÑ¢-[¶?~ÜÄÄÂêÙ³g6â#ƒgggGEE9;;_½zõï¿ÿ^°`AÏž=IHhҤɲeË ŒÊ:Ó!†ìÝ»wç§£rÙ¹sgé¾Ñ¬Y3mmm…Vè‡B‚3f¼ój@‰ûúú^¸paéÒ¥:u’®º.øš5k$õœ?¾¼øEg2dº}©×£´ÿþŸ~úIáf¢S§NÉ<˜5kÖlÛ¶-LMMÍsçΑ«@]xZiGƒºº:Mb´nݺÔÙÑœœZ嗷؇ä§Ù Úÿ–a†a†)6l 5ZžB&Mš„BÆŒSe›qòäÉhH´@VV»®®.Zƒÿo¾ùF~½Rž† bTß­[·% >\MMmèСôµk×®­Zµ(ÙÇ¿oß>///Y‚˜˜±OÖÚ»víâ§£àççGÞ, t!èÖüü|eé/^¼øažå—/_ÞºukÕªUèðÒ}¸Q£F7oÞ”IŒ kiiÍ;WáJ· ±±±x#) ‡GøøøˆqP­Zµ¯¾úªoß¾S¦L™ý? ýц’9´Zµj‘åÀòåËñõ—_~®í/èÓ§äÈÛ·ogΜ)™^ S•õ3 Ã0 Ã0UÂÂBóˤÅsçÎ2j}òäIÕlF}}}jh(dÒ‘‘‘¶¶¶çÏŸ×ÖÖþõ×_¡zõê…[ Yª+ü .ܱc$Rxx¸H7w·oßVf0 MD• å¤-L¶ßjjj¥Ú„˜ššJ ÏÄÄDpñ—+**‚&E!§OŸ†²ÖÑÑÁ»Ï…ðuÃÂÂ’zµ|LùáÇ‹|G¡o6ÌÛÛ[ MNN] ×EÊS§N-]ºtÀ€gbÌÔQÌ333z$…©¦¦&ÍP24/E»íÚµKJJ¢ x¢¹ë2 Ã0 Ã0"144$ƒmõ;a È׺uëªf&''S(®?ÿü³<ådddDEEAeØÛÛC•píÚ5]]Ý7nÐW+++ggç   Èñ®ÅeHHHxøðaaa¡Â³ÿþû/~K¿~ýøé¨øûûoÛ¶Müú¯““ím§¯÷ïߟ={6”ò”)S´´´Nœ8Íéíý??~ Å­­­=oÞ¼Q£F=zåÊ•éè´ÔÏœ9³zõê!C†à)pirµ'SUsssQjÍSRR/^Œ«‹‰¯GN>å#ÓÅÇÇÛÙÙ9räçŸîÝ»·´Ÿ 5jÔèÙ³'®E»öìÙó_‰w J,ïº_š˜˜*-ƒ¶•”?yòdRú—.]"³ îº Ã0 Ã0ŒH0Çrýúõ*—°{÷nÚ®+Æ>¶R2þ|‡W”è~¶¶¶/^¼xðàÂuXŠˆwèÐ!~:ª&èuêÔ‘9ž‘‘áêêjhhxìØ±M›6ihhüñÇPú[·n…rGwŠ‹‹+uÆ`üøñÈ¥ÌV¤I“&¸´§§§äÈÅ‹çÌ™#F§C&2ÄÆÆFäϤÙHKKKádÐÚfffï¨I=ÈN^šöíÛSbŠ"±sçNá27nLñ@i¯ýçŸ~øðaév&3öZÉ0 Ã0 ÈãgU>{öLµbbbêÖ­‹B0ü®šmheeEFÎÐ5¢ÂùùùW¯^MOOwpp? óY ÏŸ?ç¤jyNrUeaŒ¡Áž"‹tÈÉ==½R½>†‡‡O™2ESS³Lž?G…k]¸p¡¬õ/,,„â¾~ýúÖ­[ûôéC¯PªäñãÇñõ»ï¾.aÖ¬Y’9¼?ÉŒ_üœú믿¸72 Ã0 SqIII111©(KŸrÖ„¿*—0}útÇŠwä^™ÈÎÎnÛ¶-Z`ÕªU¥Î~~~999^^^ Š“õÅðáÃù騲@Γä³­¯ë   GGGûÿáææ%f…]ž®]»âºVVV"ÓgffþñÇ&LÈ^r;€_ž¶JLL¤¶200ø¯$îÉü„„\xô(W‡222ä\¹rg»t齑a†a˜ŠË²eËȃ¾¾~ÕT‹___ræáá¡Z &&&äJÚn¶J±fͲ§U-þõ‡'77Ê b$&&F~=7Ú/|âÄ ~@ª2 ÷¹K€lß¼yóøñã‡þã?®ZµJ[[ûÀÿØ´iÓ’%K&Nœ8bĈï¿ÿ~åÊ•ººº>>>bÂÍ÷íÛ·ÔPq’¾ª§§7pà@üé+ÿ矖!PòÏÈ5jÔåL˜0¾vëÖ _/_¾,œ‹¢‚¢> ÏJLñå·ÿ3 Ã0 ÃT(Z1`À…ÖÂLù¡­ –«–J–â5—go~…ÆÝÝ&FÌÌÌ>…úDGG—jå’““C>÷?~,ÖÒÒ’6V+ kÎTèÑ~øð¡Â³è?®®®bŒÞ Ÿ>}zõêÕ5kÖŒ9rüøñ»vírrrRfá?tèP\W___¸Ø×¯_1âðáÃÊ|?Ê“žž>nܸ۷oÓ×ìììÁƒÓ™¶mÛNœ82_WW×ÙÙ955µLmE6ó 4 ¯›6mcEWG;+K ®®Ž[·nåÞÈ0 Ã0L?Œgš7oNkF`êÔ©ÁÁÁÜ2ïZj T­„+VÃ(HÅ*Ø€=zô@ Ì;÷©T©“`öööYYYW®\Qhý;iÒ$ü" ~@ª8½{÷~Vè{–––ЪcÇŽ…ÊŽ—Iðý÷ßãºÐ×bf Ä_7..nøðá’mûøÐ±cGvM›6%¯þÇŽ#'“…S®˜˜|Å3ˆÏõë×®!íÄÿì³Ï”½?õôôõiÀ0 Ã0 ó©qùòeŒgFŒÁ$´'íX\¼x±ð¦EF$ùùùä Ú\µ00&OÎâwÂV2¶mÛ†Ÿß¸qãÄÄÄR‹±@.?±À^¾|IÞ¿ºI 'óƒ'Ožð3RÅ3f zÂ¥K—”%ðððUœ9s¶oß®¯¯# '‹ÞBò§NŠëBM¿Ãßâææ6xð`???|~õêÕúõ멟·hÑâèÑ£dEyÙ²ejjj-[¶T¨ôkÖ¬Ù£GÙ³gkkky{{KêÝMÿ¤¶lÙB{Æ ñUØ‘&jB¯ÐÿýWa‚ÌÌL\”Mñ†a†©¸ØÛÛ“C!úêãã3nÜ8\}ùå—{÷îUÍ##CSZ“*«Å©d@Nî­,XP5Ê—¶Ç^½zµÔÄ999çÏŸ‡èNIIQùŠPAAAî&ÒÓÓQhbxšlllBCCåÏ®]»¿JfÆŒè ÒÁ×”ñòåKGGG]]ÝM›6©««9rt (á·ß~ëæìÙ³"¯K¾ìöíÛ÷®~ÈåË—¡Ö“’’ðùñãÇ´ùÌlèíÖ¾}{Á©äädÁ_''§sçÎýþûïãÇo×®B¥ÿÅ_@éÏš5kÛ¶mž%ÐEÉÝýÆ…ëF.7¨,ÙÏ  ¹C2 Ã0 SèÀ`ºI:¼Ä>E¢PéxO1˜*=Pvä‘I`1N˜¿þú‹¦h\Õ@·üî»ï¤=e ãååuýúuáH‚P†††·K0777)áöÿÀg++«þùGÀ"å–`gg§0Ann.4ž…÷=11‘¶½Ü¹s‡Ÿ†œœ¨gíÍ›7èQ´1ÄØØX¼ÍüÏ?ÿŒëîØ±£ü?!!!aΜ9ššš…%à·PÜyhpÉ0 Ã0LE¤qãÆÌ(tÙ——wðàA²{¤¿ûl™/Z!B뉉L­pÀ–——gkk«Ð×ßÿÕ©S'‘?Š©ôèêê¢K ·àëîØ±C ª{©¬_¿þÌ™34µ…'‚Ä5PSSöi/=›Q½zueþØ»w/òŽ7޾RT—ñãÇ ç"ÿ„Íš5.öÃ߆a†a˜w†aÌœ;wN8YZZÚž={ZµjEƒ·jÕªýôÓOwîÜ囹êàææFÞ•µ´´T+áùóç´ºtäÈ‘ªÙ†—.]¢ý°ÊlÝeprrÚ½{·¿¿?>ݺuKÞLgK-íÊ•+¶Á¦¦¦-± üüüîÞ½+ï!11‘,„W3™*Ånëׯ}½yóæÙ³g¯_¿nnnŽ^íëë‰×ï;ô°oß>\wΜ9å)äÍ›7G%xe>}Zäž#$ÃÚä¥ÌîE>>>ôrÈÎÎÆWoooé¯6ýó"Ï~òàå@ÞfÒÓÓ¹[2 Ã0 Sá˜9s&3“cKƒ!C†Hü5lØpñâÅ8X䕉ÐÐЦM›Òú‘ k²ùùùááá&L ïÍUsU7!!vàŠtOM“K®®®h®€€333…‹€¥.Ö¿|ùRÙö[Iÿ Á_+++…Ê PB||¼BÚÑÜ«W/^¬g$}PÚ¹sç\\\ ÍJ-$++ËÇÇÇÐÐððáÃnnn• 1ãââ:tè€ÖèÝ»·@€éW¯^AþcX®§§·wïÞÕ«WctÝ·oßfÍšI;|¦0ÐUškêÖ­›˜@ /^tpp ¿téÒ‘#GäÖ£³ …Û!œÀËË+55ÕØØ˜¼„É É› s***Švß»w_;Œ<æW´L¹ÊïÅôüùó*›CJã=OÆ'µjÕ \5'ÖÖÖä­®¬±!–.]*ílþ‹á¯p®N:ÑÄš²6l(¿ Ã0 Ã0ÌGaãÆÉüöÛo*䥅Kä¥ñ’ uêÔÁñ¨©©Mš4Ií|÷Ýw;v¬_¿¾tâ.]ºTQO±æÛ¶m‹Ï¹¹¹Ð’öööW¯^ݵk—††Æ?ü½OŽ ¨V­Z›6mŽ;V5;¤©©)M‰œê C'|öìYbb"ÄENNŽÂ9¥Rë_¼xáìì,œF__¿°°ê>$$DaoooÔáæÍ›ò+òÓ§OÇï9r$¿s™ŽGþ;·´/µ3Ó:{Y3âùš:u*Õ¹OŸ>´ùEe ÍQNË–-333ÅçÂ#FoZé— Þ°~ýzš2U–ÀÉÉ êÕ«Çûˆa†©plß¾½<Þ“$DDD@:ijj>\zÝYŒ H תU«B7ãË—/Ɇ“ÂÍ7lØPø‡cl‰A)ÚjΜ96l€Š722zôèQlllUŽ'˜‘‘A&µèH"³Ü¿­9]påÊ…‘Ð9ÝÝ݅˹zõj©666¨¡²111...8+¿'ÅÊÊŠ&+F¾cª2yyy´f=aÂ1ñß&&&¸è·ß~[¦\xMÑÌ$Þ`ZZZ w£”‰ììì6mÚ @¼ÅçJOO'úäé?¹4¶É‘L¡(3(..<éÜ3†a†©Xì޽؅ ¾Ûb!²|}}mmm Ï• û?nÞ¼igg‡³´® Dc-ÃõOŸÍ›7Ë‹÷/¾ø¢C‡#FŒ˜?þü¡££ƒ±4„'¤Ç.Wl×®° ,i­ý_‰MrAAz†ëŽŽŽòÉôõõ…Ë‰ŽŽ~ôè‘@‚·oßÞ¿ßÏÏÏËËËÒÒRašÛ·o'&&ZXX¼zõJú8êF“W+W®ä[ÌÈsèС5jÓ6t’£î­­­Ëd(•””4cÆ z³õìÙÓÛÛ›ŽãmæáᑟŸM­Úk<B§+ !¡Œ¡C‡"×Ñ£Gé+9€Å¿3á\ØeÊ”)Ê,Y² Ö­[ÇÝ’a†a˜ŠÅúˆ; ¡˜hßqhhhÅmÆàà` È·lÙrâÄ ¨KOOÏøøx‘®¡ÂÁÁ.¡8ĤÏÍÍEkÓ½q =‰ÅÄĸºº uíÚ5á/^¼¸zõjaa!þ*´óÏÎζ³³KII177—9Eq¸š4i’ššÊw™QÈ“'O† &ñU2iÒ$ôç¼¼¼÷wŇâZmÚ´“øöíÛd…õ­¥¥%c¦Ž¢"""ððÞSÍ‚}òäÉ(- þ)ÞŽƒý#Ö¡uëÖ¨ƒ°+r¦róêÕ«Î;£,^¼Xdz(hkkk²lŠŠrttÄ_ù”ÇWh^Bxxx©{ù¡èq¡—/_Þ¼ySþ,ÄH|||PPú0J“>@ÂçÏŸç»Ìcii9|øp‰ÁOݺugÏž}ñâE1áË ú3.Ѹqcádééé ,xAQö¤àI tuu-Ó6y ô˜–©þÈ•““C%ДHbb¢@.333ú-Êš4--,üQ wH†a†a*íhêÔ©± (ÓˆŽ©|ÐF†¦M›Ê‡}Wˆ¯¯¯………——×%±ííí•-¢@ˆŽÛ·o›ššš˜˜àƒ‘‘†÷ÐPôµT—zàñãÇéóc]ÿäɈšû÷ïKï8.**8p ~ר±cÙxƒ úÒºuëš7o.½©ç›o¾Y»ví;wÞ•Õdx©ŽMlllhóûgŸ}¦¡¡A Z!ùùùÑÑÑ/_¾ÄS¯B}þøã\¨cÇŽ"Wüß¼yóÕW_I˜ Ý.¥:ʨ^½:’mܸQY‚Áƒ#Á©S§¸+2 Ã0 S8|ø0Æ03fÌøˆu˜2e êpâÄ ¾UÚ_¬p5\!úúúW®\ˆöóóCöÝ»wgee½§ê%''›šš¾~ýš%&&FY²ââb™Þ;wî¤UW^ûcÊ º“ƒƒÃ¦M›úôéCûS|îÑ£Töŋ˴!]†¨¨(*Má¦øìììåË—ÓuÛ·o¯p‡‹ ‰‰‰¨0[[[ê“‘‘A>ëð/Id–E‹!ýš5kè+E©›={¶p®ž={ [Úkkk#ºº:wB†a†a*ûöíÃfîܹ Ï~÷ndçYªË#¦RRTTÔ·oß2 ¤Ï;]O7hýêþýÕ0!!ÁÞÞÚ\Œº‘àááA“gÏžå»Ì”³¢Ã/Y²„¢EHѽnÝ: áÍ& ˤä3BžwèÐÎB;‹Ÿ1ËÎÎ~üøqzzº©©iYëó_É–\±Q£F"ù¯_¿NKüôõþýûøZ¿~}áˆ;vì ‹}ù`”„»»;MÇq´;†a†a*ä}ƒ7…g½¼¼žÃˆÑÝèxÓ¦M«S§Ž´~¯^½~ûí7œ Š×××_´h‘Ìf||ÅAœp"WTT$ãAÎÝݶ¨ƒùóçã…Ovõ"çÍ$Ü¿y£¢¢P`YõùóçÉ›ŸÈGuРAHüøqéçnÓ¦M¹š6mJ^/”%˜7ož˜r†a†a>Ö­[‡ÌúõëåOAÅcÜèââòôéÓ€€ˆ)OOO|^\${÷îE0”âÛQ¥xûöí¨Q£pëGŒ!rÇGttô•+WÐ'¡JâââðAâ5KôÛǧ¤¤”É<µrttÄU‚ƒƒïÞ½+2×Ñ£G)"‡x`Ê :6zÚœ9sh¾‹hÖ¬Ù²eË ”ét‘¼ê‘†üÀCóS‚ððp¨þ„„<>¨˜ø_ñìÙ3äruuEáeúù¨dûöíQþùGLú¿ÿþ›¬bèë¥K—ðµ[·n¹fÍš…dõêÕS–àêÕ«HгgOî Ã0 ÃT–,Y‚Œ¶¶¶@šâââØØXœGALaÌæìì±óNlŒOœ8:L™2…oG•âìÙ³ä‘[üàßÆÆÆÞÞ>'''??ßÍÍíܹsbÄ¡åMMMÓÓÓ-,,Ê´d½ãããóôéS2-YCÒGì/‚)ÑÑÑÛ·o—ÞA…»e˼uËäçOǽ{÷Ö®]+Y|' cÕÕÕOž<)ñîHVë½{÷¦4?þø£ÌÔ““D½ŸŸ_™ß_½z…Œø'Nüþé×B“&MÄÌÓ^x¼Còòòð5))‰,óeÂMÊ€ÿ_ô{ñh+L€· mFx†a†aÞÓ§OÇèåÈ‘#bcìäëëëààR¢...AAA¹ŠŠŠ ©bcc###“““å·9_¹ru9r$ߎªÃË—/6lˆû¾wï^‘YÐ… q Ðñ]ÄXà¿}ûöùóçè«PèÏ—©’ÞCÅÅÅYZZŠIJ?jÆŒÆç$S @·„ &A Ð…V®\‰ƒåŸ5…²>wîÜO?ýD^BÇŽq‰Fá3Å}ÃEõôôäK(..Æã½Œ'Hø=/T¹µµ5rÙÛۗɾ«   mÛ¶¨ÒþýûKM,Ù kÑŠ,Yjt²jØüÕ¿$ÐÕÕåþÉ0 Ã0L…`̘1½\¼x±L¹^½zïçç_’æ222Â_333“ÿqïÞ= í¼¼¼¼½½ÉpúôéÓÒ¥‘[ã¡C‡òí¨:L›6 7½OŸ>"ÝÙa´ïîî~á¨ìÂÂBŒù/]º$&/´¹……Err2ºø ò„““.yYjâ””Z!íׯŸ ÎÀ™ªÆ›7onß¾MÑÒ |¾|ù2-=«€@÷.**»wûöíƒ ’L H˜0aBll¬²¼xÜ,--ÍÍÍ’ÉóâÅ‹§OŸ"#Ÿ2=z§N¢Ýbž#Ú ¯©©I_)JÝĉ…s 0ÉÚµk§,ÁŸþ)&jÃ0 Ã0Ì'B·nÝ0z¹IY¨ªÌÌÌÔÔTúŠ1ªÈŒ2)oÞ¼‰:`ÀÉ·£ŠpëÖ-Úîéé)2KPPÐõë×ÝÜÜ Pîß¿ogg'àLh ¤ôòò .S%!gŒ_½zQSjHˆœœráÕ¢E‹²3U·oßš˜˜H¬ß«W¯>þ|Ÿò”ùüùs›„„???ôv”xcãüå—_êÔ©óÙgŸíÙ³§Tà ]—””„'BÚ~©DGG?zô/žYñ;ôóóó[·n–9tèP©‰õôô²k×®ô¯|­Y³¦°‘ÀáÇÉÿp… ìííi;Þ0 Ã0 S!¨_¿>F/ÞÞÞå/Je]±"êп¾U´´4rß-ÒÝtqq1ÆÞǧ@ðÐ/§OŸ¾té’˜¼QQQ¶¶¶ <*¥;wîÄÇǓ忯_¿ž4iEë+§:c*=}ûö%Ee½~ýzùø‰èEnnn999¹¹¹îîî"E´¹¹yVV–«««³³³˜uñËèxÂÃÃQ%;;»2YÝD&Ù|GªK—.Åíþúë¯Eª¨æàà`{{ûû÷ïCà@§`ä_jÆ·oßÞ½{b“’’ÊZO›ÄÄDa£‚¢¢¢Ù³g“ó.áÀÙLÂöûï¿§WníÚµ¡è•ÙœàѸyó&ú<Ô%:¼™™Y©#DXXžŽôôtKKË2-¬‹!44ÔÉÉéÙ³gx4Ä/¾ã1tvvö÷÷/õ1LKK;þü˜1c¤w ˆ‘Õ´þÔ©SôuÙ²eøºbÅ á\ä¢pÈ!ÊÐ&µcÇŽq×e†aæ#42‡...þ`º>((HÆ"úÞ½{¨F=øŽTz RÈüƒ|‘Y á}}}ÉöñãÇwîܳÛ>|øýíÁƒ*TÕÈÈ(!!ÁÚÚZÀå~aa!…ÌÆCdbbÂ÷—QHVVVß¾}i¸zõê«W¯~ùò¥p–ׯ_›ššúùùAÚ£'߸q£Ô,„Ä•4xYÃÌA}ãYÃåðA¡ Žˆˆðôô¤˜§â‹ÅÿdQv677×ÀÀ`êÔ©ÒúúôéCÄüêmÛ¶!¥ºººä?¾¶lÙRxM0ÖªUKY‚]»v!Á´iÓ¸3 Ã0 ó‰m…qK›6mÊ_Ž………˜”VVV2 µPj¨FïÞ½ùŽTnpß¿þúkÜë_~ùEdŒÌÏž= …BÃûàà`tZ1;^Ñ!=z„ìvvv*˜£@׸»»»ºº>~üXàd- Q¯¯¯Ï÷—QÆÑ£GI¥BÝ‹÷*…nlllnnž““ãææ–šš*föõë×ã–k×®EEE‰¼\xx¸ôzz~~¾üþ,ÄCááᑞž^Î÷îÝ[°`Aݺu%r¾S§NÛ·oGeeeщÿðœ"%Ê¡mÈKS–ÿ8K—@Û*Làâ₳ 4x'óÞ Ã0 Ã0ïŠÂ/µL4•†*Ñ‘qãÆáëž={„3Ö®]É.\¨ð,ZïË/¿Dîà Ã0 Ã|ÊlܸQ8†¯x,--•9.U×_»v Õ6lß‘J í5¸ÑÆÆÆâsadŽô·ÇÅÅAàûùù‰Y;ËÎζ²²zñâ…©©iYcÛISXX¨ÐeÄηß~KF¼Âî¹æ¿’   ûÙgŸÉúÆÙÙBØÕÕj]__ßÅÅE¤|ƇÄx ð‚…L.5 RÊïWèR5--ÍÁÁ!!!/s‘ÿÿ+Ù£­­Ý±cGIS4lØpñâÅæææò»õccc)ÈüäãÿÑèë‘#G„÷Î#FŒ ™Fe hînÿþý܇†a†ù”¡âbb © Öŧ¼pá»2`>M {õê…»üÓO?‰ÏehhèããCvËP7bƒãZd?ïïïÿ>¼Ó?yò¤]»vø-7F­øæ2¥’M*uΜ9$핹aWHLLLpp0¤zxx8>ˆ1Mÿ¯$žÝÇ!í!ê ÜDHpww—9¢l=JCÉOŸ>urrŽ(÷üùó|óÍ79_«V-uuu===Ï™aaaä‹@d]¾|é»wï.ýóÏ?öÔwîÜ9ª’² þ9âì„ ¸3 Ã0 ó)CÁëÍÌÌ>®®?}ú4ª1qâD¾#••;wÒNU1~ì‰øøøû÷ïß¼yƒÿ/^\ºtIâïZ˜ÌÌÌ   ¨ ‘FËeâÖ­[´¸uëÖ‹O:uÈ»û/¿üBÒ^GGG|ö—/_C×\¹rÅÑÑQL®´´4¤LOO‡´ÇãPê´ž5777‰ÿŠˆˆ•xBÝÝÝñ )<‹'?pøðáä-ö à«®®n©¡ëÀÇé)Ù> t!I…»t邯׮]Èõúõkò½ÿÏ?ÿ(LàííMáÑì܇†a†ù4ÁŽì¢1V”95„ø¢¾ÔߺþàÁƒ¨ÆŒ3ø¦TJ ²kÖ¬‰[|þüyñ¹ |||0bðàÁ½{÷ RÄd´¶¶†~ ™^$EEE›6m"…2lذw’©:z2Þ–kÖ¬!iôèQñ%@±âå‰ÇjÚÜÜ\¼ã ‹ØØØàà`ä*5¸$Dý“ÿ!ì‹ÿ#äçÍÒÓÓõôôÔÕÕéŸ 1`Àhü2mÆ¿uëeŸ…¶Æœ={–¾’7¹sç çêС’!¯²Ö ûNNN܇†a†ù4ÁàÕúõëËÍ’““ýüü0nÄhPŒ‹3ŒE:yÎÍ͵µµ•9¨¥¥%&Ü0SÁÀxøðḿ£G¿zŽÎ y~ãÆ˜˜Ûîó•rþáÇϟ?™^ü$mÅ%………|g™21pà@tÈÕÿJ&B555©;•êÛMBff&´¶¡¡!^ËwîÜÙÉÓÒÒìíí‘åñãÇ&&&ïûû«W¯ÌÍÍgÏž-«®GÚÚÚ"½öÉ ££#ºN [·nE–ü‘¾ÚÙÙ‘ð5ͱԨQCYŠy±{÷nîà Ã0 Ã|šœ9sÕ‘#GÊŸ sttô÷÷‡À÷ôôtuu}úô)†gÊÌ81Vz  ù@ÆPô¨ Ô=ß”ÊÇñãÇqsk×®-oR*yyy÷îÝ;tè‹‹‹H¯ŒVVVqqq<111ïê'èéé‘[ìºuë^¹r…ï)£äÌäàÁƒôÒ~ýúõ¤wîÜ)²HrômkkëÿJÌà¡Öñ®“¯nSSÓÈÈHÏÊdŽ%\ÔañâÅõêÕ“ÈùöíÛkjjúúú–§äÍ›7£¨åË—‹ÏâääD)ÙÌÒc+¼ÔŽÿkTm… þý÷_Þ&Æ0 Ã0̧Œ†††+€)<‹_jjjll¬››9UÀP êÌËË ¢)++K²ü*~s½………¼ò™3gJx™ÊDçÎqs¿ùæ›èèhÕJ€¢Gß“2!!!44ôÞ½{!!!ï¤ò¨³ºº: û(?%Å0"Ù²e zѲeˤnÛ¶zW™f5srr=z„÷3õv-ðÒÄÅÅݽ{/ögÏž¡c—ÇõÄ›7oðOÿ;š5k&‘ó­ZµÂ/¿µÌ„ P¦ü>®l{~QQQƒ h³ùé§ŸðuóæÍÂ×"ù/Yè—áñãÇdØÆQì†a†ù4éׯ†+bÖ¡Ä!ä1Tó÷÷wvv†Æ‡º—‹¬««+ò¢ g(Öp™6_3t°Zµj‘Al™"w« Fþâco)š‚V!«U«¶uëÖwµÄÉTÙAa䵿ÿþ›tq©òS$9ºƒƒºº‡‡‡©©©˜I3ÈRèq ²™wwwWAÚ ÇªCù§OŸ6l˜——W9›«yóæ(\Æ=`JJJ:uzôè¡,׌3¤[òâÅ‹´@øZjjjÞBáY<øäóÐÏÏ»1Ã0 Ã0ŸÙÙÙä×H¤§ô '... @ÚÎÃ-ƒÇ«¦ë1îBM8xe%88˜&‘h—½HW {{û>}úP…¿ýö[H'¾‰L9¡eß ÈŸ:pàu¶M›6‰//a[[Û/^ ÌO ÞZ8[¦Ð„ Ã0 Ã0 1PiÖ¬Ù; uÿàÁ½ö u=™A–s?&ó)SPP°uëÖ5jàF׬YsÛ¶mbb]}x á¿ÿþ{äׯ_ÿèÑ£l|˼233Ä#Å«V­ÿN¶³³svv&w(é"¥ýÓ§O‘+66öÞ½{xi ¤DŠU'‘óÕªUSSSÓÓÓ“ŽYŸššºzõêéÓ§GEE‰o¢¢¢‡*t’ýúu\«k×®ò§h ÿh”U˜„ü‹/èHÿþýñU8D&þaÑ,7ÞQ Ðv‰yóæq7f†aæSƒŒ?úé§w^rRR’¡¡á­[·‚ƒƒÅèzŒEiĘ’’Â÷¥rB&¯dõzàÀ‘Þð>®®®êêê$ ªW¯®¡¡‘À·Œy‡´lÙRz÷· äŸ.ˆtCúúõk2ÈGz¨õ˜˜‘aÖ£££ïß¿‚×µüYùXuŸþ9Ô=4¾Lz\)‡ faa!²RSSõõõç΋·lÙ¢0^äÂ… •ù~YµjN­]»VYù½zõ’ÞÕµcÇ| õ?V} L$úeæÌ™ §¤æ¼u¡Ž•%8sæ Í,-_¾\¤´ÏÎÎNHH@…¢‡Æwww#íóóóÓÒÒd¾zõÊÈÈr^>V¼k><8/^2dÈÁƒÅ„} Ú¿ÿ¸qã ±Oœ8¡leï—¦M›âÒ–––ò ôôôpªÿþÊ.DŽôg̘A_iûCÍš5srrªG±V«U«¦°Ù³²²hŠCeçŸ Ã0 Ã0¼…Æ·°°¸páB™jUPP`nn.«RWa\‰ÜÜÜcÇŽ <øÈ‘#ÂbÙÕÕBòéÒ¥&&&éÐ>’?Tÿ§ä“QX:<­Ê6iii$Øå­Ð¡|Ïœ9uOÁÔnܸARwöìÙ"ÝËCÑߺu Ùƒ‚‚ i•ÉÞÿJ,U´´´Zµj¥0VÂô‹-‚Hÿã?„c½ùøøà±EÊ;wúûû ¤ÌÈȸxñâ˜1c¨Ahê+W®”¤2¯Y³FY‚üQÚ ž‘‘¾âÙžë \õë×Wxwg{÷îÍݘa†a˜OòtíÚµO¡2£FBetuuù¾Tq LNœ81bÄéÅ;йsç¹sçjkkC¶@8ÄÇÇ ,bæåå…‡‡;;;_¸paÓ¦M“&Múꫯ¤K«^½úèÑ£utt:ìb˜÷ yuSö†¶¥—áÍ›7ÑW‘X]]]¤7<þœüoH`†a†ùˆDFFRhàOÄÝ7É.‰Í$䦦޸qcÑ¢Edp+z/ºÍ×_Ý©S§`ÏmÛ¶•Þ , FãÐS·oß.u5aÞäÎ]À&¼¨¨H³¨cCCC¤?üðƒH«’   ™ÝU"cÕ©FRR’¶¶öàÁƒ=*¹ÒÛÛ[Ææ,ŽøùùyzzÒv‘MIIQfö@ÄÄÄÐ[BRpìØ±8òÏ?ÿ—L­­Ì€öé;::r7f†aæSàðáÜ`$ö)T&!!ÆxÉÉÉ|kyâããMLLvîÜ9wî\è÷ºuëþ_i`ÌߢE‹#F¬X±âÈ‘#÷ïßV óÁ Èì={ö,õ-½páÂââbccc›“&M*Ó†ŠUýNöƪËË˳°°€Œ=tèPYHZZÚÖ­[Guûömíó!!!þ;w–±ù···—,ë“ËzH~ñW§GU–€l._¾L_)† r ‹7 ’uìØQáÙ~øgUh+†a†a˜÷Á!C'#´÷F•¨L»víø¾0"ÉÍ͈ˆpssƒ4°³³322233Ãggggÿøøø܇F…Q%”‘Â%DFF~˜%Î]»vIÇf†©Ü 0/½ãÇÓ×üü|¨]eÒ~ñâÅÐÎVVV$íG¥0TœÂXu:tÐÒÒ’lÇ… &Mš„÷íÍ›7!½ËZsÔäêÕ«ƒF9 §äg$F‚ÚÕÕ)[¶l)¾&QQQT¸²Ýdvvvd ñÅA6Âê233©ÚçÏŸ—?KqdÚ·oÏ}˜a†a˜Î‰'02éÛ·¯²nnn¾¾¾5=zôÈÆÆÿÙ³gïÏSдiÓÄl{d†©ìÞ½/½qãÆIÄò¦M›”½‘xÛ¶mø€·qíÚµ‘qĈ’²$V]Ó¦MbÕâÈСC<¨²[??¿±cÇ¢ù‰…ââb{{{™Y2>ÒÙÙY>ü_©P¨J…œ&:¨2®®®tdݺuø:þ|ábi=YþTZZÍŠ'&&r7f†aæãB†‘+*KðâÅ wwwccc 1~ƒ¨Ç˜ßÜÜŸ#""ŠŠŠDÆ]CË–-Qkkk¾5 ÃT(.ƒôŠùöíÛ!<n!Y½zõéÓ§ñÚ¹N:ȋ׸““Óï¿ÿÞ¢E ‰ŽnÒ¤ÉÊ•+q\z%ÝÓÓsÆŒ³gφv.5¢=øûûŸ:uJ~#ÿÑ£G§M›&oåE!ó¤«ÑªU+šUß ¨3¹Ñ+S3þý÷ßÈ5yòde ÔÕÕ‘€fEhb_5j$M@ø#ÚYáÙ¯¿þgïÝ»Çݘa†a˜Hxxøg%(3—€‘!Æœ)))¤è1"JLL„ÌǨc0Òøéééåt-ŽBhÏcFF߆aª$õõõ¥žàë‚  4e¦[ñ¶‡œ_´hQHHˆpe¢££/^¼=;tèP cccy{“-[[ÛîÝ»·k×NRúõë/[¶ìÁƒb¶ê£ªÒÉT°o÷óóC®5j(û÷qêÔ)$0`}-((øòË/qÄÙÙY Xrâ¼½½åÏÎ;§þþûoîà Ã0 Ã|DvìØ¡ÌÂPx –œœ€±œ………»»;ô~ZZÆd>}ú_EFX–æÂ… Òã.†a˜ªÀŒ3(|¼Ìº6$'Ä5^ªy¡»IxBìß¼y3//O&Á«W¯´´´&L˜àã㣬·oßBÀ"Ù°aàUÏŸ?¯,fœ4xÕïÞ½»ÿþ9Yj–êÐ(,,<}úôàÁƒƒƒƒ%ïß¿/à…¾Ôé…giþgŸ}OG~üñGÁ¯.–\üüóÏò§È¯¾€‘Ã0 Ã0Ìû9AM«\o‘‘‘[>|ør>,,,66ÖÓÓÓÆÆ¦T;O-Z„úlذïÃ0U„ׯ_Óþ#¢_¿~—.]’˜¾ÇÄÄŒ=ÚÌÌLYö/^PF…+ã<2dˆŒ%€„ââbÚ4æææ¥nªÂUÜÝÝ·lÙÒ¥K™€’C‡ï|ÒÓÓÃu8 3 `kk‹Ò:uêT֖ܸq#2Μ9SY‚®]»"®K_ÏŸ?¯½zõ.–BÆ(ÜïO®7n\Öv Ã0 Ã0ï ÚÃX»vírÏK(((€¢G±–––ø B mÚ´A•F° Ã0• ÁF›¸%~ã[´hqôèQZ|ÏÉÉ™5kÖÎ;*wÊ"³¿¨¨èÏ?ÿDF…žç}||Ö­[źuëVOOÏRe)d¸ÝêÕ«[µj%òÕªU3fÌñãÇ555•­h+œ022Â¥µµµº`µ¶¶FiÐàemIwww2{PfŠOõœ7o}}ùò¥˜ ƒä])å=æææ¢pVŒ?@†a†a˜÷ÁÂ… Åxþ`<}ú”œG½«y†a˜Oœ{÷î‘´_ý5”æŽ;È»DÝ¿zõ º[GGg„ òîëccc)±Œÿ7¼ÛÏœ9#“8//OWWwĈ¿þú«Ä3¼Hobb²xñâFIä<„óÔ©S/]º$™1 ŸuK—.. ¿ÂÜÜW×ÒÒxÏ[ZZ¢´nݺ©Ðž´"ñâE…giÆ¿E2Ò·o_!?„ÊÈÏϧ{tøðaù³={öÄ)´wf†a†a><ÉÉÉ5kÖÄhäáÇŸH•:Dá˜ùî0 SxñâE“&MðÞ#WííÚµ£ãPß­[·&ݦM===ˆbOOÏáÇËìÁ‹‹S¨ëe¾&$$@M2ääÉ“¥*MOO722’ TW§NÔ5ÉÊÊ’I¯­­]ª®···Çëu÷(?×AqñThÒ;w"ï˜1c”)tŠ àîîNG¶oߎ¯S¦L.¶mÛ¶H6pà@ùS ,`×y Ã0 Ã|,öîÝK§OgWà¸qãP¥}ûöñÝa¦Òóúõë¡C‡â¥×»woòתU+é¯^½ÒÑÑ‘¬ÝCûûû'''C„8p@b“ÁN ä=æI„¿¦¦æØ±c¡—…½Ó§¦¦ž?^MM­zõê9 hhhX[[*ËHº~É’%ÊýèÑ£Q‘qÞïÞ½«²®ˆˆ  /ÊLë'Mš$-ÃÉt¿víÚÊZX¾|9’}ñÅò§<ˆS?þø#wi†a†a>0ÅÅÅèÈ‘#'Ož”8þˆddd`È„*ùúúò b¦ÒC{½ëÕ«Bêò«¯¾’O–›› ÕLæUÛZZZùùùÐõPß111ÿ•¬Ë+Ûâ÷êüEokk+PHZ###uuuz íÛ·G !ɅûÛ¶mC–_~ùE渋‹Ë„ 444Äÿ—ñððèÝ»7¹ÖW­ai¶dÿþý Ï?~g D_ß¼yƒfÇ 2q¨YdNÙØØàx‡¸K3 Ã0 ó¹sçÆ!_~ù%ùŸ_½zõG¯Ò•+W(°{f¦ÒcnnN[¶ÉS½——¹UW–>,,lâĉ$-¿ýö[ÿððpÉžnr§/mŸ_\\|êÔ©Áƒß¾}[Y™………(á§Ÿ~¢8nD—.]¶oߎòËôs¶lÙ‚¼+W®”IMME…ñÏE¼Õ¨©©Ij‚ö^CWÆéÓ§‘½{÷îÊZg?ÿüó¤¤$:²xñb1ÿëÖ­‹d³gÏ–9Nö¨­2g} Ã0 Ã0ï‰Ñ£GS0 ŒmðaÅŠ½JdYja†a˜ŠNtt4$¼´–ôóóÃ×úõë g422"ÿu5kÖÔÕÕ•0`ÞºuKrjZGGG™å|`` ^¶´NM´mÛVSSÓÅÅEµ™Uré¿víZÉ‘¢¢¢—/_ŠÉ‹+Þ½{—bÉ‘âîÔ©}¶¶¶V¡2iiiÂÖ_Tþõë×é+ÚZ@ø·3Éš5k&ŠöJ8;;sßf†aæƒáééIc§o¿ý–ÆN¿ÿþûÇ­RJJ EwÂà–oÃ0•˜‚‚’á}úô‘Äm§h uêÔ)5û‹/ÆŽK¯îåË—S˜û©S§âë¿ÿþ+œ733óĉdåN4nÜbüÑ£Gå4”B!( ê¾L¹Þ¼yM-©þ ,Y²$88øäÉ“tdãÆªÕgÚ´iÙ׬Yƒ³‹-’4 ý (óêÕ«T+y/ãÇÇqT›»7Ã0 Ã0Œ™3gbBK⣯’ëêê¢:uâ»Ã0Lå†De½zõBCC%iû¶B·lòkkk“µÕ¨Q£ Kÿøãáðñ¸–¦¦¦Ä¹=òª©©éééI&ÊÉÊ•+Qì–-[Ä+zsssŠ1G?|ñâÅÏž=£³û÷ï§ã½zõR­>FFFÈÞ²eKI<;iÈß~Ó¦M%^ɆMÙ–|I³S›Ë»¾§öÿ,߆a†©"DFF’‡%2æ$§Ç"ŠÉ‡äûØÿNžð·oßÎ7ˆa˜J éMpãÆ éãááá$·ÅejjJ!ÛúõëwæÌ2OæèèH«ÉDÇŽ8ðn—†††È)bü111éÑ£Õ§nݺÅ2õÙ±c‡d‹½Hc~òóó6lˆ: ÌÍÍ%—žžžt„¢¬Ž1B¸ØÎ;#YÏž=eŽëëëKûâc†a†yßÐè«E‹äîø‡~À óÄäõ÷÷úô©³³óƒ‚‚‚^¿~ýNª”œœLÓ (œoÃ0•ˆ÷ à]·fÍ™SQQQ¤d…ãÐÉðèÑ#š¡íÒ¥ ÍÓ’Y>acc3lØ0ÉýäÉ“Ks§2«V­ÂU6oÞ,œìñãÇ£F’(zMMM…~ò7n܈Mš4Á_===Õªô믿"ûâÅ‹ž¥¹Ž]»vÑWüGÃ×jÕª¥¦¦ ”InLf~; €‚å)4`†a†y·ÄÆÆJüöÙgÿÏÞy‡Uq=}ü5ÑØb¯±kLì-"ö‚bï»hì;v±c¢ˆˆ¥**HDŠ (ˆÒ‹ ú~æqŸýÝ{Ù»\01:Ÿ?xöž={öì²gÎÌ)3NNNd×ïÙ³GÎå÷îݳ··¿ÿ~PPÐóçÏ£¢¢ 7úùù¥¦¦Ê „”û÷ï—ð]Ì0 óðþýû6mÚÐ(+œ…D%É,#^%°(+W®LÆ&þzzzRbŸ>}¨@û&L ý¬OG› $öׇ…… 2DXu?þ|Á½2´ªÿ÷ßï‚Ï/7oޤуŒŒ å³;wîÄÙN: )äLOaE^ÿ¦Ë—/‹Ó³²²ÈSŸ°•€a†aæó1kÖ,aíý¼yó¢­­c33³| (i·nÝ ôètHWWט˜__ßäääüÖê·ß~CÖ¯_Ïÿ †a¾V`ÉBЕ+WbSùìË—/É`Ô ²›…`#A ›l|ü>}úÓ§O k\B⬡¡!îh`` |*33ÓØØ˜†”‹)2räH•o@ 8S÷T­Z5Í6áªzõê‰ýÞ‹ Q˜ §¡‰qãÆIK+.tuuÒ›4i‚t[[[þÔ†a†ù¬<þ¼xñâ¤ûA!wI-[¶ÄÏK—.iP`VVÔ³7n8;;?yòäÅ‹Дîܹãîîž/^šäœÊUTTÿ†ù*±··§hõyMC`’pNKK£”€€€ž={ž?^Ž …9Iå B¾_¿~AAA©sJJŠ““ÓÆ Ô©S§M›6Id†å®2¶»ƒƒƒ´®sçξ¾¾rn]»víÿ±xñbµC*Y¶l½ •g4h€³gÏžþG @zù,zd+_¾¼BúСC‘¾mÛ6þÚ†a†ù¬ÐÊFŠ%äççG‰4qýúõþòåKXôPA}||"""`ã㦺«««ôúÏéÓ§£ÐùÄ0ÌWI\\Å7Ÿ:uj^y’““I>'%% ‰¯^½‚Y­­­=pàÀuëÖÁF†tÍËÌ1b•P£F …Uârxÿþ½¿¿¿¥¥åŠ+`¢jii 0ÀÈÈèêÕ«ñññj/?ränݽ{w!%--ܹ›Vù[û«T©B]•غoÒ¤ÉÒ¥KÝÝÝåïa&åUú $Ÿ'NÞÅ @_&Q¦ ÕGa!ÄòåË¥ÿÅ Ã0 Ã0&6-¿WåS±bE¤ÈœC‘4.òžžž‘‘‘°÷Ÿ¦³³3ùb¥Ÿ°¾iиH‘"Ó§OVÈ\Ùã‰Ð7-Z´HKK‹Ìè¶ðÈæææ©©©j‹"Ÿ*§Ñ/_¾L^d…uþzzzH….Q 2SgªàL€¢Û£ªüÍ3 Ã0 óù õ`øðá‚#è'aaaŸã¦AAAÐÊ„@BÊPØúÚµk³a†a¾J6nÜHËãïß¿/‘ííÛ·$¢Uú‡Ï‹wïÞÁ䌌ŒÈåÞ½{~~~¹.¹888œ>}&<$-þ’¥¿wï^ü„iûöíi÷ïò!þ°¾322`Óÿ5j¨ 3§r@N`ˆøøxò0çi(˜À]`Gã¡=z”WQ å^æõë×´mïR>œW¸@1Íš5C¶† н½½iÌ¿y†a†a>)))uêÔÊѨQ#±S&(`¤Iø%þ¬´mÛw_»v-ÿ†ùúðôô¤±SXÓÒ9³²²H?þü¿ø¤°šË–-‹ú·k׎dذaÌûdn¯^½ZåP†‹‹ LþZµj‰Wé7hЉ8¥°;ÝUL¥gƒ=zà”à: ::šÜDFFJToÍš54ˆ!öš––F×ÊÙ¶À0 Ã0 “_Þ¿O«@«U«¦à›îÙ³g´N² Qê4ÆÏÏ&\þ£z,Ã0Œ¯_¿¦°òºººj=º#ƒÊ]Û_oß¾½wïž™™ÙÂ… ‡ "î;„Àô%J”8vì˜ÌQš‡‡‡B" †lß¾]úÚ   ccc---2¨‰Ê•+ëëë[[[ W­Z…ôzõê‘·X1Û¶mé.]º)­ZµBÊ¡C‡$˜H÷277§×¨Q‰·oßæŸa†a˜Â%++kРA¤h¹»»+œõññÁ©J•*ý+u›4iî®§§Çÿ&†a¾>ÈUi•*Ud.ˆ¢µëÿbtÔÓÅÅåÒ¥K0ŠOœ8±ÿþ7.^¼xÚ´iÔ0~a¹÷íÛwΜ9G޹{÷®ØLvtt,Y²$ê¿^^^jïõáÇsçΡÀ™3gššš*œ¥ÝôG•_sZ¥OŽï„á…^½z™˜˜„„„ßÂY³f)\øðáC^<¬X±)”¾cåÊ•‘­[·nâDšýW~†a†a˜‚““3nÜ8ò*¬2¨.ÉÉð¿¢@R8ã‚»âg†ùÒpvv¦Iä‹/ʼ„ŸÃý·êìïïO{ðMsÝíääûýÉ“')))^½z•*_½zu9"=88¸OŸ>° “““Uf Ã|̘1¾¾¾ù ^ÿúõëK—.M™2¥jÕªâUúB¬=…Kh“Úùóç駇‡Nˆ÷¬)3räHd+]º´8‘üØ(øÓc†a†)Ð…h¶è»ï¾³´´T™çرcÈ ££óÏWoíÚµ¸u³fÍò¥³1 Ã|ùÀ\­Y³&yt—•x®™¦›+ü/°šü/Mš4iû¿têÔ©×ÿ¢««;bĈ޽{7oÞ¼lÙ²øK—.ݲeË¡C‡Îž=ëàààååûþý{ v4¤4h´-LÓöíÛQ Ow‚«oòÏ?ÿtttÌWõrrrð\+V¬hÑ¢…¸4tˆüñ‡°Ø€b­N™2…~fggÓ\¼½½½Dù·nÝ¢…Dr»‡ÿ7†a†a h&S§N¥½óÇÏ+ÛæÍ›‘gèСÿpõ233úé'ÜúÈ‘#üÏbæ+ƒJÕ­[WØâ---­ÿû·)Y²$„s“&M:uêÔ¿ÿ±cÇΚ5 Öñ¶mÛ ®­­­]\\|}}ÃÂÂÐÑ\¼x‘Œz]]]µv÷«W¯ °iÓ&é@öIIIT™=zÐ2Ç#GŽ´°°Èk–?/ž={¶oß¾ž={Š·á—*UJOOEãÛxjayüøñH™={¶t±?üð²MŸ>]H‰¥ÍŸ)Ä Ã0 Ã0ßoß¾Mûú•½1 Ãü§9þ<‰ß7nä묬¬!!!~ÿ‹‡‡‡ËÿríÚ5k°RçÏŸ¶^½zâ€ï hÑ¢uêÔùå—_ôõõg̘1jÔ¨>}ú´oßþ×_­Zµ*™¨3dÈÌÌLé§ èСƒ²‹>>”ÍÒÒ?ñº¤K£x.µk×'jkk#qË–-܆a†))))䔚ÄL=Ñ«W/A·©P¡Â‚ BCCÿJR ¤eË–ñÿ‹a˜¯‰ÔÔTZŒûúŸ¹cDD„¹¹¹AÓ¦MÅóÑ L™2òFFF...ïÞ½“.çÍ›7/^¼ ºsçÎÕ«W-,,ÈoÞ_ý5uêÔáÇ÷ìÙ–lƒ *V¬(4¨W¯žZ£êèèDGGËy"GGG*Y쀮oß¾HiÕªn'~F¤¬^½:¿Ûð³³³ÝÝÝ—.]Ú¤I¡¨ÐÙäädrÈ·!QùÒÇ;ï>Ø»w/ûí7n Ã0 ÃhÌóçÏ[¶lISð×®]S›¿S§NÈ‹þþû__ßË—/oÛ¶mÚ´iÐŽü8Åÿ2†a¾&¼½½I„^½zµpKŽŠŠºpáÂ!C`½R89ñ¢ô¶mÛΛ72â·€7Ç£W ¿Ò ÃÐ1õéÓ'_[®öïßO†¾CšÈÉÉ©_¿>>,ä¤ðvoÃ/UªRLMMe†üøiëxúô)¥ãg×®]¥/¤€õ:t'Ò’¹Í›7s‹`†a&¿ìÝ»—œ5jÔHæZzèoÊÓ ÑÑÑ&&&ݺuSÞn í–~Æ ¡CöêÕkøðáC‡%ËíÚµkÕªUõêÕvtŠÁµÈ¹dÉ ‹‡âb†a˜ììì6mÚ–'ÒÌÌÌ[·n­]»&*Å^óã? ì322 nËûùùmÙ²¥wïÞýúõ“/œiI¼³³s^Þ½{שS§„„„|ÕgãÆÂ“ é¨!EQQ¾äÍ›7¶¶¶âadtpZZZ°Ð?~,}Ç>Po(„¨âÚ'&&J\8qâDrè'NÜ·oñ1p£`†aF>oß¾%ÕèééÉw¿üüùsÚ¨r&åõë×NNNЈôõõûí7…"iÊ•+פI¨£‹/>rä´Ó¸¸8þO1 ócbbB7D«f%Àº ܹsgÿþýK—.-ªÔ¿þú+ÍJ›››çkV]™ŒŒ ògΜY±blymmí9sæØØØäË{? Ád‰‘dH~ ‚¹/Y²Dxp±ëׄ„„%J ÑÝÝ]btg ñºÄ/°iÓ¦HÄ©¼ö&ÐFûŸþYaÔâìÙ³Uõ÷÷§òÅþ…¥øÿŒ¿†a†a¾îß¿OÚ´>##£|M‚ß¹s‡¦ÑådFÉááá>>>0ö­­­MMM·mÛýüèâÅ‹(yØÅ=Ã0ß111eË–…D…TÔÀœ‡U¸`Á‚Zµj‰MQ¨§§·iÓ&ggç”””Ÿ«‰§°?æqsqq¹uëùÌ $wú8pss³µµ=uêÔ¾}û6lØ0{öì>}úÀŠïÛ·ïüùó:tóæM§ûß¿Oõ|ùòeá¾Lá% >\|ê?þ@âØ±cå”dll¬¥¥%Þ†_µjU}}}¼…e+W®¤èöYYY”2kÖ,¤àŽÒw¡AïqãÆ‰»uë†Ä7rÓ`†aF­¡ …Ô¼J•*AKÉo Pöpíï¿ÿÎ/“a¦ L:â´eË–ùšI÷õõ]¸paíÚµ«³X±b]ºtY»v-,}…¢`oRž¨¨(q:Œ÷õë׿kÝ ÔG9î<,ýBwMII¡úä7š¼2¨UHHˆðf;™ØÔ»‰Ç«===‘ˆŽ/_kÀTnÃÇñÏ?ÿ¼ÿ~Ú†)ÝÌÌŒ®ºví~V¬X1;;[¢pü¿­Zµjâį~n Ã0 ÃH©££CJHïÞ½5ó•´zõjåY†a&_ÓºkØÎ2ÍØãÇS¸O¢D‰ƒ¶°°X /ØÑIII_ÂS¿|ù’ê£6‚^^deeYZZêééuëÖíÈ‘#B: pšX§ë€€ñU5^³©p¼ÞsçΡ×+_¾¼x,¥gÏž{öì)S¦ ~¢oþM¥J•BЧ§§D™¦¦¦Êÿ—¸¸8^ŠÏ0 Ã0Œ999Ð"Hý€*hll¬±ºÑ£G£µk×ò[e†Ñ˜¡C‡B–öéÓGmΧOŸ.Z´¨B… ‚c7Xµ§OŸ–³±=::š®’šä ""‚¶€iM°cÇŽöíÛoÞ¼966Vál÷îÝ)V ––vïÞ->{äÈ$Ö®]» N²²²h¿²¯WØòB¶ eåÊ•ÒEQ! C ô6làÂ0 Ã0Œ~~~fà ((¨ ¥Ñ¬Ç™3gøÅ2 ÃhÆÃ‡‹ärïÞ=i+xÊ”)ähT¯^}ÕªUùò°JqI¾ר®?þ|ÇŽ>œW yœEÉMš4¡Eezzzâ³oÞ¼©X±"Òmll RÿœœœÖ­[£œ1cƬ[·¢° _wðàAüD6é¢ÈÞª{º¶eË–ÜF†a†HMM]°`­ëûñÇwíÚU@È€¼<ݽ{—_/Ã0ŒfèëëCöïß?¯ ááá“'O†=N6c§N¬¬¬ò2i%ðóóÃååË—ÿB\ƒuø±±±C‡]´h‘ôúaýƒ««+XQØáŽÞPæ i®^½J»õ)l}TTî…”+W®P†çÏŸ“±¯àÓ@Ù³gÓ‹xˆ#>>žþéb× Ã0 Ã|³À~?pà@•*UHƒ8p ´‚!_¿¢SSSù%3 Ãh@LL MÁß¾}[ù,¤ëÂ… …9ú.]ºH„zWË­[·PH­Zµ¾gϯß<Ë;vǃˋ¥K—¢Ø™3g¾{÷ŽÛùúúŠ3„……щGð)´µµQþœ9sèç„ ðóÏ?ÿ2´hÑ)¦¦¦…˜˜˜ÐÚûªU«â}®Y³Ç'N¤ [¶lÁÏž={*_;fÌœÒ××/à3R¬Ò¥KgddÜ»wþ›Âs%%%ɉXGîþÐ+#´õžöï3ÌWIff¦­­-Z"ÍM›6566~õꕲíïîînjjŠ&3räȶmÛ–,YR¥±_¬X1û½zõ200@Q¸EDD„BÔK†a˜ÄÄDèH´9‘vhN›6MzÕ=Ìù'N@x^½z5/Û_&gÏž%‘Ëÿ†a ¢¼ýôÓO4LºaÙ–l¾HOO‡¶,(ºÂ,¶LQKKKOOÏ‚xbÉÊÊŠ‰‰ ptt¿üò‹AKK )Û·o—(Dˆkee%N?rä7nÌ­†ùúðóóC“b14%ì4‰–õðáC¨¯j—ÙCþ¸¸¸Æ>TÚØ¢Ì?ü@Æ>î‹ü¸ ÆþçX"Å0 £–GAцAP¦Lü”³ ”7h/÷r)H,X R?d†aä#ZÐ3¡ÓB·üwñõõ…uIË›5k†ƒåË—+äyýú5ìè%K–Œ1B[[»[·n°Ça\CÂ/Z´JòºuëŒ?±~ýz¤,^¼ØÀÀùurA~\5vìXtF6l8qâÄÍ›7£¢¢ÔSPè=èØb»z¾Ì§ÃK£Q‘¢E‹Â–n·víZñ,üßÿ]¶lY¤Ü¾}[¹–-[â­€¯š–âÏš5K°P¾ûî;afpóæÍHÁ[’.¤bÅŠÈ‹Cœ˜˜˜H®aàpÃa¾"##ÑèH:åË—G›E£Ll´è;wî@eõòòº{÷. ~†……ÅÆÆ’¸¸ÎÂ`'c¢ Í ¢­R¥±_¼xñ¦M›Ž9òM0öùßÄ0ÌgâÝ»wgΜV H¡_ýuÏž= Ó@Á8vìXtt4äÕ…  21Ô¹sgTàСCüa†Ñ€W¯^ kï廆“òêtZs®¼Í\%IIIPž}||\D8;;ã/4m˜ÞP­ ¸¢š3Ù¿oß¾Í×…0ÕaÈ“Š^¯^=Ÿxäv» Èk);ň¯S§NŸåÔ©S´‰+T¨@ÿ\kkk:ûàÁHII‘(„”)SF!\¬Y³†óŸ&99V³–––°}õÀÍÍÍ•…À³gÏüýý!sÐÀ!v sîß¿¹ƒ¿©©©çλqãÆ“'Od:ÿÌÌ̄رµµ566600 c_¨ŒhÈmÛ¶Œ}www!v Ã0ŒfA¤T®\Y˜€ ‚¶_%ù!ýÞ½{òüùsë“••E[™ØiÃ0ŒÆ¬^½–æçpãüêÕ«~ýúQ—þ‚V§ëééáçîÝ»¿œ7““C½I¾¶†AÛïÔ©=TneK™ÝSüzbÇŽHéÚµ«riåÊ•ÃY;;»‚<ËÓ§Oi]þÎ;—ÊÄAÈ@aõ`‰Hâàà@Ï¥°«îèÑ£Ê.õæ¿4Oh­A´ò„ZJ—.]> K_N hæ±±±‘‘‘P‰!7|||ÜÜÜp iéôîÝ»·nÝò÷÷óæ Ú£üÍ5°Ö}}}---×­[7~üøöíÛ CsÊT«VM[[{Ê”)[¶lÁCI„éd†€¬Û¿›6mÄÂdñâŰÍ5+0--ÍÉÉ),ù •¡˜ËPÆ Åµ>Ã0 Sˆ@ÎW¯^|F‰W§“û}Xˆ_Tmi¼´µ+ŠtùòåiRÛÔÔTežM›6!Ø1c„òe÷Ã?¨t°?gΜíß¿Ÿ…^; zÿú믴©_8KN…]ÿ*ùðá>³fÍRÐhéE}ã0Ì? „ í©S§Ò0ѨQ£õë×0Ž'ZÊëׯQˆ§§'Œz+++ooo´Ž/^ÄÇÇ#Ö½——î~ùòed€ùŸ‘‘‘¯[$$$ ð“'O®\¹rÔ¨QÐÆüñG•–þ¢E‹øÍ0L^bÐÝÝÝÀÀ@p *LÐÐŽ†L;{ölDDD_AÂú8pµêÒ¥ ÿ³†a¾Þ¿?oÞ<š2†ò¬°¤ê÷ßG:z/ªÎ `ݺujs¦§§£g¤n±mÛ¶CÜ´™â× +…˜WéÇ $$¤H.›´CíçŸÆ1mü04è¬ùRÞGnêÕ«§N 0V­ZÅß9óå¼bÅ Á·3}ùsçÎ…~ûù¤,}´å   4s Ü.-- mðñãÇÿý·ƒƒ´ß«W¯fffBž@+ί»¼Û·oO˜0¡jÕªb»~áÂ…ügFXÜëׯ§ÝyDÆ 7mÚSX·ˆ…4;þüÅ‹5.düøñ¨Û_ýÅÿ2†a˜/__ßæÍ›Sß¡¯¯¯<9Õ´iSœ²µµý¢ªM¾ëÅkæUâçç'8\´h‘ôæ l7jÔ(qâ!C[Cå%´˜aÉ’%y–&Mš ØB?.ÜñíÛ·4\ïíí-QÈÆé1¼÷?~œüêð§Î|±$%%Ñöyáû/Q¢ÄÀif*;;ûòåË0ùýýý¡ñFGGã# ½{÷î³gÏ Ý#=,}©»wïž½½½““Ó;wRRR`æ'&&ÂðG;uqqquuŪ!±—ìØ±ã·ß~;Õ•ãСCþ6¡’j¥ÎÍÍíñãÇ=²±±Ñ¬H]’l2]0 Ã0Ÿ›çÏŸç¿I˜]¢hÎ%J”€áß¡C‡qãÆmÚ´ fò“'Odúîû!žƒƒƒ©z*ë Oß«W/ n¥–mÛ¶!ÿðáÃʼn°&È#½Ê 2ÿýwÍš5‘ÁÌÌL³¡=Æ ÃК]]]º£ðÞöïß”6mÚHE“€0Ò©À•+WòÏ| ûFË”)#ˆš&MšEDDÀØÇß·oß ß?šZ4ŒúÀ4¶µµ…ElÑÑÑ ÐoOœ8‘” ÄZzzúç«?*§ìƒu¶¶¶2dHñâÅ…çB³Ý¾}»8v‰à z5 ómââ⢯¯/ö¿AbPÎÎ>ÿS§N‘ûÍ7oÞDFFJÍQI¸páÄé•+W4V]È+ïo¿ýÆÿJ†a˜/‡¹sçR,xèÌ ,€Ù¶m[!œº4¥J•"{ìØ±6l€½ÿôéSX»BùP€»wïÞ¥K—nݺ?~ÅŠ¦¦¦ÈæááA«j¡±‹ÿC7Nþ”öˆO(  O¤ÕéÊVœ€ÆÆÆòc³Bý&[A‡'{9¯Úо}{ ^>–¼ùÙÙÙ¡ŸÅAÅŠa˜Ð»î‹†Æð¥—Ì7NÁçŽ[Ø¿Ï0ÿ"ø¶Ñ^êÕ«'J•*ÁÀf®a­»¹¹AGõòò‚Á~çÎ(®aaa0Õ!%ha Ŷƒ± âää´sçN\åççK—‡„„ÄÆÆB¦Ýºu ?Ÿ={ö S”-[Vx®:uêÌ›7Oeø§÷ïßSžBÜ-Ë0̈£™3gÒ0>%jñâÅfò ‡†@2¢*„ü¹{ˆÙÓ§Oûøø@„jìY__Ÿ„0 Ã|i@a¦É#åE¡Ð?aPÃLÞµk´Væ0ÿË”)“WÔfd€uY£F â¼råJ+++ØûèÎp—S§NmݺÕÐÐpΜ9S¦LA†~ýúõRbd.£GÆ­Ñ *OÀÁ”ƽNœ8!¤ˆÃÓ×­[FA¾^¬\8dÈ…ôQ£FIl¢ùò%½À»wïæ÷å[XXPÌš¬¬,ŠAw‚tÀ04kÖLmTOOOzÿ¾¾¾âta)>™eþ |š˜˜(lŸGë¶µµUpìøðáCGGGhª=‚…ŽËa­_½zð…  ¾B§MNNÆú`æããGæ   4Cˆ,///¸¸8\‹2‘˜””ôäÉ“W¯^…††ÊŒ\/=L9&øº¤q9¦X¤QF™øÛ`˜o rËC;ø¦M›vóæMù³žgΜyðàA||<$›ƒƒƒüòÙÙÙ~~~Ðý !ålQTºV­Zµð—/_æ(Ã0ÌÍóêééÉÌUš¶···©©éܹsaƒ7iÒ¤råÊ´b_ÚÞ/Y²dõêÕ›6mÚ·oß ÀÆ‡š­¼¢U3fÌ@™óçϧŸ‘‘‘äXžÖÒk°çk×®]¸vðàÁ é‡Bz»víòºpĈÈ0yòäüÞ±gÏž4b˜˜H¦7 èèè'p!çÒ¥KUŽ9(@ €'Nœ¨>`À¤/_¾œ¿væƒÖ¥+o3‡ÜP»Nv1ÔÎØØØ°°0øiiiG…yãýÙ³gh&0ÿñ -,wÈ7nDDD¼~ýš.‡ÍŽkaÑß»wu€¼züøñ­[· ú¢(ø<33åàBÿ|I!TÀØØ˜BRk*‡)T‚ÆNW©ÜÚÃ0ÌW „M=XXXdhñþýûçÎóññÁñùóç÷ïß™&ÿrÈUHHÈC\›ß[¿{÷j Ïòæz†a˜/ ¨µdt<64ôg(Ï{öì™6mZ=7n\¡B™ö>ÍX´h‘¹¹9ÔoéAìƒâÚ®]»âØÒÒ’Á–.]Z<ƒ¯Öî~š˜˜¨ß@MŽ§È« suu%Ý^pö%‡ÈÈHê߃ƒƒÉ;ŸàµþÈ‘#ôf’’’(åöíÛôt îîèØ±#²ýôÓO é´¿I“&üµ3Ÿa]ºxßhÓ¦MŒŒ4^ôòåK4@è®°åÑâllla#MÉÅÅ&<´Ü›7o^¿~Zktt´Xm†ÉŸ‚ËQއ‡Ú-Ú‡ÜÃß;wî@vIÌ^AÞ¹s§‚sûAƒYYYѾ™¼zõŠ.W>Â0Ì× …Ý‘˜& ä¤ :::B|åk”àܹs¾¾¾’°ëóå R ªísüÒÂ3 Ã0ÍtCñþLåCï =uêÔ‚ úöí {¿jÕª0„Õîß/^¼xµjÕš7oÞ¿ÿ… ;v, €º!Zvs~Þ¼y”¹Y³f2‡¬½½½g̘§V“q=pà@åüäïÊ•+yH±wìØ!ÿ¬]»—tèÐÇmÛ¶ÅñæÍ›éTVV™ü›6m¢”ììlÚŽçää$QæÞ½{éU(øÑMLL¤9SvÕÅ|>h]:y· jԨ橱Óf777åÄ””ÚbVlkk{õêU;;;˜öiiiqqq°Ù!v._¾L[õsrr`× ®?ÐÄÐ(Ð —AbHMIÚ¹}~Á­©±3=†a¾HU€ôPHÏÎEf!q—.]zðàALL äo¾&ëADDÄ;w"##Oœ8!@rrr§NH1Cø¿É0 óeB®MëÖ­«Á>¯‚ðæÍ__߃þù矽{÷†½ëUz%=¿_µjUqÊüùóÕŽWC«733ƒ9£^9<Å P¾püøñ8µ`Á‚¼JÞ·où¦“ù?|ø€Ì–Ž|ûÃXxþü¹¡N: >ðÇŒƒXIž{÷޼lß¾]á”¶¶¶Êt†) °O¡¦¶nÝZy]:Z>õgÏž…„„À ÖX¼H‡„#§Ð¸Ô]ZCÞÊÊ Šëýû÷! ¾âî´ïþÖ­[hû0ÿ=zåV¢)¡þúúúäŸS¼ê@â*™ÐJ‰À÷ Ã|}Ü»w‚Ý(ÇèP:sæŒÌ€Â n{ö쉋‹ƒŒ…XÛ¿¾jxíÚµ'Ož˜››Ë\n„:·lÙõ‡ørqqáÿ&Ã0Ì ôaR_¿q™™éïïäÈ‘¹sçöíÛêtåÊ•iº20"ììì¤ „AammÝ©S'¨åymk¥prýû÷W>uìØ1œjÕªU^å§§§ÓF9HK÷K”(‘’’bhhHñøÄ¦NJ }…”Ó§OSäé’k×®lmÛ¶UH'oÿ°îùkg a"[Øhƒ|ÆH¯0ŠŠ‚ ûúîÝ»hÔÐHi›<¾|qà i$|`¢üÐÐP•§`é¿yó&++ËÞÞJ¬§§'”g¨Ö°ô_¼xñìÙ3å(™ÙÙÙNNN'N;·G£[µjUpppa½ººuë¢XŽ`æaáÂ…yéçÏŸ§é9‚‘¼ÙC”A6BS’XL¨Hc??¿ÄÄD7779^A"##ùåòõçååÅÿJ†a˜/ŠZ2~üx!åÕ«Wò#¢þ3@QøðáñãÇ,X ««KSöuêÔ‘îÑjii­[·NÚQÕPZ¿~ý”OEDDЪ Ö3gΔï~Þö¸qãrrrȇ5¤ÐË“M!¬@NJJ" 6‘DÉÓ§O§½o ›æÂÂÂÈòÒlñ0Ö/…].]º´x"ÛØØXyJ ´ÇwïÞá;|ðàí…G[~þü9ÔK$BÚ^ï”Ék¾e:::ʯœœœ ·Ë—//ØÈÎÎÎ0rutt–/_nccóYc@kz4Šÿ~úôi•`G0@¼Ä=/h¾^¥](è6:Ó¼. ‚áÿÝwß©ía322h!.ì#¼drˆ§ìD‹üÀöRhk›ô.þ²J”Wô5iÒéfffüµ3@ÛçÅû_jÕª5oÞ¼|…]xûö-”XÚ ]aqãgTTÙûâÁºÇ+Ûã0ê¡0\]ÛkÆ’%Kp£ &ðGÅ0ߔЅ®_åæµk×srr`ÎCŸ‘vÿ ¡w$—¹¡Š®_¿ž¯Ê¼yó&""·‹•vÆ óŸs6lØð T†a•dff’±©°ä2ßÕÕuëÖ­00µ´´ºví:jÔ¨¥K—îٳǠ-èzðàAD.PË“syõêUÄ'pyœ¹ +W®D[·n­|êÑ£G0„æÁ%Ø_&Mš„³³gÏ–(ö°/[¶LúFäÍ6Qvvöü‘—†¯ìÜ~ãÆHéÞ½»tù4‘:|øp…tZð?tèPþÚù@oT°|Ë•+§¯¯ïââRˆÙÐu¡aBD@ž„„„@bÀ–‡á/dptt/¢ˆöùrD/†œÛ“¿Ê‚8·× rÑÙ¨Q#þºæA¢¯‡²djjJÎô ÷`J;;;K¬B …<ôòò‚yngggcc#íPW¨yaaaYYYgÏžÍKâA¼Cò“ _è~¨$ÿ†aþCèééA€¯ZµJ"DýË—/===/^¼ˆž–&¬Å äãwäÿ2}út:5gÎ Î^¸ 2´:= @œîîî£^zÉ:l±a’Wœ;ÂÜÜ\m¨8KKKä©\¹²ô8EX½z5lKQ9ØNõ)R¤ˆ0•O‹ó‹+&½?¢[·nT …tŠ PªT)(üµ3rèÙ³§`ù-Z´OŸ>çÏŸ—þ¼?999ø€]]]]\\Ð^‚‚‚4( çØ±c=zô e•üUêèè@” 1%?ïß¿·°° U7˃?0†ùúzìÊ’æÁ)N®‡‡¤œ½½½D7 ÛŸ‚rã ¿Êä§ n y¨rk„< D€©S§*»"a†a¾phƒ¹²Ë5™ #˜1c†8"ü?C¿~ýPí¿þúKH9s挮®®„ñ‡>kòäÉbÝ»víB9ƒVyÉóçÏ©Ï!*••EÛÐòÚð1w4¾H.xQV¾fÍš*ܼ}û–œÛ‹câŸ|qx¾¼† €Â=|øøñã4h `ãÃLƧ¾páÂsçÎÉqañØÙÙEÁ¹ýÊ•+ îý BRmÀ;H›ëׯC¤!*W®¼téRÞ¦Ê0ß4û°hÑ"•ga¤Ãð‡HAßíããqªV²½xñ‚ž   “'Oæw¾><<üìÙ³±±±VVV þN!²Hñ(W®- `†aþ£ÐŒÒÍ›75»|Íš5EŠñõõ-Ä*¥§§K8Êþ˜»ÂBà),ÅWö~=ŒŒŒTÎ3nݺ…Œ1"¯ËÉÕ<þJÜÖMÑ¢E‘ÍÏÏOù¬àýqTTYßyEéãÆ#G^b€} Y-(lÿý÷ªU«H- Á®ï†aþëôêÕ "}ïÞ½š]µúsß¾} Åœ‡:xðà%J¨uõFq£vîÜ™W†ŒŒŒ%K–èêê*/9€ºŽBF•WZ€þNº2¨m^濽½=yÄE}È ^ûöí%Š¢ñ@Xe÷úõk¼¤øøøH\Hqr¿ÿþ{…U Ôkç7,Ãv½ø´`>C …½Ü´iSaǺ°‰8… ÈVè¡âTò™œÛ£òhn‹/ÖÑÑ™;w®“““Ä„G ƒÅ‹G”W1 ó@[ü”‡Ù‰“'OÒ áË—/ÔöÎP$æÙ/_¾ ‰”_§v‘‘‘wïÞMKK¼GGG“ã_0lذ/-Æ1Ã0 £dJOIK½Zu]`âäd¦FP¤Õޝ_¿™û÷ï¯ò,´úŽ;ªuŒ?cÆ R·nݼ2 ë¤ ïè%Ê¡Ðu¥J•RÞÎ0jÔ(œš2e Ž7nŒã}ûöI׊–"L:UH¡}kÖ¬‘¸JðpéÒ%…SíÚµCº©©)íLAìz " Sù+VT˜Ê/W®\¯^½p±Ð5Ƙ˜---jž4¢…Û¡É+‡ÌþþþýõÌyõ0í%F'rrrðh¸©PÈ.¢ÙÄDpnO_/Q¿~ýBqncÜÈÈH[[ÛÐÐPíæÖäääíÛ·ãÖÂ=EDå5öLÂ0Ì?IxxøÒ¥K©#¦ùô~ýúQØÖ­[çw»º„¸ƒ.$!BaJß½{—f>|ˆ^^Ðaò‚Ìôþ=Š511qttÌoÅÒÓÓgΜI³Õ«WW«Š0 Ã0ÿE¢¢¢¨›+àd.­ç¿pá‚Dž7oÞ,X°ýi¥J•öíÛWÀ;öìÙw…ôªU«"ÑÓÓ³€îøÐF®\¹‚[Oš4ÉÍÍMmiÁÁÁ3fÌ !;ZE3{ölh×ïÞ½=z4%Ο?ŸWà3ÌËõë×uuu…Í;UªTOúýû÷iAQãÆ eá í„‚‘—S___HÚ7„̇RÖçc®{=r†¦½Úuû 899Ñh9rdá®O`†a¾Ðû´W¹AõÅ‹è`ƒC744„Š;~üøéÓ§£[ܲe º¤K—.¡“‚…ŽŽ¦Q£FM›6ÍKŽ}ûöÏ?ÿ\¤H‘™3gæwÕ½JôõõQm###™ù---K•*…KjÕªE±_i½œØCJh¿€ZK½3Má‘“=×ø #ǃÆ1 éÜÝÝiþöíÛiA8uóæM2+¤Gš5k†lxÏ é‡Fz‡øƒgþ]»^'Ožœ:ujÖ¬YmÚ´¡Q)1eÊ”A3wppȯ«LZZš©©i·nÝ 1Ôªµdþ‹}â¡MíÞ½[p%ý1wbnùòåt œW´2ÌÔkkëöíÛ+„ž|ûö­8ò•iceeUÀ›Rl\‰Í};wî¤Èõ ÐIΞ=«vtñÝ»w¤EJAAAÎâµ|j Byšžaæ,ÉügÏž‰Ómll:wî~óæÍÒמ={–êI›  œ(ŒZ gW¹Æ^Ú³¬£££NüŞɯ]/‰¶‰©oß¾ÆÆÆj›ƒfÐb´8·Ògee:uª[·nk×®çä¹Ä8p °ä¾~ýúxº|΃ºNÛWaP¨U¹†)t¢¢¢Ðá–(Q‚ZqÆ ÷ïߟßÝ1ÐIjÕªE% ‡ž/×äÇFbàÝ»w!ÈBwssÛ¸q#m ”æéÓ§¼ÐÖ Ò@}’?„”3f I³²eËîÞ½»à›˜†a˜ÿ Ož<¡Ú…åú©S§N5kÖ|ûömhhhíڵ˔)#ßw+zá{÷î8qbÒ¤I;v;v,¬Ý¼Ðk« ×.`kkK‹ÐjÔ¨áå奜ֽ¯X±BmÅÈ6Æ+$X¶l-{Ã_tßB([µ¹ð ;wîìä䄃 *r||ZÜ‹/ çmÛ¶¡…>¦nll¬œ CéZµjå«Úd¤Ã¢Ç_µQ'=z4gΜ2eÊPKo``TÀW½zРAT¦ô:"†a NDD:qÁßfûöímmm 2ƒ€E ±&ˆô›C‡Eïœ×{pèÐ!Z' Qœ‚t‚ØLLLtöìÙ*—ÿA¸IO„††îÝ»×ÁÁÇ !!!]¶¶¶M›6¥êÕ©SçÌ™3…2²Á0 ÃüAç(Ó«¼|îÝ»×®];9QY ‚±±1j>|øpqâ“'O¨+Z´(2H—0lØ0ä„b¯ö^°kH…P;RáããCwuvvÆqéÒ¥ÕšE°~ÇŽ8ž|øƒžèÆÐÆ¡ºÃ<„~>sæLƒ\Æ?2—1cÆPŠa.7n<|øðÅ‹oݺ£øåË—…µ‘Ÿ–¸ãFBн½=9¦®\¹2ê©¶===d611‘s;Ša·gÏélx!È6dÈŸÖùO˜0Aú²ÖaÐ~3gÎàgãÆŸ>}JÛ~ß_ø/Pì¼O‰iö*Dµ£t•;F4XòP!¦eË–+V¬ðòò’ÞÁ û}øðáøøó Ùºu+¾F ñ&SèÛäSºP¼Ü OQ²dÉiÓ¦ID¼’ žfÒ¤Iâ÷Ó´iÓÍ›7ÓΦï¿ÿž¿†)D`´¢}U¨PADrÖ±+õéĉAAAIIIwïÞ•é$óýû÷èy,ìåÇÁ¸qã OÖ¯_ŸÐ¦$.·µµµ²²"yxòäÉcÇŽi¼'îñãÇ®4’P¬X±Ù³gÊÔ?Ã0 óŸvMC+[vmll +µoß¾ÚÚÚ:::cÇŽ…†¼víÚ½{÷Âötppðñññóó Ȇrr2ûûûã”››²YXXÀ^³f zŸÑ£GwëÖ vïÞfïªU«Ž=zûöí„„„üVú9j¾|ùòÿ»¡¾uëÖ4$®<ò>~çÎÂêwô¶¥K—ÆÁþýû%®:|ø°««kVVVXXعsç`ækð* Á >>üy0 Ã0´P|êÔ©_H}233ƒƒƒÏ;·téÒ>}ú@‹F wïÞ­r™\ëÖ­Qù½{÷¶hÑ‚¾Jo¨?~ü¸¶¶¶8jÅ¥’” E±‘0Š{÷î ýõ—0h@Ë $@OQ½Ä³–(‰ãÇ'}°„Áׯ_S ›¼‚‹'N$/¾ .tðäl»`±ˆ gPP°…-êÆ ƒŽ:oÞ<Ú"РA$º¸¸hlG£±SQ‰‰‰ùº0""ÂÐÐPØ‹•/ —´Jkkë ÛçÉ— ©©i^#îîîy –2 #q(vôzèLå*”ÁÓµJÇwC®HFÑ??¿{÷î]½zw·±± ’ï²>++kÿþýÕªU#…çÚµküy0 Ã0 *+…qqvvþb+ ]zµÊ•r´³•Ö½C™—x ØòãÆƒ¹¡‹L˜À2+£££#x·S&::š&4zôh™{ëxùòåÍ›7aMSK[[[333tÐG·W^}çééIÃ}Ê›óR‚Lw'OžBÒרQõ׸ò Ã0ÌW̉'H.,GvšÓ59èáŸðËÅËËËå.\°ÎåôéÓäNзÃÃÃó*ÿúõëmÛ¶¥à2*͇&MšÈ¬*Liä0`€Ê³„î÷ßÇñÆ…c ðÔ´@¤þ£hm@```¿~ý¢çìÙ³GNá¤3FœHNù~ûí7þþ9ÐW­ðásb?Á &Ö_½zC)ùZ¥¯ t°´´T«üãvÍ›7WXr_GôÐÿÑÖêÕ«'” 9oÞ<ù“kgÏžÅUíÚµã‡a4ÀÑÑQ/íÛ·÷ððРØÎ÷îݳ±±quu}úôiLLÌ•+Wdz¿—PB<ÔÑN¥Ñ£Gú{ðöö%¡!ôÝëÖ­ãt Ã0ŒmÚ´!óÐ8—C‡™æ«yåÊ•fff¦Ÿ011¡<›7o6üÄœ9sÈïý”)SF~¢oß¾½réÚµkÛOüüóÏ r©Q£F…\Èk}¡0|øð¼vâ¿ÿõÛ P ùï¿ÿ^a?/nݺ…üeÊ”Q^cüádž  ^ø7nŒã}ûöIˆÌ4µ§p–â×ìܹ/_a_DDMH;ü!• jÕªâÄÇ“]ˆÃÈ‚- NÐèfΜIôh× ëBñu¹¸¸Àû—“¿J̘1È õ5¯ PÔÅKîøá4󂬭}ñâÅÖ­[iGñã?êëë;99åwØ“ÞG`˜ü-¸Ê©\¹ò±cÇ4 Åž™™™ã×ßßhÅgΜ‘ü—Ó'ON:*N¤àƒ…øÐÅ=š¤+„ÛäÉ“—.]JêÖ­  ²”ãi2 Ã0Ðcÿï J5À,mð‰6mÚÐ@AçÎÿýwêòòê÷ƒƒƒ»víjjj*ñ 9Ðíd†Ë¶ ¼*ž ¯z%J”HNNÆY²Õ®¦ ƒ*íšñïÓ§Yâ°âÅÓ5Bâ‰'$ dzÓÓÅÇÇ‹ÇhPEùFZ¢§§§ò,>û:uê÷*ý`h°JÕªUä_Bù-¹v»W¯^~LLŒfO'±}^­ßμX½zµœè– Ãdggïܹ“Öù  N›6-¿î5ÜÜÜ®\¹B‹í£¢¢lll bü¢n7oÞ¼|ù2º`(NBÜùAƒ¡ÂC‡-¬÷pÿþý?þøƒ¢A`BÖ‰‡#"##÷îÝÛ«W/Ê@”+Wn̘1gÏžÕ`ÇÃ0 óÕ°uëVôžÂT;LHšj‡Mž{öìI)Ðê)ÏèÑ£ >±páBš¸_¹r¥ñ'8@SüfffÖŸpvv¦…ôÐÉiuý½{÷„%÷±±±´?--M~åa,ä ¦+*н{÷°°0éBÈHÏW¿Œw‚ü[¶l'œ¡©Zß>kÖ,µñ>æŽÿÉ/AaôÀÊÊ E‘†óþýûŸþÇgΜòc½áÇK” )ð߆ ”A:"ûví’þ˜Ñl! Èfÿé§Ÿ$‚7©\¥ÿý÷ß+¯Ò§ uêÔ̸V<Ÿ^%÷Pø!޶Ï7mÚÕxùòeßØÌ™3ç™ Ã¨%00ê)L­§§§fåÄÇÇÓÚû¸¸8H(/^TëCH{âĉŒŒ ”‰^øñãÇ´ÃÝßߟzð‚¯Š‡ÒríÚ5êš HE‰÷’’bii }Œö0ö¡­íÛ·/**Š?*†a†8räút1r:£ÄÄDاÞÞÞГџž;w65zckÖ¬ù¿yófúyøða²ý‘™ \ëêê {–8ôj9>o)PX%‹žwðàÁ¸Z… båÊ•e¾a]HÚФI*Æ2¬rZpéÒ%é¢V¬Xl:::BʳgÏ–/_.¸½%nݺEüñ‡¯‹"Žáv· mÂ-[¶'âå qòäÉü©3j!GÒ#HÀÉÉIˆ. {Yº «]¥EšœàA…މ‰122ªT©’xɽf[n?æŽâû§È’DÍš5qS˜…õÆh!±tl†a>æbC= ÙçÒ¥KïÞ½[ƒ8¸äÝ»wwîܹ|ù2þ¦¥¥ùúúš™™‘¯¼‚uRècnüÊS§N‰ÃÐ@*Rù‚Ü:Ïúõëiä4¾üèìì<{ölaÝѦM›µk×ò >Ã0 süøqŠŽ*¤¤¤¤Àfß»w/TbX—Ý»wÇY¤]»v2dÈ”)S/^ ƒwëÖ­°ÖOž< SÝÞÞÞEdÈ“ù:DÆþªU«.\8}út(íýû÷×ÖÖÆ]ºt颥¥…{){š…ýNý—x¹¬ƒƒCÇŽez¸B—'îÑƒË¹Šœß–*Uжäûûû ýi•*U²³³/^¼Hþù¥÷ìøð<ùã©íìì6mÚ„—IÓëTEúÃñÌ™3‘G¸YYY´œþÆw¡¢E‹ŠG?Ο?ÄæÍ›ó§Î¨m_˨Q£èçÓ§O¬rR ÊÀÀ@Øû)':3ZŸŸÌö¶mÛŠWéWέZµ{¹_·nÌvª@tt´‰‰‰xƒjÉ’%)ú|ãÚ+Cƒi?ÿüóĉÑ®akh¼M€a¾b¼½½›5kFí±W¯^-š•q„îåååèè%¤àdÐÉzxxܾ};>>Z1n$tÁAAAÔ_kDÞ³gO‡Ä }=!hÆýû÷aËÓzKZf Ã0ß8fffè`f )ááá»wï†=Žnîùóç_‚Ÿ˜ób{½-yð“¿+«àcVyi}^À  à€îîîVVVäsžÂЬ\¹`õàxöìÙÒå©® ^û™3gÞ¿]‚|—*UJp›/ž, iÁE‹IÜ…ö惫W¯ ‰Ïž=£õϯ_¿æ¯‘fóæÍbøøxðÍKLQáÆNÍjÖ¬YòÛã‹/LMMQ2µ)1Ð~Ñ(¤—¦¨$55õøñã:::ˆYÑ¢Euuu---eªýuÐÛ!ýF#]Î%BP*15kÖ2dȾ}û ¢·3Ì×:¸%K–Ð]ùòå5ö‡«._¾ìêêJŽî>|ˆž.!!A³ÒÄyò„?6†a˜oœS§NÑö®/¹’0äɧA~üTGDDDtëÖM¥#ÜÀÀ@$§ÅÀòC¿Qà¹þýû“±€ ©&ÐÐ5S¯ªv „ ´ƒ¸yóæ76lØöíÛ…^888¸~ýú˜Î;zõê…ƒõë×+ ¿4jÔHúF4 !ö{Fûú‘“‡¿vFšåË—ãS™:uª²uëV×Êë’¤¤¤ñãÇ Këå¯)%`qÛÚÚÂŽ.^¼xûöí5˜ƒ1N%ˆMìvíÚ™˜˜(ĨRIZZš‹‹‹‘‘Ñ Aƒz÷î=oÞ0 ÚÉ`jjŠW7|øpñôQ¯^=”ÉŽ+™oô¼-[¶¤¶0xð`W³|xúôéÐÄÎîhܦM›ž={Vð âŸ9s¦Ø¢···ç/a†ùø)ÄyÇŽ¿ðz’Ò.±‡îÂ… ;wFï¯ò,͘Ã.ž_Ðöy±‡ŠZµjÁˆö÷÷—¾ÆŒwä8p Ìy´qwww™á/ÅXXX(orILLttt\½z5ôma[øå—_6nÜ(sÄ€aþëääälß¾Öž•+WV¹…ÐÆWWW4Ûøøø«W¯¢Ý >ê ‹/ 6\ºt ¥Áx·´´TÙ½Ò°|=û=22}+.ܳgÏìÙ³ûôéS¿~}qc'ªV­:nÜ833³ÂÚ›£`Ñ·oß^!ä(Ã0 ósöìY…€é2ú;Úï÷îÝ{þü¹ê±È•–Êé¼·oßBEGç«°vN …™îÛ·/… U9öîââËZ<³Û_OOò¯[·Š ¹ £síڵñÚõºæææõ[94¶©©)êÈEòN½¡'ˆWëá„D‰{;wŽj ÅãâÅ‹¤i|—‹ô¬+Ãmmm刊£G®^½ºÚq°””aÇ=´Ü›7o~¦JBÈÀ|O‘Õ ¯¯ö›W%³²²  Ðvвºuë†z¢UÊq´|üøñ¼Š3gî>}út ! c2DPÅK–,‰ü q±æ+ÍúGн{w}¶§¦¦BÇ€jˆþËÍÍ ? ËKzÉ[·nedd =ZXX(ç §°˜ 6lÖ¬™àÒS%¥J•êܹ3´/ß ¶è;vì(ì0b‹ža†Q‰µµ5…‘’È“––výúõÝ»wCîÙ³§–––ŽŽÎ Aƒ&Mš4sæLÃO,\¸püøñ½zõêÒ¥‹N.cÇŽ%_RìãÈ V6Ð{¢>VVVÒ—/^¼—£þ?Mý‹ÎBð ¬X±Šžˆìâ;v ƒ££#9òMOO ¡Sj5 gƒ÷#N„ OSÿ`Ĉˆ…'€=NûÄϵnÝ:¤ôîÝ[â^PxÈ–ˆ+V / V°Ì€aò¢nݺøNœàÑÀu™ò„¢@ÒÄ}!zuHIIAM ^Ÿ{øÔñ‰*ïgkkkdd4dÈ´A47ü”3ÍauôèÑqãÆáª¹sçJÄò£ð” à yøvÚÂR€u_ð({ óeB,úÇ‘#Gæ+¦m^À¾†]](Õ{ö왥¥% ¯ùúú^¸pAåö½ŸB„(SµjÕ-ZôïßöìÙ{öìqpp@ ÊC÷…bÑ‹÷Ñ7lØ-z†a&/УQœ…t˜®—.]B‡ ±_¿~kÖ¬9þ|pp°|V999è’ìíí·nÝ »Fe×®]çÍ›‡;ÊÙ÷ªMÏ)ôhPé»wï.dz®ŽŽ.ßµkŽÉ-m5òxxx 4Hè@ S†Ñ£Gãç¤I“p¼lÙ29ñ_¼xA†v`` ˜‘‘1pà@²}`nNw½½½Ém>†iÓ¦ ÷"`XÑé°bâyÌÒ¥K“ꕃ¸ººò7ϨJ)}$ ÞÞh¹©©éÿ³÷æq9fÿÿø÷ãm¬Ã`lcß™±¯#TJÚÉZÙ3¶È¡Œ5 ÊdÉXŠ„B)ÙJQ *’TŠˆˆ‰,¿çÃë1çqýîåºïîîržô¸ïsŸë\çº:¯s^Ïs^‹’í@º)'Š¿páB1{EÙç«T©"‘}^z%Çœ`cc¾?bÄpe"¾~ýúøñã˜î ѸüàÁƒ Cñã:ÈSþðýÓ§O˜1e1ñ\½zµÚCôspüçžkW¯^}úôéÂð¿Dº ÖÄüü|È#&(·÷ÌÌL;;;è?Püýý/]ºôðáC¢zª€´´4!£Çt¿cǎ壋ƒƒƒƒCüüü¤“ž>ŠñÚµkoܸÁXgñ ÔuÆ ƒ êÓ§ôçC‡½|ùR™kéhÌ××—•`Ãj«Ì9nA^~ׯ_Ç×7§–i·ÿâÅ‹]»võîÝ›Ó9sæPyNNÅî†À ò=<<Äo ½¢x±h” ]aåhú…æ{öììú˜> 3þe"wd¶ÐuêÔʣǜ98$””D‡àÑã!bÐ-.\(,ÌËËÈݳg¼PóÞÞÞ¤Û£A{{û¢ºç`´GFFN›6­V­Z”÷ á¶È5˜;8¾™™™¦¦&Ø+P+11qÓ¦M¦_°yóæ"…¯ E—ðŒLB³³³¡ù+é:88¸k×®, ÍKeÆÆÆ·‡ Ïýúõóòò*!O=%!½}û6Ù½{÷FGG+©”&0ƒa*FÆ "sÁ5j| )Š88888¾N?~\:ôS)!ÇÆÆþõ×_¿d:¶H}¨9Ê Èñm̘1>|600`¾áµkמ;wnLLL)w)//Ô æ%,²»wïÆÜ¥Æc µàþýûS¦L‘ë3 íü5çÇ÷ƒ'N`¥øõ×_ÿÃ>@¯†¢nccC‡øø,mçFÇÍÛ¶m+RË "^&ªU«†Û¹¸¸€égff²«RSSÿï „µ) ÐÊ•+ñ™ÜÕñWüî—/_&÷¬¬¬Ï_‚Úyoß¾=nÕÂÓÓÊÆÑ£Gi8p ž½I“&Ô=Ê .ŒË‡šT.¬ aƨ֥K—Ï_bÐ)?›–Ž!Ç·Š'LrÇ!‚† ý¼nݺ”WÂÁÁ!00ŒÕŸ>}zöìYy–3ûöí#ï’òåË/Y²DÞ$t &ž 33³cÇŽ IqvvöäÉ“¡“'$$5dÇ­[·œœœúõëÉ… s÷’¶þhB ‰4<<]•ÞoDÉ¡C‡döc`fùãÆ{ûö-‡eF¯:»%''/\¸‚o u¬ZµJ-©ß"77âUó &««W¯~m©'ñ0³±ìx½{÷>uê”DÁƒã§eË–ñÆÁÁÁÁ!X;”IÖV:5ˆŒŒ\¼x1to 0¶ Ÿr»+ßÚ™3gêׯÏòÂ5jêÔ©h™òÊI<‚òÚoß¾_{öì)d,JË[,ÞiÓ¦¡zâììLÝÐ××ÏÉÉ # §^½zä¥kjj:þ|:Ô@·Á¡(u¸0Ø]^^9ˆvØÚÚ‘''}ʱuéÒ%>Ú9D@‘ tÒ? >¼råʜݻwŠŠ’øãôütÖ¬Y2MÊ322È.WÚìDøÈ‘#C† aGT“¾}ûBAáÕò\Dç ¹ˆˆˆPË ”ðÚµk³ƒ7oÞôöö~ÿþý… |}}…†²Ù€€LkòšB0ãÑäЪU+>9ÊÀ£I¢%ÖÈ;$ÅÈȈV=&ïÛ¶mSÆE5¼yóÆÓÓ3!!!??ÿíÛ·ááá_UÈÊÔÔT!£×ÐÐfôJ­‹ |€qppppÈ#¿_§>™––¶k×.vºG™µÿüóOe®ÅÚ žTe°•–-[â˜2«ððáCww÷­[·ÚÙÙ 8è?qáÏÿÆÄ›:u*«?wî\‹ÞÃÃÒÍ‹»ö£çä_|øðaKKKj߯Æ:¿««+i5,ã­‹•meeEqqqtÊ)t$óƒ+VˆÜ4ŠmVà%L›6MaÉ9Ê$=zDféÒ¥ÒGê´AÔ¯_?ñå7n@j@ÒeZŠîÞ½û§Ÿ~" –åË—ƒCè(Ÿí>¡\^`jÕè¼®®.ÑyµäœÊÉÉÁ¤¤¥¥Å’M¼zõ*)) Š)dß¾}Q;0í 'À«W¯Êó,>yò$MuëÖåC‘£l€œ¿þøã™¿>}ú,•bز}õÁƒ«+7=Cbb¢¯¯ïµk× ƒ~~~PxJ"j½ÊŒ~Ò¤IBFúôi‘úñññô¢¸Ý‡L³yóæÍYIpp0h£³³³››ȯ···–”GGGc}„â’’’­ÞõWS¦LA?Á¸ÖLHH ÀtÄ‘óòòèdMÞuzz:sæ…^ñùÿŸïó—hDüñ*ðLA™žP¢Ж>}ú…-7nÝËÜÜ<++ ïÙÐÐŽ6jÕª% M¾°póæÍäv'~wê0h”¸žÀÁAÈÏÏgRÓ¶m[æÔIÀh‡ò «LS?†A”îÝ»'ñӃȡFˆŸþyÆŒÒfªáîÝ»K–,õFŸ•Ìͧ˜Nœ81räHÊÞÅ e11fdd@<ÓÒÒ@çÁS0ù/Œ‰‰Á¯zL³¡¡¡2µñÈÈHŠt-¿”ƒãÛE@@†ô?þ(~YbùòåÂxåË—×ÑÑÁJ5£˜}¸}ûv`` ĺ ˜cÇŽ}%õx´‰'2F%áÌ™3ÊLDäÊ'ôäààààà` ¨ÎM›6ò\¬€X ¡µîÛ·ÔÞÅÅôÓÑÑÑÞÞ~æÌ™ ¼cÆŒ±°°!%Ç[™ŒŒPgìØ±¨?kÖ,\‹UUå~Ξ=ý´µµ¯æééIJ2(-Ñðׯ_“q»Ì(Ù÷ïßoÑ¢ÙØ³DEEAr¯\¹"¤ ùùùxuááá˜Xdš:à*š"(pÁ焃C€8PØØ¥K—*S²0gΜæÍ› 7ý:t耵ìòåË*ðñ¸¸¸‹/^½z,8,,ìüùó_ƒÝý„ £ïÛ·ïÙ³g•¿¼W¯^¸jÏž=|€qppppHãÂ… ¤¬ª½å/^dggcƒ†íÚ5¬ÚÅÙ~'¢*3¨áåË—”_žŽÒؽ¢££éÔ@ZÕOLL¤s¤T£to¬þ,=íŠ2„ÙRÞ:¡ë½L@™g 7°(Ä Æ“G^HÓ¦Méxbýúõ2™úKÊkÓ¦Â{hœRéåååñAΡ<0t§L™BÛ\*T‡¥¤¹¹¹TEm £ÔÈȈâF2€“hŸÑSvûqãÆéëë»»»«k´gdd¸¸¸°Tt´5'ŒÉ¼ÿ> –šš Þ*ñŒàò`ýèá©S§@.dòrÕùý÷ß}||¾ž8'j§§'ek…Œ(UllìªU«°È²…˜bÎLœ8ÑËË«¨®ñ‘‘‘ÇŽƒþç'õÉÉÉ`ô,°@‘=TrBœ:u*®5k]Òˆˆˆˆ[ûubåÊ•èçèÑ£eþ ¥šòäRÔwááÞ½{e®ß¾}›Î7kÖŒŒüGŒò;wî°˜½ššš™™™ÄЉÔЄH‚<HùàOŸ>šÿöíÛ‰(¡„úÉöÝå—×Èݪ+´³³C‰………H ÃPB=P>È9ŠŠëׯcð³¼  Ì/^¼˜7ožŽŽŽ««k‘p ‘jii cå©…×ÓIº¶¶¶““S‘XƒòóóÁ¯MMM™îùDOOôDâ¤5Ïœ9CYíðhRöòåËGa†ìŸ>}Zf¾é{÷îÑüÓ±cÇììlJ)ô‡âàøÖeˆ2\ªp9Ä¢‡•Ž9ªZ´haccQU2ÔÞžfâþýûè0›Uúôé£üºœ0nܸ‘#G’[ÓŽ;(Ô ]ÒˆŠŠ¢¨ì_y?7nÜ(3ýzaa!{²oÒ¤Ixx¸Dr–Ÿ8q¢°ðÚµktRžž‘‘AfëÖ­ôë›7o 3PäyÊL÷Y·îÙ³gâ½¥“¾µk×° ôìÜÁÒÒ²J•*ˆOâ(SàD¨¹nÝ:VB!ªW¯.“/0#¿¼°E å“LJÈ-s˜ø¡C‡ŒgÍš¥|‚*È‹Ð{´8¼šüæÍ›uttf̘¡‚ý€<öÅ›ò\~ûí7ggçS§N 3`rsscccñDàï/^þJá¹pùöÊôñðàA³fÍ(T µþüy|mܸ1ue 7nÜ >‹%UåF SG6måì`(W®\·nݰÄ•f´å2>~üxÆè¡iP e––6uêT333á®>)!Xý¿’@_h™¨]»öWÞOÚ¦ÖÓÓ“XøúöíËÂÐÉLŒEé¡ÁX ¸?–EvîÜùéÓ§>| ã [ÙM›61ýòëJPÞ:ñ®²¤xh°wïÞäPoee5qâDaн.]ºH„Ζ‰5kÖ rÿþýY è<Å ¹ððáÃÄÔåkÌñCÔÉɉâÅÑ0¦À˜7,,,,--¥ƒã)„j¼þÂ… ¸©©©¯¯¯¼ÀòE¨7žŽ(6¡aƶ¶¶d]˜˜–ÎGŸ’’²wïÞG…††?~\X² ¾Oª{jjªÌ ¨Of?MôãâÅ‹dÁ‡Ge“iРZ2WfddxzzŽ7â#äø˜Ú´iƒ)bË–-˜Ô5E‡Ñ£“BFOæ=JΘ…LLL¤Ú¾zõаÃÁÁÁÁñ}Š+EbÿÊû¹oß>2`c%>>>D“+W®ìââ"óª·oßRüXvjæïïOgåÝ»w'+¾›7o’+º´&0bÄZC333ÁA(®þÑ£GÅ»J={ö$;ÛjÕª±€èϨQ£èÐ_Éh7nÜ üœœVH)„p#‘ QŸløãââø8ç(’““ÁâI~üñGpaðb333ŒCáàT/¯GËîîîzzzöööêJ÷øñcÌlKæ<`@@@aa!ÕÉÏχŽšø+LŒVÂŽ¿øi÷îÝÂX—P¹ÃÂÂ0?à'|é_óòåKÊ;P·nÝÄÄDVNû«uêÔუŒ!//Ì~¬ÞM椤¤;v`™¦¥Vˆ *ôêÕkæÌ™Ð0M‰Û¶©蕵µ5côZZZÊ3ú¬¬,Lt¦¦¦ÑÑÑòêYô>´88888$pýúuŠ õ•÷“"ÈA%&ýÙÆÆ†ÍnݺQlj BLjXOQôŸ4óíÛ·“Å~ÿþýsss©2”sy™ã¦M›F·Àg¨ë´"~ðñãGŠÅGËzëÖ­…fº¸)µïܹSÉ ¥>¯_¿žRŸÛµk'~­¶¶6¹ðqÎQ|@š:tèÀÜINœ8Aå§OŸ†@8p@½¼þÚµksMMMðzµxÈ¢rŸg1-Ë•+v/pïùóçgΜAaPPгÓˆ——WJJJNNÎùóç%NÓ233ÑT~~þ¥K—¼½½¥÷: þ={ö$û¨[·n BS4SñaÆQöpùòeº¶mÛB¨=<<”Lš©<=zàää¯Y³¦ÍÇÝ[´hŸP“¤¯$²Ø§¦¦ ýè1·(ïGŸ¾JDà”F«V­Ð8Ï`ËÁÁÁÁ! :­®V­šj—¿|ù’r4oܸÄjíÁƒ±–am‚Zr ]W-AªO:E4ùÊ•+-[¶$»»yóæISƒôîÝ› \—,Y‚šC‡ýôéM–]KHìíí¥ð?IbE>ø~~~øjff†Ï3fÌï'*3]bРAº=Y4iÒ„ Š„½¢€{ÀرcÙOOŸ>¥rq+èuëÖ‘ çjAAA€††™P˜‹Q£FaB(&¯§zmmmhÈäW50÷yò¾aîóè°ÌÜ—èH~ –ø „>œýáO¨O'hànnnÒïáÍ›7+ã§Ÿ~’vº%[>Æ8Ê$È¡¬B… AAA`Ö¶¶¶Ã¾bASoh;pö¸¸¸]»vM™2¥sçÎlOˆÊ•+wïÞÝÚÚzÕªUˆŠŠ*j¤}!îÞ½keeE;ð¦/q/9!  9;;ëëë+¹ @á€öîݡâãã)x5èíPà±þBå^´hш#zôèQ«V­ÿ§4jÖ¬Ù¸qã_ýµgÏžzzzXб¤N›6 ´+þ–-[öìك巀òŒ^Ý¿ÿÅ‹lSòñA3§5º~ýúÂH\ Ïž=©§ütnTvuu¥ˆ÷Ô ‰€3”oåÊ•M:tå öÐóŸ?Naô._¾,þ¢h/\eq_‰€½&LÀOsæÌQøÉÊÊjРKÛ'ï…xo"§?” µ86rp`<Ó˜dgR ùdÊ…UÔU¡ß‡<^Á„€˜˜˜@ôÔ’ÔþÎ;` -Z´`³¤3h¾¼KrssOŸ> éõ¦‡bˆŽŽ IMMõ÷÷©ö5=<<2220e¡óÒþ¨L81Óʼ;?¯ç(Û€tƒºR2G&; ´°Ú¡C‡B+€lBŽhQL¼ÿKááÇ—-[Å`\šìÿöÛo˜‚fΜ¹qãÆ£GbÅOOOÙvHLL´´´d öïßÿüùóJvìõë×...:::xjå=È%Š›áqppppHãöíÛX#*UªÄJ šB§ÅBƒÕÖÆÆ«-c¦ÆK£jÕª:t4hVLTmy…—¶…S XjëÔ©ÃH.`ll,sé‡ÊݧOŸK—.ÑWh×t¬O¡óðJ¾ôU½zõ¯û÷ï—('=ÜÎΟAŸI!_|A X„1æå‡×@þ}t`·gÏñJBB‘¦E‹áÝRkÂãK2?@'Å›¢˜`à|¨s¨…)“Q+8,6ç «nnnÌøI5^ÿùËawñ;‰>¸»» Ýç!•ä>¯ÐÍœjü±cÇ„‡wè'ÔûíÛ·P:lá%oÞ¼¹qã˜>Ø=nÁ6>|ø@‘:0œ/qò.tF™D"dGVVh~rròíÛ·ƒƒƒ…›ŠÐÉ)>fÂ'NHÀÇd5iÒ$2›IõF:|Œq”aüý÷ß4Q(dë8ˆ³½½=t'''|-R|΢‚òWúûûoÞ¼ÜyРA:tPÈ÷‰Ñ_¸pAÉ»¼ÿ\¾ÿþ˜—”qÇ“ÆÒ¥Kezrppppp@—^§À…;uêdffÞíæætçÎRNƒ%ïÅ‹÷ï߇¦M”YhWÀðæÍccc‰´òÌ$ÝíL™2Eú.D™%ÎëAá)fþç/®sĬ&ìîׯj.[¶Œ•@ÏÇM)Vƒ<;|¬øPc¨?xÿÐd*T¨@ZÐäÉ“ñaÀ€¬2ô"Ð+BéR`` Ùðót·Å†Ô]a!èªÐ%GKKKÜ’Ví¼|z8¥« ´k×â£dÊ Â­/¸|ù2æ:ayZZ&@ÈþÛ·o÷íÛ'L“ Rþüyh阂@ÌÁ;$¶ñ•6Ö Ô»wï¹ûéÓ§)~ceyyy´Ó®|ˆxZ⡨¸¸¸Œ5 Ó‹ „.55µtúŒu9###&&󀇇‡³³3Vð±cÇÒ„cjjªd;X‚1U‚ÑãAŠªM%''SdÀÑÑ÷?~<N ,çÕ«W_¹råÀ ÕîݦÈŒ€ÅÑËËë÷ß+—Шé¹è üÆÐü{öì)­ dee±`zÂrJ0íææ†Ï‹-Âg]]]ñBó'J.L_EÈÏÏÇ»Õ××§  ù(‘¨“””Ô­[7"\!C†dgg£ÿdu <'o}éÍ ‰[S^?…‘88bÏž=ÄÜ%ÊÁÐ/^LÛPä}?kÖ,y´]]¼>==:6Û¾£tÐù•±ÐÛÁè¯^½‰yFøSaa!ØúÍ›7333¯_¿.¡SÂ; žñâE!å',\¸HýŽ;TØ0áà({077—Øý.*RRRÀëÉIpðàÁ˜ òê5þQ ùä‡ÈrëˆcÆŒ`ôEˆ¥ôèÑ£FŠ¥’åË—ã¾ÖÖÖ|,qppppH`îܹ߄¶¯öìÙìÙ³544°¦K‡žÆêIêׯå?<<¼wïÞ2]wÁ¦‰4lØ’ H îòñãÇÆ㫇‡‡xÉá½OŸ>"uvîÜIÔÞÈÈHx€ºD§Õ«W?¢`+VdNø[¯^= CæRî¿_~ùEÜë÷*¦ÅÁA  C† ‘ùkvvöÈ‘#™Ó}µjÕ ~«×CÞÑ,Tzv#HŠ©©©jYªÁÍoß¾såÊa9Äêܹs ìPÅýüü$‚ó§¥¥[PP0qâDR§MLL°èC3×ÖÖ–0Ñg /uKzE-Œ1Ÿ¡3О¼¸‹.zBÙ÷Ì1KûiÓ¦á*Š©tìØ‘BßSþÐÊÊŠ®b%¹¹¹tB*ªKri$ŸŽâ€ ›4iíââ"3Í"ø/Å‘ ´iÓF‚«Æë322–-[Ö³gOæ>9ÒÔÔü矔I®'è X9æ<‹p« ŸŽ?Á‡‚íáá!üõÍ›7{öì‰MNN ‘6¿ÁË¡N:::*Ó 777T644äcŒ£lãäÉ“%ärBa-7lØ@!|ó]ò}4~ëÖ­ÐÐÐ3gÎI=X¼¿¿ÿÝ»w1m‚ø'%%I\»k×.pʦ¡ HW5jce´E/3TŽzQ –ù”Æ¢råʘ‹ßZ^^ž‹‹‹––þŠLkk×®ÅMGŽÉLJ”@­4•Ipm(É`}úôÁŒŒ”>êY@Eò@e¥:¸ÿ‘#GPžŽ”nÿùóç–––ô™Î(®ÝôéÓQâááA„úÇX[É<+Ãwèˆ_¬_¿^˜SÛÀÀ€NÞÑ“mÛ¶mݺU__¿bÅŠÂd‚`F ÿþûdÓ¨¡¡!~; TÜÅÁ¡C† Á@¨¦¤¤@yò·»xñ"}  ¿;wF‰¶¶6HJp|‘gyûö-e¦;qâ„’æNºMÓ¦MY¦0]]ÝôôtVçÕ«W¾¾¾ÖÖÖ©v„Æ,M¡x´C¼gT377çÞ£8 ŒòbMdggClmll ÔöööYˆ9†1(?#ãµkצà{Œ×¿yó&44ôÏ?ÿ8p m£1€ wïÞ}öìÙ Ï,¥&¦¦S§NAä ¥órBXLLLV¬X»+ÏêöíÛE²V”súôiLP[˜OÈøgôèÑEÊ@—†«ðÒøã(ÛÀRE¢*ž¡õ[Ô < &Õ.¿{÷îÔ©S töìY%/¡óæÍãc‰ƒƒƒƒƒ³W¯^Òqàé§;vèééaÁ:|øp)˜èƒ5'$$œ;wÎËËkÓ¦MÎÿB¸ÒQ¼èŽ;J\{ÿþ}âÀ¸qãÈnݺucÇŽ•Þ÷NKKûý÷߅ѱŽ=Š é8ì866–åº=ÁçE‹‰÷Ÿ,äëÖ­«|Ø®k×®‘µ?¡R¥JxpyDï'<<|Á‚Dðûí7ᯭ[·V!¼‰‚ò•~Ð`޲Ê¡pÿ #622ÒÁÁÁÀÀ€²C‚>“” agg§¡¡Áüå •+WÖÖÖ^ºt)ˆ³Â¼óŸ>}ÂÔ±gÏðbLtPΉîСÃäÉ“wïÞ}ëÖ-5¦z|ðàtx.Ì`dò·-j?\"mÁÁQö™™I⩤©ÞWJ‰ b^Ô ¡Œ?Z–D¸N…°°°À×®]ËÇÂ:U©RE$'{zz:²‘‘Qß¾}¡6Cy¾xñ" _¼xQPPðúõ묬,(Õ§NÚ»woI§GÇ-ÐaôDXèããS³fMâÅx"*tvvž6mšt{öì)‘ÇŠÒáõèÑã—_~¡X4ì.D$.‘È ªÍ;·¨Ë:™ðuíÚU"°˜<\¾|™VèÍ7{öl…Þv`äkP¤¬Á ”Í—.]Rír&°@¡©©)f›ÈÈÈâl=½zõ #|ÕªUh­N:wèëë;::©=bvTTèéé5•€©‰…øàà(ÃHII¡˜Ê{©|Í8}ú4…U²>…ŃÎ`kk+4ÏA^^ÞŸþÉÜè(¨ÎÎ;ùXâààààøü%+­_¿^É•ÜëÈ¢E‹,--)¡ & ðýÕ«W:t¨¤×haÎÖÌÌL  äÅèƒL[VTÐÐÐHNN–(÷òò"ÿôaÆ1G{J[Cûð üâ{ôèÑ‚>xð¯Ny"üù@LXáÙ³g©çâG„”5˜ïq¨ ?ê2Ãà+ @«/W®ÜèÑ£·nÝWB»‚èçþýûgΜٽ{wJ|É€´mÛóɶmÛnܸQLW_´@}úôQ-Ž%Ó åÃŒ£l#&&†,®MJJÂöUYA© !…&:žžžÚÚÚNNNJú9b^rwwÇ%>>>LÅêÒ¥ î(Ùƒƒƒƒƒã;”V­Za]ÐÒÒwÿª@¶gäÅæííMç†ÐÕ—.]Jë)žeÒ¤I2I}tttß¾}322¤"zMMM @GêÈ-—LŽ·lÙ"Þ1ЀסC‡ÒydQ0kÖ,V%‡LúÏŸ?/r!95㡸p¨†gÏž‘Œ”Zú 5³Äµk×\\\¬¬¬$¢ë“Ôcаµµ…âÍò]*Ï5êׯO:T KòñãGrFHTÍÁQö@.uÞdJbÆŒdgžûõL,´Û™’’"¯Nffæ’%Ktuu1½(¿)Ü¿ggg‰K5j¤p¹çààààøPXXhhhˆEŠ¨çººº®]»öܹsÊDšúO@{ÔPËÉèbè…‡‡³ç7nÜæÍ›¥/ É_ÿÏ?ÿPÀ:2qgQé®\¹B¼³²²Ä;Fæ¾E5ÂWû÷ï—Ž8tèP.X°@äB¨:@ÚhƒCܽ{—6ÓÔbœ¡§§7yòdÈ`\\\)ï1¦§§:thΜ9ÂÄÿ1cÆ`VÄ< ~ —ššJj6xŠÂ¹BX$±oqă£HpssÃPÇ:®Úå³fÍ¢¹àø*ܺ$’Â4hÐýaÚˆ111üñǤI“X¨^epéÒ%èiöööÒúXAAm#ðuœƒƒƒã;´qJǺzáÂáO ½Ë–-#ozpäuëÖùøøDGG«¬¬ŠàÉ“'QQQ^^^+V¬˜6mh©¦¦f»víZü‹ÆwêÔI__ßÒÒråÊ•ÁÁÁä»J9³ÐpXæcŽ•nøðá2×ëÀÀ@4"²Y±}ûv4ˆ:xL¢½'Ožüüï¹À!CÄK9)äX»K矈ÿi5B[è]»v)sÒ½{wTûû,p¨¨¦´%¨Æ6=z„™ÇÉÉ ²6pà@:1Y.Íç*,,¼uë–»»»••KNÁ€Ù‚C“ˆƒÎc²"ïZ%]eå©ñh¤F|Œq”yPJÇ)S¦¨ÜÂíÛ·Écë¾’‹& ò=¬R¥ŠžžTèAAAâyd”DÛ¶m%œã>|زeËóçÏ•oêÎ;cÆŒ™:ujff¦¼g'E¨ d äàààà(-ZDŽ¥û÷ﯙœœ F 8wîÜaÆtëèèà/Xÿˆ#lll@«±,²Àõølooå\æÙV~~~dd$4Èo¿~ýhEVh2Ù^¿~mhhèëë+}_ooïÁƒ‹Ý…ºNgDð5jôñãÇwïÞ‘ÿÑ£GÅ_4ê•t þ’C=$?~¬ÌY¼££#êàŸÈeC?~\eZåù5è3fH„S XÿË—/Kó1!M~~~`ZZZ`óOÆ ÍÍÍÿú믳gÏR„LÅ܈ ( Cypp”+ÙòåË‹ÓH^^…º0a‚xÍ™3gÒwåÊ•­­­)`&.ˆˆ ¯L5C† ¡©†%ÓTaE>tèPqžèÑ£G˜÷ÌÌÌ’’’Dªaj¢ >| qppp|ÏØ´ié¥X8T6¶‰†Ò›˜˜,…°°02Ð5¾}ûöÞ½{§M›ÖµkW‰ˆU„ZµjõìÙsäÈ‘óæÍ[¿~=*²¦.\¸pìØ±mÛ¶aõ‡zÏbhïÚµK«¡LG3ðô¡C‡Jç¯Â××—Vü^_€þù'Êqkê¡øå !d?@xðàAéü+—-[†Û »uë†B777‘ e†ÓçàP¢l·HW…„„(LW'¸ŠtïQ£Féèè@Ççk×®•¦Å>d<&&b…»SBI Ô®]›rb˜vÐÔˆ#øã(ó€J€Ñ®ðpAjO‰_å­zÐUš6mJgô2}ô„M i>ÛQTò4_SSwñôôTùAœõõõÑ…•×­[§Œ%!GÆÕ«Wé<—¥un×®¥¥å† üýýÁÁÅ ¬À²Ÿ}ºø]ð,t9¹Ø—„ãžLDFFÒéƒÐȾøYüÇëÕ«‡j\(8Š 9lØ0å/Á­X±"d_…Ôo ‹}{{{f±/’¦³$ðìÙ3ÈÎÒ¥KûöíK²¯LâÈøøø•+WŠT7nšZ¼x1ceïÞ½£Íp%S»Š#55õ‡~À:.÷îÝ»U«V¥¼“E5YÏÉÉ …v4jÔ(L; ëkhhàF^^^Eí?ôî^ÉKÈ•ráÂ…|,qppp|·]mÞ¼y­Zµ(ê²4Àôùå—Ž;‚áŽ3ÆÆÆfîܹP¡W¯^ ŽìäädÿÐ¥'OžlaaþØ¥K\"ó,ž9¥N›6ÍÃÃ#!!ŒkkZZÚùóç¡£ÙÙ³gãFýû÷×ÑÑéׯôd¬nøŠÝ¿ŸYØììljV™pÓè0(¹x欭[·’—z§Nð—üãðìt/Š£uùòeñ‘.˜2ÞUi·}øðÎ)NŸ>Í é,=ÏË˹ÖÚÚÕðáBÁQT`PÁ1ÖÛÛ²6xð`5:„Ê´Ø.5CŠýÕ­[7e*6¬N:"ÁûôéÃÒkrp”aÄÆÆ’Í˜ºfƒÝ»wK;=yò¤råÊ(_ºti)<û·nÝZ<è÷óçÏÉbÁ‚gΜÁ‡š5k–š…ðÈ‘#qG<,+agñ":tu7nÌe£¨˜8q"ƒƒCQ/ܺu+.õ.¡ŽåææFDD@®ÍÌÌ0Ï0‹}ñͽâÀÈÈO´lÙ2…5A1~øá‡yóæ‰ÌZdà¤p#‘ƒã[‡§§'†z÷îÝÕØ&¹·oÚ´‰¾‚&SÞIÊŠ[  `›ÇWþ(Bk×®þ# (@øÊ•+|,qppppèêêJoöb±HMM½xñ¢ŸŸßŽ;(ÞÌ™3mllFeaaammmó¶¶¶‹/†þìæææëë ]úîÝ»`¸·nÝòññA9êà½{÷ÆUhÄÝÝuÔ’;6D–<ðŽõë׋ÿùó穟1cÔ~Š%HžtØ×³gO|]µj•xfÏžM¦ûÙÙÙoß¾¥øZ—.]*ÿãÞ½{ÉÌ@XHÖ¼S§N¹0''‡l6âãã¹8p C† ÁÈÙ¸q£ ׂk—+W.,,¬úyïÞ=///LV¦¦¦%‘¸òN;ÊÈ;´wÔ¼}û¶¼ ÷ïß§™Dµ(ßììì0Ú±R«±ÍgÏžýðd«Ý·:th©=T­ZµJ‡kß¼y“¬$2Úspppp|Ÿ6lÖ… 6³}ûö?êééõë×ÏÐÐ$wÛ¶m!!!%;Ž–Îèèh™¿b™Ãjîêê*NêgÍšE,žé³›Ïÿf膎­0À5ùÔwèоâ%”艤d&£÷ññ¡èÜâ–ZZZ¨æììÌÅ£H §rÕÂC´¶lÙ²E‹Åw´ÿÏqþüy¼‡Ÿ~úIûœ6mÚ`’©@Yðrøã(ó Wth êmvÅŠh:À… (šeÉÙêHë´'Ó¥’رcn„wÈÇç-i‹ïtvåÊ•øøx•£í©€&Mš ç¡¡¡Ò?½yóÆÄÄÄÃÃCärhàtœ%ø¯¿þbå–––ÄëéèmñâÅø¬««+ÞÚ6öìÙC%›7oÆ×Þ½{—Ú ¡¨Â[·ne%¹¹¹t+r!¹!5ª9‡¼4ÍJâìÙ³¸\Ü¢æ›9š*¬IQ/$çoß¾mggǾ®ZµŠÒ”ðÆQ¶‘ŸŸOvwÂLµêB5Ê•+GÎh¥éÒòàÁÒ+Ô®½{÷N†‡t˜¹sçò±ÄÁÁÁÁP„·™3g~s='6içñ¼¼<###ñDóXp‡ŠËÿ÷¿ÿIø k^íÚµ?}úôñãÇÆãëÞ½{Å;3hÐ TƒŠÂ"Þܹs‡Úþüyé¼Ü=öïß…«W¯¹0>>žºJ™|98”Ù¨ÇÙ¢ õ;''ç›~”>ƒY=ÅÄÄÈË…akk[©R%aú‡êèè<~ü˜•Ù°2®úß4ÂÂÂ0Ô1”Äa:eáÄÍcÔŽèèhÊŠ«Þ½‚%K–hkkKäð¥ÕÇó±ÄÁÁÁÁñùß“&KKK‘:gÏž]°`Á×Ös 9ëíí-,3ÕÕÕE‡E.ñ§(:åË——^[µjÅÌòCBBð¹jժ⎮ÐI «K'•kÞ¼yi®¹áááÔ[á1¸ ûôé#~-eõåê‡òÀ°§¼B×¢âêÕ«·ó›~ºŠ Rú?i;„ÂÂÂzõê™››³’gÏžiiiݽ{WX­Q£F¸üĉ|Œq”miб±±ò—¬\¹R__ßÆÆÆÍÍ Kžø–`ƒ Ê•+—––¦LË»wïVK®½ÀÀ@½víš’m6oÞÜÄĤøE.xx´â4’››ëîî>`À{{{y´âç4mÚ”$e™éÛ·¯H,”]ºtiÙ²¥ÊYÛ·oß.tý.>Èôå²¹ÿ~Ÿ>}nܸ!ÎD(¯_ÕªUÉŒÐÔÔdçe3gÎD -î¯_¿¦c8ñÓ/Õ~þùg‰ò£G¢¼aÆ¥ÆY†Ž;J¤Ð" ÊÙ'¨S§NR .Äñ­BM|¶˜Ã›¶ •W¿E¦)hû—/_öóóÛ²eË¢E‹ óëëë ·¹Jû÷ïGÿ1  ß½{ÅþÿûtoV¸téR”þ“'O!Ñš¯¯/eÕ䌣l£   1FûÅ‹‹ÙÄ ŒÊ Xð°aÃ(µ¥³³3Ö5P{%ÁŒQ¾|y¡GŒ<¤§§geeÉûuÒ¤Ix¨ùóç«<¯ÚÚÚR"{ñ˜¢I<ß Çw"tíÛ·¯F;ÃþþþÊ·ŒµoïÞ½X^Al‰A÷ìÙS==z4ËH{çÎ sV @‘îØ±#yóEEEº¸¸^Q©R%èùùùµk×fj´ãÑ AñÝ ÐÿråÊQš<‰ŸXغRK!·k×.Üî·ß~R„¼.‘ ñ씨‹§ÁåP‘‘‘0õêÕ+f;ÐÁv‹tät`Û¶mÐ š7oNN PÑ5j„iáܹs%úæÍ›'Ó,'//ï÷߯X±bHH•€ÈwíÚ®]»¦¥¥%3V¥ÝTh#ÄÁñ­‚Iùdß¿¯öÆ…ú¦¦¦ÆÆÆt Ñ“ÎŽlÛ†ñ¼~ýzÍš5'L˜ ¯¤^™˜<€še ]µ¶¶?ž |úô‰4+???>–88888ä”B¼XðÏ?ÿÄ#Èœ.0MaþAk;vìàŒ£lcÑ¢E¥–Vþýû÷Â}]]]v /”ÄÞ½{‹ŸqÄÇÇ×®]‚,/ï-èvµjÕð\˜…”ìT&ôDGG•]KæRßzÐQ5"..ŽìÒÖ©¯_¿¾¼_óòòöíÛg``@úv·nÝ@f±ô”œ ºiä/÷îÝ£¸p 4HHHøú¿««+Ü=zô@aFF=ˆÂ£v´‰jmÛ¶•ù+ÅÒÓÓ+µh§NpGwwwVRPP@šFxx¸È…[¶laÏÁ¡[·nÅ€%/~SsæÌ©\¹²Ìc»>O:•¢PÒjÙ²e~~~iiiÿ¹c>mJ'æ `&iÖ¬¸fžŠ+Ξ=[&£'êA¡?À,Þ¼yÃGÙùÄmß¾ý?¹ûÇOž<¹víÚQ£F1›ytF„’ß½{÷—_~©W¯Þ;wä5 ¾Ê•+÷úõk…}¸víÚøñ㌌¤câI#))I‹cݺu¸Qÿþýù@âàààà` \«À»wïÄkº¸¸ Zff¦Dyzzú¼yóªW¯N!\nß¾] =‡b;6iÒD|‹ÁZLÇñòwcI¥<°Œ§¬Y³F’‹…ž®)–YÂ}CŸÏËË+èÂ… ¥“_2D¡í)$ÿ÷ÿ'¾IÂÁñù‹¡ %•€X¿5///é=´èèhÐyJ¥WµjUŒáE‹9::.Y²ÄÊÊÊÀÀÀÐÐ*ñ„ V¯^ ŽïÞ=•€¨ŒÂÂBòµQõ¡ƒ 4jÔÂ%’½Žìùñ¤Ò{e YYYä¿VœljGNNNåÊ•e¦ýÅôÒ ALGâê Y1µhÑB¤Î«W¯ÜÝݵ´´lmmïß¿¯°W¡¡¡æææ–––l’ñ÷÷§¬k×®åc‰ƒƒƒƒC¸Ä3‰C8räªÝ¼y“•¤¥¥=ºüŒ1âÂ… ¥yvæììŒþ >\¤Îõë×Ée¾M›6|Ø¢E‹5j(ã2O¤[:ø4 cccxLLŒÂF²²²0ûikk»¸¸0{~L5ó‡×Θ1Cµé‘ƒƒƒƒ£lƒTJ°`ñj7nÜ@µcÇŽyyyË—+WnâĉPÈA硲bîÝ»÷¸qã<==ããã•7ˆÅå©©©*dºñðð@úõë'ó× .Sy·nÝäe‚ÆBÙ¤IJd¿*T š”ínÈ!â ‹;`Μ9"Õ(®~›6mJíjff†;.\¸PXHÉøÄS ²Å 28¾C@¨íííiÌ 6 D Ë•Gaa!4UØŽ;B²ÔõÚ/tu''§Aƒ 8Ò ¥]]*qHHˆò)¤¯\¹"‘­þó—¸>}ú9 w«çøNðÕÆrÇÌÓ¨Q#SSSúúäÉ“víÚaMT&S ”ҦΟ?/=Ååææ*l!))ÉÖÖV__ßÇLJ”(´¤§§Ç¶RüñG¨.|qppppÈ)ÌÒâOü”2ÖÉÜHLLtww·±±ÑÔÔãÁœ={¶³³ó–-[vîܹwï^ü j¹jÕªY³f™››k~¥¥¥««kQ»M~i£ P㉪£ò¢Å¢ÅÀ">tèPvN J+Ìv'JgˆTƒb@gåâûÕ¼dÜ®S§NÂBŠÛoll,r!;ë årÁ!Ä‹/˜n ÍÚ/äW™´PJ¢U«Võë×ÿçŸJÔGJò;w¶mÛaÇ···.Î9þ¡C‡Šm3$éêÜ­žã;†:Í$¿ýö›••Õ_ýòüùó¯¤{˜(‘ýÓ§OÑêU«^¸pA™ ÁÊé0]…p:˜QÇÇ8;æ%hM¿þú+½+h†††ÎW¡;Çw ÊIçãã#^|`+T¨M^ÉÓ´gÏžÅÄÄœ={{xx€oz{{ãsPPÐÍ›7Ax‹cºOéÛ@$Ê*V¬H¡b_½z%óZ ÚÓ»wï´´´5j0øcÇŽá³´‡@ÿY¦-¼ñ­ø®]»–fà߇RÇ„!¢¢¢È2AüLaY|`ÒW)ö$ ‚L…àÅjÌÈ–™™YʧÕ>|ˆŽŽ^³fɬ]»VaŒiüý÷ßd½ Z0Yq·zŽï  ÌõêÕûRhÔ¨$ÑÁÁJæœRKU)Jd¿páÂöíÛW©REIRÿùßøŸ;ê‚áéé©££cooŸ‘‘A…P)d(­ÚS§N¥ y4ë.^¼˜"™ §­;wŠWËÎΞ0a‚0ùû ÚgH½çííMáŒeÃNŸ>–Ë#F 4jj‡Ò»ÓÙ=êˆßælÿðáÃ"•)Q¯DŒúÜq×®]¬„Eð;qâ„È…»wïVWRr޲3gÎÐÆ†úåË—YyïÞ½Q‰S²h¨ë±±±â;fÿ 0« âÏ?ÿÄK;v¬ 7MOO§ PÚù0ãø®ðáÇ”””€€'''SSÓ-ZHÓü *о‹‹KDD„2™ãÔšÜ@¨CBB”¿Šlo”Œ’òŽgïÓ§žŽé*d‡OÖ†–lÔ:þóÏ?(oݺ5B2¡^{ÚRÃÍ›7É~••¸»»Ó)<»Ìõ/^¼ÐÕÕ%“6{{{²ÐÑÑa9ಳ³é¬ÿÒ¥KâwoÖ¬ª5oÞ|Ú´i {£^^Ø|µƒrfIDÀƒ‚¤0TQff& ~Ué‡8þ+@¦h£¬sçÎiiiŸ r+Ü&jüÎ;çÏŸ?hÐ }}}üÅ(EIxx¸¼_?(üõ¸qãŠz!ËVß±cÇ’èÇÁñm<÷Ì™3ëÖ­3fLûöíiÚ‹{Û¶m±¸¯Y³fß¾}‰‰‰%×™={öTªTéÔ©SEºªW¯^è'¨·xµ7nL:ÕÔÔT˜¶>""%´ø’ãï3`ª¤7ÃÝv88888dbÒ¤IX&¾­nƒxC'k=777Z¡ÐÉ»t}fK¼ÿ~*¼ÿ>mÐ*IVµ­[·wÈÈÈ ÅwýúõäP£F !g?w‘ÑŽ;ÈÏ?‘/¿t8…óÂM…½"_àÆ‹_Û­[7TÃûä¢ñ=ãÝ»w'N¤q>|øpi#yJ ¬¼‘ª âãã}}}W­Z5vìXccã9sæìÚµ+::ú[‰ çä䤯§àœ?þø£Hâ{Žïoß¾½zõ*82$ESS“P üòË/àÂŽŽŽÇgFìêBQ§ Lht(€iMf(*ÁÁÁ˜K­­­oݺŮڽ{w‡„NôgÏžÑ@ð6PsóæÍ|pppppHƒÎvZžmxòä -…àΔ˞,Ze:å]¼x‘¼Õj×®.¡–khhÐWÚoÑ¿õ¬Y³h Æ¢ úC*¸<«`kkKýùé§ŸfÏž}÷îÝ!C†”¦[zÊ€; 6''‡2”‰GÝY¶l™Â{eÏŸ?ïß¿?³l‘)S4ìÕè˜SXXxûöíÇ/Y²dèС477‡„ˆgœüÏy=õ"]åëëKóƒ——l" :,,L^<ÌÒÇòåËñ +Irr2eøæ¶R98J·nÝrrr"—7f$===—‡æääDDDà3¤Ë+³`g¨Q£Fß¾}±.{zz¢©âéUýõnŠî)¬yïÞ=ôªJ•*ÔÏ:uêƒæ)ÄñãÇqT>B88888¤AÆç_ÃùìëׯÁ»Á+:äþ6lpvvÞ´i>{xxøøøœ;w¬“˜ä%ðñãG}ª`bb"A(];ìË—/ñ_uttÄ;ÏnŠ¥üó¿Qp›6m*¡9àîXè…*úY:ÞÄÛ¶mÃíºví*,-¢ô"*a£L"((ˆâ6lxõêUÆMã¹4]ã!§gÏž]½zõ°aÃ@ó'L˜]áÁÜ™3gú÷ïÿöíÛ’èÅͳ´´T²~~~~Íš5i‹¯„ºÄÁñM2²k×.J"C¨Zµ*D |Vd«9;;;88ª‚……¥î•@íÚµ °Ê9rD¸½¯.ྸ˲eËDê„„„@ÑbúÀo¿ý¶sç΢Î?¦ËIoáàààààbÿþýX#úôéSjwÄBvóæM0ôµk×þñÇFFF¿þú+Û¾V?ÿüs Y€>@fÏž-mUéä ³7Æ×½{÷ŠwžÜZ·n¿ºººD7Ⱦ%ó’ÄÄD[[[¨bŊТ¢¢Jô%Cu!Sa”ïÛ·oS‚]ñdÁaŸ'~WøôéÓš5kh¯LCC#33S¤2 1ñ’S0ú}ûö?~À€S¦Lñöö–ÙgŠ5QÔ,“x±±± ãgÒFÙ°aÔl½¥÷¦°eŽï X³.\Èìí±N‰CÆUˆ„E‚ñ9rd«V­¤OókÕª5pàÀE‹AQ‹ÑQÓ¦MÑl`` ôOïÞ½Ã]ÈËзo_aм¢‚æc5çc†ƒƒƒƒC~~~X#jÖ¬¹cÇMµÛ¸’Û,´n{{{PxÐmá9»Ì}uÐüîÝ»ë}tf°`333|ÖÖÖF9¸t°\€‰K÷*77—vÈ/ž””ˆ?>ž…Û­^½š|â¨>…Ù_±b…ȵ¸£»»;äð,()¹hØmÛ¶•Þ© ³ ñôdD&MšpéøNz>fÌ–ÖÖÖ SÑ%&&²úúúŽŽŽAAAâ›E% hæ»ví;v,8þÌ™3Ñá¯=zôÀ°—ç÷*ĆŽYO× Añú;wîdû{ A• ÑÑÑ|Ôqpîܹƒi‡-ëõë×Ç”¢BÞIyÈÉÉ Ý°aÃèÑ£Û´i#Mó¡ÿ`êX¸pááÇïÝ»WTƩڑØZÄ}]\\(Ä() PfŠ/ûä›P¤|ß ÈŒœKtà¡C‡.]ºtëÖ­þþþ‘‘‘©©©JÒO,dçÏŸwuu4i¨k¥J•¤¹6 ;wîlnn>wî\Ô ˆÅš(3”½4 ¢?|øÐÓÓÓÉÉ)X>ˆØ‚¥ÊÓ±›6mJ1Á T(cO ¾@qæ¡ÿ“ûü±cÇPŽG ž®°çPÐ1,îL‡©W¯ž½½}zzºÚÿ³sæÌAû#GŽΘ1Cab¾/^P÷XØ^Ž2 èÏt–T®\¹uëÖÉ«–––väÈ‘ÇÓ>€žžžôötf+++Ì111JʲڑpôèQa º­p/ WMœ8‘,| Ú˜<<<2 %ãf\»vfBâ¾¾¾|àqpÄÇÇc…b[ý¿ÿþûÞ½{W¢7ÍÍÍ…Š²qãÆ1cÆ´k×Nú ¡Fºººóçχò””¤æÓ¹@ݺuYIrr²­­-³üé§ŸðJ‹Zúß»wo´ÉÒúpppppp0€¢þïÿÃ2Ѿ}{,g"ßÕªUkÞ¼9³rïÒ¥K÷/hÕªUýúõñ«¼ øá‡N:Aáß°aÃÉ“'SRRdFØV;( =yÁKë à''''z=þìÙ³â BA5èÿŸÿÍ8eÊ¢<ÿ÷ʇáÅK§cA¢T¦¦¦ üj ïC9øjÖ¬)dXxÿd…(N»(™Îúõë¹€”mܸq£I“&”sÍßß_^µ§OŸîܹ333#<..Ž,cß¿ºJ¡«(Ôž„Ôcr ¸U cQ–(0Û@{ïܹ³LáJOO1b°råÊ“'O†Â¯üì„C™VÙÙÙô~ttt ñœ‚=Žï666¤{0Óôÿ¤'yyyÂ|¬KBÍG‚Oz~  ym| 4hÛ+hÛ¶íŽ;Ô„ÖØØ˜§ºãààààh¼X&öíÛG500põêÕXãôõõ;tè@QÔŠÐÕÌ;ë ˆCIo¿ËÃôéÓÑ;;;aá‡(Ä hxrr2JÐI²¹·ÔÍÉÉ!¿6ÊÙM‡€¿üò ‘z‡[·n-R |||444Ø«ƒƒßoß¾%_ƒÈÈHáiãâÅ‹"×®]»u´µµ¹t”a`ìÑ3I±ª•›› vüøqy¹í=zÍÜÉÉIOO$E:Ù4Ø”œï‰<ìÙ³G:$$wË–-xè­ƒƒCVVVQ›ŽŽ¦]2ñ]TkÔ¨^ MJ³gÏæÃãûf’%K–°ˆ:Ž’Ž6£Í·¶¶nß¾½4ͯ^½º––ô //¯„„8Åê:t(¤³ L°Ê¸ÿ”ïžÛüpppppÈÄ”)S°LÌœ9S^…÷ïßgdd\¿~]hå~ôèQŸ/8sæ HâÍ›7SRRž?®Ð9·Ô@^ðBCtô ¤žÜáYè{Ðyõ…pwwƽ‡rBéóbccñÕÑÑŸõõõUëêµk×lll˜Ï4|-~`ÚØ—Ò+3žðP¨S¾|yt·LcØÙÙ™• ‚oʬ–““sòäÉ;wî@×…îíçç§ä]aaá­[· 22³Pa\¡#¼tRP}þºªqãÆÂLOž<122¢T iiiª5Ë¢Sb†”WÒGÖ ´“F!ô¿¹¼¢ÅÄÄÍÍ­N:4tíÚŠÄWÞçׯ_GFFnÙ²eܸq;v”v>úñÇIf¢‡²TBýùðáCÅŠq£¸¸8>¢88888¤ñÏ?ÿ`™èÕ«×Þå@ßNQò‚ÝíÝ»W˜Ö ÜÄÄÄäÀd„Oö ´!¯p•ýA5ðwVÒ¿–Äœ´÷âap °-²‹&¾ §§çã㣲«2´´Ó£GaáŽ;PØ©S'ñk)À/îΤŒšê°aÃhŒMžè 0|øp lôAfÈûµyóæôÕÈÈèôéÓдiHÊš5k¤™¯ÌÅ”ÎïÞ½Ë ×­[‡<Âç/ ”)ïСCB`Ó¦MâïÒøðáƒDâû-Z€ï«+<%%…œ÷Ÿ|H-‹SN:uÆÇ¤,t»{÷î¤bPÉ«vÿþ}??¿—_€Ñxþüù"yÓ¼xñÂÓÓ£“€Pdذį¶¶¶è‰tÐ*Œv+++Ððk×®©QóÇŒT»vmêéÓ§cüC'q=PWDæñä‹’v Oç}}}餒EŽï7oÞÄ*ÏBÒaÝ,œÊ´Jq[¾|yè0*äãS¤À´lÙ’+™xÿþ=i×ÖÖÖª¹ƒnß¾}þüù äš_`bb2aÂèç –ž˜˜øàÁèü¥`yûùßtí+V¤ÛÑ®…¹¹9SRrUsuuoŠÌì…v¼Ÿ¿Äò%~D‡Œä9+Ôá÷íÛGÊLÏž=<(b¬+”øžÜáUN|ߪU+fœÀR£0©÷ñãÇQ§N:ßâ© ‡L`ðÔ¯_ŸŽ–$œÍÀß/]ºtôèÑôôtPrÿ"¥EÀ¹ …–›œœ|îÜ9áž’4˜7+ƶt( ~ŠXåãã#ÏY@y 9Ê< ûS¦L¡CmP`r‘²aÆÄÄ`ÁDô_%×ÌíÛ·§9JKKKzë²ä°aÃÜÔÔÔ”.GX°`j¼D‹¸_ÊÈÉÉ¡‡b'ÝP*È7BÉQØ«òåË‹wûÓ§O-Z´@Í;wJüDÆê‡Æç3gÎQ1;Ùß=z4óȃ2¿nݺ¢êËK|¯$1™5k–´?¯ƒƒƒBݼŒüýy®í²ooo g*š ³ÎÇÃÃÃïܹ‘¹rå ¸‘20BâΟ? 1!€­uSˆ‚ïÙÛÛƒÎK§È¤à{ÎÎÎh\bþâÅ sssÈ©ß*¹çxxxH”?žN'ïÝ»',¿yó&EØæ’£ ãýû÷...X IrõôôŠjuâÆQQQ·nÝÂ_L_±±±‰‰‰ÿíY~~>f'Ú©ÀÓa!.C †É“'ãÖóçÏçcŒƒƒƒƒC&ÈOœ21)ÌÙômÈRh»Ïÿ&šoÓ¦ ­Å3gÎÄ×Áƒ‹7ª‚j`Ò”ü?þÀOÐáI“¡D!!!Â:?vrrbnÅUªTéÙ³gLLL‘„%¾g}J&¾ ¢ BKŒÈÈH‚å‰çß¡8Þ” ãÛþ‰4lôõõåí,öB…~ýú5Ø}‘ThzÐm l x\^|jÀòè ÷µ¤óèÉ¢@½ dšyë¶oßN†ÇŽ“¨Ÿ””DF>|Xr”U`d1~ýõ×Ó§O«ÐHfffJJÊíÛ·)Êæ“GÝ»w/77ÓTttô“'OJ9Õž‹vø33³’v¥—‰~ýúɵ /4p¤gÏž\L¾]<{ö¬mÛ¶,Jž}úøñãXÓ“““!J>Ä„pðàÁ;wî¨ÝªåÐ0á¨<¿…„„(œÞ†žž‰•‘gAþþþªÍfÇŽÃÌ`oo_ÌàŸáááÌ–0iP˜÷:Ðñ¥x600øÊ» ý9333.. úþýûÁG°b&''K×$g´={ö¼{÷«!KÈžM $â÷"Ú>oÞ„‹W1=w0³Aê!w¾¾¾/_¾„2””ôìÙ³«W¯‚Ý«àŒ©ŒÞ1IÚØØ(Ü]”)ìxdmmmL¤Xp‹ÿVi¶ÑÔÔ䌃ƒƒƒCP˜ëÕ«‡eb×®]TrìØ1Z‹ÿÛŽ/Mï‰'@É׬Y3gΜ1cÆPÖ{í/€z0sæLÐç;vøûûGFFÊÔÿ;vìˆ'òóó;rä>ÔªU‹ª¹¹¹ákëÖ­Åí=zD–„,òž4îÞ½K¬™¶â·lÙ‚¯Ýºui–‚˜áqØ?«?‹ Æ\ï‹hW$ñ}Ë–-ñOX/…ëÖ­i|ˆžZÎa9J4òå%LÏÍÍeL2…A(Pž¸*~’ÉôAÓ¿@-½}óæMpp0D âO¾-ÅÄëׯY=šî„À\Çòè©f¾K¹,ûõëÑ#¹iÅy=Ç÷Ì7–éÖ‡2¡£  7ÐgÈQñwÛ0A?><<<55õáǘOÂÂÂ0Ÿœ;w.** ˺¸i*P ZMVp™™™ò,]Ñæ‹/°Î‚#_¼xñÔ©SÐ¥·mÛ¶|ùò3fàÖDØ¡!8ÐÒÒÒÎÎnýúõAAAh<##C…å¾Q£Fx,ñ&&&ø0sæL*ïÕ«¾®\¹Rür2²•lj(‡µ——>§§§“z/~o€Ž*„èP„ í˜šš2VÞ©S'wwwhAE}jJ|O¹ˆ”¯·²²’~:ü+Åi6C/â"ó-‚B;vèÐAÉú¯^½ºrå &‡ 7kÖLæ™>FW=¬­­1Š!û*ûÌ2<þ¢ I÷÷÷/!3uÌ?ÞÞÞ˜¸~ÿýwé£|”€æOžº88888$@Qòé+X3źQ2$>(<ô^???WW×Å‹ƒ›Oš4ÉÂÂ\@GG«yŸ>}ºwïÚ¨÷/ÌÌÌ@-§OŸnoo¿víZ777páøøø'OžŸHƒLþBCCIm ìrt¶%_ür2˜ß¼y³x5Ê?vìXúJQ÷ñt"—ßúîÝ»¥ºyó¦ ËT·n]¼.Rê¼|ù í9Цð%ãµÓö‚8y¡@`y\d¾Eœ:uŠr;ªÜB^^$ÝÃÃcáÂ…d½/óL¿J•*ݺu³´´„hƒ˜ß»w¯Hõ“““Aê}úÔ¯__B+ i×ÓÓ0`À¢E‹0×`TZ†F•¤^Þ¼yƒû<|ø0hˤI“ªV­:|øp‰Ç‚Œ¨ÌaÂÁñ}€e›Éçsnnnpp0fk¥J•„Ò£aÃ†ŽŽŽáááš-b:;;Ó¢Lü¯eÆu»téE\8‹“aaa¸O˜|\qpppp1yòd(ÖBL–ª¿}úàääé!t›)W®œµµ5Ä…ˆœ  ò4h@‡›šš¦¥¥I¿Û·o÷ìÙsΜ9ZÉCò°{÷îâÝ( ޹ãàààà"++KGG‡ª¿QKtt4óñÆ_(»‚ö(+PÆ0òL8|øð—¼e 7 ?–’ÅM˜0AâµîÞ½KÜÑÒº®®®Hr­V7ãî£GÀŒªT©Âv}Z@—xýú5ô¬]ÕªU…R"*ÂD¸ Á2òA€¨UO3!!ÁÈÈhÛ¶mùOÎïççGCýúõ×­['%YèÔ©S…µz988888@ú¨TŠ»»;µÜ¿ŸüÙ 5LLLðÏæÍ›¿‡%Æ*¬ÑF8sæLñaí“í­–ú¦‚ÖÖÖôqàÀ*µ0mV O3È„ÞÃhQzOÁ+V> ø/¼5tèPô™4iŸDßnݺE^+ßèýKdú@¥J•0ÁaÞÓWèSФÂ';v¬²>>>èо}{>29þ#¿.œd¼˜Ý/^\²dIÛ¶m…:tuuû÷ï¿uëÖAƒQ ” ZËé8³««kß¾}UÇQ‰˜˜ŠM¯»—^oôèÑ8Jå¶>ÇþþþP ¥K—fÙ˜­¬¬h9ýÍ›7Ð}øßÞÞ>''ç›~L°Ú§OŸŽ7Ž”øÕ«WÑxïÞ=Ê¡GE@®qK—.U뢔‘OGG‡|È[ Zµj"‹´y«Cb¿RRRÀhåÁ9ñ1##CØ';;›r]ºtIØN›þ`C"çgÃ'Ñ·…ôôt'wúçŸ6mÚäíí K8<<<..îúõë=úZÑ:?~Äh Z¾|ùàÁƒ›7o®0N†}íÚµ---gÍšN‘¦O2¡€Üï< Ó£G‘œxîîî´QÈG&Ç´Ñ\ÈäP^^^ýúõ£¨CÌý‘#G>þ\ú©²²²èää”Ϫô/^¼?~<äRåÊ•}||Ô=›µµ5îßÙÙ™(yÚCÏÒGÐIJR ë÷Ë¿ÙÞÈ$.S¦L½zõLLLzõêe°~Ûîïø/V¬Xáœ777ϱwï^ÿ<8p ü_œ?>!.\¸ó/233Ÿÿ b  ŸPÊø ô‡àÀÀÀ@èAœÖÅÅeÑ¢E¸(ìóaÆá®p‡;vlÑ¢E­Zµ*V¬>+cÞ—/_ž÷)Lm§ ä· í¯n ßwïÞQðþ™3gðñåË—D¢/^¼¨ìØÿ¿ýö›ýÛqQ‡?ÿü“âÅÄ݆††h!âÃÆ€2àס¡¢0E!G‘æ ³ÏÁ ÆŒÆ\µjÕÂ… §M›†ÙrjfffjjjnnŽ ,ضm[XXXrrrþשÔ,äÛ·o:ts\|O¿àHýéÓ§‹/Þ¦MñtsçΕ…áàøŽé1_µjÕ¯ruèe˜ƒ¦¹O™v¤¶Š¾¾~TTT>o#>>& ,+˜OR¼îåy«Å „ß:(eÓ?þ˜ZþþûoRv´±{ùòå®]»R`øwƒ‰'ÒÃ6nÜXŠZtttÔ8Ï9?€&ÓGrû9„}F­]KÆßß¿mÛ¶ò¡÷...øCEØ?22%K–|óæÈi;uê„n`v|*}Cxòä ÍŒI‰xðàAlll@@€«««]Ïž=»uëCÔÞÞÞÃÃãÔ©Sjmi…éß¹s6<üðáÃ[µj…áMï3Në—»té’®®nÆ U9R("88¾{`î“W¼Z9çµ '''Ü€™™™ZGA õèÑ"4ŸWwssûùçŸkÔ¨!\cW”ËwõêÕ|Dqpppp´dÍ*¾´¿,¿…M=;tèàéé •DÛñË—/g{ô0ÝÙÞ}ÿþýiCßÒÒÒä_´iÓ¦eš6mZë_T¨P¡läwÕ·W¾|yˆ“´k×§ÅÍ21cÆ‚ pW›7oöööi ?MHH ˜ôTäŽ ßÄÅÅQ¸ÁÇÅéåÞQ+G.^ŽmÒ¤ }¤8ýæÍ›‹rðàA*ÓS5pñBð»PôP»ví™3gÒ{ÖßÇ  ýøñã"gÃ@CCC>•¾!€ÎÓ¯¯Ì:MLL, K¿ÿþæÍ›AAA˜§ Ó‡iŠi{àÀ|Ö³ÖŸ?&ÃX목©©•*U‚ÜøçŸTv622Â=lÚ´‰LŽÿ5j„a¿{÷ne —ããã ní‘’«•RÃËË ¶M>]`QPYa++«|®mB„â<+V¬àɃƒƒƒãþýûäN^â_þ-‡ œ={V¦sݺuѲ,åÌ<›­Þ»wïÆ—,Y2uêT¢üÓ§OgKÊüß^¿~Íüð)×Ü”)Sò_–öÁLqN•®æ_þ­OW²dIÍn ##ƒò×Q:ü¥°ü•òæÍZ]9uêTýôÉÉÉ&L`û•´u²}ûvaJ(„·$ržË—/˯ pq`~Ñï®0ãU|³··üøq!ÜLnnîùóç=<|PYïàĉ˜züÒ ÆiåÞ½½½aðS*ˆÜLþ—õbÿþýx 6ÔâšIÇŽ‹+†{–ÿ6))iùòåÂ,°í©€&ORÁñŸU˜ÕÓÓ£oß¾eÁ€ ñüùóÈÈH¨QGGÇÞ½{C8€ìÛÚÚÂ6€N¿sçŽZ4™œâjÕª%¥3Îloo¿xñâü?5l$-î°OŸ>g7nNÿqÀþ$GkVkæüùódíoݺU¦ó™3g„éæŸ>}‚>…bmÛ¶í˜1c¼¼¼`µj=!v«V­pé}ûö‰ôY·nnC¾ýư±÷îÝûå_W„?ÿü“йS}·²eËŠûÔ±Õ…VºDP:+++úHa}0KDÁóRå|îHÁû÷ïíììp¹2eÊ>°~J‹‡ŸUäp*Ìdz~}[ [·n‰wËÈÈÀä277ïÙ³'øõéÓ§ “ãÉÛ͈ˆ€ܧOŸ®]»Ž;V¢ËD€MS2I­Ä¼@¶XZZâÝÊ,s%&&Ξ=»K—.ãÇ ^ o˜ò™|ëG88Ô˜8¹ŠAѺ:t(;Œ ‰VÄ›7o®\¹¸|ùr( Èén¤…  ¥ó¼yó\]]e###K–,9|øðØØX‰]¼x1.:wî\m½Ã7ª´%88888þ  ªÊ êŒØRÕÒ¥KËw¦ Ëàï¬e×®]íÚµ›6mÚÅ‹ ´¸ùÿ+‹ò†…0 a ‚C[ œ7nHì:RjÞ ûÙÁÁaçΠÛ‘B©©©Ú Ny÷îåšP¸W˜/})ƒªw­[·Ž>>~üØÍÍÍØØr&**Já‹¡õF>&9þk¨\¹2ÿ±cÇXËýû÷A¢ AAü îÒäÁ¾`Á•=·lÙ;G¾JÔѲ?l§íÛ·‹— ýᇆªE{)$$Wÿõ×_·nÝ*Åû‘ƒƒƒƒã»4Kƒ  `¨S W¨Â¨\¿~ýXKZZšB¿w­£bÅŠ¸ô¹sçä¿zðàA÷îÝ7oÞ,Óõ:vìX[[[¶d‘’’òCÈzöìù¾ªdÍT.Ÿiµ>~üH¥ë(¨Q£>’#2€@¡ÏôéÓ gHtîÜ—sqq6JI‹—››KµÂÁ€øÌúV@©d–q$üôÚµkT8ÃÛÛû[|¤p¹`þüù¬ê}Ÿ>}V®\)’ƒÖ'Ožü%ÏSòÇÂÂâÀârrݺu|Çã¿ *Ó†i%¯1ÃÂÂh ~éÒ¥.\ÐúÞ¦aÁq"ÄyðàÁ"KÖ¸7¨Nʇ£««‹Y¯0 æÅ‹U«Vý믿D¸?žñòåË«W¯†ê?~¼”§8~ü¸°Xg«V­.\˜P [-E ÇŽƒ"·e©à{öìI ÐÖ5›8q"¾uppøZD&ôþöíÛÛ·o/Ï÷“’’:tè ã¬Û­[7œÄÀÀ€>nذëÖ­+®þÒÒÒÈ]Yú¶¦2P¼<¨}¤t¸9dçÎèS£FÂÑÑDá»té"lÄk—’^/ÏÞó *WÂÔø –Íš5kРÁ·î§q¡¬ÚEVVV@@v¿~ýjÕªEÆ3ì|ù:0ï!N¯^½Ú·oßáÇÃDWvEœ²èþýûø¼Êì”ß%¨€¬HîšwïÞqqqæææÊ"õ=z4f̘`¦Cž:u Rº6ƒ©©é¡C‡„>~£FÂW —¾_¾|‰Û€1éëðáÃÒs‰„††â)J•*Õ°aCaÙ Ê•+ÛÚÚrØÇWô„?´}„æ¢Hj.J¾téÒ|^ö0TÌÚ•+WNœ8JS__¿gÏž"Ô•†oÞ¼I}||-ZÔ®]»eË–É/}“ï½Ðg¦¼÷Â2¯TÆù*(Eà £47Nõ×_ÑGr¾ÕÕÕÙË•¦g¿xñb! 3CØ^½zu´ûùù‰ëîîŽ>mÚ´á3ë[A… òåA™¯”UµøV@µ¢¤$ÅJKK›={6feµjÕ„Da‡×­[·R¥Jvvv õ"þÃ~fff 3dºgddèèèB†LŽ" ­Zµ’Ò<úÀS§NÅ êÚµ«³³3„ºó´_/ïì'ÄöíÛ•-hïÝ»×ÐÐ0::Z¦ýþýûNNN_Õ¹|ùrÜö7~üñGܹ°'Œ.†……‰ë}æÍ›W£¦Y#AAAÂvÚO/À2 ifœp>Èùœ¸Ô ư];uêôM¿Š3fàUŒ;Vbÿ„„]]]===¶‘!ƒÁ߬Y3‘ìš°«1•FŒÁÂ`£¢¢(È(W®åø¯S‰¶›58ºÓmݺuãÆ3Í(-fñÂ… ·nÝó†2ò)ÄèÑ£qiÌ}u¯ûøñckkk(e‘Œ»Œþþþä–]³fM<#lú6&&fÔ¨QPîkÖ¬ÑxÖã0®`PáæææÂ¯ÈËB‰*þ0@@á¶cccy&Žï ”Àj…µPî—Ö­[+;„ÜÈUgyñâExxø²eËzõêE,~Μ9¾¾¾—.]O;/º7ñ@àÄÄD\N&5~¿~ý˜Rƒ&¥vܒʘqàܹs´ ïs«Z¶l‰nذ>’ „ø>å6¬_¿~á ù¢9‡F#,qc ^½zÊœ™9Š (ÃC~ª<ÜÜÜ4ŽÓW LḸ8Ì‚Ýl¢w333é‡=z”哤×Ù³g+K­™““ãääÒ1È===ɇRƒš˜˜p{›ã?ðnÒÎZQ²éééPܰÜÝÝÁÙ& "¬^½ZŠ ˆ#}}}éáKׯ_‡Š×ÑÑY¸p!äC`` ©©©]rr²Æyþüù‰'R1#‚²(Èt†ÁC•v*T¨shÿþý¼Çw I)b=$$„Y˜$í£¢¢”emmÎÎÎò_¥¥¥y{{9²cÇŽæææ°`qæÇkë†uuuqi¡I,\ÝÀÀ@fó=77—‚¾üñG 1ˆŒŒü’·+MŒfÇŽRV?úöí«­¡\=zô {÷î¥Lû">„>¤dÝâ•æ´*®WµjUaãëׯýõW´ÇÄĈëàà€>ýû÷çSì›­Ã3Qk¢ÚªÜôáÇ«W¯nß¾}„ ­Zµ"æ lÚ´© ‡}Ë–-Õ: öyÙ²e333«W¯^¿~}…iIð8®NÂth¤°bZLxñâ™2OªëÅÁñ­ƒô{áç\…J%ó€m£«Ä¶mÛ,--E|”ôrÀÐÐÖ‘‡3¹›ŠJ—.mee…3K ¢‡¶qãF5„_~ùrlýúõ"é@98888Š2–-[F)ãØÞyäV«VM䨡C‡Ê$F‹ŠŠ>|x»ví«[ ñ|ûö-tè;w®\¹~ðàAÕPLkÖ¬Y±bÌ];;;jÐC–+žÖ¥®gee 4‡¼ÿ^ØþüùóöíÛ“Ú3fŒ0EÞÉ“'ñ±D‰2Qä2€•N‰Å:¤­7þüyº4iaÜÑ– .ˆEiêóŸÙ@ ðÞh D&£o÷îÝ…%‚e ù-8Š&5j„ß+888ÿ§266®S§ŽÆ‡¿~ýƒgöìÙ;v¤$@GG§K—.3fÌðóóS/“OÐЭQ£†ôC›5kF«ø¡ð´`ô›7o–|òä ž‹‚ž îØ?e¨ÀìSXøƒƒã{EÓ¦M1òe|í SJ sÃ<µ··Ÿ5k–ºånaó¬^½ÚÈÈöŒÆ%Asss×­[W³fMQhnn¾ÿ~Í| q¶   Ñ£G³ BãÆñ€?ù)éËÁÁÁÁQ˜ç"ÏbÆ###Iª‹ï_Sê9¨6Ör#j]ÝÃÃÃÚÚzäÈ‘ãLJM»hÑ"ú]»vùûûà ÆÍ€¿ßºu+##ƒ…É—/_—Ž•9®Þ¶mÛ£GÊ´?xð€¼ÎJ•*…sÒúö²eËè[ ·2dˆø­‚Mó¹Yê§OŸèYØ=Sø¼“““ÈQkÖ¬AŸæÍ›Î¡Üà®®®ÂF* ~ø½¨ÖBŽÃQÔ@´ÆaþOµeË vÜþùç777X¼´JÛ¾}{;;;HLíÂôH¿tém~Ié|ïÞ½à>srr(¥¤………Lˆ/H9[[[ïb\ˆÁ#ã1…_}þü¹W¯^ä-£ñŽÇ7‡=z`؃·þ¥}||pé’%KЧ…ÁLïׯŸº!f`°j `áh̔߼yãììÌ\îaÒ̘1ãÔ©S¾¾¾ø {I¤jžJ@æÄÅÅ-X°6%\"üþûïÆ ÃÍgeeññÉÁÁÁQ”AÙSË”)ÃâªÈ¼WiÓBø«LžV@ dnò10°åsΤ¦¦Ö©SýË–-}íÚ5ÊçFñ¹¹¹¹Ä=CCCÅ/jnn.³Ž¡ 2D G|?È!à¤sE’lkT@¦švzzºxZEåð™9s&ŸhEmÚ´Áżbòƒ§OŸþüóÏ÷ǃ΃ÂÓ¨nܸ±º¥´L12hÅ÷¿>|øàîîÞ½{÷ÄÄDj™6md‹°žÌlØá *2u9˜âäæ®p äùóçÕªUÓnìG­´³Åm‘1Z¨7mÙc^‹t3fŒº‹ÕÇïÒ¥ËêÕ«5N+Ò½oß>Фºu“'O†¸†…-üàÁƒ»wï=zôÅ‹°jò&snÞ¼Ù‚Ò~üñÇŠ+ò…zŽ"nÌ3 œqF•Yai׸gÏž…Ï 4XK+))©J•*è\©R%JäEAߦ¦¦Ôªê@EНŸ?zôˆÜÑÅ=ä5^W©Y³&S¦ôþÅ=[·n-¿‡^@ãÖ` ûgëÖ­"ÇÒ¾-˜ŸhE;vÄ%Ü5Æd111éׯŸ•••Éÿˆªµµµ™™™L{Ÿ<àŸ²eË6iÒDüŠ/^´µµ%nÛ°aCXòê:ü@ÆÉŽ¥‚ò Q@墄Ž/_¾¤¬„àààN:y{{ËdÌ€´aõ;w‰ç=sæ åÓðôôäC”ã¿€iÓ¦ óÇ®Zµ ŒxêÔ©aaa sVhK—.ÅÕµuÂÌÌÌ⡔ȓ‚˜˜rœ£Ýó7ÒrÇóçÏcccñf Ÿ>} FÿêÕ+ÈpÈ"é‰D0dÈaR>¾ÌÈÁÁÁQ4Eþ®éééÔbaaA-*W•AèdRè¨X̶mÛTRh@bÍTKîÇT¤{ß¾}Ô‡JÖªÜX\²d UžÒú³<{öŒìö›7oR … ˆ{!®X±} è ámƒ¶ÐK“‰¼ÆKC#ŸÈ± E´LÁ“ð}дھ}»VÎ’þ¿ÿýO™9æ&+ù™ƒ¡‹´H½ ÊtÁf¥°Ïíìì`«‹äMIIéÕ«ºÉ{àP¸ `kk«2®‡<£Š/.¿ãÏÁñýaùòåð˜_¬åóçÏ/^D»¹¹¹©©éœ9sŽ=ªÅL¼B`–áê?ÿüs~h8»mðk##£¸¸8O¶>|øpR£–3fÌP˜ˆvó7lØ@[™™™iiiàûxQší݃ÎÏž=› û˜g~þs«rpppp¨èÛ€èã›7ohWºOŸ>*­FÏ.]ºþmㆅò qúôiÚd›n LnƒvïÞ=âÔ*krÕªU«€x=@ ýÜÜÜèãÂ… Uî€5žÍÈÈ(„nccƒËMœ8QØxæÌ E_¢°>ÝŠ8ˆlj+Ï< ùh}œ#FŒå¯P¡Â´iÓvìØ±zõj{{û¾}ûÂbÇ=Œ?~ëÖ­0ã¿nºEJ’‰Ûi644„Á¬ì@XÑÓ§O‡hU&sóæM2•a¢K\Bùôé%ÖkÔ¨‘”4×ß4(c¤¥¥¥Âo!¢££]]]LŽC3gÎܳgϵk×´%1ªV­ª0A®Z)>nß¾maaáä䔟8ÊÀCY;h{B` @>œ“GQƒvÓUÁšýõ×_™3-ÁÇǧtéÒÅŠ›1c†²L°]ýüü`«ÓÞf‡HEË‚%ñ:Õƒ§C€8::Š,d èëë9rDá·‡¦ÅFœœI])€ÅN~°ãÆã•ãûƦM›0Ô»uë&¥3&ã… ¼¼¼¦NÚ½{w…I:yòäÕ«WÃü€è/s£½{÷V¹q ˆ/q.ØQ$Úµkƒ˜K?öÅ‹Vx|r9øüù38¾ˆÔ‚*?yò$ì"z,Ǿ™™Œ7æAQu°©øåààà(‚ (¶V­Z±ªbߦM)‡Óˆ9}„n566¶´´4h­­-ÌòE‹¹ºº£ß»w¯Ž?þ/ð?ZöíÛ=šSÔ¨QPÍ;wîÔ©˜ ˜ûæÍ›Ïž=+äæ_þ-̧¬0úîÝ»i½w(t‚}øð!Ȳ0MwãÆUfÈ`0¦ƒ¦.ˆ"!!A&€ê×øúúŠåää„>FFF…0Tžhòˆ#æÏŸ{#88X$ã=LášLr qdee 2ÚYcI…Ëmܸ‘ÒùÂ’ÁÍìß¿ßÇÇš4000ÿ ñ„ŠŠŠ‚\¥8;45Á®]»äÃ(Ÿ!¤1¢E ÐähʬDZ$Ο?¯òp–GŽ%‚Ö:^¾|  u6kÖ¬^½z,,,00"ÚöÞ½{É—/_>}ú4Ú¡úO:…v‰eåSSSa¹ Sá/^¼wïÞ ó*“’’Hˆå? ‡vÛ˜d;³3#""HÎC¥ª<&%{Š×8+8$''Ë$íÇýý÷ßô ìò\#66–¡M(Ç?þø-â×¢MÌæÍ›ã/Øw=(•±f|Šô»xè:•Ê* èÄÄÄ ãNOû°âÎÛ Ãó9Šhqiþüù*Ù% Îàà`Hü=z€ìSà9è?‘}ê™™™Ic¤^$Ñœf¸~ýúøñ㌌`_¹rE]_• ½{÷ne0ðȰäEœŽ;Fù÷ß?yòdþï*%%…2‡Àò9räÙ³gÕræà(úøŠ)y ”'vΜ9û¿{÷nÔ¨QË–-Óx2‚,:” ˜† ʔӥM ˆ\XüMKKƒóðáCˆbÐíõë×CÎxyy)Ë$ðæÍ0w Z„'7¿Ž;âlÒ“P2ÃÂ)ÁÃÁÁÁÁ¡:ý믿²¸uÚÒÑÑ‘r8ít×®][e-¼Ôm _»víKž§7´*),XÚ  ç|úH;‰0¹ÅZ”=ÇŒ£cžtàBûOO ½ÂÅ •ö´ð&Z ‘q§§j¿âaþl[_$<™ã«cìØ±øfÍš¥™]·gÏ''' Ýny2dˆ®®î?ü°víÚŠ‹‡(···ÇåºwïŽÜÜÜÐéÒ¥„}úýÞ•aóæÍèV£F üÕVpO¤¯¯K¸¸¸ÐÇ}ûöQ „ȾªV­šø®¢1hÐ r‡6²ìýâîy:t@7WWW>ûŠ,&NœˆßhÚ´iÚ:!¬Ç™3gÚØØ? õaÆ­Zµ v¬”Šêâýû÷III8ùŽ;À©a‚:æaöìÙT†cõêÕ`ô êþþþaaagΜIXݹsg…þKçãÆƒù-’À ‡¶üh1Pë#iÑ!„µ¨ðtù‰ºåà( À<.Â2Ξ=K‘wRVË!@ 5.OžÙHÖWõêÕO:%ýØ{÷î)[,}öìÄl½zõ¯T©D±Æëêoß¾¥¤ÊçÎã㓃ƒƒ£HáÚµk?ä y˜Ü䣮²Ð*ˆ¤:›˜˜|ݧèß¿?yÊ,_ŒyùnôŒ¾¾¾èS¾|yJ&­GÛý*3’/.¡E‹÷DTtF}ÌÎΦ›T–Œ‹`oo>}úô)„wB¤0­­-ˆG4P&¢¯èZÉ¡òë6ÚLåÈÈHwwwrà755e¡úÄ¥&&&J ,Õ$èd¤Ê‘#GôõõOŸ>-r`FFF«V­H(9;;„Ÿ|NNíÛ7o&ׂ®®® Þ'÷ÏçøFµ®Ax»¶@…~ ¤²'ä:kì*è·µµµVœî`-Œ9’-÷Á„èׯ_HHH>Ý¥ OÈ¿Q㬧ˆ}aPöëׯÉY´oß¾*¥ýk(‹ëׯݧ 4næû‘ÏÑ ³vÚ´i"×µkWÊÅM_mܸ‘üWÅMß[·nÑÈíÛ·©]©R¥ ÎZ¾råŠL^Z²X°`ÈQgΜ¡ŠBا{üø1Õ©Sj¦2ùÛÖ× š0Gဪ;©tbÑ.îß¿O¡ú`£`©`úvvvÞÞÞ˜q2õ,äù¸páº1CCC¼íÛ·ÓGÌJ¼ uñ‰vöìY*¥££ƒç*¸÷_¬X1–ÚâÆŽŽŽ¬r%Ó†LOOç›ãÛÍMŸ>]H! Í?^ yÛ(c-ôTrr²xÏC‡õìÙSXHW:Þ½{‡g!»ë?þ dé‹5ÃÛ·owíÚE5kõêÕ[³fͳgÏ´òZ¨Ô¯²ÊÂ_  f”v‰¥±š>>ž¸»»; 0þ|G&Nœh+À€¬ÿEß¾};wîܾ}ûV­Z5mÚ´Aƒþù' ×ßÿ½L™2ôd?ËoŸ}üøq̘1 –‘‘A Ä™¾%õ'Ìû­”—²òæääÐׯ__p¿ŽÌÆ7­?àÙEùôéÕÈ+œê3-[¶” ”®¡|ùò"¹Ë>þŒŸOzÐ"GácîܹøFŽùïobb"x=„CïÞ½-,, 0‘!XÐ.\U{ýú5îvÙ²eÏüðáÃΚ5«{÷îQQQ*û ãëCBBôõõ#""ĸ£¥úõëƒhô»Z¹r%qèèh&÷ ñƈò“¾‰‰ Þ§ÆÅõ88 00t—.]*lüðáØ=Æ<†w×®]{õê5sæLh¢àààË—/k‹ÀÒjžJqdee¥ráQ!®]»Ö¢E šžfff·o߆É “ J\ÝüŸ=š3g¥¾!!KKKœM»”fYJReŽÂå\jÔ¨‰}ü¥°©6mÚˆj ›Ÿ9w)ȇ¶½}ûªË–-ôqÉ’%èÖºukú˜’’B»ð,k·2Z³fMaÎÿåË—ÓθHLn>AßÌÿðÞ½{y'^®zܸqè3xðàB?´Ö!“g 77—=bccEŽ¥´l_Ë»’C%¨x%†\Ó¦MA«O:¥20§ðøñã'N¸»»3¦[·n°„'L˜°iÓ&ZM_g{ñâ…ŸŸßˆ#h.“?LË–-EJW3/ýöíÛ¥lÓCæ°Ô˜…ã”eaaA)Leâž?îééÉèùÐâ)ăz88ŠhIMa`ëW¯@çAê7lØaõgjjj–‡Nœ8ªjÍš5ÞÞÞ!!!çÏŸONN~òä‰8Û¥<´ Æ0Dºùúúârì°øðÖ­¹éêêN:õÀxHÜ';;<ýÌ™3°jþùçq§÷àÁaÐ/S¦Œ¸© pNZ!|øð!œEPä¨É¸*t")e†nDDD¿~ý` ³Ýßÿ½–õëׇ©Ü¬Y³Æÿõ×_ 6Ä?hÄWU«V¥Möß~û­T©RlI:~þùg(¬*UªÔ«W¯mÛ¶ÆÆÆVVV666Dª['D×®]Y~<èñ:uê ›‡‡µÐ¦$ cWÊLżþ>~üHýR4CPPÎ×ÅÌÚ_»v­ÈQ¡¡¡èSºtiͶÔ¹sçp­%JÈlÿÁ¦R2 ÿtE W®\ÁÌÎ>ÌÙ^½zaîˆ/‚&>}útûömŒ%Ê,¡0_}jjª³³³ .PÚÞ½{¯\¹òìÙ³ÒSØ5iÒ„–@Ùn¸2Ü¿ŸŠÝÿðð´µ^qOáKÀEsssÁÈ]G™‹lbb"n‰mçQ-¼È s:ñúõëiii/_¾„ÀÁÍãñ!åðâ|_ Ÿ’’2zôhfMaF{yyœöÇ îŒppppp@øC>ƒb3ã–lÂ5jÈô„Žðöö&Ë–P·nÝI“&mݺÕÝÝÝÉÉÉÎÎŽâa¡Sp ;(3oµ°° ŒÙ8-NŽëGFFÂ" øý÷ßqØê2íÂUe ?ǵ() Û…ga³Ê@µ¼e’çÄÄÄÐ:ÔnAü@0Ô)WÞÅ‹©…¶PūȽÿ¿)º9r¤ ‡¬ ºVhh¨°}ݺuhį)åéø¦aQƃ0­­­Ë”)#œ°µjÕ²µµõ÷÷/¸TujsPXá‚ØîºvíJY ¾fÍšù YΨ¿þú 'i-Þ –9IÑR¥Jå?sùñãÇ`OŸ>ÅA)¹nÞ¼yõêÕ¸¸8ØAxF\èÂ… TãôéÓgñ®ì´oß¾Å"à XCbwïÞÝÍÍxŽ"…wïÞÑüU¹–˜Ïõa.ãDëö"¶Á‰'&Nœ¨îÂ݇œÉ¥­D‰ø_þ ˜ø{÷îݳgOXXØåË—SSSaƒ=yò–D…:â<0–Ø>KÓ¦M!« ¨„(¯pÇÁÁÁQAEêçÍ›GiKZ~Ïk„ ÌüS }uëÖ…~„ 9tèP°u0S˜£¾¾¾Ç‡iz÷î]mñÚ#†–TIÏYÝù“'O’nw”-]º4z²úÔ‡Ú°a× äII–«Œ…¡…Pñä<,ž,wøðáè6zôèBET‰`êÔ©ÂFrÕS™¥bHðÉXôs1!!ó«cÇŽdi3Wv´ ß~E× ÊpE¹5p0 6DKµjÕ,XTªaÍò(„E'Õ©S‡Õ’VFØñ7===--íÒ¥K·o߯cvÃh…qñèáátæÌ÷/y¹çΑßÇü£¡”?22’Nîèèˆ{(Y²¤Ê ~ŽŽ–,2 t_)))ä ¯ÒÑ}Ë–-ÝòâiaaõÛjZ;99Yƒ¢ÚµkçÇO@!¢££™T§NdRÎ ‘ 9–””.Û ó”U™‡¹‚'²µµer888¸ÄïëׯÉÕ_JìG¡XüÏ?ÿœ‘‘A-´¯££#Ó“ò9 ’[½zõæÍ›ƒ—QðÚüùóåƒ× ÁU_Ê<£’ž3Û•hþ!CÄÏLÝ*W® j“••}ÊÊÐDEEÑkÔ ,—¸ºº’Öf-ä`°gÏ‘£(Ö¸\¹r…P††¼>@ dÚ4h Òc}Ú¶mËçã·X˜þþþ˜˜BÉY©9 •"Mj´—<[ ÈmÔ¨îD[S€Ü”9áã*ĦSSSXãxE7oÞ„õ VÞ Úž–¾mÛ6 ò­Ý·oh;z¢?Húƒ “aºãŸ§OŸ¾xñÿƒÂƒ¶ã/.”žžŽžMœI¾wï^<~DDDjj*ÝL‡p'zzzóãÑêPpÙB884…kÕ«WO­£0¹îÝ»‡Ù9-3yòd0}JÇ1fÌ77·ððp•ááàݸôªU«´ò ¯^½‚ˆ -]]]wwwµ $¶. dÖ¬Y,Q°¹¹¹”´ŸÚ ÆÆÆ¢&úCâgî1ÿüóÈ@\¨|´£GÒÆ!|Hs),^¼X‹Il ÒÒÒ0à]\\†J›û°^ =`ÞÈx°S4YÉ’%1Ýò¿:A„öURH 7:OëÖ­Ïœ9SÈ?ì@¡ÝÈÁÁÁÁQp÷î]Z7fÙãÍÌÌhßYžC†‹„SÑÂ8ï‘#G W¬Xáàà0dȺ þ`ý ˜2e ´§§çÁƒaÂp…A«Ý‡úüù39Î)£Ø;wÆ·sçÎ¥0›Ù.¼Èiñtô®`{ãƯfÏžo­¬¬ èÇ¢‡òõõ¥;PªT)w‘£hZ¸†t°T„„Ó§OK¹Ïºu뢛··7Ÿ•ß:rssƒƒƒAl©>#Ãï¿ÿnmm¹éSpWwww§Ë1Bë%­!¬èäòùå@ÛkÔ¨AY;hcÀ£[VVø;ùÊ•+´¡²ÿÉaÁ/`ð;v íÑÑÑÛ¶mUõ@Ï‹/‚ãã$8K¥VÈR@@ÅÂsÈt†VÈj>Œ9ŠH‘-\¸°€Î²œ””´gÏØ-”Búôé~~~ Þïß¿ïÒ¥ ®þ矊k1À@š9s¦0p ÓmêÔ©ê¾ !8Š-Ú½{÷W z"wAfpppppО/•bÿ’3EÔUá.0­ÐÊPKX3 T·¡¡¡ ÒnnnPsÇ777ïÔ©SÇŽñ×ÄÄ–ÿèÑ£ÿþûohð•+WR±{///` £qóæÍÎÎÎ`Ó0àé$úúúí5þ|Üj‹-.eОÛq£àî3fˆßÿŠ+”“F䥀ô¬Ì 9ì²e˪t3€eBÙæ a·”V6,--eì%Ê´.r,¥10`Ÿ•ßÀ]]]1Ř¿(ÛÇ×ÓÓ7nܪU«@<ãââXÐh>Y¡««+Ÿ¢1þùçºó~ß¾}m ËŸÖH¯_¿Ž©·~ýúCy€Ð;{ö,˜;Ì{<)æ,䥿c‹l©PƒRYâ R’ééé ; wÎ~É“'ó¡ËQ¤P¯^=ŒÌü§ ”Nó/]º3ƒ"Èrss©x¬ ΆÉΊKöêÕ æ Ûm‡5b``‚¬rÅàþýû”ƇÂ$aB¥…¸uëù×Éïnppppp|-dggC;uåøñãIÑ€€+cmš„ zêÑ£G)))  ¸1°xb÷nnn...ô?ñ:DFF¢¿Lé{÷î‘·[DD„Ì%¨ž[Ê€®d»ðâ÷FYnÜÝÝ•uÈÊÊ¢2×µŠhûý÷ßC2dZ&L˜ rTNN¥ð"ßÝU(Y²¤Œ‰B[-"ÇÒª™ÖI GQÀ«W¯Ž92eÊrÌPŒœFYXX€WºººÆÇÇk°Bã=5•¸rå îžµ|üøÑÑÑ‘&~§NX $RÑ)¹JYS ÷ä½’?~L1Dµkצ4#/šbêê#ŽåË—ãjÖ¬©n¦˜+l”ˆ9¤½{÷ÎÏÏÏÈȈž‹bÕ§OŸcFþ Ÿ?Æ”„r$6 ;M[« III¼R<‘øGácõêÕÎÕ«W'Kºƒ¶œÚ·o/¢×ĺ‹†Š»Õ××6‚“oðŽ;¨ÅÙÙYІХŒßâà+VT¸˜ Èg ¥½øÊ•+Ë{Ü¿Ÿ-æ[ZZ¢Û´iÓ ú³­y™8D3ÄDŽ…C©ä r|g uaq V¡I!J•*Õ¸qcðý)S¦@jíß¿?!!á«lajSjú˜••Õ³gOP_”—¤i}OÆ“ùöíÛõë×'Z‘œœ\ ŒƒC3FLΞ=[®\9Z¼råJnnîWßåàÇŒ3¤¬)hã™Äò°°0ªòã?Ο?_|—ÿíÛ·¾¾¾Ba8kÖ¬E‹QÖ 3ÐæZY9|òä ¬……Å… $òîÝ»   *é +‚BXµ_ޝŽÀÀ@r cÛi§¦f͚ʡ*o:tøVžqòäÉTy©ÔRB-ú/eJ–ÓñÒįHëêçÅJ‰y[·nÍZLMMѳAØ-##£J•*Ì·yܸq• ]k ª,&ÓÞ¶m[á"’BwŸžžŸžß7†.L\™’’;“&OØœ,ÃÓ§OÁÖ1õ\]]§L™‚¯@«K•*%Â÷uttš4ibiiÙ¥K—ñãÇoÛ¶ FidddRRÒ£Gò“h‚’íwîÜŸÜK*UªtþüùB~0­!”Èc!;;†úÕ«W©ìÝöíÛýüüp{·nÝ:tèЩS§ÀÒÒÒè@ZvûóÏ?ñV®\I«‚xW:DQ%J”ø*™¸88”*O>#káƒÏêׯ/ÞíÍ›7ÄÐkÔ¨Aé1%âÆS§Ne, 4¸xñbþï?''ÇÙÙ¹[·n ‰ŽŽž4i’‘‘ÑêÕ«ž8q‚4ˆÈ^³p¯J" !¬[`»’íM»i/_¾$OTV†ÒöìÙSü$øßzyyá+›““ƒÆ„<°-3™MëW®\IKKÃ!`ú쫨¨(’¿üò Î/ô^X¹r%åëæC”£è€¡ø¾ú`–Q]ëׯ+ì°wï^ÚJ([¶ì¾}ûòy9‡üר}ÿþ=¬hdñJ¾Ø-vvv°dp”ÂØ1cÆà®Ð‡LŽ"Ê£Î*­§¦¦’¥7oÞ<‘£`F¢O™2e¤_Æ-Ìòúõë«UpY‹€áMDØÖÖ–|ù–,YB_‘û®®®øbøÓ§O‰°luòzóÒ¥Kô?Ë~#Lñ]§NPƒ>}úLžÇ×…™™™ŒÒ„­Ò°aÃ~ýúaFïÝ»¾Ð*¹Sz™ÕiÌ2è_VCƒåz… sB³4¼&&&Ðï"!ŒþCR¡3^&d”xg¼gZö¼yó&™ETÀ]OOŒêœœ*85`Àñ>|HšK˜/%!!ŠÕÕÕÕÞÞ¾OŸ>úúúíÛ·‡ŽÀ_ØÀøÇ¢V­Z¸„ÊñPfºó®]»R ,mÊ¥2üŸ~—/_.Ó‹Jæ1ìÖH Á,Xð%¯â@ffæåË—=ºsçÎ+Và 4ÈÀÀ AƒTN*KùÀŒ§¤a,±$¼a‰•¿ð;:99•-[–%Ù×b˜ðû÷ï)9[8"€ ±bÅŠ"l/ò§ñ\»ß1@oiìI/±>Û»woV¯Zµj+W®$Ò*ðtà„ ò“7O|)€>ÉTc:++ëÚµk ÕwïÞŠŠ¢{éÆÿ7nôòò%ß³gOjjª‡‡¤„¿¿?‰Êǃ¹ãÁ1À\p yà„¸„0,vËXCP’0ç-ðâ®øå(:€²ÆD˜?>ˆ<è¼BwH†:uêXZZ:::BÛÆÅű’7Ú­1²„_òVË©Rd‰%` iñZäá&£FU"::ºGx/^¼ïIaz˜õe)NN6CIQµðúõkrm…î£[[[òS¥d§âÇ’r@pÛõë×:t§²3€o‚Æ~ÅÂ÷0¶i÷œ9ÁvÅGXâ;†×¯_§]~a´ì—¼Br:u³Ëh7r’ŸD ;ÌfmÝ›J=z”¯˜Ü ½H‰™µ88¾ 0AîܹƒÙ„ ë¥cǎʲe–-[ߢ4]xx¸J G ÈÿÈ‘#ô166– ª *(‹ÔÓ ?~¤eLéÙ! !Üð¼*×Kaö¸¸¸¨µBxÒ<Ž"*%V¾|yò[-%¯l‰‚šì@˜£ê^wúôé?ýôó׊ֻvíìä±cÇ6iÒ¤M›6")”¾téÒÌ' ̓P‹_…BÅ…YÜnÓ3K¼Â2»0ENž<)ŸÝnË–-´A?„§»M›6¡g³fÍX‹½½=Z¬­­Õ}”T‡²&²cù/a@)så³ôÓ† ¸£/X†x½EŽï”ì‚°¨¢k×®­S§Kp×½{wðe•^ý´¾gee%%àT Ž;†§Ø¸q#NvOÛë!!!ÏŸ?ÇÇgÏž}ÉÛ‘—žúO3äääܸqC­}4 ¨×ÑÑ!îP­Z5|dÕí98¾Ü¿Ìü˜>+÷ ŒéC‰C)«•BýõWœçòåË_ò’ÁÒc£FRSSµûD,÷¾”ƒ´´´ñãÇ8PÊ"@dd¤™™™£££YȦ÷áààààøŠÕ‚X^´h}¤²M@BB‚Êc¡7©3%}R ´c®’G«ÔÝAAA³gÏîÒ¥ e¥<~¦¦¦6l9Ú³Pú”””ò Œ9•,ä?ÿüS¸Ë¯l›žqä‘#G¢?X†Ìyðê`À¶?}ú4³½?~üÝʪM¯—Éd%®ñïÝ»G-Ò^ªT)à ¡ëÁè…ióýýý¥¤Ï•x‡JVN'r,¨íSàEñ û½‚Bc–.]ªñÈ‰ÔØØXXåyóæÍâñ¤»wïþé§Ÿ(?«h¯ñ8'hݤâÝ»w>9¾?À8uꔇ‡Ç¤I“Œ+Uª¤°Ô$€² ´SŠ˜ÄÄDR¸˜§ä“ aòäÉ8í Aƒ0©ó¿(íççGçWÖ×…Œ211¡äœâ¸{÷.nlìØ±ùô¢BŸ<GQ@÷îÝ… ÉÁI—I‰Ë¦|)„ˆˆ ®NÅ‘e6pÜœ“ö(sû€Ð©2¿+Cffæ®]»¨ h&5~þü™¢Ñe(§<(Ð{øðáøßÕÕö€Â5Xï#FŒ ]]ݵkײí¿'OžÀ†‡ÆOMM byl`çí-V¬ØŽ;ØBíÚµÕ¢E}úôa-”ËZ&½VV–ôÜbBÀÎÎŽ)rPz^ª¥Õ¯_?™vJ1¢!r,øúñ9û½‚"5¤qLC b¦´ú‰¡lëæ}‹-Ô­hÿñË/¿àÑ7nl``лwï1cÆŒ=ºmÛ¶ìþK–,‰–Ë—/ÇÄĬ_¿R FX’ÿcBAÚÈ׿ðññ!ïŠ>{ö,ŸÿÐ:3y0búÔªU‹ÍSSSyw>tÃWæææÔ´iSùo¢àà`0ntëß¿¿»»{BB‚ZÞþX;ÊJ¾æææ:;;wîÜYJ*Œœœ¨o ŠÈ'”•ùãàààà(d$''“™ÇÄ;QK‰õèiM€2±‡……ipäW&^¾Ì”‚ãðwàÀ[·nU˽ ZìÈ‘#l÷œvŸ©zõ—]ÖK”(!^ß Œ˜ˆ­H´)”µ··7+± ÕÉv ñUDDÄéÓ§oݺyïÞ=¶EnåÊ•c©nao£E___âcâ@™ZrPñhñÏLˆOŸ>U©RŒ`Ô¨Q#€}{€=®²/² *ŠÚÀ(SkXßââŋ你õ|E!´^§ÝÓb:ìÞ½›‚÷Y-i´ˆ¸ÁdggCÂÄÆÆ=z vøüùó§Njkk;`ÀKKK“–-[BZÖ¬Y³l4ØF‡ì¥ckå¡Y³f8'H:Nnmm=bĈɓ'ƒ PR///Lç'N`"¤§§ KÑ}üøñÀ¬¨P·nݵk×* •Å£…††âYÈg+±2û‰Ã† £¤âø+eûƒã;f M æ~ëhäÈ‘äà‡™ ìO÷êÕ«‡¿•*URYDæÑ£G˜È'N¤}|µ´0)J+l„2õôô444ÄiU®|øð!d´˜ “Rô³Z<_ TÄ™¥€ß$#Vå±—.]¢€tZÐÖlµöÍ›7ÅŠ›5k–²KÀ¾Å%Š/Þ½{wpj…Ùç”!11qåÊ•Ðw´…“àIa$ïÚµ‹¨=Ë šrb‹ŸpÛ¶mèöçŸ*‹½Å “»8ù«Sšk³gÏ`NÇÇǧ¤¤>|Xèù†ÓÒ6nÜX¸^A;Ô*K U6Õ’;uê[Ð ïba¶yètfσA9rDÝ* N– qm›k×®IaX2õø'Ož$¾/Rä7Iöƒø*Ç· Ú)‘ÔV­gœ;wò„E””/_~öìÙOÕçBX4ÿ€Tqqq©^½:Ë–qôèQ‰‰ò®_¿>gÎáá={ödD·Êæ8Ï›ÇñÁ«W¯hÌËÄ…]¹r¥M›64MX‰ÛÜÜ\ÊCþ3ꦡÇWk™š2,[¶Œ>bšƒžÃÂU—R2#<<ÝÝݵ[_ƒòŠW´áàààà(hÀȤZ0ÁÁÁÔBqR i2Û© ѧOt¶´´lÞ¼y~ØV‹-ä«“’’h¼\¹r ·´ñ4vìXܰx–ׯ_ƒ¨Nœ8±F¤mõôôf̘N¯¨¾:³AÓ^›†+„¾¾>ºÍ;Wþ+hg;;;ÚÛ‚¢wrrî‚ó†……=|øðÖ­[¸fÛ ³ä™ššÊ¨øI“&¡}êÔ©Ò_fß¾}qž—µÐkœ7ož°%Ä£02/=–9mÛ¶&ÖccIðÚeêñ}ÉÛq(S¦ŒJú@ùy´ÍQk“HwrrrÁ]%==}æÌ™Ìç„Ê=HçÂE`߇,.lòäÉš½7òˆpuu•þ³B‰¿f6 ^)µ(«ß÷øñcggg–M«X±bÖÖÖ111ꎨ+W®ØØØ°ÒZ`I }ðà4ÌXÁËË íõë×¹DNNÎ/¿ü‚n.\àSø»MFñ •ÚÅŋɈÆ-$ †1lÔ¢¶v”O—{鈈ˆhÚ´)]¥K—.÷îÝ£’ Ð”囃ãûiC‘ŠS§N%ÝMúÄöÑ£G}W?~$ç™””)ýsssa´À>‘ßIOOO_¾|9f÷„ Äí%eÀ!žžžd­Ñ«¸yó&9_ ¾¾¾”|ÂaR˜XÇŽU †Hú…ràC5PE$aÐX‰U]Ξ=Káù×®]«V­ìjGGÇ€€°Bç<¬Y³Á4³²²–,YÂJ̃>ŠTtðàÁÇŽ“Rršh¸ƒƒ£½ä¥Z*~ …šnÚ´‰é5'''¢™xvvv2‹ç¸IÐ|œÄáÌ™3 Ïì+}Ê’÷Ûo¿±XxyÐÞ™º‡Â"<<§Ÿ[¾®.Û.¿uëÖ—¼ø;;;朌ŽòÉ ÄñîÝ;¼æªG ÊðtÇÇDzeËÊ8P!` îP†ääd:U!ø=r>•¥ƒ(L`nzxx@°-9˜Ó˜⫎Ú ò;w2gx*YräÈm¹Üã<¡¡¡>TÙóåË—ì%T¨PR—ˆóŽo0®²¶;´$4ØnáÜåèƒXPÖáÆƒ¶µµ•áÚGÓwqqQ75.444dâ¨Y³fP_e©“ƒƒƒƒCýû÷‡p¶¶¶fbŸÄõÞ½{U ã–r£1>KEÒUny‹Ê±fÍš]^©J´ŒŰÈÏ–¥HHH /zñldÊÖvOìÛÆÆF>Åô)HkFFFRRRPPÐÏ-''‡ÂT•eÉcýå—_FŒÁZÀý5ðñY¦Ä€Âôþ”ŽÌÇÇGä@r×_»v­Ðªwww§< T(cFÝR>”6¿cÇŽÌ*hß¾=¹øÊœŠ~ŽbÅŠ‰§ªS§ºað‰üýF2­J :ÔÜÜ|êÔ©;vìÀÀP+›“qåÊ{{{ætJI)/^\@nð)K—.eá0$Tò éÀŒ^³fAbŽ#GŽü¿ÿ‹ÆkËÁñ­€Òõ@ìHì?{öì®]»bª®Zµ*66VÝà5‰Ḁ̀ļ å 3+++™œ©©©hÄíÉo"HD„0ˆþÿûŸ‰‰ ´9Ï[ËÁÁÁQtpïÞ= cùInC—©<öÑ£GæÉ’ÉÉ‹G L_o)77WzYçW¯^_‹ä´QæKÏø8­QXXXˆ¸wï^¢ÿl±:::ZD†……ž™;˜~‹-è$lUAFFF:::Âlr´ Ò—@ƒ Âà#¬ÅÁÁü DŽ¢Ä€Ýºu“i÷î¿¿¿0sxË–-E2Þ‹¼ÿž={²}Àĉ…`-T®\íAAA*W–Èçò÷OV<ìÎ;0#œœðscžZZZâŒÆÄÄÄÂ,K‡)н{wŸBk›...Ê’f«‹›7oŽ7ŽÑCœÎ;WcYy$''câ€ÑcæJ)cÊ@Þ¿,00~üx>V9¾Wû¢ºÉcïß¿üøñY³füB^]áÔ;tè´¶Ì"ùÇW­Z‘%1Í‘ ®_¿neeÅÄ]É’%¡¬ 4§‡f˜1cQ3ú˜’’B¢³Êc©Øzƒ „FõÇé ÊJ£Œ5Jè¥Ö@ž¥  "GAÓ=·ÐªW¯^Ù®Aa .]è·ß~;qâ„£üüü„Ž„ qÅŠê>)¹4Ô­[—µœ>}-¥J•Ù÷Œ‹‹£-Bek,2¡÷µjÕrvvVw# )) ?-’T«VMáo4fÌ‘3„††Ò2”fi8Š8ÈÛDaUµçÏŸGDD`šŒ;¦¬™™Ù„ <==4ðÞÑOŸ>/†Ý.\žjذ!&¬zÍÎ)3­êÔ©£°„f€ ïׯ߰aÃ4 "¸yó&ùêØÚÚ ©½ç.Žo¥ñ™å‚{÷î™››SJµ.óÀÇLJ* «'ôðð( yD98888`.‚]BPïÙ³‡Z(9[±bÅTn‶SžóÝ»wË|EÌ·ÐÍÙÙÙ ‰'Ož…]=}útXžìÙ³§±±±Ì^pnn.Ý$+}èÐ!|ĉû”R”<*V¬Ø¾}ûÁƒÏ™3gëÖ­ ì·oß–‡°~i« 溲•ó·oßÖ¬YSOOOÆoôèÑ8PKàÉ“'Â`ù/ç|‘Êà äŒ7#rò;wîȇÞ+¬+J &¿ÿ~•êñºJ•*…n D|F xñ˜6b1ÂfÍš³³k×®ãÆÃd„ RkKZÀ¾…ÝN™™“ª¾¾þªU«$nQö‰fÍš ƒèCBB´åãúâÅ ww÷:899ÉG If(Ý^VV– »Û2eÊhËWƒ£HBϨÜO>qöìÙ^½zM˜0*˜Š}HÉ<™™™éëë+“ƒbÙ¼¼¼Ä… 144T7A=ÔúÔ©SÉ8¤HCˆ£3f 6Œj÷ƒëçÎS˜S A9î*W®LÛ[ êDÁOUK~ÚµjÕ’ß'mÒ¤ ¾úÿì}ut×÷ý·ŸB)ZÜ w(P @nÁCâÁ-@‘à)Á‚•à.ÁÝ=PÜ‚&@Ñà ¿½²WïšßÌ{óæYhÓ»ÿÈÊ›7wæÎ¼{Ï9ûÞ#0°Ñg˜è°ÞwìØ1kÖ,(šÆWŒE:u:v쫊rÓ¦M'Ož„E {ûéÓ§oß¾=wî܆ ðÕ/¿üâI7rFÁY§ªVÿîl˜(Q"Ü«Zµj¹rå%Úµøú믳gÏîêêÚ¶m[¼®ºuëò8‡Î¾6ãæð€ªãÌlß®];^‡2X¾uëÖŸÝfø¿Åë3ã=‹œx&÷XÍaò*úf°B}½zõpØœœÑñMš4Á;vìXÚFFFÒo¿aÆ`Ùà¡¥‡r^Š§Û·oãÊôÀ?ü€I„ž˜¼/ÓVdÍš•'óÍ7žžžÚÓ6sw‡ÌYµj•ý>-¿ìçÝ»w!<[µj%BÆÙë'q9r`xïÙ³Çä·/^¼°Ö9–ɧOŸ0=<<$H°oß>s§ 0ÖK`Ìž=[ù-L 4çòGLš4ÉÛÛÛªôôa†©R¥‚ôPæÆ ƒP-Y²¤¨ÍÁX!4 ù‡;jJHHHÄW@³0qœ°™éö Ym17ò«W¯˜<ÊdÙ5XÑøjüøñv·nÝ:xðà¢E‹FM]¡B…*Uª€oŽ5jÉ’%G5™ýÉ“'[·n…ê©U«VΜ9•a°Jˆ lpòG}*úöí[^ /J„q c~ÿþý .ÄÛ´iS±bEXéJ×\%ºwïNëv¾öí½ÿmÁA´w BsX6¼L&ÞW)`6]ý­pž“9sfƒ›†Ì‰W¶lYBï{ôèóATÇT¨‡Áƒs`ÿÈIÿЧOü¸]»vµ_Ü]½zuÙ²e~~~˜à¹>>>+W®´Ùa^/^„\-W®œRø$K– ²qÞ¼yÌ›qåÊ<—¢O“&Í!C”)5ìó`àv0ËU•7uæïõë×7nܨ_È’Î9üñ¥_Ë–-Å¢ÿrÄJÄ3pÍY»ÒNDDD` @O7ÎÚèõ/^àâyóæU­ø9s¦ ^`ðàʪ•mLUÖ!2W*zߠ€óã?й\¾|yˆGý€&X>3g΄MÂZ½bsFŽ6qŒM›6±PëAP8ƒ;[l ÎŽ3Á@MŠ}ftQ…EOž<š¢F­[·îÝ»7ŒÞ€¿1 ݺukÚ´)´x±««+þñòò‚¡¼mÛ6hLý]6ØçK—.…›?~å2²ˆ+X° ®Ù¢E ooož œÓ ›è¯¯¡^y5#%ÞðfÀ#`  ÿx:.€++q³ŒÝŠ+”­ðZ÷xüR>| Ë.^¼¸ ¿õ‰'TÁòø‡?÷É“'ÍµŠŽŽ¦ñ`m î°°0üvbÍ?GŽø•Ÿ>}ªÓdóæÍ\óW¹óÑ{¡L™2:mïÞ½ËÔZÿ‰>tÒ>Û ³óçÏÏž=ÕÍÍ ñ¿3òï=zôhñâÅÍš5cVmaú~÷ÝwBLåË—oÖ¬YŽ ¢¿ÿ>¦dÅI÷9¶8×¼yó:vìX½zuww÷.]º 'Ú ¾çÏŸ5hÐ’®Â-Š£yóæÂQg×®]rÐJÄ'pûcË–-:ç`:tÈÇÇæþ⃄zçθøÈ‘#ùñíÛ·}úôùúë¯S§N=jÔ(s©2£¢¢8ãÌe¿Z7˜ò“S[øÚAã·jÕêÔ©SV½¢W¯^ >1 ݺuk777LÉ¥K—bªê\ç@Rså¡H‘"ª*e ü¢®½óöKH|q.\Øbž¥ª¥›:$ £o,š4PñéÓ§‡|ÀÄ)òÕW_uîÜY?-ê-ÒÁË—/'Nœ(Êh¦NÆ€ þK·nÝ¢‹&ÀÍ9l$$$$â Ñ_ÅââÅ‹@¹3o-,(//¯+W®Ð ÉQñDFÀäê"àšÙà•[¸IINަ>ÒÍèr#þêÖÒùÐÐÐŽ; /ܨZµj‹-2¨GÀ(Y¢Ndw:t(ޏººê7l×®ogUZ¼Ì++öÊïÞ½ëííÍJ‚gΜI’$I¹rå`œs=„öØ=,jå½ð좖· ¯nùòåªZr‘‘‘TÁW¯^5×êâÅ‹\L`°†Í`è½2ŸX‰%Tµ³§L™‚ã...ª¶xÊŠ„&Ag†¤I“êTî“ø7BÔÍ4g››t Mš4‰ŽŽ¶çî·nÝš?>ˆ0èð/¿üb[m8“Ýc„‹m夕Sb¤B… °®ÍųÆzçηmÛf1g ¹oß¾nnnª&gùûÔ©Sµ%RƒâŽrèJÄ”*U CzåÊ•öˆÌPÌŽ† Bë©öâ1q aaZÀ0˜uÿ×_µ-ÙñªU«èyHF`Û(L©|ùò‰D:ÂÑŽåvîÜ)GŽ„„„DÜàÏ?ÿ¤ÏóöíÛy„dFܺèc¢ª¿º›3gNœ¶yófÕq°é§±å¿‹ððð°X€š-\¸päÈ‘ôÌ_·n” èÞàÁƒÛ¶m Ý¡L>Ÿ%K–!C†èo²kÁ,OmÚ´áÇOŸ>ýðÃÊí{s`Q?ý@o“8pà+èA}Ãöfè«R}/[¶ üºC‡ ®gÔ¿ÉÄöÄ;gÀ»²ä ‹ˆá ë4Ì•+—²¢P…ÞgÊ” ÄäÉ“'Ÿc÷M®!ìÞ½›ôtEå>1¤%â`ˆr´\¿~ݪ†“&MBCXž³ÆécoÏž=½{÷ÆäíÒ¥ $›µë{**Tg[sHËæÍ›7hÐÀ\<{LLÌš5kpB“&MÖ¯_¯ŸÿJÌMˆYPýy–ÒÁJ¼}ûÖÝÝ®2Ù…DüÃô¢¡Ú`Ò`VV­ZLÿÞ½{<Îâq˜°¯Ó¯_?ƒ¥j”€(P €`ôAAAFÄ‚‘‘‘¢ÆeÊ”)ñ JB777Ÿ>}º9qƒQ£FÑkÞ’Ü“5é­eOŒdç^³¸§“$I’T±ø?Çú¬<44ÔwôçÏŸ3û´¨,³wï^nß뇳1@À}­½) â…?~¼L™2Ë—/×:©Ò¼bÅŠ:n*å 6Øö»W¨PÍ'Nœ(ŽŒ=G*W®¬ÓÊ\¦z{À}F10’%K¼žËAË–-SQ*.ª˜«D0y—œàñ L ÁZ œ°O:e$ÇÁƒ3eÊ”4iRÇn]¹reÒ¤I5kÖĤ€©l›‹‡ëðáíjõòåËàà`XÎ 0ç Òíêê:yòd#¥ê¹…W½zu???#5è»u놞‹p!Þ¼yS§NüdÒW"~€z|Ü×|ýú5l °ã²eËBº»»[U§µE‹æÖÖ̉,È+j[ÈCHÛ™bbbÀâé-IÇ{mŒR—.]𭯯¯9q€÷ïß3ëìC­ã‹ÅÅ[n(C/X4'L˜`§ãjäþ™3g¦÷>lBð»âÅ‹—,Y²|ùòõë×ïС´ÞÂ… íLX͈ò9rˆ‹Ð»¾eË–ú ™>.I’$6ÄòõN™2ö¿¹7ŒþÀæ ý7w)fºÓzÀĘ1c˜ªK9wî·Èu~Э[·ÒCö¸~À´À³Ð_‚1ü_xS4jÔÇûöí«sµÅ‹ãŒ9Ç㔉ڞ>}Š`—ÂL…1ܧOŸ•+WêÄûDFF.\øÛo¿µy5L÷î݃• F\¯^=Pc‹.îJpI­aÆÏ¿vힺZµjÛæ\NŸ>ݪU+L–mÛ¶‘“GóçÏwuu8q¢ñèZ.BªÊHHÄoù㤠hX»víòññ)W®œñDúÜÀäµx&浟Ÿñ·gÏžþù§m]Ý·o½Œ€bÅŠ>|Øäi“'OÆ uëÖ•#GBBB"BšÆxÌçÏŸ“M·nÝZ¿!Ô ÌK‹wUyôèѰ¿qýúuz݃?Òßäv˧®^½ÚIÏ^¦Lå*7Ìcnà ÖiCµ¨âmNk3C¬ÅÈ\è_æÝÕ MåN™Í[Òè•»È-ðùï¬t‹-Òy:9pÃÔáøøñãš5k”¡÷øQT¬ Ž(P@ç:Z¬®ãð ño+wh‹`äœ? 3¢víÚõë×÷÷÷ Uw{òäIéÒ¥$H`Cæ+ƒ¸uë¨1¾qãŸÉ²,æ)ÅD€Ù߸qã¦M›êL@МӦMƒûïÞ½ ; ´6 €å>Ñ92%â7Ξ=K¯rœÞ­KÞpíÎb"}.€[tCZºtiæÌ™Eé HKÛúvÿþ}///fãIš4i@@€NÂÏ%K–˜Ì“#!!!!á 0¤zðàÁüèííM—*‹9Ÿ×­[Ç:&Îs°d¦å ØÐÖéíÛ·Oœ8±yóæß~ûm„ ªuiÐ=>©Éço† ô³RÏš5‹šQ™nû÷ïç*Š¹í³‹/Ž;–ÿ_»v g¶mÛÖÜÕ˜Þæ•ðOŸ>eÉ’WÀO)2+HNCúˆ1ã$à·kÒ¤ ‡°°0åWœ\}Ò¯>Æ@Hýtÿ:0'†Å2”/_¾„a ¢Ú¼yó*UªÀÅÿH˜z/^¼ÀØ€ìÕ%¾8 …è£b.ß]tt4¨7¬qs[l˜ÑëׯÇ9C† 1˜´o ï6¿mÙøg̘ž»»»Ë‘)_&Û¡C*".ÆAÀ1ëkÔ¨ÁDú*YŸ(Q"tI3Ò"22R$±Ìš5«ÍIÿèxÏí–ÀÝ»wõ›lÛ¶Í`e% ;Aš™0aB gm*ˆŠ+\èÙ³§óºW»vmÜâ×_Õ~ãü?þعsç’%K¦N ŽÙ¾}{h®Ê•+WªT ý÷ðð€ìÓ§=x=ؽ*î•©fÜÜÜÄVÃqý^1©`¦L™lx¢iÓ¦¡-n¤ý Ý6l¾Rî/GDD( µøðA™ýžµ¼õ+Óéƒu:vì¨É’%Ó ž9s&Î)^¼x QîŒ=ZuœI‰ñ>uÚþòË/8§Zµjr¦Ç'ôêÕ ?k=¬%ÎË–-óõõ­_¿>Ý£GòåË—2eJ‡¤Ñ³0ΙóÔ©S&O˜8q"æ»õÞµkèù€ôsƒ¼yófòäɘ¸¬=uèä~œD<¦ ´k·1ç<ýèDÜb\âÊ•+Õ«WoÞ¼ù–-[xP”1;³páBæ®I AÿþýÍ­ZÄÉ“'iõyóæ5˜¥ͶʤÖ¢aÆÊh ¸Önj±}ûv.85Ë1sIi9ÝçØõsŸQ£FA½nذáðáÃPyÆs¿À}p£îÝ»;üÊL¨®¤®Ìh1·<\±bÅ”¡Ä«V­Z¡Büõöö1bT!ÞÒ;wTqô3fThÛ²e‹‹‹ËîÝ»õoºsçNØW®\Q‘Ö¡C‡Úé¯ZjAýŸÿÞÄÏ!ƒNmP œK&jöìÙµ¥½Ñ7¾LýÄæ 4ɺã⨀n:„˜ ö‰c€ '5kÖ4x>ã°aà 2úϱNV˜ìxRÛªTkñáÇ'NLŸ>‘;rdJÄDDD4mÚ”^yß~ûíÀU~€tº3Ž)R.\Œ !mBCC¡Ê¸y¤’ ð¾¾¾|„üùó› í±ˆãÇ—(Q‚OëX4T”’!  aÆ,”É\Á6§é“°ˆ/^0ù‰È6ÏJô©S§¶Ø–q莭`nŽr¸UáñãÇL#pìØ1 ã²¶2z] úu‹/V‡5¢¦a°¹È4ÂbµëàààÚµk«\…ѪY³f¼Ì{{v¹û©Ì¨ðòåK*báÈ¡ÅÁƒ`Û.€UèÔ©îÕ®];Õñ¶mÛª’h±víZU Ä¿‹-2ša00<<<’$IrýúukÛbðïÝ»ĶGµjÕªö7úöík1”É$ïÆs}ÿý÷c/^lÔ¨‘CvïÞ½;zôèÊ•+³.aOÉQ ‰/(èþýûÓ6Àx††%-UáãÇçÎÃ?pàÀ®]»Ö¯_¿jÕªyóæMš4 Í¡§êÖ­[¶lÙܹsSšD„ óäɲ?`À€¥K—†‡‡ÛÌô¹Æ.Ö®/_¾ÌBB@ûöím‹¦úô)Äý9éxo\ÑÃ6€p GXàÞb ›Á½¡ìÙ³ÓóÂ… T¢è›·ý*qo ŠÒªšÎ1uêT&~\ÞõP²ú ™zß¶ ÔK—.1ÜÛ ÇÄ]Ð1°Z•Çìãǵ`çÛ0éè’¢ŸC}K:µ‘Ú:öƒž$3fT½·Õ«W[äì/_¾¤væÌ9ëã¸VãÀ´wîÜå [ÔàÄ„©<þüúõë'Mš”b3yòäE‹-]º4H}… XfذaÆ}iDÚ ÆûGFFvèÐÁËËËþD( í›6m‚ ¤µ/<þü™3g†Ä#Sâ_ hØY³f¥OŸž£ºL™2GUµkÕŽô-“€)(ï'NŒnXŒ˜={6¤bþüùÍ­<Я)<<\9 g&Ÿ²ô|›6mèÿùçŸê7dá9ã™ìį¿þªuÿý÷ß¡ÔæÏŸ6çëëÛ²eK;<™{“&Mzôè1räÈ™3g®_¿^[ÿᦙ ÐG:wî¬ßîò§I“Fÿ´?FEEtk¿¹Laq»Ÿ5ïTYò€¹sçÒ¿·hÑ¢°4øžY©*]ºtJÀlÀ Å:œ…f€¶«,Ü¿² œÆÎáá@3Lâ b÷îÝøAøáåÁÕ«W׈dÔСCCBB`Š[hJ€ª+]˜>}ú4oÞ¼T©RaµmÛÖx:h%"""ÆŽK‚ë@RÁÖzö¶oß'ôë×Ïæ—sÿþ}oooˆtLO;ß3æ5ãqèÊÕ©S' ‰ ºvíJxh±Ž;šK­ƒ3aK€Å/^¼øÁƒ˜V˜¶üñÎÖX¬Y³*æs¬‡ŒÝWž>}ºÿþ   ô­T©R&CõsäÈQ¿~}áÕIª,µct¼10·,ziUsµjÕtŠÉ2GDnJHHHü¾I/”]]]õ^¿~äàÁƒ_×5 lnÑ¢EÛ¶mLJ©i<áÌû÷ï™ÐºXhO>þáÇu¾|ù’û×=zôP}û¼K—.uëÖ­ Xì`½zõZºt©êÌaÃ†á  :7Z±b…›››Š@ó2… àáááðjì¯^½¢Ù tÃ`ÙYýQáââ‚s¦L™âì‘;ŠªÐcƒœ=wîÜ8mÉ’%rúÇìܹ“n¢æìá°°°U«VÁà­ OOσ¼ß¸qÃ\=¬ÓÌ™3+wîÞ½ëîîÎ5%‡ø‘^¼xqøðáLRš0aÂzõê)[19¿q%•”€Uéa¿3fYïÞ½¹ŠÖù¦5ø—¢eË–‰'¦>Ŕן×111 ¤àò{öìY¾|9¸6Œ|˜˜¹˜°@`<`öÁ Á9Îè3ºqþüy¨°~ýú¡Ï"þ]ÄüСCÖ^T¹råx…~ø!44ÔxÛ?ÒÓ¯uëÖú6˜äõΫ“Þ4™RÝb¶ÒvíÚ¡ÿD`` îÊì¨ ÂÚçž»HîÊšYà}ú)³† ÂÅíª>ÞÛ… Œ$šfaAsf9È{óæÍUþo04hÀßm”tš5”YE>=?˜Î ¢ýÚµkU_1ÛÀ¢E‹tš÷ìÙç´hÑBNÿxæÇïn¼‰–ìcЪÈ>NƒeŽ+‹LÎ;vìH›6-ŒÒiÓ¦9|Þ>}ºoß¾UªTQªÛ²e‹ÖÁ"""j×®§³ÇpÅŠÌ7 {2*V">aÆ ‚ g̘±}ûöÐÉ8ÔЙ3g<¸iÓ&X7n„!ƒ˜t þø¸nÝ:H§•+W^¹råÖ­[,f§Å½{÷6oÞè•ýÝwßél޼{÷Ž)yõ£-$þ˜={6~J xð€ñhŽ*¬f7V¤ÓÄܸA;nÜ8\­H‘"âÈСCMfcSÝ$H ¼÷mÝéU™ènÞ¼ -yäÈÕÉÛ¶mK‘"r—À¶ BW./8p€‰‚uRãvèÐÁä6ºÃs‚¿ª0½÷ïß“ ·:ÍëÖ­‹s $åÀ¿ ›ø9 ’%K¦=!22µ=^7nÜ Ñ;|øp -&©€_-:u ܵk—ñÓVþ9FrAÌš5«V­Zöoâ ,•/^oÞ¼ñãÇC(9r„ €ïÞ½ƒÂ…òõƤ^¿~½ ÕçupõêUVôàò» Ž÷Â$«R¥ H½A÷ûsçÎAS[õÂ%$$$$ ‚Õ™AÁ˜Ñ„—…Û¼½½õ2$?wîܬͪ°]Ü‘ÛÄ„¾õêÕ«ÁÍa—jù˜{–,Yð˜^^^­ZµÂ¥7n,¾ez‹9Ò™X/yòäö?ZñâÅ•ÝW®\©²ùAêa-ð©ñ»ÄÁ¸oß¾e=eP·ã3dÈ COÜÜÜ,î0:æÒôEEE‘³ƒê4/R¤Î¥!¥Á¿9,“²G`£˜ø8tèPk¯:<<v)Ø=xõêÕþùçéÓ§cÀÏSgOŸ>=tèFšnûV0ý°°0}ÿ"f€ mòÛY³fµmÛÖþ4•;vì`f LtÒÎ# ‰ @®mó¾ƒRŒÙ—#G%Á‡Q¬X1__ß 6(k[hý» –}ö yvïÞ "÷î](¯³gÏâcLL È8¾²ÓyæÕ«WŽ÷~~~6Ë z1H`m “ëÚõêÕ£WÔ)S[ÕHBBBB¨]»¶²x:y.Œ:U©t¢££S¥J…3ûí7g÷ððáÃíÛ·§ Ïtw[\O€¢L‘"EÖ¬Y•‘×S§N…ÂÍŸ??½pS¦L©ô'ÇîàoÛ¶MçÊ8©öÚ´icÿ2›ÁöíÛÍ)}¥Á>}zƒI{fÃV2&QÚþøñãæZMž<9nä?}ú”)S&Ü ”ê«%Jà¸~É98§~ýúRü+pãÆòåËs:¸¸¸‡Ƴ´hÑBÇnݺ…±ÆÝ°aC\¶Y³f°H÷íÛ§¬)ï|pww7Hêé[…n ÉÖ£Gò¾6àêիܧ³%($Wq-®Z;§}ÿý÷ú¾úöcÙ²eB9.\xÁ‚°ñ? {#Íñ\`| ï°É?džâÂpmܸ1íóE‹qÓY,€CiªŽ˜ÄĉÙ%m¼Iõwûöíǯ\¹rÚ´iZ œÅò ÁMšë‚Ô·nÝ:_¾|øç§Ÿ~ŠK?|€ï\{È!Œs—/_ÖæÒw¸WÛ¥KÕqz•xxxè´Å›·˜PâX†Ìk‘8qâÀÀ@¥Y[£F !+Š-:|øpGùs7í—_~©W¯¨·¯¯/沓òãÁì7™ôžé£aE;#§ÖÉ“')[OOOýíE ‰ø®B7hÐÀQ_µ),8¾ÎDÃ4Çð¾cÇŽ 6;vìþýûPRG÷îÝëŸ7oÞÂ… ñíÞ½{ 2kµb§ã+ÌZôsÃ]p$§Ês’ —cOBBBÂQèÖ­›Ò·sÔ¨Qûú1ѯ_¿NŸ>=NÝsvƒ‚‚Ø¥lÙ²1ñìèÑ£­*^ëÖ­ $J”hÅŠ¹rå*^¼¸0Œñ઼j¤}ûöÕ¿&Wã•{g¬Z»gϨ˱cÇöèÑЬbÅŠ®®®¸‹——×ÀAêCCCµ ìôÐóïß¿ËþL,¦Lw\0.Ç 42½8”5|çÌ™£^‡¹Ò°aCÐ~ÔæÒwðãr¡IuüøñãôñÐÙiýøñcêÔ©q $)þ±xðà—’¸´Å"Ѫ\\\”Y­0ƒz÷î}ðàAG… aþÂØ†¥ äæææããƒIm¿¼E@p ÖÈZ¢US§N^‚Èæ0[ ‰5¸UѬY3g\üƘYPŽ"Iàø%K–„ Ç×É烯V¯^ ò¾yóæõë×ïÛ·ïĉ ÀŠŠ‚¶Õßµóæ¿¿?ýë0ÓÑ û«sŽ9W2dˆþi7oÞôðð€XÖö ‰žrìIHHH8PÜùÞËd7·ú §NÊ%_Ç&r1‰åË—³–yôÕ«W¡J¬* B;¼lÙ²´öE–{hZ³/^äQÈ^éù¦4©ª^Àˆ#jÕª….á\Ë–-çγèn'@ OQºß+ÓÓmܸ‘Ý ŠËÑR @e%DÒ(öäÊ•+‚#p¯º~ýúx̥߼ysgwïéÓ§üíį)ºÄŽúöKúúúJ±ðÏÄÑ£GéÖQ€Y¦ïNƒ‰BÇé'RŠOì”*UJ,¹Û¼ ¨øÖ­[ëìøs›BؤH„^æ:ƒmø%$$$$´?~<÷³¸“E ¬[·N§Õ‡¸æºÊƒÌ@® 096lÈ%¼"ÖL•*UÔÉb&ÃÉ“'«ŽÓE¿sçÎ:m‘‘3gN)þ€}ȵ¯\¹rYUEýéÓ§‹/nܸqÒ¤I…ýœ}úð#ëFé dîž§H‘"Î&/X°wtuuåGÐpV…ƒEjÏe¡š™a^ñõõÅ‘:uêè7dMöĉ[ëÒ† ­wéÒ%°](e±ë Næ‚ *I½48zô¨ò:·nÝbù׸ϡװaC-­ ÅÂ… ͵ھ}{±bÅÄÖC§Nœ”H/é7mÚ¤úŠôpìØ±:ÍÍm÷K|h¯£éoÞ¼qˆÀdè=ó„½^½z|Rooo“Ôo›%ìÚµkÓåôéÓrLJÄc´k×NUËÕ$pNÛ¹sgœuLp|¦?Òáø0 ømªT©À¯…œhÙ²%¬ “'O6ŒV–»»;÷ˆ7ê¬+®\¹²J•*%'ß¶ÅÅFƒ–[¨ÜŸzøð!·o lõySáÂ…qŒá8ëêܹsqǪU«ª”Kþüùí1nAp±ìÜTÐM: qw~7n¬ú „=$$štĈPŽmÚ´©[·®2ÌßÍÍ­I“&;vìß¿@@€ Ÿ:H}ÆŒ©”•»Ú€â'NðŸ 6ð‡Ó¯Ïî(0~‘"E”wʯß¶G©R¥øtxù>>>Žu~V.×hs/°.¡~mݰ0®<ÄM€‰„06¸”,Y²Ý»w;ûv˜¹ä°DöìÙ1J1nã 5„A0J) ­ÂÕ«W¹ˆF¤=¼€IHè" våÊjЏq ’øR«5∠Λ;wî¸/Š  ÖÂäÉ“ëÔ©Ã%}ĉçÍ›—IH Ä`f<~üØàeŸ}bZƒõë×KñMRŸ*UªcÇŽÅå­1­@fa6ÓB&Ò¤IãååáØDú6#S»°f[¶lab´iÓj—JbbbY…•°ŸµvíZ;Q%$þ€9„¡>a‹gîØ±Ã…×aKذhËçÔ©S'N¬]»vòäÉ…°»7îxÿáÇààà5j˜3 73dȵxçΟþfFxx¸ø6,, ‚ÂÕÕ±*ýÝöíÛ%Jd12NBBBBÂîÝ»ÇMg†|ÂX¥k13—X{÷î—½%SSf­_V®TÃXM:5þ.\¸¤ÕÌF;cÖ† &®É´±:¹p úœã^Ѓ±0^ÌNµDä§Ò„ÅóªJà]¿~]¬Æÿõ×_̦ý+ë9$\³gÏVÌó£õ~7 txÕªU|“ÌÓëïïï¨Ìä:éï˜ÃI§yûöíqNÇŽ¥”øR€8bÐÕ,„I·hÑ¢FѱG$ÒoÖ¬ÙŠ+›Hß8¸†–%K«Z}úôiÔ¨Qœ%J”PÖÝö9e;óuw Ï±<µU0$$â¨FEa}€ÌfÊ”É'pêeË–1Ô†‡=™êcbbÀåúé'\ªL™2[íÚµ æ(¹þæ„pÒ¤I!7 @¶ùìÙ³iÓ¦Á\ìÛ·/·òãæÍ›&,i³Óøþ¾„„„„„9°ž 5?2fÓä´›7of>ƒ»ã ôº/T¨ò`ýúõ•j¶A¼ƒ ÏÕcýÂзnÝÒ¹ÚW±€îK‹$±H ˜âY³fÍ‘#GX@»¸¸T¨PÁÃá „¹à>hà .ðhUU?q„4F‚³ „áý+²œUt˜ìž%HââëKKI»™Ò³gOoÑ¢…NÛ5kÖÐÙáÊ$ 2Pgº¨ÒJ|)0‘>F¸*‘~­ZµæÌ™—žKÀ¹sçXÄx“/^0-Ó‰¨¦D‡)?¬wm]*nbŽ9RN‰ø ¦xUÖÇÑÓ¹Ùp£G3†),òäÉ3iÒ¤‰'VªT :Ëõ}ûömNd¥;½IÀ–€L€h0âlÊ”)¸lÆŒ¯^½Ú¯_¿5j¬X±ÂZç%Px<`íÚµÃÃÃEñb9ê$$$$ìÄëׯi ŠËT©Rác¾|ùô2±ž~pg`ïÞ½tS7i²‚ðž:u ö?ü@ÛµdÉ’sçÎgÄÁ`S —qÜmÖ¬Y,­Ïæ˜XÏyð÷÷×çPˆ0ìµZûéÓ§ .dù?¥cƒ3Àr Jµ¾nÝ:: X»é@?@‘¤+kÖ¬Pývz;sªfÍšªãÛ·o§k·N¸ttt4׋›6M &OžÌp PiÕºäÀ²eË6oÞŒ)ðEb½™H¿GÚDúè¶cé›Cdd$ïkð (êµå;CCCÅÔ«S§ŽÉÄø\0Ä—ƒS"~Y?¬ ¥J•*\¸°µŒ¼Ú7rssô7$$ìúËæØ´%JàÊ¸Ž¹¢¢¢`Â5oÞ\™ Ï">~üØ´iÓºuëV¯^}¶¡ch…׋ŽÑÄâ»¶T±„„„„„µ˜9s&$jæÌ™éE/w‹–«ÂÁÞv`-fƒ`Š?Ð1‹Vw@@ã Ò¥Kgîq ¡xô”8ÈÒ÷¤pYÜ uL?ü3gÎìlûÖ­[*T(W®\ø¿wïÞС­cQ«V-¬R¥ŠK,`l(P [¶l‰'O”(KÚ~8°ÎE‹õïßì\Xµ> ªòæXà2+¯ðvàbÝ•m‹†ÆÝ‹ôx-øhs²2ô{šªˆ¿wïÞ1|øàÁƒ:Í«V­ŠsF-eEãĉ\T)Ý0λwïž3gN­oLŽ9ªU«Ö¥K—‰'®_¿d?ÎÒX‰Dú˜ÂÊ^+V 6¹¾×“À潌8M)êUu©®_¿îîîÎKÚ›+Ù‰WÊRwq/ö%$âôc_±b…Áó¡¤pþ‘#GŒœ e4bÄ( ÿýï-[¶TF©+»’ÍÇÇ'22ÒÚGSF—üüü´_½yórWÖwJÔâêÕ«:thܸ±Uõò :4h€ÇQú0ƒîüùó娓°Ó"¥-*h ·¹ÁÔô’ì´iÓ&îû|ùòeî7¤ùò壽êéé©Í\7cÆ ~+â wèB¯¿ãþn°Žó«W¯ š;uêT¾|yü]µj•6÷öíÛø ¦µÅêQøÉ"""6nÜ8f̘fÍš,XPDâ+‘&MF%´ùíAÓ¦M•‰:uêààÀÅ‘¨¨(«,¼7ôaî;‹¡æV葲uëVÕWõë×·Xþ{Ò¤I8§\¹rR\Ä%ðë“¿{xx`ÌoÛ¶Bb[D¾L™2$ª&š;wîzõêa.^¼3+¶õ!FÆWºtiæ“$𠘇²'fÖ¸ÙgŽ¡qA§ÜâÅ‹+÷æ>|øÈ‹@’ÀÞÖYd©Ž$I’8ãA$$þQ(R¤ˆUISAT15ºuëfñÌ+VÐÉìXÄÓéÒ'Ãâ²*€vîÒ¼ys•4€R±bE±]n?îÞ½;Ô½~v;œfò¥½~ýÚßß¿V­ZªG†XæúíÅ‹娓°[¶laIfçV¸rƒÌ$ÀÎhZ‘4VÂõÔà~´ˆmÚlÙ²íÝ»Wù-“§AÉŠ#Æ ÑJ•*é_¶nݺÌô"êÎÞÞmÍš5AºñOXXØÃ‡ѽªU«8pÀd“çÏŸC§ƒÒÂä®V­SÒ©0aB|OOOèÍÐÐP±"AW|ƒ–ƒÍøí·ß´)²Y¶ @â3qU¨PÁªDý`xQ¢ˆ6‰µÑî-Z´@[¼@Õq–3Ðwž¼téI¢ñ:AöD˜!œQ‚Ñc×®]{åÊ•”WOž ,@sNwÐø©R¥Jœ8ñ¤I“l+ÈK@ úøø0¶]‰›Kîܤ¸{÷®··w›6m`öXu;Ø'®®®:}æò{ÅŠµ«î0 ca«¼zõÊd[ˆ_{L) ü‘v½ª渟Ÿ¨±Í××Y¸€ìêÑ£‡2Åå×_™ó[ß6ǵgÏž­<aˆÙÇ´¢E‹ rõêUVïb½k=3gάÊ)!_Á51ã+Ϙ×Pdßÿ}½zõ”Ç###¡ˆ¡éŠ+6eÊ\Ðæ°Zè»VÒSÞ†;°”*W®|òäIç ªT© •·CøAöµ{ >„WžÉÐB±ð(!!!!až}z­Ï?S™,€Ÿ GŽd1Jv¯õ¸ÖÁ¥K—ðª¹/©¿õøða¦òV…Q‹žoÞ¼YçFÌ)1xð`):œ X¹Y³fÅÜÑÙ'úüw5Š (·~ˆˆˆˆ9sæÀ¸þêDþüùaî=zÔá)ž0’M&Ò÷óóÓO¤ßºukeQÎ7n-Z” #0­) ÷ïßÏúÏØ–H“ qiÓ¦•£Tâ¿s¡[ú˜:u*ZEEE}Ž]îÆ|E¡ÝôóæÍ`®@³ÔªU sl×Ú|°1}út‹Þh*lÚ´©råÊ:uy`hµlÙÒÇÇÇÜŠ4©R,ãÙq²««+Ä‘vIpÚ´i²ÜŒ„„„„øðá]@gÍšE†Å}jUJsD•[cV¥,súõë‡ntèÐAKA–ëׯ¯­g§Âû÷ïIÛµk'rw»oß¾úm™›'O•S=‹¡kƒv ,î ¥f§S½ èÔ©“ªØœó@~Ñ£GåA¼LÆG›lÒ¿F‚9r„•¹tn[å7xþüyOOO"s[ÿ?~d\³ÖßYºvíªs‹™3gr BJzöì©ûpÒ‚Õï¿ÿŽÉ Ë“v>‘9sæ>}úœ9sÆáw„I kÜÍÍMY¿’‰ô·nݪÝAëܹ3NÀTú›”ƒ|øpîܹuëÖ…¹.¦|Á‚!Lnß¾íðÛÁŠ^µjX¹2 ¦yHHˆØ,cAÀîÝ»ƒ³s) þü—.]b~<¾(Œ[\ÇH2À#GŽ\½zÕäW\$Ô‹”ˆ°­ìÎçØÒ-hÕ¤I“¤I“B8X›É‚ š7o^£FqãÆa"ÛóÌøªUyZܼyw\¾|¹ÉoaÆL›6­J•*ª2ÁZ¼yóR 掄ëãÛ·oñ±Q£F#Â{2ŠÎræ’¨HHHHHÁO?ý¤ÜÆ¥;4,@ý­²{á5 µï‹ÄZÒ§Öaa`ý{öì1w‹>ƒƒ‹#&L0²!ËLtÐJnnn½zõš?þ©S§tÂítë­[·öíÛ½?|øð:Ô«WÏÕÕµB,<<<´yªma1  CðäÉ.Œ(ÃÑgz2cä˜lU¤H|;uêT岌XAÂ0`€Eï 11·õÏ"D P5Ebr ýü ¬6gÎ)@¾,V¯^M‡pýœQÎëW¯–,Y‚'¶Ôÿ÷¿ÿnoÛ¶Í%˜a*cú`$gÈA™H¿Zµj0Ú™ÇëÖ­Î$$ô,2’鳬sçÎíÚµ3W „Ô/*!?ðèÑ#NÌ&kÛ²NGÞ¼yéo³º?tèL¬Š+â/¦° Ùöˆ7vìXýÓÀ¸«W¯n®Øë™3g`äÌœ9Sg“r½…Œª\¹2„ÒãÇÅW.\€Çõƒƒƒ•[`ú'N¤švj4¢„„„Dü·Pa‘‚üâãÉ“'©¿Œ4‡‡‘É¢É@²dÉ ´ÁéâòD'ÅpX§PF"'žlþ믿ª¦~ §OŸ>1¬hèY›KSäøiæÏŸß§OŸ5j€¹ƒÂ·jÕjذaà§`÷ ÏúÅø>ÿ^7¿KÙ²eµï°mÛ¶8øóÏ?›lœù¥J•Ò® ‰1–µk×gÇ$‚¾ Z»v-ô, L•MM·{÷îùóçƒ7kÖ ê²^½zC‡ݹs§ÅœðçÏŸG«ªU«úøøÀZ°˜+ƒ>f°[L~{ïÞ=ôÜœïý¾}û CÌÅ:={ö ´Æd›6mð¼Êž„……Ë»ºº«ž–Ìĉ…߬‚ &ÈLø6æ­bn»@°sÓÜvªvÏœçb_ÕI{U*°º“ÈmЭ`µª’Ð4¿•Yý}}}¤uqqác:*oíÓ§O×­[׳gÏJ•*AY÷ë×µiömƦM›7£ ûãJãLœ/üèÑ£&[U¬Xß>Üä·>|€ýÀâ@ºtéÀîõ9ˆŠ­\¹RÔcé"Ø`ªÓ.\¸Àâ:(:™÷$â L`X¬X±`ß0'Mš$\â“%KÖ·o_gG*ýþûï-Z´X´hQîܹE’½¥K—Zlèááa$=>%‰*{†„D|4õ…ê8{:ujԨѵkWpóððph(;ïõæÍ(ÇqãÆA1Õ¬YÌלK¼À™3g`k;CÂè , oRóîÞ½ÍMÎý'OžtéÒÜ\»ˆ%ß¶m[úÕ+)ytt4ŽT©R µIŠÀè!m2fÌ(½µ«ôZ0É’ØÀmÒ¤ 8UtšÂ8uUí«Úà5mÆŽ‹{AÃZ<š«B… Bƒ¬]»–ýµÈaßrPç:Pa\iÓ¦==÷îˆ!^¸<ŒêñãÇŸ:uʆÐ9#8tèswÇÍè˜Á½´ a®è”Ÿ={6Ct†Üû÷ïa3ðâÌq#Áø¾9¬‘A¸¾ùæm[~»lÙ2ëÐÓ£W¯^R’|)05â°aÃþ±=Ä`[¼x±XJJ’$ÉÈ‘#aº;év—/_nÕªEйsg#~S~+V4žŸò¶^½zrJü@¾”)SªŽCS;5­Ó¦M›¼½½AœÁ|õ«ìÑoÇœ“¼Hý§òBD+\ÙÓÓÓ¤‘+Ü—Uÿý÷ß}}}ñÕ„ T+ Ü ‡=y¢¥êènÇ%q®:â£óä¡„„„ݬgG ÌtaÕªUSžÆló¥J•RÕ"×÷UÅžQš4iüýýÇîwïÞÍÝ[#véòåËEý5:fCˈoCCCqoF_×@ñÑÌå‹ÖÇãÇ-ZÔ¤I˜ÓC‡Ý¿dý §ëxœ±víÚ‘\hG”É*ŠŸcw9%Jd$t#t^xñeÏž†„ñ% ÑY³f1×™6§b÷îÝqIç áLˆ$…Éf(}?Ž;¦sÚ«W¯jÕªåîîŽéÖ»wï©S§®Y³£+**Êá¢Í᯿þZ±bý`lÙ²á£cïþöí[XÚ‚Ñ\qzöì™O³fͬJôݲeK\È!rJüpäÈ’Ð/Õ˜[·nmß¾=̳   Ü ÁĹ®¨;=ª_¿>Ô¨öüèèh(nˆ“ æ£GVµ‡uý[¹rez“)gqAXM©R¥2÷5îk'!!!!¡UH×,Y²ÐslðàÁ”·`ÊÓ@çɳ«¼ŽU^Ód÷6d”µ˜îì¤~=;-ZìÝ»­Í­,³ÎògÐMúW‹¤n²ªŸ>œ1cFõêÕkÖ¬ í|ëÖ­¸üÅY °ßWÐ V­Z…ÛeÍšUiKà%˜ ¢'`iàÛž={¹ÅË—/a-0‹— 0䌧b~‰¾}ûªŽÃˆâ‚ÎB¨͵ ;ÑÄÕ<“?7~mÛ¶)‡ú‹/Ο?ƒsçÎ>|¸···‡‡GÍXtéÒeÚ´inN-\ˆ~Λ7O¬DU¬XñÊ•+¹2 i&‹`p=ä-z°0?ž $¼×Š+ä ”ø/€eè­U÷N"øÐªµk×nÚ´©*’]tM,\¸°8Bß{e5ycÇŽ)cG„……A~Ö«Wš×änÈ£G`ø  ÛI2z ‡[˜ô4ž0a?²»¶ìù `÷¥K—¶ªT4½¦EÒæ´iÓ:#–й^ù8ñüù󈈈2ŽØ«ÂqV£>|ø°Ns‘Bÿ—_~1x»ùóç{ÄÿÄeFA%¢££Ùmç¥ðÒÞ‘,CµXÄTùæ~,®€¯ß|§wÇ0­\ĈÍЧ²vXI“&µ80pŽÉý gƒ>^^^æÆÞ¸qãÜÜÜ:tè°cDZéwýúõÍ›7c@¶oß¾zõê0›G޹oß>g8ˆ¢cýúõcŽú$I’LŸ>ÝÎû¥K—2SDêÔ©g̘A ¶dÉ} f$?žI|øð?þ¼„ÿlÛ¶Í¢kÄHÆ ¡â›7oÞµk×!C†Œ?>8˜ŒÐGëÖ­Ûõ7Ž9ö7®^½z#7oÞ4n\¹r¥oß¾•+Wž6mšOHV‘cìÌ»wï0÷›5k¦Ý÷‡œÇ#X¬j„¶x4HK\Ê\€,+\Mèå~øÁ*Ÿ: ƒØ°a­JJïß~û‚×\®Ôϱ¹Ê;uê$j4»¸¸\ÎU²{&®Ïh6³DZîܹû0m‹2ܬY³¨}ô-mooo&"ÐO E ÞªU+(_ØÛN-„§ÄÇa!h“ñPÌ‹˜9sæ¢E‹VªT Z¾M›6>>>ÇŸ2eÊ‚ `{àg=sæ ,‡ä¯£žçÌ™£:Î ~E‹Õi{êÔ)œ“(Q"Yð+޶Î!d|‡ Æ6ìj®eà42q~egøçüøq̘1Üû†$Øw±bÅR§N-^ã´iÓìl¸N‚ T»ÿùòåÃñ ˜lµk×.¦ø³¸>c*÷’òåË8pÀä™ýúõà 5R[ù:iÌåü—p6V®\i.nȈ¸À°¯P¡è°q‚ï$üþûïœ øóçÏ7ÞpûöíÜ©ïØ±#y:h>½q´;éÏŸ?ïÚµ+xUùñL‚™XôSJJHÄ',\¸PÇÁ,ŽKiÿþý`5jÔhÑ¢ìa;Á€¨Zµ*ºÊ$câM›6Y{;º6kÖÌÃÃf†Ž´„Îõññ+êEŠ‘Œ^BBB"@7rQî§Ÿ~bmV‹~•L½’$Iƒy ض%Ù=¨¥ñn¼zõJYÃÔÚje>|à#€»M7lØPt ìµþä cL ,GÖŠ+êߎŽå‰'v’Âzúô©’¿ã­–,Y²L™2žžž †’½qㆠ;nÜ\Ì…*€ÀÂ$ -Fé½ATË dÓõë×7gK0dÃHémܼySµ¥Êâ ìÙ³_¥H‘BëRX´hQ|5kÖ,[0ç¿ÅD‹Ž…ŸŸŸýU&ÏŸ?O‚ŸïСCöìbÛ(î¦1…£‘pûˆˆÖŠjÞ¼¹8ŸÃuìØ±ÚówîÜ©ïµb\UEÖHHÄc@íbÌ»¹¹ýÓ:vïÞ½iÓ¦Ak÷éÓG¹ÕÛ ÖBåÊ•!ß Ö!ÙhðXå=…i‹—ÒÏñ =«LÁT¬X1ƒùm$$$$$ìÄǹ  zøY±)Ù±cG‹m馮àÀª&,[¬³øð96½9C¤ ÖX”p »Ü¾}»c/ûe þ”)S8 ýüütN?~<=L®]»&¢Ã× ìÇ‹/Ìå™”ˆ¯`2ù|ùòÁ̈ãê´Á¾}û¸ø¬Zdd$L” *À,±8Á/\¸Ð²eKá ‡V6TÌ”°ïÞ½£ß;“ŽzõŠeÈ@â,¶)Æ™M›6Õ9çøñã0,)çI¬*ÐLvÏ]c¦»>»þü9ëÈkƒ£•¤]R±{š¦J×¾}{:µê÷é@Hõ_ÂŒ3`™ãFbð·nÝzùòeb ‚áÇ3¥€òàªU«Ò¦MK m.b1Ðm ±ÿ¾fôÐSùÀÓƒ½C‡æ,X'LŸ>Ý/áØ±cbˆbð{yyݸqƒuŠ+¦:ùãÇ|9øát®É‹&ýŸ%œ$ÇhO:|˜%!˜¯¬eË–ÚBB°v”•#t¸Xùò奄‰\¿~ktq”IEðãàéX²£Ñ¤+ }KÊ”)£Ì@Çð}V5‰9sæÈ¡.ñ_CLL tzçÎ ,¨´"hM5hÐ`Ê”)§NúÇÖq:t¨¹l$ãÇwuu0a‚‘:¼gΜÛ"ÜŠ‘(!!!!aÅŠƒ46lØçØ-†+ ¸›C—.]´ÕÊô/’°‰QãÍAÕaN“n3ñµ*·*ô,× vïÞmðšd÷¼ Ò éҥ܅××ˬ ¥öèÑ£Ë/þàÁƒ+Vøùù¹»»Ó"mÚ´8¾mÛ6&¦ÃãtêÔIDé 0TÁbýwƒ+H¸)Øúýû÷¹œÂG°sô&„p˜w,¶nÝÊå $“ùXÕ+[¶l:×aÍDÐL‹Á,ÁñãÇÅHÖ˜/†q`` CnjJŸ®,~*'>8&…ÊõeàÀ8^¯^=g¿ùž={âFPrJü7½k×.h4ˆF` $MšñNpö ›UàÂ5 *íWF\Ξ=+¢Ø˜ÖÈ„„„„„óÀ¼ßÐDL¬4oÞ<Šh‹Ü l Ë6–˜ØxkPHí–¨þ­¡ŒR¤HÁ+,XìþÎ;d©}úô±ª?{÷î奔;Ñà¼cZ†ÿ)RäŸùûâÅ.]º´W¯^Õ«WÏ“'Hð”S"oÞ¼LdÇ<æ<èü~øða‡ô ƃ²3Ü"ÁÇþýû›l{ãÇÄ ýúõsÒKÃ-Ö¯_ß”ƒé¢:áéÓ§L tþüyëäÊ• ç,[¶LÊ™8À¦M›ð¶óçÏoñLü xôNÿ믿 ÓHðaÀ[•_Ú8Þ¾}+2ã)Ë”p¥T U¸paŸ3gŽñ[¼{÷N¿ §IÐËű¡1ÿR¼zõ Ò ›ë@íÚµ‹¥è»ŒŒ4ÞüÑ£GJv_¨P!F^Úµ6VÝÅÅ…)§Äô„!úyÏX ,\¸ð‹ÿ”·nÝ‚ŽîÙ³§››eòäÉMRxo¿ý6sæÌPî5kÖdFÀËËË\½û˜˜^ÐñËôO$š ø›;wnž súôéùóçãÑ*V¬(~qôß©ï›>ÿ)S¦Ôúl 'øjüøñ:WèÞ½»,êg E™2e,žùæÍ›råÊaü˜ó ±ŸàƒkC:Y•&ÔàçÒ¥¨(wðàAò…Ë—/«Ä£µ¹ìöìÙãêêºmÛ6k{•.]:ÜèÀrJH¨”fXXX`` §§§È,²úÀbÙrçθï³ÄX+>,*YGæÔ©Sò‡–ø'àÚµkdj'Ož&"0qâDý†oß¾åÖ­~8ƒìž›PÌÞ5Glãì~À€ôܺ&gΜ 6„]½víÚëׯë¯Q¼~ýš/¡sçÎâà„ XŸEÿîÜÓÿæ›oâ8ë]DDÄâÅ‹{÷îíááQ @ Luhøç+V¬uëÖ ¢û÷ï'QÁÁÛããã5—…ž¸wï¯f¤,ŽA0õ½öíÛפIQ‡«FE‹Õ>šH·‹÷àÔ÷ŒŸ5Y²d¸‘ÖÅÄ Ç+Uª¤Ó|Ë–-8o>"¾%8ãââbPnäÉ“–­“¢9ð‹C²uíÚÕá»rÓ§OgÔ<+xÒÆÖ®±ÞDöìÙ\óÉ“'~mÚ´ÑûÀTÞþQQQœŒ2ÞDBB_&œ?*ÏËËëûï¿W)5-8Žoõ}À…èèhÞ×xe(AeŠ$ü¯_°å¸9pàÀ   L™2qTéäi³gÏ&Á·¿àÝ¡¡¡t®f<šÏÿkïÌãzÊþ?þKY³gûƒ{¢•ì2¶¬£3FÙ ©1–ijd&„dßà m$%•d‰,…–ñ{=¼ßû¸ûù|nŸÒ§2ó~þá‘sÏ=÷Üsï9Ÿóºç¼ßo{û|2{úôéÏ?ÿ¬jyºR¥JÝ»wŸ:uêÆ/_¾,Yž3g} ÏK!'‘èîî.sQ´YÒJ8u™o/üñ­Â7oÞ¼råÊò«ðeË–Ås„ºÁ,}õêÕW®\¡ >”D½¿zõ*„³°Õ<Ïi9ŠBÎjÕªâÝ%%%IV“““%Z¾|ùòvvvx‚¨ÆÛ·oém),+ih&³páBIzDD}aqÏ(ø øûï¿y´)Qºþã'G 5kÖlÖ¬YIse™§: ¡#GŽŒŽŽ¦î£asîܹêìÁØëç燱EÞ0cúÚÀ÷/Ó/~80¹•HH(âÇ+=‘vxêêêjbã%æáø£ï´Ô©þòåKõKHJJÂïc¹r娃U«Vy{{O›6 xÁ—¾üÌ %̘1)Pdò"çðÕ«WÿL ß´iÓ *ÈHxBUžT<¦èBÊ£G0ó§/3¯_¿>sæŒØqADD„°5³q¥> P š]òYcþüù8eüøñ…ûÄ,X€b---%éBt`¥¡vnݺEß^4í}OŠ9–C!­­­eN‡°"<àht ÉÂñ¾}ûzöì‰7CJzzºÒ³þüóO<ÜÑ£GY±×…€ŒsoÅ d<«ÊEFF†««ë°aÃä­ï“““1“wrrR AcõäÉ“©wÌûÃ0ŠÆµ>Ù‘ 2DFÑ“c=!t‘†L–†a˜B¢œôèÑã£(v´ªØò úZÑ)J÷îÝqhúôéš«©ûæÍ›S5 1 U53WJbb"Ô½°vß­[7Áo?”ÚÁƒýõW+++òøT¹reaVŸ]§N<×a!6©Åòl‡¨¨¨Í›7O:ÕØØÚÝD5_˜@ñzKÒÑ#ðì Ü¡…1ŒE`ùòå8qÁ‚_ÐÍ¢{RïPêD°yWúÕ #!šâÈ‘#2åcÁø`ff¦Ê)Þù &л½víZ~ý¦ÐÑœk} £"…H¯eÊ”¢ågÁ0 S’‰‰‰¡mØçÏŸÇGŽIÃ8…0óõõ¼Ža` !³â„CÊ/YYY˜S°0 §§‡i¹*oíªT•XÝIâÚ“¥ªX«R´,ܾü÷ðyóæQ™IIIB"­ÂãºX /Y…¿}ûöÇO¦¬´†‰Mûî„Ýw¹¹¹xpâÏæááኲáiÒ¹øuþûï¿Q  9ãââÈ…;066VúøÐ8ݺuC# Û’qELï!š(V‚¼(¨!ž,J>zô¨ä¹þVµÙž¢fC¯iú=tppPz!5Íçi_Çç{˜däIOO§×[UXwïÞÑBXß¾}ÑI1>yMœ8ýQ沄ƒŽIŸ=•FQ¤è¥JmÞïܹ³páBy×—<èׯÔºªVHÇEƒ‡·c˜" p]ë[XXHÌßȲcÇŽâEâé Ã0 SbHÁбýã§ë´!¿mÛ¶BˆÄùóç îË0ïIJJʰaÔFôÖ¨º÷ööÆ•jR³fM77·|mBKHHÀ/”àhêóÞÿs}†{ÿâÖhkk+_&IQ]]Ý.]ºÔ­[WØö¯\¢J•*-Z´èÝ»÷Œ3víÚ¥jõB#,, ·Œ¼qãžBZZÚÝ»w‘‚©x||¼°7SëÁ»àëׯÏ;GÍ‚èàà`Ü5‚ÆÇd€¾öC‡zzz*n9¾wïÞ¨Q£lllÄî ###{õêµlÙ2Ì(„@M8£­#?ÿü³$ÍE”žE»Ð°…hu¨”cÇŽ‘Ã@E™CæóŠ^õij¡C‡ò°£ih¯Ñ‰'ò̇N1hРàû÷˜ ;‡‡‡)7 …Ž‘D©ù€}-@±þþþèw111ª2 »Ñ¯ÔÄüÁoÃ1ŸïZŸœÃ?~üãÿ¶G~ýõ×â°D¼ÁŒaæK!**Š„ãŠà–˜˜HòêU–QOL¼_½zEÿù…®Ã¹‚ÅÝu=cE¹×¯_Cx¢¶´[€xûö­««kŸ>}„‰9UhÖ¬™&.y2oÒ¤‰$]0±öì™Ò>hjUöÅ…^3Z—Wôîåå•g¥Eùúõë«ò}ýúuá[.å,®šCAë‘ý;hР~°ò%—îܹ3vìX±ËY±=Åïkܸ±¼-ZGVê¯K—.“'O^·nݹsçÔ·zCËCÂÓRøýû÷“““‘MM1Ô =ð£,,“[Ã0 SZ¤Ñ>88øãÿ6 ùÅè>___Z¬Ÿ9sfñÞÂÛ·o!çk×®M5oذ!Ä>­V«ITT”±±1Î-W®œxK?¹üå—_äçÿ´zÛ­[7LãQkkkü† Vü’¯åø%Å/&´3´¹ÒO¨ÀÍ›7ß¼yÝþö111T1œõàÁ!óÇi)ÿã'§Öxš´jÿîÝ;œ+¬k§¦¦BÝPÚ¶m&¹èÝ»w €Š þ p94#ýÚµk7B|ûí·(jëÖ­z¦B(åÊ•’t2$D*=kçÎ8Ú¨Q#M¿rh\¨K—.Ї¾ùæRê„P€v†{Çù×C[#*Uª$|ÚÊ/èåÔÙÉ/ðüùsô‹aÆáº4¤ g)qÀ…ªi›‚>Cyzzª“ÃŽ³³ó¸qãä“b´¡°zõà—aJ8˜ «âw¿\ÂNE U«VuqqÑtX†aFC >\7 IHÛΡžòœ ¯X±‚„jÑLMóBØÍÍ\«Ñ"{¾Ôýwß}‡³~úé'!%66Vëò.OÔÇŽ§£¡²¡ß---…MbJ—.ݺuk¨}JýŽiún‰WàÈMâŠ+TeÀ+º|ùr²pA÷™3g†yË1ètãÇG= üñ!O(2£äãÒN‡áNÑk„âýÒ W¡B¶%a˜/LçüýýÕ÷üÃ0 ÔL(ù€>~Ú¹]¥J’$ªÖ˜6lØ@ÞêJ¦S)ˆ>WWWºÚ~ðÇÈèîU«V![›6m„LË›6mŠÄÍ›7Ë\ EgÆ—ßJfggGFFâ÷Uµ´´¤ËI€°E:ŽÒ‚~\\é…¤¤$aÙ=++KðU½Oy0§¨ZZZÐ5’gúäɨ ¤ Þö Ö¡è7nœçb79dд{Æ qI¬1!xÙÆ•žµfÍ500Ðô;6mÚ4¥¾È„8}ä[X]ºtAŽô­i(N%†‚ϩٮ8ïEGÃÀ‚a]¬G .œ:ujÏž='Mš¯+>~ü}ÜÂÂÂÏÏ/_6DêP·n]4ÂåË—eòìÙ³§oß¾yZÔ¾xñ‹~&Ξ=Ë/Ã0 Ã0L±N‹†!!!ø¯‡‡)¦E‹å)H›4i‚œ¿ýö[I¾ÁçÏŸcª,„ŒoÛ¶-D¢Òu4²wwwRÈ2:W²^,§Páo×/è“Ù¾¢ù!²!³Ò/0êÈ@ù5j¤8ýF;tíÚ•¢û^^^h(SSÓ<ãÖ½{÷Ž ‡å}j}>S¦L¡0ñ’GFªY•‰}\\}ÊÐt\ž   \¨FŠß‹ÆŒƒCÓ§O—9o¦$ø£ 0X‘ªõññ)p!wïÞÕÖÖvtt” /æææ(¹{÷î¡¡¡âCñññèž6l®«jo‰Òž‹!ÅÌÌlíÚµ…øÉ”Ìp®]»¦ôhNNÎܹsñºæi{õäÉ*«T©’ç²>Ã0 Ã0 S4#5KKËŸÖ|kÖ¬I6V˜¯ÊŸèççGS;yÍ[B ‡x´Í|óÍ7ué.­Œ‹×ª&MšD¢R¾pÚŒ]¯^= I’¨¨¨={öÌŸ?Ö¯ãèµjÕjäÈ‘K—. |ðàÔ:´<1¹¹¹äJñСC<i¼'ÔwìØQàB.]º$¸”GǯW¯žžžž¢Ã ïíímiiiccsêÔ)u¬ï‘cÞ1{{{Á[fÁ N%I¿wï^Ïž=ÕYyÇ-S,ìZµjݺu‹_*†a†a˜BçÎiu2­eË–äU[[ÚMþDÈ@2®ÌsÃv aß¾}‚ïqÜ&ÉBºnݺá(¹Ð?xð p ù…«]»¶ü’4YXC óîÝ»VVVùýõWDDD£k© ´!fæ{÷îŇ "XèwéÒE²õ÷Õ«Wßÿ=î]"Þñ!yºví*¿RŸ‘‘áææfnn~âÄ ú˜púôé¢y|ÏŸ?Ç¥…hm GQìÓÓÓƒƒƒéC^iá#=>M×mõêÕô)R§O EŸ2e GšfÁ‚hjtUŽ(ÕÁÀÀÃä6:zAÁä-†…yóæ¡„Å‹«NââŋÇ·±±)°—EúÊD/Ž=Ú£G!j† ÈC“ЧP~†a†aJ‚Õ¹¨?y§y:uB¶3f|)wŠI)éA!$k||ü?ü ŽßZ³fM±ïׯgÏž-_2ÅRo×®8‘œÞ{{{CD£œîÝ»[ZZ:::RÀzé…B‹-P¥Ã‡‹CBB •î=ppp(]ºô;wTãïïéŠ;ÊÍÍ¥}õë×ÿœ-Í—Û¿?ùºPPµmÛ¶xƒ‚‚4]«èèhú¦hº¢*NŸ4,5¦ú¾Ó™‚‘––FvF .,p!^^^TþÝ´iÓçÔ]éÔ©ScÆŒ`?qâ„:/ÀÕ«W­¬¬0pɇÝTÚ…©kˆ?#lß¾}„ ê G8‹¼©Ô­[WqÅŸa†a†)^/^,ìâ†æÃQô¢ 6(=ëøñã´ÊŸ””ôÝ,9Î:yò¤8166ÖÚÚš¾oˆ½Ù§¦¦’ä—_»qã5Wž›{%JY¬ôÕ1iWŠÖ-ÔSz\ôîÝ»÷îÝKLLDe„/ø£zõêªJ ±°°@UÛvSSÓÏGŸIxx¸m/"Bï;88øúúâ¡n{æ í‘Ø½{·$]Uœ>1¯^½"·y `>ò ‚7=1::ºßRRRRJ•*…£U«VyµT“Ç»¹¹áÆ¿ê¸×‹ˆˆŒcyòáÃê)âA;ψ'Æ Š©Ñ°aÃü~O`†a†aŠH<(M Ó}1qâDA.Õ¯_Ÿ‚Ú‹!YW¶Õ… \/_¾\’މ.ݾXX­\¹’œç«S&dBÜlj•~ÿþý ¥Yà¥pKÏŽ–SSSèêê 2`Àñ¢våÊ• † †¿wíÚ¥XTBBÂèÑ£Ç'ÖË–-ÓúĽ{÷Š÷>yòBÞßß_]ÄeêÔ©hÃñãÇ+"Û¿þúKætr¨^ÂãJü;€ï÷¨V­ºÞâÅ‹Oœ8‘žž®f!d^±zõê­[VV^f²¾/ô<èþtËñññù:1::ú«¯¾Â‰7Îï¹ Ã0 Ã0LsóæMòO~Ýœœ4h Ì~!ä…íëW®\¡]ÇÅ.ëò‹³³³ÒPãK–,AzçÎʼnŠ1ï”N•i8¤Aa}c+}33³#F@’c¶¯¾Ò§5â *àïÐÐPCCCÁUû;wvî܉òW­Zµ|ùòiÓ¦õìÙ³N:eÊ”‘<Íììì+V๋¿ê ä]@Ps¯8xð Ú-©¸þK’JMæt45ò rKOž{ölÁæÀ³fÍB6èMüwìØ±_Ü ’¼Ž;JîºyóæH„……)ƼS„,£æ‚8'$$;vlåÊ•?üð48$Iž§PDu}}ýŸöx«³ÕVâF“y333777ñ—„÷ïß1‚ì5\]]¹¿ˆA#“FI”pøðarÝ £###UYè3}j/^ôððÀ‹]«V-‰‹†J•*9::Jž úËõë×5]½gÏž¡öîÝÛÛÛ»PrR¼m•ö`«?9,9ZÇäV¬°.\¸@éÅS÷3f qÀ€ò’ó@™êŦM›P+<5IúíÛ·»wï.;##Bæ»ï¾KHH§§¥¥ÑvÍ›7s7Q„ºÉÒ¥K%é™™™¤§íYÄ4nÜX©…>Sd@ºúûûÛÛÛCÎ Á2š6mjmmíááZXfõêðþý{???333WW×ÏŒbO!?Pu2_¿~<‚¶oßþK zÂ0 Ã0 ÃHˆŠŠ²°°P½b‚k(¬R¥JI]`+²±:þ¼|6d €;wVÇ9?Ã0 Ã0 Ã1;²öõõ%?b1EVäyzû'?ç˜Ò—´{¤YûáÇfff¸M™üÛ¶mëÖ­ÛÅ‹9s¦råÊt›_œ›Ä¢§aÆh+I:žù%Yi¶ëkÎWS(dddÿþûïC† ¡=’½{÷vqq9räHIÅ-Z´@ ;&“Gɧб±±×’a†a†aJÓ§OÇ”ÕÞÞžþKý,X dHOO§i­R+FÓø•+W*Í€’ üîóÑ××GÅ‚‚‚>lhh¡*gjjê°aÃììì UîØ±ƒÄ¨ã¯±µµEsMœ8QñP›6mphË–-2§SBùíúLICÍ¥|Œ'YYYÅ[UŠñqàÀU0hP€33³7oÞðÃe†a†aJ&d=dÈü¯¥¥…ÿÞ¹sGÈ@Nç7n,^ Ú6]«ÚÜîääDñïdv¿k]]]\zݺußÿ½ÌäÜßß‚ýÂ… JB‰/‚>}ú𲚠Åôôô[lÞ¼y‹§ŠeË–Ñîy¦Äåо-OŽÅT¬XÚßÞÞ]¯X<ÑuíÚÕØµk—Ò£{÷î%w©ýúõã7a†a†)ÉìÙ³G°t^¸p¡¢£3L¼‘˜§kÕªU‘ÍÐÐP&ÏÆµ´´†Zˆ¨ó$--D„Ì`hŠ#FØÙÙ) —““3mÚ4*ä‡~(–-_(< vÃs¯[·îÈ‘#8ðêÕ«ÿ » ««+ùΓhffFöÄo¿ýÆù/@¼”Oëàbð† ÒR¾$Ф†077Çu·nݪxh÷îÝ:::äµPbê1 Ã0 Ã0Œæ¸|ù²Lœ¬¡}||„£±±±Åïþýû2…\¹r…f政œ»»;²­Y³¦ÈnðÖ­[ääPU†   îÝ»Ÿ={VéQ¨N¨Qº;è~aòEvv6‰#1xêׯÿý÷ß“/²“'OÆÄÄà•055%ŸŠôïߟó_†x)_pF* ««[Kùdèáéé)Ißµk½·VVVÅn,À0 Ã0 Ã0y’””DéÀÀ@šN‹·L»¸¸¨ U&¦OŸ>¤ÕYˆÇ\ºråÊE¶í–ܪ·lÙRñЋ/ .§L™¢js>2Ãmmmr»Çä—^½z¡¡Ù;tè@Þ $PlD ÕªUÃKµeËz|+Vdyõï¦X–ò‡ŽÂÿýwqâæÍ›ÉâfÔ¨Q¼9‡a†a†ù"ÈÉÉ!aeii) ò‘Þ´iS$b¢+S²‘w,L’Õ¹bdd¤–––d.­”·o߯ÅÅݸqãôéÓ{÷îõõõõöö^µj•››Û‚ ¦M›fgggmm9ÿwß} iee%Ù×½qãFÔÍÂÂBRø™3gºví*ç'!99™ÜjéêêB]ò«R0\]]цƒ¦—íÚµk³fÍjÙ²%I'‰ãt<&<¯””átÈyZÄæÆü€.|ùòewwwtgŠ))±Ê777Çø™ŸÇ‡/^,.ÈÇÈØ±cYÔ3 Ã0 Ã0_5kÖÄ<–´¹8”3Y@—+WîåË—2§oÛ¶æÛ·oßVóŠ]?!I|þü9äó¢E‹†Ú±cG==½ÿ“¥téÒÕªU«Q£FÓ¦M›7oÞ銺žœL˜0A¬GŒ¡›^ ""‚ª‰Á/I9uê…¡—ìåÈÈÈ8räù%›9sf||¼ªè‹“‹‹ 7æZÊwuuíÕ«Åæ(¬¥| †+W®¤2mmmsss¹å†a†a˜/ˆÖ­[Ól¶I“&bñ5iÒ$ÚŒ*:-j×®][ý+Î;·L™2´–˜˜¸téR¡ÚÚÚ­Zµêׯߔ)S–-[æããpîܹ[·nÅÅÅ%%%½xñB©w;UŒ?Å:;;Ó###MMM½½½eN9{öl•*U(&WLL ¿!ŸÃ›7oÈTYdA‡ð eJX³f òqc24Ð…Ñ­­­…AC©U~jjjž¥Mž|ø@èÚµk2%3ˆ2nLFM=z´ÿþÙ³g).å7iÒdìØ±†††B ‹z†a†aæË%--¢ikk—þmŒGwrrRzn||<åñòòRUþ»wï¶oßÞ£Gkkë+W®Pbff¦ØAŸæxþü9ÕPþÂû÷ïG-LïÙº¶pyüø1µ-¤–âQ¼8´jÕ*™È7cëÖ­¹1™••²víÚ1cÆ4jÔHñæŠ+¸•†a†a˜/—¥K—bZÛ¢E ±ÿg[[[$vèÐÖRIR¥¥¥IÎ;v,­éËon'nݺ5yòäž={|öìÙëׯ ŠŠŠÊÌÌT¼âãÇçÏŸß½{÷<}ÚãÒ±±±¡¡¡/^Äu÷íÛçåååââ‚I8®elllbbbeeåäääããƒ|5lÙ²¥Œ`l׮ݛok (æàà xèÌ™38T½zuù¯=_ý5²ùùùqc2 Ã0 Ã0 Ã@“¤«ì  ñ›o¾¶£Ï˜1CØ“ÿã?’þ:wî%ž>}š²½xñ2ÜßßßÍÍÍÞÞ~Ĉ½zõ255ÅŽŽŽÞÞÞÎÈ‘‘QXÖë©©©ÁÁÁ¸ ”ß¿##£Aƒ¡þBÄy///ÔÕPzzdddƒ ¨.]ºÄïƒæØ²e Ú¹S§NЇ233É$<<\¦„éÓ§#µµ57&Ã0 Ã0 Ã0 ÙN¡ç]]]…D|===$nß¾]œùàÁƒeË–öä?~ü˜ö®W®\Yþ*¹¹¹III/^D‹/ž0aÂàÁƒÕÙ‡_0ÒÒÒÎ;'èzúF‹*æD6 äפI“»wïòû QîܹC–Jm(ºwžžž2%:tyêÔ©ÃÞ†a†a†aˆ£GB(A­C¤ ‰«W¯Fbýúõ?|ø ÉyÞ¸qcaO>4þ7nœüUÒÓÓ‹ñmllPÉE‹IÒ÷ïßO¶ß~ûmrr2¿ šbœÂ.œô>„üÓ§OÏŸ?¿iÓ&ˆý>}ú˜˜˜ 05Ù»wo\\\o“âô‘C6qú… ²™vsåÊŠ9˜­x´S§N8ºeË™‚ƒƒ‘§R¥JüA†a†a†a˜ÿ8ÉÉÉäRZH<~ü8™Û§¤¤ÈŸ¾yóf²ÁW¶ ýöíÛìÐh®®®“'O†N×××Üî©Òû]ºtîvvvöóó»|ùrll,ª·zõêqãÆõîÝ{Μ9ùrp÷ìÙ3*üåË—ééé´'_[[ÛËˋߢçÇô™åÚµkŠGgΜ)ãî>55ÕÃãsçÎô@¯_¿ÎíÉ0 Ã0 Ã0Ì™¹sç*³°°@"dxž§"§‹‹K~¯+„ggggii‰:èêêªûåÊ•kݺ5…É[·n”ô¾úëìdk€òSRRÚ·oO_-pu~Š sss<…Þ½{ÿùçŸOž< À¡ ˆß¼y³}ûö~ýúÑ.}²éÕ«—R§ú Ã0 Ã0 Ã0ÿ ‰(¾ÛîÝ»…Ä[·ni}"**Jþt X†œ÷ïß/”úäææ&''S <—±cÇT¯^]•دX±"Dº•••““ÓÖ­[ÏŸ?¯Ê¡}`` …±£ õzzzBü;¦Xpssž#^!<Çyóæ|˜bÜ“?½Y³f?—)SŸa†a†a†aJ‰‰‰cÆŒ¡èðåË—wqq‰‰‰2dˆ/ŠÿŽ5ŠÛŠa†a†a†aJ&—.]êܹóÿ©&((ˆ[‰a†a†a†aJ,¹¹¹¾¾¾õêÕáU«V­R¥J:::zzzÙÙÙÜD Ã0 Ã0 Ã0LIæÿŠÖ‹ endstream endobj 10 0 obj << /Type /XObject /Subtype /Image /Width 1352 /Height 660 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 888 /Filter /FlateDecode >> stream xÚíÁ1 þ©g  à×¼DÍÑ endstream endobj 17 0 obj << /Length 1194 /Filter /FlateDecode >> stream xÚVKoã6¾ûWèV ¨¹âK^ l³ÚËn·¾mŒDÇÂêáJr²ù÷å(‰Ìá 5ïùȇ݇[m#i„6™ŠÇH*#ŠTEyš ©ÊèPGÅ2ÙK©l|3${-ãêÒù>bž`ŸÛØõ5gwï§äŸÃo»O‡ŒRøÉ«J[¤¢ÈMTu»wBk›etbE’H¦ÊÐN§éÂýðk§¢›a÷;ü½ûEñ~¥ù#†TD¥(3•Q@º¹É"kK8œs@_UÄîœìañã#î†ñÛŽ)â¦GÆìÇ£«<²ò¸ ¢jèð«<€!c_³x8ò:' buÌ8»Þ·“Hö¦ÈãÏ}8uò¬­õÇ™Y§6½½ï/MâiÈ(„kDi ¬R”Ör m3¡U² °º¶eâ‰Ü¸Œ¼« –K‡ÑMÌŸ†q¦(€¾CÁÓì#~èfe!EèÇÀo:N$iÂPæP×jÆæþDv)–ôeý]{ñ!x­cGʵ €Ã­E$…º–U—q aµOÌš<Ö§M FHT$éYÊ.È•%«J‹R²;&¹À1­âÊõL¸ºfâ J¯J&æÇ¡cjòØ~tm`` Àê—éG`Z×>(è릿烒2jÿÐTä~°R }ï)”· ‘±ï36^™cõóP}ØaÛ^ ¡Jö6— ¨Þ“¬€äKëæ;êj_ƒFšõ‰<>z_û1H*×Al´Ñ±Ÿ+(x¦sÌ™¡œ¡Ê“ÃZCw ¬þûò0™ãåÍsèå—“§aªy-·†ÞíäÃ+Âó„p)ŠâŠ×¡HÿÅÕU endstream endobj 11 0 obj << /Type /XObject /Subtype /Image /Width 1024 /Height 300 /BitsPerComponent 8 /ColorSpace /DeviceRGB /SMask 19 0 R /Length 282755 /Filter /FlateDecode >> stream xÚì‹TÕ¹÷ÿ’súV­µ§­µ(Š@„„BBHˆ!!!!·Éd’¹ß'“ëÌìÛLHŒ ‚Ö{mÕ£Ò[¯õR}=¥xAÄZ­5Éd&¡ï9ïºìËÚ—™$HÐõùü>óÙ³gïµ÷ìY³÷÷yÖó¥&Õ•ÿ¹ìöYøÃ(xÖçþ+ýzìà¿_Ú³ùÎ úÁÑ K¤D|6ù§×u¦/ø }ÖPQQQQ]©ü”…((üÄ(èà…Qô(â³ü%•š{?´ƒÃ!€Šê²é²tûÊÈãáóz!øÿ4èûÀ?€ÉÑѹx<§¨.¡–”ÿ±À¯æqžF£ç©¨¨¨¨¨.“4üOðÏßõ Ÿ÷{?°Å&#ÒüRiV‡ðœ±Ãƒ’ç@E•c]–nù¿ï¼^ý¡óáà9¯ót,ú5$!EuÉ•þŠF¾¿£á¯LEEEEE• iÌ~…? „Îû]§{–Ãá!*ªË¥ËÒí+"V§ ‡> Ï@¥”~µó"> D .QQQQQ]¶’w£1!úÔAhvéAhЧ>\ …R(Õe‚ÿËÓíÿãB4jøGüøòœ‚úÕÍÿ@”ÿ©¨¨¨¨® ÍBBŠÏ(ÿS]QüŸËn?/ÿ |Šj‰DùŸŠŠŠŠŠò¿þÌúÔ›[ò‚ƒÒ ªËüsYº}Eä1€úúàŸpè\(p–ò?å*****ª%äÿÏDê;ïà Äå@„Îyûp ÀgA*ªÜëruûŠÄÿ¡ó¤Àš¾à¹óÿ Õ)§ü¯þ‰©¨¨¨¨¨r' ÿÏB|ŠË(ÿS]QüŸËn?/ÿóü Õ‰ò?ÕwQ*þ‘« s Bàp¸PXu&TT9ÓåéöÛÿ£€R°øOð[Áÿ—Ü\üÐ5×û—-gÈõ·®Œïmúü»[,ïƒ-³l°výxk럮|þ×ýÄTTTTTT9’ÖÍx%å*Êÿß>þïèxkÙò°ü—Ãyæû×ùðú«Mû^žw÷·ÇMæw³l`·Ÿ¹éæÏ%)ÿSQQQQQ-Hjþ‘ä÷‰ 4Ã-Jÿæ¼h±{IüïÃ)ÀW»–E–ãëðï®k¯ Üp3ó‹m—û>v]¥_gõØð] Olþü4Yµ¸nâLZx·ß>òh8t™¤Î…‚ŸˆüÏÍ,VkÖ)ÛöØEìxÑúÅ þóFUU?S´åa‡Ëq>5vð_x=äÿ{^ÎÞ¬ËõÁÿ£/û6q!õÓ›†ÍÀFXüiç–ÿ?¥¢¢¢¢ºZÔr,+¿ï¹¼–<\â—F¼¹¶>²õÆ¡e×x¯¿™¹µõ¼þß]ׂöý± ,;N[ñuîyÏ Þ^øX.}´l…°òûÞë6rsóËû@û×nÊ?VÐ']Ub|\¸Ù²ª§«ä~ú1h¤ä‘ÒÛGW_ë»áGý?­ýÏZ°´Fb-8XYõ›?ú98ùülÓñBp>ßþ_d·û³hü?ühXïOž . ÿßò ¶¬üñ•«G¯¹Þÿó[¢6Û麺çÿã§×þ0P¼åaŽ–7«¨| lvíõå·rVëãõÏßôÀ¾áÇáME'††¾”·¯ÜñëU¿»öz?yc„±úÄ™¬Í×Ü9aüŽÿ#‘–n{ìÇ7]wCì Çë׬½÷®ºäÖêNýägCßÿœ§ÓyF^ßÔôGpΔÿ©¨¨¨¨.5ÿ» åŽÿ—-gÀ±~~sÄãü«ÇufÙ-1øö–åÿ«ˆÿáƒ5ÿÇóðC缪Ë+ó}ìÚ|¢,/çVô¡ËþóÈ-ØRpŸ±÷¾ß½õ‘Rÿ¿|O&þ_[îùÀŽ[ªzz‡ëŒýÁÿË §êñÌV7EàqA›à¸ŽæC¯þƒ›Iþvhlƒ—@ Šÿ_ÚÒôv<\t90UÀÆ»ž­Ëwÿ¿¹rÃÿŒzÓ°Çó1Ï¥ŠKx_\òH,6îÿû~Òßràuy³ü(¬Ž›©«Xƒëá¯Ë»oxøŸƒCÿX}ÇáµëÇåíÁîçnÇÆþuëJ¡ùÀë`¼%Ïdtô°>¶–= >òúÎòÞ†ûö |޾½ò× qކɲå1#·ñûÎ~ïZÓùA<>ër}X^ñ¤|”ŽŽ·€y²tüowœ©®yÆPVÛ_(ÿSQQQ}+ùÿ߯q'â³²rÉÿáðç?[Á&ÀÏo‰‚ð(…>Ëÿs3̼ʱ¾õü_õ›øjª¿ç{Ñòµþ³æÛß8°ïMx¼¦MÌÿû3ó?8X®q7n\OðöÜJlh€eÜø÷Ü×?ñ ŒoLJ0ÿ«ˆ§ôf«žÿ¼Ö Þ^¸¡ú™êÖ×[®Þ¼†+¤ÛÏËÿ7½XaþÇË€¥ëðX­ù·ï»„Ö`MaÑÉŠª§åͪª‹¢ô“ñx€wãÞ—x@†$pô6þÞ¾¶îyÔ,ÜÆÿìÅðdJ·=VRú^Æù¿xó?Xèëû 4;<ô“ŸŒ ©ënºÜ‚ÿÿo Æ 0dÀ28.¸ˇhïxó†Ÿô_Ä…Z¸ÿßÐX üSþ§¢¢¢ºJù_““3þ&›@?ùÙP0t®\þ÷c!G´7xΓ[ò€ƒ¢p”«^Ëñ¿¸f‹âÿ÷lË×únÀĪáT=þèïõú6 þ÷Ëüoy¯ ¼ýâ@þ`yÏï`ã~±qÌÿ¥–‚eܸ^ÝïšÀ§˜ÿq#þ³nüQÛÀ[‚ÿý8H~ý}wCÎq.þÿ«þW»\Ýð?Ê'R ÿœ ÛìRðsËkxÙf? ømqɯ¶•+›5í{Ynaý† `XzÞÿÞµ€åxe,6 îBvûiM³ßÿ{zÞ×Xvt¾>Z³ö^`eàíÁi˜»ß[³îÈòü梓.×ò!îÞûX¹¤ü¯7ÿÿŸ£¢¢¢¢º* ~"ñ¿²RâÿƒÇõÁÍ¿`ñA!àržùf jø>J2ójì_eaø!×,¤…o7ÿ`–âÿ׃·MŠÿß ÞÚO÷â‹ÖúF‹44pû›¦Í﹯ëÁ¾`ÙôVûEð?>î÷=׃ë¬?çlüè’ÿ±¼9Á òÇ[z?v~«ø‘Ý^¯…wûùùŸ^¬ ÿ°GËÔ›_ÅË6âi3‘ÿ¥Í*«ž–?Z¶<¶·éÁàypÛ Ïã•n÷‡p8 ÿsM³@·®L@þ7:™Ò2ÄÿhYä´ ù¿é`¡¯ï3pŦÆþK–À§ÀGUÕÏl,x@n ¬M̶xíÚ¢‘âõ[¶þª¤ìÑ‹¸P‹ÿ—M€EÁ?å****Êÿ‹’ÓqZŒÿ¹%ösüã²°ò’âR€)Ñù¹È½¾­üOÖÿùñÀMŽ¿Z±Ãÿg#Ë –?V°GìßÂÞ 6W@Šÿ_ï:c·¾ß½åá-¸Mº ì²~<ï"ø4Ž)~h‹ïcº_ª~ÍáuóòÿÆc0S`õØ\ ©óíöüc¦·;ŸxZQ,е¾Úßnþÿæºøÿar³ëê¶¼7<üÚºç¯ûa`¥ú®ZshmÞx8üY(t~Õš±uyÐs®ãÿ¼ ÷oÛþ›\$ÿÿ.sÉ ùÇÀQ¼Þ³‘ÈWà$×o˜Àlïr}xýôáfM]®¨|Êçû|´oß+ß»Ö32ònê§7twÿßð?Õvè¢òé#•ŠŠŠjRçÞ*Êÿg¨ÿ“‹ï.æÿÞø;6–-- ÿŸAèœ7øInùÿ8hßyå4®^aþ—ëÿ/‹./{´Ìû‘SÞ'ê‹àûžüdð¦â‡K¼ŠŸ‚…’_m…Õu¼×ßûÅךñúö?¦Á÷=׃ƫ[­ðÿy‚ÿÏû÷œ’øí¥ð?>î‡N`PÈ¥{6͇Á?è#…ÿÏûýüÞ¶Y[þ°E¿Y: ƒC€Éù¿TT—K—¥Ûãü_½pþ¯×}Æã<ü“²úUÊÿñxÚë:ð~dø+SQQQQQåB‹@Å?^Eh"$ÿÇ.ÿY—õ=Sø³@ôëáK@àYë{àà@xþ/Õ9PQåX—£Ûãø¡ù¿üžýÞ­Ýï„CŸF#_Qb¿Šø?ŸE¾ðî½g©¨¨¨¨¨.ŸÔæ@:ç œuû>vºÏX®t¿ÝÚýÖK©·[A³®3VpTü‡ò?ÕÀÿ9ïöÙøßÿqÀû‘ÏóÛñk÷ÛÝotw¼Nu øIåqœx?¤Ï****ª+K `!ÿÇ.ïGNïG¨/‘pk9Aãþ©®@ gÝ>#ÿ&€ßó¡×ý×}ÊEõ¯äàª}ƒ+LTTTTT”ÿ5,üáÐY×%D 8í/…ª+ÎÈY·ÏÆÿ’ 0ZÞ©.•ÀõáßOTTTTT”ÿµ,$âÖ'—HRƒ¸}ÊœTWš ³n?ÿ#@´°|TßXÒŤðOEEEEõ]çÿsÙ¤°Ð¥Sö#RQ]vå ÛCþ÷Ÿ]ˆ€êRh—ŠŠŠŠŠêª—†ÿ)ãQQ]V-œÿ©¨¨¨¨¨¨¨.(€QQQþ§¢¢¢¢¢¢úNòÿ%®sHEEµz'hN******ª¥“†ÿ)}QQQþ§¢¢¢¢¢¢úî(>+PQQ].¹N÷4>uøðÿRQQQQQQQ}CÁÙ']Î+ `TT”ÿ©¨¨¨¨¨¨(ÿSQQQþ§¢¢¢¢¢¢¢üOEE•3þß½ûy“é-“ém ^kiAj~½¥Y^x½¥å––×xÚÜüZóþW›÷××Ðf¯Š{µ¼v mÓŒõúþ}¯î»ç° ZÆÃ}÷½¶¬ß÷ Ð~øú2xmÞ÷ª"Ðø~ظôVl°¨¹ùU°…ZšÑBó«p¼¼ÿÕý@ÒzYû÷¿²´ïéõ´ý+Òò+h3¸ÐL´Ü‚'MøM(D§W¡jE‚˯aЖ¯‰›µ(@µb½ _¼Ö|àU¨pb¯à+ µÿšrâ Í¸µVEÐkkëëÚÀò«àµ,Àå×ðrk;z ÔÕÚþz+zmk¨U§­¯ƒÖZÛ^—×´I’ß’Ûã·-­oTT§n?.Kšæxp,,tþ>a|ª|JõÅÑ)Óæˆ·‚r}ä ˆ¸’å”/Ž®Ã Z˜aEÁ•,Ô §ÙR94< í§äöðJÎèÎSsæxù¡6ñ‚܈f›‰1Éú†–Žÿ;:ÞÔ}/ùÊ«®¹ô:+}4ËËvž9y™X)÷(eKß,)i3±ÊoÕWX¹¤êsK£–ˆ^×,#á–3üЊXv†ad%ñËÎdºtÄÕ ®\äï˜eu¿ÒŸ0<Ÿ,RŸgŠ<1å(ñ4ñ'U®˜úpø˜Âm’MÉRnð7%ðӠ܇ò£< ÔÙÐ5¿ôóñdÿ‡ëgçé]Ä!C÷S]+õwœÓµìMRñ"Àå¸ÒÁÉðñtö–N;M^"Ýï¢~€âKª\ùt\÷?UnYÄ+þšòUÝ ð€ ÌÔÝõ\ö[4Éÿ€ù·l}DÖÝ{_ÊÄÿà_UõsãÓ#ßtˆŠêÛ­3²óbü•Ïÿ@|f^T¸®}XèCêÛø¬æi%3ƒîad€Lê•ÊP>Cò=²5ÍŠÏqù•*5ð“÷ÌÊÈÄQt'­¾¤³YåäWÖÀ'yŒ€6M®!™V}òœÉS2 ©ÉS´×¤Ë›–™¼ÄÕ˜5²”ŸX% õKÊÿo‘VÓOÔ}É K}¬ $SÌ£µæíɼ!шè3iiKÍ•ÿ8ä_ rÙ›i²OJºË¥ï“2KÏeáÿL&€ŠdÄ/5kxbj E+#`þKDÞ4Ç2´&tf~Z%ÌÏMþ¯¯±ziüÿÿëÿø™~ƒþ–év­³p5ÄKÒþ Ë+ç²wÕ5„O¦9uGRh™dr…ÿ…ÿÁ[^ý3ÙmLÉÜÿPêÍæHà×,h6ËüÕæÔ›ÍéÍ%uç™] )A|¯9ÒN‰ë¬~Ü+²7>¯ Nþ/Äÿ×-‚ÿ·•?Aò?x›‰ÿ­z1JùŸê;ÁÿOÜþb´úÏì•Ëÿ&ÉÿŸá¹èQgÕ~uÑ3Ÿ’©I¼ÓùÑ/ û,1òÝlVÍ?2[f³2Àçׇ–T ×ÌÿŠ•A<…Sj¢Né¾‹ê‘ Ë ðK“£>·4á,ÕÙë&M˜9äö²©¢·´nXâšÈÏP½[ ²aè>òÜ२¯¾|{ø_ “êñ”‚Ö0´ ™°ûiõ\D’°ÆÜ“Ï\¾ò ²/°ok~&µqjðç•OX󆄟]Tßq#3ÄÛ¤¡ @t »&é,£Eò–$Jü?ÉsSþ9v˜´5µ¹à3Aå:€ƒžøæL¤šN¨Ù%CŸŸÍ@¶š .$ÀÿjäNë _eËý_áòÿ‚ñ(Þ¥yÄpn<Ò§Ș3¢ýYý%Ò9 2·§õƒ Fís»á¸Œ|ÚDWŸ#L†¹ÅÊÆœÌÿw=W¶`þ'á+ÿßø›Ež/Gi Õ·^î/GAo}þ ç,4¢£kTq5< £tDþ“Ï•-ÎທG¨g5 âÞ8'»ƒÔ÷UÅ‘NŽ g–Á£¾]Ò °´10W¡zKÅNÉ2kˆUÒiDwè®ì´îè*W¼äUVQ½Îÿ¯´,‡3‘'C>šÍê† }àªÐŽúú¶-©ÿŸËÂÿiAª8 u®~‡sNcÌëö׃–.BCö¼¥±ÿM} ÉŸ•d$•3p^Ÿ¡ñk8 Äq3º+–Ò­š®´.ÞcVl#ñ˜ÖžÕ ii~/9ÂG¢ý¤ÄüIþ5&€žÿ ¯†Ü±É~BÆ>éŒåîð2ÿ3Ì$ÇMbþ¯oüÿLnüÿš‘>M—‹ ÆhÅ>5{=üϪ­`ÍåÙ–±“ìÏD·!O8¥» ÎfŠòÒ…bÎ’—êÛ—êOšù¿?§Ç~"LH5F yô=à´¦±—Ö‡¯¿äX ñÕfu½ýb~‚ÿSŸ¬»ëÙòÇÿ/œÿ±_”’!ÕwD¸Ã_±üßÙ©æ=©"à—€*زz, {D¶‘`@Y¤Æ*´ô¾À1PC"2¢Ù”šlS™øßÈÉŸÎP‘Î椻çkà?c4”Ús;«Ãx½]“Ö§Õc)"X=-“~L_Ó¾Æå¨ãaÉÿŸõáòãÿ âÄ2[^Z>_ˆ ÔÐÿÀ¿€:ŽHÓ”¡%ÿ¬™‚´0 „&zµrD²¯˜iLKº+õÌ6«mšÕŒU‘‡&Ãû oRmhÇÔÿDã» yëÐÕèC€HtÔ4‚øÿk…ÿ럯©Yþï4ŒÿOgâÿy#ôð¯ z‘uAóC®‘±ÿâù?Ãm|ÖpœÑpÐ6Kä9‚ ß4·&Ãk•yÔoN“&@:Þ ùŸŒkÒ{ºÔ¶¼vcÒÖÐñ¿ù/ðjëˆsÄmL¬«}¶lå*ªo3ÿkýÿš•œÿáç—’|çâÄA þtÑ>šgÓbîQÒÍVÐÜ ˜á,¤L i_ÿ”Q»ÜµÑÙ#¨3'Ÿ¦õþaCÀ#ý`’ßU±iÃÌM´¿ÚÀIë,E€™j€À0ÏT÷,ž%2TX¨?KKêÿר_²%«½þR¤„A‚ ç“QÁ2q»‘Ï?•ÿµa¡´£F¹·iý@€µWòÕ%™µaK¢_ÐXarP°DçÈM«sŸÓ†4«‡ðùL€¤ü‘QPZ+•)8œ<4™SLüOµ—œ?:ô$þGþÿç—ÔÿBìðO0«óÿ+${XK†ƒ-#ã×pÍ…LþÿD"{F€1‘j\÷™â65÷¥ 6‚ÆÛŸÒûüõN˜ ªÌ]–ÄœÞç¯qþg¡&«FÈ ¤…Nüˆi]p (›=çBŸ`xÇÐñÿsÛ¶=NùŸŠê[ÏÿRü¿1ÿ“eâ”ÿÓ†±¦ ~"ÌÉ$¦)3¢'^|^ÕlöÈ}ì½.Æ&¥ žÉžPi”ð›^H :™J á“*ìG†¤‰SÊ˔ҕšQ %drÁéù_NÜP;!uqM\ª~÷ó9ÉÿUS+§KøÍÀÿ°Â^7gä#Í9l”ó®µì²ýê†Q2¦‡ë»½Þ@ÓD掚ahÏÄÿYœÌ:ÂO«id3 ºhríg³ ¥É&€:æ_ ¤ð¿.(Û° a´¦³¦Ìê¯-ü³ƒSŠ}-óÿîºSKŸÿ;ÏO£÷êgO Îá¢ñùë‡ô_¸ÿ(Õ;ÿuYZªðHñÎfŠœÉ§—éÏ®2xZéžhsFMZ¼×DøÞ Ôqþ(÷Yý$ZÔ¥^ȃµ a ®îÙm4þ‡Šê;Æÿrü?OÿËaÿ™ù_´”x¡Lñ?Yª+A•"€]¤WQð¿ðâ?ón9_A•T†(}ƒ8Uÿ\ðøˆ3êž2¥pZî¾BFKA ü`MæmŒZ ]¾â¡wCÿÿ£¹áÿyâ%$‹UëÄh4=çë=ÿ*+º3¦Ê 9Íêº ‹Me ›7X¿´iÕ TfáÉ2‹J«ÉDþjç¿Êÿ‹MëM#‹;•id$Sýõ8‚öÉûÂdؤXÿgIãæámÖ•axÏ|Q.2Xô ¿êõ[$ÓÐó¬ Ê’K·éûÆŠÌäZ7 NS›ÚˆÖL×'s\ý\V³ÅÀ`7Šê4È;Öð¿2¬†j‡âÜç…\a²<× €«Ša ¶öÙ²²G)ÿSQ}×üÿ¸º¾TöG¬ÿÉ«ù_òxÕ²h¨ËPèo§bÀ?9F/AÉ2Öã«ÞâãÒ+¬ ‡iâUr•)InAÍð² ?'‘0K'å8ô)ÏP-n#+I,ã²ü*8GWû¢q#dSP‚xÍSÒ‰aØNk7–Ž®œ‹Ë7Éo“âÉ£mDñJËÒ²¸=Ú %m%ˆJi—®˜îSX5B§ã²Äc‰+µV¶»åeeÊL“÷’~“xØÉµ?Ÿ€¤ÞWêö¤½¯ú•Ã)'‰vO ê“Ñ, ÒÉ òQð‚Ø>î½Ú‰'dü&{‰!€$YùG?yÂíàYíVoz¨ù?­y„w9Òÿ_Wÿ|õÒó¿.ùWç]wÔ923+NÜE5åî3Wõ™ËLõsY‹^Î ¸·§ÈÜCÐB÷I¢÷Îðbï’_ɾª6Êt}¬Ÿ¦/ÎfäåPÙSÒuÃ'&/¨¢t¤!i"ÎGÜRº9ø¯!ýA¥ñ‚äÆG¦·hªÄÑz„÷*c!޵ª‡ãJžŠ')N@#>Oç” q1O¤èÿn[ùUÿC NR]´(ÿóÜLÆHu¹šŒC‚Úà´€¤É4òÿÏaþW˜Ÿ×æEJÌV”¦A™áFþÌ<%ô?&„¿âà ý áGõׇ᫸ð°‚ |ߣp!ôz˜¯Á_qÁ‡%=Â…¯<\Ÿ>Äõ=ȇŽó}r¡_Áíƒ`%Þò$BË¡‡Ùà ´x½‚å¸àƒ\ð8<ÆÁŽ‚&p¿«ûI.tŒãB÷s¡£\ß1&xÌiÁ+ïãC÷ó}Gù¾ûÁà• Mðá£è££h—£p¯ Ð<Êîgý@Là>å>Qp›£p³Ðº½Žó}ã\‘ï» Ã¦‚\plÉÃ×qtˆ mɇÁiCo'ø¾#`%WE­ó*'6øÏMbk"ÃØ=TCýóOä þߨíÏÍ¢3Lòl’g¦yv.CG.,ç. •MŒ©iqå nwGb§€8vˆ—Ä1Iq²—Æ$™KÇG{Íp Ú…™D NÁfRjž ËN3 "O— OaëeÑQÀ.Ènø$Þ¶ø ¥†O65%.°Èfd“,h}F\ƒ6¾>©i{Êæ§fIIùÌå•â^è'@†söšÿªÊ?Èù?ƒ_5U€ Ë=éëe*þ©OþÕdÁ(Ù.$ÿ3_××=_½3þÿÙ,1?â –˜œ‘‹LøÏÊŽ}ÕÍ Q.“¢uAW HÍ¢ŠEYP<ú+N Ň Ú†IÜ qÿ‘½ê>†,8QB 5o"Ý&¸õöäzÙ¸àÔþ•Å!_$©¶p¥WÕÑ•eßC”;yªø?ŠKN*[jÛ\0úšqä¢á / Y½Êða Çdþßý\yå*Êÿ¹æÿ;Žäý›ó¾ç¾®æÙ]K4ÿ—œÿË…ýðúä_ÏŸ›a"“Lè<¯™@ÐÖÉì5š5ª2O8Ï|Á|°gÔß•ðwÄ¡:ãþ.ø¯f´,¾ >‹º¿ ¾E¯¼·—óXB{Äåæ=½á{ÔáäÜæa«ƒs÷ÛÀ²}Àjvº8™q™#ë Õ¶:ûmΨ£7â°ó^ë Í1èpƒvF¶¨ËqX—•qv;;|ƒ6'ï1ƒ}Aã!‹{Äîf½–ú]#;vÝqÙû­ðèa«•õXj™ÚúCh¥µÏjç|VÞg‡p9x¿yÐæâ|pã>«3dµÇ\=ƒV«³#u[8‰qu-àÄìà@Q{O¨ÇÞ×cç¼`wË°ÃÆ{»lvÐÚ×s™ÆÓ5ì´†­à+;Bë­ì¾—àW¦Kðwƒ£óà5Ð-:'ïoçý‚¯;îëŠ{;o;ï5ñÞö¸·3îퟢ½º„à`œ9‡92ååÕ׿P^ñä’ò?§©[«iԾǷ¶h¼¢·×Õn/,:,k ŽÞÝ0¶¡ôäÎ:Áv xû†“öÖ@Uíµ»·®?Q±óHý.nÃÖ£5»À â½fÞ‡.—׌ÈÙSàÂzMÀh|&Àü‚«“wšggÜ L€v\sà~ˆÐˆÀO‹ãøeBÓ /lÏÿ§tfÇž™=ÿà‘ýzð®\I8V:Ì=Òè1*ˆL¢ÄDIì$ãh  òT 0?²"‘Éh?\ ø?ø®à á—žã ~e¤Ç:-CpƒõäakÑJ@ÄÆ5#1‹Þ4Â29H>"ùƒFŽ>°A¤!b67ƒ–Â4Ølc$C6ÅÀï‹ø ­-ÀíE3‡A_SÜclj¦y‰´ð/]4ey|ÿ 4Á «–Úÿ?“½ø§Þ ÐOö­ÎdIã4^Vb?MýÝ„b)r^í˜Âÿuõ/ì\ÂøŸd–ü_ûqñdðÊÏF¼a6‡ÙÍ^¦, ú*M‘«+«“Y «ú'½Mõ›yþ_1tg† Œ«Æ¼T£`˜ÿÕÃaZ0ÿÑ)a?’h23ØÇ­°q:ÃHË2äãõ2ä㣨ŸÌ¥BâS,z•>‘R½ˆø7‡.Vj„•NTü?¢ãJã +†‰¢óTŽ.½E9æÌŒ|zØ™'®˜|yå;ü˳xh2%™ )žˆ«fÓ&£ú?0’s÷îç¶_ÿ¿÷¬wõØ· ·“kìôÕí쫽+ž·1±²àhþæÑÏÚü‰‡ç¶u‡ÍÍí;îå\½ë7%úí–{œÕ»—l,­Ã®Û†’`ß[óŽ—l;ØÑÙ¸ytSéýæ–ç±0®žëÍ^KóРÍwÛ†‰]µBÔåí¬-:¶¡hðÿ­y÷ÕÞÅG<μƒ{„µ…ŒØ[\¿y<æu¯+8õ¸ÃfËêÂã{êUâX™wl[Õ!Oò¯-oóÉA«mMþ‘¶»½ë‹'Z÷pëî^›¨mo¤tçľ=Ãù¥GÛ›Gl­î•–WŒí¨†I^¾0ìp7Õ… J':[‡ó›ðÕÃâÁµõšF 9\´N˜®.ÁÑø_p¶ `½X^À:€{}ãÑ·âº=éù¿¢réøÿM£Ù–e )çø3IK¥ClI?[6Â÷=ü<DržÖ¸¬ñ+€s@˃!6á?6‰Bš¯€ÿÁŠQž)µÁ*ÜEAô$O#®†‡‹óñ?ƒÇbÀ”€ ¸›F0€â´b‰%þ‡ öÂØ€¬d¡ ÓfÐr!7²ADˆŠÅE€„ÃØó/ð¼Ù¸¯ìS%óGp¼¾DzŸ?¯ à$+Læ‰ñRdUO£â?šB Ú)ÀôÑûêÌú”¦Œòÿ'5Ÿ"ËÑdaJþoÃÒÎÿ…¯vZ]•˜4J ûÁüµþ-ìc7ûbA~øKp'×ûÿuÙ¾úz>sj‡¿¾:Ð\–ú?Š_Zâ|Í«,Õþ—Q<&Ž»%£hèJ-Sœú„;Rq>讼4F Úã¢E0ƒ—¥À9Ù$'k)¤Ô– Œâ)#S‘4"R¸£â&q´‚2C‘oØÀ‡ÏG˜ÀÃj)iX* î-GÚGøŠÍ±RrÏJ"‚‘äÍâ<9¶>§ápqþߺçË·?™cþ÷T ÿ¿® ½0þ{ÅÓU؈Ì7 °tdøêàÖ7˜Üìuiýÿ¹<‡o1ÿg‡¬%ålá…Ê_W9Î8€ 0oPÐÂãÿ9mü¿MjTùâ=;éx™/òñE®¬Ÿg¿ ù?‰¤× e‰ø­ßIþWÏÿE.pá§^ä£ö™Ð) øÓ,Qk§ ,xíà}]`›8r\Ç=¦¸Ç_½`Á궬.8ŽùxÄåk¨ îªÖßÉí¨JÜøËû{ØÓÉ+‹zœasW^ñ1{{`þÅUµ3RTq’su öZ×°ô®Ù0ÞÚèÛV1æ5y9·‰÷tÖV­Ì «%ÖÒÙQ3á5m-žòêÖäWÖLp^ˆaØiÛWªÙ5´88/°•ºà0‘¼½‚¯ð?´¤ `†W\sO·àêÀ0ñÎö¸§Sð´W`dASËk‰?-åœèhhx1ûÃå›Ïÿ•! É_PÂþ“løc®¬+ígJûùá§þ‘T¥‘Ò€2Éhd’ƒDó×£Ñ)Äê“8>€:(=ÆL“!Ê zúKÁ 8¡8$Þ µ)ѱ0rûËL) ‚Áp&YŒýRìÈ¢ÇQûR5 ò‘ây¦±Ë‘AAD1ô¡ ÂÀñ‘4m’8æ ¢ÝªÀ®Á¾V‘U„KjüÒ²2  ÌxzbŠ„–ÀüÿüoXÔ°†§A%Iñ?”cÛŒ¢€T†¬ÿóµRÿ§áÅê¥ãþg kXÉ÷d&ü)‡F`¹èW‘ŠS`ÊcÀÂE7ä9Åo#hêö\0š`VÇÿšr Z«A,„ãà«ö#Ç¢è8Æø-ŸR€3<‡¡¦¥Ñ7t‡ld`BÎÄ”H¶i¡'R¥¤î‘”[ã¤ù#Äp>ÑŠL]h† b1áãA1V‰;"LNe/N:(ÎpÁÃgç‹ÿ)ì¥GÞx2âJà€½Züú¨VŠÜ3AÔRDŽ˜ Ä‹¶€&ÕHŠ ÒWÛ#2b0ÿ×ïþÏòí¹öÿ׽؀á_³¾™u/ÖSþ§üŸ{þ_üç€ÿ5Àøbà’Ïÿ¥Iû5ˆögSìàq˜G™b>gÊF¸b_ËÆ%ÿ? LËs„ųMû52Õ—˜K€ÇJÖ’élø1äÕ7ð—nÒcW?rSÇQ;´Äz{ çßÓ1Z`¹‡÷Xx·¹p »¥üP]­°«:¶©ìðÊ =æþuwÆü–ðOn¿ðÿ²5cë Ç«kG{š•U÷qžÞõÜ€=ܽÏ^]3jiñ­/º÷ÎÍGöÝÃÖUÍ­±;òíû¢E[„’²ÑuEGbî^Îm®­ØP|ä—ùãÓȲ;F7››cë ÏMkÆmîëî-(ïlŽåå ž®8biYÂÜ1ÒÞÚ±klÍBÁÖñ¦ÝÑåwßT2Þ´'ºiëx~ñx}c‚óvöô._ ì²çn®c¯{õ†û Šï:­à#w»ãÖ ÷E]ö–†¾Õùîié+¯>¼·>\ù¿wc?ìòí¯ï[³áXá–#œÇ&x1ÿY€Cz€ ühe8¿¸«ÀÆÿ@ø<À hç=À:€æÃèÐ#¨Tʰ4_Þ³'—]šøÃylèæŒô¾…ñ^ä`z:VÖÏìdyv’g¦â(FH`Q -NYe“d*+‹P33âõcÇb(93¶œÿ8z_2ˆ ØD£b6l3°(*³: ¹É'E{Á3ÁoEG=ö´Ã€ËýüŒˆÙ¬h,LãèD8Ó8#@Š”žÆ† «ªg¥œ°4²€â“y"SIÞTÅ [@¶ݨi9þG?ùoæ,€¤&þG_H}7#üÿ²e {ˆHbRx’IéÏúû!Q Uæ\ÿ§¡þTM.êÿÌó‹,÷i¦f‚gfâhd–8ËÜ=ÎÙ^ËìЗ‘î7#ûOEüžõžÃéÀqAŸið“%ÚG_;TUóGІ©HðO¦÷ò)Ui2u2¯]/vrÄÿœô?ÂY*­E¤ÇáýèO‡Ll1­u 9ƒ€³Èü_Òu/?§Kct+•ÂËr“ÃÆE þ©“,#òLLÞÃ¥“o (õFnÄË)Ì´Ï£ªÊÅË‘Šø•™ˆšoäx âã©0¥øŸç·åÜÿ¿~bà¨ðçaÍúþ/Àúõ÷mX ÿ×¼Ë NÄË7<9Üt†žãç5(üð HÈ?yz¸ã“83{ˆIj?ÿ§Dl}}°þ}ÞùÅhü¡éƒy/EÁJÓ¹¸žôQq³ÿæ]h³¢W™ÞÏà£Cÿ{¥ö=îÔ”~/Rßü¬€n|z¬ìŸêrXÁù leKkcã'ù žN¿«]p™7¼¼hMx 1,ðQP™`‰á_á2§šÌ_<‘Íž=§*rÿoXÿzï§M/GËÖ–c¦ÐˆÀ$çyYÿ7x;Òófô®‡"Ûâ‘òÑhããìÀçˆÿ§cQø¼æ%g5r×ËÑõÓ2ÍŠ]<^ ¥ÙxTÃñ(bYŽ,ÂŽú)g3ÓŠŸœØ†WR¦ „–sµøJ âGÓ1G$9EÄùóJû(=9EEá89§X.ã3-å'Ås¼¸â•1‚2°JòÿOaúü_M´Ïcÿ òüËÅ„ÉW"ÃWì r×âÄo:ù´¢+»ÖaN öÃO³ì4g9;GÙ8FIÆB‘o3d ¹?nŠSÛ ¼ó+€Íé’‚UiËÈQÀáóa§¥ï+k†WFè”ÚbJƒù‡R6Gå®+°^ª¢µ¦°s–ÙpäøÿzX¢-×ü¿rt5à¨ø\B³~ôÂ(X[bõEð¿å|0Þ/ž‹üè©ámo²ÿ+C¼zÓoGœhY&LÀŠ«^Œ^ÿÄð®÷8Æ×yÑÁf±ÔØ/OE¯%è,’Ç-~™×÷~IÎ ´`þ40þæg"þ¯F ãÿ5ç@~´¨ÃÝòläàÿZs*úƒÇ‡WŸŠ6žæõ_Êóåhç¹øO~=¼ì™ˆ8Ÿîóq`,{fÐøÝ§ùà?^›õ{eÙ~!—üކM~—zþÿ·ürpàËA°0üÕp.ã ÿ ¬ÿƒâ䛞4Ø­+ìžžCοD‹ûù’@lÿãŒç½¨ã]è…ƒ3C=Žp›}\¡F•„x÷[hxVÆ“aZy9CM2„¹D<[‚0~$îí’h¿-´'àšvdtB7µùˆµ6;êv´ßáÜÖ»k‡Flö¢DEåXÀØ[7À¸­ƒ=]u5#5Õ‘p¯³g¿·|»ÐÒ陼«ÙÛß0Ò´;´«&jnèïîmibÖ¦úðŽ*Á×åÝ·gðÀÞ@MÍhÍ®˜µ%_|´bÇhÄåä{»-ÕÕÌ Í2ÙM-#ýÝÖ–¦È=ƒ.ÓÈž»¢6Ï@©ªŠÝQ•Ø»'ælõÜsw À|scÿމæ}#›¹¡>â|Õ;.“¯´"^Q‡{Í{ý•UcMѨ½{SÉDIÅ}.SÀÝn/«ØakOSÇz»;â·£º‚÷÷Ú÷ö7ï‹…Í]Û«F·ï õ¸kª…!‡£±Û[?°­b¬|ÇXgÓPÞ–£[+ÇÃ½îššÈæÒCÖÖ>ÞÙwšã®` à« }þîNHþîvÞiâífÁÕ Œ²ÄðÃøQ¨ž V„ðFÈÿOå þ§A"3 ÛÖÏ–ôÅÊ"‘ÆÇ†ëáü Ðá?u½Å”÷1ÛüÜÖ[Œ–†"uÄ¢Ó¸æ$rÑãÑy›ŸrbLÂŒäÿOâ°|äÖžA@IžSüXNÌé½Íh/@2(®!3c¦¢Èá2Q¶¯´#Íì€0á:B8Í ÔGÑ>ðÐ8dåpŒ—[Π Ÿ0 ^ô£"§¥8$g5¢,Ktt)„dpµº’‰øDfR˜é§âʤLäŸe/mURrÚ>pUQª5›D¯b:°ffMùP%þŸ›lhXRÿ¿&ÿW;§UlðS¦4Ìl °…>nS+7´ÿ™ÉO³æg™Î§c{ǹ-Af³ix±w¦ù¿ÂÿäHa`ç¬@Ìû hzÍŸÁfdØþ§àÈ7í#f¦ãÄi¸‘ƳPŽ€H#jP×EÃjŒhàh:ž°5¤ãµÄá6é?+þµ•ø:¢@PR.4ÄIÉòøïE%Um") &EôÁž,&Ô‹§¤ŒD(£âU".”T ǰ‰U†ä +x&‚” dag›pÏÿ[_?OŠÖRðÞÄFCÿøïýÐÿ?±a±ñ?€lÁz€ÇäJ@§`¥ì ¾õ?áÛŸÁ„Yõ‡×2‡ë3bÈÿ€W Á¾òmÎt.žÿ/ÉYÝŒ¶ðׯÿ¯è¢ø±‡ÿסÏG2ÅÏàó‘ÖIçó3ôeñeĸ.\Û1a‹ßäûOÃÌ_p³õü•7=ǵþ†Ù=Æûøâßü`\ž&æLÏ<¾,çùJ31e/Äô=‘ðZ` „ÿd ˜ãØ “àÁcBQ+] 5ýµ» ¦–ÈÆÍB¿Í·ºpÜÜt8Wåf<ž@gO^ññîÖ€ßd½}Ä£#äér77×o~ÐiòÆ[[Ø[ïœpµ÷m)ŸhÛ(©<ê1ûCfg~ñ„¯ËYXrp_cmñn;aíôpžÎÓåi·­XÿÀþ¦DÏ>kUõAO»³xÛQ[«oUþÑ‚Òc0/ØÝÕ~7¿ìA_»¢<²r㉈ÛSZ*´ïgoÛxØ×å_Wô £ÝS\1áíö–•°?l7ùX¯•óvÕV µìcÖåòtõ¯Ù4á2‡¬ÖµùG\æ>{‡{ÐbÙTr?çîêÚë«ÜyÄcöÚ7¯9±oïhÞ¦#Åå÷{Ú{J*{;pw÷òµÜÓÛ´õh¸ÇU\6z`ÄÚÒ·iûƒ¾î³Õ»¶àAW‡/Ücç]qWWÜÝèÐäˆ;Ìq§ y`þE|ø¤4ÛY;]¬ÇØØxª¢ò©¥öÿëS`URXðg2²ï~®¬-égJû€x×k¸ì?Ç~9ËÌ…^‹Ô à£Øž#0ÏGò#’gb“Øù†ƒÞôDÈq¡ž(`xDÎl ¥úÎÈüæØo‰£Q Ÿ$®½ƒ]ô€¨G¢“bT‹uD¢f¤$D\óí+óŸawhJHâÔHqr1ÚÈ4 §°¢¥€£ƒX´K C¯rû30¤&ÓRFƒ€Äƒ ›ÔãŸ>¦ ñŽŒ³ëG2ÿd¨ÿC˜â´S)i `ƒE_ÿ?sE Å"H$ôù¿s³Pi¦Vä4SQ1ÿb¿ãͤ\]²æ§hP#³Tò¥'ÑS ¶Á†0Q®Vœ#C®üƒû'##:2(¢1éSVÅórö±xtV "“nXÅdxÕ€J(@›±IñÜÄP%³'eë0IìRöŠ¡ 8ˆtôO'ÊñR(²@Å’¼<ÆFºý9FüÝßRâ䃙g ùúÿ_ØžóøŸÝ§PüÿS;.Uüÿ¿úŸÃרW®ý}tì”É~ð8$ÏU/F1an‘ÜÈx=¦t=ÿ—¼®¼-|• þó @J|ž/G³óÿ%9+°=8¢¼ýÏ;²(þ¿ˆ‹ÿǘíóh°õã¸Þ€çsÁà|ÖüÎ k;w(ûö ¹ìòwÌÒ”þ»è·<ðF›žÿï8’7ˆ<ÿÐùÿÏ‘u÷Ý™þ×Ãÿ%÷ÿ'â)2ÿN –H«§ôMÃà×;l Çm 0!®ýdœ›”3pì¼OšžçÚá"ŸóoªŠNë¦P=qð¬å¸òO"SùP<ò‡Àï3a{:xì”öâ`u“àÁ ¿JM ;ûZšM5ýõwq}ë°Íº|õ‘üÂû£nïªõc1—ÛßÙ}óº£E¥Çºšlœ»ºxÅÛnÞTvœuXò7Å×nº· l ¾üHÕv®uŸÀyzº­ŠÆ·¥´Œu˜†¼øóN”íg=Àÿõ5ýUcE¥÷[î±Wîsµ[‹Ê'—yÕGöÝ=†Bkº¼&{QÅDÔѳ:bKùXwk¬¤„[»ñD~鱋smñIGkàØ]ÏZZ‚wMäm>>ìðró®Ê¡; 6K¿Õ»|ݱM%c³oMþCm ¾‚âÃÞ.߆âûXÙ¼×·jýÑššX Ë ¬‰ E'Öß¿aËQO«å¶ü+wŽô˜ÖÈ+<”_z”suo¯`€íãlóÞ¾ñ8ùˆÓ^º[™÷`GS Ð>º¼m‚dåiƒžW[Ü LƒN1·ÂgJ ”æ®%Ë'âòû{öün©ýÿ§Ã5?™É˜ëwLË1¾å8ç})ÎH{‘SwœxߌžÀ%qô°æÅ$Á$.ò“÷ÿ‹é‰ÏŠE¼Qv°œÜЉ)H0ZÃÙ¬±\'+ƒ·çsuY‘%Ä ¸ø‰ ±7¢ì¡hÄ‹Ð"(!ØáSPáÑôHJ5 §å:¥bä/g ˜Q\ ¢_]a!=ùÙbHl0­O¼•_od)þOð¿j Íê¥ir\@òü§5Õk5¤AÆÿ@þ_*ÿ? £J&ÿ’Ó¬pqð³~翎‹ÓiÁ•‘Ð9Æÿ!ì¢!£=CTö˜M™Ð º™\Òª¢ôä¯óAˆ±q‰—f¯S'³K.¦ÀÇ_·RWG„Ž˜®‚Ñ”ýDˆIõ3{£Ö¤dý¼`R÷“ õL““HÅü•ž¼d2pRñOqdý×XìÞ¿Qö½‰u½°! üâ1 q‚¿¤\þÓ‘Q#è’‚U>…˜ Œù?ËÀ(þò?,ÑVq9êÿZ PjûS•}¨þx­ø5„ÿ‰Uúqoâÿ¿)ƒëÛ}ý_jø_Þì§O˜/x9vÓÃéw¼ÃÉÑþš½.íYiüÿë2øÿ5ç ñÿ/ê"È^tð©páÐõO /Äÿ®ÏŸ2˜˜Àð@ Ü>Ëe—¿c–¦ôßeñ?ý_ à° °0€2S–”ÿ á?K‚ðÅúÿe·¡<€‹D¥¸ÝX˜¯n Þ.8\ (õe` ²åàÍGœØp’JµE ?^uÐdÍ`Â'¼bÀº£Ûy¯$E§tb žÎÆšÀÞ†DYI¬ížëéŒ:,k &B½þˆÓ¶jýh¨'ìj·ç•÷[ž×Ê Ãv÷Íêí´–Tœ_ÈÔîJTì<âkw•iÚÝWY31h³†-Îü-ÇXm[9ç0õ{Û]Eå'CÝ>NËe^¿1QTvdùúcíMÁÂòãíM-å÷7ׇ J®Ì?uÛÁâ3Ù Ê'ÌÍÎ5›Ž–Þ[±cbk[_—(,=:hµ¯-:éjóTTMðžNO‡'Ôë[»ùˆÛÆEMåP}¿±øè°Ýºjø«3Øouþ2ÿ°Ç^?î2õ­+špuyš÷J+9Mv×Þòªñµî«­ÛP<áí°U<à6ù–žÂ­Çª+#y[Žóî®ò ÎÞÑçnóå—Ÿpt‚»ÛnÜ©¨9Œ°¿ƒG>tyÛ€E x[ãÞh:0há×ÑÁ“lð^ Žoßx±ñÿ=ŸÁHûåÏE~ôäpiÖÜÅ¡ïÖ¿%²)×ß{š¿ö1ý9€Ìÿ=¼ö÷b0ùÈ̘ ¢š½H]’³ò|9ÚeoOò¿æ4ñÿ ?\ÞKц¿ð`¬)yƒ9ø?‡xë ïdˆÿO€Ýòl`öª£à-h$Ë÷ZÈöY.»:þß )Ãï²ðü_`¬Ï@¶ÀRó¿>ì'{ ‹ÈÿÅüÏ‹ü/Íš*Ó¾2w’þÖÀ bÎVL³öÿm¤"ÁìNG5t6Z+ĶöE@¯Î3Spž_4Ï‹˜ûçqè‹σ¼‘®%.U¶çpPî´’ZÈC³…Êu/ÅT\¹¸jY*.µ&§ òJš¤hDˆ…¾ÉI¸äD`ј§<æåÜFuM|’R™S%Å*©DËsœKêË{ª&$B©ˆ—Ôþm48ºªq"&?SþL6Ãì½äü¿"ÿ Š«_ž y3’¼.à‡Š€IÏÿdüãÞS5w=“Ëø…ä¥ÉVØÁ/øÈTÄv¸öSäZŸ‹3ð~i}œ) D7…¢Ý¯áË¢÷Àdžo}.«óü:§â”V~zy’šÁ©êA‰A2b9&6É%°¤2›ÊPSØG$d]–,ÀÅê'Þ•£hR¼Qb¯a.0+Íë§äóúÂYÄt¸„+;fÈÙ4 ¥ ܘQ&4$r+$ìO“s±‘ñÿú@$ÿçÞÿ/‡Uןjțظrt5xÝ}ªaàËÁÍ'·ÄÊ \¶Eñ?ì}‘™1nV©´óÓ§G©²³‡˜YXúFöZg"Ò5§¢ýSÇþG©ÿ#o´óÏ0wõàÿ;>ÝûW^QÍ^¤.ÉY©êíÕÿÑŸùÑ¢wÝãÃÕ誎þëØ àå˜á¸†x>SÁ5;b¼6žæ‡’0Vœ€¼o¦ïµí³\vMý}S†ß%K‡4 ÊYýO}Ìÿ’ñ¿<ùWÊH¢EÀ±)fà 6úõ°ûÃÁªû¹â ×ýtœ™á¢ÓÃMOpÅfk€·ÿ ÝuѼŠü5æ@œœ/L'ÿʬȧ™Ð“bäŒóǯ€öEøGé»°ó •µñv n ÞºÁÆfÞmÜfXÈÝźz—•su1®NÆi|—™sÁj?`GXWÇca`9XPP=ؾõšw/ã±s^ 㲄­À¹·‹÷˜`a›‹…3 tÃ@žÎ˜ º;æ²FÎmfà¡»£žÆÕsö‚•ŒÇ±õô[¬JÔÉzÌQg/Øžww¹;œEÛ÷Y}`ÇÙ>l·s®¶ˆÃÂ8º"vk dÔÑ=lëØÌŒ³3ê0Ç1gç°ÕÆ`´NâIˆÐ ¹¸‰7ú Šsæ¤é„P<#N-$:£r®"œ?3A¡Ë5Q¸ØEH{á P6Få$.TŽ•UáÅŒc9†_Î fÄp ËÈ’d¤P"W#W&FÁ rö1;£3ÐDû¨ ¿ã© ˆ¡^Œ”Z£ßTšº¯dÒ.̈§Í*•iã°Ž131M ¼&n-­ŸÄ\ôÿ#þÇõÿïÞ{j×]Ï,}þï¬ñ *Z Ÿ”õ³E~¦Ð­9ÈEÿp¸áÏbà¶Ìïit[6p¿è²´´`Ö_Ðÿæ2äÿj @9æ*Å«ãÿUcYÍŒÛ(D‡Ekq+\ÿ?àÿ=ó•hË1ÿ ¿éD­Â“Å”ÿ¯@½Ê¾ÂÜðäðŠç#}“÷ |køÞYÀôIëW ÿ+óÍpj‡¿ ¥ôÊ PL*â=Ý„ÕäJül}‚g¾BvA2þ,Úp„)ö1¥~ð/ê1ëlÉk†AA"ÿK„ÄÛÍÄÏ&ôﱸª¿»yòa:ªài…¯îX©ÎNÕŠ¬ƒ6dà™ªïù«q4;ÀõUëÆ\áUåÄl}¦&OѶc¥eŒµ}¨¶ÊgjfÖçs-Ìmyc1—“uw²Þ£gEÞ±Ö¦HÄîX¾öPÃîDŸ5ÈyMþNÛúâŒËÆzº‹Š}½Àó+óè³xnßx¼µiˆõXVÜy¬¨lüÎÂqÖk«Û9ÔºŸëiöý²àÁ}{c1·™ótØZm%ÛŽTVF„‚’Ä®ºx°ÛSV+.ïi÷u÷¬->nkv”W¶¶¸ Kí®*¯w™Íõ¡åyÇ++„]u£¬«ë—3Kãî¡Æ»Gwîd+«zÌPK ø)(Ê*Y;ûy˜@ù¿•÷µó>`7¤o‹C» w ¿x‡ð?.ø.0Z9ht‚õ<š‹!îíJ > Žÿ'‹p.uüÏ›Yú›pó“‘ö“Ì®¦zˆëz”‹}%Hù¿\ø}¦–eêX.ô>›¤y @&LœTf•圊F'áa19ºžœÖ3);qîb±šâœ%\OâIˆä†Rª©H;¼T TLO`Uµ¥Pay|A8À$À®K¤$(á $u$ÉÀ”„ˆg(se"úW¦2{W„ៜJ]T‰½_ çg‰üQWË—Ký§åÈ%ÿ—W‚=ð—Õð?YÊ܋äÿ=¿¯©ýÏœÔÿŸ5ZnÎ#Ÿ3Þ·Yï»( ¸¡äpë¾ÁµùO—¿gŸ7¯ädY)kmÔíššÙ¼‚ÄŠ 64ŒqînÞc.(æ|æ~ÆaY‘÷@ÓÝ‘¨Ëé6¹+*bë‹'¯ÅÞêÊ/{ˆóôðîîMʼnPO˜*«6÷xVœhib¼=wlº¿°4±jÓ Îc¯¯‰¶7³œ§×Ü(Üzo}Ãï¶ØZ]k þâÎvoQI¢Í0hëÝÛØ¿|í„õ@p]Ñ [³»¢ê°£ÝQXö`ýΑòêÞ®@󞾊÷Þ²öè®Ú1ÎÕ³fÃëîiÚ=²·q¬ªR¨¯gS}ÿ¾½QÎÓ9h³ßÓØ·|ýý#.ЧêBäo‚‰xºd|yá¤i]šOA¨Ð5tcÁ5<)ðš'Ñé!Õÿ¿ûw•;žÎIü®¿áÇ%¦ vZ`þ ­WÙÉ/MïÅ3ÿØ/o¤¦†!ØEÈ ¨ƒ)ზáS[Lkþ@ 0XnZ®Lª꓈…t âŠÅš!3xÐmJ˜¤ f¨ª”sR*"'MÄrâ,¨,#U âþᤂ$œÂBò…vªS¼—¸¯Î$§j¢ú5üõ#ªy8)!—OiŒ..(ˆ¬ÿƒ­õlÔii R™ÒW7s9F©æp)`¡$ðëOñìäÞÆß×.yüO&øÿYœxVnภ³Òè-OvµC5å€H£€Àû Fé4&YÞ(D™ÒÁ¿:‡Ÿá‰ˆq6:%¼rPϨÂÿ´ìù——ñlÎRmŸiÙå® ×!ýóêûÊd¾,QMWNò5ŒêQýG"ŸWñêOË7+MÀH^^š‰›“f –ï ,§AU%P«®9˜’âÔ3 Š¿‚d‚áDuÆwÚ˜ÿ¡ÿÿ×Wÿ/„µ¨¨®jþ_{$o^ø_;ž—;þ—J€Jš 1i ”|„ž5¸° ÖƒOÙt†2Œª)5õA<$Ï ߯d—],ô8tY»:yŒáA¼ú.€£m¼»=î2‹ëÿ?{oÜÖu§ NÏtÏÖ]oþ˜ª™©W]ý*±“î¼÷:ÝéLÚ‰—v;~Vl)ŠdIEФ¸‚ @  A¬b_.@É–ãÄñÛò¢H–%k¡D‹¢HI¤¨…E­©…¢¸S™©©ùÎ9÷^\,¤tËݳêêââà.çž{Î÷ûï÷ý¬” D0ª6A– þ‡9Àì ×ÜðÔ³öf˜e…-«Ö¼¶jõÖªòä¦þUë¶ÿøùW, mϽÀéUg_x#jmÂß_üYb]Þ6<ðسonÕÊýyyÑ‚MÜÊ—~ ë jmüÑŠm%E[U±çV¶ÿ<ïW*Eôñgßh5Øÿñ¹ß¬ÛôK‹ÖóôŠ× µŽï=û&gk*É©ÉF¹msÁÖçV½¦q@æUÓ†MÛò6F•²ä‹?ßú³—~Q^Ý”ÜTúù_Ú4ögV½iR˜ô›ϯ|­¶&XZèv.&©¬h+-ߺz WTL¬•®þo”mñËd[ òc+Öü¢¸(Y±Åÿ“U¯m}im(?¿ýÙ±é²Åð<]JCM4 ‡2á¨ãΡe4*²ÓÎêLü‡ü‘l$]ÚmLÿ3E¢N{î•Àÿù{&ÿ'£ãeêÿ xÜc:ÝgŒ‹ÎDÃvLjÝ~Ÿ±‰ó'lö›VvÞðùÆùÄšLÍFBÝ€!íÄ7>…ÙsQâhù‰7˜rzE  >#‚…)iaš2œRÅN*ÚÏŸb:œ„ëRÌÀèýÏÕ™áDN /‰yĨ¾(É/KÌ f O0ˆS]D18‘9ê“|œãœ”ö“” û‹ _Bò–$5Ór§oEöþï…ü³wJM‰xœÏÎ@}¹ÂW~-f#²¥Dâ•äD[Œ?&€%vmÔÿ?MM€©ÊªÎÂ’‡£ÿYß/$b~qIÒ vèñg?úÖ÷óìêƒï]½éÚãÏíþþs»ž|awAY/îK§¿øäO÷<þü®'VìÕ¯£ArD`¥Ùd¹úSø?—ð;i±Èÿâ|Å×g.ƒ»ž–‹ÃÕEIØ.-É/Ëù51ë{Z0¨ÙWÚÃi¨ y1#Óœ˜G,>+UõLH Þ´ĵ„·I ×%›Ég1+#=Gp\”!âÃXHÎŒH1„z˜µ2Í<ÿyžb'H±ì{¬»F§Aòât(90Eœï‘·ÐãqAñ !åÿ/¦ÿÃëÿWTÞ˜÷ï ÿ/—åòo­üøÿ_¶|þ×Jõÿç¥qš)‡?Åÿl ‹J}þ‰Ÿ|÷ÙÝk ºýþIòõ…OáÓþ¬£B~.žªRö?ùÓ½ÿtßS/î·:G³á_Û'k.{ U¨lÕÔV¯Ùäl4ZulØu¦˜½Ñ¦knÖ›‚½£±‰sèíz3çhð›üj0ií6½ºÙë#ÖF¯Ù¶Ö·šÌ“Ñ©orL¾&ƒIcó›Íq[½ËhŠ4k†¦VSgךêqU®FS¨©Áפ[|f®¼Õ`ÄÖƠÅhjpMn“1جsÉa}æFsCSÈjH8hXùO¨¯a$œ‚ Ó‚qì±4D,õQeÜ€ °ž°³jcVtÕo ¼>‰™èKU•ùù{¾Äø_I!{º\Öûè÷ß|ôoýû¿©Pž±;G¾þø»ß|ò]ìù/Oïh0 ›L—þúñ÷}üo=õn‘¼_X|Ÿ£žÿ”—›wZ Kó4Áê)|+Bš™v¢‡3+ТÒb`*n§b˜IV3=e ž3ÆË,© ÐÎd6ÝNa™¿ØU±+̈"œM¦@Ú\2S¥G äL‹óM£vKÅ^rñÿ3”ÿyÞB:Š“iþÿÅðÿb‚ÿKÐRº¬ï£ êGX¾7Á6þÑiº‚#] È\`#¤ˆÿ㱩ÊÊ£Ïÿ/¤]x „3d › ^ïø·{ë©öTÈOþÍÞú醃Jõ…G{{CIW~I×7þñÍõ%=ÊÚG¿ÿΆ’c2e‹ç6Ç-,ÂÿOËÕ(ú™ø?{Õ µPKý̒屟d)‚.œ <“R¾¤b9 ´%ƒƒHà‰ ¹Ò´}DU$‹”~1H?=mtŠöŸi¹p)æX"m4 WEƒÍé†àí§±ç‚¢«O¯96+]îtš—0ŠçŽ Y£S´ÇN‰îšP |šÅDèLÊ,Æg1þ¿Ä°%d`Šÿ7ä/ãÿå²\¾øŸñÿÓÔþ³˜ÛXìŽÑoýàþ|o~YÏ£?x'¯´·RÞÿèãïæ•[±~ÿ7Ÿx¿Bqfsé ì)¨ì-Qx¼.îI.žLüŸs!`K'ôÆHü¯>É+ü7PäOƒR ìWS÷~=)„£ÂÐ~}ª¥äÊW¡Îmæñ¦@WC⨣Ö6I¤¹(IØïºÙаCÑs5ð4bH5 _'ÉêÕNr{12 ö“ãPßx}Â¥&Ö¥-™ ¢DÄ‚8z Ô¤Dü•9{#êPM‚Ã9üŠOòk*o<>ñ_ì!pÞ; qÈ«°Aô|èG/†:öq45­VŸ°3Å~RXIDÃ_ˆ õÅ¢àÛ51k}¤§SG-Àÿõq«_£mÌV‡¯1+¡Q+ >éþÿM2™&¥(YñY¨¬êÌßôñz¸Aºù‰ 1tÿ¿>ùΊ¼ÃáèÔ?­Üõí}`wŽ>úÄ;EŠÓm¾»=·ó~ò¡É|æ€Ls..ˆüH´5øù7çÏ ê—)è›ÁxÉÀÆ8ɬ<¹…|ñøŠ õ,h=Ÿ ³%×L#³¢’E¿™ËlIíI_nÈ‘Ò+ƒxœ,¦\ø_0 f¤â?ðÿ [6v‰tK¨ƒŠ ì  Åç({Ž£cMd0ØÏ?µ ¦…Ü éL$‰ÃþŸ¤Pø²ªª³¸dÿCãÿÏåäщÛõºÁG¿÷Æ3/îÝPÐõ_žxû»?þHYwþÑï½­Ñ᎞^±ë;Ï| Tžþ1ÿHAio8<‘™EêÌψH×ýÝb±Òítüœžš*‘)SŸž¦J‚ÿ%Š[´0¿ú CËœ6'Dñ«øœ’çDŒ-"íl,vy\< ÿ§.;NíÉA¤”›ts`N ®aVPú•ÜT<%Þ+TX¼ —x#³"òOá¶½Gú_5Ç[µÔQáNi}œº–/v©@H>ä_ '=š“/u1[}ÌV±ÖÀO‹– ª(±Ô1›*Ú¬‰ZÕ@þQ+ÌuÒ¥Þ|'KG=e»UU~–¿qï—˜ÿWÒsâ³vûÕ¿~ü­¿yjÇw~üÁ7ž|ïk?xÛbùÆ“ïלÆšWÒõõ¼ÕÐ8ô7OìøÏOøgw,×9!3iº{.Û×AzÏ™÷6‘S SB°áÒL£ü#r)–ŽD<|–EÔC !È“2ªOl:Χ Î4gx.qê±#‰!Ã6D9ÇLO.G²§ö4Ê·øÓâ)Ä…y óçANäŸÓÕçó¨² Šç³Læe Ÿ¥r#!ÌþÇ…O|–7²F ü= ' úŸ”ÿÃøÿDÿ§òèæ¢ƒÿ?X$€ìTןÚögŸ¬ß|d}Ñ‘¢²n¥úÂ7¿÷z½n(™ùÉÊ}ûÔ;rÅéoüã[Ï®Þ÷†ƒÁà¤x_9|v8@–ÏÑ¬Ž‰ÄBz&5)¢N)ÿgÒÔ%*@­=wS`˜gˈZ„ô¼ƒ=]W‚¨§.•¥+6›.­Ï:̈ÉõÄR Sh–‹ÍI•{ Þ”=ç…ÏIÍ™”n°4¯AL°hbb‚Ñbâ½Óç* é@Gƒ(Hðb1Ž:ÿ)}ˆ-lq"þ_"ÿ/7ÇãÿÊÃy›–ñÿrY.Ôø_¢ÿçr&ÐL͘J*ª{ùþoþiÕÞò­ÜtxCÙñ âÿßÔt-œ|rÅî¬Ü»¹¢÷ë¿ûìºOWl8@xÎélÕ\ÎüLØŸúÌþSÎ%®í`BtþÛ™÷»–Bb5óÿ ±«uIž£^O¥l®zßJ –2˜†¸&yf{m‚m“€Vm‚÷À×S÷¾.I ±F Æ3·?­@вΥ3>¿z{«ÙûÂÏ·*eQT—¶½øÒku˪µ¿(*MnØÀ=¿ú×EEɧ^x³¦,°bõkºZÿŠU¯<¿ú?zñ5½<òäŠ×_Ê{µ¬0´.ïÕuë«×ý2jmjiЭX³}}Þ«ª²ÖÖ¾Ú  å½”\½æåª’ȳ+ß,)Ù&.ש¦_Ù’A=¿Ó€¢e¤¦šHÄ ¢Êÿ´ð¦D¹NjžØÕq›ïɾjQ™€"¤Žc¿½.f×DšbÍ I§nkäp2ñ +Ö’|UUŸåòä;›«û ^Ðùè“®<úÔŽ¼Š^³íš?4ÁO¾‰,ýt(Ûž’Ú(=ÉÌÀØlnL*t7!ð2J3ã$ˆÎ$™¾i>Ây¦)DyÊ1eD³IŸ“ÄóòiFYR³ f#$³ ¤$ >Æy¦pÒ‚yE‹¦ê>æ³V„UfGÄg²W„\Küú…]ó’;R{?ÛÿŸíügàŸ}f[ ÛãWfà,¼r;áÿÓ5êåÓ5‚ í)øG¡Ñšÿ?>U%û¬¸ä!ò þåGf§sô›½ñ£•{ ¦Ë ÕµnX©¹øèco*µƒºÆ¡oþã¯Wl8(Wœùú÷ßÖ[®“t±‰Üþ)ç?ÃX"e@ö¡RDMNJìOËF—%þ#­&wŸ¶ zÑð/õ–g’âÒe…ôÐÝØlº=/˜¼óœuž6Æ›ó¼É±°‚_ˆùåøp&Þ§žù˜ç¯œ!!uHF‘®z ™¤k‘tè˜g—DÀÄ[Ç„(íöÜðÿsüû>[Qñ9 Ëø¹,—?üOÁÿÖöy.]y/›DE«|äûo­ÎÿÌÝrG«6˜®—ÉûùÁ½éоqø[OìøyáÑ¢²Þ¯ÿàVï].·ó?7ó?c-`± a'¹ÚXd”³™¨¯^ÅËþØtÄ1n×p<ŸGC9<ÌSwº”¨C”*y ORzÕS!ÀjHPùPžêc§º7¤!ç$mzzØzj à/ÔÏvC^¸ÍâãFÂÞ±7¨+=ϯ|¹(?úÌÏÞ^»qëš5ImuÛšõ[7äÿrݺðªu¿ª*½´–[»–+.J(+¢EE[W¬ÚZ·hO=÷úÚõ¯º ΘM'/ó½²jUÒ¬j[»~ëÊŸÿ²¤Àߨn-Ì‹: nJb« hz>µ#óðk"l›šB6ÊŒ²6P¢¾ÖqdE@M×ê9ž³D7œZfûৈU±4Ämâö·4ÄlõQÀÙê(þWÇl 1âÿ×%ÜövîVJ_=…èx›ø?/ÿ“‡Èÿá²õ,†%A„j¿¿âÿyjǺÍÝk Ž>¿î`KËØ×Ÿx÷™µò·tÿõSï>¿ñ°Årõ›OîÕ‹ÇÓd·¥ëï¹­€\¹®¤ú{4%îsªg,åKTDfEå!K׬X‡×Ld v„Š(¨Æ½ ¨81@6—R}¤·¹XÉ\IÓ'I7$\îLç¿JÒ[ÒÄ9“¹å€¤üŸlü/ˆ”¦­ÿC“1Ú>”=Ç|þ Ö#(ÿŸÊ# êÿ§ð?7]Uu´¨äaùÿ©É–3¥]Ê9³¡¸óÑï½ñÈ÷~õè÷^_[ԥМ仿úOÿú#ÿðúÓ/ìòxǵ<ö¶¾é:Ó5ÊPû_LÿiC@:nKëd“„@€ù ÿ¿üÏJòÿJI;,³Þ¬tQ E§‘Â{Bó YÀÉóâ(ûÇާŠÙŸ“¼/9¤~ø(~AbKÌ–ö§ª>±”ÜЬ$NAÿ’›"%µ Àcþ„¸–Ÿ•/q¤´÷NT ŠeÑi–p„j³•¬éT'çñÿÒúŸ³íIâÿ¯ü¼­eü¿\–Ëþgñ¿þÿœKáÈô k?!±“ÿø›G{gCIweMÿ×¾÷Æ£½ùï¿ó£5û[ÛÆ‹+N|óÉ÷¼¾{9k–âù$3U@ .†ÊÙÅýœÍÈ´()¾Õ 25 l €"y-!Ã8ñI— zŠoi¾0õÞS??!ÿ7Rf>¶I:Ý$©cHÚõô/:Fïçq¾½‘®g{ÒiH8uI—1áÔG-+¾M£ gÑ**ZÖmØfT׬OÊ*¢«W'W¯Ťñ­Y—TËÛ6æo3©[«¶øËŠÚje>Ò·:ï•Í%[U•~¡¥²ÄŸŸŸ [›ìšÆÕ/ý²°Ó)ì6¾lÖúJ‹Cù[ÝzÇæ‚í !¸€Ýǃ­DhK„§Dn–îl'Tÿú/õƒm¿^@ÌÆùgËõ,™æ®‹Úh´¯£!nòo@‰YbÍ„ „OÜL~J´X¶Æû’I^b]p>HHl:€¥üü‡ÈÿY<å“IŸw»Ç~ºaÿc?ýí³ëöU©Î¶yïþxí¾®=ðß6t”*ú1i¶´Œ<¿þ Öt™KQYf2 l{ -‹Èy6Á—9ök; ¸{)Êm§ø?] 3…üSZˆ¼Ç{6)…Ö aÒ±0äy¡þ¬”?Ï„8‘VDáS;/.áù÷’LÌŠŠ??¹ÁT‚pkÉ\ ÿé6Ñœ49QêïLp•/ó§ãé@”“0Ÿ¡±™2’)©Å¸@°Ÿ%{Í^` Ÿl'æ9áhiCœ ³Ï%Ò RññÂbiø¿«¨èÐCÕÿ\\æôÓö ï»Ü·Xìg$2ãóOøýã”øAn'™ñúÆ™ó_DìÙø1» {”^Ü(ûxZWÚ*@b6—ø†å8—ì9©'\døHñÿ¼(Å#hXÍKIø™´‰ÿ\(óÂ+#&ÂÈIa’¤êŽÏåì§Hz’dÙ|ü3$”~)¡ˆÝcJÆ?mñ"žHKFóúñº¦¼áO:Tð°µ€XlVÌtü7-«5ñKRUÙ¹ñ!àÿoúöžm|Û22\.ôý½}þß4ÿ?¹$þç2Cð0¤Ø\#Ëe@ýhtÆï¿owÚ\7½þ{lÍÔ˜p¹oŠfa5'Ô_<ÈwÑõnI™å‚½œ»-ak¤!º ¼ܦv¥Á³ÌuO?Ç¢k:ŽPñu-; œ ¨^Ÿt øw9®'•i}R®FÎ¥çð/òÕ@ö8±aL8LŠÓ”pÿ›. ç2r.öÐOr¢98.Ì@¦G)-ôÇÍœÓwÉq\¨ÜD?…ÿ:-œ³‰s6s+ý©9áÂÁÍq²m¦Çžf|r-Í6ˬ £Z¥Ÿø‹™l¸ñµPœm$Ɇ™k±&Ü6²Çm&¿º-ø×b"Õ\(¨†¿Ø’n; ­‰æ¤»©üõmÉ'ÝïH¸]Ý`•I}-éimüª»š èHå-·òÏQ&;š_ðÉ—Âÿyå,åc²ð@š  À(ÈD‚†^вžþÓœh´óeA²“éäó|DŸ)r§š‹âùä\²? 3’Iº“À`ò™H}ee¡96Ó9Vxdž”DЃ¤ïŸO á¡2«–œËNƒ%\H¤ýWZ¤ÄéíÆn¡=-À6u|¶/¤’‚Ñ…?©ÿ?£HL€¹Å"‚ÓµÈ$¥žK,´«ˆ;3ÿ/ÁÿÓ|þ/n]ºxËÁ‡Šÿƒ%çÆç&[Ì„—vòKrÔ‹¤/ Ì/Qø/°8ü–Z¸‹Éõ¤ õ/}œ? ,Ò½Ó"…3ŒN"$v2îbé’Ò J1÷Ò.&ãíËy’ŵé |–7¦ÿ™LÌVUtæoüä_ÿœ‰?Ñ(Zœ_.ôý½}þß…þ'Ãÿ;‘%³¤‡óñØ‰Š“=¹8Ì›Y®ûżI¹sY~±0@A°ÃãÝw;ÁÑO¾$ùüv’»“$wÒ7Ø~Ô¼“à?ÅÂþKvÒ ã‰ÄÝdân"1N·ÇÛãIº‡nÉÄ=ìOâWN¨)²sœKLp¤Î}V’‰©Db2On2ÁMÑ |N“Onš”Û˜I$føÏ «iò"*³Bp(ýUMˆî¬DŠ^"™wRÞ'I²§T™éZòÉ»F(!IļÈË¢Ù¢Òó ñŠ‚_šÿŸËÁÿYL8ŘäŠΖ«%Ùè~—öÇdÚË&™LS)(ÅÐT’*±2¾JÓ§ŠÇa;yÌ)©Ÿuºäâ«ù’k[à Ø·ÉÞL£ÛIþ«ðV E<‚°ý;VÚ%ûy¤Çê‹à„ðkòAîÄiæ& Éà ‰$ÄØÒ…ì@€tç¿´¤ÙÙ‹›¢}*i¨4s5g 0¼SÔÿ?“òÿ?tüÿÅJî_Ìu¿˜æDÌg)¡†%ÖsiÈL¸–ÑUø¯lÉ ™½ÎûÅ‘yFý´6‘èe¿æóâedX.¬'Hóð’eÄÞ˜­e—&•È̲~ƒŒÎJgÌ䃜s_ú Ò ÁJ.éA2íeY¯3Cá3™\ŠÿÃ1üŸœ­ú<‰¶? ÿãµúö'Ëø¹|ðÿ'!ôvôùø?¶¸zvN ¾ÅT¸sÍ; KpGÓÇÏ¥¦¶lóDšè‡tS9P~¿².øeÔˆ%þù™I3tK·êbaνœŒ¬ì„§9¹[ÿܫʸ¤Œëœ± ÙÕÌ níiéDÿÿ¦‡ÿ›á/]D;=Srö‹„¥H;-Eæ¿£¶mîìH‹‰%Š6BF"ž,iî¥~ý½föœËý¢×=[^º!ùú»œ‘ôŒ¢¹[2;e•T6ÝX—˜³]¢µ æºÍÿ™[ÚÈÖJ¦2ìÆÒ%€R¿Â ¦ü–KzºZv´¤øaçÿ}ÈÁYÊ™T=—»¸hg;íß ì‹ÎéÏáñûBádiS"—ý"õo/a¤€wºí&îYXDbz!Û€•؃/ëœtFOæ˜Ú¤ö,vrXIO í\º K¼#ã—ž¨]lÞŒ™·hRæ¿ÄøÊ12Æ„¤ˆÿÛ窪>Û˜ÿ/ïÿ_.Ëe¹ü÷ÿ/ sk?ÿ/5SHËb ÜKç÷Y x/>i.j_,qG‹ÿs씜 ÷Ù¨>§Õm,}9íŽì Ëi˜¤öäÆö 9™³µ%Y¤àŸpTáÿ| þÿœ¿ÙîЬ+Í[Ë`¬IØéYP·T^¼ðñÖ­¿kÏZGȵÄZȑ͓ÉäN¿.š÷'ý Ídm-¡ô²ý#çr^¶Í›ÈÅ$xIX’ïEtÒJÂK2|RðÁó&À¢.¡Ç >ÕvvÞd*A’_I1”bü“öáÅÿ&øü¿‹gµX4ÁúÂbäŸ%@~N¢fö6³Ä×!'M(™LËžÛŸCò|°ä­-d9ùçsv)TÆ.f"-Ñç—˜ÚËn#QµJ 2ÙÍž«¥oIÚ6e¤[å ÙœŸl=[ØÆçÿ%þÿ‚eü¿\–ËW ÿ/ }s®¤/2œµÖlûðù—ß@ùoÛ–*Ïmûµ¤d|ýµ6qæó¯ å·4ÈÿâXzi˜1áætìgüší3ÿ\ðŸ±g‰öÏýß%¿Š‡ŠK*ü-“…=ÒCÊXX*(ø2ãsáÅég ¹œo¹BÔ¿ ^r ÿ‡¹þx·d{o!åߨ>)Jp’EÑ.d¥c`ÞÈ…%n?;[_ÆÁâvýR v9ðþR6Î_|B¢Êû"K³4þq–áÑ6rgHC•ô\â„gòm+òÿ£"ÿ'>%«ê*.>ô%àÿ\ýsQêÚp—õÀ\Ü•ÌN•“qiõfÉ+Ïód–@Τ¤Äæs²õ8.“çÃ¥}ÖBz²øD \~€…¥ÍœŒAŒçÂ¥ó—[ Éà2™Ãë•1¹·4í(õôSZê…âh¿‘ð¬x®]{м'¼;ÂPÀèX)?Àï2×· üæÿß´Œÿ—ËrùªàÑ9–19–l=ôÍWœßx9wa?áséòg¯–ýw¯ý3Ëúö]™H5wÉvÅ“Aõk¯4ÿŸÛ~ßòÓmoKÛdiOx„Ÿ…ÿ‹»Öÿ™öHiÁ Šgï—ló'aˆe‹1.‚è¤3 »ÂÿÈþÿ/à]XBP=\q™\âEÁ”2™É‚üÿONRÐ’&@Ê^H¤Üã)Ô‘ÞÎiŠéšq‚R²ñü’í³ ò+Ò}˜óÂed§x{Ó¶]"‡WÚy“ó©LÉ´ÂΛJéËÀ?+Û3œÏtþÅ|¾lOúŠ@Zî`á–æ–¤-$¤øŸ›’ÉmÙÿñ1´EVßQ¾J=¾”›H.JÖJ&s."ä^Vz¶ù²…'‰ .W¥Hú¸Sƒa*¥„Ù(Ž?s\Æ3J.¢Ë‹Eg… ¤¤2Ò¤{Ô—ÍJo´…œë×Ùnÿ´“Z¹66lÛý¹³á_~-…ÿ…1!!ú0\´³…?> CØÿ =:IBþ§É€(þ?š¿ÌÿY.Ë嫇ÿ3ʪmïýó¡;+ÿõeïÏ·~°zÛŽ•¡×ðIÊÖ«bo¯Š½ŽÕíï¯Þú>ÙØºãgüWl¿‡Ï¯½lÅß×µïb‹ø1wLé<—J³Î'?ŠS‰é¸4d•~þÅvùpÍOnÛãñyŽý1–Aâ8÷ !ÙlLÙvò5I?ÛIÌkpñø¤Z” l›™Xø^Øq1#CnÍóØübò&,¥‘ˆäã‹XL<ìÏÇbóRBW†õ·˜iÀ¾Æ2Øs““ÓæJŽøÿ»6|iñ¿¹âJ¸<‘PpÊã¹KAˆ› Íç«·õ®¤)x}wÑV$ñ£MvºF=­ã"»iÂbœ· ¼”E›éT´˜†™9ÍI4ç£áé¶Ö;L±­íN›÷''ôù(MWMÁF(8ÑÒr3™nóŽ£N00áÅØ]ÇX"Ô9ÖQQ<î1ö“¿ ­1“$}{aâ$ô,h7rñô^Ô깋̠ø¼wÉFt6J¿qòÈ\,:ðO0¹rTv9Gˆ€˸㥩¾:‘XD¦¨¾úŒË5OF#ÓÁà}»íZ‹k$à¿çpŒý¡àd p?èŸô·»Ø?á÷Ýkh8ãóŽãJœŽlDÂÓA"’y/œ ‡îã¿¡à}¿oÜh¸èvy½w$™ñÁ¯dIñÿ´Lv¬¨¸ãaæÿÍ‘ùíc³]‹F§››¯÷46g6]²[¯¹]£èVËeƒî<¶½ž[Øi4\`Q*O0Dm·_óî¹=·<žÛfó¾â¹ã8áð”¡q  N¸[Æ"á)ìñ¶ÞÆqTC‡Aƒ£‰X¶\µºÏë½í÷ã§ph׃mô:ü_ñàðŒPÐÔøôßóxÆFÆÃæþxdŠ>è™°¶+â¼¶EüwÃÍöÁ ád¸åzØ}ÓoèxGCÚî ž¸ûf¨ù\¨¡'l>‹–ñO„[n„—¦Sa÷õ¾íi 6öEÚFbÞ±HðNÀжœ áÓy%¼õŽQïí°}8l¶\ 6 $Ò¡»Äš–ÚÈiïfj*1ßÖv7˜àSNP; ÛÓî¸NòÍ…§Ð\Á ZcÞç'r¬¤M¦¨KdÞå '|þq6†xZo3üÿ¿mW>úŠý”—QløÄW”ÿý5~ýA4‘a­K&»xû|þ{i¾‹df{ýÿW¶ÌÿY.Ëå+Îÿ!øë»m¾— ËÍoÔxöTߪq~TezWîÚ©ðì®6¼ªôì«i~WfyWn~­Úò®Â{¨Úü¶Êw°ÚøFc—ÂóiåÍ?ÛNüÿ+}¿Õw„]ÃAÅ{~ËÙˆé”ÏpºMy Ü|´­þh¨î@$xßW»?Ðz'b¿è7 Õ~ãÙêÀÓ‰$þ¾Ú‘ô©ú,C~õÁˆÌ¶©ß«=Tu†õ=>õñ€©?l:¬ø¸M"¬ü”óß$ƒ!™¤æ£û ÿ+m{Í–:Ó~£î]óA³y¯A÷¾¾îMƒeo£úm³yŸÞ´¿Ñò‰Iùæ‹Á8ê?Þf5 øåEÝýõG1×øjöä»ýú“a]GÕå¯ümPw8 ÿ0æ¹´•»1Ýø4¡ª‚¦þˆ¥ßÛp"¬ëDýªa¿ü#¿ü“€ücÝá ©/¨>àSã×N_Å{hŠˆ¡3›dL)´6›‡ë5--£î–ÑfëU»íf“iÈj½0 MZ­W1 ûÚîêíöë6ËLú¡ðД›üq ˆH]׿`ê±Û®+'°S¯;œ`0\À_tÚ³@Ëe«åJ›÷®Ù|Édr¹nâPMæaÌ\@Y@8#ê4™/Û­äD Ús8ˆN{Îb6/:7Üî[9ñ?›àdÕ]…{¿ýÏôn^^;àöÜQ7\Ї‹+Ž—V÷UÈzKe'dÊ ÅGKd§¶T,SôWt—TõUõÈÔ[d=›+ºý‰Ö*­Pi‹*zjµƒŠÓ%•Ý+Ö}Úä¼EÒîôµJx)ñ”…˜ÆÝbS”%¥Û1 lfR€¬ªK¯;ßÔ4 kW¯ÔëÏ•–ÖÖŸQ©zëëûZ çkäÝ&Ó`Þúßj5ÀÉ€U&ÓÅ—^ú¨ªê¨Ëq Z­:\YÑY§>UQv¸VÙ«Rž(+í(ÝÒQ§:UQÑY-ëjl<‡²Š£Ö¦áM÷T–uÚ,Wq‘uIÑü¼ïmÖ+šº>ÒÚñY¥¢§´ä`Éæý ywÁ¦½ÆÆÁªŠ£%% ùûÏ|ªTôâW¹¼»VÑkl¼P¼yUY§\Ö½~íÎZå‰Í…¤¨Ó­S\»æ ó-%qäÒ-‡ÊÊã,[Ѝ”½å[:õç`| ƒ¸rrµ½uŸ\v M„ËSÖGWÜR|°pÓ^³Vy²ªªkÍêôÚ‚}› öa'ˆ®^YvX¥8¿ø¼·q„ªªÏTª“hV¥:Áñj¥ ÙæÇÍKóÿ¢ÑJbþ¯¹E|ï xCñJæçïa#ÚV.ïjОÆ-”—wÆ7hÏà^Ð+Œ¦A’-2]¿—=­v ¨mÞ£Ó3/âa¡«à8 gu g´õxXº†³0pkÕÕ]¨†_›Ì—Ðz:퀬ò(=éŒBq¼¢ìކAÀd¸€ƒÔÕÊËÛ>ÙÔ4K c®§FÖ]¯PÕžD³Ó;Z6JߎY BÞ UìV¼ã®Úá¯ï Êvú«? ›NùÕûƒå;|kSOP±Ûc:Üòz°vw¸n/×z¦ŸW±Ã'ÛéUí™{½ò‚ ‡cÑ© gÍÁVÍ¡ |—·ú£Xp4èލúûC®A¿îp°ì`Õª·¢¶sþÒ·C†‰”ª?Ÿƒ;ÆçÎèäégŠ×®Ý‰Ï*YWiIG­ê”BÞŽL7hÏ–—©–uëõçÑëTªSxÁ1zÃBD»¡qÊÊŽà=ª¬ø {ʶFÿ¯©é©×œF·Ç+_Wׇf®õu2熢õõ8þ¸eK‡¼ºoŽùC׫øõÛŸÕ~ ©Rž¬Sõá/½´‡Çs uðB•D·”W++ëÄ@¡TöªÕýlHÉ’ÛzÀÓíRüŸ£ù÷ýóñ?àÇrY.Ëå_±|üÏ¥ñÿ3Þx¨e¨µáDÔ}ÎWùŽ·b‡¯ =l<³~¨x?,{/d¿Ì™Žä{ýoÃ#¡ê¼E¯‡K^˜{²ÿ§íå8È*{ ­±;lè Õ¼°œok«ÝÛZµ+ä8í­Ú¨zÏgêóm 4 {}šn¿v·S@åožŠsÿÛ¢M§Wµ§MùA$|ðÆ'ßPîòWí 7w{k>õý"în«Ýçq ‡”rÑIêÎ :/µUìø‹íÕ8ˆM±#™Vílk:ï­ø Xöz¤þ@«joÐ3â/~3¢=䩸­¯fO@¹/?±‹àÿH®Í_þfØ7æo:ç/Ûlì VíN†J_ ªxë:ƒîáPÅ;‘àXÈ|&âè Ôî {®†ËÞÅ×°±»M}4lîÊ~‹My[nFL'¼ÕŸø+Þ *÷«wÅ"Ó~Íg‘¶«¾ú޶úc1sO$:Ç qmŸ‹Dg1ùÿëôç€Ð”µ½ZÝ€Ã9‚qó Ë=ZS}\&ëÒÖŸÆ×ŠòÃòª.À9Xó1‰#Û `))ÚØo0^Â<^ZÚ¡o8[^~¤ºª 57îŽÂä…m€Xùv«U}º†sÚ†³ªÚyvcB¸Â4¡®ëÃÄ·võ‡¸BEMoqá§À¥øo¶>‰8ubÆÌ/Ø÷Pù?Ù”Z”Ï­§Wí6˜‡øu†a½a¸°ìøê¼ý«ó>ì~íuÅ]òº³¥•Ç_X»/¿¤ó¥’ÎÒšù%GK*{¼þñUy‡`ÔjΠ¬«¨¼G©îË+9êõOòü Œqβý¼F¥¸˜"|Íþc† e `¢wØ®ØlŠkú€Ð0¹;×Ìæ‹Ãy@ µú$Þh›õ2ºÃ~Íh¼x†ú€v˜‹›-Ã0i€jø¯ÁtA§=Ó 0›†`8˜ŒŽëË0öX›¯ º0‰^weŒ¡Cx²fãE.6 K³QwÎj¹ €×Ü|(Ñlºèr^7èÏá88>Îèj¹Áóícsè-®[œ#t0ÝYìq:®ã8n÷HSÓ%€v˜؉C¡B4:írÝÀ âÊí6ؼ×p#÷˜B‹Hxý—}u·ÜÄO¸ \°¥i¸Å5Šû²4]‚ñ‹¿ã,ÀH¸ßÝPhO ÿÅD5ìDƒÛ¬WñßfËå6ïmü1˜p·Œ¢y­–+,«¬Ç3f1_BCS£ñ_ª‰´ü ¶öäq²:¸ vI ÿû Ç‚µ4×õpx"ZóAØu>XúëPùŽlW¨zwÔÒPîñoyÅSù–ßÐÖj5ôäïG”ûÂêÎ7†îÝVõŽWö~›jOÐz&Ü2ä«z7Ú:h<súJßì|/ä úÆ"ºî`í¡€¡;ØxØW¼=ÜД½m¹j¹à/þE":%|£ Lsì#‹ÏII›ÁÀ„É0¨Rõ¡Zš.GâsèÃèê0Äð²`¨ñùÆaUáåÂŽfoÐ%ïy¥Å=Z[{;ÑñÖãñû#'Aø͵lpîZmÙQкw}'Ê×®õŽß ‡ñëw¼«í*F˜ŠÊÏ0JÛí×Tu§pÍ8 ž ¬0ÖÉk=8¦J}Êåa àÒM€ßeèÿ·'ç¨DÛ'ÿ"ø9ÔrY.ÿ*å‹ãÂÿ¡còbøÿ¹È+~å>Ÿ¡7X»Û¯ÞÙVwÈ_½3d:’ý:Ú¸?¬Üq^X»ƒÊ=aSwP³/Þt0P¿/Tö‹°µ;yüïŽùDõ"Šw‚¦Þˆ~_´öCoõΠé¨O³/¨ÚéWî 6Ôí T¿ë«ÛRíô5 *?þ'.Dñ¨M¹Ûk9PÝÀÐç× ;úBªOÂúN¿öpH{˜ó^6ñ·\(vÅ}7ÈÅçc‘© b矿\‰ƒØÍûýºÏüõ‡Újwµ:|¦î°~ŸW×ô]óë{T{ü {|u{üÚýy‰¨ÿ}Ÿ-Ôܬþ ⇧Â5ïE\×"ŠÝACoÄ|,jè NE½7"5ÆÜ×ÂŽ¡°ê·q÷Ùˆ<¨ø0hè +ë¯ëk…Í=amWÐ;Â9ÎÝAüQ0ê7tÄ#S¯ßÜÔä¢i~c:³cŽváxn·Ñ…uÌ¡¸ý`pÒí¹E¶£3­Þ;Þ¶»€@nfرÖVò‰ «Í{ð l üÄá™jó£ ùaÇg‹ø¸GŸ<ž6Àý ¶Ÿ!á§@°&° ð€ù+H¿â@#Áð$&åh*û[*_3[(ÇLZ-ë*x˜ø?‹ÿ#Ò~æ[¼w³zøœ£eßé¯0³ŽÔû—JAµ n 4€´å.‘[§1f°Àe!¼"[ZÐB Ì'f€€Š@ # Ÿ8^ ßÝXtš1âȯ±™Xt¨Ï…Bqœa\ ì87 œ MÖ ¡ÓL„¬eÌ`g42 OGÂS±(‡`e šºîTœ,\V7QìF#ÙfÑh‡Á¥(úZï0üOìÙÈ4ðYB²_nJôûîù¼wñ_—ë¦öCÀWœ—tò¶»¸At0ÆléŠdm¾ì!ψpœ€Øq›Nç ÖçÛ¼wHÃä6‡ Ìtm„5 [Àé¸A×­®;ì7pX·kÔn…™s•,Ù¯»œ£vû üêõܶ6ÃÄÀO—qR*›õZ"-;›41ÃÿSœàÿ‡é]òãç‹ÎîÛ­×õƒ°ú›š†Î+¬ó%\¿Õz {ãÑøf3, 2z`¬@£¡QÍîqßF5<#—kÔh¼H¸=¡É––Q<;ó\ŒEÇc±x|: GîÆÂ÷"¾ë1ÿ•ˆïj¬ålÌw=ê‰øF#Á1Îy6Úv3¼ñÝŒøÆ1šéØ=˜Æü#qÇù˜w(ê¾@|w¢áñ¨ïZ48Šƒs޳±ðç‡î„íý\?]¶GZ9Ç`Äq†ó &iÚ‹åSËÞï& ÀÛ Ú3vËU¯ç–hÀÞ)¾Ž{TT¨¦™#fð€Dz*jqm”m¬Šìø\bêñ­¼VZŒRFlHî¨ I>ë´à#Šÿçþ߸$Esÿ/—åòG†ÿsúÿW¶üÿgÛËÿ|{õ\þäÕbä$‘Ñ=2ɯ²ô’½Gö§ÛKñ÷—’†#÷\ã±ÉptŠ:W§¨ût&ÆMGãÓ€:ÑøL”þÄÎirGt ¸¯† G™ÿÿ÷-omFg#±©HŒ†brÁ¤%'"È<2CøóÜ\8>Ã(¸Q†@ž¸¼Hœ^óñr3q2òϳíô'–{k^Ð'$—‰Qj4*DgDò¾ºÝ·Š^£á¢ÉtÉb¹bm¾¦k8Á…EfêT}&Ãö«jOiëŠ‹ÆØ7PY£¨­=É<ùÀê8)C8Àêº>u]?þˆ¯˜ýqÌzÍ€¡ñbsÓ‹ùRiiG³ù2f\›™ÀªAÀ0“þ‚A7hÐ_hÀ¶á"€‡¾áœJu*!· ®íj2›†Èÿ©3MVýýÿÜB•—úlãs<÷­8Ÿ´nÞï#¦L$‹i8ÎâJ`0FÙ™%d]n>™ÆÍz½wD†€iYH):<Ì;a'Žãn…MÄ9‚¢žîÅO·!bsM†‚“@Ñ0²‚„nMpÚb€[ø¯Ÿ¢ev#8Œ&¹ü¸Ñx¡ºúŠRÙ[«ì-Ì#Üt†Š²Nyu·Ju²°`/L9”††3¥%‡êjOì-)9¨Tô(åÝùv˪ŽÂ ïèjBã9®(—w—”‰ê몪Ží'ŽÄº¾ vUU|¦ÕžÁOèØYYv„#’3ÞÖÛ›öâDx¬%Å5ê~µºýç**ÜÃ2ü›Å‘ËJ—w(•'Õ¨P|7ž·a·JÕ§Õž--=Œ[ÃXšÜEá¾zM?NÄX´i.çÅ•cC« þLÕÉuëvÖ©ûpã› >U«ú/ËË:=îQ¥¼G§=ÝPßıZ®hÕýtáã ®PQÓ#—uÁ@oß\°—`IæpUY§^{6Ã.´*ÚVU{’“¤UMO|Lõÿ£¼óŸðä]E[¾ýÿÌ‚7WVÕUQÞYF°»Fу>PQ~¤²ò³â¢xˆ Eú¡^O}ð\ ö54œµZ¯›••u¨5ý e/«Nw® Ÿp¥ðòâYà¡ càZÍiŒ'xL”Uh¿.¯>¦ÓA}ƒáb p¯ ¼ºKVÑ©Rž@ £·7êÏmþ—a4ïÇÓ$æ[lÍ‹!׃³‹¡@óªMÄ2óAܳ±8'#B¤6x£dÌŒÆf`¸EÉGß»Ø,µdç1êFã¤ÐÑ’Œœ1:~ ,»عtŽ,Çè‹Ï’‚SðÙ??P1úÄ”Ðø ë ÝÏÔ8¸fõû奇²ôü ëvÖÖö¢W£edG1Ò¢b?¬0ŒNè~èr%Eû++:M¦!ôI<¸*Yn§¦¦§¼ìÞ¸çõoü¥ßôŸÂMßL8ÿÒgü« é‘˜ýQÎþ—~ã#1Û×ÂÍÿÑÛ¸Ò÷œ¯˜BÞƒS§Ô¹YüWZpýƒÔ¤é3g¦6à³É$ÿóó÷,ãÿå²\¾"ø1ÍO†ÿÿ-”µ‰DÓƒ€.Š®©Ä‡È²ˆPp¥K´¬‚¸€ËXÖÿa»âxuËï[žÜº-»ÿ~nÑ$"”.ÆÆfžÎ~$%§ôɉeAÁ”rÈK·i6)k{1æ‚.æë‚½¡0iªª.î,`Uyy' ¾^h¤¾þt½ætUE'¦þ²²#KfóE£é"ê àW|b2ÎÁ¤ŒOà: ר\Tø) ƒþ|yùLLÀó8;êcâF}@#Ì_ |ªëNU”iÐl.Ú슙¨h„±M2õ‘$üŸjÙ±üü‡‹ÿsª”P2ü…¢ÍûspµhLL›öÕÕ¢È;ç`)'JK:jä=ØYWׇšç-ÏÀ„ª“¥[:ö1ÂÀWÇsÁßñßââƒØÀÙËÊoÞü)еÁt‘Ìc'¦é:åI…ü8À9 ¨ªî ®8XT&;F˜çu'óòvbv絘‡qFÑÇüÒ8#s»ݣ°&̦‹˜ÖÝž1ìol<ØßÔt©Íw]Õ°Çn¿ÖÚz«¥å&Kì‚¶ÛØc³]¥lŸË¸eà1jnÌ’#/ĸYFÒÀ5´µÝñùˆ‹•[½·IP¡ï.~Â~\N L Í":ÑPÍåeÄvy"ðÀ~€%› sõÎÀEèÆØ ã ð’Ú,w`ûX,øÆHÁ…EbÓ¸Æ3ÁíàòÈÅxnùýãøŠ:h"làÈqbۇ“è~vÛµ&ÓŽŽØU‡ý:>½ž[ذ4‘(X^¨£n¾¢ÓààÍ–a_Û]›õŠßw·Õ3Æ|¶ÖDÔDÌ:Âÿ!ø?›ÂÜ\ôPýÿ¹åd™‰ðߣË.“"Á_QpSxîh:ØP¸ý ÿnßí‚ù9…q½-ït5qïÇ ´m‹¦ëxœ68¾Ã1âõÞuÐ £ 5WÑy ômüÏÑCÛ a~lœ«É<„¡OgÇ`‚±•#Ÿ¬1Ñ€ßTByi‰ ¶€8HJÄDñ)qŽ£8|1è.RéâK*$g/¯¹ÎS¹¥¬àÐøqãu­ö«.çˆÝqͨ¿€¡ïéší¬mÀíúGŸÇ~WËÆºçÞAl ¹¢Ñéjb[…¯Ó³8¬aüW©< 8!eY/ã]ÀûˆÝḠ[›-õçŒdX¸$¶›é´2ËÖ ÄýRþv²Dbà?™˜•UÍ/XÆÿËe¹|Uð\²Êœr}ÄæCñIO ˜¡ß­ÿ Eý¾Û¸Ç®|ÓíêvÕ}àZ«ßq»ûœšÚ‚ƒ.ý¾6×1—â–ê7\šO\úý­®«ë¤×rÐ\ÿ–Ù×kS¾Õ¼ØÊÝAñÄo·Æo{b·h!Û­±»d#vŸ(î(>ùmTF Æ'E,-NZ7™J•’ýñø¼€ºçx{øÛéÀÈ› s˜±?™¤Â‰Ä/2ñEÌU²/.I@¦¢Ÿ¾JË¥–’S Ê\zž©÷ W…)Þj¹Úl¹LÂ~ ™€ ö¸o;œ#ºd€y6Hô7ý&‚BW°£ÌU²32À:ŠÇ{+¦u¦ð[=@e·‰cœ6áÌv“µ¶ÍqÐ{HËL`¾c¤£µÂüûØF«bÞEgñ+æµÅüÿð¿¼+¿ð!æÿ]DêŸ8r1½bVe´OQñV”ÖÛd¥Ã<Ôl¹‚¬b¤±Ì´ý‰ý…ù5Wpð_—cÄFeUpFÓ4P7ÁBž1sMuSµƵT¦Xšf|^BeŠ„ñëh›÷.~ÅY|>¹œmØ-hw Íqdʳ" À`‘È@ECýlãÈÿý×]²?8ÁØ@ЄÏ‹`Ê`¼|ˆvÀN5$¨¤~@U{ŠhÅEè(ˆb ÿŠ‘Â8Ï¢¨”€å„[i!Ìq^o;”7񾂥ûÚÆ[=wZ\cî–[.Ç(@)îÈÝ2Fî×zMÇz)šÅn»N4jÜc0Rp6š¯„(ߌ²¡ÈÚQ¼i@Å»`±\©×Þ³&“ª®êj6_Ô7/™MC~‘ý©b2 ákÐ? OÉåÇðNiÕú†sêº~\3D=ÉŒ‘b òæ¬ÌšQªyg+ÈìÈœ wÇO t;•ªžÝ»'†I“â‰|Bq¢Ì•ìŒÏÈ%f’ís‰ä,õÿ/ó–ËrùJáÿ™ùzâ D<'2ç³… ‡Ãò÷ ´¨ú ì>ªùm,xÏ+{?â½Pî&{Ã@Ôs9P¶#¤øÐ¯ê©öÆ]ƒ­ökqËI¿º#¼‘ U´ÓýcÉzx]n ¬Yö¡ÙSÏv8<Ãöõ%. !ŸB&Î|j”¸é暬×õækÁðýFãu«ýƳ«4š¯ëŒWÔÚ‹jý½ùªR7TZÓ_(;©Ð\,(;QPq\¦>§Ò\²»nš®¿TÚ xÿ§ÛK7k{ªL}U†ÞBM÷YGQ}w±¶ç¥êŽ¿ÚÖÌð?o˜W"âŸxú°œFY\°`´F,g.ì4‡œŽ âLVö1T]ÃÙÒÒŽZÕ yÍq¥¢W©8 ˆ+—×iϪT§ ÷éÏWËŽÕÖöª5}ejM?NP%ëpÂ<ޝ†Æ Úzâ¡ÊÏÛ«ÕžQ×õ1Þ5›¸Q¡Áqö gûÓžWVµïøQÛ/žroû‘ïÕ¿7°ñ¸#ùt+Ùÿ´÷•Ù'*EÑp^£éËÖuepªåÇò:ÿ?Gê.4á‚*S”8 ÄpLNxÛ8 d˜ôû&Ðn÷-êú¾Ó šòµÝƒDùÌ÷`.…qª‚è%~Ô1 ¶ïOà>À{š:ý¹&ó%‰Ä$öl€¥ÆÆAÐA‚8\Äv›Ácmq’IÀòÚÚ„úNÐŒîëM¦!ÖŒ¸æÒ2½BS‚ÊÉÒÒCªº“õõ$ [­>Y²å€\ÞíñÜ*)9D–oÊã¹Í–l9¤ÄC1^ a¿ g6nü¦‡¥étUU'ºZ}jsÁ>|¢é6oþ´Ùz…­²±u(¶ÍÞÊÒÍb[|Eá#ÑÇç—´fùå0ÚÿËÊŽ”•uÂâ`ÆTyÙÆѨû‰Qžlh8KÖ¡J: úA€ybKŠÊeÝú JeÉ8(—wÉªŽšŒThE Ñ8X« ¤ tàÊŠÏ †ózÝÙ²’Cx.¸0Bz©íU©NäçïÆ‰ä²c”—>ST´¿¼ô0Z8œ,+íÀñaa½¦¿²âhª¯¢¼“ ¿d¦W¦_ÓøÿÜ”¬¦{sÉÃòÿsܬJ3ÒF /UT1›/j4¥%ÑJŠ÷£ÓÖÕ½Ïá×Ò-†ÁFý¹ü¼Ñè¢ÖíTÔôlÚ[YÙ¹¹èSŒÕUÝÅE±ÑhlОÅF42S\LÖ¼ô$du-Y˜¿·FÞC™?äòì©Qt£Ëii9Œ‚êêcD“êByµƒþµ~ýou:Êr¡|$"`E„jÕÀs?Û§Òž[³¾#žY±vïæÒ®•y¸bç^صaó‘§²ó§k÷½ðÒÞ¯úxci¯¥ùÚSϽÿüÚOW¬Ùóâºýè$«×ï{~í—6v•ö¬+8ôìªÝ«ò>]›øÙ•»Ú|÷¨'d6&ÄÚ§ Â,—¥di€þx®üt’µ Þì%›4h} ]ˆø&Óú|]úˆ“ß9‚ñÄÒt™. …-¼›-0rý÷ØÛd ‚]ƒ¡L¤»0”Èâ‹ýÆ¢¶ê½ M²@´6þ ;. ¶ß=¼/yJ!¡ ‰+`v†I˜‰³@ǦïélˆnàEƬ*àÿ…Œdp,± Áÿɹdr¶šøÿ—ã—Ërùªñÿâ1üÿ?Eæ3AïÍPã¾°ïZÛÖÞ°©+bíX{Cæ£qG_Øu1ÒÜt_‰G#-烎sç`804 º.„[¯Q!<0ЏÏóŸ G3ÁÐ:²¡,LF°PxŠ8Bdì Q¯Ì€Ïü¶ãòLJkEÀÿ1^_q®Åu+¯´[Q;°º ÓåûÉê=ë ;×t<ùâ®U›:V¬û´Ru¶DÖûÌšÝëK»òJ>»zçsk÷TöU(ú +ޝ*>ÀðÿºÍ˺žiÏ yûó˺Ëä'~´ú“ö}m«Môÿ‹gç„)FzIl!XTÐ~”®eˆK·Ì,bÔ º¬¶ë˜_êµÍÍ—©X÷u˜K€s˜è1Ì0¿7A‹eÈf»*W¯‘w^wýiÔ°'Z+-7É¢³ù"_î`"xÀ1ÙL¤o´Ù®DáïD¦á P™ýqv•ïÔY)jÞS0™Œä›þÏ‚\~¬à!ëÿäL~„V­¨èd<Ÿzà¥-åDU˜ó ,&•òTAþÞjYP1`Rƒö4 «‚JöÕÔ¯(; °Š‡RSÓƒƒh4§ñhЀh¢ªòÎúúÓ••Ÿ¡ì/TÐëÙ š]§¨ª<ªQ÷iêNï×EsxÜ8,a%Ñè bµd!õãYà™›.1’cP´¶ÞBÛ¢lÊù9؃ž Ob?"NÍ*àW§kÄã½åÞC5Ô‰q³ØO¢¶ãÁÐ!øî´Òl“å$bÇ÷Æø\¶TQ<Ýퟑ ..îD×% >%^z´ ð¶-–Ë^â=¾ƒ¯€1–Tˆ~=ÖOsÀöÄOÔzºË¤þqyLÊ; «$1Çh*¸k› +;L*ßDaTpüêm%÷ÈDCPgR"§n½¢ãŒF¯‡B÷I5J¤õOQü3#§[àÿiyuwñ懈ÿ¥!¨ÒäѸG¼_¸SKÓ0 Ì’âC°Xe²cµÊ“ËÊ——uU*Í€¶þŒ®á,±­êÏàÞdßó„§ýï,þï4žônýaàU|>îNþg½ûqwâ,ÁÇñïZßÀt¥° aã°k×|€¯[ŠlÜS§:ei¾R “Vѳ) ½•+ÞFUíIe’ÛLõg!ôB‚#üÊÿïÚ¸ìÿ_.Ëå«‚ÿÅý´…Q’g*6RbL„N°ÍgŒâت"qÐõJѳ-ÈÆŠ˜‰pWhÃÔÕÏxÒEŽÌ2W†àퟎ0÷#9)&²™ "Œ¯^JòÉ•¬ªÉz£ÞHd.ZÄ…ÛŠé>2…Ò˜ð'°á Þ'ÈÆ ÞФ?t?šl Þ£va¼x#wnÿäÕbš‡EÌÆb7þ—íU¨ nïËÈÂÉ an’ì·Ò™%·üKÆÚ4 jp{n“`¨‰Ä#ã)Dgã©|¦„ðc#8pD£æ¿a6 aêÇÍR87MŸÚœÃu“ò‚ø%»íZ8LPÕvµµõ6ö»Ý·[Ü£¸e”ãE¦­¶kúèyÜà_l¯y6ùËg¯=Ûþ«g’¿|*ò2¶œx ÿa»ê§€(XkV"°”ñÿ?TýÿEòŸ’žÐ4L0 ­µÙ®ašÆL‡[¶Z®·0ú: #šŽHš/áx<·ð/_áç £² >ÿÝX|Þ¸‡šúó8©ÁtÇñ´Þ6™‡( "BC.Ê¢'ò)”4…FÌF%ák H;¨ìtÝD|E¡í¾Û3†kh# Šii¦EæucòF¥mŽ‘ø÷Qª_” YSÓô‹Òò8³?²ÜgÒŒÏâ‹–ñ—œ™OËaM×’®ÃV" ¢;‡–‡IBéU×aàðf½¦×ŸGC57ØÐÜtÙj½ÊP+•«…X¸B}ÃÙ&ó%˜ºuê>ÀÑfë—s„(‹¶ÜÄð*£L˜):¢$¨{0ʨp `4 5hêêúˆp"ljëUkì…òúîZ­—‹‹Úm×ͦKúÆsÚúÓ\¦ðޏ1ŸŠÿeø_q¬¨tÿ—†ÿÅLd¡à¤‹òó© Ï<î¶$º+‘9m¾Ü¨¿àkgö~òSÁ.oéQ6Œ‡©|ŽÇú¤gRƒB«=KjzÉŠì)¢Þi½Ó@«=Ã"Óiìü¸ÙpÑÔ8ØlÖÕŸá¨yè¦RŸ$éabžD kH"°ÀI»Öz WK”(ÿŸàX^Þq66hŠTÅô>ï€â—Gg¢ÂhO]Ù$Ô‹äÏ¢¿bÌáRúšg³ Þ§’V¸–Ã1/ˆ©$¥Ò[t|rãDg3ÉBÂã:-[ÎØ‰þI’|µËËI=!>Nr›ôOêŠaJJÌl†îÁ{èÞÏÄ_û">ï43ÑÎäõ1ã±ZíW}”OHÔ´ZFíŽëèÿ851^ƒžˆAáe!)Æèõg¤&ç­ÚvžÿR]}tÓ²þÏrY._1ÿ¿iˆøŸÄ9Gy 2G¹<}£+a T–åœ3ïÑ—óÜfÎ(æT Né¥t^þ‰„ æoõÜ!ž×h0DªöX,WB!Bbn¥Qž$k!¶Æ\v­ÄË4¢Jƒu9Q‡Öœ²†ö}ºgЇIt¸ ³1!^8Jƒ@矚$³jŒP÷cŠÕä&¿ÈÈ,àÿ4žš¨cÿ_²±ø5òç¿ú´VsšèóË»‰3GÕ—Ÿ÷1Œ²–$vAêA½e6],Ú¼ßî$ú¨ÀTUAþÇmÞ;Ä_{¢´´“Ò`®ÑTAÝ$”v€$„ªì¬Uôà8T%¦W£&ù¤bTãE&;–ßð nðÿÚ¦CM…âxIñAE ñ;)•' ó÷ʪŽýÕËf"ÐZ·£ªü3•’8š¹ô?™;N^Ý]°iß—‹ÿù)(È织ÎÊøù:ý9ÌÈh^B¶iÆÓ§RHWjkO¢=Q --d•ÕPÿJÄì†Îìvw¨^wžÄ“í£Kèœ$’Zw¨Ét‰a“qÈÝ2Údn¶\æÁŒLhÛ„œ?ˆG‰+Á‰ê¾þœ )Äë¥û-çãéáâj‘ÀÆ™¬ïš-WB¦U0OSá)úñŒ0D>⊛HW‹Kòdf¦–pþÅcŠ"«õšþ¼µWU|¦@¯+>¤©í+/?¢ÓÝ´n—Z} èÉeŇ¥úXYI‡\ÖÍ\Ê•eø }„$W@ßcj*4¶½ZÖUZÚ6„W#ïvS%üuk>ÀA®lö«ù?FS0¢)´_«î_·n§BуDŽދnO³&Jž]Á¦½U¥ej’^át,>›mìIÓñ¿¼»¨¤ã!ãÿú?ýdUG++Ž¢óà©ÁÂj Y½öW”ðÃ`'ÑIöOÈdÝx©óó?a}ï š¬Iõm¡«NøcAÁ^ Qº4¦Õž.(ø°Q\¼_¡è•Ë—•vÔ×÷c?‘‘'ì—=É6È4mX1U\¸—(Ðbè¨?W°[ÏXUº>0ø“¨1Â9¹TRr“õ†»”ª^™¼‹ZÕ)Yu—BÙ³¹èÓ’’ý.×X~Þ®ššãrù±@`³yaÁ>9¾Vw¿´ö#"ÃRz¨ªê³²²Ã€ÀQøÕf9è¢9†Ö¯û §f¨s†t¿¹ùJ#æ,‚oÛÚÆñwŒÃ˜ª0/P^k7¦’àRwÎ뽋©øÐl*ó.÷Ùд{ƒyWiëáBǾ"×~ìÌ·~\:V—è¯Kôù¸{)=Iè™è>KÙ¤éaË1I®ØlpEkc®–›n÷M—Úâm¥ëò$.Ò5BVGˆøÿ©n”¨`jaJÂ}1Ó ³!¶QÓÛv¡A|ƒNçu˜cãsŽvÅf¿†»flF˜G)i:„©çÝ.û»pàï#ïÆÂßå"߉…þo.ú·Aö°¹iæC‡ãŽ€ .Gü¯`ïÈkŽ=ìü¿¹üÿ Œ½ƒnY\|Õ€L6múÏ͈ž¶eË!Ü8LNüDU}úÐ70M3u…¼G¥ì“ÉŽÖãëDMuwIÑ`N’ËvµVy²±qh   ÿE«VT¡äüâ¢8 *ÊbÃï§ÌŸ ø *cyùa¼Dç¨+{4–ZÖ¢ÿ¨ÈI]=,²yn0š*•õTÈûó‹;Ëd§ôÆ+榫jíE…fPo¸TTÖ]W?T¯»X&;±©è°Þ|¥Ñ|¹Fu&Ÿß\úYæl£iX¥9‰Í”Wõê CFÓpEu¯Fw¡JÖ›W|tåºOeо y_ú åð‹Z")Š]¦‹ÒOé´pRŠ5ñ*OÂ’2/šL<$iÉZEù)o‡z n9[F|„ÁrTðÜ ‘8 )¯ïn€¦– ñ¼D75!ëlÙ‹â¼n3DV=NÒ[°•Ž8'®†0™GËÌõp†¬©Eyó?ãaJ¿3ñT¾×TOfJ)4{B ÿ+äÇJжþçB–R ñQ“ÐZÿD„Þš.L$ÙGd*œh¦«]¸YÔVï`‚ehvfE(Cx"¨‰¦Ã[Oüÿ¡IOëuS“lbTDh„2Íî`üq9¯ÞÓ¸ª 1‡GCTÌ6N<í“t€º§Mû‹&wñùî:œ×ƒ¡ oÛmgÔGÄ…ØÌÃîÀ Û£7L9u]¥Õ‡†÷Ñf½J)4û›š.a¨÷ÿÇfûY&\ظ6<Ü v1¶¦v 0ñ+‚Ê0Q_«9KªUö––*/ë$}ÓRуó¾ôÒGdü7^ÄUÕן^õâ;8Zmí ¼¸HÃÎ^WwŠ$XÔy=HãcÈÅ€` 3ήxlWU°ñc¼ÅDfVÙƒvÀUmÞ¼çÂ1ñŽËHÄñ-%‡p=%ª«º T¡K!?þd CèS­ÛΠY0˜”—ÆÙ´gp XÿÇ+ ¨`I\¨M<ìO…-HôåÄ9HV6'MþE×Da«Lü/¯îÚ´iÿ/—åò•ÁÿB"¡ô««¾®y¸É|“ `R³åŠÓ1ÂÄAíÔé ܧ¨ûJ“y˜$¥uÝ$xÒJ”÷ u0Oa¾ ÚWm¶kD²Þ|ÅÒDü¨˜&0RñÀa*â7MiÌÄ/ Mº÷êH:Å g1ÈS1j’–´™PLqÞŒ¢VºÀ;Ä'Óz› †˜ éa¯(½öJéŸl/––ÿþÕ’Œ=0:JеznW”¦VÄ]`’­U`¾BÍ,ª)ÿÖ5¬44®Ô7¬6°fcœœšWã”ÍAÔ;Â0MëM‰õFÎïH¶n–…ækHÈ}³sð…YÍÉø©-‘ž—æÓ’öcO:‰PR3ɯ®%ã_IL@¥*Pwk»µE#ҹݷúϨ/¾aÐ÷ªUWŠu×Ý® D ¹'(QÚå-,¸Šx_SØß¢›MýLhQ2ýÓ!€õŸïPzÙøÓ­²9]Ö¢‹¢(Œ)©I’‘¤tz–Iiÿ/š_kKãÿ=éçì·þÏÞ "øYQçQÍòUW †^´V9»]µÇÄÀñãg}Þ©¬c?Æ«ÃûDý1›ú²²Î’ÂE÷C99çÑØUªKhþ>ßΛ{Ñå¡e,¼”‚¦¨3!âºØ®i ®:ìd f4ôò|81%ÛeŠ.H§íòz&ˆ¤ºˆ®I§ë*,ì@W“›}Îlî'}€ð"ÇnÏqÚpø6¾fú"ͨÛKI½ê*¢BG™ÖdêW©® &£¼Ü®q7ž‚"¯-Y¶“,²,a¾"¥–Gï¢:¡*ÒvâýŠTþå`pÖj¥Õj¼»ƒd’œwc4ô·prJ04g2õyÙO‡ÞÕhìÃzÜÉëV¡w-/_ÈLÎP™Ø‘¡¶½^–LùR¾éÄœmëtcùÆwþä‹Ì±Zç”Ñäß·>+µmH¹iÊ´&øO¶›ï$ `}qϱ—Z´üñ?Z¾ª]}>ç%›özqÓÓ¦/ØJ€¥Q/>ëTˆB·Ë¿Èy•ø¦ËÔ?ëTUêŸ4¼âS½Þ^o?-ÿ_EÐ=$:FYuµÛ†¶ŽØã¢‘ßЗô0}zF§í¶XÈÔáËS]6{M¦¼¼KVë0Æ£BM'†mQwyx!žoâyÑ uÁ­Ôg‘ÓiªŠÚÏ6C†WŸ3U€vé“§¢†t+ú¯lÝøÏ|O½¢gÐS6áp¸JÇŒ–—gÌl0šûæé[›{Än‰UÞç-–<5Ʀpä©ÞÙÉ›©ž'á…C‚‘‘ ·TðN™®ƒIZ(~ˆQ£a‘æÀ•Õ:d÷LD˜sŽ·ÄÓn ø-^o$¼d4öW‘Pä»ÃÊ!dÎÇàÈɼH/™ <ÝüµåØ>ó25.25=xq„ÄaãO˼Óx ·›8Ìxáÿ¬Ø¤b /ócßDÞReÆX¿¿uÖ×2}Ô|ÆXÙo®¾i¬ì˲ÅÛ¬&pÍ_9‹€ ø¤H{8<Ég(‹y°ºjÙh앪$ãt’"Žt¹Æ±F&Ÿ‰†ä›BÍÁUU÷…±)Np¢ŠŸŠ‘颋|–²~Ô$3ŽlIávM"™RæT¶Z‡ª¬C(jt’ƒm&åœåx|5¾ÃÉã›(¥3ôSÑ 77‘÷¹/M'Ä#ãÌ»äÍeM¤¡á ÔOÄ™ÅvÖð·Wå_–â¡Ñ6”ÂÿiIÏÕgòëmöÖsã¼SI[ÞÊÜ”äèËöÂ܆ôe’ÿ3ð?e4dâ½áFŽjÿø?Ûb5;ûgHSkXìL±ÚHÒFä°†Þm“ßéÕ²„€Þ†øJ³ûP"uõjkÒô~ÅbúHJøEÉü%MÔàü(”Ú‹”:v£X©®¾ïõNà4R¼¹*¿M©©4Ý£Ž=¬%× Ù«¥ä›–¥OˆF—ÐÜDb7IØ~ÌL^W.ÙO‡ˆ½‰N›˜3Ô 8Hw9Fñ/O¶oÉ#Öp³Ä¬ÉЇ2Å-ù˦UyW¼žÉ"ÍÕ2–>Ót rÁIÈ‘¨>“À·(qw #qü³h€¸(B :ž›!Πµ¬lVÔ«°Ódì SðBeQ^¾¨Ó]çfïèµ GÓ®ážPr«q@Et)š¯oxRQ¹Dœÿu¶¤Ä…Å ŽØ**îxZ'Þÿ顆ީþaVóÙ¯úÿý7#ß;Ö|ö­è÷Ôüð@í‡oEÿì`Ý_†ª€«oãýëKzá´ £ÕÛõßÏ©?Ÿ¿ðíèG­þñ‘ª3#þòiâ ©cW*88Êxmóÿ”нy’ñ¿Aß}|üs/«^Žü3q{ônåÿºýçžÍ1êüÜóúŒ_䯢KÑWvª×Ûëí•ñv!ÿÌ1 '^õx¦ñ9? žRR9«¬¸Wæ™E§WZ@\€®ŒÒšßL 0Ïl †æ0"û¼3!ÿ°(F¬ê2šFø›™ _™†Ý£U²3NiÛáí’!{ò¼5ÀûöÑŸyŸ~®û’Æw-Çv¡$tCWvÝî{KõgºÀõþw˜Qúa|ÈÇlp:G东c¼¾iƒ±`>œ·Zoz}“ùùí€d0ÞxCÃ* ¾Õ2ˆ‹Ò¬{`N£¹¼d4ö9œ#DcHná]a¼P©.;]£fË »tÌå'Öhë°"Þ›Âç$ªm`ã °(^”?0g4õcdŒT,°œË=æpŒz¼8Š1B¼q ð¿"iî2r> †n;Ýã÷ƒÁ¹‚ÜöUîÊi#Ïb­¶'ÇêvŽã†6›uÈã¾…Q#ÈÒ7Kd–ê¾…è@R)ùÍ.ÆDŒ˜”VмnsŒ–ùgü á)6á}±ž)ù¿ºžcG_1ÿ?µ ä_L©ÍÆMkzíu”°úëVÅe”RZD“~xv” ɛۆþ«ò>wžíëÿ85ßl"ÌP½ìñÜB•6›û-¢\ʼS$"â´à½ ®F Di»ÂáÛ¨Qͬpb2õ•â i çóÚ­¯çI¼tÍ u2H¤»QÔÇSá yšØÚxK'xζOJ……še4ôwã¥!TAÉ"üDEâÈt·˜ôøñO„6ßœXÇg B{û9 3fFA£&74]ôV(¼PTt&êÙYçZ“;lì’©¾Ù’ØL°˜@j>l6gš}È|n’7L®¬)(Å=®ÛÊLiØÁjÛ&í6ÝË\+Üy‰LÊdzLü/à¿õ?s²÷}þ/þ7¬DÂK^ï4^NuõÀwQ¢ /ÖR&MçF‰®IÎz}/ª7*ñ0ýsÁÀ<Â1NËšª¬¼[Sý J–sÏjÐÅy¦¢Kø‹Þ««yXWKÔ,2ó/ºÔj4@â÷˜UN¸ùie 70^SKÎËx½$ð­•  @}“µt1eªQ‘vŠ‘B2EÈÙ¬¤l‚Å 6¤ÃWˆkP(x¨êšeüª¾a…Kຼ„¸ Íl4¯sÝØb¹!’¡õ›´ÔÕfcóö°7bÊûIò¶@‹§“;\ö‚‚«(G:+Ýu4O\âçß3¡çQ•^F?Œ«äå^t»É»¡³þÙiR¥~Ãð'V〶¨ ÷饔d¢?¥1Fò/þ=¹ÿñhG³>Ù_üá„ù¦%²A³>õŸN½ÿ×ï£$#w* ¯m#ä 'êÕ½¼‰˜­Êñê«…‘¥(Z9ΖÜLúg™áF`6ð’óX‡lÊ‘'.åù¦Ëš×šäOýÕ馧Mî[¥ˆG”À¤îqý«9ÕëíõöÓäÿìà¥ÒR½åY&+8Å`É„2¥ŸåIê§yS²P›Ò ŸB¨9Ì´óûf¦u—‚viîRøT¼¥>UüSa&pNÜÆßûàóù?õMORGüÃ*Ï-SŒ"DæÕÍéý<ª\·¦æ‘Â:¨&>ùò¶x]ÓºòÞH„“(ÍÉÔ1ðyz<Ú‘,L9¡¹#‡~ĵ³0v¨r/¹c‡þ%ð*ð§Š9kâñ§,–›ÅE]œœ:AIÍÀ³0@ç©.bäÑï¾û”~õη~Àêü£Æt¾²µúr¡æ*®(‰u:]wvö9ºÕ%Ma‡N×…gA ”ŸY§»†«|:ù‡Ÿ¥ƒKö™}äÿ·>ß å6H•æßÖ®Ört-|<¬¬\â|gf€°bm‚ùü2ôÿרB­øå÷ÊöK§¿üÛ/½ïõ×c'Ï&Z¶‰j;,±éÙòÖ4CŒxq$Šžö›^'ÓÞÄZsËz%«Ê°”lÝN°E b”÷z'q‡ø >xX}¥¼ü6bL23õ‹îŸÓ5f!Âüt¾º´I™ “X±y %ØØ¸êtŒ d#Fè6À9Q!Åb ^ÀiQļñ€|¼=n$²$k¨Š4¹Æº) '7(6?’”ÌLT…W“aðG×±ØÃfÒûJýËþ•ÏiAàuYHgÊlÊü|uMj¡aW«Ï׊U/Ǫ–Óî«/vàÿ=}Eržê.ï-¦I¼ÈôÿeþwNî…}Äÿ²lQÀsà@ħœý´ätŽ%†y€Ø´šk¥¼:Y[÷¸ ¿]G“Ûsx(ßbíu2¼0P~“•”yòUdþå°g;‹_µ2çø±;­Ã¸´Ë1VTØéæ4ô·Ò"Ú¤ÙDD ‘¸Æq*JVzïš?êV×MpÔr3œCd;ΗEÚbÆ>ÀBÁüˆˆQÁòr/¡NRM3ßT«È«Ñ:ü2eóL’;¡bkòÜ’é¼ÿŸ?ø¬©~P­Yԥœí:’w%_ÛŸuѪŒó¨®äãW{©\¯àö‚NÍgÝÕOðT¯·×Û¾ãÿ÷^†ÿ•A§²ò^**#}µ©‰æñD–-‘H ë@³Ê+"”xÐÈ:œqŒòU)ÅΆøªØáàÆøš¨€b æñ9Z,óÏ¢/eFÐzÛ ’S*©ÜÜÇÙ0 ˆÙ 6ž¢Yçns7)†Aiû°fšz¦$ØR*\ÙÌ/œ´ýü)ÓÏ4þì{†Ÿ;iøÙ“†ÿñ”ùç¿c‡Ÿm3üƒÓ|eubD·_߸ª×]šòð:2†C A_…ê%ç&âá'“›&‘çíÌùÁ`1(Zðz§¬J]ÌÎþ¨Ñ<@ªD-;)ÊIÅ5l;›r‡ =¥]Pn]œI°©êê0 ïžBw h_¡ …†³ ¶2‚6kiʬx‹ên²qC*²æècƒŒR “”¼°Áêîóø€0$¡hZ Wñ‰ˆUÞF–ÜŽ±HùbUìAsÓºÄÂt$KŒRDÓœ‘“þa£"º„—К”U¼ÍwžªV.—n{ð“¡VcoF£w(%ÿ ¾r33?4’(Üœ göO——Ïû|Ó¸=Ä ¬®?eµÞD34R~Á„Û‰àzZ"A~ðy 7è(X•#jöϲ½Èm<)Ë~á´n’¾ ÐŽñ¢¦–rå*hyâ.âeüÊÇNŽè(hÍ"JN2ßÀÝâä(—òðm¼45$¦ÁúÀuõd 4ÎpÊòù~ïdææ·íÌÿÝ0þ'þÿ{[ºâk‡þh?ð¿uȆÀýåµþý¿~_Ó¥UPtíg,|ðŸ?PœþT¤-z·òsY@Únr ügª…°rXùBx¿Oõz{½í/þ·þ—%¿]üÿ“·­ÏJK'xɲ£IAAg±îº¶¨»XÛã°h ;Ñ9ü1k'tX­#ûX±®G§í6újë[,´0ŠQÒhèÏ=qÑn!æ@p.7÷Ra*‰u07炦€ÒÖ²ŽžÅ âpŒ¨;Œ%¶ðA«é*Ö^w¹Çdò]÷ÑC?Š7=-Ñ÷ª;L¦~ Ùz}/éŽâ– ®áB²YeòŸä1Cóèä}Þi¢7؆pN¯gÊl&a v t< Æ&³ÿèöYNóŽ‘ÒÁÆ|ži7Sk´…ÝxF€:7‹ÑhUJ¶N{Ýlðò‹Â‘8'Æ\G–—cüŽòfSïŠjbíï² Þ¶¤çû'F:†Œà\‚²Git»oRb”"5™$UÓã$ŠŽcD,p¤^Ãåð¢-ê2™DárܘæAúئ;ôÅáµãƒ×7åp–óN¡¸KÝùyW %}fÓM'Ï–ùfp3Š€ˆNƒ“#HtX‡Ty—‰6°“•‘IÜ*Òt¾óÎöÿ¿hÛaú¹=ÿOþhDÖ]DM§c½ŽÉqÀî(|%ÀáÐþª¢àÿ¯ÇþøÍšï½Y÷ߨùî[uöNÓ_¼QõÝ7bßý''øöè{gÝî1ÇïJi¤dÅïaÑ4ª™?0Cq´|š3f°0¤A$RÁÎvÛ0‚” °j,ba¥JàåÛl#6r.îB`Þ KÓ Í6(i&¸µ2#ZÍS1w¦*Ör{9úcÁ!”"ªí"ÙvCovÖ'>ŽU¾óaS#aÅüüv.P°‘÷ øÉ‰¬ózTï’>uÞ4³q‘ ªDÖ±Oð“ãYçÐ;¿'_;˜£º–«éÍÊë~ëðyMÉÀÑY¹Ý‡r.ËéÈÓ÷« ú~ÿ3ÅæÑ¬‚.«{ºP?­îþæó ®ÛÝÓ9êk²:ßɺz8·ûXn盇.[‡guäÞЇïŒU?” Ûm6óʤIÀ’Lîÿ̬ÏÀÿOÛ’þ±t>tfßðÿF&þÏ €óKô7ÐG¡^•ºo"zÜ·*"wb•÷Ð?´&·˜ØC¦ä“Ò¼îc}À~@tôu¤*]ò³°ð$¢KT{ô·€¯ký3¨d¿YÚé€öB˜T™nÈ;^QZÞs7çj·…éç¤uViÂ¥««H`˺ú‹Àç"ã#ì§šHý$™ÿyÖFýä&°A<¢”ñÄsÔÈî„õ‚#äÁOã«âÖ‚ÀЦVÈZ.»›y‡­2-C]ͽ—I¸¦‚ÿqN¦ææ^´ZŽgŸÕé®K 3Jäí·¿o2õ¡á;z†µ¦˜#GK-hwhnÇŽ~ìt ûÛ¢Ó°˜û³²Îòú­D45=Uå]R«Û11#;•÷¢c7ûÐfM8›eðpñGöúÛ,os¶¹ôçÙÀ{ó~þ·©um×°®0ÿ3õ?ÓÆ¤ÿó^Û¦FÓñ­—vÑû­ÿ¹S¡ÀãÒ‰O?I|%®ƒ°â%g+ìÔ(aÂ^áÔå<(^˜(™ËŸzäOðT¯·×Û+ãÿìÂÿm{–›1R”•Í”•Í67oú¼3€îâB(úð€1n¶n±ÛGÐêí¶QÖÛœóPÀtuõ2An×Xú„—ë›K}Ôf‰V.aátôö~ÿ @uSÓ:k¦-Á¢ç/õa5Rq_±¦ô= )o²¹e=RAXâ\ÌctÀÆR¢´^ øy{m"±Õ˜&¤fÎSÎb0¹¥c@ètaLÁàB ñîqÄD¸(Æ}žå³Û‡q ~ˆQLÈ«EE׉Yã6À¡\p%)×x8²HŠÖ4¾™A¾‹º üññ•èîHÀ¥I›”—±ÒI©ë$Ó'H/™EÏô®"ÂËüÿò-ëäY¥ÔDá“gکμÉÞIæ4¬‰4?eEf]DA•Q./Ê(swìÇ4äñNØìƒœx¸ˆ{óz'QDÞ Ìå~§“ÜÜ**hѧ°ð*ÙZ‘Á­@`Æå¥ùXÎp”H7V¢ï s“q;ǹà6Tù—½Þ /ÛWVÞåèõ6·»ÛQnkh׸7´¾pùmüDqŒnþfåB´¾À@špTÚ <Yú_©oKžnÄÑèiíIŒÿRäɦ¯6R«„éfËkë¬V$«$òŸ ªÞ£úøJyô~*û¸-­™Êü}ÆòÏdg¸¦³ƒYõ1“ÿ¯Ðð2SHRüÿ65O…ÿ“lyZPØ~ðÐ_¾ÿß)ûT¹ ÔíóíÖ!ºÝj@P¯V]imÙB[Ë͹àtŒ ÉÇã+@•¤Û£í¦9pË BuT}ñuÒÕq£.qNÊDNÎy´z†ˆæ€?Q£P¦±{Åui†0NÊ(¡-ýÂw;qó#Hë»D]@º¦f™à4Ïi˜ýGHÆ|K¡:z-c¡ªå°  ·$ÖñDfÑwi´äGÓ_ÁÍ£V;c:íuôÉèßú_åç_‘‰#<z‰#G>Æ[B?f³ £Ð5šN€.o 8ìä{øípŒfgŸ#þ‰ ´¤[~»í½mç\É\¨ä|äÖVe&‡¬%$iåÏb½‡fŽh)”•€H$¹É6bK±‘ Öк˜3h‰C$AŒÁQ#I+¬ƒ¿7¬™²x\îNˆ{®ÌeN†HöŠˆÿ‹þ¿²¤%®Âÿ!ü_Øñ­—vÑûÿ1ö*@Ú2hýÔc.”c^ž&˜ lÏÉ߯Úõm彘ò­gÒûòËäö£ÜöïT¯·×Û«™ÿOáÿäÖ®!f[ž9ÌÏ õ+õu+’”‹-75¥èý YWaõ’¿6œeÒúN¡ë¦uE؇¹¼úüç§Å*‹AZ3éI´)¤êÓ"Ù ¨ÏÕËdUÿð»%e-±ÙÔ¸*ÐÅ„H9V}¥‰øÆ´êj¡a"4hiÝ-—šÚ‡eÙ"#´_hh à‹V“\ÿ4Ú)BQïŠ-×7¬ˆÂ ZŸÇ=Qßðqz¬ò~UÍ2Bõpù">§]ƒ·|lÿA>¾†þT€êEh­Œþ%M-tO…̆@ ¾#Ìç8)š®6ƒe­¡~5Î?Š š¨ëà ‚û±Ê{¨½¸g¡'ÕÕ=$–LÛ ¼¯$ïWú Ð4IJhV›ÜRR¼¸ªêx(±5¹øŒº¤äÿ ÿMð¡¦ãÐá÷ ÿ'7>5”–õ$ìó(ÎÅTSý°®Ž4vYÝ ZzCý“ºš‡U±ûx“ˆãpDïäø÷žŸ4y¦E#HD>Ýî1†ý(ëXtÉjþ缆™òršazϦ§ôC+&£á¶çxÄ¿&S-þÒÉ••KîÒñŠŠ;±Ø]œ͇½ ²âí¡—ðû§}¾IóÞåÙº=Ò5Š,î¦ÍSÏö<3A#µê!þœ,ܺsHÝ“Êñ\y-)͇Œ‰#i>”w––½R†žLK‹L¯IE:C$¿”Ù'±]K›e*ÿlë þ×]=pà/~Šø WÁƦóç0m.œx¹œ~æJs̵ëÛà|Hù¶âóyÊfüÊÁ{eE‚§z½½Þ^%þOîôÿÍü,ÚÎ%ú^C 1DøE£¹ÆsËCø€.¨Þíºe6R¢±/'ç<ú[üU´ëõ=¹¹—l/àà‚ÂJµ é´ÝGœ±X€…nùäç·væç^*Ö^3ûŽøgÀåÊC$¹Œ«‡‚óø€KKJ£Ù4PWÿcš2RU¹—qò’â“¡Ouâb™gªÔ=!×=räã ±,¦˜À=_Õž¯n&ákÍ5tøb_ß,1ô^Õuåä\¨«œ—{¹ªú~Îñ‹ÚÂ.½®';ëBªèe;ßp§ŸoK†ùQæü¿¢ÿ¼Ã€¶áîþ\™1cýÿNà`,Tç_jÍ:vQ Þ§ÑÔ‡3ã¹4šN³µHF­¾¬+î**êt—Þ2,(¸Š÷† ÈV«»†ÃˆêC”S¡0 ÑØmc€syys áÕv´Ì=q?!Á"š ;c?Š5?ÿ2 HÙí9|èc£¡Ïj½™›}¾D¥¹s2ðE[F>&áÿ?Øÿùÿ]Y4ÈF*H‹ÏjbeÚ~|.-½å+›òø&ÊüÓ‚˜÷;Í€‡² ëÈôaVàgO¬»<·Pý°Ÿ U“[”Z˜+Ýþ¶ù£/"âýÆÉï™Íý‘ŠE ‚@YvY½ 8Í‘õ=DRø h\¤Ñe:ZWÜ]XÐŽ¦f˜›{Áç:zøcƒ¡§ î²Õ:`1õŸÈ>o*éC•¶Wå\0›úÑ‚ôºîÇ>2ûâM«Ú‚μœ‹¨áœÿؤGÁNÊ^u/H©X×e1ØíC’³ér2éNÛÍAƒh¼¨„ìÁÝ^RÒƒ¯€¾òs/ëi5*'ëê «¯Ú-Cië„-yj“Jž«<0OîÉÚëäÂæ+Ò\ËW]©­~˜›{‘rœź_y(ã<裲³?±Ù‡QÁŽEw1s✞d‡ñ.â6P@yª‹xÔÛœìslÐÜ'KW¨ºôJÝãMª:ʯýÐÁñB‚À“®±‚|RJÁ›ÁaÇqróÀñ¬³……WÑ!¨N\Hð~–¦µ(D—TǘhÙÆÿEEGŽ|ô øÿ»–Hó~%‘MJ{¦¤Õ)yj£¥y½;Ù‡NÑPM-retPˆ ‰?“ØPµ(¿U&øÙiB›Q}kŠl“žýhÙbÂÏ3ea…ñÿFŽ¡3l¶µ¦¿â)q%«æùÆÖýñÒ*Í]P®bvåþÇ#P ØHÒ¦ˆb8l!5!`N‚YòÔKn%š×Ãå ¼òHÑQø"‹ìß÷€[YÀ'^”iùêê¤&ÄôNŠYI¦õù…M¤è]¤s«"²ÄΉw·sðAæg˜‰¤x5*ô!ż›ï'•“̈žh]H·5í5F¬¤gâ)“¾N'^%vbó¶™Öà}Öœ²ØjlYàm'ÜC#s>EÅ+IúÿÛ™ì;qÿ)ü¯¹zàÝŸ&þ¯{T·MÚ߃؅ü¯¤Ð"øœ„‚Œƒõ7Jv}ë›.S®Û³:°SÝ.I6ÁOðT¯·×Û«Çÿ»fþü®/¹ÃÓ5Fi¥˜¥ÆFY>æT›×CÁÛBÁN»m$^Äg¿#¾Õ6ØH)ÀBå ø?Ä@ì÷Ïàxà̆#wП‚sÿ úXtû¸JUì%:UÞ#¡†碑E´/òàßuß&Ò¹íãLÏûx©••Ká0›æÔGD ΧÍï6)¶*› ‡æ+¢wpzÝ „óÀc^Ï”Ã6„ÛŽu;ÆÜÎ1œße ç]ŽwÂO ð#åáùI鎋Q8z!1¥Â­¢ÊẑÈÝ6~Îq"_fr§a.É,.6ùL Aœ7a1ß ²õCmÝCôzL<»P†”9ÿ4}Bô¬vðhþÿÈþÎÿêì±Û}Ëí7›o6°µ:f©ëŠÒ)1ôø<Ó¤À_óa‘Å2ˆ÷€"£^·Œ¸ýåA4áÙ@Ù\™gŠƒÙ'}/™Çîµ´nâýõ½è*‹nǨË1z²õ9^N4rG‚_¢ÖnG+–PÇPvm´Dxå‚‚ÃyÊYÞÁ¾K_Ähä!B‹¶Ô¹¹I“E?u<ëœÕzS«íB/ ˜MÉïêvüëtŽ:]cè9Ñ/9ò±ƒ¹@¢9Œ@q¨ ¢|ÀIÉ'÷¢¦¨xØá#N¢é™³Žþ-ÈÇâHcŸñfþ³-ÜÙâD£u5›šŸªU—%}'r.جCù¹—Quq“%úÒ ¢–¢VHgbsL|ãàù–äF©w¶±yãí#—¿~à’Ù1i¶O™í“VûD‰q\o·º&l¢Òi ÃFóØñ×-¶‰ÈÍ9Üw¸fmîI½q¤Ä4Væ_xûhûÁìkG n~ýÍ35uOJÌc%–ÑhÕ²Í5ƒË9\S÷,ZÖ›/Ø— ”¹\-”ƒs/«v³ƒæ‚³I{]~ÿNõz{½½Rþϧù)Ú}Âᯨ¸ÛظδçÀ)ãëõõ«¡zxZ¯oxÚ@KùO«Háõ?ûýs¬x0+¢úÀ €)†‰‰y>¼e›K³CÓ¯%e3ÊŸy=4r'“;¬u›3ç¸Òú?¤TÓ¼N^BäS¼Ž±&šklZ­©}TW÷„yÈë‚úÀâ«)sXŽš>Äî I!í¤õ ×ø6ˆ3#$OB‰,ðÈ¢mk²+V°xj£±?{ N²€ì’¼Y[—2OO±=Ÿe‰ˆ­DvH¢)·ÁR~›õuOÂá;‘ B5¢­ªãAp-†¬SJA"ÇJª’+qÖ©&:ÇS"_U/×Õ?Æ]±“,½ÊØ}„c@UUË8¾ºê!ÐE#éü¤ü§ÊáàHd©žÌ›Vñme%@ìi¼DïyJ'Ó$œ{²q…ÿóƒ}åÿìÔÿ|žÿÜÔ`(ì4”ôÏP&©Ïhè+Pwè´Ý€…W…V—{É`èEP©ÓuW“ÃÚŒL_#h R.)mæäœÇ‘%”×$©Ê¿¬ wÞÿÒwœç%%=@ nƒ*.îÑu?¼qòOqÀo„›Ð|p?¸î¯4‡ÿQ«çJºþçSþÔZúÛ<ÿ¸Í‹Ø~±ÉŽ¿ÿôtð·O}Gf)&Ç™ åvOúÖ2w‹ éêŸÔÕ>Æ_ª~¤HÆ^¨Z(YOq¾i™Gå…†ûÂ!C%ç8ÂD‹h•¬µu¿¦öaŒ<ÈÖÍë¨iüÞëˆTÜñRÌ88W{@ Ñ?ËI7K5ÕË’>OB[¾ÙXåìròN:Ó¤MÓž¢ ¼Þ,l@¢ú¯5ÇׄI؈€ -Ž3ðm¢y£"¼„MëMâ@¹øÕzUUlŽ@ïpYK–®’"óàÎ[Rº¬›)Qž§”Ïè]nO¹i?n ÌrûXÕ‘Òû–d¹îÂKBüNù1þ×v:´óÿ{ÙtÒ xáiŇF‡°Ô=qôðÇ@Ëx!>2(é-P·WU=ðfbQ½Ñ:Š4]ÇŽ‘”؆Œ¦¾@pFW|="ã ½þ†Åt“jTÃ^šé,*ºf·³ÕïÞ†Ý6RPÐÔíga¦ ?±šoâ0¼.ë¤ë¯ 7|,}Föâì“…—Œ›1è{Âå òèOXʆ:Ž:礒#GYÔ5<Á=Hñ¡bG+ï!ŽÀýG+—ª¨Š.IhÑG¬ò.Ñ#‹•Ñ¥phQÔ*¢aV ÞÙ"‘P^.%FÒ§E‹ÞǵP9Cʸ§«×=ÂÁIÎQÄËhn2³ñ^Û ½yè«ßúðûw~ÿ#³köhεßyûÌ×Þ=ÿæ;g~÷­3_}÷ìWß=sXÕõæ·Ï}åí³Ïü×|¢.û滿òæÇ¿õ{?xãí3š’¡cªëßBû&f˜Å5ѺéÏ øßGx~µû¨úA l&äŸ x§¾©@ÙB-÷n£®ö1:oº<0×_ÅsáHD«ñ†â„7…ÂÚDlŽ@¬Ì?ƒº‡“£›ÂÏqK>ß$:”NCœ`[00Ǧ·Y•ˆˆýòŠØOöA„Þ=ìÁÛ#°Wu?\~[±©UŠâ%àq ÿsü¿Ÿóÿ›{ƒÙ–¶­xÛS³{О°û†]±[Ã7fuyBÖÒAµ®ÃéC1”ô%ˆÕÿL: t€¥î[h&Ó1ðÓ2 Nîè÷ÓvóSý”¤2«ŸL÷«<|ù Ýiü¿™–úY‡È9EØA‰¢ÌŠgí‹;à‰iðŒP¢e+NÌðÕêØ2@#†{2r ÌÄWαFfc'‹çw¨ºfÝ,žؾ‚ç—pœÁK#’ý ð? n   ¯âëÍÿÐî?Uu éÃw~ðnü‡oÕ}ÿíúï¿Ûð›>ü—Íuøö_Ÿ>)/!ÞôÔdî/-ðôõ]·{R–øñP1pEìw»o‰Ò,™ã8˜œh/ù|3.ÇhDö—/à/Æ8»}—‡ÉÚ 7‰¦ŒÅEýe3ˆ&0 ºÃãl:mw4Jì\:¿{\ò22‚¯ÍLeË="/#`àÿwßùóW¨ÿ¹}ju»Õ Ä2zôÈ€ À†‚ÂãV×V©.B`¿°§Š‹{8ízL&Æ„áÀ¬´Ú‚p€Ô{H{8_Ý®quþj<ö+Õå¿Rþçu¿ÖTýϪB¿Þ\ÿ4üõ¦jìÿÕxUAÛU¯oÊdìÓuÈü¡«`Ã`¸Q¬¿´ƒj£.¸LBýuÝÊü»c£²ÙHh÷6‡œw™ ?Í|6 } ÷G¨]N×h4F.½îÒ «eGSÐ,  BÎu¤yNe¥¸.Ôäw6Dq=%Œló x#1"û*BMa§øJ :Ï?[Só¸"zOWÔe(¹á´ä¸\„!œGýáܓԺ^¢ySæ¥eCHå-lŒ¯4ÅWi¢²ÛjSÓ*‡(ÉþŠ„ï“Ñ×ȉ;Aþ¤CáêŠä ÐE£deUWÿ¸*v¿1NnªÁÀ,à=@>À-¢ƒJ‚¸4;MN‚ñ§ˆ)(€Š.)"–‚Ž2’%i†„Î37÷2ŒDòØ#épu‚P·œÎQt°'N\`ÎÎl±Š©=þâ€f^eP©®ˆ , 8Óz :ÐÉ* «ôOáA~#Ô„1ú·êÞÃKб{'EÍÖ@Ù F7b"óÿ’Ì”‰>Uîe±m:ž}÷ ÐÅNœ_X7¬î>R\|î Ë1ΧOÕ4øv™MÙYŸJzÊbPÀ›}Î癞ÇCIŸ±¤7ûØY³¡O¤Vµ“F·é¦ZuÙb8rèG•DßIMÓbcÊb¢l¿Ó5iþÏäÿì'þÌp#Ú€<«¡0íIeå]†Hd¡®ƒ”@Ø-â^eåRuõƒj" *›/Õ%à~Kb“-P—¹J/°ªíj’ÄWÑ(î𿨇÷¿ó 9M b‘ãjý#¡åãü’H‚Z*T¢ŸûÀˆ‚þï?Ðþýt{·ÿîƒ"ÿ“U±i5“ò"#÷­ìãÄ*¥D×IìG´"åÞ”XBpXQ×P=²³ÎÙ̃z]w~ÞeRÊÊ»DJ)ID4@[‡|Ì|žž¬cg ú”;nÏj2¡QdŸÒ+*ìŒÄ øÏøQÂUZ§íbEÙû¨CŸ“’#&Ðܤ·Ó©/îå™öTlˆFWZ:Íl¾‰óJ!xÑquÊɹ`5iŠ®ÿà‰p-µŠ¼ÍæA­†t·¨LÆÞcGÏØíÔ$펴nÔa<©FsÕhìE¡7Ä ¶y<·ÌÆ>Ö¿i%JMá’^–º¯ ÷ ,d3೎µYi¹¨èšd@Ò—fì¶!›j ¯µ¦2˜ÿÏ•\à– ü¯Ñt|{ñÿæÎ|ú{â;„ÿæóÿÛ ÷nï5¾ýµÓÕ’:$—–ôš)cé•Ö”!ì³¶´ˆ¾`ïu‘ð=Ÿm7d¼MãÉ(x¦ìT<¿¶D“~û,ý™Â¨††'óÍòòùv¦Õزi_ÙÊ7»K¼,-å š‘+/â8àE+@ƒ 3…Ï]z ]™……kª–…*YSføPVñz”y§ea‹Ò(^&%¿g†­ê)ÆFï`Oˆ-ùüþÙ'I¡Ú„ËÉÓ¼"Bn†hû”Ò˜“)tJdóÎRBű çÐXÐpÐQ¯P»x¾e$X6m¥:O¢ý¨“&ó@4²Ø’Ü /õÜ"óÇ0F"tˆÁ±ÇfÀàÁÅûÌdîÃIê°o"€BÛÇW¦Dÿì Ëo—zÊʦJ 7p@™ÆÂ«ïK“MÛmÔÈ‚Ç9²'Ÿe‡è¶þOÑÕwßýóWŒÿ뉼+ù F¹½äàŸìüÿûý¾®G¯pŽ«ã~NÿÕilˆÜ%0ÙÎM8ŸóÁžIûŸà©^o¯·Wƒÿ±µíáÿdêÿ„B·sr.z=SÀ´Ë,9r†GØ¡õòçÕÑh^XxUEäa"X,ƒz}ï¡# à±³aâ¡C⺪¼ËœS6 ¼ð€Ž(£?Ð&Æ}™çÇ8^¬»Žž“±Ê¸Í6Œð@?ÄÀ61c¸ÉW:F9´E]2rCžæµ¦eþ_¼qkjq.$Qµƒ”´¸ͦ\ÆÊ©çgºé\¬ê>ÐZsËFmí#„åd1ŸF„†Ç•±¥ÚÚe_İ€%æjë–Y@†ø,‰¿QE6÷D ¤¬ª¾oZÁhà$hPbœHÅâ×4ÿÿ÷?(þ…Ó¶xÊö‹ïÛñ´ýN[ù¯íKï—þOå>·lXº·€Ü(ìj\ÅMJÐÄYÆO²ŠÕO”=æ\æUJOnÙÀñ ͼá+šÑß%‰›Q4§šE×{ä>ô–÷òÑÝ+šÿß«ÿùœ–cBdëŒQ¾Š©#x@>ï4O°Ï`È®£\l"ÛëPÙ,-v°50Ï .Ѳ ùo’˜ñÁf0þ¢Î ~b,ƈ äI*(áÅ``‡ÙmÃ8L«í$‘ÿ|‰±—@‡xˆ§µ˜/ú¢ü 1ªîáå8ÕQ­[%A~Џ)›[dˆÈ*(þZß ¹çìd‡2}ŠÏñ&T=‘ßÈ„HÌÅ”å޲e“‰ÖZDâ´b±ê iüJ¶H­ ²G^"q“HçÝg, ñ¿ ‚aÁ‚°í+Ħ~xU±û€vßdnÎy4DÜx퀬h}D@ªz 4lìÁÏËËœÀ^ê™Ä ¤Å©òæ­£Xýe³"å„¢p+£”¡€ðZªkîGI:þ>NXW÷¨’'ÿI©š¹ZÛ€7¢±¥F~KxEÀ«(÷Y&þß=ÿ_ÔqhŸü¿ìŸªÿóBðÿ¿J6v¢FsŠ1:­ß¹Æßö}ßþJKØÊš?èEñÁçBMÆ1Ò´éqs….Ôë” _¼C‹…ôTÇ‘F[Å™LýÄ¢!¡!Ê‘Á{åŸ(›^)ø_Ñ®ßáú½õÿ,eöñ^D…UÂlî/(l—y邎<Õ%—c¤@ÝN–Ó9ç¦>‡}ôð¡¬6gÃ¯Š‹o =Gýˆ²¨˜¢ƒþŸ&@Ôˆìú1š´´>Ãh">_€¾(S ê#G>FcA¡c¬Áq!Cɬ#?N4oøÊ¦‹u”‹08\c9Ç>‰“ÓÄJ¾ê ‚P¹ îßhèw;ÇñìiØ Ô.JNùÊ¥N±]n ysl)j¨ø¹¤“£¿%ÊhíÃ$­˜<Wôº2½ONÇdªHõPfÀ"á;’ÑP]ÂñiåÕ”§¶²ðM펂D*e‰œ]6E+C&‘êx "#HáÇžïÁÿ¯tþϤî(x‰JÿþñÿeÃÎÂkE»æä÷n¹ ¦KûYRB?ñS½Þ^o¯„ÿó9óÿ¢àQ{€N›­ä ÿ£óÄxŠ‘šù0¾ç,CÚ>Ì]äÑ™Ô8›YÓ˜Æzö G¿$>3µ¸ÜãÉÅ>z7\¾Èà„. à¢aÊÊ™J$ÖQ¸ØÃJ¹3^É·E%m–a^f4zÉf‹h€²°ˆû§$ëØ=¡×áþë5æQW…¥ ΣÇ@m¤æ°®l†mž65®Iö N‹è>œ•tIÓ&ÉbVtÄɵºîXŒk¥µ¢s@Ÿ†Òa¦ÇðjZ#eÇ*P_Bü¿Z×EÿÿÐáWÉÿ‘{Šðÿ¯·Ô˜ƒ¹Æ‹–ÐÍ"WgŽáœÁ׫¶^y3ò=|û¿4õºëè–µÚ.+*ƒ^ß̨ò® ‘úý3ÃÆ^”> À%Ë ïG§ëbؾòy'òU—ñÞPI#Î:xðÃhôN¦¿¡²Æ—vÅJù}(vÀ²4 ü™÷v2þ› €ºšVZö¥X•±«¨Öo4%Öß>c»vJ‰eRÐSZ¤cÿ;úмŽj#‹«Ø¤CÓvQ·–lÙ&ÖÈBU¤—ùÞsN߈7®4KÖ-í§ˆFbç­5¯°z‰Já„?ƒS¯¿Vƒ7l·á3¥ ]Ca2õñDý˜x©°‚Ö""MáUÀxI‚`ÛÁ!YKÅ·EÊgG]ÍÊ:‹ªhwŒ$Ø5XÖjÉ›ÆØ'Æd(DÄ;ŒP¦œÆþŒ–±ì”Ê„¿ÙÙçpÞš*Ån†>›eXÌ.¡áïÄÿ/”ùÿLüM«½úîW7ÿ*I›· Û?w2ü¿TÿÇÐgü,ýeÃþÌÔã] z„%=•I{Üóg]î'xª×ÛëíÕð>‹ÿ/“º2K ÀÌð~=½­e|†Él-ÈOð@º%57¸Œ§²Ч Ëoó\ʲ’,¦]åå‹è3ˆ%[ìç²Lö¾4RÏØ»:)Z5L¬ò¾¸ §&´™e¤PSÐWÛyq6?ÿ -[`\Ë¿ŠN•¦ƒ˜„YXЮ+îÆØ8lC†’§cX¯»¡/¹nw —’éX¿Å< ™en÷Xmíc%%6•n ˆejû§­e|”y›šÖGÖùÐ{ øh›Çß`Û¼¿uVöàsùÉ…ª¶e)μ"Æ‘eÀÆü—{¬%¹8Èb%v7†3ħžæ3[Ÿc”Á~òðʽÈÈpíöa–÷gžÆ56w›@È€Ÿvà`v¡ZÃ%¬–¡|U;®"ôxžjëT $ì›Æ0$YÃwȾÖ1Â~µ”p—bÉf•o[€Qþïþê¶µîÅÿ©PUDøQBÓvÉ´„‘`§$â¶ÕSZGC|•µ5hA$5á–ž$—Ôõ'VK=çÌÖ{œä¤÷Ä–P/ö ƒBRóð¹¶–(ú¬À³¡œDöPfzí#IœQRǧ ñ[UÞEuAÊ÷È‘QĪ¿‘«ºla·x|U¼Þ ¯àåå^dߟüÓ&#q³‰äç_FÂaZÍ5òøçäÃW ]nš-$¨Xü•uŽ3ý'µÚnmÁ5Ó Ëï´ÚÌFszù@þM¤ÒðéAp’œ¬O¸fÎ#°*¡TÍ13NnDào4÷k‹ºÒâVq!t2À0…ùí®¤X_E—b5ßÌ=qªœu5’5ŒÈ¨;l<›£â‹?Õjº´E×ôÅÝh)zmw#ߪÙÜïv:lÇ}hc‚ÚK1Žq GQøBGžaâú6ÿGYP–Zš×Ú’ë)ü¯é8|èã}Æÿ;øÿ‚ÿ_¾1ÿ'Uc3ÖeèÍQЊõÉÉôq:ÙJ1“UL¾¶wÖ“P0e³®Î6ß/C5b{æ_±2oMwJb0guõ鲜uòŠíš¤¬>֕溣 vÆS ú!TgDm¨HÒ5¡/©¢]­#‰¹qt_ÁàœØ= Ï'qƒð¢Å2ˆÈ#K^Þ¥òТcüu9i]£Š½!¨ãj{Ž:_æ ¤ìifX!ŠR«È_£lVb‘¢Âñ¸11І$3¨Œe®¥¯ ´| ^K¥A °ÜŽdÿ”^ÑCDoƒKlö!“ pÏxÛÒyè—6ŽâÓ³¶°×7Í 1w…“ã[UÞ%4ô8?îSÄþf"p𬕯ÿEW_ÿÿä‹“Ê486ó õ‹0a2•vÐŽ?_ÿ?_|îL;wÊWÜ£Wµ«s.æâ¯þFI5Ëân3oõ•êõözÛOüÿ¬MéºwtæÛÀ¢:X¬»®ØÈ½$Þ+øËŠ@Ó,(=(ûé<°,.îÉÊ:‹ž Ý:^ôE8 Ÿc) ®–ºo‰{‹™û=¯w_¡Gu:…<ߨc6Ý,,ìÌÎ>ýÇŽâl[¹'γnGaÁÕPpÙyvP¯ïÖézJô€ô“2ö À …nË*j$r§¾áq}ü 3V#Á Ö@üí»µuI\®ò°PM-©âSÚ ±IIøðŒd‹ªD>ýI]ÝÃxãê¶ôhëñÒ]í»ŒÚ[3œ•A–Æât²sëÎÉs%»¹)A:ê²ÆƒËÉò2Mî´k¢à—LKF x&m·*Îeb¦¹ªPhFËÍœ¤|¿†¡iÚ—aSL µ®qÎïÝF¦cÕ7ðÌ[ ½ÕƒØpw²!ª/rK;ñÚ8UøÿûèÿõYüÿçˆ <ž[Ñ»”½ËÐc¥ÅzS&9KR1R ”Í¢žBø3e¾@}‡coÀã™,åÙò@`›>ç9íb®2zÂl…&'A+À…°!Œ peII/ê¡Ë5Žx b›¥Óvóàv"v¶;FÔ*"÷J¢‡ÐÌ”0jKJݱ… @Å‘A*¹%Ó´6S¹öÂHËá*0¯u{qJ>¤v o!­:²© ÷´å¨˜Š® ó§)ò§þ6qÐÝÈ[*4HqÆè<8³< *L™†ÑÎ}¯oÚš³ã¯Í-VqÞ-øY§=Ìlœ­ºz9Äd<"{GýþiìÁk'ß+æ‘ÖËQ”×°!›ª5ÕËl#{Gæp*Jè¨Y®ŒÝ¥(#¾‚®@¦…wñÒp͉5Ñriû4ó¯“'_­=Ñü´5ÉóÿÉýöÿUlˆ·ësÁÉ«?ûáKï—ü§õø¹})ýá˧Z„Šà’2¯’ž¯HÍK„ñJ£w#¡ªÀ±ûbeÂÀV2ÝS“öÉã‚øJ(è$"ʧ¸@­ÏêÐC’`&&öéHÅežRÎÍ7 ;0R þ£EèÏ{¼“èðQ€œsrÎß"*ÄE¡¨x¹ ‰RW’›¹9¸¥v«Ï3IÞô†^”89Yc—ô"úËÉ>ǹQãFö…ÇÏýÏþÄnÆ8ƒVÓ‰ À ´¬º”Më€ÌnçŽW“Œó-œÿ­?øž§tÜéÁ(˜™2*%ö9;ˬ¥ßí¡lßt—hÞHw€Ï9é!÷EÏZ·£¹m_il¢¯Õš!ÄÊïó9û®ÈñgX¿kCh?ø—)@LR„¯9)à[þ°•LwÅ;e?·%€2çÿ_þÏwþ¿ïh»u 6˜ßÿë÷¿HËØáÿ{½ø‹ûÿÿ휶2 <GNõz{½ý-ñ™ó¹‚üå_e~›½J GfÅð·ºúúpÒ¨gŽkÑŒã¯È,ƒóNœ–<1½Sº¢îü¼+-‰ÚºÇ¹91â¡Øâf]ùEÆð—Öÿ©¹äßÿ§’ÂÔUjµ*÷¢Å:PTÔ©×u[­7™8MtØòó/3©ìŽÛ}‹û]EñùËfíö!ޤõÆ^Ô¼y§kDÏ"¤_pÙ`ìåyË)™ÓF•s:GŽ?‹d‹U¼m ¼L|eµ’ uV·k D¯».¹ÛÑÊ»¸´Í:¨+îÆ_“ùàçhlƒT7 Ù¦e3ƒu³± Ë…«OpˆBÆÛaŠ‘aN-ø_Y&KÓøS §9=ŸÏ.x©Pš³BÖ„üÏ^]¤÷ÕÈt ù ÷@×å¨D–…áãó¢æ/ü¤eê÷Ïù—‘¼çd¤|1Zq7¼-.ðU±ebãÄî•Éd¶Ì7 ÞFì5ÊËðóZœÐ‡´ÚnIŠD£À¿ËZG÷%㸢âê<Ú~«V·GÉËxÑj ’92Q§„m ÌÙhŠõÖ§&ÿ*ááÿ–µÖd*ÿ÷Èþùÿ¦ðf*Mʶ‰<>ܤ‡©)¤ì§"Z’{ŒZÊ,4­R]F ™£åªTíä§àÑhïàâ“¡±°›³«ž B¢á£u£û:‘spš¢£YÇÎ&[¶ Ô¤:E ¯ Â…Ó]#b‰ƒ **–"á26àW.Ôy7-˜†‚shJvë°§tBdjR€óä àÒÖ¶­6Bž[ÂgÒ*$ÁZ±iH*% ÓÆÎy‰iƃøè–QÕ)½Íg¼fºPê™o“mÄ¢L“ªûµD¿§Ãªª(tzçÜ–žxŽ?Aë p²‰T¤ÒáÏ–Ìÿã  pÚii ´t `vÙ-âCâå{'¬–›èg,Æ$é¡=ã\õ>T3“ÙÜï+›Æ©Pó-ÖA&_³¯ˆy‰]έ檕RÔG©Ò:ѱ ¸£òtx‡ˆPLÆ>ƒþ†ž\`¨× cGâµi®Ñ¿æ›^’?ÝBÿ†QEÆ+/ÏæOšüó)øÿøÿžúO§2Se }ÆÓuú‹7ŽíÀ቗ÿ0¾ÿâ™/ßPÚÊ©pÚ¿#§z½½Þþöüÿ]þò „“É@jWEÏG¸= Pæ )/2eéE–Áâ«"üfàLbøN2B˜?•Kœ6•Nl% +óÂÞÁ8Žã«ªHß+ŽB™¬ž4eH8ÆO€çÓ0èËÎmušä–LÆ:c€sÀÉ´„Ê:6nVÿÀІqw˜›sžrå|Ó@1¬ÓLc`F¥"Gtøjõe»}¸é7>ï$bté&s_©gcnNÎùªª{ñBuÅ×±46®=ü13¦D¶#¦ŸÜǺ}žIZàÈo]Íüü+b`¥UÑÌo{Ž¿1ŒkÖÖÆбóÐùùÐ3áV56Àíá¡„ð d…a "Àñ^-–›²-ÖQlǹˆŒ¯ñ¶Ëü³-,ƒ_½WZz à…8£øJD/Å Õ5­n‰ÙâtŒü³{’p·'¸´Úküp?ùÿ{’R!°Peå]ð_¨áôèQ›äãÀ¹éÚµ)’)¢+u ÈAHh-$îúHm"÷B>Ò)Û›;Ó`7v"ì•垤Ìê'Ò“öÉ &­Q®.i†lëâ¦¦ß “ÿrœ’Í7ë8}[&·Ó¡ÁzCýS&Ò¯¦üÚ„™ói–d æžQDwå€pø^ÙÈ×B‘»‰”ytºž¸ÖÉœˆúøªË5]W·"ƾ©Ð€ˆ‚+>Î.Ú0 J‡­ÄH­]­ºR¤é*uŒA£žQç_\DÝsºÆÐ–}Þi½®G•wISt­„ gI ´þ1Ú¬*ï²ÅÒ¯V]nd-G›™Ñ„QÕ™åqèÍÇ?CmÇý‚½±GZb1Uî%£áF‰¡'7ïê?Zâ51A@¨ øtâø¹Oÿ™ø¿­e¶äZQá¾á{&ÿwJ KMÊfÜŽÑPø6zTQÄSÒ®Ñ<QÍ€íÃå‹B¡ÁN^™š²™oÖÖË.1ÛŸÂÿ/Úwüê¯Nëo”(ŸOý—€lžI¯òóºGu/920Pެº_õ7nŽïÿõûŠB‘æ¥ö^¯òT¯·×ÛOpþ—}’‚g0†óÔÉX(k¬¤ŸKô7²Ÿ3ú ;YÏgƒ¸VÓ€-xÛë2û²Ž~‚‰Yc<‰Ý——wÑé1tEÝ€‹’Aì´`äÍ͹ˆÞŒØ¹Ö!¯g²˜ÍyV ;ÄbD`º{?É÷ȺzBìÔézÐÓ1eÂŽ'ÓvÀ2wJ®I5ÒÙ"ãSÏR6 ÄçyÜÔü4R[ÿ(™|Fž‰ä(ÔÌ)fMLB`5òÇ)†s"¥–#ü>§(®¬ 7&Þ´’ZmÙ<5|‚Ó–ÇléÒº%´¶ƒ\F®‚Ÿ…LK“¢+Û‹Å©Ðà q¤ÖÜ#we'Žôx¦w)à¢}" á}¶¦歷³€ø£ ×ùsKÊAfSܲÈh’ò>ª«° %бÑc€3‡C·¯%ü?æãÿ]ÒCLlK>3zi&³ð n¨’Lý~ß4G—sá"2Tš· Ìô½fÓ@MìAÉ*m?M…õLÒ:2h©-!´êŒÜÅNñ¹–¦˜9é`VQU¶Wì0x{–£î †¬Ž‰`øŽÞ0¬7kô}Gs;Þ=|A­ë-(º¡Òô™‡r®¾sôŠZÛ«-Їþàà'1”Zó†Õ1®5 e«:Bá%Ò´Žæ¨{³ò:du¾sô"NnvRnNMí㯽sö°êšZ{£…\0žæiz¾ñöGÒ ²r»Ž«:ŽduÊjÏÎë>’{í„æÆ7¾u.+¯óhNg¶êÚ8o¶M°8ÀüÏ+«ä¼»­¼‹àÅjŠUÝR­©}$¯’Þz /T‘†êC zrt /`g¬’¤×ɶµa¥®þIEô.ÂL4‡häyüÿì½il\i–%öË3ðÁöØ?Æc÷âée€±Ñƒ¶öx€qWWwV¦”JJ÷% cß7F#dp_"HJ™Y90`ôL»ª³2+3UÊTj£(î;Å7í+).RU·ásï}ï1();{ºK £‹ÀñøâÅ‹÷¾åÜû{Në“Ph¡¹…xéÍBØKÝkj~H²?uDÕ#Y$é¹Íš[7“°ÕS"¢ÔÎJYÔÛ·ººñß¾¤ù“M"þOz›ø?šÿïÉÏߨþÏáRzå5úiMr“”a¸œ /bÑUÃOA+gÎ%Â%W÷Òé=pÈ…›_}ê^§º ”Íóé<ÄcTÛ÷~FRñÜ8q—ˆ3ÆWš4™a=d­]z"äH¨Ð~6K÷žPPj›è}.ç$g×÷lv’€žÇ!j\ô&f ·kJWÞƒ פ’È¥‹ì1섳8ç=–*zÇô„ËðùH„“+ý—IÕ'ï«px3¦ ѧíä´I¥iÀ`Àl5*z\´<çļ3É‘#ÂLe¥ÀÿdF†à…Í 0··‘tO÷™ÝÄ’þ?œ‰@ê/ÅT¦ôà 5›¼ª»¯Ú.o‹±#ö y£í%UŠ ©UaŽk#I»C¤Y@‰®Z­DA˜àc(a)PUWdÿeÁ“y{S . È1üð!¾ŽlsÃ+nÏL¶Nç4f^¯ç¯-Š—Ñ4(Üiœ‡•XÈM ŸÅ÷r‰I¯w4½ƒ›i6á-.µŠŒJ7p Ùš™ÑèZ¥i¸Bß‡È ×Œ3æ_pÚÇ ò. Óé®VÇ׎IDaÀ\2IšŠ%Å—†>‹efO<@Y“aLIÝ}D§#ŠK,¶n³‹e%»J¯ˆ3ɩԉ 6ðzo”ëzpÛ1 z¹-\0ļýÂIi·¡¼¼¯ð{qžüü¯™;ñü°òÏþ7Pþÿ'o>ÿÿâUþ?-úXG;:vË˯µµoYYµ÷ÊÉñøH¢Dÿ˜Ä´½``Þå¾AüðŒbÊ)욃¤º’ÀWøÂÆWèÖ»ZùI‡Zƒ©hlJUEú ?ð·ãpÆ^¡åì;ù5™i¤°bÌíY²Øo8¼3zËX^q¯Ñ:éôÎÚ}‹zëä¿w©Â2i´Œ™Sçt±®¿–ðÿv ´duÍëz$à¹ç ,"køë ,”ö»¼³nr4£ÊŽÂ2Š‘5ùi&ÛTn@–|Á%»{¡D‰~Ä^ò—=¾E‹cÆáBp1Š®:=ó5µÄ·‰'n-S Ó‡ÔZÆ«×í¬¦­û}s¡À¢Ã>YYuÙ¦ªÂ7ÑäpçÑ]Î)Ò£¾L¦Òë(úZC=Õx™Ëíó̹ŒØ‰Ä†\<ö÷vgAÙÎ.Õ—­Á:ÿÜ}Føw;Y!³‰…Ž3Â~ç([©PîÞÇ3ÕJ•É9®í‰„]jhCJ›Œ·9ÄÛçâúTF¥áü˜GðØÇ`/Í(§EwØ–âåPpI*Ô0P‹Ü¨Û38³ƒÍ6A:KÆ~´dZÑN܈©GV~±á^aFÃÝs»É 1v«uÔ ï—Ù¶²rÈî Û‹ÿbЖ˜Ï÷O—NŠp©¨ð¢™u‡銅cÈV=¦÷õ%»n{ëfN›Î—8®Xb£xkÛ¢£¦Ð`²ûNûÙíWêUWkÆÿÝÝ;œÿÿä áÿþå-c6 ýêû ïÿüý¿AçøèÿýH+°­ÓÖKNîž¿q_Äù5Ó®òëþ-âˆ_⩎¶£í—Âÿé>ÌÿQ6Æÿ‚X²½½dÍã¬Dþò™}Î!!²_gúñ^Öž=‘Áin~ÔÆdƒl3)E YËAQ-dF)J­KÝBBZ-~Tä‰ÈE”,J™ •ü#Ú옪ªª–½¬AD…–%Wˆ(ë˜8yòy•vRN)\Àx^Tt ÿr¹&iˆ6`ì*_„ÜÜôƒ?ãdZGnj|HIã" AY†ø‰_£ s³Ž6ˆÒ’«•æACE?FxüIâ9}fàˆÌãl@àÙÄõ––§€=l:¹.R¨¬]?¥ÂR <—(Â’ÚjÇ60YÔÉAÙf'û=ï¥?•¤¢‰ÍÚäm<5œG®ªš%•šàƒø ˆJ¡EòÙi¼-´wlI𕪿‹­ˆ®ùÔ$6¢|$fyœaW]òÎëÄ?Ÿkøÿ çÿŸ_"k=k/˼x7ÛÂ,[¾þ –|“§µ’ØÒË‚Ž*x%ÿUzöTñ«]U,hG•:àÛ§³jlå[´ïR€L›íĪk|ØÑ®–tì*„|!ÿ·oצpBûPqn‡zUiEõe7» £.“ÉÑòÀ¤ ,éM.éàäü½$””ÞMwìÈñ î¡»€7ÂO,ÄëÜÜóè&ˆ7²RÂLì´9Æõ†>–1œ—jä –÷U,ºÞÜü”R¸lì¼ äãpRu#Y{<¼t»gð Ür]oþé¯ý¾ù¼ÓçËJ¯Lƒì[½ŽKeêÑå ¹nª‰/­N׋~-ÎMÀ°¿[I–ÿþ_¤ÿ£à]EOÎÉ/ÞpþÿU>±PˆåîŸcÙ„E.°šÃ]miy¬U/-?Aä‘£q¹HÜñ3É%!²‚‹°'{K‘Ñ3ÕpEWù†üóˆ‘Ekµ£+(µB¦W$Yãóáü ,3K‘o6\ÀõàÌUáeÑÞÁj >k³ï‹íÔi®Á@³‹ª¨4†XX†bްT“›¶®ˆ¢Næáàtfƒ€“¬dH½ 8?Uw × ôHÂ̶±‚‚¯YgÏç'5!„Ÿ´æe¥–ƒ‡‹'~*ç\Wf/V½^i,/íeÞã†è“'>s9¦ò󾲨õº^Œ´9ï~Ž;F EÁ….^¼/`D¬.¶Æ£1¶f3Ánòú²ÞÚä-üvò##˜»V.¼ÂŠT-˽’»JebÎÉDõº`x ž² cµŒà#²‡á#èµuwÜ®éDb]¬@‘eQBÇq»¦ð»Þ«ýâ[%¡°½óÁO^ªüUÿþÀfxcü€öl)~ø³/ÎþûG}– @ÅëN¤­Ñl#M|Ó©ÐL¿™DÔò¸¥øj©ö]-%]ÿ—xª£íh{Óù€ÿlþÿ7èÿï’çñEo˜Í#u1_Æ`Ù5Œ¥í=®iJD—÷b@(e±Œ‘J¼kZ†nf¢Òy€31¿©âT]´6}‡æqûC£í¢¢Ë.×4P´˜Š²(ÄÝ6Èê÷Ï—–]ÅLV:ù¬Ï?[Tx™ É;¬¥<,iüPx ׆yMÃÿò+ZIŸ©8*´Kó[òråü¿~Ò¥Ð`H3§­c‹d¨»`’J’Ù“d©ØhRx"} •0D/•%Ú†z^Žs>aZ=¿bÍÙM죬 Vªs8Æ1¡45=FÔÒºÅr=T%]ßp?ZJR}åmŽ¨Æ {Rõ÷ÁÅFvîÎV“Pêp9uf­ÎÃÖuàÝ™íò©ùûˆ{wï&ÿ¿TŠ»ÿ†ë_åÿ¿¼$E¨·ªL¤Q4”«Yb¥;Á~‰:Ó ÎßËÊÕïªj<{ÙÉÿt`nWC×ìl¶¨Ž‚ÞÕp £Ä°{êÁn‰aÌæœ1˜ÇuÆá²ŠÂ²þ2ý Ñ2V¬,*ïs{çîÙDòN ´òÎÉKïä^9YÔw<ïZ‰~ìÿøÞÇ¢ ©!ÿlqªƒ{rx¿Ä ò6­–!tpýï¡5 üjV=UJ€y“ccÖ³®1½‡A;Z{«o‰/3v²²Ö#9†õZŸâEcÓ£¦¦'-Íâm÷¤¾áacÃÃ|¶‰Þ²ü–”í·´>E›o£=OI¾•ñžÊ £*ýº-Žiˆ›Ð‰(ÑU^Èš…Ö’³hÒ kº[áol ù‡ù?×rrν9üÿJ5ý‹—kµ:‰Îש–Ÿtu*VãðD£+R䢰Jø˜N•Ø#š<Š€O×A˜“éË‹3ÝÏYRX“2ÓL¯ö…Ä",Üóûá2e…F6þÔ^ö–Qîí YÌçß±o6ÂÏÞ 8y ³C"¶‘H®ã¡°:Ö¢Ù8”Iï |𠎣}yøÒŠOpQ™ý9ü hd¥S©¦Â%„½n/Í,äeÆz¨(‹â5Ú ×ÕÒÒ¶É8€¹ áL4r“†ÖšM¦mòjõšF¡Ál…Æ#kZ-hòà‡·¶oñ¬±Ë~ß[êø/?ŸK’™4…f©XhKrლ­Lªþž¨@àucÓƒF.”ŽDW’µT=×¼ <ãÙÀûÿìß—ýÃ,ÿÅGÖø‘•ÿZ´ÿ#8öá'ߤÿÓ­â½¾÷øñ_~þàß9íÖ oùõ QÂüÛlÙÑDéµrLƒh°?üËânEV"Ù»‘¿Ò&L–$ôý†êõ8¢†þâCœ§JÝM½¤äÿ6ºÎ/ñTGÛÑö¦óÿÙøÿµúÿ‡¹¤6æm¶qR{ëÚ¯©¡ÑúÔ]q¿Å­Ö’ ×û’LÅ¢¤9@^ä\ú$c ë%wˆ$Z£ß?V¼zw¤.ÐÇø|³ˆ,0)PΙ¿%ÀDž,–h)¹fSs3vñÇpæŸR.±êU®Ö< ²bؤÂÛª•``‘hÑÕ[aÅ<‚ $ˆÇ7Ä8¸…%÷o`¿Û9 ßt9IàˆÖªÈ`4¹ -Ù“@ ¡àRÀ¿¯8“Õ±u¼Ex Є=Áà"bü³y4߬æü˜ÛMUu&cÐ?o3:Ó¡À"¾B*&vú”@Vù \;6¼ÀÖÞ½õ’Ý[gûK F´rÑ®WÚÆVFçÁÚÍ+´ÿ¯"ƒáMãÿ׆Ûžg-'=t8g3¢ôkÉÿÚºfû,pTŒl,i‡"«&ÛŽö@doÒ/[ÜjXZ#ÿ¿´ŽŸ½ŠùYBçÙ(+Ð*vÕØs·C=²Ô4ÜÜò¨Ì0ü½œûã_æ–\Ï-êùWÿûŸ½—ßS\1øïÞþâs.X3§‹¯Ÿ.í·:gN÷˽XX1Œ¡ã€ž´§=Ùìp@uÌ6³Ð®D’ ¥MsþJkê@ÊꃶÀ¡w—0yŒe©€¬Ð€®zI{jÌç›o£•µžHd]C´O¶ ö¢] NXt:¦Ž‰6(/ïÅ&Óz®Ç3ãr³ ;ìc\44E Tæ±æÆG>k] áÏ,UŒzf°Ób!It%gÚåš4Wyˆâµm4 4ÚÈÓ|‚+^‰ŽÌ/Liy!!SAð¿^ß“ófùÿ/^uÓ ¹˜ÀBEy®¬§‚¤ÀæÞ;ñ9:F6ŒTÄñ³Ž”–^.,¸Ð™Ù­¬$µäÒ«%%W1áƒÄ!, F ÞVU-›Íƒ¹¹?ØÆp'Ir±©ÂP‰ßN¾íÇ>•œ ÞQå× ¡¢/XL¥îQ–Æ0€¡>‘¸…o·YGM•ƒß¡…'>#ŠKòi,”õ&¬^üXËPy_03™/#l¸O…"xEôE¸‹Ôuî(ËÊ»ŠXS§8çªN+L žv’eÞaB‘±RܪÔUÕ1h—¯ãÖö§èYªëªªÙæÝYµ<< ªJðÏaüÇGp…8ÿ÷ÿðþ7ÏÔáøŠŠëx¾'1Bí¶‰²Ò<Ðÿóƒ?åüÿ'/‘²õº»wüÿø?¸ßêŠûêVÒSöWt‘ÿâCÀñ[Oò­ÌŸlJÒ7n_Ä7ßÚk‰§:ÚŽ¶ïÿw¿âÓôRþ_&wÖ缋ÉTè äd¤R’öw¨ò”QßîtcÓ# uhiù §­ƒu©J,ü_œVäƒ_Ér¶úúMM¤)ÚÐð”ÏÉœ‘?uuwÛÛŸ¥êî73a¸&y[•k)Ë[³Prpu0„] ‡uå½xá:U—DÛȼàR[Û¯íN‹j‰68'ÅýÞ` >Æ^Yb×ÌÕm̰-Ì»h4Ñ( ˜áf¢ãñšš[T5Àf7,+:‹QG¯ë øÉ§FVÌ úht%ûYà{c‘õTÝ …p=<¥>Ep„0ŠK'è6D=ÐõÁ·®c.e! øiû@æQPœùÔe—¢aWJ ‹ŽXY¥w¾)W)þ¿o>ÿÿü"*fÉÉëñøËuÃóT‘®¯=³ÿýwÎÿØÅܲáÿí?}ûÔ•œìù~Î54ï÷Šú~ïßþäTñPAÙà;yWïßü¸Ô0~ìtï|ïÓXüöEG±¸Êjÿ*I&‹™vþ6•S”>¤´§Õdßduåhï@‡¿}»µƒÈxM”DYm[œQ§L8ép2—×Ä‹k}"%®Ò/”5Õ–îµù%Ðê ù)+°?½s¨xáÐöL˱kü(ÕA‹Ž£ï7W’¬::U§kŠÌANŸ.Å¥^$v:©SŽT”÷þà?®Kݯ4ä_01Åúoý0½æTî@¶VËèÛoÿ9zp‘ƒEÑ}òò¾@z÷ÝO$ív²=}çŸ`k˺§É0èóÏ¿õÇ?øæÄâÁÊ"`ˆ¬[Û¶Oÿ A6{³ þÏNþk±Ý“ŽmÑÿaÿßko’ÿ³ûì×6FÈTêÆ ð †¿Ô&o‹+w’Y(áðrgf?‘ØDDÃê=K]ÉÆ‚B€Qú/ëI†YTŸª´êî°ôd0¸Ày›Eâê$7IÕ'±î°WÇWkj6…üÃÍï!M08ßÜüwºØWc©Yñøj4¶¯ÃWàJäúþyZ56W°• …i^Ò+{ûíŸp ½S\|1EAÁÅÚZBþ«Oÿøã^yùU ËVÏAß¶®¼'?ÿ‹¿QJߘÇ[o»uÌlÄE––\egù=4•â‹8!ÆÌ²â«NÛ8=•V]C‹õûæt¥=F}?Z CÃÀµy¼7p‘h“åγÅ:¶œŸ‘Î’{JÞz½7"±•xlU¸£Ä²‡(š Ÿ‚tz»ºz5‘XÇ…¡SÄë¡ð¢É4à°ët½~ÿl¬zU¯¿.‹&tý³¸6’®2óO#~Q,vÓfÁ¤\ÜXUd¹³s˜ÿíØÇØ£»6ÌârB4BKƆ0-á÷[ÎþÏ–ýÌzý\ãÿ¼!þÿ›Àÿxg}ßôñü‹…±µêoõûVÐnªü¦ƒ7wª£íhûŽòÿ¯ÑÿÏJðRî‘J™ ˜Ä…»›{úK¦Qã WíÍ™ ˜¦±õå×½®™‚ü¯öIŸgÆáœ W­¸ KÏÕ¥îšM$__i6›F1JTG#«ùy_afw8¦0б†<1‹¨0Ó9‰Ñ^§»ÎsÇ,O^÷OŸþФ­ /ÙÙk €åê1ÝØÆòr¿Uü—@aÕK®IêÈÑ %Ö ê3•¤-ìòJë^Vö[)aèTé=±È*I¥w¢U«ªXt–Ý’ ¨Ô%x^îÜëì:ä–QyDÂ5|ªFòfÚÒC¤†(¬¥ù‘œœíéªkñöß~øaœÿûéþÁG•¯nï£rÁÿR߯ÃÓ!ñ¦Ç˜_H†HUó8¨ÈÈbËhW˜éT–ø•{Â:±\|•¤á£¡ïøw„ÿùÿâ ž(ì$å-l7€-î«sÆë_ ÇÖÍö)o`Ñ\rz—:Ú¶œÞEi<^To„"kzËT(¼­Þt¸‰”®aÝö¬"ÿkÕÁª4n6Õ'ݱ«ui2û»ZÁK%Ú1Šx ¹³IÐø·>u_ Ò5{»Œ’Û¿¥å)ŸGœ”zaP£ Ç@žW²öŽ*ð²'|†ì…’LçÁ ;I=K+—G'Ϥ%3ÀšWiz ØÉ7aGã¿1¥Š®­µíiªþ>Ç& D8øšPcã#Š_Úž²¡¹3«‡ƒùIÖl"F`/à'­-Dìij~ TϪ>žp^â ÑZ·…5T[{·C!¦Ñg£±5œ3™¼ƒ¾,‹ Õ±µ& ‰P+G.ø™l,~ÿkKB–ü/KÀK's¾xóüŸWYmÏEŠ ?Šé™Cuj†éJëJqÁTv@Ž,ke°-Ì6”×x Âa4TV[­cEE—˜£ïpåìZ™ß­D#+¥¥=Øo®$]y/NXVz‡•”\AÄ~³iÐá/(¸`·Si¼N×[QÑW\|¥ºzµ÷¯O™sRêpæëõõœþêô©óåe½8žø ÅWJŠ.+¼s/œ§ “iOÒ§ý€Ó> Cüeñ{ç–q¯{ÆëºAÒ=>ÒuØ&VJãsËMÚ-öñ+ †·{ÆjG¼_ßЕ_ÇÛ¬ñØPUbVôû¼T»ŠO…‹}aá×8O€~ÆÌ¦a\¶¥r$F½~T_Þ‡‚ÐÃï7éñÃ5þÊüWX@ 7>Íõ¿]ϘÿÓûFë³ðÿ¡Å£Ùüé¼óµ /⑉-Ý©S?«¨è%μy¿37÷K<²;@Å«×Ñ ¤«| ætîyÜIÜjé×ÀbYY¨îc .zUxI+îZIÉe„"††–ÃëãâÞ‹GŒ#Eë=#s…î:­·š‡N¼÷¹Õ:RÃzÅb+ãóΑF×^Cýij5‰[¬bú¤•´wÖS´ª»…™ 0  Ë‘àS¼ ëÆÀrc©ô°.%vТð·‰Í‹=®ìGD HÕJ[ë™§wì°Uñ3‘zS#Ó½x|“ã#%rO‘xi“]cœ>È20¯ŽŠtÿ«c”ÃÇï"¦+W@ãE˜g¢œã?Eœ‚É a…Í6ŽØÐBªqtÏ¥¥ºz ÷Ÿ&Aï ^`'p>nNyyFÈòòk˜q|5÷ý}_nîyY &3qÓF;¬Ž­V”Ó³Îm8ÿ׫ÿýD#ük|6Mÿ_©ÿ%þÿ÷ÿ:ÚŽ¶£íÿø_u™yþÍü2Ø’ê|´+.HÍÍZÛžbïèØÕôíy¬ÞÈÔ@¥yO”l9¹,ÍÖð”dþ瞨å`ÄÆ(JÊ!À]t­ÌP$VYµ ¾b°„Y#A„íg­mJÎP²¬šT; ±1 †hLg^UE¢d¡‹ñÙM2wCÑèŠÉÔÏ.T³ŒÉä-9UZý½Ù’…C£RhÕ }Bþ¥‘ê³C dfÔÛ›Q“½rÏÕüÞn$z?Íd°ÙF}þ9“¡ßéšD¨%æ›b+†É7[MÖÝÆ û?·¤1Îÿ^{g~õ…œÐ%uWÞ |š¿ð»]ß:;”Ÿ¹¦ªÓ X²Åí;Uº{vÙ¬ösÔ‹}ºRÍÿ¿Qÿ¯W«ä5é,56>B+ò­Kñ:Rµ „Ìi ‘ð ´\3ÍÍOÙÏt³.y7"Äz­t…‡3hÀ8;Xh§\凟+2ñ‘‰mí]¿o!ZŽÇ7Hè¾é¡ jWÐM8b%ÑX”'àöTãÈêØ¢iœ6Ì *ÀBÑÁ]%»%¶ £“¿é½ Œ%ª¶¾!âq" ‡(ž°XÊ/¼€Ÿ†‹Ä%1„žÀWSüȱ0ú‚§_GÞÜb3's¸“uuwNü_š¨¡Zôb®ŽYhj"“)Ä›À“øjq—9”htßËÞ‹T/“Q–ŠÐËôºëh¥–ÅÅ—©–Ç 3hÔÐðQ-~²Û5}2çNùföq¶÷z LŽÃð_ŸŸ¥2W;öÎOYgß­°=ßUæóÇ·pœ§23õ™uãee×"T4_¡ïõùgq¯H ’¬ýH ¡†8\ ¿’e,-;ª•KWÑÿé"ÿ_}ðÿ›ªÿí|¹þ÷`£dubÃ혪M3ÐÀ\ñ8ÚábŒLØ89L÷ßaR¶dYäèÙë|ž­–ïTU-“:+—÷2šBK¨­½]Uµ"î”Á#,àÎà[â‰u¯oƒ6Û8®'0_]MÍ¡V-« ¡¡ydXÌQCæ—¨¹`/í™…^'ËJ®Jžq„×3cÒ÷ Y…rì_è‹ÇGFe×H“ )ïñygŒ†~7W¡ƒpEð¬Í<âõÎ6ÔÝæÆÞYöeHÁ=ä^¼‰h~„Ò»Ÿc¸ÀF&h¡¥ ¢tÎÕ$6ÐÇÑ7ñó“DÁšÄòGÂõà-’Ý>.†k²ô† so¢^XÀÄ~Üa\Bc~qOÐ_p«1;PÀHâNÿ¤%1’gûÒLœÝp5LÙðÖñUelPº^èñ4LcëÙ§YäŸÙ!€èªøÿ“#ü´m¿2øO8Ò¯ºcÀ©­½¨Œù“FNZ>fMi»}B²TÓê¹!Q§».¢¬„L¹tœã›…»1T3~›MC8XÀ<†q¯{ÚÊö‹W#UËFÊìÝÀ|MJÈö ‹y¤ƒÏ‰ºë˜†p€0¦ ÏÔƒÃlã`†jV±ëÌBæu\ALq„B´x&ÌOÈÀ ј™°Å¹Ù­5+P×Fœz+>MŠ®£5rñ]̄׸Óx!†¼øo;¹¦n7³ÙBâåæ 8;XÖÁáZŒ½¶¶§¸íÀ‡)RûYäƒIȱCÁfº‚ÂDú×]ߊóÿÑGŽ_ÿ°öø æ×>Lþú‡ÉÿþƒÄ?ø¨’ño&ËÇVÒt©Ô½ö6¢ (ñNu‰_­ ÉÞľùuE¸Ê[ÂÿÇ?ùóÿÄVë?LqñE´·{²¼ü*©A’kÃ|aÁ“a¯‹ò/¢%8ä„fG¦¸R˜¡Òˆµ˜ŸwçA“;•ó+š}CÃ}î¥ïôýåºÀт VÛ¨ËÆ? ‘“iQÑEÌþx‚-­O~ðÖmv€ÿ«yy_ÚlTªYRrÉPqˆöà_ø9Z¨¥ðð3*Ÿ‰ÀoBfKK‘NúY{z;¡¿Ìš&7:¡OH½$9¾uî’\aò–?rQä>zM}½0 Ð&ïûýsdá_oj¼¯°†R÷Yòw?¼&q«¶ön 4Ïô9²Aƒln~‰ÜDKŽ“1¡5 ^鬮#*[$³“¡¾Ö¡¨î°Ë^f§±‰(@òZ,óêjïðjÈv+;vqiâu•ÃÜ‘¢÷´>–z‡¦f.ˆÀþö­6&‘.+wpï:Ðú´¾á~ïÉZµ!ê‘ÄòÒ²ñ¿¶ì•Éà॓o.ÿßµóRI‹¦¦…Ÿ«^­KÝQDx®Ž2nyvuîÇ4.u¿X€%Ÿ“tsõF÷ky÷X‘˜šî :r[ëVÆÿº;”`m𨵫i ñÓT24¢â_LYéPÚ "ÃãÚÀAŠƒ4ȸvƒLœ›ãiâ'„«–1Pã{Ñzñ¢žµŽYǘÄBqh·¡ðÚI$z3Y{[åÐ<ªÂdCÌò ‹ò¥UUKh µ¬YŠ×hWèÅ~ñA˜jzX_kl¼Ÿ¬½Eô¡ú{˜ªðu8sœ'XHí^$J¾`õõ÷YƇ “å46>”õAÉqiJbü‚J†ñ½R/Ì{xF"pgùÓ¬EÞ}üºNRû9$¤–é½zÖ™Ùeª ìéNšžb±5UÙI$˜hqG]‡¥ï øÐÅÌQ%îi:oY|6m1ë èîÚ=ÂÿGÛÑö+ˆÿ;»v üwšb4ü‘‡gÛ[@PNÉj6±!ëËx+®¾N¢ÐÐ?F$|Äbu8Æ9×ñ“”èø 6‹e„3{©€ð#ÑYªÆ¸ ÜÎ,£Y¦¯ÌTU-hµ´<sv)=A!1šÇ1x!ìQö÷à->˜-^DŠ=ÁE—kšˆ@¡…hì¦XY57=`Ã×EØP’½àIn:Nv9Éĭ€o^²¸¸f»}¼6yÇï_¤¸ÃuƒùWŽI`EŸ—>UZz ×ÆÌ„Nç`!þ…«*(¸ˆÙ'YåËX 2j#¥=+*ú€9YóCÁŽ…”K1ߎ¿nË a¡a< ̆~߬Å< \êqϸ$“ŽY÷ê_ùÚÿ«´ï¿Îøÿ›® ^ü“vÏ?ÍøÿÛîÐßû˜ÿÿøŒ ûÿ°îOKK{l–1«²_þ÷›ðßï…ÿ£¤s1cêËzue×ZÛŸ’Ê„¡ßÜ(|;P±< Ò—Åþ(º´ä ›…%ãu¸Yú?oÿw=ÿ¦êá`6Fo-àA`ÆÄ‹–æ'¤NÙô„Ô ›¸Œ±áa]Ý=.-ß–=-dJK5æxM•MY©ò>YK×ßç¶÷ý‰È™áè“Õšø?mJU¬0ˆ¨tÁ9—å>CK–ðSö¨BC»Zå…Ý2V¡ë#"AxÅç™õ1‡9\@„Búí™]ôM„Ò…l3$4 ’R·ŽâA#ö¬oxŸJ#ýs§NýLz.9®HÛÃÁEE—LýÒµcñµ²RR•1TôaCn³ŒiŠZ‹ÇC‰oýàÇ>ã³×Ož<‡ÿb“ÂC—sòcs¹¥Â"C' ‚"WŽkðÍù¼38g¥ˆ"øv49»m¬¬ô*ÕóúçK‹¯ùý‡ÙÆôú~â)ñg­–1Ü |©‘]9Ð+ËK¯9]ÓþE´U d•Pö·¶€|©ñ"yÛ¦îWcþ•†ÿ  ŒÏÿ¯®ïˆÿ󊉆Ҥ©¥5=B4²dåÉœsd#bFZQq=÷ä9*²™MC:i` +È»PXpc ·8¾HÕÇ0àr’¶3®Äk¸±xš”`g™ ¼µ¢ Hô¦²r°“‰p±ØºË9%bõè8’A·BKÓ¢?4?Œº"®˜Mß³Ðïs­D‹ª«ÔZ-)090ÈV4²Ü1:v²Ì8æ^&­™qÈp¥•H™>Ò©®Àf«]e›w«L¿çŽlf¦VõLŽŽeáâñ‚¯é>Ûlj«FsÁ¤Í2*î0åå׉`ç /£ë1#8&#U+hÒҼц…b„¿ïû”\¶ÙO-™¼ƒcJŠ.ãSèè&eEW‹ .%knë*ˆU…cȬr} ',Ì¿XVvµ¢¢· àëTý] 4™¯®Cø?»X-oy®áýþ?ÚŽ¶_ ü/!e™‰7¾xÞ£b­ø*GŸÅ´+ið.N'¶rÆXN œ/ù%ñÆÍ®,æÑ^É®‰udvÈÞ‹™Ò©º»Éš[ìÆ¸Ð ›YÍU÷)›×º¥Lñ\ë‡ýµLðHwìdK2&›AZW½Y_#¾¯óbT3sÝÈ™†™&äõÞðúHW‘‚Å: _›M·gÚ垤 gbÃᜰÛÇ2HÔàó“î4ñ´ÆM.¥¾Yà(®/[æ\ñL8¼ÂEdk¡Ð’ÍN¦ED½pMáÌÀ“€ù½ÞY¾NlЄޖ”°”eåx|=É™[›m”ÊÓÂKË8Þ""ðx¦1×àyr±®5ÆUQ†°Ž¤áÿ~û™ï7ýÙŸ4ÿèÿ /Þjýñ÷êÿôßÕýßÿôÃþ›Û|˜¬‚‚aáR_Ήht¥>uçO09à„ÀÆø9¸Z\ À?"&ìÇÏD¬ôŠ\¹ò¢‹ñÿÎÿcéqxÈ䧉߈‹ÄÃ"¾DlÝëžÁÎHÕ*°eiÉÕÆ†‡åe=ôÔ(ü\ÁCÁÁÀŸ>ÿ¼—h óÑèªÓ=-¶ª$Xw7{ˆ_ï¾d›•>ð “·ZÍ/mÄ0Õí7­žAëbfÖTÄeøIÅe1ÕpÓ:.Œœ†P ¯¡ /&’›hh‘ØÍpÕ2&âŽÌ³¦æ‡êÞ²…Ý`S)D²³Ò©YWd%™ØèîÚkm£ø‘{mòv”¬®o…‹,ºõ€¬%‹xAušÁy¹0à 6Œ{ÌBî$/ƒx–$j}óÚÅS©>)hM’\Ã!ìAð‚fŒVФ×#R&ÒÓEë‰[е+ÍC؉c¤4?ï¼Á8@çqOñ:lã•\ª ¾«ñjª^ony¢­¨Iþ-¦‚ÓkMžH+¸¡£MEþm\nÜÁà_ÅÿÙ.Àϵr˜4ëÿkøÿä›ãÿd^ÏÿÑV"‘›èõÕ±µ YJ­Ë €çË Ÿeô\<å`ˆöKÁÑ/ÕGƒaÒåžJ&7ð,ж£k×ÕÞ¼giýYàvÛâ>û½³²¨ŠžòÏ›+GÂU‹ J–ÆdêÏ(6(;ø¯% ñÕD×§ïnm~,*C¸áåeW‰öãŸÃX›¼å÷-ЪYPL o¡5¢ë8ãÔD,µdŽ­rf%g^¾¿è°\5°dµŒã'„CË”Ãñ/T…ÉÛ­ßÛPÿ×O‹Ñ±*[rÚ&*MCmpXul£1ëÓÎËN†;)“›†¡¯¶öf·k:‚{RCKfãÉ<„&Næd_ª˜ÝÓ"u$¼ÜÒò(¢ä›¼ƒ§y$ßôpɶDrÃaŸ‚ \4žs=Ý \-ˆÛǪBËn'BÝ'˜žÌ–a¡ªâÌäq@(°‹ÞÁmŸÚµ…€šµxôüpòÿçÚÛ£üÿÑv´ýÊåÿψþÿK*ϳ‰(ò0È™€o.Qj{´S©{˜d+t×…PŠ)ÕPA2Ô–÷ ‡oú™j‹aœe“I„ƒ¶Í6.³†hœ¨“ýór™¯‹Áy¶²rã¼ÃA¾‡@køºÊÊa»}s4§žf̆a¯g®!EKÕ^JƒO­Y+G0פ’w{°²æOý}U˜H`›'z¥Ê “a“´ì'=“vv¨ÇÏLQiÃN]­kKí/j“»M†Aˆ46‘öu²Vα"ˆJ"ŠL§t6Æ)ç—|“éHY¬Ï"b)õ4‘šßz:½-’8æYyÇ·‹ÅO”+¯ù·+W…ÿüÃêoåý þ眦d¢Ä8.[,=Âjjz€oinzÔÚòó`-38³ú¤…—ïIë#uàÖ+F˜Ü Óú?¯I– X2Oç~‰Y訤ø2éµ’§'‘®Ë˯¡Ù°ÔÞ³?~ëGh'OýL2Ìhhó¦ÊÁS¹çñ·°ðbyÙµ@`Îb6‰±ÜBò&8_-ñÈöL«faY–»éJµP%Ûo·3«´œùÒ3‘ðJ€ ÀW„S!­ؾ#ý wží¤™9liâÌc·Q5å*{l=B󮯿—dÞ2Zˆ@G Aq¬#ú¸¹å1>ˆ¿Ø¢ä½Ž.ÓÀÚS],6"T¶¨£å!Ü·æ¦'PÜõ\|@+²z8Ç«TÐó}Ø1vÙDŒHžbž’"Ì¥ˆÊv(<½ "æ[úoŠüµC¾°,ü¨;Ÿ’Q² q†¿]­jaýÿo ƒ1“å¦)ÿ¨¨û»«ÿíìÜù†jzÚðhèÈаofÒ{ªó ¹ó~´¢]Ï›iU«S¡ùíD£éæáÜ•ô»Â–TnÛZ·ÐÔ8w—*³øEŸ9³+¥X¢þD¬°ôNuõj†ÁñíšH7loôµ2Vò$‘·²ž¢Â¯Ñ7]®IqdF¿ã‚¬>Œ68FÏuÄ%%Wpf. ¸ŽY¦¨à¢Ý6V\xÉíšÂgOœø©‘ê¶6MÆÜ“çpþ‚ü 5ÉÛ&ciéå²²«¹§Îá5Âvt¶Œ))¾`o·š*¨ÀÙ4”ŸwÁã¦5©Ò’+¡Ð<>e±Ž˜ÍC+4ü¯i(¹2ü’•À“Œªç–Qd"vU Í_{OµfÛSœ×D Ž-x:‰ü(ǨžkÚ,°§½ÍtíŠ+jѨY‰©Fo‡‡b­«e¿oðÿÑv´ýŠò:w³s¶¯dœh Ai—kª¬¬G8&Ê¿M mý=ÑpÆøßÔüÃo$ºB#v`!^½î ̉9»ß?ÇÆñÄ0±³ç/¥R7¬Ö1»}œsG$¯¯è‹Ç×ðEVë(pNK”!ó("7Gí;ø Î0YUµ\^ÁÔƒÃøbH€ˆŠBË2Ç Hà<ÒfiéU§sB2Ào_ã$\›0Ix@ÄùqŒæi1]×ã,èt×ñ-¢ŠowL†¹\ÓEE—šâ+**ú$|Ì?&›TJȪ˜Dªi%1Û.“ò²“¾?ÝA¥—¸Wø±6Ûh€ÕêpǬ–—c’y¿šÏs.îëõ••^E†8K_Þ—¨ÞøÃú?ýݶæßj®ÿµºšßHÕþvKãï´6ýO¿Q_ûûœù­æÆ_O%§¥)/÷KÜŸ“ú÷¿Ußð›uuðỡñ_¤ê§±ñw›šþ׳ïÿfmÝï45ýnsó[•?²ÛÇ,•Øp[ŠK€~‡ñàŒÆA„~ÿå¥=6ë.ó/ñ@Lƒ˜‘Ý^ªÄtƒ×ø/©a¼,W~ZÞtþÿ›Š%E…I”leª]ñ®b U«G€Ÿ¦ä“-nOoÛ[[Ù‡¯Tïio≠‰|j‚BYÈÿ@ä3‹™ UšwVˆ2W;œ¸çvË ¦~´œœŸYLÃè€+¬¨¹J4Ó ¹r(7÷<ÀÿñcŸZ-£Å…󙔿‚_‹eˆŠ ƒ ©úûhQ@PhŸ99_ û J1&Bo1¿žî÷’ÕºN+j'äF¤ïs:&±ˆdR9˜wšj-ÑñÛ-æá“9_¨2¶ÏYqOÅœû@’Tبrž›¸ur6€éŽR¼#÷ŠÐéKÇop\ Ü+.„¡4~[›õ™U¥xRâKy¡ 2mlx‹­7°ò¤äùqUU+Àb-I>â_êjïbœQUL•%€,óß ÿ_Áÿ¸ÁÿoÐÿW»â“Ü$d™MC9'¾Ð•_Ǩˆ±…x_å½CÐ ðLñøŒF*‹F‹0 Ck8÷ AE̤00¢yà0œý³¢Èõ彈m I-ÏšÓ2K õ0ÄÈ™}Çã¿8îK©Ö’ÀL+Xc³ƒó9x†D"Ïœ»ÃðWê>de™ÛÆ6©ÑR<ø” Ê¢³/h?^ÏLKÓcNŒ<’È?_gEŒˆ…‚·¹q’h­”–ОöídíÉAÉrLu5-d5”­åž!×ôˆØ„…b^Z×-¦¥r­“LÓêRÄWÄkÞO&b%ϦZ¡ÆÆRæ£MwïÎÿ+Ê?/óÿ Gøÿh;ÚþŽã×!ÿß×fk³ ”´FzGxû¢ü¬iBjŠ1$%wØ\^R]Yê1TßÔA“8FÚÓ{0È+§ªd" }?ÉT”1³¹‰ØiŠoáŒ_Ó#ìAÜÑFcþ#å`Ö¢¢Åäm ŸoÞ˜'Ö¼Þ10êÆë±8bifaªš°_³yâÌŠ'/fÉXl-\äPbÓçŸc†Ã¬¸›™Í£ryÉ8Þ˜K&7«˜äaùpxYèô_ß|œ¤Q0åÝfjÐ ö;ÆìÉ×CV•ëQÎ*ÔÓÌ^M‚T8Dì÷³Æýùí3Í·ªð/RÜJ’Ú6­ïããx‹ÓRF÷>¦¡ººÛI¾E÷$Û™-×ÖÞÂl‚#›[až­­½‹YÒ횦ê¶Ú;L}ˆ˜sY’WvÈø ¶ŠÓ²]æë“ÿÝožÿs¸€:«ô ëySmŒn/@®?“ÞKwÊCÛcÉ©á¤I#”H0Mjá[ñø&Ãu©`Æz¼Ó!Z÷¼¸ƒ3§YÛ hSÉ èEPWyð_u!@©ä•úG¼‹"qUòéTùƤ.\ …‚!€ö»¼Ü³–›˜ðyæ=®Y|œ?8m®CˆDÑ+#I¤Ì)´*Mò”YB‘Ú+×ø› CUœƒ¼wØ'ÈNÚ:†×xðÏá÷jó`YÙ5£a?¡n,º†æZÿ•®ìÕà^Äj2õ“A@h)@íg)_wØnšÍƒx@ïUáe઩ .²ÝÍàd0¤Þ7·s ‰…˜}ç3Çã½Q\@ ú "¸¨f†²ŽúþÒÒ+¢1‚Û‚¸ƒ!Óhaá@&jÞÌÞÉ=ý%n `.m²¤ä ¢-ÁV\|¸"ß°ZÆNŸ>o³Œ\¶Ù&ˆS†®ì*㽕¬uÀ}M6Gu"ê XÓÒa ¢µÓj®Ð»ó©9ñ°& zÖ¨ž¯­½]Ë« Tb̸Âë½!_ägϪDHÞþyCý}ßÔü#z ¯UÝNQP0$‹V­íÛ ‘&G"¤†ZCªõèãJ¬ÁUN²"™eŒ¨Uïó¯ØêÊ(ùƒ¾÷Ô›ãÿ¼¢ÿ©máð²ȹ¸wLR xW¦Ó{Ä´¬âø´Û{'>!ß¼Ó_U°`Þ²f2é;Î=×ÁÞâ2€£`Ü+(øÚI†k¹¹_âüåå× /Ù¬ced!7€×åœÊÍ=_i":MfÇhD“³ÚÆ€Õß{ïsŒ„^Ï,Fc ÉâÝŸâqpæ°DF]•À휈H‘ è}ˆêÓ‘ÙF ŠíŠR^Ô×ߣdž5°4DkûÓDÍ¿ÝBâZ¤‚+âZ|ªme©.sàÇ ½¿åÀäE1òZ¥j¬C3õæ2è­¹jlWXg~ÿ¼„„ÿ#?MxDØÏØ~K¥'Q€&†5Ùƒl=F?¹&q+­$‚”|‹Bäšü·ë°e¼˜vª”M4pí‘e6:®ö€F¸'D2ÍÏZ‹ä¯àÿîîàÿGøÿh;Ú~õð¿Bäí}üÑtòè . {SRíæêÂ;|=Îdö[[¶š›§ݶUŸÒtíšø^ÛV{Û³ÃÆ© õºµuKÕëÛâtÜŽú¯í¬ã   g ’°:Ð`!Ò…HhÒRxbef1 `¡ÇsƒBóáÈrªáÐ`€M$ºÌžò¤žÁ+Î$Ή®~Gcd4_—º"û$à™‡ì;OÐ%LŒÛx .z<Ó%²°_’9¸œ æLʜۿCDš$åI€1¶Ö™9𫯿‹®’´‰ðÜÇŒ™¨Ùlmy"¢ÿäCÏ?;ýgïGÿ»ªéÅ1~Kÿ «·NÊôHp¦c—oà3©H“ŠûSÉÊÜJKœ²ÓH\u©ª¯™–ùר,-­O„륊¥¿È’Lžåÿûåÿ_ö³Hr¾])ßË0'-³Ç²GZÕ'S}6ÄT)!éØ>oj~ÄŠ‘ÏêS÷5ƒæ4'3¹Ž[ÉӊΧ<¾êØ:^´·‘ikËÓ¶¶môˆ&RÈÙg&Òl9]ÓÉÚ[ Xhô> :¶ÆÆ\H]m­—ƒ‹Má ÜJsâR•.^$ënaòÅÛHô&‹™ß¦ÚÞÖÇÕñõ–Vú ùeöƒi-©þ>ÀRœÅxi¥£öN‚±:Ÿð~©¡>$’sócQ:åÛÇÔg©»5šÛÆŽfz˜:¨fr MvAþ…’âKùù_a–_!=ØcŸà㸽'N|&2æ8,œ/)¾¢+ïÑé){çÖW$Êú»'~Ê–÷8ÍÛWi4(¥\µbfR:`§Õ2ª×õÒýnÇtî©ón×4:®ÔÛ?øØ‚€Ú;[ZrUW~­´ørIéeDÖ!*ŽÁÇÝ$G°“mÉý’ÿ×Køÿä©ï@ÿóec <<èJÓ0Û@Pg$áƒ%²é̸¦þY1’8j2 TU-K<³‹Ñ‰uŸ(a.åä”~!?5Òr{¦4Ía‘nÀxP©”Û= /„Ãä<¯^eH¿Gžqn®ÁЇ;O¬WÇ×h56LßdŽg«Þ@4:¢ ŒcVëX00_Xøµ¤‰ÊK{"‘Uu×2S"=ºŠh×lU¯;ñ½‰u£iao"¹‰ý¡ð~ˆÅ:ÊñïÓ5Å“\1kwŒ#œ øç•ŠrÆÛ"¥$@Ô·Ñ €¼ü‘ÖªžI“À%ášm! ÜŽ  ½Ó… X×+ã|Yù5ƒaaQQá%"9§$yb4ôçå]QÔå"bbj Ël²[Çì¶ñ¼ý# K­co½õ粺êeýçœ÷>7è}ßÉ´´˜j¨šôøº@EEoQÁE“qÀnµYFOÿ Ý·åp'=T̽’ÿ7úŽø?GÛÑö«Ãÿ§ØÿìÏe;£‚ÿ÷’ÿ„ZZž˜MÃÕñ 1®;^]ë€Åí1çš+‡1zcÊÀ`ŽyYؘ|…äcœå&?úIë3‡Ôq~áÇC+ÁÀ">¥×÷‰á…N×Çò};?q)/î±Ypz€p*MÃÕÿÔïŸÍ;}`FzGø6dôc-)¹‚ÉZÌŒXNþ[QÑ È„#=\<åvOG¢«ëˆ×sƒíTp“]ÕLÍeáð2ðjqÑe«mœ4ÛS÷%ÜèP'GE×Eä•ùTxQDªyÓ3ɶiê1ÙUªx…FŒWŽÌRçÛ=´Öœõ7K+&; ØMÕÝ3›FlÖqüp–ËÞ˜Ç]=^ùYNÕ¹üø…w¼?yËý£ãOsÂ_|ßþgÖαw|ÿ‘õ?¼íýØÖ9ÁE$«ž—÷U€l˜ÝDoØ*)¾b6 ãü˜ .azÅTÀo5äç}…ÛKIT.2ŧp|aþוFâ ’ÂÓÄs±˜G˜×4 Ö }¯“,–²ý}^R2¿%¹ôKòÿz^"n~i”8º7vÄô 32BNÌÔuÉ»²®'V½ætL³¥)íÁLšH¬ü°¹¢­ÚÉæÎc4F`öÜÜÇt /‘£hê QKË£x| ÿM¥î±`Önl|€æÇ«óJþ_ b¬pŽËü ¤„kcsO…Ec®$ѪðR%ñÛ—ð"Ìv{€fËZ…¢íoéf”ŽG €·8Øãœòyú-ЉbIö„Ý'~ë˜Qß'·ˆ"ëĺŸeÞƒ–“ :YÝM[-#dØz—‹+oØmh<ˆ¸¤#èf¨ÑŽY<îfÓ%]€;†%UÃÍ-q©¢‹B–¦ÑU„Ûx4ä`Û½_KëÑ©Z™Úº»õ d¬–¬½ƒ¤‰ê¦â@&yޤ¾R{+ÕpÿE$n6±ÁÉ|ÍWEpÿïRþ9BUEt£"+.ª‘¼¦F1ûÝgëUuÛSít³ žgë þïÊlõ½§ÞLþßEüÿ]u±é…ägÔ(`Ÿî3Iuõ£_ã1á5«,²a^îWå%=+¤r¶¢ìZΉÏq[Žû}ÛXúé·>±Û¨œŠÄ£ôýxÖï¼ý“††‡xX"ïƒîÏÊ<ÏŽñ€ÆŒ'zò}ûqt^Þ—dKÁûÎ¥Lý,øùL*sKJ.áœb!GOG­BÒ2íJІ>Ê¢p‡š×FÝ&2IÏ’ÛêP„vµÚ«,ƒê¸úš=«Ãé=MiöðGv¥äá¥3dÒ»ímÏššž47o5ãoÓã†ÔýHè&ß±­¦†GT‰Óô$„nÎóHÈ¿ ?F›ÚÛ­-O[[¶ñ[ÉÄ­¶6b£‰ülö×\µÍç™Mg½•Ô–\&²:± iWòNi\%R¢œ•éν×É2k‹tûZþß`¸þáÿ£íhû»ÎÿÙ˪ÿ}Ùü,3‚y)ò˜L¯YŸ­eºµA‰v*‰ômÒ,¦MZÜ-¤&dž­e¶Û‰ö£ðv8/zŒÏXX~+ÛêK¦Sµm· £’…»©zW³BB;É€·´²PǶ6¤3-óv4º*.‚ÿ›iü"…†¤hB>Ó²jÙ†¡,¾¥… U&ª$…v5Qí#Ú’V|ð‹°_™àžekQÊØ."*¯„Ï”% e¦WÙ-5;GWÈVõw…ÛÃz•Ø´ùñ™<,YãÆßdÍ펎]Ü+5<ÙaÊÇ#føK* sÇ=D^,—G.·™ŒÆãÚ=ð;’gõ-wá祀Fcÿ»Ç?}“üŸ×Šҷ㧉îk$¼ŒH ¿ À»¹ùQcãCD4T¦GžTç¸BŒ¯Ú;…Ø^ínMâõÛT&?hÆ'$ÏutXí]œœ®k6І1ÿ6³³0Ñ·bkm­[8ac}—(>álT¢ËAAŒ8f7Y™ð \]ŠÔ–(’"hJÀÑš4~eå øþ˜ÍCRŒ/Ž?$ jGÔ,9ùS§~&¶YˆÍKK®àüø[^Ú(®×_on&°íáó\ €P"œ·X†M¦3/帓|p»mÌb$¾SÇŽÓ>árNìqQíjqñ%ò«ZF|a4V!dÝÏD4Ipªãï|‚vb6à–žÎ='姤Tš†9HB¶ø 1Ì ªàœ]½®×a'qK`·Ÿ:ù3ÄžÛDnÎ9ÖN¹VVzÕï­Ð]Çaà¢Ý2ÖÞ±uê½Ï½îéœ_àb¨¢«!öq`‡x÷3®òØ{ ÿãu·R껯U1dñ%¨-þïTð¿ÁЗsêüÂÿ]¬Ì,VM¼\ƒÏGÕÜÓªªVp3ÑœdüD, İËŽÉrLÜjÄAóìû@ˆ‘¼×#+ˆæê’äˆg±ŽR"Ú?Ï&S4ÖY,£<`’ÌF’€)[Ç·„Bô½”²Ž¯WV! úˆ0IAë¶Û;Olþ7:S^çL Õª“Ÿ»È´R˜Ð¶…ïe7í¸rªa¯£þ’J=hlx„×¢q‘ Ü_ÐIñ¢:¶^ŸºHÿ©7üúEÀ(îB7•׈&p‘t‰Án‰ZlKËc~ûTÆv ÑœVÚE´‚à‚ñ–nÍqI­-$1'^˜zXñì ˜Aöb09uòœÝ:n¨è7T\GÌë´QoÒëú–±÷ŽFj­O%jn‰R8´TAAC¦ÊႯ£U+B O_håó#L£%ÅÊa™òó.Hƒ'óÓ.4Tƒ¬Wpw¯Å¼ ï‚ÑЈ›VÁêî:¸{æþJ¯ï;}úË’’+ˆ &wv½hëJYúÿÀÿ'ŽðÿÑv´ýÇÿÝÝ;âÿÕݽ—­  @¦.VºPÔ¢ý‡}²:¶–ˆo4Ä㛘l¶ g¦¦†|?ClSKjƼb‘j>(S†ÕBšlØŠ0­TTôa°%=@÷j’ž[Ä97;/õ¿˜È¸®vߥÓõ†ÂK˜¸´ö†Ì ìâºðÑ9\Ó‡™ÈÏùêl»OV{&H®Ziâ#öcÞÄôAû¹t ƒ?1[Z¶³Ôá™Ä!ˆf“ÆG€Ç<‚oln"1LÒÐk IC±hña†ÂTÕÌÐZ‘j}Šß LˆÛˆÔ8Éù÷î.Ç‹£&ªL¬^O«¤SÖŸ¹cµŽa.ƼŒ“¸ÝS€A߬"ˆçš2W/a"Ö•]ãÂÒu©nÖú€kj6Ù¬v’HΡ%œ p1÷Ô9̪¥¥=˜ØõxÖ`¨4 F#7OüÂN¥Ù“¸ç6Û(XaáEܽ‚‚‹À‡R¿Œ3?þ)§É4(¤—Šò^›eÔjý†Y†všŒý'¾ üÿjè±/uߥ¥W0AK+îÆñcã®ò|:e4 "ÄÃÝ'Zë±w ýøÎ\Tt‰jÛK®åU*Aݸí8[UxéôÉs÷ŒÉ8ˆ=¸c%äDr¯¸‡ú ªmÇŒŒ6Y{hÑh>'¹!ßlîɟᜀ£xkÐ÷ã#˜»»Ï>?C]òÝ ù¦žÙod—7Å_›€ë^ªá+¨o©58”¾fE©m.Ï!eQÊ$3wTF2Û/iõ<׎Ѹî,Þ»‹VTßð€ü‰øÉŒÉ •]¼kÎÌ@,d¿`2¤F¤[­Inrîz#/° -…«–jkoã»ð·Þoá)ˆHÖÞŠ'ÖEMç—Ê_®t p:ž%â™ ¿CÅ]TqÜÜò„l鸈»Gò18^ÄNåþhà_{¡]ùûïÿ\¶l¥Dü7#Éÿ®gÝÛFCâ‘7¦ÿ³«åd´²M­Iã~ 1R ôPÆÃbŸ¨ÆÇLR“ R]4.€·K¬ÐTµ§T`Ź&Od*¤P ÿâ{ûHÖ0”ñúé¶6¢JF%;ï!ù_èA99_œsgœdÁ„^½áziéåPxQôµwóò¾BHŽ~‘›{®:¾†¾SRr q"ºž¸T 7ab®Ýe€á²òk:ýu2()¾Œ®wìØÇh!ïÿÔ\9âtNÛìˆ}*Ê]{ܳxO朋E×p<†£¾?ç½/L†þ'>£Õ?ù—D³OhIâ ›h1€Ìëêů ±jjØD6«¦æíóÎ46?Âýôyg¥" ÀHŽœ¼¹Y™'D–ô«èûm­„ÿ©J¨õi0¸ ³.[ˆ‚x!ÆšïLÃ.QõA +²Q^ÄW»ÜSâsí¥²ŽUYëx®5Û ³°ìž~ˆ¥‰×;ÿÌÿ¿~Äÿ9ÚŽ¶_ ü¿ö,=ÉöŸQÙ>¤*Ðù¼+³ŸéØë`"h,ºn³‹Ùƽüü/1ê’‡cÉk $°De×ÊXÍ8çÄO1¢ v%Îe¤ ÿÆÂü¯$!HUÍKНä_t’¤ç¬¾¢Ïíž‘J(ýÀK8¶Ó§ÏëtÄ2Ba·á_åå½ÅÅWpÚ¼¼ :Ýu 7K%qWB¤xKŠ^[[if¨KÝØOâoÅ=2»‘0µcÊãœÏPœ¶ ðk/¾Ý>yGW6ÐÆs¢ÛIB‘Åy—™ú²ÕPÿ°²r¸¸à2P7ðžÉD>Åø8~&FlÌ Ø‰Ÿ4ØFß¾å"üLèÑáœÀan>Õ nç’ÆÒ’vw§tSóËeOÒ=Ç„Ûö gà€hÎïŸs;¦Þ9·‹4±i °O„˜‚ ˆFWpfVÀ[õ3swëç0Ý{=Äç¯ /»\S˜D8µ;75=©äÔP2y»šx>ó˜5p—sÊf'ꈋ¬êo„CKøF aê×?ïtLàJ˜4ï÷Ïbs;§0Ëà€lyŠì*¼5šúÿêäÒßÚÿ÷…Æ™ÉÞ°&×–np…5UÈâ-fj…rÃJ>€[¬¥¿•¢ <%1‡¶É´>fŠøz²Žh'‰š ̼­mOHyÒ}ƒ³ÛÍÌ'oi}Âv ·q˜xïâ³õ ÷¤œ7‹·ß¯KÝÁ\±‚ÓÏššvdžíc?¾¥½ƒÎöƒŸ¿ÿÁ/ðû«í¶q-÷Í ’|:a’EÅ)×¶q“a =Ð7àC¬=R^!Mx×tYñQŽ:Â%‘k›sº„ûŽƒŠ&öñ)Ãú%aŸò^½n ûÌs4)úH2KO¡âì'ý+]z%^“ ½Îl<}êü™îçh06ËÈñcŸjùÿ³|ñJÈÀM7¯k(Æ£gÔjD>Œ÷p|ÐÁ|€úÇh[7ÿ=û>m/½P¾¯?øùÙ~AÇ¿OÛY yìÑŽ\­¦ì—íý~þÁ¿íÃÿBû‹ Ñð?þ}§rßTþ±ŒVI­©5ÊŒ–x.§s¿B¢Æàƒ¡±' q¥Wñ°ð/DôÅE— ò¿.*¼h±¾ýÖÇh!ÂK8üm¦0a»¤äê‰÷>gw¿~4’ü‚ eü긌º˜‡hò^iß1¥”57çœÉ4l¨èÀY\@uÞé ºòë9ssÆÇZ&"\‹MqÙÀÜQ Ðþi1"´‹¯:]“€ÓØ"‘Up[&ô…ºÔm+ .FT¡±êõÕÂßcAi±ÐZè/Ò*(õQY qñ²Õ2оàõÌ47?Æ i¯ö­˜øÉ C΃ï÷ÍÕãvŸ‹Fƒp˜dÜ®²N‡‹ç(éð9¦Y¡¨O=H¥$kî¤øN‚.üRÜX\mcÓ£Tü•@)¾YUµÚØðˆBîGªVe1±R/IsÜô¿« áC+YW·´p×Jd!İØ)),2}¨¹ÝÄg1FµªQž,þJ‰¤}Ù LL ½¼Ôÿž8ÊÿmGÛ¯ÿ‡òÿûÝ]èø/È)ž ÄX¦ý™Š?·ZšŸbä§¿ÍOyŒz*K®ôšÓM$›š×$nc0Ç¡U`” ‡V¢U«|ðc¾hЫ'­’‡êùƒ-\@Æ-<²µ*¹#ÙZZä¿”¡Q”€O³wŠ&ICó£&ìi!®f4¦ÇàT” kbWP\@4¶$ËúRJÝG–bñÕú![˜/"\’ORi©8†—[€ö›Å›$W¹™ª§¥gü®dên(HÉLLFc£QŒxëNþoã+Xºð›”Qf 3EU˜L¾â‰[ñêu³Ph%ߌÅ6°7onÞjj~šLÛwžî/@SðRw³~uK3bb6óÖÒºÝBÜÁÇ•p>p«¹ é±üdl‘ðJSã£&NF±("&‹íxl÷Ÿ¾±é ¾“T‹òùª&õ'*HÞª!¹ÈYìIÖÞšªŠ,74>ø¨FGh%‰ nQB5 "4¯ êŒFnAUW“FЍ²p[QíÚ ÿË€J‚*ÁE„*Ø_GéÇYtØÆ±è—R‹T¸½îõÍÔÖÝÆµy¼ÓÁÐ<Þâã6ûX$ÃáEÄ58ÎCõøá%@_QÄBhƒý"®¨‰‹ªckUá%¦ôS%LjީhÅà_„”¢7!vŸQÐõ™³ûgUÄÞ­oü¼^p&ÿ3÷†1ÿþÆüt+ÎîKh  zöôßî}>9¯‚ö_œÍFõï+ADRïHoñ"Óµ÷þû¿xŸ?•ÎìàHD” Å‘#Щ>ÀÁþŇ²ýP¶¿üèÿcï̓ãH³;1;ÂÞð?»«°ì‡å]Iáµìð:vስ¤•ÖÒ\šžžîé!›¢ŽBê¾oêÀ}…ÈîžÞÖVÒh±›Íæâ¾o€ @$ˆƒ .r´žðï½/3«pfg´b{g„ˆŒŠ¬¬Ì¬Ì/¿|ï÷¾ï½ßïãçã·¶î üŸhÙ¡ñÿ oªþ7Ή‘"ý§Ù3¿o>X¨«Ý‚¡CGåp’ÓX[lœ*VÂËÀ1z^kfã /‹¤Oàu¸%ªÛZJ\‡iòRBÑ"z‚A¿o6昋 göâÕ`üŒ?„2& ïöLãÅ¡+÷4-:‰Ã>F³/D ÎL#ž©:®ºj¢)ѧx)l¶Q¢åñÏú|sˆ)<ÞYƒ¾Ö’-ù¶–!L)ÛµÂ#4ñœ½À6»¤mù×çBú™½Æåç×=§ùTD *Í_¼ãB0eü¹Ûи[× f=žóŸ²)#ßG»5òBv•)¼ÐÔÇ8Œ†QßW¤ëµ‡Št=çÞ¿‚¯6óóP ûÄÍ´sŸäuê‹z᱈ꆈµ¯½ûîw±ÎJñ=Ÿq>nÐJÙ}ßz÷{8 «Ã,‰£Tª›ˆì¼¾©³gÿñÕ2¢-쾘y*޹@˜ù]ïiYYTÀÈ|㉠@ìÓšäaP¥¥iÄVšë§ñÿ¶¶=âÿù©&úÿŸ.§Ë/ÿç¥ÃDË^mõóвõÊŠg5•5•›5U[µÕ[µ5ÛXjª·xÙ¬cc[]½YQþ¨Ž×++6p,p,€Ðn8б²Šã‚ºç؈¥ªr£¬âiyÅzEÅz4 Ç´‰>ŠEWUâl뀣b7ÀW®«Úæ+e·yxd«†íÏ4ðO!©ÇÞÕëº33>3›Ýž‰ŒŒkÏÓÓ¯âS£é¤ümw \„5—{Çn#V|!„,-ˆp*œPÃ¥ñbXµ à.qÔhï!°Z‡ñ »ŠŠzŽQ¬ºWW¯+–3Oþ&u乩i'™‹òÁ«âç”öžoeqáj‘ÔzÐÖzXQ¶Ö&S‹Ïšêõ–ønUÕSQoK`XÉâÌÉt—^rn=HÍ{Q¨œDF:]ž|=JªŒt¸`¾ŒÓþÝ= Ë€—1zÐ’8P©{ÑQCá¥`h)3ç^0¸T[·A^B­áðªÓ3ƒ€ôRÛK­~Ðdô/-cv÷ŒË?¯5 kõCzÓHžf@[ÔoµMº=óvÇŒÙ2.2½ó5}.Ï4Î`¥4D1”ë¢Rwhû饫ÝÖ û²s{¬öIƒy4|x&½½‰52²:´¦«c;#\Exò®ÿ2îíÿï?øËßþŸ–Êüø_«½wîü•7„ÿ2m²Hò©ç` V`µJB++ˆÔ í'¯{:X$Y¨ðCØF›m† -ïõÎéõý€¯µ ›uœÍ(Úª¶¶ˆ–ZVQ§Q…:ç©¡á‚-NÎ'#VUý¬¢ò)Öë$;Œ}„É"›L—T·S[MžB\iC³ G“hTU[ÃQ·ÓÌ" XoÂ`è7êiö3Sõ9Þ©lÕM«eXÔÃt#Yo±Á©#7Ä®aS²¸þºMü٤˫¥§¡'ücÃv-O᳆vØWÞØÀ œ¸HÞXW/™b2Y4ô±ÅVFKê)vàólÖÖÓž<EGRüþy§{œ)‰<Ds¬d2õS…Qh±²úYUí†Ý1V~€®^þa5‚)–§œRÊóq”ËE¥œéj«Ÿ#dcÒ† "j6#‘%´ü‘Ï7…ˆÏbÁW¿Ÿç;|SN׉4>olÚÉιλ}Ó8'ßÝF04g6÷{üx‰fê¶a¾¨"¯ ;Ó"Ô0EÉ^KË ÿuº{ßþö÷Nñÿérºü=ÁÿLžO£Õ5ä€Ïñ ¸^^ñXÑC¡‹jõݲʧfÓ˜Ç5k2§§Îé@]fó9ì’^×§+ìµÙFá)|~À›x(·}Ê ÷m+Èï²;Æ«k7Š‹ úþô´k……Ý&Ã`¶ê@f^þ]­î>À¶Q?§î!þç²u«uÜdÕäß×öãÚòò:µÚ`-H)îÖa›eX§í¶ØèpH«éÖv9ì“Ó¨˜QãÞøSn³Ùì#ØS•yfÀ³n”—­ªÕwp1×$NÈIGÃvÛ°VGçÑQâ´Ë9épŒ[-£š<üioú¹OMÆ’Õ³_YI²•Õë0øÕ  [d]‰ònWT· #ÌÂD×Õo5qÞl¯p¾•Äm"8Ê0,y¼e¯¥ñ9m* `NxâKŒÂÝ”ÞY$ú0Zú¨$ü°¢|Ô!¹Æ­84Ž<¨®yߤÆnч&HA‡p >ÿLié#\<6F"…¬pyÅjyùjyÙÀcœ3\Br–5µðþkšæ ‘~YŒQË9<¢û2É•REND²bè•‘¡^ßûÞ™7Êÿyx‚àN $Æ'V7`?No~!ÔvDb9“ÒдQ¼y¿±a§¬tUðù .ÐÖÂyHr¢Qª7§Ùv-Lqsî/»òáœÍÕ$Õ¤H,²2”DHȼR‰¤Ôò¾¢ª,3AíYÌCˆ4š. ¼bè¥=òÔwB¡”ä&M½Hø! “±ßl¢:Áü‚»ÚÂî’ÐÀ-Ÿg†† ïü³B!®9I9¢Ô˜Ë7ßKe’þñæd¸mÉáò:õ^n )¦wß;ãýô]¿JÝcµN~é­+çÒnŸÏ¸]¨ø½/ýÅ·Î\uºæëk·ÿøÝO¾úöß9{ý«ï|Š(`ò\Fç—Þúá¹ 7Þ=ûYºêΗÞú~¦ºëlúßþ×’žÝ©Rw¾ýí«8$-ûÞ¿ýýpô1Þ ?üÚwß~ïjúÅÎó•¿|ïýu 4€‘Ùþ‡_ý‹Ò²u¬g«»¾ôµï«Ôwß=s53§K•Ûýå¯}/¡wá+_ÿþÙó×Ó/v|åëUQù Ћ§>–Ÿ3ð¦0Vd€ÇãÉü<…soLÿ‹õOvišÏòzg4]ÅÅ .×8ºAæÅë6ëHzÚU‡}4#ý[Qa ©Ë 6FRtÌ”/¼¤°¹Ê'—“¬èWQzùGbæõŽˆz¼dS)õ)â´\FqI[>Trº¸È‚Ε–Ä^¢õ Þ²›hE'߃!jnÙÅW¢©ä¤¯Ô¢ ‘9Ö&e‹ñW±®LI_œ]&ÆÚÄÅÈMÇFòié²yFIØ®%猤Qò#ù§d=>aalaj¹rŸÊ«K–*ÊVcѼ}|F–IÀŽ(OaNÃzàÚð8ÊË×s b]ݦ×7S[Á%!ÇOõõ[ u[Fc?¾"4€†Šð”.¨0 ø*´ÌpÚjÎ)Œ Ä—K%ÒOqfÁÔ-xpòHt‰«3ˆd#µ†E^8`'ûü£þŸî÷Μæÿœ.§ËßþÿÃKmÀiÒhž”lðáG£¤¿ÂX|³ËÌxqp0ÃË‘Áâyl, -³Pš±sÜá!6•âE–@]±ÛFÍ$J;Ðn¶ íIùcwÒjÆ ¦…“ùÍ–aœÐ`è% ç¨?0oÙç±®Áé‡éI/ [¶;Ç‚<Šâ÷͸<Ä[è„ÁÿVV 0­Hâý€Òz9³÷ÃÁ™ÂèÕ•ÀÛ60I†Õm66>oŽ¿`ÝÆ=N¸}‰ÒÀH\p(b³}Á[H•ƒ$“ôìsHÛa‚)Ù¥ŠHÁ¸Ît‚Âý)ƒ¨—…“º¤¤4“ó‚7”Ò˜…Ãe‰oÿ¼WV¶ ¿GCÚL5ØNœ‡Lúâ×*VŒŠ•®ˆªÌXlµ´l¥¢‚?ФD¥X¾VW¿é£¨YlF–q;pˆnp qB2Ë+ð¸hA‰ÒÆVðÈ‚¤)¿Ä—ÄRá€p¸—žÔd}ÝŽ ÉÄÅ”FV‚”rœ®Dĸ0“©?-ãê›ÃÿG©‡^¦¨×‘à¯ÄdE"_ÏÃá‡qYy“Ø?$(iº¿¦zSÔ6²¶ïL%k««žUV¬sº " äqÅN‚¢\…’Ð26ZL#bÊŒÓ6Þ5zh‘F…`Ùã™øDß¹^!Ò‚õFQ2)38ìáYàyÑÌ‚o/W0DbÁU•ëTw£Ü3\³Í>*`<œíC€Å‹v΢d ï4;Pª‚G.óÜiQDåfc /–È…ŽL5Ÿl(ò¥Q_‘°'²òž‹-| í#ó"ÑG&Û8"P|­¦açí*Ä¿5Õ¤Ó°3á>¯Å9E>3Z²äAà­:þ¥S5nKÿU¿S'¹jµ‰+O}¥F& Ch†0\!Ëj2‚¤KpˆñX.-œ""g‰P¡ø‰šEl—îŽÒù_0…¯Œÿ[wƾ‹™7Þœþ/[Œ—G5›hÁ%Åb¸„d a~yÅZŒë¦$a%âñ]ñè…TKË=K%–0p[Rá‘ὄ¨ÛdüOñÂ%I~B ‰cyãÉó¼RªÔe«(INHñÂ%Q9ΤZNe=‘4›ÊúXiIìÓX U²'÷i‘÷ž?JâúR¤Éy hdÐí(\OrIÒ&K©hrà êdtàcái—k"/¯ˆï”:§ÝïF ÿeµ añ¸'óó:¬Ö!—sœ†MÚÑOà×ÌT ×Óî-ÒõÀGà½FlN ÝöÑ‹¯a»Û5~!ýSlq{&Üîñ´óWI§ƒˆ£Ø9;ûfÕÄuhµ÷Ìæ÷ÏüÀéc~ƒi>Žiåƒ#{ŠÑæåag±9ü *{²™z(Pà4Å œ&p,U)I´¿ X vëvëÌxUõ:³ç­U±oIˆÎ‰µ{sí x+-ˆP`YÀhIù}ó%¡¥iá»u´4ºRY¾ðÏÂJ*ã–í–á²ØJié£Úêg²M–(VìDé6HDIŽQÁN‰V‚s×ëz‰ê$±ïvM"bbé„1üTzà$V¥ñ¬ìT cuº&Xà‹|MÃ!’N¨s\¤yã@¸¶ŒŒkó Ï7…¨ !ZÌ ïUe^Çž.|F‰âÞé´sŸà2°ž}‹Hšv‰(÷N®º»)ƒð)£ñÒS†cÊP]ÿBðÿ«c!€ß?ƒ‹ôP†ÏD+ð›ÄÌ£íÆQz}ÐT^n‡^{¿PÓÍ„{ýºh8q£¾ÿbÆ5«yH“×lr:' ò»4wáUºwá+gzÚU“qÐhÐöèt½Ó *óFaAÜ=ðë|Qi¤Õ‚3L:ìãvû¸VÛS ¹‡6¬ª~¦Õ‘Ô©Å:Œ‹Ô“ˆç=ü;±ÈÆ…énc’˜Eš] R™Œœ,-vX\¸$Pà^‘ÿœÂî²#ö'èÛ@OõRòsÊá­HU9|*®FÜVè\hfRD6D —T -‘À(ô/ ŸŒ¸`ÎÇÛ 9—ÅK¢È¨Ž®‡V”¨DwIÅ,rN¸’Ñ-¸Ódúš&™#W´¤Ä×*՞ąG\{¹%â "êQZ@¹r…€W!F †³ÁÿæþLõ­7†ÿ3óNêYpÒ¾é“ Ý‰#šÝbèXÒ^—µN„–¢…-A^R%Þ­ÒP†`úm‘EÉÅÒŠ,*'tåø«„´…‚†ô/ÒÙ^Êbv/Êþ‰ƒ*kÝ׌…xMüÔÂbvâ9Æe±E„Š’`bâ@þG,(×"—za‡'ã)ði{%Ç2RÈ µ³¢yÇ[„YŽF–ñâ7P´HSº‚„Šõ>–#‘‡,ðHv“„ºZvŰ|Ñ)oJªsUé2#ö™{8+eLT[ûLh…ûÙGà"Ý®‰bö)3>±§:Ý0¹uu55Ïð§8!¶ÃCáSð x½S4Ã[¹–Jlõ:üOãÿXL¦¾ ª¿{ü? -ïÌO `¿•Ýò:óOñÿérº¼éñÁt-Ïx¾ú@Ö¦$^"N߀aqØG8C%ˆŸ¼â ÑQ:ÆcÑeà?ÉÎÚl# Ê@~ Ìû<3ÿ|1uNêtÝ@•ÄTV» ÀÃì“•Oñ§ÅÁù€Ÿ¦ löQŽóx¼Ó”‘ž×éóÎ42b) -xˆ²f¢8¸€Ó:l£.פÕ2BãÿîÉPpÁer?œÅ´íqNUV¬••¯¦Néòˆßö/Ò›u_b*Ò9Êí¼Ç:¦ÚG­Öaà.œY¤‰q·šÓjˆK³¬t5;ë–Ë5‹T]¼îÆ5”<Ðjzpãä¢ËFC¿@¡0ïåå †>—sÜç™&’:Mwˆ¨'¦E$ñð8(4€YÆÎ:€´aäÝöñºCfu^khzÎr“;D~H¤‹X¯­!ŠQAØH”5u4Ê×zPÎRÕ5D—MÜ­„î¨tR¤€Š ¡ËÕÙèx0êEmÍ3x®f1÷‘Ø4’L–¸‹3`£ ²®‡Øš"¬Œh£Ê2¯R)€˜¬éÖÆÿ©4)IÔD‘ŽcœØ&©(ò!:únié B$´Õ*úçÓY,ýBR—Ç=UVúØá$Js­L—•?²ZFýAN»RV¶ævO5·ì9ݤNë™æ‚Y"hb>¥yA3KB·¾Yô¢÷){,hcI¸3¶džv&|+%¢p”ô좑%Yrt! %p¶0.2à_à1ÿ¹ ÊCž´áju;ÂÜ&@¬‹D²1Þ£LÕ šÜ)_Ãß¡CÒ›‚=ƒ ~߬Õ2\ÛIB«ÄÆ?e± Q¿eÈHòñw†"Ä•¢…ß¶˜‡ì–Q·gÒ`ìÅõ `¡d$ï4ZgpÚI¼;[ÌÃͤ?»/0§<{òÂéžÓh¾úÖ_½sæÆ—¿þW_{û‡ï¾íýô[¿÷oþì½÷?»ÙyæÜµ¯¿óäú†>$zJ\“)r®’ Eë‘!â„ 2m;T”øx¸15vÓŸR‹mSq2³"³þáÿ³³ï¼¹ñÿ¶¶— óOêÄž{Cý6B{\’ í ‡Úl£±(!FüŠ¥±a§¼ =mñà`{i¦ÕŠXpɘù «ÃþÀæWV­××Q\¸ïD±JC•ÏŽ1>hØn•$-^¦Vô¤LÎJãÿD*•yóâuGÞw~üñkO\ âÿÓåtù‚ñ¿4Þ.¼aåZ¥¥5q{®/êu“6è‚N×C –úûøÊÄË=4óHìñ=p©0\vëH^n»Å2HøÖ9^¨½#‡òX$í#4Tki;00ƒ(q˜ø© ð£$¼ä÷Íè ï'‡K–à/à•€+¬¶‘Py .ÏáÁ¡É»Ãàà:ë¶p1ÅÄä³(’N[ó¶NïÙç ‹=ÎêyÑ,gøˆ$Ÿf©j¯¹eW´JHG1 Ç cqžvëI¾&öY SŒƒÈX{‚V]ˆdµò„5%»òžbI]“‹õ6†+mòƒÀyûá>€Z[™Ò‚ý)¡¾phÉçžÆÙ8@¦Å“‚#À³y0à›E³µ–„Ucú’^M Ëë4ÍEÚ–­e#ÆHŽ«]îÓø±}À&L‹g†çBÛ&x4‰HðŒàPZZ÷óó:ð ,ƽî~UåS #¢ ÎS]†¦ ‘Z Ë„’*,-€µ™97¾üŒ(ÕûK#„ <£ÃD ZxS$ŠH˜§YÊÀ§”¡ ±Dy=3Šˆz2åµì ¥òŠ'<¶‹óÔÔ<É'"áÝ’°«Q4IzC„Q±E”JLý Ç-H›iIð²M(”1'À[eÕS¯w*;ûV‘¶ÇËá¤Õ:„W 'ç–VKå0yyxãX#ûž*óºÁا×÷f©nUxÙê¹´Oòó;{âɾ÷îwR°bUÄÚôF;Ç r;Ô9í‚ÆG­&ºZ•êFIÉ“qPs+[u ÈM–‚»8[A~§&ÿ®ŽÊ6o`AOÓõhµ]x‘3.~Ž_NÈÃïûU56÷´¶hÀXpº§Ó2omvç”Î8àpN¹0<ÁrÏ4 ˆdÝĤ  æÑ´ìÎhlõý´va¨‰ŠDn¾sþFvaoFvç×Þý윪#KÝõ~Æ-oàÁ[ï];s±‘cfîý3¿ýþy®fðKoý0]u''¿÷í3×Ó2ØñîùöÊÚ-¡Y£t îœ5ÔrdZDðaJ’ë øEø_YO¦,‚£AW§FÓݧQ¬À,Z ÿ_––~ý/ ~ÅW<Γ²)â %gç™v{¦\® ’löΈ.íóÏZlâp¦#NJkùVÛ05¯m4]Ák‹§\Pp-»ÃóÒhº²³ojò;-Ö§s4íüâõµ\¸p#íü§¸H¼õ J|:<1•/IZ“þã³™XaßþªÇgåÓª“çþøÇçwi”}Nñÿérº|Aø_âüOêÑW± Ázˆ‰cXB²÷"Œb4˜¡Ñš˜Ž’%©9â±%Ž&Rÿî(^Y¶îóЈqÐ7ïóðR´äa,º¬ˆ{$šDþ¯Pp¦0|3ø¬,âqN•ÆVa¨q~·s"\Ä_GÃñ©µ®nÎ' ËÇ”Ç9‘›ÝîtŒ“ï ‰=€s„]Ù™7]ö‰pè! ü”‘q•ç)ÆMîÿìßfÿ—wBiÔõe«nš ý.Ç„® ˆÆ„“”éÚ'¦ûIÈ€ƒÛ"IªãÀFæŸ9¦2Ÿ‚ÿM™ªÛoÿ'³ËRñ?<°î¹3?iQX±Z†²²n™òPù`+Ãôêêgð›èf€VëpzúU‹e7h2õ£ á–þ/\øÜÎ3VpñFã pŽuÒœ÷f͆Aƒ¾—ŠpMC>ßWãà'_¼ÅgÞ?wö <2é\dÝ¢‰ ×8¶û3&C¼¼¦€$!p©Ê "2%ªXq¸‰ ÌwЯðº56QBuÍzCã6666=+ølnÞ‰·ì’èUݶ#Ô¥…•Zâ²~wRW:™"g¹g¹ZyAq¿UOh‹òS|—ƒè}±Nïšœþ¡¼ÑJêEjš SbÜ^½—!Ár±Ä÷„jV@lCJnIrÈ7öËõžÒ:ç ›C!v"5´¤$ϤâFó§æ=ŠâÿoÙ‘ð¿i KÝñ¦ð?Õÿ¾…Dc(´„n =@›”ÑvbT`^…u!ÎåZð+"/,Ø‚¦&±ƒÐ´¡x %!ㆡ k£ØŸM—¢¤žðBK2 Ke¥ý>‘`2¢µpèA9O/qìq>×nÄbË0 A¢~£¡£#FHÅÿ€&sÆ›Äÿ¹>ÍC–“çÆÝ ØïœtŸâÿÓåtùbð?¼Œ ÷hiÞ\ÓäXihôK}ýsàØŸw˜Ùdì÷z¦jªžÁ"Ù­c6Û¨Í2b¥ÁùÑu;á&Š—@R†ì0ì+ÈÿþOV™¥Œ¹É¸²×STJ“¨òeJ° c€ÖöÔx‹Ù4¤Õö˜Lƒ$Vå*|u9Çí3/Þ𱚌žÕmB¡…¼¼NÊõM8“FÀ&¿ övØ ï#¸[²ˆ3Xœ$-íª×K´opv~å ‰‘[RËòÍ0áöžŸ× ©óQâbO³eˆ ½{2W}Çíšäù#ÑÏ#(W«HÁ•œã®˜È(+]M´ìWRUÂ:J“†¨%ݼxÿŸÿÛœÿæc»²üêwlôÉ+ÿàãì ¹ÔÅ£âtÙµõ[ð_ÀrpÜb†‚Ó{¶Ää̓ð¬ ËŠC î9≠IJ˜²³n¾9üö'}\uÍF0¸P^ö޲¸x÷%8÷HÏ‹$Àž ká3T²äÌr8y€gGôÄ‹µŽë¹p$ß\ö¸ŒùÿáÊœ°?•`SÖÓHdÙhà˜hYè|¡ŸDc+ÀQˆEã ªÂs GV×>Õ”W¬a{$²‹.㜀ëˆê·[N^0séŠÝÉ1އŽÀ¡PÓðÍzÝÄ^…nSXØMpö1»c¿"¾@‡,Òõâlzê·³¸q„«Ì.8Š»Àݹœ>ÿÐeþp2:§Ã>¦Îîp8Ç Æ~–[Áù †>„«bÐNIzøG½ö~‘¶'XL* r6Åq¤Šžž":3ÚVR²D@‚tSuhí)1ÑkˆË㩺=ÄžeÀ3¡%4 "îXlÕfÃ^ª^9äht4˜/%F”u*ˆÎ76íö“ÌP£=]DðHˆáh<‡}<\²„ˆ 4‹óp9)O…X»!ÿ¥?Å]¼HüŸx.7÷Mæÿÿâ+zšNwO0à§æBáúítSËV˰Ë5 ÛËêê¸Ç``ÑãžvØ'Xpvû³Õ.$ÕKàCÛ;˜†¨\ö D"ÿâr-v8[öC`€Lüª-ìrÚF}¬0e2ʧÕ4„¸¯H{ßãšT]¼ŽˆÏmŸÀ'®¹®vSSÐ . :㯫‹É<”™sûÿüfºu€ëhä†úçÀ‚H¿´áh®JÒô\‡ß„c€h<¨Œ­G¢ËUÂM£·£KÔÔm&”ÆV+«×ê¶ÛZÑÂ@&•kø "k¥ó¬×ã«7}4ë´ÂSB,–„åkh4À$ÎÁ^âTm†då”n„g‘HÙQj4]x"¸ÚsgXËñË…´OõE÷qã3?·/î=¼ž99·ñÔÃZ,çÎ|Ñ:ÞÙ )«Î›ù|SøÄ>ó`¶ê†“G–Œ¦>!ä °] !]o¿V¯ïDÚ¹üV€¢µ…÷Xn¸ÏjÆ©°'öÁ¥ŽT+ãè´L±K…áÿkœ¸Bu4zÊ\º/†¶±üÜŽ8Wj0©;òpBœÖÐoŒ,G/¿ºüÚó´´â<âß º4¾¹Àkÿút9]~‘ð+£PÎó‘l3©ü³ ° Ü°g0ÏsœÕC‰=Í/”b½‰Þp'Y¾ÇK\&0$ùÔ–åŸ%åo·\h»¦pwHº9\(Ðx,ò1 L1–ºúçäõœ“NÛD˜ªA§á×ðkqp/Y±(À¿Ô˜ •,Ú£¡àB ºn#ƒñ„'Ñ8ÿàゴاi±«ç¢ŸdT\Ã’Y}ãlÉΆð›–`‡s•WT»Mò1vçN çE–¼äü~qp!B9ÃT_†ÿB3F#K¨vu·¼ì±“dñ‰¿ø$u*'‰ÿMƒ*Uû€ÿS^ À+)š ®ò\“½¢9A’£˜J— a*(:¦$¢*z¦Ô†•O‰4Ì7]Y¹F™0å4ÎÇ ž¬\^QŽ7ˆDб…ijJ–ˆOØ3UVþˆiÖ€¥}\Jf¢ÚpÉC<}¬àQÒ¬Ñ&xqI–¬ÁDÛ-#Å¡ü). ÑÂg]a·ÅÄzDZåÚZbˇåt»'b¥¤ùˆ¯ýMò…Ãð×TéÏýŽpBØ.+{@û\æÂJ7å‘®HáÀŠ ÒÔõ! ÆÕ’öGó‹Pñb}Ãs\ƒË5‰0;#ÞGø_{$$]ÊÊW… IYl€˜N4~%‘9ÓÀ>b4¼„+ç-륥+$&î›kf¯ Ø/&|Ybž¦5ñ…ÃË~ï,=µ†/¸£Xôa3³=œÿO™ŸMì þÒ É¼ýFñå“J¬hî¦î]Žb#à7Ö_‹ÿKWË”Òàc  8^埄ÿ5d·«•ü_·UØÿÚZGl'σW$çNî±= »µ§!Àéò‹>þOYðÂ‰Ä ù+øŸÔáK–¤Nb Lä"qQA¶Jì XÓÙ+Ñ’*^m]Ôü/?.øÕýËêÅç¿ü¨îŸ_ªúß.WÿóËÕØ¢üô?6ˆë?øðÃßmkû½K—±ò;m—þõå°òû`ã%¬`ùï¾ãÆžmŸã’R哚S 5<5 ¦Ùl‘‘íCˆBÔ†RnÎðü¯À§Å< R¿±ú_LjÂüs‚è%‹¢)_,ºB·t•9yfŸ—1“â>Ž^·™£o½‘½0©¶Õm±¹‡CK¸‹(¾Ãi·O°1Al« ÄõÇ` ŒRƒV©šû°T•>â1½­ººòr*â¦~FªUUXÙAœS]ó¬¹eO¨NHòœÇ"±Ž_ú§¿¬¬z"Øn“ºHG‘x€ZÈq°PW¿…Ïʪ§IGßv­´´RŽDe º‡Ë Zôˆ‰ª«n ¨·Ž,¡Mè¢JöCEüKpmá'NcÞ$ÍRÚ"š)–ÕØª—rï/½Ä©€÷O>ÍÉ*šŒýÅÅD‚TA™f,ç1 €„}˜IiÊÉ“ÜbO¡EÄb¸l´VD¹´H®ÃnçPIÆ[{e4ô»œã¬‰L´Š6ëBûz"ÎzÉGÍáM7™†þyCQŸN{Ð §%1V÷¤Ý1–Hì_ºt„ QÉ’ð¿œÿo±äæ¿Ñúß×c6–oXÂ]Ã^sÑÅ,¢oý4L ÀiÐ÷¡ð†}sÁÀ<•FÝ, = Ü§ÐR155 ‡Bzq6J ?¼dÌ5ÞŽ%\À9ƒÁE¦«Œg©ºbÏXôÙŸæ=šv4 ˆZ@w»“Bi…Þb4x½3œ·L+fNaÁDùAhVÝ-/BÂ5›•U„ŸMˆ `ël³àõ³hdû75¾¨«Ý‚{Â3­­Ù,§B®¯oÚeÛÈÕg$N·GY@l6SgfÅÔ­T '¦Šš¥)ÚmûÅR.«èùt³¸w® [uÚÆKÂ}žYt¤``1Ä”Jˆzð °ÅaVdz š¸Ðƒòе’’¥ºúíPñƒ@p÷RUý ýAqñRUÕ3¦]z\S½†¥wá šëlb?Î*Õ¢¡%yXá8„b:8®—‘óR££ù8þO$v%üoéÿé&ú?ÿçÇ àݰݠ젽_„-eËþ/_«°ŒØð‰öøàGàFCåöqma7 2Þn!ñ 'ËĘlx÷ ¼ƒÅ2äõNåæ¶c¼oÎfÉξIcÑÕS€šÿõÇV¯wÚãeRz'Õ±Z­Ã”{@EópEœÚú[—K±ó¯~ÇVPp—2“ícFc?¼Í6LŠÃú~x•ê¦Ý6úÛ-Í4‚Ý|¥   ¾ÌéœRæ2ĈJ}ý¶27?UUµ.†¼ð“þ?‰4VÃŒâÒ\€œÄã]4žÆ,–*sÓfÍFi) 8Áï4Ó8›T7-§IJ¯ÍÍû<·Â²Jø¯y®¿fÿ€OŽe¯¬ô±¦àPS~þ]‡ƒHãuºûóÉ4h4õcÑi{ÐìEE½óp °¨×ßGK–ÐhÒ\°xQWØc´÷ÿfsɯÕùÿ§¶Ò_«õýzSèŸ%¢¿ÞXü[m¥¿ÞTü¿~T…åŸTå¸4~rÄ^©šTR’R}Pj¦L ~ÿ'}É<ôæÆÿÑ¥éèëðÿ+@Je®\n{ ªCÊáGˆ~%’½ýZ°'XR«ïäçu4ñÀ)¥ØFÔY·ôÚnuV{aá=àC‹i0[uÓ ï--}”Kœ]C¹ywtºž\õ]Aweź:·]”Ÿ‹RàóÜú÷"mŠ™…HÁ2$¤Οÿ¯sVÖMÜÈùóî!¦ì¶1\3ÞSÂêî)¸LAZ"XJpÙØŽ°‘昊pÁØ‚KÅ ‹zs²n! átµA›}ë°çÏþuC#q }° z]OVæMôy˜#àóóî¨2¯ãÝÄÅè4wÏ¿B¡x|LDL¿@ªÐtÔžºlÇIp ¸6î/!åkKËnrüß<˜£î|Cý¹U¢;–­Í%$žé‚¼7aË)“¾?íý+ZÍ=4W~n'Ž*ÈïL;wÅd¬kØFƒgeÞ€¡vÚÆ<Þ™@p.+óºÃ>j³ã'£¡ …G€öÑëzÑKÏžùÂ%x©T¸´rþÛ¥}¢hË~³ãÿøŠˆëÎI·‚Æñ5»]-~ý¹òÿ¥‚‚*<Ø“ø?uÀ?u)êÕ ðßvØö³äÿÓÕN¸Žý„0AЙžÎÓåÿ'sÎÅдLˆÑ¼ Ð Åöj‚“‡gð):ai=žI&7^¥±?á| ·‡Tz±?€z(´>älä!À Sd@ý~lH‹^M^=ùDUy#£ôÚ…ØgiáOU´Ž%-òiNõí_»ì£`á#Ì£ßOÉ->ßl€´hƒÅ¤8L´ùvüãÒÿÞÜ@ø?þ‰ÁÐ Ò4¨bÏ9‹`àM§é©åB?‘\ §Ì _†fÓ ÎFb޾9 ‚-¹œnÇÜ¢ ÄF8G5\{ûo6Á=uâädØMƒú¢^l`µŒ¨³o»]SÓ»É4$BŒ” =‘EÓî ;©þHÄ ÂÅEÕeÕÖlÂOµ¡y "rJ‰ß?‹uQ€Øòò5ü{(¸ˆ À \€S.•†¸gñ)JJHújŽÔê+ŸðèÜVpøH¬w²CQp¾X… ÊøRj¶X\J%KOQþJu7‡KÙÙ·ßþ—34^¥F‚ÿÀ;#ãs¸ÖÆbÙÍ1tàZ§hR\$7,É–•R&ù… €.T˸âëV-z¡èeÿ‚΃h×ç›2êûÕê[&b#?;£,|’^€@ ¢Æ¯z—‡óùÕ9퀻ùù@ø_ìŒó§¥}ªHv2ø|É3xúèpM§`Çny¹w|ÞéHx)yˆ×÷oÙ ç#‘‡õõ[4ð¸XUõHyùªHŠH¦rEifÄj±¥±•ÚºâÐ"–Ú:ªŒˆÇwyðö¥7„—€Ò…ØDY9ÑSæFô!¼Úï´˜Ô@çdhVM½ôŠXU[šå.”{HsüE\å&’ûñyB)v[Z÷¥©("Ñ=`MXifªºFš|ä3 ")&• Ò÷S6î×›ëA*4Â9X#•s@ÉüO­ü=´R©;áÿ¶Ö]Âu¹oÿ;•ñÿ×r¶e­ ~si¦Ræ¨[Z¸Íeⵜ¸4)½¶brVÒhyŸÄ0ˆ(DMæ+²ÉjhÜaÖ¦’`4ö$–!Òxe*+Ÿ66í R®«ß¢•Úg¬¼L“A<©Dõ5¢ü¶ºf"œ-¯X«¦´"b*E¤] †æc¥”ÓˆþIàp%e+Øü’Ç9+$®Uø 櫬b•kÌ·½îYbc£3,ÇJ¹Ü“Ø']Jc«ÑØ£æäÊj2ÍT<%o3ß;V½¥Œð ~Á½³’×ç \*ÌÂí2’ZÞ"©åšg•ÕëÕµ••kåkD PM\@u¤g½-bR±.„픑YÏ?ZLª|„ÿOZÔcŒ ‡ÇÊÜN.m?mð?iþ¿t™)T·Þ4þo> ø=Ó^|uÉáÀÏ[ÿ«c0¿x-n?™$þ¦VË~Æú_Õ­ìÔ¢±Ôo7ü¤¿8]N—_üßv pï$dž$cØ”4†qÙ0ÖÕn%ýl|Ÿ‰dž½V&©ƒ+áÜZáUKÛVÞ¬þÿâã¼r9ð›•`ù þTÖã£Ðo|ŠÈºÐv-Yi—Çÿ›w©œÍ1®Õtãb,–‘ââ* #U\ êáúúm`9ñ1PË~Í[-ÃNû\ŒÏ?Çc>”fÈçæzgüÕØFJ(Iuº$Du@€ðAøtº&yRþÁ±, y:`_™APÜØ.áj*Á&/pÍpp%‘ÈJeå³*šÑ~ð/”•®ÕVoÕ×>/‹­Šá©€¾¢ü ³dÐɈ”T\6©©~æóÍ•–’Ž ö'" çxŒ“QÑ>¬fõØIð’2[Ç T/ˆñEí*¢'Îì:@ø*YyJzC‰àæ…ÊÃI…eŽ—Þ˜þ× üŸ ™ê(‹€w…êº'3fÓï°‹|ÆÙG_b×)tͰ´$ö+’Qãsöà[Ø“Ýa Eg(+_F–/“”%ÅUç²èáЕ¸·EF› 9]ÐX‰)ù'$Ì×ÚFÍTbÌEßñ±Îÿ$¸î_*™?R-À¦¬Ãd¦œœßv\&é0õ«œ\ÄñÒË.ÊCE/õ(xV(€¤ëÇnx/i8rŸƒùL 1 Z %–Ì31/•W(Ê.^Œ„–H[óÀ‰ç°â1ú?^(¯‡JuЪEºûÒ£KS zÕ:Œ†—=®©òÒÇxðbú½DhÓÌ@ÇÃÈ8VKÏSœÙþ¡–Ï;‡°Í“x«É4`±±¾ùkòÿE pk‚ð[ëâÿÏ»ó†ð‚õ¿”8Z*‘æ³Ve¥Å9X0Ë‚„am¨>F£U§Ó¤È¹â$“U“i8 ‚‹´10P.ái/„“xyañt`”/´ˆ„t‘Û?`ö§y»},\Ôvã_ÐV;MÛy\ÆÖKS ó$}]v¹Æƒ<Ÿ["êcœ0•lSóLNÅJ”uy !s1¼Àû(L°Xo ô¾›6A$B[ØNE(”9#‡-â$ÍR ‰Âº—ª%ÁSx.Ü&©Ú+•—2É¿43íƒÈÒ“bºÛyK§Iæîq·IxO¦Hþ{JeYYŒý–”¤ÓÔ¢¼MŠãcþ‚Y÷uÓµG¨ö^g“%ý/ ÿ_:0YþzÖ'øŸ@»HøY-ÑWßð¼ñ§ã‘ucè7ŠrÝc©ø¾¹ÀIÜ^p´Ê µÖËÏ’º/΃«=ùlƒ8rå§Ëéò‹ˆÿF:6t Ì ñ—,i {œÎ à[ö¾Å8(Š‚aÒ­Öa’CŠïYÌ4¶ ÇêñÌ‹X\•8>…Çž¤œù'Í,ÿã¥Èo}Xú¿|Tþ›­%ÿC“[þisëXùõ–b¬üZ£ïŸ~ü¹"…·ÊþÔi˜/!§ŸÆ©§á”má5Ô-j¸N°ôì ø—º_¹å_“…½"ØÁÉJ$¶à_âÉ ¢knæØ¤™;)·GPÃ%'š’!€(²ÃùŽ ¶á‰NÛcµŽÒþ÷ÍùÜS9YíJÍ·£Ê¸æñPl‚¨¡š¨áæÌ&âå"³Rtºû¿üà¿ýŽãW?´ý£6Ó¯\6ÿÊ%3>ÿQ›ñWÚhýc#oÿ¦ã/€1¸|o@BðŒÏÐpW–ê:Sù=ÎÍm÷º§Õ9íý}·sâuÉ?Ò(Îdqù?©ã¥gÐó"ŠA8Ã¥ÓË‘ðc–,Æ(Ÿ‡Šq$÷˜Ój{¢Ñ%’¨¶PÆuÉQj][¥(0—PG`ZüD„¨­zmeóz§I©a›&Î<3nç‹äNø¼³ð\²· —Ùf,GMÒÛœÄUºûÙY7³³oá~lB¡§s?á(­¶[æÙ 07/Z8[uÃdìG,æñRžaAÁ]‹i0ÌT®ju»È häª3g¾ïóÒ|JeÕzMí~**ºO&ĘD,FèÆØˆ&E$¢TP²“¾·¶n³õ„X’´$ö’ùÿolü?…ÿ縞®A¤Äœ;ww[‘vþS£¾ý ñ¾™H_{ôúûg¾õWn÷„geg"tÊU·geÝÕë*Õ t<ô"‹e0/ïŽÑØo³ ¡ÁÑ E$ø8žÓYÙ·ô¬óˆ&"Vé韢±?)Oin˜-øÇXéŠÛ3©Êº‰,áï¬6´vÏ… Wa”´Ú{ˆ[Eþ¿àÀÄkøÖ[†+Qe\W©>7zIèÄ9eÔ#¬Ç8“.ç¤Aߟ“Ó?Ó'foÑy`ÇÜîi½žø‹°3® Ï]¯À‹L3¶ö1Òª¶ ñƒžç—ýÞGÈžv8h†#^|»m /f]ý6¢$XW„0èTØáþ:ʵ´Ä‰êž ³ú/DŽÑÌEÄq׈å¹P£fŽDZçÏ=)Rìv“h_ä É wIa»øž¬—½ËÇî*ZØIYêR;ÿÅOr Ú¾¤‰£”›ñ´ËQ ¹#ÝIÂÿmûDâ”uû Àÿx&"¯¾b­‚Ê»µÊίÅÿ Û 'ËoSÏ´÷$n7˜NÞD`>ø³çíˆó¼V°áƒøëºÍºSÌyºü"ÿ¿|-g#Í›×o“/.¤DÍ``fY¦É9̽¢ä–Óþï‡Ã(ÉÙC=Œežg0è{Á9ì`gʸ„<ÚÉônýðæ”~˜ƒb®›EØöê¦g¦¦¡ó¾OÕ±ö÷ÝW¬ñuiGšÿj^yGzàjn>?;ëþëó¾OTá›ø,òô–”,ÁæÃC5K¥[d9‰r!úÈl¨àº0—s"?¼˜ÈÓ°š‡…¨kA^§à9lnzáõÌ „ÉSßÁ8MøV¿wÆíš,Òõ ãl&*û[6Ë| ±Ä˜†œö±ÜÜ1o^¤½_ |X¼HiÌÆ~ >~Žqü¯Ù2h0ôkµ÷uä¦ûàÝ„/Peß"’FbÞW¼F#Õ9Î0M÷rYùãPñReÆ¢xÊø)Aæseå,4'(NHª1Ñ•\!O4öèKõò³Sê†;ÅÅ󂤢œ¦¶™©{U¥P=lä¡§ÂÆÊêuzVSÍDÓ´°„ô1üoP©ßàø¿oÔ÷ãÉŠT:]Q°™ÙL"è*ÕuŠ,<“ùš»†vè™x;þ³'ÑØr9) =Œ»ˆeprèÝo} ›—ÛNéšÖáü‚N¼é ÏÉgÝÂ[\߉E[ØåvNPåBÚÕPp^«¹WVº*ÔÖL–ñŒìÞæ¦]¬TVoeªî«µ}yš§kÖbE–žY·{FS4”™{?OÓë ,†BËv÷´/¸XY³ÙÔ¼çõ-„£«Ø&þÈã[Äi5ú|Ä;Ý3Íñ4#Γ«Ð=¾ù’èŠÏ7o0Oº½s,‚y *¡'e<¡Y]³‰¿ÈPu¹<óáÍÕº½ó:ý'°XZ¶*YÂ#8š–ùêµãÿX`¢³r¾ˆñÿeÂO ÊÞI¡=‰ÿq”ÎïÒÀ™·ìµàðü±øUßgøIøÿµ¼ý üÿÚóœâÿÓå—#ÿÿOKêŸ4à@ )ûJ†dCÃÎ1ƹƆEu+%I@Qò¢´‡ãÙüw‚š ¾,ÎŽ&BÃ,»©"¡¢ä–Ëiwka?å„yx„¦¦]AÛ.½¼ó¿<Šžïª^w9ÇÏ` IQ‘HÞh5\ÐÃéÀÆD4y*y øapˆÏ=.ÓöÐÛ+. L*YDA hv’ŠEW"‘e­¶GÈ|s÷´×3ë°yHÞk Ñ%9ÆÝÎI\â Çc{1KÌà:õº^®€ž‹såµÂÅôÍë {uù÷î™hh‰êøèÂV˜âûq4òÈaxçÐPÍ"%¸ài‹yÈïŸ#?^¶˜†O¡¡püráÿÿ£%a-Ö»õá¾N±IJj ¢?-”eþ(½ZÁÿx›T?uŠöï ÿ+‚_'³ëOâÿšZ±'ŒôÉ‹BPðsá1õðsåÿœâÿÓå— ÿ;Oäÿ­ÖL2ÀT×nFK–-fÊ€ÿõz¦Ž ¸`Ø|øåPp±¨è~¨xÑnã™ý9–zX_· ,x&^åÇ0§EE=&B‡YDǬ¯:.jZƒÅ @ãn'0ùcQ?ð$÷Q’ü>`¶¶ xÀf)‘UwÙæ°ÝP4ˆ¿F2'ýÊðCƒ¾¿ŒSÜ•E †7q-³ðŠ™æ,ÙrÖ(¡¦Šò5!&ŠãàOãq‰AN¡¿fá{)&‚Ûé¦"&jàúh1òFª—’¦ü~Š4ñ@ÊDm‡µµÛD?àLæ§)Rb{ÀÕju»pÜ™Ÿ[‰ù‡à 6êt=Àð¼EºžŒ ×p™?ÓjïÁ £­|þY·‡æ8²U7IÓ§b½ˆµ`þU¤ðþwjZö‰ü¼ŸwZ£é¤Ü-÷”žç#þç¶2ìð†›ž‹úôE=ª‹×æàX€±ºú-ƒ¾•}Ëãž^ÂùÇ †¾ŒŒkFcÿÉR5ÊZ,ƒÙolü_Æÿ‡©ø_χ±ð2ºÂ:€0ÍËtãÆ‰œÄ8€›:9j­{N¼#Ø>óòv©²õ@ÆùÇóðS~J†Çö×(UÃÌNfh,-}¤-ìFãçð#À{„7ï‘“±±BŒ£õ›z}/Š?0G\[œËQRò[‚Åó6ë°Õ6Ò-çµ]~¸£ÂÂ{88}Òå"=»<õÁ²b2:*ä”žæø tr»}HH ã$º¢DñØ“dÅl#€£hÜ”HLøŸÛÿH0á™ÿ‡Æÿ-yo&ÿßy¼þ÷ÈD€s`{ñ p_B¸æë¸þ@€à¿ñ‡fÊ\ÁÐ"2/¯Ãë™Êͽƒ‡&}ûí¿ðûgŽ1‘«–_pÏ‚Ÿ×—sL(µ‰I+ôŠ ¦{ò{gÊÊÖ2Ò?‹SÕ]£±O«íÁh@´^N{8²Dó¹zº$šb³ geÝ,ÈëDGJ´J(”¥Õ¶LV"<¥eáŠJ4òÏâ_`áaÿE2^¸d ¾FôL<⪈3Ö?ëõÅP Kb5'iÖ$­Qç+ 2Ê<ŸbâRf3>H•ÔyÜ•¤“ó 2k(Šº­æ¦£q¸š(L·›Ÿ×ÕnÕÖnYÌ“ˆ2¯) ÕH§Mõ;x+«ž±80Y¦`ZkªŸÑ¤UÝvcýŽÂ*«ŸUVmÀ]’$eÏ«V>ÅnðƒÕÄ}ºÁÌ¢«4pѺ‹k1îQRuÕzEå“ŠŠ§¥¥Cáeæ]‹F–«+×Ë+ÖKc«k6G„$¤Ž­$¶%ÇÿÍÙª/ÿãîÅFK ßþkñŒûkGì‰ÿç'çÿ¼·ÿ-êOñÿéòKÿ_¾–°½•Å14]°±ÅÅð›÷]®QØ^µú¶™ä#ÇìÎ1«eðÜÙçÎQ$˜l_$Ÿ/NÃw[LøŠ0ã°ŠØü¸¶Ëî5[á¸ñ«K¢’†?Zâ:í½,Õ-J™pN"€Í´˜‡áÇyç>üJÉ<,S wŒë´YG(Ni0‘åBÍ= ¸‹HÔ ºœŽ±ô´Oá÷™ª” PÐ:¢)è´9À!~?QgÚá@¢zËë´ÂXGpZ``uN»ÞПGŒ.-‡ _¸p w—Ÿ®Ð"G}·†pÆí^ê\¦€Õt;ƾ‹Ÿ½hÆòòÇðt&ó@j&'Ê°â¢ææd™À‹&™ £ED1×è ."KÖŽµP]öf‹ð\4Íñøí¶?¼ÿï?òþî—~÷ƒ¶ßù õw?lûWm-¿ÇŸ¿s¹õhÂEm÷[ ¹l€ÛÄ¡ÄðŸùÿ㢜MZ©­Ù±Ò Ò‰d¥É2¨ÊiÓãÿG}œ4þ¤ªÕÜÃ㫬|RœÇÓ40ÍŽË1ðLWV<9üà1#v‚LãÕ‰1ÿ”uZ¤7ë’rfZÄW©Y¤CRhgŽâ:Ðã™®©yΡ¯2s&¼Q8ROëÄJ~~‡ÝNRb¢?ã­!ˆ«ëÍκ4h1SÎÒÙ³?Àþ*Õ tft~€dlD£fh »ró:ÄèçÒ®˜hX»¨àcx_¼^âžb…YÉ,ÑR)ʰ&ÿ.ð^IìïrŒ_L¿†‹)ÍcO š€ )÷CfHHéCÔ‘¸„sëXð•³D¶åٚѨgtÄbR«ÒOåTV=űDD‰+ûr‡¤ø ‡`tK`$lÇ'Þ…ššMD¯¤f%§ý´¦<5Êžj“4/ä@ìUê°¿Pþ<þo² ¼yýßW'U”™Sƒbò¥%!Š@SJD“sI/å;•´ÞÚRÒÀ„Þ‡þˆ·¼àwü€S§v¹Dw¿±iG²'ñ¤v!ånÉ5ï²p9Q6QMGBBÔ b|¾Aª½’Áÿ+‘o†. ‡’}= aº÷Ù3??Ž"CLŠþfâ9D0§èià|‘þ~–êFIÉ" fÆÅk¡Ð:?vãYÔ#ò+q™¿%qÿ‚øˆ#ÉÀ&¤•¢cùÀãŠ-+Zâ0ѼŸ p€ÌomõV¬ìI qõÿ@…J– ıÎ_Áàp8”¢Ú'©‰ ‹¹›¨–„6N­Ê»y¯µe?A…Æû‚تµå€zöy}_UPHAÅ:-tªVZö‰¢*!>q oo=<¡þüo¶ ¨¾üŸŸ²œÄÿ,v’içãl0ý¼øÿoÁÿyŠÿO—¿Wø_¡˜SR€ä!ÉVq©£B÷ÁþH¢Sv²Yh±÷áB§]– ÝOü9 Öå¡•çTË·¹iW©“ò”LÎOg“Ê©’UºlreòŸ£R˜áðC‹ž¸=V/„KÀ}0ùáx,F¤‘è²?0çrMx}g#M–À|MÍFYÙZ,L4‰pU8Þûã´÷$G(<žIüÑe”?Æ9ýþY¬`O¡L$Äbp~@&„8\–" òûfEÑ(]Rx©¤äAuõ3xº’’¥T¦††VF â1Ñ ?´ÛFþ9b+uLYÌQIqñb‘î¾Ç9…û‚­®YÇá<53¢×ÞgJÀ}#PùáÏ’ÿüo³Â½F"K€¸„c¡à¼Í2dç*<œ¼¢â °(®$\0éЀˆ¿ÚÚ^3þ/™çß4þ?Âÿ¯à%iœVÚ8¢iM¢telÿòå)éØ"¿S¹õNðìËvKna6žcu²2æªÿ…&D(ô¿æ'õ¿NñÿéòË‹ÿ÷Î9Ê m©«Ûöùfm¶¡5 /ÃkÃ#ЊgÚn ¼ži*̳Í$óHÐh!\m¢eŸ’äm£F〨Tõzg©‚˜2&Ê 'ñòá¤lsÖ„‹ 1éà¥ÅDcŒ€µø0À𤋮\ƒÏòzf,æÁà T ¦»Ig¦¡ñEŠ /Gñ²öÚˆäRÁ˜-Ä5IUoÊȹge.rBÿ½´t•Wˆ[› c+Ÿ´4+£Cäò JãaÇ$ "U˪—qV;Œ§J§ŽˆÊ1Ë1&ü‹¶ðžƒXFÝ !p0úŠƒóx œ¬EC¾¡½±- @…v^’ã'LÆ1j„Ã5Ñ{ïÕ}ïËá?ùFÅ¿{«ôO¿QñgïÖ|÷ÝÚï~=öÿ¼Sý—X¾þ¿Ò[¯–µ®*àÌ@ˆk˜6sÿe6 9ìDÊ.~ÕXÔîl`· #„Áó•aðkÆÿ)¹T}óÍÿIþaÎÆ—'9±Þ¿JMïIX/S_ýääŸTüŸ$êQ¶œL«`þþo;žöÓzd.@ï=à$Ÿa*KñÍ~ë!^+"áêöÍp¼9Ìâq“\—w ]×JÎ= Ï8…oÂîcj”‹•æãÐU윓ŸGS µ5Ïð_ÔcE¸‡×\¯ë¡™8ã@Æ…k@¼„ˆ6bÇÕi»iº-qh'ª5ÁØC™rOÇßáòà)™@’ÒÅëë· -FÊ!Äp‘LmŠx™¨Ýa=ü~R¤º±B"g+ƈÒ?ët’Cuõº¸£œì[xISÌØ_^ úçò²Û}ž)ƒ(üäÚ``¼þx_p_hCX#U¦‰½Ú2H!• °(¬P¢°T¤t‰Á×ÿˆ¾0[ûs ¾`ý_Z¨ÆMed\­¯ß†yijÃÓ Ç}±A¤>à™F›ð|ë0 «Ý/,¼‡-­­x‡ 5÷´Úž÷Þû¾x:NíåÜ¡¹ŒŒkC/€}æÅè,¸°Üìöºº-ô|Ä#¸xma7^\®œ¸› ºΘŒCê¬ÛpÄÌ–8Ù’èEEÚš jÙÇžyÂçæµ»\ãnçOœ  ý÷”Õ6 Ïe6 ´°‰C 8ð¢…WN²ëãòò´ZãˆÝ5ð-žË¾kqÍèM&˘É2q^ÕeuÌ8]³ýpž¦¿©i·õQç £tRºëh¬}x̤´žHPl•Ýwê Ò1‹”jOŒÿ÷gåÜüO ÿ§’v¦.êŽ< yD?/þ§ì£­z!C|r±¦ä#âÿÓåïÁøÿkÅé3VºJ£ÊÄ:¸ž—×érOàí&Øà÷z$Òx[X'ØáXt…AÅT$²,†,ˆðD×­7Ý‹²UïÉÃ#deݤäHáwiì‘ÃAU{Zí=«uÈ`ìcæº)›m&šsP'ðïÙÙ7°B‚•æA‘”Žõ@pÎ]«¥á)Aó.S˜î—–­â:³T7p óp\žJuÝXÔ“Eüu”ÚäfxƒËP«o`c=yhãl 7Ñ¿Ü3Y2/^óû¦±üiZú§@³F}oNÎ-ìæàJ:¸Ý´´ÿ½7 Ž+»Î{&ÆÓ­˜%:úÑakÔòÈnk±lÙcµF²-»Ç–dw©ª(n±'–D.ÈD"W ‘ –ûJ‹DÈá˜ylY¥RU±¸ÄBìûFìIتd÷|çÜÌ—`©gÆ!ªe‹/2^¾|ïå[î=÷;çžó}ïÀ©Q©îã–E,ð‰FÝóäç·QrrÞ’â.8AYYD£Rj’óù#Ì~숳Äü/EYhã¤Öð~ý´Ÿ|×á¤V…ˆN‰Lž籈YÝt\šßZ,Uá"yL‚hˆ¶D÷8ì|á„+a¦’˜“;& ¬!jÚ£R$Yf]¼I ¿Ä1úÐ4ƒE5ì9Æ ÿjËm–)·{I£†§C :=ÀÞ–*»Îž ;mØ`+-é¹I8¹RÙ-p8ÆÒ/@§à ^ ,?þÑa_°˜á×a=¥±ñ¡ôdYF)ϘYž’Ôm{ÑH2õ(’9¦>’äðL‹'Ò•¤ÎKÍJœâ‘ÞH,mCÒ5ûòÀQŠùó MσÇNX‰ö燧âÿ€Ô~:üŸÿñ?ï¦W= ÍjÍɼUС0MYDöÎ? ÿ oŸ¯ÆáÙwrqÎü»€Î%—¼ù%þ¹ü“ÿKéÍÉÜ.eœŠYËSuRÞBÒ¥ë¥'Ià#páDOóH\Ç,w+„Æ"á!­’’Ks ‡=œ0™9ëÃÜ 7IÛ(8 }-\òžÌÔÖ!ÙÜú58#壨"ªÌ¨ ¹zÞf›õ4¬N`g—k X‹DÜËðê=ë¬tC“¬¦ºf2“g„í€B¶’å±èÀ–Í"áT×’»fÙÍ[Ä9?8êy›/2¾ÄÖ+W¾ûµØw~Çùrý_i¼öçÍßýï5¬‹å‹5ñ/»ß`Úɳե⮇¬£! ¨€¸÷ÒÒû‚œ§¢b¼  ƒÉí;©VBGâG"1©¤¤ ®¼|¤ŒÆVb_q8mKn.¥‹3áÿ*N° (¨Rõ˜LãpˆŠ(®x—KÂgN`y*;†ÑK/Rÿ÷Yºÿǧ| ”T5åÁ±çÃe2 ,©–üP’·“€Ö“˜ÛvôP6u(£ã>”b€/w,ž^DêB’½ÿ”G\ÈãÒ¼USÓcñ5©™?lô>nh$‘_)€G¸xÞÆMîÉÁJ0´%zIê°þÀS4Å”:˜È\z–h~£œ¶+-L‰‰´|@\æ(Éä̎Л€¯JˆV}Ñl™D;ÄWžŒ˜¬v,jÕÄZ#xÝIb[Ý_¤èPw‹i‚JÎË…€²¤;/·UÈ"àk1•Ü…1á ÊAx—tª²áüüŽÌÌ›%\»Š“œ9ó6‚ˆ-£Í árÑò33ov¨ÕÄc_\ØIT6¤È¿{Rø85©ÄD —)ÿ'¼ˆîÆc»Zu_^΋Êÿg͸£çÈÙhEpyaѪÜLh ‹jE§“;ûk¯¿Í.½9Ù·áp¹kV‰Ÿ™ˆ7gÝîUìÀ™<£Ûø¬«#Á/¼AÑ/Ä¿lÖ…âŒv7! 'ûi© j ºzžiH±»E#+ŽÍã &%#)•/æwÀ.ÁTRSIÿ”cžk.Û«æ„,’¯$÷„ÃÉœ!¼+ÕÝ»j–=ž Ññét-%d@šÄÊÇ‘$MÖVêê×§»vj6–îHûX–ó l‰õT?„7íp,vRõnp×dBÓ%Ýyî÷︜«Vë¬à)’ô¿¤:b¬˜ÍSèãØ§õr¾–°„®b¥uVâÖ‹²›ŒpSV¤Œ&¼š´;–¾©êm¦–¾þø‰)ÅS‰mþ×j{³²oþÄñÿËååòrùÙæÿLGAå"JÁÀŽÉ8Um_¤Š]DzF=Ë#Ø{0ÊÓr»œ+†òqª–%Râe1½ŽMÆIØ.bo íbÁº½rÁa_ÂhÖVÚæ,æ§cI¥êS*ï_ʸ…ˆ§Å‘hÎfÁèó ±ñ VÜî5ÞsÙb™ÁQÕö9ƒ~P_§ƒ”ÍP½P¢ºž ¤'ó*£iÚp$?Q,&£3}þÆNdâ)ÚóX:«ü$T‹¥%ZÄÎ1)éúdö¸|XbÄWWbùÿ‹8² C‰@à"øØÃ\ûBµC3h쀟ðÕî .@¾ØˆÄË­vÌ¡UàWŒÔó„ÛMìL€x,”[bç=‰MÝáÀXODŽõ L=ڀùh༊þOÖÿjú3_,þ?–“%Ê«NM£ 2ùãý±¼@ä÷J(=–a9º/ˆèã±ýÔ+fߘVå-ÑCQ²‡aÏzسDZر£D,ý× Ñ®¸ %DS᪄˜L¬óT£²2¦ÂCÖi“z¹Y¤ð\Žç^âÔ»>µê¾§aCYÜÎhU´ÆýâÍ:œó9¹­×"¥Óè‡/œ{7¥u{,åf§—ËÏâ²P€¤ÿ%H×ù|Þ‚8'Ìp3L>Ðh(Õ¸>5º¹N3`µLéGS„‡ŽÖk·sn¹~¨»ò¾Óu*ô£û<ç¨<ÀÕZ­Óع–½i @Rè¶L Þb+²Reöñx( þ,¶ã@³y’ñÿ–…°ƒ Ð„ÛKyDĤ´¨-#‰¨d¥çÉŠoÁŠ;ŠF÷’ø?¾Kú¿/ÿÿÇâܲV3 VÞ×jú8YkD§TÜ-)êAS¯TÁúùäÑ«[¬”“›ÍÉiÍÏo·PÂØ4ÎïàܹwƱW_}‹˜ˆ¬GLîdf¼¯¦$¢)ì€çÛ¢Q÷çdÝF£Â{£„âÙÂÛ*UöÀÊÉþ¾úˆ…ÆDjYVöí¢"rÖ¼$»ž¡Ã;"‰¬rrîà¥àÕÀ_”°*h®x¡ÅEÝbrYQØ©Q÷‰^1VÊ4¤SVÜUW¡ qç³gßÔÇÅàpv ¸„4>Ê´¸`3Ó:qؤª”Êáñ׊‚¥’&μþ6FÜ#¼Eá=<b…*.×’t eÁ ¹œKâÊÑ’óóïâåd·þÁW®ä¶á‘fdÜÈ̸™›{ç왼ò¿+¶àó¾úmë¤Ã£Äö¬K¼úÊßþÉøËK™7Å‹¸xñFVæ­o|í;"c§±á‘§ááŸão¾ùÍ¿=îÝìK·¿ùÊß~ëõ·órî`第V1jð׿ò•«4F³!x}߃ûçö7çÎ]ÿÚ×ÿoxÊg^ÿþW¿úm\Æ«”â5øãò$ü<¸|@ÓÜÙ¼Äÿ/——ËÏYýo:GBJŸÀzSãfAqÊÕ×­ÊGr‰v²³Æ½Šá83ó†žJDç1²—q<†í ,›‰ÝÔª>­–rcíìlâ«ÌɽSY9“Õðo£eª”Òî¨T÷KU=°É‹aÒñk!Ó÷ JùœK·5ÚþììÛX?Gj’TÎ;ï•w[LÙ—n1u ƒlu}íº„Éá‰`¸ˆ‘ê²Çó`Ãç£Ô} llÿ0òìÎ,Û«ˆ ¶v½Æ½‚a®®vUŒçä8'–ÒGÁÞx*€/}¦ƒHò°sìP~Tê«DFq(ÇWîÄ þÇ®ýQâ/¾šøö7ÿ%V¾¾J_ãßþrø ÿ}DL½ lã÷?êcØ‚ ®­¡zäPh›|D{ ïÒGå,†$—cIpÓaÈó6m‰ðy7«í ÀT4…Ùo"y…¼ýPpÇK˜ÞéZÔéEAq8´ë©_ø·ý¾§•¶™††€ÿ)1(VÎ>ù—¦/ë§ÿ—7éh`7Ø $Òw|æ!¿þFÀ2vMŒÍm¿¾-PrÃkìñUôÌ>å;~]‡×:ä7ôøÕ×}†®€úÝxhǯiZº½…?Uùê—}ºÛaïFSñuŸe(Pòn¤~½!ï=oÝ‚W×ê+oo,ü¾¯äí@e¿GyÓ§»ã×¶yÔ·CÖž&å{ÁŠÎz]g“ªÕ«zß«îðVOù´í^ÕÍFm»Ow3Þy¾ÖÏ–¤Ç8gý½è2ùÕ}x ¤þfŸ‡wVO¸wPÇf2Gƒ¡­¶-¯©Ò6 İmµMUÂA €íœD2#‡ñ11—'Çÿ…ó)á°Ø‰ÌƒdÊAüXJãÒÎC3—êG(*‹¥Ÿ\Aïó>©q-G"{¸ìª¯ØÞc“ƒ4á;P×MÏqN±=©#&|ó˜”GqP[·ÆE=4ç7DäÁ²¡ãô£U•Ðø­¶Ù¦$R=–KŠ,…|¢¨ˆÿÇv±þï‹ãÿȽ-Ž${– TŠG¢Ìå'ðm%¢I÷_cÉõƒ†ÆÇ²¶t˜T»ˆ¤6&xÄÏ‹‡r¨8Éç y6f¡áÏÃx„©fâÒtØØ9¹‘¶ì¥’ õ1I™È{%k.PÚP“¬z` ÒìÙ*š‡…Ã[ätRpÃçßÂHa4£ ÐDƒ}®œÌòšH9C“ʆ&*CCSÄ¢< GÁ=¤‚µª9Q#ƒÃуà\TW/8Kîš•ÚÚ5“y²¶~Õá\ú‰fg©«[÷Ôo9¬+Aû”®œ'éöÑáJ¸IokÉáZªv.baI… #eßÍW±¢>{7á‡fçÐV¦4ò>¸$³eÂf›ÖëGRã½Ü3¯½?eé™IµºÎ Ü®*û¬É<g øÈDÕ¥ì]@§S0pX̦©rÚq…!YDOaœÚ5ÑžŸGþ§ð?þèRFÛKüÿry¹ü<àÿ7šNâÿg'Y¯Ÿ‘pŒm6þ\¶ÏI‘£#¢—‰ñ!ÖÓ¡u&Ì`8•´–x(i'ÌÉ?¡P’êGL•&É-™H0B„#»á(NŠÌRŒÂ16IR§"Í2o'  íææ¶‰|Q¸‚´îIŒª&².ÝÒ— –ÞƒÛb³Lã×K™7+*ƄرVÛ§*¥~ 7yym"Ø“ª´NV]þzò§Óiä²Ìp9¬’®kšWðÿÕ›eT îÎ̸©ç’ÌâÂÎŒ‹×uÆAÂÿW󊘑ƒKII\$"KÑ fg} å´*¯ (Y§É4f1NTðð¤ÕöæåÜOÇZÌTϫӰŒBo^.¥‚׸—ùw±ª¸» ¯ 0 ¿zjÖ)µ¥½: ‰ã±sb¼³š'ËuC9Y·ñwªâé,¦çð¿¶?ó…óÿŸV·WâQ߈º§b4wÿÔŸÿ]¯êF(ø¤¾è­håpXû^ƒâ{>õ É÷½WÚ;ÏFÐØãU·yËïT7›ò¿2ܪnÄÂûþâwŽÉÆò®HhË«»…«eŸn¼ôm¿¾ÝŸù—~[cæ_4)¾õn„¼›äJ¾vNxr¿ëW]‡ßá7v„Н{-C‘ƵzåÍ®£I×R|ß_5PßÀ5jƽ¹õmžšŠ\¬p¸dÕâɹ~ô&N¨;ˆ%å\÷£éô¤}A¢" C$Ž ^?²ß㥳ȯÔwR|Aǧ𩌩„tTLæÕÊÚ¶àùÌF»Òk‡‰£¾ ]«î7VŒ¡itÀQ)ï£ZL“…U¯ª˜èúµJj¥eªþ0Ëm£¥)‹»JFýð…óïá ¬Ðݪ×––ô”u:ª‰s8'û쌛Êκ-*}^í-0`¤Ü¬VŠ]+:22nh4ý¯¼òÝÏ#$UIžanΓi†gN©J³¢2:Ö˸YŠÿ þO˜ˆœü;/ÿKpÏÒBr‰#Z‚ˆÎ%£aœ©À¦*¸³£o¢1y¾uN °Ëfš²š¦ÐÍ=uëø?UÛç¼ÞMVa›Äx˜DÓÄ•‹ŒùEmQ¤ì‹fÃuI‡ñT+’¶óES',~‘–QNg„Ê]*ö ÇD "Øöû¶jkÖð‹ ‰yæÕ'bX’´ð=©©Y Ùþñ¿,ãEòaÐ D†÷)ù ×N^'ëNîÕÕ® £$œ~1±BA›ˆ ÆW̵±nÇ2àºÓ±ˆýkÝ«øÄâr,]¸pÞÎUÆ0žœéöVWÍ •v‡ÂA”z"ƒâÐé\$¤thŒzJù|O1 Àr‚Û@¼8*Ürº= X¯«[ml|ˆA;cH"¶ºØÁG‚ö“žU1z²æô#8$ÓÄïÇÒˆï¾Lñÿ~Mñù°ËâÁßI„¿ }!ú\°é·âTþÏü‰Ò§sÁë}T[»R_¿*$°ÞÔ°ûðŒÀŽÛ½è©_$¨8ÜïÝlj|ˆ¯M¼Îð=<ðxÖ=õk žu‡cÞÛô;`PÆsðû6ƒ-§c¾ÚþÀÛøçw»6ìU³u”bt¢Db™&ü¯ø)èÿ>WíK_Ãuã>MkÐ> 0´÷…ÜãACkÔq? }/fnõ™»|å·Ã¦V¯ú¯½†;‘¦€} `j ¨Þñ™;‚–® ñNHw#Ø êßTø-}ñÐvØ3*¿ãÕÝŒTwùTï-·ýšQ×@@ÿž_ßò,ûíÃpB•½>k_°¢=blõZz|¦Ûðâ¾u¿­'h¸åÍÿ뀩=¤~/ìh?ð[úº[±Ð¦¼…°é¾Ó¹ÜÔˆ½éR lÓÞ‹÷ ºUcãoÓÆQ›xËM›VӌϿU_f¼ÞÄø íÇ&J©Y,©«_ÇÎ55«Vë ZE]íš'qÐlpžZ÷ Vü­zÏz"º?D·E¿®!ÚÛ –ç[*-½OTºÌÌI[jH.„CëRþ?\$ñù˜§ˆ„GÑü¿î§Di'MïQ43“yÂlžt»W€å€£ŒÆ1\û‹zO,êD½kÃþµu«Uö%E÷DÈ×éX ÀuüΩワãÀUQ¸¸r–:‹ýÙ2%ò)‰…âÿchÞ¸xôýTâ}2Éňh=¼“ˆ½xýߨ¾Ì¥=¡ÿx)’-ñáï£ñ«Õ½…E6ë4Þuvöm4Q÷*÷àÚ¨”=yÙèuC&ã¸A?ŒçO4Púa<µªWèAÀsÏËkƒ_•uS¡¸+Lk,úÑl·'Ëdå.@ £È©)%¯AÊÐÃá¬þ<¢Q÷—i_{í-ÎÕÄ5*îa¼ýÌÌ›B<®\•m¶Xq_1.”w‘ÔHp'óâ . éQ–tõùÖëoSiyüPYÜséÒ-ALTª¼w¯¼lv^§Rl›Zy_UzŸ´ÒòÚqUj5QI¨Jz°dfÜÐ’LùM¡rˆcssZ+ô£"9SµÚÁ³gßùÓÿð¾úÊw1îœyõû¯}ó­¬Ì[çϾûÚ«o]<½¤¸»~Gü×\[CbÍóä믾…~ãë…h'&·™LÅ—O$àô@ÓŒñâ1ˆ¥¹…N–áH^ÌñóÜhBÞZžÿ¯&ýß—ù?/——ËÏOüÿàTåïåTM¯ÂÖi4@³²0ˆ c¼>óÚÛ†QƒaÀ>'ç§úÀz·c0"Y¢‚v²ÌÊžZ ÏʺUTÔ ìa0á¬k¡¢£¤¤›hy.ÝÄX“›Ó†± {R`Y7dÐò>÷4Ld¤˜¤B‡a  ºq"'ûµú>Þ¦HçFC*äìe…¢ðÉdž4F+ÊÇòrÛƒÁôS Afƒ§4‰Â‚ Eá= ›’V…ë üJúªµ5«èPÙ™·¬Xw/ëIk¬+sïZ¨˜·+7¯Æ$+“ôÈôeƒ€O° ÊÒ‘ìvƒRJ˜êGƒíp²¯Æ½‰$…íЊª¹ŠçYÇÎK,U¡ ç$•¢K^n×rRåJŠ6§‚öhðXÛ˜I²#¡Àv„ÅòDaÍ¡Döá§½yÌ_ÂÿÌÿsLÉH)ü&ûâô¿bûRÑÁs û8©E¥ôB«tU{²Ù¦—L1&%N UÇeZ`Røâù ·TY#AG9ç­”B–ı 9ý¯¼Î7}85iF¸—áu æX b*Qq,Dã‡øÄ¯l´ÃxbV[ðUXK4*`xl©ac^Ã0€x•U•èÇ"þ™An*ð‰`·±ÝaŸw:ÝLzÀÅ °–hlvaÍ‹TQbV*ïÃh;]Kµä)?–h¾ðRp©8­à§ÅÎ\é0d!‚ë•U`')ï”Ûz%>É+o¤Ü~—{‡p ËŒ¼ÒYz\E˜\1$ù5q$Õü¦E â¡tRËL(Ë) R¬Ï~\ µ´TüÖKüÿry¹üœÅÿŸ¬2;±EÊ`¹BÞKnŠâY^§ì ÀB!Ë%rx`¨EnO$LjV¬¹-òWýþ§D›&ļˆhnOäK<üòdI0E¤ú`‹‡ùsR¿îË«k¥ŠE ‚0Ýð>`Ï©²uç­Öiâú.¹ßÄQ}­¶?#ãýRU/° Šº´—"Q¹mjU/«w¹]KËDQá=Š¡1ë) ™€x'b ªªìçP'‘rDegÝ¥gyymø; &‚Oç!.ÒH$¨w0²àbÊõ#‚V+6NÉ“³¡æ¬+·ÏE¯ÿ{Ë•¯×çñ•-ZûŸ¾VûŸ¾áù«¯Õ}ç«¿ýïô  µJÛ ëcö ã Ö †Ëc¯ž§Z ý0ð<,¦òèÂÇæåÞ‰†÷2.ÞÀþ6ë4`›F݇7xîì;aÊ¡ÈWÜ|‚Ü^ù@¯¸xá]œ ®€eÖ¥[‡øG\yqÕÖ?ÿ.ϼœà’c'5žsö?­øÿiÉ$ÑtÑØüªöóW×tÍ„×C5K>óP£ò{¡êþ i4ì˜hÚ|®¹€¾Ã«¾0´7¨n†LÃ^˸×6°öúÊ{Kß÷Ú}EnXNñìÉ+ÊR ?I× U]žÖ}HK”F%úŽä–0kR¤3ÍÄe‡÷jj×(lhŸî%´’f[\$-GPc.Öá‡)MÙY‹Áá\ Z÷2À6 µ˜Ì †¶qZ(ë~Ãç#ôEñÿº5l ·­–) ,œ““.¶ð§”ÿìÙiè³4SØò4>ôûž`Ot"®1yB'Sï&Ò¡›±bLðê«T}pLÊõ£‚J]r­.óÂûpááP¨JˆN*™ïÙG§€¹0'DQ*ÜCùœ @,´ÉœœV\§5Ưy9­¬*ud2O¡O]¼ð>$Žpµ™™7ËÊa”%ÝzÝà… ×K*0º6ºH·@VPpX£êkò>ާT%ü/ô¿$þŸ”þoÖ Âÿ†düÿy&"|ÂLÁ¬ þI4iÀצÆMÑ„ü¾­¡AZUDRb…ªHJÑ;}r˜î¦¦MaNŸc²<®“L¶Ç|ªG‚öJÄ=N2ÜIüóDÄ;m–E¯¬ªš70éP ±­ÀÆâ}Q5ó³qÃ6~â9Ê&­:®¬š­¡ù ¢¥"¢‰Š1|64>¤zËtŒgÊÐÌ(!Ÿ©Øâ¼ãf5š~\ Î,¦ÀèïjWÐnáƒàl:"¤:´Ygëk×5¥½D[Dä<ÄóÃk°ÛáÈ®<þ³á_ð°Û ×c-çFŸPþ¾úž¢gáWtüÿTˆ& YLñjp…¸~ÖGÞe8auõ<÷Çdú«àt…ÏÇ9Ʊ&¸¬Î¼Ïñ«]ì,Xm…1©­[Ç«G¯ÄÅ`»»fY$ÊÊ›\ñTþZÓ›ñÿ¿\^.?gø?þÌíÉA6 xƒk~‰œGdû;IÕkD£P÷ •¶¶ÊV Ú ¥b²toqq7ìKÒŒÃpÁöˆMh’k¦–…/¨‰¶—Ù>÷xRx Ûñ(ŒiÁþË5HŸVÎf›6™'a£Ä÷¨¶n­²jÛl¡¸:† F™Ð Ñ6>II¦òÒ ÐÐvLei Õªd#;SÑ]Æ]ÛïÒÂÑä]D™ ›†žÀSâ0§dÔmÁ’Škp:p14Ĺì1¼‡¡‡•(9k¥Â =ï&Ž à~©"c'Ü¡’^Þ!ÙKêlz7}Þ'Ë¥[ÛÃžÞÆÇ´sh;œ ¥ÊIõ%–¿$þ×jú².ý4ãÿ§ lEÖq¨¢+¬ºÞPò½pÃB¤a)bŽ4ÎúJÞŠ×Ï…4·Ã–¾án“æ6Þ²×1¯[òåÿ_AÍ{ ºö êz­H{Ýkè 5®ú nÆ£'Ò!R„öÏsF"¥2íOPQɪh¥£„D)ڹݾè¨^C¿Óµ\Y9ÇI «ÕU UT†OŒVªøC÷´Z¦ñ‰nk«œÂÎäɸpC©êqºˆ† þB.WÛç´)m¦ê¨¯¡Lž«un#ú,|LÀxÖ ‚û\Í…ä‚îÕOå™Ó ExzkÂ,(t8žÉÚ¯$L†žŽ©¶/à‚áMPͦ}Áá\2q! –ÝFB!–µmj|l¯^¨ª|p.@~ wˆó§jÎS¿a!’Ÿ Àõjä’.yÃC‘ Çä¥DyŠg‡hN Cì‰}¼¾M¢ºJÅu…Pü)<+xL0zñt@û‡:fŒøÿ·“ú¿šþÅÿi†éåÌË#Ãx/ã Eà¶èà‘–q7Ü­f€êÄK)s¦Â(<¯‘J ‹×§,éQ«ûI2L-” H!mF§#ªUxd*æÆ))î†ÂI€Ò)YK7dª7èGD›Á>xbeeC%E¤ O]ÙN;„"äN ï‚[7Xºe¼Œì7‚”›uš.U7ˆIR†0_hH°¿²ÐL': Ü>ö„ƒé©[ǯ99w\vú;´Æ‚‚»B\ÒEä¢éÉ ~+8…𠄪(¸«„¯ZLDFè,ß:ó6y”¹mz~;è¿xJ¸e¸®xBÒë8Inn«¨PS)ïãáÞŠ|[å,F·ŒŒ›¢c¢'â_ð^D‹Ù4qæõïcd©0Ž9˜n8Û¿”y#3ãz½Îh™õ(~’üÿyý/ÿɉÿ_./—Ÿ»úßÿbú^­îU•öäå¶šYf…#KûÀrÞ×j­–©¢BØÕ~Œ ¢FÕl¦ÄZ§s©  Ãh+,‚A»[Aš_³»¿Ìfª·v/^¼ãf2Qb0<‚o}gˆð´F‡W¿ù·Ë$¬%Œ¡@GVËä… ïbp¡1‚¹rsï˜Í“ŠvØyü;¬«TåPW¿VF1öI•?„Ø*Õ}»ýÍ6Ue€SÉã<°äF&DQεT¥D¡0k¯ž‡ýLj-2W±C­{'‡UÀÀmŠ4žjfCÒé‡Ü5++nÁàG†911s–þ’²´Çb™`=âµêjšÑv8–àÎ`X—Xë…_–ŸOIª¸ ½~¨¸¸“øñ¨ÌáÐ Î&¢yvÞ0äá•9ìó¸e—cÁ ÆEb ±R|ŒFC¾òU#±Pi‘ùDv)‘XÝ_^Fë¸/ ©63%¬Â}hj|äv,UÆ0Þag+¶›&í¶«iÒX1®VõaÈpÅÇ䀟“H'­¶/3÷…âÿþŸI@­Î§x+ ¿ÝPò¶Ï1ô,”ïD› E¶Ozs¾ãU¾çÓ\÷Û}Æn¯}"V;çW¿åÓ^oжùµï6UŽ„5×=†®`ãªWñ@ýr”ý8)ÂÏHû ‘ëSìKàòà¿ÒÒnü«Ø_L߇SÂ@ “k$«Í«Â0ž•õ–Ä¿Æ ;‰íÓ6“•q›@šy’¸³ÔýçÎ]W*ï—ë† À ï‰ù)l$•jœýhÉ*õýü‚v“a’Œ Xì3´è#Ù>eÅ4Žˆš6ÊkC_C?"H¦ùŠ³êŸˆ¨ãªb$01öúkoû|OÅë@óNÉ| Z,Ç6)áçw]®eš7¤ú‚%Ž lÓgp§¼|”&ƒ¤ëóÔÖ­ÂD`ÏË{<<!vêiæ‚*ÖhÂÿ4U™Û‰ËGM›D>Úöúž •cUÕršSN1á/ã™òT ålsþOš#EV8IñÒÿJÅÿ5eý9ù/ÿÿDâw*„ŽOÜ) )¼!@kk@Ã| Nc…Þ“ñ6y7]Î%`BtU<½šš Гâ-å}ÙfI³»ê00v€ÿ<)ʵˆL†yÛà&Tp‰qQÑ=Xwí*ž¡õv…¤v°Øf``úðÖ0Ø,Óð¡p*ÎM;S Lݺ &/кàáQã²)ÇÒ³AV”ž´Ùظ‰!WŽæ„3cÁ`ÍöYÄüqGMMEîù,£rÆëׇö §;ã@3¿Í•9oP ¸ñú#RM.°V¶íž§ƒËóÞPOc,?ÚÉsb'J€Óø&:û%þ¹¼\~nâÿi•ùÓ“¼"‡!àß vBœÛæûœçCŠ¢>ª+Üöù¶°Ï¿#Lë$6º íbäeóKå‡0Œ~š Ýt”~*iÜM‘'l³6 Á!)Ëâ‰ÉÜ fxØcaJ‘á#éN 接ï&…„‚-<šæc±`6¿ à®JÕ£dÍ d¥¥4*iµCðJ²sZë=”5 (‹‚³º¨ðþ–È[**F/ŠAaWRÒ“›óv‹³Ò ,FK(†6Jô#š~ƒq¬Tuû«J{ ®-;»U¯#Js[å,ŽQ‚Ä0?þˆbS:¢!•'ýžc;>+IÂläRæ-«u— ŸKÇlð”@ë{àGºH,–d2OÁþS g+a{qQ'‘Å%®Å¤Rá=eqѨfÜÀÓ«Ä]” feݳ­¬œƒ|ˆaEdŒuž;÷® QàÔr^Æ CDâjš¨()b6×òò‘çtuÓyÔÌÿßúâãÿÏ'ÿ<“)cÆ#›‘øn,ú4Ý"È}ŒOZÇÞŒD6ñ#Ž©ÇÄ4ÙF¶°„#h™´C<¼‰ìR9vo‡#IúV‘´&šqØ'Qý„ó#)A’šè?”ð¿È…KZ)Œ¥‚Q€pˆ§áWÜoTUÍø9}ÚOHi¨ƒVš(\´ .f_òF€"ÉŒ;ޱÃóÅ"¦«Æ-3$3@z6hjŒQrž+š¢|¤®—^Òê`’6“¤OjµN_8÷.›œhÇâ™3o‹ð&ú R˜$*†‹©y;š+.¿¢y—i©TÙƒõ¼œ6 í|*%=;´4ä™—sí= -6ëÜŸa8éœÉs—º³•ø)³N3PÁO#+ã&àkÆÅ÷ÕÊ^ôk!%†íèpyj){ü¨HÑ G:hRÍo3Ñþ\†KÞL.@LèÿÆ“õ¿Ù¹/´þ7m™£'…!(íŸ(á` SébBãdBf*ù‡tÃëÂ]ŠðËÔîËYËb'Õ1b©™,Êí &qošâ,Õµñwh!©¹ã4Cl<%ʜ作*.4&XW‚eœK‚ ˆ¶x¸ÞóÐé\Â:14£ym˜}´Ø@t ø/ð5` ¨DÅ8—Ž~ôët,ŠÒ*J„3NV”á6ÅÑÐü„@‰ƒ#Àÿð˜ðê¹ìkð‡ÔÖ¬bðR–ôZŒØÓjžªq/Ãñ·«wCL^ˆG猎_W»x/J’b‘ž‡Ÿ-ú¸“‚jkV¬¦©(«- Óad$΢$ÅJû´Í ÷¡ÿù‹“¸¨G?¢©Ûð®×÷4JgÛnl˜ø7hÜø?ÀQ)ô\wÍŠxû4›f_|z4þ&EÓNUf=“"3rþÏÌÌÖŸþÿÄ[þ—ËËååòÓ_þAüÿéÎSâ§EE]°Kµ5ën÷*,j%ÛôÕÂô¹VìU fã´½rÞíZu8–‚]/)¹/TÇB¡=[åƒjûŽjhÜ4'© µš²†w9 `¥±ñqqQW-%y.Ùˆ +•6ª®%9çrUåƒe?R«³r[¦«‰ç|dyYT·¶Ž ÄŠ‹î1=È O4Iz¦${š`¿ ÉJÁN— ¤Ë “c–ÈÊ8J©A¢aOº¢ºRh/Éz¢î‘—q¸ÉËEB‘TŠ<™ ‰ÑÓ ¡¬ðN³$Rù?²¢¿#‘ëˬ,O$E**U d]ʃ~«£<ÛƒJVGäo2¨¼Ù#ß»r@¥º‰(#7¦LOJSIûóÌ‹ ûÃ?är‚^#‘˜Â¡àÎsBÒ²üm_Ö Ïÿöãðÿ)î¦DüX,Dt)Ô»¨”òˆ)Óñ(ŽNÆêÓR¡aNB‹PÙ¯L?4ÅÉ‘jñ’åxÉäÿ>B$MÑIžš Å/‡’Š\r z€.¦QõSl¶’²8Ê4C@>èŒÕöE½nÔf™¥ Ÿàg¥¦vM§B))겘¦YGoÖbžE׳ZfщPHíF¤ËÄ¡â]§TÏ$ßC™þïq"!kð‰¬#ŒŽäÌ·4È*Q»pÿö³i  ÎY=_W»k,„NM8Ð2ƒþU[»ÆÊ¿¤(Ê<…2 ÉD~.pšÕ6å!&«Ç¸~Òïp/‹ùô8Îø/EªvÉZ†­8—çÀDàØZÊh¼\khØpº–€¬p_TõP³ZmŸóžFùÞñ×è›'ð?™‘ãËÍI¼$Çÿ\ÿûÂø?ãûò~“ñŒÁû+T܃¤UÃo/( á•ì¬x‚¦­¤¸Дk´§8n0F)(º‘óçÞ°ÞÌN#+­b~ öK²r*W‰ÙõD[R˜€P}jÿ”þBBFh™âL¾Ì²2Ø^N„®ÝçξCb1Ú¢"Òð"¾â¼;œÑ4˜ué–Hשb±B"PÜ ·³/ÝN&ð(:ùzb¿ï<{æmcù˜Å4uñÂu-Q@ âùÀêâ(œP«é/.îÂã²X&´Úþœ¬Š ;©véÒmf 'ûŽ‚Co¢¤˜„Ær²[-æ‰üü¶¼¬VÚ˽/ÈE÷ݰ‰µiRµnÐT1~áüuq#p]u,‚Œ³)î·Ã]5›§D.PvN+Žò6nâbX§ MOC¯%†ÆÇÊ’ ޏÎÌ‹7´êþXôð›ßüÉ¢qN‘ª´÷ìÙwŠ»®gÂu­¡a[àÑ/,–iœó•W¾‹Æ€&&-×ÿ’UsËðÿåCÂÿÚÞK9·_âÿ—ËËåŸ6þo¾|x*ÿ'ñ)½àFP;wgii/,¶Ï÷Ÿ0bYLΆ‘ú[¯¿ÓZʶ®®vÃhW+{0â^žùÖ* ãFãÆšü¼vüifÆM£a¬¼|DPÙ“:dÖm [×Ô´iµN»\‹×­–©Œ‹ïcl…UÄ \ÁÑõœ¬V«u ãrQá=ØÀÒÒû¢¨0“Ù„`½ ò0ðuÊVTŒ¥à>€”Ðb›©®ž§iëLM-Å—02ÐÍ6–Ø«æ‰á‡y(§Ú¾PTÜY] Ÿ…ªhyÀX0i4މ\S6*Œã1BÁCÁ!ju¿Ý>ÏÄ·ViZÀ³ÂSžøJUf<ÿ˼ÐCvº˜iQÿ«RÝç@M HS´Ì¿º]Pp·¾~¦D­`™Ôâõú¡aŠS)(ÇcÃ^=g6O–(»4Ú~\‰¡|D¥îѲ˜'ñYV6Œ+©ªœÅ°(H¾CÍjöÃí‚sQZÜ%”7…:0îš\I|‡S¼qåx¤øª,îÁã"•g×ÅWU}zÝ Žr'NšÒE”Äÿÿâð¿á#êåø_bÉ&b)|.•Ù ù Š›±EJ¥"ÀQ}Ê[KÅí±0 9­0K'M{qN Wgø·DZ‹8•83Qw¼¾§~ž&£‰ g/ôó=ÅÉ铯$ÅöÈqò!µ¦ÏY­êÍËi£iN0»”qS_>Œ>¥ÈkÇûÅÛAc2Ä-Èo§¬¶|@‹^¬df\‡g“sÛb™*R•’IJÑɉHŽ ë#K°0MHrù¹@´CZ2 ™) ã¾hr0B·¶ðY:f>mlxìv­ð¼áS‘Ň&TrDz ÉIɱⅹ͓2Üq™î_¡ˆ<‹•d:µ0¼çÆ)Û'íËð–4ø—]>&Î()þOõ¿í/(ÿ??ÁÌ&·Ìð˜`$Ë´psÐ[‰Ô v¦bœc#øºR㦔tm88•¬kÆT¨S¤îMªXê=åÊÎÉ¿H—MÑz%Jì”'5"%‘èÄe¹ÖÆ3Nò9Š'NÅN#O™.@r‚å„*\mlx”"ƧðÍÄŨ žf™IÎŒæ|ý¾§I7™;T/,övbb"˜ÏIÅ_±}1“%üQoŠ ‹TV‘½`~½¯Éû$5¥²ï¥Â±?—èJ‚S.)§ˆ³zhÒ:oxÏbr×®ÀS™Iõš½Ã¹èt.â™W;pI&â¶%¢i.æ)ðGuõ”ÒSïYolzä pÖŠ—æ;VkÝ+& ‚-²ÆÙL£LÕœ§á!̲›ØØáD×­ Å41 ;W#©½Š¶™¤w #¼ƒ”¸üÍÿ'þÏæCµ¦/ã'Äÿ) È+ß}åõòL¾\þ‰ÆÿåøÿY"ñQÄõIíN²~RòÏ—Ìùñy‰¨UŒÚÍaŽ’Ž)0#ð,3l‰ÜÝ@ùì‰<.••nG<ÜïÆRgrâT»0ûøUÂÿX½-$êžáâ¢n½~°Ü0‚3/çÜ‚ñž ¸6gϼ#h‹‹;\z†ñ7ëÒm ¦C‰€ºjnŽÈz-(h'ža"½ä¬é ü­n@ '2¸y¹mº2b¢äXâ§š²2ÍÿzXZÚSÈì‹ðb0:Þc#¸CV¼,ðYÙžKµ>À 0¾Óä¸k‰Ä—m¤‰i6MÛƒ{¹¦fÙb#!‘ëët.hµý؈}hÊÇpÙžú††‡ ,”Š£V±>šqžÎÌÜ­+pj08Ú¬3ZÍ þK[6€W Ø ÆÛ‡ëär.kÕýÕ"è (R5ÿ\ü? Ÿ4šþ¬Kw^(þ—RäÁ, †Î'.ת§ñI±jÄd/ÑŽͳ%êÁŒ¼n…z¬Üô@oÍ*èÎÈïËÈítÕ¬Wçr}v÷ºÞ8¥-ŸÐ¦ æ™\EOfNÇù¼ž¬‚ž*׊Å:w>§«D3ÒäÛþÆë·ŠÔÖÊmÙ„R=R¨ËStfå÷(U#:ýT©v¬Ú¹l±Îg(J”ƒ.uæ+ŠúuS²:Jµãç2ÛñÙ=ç³».æÞs¸×Ep>5!90ð.gí…£»0¦ j)ÝHðh±/“ª,äZ»31ê0—ÎáI†¢tÑA2ü{öŸÔ³æO-<‹Jɉœl*L è¨qÜhÕ— ÁODƒ×_¦êË8ê¨|²£¤¨;àÛ’\Éç’H¤9™TOqRãXš˜Kz+‰#‘­$AýS­T6‹qt"çÿdþL–ÿÏú¿w øÿ#gfE*¦xƒ)7S¸K{RAŠTu"÷Ôdýg’ ¹äîɘ|äh? ã%O$v2‰(Þ“j''ä¤e!h¬Ã$Zm3cåå£ù$›KV´“KîÙ-× QKÙÚ,D­I֘ˋ ;¹Ša\¯Â5B;F&•R•öZLSDË?„ûC“È®%ü@¸¼8KðŽaôôeÃ$*a›¥°M/RiLq7þBËZöð‘Ñ,afé«v ‘òÒ5Yø0 8ìD¹Œ“4xá T_àyˆ… ”DµÅJmí:ì¤(UàìýuO¥ý44>Žr)`0´ƒ1KË$Ûð5à î ¸É\Pð[àA`È#÷Œ6I'à'Gõ¢Ïÿ„ù;”ûçßÂÆ0ÏɲÃéµ¾-š¹ŽÉ)@%-àÓùÿZuߥ̟0þ+ѵøößh|}ãÖÈî‘Ëñý+ñƒ7ãGW}» ÿþåÀÁ,ÁÃ7ñéß{ð$¼ ? 'v.'v®$¶Z;-ñÝ–8vØ †£¡ýæð^Kóq öŒâ»ÍÍ8Ûþ•ˇW‰wÿJtïæã«ÀñÃf,á0Nt/|åY"²í¶D÷q%-Ñ]:mt§%¼{%vÔÿð²iîôÅ¿\^.ÿ¤ãÿòØÎñÉü † |˜#Ö=€¥4›Úu—c¯¾nÃíZ¥:‘®‰ñZ$óx½[,àx ²UÅ‚ÃÅx”RS»†“³ƒ°.2‚X>¢Œ—ºuØL‘Z)2Oò°EæŒ8¢—è„\ÕEÜÑõëµîUÁ)-/šÃž~6’Å )}E’zd“».ªÏDþ³¨íòDvZÏTèÚ‹î..òFNF±è Ì:ØÐH6_½¾'4ØŠK¤î,”#Â\8?î]dæbÕËB‚-5Ф@Zr!LÈÉ?IæU⇂áŸ< ¼Š„œ#J)‡k@ZN"“$RàhA I‹ÁOÁ•~ %ÙçDŒZPJ2ýËŒ­’Hfp ©LòÝPpÃ?°“¥’£úßœ[/8þÿì#…jH©-,„#WÒ¯Öüñ7ß?—ßóÚ…Ûg.µíìLeÿýÙ÷_=×–YÐó^¿a0ͼr®ýÏ^»^í^‡ƒð/¶åk゙Ùþ§ß|ÿÕsdäö|ýµ›úò©Ìüž?{ýÖïÿÉ¡ƒWÎÝü“oÞ8ŸÓùõ×oæw¿záN^qïÙŒ¶¯üé[Ù…½g.¶itãyEýÙEFËÌŸ½~3³àþ|ýíóY™yüÝÊþ̾‹9÷.öþùÙ–ª…Xšè(I MÖ„Rõ2@õvûBMÍ¥‚GöEúwˆ‹jC¡½`p7Àü]~ÿ6 ü\Œó$>¨¯Ý§f1"|*OýÃW%Ãï£q݉zÇÒ™çè•’Fp2EÂür/@üzYÔÿ®ºkVá´¢-y™z‘“v\î%|èTŠ.÷2|ÛzÏzmÝÚ öàð^ 9‡²/ª‡RS*ɲki"Fx=RW’è+Sâàò¾/ÒáNÌ$Žä).iÁßç|‰ÿ‡ðYß‹ªÿ5Hù?Ϥü “ïy›ž4Q™” ?½GOÕ%RV?ÁÈ-lG÷çÒªdÔ…¹(wðHBdÉ>Ó¤Ça„/@9ŠA²^ÒÛ=áz0;(±Àá± ”“ ŸÇ±ø¡\H:õޤ4âØ7O´;] %Ên­š¨lຜKùÂaÄ]#Põ"i>Ö¬P Wq78¨z©´ª|´´¤›jf ÊâNn@­êì/)îÂ} òïÀöuÚ«çD¨\§#†Šüü;f3QËu õrýˆÍJ$WM^ÞʪQÕŽ* îŠJÉ"öM_¡â®^?T h‡ÁÇØWªì᪓4’K—n¡mkhv—!‘ʉÖæ²i>ãi`>/ü’-‹œ=ûdÝÌÏoÏËiû€•$«sÆ t^“yBW6páü»ù9mY™¤h?Z§‚ß”™qC­ì-Èm1—œ)xå†Q­ªžÎÉ9Ù£?Ʊ<þE­íÍü‰æÿH:|øÆ•¿zoN4·|ØÒ¼›¸v|õÍã+ E›¯ü] ýúìÍø³+‰g×ÞøQ˕Ö7š[~kùûpˇ–gákDZæÃPó‡¾Ä3Ï•¿6HùªÍGWšãWŽÃo>kºrÔ?ð\ý0píïÂ-ÿæ'Ùó5?‹^ù0ñ}óYâ£XˇÍWc—Ÿyßü;ÿU,?òá/®ý(z™ˆ#;i}Pýÿ¿\~®òN|Òø¿Ú¾¨*ê)×+•Ý‘Hr.þܹwLãZÍ€Ñ0ž™AôÝBY’Ò{ÊFE ÊhœÔ±e3'v­¨Ójû33ošLSb|±Zf€(¨NVÕ+òX*ÊGõú‘¬K·qfŒùym•¶NŒ?¼”yKÌÚ®\¸pÝf™†õ#OŠcz݈©bÂ^ù@ŽÿÀU¥÷­4.FDª)Ömš¨`L–Ošª")Ò «uv›u‘(§¢b‹˜KÕ—WÆëêÖD"¶“ÕŽKˆc«íónÉ$)rÚ‰+¯b¬Â0l\RÔ ÿ¨ÊöÀlš´š§0j™OQW(°[Ž[ÖR"l;FÃêÊ9yœ C0žXi)…î1¤æw*:ˆÒ_y_¥ìU—öé4”¨m_¼xCϤ.ohKû ò)963ã6ÆA €yCùöÄ9Š»—2oª‰!°S£éÃóWÝ+Óäæ´jÕ9Ù­Ä짤±‰Þé OÃ#ܦRÙï ¤¤[h ”–öH˜L“*º’žììÛ¸xµzàùB³tþºÿÒ¥ŸBýï ™ËdÚ2ç¡9z DâeõqU] ¼¤:»m?;>vd"”Ò³Šìãkˆáe ´Sa›÷Qµìv˜ÊÕiO¥‘ý`x'ÞÁ©ˆÉÃ8d:éMÓL}î›ö½ý§ýp–KP 2ŠÒ„¸²8ÌêcR4¾°°ˆEHwÉà…*K{Ð/œ}>&¶p±ä€ °ÒjúÑ0*« ;0¯ÔŒN7X”’ß—­²òAqq:&ššíYù@¥êÃùáÖéõ£ÙY­è’‚Í2;»ï襸°++ë¶N?táÂ{¢ø%™ð#g§‘MÐÆæ¤,TRÆc²à³‚Žq탔ޓ þï%ç/Â2„ÏΦŸéðH“åìHC¢HGÊôÂþ)T†µÌ©.éî&­–,[H4§¿ÿ_üŸ²øÿ Òÿ-7œÈÿ—…Ðé«Å2Lרm€(=U}hçν%¡ÛA‘Éi{9Y·‹%ŠÎBÅ=L€Lxîy$}{K‹ç©ÑP:½²°SP õ7øø0q@¹èYù°$™7ñ*±VШΞ}P6/·çµÞét ~’IOJÌ­Èr«$›àixO’PœDèdq˜…¶¸kIfš(ŒÜËÕÕ ^’ç; ÅêZÊf‰EШáÔw7ŽÍ‡ ‰ç%†Qù­òPŒ%U´ÎÿµïJÑàHÎ?džœCá ʪŸŽ¤zöTrÔìmCÃCŒ#èéMIokGÈm³LA^­k ûàNë™À³†(Ç]CY@h¥Œ°«$Э9‹&ËdMÍ †z TöUmŸcGoèšhh…\Ën ¯mÂïpÒDðùÑÎE±dàq oôbü;I9Çå¶1 ûåñ¡ÿû¯ÿ• tòUïG/ï„ZŽX®ì„®îG¯'Þ<Š7E‡Q´š7°ý(;\}ó éÊ¡áCÅy-ÏT-?ĺ¾ùP?,k~f|HT7Ö$v]͵ÍGº7ŸU4®<3Fvu‰CÓåCëÕ¹âû•‰{dÇÖ|躼ïJì:š÷œøŒïæ¼yœ{å8#±¶ùðÒÕgškÏ\×~?âZÕ¬û%þÿ_¾x5ïœã“…åÿ}IÙ?ûYp1ç¿ú{Wóÿ±ÔÿüËòÿ?"ø/&ÙˆÙ{Ãç{Âù?{áоV=èrY%¶AÓþ`¬xê¦d¿v…ØŠ7}ï‰Ã1Ïz »RD½‰ùÙÂÌB›)†rXB±%"–¡``+ž*Okj|œ‚y¤Aƒ±Xú[>?ÐÝG±vðä7îQ÷%uÞËGIùöÓ¹|”+¨Õ`„a*1–]3/G~ÆàYØ«¨Ô½bR#¬Í:ípwΉ°uH¸Z šðSpZžO¨(ÙfûãlÿS¥² .R]ÍvÀHMÙ8¥€aƒ>ÿÜ}ó$œ¬ššeø'ýØ!L=FÜ) (  Ï,¯š¨ªbÃÕEÖ¯'HÝòASÓãjÇ\væÇ"À¼Œõžu."Þ ?·Ç+™pˆU,'‰4¯a£²j6©åXÄkªf©)œAÐ= `Âÿº4¨áí³äÙ¬`±ÃÐ T ôƒNú’iøDÉÒ/Nÿ×ðõ¿I™Ê{X_ÿÐåZñ6R*Gƒ|þ­”˜f²Rˆ"ED&I쨾vƒå}“ùð‘0KÝE“>™Oª.XJD9p¸–Ã"Ͼ0>=õè,Û‘ÈA*z¿M¦ÜKô>[è;‘s=Rþ?c@zÊ‘¨C;).î,S÷˜“¼Wëk›’t¯Šh¨šÞlž°˜¦hª®fµ¶nUGµŠ“V"r±YfÄRmG[Â;L$+lš “%-Ô¸W˜Ò–°׿´Õ×­3‰î¬<)Hž"¥Z ­j ¦Š/^ ~-ÓØçëåúQnËžú xßNç21ܲZ+^–Å<ƒ¯ØN—a"y¯²²A•ê>IÐ-Ì´TÚ)¥n'q;I˜•8‘ü[hœx\¬»†Xiilx¤*¬’Qü“é.™ü­Ö½"â°c'ÛÒéüŸˆ„ÿµý¹y/Žÿÿ@^Ï’Já8êZhB@›èÅ$îl™u»Wñ@\”¹/4ljx¡4gKKzЄ)ì0Ël‘2Ú‡aÄyðñã[ÿ¢wé«îé?Ôv~¡¸í· Û~»¨ý ªîßÓö~©¸ý÷Šî|Ù0ðÚž/Þù–üÖßVu}IÕýemïWJ»¿¤¾ÿåâŽß5 þ~Yï—ÔÝ¿§¼÷;ªÎ/4Î~5´üûáßñ­þZÃÒ¯5,~)ü0ëÚAmËñÇKüÿ³½ü‰ÿ«?;°ÿùåÿüÑ?ŠøÿIü|ŠùS,0qÌ϶Xm_lj|¢×3ÔÕnÔP²Í#·s¥®¨`Úí±„¡x?¥Âqû:ݬ"@àŸÆ¦M"¨g5RX* .Íñ/°~ÄäSK™ Áb¡!€ƒaÄÆií°f,=yÈc.Ýr"îÄË‚ÖÃÇtgRÐ 8ªž;A`˜^bû¾ÀÓ&ïc!•“‹uÊJ®¨,ˆr(‰˜N©~!ÌL)ø»$M ¡Á½FþÊ”>ÑTZÀ9}ÑÎõ‰$‰b(3G¤EQ|˜9TñH)‡'•h!¥à %…ºº5š¯' ¦5†Ï‚í4š»—ñ:,–Ò£WvXíX0™§„ük=½¢¶c9ªu‘¹ËKµÜ+ø<©"ñL^A©þ—yqù?z™Ü0€^Vô OO«P){ÍÆ xj¬†q¦R!ŽÒb5"¼&6R˜SLQ8¼¤× —놦 ´pÜ~…a gÖj¨Ík‡Ô¥½”«ªæ€4r²I¬‡hÔýhIq7м|c¸ªì¬Š‹»lÖ©¢Â.ì‘qh[ž›á>”œ€£y ¿ÿi("j‡wYîV˜]p'”Lž¡Ù Q~+øði†‚ãçA)k‹å•=ÎI‘”¦ùKÅÄ„è2)æ"éýr&[Ú]•!= ÿ8©”÷qxûgϼ ì] ¸[Ttˆ(3ófqÑ= ¾LŠÒjûxVnÜj!/¿â +‹»÷H[M(Ž E¶‹îáééÊHëêRæ-¼ì3Šïãé©T}$\hŸâTeožÌÍi­¬œÁ«ÁF¸ÿZÍ€‰=}|-×éÔ¤ —s'…ÿSyïI–´’ø+ÛÅ¢Öôeå¾ ü?KóÒe  œbfޤL®COULç”3 Ø»$4¦ä1® ÷±]Éi?Ó\÷N3vžBïI¶™vpªtW¢ŠJ$#êI!¼d¶¥zÆd³EXšªÒ^Øø¶èž°<4"Àu¥¢ª}ÉÍŒ;8uŸÖM°óè§x2Ó¤É0n6Ž[Œ“xõá(±šÌ“$ç\Äóh0Ád;€ý4³ îà«hŠöªùŠr¼úôkŒMü0Úu_™nˆ&óÛíÕó4Áªê)Cp…äJ‚ðšµÚ!ƒaL ¤°CYDé7–$Õ‹Á¼ÀWÍʼ«ráÂuò;X€¾L;páüuôqx+fWΡY×¾ çßÓ• âò€ØËuCx20hÒ¦Šñ¼¼6xd¸ëóçÞebçÁsgßÑ({q½fðÌ™·aÐ^å-•ª÷Ü·ÞÑRTª_£é{ýõ·ðÜp%¹Ù­6Ûl,.éÙ¥Ãþ§òÿÿÕšþŸxý¯X¹ú,Ú¼¸vnùÑåà²Ã7g«ׇW¡5'¹ÏÂ-ÆZ>Œ¿y¾v¥ÝŽjCë¯Õ/Ò÷ø_…ý’oñ“µãŸ©êû-S×ïèÚWÝöÕÝßÐ÷}J?ð«¥w?¡îøŒ¾ëKå€ú¿[Öõ{ªŽßÖvÿ®êÞç5]Ÿ×÷þ¶¾ïó¥Ÿ2 ^ß÷ëÚûŸÔvBwÿ“ö»_¬íû¼wæÑÕ_Ьÿ¢oéSÑ?oyVÝò,ážu½Äÿ?Ë‘ÿŸeð/–ÿº³ÿ0ý¯¬5sÈh$€ÔOlÛúá‚‚ö⢮rýˆBÑQXØa4ŒÁ´(:44vOfdÜnϼtÓG**49‹­Ö)³yR XE‚aLæl¯"â‚ü<:­Åºœx«Ž¥ºZfÄîWUΉt²*ë¬Ïû”­–´p£ÌDÅãr.âW ˆêª9üN•ä{Dœ–zX›pyNæú D2 ÂͰɳoOEN>PÚscã&¢O_†wVENô*~ÅÙ<õíD»„ûóq€Áìksá¡çQQI'~EƒD+‚»‡38©–‡ª{pÙ8Ccãc!³K’¾q ÏìÌ–i‡ªìó<”ÏOuå\Ì®@À>83‘Ò¸–X<‹&æ’¾—‚r…þpºyRã@”º ›0ù-1Ä BHú@ªie9à¤;Íë}ê÷o‹¯ÁdjÐOÓÈJb“¥ìÓÂÕ‘O™ø7)a!Ƀ¹œãø6¥Jgy–Åÿ(&ÞJD ÿk5/ŒÿÓ0Âõ¿'Ô«%ý/8Gx‰x/$ÃaŸ·Zfàzëõ£ð÷Ò%%²‹””Ì‘¨o:]Õ“/ÌnÁüüÁ-¡)F±÷Ðv2Í…ºà‰ãðìÉC_àiƒç¡ƒ¦˜±Å“AÇGß2+”áCÁ«'xb<Ûþ”åìWD&Í8p +)ˆt ÀÑû¸WЧð„q1xìB&[h™á+[›9Ž5>Oû/-iý/ÍOLÿ÷„~ãzL ¾hùÑ•ðÃzÇhùÕÝ€}LXw·ü0~å(òÆQä ó~øÍ£ø•ÃhËQcìÑë¾õ_ =þ˜wñ_ØûÿgcÛ/–ßþ„éÎoï|ÑÐþïôŸ6ö}ÂÐÿ¯µ¿bîÿ‚ºís†®ß­èùߌ½_T·VEËgt]Ÿ×uÿ¦¶óÓÅ­ŸÔv~JÝñ«¥mÿ‹¦ãß”uþªíæçm­wõþÁ¹_ˆ¬}Ì·ð‹áÕßoÙ7¶EÜ3/ñÿÏîrÎñÉŸ}üÎù«ÿù?Ÿ=_ü‹ÁWp÷55R™Í;TÇçZÞ€ib °îtQðHÀEsÇKM_uõ")u6<lá\›öãHc 8Âfb¤ á£vÕxJe¿5k@8MMOb)îÁšÚU§cÑÃ¥¾ÒaL—m  ìïr­°5ÞtPVÒcÁ“/å÷65míÀBþ7-Ùÿ¬%뿼ÀÞVÛçÅÉx’$͈à9JX¢¬Œô¶êëV©2˱XaãÀm­ ¥-{5Ò(Ítœ,/­s¯mºÜ+@#@P&ó”½rÎQE8 {VUÍYLªÒXi‡s¡L;PMBÃËrÿKÀ?swÍ*nO@LÜã±Câ¹á`ìnlzŒ¿Ú«fdÿ7ð³­÷¬ãû¸™¡ïIkEá™Ú:¢¤¨]-*îjh|Øä}T#+}O€0Tã|`émzLSÕñÃúÚ5œ ƒ…Ï(‘ ÜÕs^"ÍÛópR¬-àšPcpùiåÿH™ÿÒ .US£ÙµÐo?}ÌÓÔ €âIŠ9 F~ÂhÞ”cÌ BmÙë#`ÐÀ<"Ÿ-¥ÌÆf€Cs½¦Ø{cKò+¶G"a¦µ‰ì2¥Hû§ø-þ:D©ìÔàæá!s¹b’&]Ãs»nÓ¨û(c¡b8žU”_ŠRÙë¨^à ë14K4?4l š°ºà¶`¾ŽòЪ«ÉDSâó…b7<üDÙª Œ†qxë~>ÿ +”óÉ9x.ö0*áTh¥è³x•VÛ FìƒÕ€Qµé1º Nˆ3 _–Yª¼“¦ñ,‰ÿ‰ÿ3û…àÿèQâên ï¢ë[þ®Å5mó­Ö»g«›Þ–¿¿&ÞÛ•¯À/¹ú£kÍÇo´ìx#kg|«¿~ü±ØÆ¿Œ.~<±ð¹æ¥/V|ðqcëg ­¿¥kû”©÷—+ú~QwïãöÁÿÝxÿ3úÎ_/mý7ÚŽ_Óuþ†±ï·´÷~£´í×t]ŸÕÞû´ªí×ÕíÿV×ùMÛ¯º>[ÞùÙæ¹/Egÿ×ðüÿ_ÿoãþ»Àò/F×ÿ°åÀÔrsM×~$þÿä[~Ål"FåÉ×Lëo|öz@lÿÂÍ~¥Û±V›?÷~P~”oÿÍßþqÇ&>¼vêÿæà©c?w=X¾Jç¿üá5Ýr󯿓<öÇmÿ§½(ÊÿùÏ>þW”ÿ‹Tù?é(Ó)ü 3^Yù #uMÍšÝ>ãßÔ¸émzÂɺKÇrU{DÔÉaIˆJLþÊ)ĉ“t܉”–V"IC—’âJ“Ý¥P± üŸ¤@I²µ§&¾™ûNú#QŒ,@šÀÿŸx³ZZ>~¥*µbøŸC”{°º±ØACÃÃ(C2ÂcÌP”Ìýf²w¬Põ(%Éì‹&#{âÞÅ`‘‘;ƒ­„%B„<˨¤¼.ù$1ÍøI¦>Šaw€ÓHÇÇ6‹ñ‚Äâ1²Øf1ôÃ'Ô“‚¯ÁÀ6,œ Œ,MLšd1OŸ€0ÉaŸâ‹ó<,.îÆ ¾VUÎQ ÏEQ8ø,°ÂK¢˜Ã.oŸª³ÍS:ž˜f†ùd5Éܨz+*p…3f>ùsÅ¿éD 5—Ýù©àÿS³Ç*U_Nn+FF¼»¢¢.€Œ›„3ÍSý()LÑ”SgYÉ+dgS ,  àhqQWaa@#'ž ²¸[«í7Gñ‰£0RãT¹ym†Ñœ¬Û6Ë03Þ,)5ŸÞ-J!bÑà ã(Q©îQãb_ñô€Þq ¾š-Ó¥Å]8þ:Ø‘‘=2=>ñ½iÃAã2–Q©A¹[ž‡ØHÁCç’—5ÉÅ nSþ3¥{­øÛ¢DMEèaÝ–ïImýš ¢™…ÆÇ^>?žU„‚íONlÃÙa‡qÓçÊd¿äž“_É5›5T´)q° … &Õ'¦¸'gϽûP]54XªìQq L)sy¡¥åæÞÁs@ÛV–» ºOËdÃË€ÓQRÒeµÍ¢›œ?g@èázä“äÄpVæí’¢îÒÒû•4I1 ,éA“Æ“Ä;¥ê:Û>z%X&ósî © R;FÃÐZQA+_Ïâ+6z6âé†Süÿ°KèïO“ø_ÕŸ“ÝñÂòäùÿ§ÅÙ…TtPPÙ?ó6ÇŸ’Ú‚ÿ)ÿº €·æ¢rì3's€”gCH9âù”ƒ}”’Á^¸ò M‚J\7i°ÐVÃI‚¬`‹×-B ÊR <­«_Ãy`ñ säáy"s–áÿzŽ„ãXœ¯Œä àw0–Ô¢25F΂ÛJn»¬\òâ…ñŒ='m,ãpK³žÊ·ÈñLVÅpb¦@æ‹Áß,,¼wö[oãÖÐ`2.ÞÀÍ*:.eÝ*U’0 \¤ÌÌ[°3eeƒBŸ…JQtCοg1OÀd\¼ŽÆf(ÍʼU¤è8wæýˆ—”܇órî¨U=ùyw´ê>8è>pîðaiáj©Ô½¹¹­E…÷L†Q检í„åÁ™ñðÑr²ogeÝ"–$eÏù³ïêuCè\ìKž(Œ:‘ÿ“Âÿø¯ÌŒ’ÿÿQKÃV8ñáÕ+?¼V»T«îR‡†!ƒqÔÝODšãϮdž÷qWã‡WZ±Gg›–?î_ÿXxý_ÆV~9¶ô‰ðÂÇkG~É5ø©ÊûŸ¶ôþªcâö‰_6ö~²zøË¶áÏb1 üFåØoÙF~Ó>ñËðoš†>gø4Óàgð“}âóæÁkÿœeè7¢KŸŠ.ÿëðêÿÞø…ÀêÇ~%¼þ–#GËñ÷ƒÆÄÿÿ{oÝV–¦‡Åg'Žã‰gâ''9ñô,žÕsì±'=ÎIÒ®éNO×TI¥"E‘⾂A‚ v€X±oE•”ŒË3ñtwu©I%•ŠE‰’HQ”(î›HQ¤$J7PêêÓ“ïÿïÃH©jÚåf»í©sÞÁÞ{xxï¾{¿ÿ¿ßÿ}…£ÉHê­Öð6?8Ú¼Ò%ÖWMu|ëZü«§B¿s6lZ>êxÜ%ïòOÎGâÏÿòg(fØW^²¯óqû›gˆ,lºt÷;ÅŸµþ?îåçü‹å?ü¿õÒâ_±`ÀEïüÓØx ·®éŽ^7RUEJq2 Î5’ ÛV yÙ´HÖΖûØa1¶s^µc‡ôô32¹¦,.™K¦«Ó~©ÙnªÑ,ü/òçÊš~D(ÿ´i¤¦æºpZ3L©°â è‡þfNÓóL4€AQ~7 Ðð-Ù`UôÕ‘Äܨ¶iÇ` ¦R ¢ÓFÇ dN®^¶¹:å ü"iPëGYŠm$' ­¨¾F¨FѯV b3`ª’â`Ŧ¦aœ Ö×× 54Ü’Ï<£\|μ ÔZÆJG,£4JŠIMÃK¾v’RÄ_3›YµƒÐ鈃™'€öï?)Šš L€¯SÊ;c0Œá 8`,a¦†aÇ!—ÉŠK ŠŠŠ>ii¹‡}I[F=ˆW‘Æî”6,¿„ ð-ÞÅaýNòv5.óŠÎí%þöüÿg@¹rd c¥Ù2ÅFÌ[ÀÏ”KgÕ>á€ÁËdš)}\OÀ$ UÁÌ¡Y×=‹…ŸææYš) ÆŒ ¤!”°2÷ÅËàÂú¶±ñ¶˜Ä'.­\bëbVÄb$®K&UM0{Œ(C˜ØFXµ[4~_5¬FxÂeGÀJ‘/¿¦C`)–IþaAþK’àb‘6 áÖuÙ¹L<ÂicŽ-IuG,§mä%û¹¤îl]ÐôÌËvV9ð3YZ3-¼™ác‘^*áÂÔ ùÑÞÂ… Ÿ²'ÅÓX–#[Æ:™cÿXú£H‹Ù@î6….ø9¶IÚ£VZ²1‡ä&Ía þ4ÿW«û‹÷ÿ“Ê֜ܕŸÁ?B3£hÊ´çZZÎÑ6áI'2ü"5\ï¥zjÒ^Ä!wõ,é¨hô®Ã1ÏsC´†ÊH›ç<­Døñ¶=ô¶.‹.’Ï·âv-Ö×ÝÄ.h¸z¡à*Ú?Ú¼Å:-X.ýI‰ Þ$}¯ç!1|‹;•%õl§O´äTN&ãé€w'øOÉI•ŒÙ\G*Û\@þ(¯‘Á¿LõɃ;‘ÿ.FPb§™Ì¼…r÷£ ,DL¸t¸üȬñûeÄb¬Mñ¸ÝO©xü÷vÊ<¬ã¦pñõÂ%„Õ­\F¯ÜdÚõˆlœó$ÅÀs²ØW• Ñ¢·‰Æ61•ˆbó‡N×¼à!ŠG ew̉V Q‘—{ݺqɴʇhK»(@ÿÿÏê#Ϻ’?z ø?¶ÙQ?¨Ùÿ½ýÞ}#÷ýœ†›">;šxv´ã‡Çâ©ÎÎOÇ7;OüДӶðßÂ/…þçèÝ_ÌýJ`æÆ–¾šÿàü׃ _o_ümßâo¸§ÿ±åÖïë~OÕû5UïWëú~Cyù«êk_Óþ–fðku×¾bûmïâ?o_þïâ?i[üÇm‹¿ëÅŽs¿\üMßüÿÒ6ÿ?µÎü²{æ÷cŠN<÷Öå^¼ÿG·ßʹ”Á9®^wA/]?:.ÿ»¯Øß~ÝÿŽÀÿVËb™V¸N¹Y€.Ût»—lÍs¸L|Zp‘*Μ6Ã0*&Að^­¾Éöë4(ã€v„ó;)æ M{=ËZf,àbâÄp@*H$KßY½~\”?K¨/-ÿ.ŒS~4õCèÌ[yj˜â,ª^F6˜M‘=ïà}Ä  fO’™Ií´::óR$±»Dö¼ƒ4Î&â)i_¹¸oGÑŸˆ­–Òû¦v~Ê3æ­i%™KvÿÌëéLÙ®{ÐVŠBäòfMN \OÁss‘hÏ&‰l¶º—"¡5ü/J°»i`ŨMžw' '¶‰î\‚¢0\Þ‰4¸€—ÂÌN\L «vßJ”µ°Øh%à_!a| ÜnvÅビ±5ßE3ÀB;f=Œµ"lœFFz)Fª0m`I4~–G%Ÿ¬TT*––p–ݰ,§)9jÅ»$íÍŒçF¦(XDÜYzž»Á|– ¨Ã~²‘í¶ÜETe#æÛ˜Z5ÀrÛ¢va©J=¨T\çhúfqÑ'2þÇ•áÊß!¬/+ïÌøV¯3èÇIkË2g°©iDËâ-²÷±:Õ²’‹&ㄪ¶`µ©qÛãÒ©ýT¡£âY *Y6Æ©*×ÛÈì)Ëÿ7ËŒð‚ë“{^ÿ›ÍÿÙäìBKUíµ¢¢îââîÊÊË.æb}-%~?¬W£µÌàê!øµÚfª«¯TW_Å+)½¨RÝhh¸YVÚ#Ì Ôã)•¸òC¥ÅÝ¢Xµ¬ô¢N;"è1è¦ÊË{k×’›Žƒ¾.çHB¹a(?%jE…¸É?â¼ç}ÿíT0[^sôGÇÿ¸?ž»¿ KGµ‹™<¼}¥ëÛ×ã?ɾû‡‰çÇåýЮ}ÎÿçÝœ¯ôÅ>ký—øÿKüÿ…ñvâ=+ØÌ6šdÍm²J;NnÊ^<¤R˜œù+9ö_`É=rZè¢K³B3<­p"¡šˆ|Jb"ãÄëþ¿d¥*ì±ø˜èê…¹’Ü ¡¿ÜJUr[›þ;s¹e­rÙ|“uPI[ìϨ ¸bo¾‹ã{<ìÍ󸘲« Å9ÿ¿ ­UT\Fh`¶P1B“ö“TžÜxK­¾4èt¦jày^Ù/L6•¢¤h:G*y§ŠêŒ­¸òS»éÒ•˜/žØ®t«œqÝIþy¾CÿS5PXð³àÿï4¸§ñ®Q3\VÜ২¾ÆÓ(·sßü ¡nP«¹-Ü(pé0ôççž'¶Â¡uÕo¸…D¢@š;õKe½ž‡ò> ®ZÅU ÇââOêênTU]ÞÀÍÂPŽK„>|c4kOjo×Ôô^Fã›õZbæâjµ·Œ†±&Ýüü³»µÚšßQ“ˆŸq©<#&Ê„..® ÉÞéG)œ^Ä.dv^*CüÔ¯IÇIìlãÝ,‹4éKÇÓmÞxOLEY"ÿ,À¼VCHR˜}ãzŸcƒVïRÚ}u¨ F—¢ºŠÌ˜ôºV8—&êHÑ÷vi {pˆa0Ž䟋¦ ‘…Ç~Ô h!‹mŽØtTõ ¹Åú³ÉtVïqka!ðÏÖ­zÿŸÑÿ©Sõ_Ø#? az(˫žb¾èRvY!Ç¥‡TzfEãáÐ^Ø%l‘’JNhöîì­°Ê•¿T^DxËÓ4Ä6BáU_û#术˜`«m¾G¡ðSÄ¿Ä"òÏcn © W[âb´¥é6)ÝÒrÏá$Ùäœ7?Ì;xú•o¼ÇçÀ'÷ï?ùíoÿynî),oxßæä|øoü¿Oðô}ë[v8ÿ#<¸×o¼ñÞ«¯~77çýïüñŸ›ÍÓgœ«©îûæ½ý擇òN#|@3ûÆ7þ¯EÅŸ¼òÊÛx`_ý8 ÎçµW¿ÿÚkï` ~â[ßúsD ‡9°ÿ=´üÖ+ÿòOóž)<|þ›¯¼]xøœìv—%ËÂsJAÖÁSäÕUr(½‚%­Ð‡¨TƒsOWU_&?be?þfOžþ˜mË®+j®¢[À‰áäæ|ˆÍ*+zK‹/ oÇECü²oß»U½ˆÈŠ‹ºµ••^@hpàÀûè¬ðP ÚÚ¿ï¤~‡EdØ_]݇ÀÇÁ3…ˆ;/÷´Á0vàÀIR–ÖSW³“ÿÿlgù,ÿ7Ñž ÎíIýï§É­hÇfäøó¤¤šŠ¿µ:º8–Švl;7Cøêèf$±8²î\KÛòß¶œØ´X œXKžxêkÕx|CwlÝv|ÃÿÖFûÑuÛ±Mýñ”é­Móñ”¿kÝ{lÓ×…eÃwâÓè‰'ºRþc)ÿ[ÛcÛ~íXªíÄ¶ïØ–§sÍÙsØŽKÅð‹G7ÛÁÎíð[?Nù´Ã±ôþÿ?>Þ•´n¿µÿfB¼}0.®w혜„ÿê©pþ¯úü}ÅÒºz¬bªCþ(ï+¾2¦y>Ö‡]ÇÿòÄw8vø¬õ_âÿ/°ÄçmÖýõŸâ^ÿ¡ñÿwÐoä]z+¦9_½*JÆ€pÐùEÜ>ï°ÏsîaZûÝ:Ï Pô/oÔ·Ž7¹F¬þ£wRm½Y©½RgjtëÜ£ϸÙ7ù» Øòt5½ãUMWš\£&ï„Ê<€oµÎaý–®eÔì›ú½#Qlöûþ FgöLÙÂiL.8ç.×=`Ñ'‚–˜«3‘ÅAÚò´.Õ“VÛðo†ÚÿiWâ«Ï×Bm_õ{¾âuþZ»û×|­¿îkýª¿õ·¢þz4Áª,S€À!ñTŠfÓdþ¡³@ µ5×kª¯‘7™rPtï@•‘è¦Ó±(bµRVGàÖhIÉE™ªªú„þdEEoI:¯×*®çåžjh¸eÔååœí@8ZÍ›m.¿cD©¦Ýoä ­if¸¦æNÌf›Å}‚~CzïÆ1Ak‘£v±&]a±ëvgOÇw#ì\vP¼H¿%ìÿ;”¨þ·h¯ü5»õäÊßÒë~ì &ü=f­ 1›Ímm8GGÈÄÍÙ9´(Ñf­[\ T<îÌÂ;DJAÈfaD pëñ,µùÚšg#[[ï·z¨^’9B鉯÷!C˜™§ð1Ûå\hu/±+šñ}¿Ÿtxp@ð Zrk+©|47ÏÆ$‘2° _׸t7c‰T&ÏŸžÿ!žÀíØžgJ9ÿ­ñµ¯0n_¡«Ï¿‚æ$dLð5“ì¶À*‰ˆ†EL½Žõìú!\ ˆƒ‚„ë2±F\™©Äõ'z“¶·–8[p¶øï.¾¼iÇÞmYàop)JñžÒ·O‰SúëPKqýeR»e½ÓpZà4•NRœz Ú]$b8s’*a ®'Ð)]:"mÉEFB§ˆù2U)•ÅJãÿ¤Tÿ[X¶'SZè¢Óõ¿»òÿÏe*…6‘ª"Pâž™¦Œz m˜Ÿ6‡LèõcDâ™P¥¢ßï{Üî[=ŒÝ6Û¨¶˜'ݬe4Œ ÕY?©ÍÜ'©1vG÷Â&/T‹ÊÙûyv!{ìÅÍÑ !¡Ù#òÅ#†ìi]æ§f—A²#ãÿËSr¸Gk|ß7Yu™„”©Z!Jsœ¡ —j Úѽß €0oÆ“n¤‰®ááEä Aÿ£mùÏ…˜O$eŒÐœŸ$ýW…@É_„W½mËíþGÜ]^¨ûp¹æÅ_òAÜÛ,à#›¬[™‡¹Kü?+ÿ¿©ªëÏ/ÜþO×£]Ï"Ƕ#GðçfŒîñÆö#–À¼Åw×ä3º&u-S:¼º'õ‘%gëLÒ=ão™rúf|ñÅK'"ó¾9gÛ]sÛ‚3°ñ/ÄZgÚ<³®À·wÞã™km›oó ß÷‡&BÍã×”ß1é³µÙGÛ\“ÏtÈ9Þn¹í6Œëm³T½æq—ñŽÝ2áp-¸Ã¡ŽO;ìK-_ ÿÿ¸ W1{$”zëW? Üþê@Üò°ë'Ù÷»Hìß;— ä}±üîÙ0p~ǧÇãÏŽç'ÿøÄÿu%ú9ë¿Äÿ?]ü¯ÐüÂÄøÿHG*›_º‹{.”ŒsOkµ#32ª«®••ö¨”7€ê‹w×*úœª«¯VU\)6\\ÿo»·°¾¼ì’É8^S}µ¬ìWyY²öºÅ2¡PôýÃ$áÿ_J6ßÖ©ðmaáÇ€²@ï‡Îô£E…ç1ý^4‚Íþ÷æãe½f#yàÖÕ VUô`®ÖÜR*š-s±è¦Ju'@Êœ†q™<þcO€™Ivt¯æš-3Íö‡“X=ˆb¨BÖ>‡sÆV ùa 呈5¡»I·ûÍqS(´d1Oã€vû,Ð(Y´<¶š§mÔ¡º z` ”‡"O‹KG&Yæ Ï Xbf}2<ÂÊÈ“Æöÿ³Ñµ0»®;Q·ÄäIóy¶³y8Ÿ¿ÈÀ~ã륰l×N™ÂýYGÞEÂÏn(Á~xoóÿ’áב]þ¿ÏH:¯YÒ§¢×öÇ-®ûvÛ\(H±$'Qt@ô~Mý-+c,®,-¦âêÌ¢`÷–òP`”(Qžý%³’„¢9q ™“iQN75à¾+•dQÄŽ Sñ¦q`µzm†¤´lsNÇn·`Jkiµwêjêëq5•}, D!-©NÙf›4ÃÊÙÿw¬ú ¶À]Käž-´`õLéü –ŽÕ¶ÎuÿÑÍ`×F°sµý­ÍHWêıԉÎÍG×Ot>=\ìrÏ´¹lŽy­kÑä]òyãžùhp)Ù±z´k½«cý–έG6wlž8öüDtµË4ÖÒ2´O{M£Nã¨Ó>én™óµÌzSnó¼Ò¶ u£¯qX&ö·kÁ^&>íl^lýÂüAËùgLËi\ì̹•øIö­›ï´>ÜQœ½ïë««1y^à'Yÿ×ÿ+õÛ{1ÿÈãöcÏ$—Zš‚$ª²ü¢ ªk=rt=Ò~­Leú;bãÄ=‡ëÃWƒ·Uñ;6ÖE~+½ÿ´«k#zdÅRŠÍZ?~3:¥ïXn5ÿ?ÿÔþÎ+xƒãw®<çsDDðâ^_ÿ;w½ôs¯výÆ™ÐOÿk?+ÿÿ!P²è ¬0Ÿy“1Ìd„¹~*,LzÄÊL~~¢ ®ÿ‰’¿¬–·x9Öù˜~ý›ÇK±å/v)_õ½“ùðPò£¼ÄG¹±S‡’gß½0q&7~:7vú+]NlöFüý«ŽöN3*$‰L•P¾öG”c ¯±àÉš,N"²Ä|¯9 èümœóÄ‚¾4Ä•ÀüDr=õ´>p8h,ÀBf[îûbljŸ<"ä,ï,e#á áqìtÈ=§‹+)Z³Yg±¯D¢àŸ…Öo c”á´^ü–È[Šdš€ô‚‰$S^²˜W;ÖËÌŸ˜\Ê©N™á/Wg‹Eæ)e3|²Ë·…N{<¤•#3S‘—žnx¡—°“eX\úÜϘÿ#³É4VŵÛHêIOÉ #°¤ÓÝÑsñµÀ½À<ØÒdœ¬SÈ#©“Çh®Œî´nj¼ãó­ÈÁQqÑ'‘躬Õ`SZr$–#2*¹ØÔt (‰s21@Ð]Š Ï+ý´¦¸»¶ªƒ»ß¿".¦ :ã§0¶â AÖ²^“‰Àˆ&êëoâ‡pXª×exás„'E­ &ÓþryE¯@FÃp BN<, ÊA\Ä&vç¼Á0 ‰ ¸`†+ƒflÒOZehGtdÃ4Îñì|$²iwÌãR˜YŠý È´p¿+JAqò9MÚa„N8m\[á© €ŠÓÆi`¯Ê òÿ"¿Œª+bš€À›u:Á¸ŽœH–Šz!l†èö9üS·wÎëšîÔÕÝÀOÔ18æÄ9ÇØ‹ rd®ÄXU•ä³4·eLèj!›`¦Êl‘yö¥pƒ«àé~Éà?;†eü¿þ¿‰õ:uQé'{”ÿOÄ7³1ç®X@Xg³õ™ŠÞĶXŠv‹‹}6³Tn¶LbïqѰáO”¬¡‹¹?aÚ(Š­Ðµr×!9³ Y†VCáÕhŒ€=…ë¥ùMJ€ãòFX¿ªò2î ždYèn cñrV3а°Xœ#šÍP ¢6ý(nG~Þƒ~Ì€ÆGC'ïà"Ô%ÈÍ¡à𹚪>³q·±ñ6–Ö,à Åó…âVÖÖ^eu„–·_£åWV]Axb2Ó3…pAMiIw¿Q³‘\AÞGÀð…‡?Fti2Žãø~–P–o₼Cg5}9¹ ÝÖÕÝ,-íÎÏÿ(/ï€=®‰Ê*û…÷68\pNS?t¸àã@ ¿çŸ‘yè ?!»shêo¾ù>ðyy/žnË:Òv8_Q~ 7Î[²óÙ"«ëH_w![X#‘.É‘%’ä² ¬ŽÔCîÐÿÏè^Ï/ÜþOÇ“±ÍH'žžµÑ¸ç .ºBK®ÐrK`Ùí]t¸çmîùfï‚ÿèöÝs9çü­‹~ïr GèqĵÐbšÒÙî5êæ*õwæy½eÎi›ö´-†:Ö’ÇRÉÎí·:R]©£ñŽØz²óù±ÈzÌ2m±Ï³—øŒÁ6«·Ï] Fç¼Þ~Wk^¨¶-ª½lö9 z/Ë”ÕqבØî8ò£.ç’÷óõ~“5|„VÏ/Ÿ 6-vþóîȯ¼úݳẻ±í·ðþ—ßÃ_>þ»i1Ï—î+Q}>$ªÏ·¯g¦ví›7œü?/GíñJ½ux4ùùëÿºáÿÐp]dB§vü}¼ohýïë¿„7€îÁ[*¥á¿P™þËð¨&4Ò ãÿä²[eþ»xoý×_ï|쯩ÿ/fò±YÇJ[õïñÇ¿a>ñOZþÞàø¼~ºùÿÏ Ú7ŽýÖ™ðOÿß~™þçól"<Ð4¨©Ú Cx€¢#ÅÀ‡J§n÷=bÂê!}+¾¶‡*ÏÀ^ðÿ¿Óþ]G3915ÓÀ}d«ë¾Ñ0©m¸å ƒÈ)=O=Su—ÐÊIrì"ìЩð¨»YPðqmõõ²Â‹Nç= @äZ|@yÙåòÒ^­úVMõµ:Å €«FÍ0¥@˯àç×ËËzÊÔƒå—ÔÊšú[……ŸTV^ÖjÈ™ë1Ç-5 wÊJ/YŒSmÞEÐõ˜ŒS“꺛X Ǿ•åWªªúª«®âà^ïü8|4éÇÑÏÇÒD,´¿™Fû™j ™Õ/³¾wò|d`¿%“s²Ñ‚ 쳕šdCÏ ~·?;íŸt ù°r Ão1X˜WðñϲþW8¼Zmm]’ð ’"/´liYohŽÀ9çbóÜa}%³¡„8yN!v#³ã…]6y$²Ý!]:â¥Êâ ‚³DnÜ)`o¦=¬#jŽÅ6„`H,¾å÷øÝ( dÕAÔK$ùLr¯f;iŒûÜÂ%7^6 X‰²ãûPAÎl™f‡,¢4ˆðœ9üRè*´€(b ¯‹2v„ ø bìÆîä¬A¶O9hÑ«DFÖƒU9¦õüoÄs×ÒBU¨»êŽê’Äa"O°=ÑoÒ—.À¬ |EJ$.*èCiMª[á öŽààRÎ?<–j–ÉŸú>_Õu†@›™'(²á–+wÒâÀ¸Ñ8Rþ]×0ÿ9Œ%ýÏlÿ_Õ@AÑÅ=ãÿl½¨Š&_U™:šXdº=æä´hœÀ±’¯âô„ä6b›C·Ìþ¼ÛظÕMf+Mq&’¨P(Õ’V𬪎¤Yž´E¿ëigcwìH·˜w!7ó¤èð±ºúšŒw™eïËÖÕ­­÷±~—ðÒ’GQvÖsH¡—º#úÅuÁí„Ìòbë‚—òÛ©vÿ#Y&TèÐ vsV±×–`ÉÚq•8-Q+­³TÜûmqæ<Åþ_¢cÜJ» ±;œdV pŒÚí‚(ïÕèœêYc:µ:§k!¡2 ‘‰á¡øÇ¡‚¡§Ð“Pø)†Qæ;­37é1õH²n%câ™4$<È­¥£?Gù¡56SmëÓFªN—{ µçë=·r”è.|=pô×c­¿ìw|-Ôö›‘ö¯<¿ÞÞúϺ’¿ þ¯ﯶµˆ×ßïLü~W"ÇzªªªƒµÑ4Ñ R«nèµ#Å…Ÿèt£FÃhaá9£iC‹„Ü4›Çål¶˜/ }<÷=«mª™{'¼·[ftM£Ñ¨é…¦}Ë’Ñ0AN—ž%Rl ½Çi»c¡…ì5oc¨¥Îý\ìÍwËË{ íþga=¶sµÎ±ß8 ¬êucöfrS5›¦!¿…Jˆ@ÒWƒlb¼Æø ¼Á‘ã±Ô 5¼Bíp+ñ“bXóËt æKKs¾´žV ç !鳕Mé§ÍDjh'Ô§P(ù$Ÿ'eµÆdÚ¯!³±ÐxILlg;ílH¬ÿ¯ì?”wvïðÿK=nþg{\ª1èÆÞ úqáÞ‹ËÞÀ.QÕÕ}öô“n÷²¯mÃǽðÓË‚<‹.÷¢ýE©)iõXfppvä¹ÕÜhдªê Úg1™Ê­‹•¸Y¹¹§(óÏ8³¬¬íM­¨(ï­®¾ÒLÖá´™V3Œ%±hýú=ÙURñ¶¬'C êKçð à'D#BÄfÓ9ž×\3™'Uu7”ioÓ`Ä\S{ó¬¶i˜~B{§^=ؤ%ecðQ’Å6N’ýͯDx†·ž ê5ê!v»Þ ¾ÉÆ”sjåµ¢èÏR˜  ·Ð4õCj:æа€a²#¥ÓÞ)+¾h Ô؃âZÃOuàÈÕ•WÕ}h„âï`³Æú!²¸²L·yÉGÛÝr<ÀÓijdCàhž3èGõ†1àjö¶YÓ6ë4° ™íºúÑPð)žS @+› 9F²“<0K)N±Ì;›ëõë ÞðãÑ|–i­-ÞãŠáÙ V›šFáPdfjœG„°Ï¶Õ:-JÔ™«È„ó$ ê˜,ô‘I7ùë‰ü×l™Øʇ š‚¼Iõ5}J*šÔF?Í5Yc†Ïþ. SÖiž_Ї„4¢†Ft‰ÕÖ\3ÆEdA¶SÆq€ÉFͧ“¦2³ËW>ùé}gçE{Îàÿĺ¢öjNÞ™½¯ÿ•Í%=«l2žÈˆ ¹º_d°å‰<‘6ƈb›hš®†%Ý•Q.ZÕ¢«ÇÇ´Øf€­å„e˜øul4›HÏ zÉí‹JY‰çÃÊ·‚bð ‹p€üåxr+ý„>НMMwpLw¹9-e`bªø-Üh<2iÉØ8‘\¯S  % uØgiÊ ™b#u ñclo6Oà?¢=W”_B R uuT¿ kA/¤¬¹†«`L",B…˜<¶GƒøE]?ˆÅäXdšŒ'ëÿÜAס¨"l<Šê«û^}Ï>–¼§ôÜ’q2û÷½à!¯€ù?hЏ/¬Ö{¸à\£ö6N’¼ª5Ãuu¯¿ötõííØÛe'VUÕ‹è͵´¨»Q3TVz¡¢ô¢y œ«(ëAŸ¦RôW”^Ò¨o!ÞGPQÜÓl›Å<˜s ‘/.HZIì%ø_¼&“þ¯U\=ð¹]ôçÿÐ4Z'–øfÂ:m3M˜m3Í®…í°Î2EœD¬a¡Å>çâhž%›¬ÇƬÓàGÌäœw‰Åq—¾Š¬E¹wD×ãÛXÂO#øˆ_Á+÷b«eŠ‚­Öûü(väƒÛÍ“f¼¶Ük±ÍØ´ÃZ|<òìÈÑE'÷ïŽÿ›ÇþEOôg¿ï_Ïü¿àüìÎÿ7§óÿžÿ!;ÿÿYøßög¸ÿ§7S™ÿ.¢ cço)(Êp¼óJ6þÏÞë§ŽÿEð9ßþTõ^4N}.ÔB¼¾ØFã¤Phq1e¢}Åé\ZãzŒ›QÚÈ%Ý”™á‚,*$—Ér4¸êpÌcDBkä d™qþɲ˽Ž0ú¥<ž‡íJ\®{”´l¤ÕŽàÈx˜)^h]"|Ç<¢wËR8-W$©„fÓ´ ¡1‘¦7e2'ðŠ.ãÅ¡Cí*Ða{§y}xUÅezUª~.{¼Ü¤<–¥….¸÷;´%iôÌW’jz†´³‘EÔÙHK5fÈ<2™_6­®¹h]öah®ùª>ÚF¼º[!å%w}Ÿ§üT ׳ðݰûž¯ê\À<ä-ú^ØÐï*9°øÊOÊOûê¯øuCí5…,·}Åï†m#ÁÚou·¯æ¼Ïp+b™ôWŸóWœ ™†Ú«Ît—âñõxbËïš Vh†‚åDìÃþâ÷"†~ÖHLùmƒÒïûuý!Åù6퀿êày$¤½î){?`¼æ/ý~Ä5þYøo0þ8ðáçÿŸíTþ‘;Škb€"ÁГ®3Q_ÖZÉÆôiŒ…mÑŊ׳ìoH\—xZ×Hƒšt‚q“mÂ!²~lgàj1áfñâ!ˆù—Ä–°cà‰˜-6ÉÂ6«É¸Ä7dfaA…FÎoR¤Èב’$hŽ<Çf¤¦â‘Y+›ldF±m0²xSËdz¨æjY1„Ã90×hp=^wºÕª›–î±-;j­pPüÏ2ž BY%E”ÐÓ…öˆÊ)<Úo¶Í»ÝË&ã>b§“ä’ÚÚVpœV÷²½™¾u:ï¡¡ K)Qi’dê¸xb’7Í^ ¦MH:g"Z_1 }UØÑ&$ i¡h‚©ìÐá¦ë†Û¢[ 9ƒã¡³Ú柗½•í¢®nû¨2hUTH5AtJ[NǂģK[8íó"+žE`Ëö/£7ÄÂbþ"¾¦PôåæžÙKþO6‰nG,€Ó¦9G+i‚±ßx³u–„ô"m%|ÂL’3Eô$ÃµÞÆ\/ì‹ ç‰äg{e‘Žó·?ò²}3¶Ç¹q-›xÆ&;²ñÿ³´ÿïnþ?áÿì‰þ?rÀu`urÀr{4I@q’/ZhæÇ%‘7š[±xh• =€½ˆ°#À¼ïñ†±½Øž_IÆë}Ûq4ì‚+Å6üC´ ¢€|ÿ] .Ïèi{ІÆòÓÂÿ_.?Cþ¿:2®ÝÉÿÿÑ)C`P!øÿ¡‘†lþÿKñh¸®õÜ—âðø«›ÿk $—Zdü¿k¯½Àÿå·_°þ·óÅüÿ³˜ÛÏÉ8Ð6n»â\È2 o´{—#ê^là©ø0Pðÿµ©{}yo‡ìSþœ?õÕt‡T—bÑMoÝ…hp¥­øû‘–©@Ñ÷‚%ïê/Æ[¦Bßèoù”bøÅÇmgýúÁöÚó1ëh¨úƒHÅ;aëˆ}0XüçÉðSL]³IÛh¤ü`éɘk*ÖÜ)þAãØxäq¬áb{å™PÞŸ¶kûý‡N„ÝsMŸ¯ìdÜ=Õž*/&_¢ÿ/ *j¯ÈýÙäÿwóÿŽy“~¬Ù:£Tö»ì õQ7f2Œ«ýäÕJnsw*xà÷•µfÚ~xß¾w´Zš½**>öC“eºa\FµêúFzë†êë‡ ,â;î!qäOÚ5C¸é ˆMªW­!‰6Œ%%Ýlæ+yC]7j©ÃÏ9ð!Z¾ÐüÄЀÅ B“Æx3G;|cßIÜ ŠòÞ’’‹UøwŸàÜÂ,R”wð”ÍFB=¥œÇ =xð4οªº¯ª²W¸i(UýøuÄ€DÒÜBû/!y(‚娋ä†Ì“o¼ñ¾èÕiê­ºlîõ£ø›8+g¢=§ÍˤÁÊ]“xRÐÒê‰qwÕ Gô„shu/ 1jÄD¢N‡˜B¶òõ¶’æžÊzš ê© 1ì6šnÃÐf1OÙ›ï’ø’æ6BD8‚Õ:ÓâºÇ)} aÐhýþG¸òVËT}ÍSˆ§NI¾íþ©–Y-Ó š…_¥_DøZëø ýÿ]ü´ç9ìþϱ#Ï:ñaq/R6^¤ñ˜Ç{Àò–{næ ÄoÇø [âCh5,À¼ä•X(œsˆ©lïåòÀcrÇ{l¨Á2e3Ž›Mf*X¤Ý)Öàä¿Ã6ƒPÂÂFë6tº¾‡8ŽY×§]Öië—øÿ?$ýÃßö^*è|â'ýŸû.¡ÿSgý¯ü7ª»6¢¬ÿS. ~?ÿë"¿B ?©B‰]›aqžüVÇCodRÀïé>(ãÿ]{ýñÿïž Ëfp{Ÿÿ†Þ¦#ù,K¶]zC=sÛC·k¯$)ì}(”·.¢£ÃJrHL“Õ“ =a„¬N)/‡N (§&(§ÔÚº$„ú릅«)íiéKÊjך›ïº[¨/À1±»àÆc,&Ó8Ö“ï°cÁb™Áz®Ê\j<ç †º>Ÿ¶Û‡,£~ÕGÇx@#zÕ] ê/·ÿEÀr'PûATßÑ\éqØ«!õ¹hø 9ŽyƒÊsQ×X¤á|È<Ð^‹4öJ.Àѵ¨m(¤¿m éú#ÍCaûdÔ>2 E|ËÁ†žPóòÿÏeìT[{ý@ÎÏ ÿ/M°„Ës!9Nð n°QsKQÓ×@b˜}À™ÍÍ3•—¨‡J‹{ðsÞü€¨&Ú{3IÙÔ©HDÃŒ®q¸ªò²¾iDQs•A›ÀÆ„“µ#¸}”…ò¡žÔkÇuÚ;JÅu;Ö(®Y¸L²¨è¡¦ˆÓPKÿ&ЈA?j6N47ÏÖ(è°Zí.fŸ`Ó’ˆúCñ$¢[­ÓhóØF<}<öÐÝzŸÂUÞExŒzÛ–=Þ%1c=Ú?~Wd…,<ɼÇÑÞ„gÖS&ŽÄ I”a–÷n.Ú}<\uºîáÙJAàà¥NàöYb\€g.¬& c–OœNsðˆe‹ƒsÃ{'ÚŒ,¨ÒÚJž­· ÆQÜ ù(W}rÄ$þH²ƒêUqZ¨87ån¥´°×³Œ£ñc5…3ô³þ º À6«mZÇ"Šfó4q„t#¡0Í#X¬Dä@ÀB%Þö9éÉo¡ßÌCˆSb¡Q7æ:‘©t¥ª¬ù/,€ÓÂû¬ÿÙ!åÿ¯æ:»—üŸ S̨ÊåÀ²¯ÇÁ.QšØæ9ÄM™´#=ÏÈv¥-ü6ÂÓš&cçÁ§è…Ðóð ׺Àÿ"F“•¯¸äö±  iý mOW¿Ž-ªÚ…|½l -ð?î#žö(OùüÐ33!mš0QÝ–-Öi~¤…,×ï‰ e’®¢ÃR=.¾¨SÆMdêÚ"Ú•É8gJHH¡-qñÚÕ’'R€Ð&Ãg„g™ËË.6’˨†Ð8•¢ã¡ÆG2Û5Œá·€ÒÛiZ*%N2=>ÒÌvQ*ú«Øx ' ¬¥“ââ Tm1¶YQÖSxøšΓ~›‰D„N€l‘©ÕÝF Ô5Ö©r| V è˜yXSuAq1Y0‰º0lP./÷tUE/BªÊ©ºR¯$û0õM•âú¾?y'xŒ;˜ð žÄ#yáú£©çŸÃƒÐÄ>λ¼QÒøÿ‡‚ÿ< ñœÚ üßùü¨œØw/¶ n5p> s t1)€÷¤öCm‚ÔþÈE¼¬!ñ6æ’á ð?Bx|± ýöã°b®¿bž´´Þo¥ ¼YœƒUDheñÍø—øÿKÿߟ½ÿï‹¿n¾3ùüø7ØÐaoñÿKj6ÓÓItã[€Í&ãd(¸ÆÞF4ÑÙÎâ$ëuð°[Q˜€CŒzBsiÕ!l²l _m÷=‘ÂÙŠÜu[q4acD<ð4Zgÿ—M1¦l´{Ÿ¦G1ZÜ÷D®Ó±àk[z÷± 09uØZÙ3%‹ÿ³éi]F_½ÿµwÙØ‹2`¥Å^ý]tªÕU}8‡¼ƒg^ýÎwÑ9ã}UÕ•}¯¿››{ ÀcǾ}ïRrµ¼÷Õ?þ.ºz ·7÷¿÷Æþ÷T¤”¾‘èìþ}'qðPð)ÞØ²¸¨{ßkïbK »¿yàýoœ,.Ú+üÏõ¿Y²3ÙøŸ%h ÕpÝ+`m”UO/©N¼q˜õ®ñiaœÇ$?+$^—ΡoZFƒ5¸È.&j ê ~B«¹-®3RSã0ú±êjDµSˆ=ñÈàW$ ŸD =8$˜ƒ6†`ŠÒA¶¹FÍ0¢Ë´„¦Ðÿ|†ŸÀi·±GUKË=ÀíD¥ãC8|™ÍãÄd >F0Ë‘ï²ÜЬµ >’LÅáÓKd9›Ä¹äUƒ$©YkHÐDìCë;Ò^‡²ï!« eoŸ–KÍÈì‹®-!)ieäÐ2ÃÑõó|%*-\@'½Á¦P9]¶!Š/b,åʹ5i_ª× Š‘ý7ù %;Rx꣑u1%aÎO€ÍÅÄÎÄÇjB¼ñö‹ßLý¯Œÿ•}9÷ˆÿß™fõtÿŠ ßrÏíZp³BKÛŸw¹MÌð\½[Dˆ)êà±`%6à2§x}3Sz¬ÆqJõ3¼÷àç° …ùìèYòŠ©ôšäü°àrÜu ÈÆÿxÿ%þÿÿÿ{Áÿû‡_á´¿0’hß8¶÷ùÿíâŸÙ]Ä3tà@³ÍPUÅe:Vö74ÜÔë)Ÿ aÔ:ìw‹‹»KK.¢ÃÁ@c6O’¿ ×ÖaÅ<]_³´´GQ}]LÑj4·ÑM‰À²’ k–5ö–+j®in©T7Ø{wžØ>UWD±PPCà ]ª®è¬¡Â‚ójÕ Ð8ÙSWKËz€Õ³ù?K‚«,¿3GN‹¾G¶æ™VÏýf²g¢Œ"ºÊf–§Ã`<ÃéÐ m¬ósàŠÈ‚Îy“‘¦w=­Kø¿^Ï’¯ øyË…ñ—·Äù×*ú逮üwlO>/uƒ÷²Ù4i³Î¹±S ¬ÈðèØ©‚ZäZ§´°#Žç]’÷a‘tòþÒT½~ÅÇAÝy¿n¸]uÞï˜ ‡ú[~Å>çLXÕã-?²OùªNúíãÁÊOBWÚêϪOgƒÚC_@Ý®ûôê3炯â½hËLÀ2Üá^ôÖõø*>Û†%x5×BæÛ¾’w½u—°K’u„²½¡ÓU‡™Ä£œ|Yþ_"Õ*¯åäÞSþÏgI¡Õ¡‘4¸Çh=gø±R„Ñ8IsI”èXEQuU¯UÕ^¯­¾f³Ì2Ù~+cÀ$M+lï\Ò¸=É3ܼˆ¢tdÓHžg6ÞI,éHûÌJȳó™ K£ é´ÃùguMÀlczÝÂÃæ™Lã…‡ÏÕ)¯u#MBB¿â †4´d“iÏWMM_Eù¥&ݰÙ4a4ŒéȨkXK¢1€ÿýwgûË~¾1~pD)ŠLiL6û%ùPYG”Òõì:w¹’}BSÓHYqJ5˜ûæ)tˆs˹òZ¡¸^Qq¹A5¨7Œ‘6ì¤`I³ õ7‹‹>É?xº¢¢·ª¢·®îFIq· [ ;:xðtjHU"w¤Ò2’2ªOÉ - û¥Ò<ó Lï̾üŸu#v¾GxÂþ¿‰øºBy-ïð¹½Äÿ»ýåWá! ùÚZÒ™g}fîr-Óee«*¯4iïž7›ÆóóÏJuâÎ…²ÒK•½¢PW—±²²÷PþEõUá€xRòòÎPqrÛl™B*®U}ýPUååüCçpOÑQœã™”pDFÕ²vªæö¶=(.þ¤©i¸¶ö ÝÜÄ)‰ W€üï2‚¯8ÿ¼ÜS*U?NIÛxƒHMõÕýûßQ«Và„‹Š>AkǛܜñmŒÅoåYÉÐ\V¿ ¥Ðt×”%Œ)™Ã¿{‰Ë±aF8t—òtÝ$!eš4èÇðj2Œ»ÙCP§5'I Ãbaw“vAM;u › ù[ÉDZk4±•–_–’0Üü¶Ò³6[²êr–«£T”KÇöNKe–bëH%³Z¸ô dÅ//˜3þOÄ7$ü_{-'wòÿ], {ôè»Â™CÊgˆ˜çÓJvˆÎÝi~N3£wJ݇ŸF /vÄfÇ!ßÃv± ¶ñ.ûpD¾‡~¬ô¯â›Àÿ™Y„ã·?ò#Cx„1® о˜ÕÀë±ûÿ‰ÿÿ=âÿø³ã‡î$ùdðàpk©·öÿaþ¶Tû®ú_2Ïr.¨•Ä:æüe1šOÐ F"íí047Ï ¢éð…~]4+ÿ, ÓRä@Y$µOá£Í6ƒ½ÞèÿÙÌ}]w—ľøèõ>d+ÞI®U\ ‰Û4W¥Mño-²¬ô}æM)Ù².Ìy9s+Q’XÛmĨŸhjº1§´ÚQXãì†026N¢ÔÖ\'ýOë,~Z$¯´š‘€ÿ‰N?J,Íæ» ·m–9MÃmmã“q’¤„ÌÓ3zݘÃ>_RÔ­¬ÐjG°?¡Y­¾‰(¦¶vÇo)j®cKÁ¨Ÿô´>ÅðQZ܃ÅjšÆO‹rcšˆ§ÒŠåë‘ÐZ{ÎÛ!Åéöò÷Æ!_Ùû>Í ¯îVPs5¤½¬>í5ßåýi[NWÐ8(û^À3çÏÿ³hÙ»×dÜx'T}2bŒXúý¥$ü«þÆK!ÇDHÕã/þ~´}1xè-ú~Ìx+tø{1÷d°è/<N$Âk>åÇíÚ«‘¦n+²ƒE`%®ðNKâ]øG[RÖöÜ›bÉ]üÿ]à æÇH‘OG”i¡=‚Á ¡›6)©Î$œÛf1Òõcb@gü¿™IÔ'S‚\$W¦ã†ˆ¤CñLÂÿb.€çÑÒSG²"…ÝAD2%¯ÌæèF£ë^Ïr ´ê$AªÕ`±$ÑðZÝKX/| ÐNZZî ±,€€=bI¿ÿœVÏ2€– Æb õS1þCD²4+ǰ_dûåB)ÏŸFû’˜×!2ÁCRÄb›z¥%HK0¸*OȆ$dž(B_Á>÷jEŸÐØ8Œë៟ôi‹y²gÛºÄLyAËpÂj4'§…çVÊó2’­H’˯ ‡ÒwMÞRÊ?§óºbVk‡Û…Äù‘•ÿ‰ÿ³-”Røh’þ<¾V«¸öù~©_œÏFüŸÍ—%ÿ3*4d‚x’ÅÿÙ’)@Ù2¿rÈ {8&åk"‡<ñ4$æG˜ÊáúÆâ›²±g•7qëcTÐ*Íø„#k$/É­mLXM¡IL\ð13m6…vP6!דZit÷ðmÑ(i;¸ï‘“~¯Xc2Oº[iJ¢eÁ@ª v‰2N÷b¶Ð½ŒØå©œDÂÏ ý¬™yØ=–e-±ëÉ]ÓâÛç]eí@jø_­ºÁ‚]W…‘=g¥Î)júŠŸ¯Sö“‹}ÓH\€ž^$[·ômÔ¬{Oˆˆ¦ó*‰DÆÿ]öY²i³ ìéÜ2ÑMúRÄÒ^0"œÏæFfw’rþ_òÿª½–—{zòÿøßdô±}h\NÚsæßÍK‹ÌÕñ.·‰7¢V7ø$´ÏÅ¿6®¶á ª?p>°0?°=P=Ö R+£ë11M ¢ìŽ‚ç ˆwä]ö¶?j­†XÚŠÿŠqB€/ñÿÏóRÑøŸýüƒÿŠÆÿü‹áÿHê­ã?>~\¬©`Ø=©ÿÝÿŸ½ÌüKZƒ®>\‹E©–6x­Ç£)Àþ(‹@RM+°ºç!­I½FØÄ–ø'’xÎ:k Î1}”ÚØÑãy >e‘ûä®ËþP`•Õï·ÒW[»,®Ò2øÒJ9Í(SêȶŠ;ðÆûÔ'W÷½öê÷å.)îþ£ù¯åQÖ’9cYéE•²¿¶æZÎÞܲ¨èüûO–w«ëKKºóž±XfðšŸ{¦¬¬§A=´ïõwkªûœËÍùP×t§¢¢7çÍöï{“B@û—x¿¤¤»´¤çßx»²òJuuß·¿ýùW”÷Êûhßkï*ª¯óØÿ¾Í2sðà™¼ƒ:ûúŸ|íc[´È^ü#šªS!åûþ† c¯úlÈ4䝸^ î£`õÚ›zBõgÚ‹óÍPÕ;ÛXÄp5¬x7♎Ùï„Î9_×TœŽ‡Vüæ«Áš÷£î)Å÷#ŽñPDõ;ñðãPÕ÷(LО©N&ck!c_Ð6n8—Œ®e÷ìv“×¼ûeý‰>AÚïù§öÿË¥ë/ºÈ•ÈÙ!±ÃãìsžŸ&³àÓ ©~Îa ”˜ùÅ ª'a ‘[ëØ–Ñþ x ­ÏGÚ1‰päe§-§¯%*Á“I¦væ?·¨.UB’é'=/ü&ÍOH Ó+‘óßEÑo\Êüg©¤äºò]FøŒö)°ŸhB‚Zßñ´îÖÖ<ãm{ ,THߦí¡ÍʹÒÈZ¶ÛgͦI;K¹2}tÙÉV}ø µú¦É4i2NZl8ÂCN͘•cÎã]Öjï`ƒa\P[IžŽY4œ  ެ‘ñeˆÌ!ÌRÚŠ§#,éÛ$Í¢J›e9víjÙ~¾é›žEÜð¦û¢í½w-/MÈÈFÀ2þW*¯}~=û¿Ký¯Ðöé|ÞxŸ&áx¸XðÜXÐà¸]è|Š¢]@}àyö å¼Çf"|h½ï±LYMf¼ÁGQAà{ØŽpCL ˆíE(á^l¤ ë´Õ8nÔÇÉâïñ}ó—øÿç|ɵåçÿç8~å‹áÿo]‹u|z\~àÌŽb¥ãq–=Âÿüÿ’.¿]¬¨¸TZÚ½ª*z5 CŅݵŠk êÁüCgÔuÅ…«”€Ä=MMÃÍRq­Ý·¢ÑÜÎÏ;[W7 ÑÜ*+»X|˜D×¶µš[‡ò?ÂÀ¡Vß8|øœpi/-¹¨©ª®¸"‹F3*š23!­Ý÷R¸"c‰Œ­È¢s~òI ´ÚFú¥«:Ý/gD’ `«ÓUbµ?ôx—|¾Á “[%Z~r+@ÔÐ|âó¯´û‡ÂdáŠ8Áó Ðîɉ \ ˆ›Ä ¨ý´×J@@¦ˆTéà'åð¡0Ù̲ñÝÚaœJ±OÇD˜C¤Ð¨ Šs @\8‚1É™²Lé” ](IL/žŠe6!%·ªL$6ùºm1àçÜé‘T¶vœ z³8 »ñÒÎ-3yTàÿ=*–ü¬ü¿ü1ÄéJ—ëžH«¸_>ï£Hh­0ùbO¥-€|4%$© …]ƒ­³d³Ùôû“ÓnÛ£`à)¹0\CèÁsÜDö éiÂeg»ÝÑùL¦¢¥'§v7Ñìvò²ny‡ÄŸ¨ÌÊàÿÚëóÎî‘þ?F$DÀÿBÌ_ðy„æàvAã_!.àZ]ŠB«‘ðÓ~ÃàŒä!ÄÅv¡)ÄúŸ4 bQ5Œ•b^GÃâ{è > R‘ÜZ$¶ëÅOøy§sÞù%þÿ¹]~ÿ­²Ÿüÿûo•áúß_û ô#þcbåk7âÿ¶—è‹êÿ¿„¶‘@‡f¿‹nßç{˜j·Ì <©eù´´,àÕbžr’œÈÝ÷=³qÀØfž ‡Öwñ¦©q¸…5ÃÍfâí0~ÓGdZÔÜ‹ÿáþСs{§ÿÓÑñ¢Ç4ÌÕ‘fæ¤ ),8×LÖœ#å—Ô7ÍÆ ÜOë2—´gn§øG¸/zý¨X¨ìk'å}¤oÞÀ -*ú@ Û±ÁáÁTt$¾1 0ÓÐpÛJÖW·heÓ“q\(åjêo•u£q6àJ$à˜¸P8”¬—Hš3ÌOˆ¥ ; ΧâV*™]gáÿ¬ zCnW"ˆdµŸl— ¹¥±ýSñL³}ðJ!6À"ÖKG‹°˜-Índ^l옳KãÿÝiÖ’Ü™}aRæYšžý,™‰L_2kóB.ô™<”½Mö,àHËB â=éÞGV;â„ÿÉÿ·°{oâÙÛÉŒ3ûóù?¸n¸àÙa”0Þʈe*¶9Õð0™UÖš=÷!.`"`…Öå®D´Øfg¸$ð·DÛãz”(wåø‹dó…G@4¶çŠìŽ´õ-I⺇B«Â_Œ²4¡'"’ÅVË'-8?bá¶G‡Ec bÁÉz’Ó2OBa´=šAˆF×]$Tõ D®[‹¤¢zì`í)°ŠÚa¯ï!Íh8î¶zîóŽñ‘µ¨(”Ħœ,l%¦·ˆŒî¼+‘ :ž«”7j×(˜ª¼’sàÃÃÌ=µß{û÷Ÿl÷­u¿±ÿ½}ûß-kïyEñö+µoÿaY×kº|³îÏ¿©ú³oTÿé7Uÿú_”{Eùö×ËŽ¹.8—è\ÞÁ³¹9§ðš—ûѾ×NV–].,8nçàÁ3™G#]‰ ú„DV¼ •TÄ3Å ÖSzLìÔFËÎdü¿Žl)U×òò÷$ÿìGÇ<ëdüÔ÷°]üÊJ>üÆqËõ¸ÙÙ™^¨z`>ð8ˆm°cðI(º#P*a¨@€ÀúŸ!1YÀ²UQ„ ø!DúQ#BD7D¤`3˜'Í¢ò×:m^h¡GxÔµàúÿÿùüøož ýôñ?ƒÿ—éÿïÈ`@áÜøªFá.…–Dfá1:¾MœÆ˜,Ä!LyRíþÇ\ÇÊKŒÅgHÙf+å 6^ â¦b¼†¨Á§õ%¶•HsøcüQ!Ûj§4캔6Œoù}+íí²!°n6`hu/½ò/ß.)>_Rt¾ ÿLII·­y :íZÅÕ‚’È~ýõwüòòN;óßþö¿©ª Åêêk½E…ç¾ùaNÎdüZÞð¯PP9ó믿“—wª¢òÒŸüÉ÷þX£¹#Ì=ý÷ÚëþÖñò_è*ù›ÇJåkÄy}‰þBqñ…ÜÜS¯¾ú½ªª+8üü3…‡Ï%$ž†„Ò#¬²‚`ÊÕ²mx½pS„dÂ…C1Û‡¨“Š1ƒ‚½!°Á¾eŽD^—¢~¿én]²:é¾0Šp{ðp¹Â“|>‚3Œq°…®ÅȲ •eÊí&;©Tý‡ Îþlø?YÙ­ ‹†XûúvÿŠÛs_C6I4Zê‡ÙÛ”6 *9¡lIM=¶åvßÇðÓÊú“Ø—€Jà —œ< Ÿ¸‰¾N1ä‹ç¦0VÀ3ÒâæÉã]®¬¸‚8—Æ}_;îÝv£¦ª!ªÙBVVäšäg×-»cÞç”È€.&ÿd?4“Lfˆ€Á"þ’ Mxmð ÚàaSÈðÆÙ?+ÎT„DZ«„0Þ ¯¢Ø†˜]бþx„eF„D‰°9KsÖ$:3ý"°ŸÉ?¤Ùˆ¥É?"V•¦ ¸p8]\@J/¡°¥rP Y&m²{ÚVTœ)Ä<ù•<éŸvÈÅ© ;‚Û‰´ÔˆÈÿ‹7,õ³•HË`¦iÕi=¨ôLJGr+}ÀݹV¡ò” ýÿÕŽÄåÿUý‡‹»÷Øÿ÷Ùgðÿi®ª¶¶M=O ‘Ïo¨”uÊr—¨íÇECxÒØ0DB †ñõ \ÊÏl†/qÈ;8TÙ5Ñò ‹üQÖ •ùW‚v%½ßIÍÊünGºª¥ó9š½§u©Ù:‹+*/#·;æÔõ7Ý\ª#ç ì‚ÇÓd$ mãKF/‘Ç™aaµÞ0ŠK„¯,æilƒîO(Âp³™äõº1‘hÒhHâÕÆZ£B«täœ÷Ììtf±LÛ,34 ç\0êG9XÄÑ\Ì•Bo`³Î4iG˜¼$1íqaMæI³ª²×h 3ߒ⋊ª«´¦ª=y¥òÊr¢ð¯\Zü‹¥¥Ý……ç_{íâÂOÊJ."êÏË;ƒ–•öÔÖ^ÆÖ™éÚL1ò³L…r<•”ëAÒˆ)ãÿìäÌ‹ü¹ íÿ»ÅÍs{ÿã› ÉÎ&·NÛ˜«Ó,¼€‡GvìBh 6Àzﲨ^¤÷±£ðÄGQH/Ê~Eò_ˆüˆü?%ôÿ±=„lnâé»~T¯ÑY¦,ÿ?{ïÜV–ž‰i7Þ]ov½©²×Ù*?kì‰ã-»d«¼q¥vì¸üX{'=nwZEŠ @ ˆññ¼¸¸xQ”ÔÝqìxbÏLO÷¨¥VK¢(R)>EŠñ)>EФHJ$%ªÇ»É÷Ÿ@ ¥ÌÎ:Öxf¢ªS·..Î=÷}Î÷ÿçÿ¿ëáÉó½Æÿ?ø³Ç]_üÊÀÉsýwÿ¥ž^øál´­å±@uË-Çøßp'‹ÿ÷³ñ?‡Àÿ>ŸÜØæLqŠòN…¼ c·ÍJ²#²Ò¶ò²ë•å7UÊnMuFyÙ uU_$¼ À©¬$r@J|ÞrÙÍ*E©~\WsÉ+ºhö¹²­U”uÈË:Ôª>uUJÞ-—u¨ÝFÃz°FÛŒš±Ì‡”£Ž²G«@å²Ò¶*EƲ*e—²òfeù %Ú)¿¡(¿‰•åÝøKQy3GI{‘…è𙉘Ù1zL"^ã.q@µŒ cðÄ3îPì›ÈTÛÁÀf!=œ4›ƒæwâŽôŒ‹õgÏY¾—þß–œQ¤HÔ•œãiÅfc•š1 )¾{¼´¯Ruûhq—\3^\ÞW¡ÒçŒæ{2å‚òA½q¦Xq» ¤÷dIŸB5\®þߎµ+µc²ªÞ¢òSeCáÈö¿»µT9"¯F ãt±b¨¸òN‰¼ÿha÷½Ó®ÐN9‹ÅŠÁwŠ‹dý_>z­¢æ®J=v´¨»\=VP:(W”É¿ZÔõoµË”C¾ÀÆ!ßl>?É!üϱÐHá+óÿçãÿ|ØŸïìb™ã$£ƒG¯Õ Ø(zgÅK 3@ãxx À÷’Û½d±L £îþaVUÝò5ñö«eÊå\ Ç»Œ:À ^7ñ8ñ…1JÍâÛ¡lVÆ´ã6ÚfŽ9 ÍNÇ|%/ZùࢤÖö{øpðîåøÆcî»ÍÝ÷ÄÈZÒ3#ÚFÒñݨmXôÝ‹Õwж¡Hù_F|÷DCg<´$¸¦ëˆhdG3ÖÁÚ/5ŽÄ›æ}[:¾™J% ˱ÕÕ7¶4˜ÆO]1G0B©Õ=Fb»jW²!CUÕ˜íat¸øèdÅm¸Q€†§ /xcÔ(+i#}:ygUU7:‡SÅ­huŠO]%ßlð ºåóƒr’aož¶FFëž;¸„îý|PòÅsž/žsóòËg]¹•øA)*8óÌɰ‹§¯¸ÍÙ˜Á5ž«’`ôLx‹Éo–Ëò°¡Z(¸žb¶ sPlñ§“[y)øÏ±€æôÿ³S´küæó³Y^´Ó9Ò×á¹gž'ó8ÿÜv˜ƒ\˜køb_NæÃ%ÀP'Ƕ¥ÐZ˜;ÿ™•Aã9ZàŠÀ|/ž;ÌS8í§{ÁíYôVLwÑÇýÿXyÿ_—Þò½Çÿ·ÿÿÞËÈ?ŸÏóBø‰Ÿaèâ»n×B ð€f]‰‡dC¤ ú F¥¾ ¬Iâ#!² }!ò0LNÎU ª <ÂÁ_~?yMÝ®9¿côþ`MM¤ö•Œ?Á–(…Ío}«”üÝäYú>ß[Yc¬8”‡(D7É—ÈÕ9V™â*÷û‘ Šc®\Ön2Ž×F1ÄPøaT«éGW_Š¿f°¤¸ ÆH­v¨V{ÛqÎ˜Ì wµÚÛwTDD4§YŠ‹®(•]µµ$†úeeí¸–ãÇ(Õ网ËÜ0¡×üTJ‡î½Ð~Yg¼­3 •V¶Ê®Tëû4†þ²ÊëëèO¿WGø?1MžRæÞ|î¨ÉÆ?ã®þÖž7XçŠÊoùüëÅòÞÒŠ¾Â²Î"yï›GKoUªG”šáŠÁÒªÛºú‰· »Ž—ܬPýñ»W +ºO”v•wµ¸C¦ìûò‰ŸãÞ¾üÕSï–w¿y¬ÝnŸ« ãwß¾*× Ÿ,½u²´ëO ;¬¶¹²ªÁ¯týáÑëÇŠ»N”uÈ{Þ<ÖZ¬ºóGÇÚÞ-í‘©‡ K»~ÿ+'*újê§ùÐÃo< - 7ùØ `©°èUãÿý| ЃSû —Â$ñ`&ªBÙ x€Ñ¿˜Ñt `ôÌ YÕÊ›*Õ-Š&Gë”Ù|÷Ý£uúáju_ž"Ÿõ¤vÚûÖhôºyE'Þá4‘(×éF”ònQv©¶võöÕÕýh4šÁŠŠNεˆ£Ã–Ä¿¥¥m,ð¸vJµ²7àÀ/G¬ï×·Óu¥ŸˆÎá¤âCáäÙ„1Rö¦}³íÅ{<¦ú$ä™Uçźk!íõ°ú’äj[“̵Žö£ÚvI{%¦kôÄ.À๋ lêŽ;£Ú6©¡GT|#¦üVHßW]º#¦žˆâ[QëpÜЪºQ}*ÿ¦d"(}}#æž Õ¶&‚+äÿ8Q] i.ûµí¢þj’éb'¤ˆcJhŒÁ¾¶Š QÛHSé×$ǽ òÉ:T&iÛ#š+óP 6‹ü[Bõg,ššë!ígRÝ`M¬ÉЭíð—ýuTu)ÉÌv1²*U]ˆª®FÔW$[?ñ«¤ŸDLƒ)aCÔ]Õ—–~¡®õ´ô0®>w º+qçXÂ=W|Sª»*)?Jš{âº+QåÇ1ÿ¬¨i‹û¦âŠ„†’¶5Ü9¤Ñp€ÿ³™øÿ3ø¿¦¯¸ôÚ+ÖÿÚÏÇÿ9ÿ.q#Е¡šÏRâËzàs9#ùv÷ê3i³CyÐûés‡s^,ùs9‚šTÖˆà‘T--Ÿc‰/'nñiÛ^~SáÅüpU‚¹ 5¢ t˜“Ò6óAN4ħž™<±UÄÌÛ“ÚK±;C.Äc~˜*Í&Ŷ16aŒ ‡×Ù)'ží.0µ‘¬ÎݼHû§0 HbC= ­,*¼¢«®Rܪ«Qí”Þ<Œîý½_®US¶uEù M5¥icè)8~©ZÕ÷OÞ—£BeXVF¶ þ**¸¬ÅQxE­A‡Ðk0ŽÂBŸP«.+¹^UÕc¨Óê(c¢°àj½a¬N?j¨+—ÝÀ™«ªzÑ`´B/Äħ+‰ýu‚=¥U45­äÛ_yË}Îj•—ÿÛ[PôJâÿq¼Î4Ǹ“tι9ÿ?÷íá‡×#ñÇI w`x@wØAÁFþ9þGq⺓Åü‡˜¥àÍÑ~òÀ>5Àùÿƒ2¤ 9[ƒç3í`'ÏüµLZlÓ¶Æ™F˜â–øÞ|/´zÿ_—eüOñ?/‰ÿ‘1€úðä“qLQÕ ,D”ãE—Uªî*e—¼¢C¡èT26i™¬­V; ¯ì~ŽF¶ª”7µšA ¢u¯RqC«êÃ÷V¥ì±Ú&Ôª[(ø,ÙL”¨ÕQ¥ g~yy›Ó1k6+*o**o¨UÝ Å ™ìªRÑ©Q÷ª”]Jå`pf•¢³ºª`ÛbžPÈ;KËZÊJe§FÕ£·×jûó¯'M¾e^­ðäg8ÕÒÒÖ“ N|R\|WñÖW¾~²à’¢²³\ÖvüØ'8n8´öö[žx’;y—o9΢gYwŽMå1ãlÌNR`\KìPÉdFï(Lb'–ÈFt3±¤L,‡”‘ £eâ‘DJa,Bb"\_Ic˜DJ42é]žXJš§ä¢$b3v¸³ëP*ñAð¿@«ù)†¶‚W‰ÿÒt.i( 𩣯YòµÇC7&Q ­¤H¦v•‹Óňßr39Ÿx @“áî0)¿{#Æð%‰1"JÛ„(˜Äiv”ܽÃçÂ9OX åcÇT:Ƀ:üÖ1Ö¬=&K´ðÌôFþ¯»,ê.Å]cͱǒ¥?¦úH¨þvLw5®¹×wÚ«ß”¤»tKUÆ#¡Ú¶úrÌ9"À ðÌò£ªÏÕǰ#$ãÍh7⛋iÛCuIß=¡ðÏRÂJLù¡¨½V~‘#ZÓ&:F#ÚVQwˆg¥GÕ—ãæAFòó(Tþ-Ñ6ÒßL„Vc,Á$PþaHñQPß%Ö´&#[q{˜T磑 1º’_ˆ4 6œ‹(/†T—cÑ­e(?˜ûEËpü´X+Tþ—Bé_†mCIÏTHÓÖ\IáªK!˜ ÇßKJÛ¸Kbx%fì*?T—Rž 1ÿ¯§q±Õ—Îq¡öj³¸&©Î§<Ó’òÛIž#¯kM˜ºÅS– Ý‹k¯H•§£ê¶fà í%Ñ~+ihO‘Kä)gû<” ÀB‰˜þ‹ÿî:uªý•½Ï/âÿý482¤O‰Ä(‘|Ÿz!H/õŸCïù_q:/úä‘ß>}ñ@œj>OF-›Y¿àà…éPOai¨ñ7­¨ÕýFã2PšÕ2U­ê­7ŒÖj]®…Í`~½½ÓµP_7¢«Àç X›‘º0O˜Œ”ž£ÕZÌ“zÝ0 s›yºFÓo³NŸcÌÒë‡`wÛg”U·45èñ0–áˆvûœÕJiA ÅMwàG6l„E€9c?Ÿø’çñ|^¾Âfï“-ÏÎrC~梌²R”̰%¶ÚlD‚‚XAÇ€%Ïÿ ¬^ãÿ×åGÜÿßòòüß—áÿ=úJýk¡ÀtÔ”åj¥\×€5\óºýŸwYˆé@Ø8Á!ô“Ÿ{ï{‹ÿIÍòlžìÆ'ySÉçãi(´‘¸±$ÚvÿjŽÈ`5Ǻ;É]d´Â,šzÎeÌäŠ&²{1yÊGèÃáLÖX<Ë55ÝçZ3|6_7Cáµ|f9 îÎS”zr(Oð…@²çÔM_Ñ÷7þÿ`üÏ>e{–  ÈÑi‡­äÕŸ4Ç=D•Ol?öÆ{(¸(³#û*wæsU ›mhÁé\0™îâ/¼Øf3)œb Û>ïpÌQàg ÿò½îNcãl0¸ÆIQ¡¶ö6Ë8¸W_O)çØB4ƒ–„±è ÞÕ„ëqq#.¬ŠQŠx‰‡æ¥ÐR<´À £¤Èb2º*‰ ÿ<>™8)‡nÇ󒰧ܹU2 ) †ô âÒC ’‰­Çý³xâ‘ûšHчRh5“uXL†îÇ„5bÜfñ?bhY×ÄȺ„C‹ÛL~z'dOøf#Öþ¸øX´ Þ©dpA²ôæ>É|SôÍÄ 1û°¨¿„CK®1ÑÒ-:†%çH 5CK’ãN2¼3´¦‚÷$÷˜hL'X3\I¦ãöþ„©GòK¾Y±®5KsôK†«1ïÉt-ÑØ-™:’‘eÑÔ–LO5 'üw¥ÆŽ¸÷N*õ(åN„fS Åý¢yüÿû9[ ÞËÆÿ<ÖÔô—]{EùìÜ'ÿ]ð?öÄGZý˜Í±Ì¸¿ž³<½˜CÍ&Fé§Ç»Â¼ú”dÄѾ¯iÅj[8%’ÿíäÅò½H‹”Ë$ýœ§÷æÏúe?¿Ÿü£××å:²aùè‹8\-K ÖQæÂ81ËUÝjh¸KãˆmPŸó6û«áð:00 ±‰v$ì·‘½BÙ °XXpÙlÁ¾S2⻣TvkkñZ¢ÍRšÂvØïÁ*/,¼Ä\CmÀø6KJ(å¿N?L2Êú;Ÿ¡ŸÌ];¿™è4r:´X&ÓÄD?ƒâÚ÷ÒÿG›iL§Ð]¯d{xÊâþÏ’SHfÏå¹àdòõGÂ,­Éå^pÚï±þ<3`a„òzóÜ2/%FfþÿÔNÿkzO½’ø®mÈÂoSœöÇ·ÜX óœ\®f›nät,#Àn™„adÂÇ`ËSk“E5ò`!€ùœRWC³Ü"`á]6Þ Áë°¼cŸmÚæ[öaT­…ü+~Äã^ûÿÿ~²z{dÖ_NþÍ?nù¿ü0œ¹uã‹x«ü‡ ÿŸÎS6žhv€sã)`Rº=¡\։ΖÕ}ªª•ê–Ã6[\tß•¼ü†ªê–®–‚"ô:¢˜V«zêëÆj5”,€ž–ÏPó(wžx˜Ê&³ôa–GœWù¦XH|.k/'ÆÔœÎß²ŸGⱟÍú|†qDŠ?öùVp-:Ým€ÀzRé"Jt˜è–Mã†úQŒ;õ†Q 4KÃ$°.–ËÅâÂ}ž¥xbWYu í8 œ,Ž|Y 誦тÅ<õ…¤ãŸŸUýÄ9”j”ÿæ} ~þ³3U?q¶ú_°ulIJHßÊâIF“éÒZ,Sµ,M?@S…¼ ¨71ÉЈYRxU« 2"íg"òxŠŠ®êG0Jâ už4Ô`ž ½êÇê(Tiû²-;µºASý.V«%QN.[zŠ_;±N¤âÕ}xÖxˆUÊnr@iò›ÄžÇ&—1¬˜ÆUÕ}Ç^`2{²²ŽZšîÀKò²pS>ïÌâН|ø?_(™ü8½þîLYq[îŽÕ<©RöètÃGžÇˉ§‰Û…Õê^¦Z;Q­êÁýÇóŲN?BîAÛ à±†TSoâÖhÊË:J‹¯Éå¸3œ·+h"–õÃ%%­8(p>î^ÆE :šEãÌ»[püR]ݰÑ8ZTxÙX?JSüåO=ÉLÅw‰Ø"°mZRä`M„WÅà¢à_B+¢c,.n £ñðZLÜŒØÇ$a]ðÝÝÓ€èQÿb ØÞ¿Tžy¦cþ%IØl#±ÈZÄ1.¸&"Ö‘¨gFh‹î žY1¸*Xï¾…°{2l˜)¾%QÄí–ÝXÚ/ð¿˜IEÄU€3¾4å´+ªAS"MPF0K ØMJ{¬>qðÅc»q‘夋ôMKaÈg, ‰M{ÑåïP Gj—wè4šiBŠcXF#]‡u@l3Œ;”"qöõf&q…j¤ÈFýÛ.ï7RÍØ}7cífsO·ä°ë³üÈŸl€Ù“x6þG “¶ôú+ÂÿùüŸ|R)«@ýL©*”õ(U·eÊÁrEŸ/ôðËï\=UvãhQûŸ¾Û~¬¨ó­£­_~çòñÂG nž,îyëhû±Â_~ërS`­´²÷­ãøÙiw.—*ê.–÷”Þ,(íâÎü¬ÒÁþ¡õ\ÏK=E¹y¬cù@I þç°–Eòl¥Rùš\{<”+™Ê ™ñ‡»+0ªÀ‡øóJesÞ3NÊœ¢Ù‡&‰t†7«–Ø¥øÒòOƒk‘ЭְNäiáu¯g &t<ðì¯ÐZƒù®‹`ê{¼ËÄÛÃâT³Y®Ord’ð'¹©Ñô½rÿÿìƒ|Ùßÿž‹V;€•š"K¤ bçÓŠŠN_vÛ¬RÑQVU(•·ˆÐvO£ˆSæû¢^7 ÃöiFÔa´ü°«ÀB4ÈdÈŒ[T)שּׂÔë‡ñaˆa(øW± Å*knËJÛ1¦±À&Ì`âM·Ñ¦V=@ꫳùéBÝø®ÐÐ#V|]}M0÷‹ªó‰àŠdí“j¯ ª AÕ%Âÿ_½3¢ò¼$¬E󱚫AåÅ@¯o ¯YT{Y6ã¦(ÿ†X5—用ù,b‰™†b‘uJÅ ­†Jÿ,aêj>U‹Õ¦CŠ<ŒªÛ"¦> s1ò0Ãç#æÈoŸ/–•àô³ÜxV|":G"–¡¤k}… þ,¨¾®iéÛ£ö;Ù×â¾%Á9-T|3Þ ýïñúëBå×%ç }Lùa<°7v‘…¢„З =ˆ©.„Ô—(lI}Y(<W|[r ÅËÿ*%n Î1¡øƒ˜ó®Xú)õ…„úb¤øÏ{Ÿ¤ú0ߊÿ<^d‘ ωú¶xͧœš„Ïæâ"á*-Ô¥Äsø¿¦¯¸ì•òÿàÿÉêœ~Æ;dI*'—ö<Î'&=×$s¥sãAbÞôó8=mËà÷µÒÔ²ÇÑ#g9k×òŒ™’L3JUlG¬à«q\ïŠ];툰‰¯¦Ñ>[_?j0Ž2??õ± æ £Ú-Z@\`rc|P&Ó¸}Èyqͦ»f iéwŒª]ÒÀ…ø¾PœLt†ßÎí˜# Û´ß· Ë"—A€Ýíö™ÆÆiuÕ-§üBè"g°‚úxÏOŸþœÛ/x àƒXl›ç5»ÑÕ§Ÿæ±íGÅí@`-Âæïø¼LþPdÍGdžc.fÒÖ8Ë0ï—ýOçS‚kM¾û¸pt°<DbéBr5Ðßà='¦À ai®Î»(žË#»ØCÌâÿTŽÿ¿¯ è•ÄÿŸyv®™ðÿ¹ôÓϲßs?üïZj²áá,ûÝ ÌS„Ï´Ý9ípßs7NY\³v÷œÃ:Ñ ¬…„°oÙã_nò,¸Ñ¼{Ä¿"Bb' K†ë$?ùTvSÍ41˜:û³¾eŸ}ÖÎÉ?¹¬±†â(÷œfâˆu8<¶{Në¬ÝÉFÅsPM+i®N‹f ê令Ãü¹™z,ÙD@ÖÿÏV’{9䟫™‹Ê…å¹— [ˆ!¡²ÀÌn›®r3臫ÝVJÂPgª•—ßh0Ž£¨1ŽÔ¡GUWõXMØÑl·4L`”±ZÉs®¨è„ €-ÕÊ[DCm«­é×j¨XLã8C ( ¦qšM¨Ъûõµ>¶¬ÖI´CYÌÞ®cµç+§ÌW¾ªý¸Èx¹ÜÞþ¦â¯‹ÍWe¶ë¥ÖVÛéiïée<ˆÒÒ6YÙu­@´»ZÕ[Tx¥V{ãTuuo"¹ìŠS­(¿!+kz”ÉÚqoC¡uÒë¬*+»àt‹µB~³FÝüøMM?FOŒ Z-è*jU(»jˆÂâ2¡®î-—µ×ên³¦ž`X)+½ŽÝ‹ ¯’N1щ÷SXåÄÝHïx‡ ͽ¤ÈYu 7–ððaüÿÜ ä²¢ÖWÿó¢óÿ‡Ðvû,„VÛ‘@£îÊ¡n˜±9 áò½ñˆ1è¾2H§JÙƒûà°ÏµF…-ŒÔ¸ç0à”rH8Ÿ"™Yð˜Í6ÓÐ0 ­9àzuÚÁZíP0°ÁyÈñÚàPú^Ø(Å5ï¢ì¿•ò–NG³K&Óö\ÁÍjƒf4¬yÒ·Ô4GQîþYÉ?'™®GÝcQÓxdQrÇC±Ðb<´óÝ‹5tJMÓ¢°k¸-}Gº†€À%q[´vǼ“¢­Wrß•¬·â…¨moÂ-ÚŒùg£žITÂ+¢µOðNÇ¢[1ÏŒXŒY{Å)³ÈŸœØvL|Ì( ·sàÿ9þeäÃÂêËQã­HãhÜMú€aå7˜¦> asoP}AòÍGܳ‚}BŒ¬ õÝ‚¾#¢þD¬ï Zc5ç¥ÐrÌÜ%Ö]ê/‹æ~Ê;Ö·E­ý‚{B´öHšKQkŸ¨=ŸŠæqψPß™tIº«qS‡dl=#ñšo‹¶®˜­G2v‰ÕK¶Þ¨ñJÜÜu0ÉwÿíÏó ÓÔáÄ¥Í ÿ¿º¯¸äUåÿ¦ÒOŰå^oÓj’QÜð~žxž±ÇMÙÙ"&ä—Êh 25».ø ìScȾ¦™ðÿ?}_ñKï9så g¿ôž å ç?öŒXë›—[NSœ?ǨœÝ—ç5³.7ƒ„ÓŒe×9G™æÂCîÏϹqB”x^ˆ½-NŠ$bBR&[øHá!¶àár`øˆÌ‘‚pH"Îr²’Ü ÂRbYuo‚â,*b©R\ö"ãœy>ƒL)¶‡¶Q3é'²šÌC¡øDÂÉÖqbù¹E8+|³ì=-+m×ÊŠ¯ÁØ7Ô¢§ÅW\­ì©¬èÄ.—uT”wpÑ¢S­U•]=é Ëdz&µŒÇ„¸¤è*Ö««û u”„®éØÑóÔ{;ç•]þ¦•£o»Á8vìÝ äê¯îÓ2 ;Js¶N©ªºßyûc‰$?ö,Ö)ôh“:´Ê®ò²vÜÌ“…Ÿñ<²—ÿçâÿ3üÿDÑ\xí•ðÿé̲9ãÌ'okž6µÜ5µŒgÊé¼Òœ·lÉ,ÍÙš´×–ž–%î×Âh¢V÷Çrdƒû…0öéôÃVËù‹ £6ë´Á@‘á°°¥¶ö6zR¥)¿AðÞ4FtÃþ ;›mЍõw¤ø# £À†úQÒ®î3™î:ì÷<î…&¢ˆ_ÄŽfË$:y³y@š‘½/‘‡zÛð÷âd{ã\˜äh&|þe_Ó2NÅë] ×xä…¬í³Ü- = @&¢¸yŒŸ^ Ú™¡‘1ö¨‘>b Â’_ ¸˜þ%Íï²Õ6M"M¬RÀÏ{m0O0æy>`wÌâ*Ž{áð:wû³qv‡ciKøë¥ñÿ9þÿ¢ïê\ú;äÿ!Eq?—.—N=Ïw¦ÉŠäyÈvýþÄãó©¦2 G,âæ§œ±‚§ôZÌSNÇ_Ϫ!ïåTºx|ß †7&(iŽÓ rJÃ(Ó3õRJõ&}µËõ°òS8M½Ýxr'žÌø÷È. ÂCNÄÄgvhº-™ÑÒÚåŒOìÃ|’‰¨g¢o1ññi£Ç<´ž‘µL-<æÑû‰çzÁLz[Ú9ùÃ=[ÏH}åýËÝþ»ùÝfÆ-cQbëÒ­‹Òâþ•¢” ‰ì¯è£lBÁ–Ûæs 1 :Úe¬[q>á(=JЬbFà˜b¹³®Vhº0™ÞM6g¢³H9½—õ»îeøjšy ùî‹zÁ§OçO&æœØÙ>ÌèÿjúJ_‘þWÿïÄÿ™Ÿ<úN©ìa™æ4š“'/WWÝ=¾2–É>«RvË+n”—·ã$íöéÊÊN|þï=¯ÓuY{Ey'wéœ8~ }`¡ï2zž_jvº] ²ŽM?É”ë3ÑxMÍàO¾O´fïT|¬Qõqlœ§Ð¯¥|–; ¦q{ñä‰KäQ1ŽéÔè«YFŒLv\èÏãöëô#8 M™qÅíšAô«µÚÛ E§¼¢ƒQò^ã¦v×ëÐㆠû-8þ)-.óÄñ‹5šJùMXâeÅmjÕ-“q´´¸Öô©S­$¼®î—•]‡†§érÏáþ^+)nU«{ò8Ê©"¬÷ã~z¼Ë y7n zETÆÐØ8]VÚ&+m¯®îÅ#ÆÛ˜KpÆÛåt. »#Ië4ÞC\‚Õ6…~²²² c„Ù:I¹©L; PïÞ=œ¹Ó~/ÀpÇŒ4pÌà]r{´ŒûˆS ÔÇÀ 1¯Õja˜à~z< XbÌ2³ J‘®EçŒñ…éד§‚¥QãôTªîššÍ3àò ÿÌ¿ÈÎmˆÿ  Ñô~÷­¿½þïç@é³ûÞ“¾e Æ.àp ðowÎ:€ö1ÜyæÝî9'`|ðA-Ù¦møŽÑ91¢&+O×%•6¦à]ò1]¯}Îé^òø×‚¾û>à|ÿª¿åó`~ÓDƒcÎî^tÙï5¢ÀFô.{œ Ô¾›‚dÝ<ó×q7Ï™ØIœýÎÙ×ù¿ßçò#þyùÁÆÿý¯|ÿÿ‹&@Îý˜ÃÿY}ù=THj3—Ï›c¿áEÓÜÿnË…£-Ÿ `娙 Xò•cg/ÒòЖƒåŸ½_õ½àäïR~ó\2Ÿ®ðŒ…%ï:™¹à 7NŠÝ^Ï2waEc[|NÁçY$K§HÜò»ÁÝ)Ïc3˜I”å‡Å¦Ø|®¯‰„½rB®À9~içö?(ýÙ÷ͼüÌ{æŸ9×@K¶òSïë8þ'R FÂ8ôä^Ï")Wÿ»æBá5]íP(°ðÉ4VÌ» †C“«9N “û,®ŽŸ6QßèGHìÞµÐȘj|Þûç<… …6ÐN£mÚOþ”3uòh#¾…Öqhc“ÀuñF0ÖÃØÁî>ÆŸƒ›“á ç€JýªóòÂÿI6cb2ߥìZã$ŽAO@E¥ì©Õ úý«E@,6Û,÷¤?zwžÀ‰n¸¸è n© l•_ ¨U½À-XRŸy p xæøñ‹šê³é.Þ´:ý°‹a¨«¡ b ™acÝHñ©V-IÝѨd²Ë¤©¯§©3@;žµ—czçqt‰|4ž²ãá[¹ŸL¢— _ÏDß%hëíÆ²øØ;ó“%äféLÀûÜ:—ñÅSÎþÉÆüäeþŠY£ Æ: Û˜)¹Ý(iUç•—eìä]éN®óÉÌ0¦^BzóÒ’ ³ŸçóÏ×@É¥µîçM)îsþÏ„´Åñ?^éâW–ÿ›ÏÿsHY0µÑ:ãv-6ùÌ.àq€xÕV¹5:4€Oee—®v8Óï¿o£´ y¦ŸÓ Fú )¼x‡³§š® çùoÏÖ¿ýøþVäã±óo…?ÄÏßmüà+¡oò>¹ÊÒM~ yˆÆ?°f6M(*ȸàž‹y㪫uD0È‹.(8ÄCèQg‚j8%üD· ¯û|K@θ@Fé3™$«|¥Ñ6‹+bdkëDãœkjº½Ð54Üűðµbwô\þ æ ª-ã‹ó7­°ÜŸYªibwc¥‰äù¦yδ´X&êê†9?0Žëó.›H¹2­ðUäç'/S>aÊ9ŠüÌ.¥óçRO²Lôàœ™ü}f¯e$ÂqÉ~ßýætfÈà¼a|ΆÃl¼ËyÀl¶˜·<Ã(ÞÇmÇh“ËÂ<É(Å]ôæ3B¹ÌGÝs’ͧösAnø?O¶¾üÿ¬¹åIòì³tónܽà@±ÍXg­þ_`Ä×´ìõ/75-z½ n,IÃw=b¿ç´N72Ö 4Ï沿٬^;лwÉëšÇ£pÚçÎE·ížÝ2mÃȉÕ8kÃSàw/8­S Öi³{Ñé]¦,@׬Ã:iµO7²iOã´ ÝküÿÿÿÿÿÄÿû‡˜ÒŸ+¿$3Ò0 èf“s“l¶—…•¦˜@@s2ã̧"Æõ¢Â+àZ?VXðÆJ½~5›é‘íâÜP ÏÈb™Ä¥1YÛÇ"I›^ÑÐ+/ïÀua|ÄeÊ+:I¡²³ZÕC®<í zªè ¹›Ì“ó$)à*4¤>ÃñgqÑUÜÀ“'/“^§îNyiGµª—±èLôÿ?ÍÇQ¯:þ'Ÿä%@xq»ÌJElÜÞÓpÞ Œï0…`Öá "áMƒaÔj¥t<Üj¦»9‹­ÌÝ0ƒû‰'Üxà haT^¬3ܱZ&ÞùêGVóT0°FÉ× ” î&'×"Öa[¹Üs>À!6u²ÌýL¦1Ô8ilœFq8ïêpmØ $u'>nò¯WöG˜h0¼6…èfi*\·ÙtÆéPd+} mŠÒc³uÞé¶ð¯GÅ-CÃL(´éó¯îkvçb¹rÈçàñ¬è Ó6ÛýÛô Ùô6büŸAø@ã™8ZÙ¢Ûë€Åöˆ ÉGæä29AùS…(ÎÛ·}Þõ–9T .ß:n¸Ï½>ÄåÄÈ‚@ÙŽ Û[g-“uœR@žK$²EG{Ü«q‘YÒ.›ì`øÌì—ÜMñ­ê—– ÌΟx–gìó”¢Dl3ƒÿÕ}%%¯ŒÿçEÿöeNîY‰©~†òŒh¾u—æõâ»t±ivÉé}6ߺd$™|_)Éîæ ŠÓY«'à_ó¹µ-·¿—ÙwúþiÚýs&ûKíHqš©IçfuÓOb±m.¹îpÌâÊMÏá[03?jâÍ÷z–(’#´†/Ñ绎l`;®X-‘Ø¡jLx+Ál„eü‹RŸ\³5Îz}Ë8 ¬ â¦À´ yê“#UŒJaÖzB{ /U"¹‡o?ΨXœ’$qi°]ÊÇg^ÎKîàÆÆ)ùëi>j#”8ööyØþŧ®¢ U){(xR3ˆÁç[‘Qòø©S­ÕÕ½ØrìèEtõè(ÐÿÔÔ ÒèÙk4ýššA®D©Tv£{ÇU`{ii[yYG<¹ ŽÍŒ _C‹šïý¤–òŒFK‹Û _bjã:âj»…ýv¥œB°,8ví^ŽD6áÿ\nË!üÿêòþ›w¥ÜàÇ¢cÆbŸ±Z'M0(ÎçA€È¿›–}îy·oÑ+l¾ûÈCÑ·ð,6a†€w¹‰is ?Ÿ pÜs¸½ÎE¬ öÛ¸VÇ=; >l לÝyÏæœ³¹çqtËÝzû¤Å6avÎØ\³v,ÍcÆÆi+,¶3Ÿ·àÍzÿÿ~ñÿ/¹Žœj{ÿ_müÀ6þ'ßý•ŸA¹Ï©Ø2iežyÑ<&îÇê‡ãá¸wY4 DÍc±º¡8þrÌÄƥІT?÷-þ[ÑÁâWÏú¾¾”>ý%!ö;Íg'Þü¥dó—b‰ßާ°òï¤ø—"1üÄ__Š¢Â™ßŽ%¿”LÿvºåÇÏUðáFåþDô/…‹ÿZò,ÄCk’wÙ/ûH² †¡xÓ²XI…·D/ÐѶT?,yçDã`‰ôiþŠQÈÙi¿‡.C À^šcw)z@“^bÂñz—¸wÈJaØãèÄP Ûëêî°<\"‡d¼j#6Æ\ÆyÚ±ŽîÂB}à|àpìž`9¤Œh0´±)à!uˆã½yÄh×7 ÛÜÓVç”Ó7§Ðt™“GýŸdýÿ4D’( d¤q H)ƶb0ØvL¢DÝXŒ8–´Kò‚ðŒç…‘fezOˆ>ÄÕ³±lAªÆcËQg…-a#Ýä|ÑÀ Œôë*vÄѺP’©ÝHøa8D„6\a3BÚ$ânû=ôÂ~ß*ÆkROˆ?>èYÝÏ{µž~ò \Höú–8U ðp’fØñ,äæ­!„ÖâÉ]›u*•Jq×\6e/•ÚkjºÏ±%êg]O}x3ýk &âgîzæº$¶|‹{ì¹£›»åq·=ÄìšaÎa𤓉'ÀÌØhZåº`(¥}媡ZýD¡|Àá\(”þÑ[Ÿ+êüý7?+(é9Y|«PÖs¬°óKÿþÃc%Ý'e½okýÒ}ýÞ—/}ùÖãÅ=øæ§‚ðè?üéå·NÞøòÛ­ok/.¿õ•w[¿ZØ]"ï}óhk¡¬ÿþäRQi/ê¿}²³¢z(çi?ä„eJnûn,3ƒ°Ãa?¹ôŸãÿÇõ¦inÜj]0šgåŠÁÂÒ¾‚âî¢òžE}¥òþ7dò!­n\­/)ï«RWôW«GÕwJ*úŽžèð5­U* e½rÕ¹aV]3Z©1§ ËûšárEÿÑ‚v­~\^5(WÖÔMË%¤ÝxìqÆÿ)íðL¥Tœ-9‡0+,:‘(RŒ‹8Ë-ö|‚ ëðÏõŠO³ø/‘ÿ×hzK^ÿÿs$ËÆIë0K ‰Ð^Ñ]|êJuÕ-b®»£×Ý~ëÍÕª^XR€‚09aª+™ÈµÓ9]̦q»uÆX?vâø% DÆTv¨òí·>,5_û5!ð+A﯋¡ñÿJÀókÑÀÿ”ÿû ÷WC>,ßÃÿC<¢2tW«ˆ×n›Q“3d˜±æöá(Äf$naÞU¢{T*»Œ”,?”• Í„ )í¥[VzB-¥ÉÜ6èGJŠÛ º;öFrËËe74ª~v]P´BÑ¥S=zf{áÉËZM¿\ ÛMIôõ#Õê>‡2{°ÑÉå8•ªçäñOaà@²Ž²2Jh"¢¶²v”*e7÷«”•\/-nÅ ŒG½èÑw>Öë†*(€ÿ†²²`~ü aºæ¼ú˜öFã]—}C€¿iý'¬ ÜùæÞ±š'ÑâĈÀGÁœz u#AæõÆ_V U0ÖÖFq÷bñGáã¶/Hñ]´Ÿ3¬–)œž‚e7»\ó\Êr=4ÜðanDàRÐû—1¶-ãzSÙþ ³¢/õÿ÷¾šüßsŸ7üc™~’ñÿÛ ;0¤ö²ånš œýÎ9_ðÓ,¥`–ä^³sÞüÏ“²J¾äü§Hž9WàA(¸&âЛ}ÎñÇ’c¶Ñ4n°Œ³Öà}°æ¬úB÷ÝÁeWdÅ/<F×B¡è~SӢǿìm~’:óì4ì‘×øÿ5þÿË/:Ž”tüPâÿâ)71íQa]T· Š?Ž(/P]Ň±Ò¯GLÝRM{´ìk©ÐœXõQ2¹Q]Ž›® ÊO%åEÁØù?GÀ±Ç\çÒÑÙúr<0!T~=–ŽhÛÕ·Bš ‚êBÒ?S|CÔµF”—Ò»aåùÈÑ3ù‡’æÓŸj©æø_Ñt1Ô0(V] ™{Äò¯ šÖ@é_E=SáÊ#ªó¤IZ{#¤½!†D+¾±Ääß(‘Î3üŸàóõQŒs™ÂþA\n×° bbLgó¼+c–̇rÖžbäⳫŒ2(ñ)0w çÔ6sñfóc“›Å2Ú`‚\ðÛQÎä^(µñ=Åÿ¿Gñ?ØŸ¦¨¿ã&s—m t¹Ì†Pðo#ã m$™Ã1ºÉ¦6昅2Ì)æ0^`_R’/š£ÂNTòJåQdÒå´¼äéÿî½Àü¹Ðÿ”‰K¾rÿÿ¡øŸüñwI©ì‘•¶SŒMÅ Š‚.ïP(»,æI­f ¤°ÕÔpH H¦¤øº¬´C­îo0M² ç©Hd³´´ëjQÇî ™¨å] ›|+XÁ»dm˜$p¢,8öY0°‡Œl¦Röh5ƒÅŭʪnŽ‹ a£^7\QÞ˜µÚÛEE—YfúÀ[†=õÄå¹o¶Í ÑG5ú±`h½J;âö,Õ™&ÕÚ; óŒÃ³\PÜeµÍêæÆ9kãœÁ4 ð ÒÞ1™§±Q£»#ŠŒæ©FçBn ­é¦L¶{Ɔ)ƒyºÎâÔ¯kG ÅåÝ…ÅÝoo•+NÉz $3yÀÿ»Ifd%¹ÙL²I„f뤳Š$©lès–ô¿ž¶di-IïIÚø¥ù¿ÿç ØìÇ•y™Ñ-ø<ËBhƒEB/;sBT³.ç¼¹a2"ªذV ¥,áÃw8(óÝÆü\ô“œ!.÷ó ÷˜nh¸‹jø@P?‰ë€$ðVª€9í¶é&Ïú6W5E½ éÏŽåÒÆ† î?AG„ÂBÊ·ˆr…©« ãB˰pJ¸{,è;XR¶ot ’¦˜º‡^/9I°Œï]´ lR(‰a=©­½M©FMˀͰ¾ƒÁ<¡0±k¢t¹çIÅ»‰')†‡ºâÉpd#"lP—È\@ØÑçYÂ’³ >À%àXÑÈCÞ‹:ísxaì¤ùKÞ7ãäÄuñI‰Â;sÉËÏPÁå\ˆ‰ø£…­ ¼ä“éæ'܈05.ž–‚s@}F·›Ìó-p1¯<•„ ‘Ö½ÞeF7ÄU§÷³S6O%ñ‘ÙÌM¬øYÆY"µGêÃâ6ÏfJå)>¿ þ»ŸŸüËãÿ³þtѯˆÿŸ¨øÈÔ üï"2ÏYêµ P=EõÌ9ÝË~ü=WãœÛ·ÂO˴ݹà <ˆˆÛq¼°¨fcÚ>fðŒ¢šw;ˆÔ‡¥mÊŠŸ@õ-OÒÂZ ±­ãÃgv¥÷ž&ÏîÅÏ=‰ðæsO›?xvæýý–æÝä¹g-|çló^à–ÙküÿÿÿÈãÿ<ÿÿ!֔綬ñ˜ò¢o1•Üo·‰ªó¢úbH})®ëW~­ 5Ÿ5§Ÿ ÕWm‡PûYÂÐ%6­ü¦èŽ=á9÷-Eª/Fœ3’êÛ‘êãåß””W„ÚKÉÐR\ù‘¤ï5bŽ)A}AT~;r,÷ßÿÉÓ™øÿ*ËŸ5×u=AS¿¨þ¶¤i ÊÏ ÞŰì¯cú¡ìk’쯂êë÷\¬êSÁ·,69?ÈúÿÉe­U°kü4FõczÝPaÁgµÚÛr¶Šñåø±‹jfê"d)(]EŸéj‡N|„pXQ~X®Á4®ªºØVzêZ0°†¼¼´ÝP7R]ÝÇ8–ŸiµýFã(z%­n0'´iÐûa,Á¹{¿ü¿z¯ìÇÞ—¡ü£ʱÄO¾…/±ñß¼CÿL“Š›rù ŒÑ OjÅðJCõÄÀÐ[«,—Ѳ¤ä®±®î޽q†¤ÊªzŠQ¿vh–Òë´ƒ<—»šŸƒ–RšJó Ó]ãyÀ97‘Ry&@Žˆ>§&œ ·àÑ×yü°P†ÿó•Çÿ<{Qæ2ÕFU»}@(Z'táY4ÇÉe%¼ мh1Ãں磌f2¸šü«6Û, .ŒÂެÔ/n4ð“¯÷¨;’[Ï:%JÈØ <°5Î: °Úp8ò¸jptbüö,*±wp]«ò±°d3A¦ù<í€'§òˆÿGJ …ð¹HÿAÛæ>y6ãÀwyà åùçá{ „Þ³^|ÌÚ¤£Hb&JŸÞcc4ú(GïƒeTäàÿ‘Ýâ@Dé)p-0†ÿY~ݱDy¾Ùआ¥ð0Û£9‰váÊ4{Áú†(lbÛ£l%›,¼lŠ("O%ÞÑÖ±"nId€^Œ,ÕÊîJy'úp=y :`òc#F"…¼ ÃRÞ¥Ttc|©Ñ ðFT@M…²ûèÛ߯=Á–“'.©T=UÊîS…W´5ƒ³(Û­•\—•^W+‰|Øl™Ò¨û}¾¥Âãqdeí(*U/úgtS8„N7Œ‹:¤ü•3Çÿhz _ÿ?cãÃ뀇Ï]ôŽ9—{Ñk»ç¶$€|ëŒÃ>çq.úë–n®pÏí˜sGhZ;n›¶›'¬\Ì>ë€ ^V)ë%º7¢Òذ&ˆ‚¸7"É-QÚEîû„Ÿ¸ê,{BóŽØŠ/¾æÎ7J‘ô#)´ìÑÈ’7²ð/y¸ÿfâküÿƒƒÿ#ŽüÛô‘ŸPùê#ÿË™#ânf{àá‘_ ù§Š#ÿÊx¤¸ýÈ‘â#ÂcÚ.==ò»ÿÇ‘ŸÒù¯«ŽüFôˆ#SÿçmGÞúøÈ¯4ù1Ù‘Ÿ³q.)í8ò“:jáý³#§ÿS¦ÚwÙýO>:ò?ÆŽüB㑟11LÐÆßûsjí'ªütÝ‘#ýPâÿ—ùÿŸ¯§ãÛiÏhÊ—ÈrÚ?žVÓîaÉ9’ôL¥=#éÈb*²pÃGp¾Ù?ž7Rî‘d`ò·R€ðŸ;g~#í|ãLÓo¤]¿q.øÆÿ-Moœö¼ÑâÅúoœ ½Ñâ{£Åÿgƒo –-þ7N{±ñ¿/ãøÿ - Øýfׯ·xý,Û½Ùýë´;V¼Ù½Tš]|ùóçÌÙüß}.Õd±N‚iu‡óž—¡,¿…GŸ…»uÊßtßbžä3Dhcæ(Cƒƒù¯ÌækZa¬;3œ<–)s5Î0Q€§VËûI£IsúY*µ‡9{Žè%ÿÕËÏ%Nx&ûNú¿ïÍ2àôú‘@`%+^¶ßÔtŸë ð4£5æzñVžq–Ì*£qï%7j8’ÉÉpÿôs©M¾þ$¿p²š UNsÆíŸÎ£„Í¡ýD"#P•c¼ÉÃÿûó(³üŸš¾“§^müÏ!v»|ÿ?'G@>Š„60¦‹Ñm`{ÀuëC° o!à9Ø V"¡‡~ïªÄÈ-óÝLñ¨ÕLÆ»£Òaú…C¡ð†Ù<…íhwˆ7\#°*=6DZ‘Jä!vÁáÂ,˜™²Ñ øét-Øïy(åœð0°ŒNÜÓíc#Þ+ìBYÛ,¡Û‰Ûܵ€ã:l³2Òž›ºÆeÊå]nç®ëzýFÛ,금´¨È~²¦–±Žó®SUõ¢AvV;Jœ„•4Kl„5ƒ€%ÕÕ½v;…Ió¿,–i³iBK¢ÕӤޭ®ÓêF±¯†%Só™‚HdËfÁ5f >3ríÎÒ½íóɇéóÝo·F¼RËœeÿRþ»w<¾%<Ȭő™žà3|™Hì ‘­Ä¼é]fUñtin ì2£€(%Ù_»/àÿgþ[2²V<þ'.mæüÿE%¯ÿç±W=ŸÞjh˜ðz–ñtø_ô:5­âFáeàÕp`Ø6yï󟰼î%Ü"ݽG€Ó$ð­â7ŸÞa'—¡‘qirzdqìÝJùÍjÕ-€g4Ëdµ{ÙDÆ4l@Yi10+ž»LDvÔ_Xp ý¶LÖÎzYi)<~I«´š'kê6›îâI•—·ó;F:b*â:®¯ÅápŸÑfUU7Kÿ™‚¡‡í²²6´˜­7 Ûgsñÿ(8+Œ \?1Åz–J|8ÑûþÂ#tûT¡aßS™œ„aKÓ+v|b+dø»(„…örÎó®©V3€QÃíY0ÇiNAÜ®&CÆË"†w§gÅ âY¬eé`~ßr2½GÁ¦»Áà\©Çµ ©! {Ø,LY`¦ÞH|ÂÁàZóAþŸC)Àâ _IþoúY J’Þ‹3äê§«÷ùWBžÅ&àϲ߹àþ·Îº<÷¶{n #íçqþ‘ !¼1›Mã ØX?jÔîšÙ|8Y&-–1³y¬¡qÂæœn´5øæÜ‰‡B`Ám7ÙFë]wMÞ)«g²Á=aÂÒ;eöÌÚmfû¤¥y' ¼­úÏ}çL˳æ×øÿ ÿ±uÇöŽDwð¿Élÿ¢çÈ¿;{$ùŒ`ÿ¯úŸãàð7²Òß9òÇE¸½ù?füOŽØæh—ß:MëØÍzVüóê#ªþL³ße÷ŸiÈ¢¤ƒ „–ÿô£àÿÏæÿ¾Äm›ÃŠŒ£`Ÿ³w²,à§,øisŸæâCÒqÚÎHþwÿ®òÿöü?ï%Ø`ý”ëųyØÇ\¤5žØÁF€v ˆŠéøãxr7Ä$À¸W<YgêZ»QæcLe±q‚ý›!dÒWŽG’ú"ý\_Ó*œ„¨Ñ>€7@¿E,Ì~ƒ‘pæ¸"¹ðÁžÇ½è£ñúIŽiÄb™„%‚a #u´Ó#àÍ‚î]ÂùsC»m&ÇQ™‹bB ~F:—SIHÒù¬pêì$ób_1¶M‚ÂÌLÀýa"¹„ðI”6´žÌÐKp Ör²n`Œ‘{—«¿Lü÷yì4ãÿü>ùÿ‘ÿpü¯U˜êÇ(0XGM?Fy   ô“—uš…œ²ç0Â|V§Æzªèjƒi¼¸¸up¯H[³–„B€²J‹[)|·~´ à’¦f5qôuwpJh°¤´´ xFÈ»Íæ»å7j´·í¶Y@Ó’Òk:ýPMÍ ê° ˆ €à ,þÎ c E·FÕ'+mÇ}®¯;^pQ!¿ +’Òý*ob_¥¢'_­êuÚ瀋Oµ–—µ¨ Ñ-Fx÷«ï|[¥¸UQF¹äòÊÎRÙ5)øÚ[Uu Öà©S­e¥×I"¾£TöTUõ”•]Çõ–Ë:´Ú!5€Vál„mR—(m+—Ýh0MÊå7qÚG^ܪ­zçMõãòŠ›¸Žÿ †Q,•ŠjDÕW!»a4Œ›8¼Ò0:(Óœ¤ºaM˜Œ°\N| n”•¶ã½=uêrµ’&Š›øðìЈ¡nÍâ¹”–¶29ï;ýH½a¬¨ð*îpuuð¡^w[§Ì;ŠE*˜»& žÚ±c˜7õ2š’Ë:K‹¯U–wÊŠ¯ÉJ¯áµç)9ÿy¾›]'þÿtz§9õ¸Fý ù?Ƴ«Ã̈́مkágEâ¶Ee—Jy }]½aÔb¦àÿ ±Í_(êT”“gØXw‡Iß^cªåc0%´5xñz“„iàþ„9VVÒf&©‹1 Yo),¼Œ¯/ž^7ÄϤ¤äšRÙM™MºÁÚšÁcGÏ3Ê3¼Hx%È%ÎbìËËI®7‹ÿY$UË~óiñòÌ×´Âó•¸ã‚̱4(ÍÇl.r—”×ÈRãšVÔ#ÅbÛ”Z•à‰*¸T%·h¸}‡þ–k xÜ Ü®d Ýð0³Ý±H?C[Ú±’› Ðgð?jæ×oþ›#?^yľðï|’Ù®=òJŽHO2?3uäËßÈÌ)|—Ý]ÊlÇqQ 6Âü? æÓ—ÅÿC¿ä“$(ÎûkÚ%õ¤¸!ª[ÚöˆüC±¡#pê낺M0^ ÿ…_~!VßjnžP4w£([°ìRœî¦Â~fË­léÎ.yeúùæ™oüñÙÿ ¥ìÌõ¼úÙ}ÏÜB©b[ªÎd¶+Xª3=(ª³=Ö–)&Ló$ZÃІëÄñ‹Zí ÑÀk0|[Ó#†°“'>M¥÷€ëäåEö3ÔW­ê©Õ65ÝGe ŒžUÊ€ôY7±WCÃ]" Rta€cÊòÃ(o (³…´#–ª«{T,ðX‹y„æ0Ë+:åò€I »¥§Z­ …'/ž5gã3«uv=Q[ò‰¼¼S§TUݪw`˜ÃØQSÓ®’$MÝH…¬kZ¡s¬£Ü·^«m¢„ ôè%kj˜>×ÔWʉ°F(u‡MXÏ‘j•¢ xH¬ŽIÙ*å7¹Ÿ_^AáC@ø‹?^Bku/У¬´ ‡+§ãÞ®Q÷cyÐÿŸI]äÍ«ÎÿÍᥗ&ÿ‘Npñš>0æî;üô—È:SÚ„1 “H°7ªYmÓja¯Ác齫œ¾8¡ÉwŸô†<ä¨÷7ÝçÒX'•g÷"F^§sÞå^dÒ?Ñš¿i¨ 9ð€Í»>ÿ}ÔÅó88ðàT«1¦îš"›‘ÎKÀ)¾ƒ»k>@Ltθ(l¡`š• ‡?9ÒiÊ|K̰ôlS EQ&±¸ ¬‘èR”“ðogï[Äÿßána즰œM‘‰1áÎd?"ñÏ¢@“î$Ÿ ÔZηŸÿ"5 ç‚Í:Ý蘭V÷d–ÉÚñf®ëk‡°;0UU7¾¼ç0mL4¢OàBð¡¡Y¦£1ÁØifMW;lmœ¶ZHŒÏb„­m˜`8}:Zvâ@Õ=°(ãÒ½ˆCc£ÛÂv=IÇÞ%Õæª[ôýšÆ™vÆ\}ý!û,ðî9›\{šõÿ?OÎQ¦` Åÿ¤wP(þGöJýÿûýÿ™÷O¯Ζki‰x¸xK}˸d>s“¶}M÷IQ‚+³à¨h”üüÁÀ^ã&?1÷6ùW]î§kÁǦÀpCDöžð;€»JlÃîy|NœóÆql „Ö"D)ÿ”3¤a;^ZŸg)Y³Zˆ±“42Bk<€>4Ó]§k/ÌsüßòÌf›²Y¦Ð—ZHuå.LKÀA<ê £$nÒ8ƒçˆ¦ õ£Ø'Ì|ó<4®NÇ圇•s¶Z¦ùÃ*)icT™Ó.b9 I_(ìøö[b$Âð;ŒO&6QVõð( t¶4 ¢¸ ‹F«¦?{ÔÕ=Gpi'N|ŠÖj´©ô“\|`*ã•Ê”üä,¾Lý?ì½ p\Ùu%X31mOOÇLwÛá¥Ýã¶%·=í¶[¶Âvt»½Ën)ܲ¥rU‘DAìHdÈ}Eî‰Lä¾Á*µ=«{lK²JUªb÷ÄF‚±û‚ @l$X¥™˜sïý™È’%µ Y²ñ#ãçÏ÷þåý÷Î}ïÜsöÄ’{XXOžâÿsþïÁàÿöÜã“4þ¿ÓÞ¼$Ç®1§sÌšy'½Î1‡oÆÛ4æ°[Åá×7írÛ}SNß”;±M<ˆZ‡Í¦£®_‡OË0^_+ð¿a€bˈÍ2`ÒöÖ[Í¡¹€Âœñ¥WbÁ¯sؘpyQïÜ#Vï¨>ïÚ,ƒ&´"–!3ª¡sÜÙºÝÚñäTz#ÝñAG˽–çøÿ{ÿë‡^øOìnÏ>!àm§í@æ…íÍ÷üo!`ÿÃúÝå«^¨¿¥ø²+JyóؾÝÿãk/|âó´ò-îž}Ÿþ1È÷ÿøÿ““mŸRJÜÇÿ) çæv¢Óš÷¢5o$›n´µ>J¨¿–Ð|-QóFÚ=U¿;t*[H6œjΧœwöÎY˜!…-ÏEž|ظ1ÙÄáN>O–ݯ4‚´ç§Ý Qúkÿ'y:Ñ‹c)ž92£t3¢v£åG¯GÐË7ãhæ Ye9Æ Èùf=žiÑÌaL8o¶àdÖÂêsÌmi¹'@(Cšuœ8ævMŠ6¢•‘l\ê§+ò~V“l±ÐÝ®)AtÍ¡Åv…¥¹c&j:Ia QÌâYnŸ8 zjR1æXªH&këºpþ»0‘ÆI¤MmÓº6¹FœÂGÓxÐ?o³æøª}ÞþŽŒ]Ðë™yä6Ël%Àqd¾C­é±ÚÈ( —O¤&ÖÇÆß5ûçíæ»Ïðwò¤SÒÿ|õ`Çÿ=3°[™ÙÑlHÞfv&·ÛÇÐá’Í™eDr·;[Z–Î)aõi Ç vÁ¾Ñت£iÂéœÚž.¼®®ÛCðiÑÙ4E)R/tèϤ…[²›yZèËæ ‰¨ò‰ vJ'žÐc‹%J7@¼`'ë)ÄHaðÊË/בgÁ8Î äpL¨êz¬Ö1`*a¹õ™ŒC÷à‹Á¿þ“ÐW>Õô…ß5ý—Ͼôÿ?Ûüå?tÿ?èþoŸöþå¡è[´%ðå?ò|±´õà塺¯Ö¸:5¾^Gf¼ÖÝUå¸fŠ ÙÓcÅï3¼§ñÝÐzoáÔ«ðwR¬–»VÓâGÊhØc"gPŠ;DPp±kÏKŒÆâd&qGÁJXÙ7¡¨RaòCÝ}“Š éÇ#kIŹ€.?I B zÈë»ZFyR+=æÍd³OOc)!Ànþ/Q WÿkÔ½ÇK.¤þÿ“ýÍ£Þ4š>N3Y&*Že$X$rù˜Ìéõ·½d88¹%t¯%xOÄN«#L Ç[~MX„Šïn×4ŽCöÐñ€S…?"}Zߜ֔ÓhÛÁSk¶XtCÖb‰5´ €÷l$‡»º‰ûLdè¾Ò|"ßa4Ñ»ø¿m§±ñ†NׯªéB Y[{œmÕ=••WDÍårUu݈e€“Q­þEG ýæE“qÀbD8i·Þ=~üœd××÷¡iÅ'MI4Ü„ ‚bN%/°“+Ê/á 4÷gÂ1«ª®ªj®'bkvëÈ¡WÞ̤6µ4½r·¸øLƒ¦ÏÄóƒ™ÌÆ^óbå/¢ÎÇã«8¸$ˆ»"ñZóÙÜ6"PÒFã\cld#EšG@»aÐÝ#EIÄnáddÖgXq±K£ÁZW›eÄÅn,ÒŘ9nE—ÁÓ²dúµûeF@ÖÅXæp[ŸÁÿÒ<>›ÿ{ô`ø?_ïÀ“ç‰î\p¾Ù=î´ šƒfϨ£iÈä³'–CÉûáø½PúAëDÝ_ Ä–šÃ‹ìz"·‘tO8œ£hùìVvxÀíôL{“”ŒÅ3áò‘v¨/¶I<ˆ¥VXüSÞÀŒ/² ÎúG„æü¡ùV|“®ÐR(0×`¬ƒØ‚wý9þÿ^ÿwÏíÿo>=þ\!/,§–oÿ‹»ïÅÿÿÊEÙ߯ø¿c'ÿŸÆÞÑ9å§Ö¸ö½¬élÜy#£;ÛÖº‘ö æCýù´áJÂÞ“2ŸÏ%–Jƒÿ÷«ÁÏ»;JÛÏ?uþxûùÒS´`E–ÒSðõS_øÓ¿qútÉ©sR€·óÒÁ‹²Î?u\ÉâgcE£}GÈ¥m{Ì óøŸæj­ ðâÔOmóTìz*½Îy‘´âtMPÿ•X£þ+³-Kj™Y!óa2µŽ†WÜQÝÄ”ÞÊæÈ •=heV;ŠL4:G·gš{ØGéÔQè™”‡ »iqlm©¤ÙbE²íryËÍú””¢¨‰Ë¤Îq‡hé` Rњݥ['zRf“³˜™û$.´œ @4¡œ2A¬ÀN¢m“ä‘ÂìÚÎò<2€Í8³(º~ÂE­J·rì0›ÚC¨.Eæ)Fû"»Âø¿äÿ;ðñÿ'ßÀŒ‚P¢:4Ü8rø£l¶¬¬ÅõŠŠ+¸Ã‡ßÒjoªTèñì””œ¢;%â½8 ñŽÕ:\\ü ~¦˾kµÕT_©S÷46Þ,)9×XÓhŒÅVEúCK3 ãëQ!H§•‘ŸÇWL¬Òr‡ó!€™©Gò üð*–C4°ËƒJÕUVvñĉ $FšÞjl *Quuç±cgQ ’‰õššë”Xzáˆõ­o‹Apø?wTüÍe~¹Ž“±‘K;Æ#÷~ûëÛÙŽõÄéÔçg?·“ͦ?÷$÷ú“ìç¾Þ~úQæõ'­í[iÿ4¾+0ãõL¹¼ÓÞæ ­¼³~ŽzƒîIwh1„OÒÇzt% xïœ@5tp>B.‚ØÈN8øæXÌÃVû¨¡ýIGhé¹ÿ×÷ ÿÿÿ{á_^øxFáÿÿÛ(-Ræ#Þ~ýÃøÿK¾ðïJÈØz¡ò:Ñx¾Eüÿ-î¾ÿ£ð§þÛ÷³þÏÉÇê—´wÞYfW³Š$&Ú"iå'ÔÂl·µ>ùÁ׫‚ÌŸkÛÀ,Žð­ù–°©*êù^{w¾ÑA$r_Us0þXÉ>räMº§¢ì’‰“¿€íK޽×ÒrO]×8g2 =z¨‰û¾³zæó @*¹Ž`<”ÁilJÕ…>ŽðdÑ[èj úÛ<)Ü­ªíÒ6Ü0KŠß¥4|6œ ‡}!UA]ü¤b6”—ÊÅš§V©ºI^2Hò’ÔY›î`=þ—ÌÅjº¤{ECp«ÕöëÉ¡`°ìÄù:5N£_Us ]ayÙE tÖ€À–Är×ö/%aðzM/~µ˜G€0Ù)þ>àZÕÄ¨× œ(#R:º¹ÒÒ³€¾ðEGÞF]§êFwo1 ?'“këë{qßÐõ?%Â)ÑŠàòÿ=~°ãÿÏ2¥ çè½Ä¦Ô]æÀ ³^Ÿ bÚÀ’¸‹÷VdÜ K i*n¡¤(ÕH¬‡ãà'g aZÝ‹p‚ B× S"°äJdx˜N:he˜.½U˜¯§0Jñu!î mKØEÊ~YÎ:‘°.ÃÖW¼]ÔlPK3¶ˆãÃo +œ6ê³ì=Qó±ŽÄ/å—_l‹þb[äZ#¿Ð¡-§h£¼t€Í(Œ•þšö‡_ÓÿÐi=ê°‚å?]Oéù.¨çñ|ÕO‘(Ï;ŸJlþ7+ʯX­£”†i½ëõΖ?‡‹W /*¤Ø5Ô÷ù€=pQªëĉs€¸VÛ(îp+Yaº·¨èmmc?¢-ÖúújCý’’3UÕ@¼ýåðÔ"‘þꑯ11ï b:ÄwZ¢ÿ½©©ë2èz eÊË.cÑko£žã‰yO•Ÿ$¶ ƒÏ†±ÂüÉãÿUÁÿj\HéÁé>õ*íhx©×à™Æã«X8Ûz+í*ª1积¿=¸-*bÎTù—cñUEµ’4 6|~ÒÆqº§¢Ô¢M¯o6?ʽCÑP˰¨Ë5©8kœÜA[àl^ŒÑ éÑäð˜ˆ~¶*‡jiY2™››âÑ•‚$>0a&Ïÿ'üßúØÊÁ8aöfMÕU}#I–á£ù2êZé-Ø ¨Ö7ëóΘYK_€½ €;ì£êÚ.“ö–Åyh2r% åê²”Ü}&5¹ý”§}¤m;ù‰€} Á‚Ív—F™"ËA¦šDˆšN„sžÊ'†ªÓEZFr-8\š°ƒH¾Æ=…âJ&Ǥ’힪ġÐót”†€ë/3æBOòÝpp\N€ç5h.(%q±™Ì& ˆWš8 ³È1¦ˆ)=ÍãÚÿW«#œ;`ü¿Wqôiÿ_,L~\¨ºYÚ²–Ë´ òG»êÙž ‘G)/ZÌ‘hùªÌ’°>ç¦SD;ŸQLÅH–Ûk¦À €gI(ÂKÉä'ñQ  ´AÝç°ŒbŤ»S[ÝILiýÐ5PŠÕ4¤ÕÜÀ¢®éª,¿l6 –;‹ð(Z[(Ȱ²ìv9d¦ñÿŸ8eÃC¬©"¼¡Vu–6àÓd¬åáܪÊ+ònºüÀé*¬Ôèh{mÍu€œêš«ju ÔKfrÙø‘´ «Ž™?ØØ îi¬§q`¿o>ÚJ“ (©ñ¤äÓLPÜ+€W´„/a·d…ìrOP ²b6 £zã†#R ±ö£ƒlš'¬v ä}ä×vïZ¤YÇDY§ÒäÅOUu JR¾¶ö&ê3ê-^‘ÂBœ®èœ*3M{…©eÀ£ÌíãÛ¼kwNò8j&¡àºçÄAêÿïüßÉûg8§„¢™MÛl£ˆ­pùl6æbO*à_ï »ÌÍZµ>ß`ŸpºæáµTl#“ÚÌþ'߆Lx%†õi€µÿ?ÿÿ;ÇÿßóÂ?®}îÿûâÿÑNG³Ö¬¸ø ÚXt‹è£ÉÓÖ4x¼älcãM+O1 ••W r~üG§+ ­ýhŽlÖѺº§c¬QÓP-F# ˜£­þHÜ­Ø{Õ_«©éDs]ÏêÇh±oК•—]Òén£müöÞ`µ·X’}{y¸¢+1èoÓ9èêÕ}~ï\a²~Þ~Tp颉fžJiå\~5“Ý*m¿ðã¯[°üØëæ{ ‹eÿB[~­#—ßk›å7Yog¯VÞ7y/x¯ÇVnÏFe.#/²Íz ‚EárÉSÉû8IVT”K…º@ÔÜк´\K<ýE /'³`<½Žîî›xî 3B¯ávM†‰GAÃàˆw$ðÁº¤' L„½uðò2[–Tžà&µvtÊ©ä%,4/&â9¨+-=‹ÿó§4þÿ]ÉÿÝy–5ñ’û_‹æ~=yêW™_ Äÿ}â$¾þ‡XÛïw|þדí $~%”ùÜç~¡#òã­–Ñfù?cÁßLŸÆ¯¿mý‰“¿Lþ‚7ò«‘Üï¶ýéïŸúü¿óÇ~ÿÔÿUé»âóω…¨ª¦ õœ xÃÍꊫÀó¤Ë·Ôf½‹¯ˆ µš›Õ•x#€Ö°EK¢:=šºlöÀ ¢®ë¡ìTUסÃoŠD8”hå‘R;Û Ãkëûê{ox¼ÓxÊäúj¸USsUÛx£¼ü^.¦§¦æšÙŒã\7o#jó+=qΠ¿õ’á¯ñ*ýP‡îÿÍ?4ÿ×¢àÛdÿË?²ÿÅ!ÿŸ¶ýåËÞ¯|ÚþÅ-gð)ï&"ÁÿÿÙû/º¿üiÛ_¼ÚòÎ˾7>ãü"–ß ÿ)óÌ:m?^^“á®äÖ]S€ A¢Æ)û‰ä:e^{gn9ÿÂåš…WÈ?Ú=‰®íE§eÙJf©÷Ž)¯g–­ôf°‚ª^§é¾Bh€›ƒí( \Šˆ %tG °È4Äd­q?YAÍ ’ïåùÌ—‰¨–UæYˆ8+™|y¤Ùxš&·fåvò3t4þߪŒÿTþï³üaà?c]¯@,V¯éc¥Ê‹&¢¢õ”=[¯¹ÆP£îµ™FÄÂO×Ð_G:”‚J*=:êAk©ªíµ˜‡K޽GàÙ”ü/N"ñ?[#yÝ”|<ã÷Ïš ƒÀ{À0^¢Á/èM¶1”üÿGÁ¿|9ø–Ïx¿øJðý_þcÏ_½üꋞ/~ÆûW‡ÃoþhÖ¤Ø{é®ÕØhêoø¼”E[ÃþæèD|Þ™ººnÁÿÀ3"¢gå|I´@ÏåvN:q¾ù††>à‡€oÎn¿[hâx¾`w쎕¹ƒ¬HÜçYë4ÙšÝ:têÍoJFúÈkžÝ®a×'tçéýg–ý°ÿ+$ h4}fM[76ô 6©®ºÚ¨½iw° ¢º›Ä¥u·ÊJÏ¡;@{G&³*²šE~èЛ&Â1t»—êoàîáaUW\I§6H_¢±Å2TSK‚?è¦åù–—_h¬¿qŒƒ»²²‹:]¿Éx§äè{zým¢?•œ¯®¹f± 75²¢GfÇU† Ç™·>tü_:âoÚ¹ümà¥}ÌŸB5þDÛŸý­sÒ^Š|¥œ¼€'ñšœãEÓ ‘¥!4BPò껩Ñ*€q£ØÊy ]¶ª†R® ŸgÈ1µˆ¥˜Lwt†["/äç¹$fä…­‚xî€t]˜Ù¾œãL@`QI÷Èn3ï±»Ýs7cëà·uÀß”Î÷/Ûì4ÈOÄþ öüÚ*˜m¸LFã Žéå—dúé𡯢R•?ç£7÷ê3î†ÔÞ¢#o›Hõ¼º®‹n)'kÔT]CHe&²ÇµòÒ Î¦ T]ê§aàxÉÙúzâà½(#2ÛpˆèÖ)†ýï³{tQ y!ózw%»oHyIwñ¿pö€E9ÿ—õÿ’ÿ³k˜U´’ujÇr4BžfÇ7Tªdòa,"? ÈGc«‚ú’'9c—ÿ)Ûw™ee4ï^ß\‚&>–Éi+|?DÊK€ÏæÀBs`1جl¤õÀb ¸a…‘°3ÿ'¶æþOxo DW‘5“ZM2f™]]x%õDk!BWÃŒƒfãàÑâwl¶½Q÷¨\húŽ¡ä’ëéU×vK“‹*TRòB]­öVÉ1fijûÑw ?jÐôÖ«{\®)J§Âaõ4¼Oj½×Õ©HƒÅH·âª³iÒHü´Ë8‚La‡CK¦¼ÈÓ·“ËÆÚ@1/–ï`ÂT“ü/ Y-ÄDcˆØVx†¨íÔn7ö#†B'UQq™j¦uWZ_ßg"«a–öPÕt¾zø-ËòNg[·Ñð>üv¯ª¼\Vr÷¶¨èkÕUWÐÎÄx@Àç›s˜I ·ƒàã¥Ài->ƒ ¬¼ìŽP]ÝYVzÙK/ý5{ß<Þ¯ÿ¿ó¡üºûèÑáÿ¿þÿžîø ½YºÁ…@ó¼X(x#Ë-ž)—cÔæžrúgqçHÊ?çcˆîc“_Gb-™ÞÈÛÆ˜G… ÿcŸõ¹[ø3›Ùö'ˆpeøÄz|5ò8ŽsÂŰŸ´4°QŽ Ø/Ù…߬¯øsüÿý‚ÿÕ7‰¥óƒ5/ü³FbéÄ<ŸãÿoÿØø¿Òéœ|¿=ßÄ@DFW„AÁÉS4A,Mbœµh üŸo}ù‘׌?öšåGO›hÈ=?ÌŽulù±×Ìø”b™VJb%ªÆÐÎý×ZÁÓŠGíí_¢Ñ †qhÐ B+Ee½‡Jz_ygšXñ1šSÀ‘ÃÑûN'é QžUhÉÆ´ŠPè^(x/FSØ‹e”&Ùb`‘‰ ûñÿ® ˜èÿüÍËw„—ô·>,õ@ùúÉzpÿætË·ñ3§¾„O,ŸJÿ×Oe¾ð©ôþ¸ý¯>sꋟéøÒ¿xͪÐÒ:Rÿ)õçŸíøò§Ûþò“é/|¶ãKø%?Óþ¥Ï´ñ'^³£ÌáÄ×&2ÔFðUT¤d°¿ˆó² O_‘úálô½"?»¼ =†Ë…aXþöQVįˆò€yðÄŠS ‹G(ñ*‘6iðÞÑWÉ-4›Þ,-9„PZr€ëEoÿX‹ù'“M?ºå_¥œÍz:ãù©”ó#´âÆöX°"ŸÿGÂqøå7&æû‰˜í'|ýhÎû‘¬Å~4hú¹öàO¥]Éx~Ѱ9üÊ›%Åï’)À‰‹¯¼ôFƒº7•7/£Œûôf“s¸Åã™ASÆÄ ),¡³÷ÐX=êZš…2q]2ê$1Ïý€ó¸2FI¾Ñû€IÁæyÔ4ŸwÖíš–ãx}DºSŒØÂ+.÷´2øŸÇÿ’‚‘).=s«w­–÷¼˜­{,nóD ON'þ×hºKOÜøÿã‚[îI…Öø¾Œÿ“„¬oÞA…ËMb x7ó|ûû.ç$©Y5hÖå$bó…žM ñÉéœÄmGÛ.Â8ÂŒÂFÜ%¬ˆr,Bƒ·"Ç”mØÄÖ–û2Ÿ"†ϵXì!B’8ÂãAˆH© e,´øvÑɦ7R€ú®I§gß\lÆ ¾ó£;üÏ’xÛ·ŽØÐ¡!ÀWÑüqOy@õØ7äŸÝÊá“;½xä>`D¼Äq¿óQ^B ¬ð ‚Ÿ]Ã<@ûâf2[GHP@j=üêöÿ7—Ìÿè{ ºçKúƒøžÇÿ$þÿþß×2ð4t€M/šk¼9%äv4ˆvµ¦æºNO"uØ®ÕõW“½Nÿ/ŸL~ìtügÒ¾ŸŠ»ðùsÙæ |4åÅò³ÙÀGîŸË54éý_;TßV˜mÛv¹'µýøS‹eF½kØR_ßçpŒ[ÌÃÝ K½ hû› Ê÷‹ÅWµ¦¡¢òneL£Qk_g4ÜA Ѱt‰¦¾G«½Q^~±ƒA?PrôìÏ&Rß~Ëòšd#VV\Öéú47—œešÄÀì_l¢Ì'vüøytúuªžªÊ«5Õ¨~jUwQÑ;‹äýžÛþ¿ ÿg%»9 <ÿ_ª1²ÎO 0'°€vÀÿèô]Î üê÷ÎXIŽuÒŠÇ”¤u0ÉpÚï›##]ï, 7Ñ¾ÛØˆ…G†‹ÂŠ°è¾œÎ)-ðauC£îqØþ(ð'¿´,âàØ%‘Ú BNxÏfMƒâÃEüÞG¢\uæ“Ã×IÊG¦…r¶”õÔf"¹‘L1?‡’”×·“Šqð*Ø`Õ ‚—N±Øj„²¶©d*¹¯'âa÷Èln^9P„Iÿo´„ï /"•QÈ?YKç[MªV[Ñ8á.f¸3ò™{zJn—DúŸ‰m¹Ö,ÿ— ÿßÀñ¬þgñ?ZÚªÊkGž©,¿¤%%ùkEEo«TÇŠßmÐôÚ­£ÿêoàÙe3[ªšÎâWß±Z‡Ù¤«¸èm L‹eÒb¦z%ò›xXx º¼GÇKÎ54Ü$VUÓÞ³i èÈ[¨<@Âe'.jëûKžµÙ)õ8ÿÂ6У”Ò«é;ÁntÝ­ÊòËÔ²L™œ_­Š£.Z<´fD›ç,x´]Âð‘tƒfÔÌÀÍ7á)çõuÆôf6³ pžaçÇ,y`)›ÙnÍ=ŽFHžË>jË=Æ]Â…DZVÈ.AÓ½>ïÅ‚*äåÄ4}~?%yáî1¼G$5†û )±…³yÜÞYúÉ9ÙäŸ#Þž-@;¢ÉÐRØMlRY@È0ß4ŽÎŠ€=Âv  €ŒícEæP@h?ø”Y'áÐ '›~(#ÿÀü-÷Zþ;>èxŽÿ¿Ë‹}å£Ïð¿íþÏ|oóÿo3þBú?m “ËòŠZQ`CïõLÙiC\YÙxžÐ‚c-^]t:Ý- ¼û$``Dr¶Jih¼ R_ß fS­ãz]°»Äòžãä˜*ÐUîºtÔúž&ÔgÉŽTº¯›Îœp\Àv¬¨š»4¡^4æxoÆ;`ˆsNàM”Ø?YW×m³ŽàÅ®:q0NRš;ÿ7ÓLAf3EŒß ²hLo%ieØgŠ€Áv‚„î·ã©—ORVã¼^õO_oÜ]^kügôÙðO^¯ÛËÿùøéÔÿòzÍß¼üo¯kòž±Ç‚öû‡-…IêÊÎʪ«¤’a­­¹^O²ä;V^~ }·É0àZLSäØÞØp5 =ÍK/~YÌæá£Åg|¾ô±@åe°±ªê jBÉÑwËYOôúÊK/ØxL¤¼œ¦­ñè_þ“¿Æ ?zôÝŠŠËõê^rOk¸yèÐèâKŠßÞ«©¾FJDêÞý¬é§ðwñуÄÿ¹GÏðŽöáÿ¶y;öúoE_ûƒÌçñù‘ŽO¤þì?†OýNüs¿›ø/¿=ý#FÁÿŸtÿ9j2útܱ‡@ìÉäœA_`þ[c(óÙЗP·ñ˜ÄïHspÑíšD%Dд7õã)Þ—Lµ¶îæŒ<•¢LåÇŸÉÚ7—OÉv ™8Mjv‹3m7„ù#“52m$ÖÕŠ83Ç>;8'ôúÛ€‚CT(.sxÖåpEÑÞ=”¼NÖ3$ƒ¶žåméé[F $¼©É>Æb¼ï”÷aÂ;ˆ`È+ÅÅgTDê-ų3"ôFEEôІ •‡fÇJÎÕ©ºŒÇ·ªÛ¨Àí:ô⚺^Dz-9G#,zµèmtje¥—P—ª«¯ÖÖt¢!-+»D™ U×*+¯Š.LÝf·Q[êëûŽ¿Ëý¥Ã£Ê¡fbiĶÃjB¨%±¼N{M.® µ·´ä,ZQrQÔô”;Ÿa±/®Ì:äøùÊÊkååW ü^ÔÕöT–_©«ë!¡ZFÀ‘q‹ØxA·–¸šJŸ­®ºr¤è-¹èÈ×*Ê/ŠýÁËòÑ.øÐÁÿÿ?ÿ¯¼šxý°›¾cœò8 Ýãœr"rB,€u÷´ ÛãÕä×[î…Ømwí‚öeü_À< ]x%pN¸xh„*ä`]rMH(btMº¼l4Ö4ÞZ"±Ððr¸ýI;ðóÂsÿßïêò×ËÿžáÿOtVüwß“¼.oVÿSÐÞö¸½Fû÷µ m2þOo,Ñ3<&)ìbɘãD¹Â,?Zþ š)žY…‹ b›ˆ:œ+Ø&£¨¦l%xT'%Yº R¢ …þ1C“­™Ìv†ÿE´”Ñ£eÛdòµ·¶»ø‰>¤/ A§Ó¦mYáq'… P§`Ò„åå¶7¾édÄOŸöHúó§Ãß´ðÿôz™x‘VFüaZ¥y˜WÎW>eŒ(C±­\V–q&r3ŠÛd{EI’ù½Øþžà@EÛŸ®t‹îOFA¼Ë&•‘ñXê¤çEº T/ ‚˜Eþ¹b, bóî¤Hï ,ˆ¡m”0!$™\—?RèLÙ§¼“öeãÿç€ÇÿŸ±PÈ`‚ÿÿv—ã'Ï“íffkŸM¶Àþ¶ÇOÞµ=}O>ï>‡øÀ[$‚ y¸:Rî *ñÙ…“ ÷}œmKË}™üEÿÕL<+E" •½!¶ˆ7KW-ò¼Û„´ð¢'FŽÞ¡{¤hX`:Ü2®¡+ßEO˜.Ç1.“†ˆ­ðŒ,¦! »[Í#Üs!øu‘Cܪ}’} ö:Y$€$@ð[Û–º®ûàÆÿѧ¡»K¬'šHÍË!Ÿvš`´âS¾Ê:Âõÿp=¸Î0¿xù£ sæJ"ö N”Øõtb-]‰%¦ð%ÍCVIø•)²»gš(@Î §yÈ,§ìsÄÄ .xŽÿ¿ËËñ»Ÿø{þKFþà;¹{_¸ƒÔÿü¿ÃN(Oé¥ïœdüOâ‡Ñ•å×L†;hsФÈ̲žtæ\Ž µªGO ÌÃD³´â׺Ú.ìÅJõƒNû¸Û9…õxl_ëjðÓ#£nÀ¤¿ÓÈ‚õ±‚#×kúhžZÕEÔMïl5«bñºIµRS×ËéÆ Mdh;¡®íAÏ‚¿¶ÛÆêû-æ‘&"¨àßÇTµ=ø\Ž@)j¨S8a,¬cOîèâ‰áš¢ÆŠÙ<ÌsÊÓhh{p¢ÖÑe ªÝ½Oo…ù²ª©«ÒrŸÕÖkõî>}p ˜[4èL¦‘Ÿmk|9ü†Ù;dö Wë®i¬½ZÇ-“{°²ñŠ;5%ø횦®§¶æºAwø”F݇~GGZý#.÷´É<,"oõš¸ŠHeÅ$×ܲÙGôì<ÃŽî NÕãtL`·ÝN&ÌÝ+žB©ÀÑ´‹Å2ößë¡)Uà(4µèVˆníœ~–k°Lår]dzKÞô$ì“Ú`bê¼Ñp÷M¯¿c66ôëXR³};qå¤ë>Ì`f4e2 Ú-£ßÿcX´ø`ýŸM=V–òÄ•ßËüéoÄ;~'ý9¬üVòõßËâëéOäþìZ?ÿ[É×>Ùþ…Oúµë¾uü4û.(ÿ‚JÕ›ŒÇgf. j£×M¼ktÜMŽqÜ" kÉ—ÁsÇã0óM&‚±mLCÖ ï+)X’¾Vƒ¦ð€m›èr̨#$µÆU͵„±€-¼b6Qÿ„êG†_^ˆÓ¼h³ßåœýaòËm;¬w½,NŽ,cÁãv6]œåpgEå ¨±±Ÿv-ùˆáCã½LÆ¥ú ,’%~òÏ ßž!qC¾çr“Àf '›ì p$V-x•2Žb˳Ì6»Ñm3gã‘ÌYHÎ2…®Y65ÈËø—’±orƒ@Wr·ÚOÖc©Ô&û2¬FXD…"bâüozÜ3)üI3$wUN¥7¡å‚E¹Ú)ÎS$ ñTÞ›5)–‚éăVÁÿuÝ¥%nü_Nc£ò*¡FUT^AüMÙ¯žÁSFp$ù§µµ],˜f2 á+ªóÓ®VT\Æ“»ðñv›Lwú¯Åã«d$­º®V]G%Ä_ 1);qÑjª¬ºÂ‰Ø·­Öa<8ž|¬(¿XU…ÖiT¸d ½vÛHeåe¬4ò|% Ÿ(» ÕbmÈ`IÉ{YÜÀ™£ÞŠ·]Ú‚ÊìžfAË 4z@ÈÍÍ hñж‹å`0лÛ9 Œ]¯îAõF˜ƒ7ïN³ÞjãÉhÒ‰E“å÷/H¼ƒ·,“ÞDOdµŽÆb[B÷Y›t‹RVö ³ù.™Í9§cѵ€ŸH;> ¢’wQ‚”|B=‰ý"ŽÀ} p#½Þ§¡¡Ÿ…zÈqJ8tm,â#@X¿oAtDéÍ5 ÙDõs‘(Ð}¼¿8‡ g à’}LÒɱí2efáð2â+ꤣi÷—ƒŸáM¤€"öMà} yAab”/ÆÂ¹œ“‘ÈŠÝvwþÏ®™E¡>þÏåñ¿úúуÿïøàÔ©÷ÛÛ·âÍvO¹°øf½Í ¦qú^<ç–{¡À¼ß;ãiž÷#’q{ÑùA«`/”Ä<“ [BK-X‘DøD\Àf,ÄL ò ù_f pX„@ûÀùÀÿèÁd"ëh€ÿ±þÿ÷—ß¿^n_ùè÷o.ÎÜvÿg¾“‘ÿï.þß›ÿ»³ß`w”I]]é ‡–íŽq‚y$µ7 È)Wä5j*äd+Â=Óà«Eï6?™B0ÃãGÏFc«Àu€RµÕ8°eƒ¦÷WWzü³Ýz·¡¾¡h½¦7Ñ0?9ïèˆaE‰æ‘#G¾fä|Djèv±Ž›fc¾VʼnË( (RYqµ¸Q&Š¿¥Õõãä?[Y}}=™µÕv;aïÞ±rༀM­Vâ¸É¥ÁpþE8ýPò ílÇ@|Ô:ž]só¢¤Ð²¢àœFsƒZsx¡D„P±d’Ý‘PuƒYÍ}@qìñˆ€yâåjÐÜ`ùñ±`ó’IwçãvL²þ9ÍIÕVu"&Ê{Ί^"]¸Nwgâ$ʼnzÒ¤ŸR,¬¹! 7QZ·kÒdÀM@”L=Ô6Ü@1Ü.µŽÖÕ\Oó¡¦éñ¶êT]fÃÆú¾šªk- ÓœEMîƒZÕÝ@$ʤp:ÆQ²†Ô´n49ÆPóMÆ;˰ÌK>5çRüÉ#¥'ýÂÿÉ­9eü¿ô`ô? ÿïJ?Ì\H¨Gû cÑyîͼ¤Àv~£7åØr.ˆ(I²S£y]YÖò%Ñ1Å ’žðŠ˜âá_P[°h%Ö'xôÉ$Í ¾¡nà3œW â1€Kx."#,ªX °T÷d6 G±¦ªÍ‚„½Ü(u¡ÑCåAÛ^^qYš©Æú›ä{¥éA³‰· I]MÂ:µªKMüRr1F°ÃøwM4ã@Ò¦%gÙ¹¸ a‘Ò£ÔÔt%x[KK/ ÁÍ©ªº†ê‡Ó@î˜nªj»õàíÆ1‹_=c0 b;Õ¼žå³dÈ“ëNU ì$Rz- TV^R±*vǾø‹f‚è¥%g­æ!T³ââ3蛊^ù^\QyÙ%ÔLa+aG<´Q%ÇÎb—ꪫxYxÌj»TSï0i¶ #ÆÁÁqùÅEgð^”•],&ÒÔˆ—òzh²LÛHZ¬¸‡hLpùøz¢äŸgý¬ŸrµÎå6ÿש»^=˜ü_1ÿÅgz=I‰#ÃfÒü™h"?¯)—sÌn4Ú†ÌÞI'9ü9ß#„àyèødb¿Bõ¡ì7’ Jš€¨úˆÚ'Š]R†%€YC^¼üÕcµÓœOøçü’üúë§±ñ9þ¾ü]-þOÛò¾‘ÿ×ÞàÉÞáš!D’°ÒyPAa›õáW2™í‚ ’0Q™ÛCCm¤-!~r2µNÒÇÉuáü —‘ÀXl%Ï/Ú”ÉM–YØBè‘bq žn2Ì–BÊ(Ìîæ(‹Pú»Â¨£@ni½ó’ 4~˜bST>þ·ù-ʯØ=¦Clo‰Üqç˜N“%VD×"É<ÛŸïhÂÿáÓ†Ÿ<Ýôí6|î]þe‡]ð?À’ˆc$™$²{ÄŽ¯ag*’ëyF …(\šL › åEÆÜCÓ" |>ˤ)‘ÞLÄ×xØsL.ÓÍnJ¬ÂY,ÈÎekyÒÑfÅÙRÒ +”¹Ä×¾)ºôçi*ž·Ë¬JšÉ7/øõ{ï ñÿ^Û¯½Q“Á6ź7Í)r$>– wEÛ·±…µòÄ]÷œÍ(døÚBù¡”Ð*Ï(N·eSó\7–QÉqp‘¾Å Lêd’µP¤Æ¹Ž˜Tô€h÷<§.ÎÙšÎ2€1ž/ð ÂmtôˆDŽ—žÜ*-=G*@œ˜yâÄE„Õ(Œƒ—•]:zô]›ý..X¨¸¸èmU]7*†º®çÐ+oV“•™®?úðÕ¡Co§‰¿êÑ¢3'J/”?_]q…æ‚Kå%ç›Ècz‡FÝ‹#àWúkbÔ\¬UB£âF#ùè´·I¾[Ý&ªä&°KÐÓà¼Ï;oÒ áÈâŽN¢ï¶ÚFÐJc/% ³Hrv =;z:n ²Lõ2e¤šF¹IÖFÇp õýVæÓ¡HÁrb0ka/¬ãôð«“/ÇÆØ [ûY6m29*Rvs?¶ãÚѸ54ô;ì8Cÿÿ¦ü ­ö¦Õ2j2 ;áºL¬žDœ%º-½øl€„ÛȘœR2iªBÕƒkrFS¯#Ö.“žÀn&–îê8GŒu¤»û :2‹ÇSkl¸Y¯é«(¿  UCS=juwÙ‰‹5Õ4T^NcJMî€D97Ý&§Æ~½î6žxuÕ5쮥 š#pØÇpæt! ýøIx{üm·³O3ÿ÷‰*úŸußD\â€ð!w²™)Çè(QñX»†€ŸÌ¼ ×ùBZƾ©ôz’uW80$þBuÎïxàqO“¨TœÀî¦RNC –FQpº™O5ÝjkÝÉd69xy\¸óŠãRÛnú³¨è·lïvMš‰ž8ô‰¢¯’æÓº%ÝLeèôÈóˆ¢ÎM+ ¯œÚŸÉ‰°g*ñq29ZÁ¾r(‹h#åD:ô­Š…ß.ÌÎWãFzÊQº•¬iW[s’ÿÛUZzþàêó³î!òN¡~¢¨a3¼ø”‘AÚh‡¿‰è¦¬ü’³i å9=–*ð?Ú^ƒîVMm'bF´f—JŽŸE@Ç3‰ý'Ê(šÃaYovïxyÙ%Ü14¿¤fÌ‘Xý`EÅEÄYv;ZÚkˆ¤¤Ñ6SEIÉÙ,%•!NÑì4joZ,CˆF“<àSGöxfÑ$|ó:=ÍùÒ¿èðº9mcIYL#¡æe‡s‚CÚM&ÎͲåƒKÛl£h—äB8årÎIÒ>†â çþU£¹Éa&1QÝÄšÁ:®ÅNÒXR Ú;賨°Œê´vë˜A?ˆ#{)4ÀB y?»-x´ŠnÏ,bv4¿^bÁ‘*âþÙ¹'ðSKhÙlÁºÓ1ð-¸ÓÕ•×Pm,Û Là˜œ"1…zmðéŠeôƒ$O0‡°w?î•ô€@Úø¯t ½ ðÿ&gAްìÌP¨eYÛ(÷vøø}%%>ØGÅŒRÇò׸:—‹ÈXÿãÑà)ˆJ?.€ þñ ®]î¹Iº§dôµAÓ§aQ¾ö)ü#Ö›šÆQF²ðLöxŸúQæ öŒÿïü¼‹ÿÕÝGKÎþ/`Χ–BÅFÐíç’F݃› ˆ䉋-)y¯¡ñƉ’óBÜÃÊò+i NgðLŸ*CÎ ð¬ªúª?0v8Ç-–!ÇÅÑwYéyâ Õt–•_¢¯e±åäIeèÄy·gÊl´Ah瀚àçÈ¥ºê*žŽÓ1^üê;”þß4î°â‰à«^w»æŒº_=ü5öÎíXÉ»:ò"é<~ü\}=e Ðe6Ü,:ü5uC_Éñs¸"‰µ5¬A¤¥Ä‡2ÈpÏ’Zé9ÄìUUW F’™õ9ü;á±#o!Ê3èozåM‰Ovãl ø¿ÈŠ¢ÿ/þ¿­¢ÿá@ý¿ÒÑ Rö€˜@°¦®ë±Z‰ýNÂJNÄï7€~Q‡4J ¬3ërM ;pÔë›ã–™¦K؈A”Ƕ…×§¼ï,ã&Cô…ÉHa·Ö¼5·Ø÷y(lPX$s¯ç²´'ùüY¥C€ Ýq›Ý Æ Ç nÙÁø¸ b¥”60ÉÆdqY¡fß_æOrÛ¾N„¬Ç©¡Nr³¬4•²cœ,,¥d”ØDKøÉåœByæ,‘?3yHÉævXáFO)F’ª$¿ãpŽ {"öqÃ+ÉøÃ€—˜9☉ó§T ;"^“°R¤ð¿‹®JŠ —г¤Ùö¢%´Ü ‡/ñ>£cÿGÊîgË´]ˆ­8qxí<‘‚Â+Ø]B`|%i &/e÷$’©{áÄbKt.@C÷ÂÍ AÔb ùÀ|Ð5é¶:¬#vl2¨aŸæ!‹ÐûñéœpÉ.ØXHøþ#0ÙZ íG,€`A£øÿ?_þn—ïšþOÿ³&툽¯´óh”*+®Ê„ª›’’¬£èbl¶Q¦¯¡þ¦PY8a¶M™É4Œwßç›3›‡[Zȵ¤¼üŠèü¢‡bùêž,摚Úë"ÁívNaw’%4 Õkn˜MäJ£%Gª ™]µÛÇIœÍ3g4Œ›—QØÊ*FÃP(¸¬×à¬\®)»m,{ØØ@ÖEøZˆPêÕ}µ¤ÿ|§AÓ¯m¼E ý€Ápí¹ Wâ4L†áxlÕhlÐÜ –fpY­ê5’–à œR½úIßhѾ÷û’\¹ý.:Vœ§ª¶Ç@ó4œîdÙŒ2 º³¤öÜÐ6hÔ8à ºî†^7ˆÓÀé´8+lÇJƒúϘ<¬©êÄ%S“Äɯtƒ&ý`À7ïbB¯×5iy€~[R‰õtrÃnõ:§ÐkàòÕµÝè8Ò© ô;¡fâí{=”&àqM£ß ûwÎj ¢“eÕS뎬 w ¡­Ô&¾¢³ÀùÄY¤Î磨y±™|jȰ}¢ß7ÏÖ‡mBŒÌø$šI|ïYjZFžQ¹|\К#q¹¿±sùŽñÿÎ~_›÷ ëbfÁ4€ Í¿›†ð\fPwÕlôº§-iŽq“Ꭺæ:^‡$¡šêÒÖßÈæHœSo°X‡u 7¶Q!WðçÉ'Ye(ûIXÖdÝÊãäCxü‘Œu³%/P¶ ’ìZûXFÔyÔýQ~å±$„B‹²E"Zò딡ƒ2í;­í|{O=ÁOX„äCøäcáÓñÛw”ÿb\qêÔûX°1[ñúÄüw?ÑdJûN8rwåƒ-Knà²"¬ÎåH›ÇÄO(O8Ö7ãóÏú|4—á°9Ø 8‡Â7‰,ùÙù剹ïd¡°1"Vœº]3ø5Däð"l…£¡Y#y™à¢ŸÜ„çq“a‰ÜGÉ“|çI²dO Óœÿ+øxéø‰³„ÿÛÚöáÿ½.4ì\v±²â’•ç›Õ×÷/9[Qzòðá·Ðv¡2ö¿S[{e(/Uw[rO$a§ã?…ÿŸuC–•LÞÀnŸ]¡d:Ÿ–Q†kd%³÷/ÒÊš~5ÖÔ\«,¿jY6[¨G@‰PTÏ2øbfÎÖÔtºÝ“ÇJÎ’¶˜u”•ü)C­ê13—’T§âÊ`‹Ø`ÌÇX¡T¾Òºš ¤ä‡S¤¤”‘b²K4 Øÿ0ˇC†dbC”¦€Ø›ìããÞëxtÕCJ›SèñRs~Ðreùe±çp(mc?ê§›æ‹iž7Zj+O×N£û *‘{Æbq»¦íÌhB— —ì'j«˜_ôáž(&}ú2¿f/N„·DÊÍlú¼3è ÄŠ1LAÓ"k(#$Á"ƒ3ÏR€¤eüß~mÂöÁÿw|ÐÎÍFkëvÖ;éôN¹šg}ˆ3^„î»vï˜Q@hÆÛ2KŸæämwí¡¥–àb¨ÝýsüTpõ•á}FøbF¡Ax9RHò—ì`Ù]2ˆ=Ó(é°Ýµ¡=! û¨íåsüÿ|ù‡ÿ…ÿCƒ“ímûÀ¿²+â# íššëhÉËË.£)«ªºªmèw6M sA—j4ÞO®ÊÊ+Àÿ¯A› Œ­Ru¡qóðH#³Jnu[,Ã5Õh tº;( ìd2ÕÖÒT,Z¶ÊŠ«@GÕ•W«û9訮&HÌC”D\ÇÉPn ¢ü šb´Š¢„? ·¬T³×¤™ÏÙà&¾ftu/9g±Xmu'+™¬ÛØõÞ`¸ípN …ÇW‚ÍKtÉU×p>Š€‚èt$åÁ¨ }m£°¸‰Jz§²âš£i çÜì_DëM:ªnØ—“¶ÆqEw ÚãÖÒV¾Ã>Žûth…Tzl£)Æÿ€”:ímS¯»}¢ìBuõ5²ƒièõÈÛ@ªÒO¡,9ú®OWM ñ5ÊŒÐÞ®­éé`ßøKËòSÖr‚ÉÑh æh‹$ì3ôÍ[Ÿlrä¾Yˆ¤@R¦yúUԔР³;—šQ\ZòÞÖy¿ò‚•á^§•tfŸ¯Š ð²-)´xãØy|"y€j¦ª#ü¯×ݲÛï’¸%wO£+AƒF ~#µÀyšœ—DŠ M™×3+Ó2Ã+’ŸX—ÉÙ(s»ìÎæ ËŠ¢Àß"% … GHÆVW^CÓ77}`ÐßBCZzôÝÒcg#¡e›u´ªüRyéy»õ.ÚUmgUå%m}oyùÅhô¾Ý\ùe¼2EGÞDOWSyµAÓ«Ñô:ôU êºpù¨áèΊŠÞÆaËJÏ#î@‹¡×ß:tèM¿o â»ÆÆ¾ÊÊË5”I4”Mo }>Z| µ¾±¿¢ì0?î9â&uugƒº7¾¿7yäYþŒÿc©S]/.>(ÿ¯ö¨1FõôΠeubñN»›çý¡…€g‰%0íñM¹`Å:btg‘Ÿæøj+,ÚIâÿÖ´7¶<Œ§@aB`>(lR)žoŽ®ÄBKa‰Dð?gxÄS h_,€ÙÐÞËHÏsüÿ|ù‡¡ÿs»Àÿik{Ô¾ü+JNÁÿXdT9• Mw’ù*ºá ÐõχƈZ³.³®2Á*lžú”sX'ݹèZy 0abkø &Ã𼪸Ì0K‡·m– ÅDã«ò×2ŸËx@™ÏešÝNI@¤QëEæêLD¨…©ZBËøÉ˲ênÏ â—0€áð ~¢-ôu•Î _f8|_¦‰#¤ù°.´M¢Q#GR†¡Ï3}(®|Ä7Ÿñü°RAØ<½‰µ½Í8ç0)HÜøBáeÀW‘dç^° 4/z¼³AVé!¥¾ö€^. »àÐwˆ½ ³·,·„î%’SémôM–ø){ Ž`!šjŸI&d¾{)¾«¼ã² .À3ºŠäÀ–=xÐU%™BC$±Ö§sÍü^¦NÕ]üê{ßýϽ÷{§¼qç[sŠÒ»¨ö§X>»´íϾ¶³lWÜ Z}È^ï“OFÐI2ÔØO)ç“”-íDʗߣáôöÊ|7 pÒ7‰á ã”!ú@`¯!‡Ò7ÃõZJÀ©UuQ¢ +Y)é€ôØ9{åVyÙ%t„8ˆøk±ó`0šƒÌó?ùØÂñ‚(Ãã ë82ÂŽ¨Ó Ãnsì<`³Œ(é‡þ99aÒf¯¥“{†ÍQc5ê.\5" šj©¹Ž[gã1œaÑ‘·EùDƒµÄyV1UA¨ÑtÇë›AÝ.=~žâŽòËØWÔTYq±¦æš^ߺ- %\&Χlf¡ å’ÙxG×pSÇTu]•å—ÜM€Ž×ñÖ f×ÓPsé¥0ÑâDÙEÜ: ö<øWðû“Q0güOüŸÜ†Œÿ—?`ãÿøßN¶½O3 «QgÞ²Y"þjfn‡Úgj+¶ht:±™¢&nÝç[ô{¬æÑph5Y‹FF#«ÿRTi£Ö#Ñ5,ÑèZ °ÔF“HŽ]!,-+@ã¡Ð}V¡¡òÜD¯Ç¨Mf®#1'Ѿ¡£^@ZÂp˜ÚsôÊð•8-kÔVcߨCi¢‰á“$ªÎ3Î;ÞGy¯(·cßHl-]õpnNƒåI©Ùq¹§ÉcÍ~”ôÐ,ÖÑPË}¾qX¥VgÂr¦Ò®âm‘ß¿ Ð8©¡.„B›IÎ[çíë…¯I&O¦¸·Báxr´z’»lIŽk”(†Õ‡V¹U\Orד裡“JqN="MêèB–9¬XG7J”'™ŒH?”$”%° Çr‹)¬ÄªM*Gà \e뺤i ¹&=:Ná—®$]ɶnSdܳ 3›’f(@A±´B…¶qïð*vÁÿQXÑÑ3ÿsOZO~½½õI0…1àžõ4M8({ÊI½I§gʘ£é€–ÅæðRsqr™Í,‚~¬DîGƒ‹!!ùfXGçÆâÿa,â&ñB'[µ¡ û{ÅJ ˜øŸMÄ\ØÞ4ŽŸAxmwmŽ1‡¨€æ¶sxãñÓsüÿ|ù{ÿ{›ù?þÿmJ£°:sÙÇÙ4ÿV,¼j·’Î? {ÚÆÌ¦t+fÓ°¶¾½¼º®‡té9‰I¯»-R„Vë(I˜‡µý$¶CòÃ@¬—Ò­£C »œÓV3k ùçëêz,f’˜ '/rœ°˜‡‰„Sׇ¿3‡H$Á1ÑÐpÓfmÔö£ µYG±Ån'S“y½•Ÿ}^´Ú[a˜ðT ,„³Å1†A†R†…ú͆!umÅ2Z]Ýi2UV^ÕioTpÙ(ylñY¹]”ÞˆX¯ª¼¦ªíÒëîàZNœ¸U2æ¸ OIê2bƲ$©=£LyÉͧ„7ó}Ê^~þf~0mw€å‰6Eœ_”p>¬A®Oý,)îVÜÎ)£îŽÐ!HËŽ}Áñ5ôhb™Š w:'xÝ3~ïœÅ:ˆ‡ÛI,}Œ†¾­dÙ)¾~?‰Ô™Íø|sØBêl_¤„§%Z&ñ%fm¡°‡¬Ä”&x/ @`'Umçá#oþV/‘I);,f¾TP=-¤-ãqˆú“ŒyÊ'Yïɨ¤§ÙRŠ%m•ŒÜ4!›Ýµo–tKy¦(€HÙj‘UÕ1v¡úÇ!þ¢ñà"î¹0Ÿå> Ç@¥eÑÛEio[!ùpÚ‚æ-PFíÿÏ޻řfg‚1ûc÷ÇÆFl„w7bcc~xfÖíËNÛ³¶ÛžÙXÛm·ûânwWµJ*BH2I2I2Éû„$É$IHò HU݇·{<í¶«º»ªt)ݸˆ«!º!@¨ºgvŸsN~ UÝí𚎙)E|‘ñå—o~×÷;ïsÎ{Îóäeø„8+EÒ±/²¹¬¡œÿ%é1€%j.×AÀÁ„Ÿ ¯¤³èºL{K PÛCxZn ß²ƒ‰sˆ°w ÇÍïg&ÉU@ ¦ÐjSÓ*N€;ó’L7ÀmlXn‰®“ÇѰÔD˜òÿƒ ÄBßz8œhN ŒT@g~'Æ{ºuppš£Ä6 PôÖ[?Áç¾å4\2•‰ø#©ÿÕUöNJð?wÈm.8}¼M€`û±Õ2i4Œè+ÊJza*ý¾EX¤jãH¥îzyY_•þºÅûÕÒï‚CÖ¦±c†³æ>£áfÑñ‹•Ú`àn8x¿ô$Íê Ã%%½ÚòkسA?ä°Í`çšþjÓˆNw½J?äõÞ ‡Zk§j­ðÚ®S>?%±?‰D6"‘5q¨Äy†#køjZ=^p.*® .^¨q•š…7Ð@[Ñw¬àý†ú•hä¶™mõš™Œ£%E— º¡jý0nB$´Ñ\ÓhzŒúa =ì/j+úkÍ4_o}W¨!p'†aEãî+J\<‘¼t2}éO=ßù’÷»_ò÷Ïê¾÷'Ž¿ü¢÷;øŸwü»BÇ9X?¹Ò½­q’Ò®æÖ¶G¸«TcË•8.× sÖqaàÑëÌ¬Š‚AÓj·ÔŒ¿yô}k¾Ö2Ù¼ç´MyT²!Ôã$"˜M y¢bsÌVX™ñ®ÏOy³ð,4š>IÿE2;׎3˜n8àÂMkÁà}¼¼ÏB @Ô èö^ï]Ÿ÷Ž”'ˆ¡ËclÛN§¶³6Ù\ý/¼é£GÏþÏþ¸³ëÿ}+õ2›ÜIE6šCÃpà4®£ëÍM$wÖÈú_Ø€ðý×ó¶·>j‹®Åð¦Â IÚ¿Dï…öß;çm´¾õ“·øOtŸð0Ô0eÐ8’üG þnÏÔ«Jrš° ®iWÝ:Ϭ¾lð+üÿjù4ñÿ¼L§Ÿ‹dgµ€M¡{BÝÀÄ2¦ê›¥¥Ý° f3…Ñ $üt­ºšf-ËË1 žeR šâ¬à’:‘;1TÝД÷X,£¥å—ËË®ròj¥¶ßRs“óI®Œ7®)£qD[Ñ[XxüÆ>uÚ¾Pè%¸–a·75¥=@°44‰&Âå˜)-ëÖhz1”•uWTôÖÖÞ²ZÆ úÁšš‘ÒS—-5£±– X{Œ °–¤¸ú¹xöwZÓŸkëüÖÌïb=žúíÖÌoEÛÿu4ñÛ±Ôo6·c£Í1Á‰=·}Þyàj³i¬Þ¿#ì´ÏÀhÛ-S¶Ú){ÁZ;I1U×|,ú”Âk-O9õ¨%ú¸M>´ñI+O%p,‹ÃbÑ–æ'Ñ(oŒ>m‰RKÎ5Íé< BÀO&Zã‹ /˜ªˆÉ. .°¼ô*ÆÙjÃ`YÉUÜS'/ãvUW`‡kôÚk”@e#7§ à,î3îOCã²Ç3¯)ëƒóRZrE«½¦×ôéàòX&JKz1 4Ôß+,8¯×ô{lÓ8´N{½ðØ9)a¨Òß8qâÃS%Wð8°”•ö”‘¤Î‰¢ vë$ÖÛãÏ€c1 áIUU eµ~ˆE¦d¬á$ Ö[}ßøÆ»‡‡ÿ»:áeHËyýÇã"úMÖPfnnaabþ¨MÑ9µÕޏR¶%!Œ¼y-<)ÓÉ­òò^ἂ…ŸX^Ö‡÷§¨à¼Õr 7à§ääªAÊ ày .*|T\ôa…¦Ã=¢g¤ü·Úñ†ºeÀ$|eO|ï ÖýôbÎÁ+Ç îvÎb'uÞEœÞ¯kÎíœÞ#¡´º»@A€axgc-qDœ›Ë9ãw-¸lÓÊÙž0È,+½f³N¡™×=_XFcìK;^Iz—ŸÄcØÚit;¡èi5½o¼ñÞaæ³II‹*F@n5zµT²D›×¼ÞyüÄbÛ÷ŽI¬i]Ž9›å–¿ŽÊ²€ŠaÕ´V³D‹´ý…Îü\ãßH¶ø|óè@G*.&™*·{OÜnoÜ•à:zN ¬¬‡Kº&áZ¬·¼>â¨ìÈ•„ÿ˜œÄŽpÇ€À0îd;r%'0éÍLc+\U¬Ëö"Òü€’E|óìÿÒb¶¯_j .;(>³ÈS¢k¼Ú^tìzæy©¯§¬¹æÈ*è`.6€4Žû¥Ø¿ÿ¹þÛí)ç´5’À²”é˜ò¸¦5T?/Àíš¶ÔŒeÓÛ4¥WÍ–›V˨®‚Ëà>8lTG¯×Ãh_òzh~ Oû¬Ôõk1˜†:2/°2JÚ¾#¯¿k­³²°&Ú`Ì-*:o–ѳ‚xÉp£Œ<¯‡³¡~)Y;zä‡ÕÆA“iw‰dȌÅÇÏã)x<38ŒDŸ¤Š®}(ø‹VÛóÚkïþÇ3?óãÎìNG«¿[ßt¿I2sÎC+MBé#„ü@ËAóbÑÞz¸"æ ÀfM¤S‘â_¬áÛã8¼öŽ,èÝßPß=ã q°Èd¤‰7Á 4- Þ9ï+üÿjù¯ÿGð?s•dÉ,Ÿ9ýã3g~r/À™Ü"Q/2Ú§?’pb.]öŸÞ‹î •JGç®äåvvQ¢oE/_vv}$Ù¹]B¦Í ;Ì’â”ãÓ„Ð^rúñ.Ç)sµC¸/:9†™Qcž/¤ž‘ã¢/2DâM–¹3ÿÌòNK²®{$zúêϵöX›¹ðfg.Î)<äjU-¥TÆ,&*Ïì(ÕÝÜ;ÕLÝ\:.S¹Ðæg‰7#›U®r[äW5&ÜtŸ¹Ð·1&F¢kRm§$¢Ÿ¤¼vð”gŽöœ%ÕxçÛB¥ž Ûf·Ã‘ՖغH¹%)¸½‘Ji'Íb·?mkg‘šÖG|ªÛ eÞEbmâÓÎé2Û5ˆ]ÒV4ºÎ§½%K6»»_NZâK´ÐÐv䇇Íÿ©ò´ç1%Rf8†rÊ*®»=³ A’£¼L¥¶Ý!bÑlf‡&Gêï⊰Ÿ¡¦ÕHäa:µÍ4†Wp¥@,úEν_v»§‰‘»nP3“Þ‹$X2EâVÄd;­Pòmz®A˜qÇ€Ùp2MÓL ÎÛœä¿Ø$JO@Ž–ØšðX2SúR˜1›“Õ®±gìM[ÞK»þÎíšavº¨ i- q;I¾ŒÇ33ĺ×G± ìv»XJUˆg-ÅÛŸ56®8ˆöv ž n……‹V¤V‘5”oãœáƒÔÕÝÁÅVU bcSÓj¼í©È‚_cÒR;ÖÚö˜æYÚ7ãœïa³M M 'ÿŒÁ±rX§ªôð/Æ‹O^2‡«M#pLpp úJZ{|ôè{€ôp“5škðGà‚]èÅʱ£ïUꎜ5׌Ô‘/m¬"MØÅ…R$Vƒ|Rã0…/´ý‘Èš‘ý,îzqÑEMy/6¾yì}“ Àu¸°àþ{äõj5Ä!L Š­¤ÚÖÆzRò¢¥øÍíè|ÙðOø_×{¬àƒCÏ’OáÿÜ«`úT’øÚ™tNI&Mš7T­pè²áðÃ4›£ŽÜº ðú™wa÷þ»oié[µ_þûoUá×ß}+#s:hOÖ‰L÷.•tÒlNšgš„EM&€(™+>`œÉàó–§ô‘à2n”µ¸&L5Ò~à%Yªi4?Dÿ!)½ØFS˜’<(E3°È¼j4¾Äe%Eœ®mLŸHn’âpt%*ˆå5ÇïJXp;7–¥ ZÏì|µý{$Ýø­Úßz«ý³gÚðù›gâŸ=M+Xþ×·\øõÎ|;WYŸÍÕæ*‰ØòÇãO¥¾~,²žMï´·=ɪ†7³ÓšHš•k›¹Âžvrq}Î<â)g¶ÚXF9 O‡'§dpa½‰g´YˆF+ÛY¢­ßÌòJ¢·åÕÖÒ:%eɰӿð™ÍS¯ø˜ @ƒr6“Ãÿ:]ïÏ6ÑÿpýßÝ MÑÝѰ԰ ÔÍK£,LéßÈÓƒR[‡˜ŸBŠ6ÀÐŽí",*`pd7ÏÖGñØF+~!öz±°Aþ‚-¼Þ$,£­Zc±·ÿãÛ€?¯âÿ¯–OCýïi¦êèÈWn’ä@`rZ°Kkã`…—k,<$e†,§MR#0e°Q Ägb à§×?Ïe‰·£œi|‚ö„«ïMèwìèt}Á¼“@5N ~NvòP‚]a‡Rµ‡1ZÈå0Fbqë`'/8%›m‚&î›h¶ǹ‘HJý]Õ+jñ’®Ë°çÿÛÛž¯¥ÿæ«©ïýyöû_ËüÍãߥ¯ÉÿðÅÖïüÓo— A4¾Ž Œ2M:JPÉÆ£Pø¾T& þ'Ìæ¸MYM÷ˆ˜äÎ@Ö(§ÔPOœ$ pVË–’“—8ÒÛKåMôPŒÕCnÒº…?R4MjÓÄMuõÌïÀ}ÀcÅF* Jk-QpLh~ûÈÑvýï~%»Ü ¥víÅmSV‰ ‡V]NšmgzÒBõûïÔšo%™T¶‰ÿ§cOÄT}Sô¬ñ°hº:Htúöż> ñe©ím&=¯{R4ávÏ9]¹’ü0­:QNù| Ì1»YY9 |8–Ÿãx(¸±”FU¿Œ×¤$†¹Š3§cÏ%•f¾VÊG"^D¬c`Yg5ÙŒÒϸ™šá,õ)9ÂÃØzK4'¥ú„¥K©ŸÏD2®qþ>ß|+3Ê–hË£f&¿ WdJ+ÌôïøW8ò°¹yw/Pw»4¯7saM´?om{ÊúDË|ixýWBpÇØý ’¿³Š§Àr¨ËFzAV\êÆ%‡9ñ·EÔÍš™žNŠ€¹Ü3Lrø@TSCM‚p²Öpˆ–Ø#>[þµ ?™d„ΖRM¹ÛtÕ8MÒ­áÅFs7Aô¸UNE§ ^?½Æ7þÓÀÿZàÿ³‡Vÿ»—Ï&Þ·Z`BÞ«e¬ºz¤¼¼·¦fÔP5ˆ{ROêÆÝ­mO¸>tD§ ùãz4µ–[:M/ë_Œ——v ƒh­yTâÿÿ&yšuÉDèõÄÆ€.mµŒ9ø×øõ—#õx¾tPó-QQq¹fE´‚ç°ÀÁPà1UV^‡¡ÃCAªUgB×@ÝsÍMò_”z|škc1kŒ)%Å—ñ‰¥ à, óŽÆ8 MYÕFe/8+³i”H_ CpE©DÊ[̦›µ$yKÌ”¦¢»ROΩÑ8{…&|Öv¹N<¨ÕÃè5¦Ñßqepiÿg{Êãš…Çg1§Vl<ü'‘¿¤‰p‹¹z×[XpA Ëäü/²Ÿ†|£f%oŸ-á(ÖÑtýðÍ…;×å qMÏ(žŸÞHE«y&eª®±‰IkIÒ= ›€caˆ¤9M/l2þˆ«£ƒoÑç¡¡Tz7¾9^Òì`—cÊT=ârN»3ŠxÄËO\¨þWÍÿÑö¾ñÆ%þÿQÇ™Ÿtüça%?@;†¤dÂb&N›ÿ‹Î—HýüÃmB3`~)éeI¯°B Dž‚$ùH„¹. ™çZü ýu0QÌäžñà+¶3#\Œz1Î/ðÿ«úßW˧„ÿ'ÿïS™$þÿ](­ê`-Ävb%¦ÒL)*>/Pœ3úÌg_˜ŒC~ŽFÂRÕÉ QñL™LÃ6û 5,¿ß·3…6GÀT–•\†íª6Ž””ÐPvòrÏ Ã~ 3!ÆŒ,!®`ªàÚ@ᱡ4àÈcått¾t»§¹x°ÆÓj›Pñ?å÷Ö“ÐØ±Äû°ç¿–h†…ÌìrO?Ü’ˆŒá¿ùv)ØÝ”<£)íåY†ìSSÖírðε½6lø¬DuIJ֎{½³%%W{ÀËI—ë¶ø2nÊÕœÃp ¼üf³Nb?Ôœ®)‰ó×’šØP­iç\QÖ#bd§N]Áx¡Œ2;ãÐRä½8r{[£¹†£àÌјc-cvûÆ ÚÚ14Às‘¦ðLs3Ñ}8 úÅz*m^Ç®°åCÀŸn×,IýZo%S›Böbµ•F%ÊÁÝÃJ%q´ÞÁ ›Ì_•áŠñyg±ŸTj ;´Ù'ËJ¯z)Á†Îjÿ@³«ÿ×iûÞxã‡ÿ™ÿ)Ìüœ€'NcyyNÞEaói¹±¸ðªÐ$¤öÛIÀ”ëY<ä¥ÀÆââa&`AaÅ©´ÄM|;÷q¥`¸!xâhLÎoÇ.ÆbüT\|‘âršÖgìYVæÁ™àžãIa#>_3ü>R†Ï©î…ç´º¾*miÉeìßhDïµ;¦>lûW ±ÏŲ¿ßÖù{±ìoÔÇ~«)þ4İý×Ñnÿ5¤P{®ìÔÕ“'.ž(ºPXðAµq°àÍ÷õ•ýpâp2xCч+*zÀp¶>/MžÇEy¨¢vÂÀ¹REEŠŠ/j4=h‰-øcyEwqч&ãHÁ›àÑ}ã}¼ž¤9[ÙÏ¢{ ñcb3ÜôÀë‚ °bçR< ¼ûÀ0‘¦‡~Ï‚¦¬®¨Ç=§)ïÁ[l®þ÷z¬–ɺº»p+ÜŽY§ý6©Ç5CÙÆÑ@`í‰Ë6Y¥ÄËe4à†/Àu‚=¡”'笵v²Î—mÂ$v„ÌI)p%ãÓÅšæØ‰Ñ8ªÕöóS–Qà.¶+°[ü/µ¨AxYãñ´‚ÿ Þ?<þOÕÍçÿÁϨý =™Ò†e®†ØÀ…“ ¯}ª!°d·“t ¦‡¼„çoáò¹Z‡²JøJg~/ÐA†1ÛüfÓÙ¯ûþ¶¨å‘à_ ¼s4ôþ±Æ÷>Ïâ×ÏÄÃè$‘Ffj–O§¦Ã霪®b¡Æa4h‹?Ámïà”§c Ƥ¬ä*)yspÛˆWæ㉧°cpýšÉ±]m‹?†‡ÏXëF áncÎãJ<þØ8%‚V"šÝ 6.7—ü;TKÜø÷êDþŒ¿àX(^Lµ$«8±–èzØžÔy¾ÒJ®Í?;ãû“Ä_ýAìí/¦¿ó…ä_ýaë·ñùùø_üï4ñ‘Ìp Ô*^Ï$UԾȷ'¸XV½ok{’JoÑ[¯ëO§¶áTêõ×IYÒ|SÒ1t’„º—†¬Ç€…ë--¹‚ýÀ à9b€#w†Há´škïlaá9<\;Ðën9òïW•þ†è¹Ÿä,,iKRRr±Rׇø•D1 ÎbAƒ#¯½+ô'㦠ÈfòðÿÑÿO¶KQ—$ü¹PÑLÒþá; º›Ì  ‰‘è “Šµ£û´¬·à…{ÿµ| øöâÿ{ r’Bh‡ù2éÖÅ SL1¡ HµŠúIû3•ù ÁWáã‰ò-™9åôï3õerÄÑ[i‘‘¢‰ZR¥„ß•ãrI#ÍÑ)ÅbOšYƒRæR±7ìGö)[¤&1C™0ëR™Êlå‰ÀÒHíõÍÁþŸÈ~{þ?¼mü•ΦÙÑø«§#X°þ™®ð¿È±òO¾} ‚aŠ@Öùï‰zf‹¸IìñçDV›˜'\-AuJËi^ef²Y±ƒQ cP4ºjZz‘,ö€ËĨ6B©‡ÁˆHÑ–BM÷E§ž å¡eeܧ«£Ð1‰œnSúkf§¦’¥z‹’m8jDTÏ"d¦Vã†4GÖãmÏX¬øëêîàž3/eãG©ªípÔz‰k¥×Ò©çru,¸FKSè¾èÎP½j;Íbãþ$sYFÛÂÿÓÈ9ÊÆ-5ŸÏÿ/.çÿüàÿÏ׸‘3!Qƒ¦U.Ý]ðài¬û¸á“”À~üÊqþ'©æk߀÷„Û…«ˆ¶‡d#ëïp¥aÊâÄu<…æèî$†]™)z(>ÓÀKÔBÐe37¶Xÿh•âÛÂKçÂ[ôœR”Ø/ŸgvRÂ3åöŒ:]·qÅ c˜Ä±Ã+ŸÄ6}è“Ý1I˜Ó“|Þ9œMÞ%ž±Û>ÉBÒ”UŽk'¨ì›¯«¿ ¯Â¡ö{ç÷Ыáø½¤”G>‘|îõÌ;Iìaå×.ÁYˆD×|þæ)]Ï‘F2$ùÂT~ÒTCb[Ö‰£¯¿KÄA®Òb&•ÕA—}F«é-/ëÁ[`ª¹ ´#îíÉ¢óå½>í¡´ô2\ìFø€XhïqMŸ,Ü:YrI¯»ÎÁÒnƒáFé©+e¥Ý%§.«©\…yÏâ†ëÈC™¥%v£NºŒû_Ttž¶·GMÕ¹Ñ •ÓÇâÿþß#Ñû,_±.Iw~?ÌË3®µÙ!£Êì4”?yÈs¦¹”B¸E©ô ô(z[ÙÎÓûžÝyíô;?·óüåÿÀíÕÔçOL¨Ù}±ób)úÊö\²bö໹ gŽI˜Y]ð2 +>K·Y#Íà¬cÆËåñÎG‚ËõLÓÀÙnþ: hÐ4YfvÌåœayh²K!šú!7Á^Ëå æ1™¢ QÛƒÆÐêk™wî…ÿÛŽ3íñM¼þ’ø§2›‰«•=gH\-À””°ÇyžÉíæè:S:l²®ßó¤=H%sܪô›b¦‚¸'ò\p-x%Ó™œ€f¢}“Äغ²AÈeá¹Ë +¹—I&â"ßMUÕ‘yÞ6ã­O2Ù}äŸ* Ð^ü?³)øýùòˆ‰íEšÇ´´ù1ò³ ÐÄ$ŸaNj×€§°’¼}àv nœ&’€¿ˆEDϳ¼oH?w¨f\:çÿûE€3…š°Á×èZ‹LˆLë „qV¸£g~|æUþÿ«åÓPÿ{ ÿGÅÿ{2ŽI"ëfþœy“é&,vC=p…Á)lXMì÷.®þóû«ª}”b½h¨²Ù's`‚ª#Ø•ÙD É"~äc qìÄéœ.×P³Ï3?µ“„%pÈmÊ…ðÝñºæ`Àñ+,Æ'X3ƒ¨Œ†aX?!E¯ó/¸Ý³:¢9PâH_VÅ 9IžJGãïý}`’¿q¡•Ѭ1Æ AÎT_FPœxH‚!Š\á`»H#9ÓÀ–ì¬à”0±~Ö2‘ †W䂜4‚]á&Ã)€ukiÉ)3בì‘{Æï»Ï‰O/”ôÝmÜ%Ž#¥3PŠ‹âÕ³••<Ó‘æ1HCÒ?ÃTygļZZJ“àf îù˜®¢¿¦zÄJ‡Ð—¶¢OxlªYH¯ï§ý›€µFtZ wSí˜i¤²òzš}’â‹Ø9ÕÌ–^5ñ€¾j ¸ø"àžd(ô4ÁCç1¢?`{^ é þÇ ùæ~üŸ8áÿ%¯w¬¶v¼‰²ñWq p»ð:åö7¯á)`˜Žˆj‰87ðL¨$Ô‰6±ÖÇì;ÚN]à®™¦E¨^#YYÊên„]W¡1Œ—$IÂWKÍÞ&À` špÓ—sÚZ;Ae¬ª@%‡ôÓ¹¢d‚t´#‘u‡}²­’Uˆú•ùlC‘Uô[x¯_L~ËW2ý§ÉïüaìÛøÄòÇñ¿”nwvŽ^ç,Q¸'s‚Î{ª¬{ZÏÌñ®°îÈÆQZm+TðÛB¢˜ÿG‘ŽJ)tñªð“JJõ¶œ”*eq Y¢H5IŽ'¢uù¤ÈCJHŸµÂK"ýñÍXË6Òzj ·.Á¿&öX7cLÙ„…™‚ÄÞb/,wáØ-¼io—jaHØzSèŒö+Y¿H*BÏmYàÿÔSmEϱcZÞ+ÊKÑÜ%‹#ßü¡h^`y”>£q¸¸øLA…¦—8ó‰‡a]½¼¬ûø±jªoòô ñ3à……1)*ºX”¸øko5ÿìåõÓïæóßîÓˆQg÷dµw3Êu!d»þëpÐJN^¢ÌŸÚ[°3p«ô4Ÿ‹Þ‚7K«é£I:÷4 .«uÌ””\4[n „Õ²Y'ŒÆ$-]r1ÍÐnÄÛTVÖ+Óí!ºZKí­ZÍW–}H“¹š^›yÂMŠiWŽ:ßÿ·­§ÿUCë¿iíúâéï`ù\4ûÙ†¶ß‰¤>ÍüVcâ÷cæùkV§ëÇ…ÅKÎ]–ÄhÁx/Î#Œ$ì3)Ú˜nÂG®1Þt9¦MUCN;1×ᔨøW7€ ö;„×\ï§’®XŸÆ¦×_ljáu@ì˜4YôCا‡S}àÌÖùàe ™Fs cŒn:Z‡^íxMÍÍJÝu¸B”€DŠ–Ã§J.x©²äâÿ]yñ­¶çÈ‘wÿ¿õ“.t àÿÔó$>§ŒÐÎø8ëoÄx&§¯&“¶¡A†J2’Þ#.ƒ¬«Ø^(=¥ @RzéñG¬Hy¯ÈKÂó¶K҇䤬ØyÛ‰SÂ0uú£Ó¯ðÿ«åÓƒÿ;;vT}UØQjÊRIн”•]­1Ý,.¦\¢p/<+A[jL£%%W1ª’R UΘÍ#†ñ°MQᇬËË{ùa-ñ_Jb7 J2Ó qÜf+T®¨é%A.ï¼Ë9 Vc1èõ•×YýpÕå¸ ƒF"bæ±ÚØÛá“Å=®œRi£öˆ%£ L(Œ!,¡Þ3ð§öÿçhè½×êßù¼åßaå ¶¿:~ÿKŽï|Íû7X9=§ëì÷P2Ïe'|ß¼¾²_ؘKK/óô÷ ¬RbJŸ |WŽPQ¬gƒo”ÊB©B§í£}÷tYY·Óu[£¡Ü'ì‹s:ѾIÞ=STt+¸dàg|ž*¹‚‘ŽR4½¸±¹Š¿Ì'9“À“Ó~›ÊW} ²ùK –…´Ÿó{)âêuϵ3å©^ÛïóχW%À‹Æ¸?NDhi^Ãmñ’/6é¤JÏe@V‡cÒno¨_">úeÜädš8®Mxjþ ,ß 5.cüÅ>ápÑD@r‹"ÃN …ƒ ,åvLïçÿ‘¿hµ×3þKâÿjòÏÞÒñRJ€ÊËzÜîiI˱S"¥rI²dø`T-=u…Wh:^GéÇ“è±ðzð€¨¢$ü Ú8DD‹åð¼FÊÊ{ Uƒ’XeµŒáÉb‡ ŒÞŽÆ$m(¯Ó]¯©Á]Âà‹ûf³Ž¿ñú­µã¢VpäýZVéÂih5ýð§àtÈÍÚAƒŠòÞ’âKš²~ ðB*Tïÿé·J,$ú6Vtü|­åà`@ 'ý/oÛÑÀÛ1/R*è*6Ë-ÊF%ôý‚˽óÔ`•n)ëù_EÔUÜq ÿ«ž,Ü–¢^g¿-éÐp<Ñ—Œú·kVîU¨ážÝ6iwLÒh4}è¨Àçp|ÜŽÛÆ* Îã` 2 =°6NçŒÍ:Y©ðz)iÕë 6,IÿÇAÑŸkkI¡.*ÜgžR¹W¿Ï>å°Má»=³mñ'¥¥W]ÎÛx t]UÃZª_qÿk{ŽNþêϪŸùo:n)îús$‚—ý>ú˜HcE &𡉽{©LÇer²õŠV×WW·@Ô¾ Ë™¼.‘Þ_eð³t1ò\’OÜþ íyQñ?P4O¡n2-}fKqN·¥ 8‘|ƾB§üŒ¡/mQAÊšpàÃ`¦hB“Ò80Z‰Ö­Ï7O¹=ù¬)Du[A.A{Ñä…omYǰ‚…9{wØÅ~È °ãZ“IJœ=­àò†ÈmÀ{Òüeq=ÒU´ñ²Ã9…1C¤Ëu[Ä.ý sñ_@z¼­ðPÐØHsL7`lq±ÇŸÅ«7ƒ¬•_)¢KUøæY ¾0øÍ‘5x+è“TÕ^DµóœY÷¼°à¼¶¼C'΃Bñ‰‹z’œÑ]‡oˆÓ€!‚øÚW¿×žxšÍuàÙF.ÊÞÿÿÁ!åÿdv’œÿŸn~ØŒa\R€¢k-JöNT]Ä/hY§|øÉÍ´H}¹g¨WÛ³/ЈÃa±`aÅâ›'E‰ÿ{f=¯ðÿ«åS…ÿóYÓÉÄ …#'üˆ Ucã}À×–è£v‚a 0"½g…bŒsFÂxÿL¢ˆ9éI%lˆ?¥RûhØáhĘDSÛV±¤$–æµ\þ€Â-#ä3ü57UÁ¦›¶sƒmA\¥›»X>1šü¸Âp …„,ôù”…«äK„ßM|ËOÃM”Ò­3Ñv”‡ ®˜›ç!æ~¼ýi íd¦\ψ¶¸q…B—ÉÍfbDÔÖö”JI¥²M‚+\MIJ.h‰EÒ„êë—ptÎü¡¬¬D>£è/ï4°]iv‡*"¹2QrY£¢ÂMkR,Æw‘¼iiyÔÖþ„ç/Öå¦a”Á …#r”n2«³Ñ¸Ù¢L—9†ŠÛ·’ÂWNŒs´Ýù¼óR_œš9~ËÔ(ž¥šÙðƒ–èÆOÁÿ»Œÿû~vpéÿ'þ€´otSð?Ü S‹jNü”uvpEñ¶'’Ï#”5\B»-±nÀÒQI® ]e=4j}óÜñ¶ÓyÄøRN$žKj„„ ³ÄòH –p‰¨Ym #7E J,ö8#ì.ø/Ï×ãá«ë£:ßB„ç³ÐOXŸ.\”øÿg2áÏdÿÑÕ‚+¿ÞýÕl36þ·ßªüÏâbRÁº+8_ ÕæGn3y걪’l¾ƒ ú jEª ó=…ô~‰÷ _«é­,j+zµT‹:“Lló—•^5êági4×àïŸ*¾ˆ ¨øäE é}¬úxAÖà2î€zW\j+®¹É!½CܶUBh¬º  yB_FÃ`¥®_á ãNªn¸¨ yþÑYFÑ ¹e­RKbg8[ü] eÙž ÀÜ5 %þWëØ±³‡…ÿóRéàö^ªæš; ‰¶Ð’ûš{@Üu73¹,Í’,”Ê©úæ=²¼g—QÂõ|œÄð'ÿ3Ÿ4pÐÈûоûïrÌ0%ìæ{äf¸06ÛdŠÍ©Ý6§ŒÆxé)_ˆÀg˜‹Ç© ŸõÙ©oØÓNה䰉¸>­–q¿?O%w›á†‚÷áñUêïÁüʰUWÈz—ÈùDKK ZÞÒSKl5‰³‹HÀV~xÀÚþ%Èš#”ðC%öÑG”Þ“ØbµG˜Êçù:Â$Ï%jæ†Èä&çdî¤ö¬ÍLÑ3R¼!ÉÆ”dWåIñ³ËÝ|ÊJ)¡øªˆ<8n+ l»*ÅÇÞ ©ÄÿÓ›ÿÙCÄÿ°.Àÿ§?êÂÉFDðjŠz/ð¼¡N¸@¹ZÂÃåDû?LûqY’ÿ¯Ö H½°ÐIív% BR2, _¶‹ò/~µŽÛ„)Hæ˜#6(ŠÀ¢ŒGñ ÿ¿Z>=üÿyøÿåž¡æäÿ,g9×SDí8ì§Ï»pªäªÝNõ’ûm“ ƒæ¤Í:‰_a?±Ž–N' HIÖ„Ë5+ '~ßbuõ0ì-v‚Æ0øÇ4±7–8Ûg†ÚAe¶T$ërÍî5Ô“,/Õ¯Ùo¤EÂHùÔ¿èó-D›×±Âõnë8ŠZ£§Æ-÷F.¶â Ø0ÐZ a»Å™pŽÇ"ËÀNâ´…„'Ô¸j1«aœâEØŽ_™«d…É*îàÒ)«g‡ÆuIìGÇÍÁv¬Wo¶Æ O gƒ-ŒP' e¢äcÿø‰<0™n:·cÑ áŠ‘¤ÙâZjÆRœ\á¢;6e¨4›oVh®%r›uã…N×_U5Pc6U`”tØ& Ž} ˆÃžÃø nxLµÌóƒA·] ½ÕBÚgת™ÁÛh~óØË…T›nq1õÜÕeS¾ÐXYY7¶†™M7)*¾/ÿG­ÿÍÍ5ët}ß|ýÝCÎÿÙͯüUƸ]ô1Œû&ñux} 4Qe – ú7ºúže‚r¢VóX†yñh •ƒuÞ;¡à ÁלAwÃbÕë®;¬“xpáx xjxüÞù€Ÿ¦N€ÙÐajŒ#Ä-DëÈš)4ñP¸fs^ž8ÓlÞKSµæ´ÕFânæšñjN÷NN8bÙ<ÊI¢È‡ÖøšHoþ}Û$þ½íEûŒ—ÿÖäoTÃÂÉVTÀ¡âH`¯e&×÷J¡·UYpɱRsé[‰hSuR ¼K%g’¦¿SÎsk<ç—ÉëÀĶģ(59ÖYN@’uÊ­Ê%á\k~$$ŒˆÉVö#ÒiþÕ«pÅ`‰Öæ]ÿwª2j„ÿ3©§’ÿóæ±Ãÿç8'ü¯&¶e?Ñ•Οº¨å]Rš‘á$ó½)ÕŠ*ÝãÀJúgú¥eÞÓßÍÏYʯe`32n0ê*úÈÀf¶#ч†ÊJJ¶€åJ¥Í²òXô«ææu´„•#…k®‘7ñ.Ãad©©¹i³MÐöŠ~)¹…aÄÛײ¸ðBsózZ;úCÔV;^¡í«®©6ŽHe )Y׎×ZnáSË ×3Ç.[<¯Ô['Ò[Ð{mµ“°x–êÑ Õ›SA´Ã9U^ÒŽÕüÃCÂOfþo^PiG@`¸Ì%¥[œü3GTóÔf‰ëÅÈ» ÔÝ 6Rù3Ú7GÖ€Qq¬htCNÆï#®qˆP±‘3Áp¸úzÒñ 6®ø)qb÷“ø>¡ &þ¿•ïkì/Øõ3‘Dee?|,……çÄ3„Nü0µ·JNÉÏ;oÐ àzÑÃmV<¦ëUú³ð±ÌV¯…ää$Þó{ç´$ ¦Ñt[mãßáyù)çg×n›Ôkû1èkÊzí$LÄøæ[å¥ÝØ›©ú&àD­ùü,w®£ó¥¹f}7Çn'YŸ:âñ ,*¬Ý»9å_eú ‡³/3;š®^,¥Ù,š®ke=e½å²±[°ÒÖñ„õ)^Š|†BeIl–YŽ$K‘²R×ùÀ;“Ío¦¨]tH^Ð^îüĆ¹Ù„XŒÈF2û¸Xw¨Â¡ûðëÑÌn›‚ãé´Oy\3xYÈWòÌâÞJÎ9Ú§°Ã¦ð}“qN¥Ã>‰WÒWÕ2¬EÔ+Æ!My<_¼t8()ô9¦Ì5c¸‡NQP’™¦=–)³°çY½n€ÒŠðht”:ÕÁ¾ØgÇK4s8©ªÚjŸ4êo×Á¸©h?ßȱ wîæòÿÓÏ**ºþ¯­•üÿƒJ¼|‰¬KV À^CpÅhžŠQq½z|KííÏÚ“ÏêƒË­myöúïzüKŠ8õŽ€C»k!Åad‹}:ÞNŤ­4÷Dȸ«¡ÈCÝR–•D2ÙÝÇðó£ýªKÈ_s‚&?#}H¼ ØÕ•A6Ç‘H ³€Æxµê)‹I;%SNMœËËó¢xjgdö|´Ì>gþòIžZþgv_ÿÙÍëÕ¹üŠÿw"þ—ú_QŠ?‰‡V(€ à ”.sÿ K ¾y>%É_rûäãOÚý ”í¯ØÎE»ÑÐJX™oBþÕü0ÊI>Ä2Äu¾1,\çK5¿mãh€–X„h´îN]ã½ÆWñÿW˧2þ¿›·ìcœc ×ç’:¢ÐŒKP‚$é“"ñÃt@lQH79u„µ2Û7£b‹è›{=ó*±¶ýÑÜhü)/Ï8e³=þL%3gò-%² ì-ì(bÃ…ÀK¢Ü‚öó¢…¹“FÖ’©í(±1lRÖMÛc©/âD‹ œ éóRÌ–hÊÈ顽Œ8í(«Þ ·ó3ÇÈ…=D"«’‚Ëê Žó“L‘º´á’—Xà†f䊈R¦…NFx`ðÉ”2O…;wð>›Ù•Yæ¶Ó1 Ó|Zñûá’píó’ǵàv-p]*M£©gÅ„B¡Ð* ­.‘¬¼{ãmO|Þ,ð\ˆ‰i𱇖èF1£qq¸ ¹`@ûp[à,Ôù›Ð˜}!lÇ™ø¼w<î9\]c¹} ﹄ÿ¿yèù?ŸˆÿQqŸ3¤üa_N{&§³#î$úrÅÞŒ?ž¾~`#ü8ü%Áͨ\µ51¼bË^îÖ¾DQz)œK†£?+Êh»è“iL”­AI΄g²;±– ¡ñú— ¦Iu]ÕMüúÚñîc'z«-SZý˜Õ1ksÍUFK4ÇŠúŠJo• 4„Vq½nÿâÑ’^aÔáš 6Q124›ëÎɲ‹mÚh™2ÖLÔ:f«ÍSfët™¦¿XÓo®½ÍïÑö×ßø°Ê<éòãh¸Wª1[§J5ƒ&ˤÝ9§¯3š' ¦[žº%\ŽË{Go/ÓŽ`Xôëo^­ª 4,sÅBöÒ° ÷Ý7J_yC²÷íÖ‰ò’«. ~i5×€ºá0—NîZ™IÕï øïPô zþ¾‰Ê|ÆáAÿS¿ãz¾Ý>átÝÆø úÊþœÌqí8°@~¸éžƒdÇ-æQgû‡7? á°¤ŽPy‘kŠ"Ñuí«Å¿y[^ªùÿ„ÿ¾w¨õ¿J7ÞÍ_/,¹f4M–à‰ØfOi[Ï¿ðÕ÷>ÿ¥÷Ž]ûÚ±îßûü;GŽ_ùã?û ðdÿW^¿øFÑÕ?úê¿üƇ_úú¹o½RXÒWiºõÕcWþðË?rzß(îùü—ßýÚ±K%𾝽|¬¤Ýæ _ýà ¯],.,8Ù÷¥×/¾^tM-FÎäç²údø( ‰ŸX¼,sµèÿ” o‚×l4 j+ú•kL7ñ”‰RØJ|Ñxù…êËÕS[JY÷s‰–Ëk%Ñoµ,]­vçñKÈ„·gK™ÛÚVRq‘R 8—ö²]ð?͸¨<Í횃YÁ`rÜ>Îé=<¢ÑÜ.5éÌù#zu‹yÔ¸4Á¼À8`,À>“éS*¥6 I¯–Ø#ÅÍÙVkóY"pGÒe‡°ÿüßí=5ÔVÞdœÆøÿeÿSü¿ûÈ7ß=$ý_Ü9’Ó|‘Å, ?×)gv£•«€©8ºÅŠÊä‰Ïö§4Ôó|A£{ÆSw'À¬MXaûç¬^jϼ@mÂüÊP©ÿÑá–õ˜œ€Pÿã”2Û™Wü?¯–OþòÏáÿÎOdÞU'jS{„!ÛI1†lrõíÏÛãT *BØB_•u‰¥ÈO’â[cçÆÌ/^eüØŒö¶²ä¾ª°í@&ƒ,8É*•×6^5ÞNâ<àè÷²ßpÇÅ:3çϱÊê sS°þR_¿Ì©;SÀ½Ï‚p˜£Ó9Íyþ«ÇŒÃ1%ö¹YMh  ¨Ú¶ØgÅà?ß7l©Ü)Šõ–ŸT…_`$'DWj)p]zŠ2m`Ë Þ·pûTÉU½þzyY· *ÝîYØâÜvÞf–sÀB•º~T%•œ±²òn CÀB…gcÑu«eÜb¾YkÕëúI‰†‹d+*zpÕØ|«ãǨ¦‘êêa­–Ô( ‹.àîYkoIrP.|+¬Ъ0Œ|ãx·Ý>ýµ#6„VŽìöûÂW~Ppª¯°´_S9òÕ×ÎÿéŸÿ¨°ôÚW^;kw΀—õ)ºü{øÝ‚—Ê+G;:_c¯½yùó_ùÑ‘‚KÇŠzþø+ïþùÑKú¡× .•kûß(ºô¥¯ÿHã¾üwGN\-)À×ëíãeýÇO^ý¿¿ð½¢âî× ¯üÉ×~TV5Ti4OáÒ*ªF‹J¯ktäja»ýõc^{óŠÍ½@éë]¹§Àb©/˜;q®’°«*’µ0FªsFÉ4©þär]D¯¶u£…š©ÊÚ,üݹ '‰{¶óE 9M»IRƒ}HÞGW®æ‘O::U š€[ ʋܒ—oÿÓòrùÿñ\üŸê*þ?˜ÿC[:>‚ó…Óp¸çJõ7ÛâO͵“Vûm_å::Üózã„Å:muÌT׎ù3;¦lÎYSí¬Ý5g2OØ< ÁÐj…aÔd™ò„Ÿ¨©Ö›ÆLæÉÊšql÷øO•icæÚ)ƒi\kš0Ùg÷O®íî¯JØõ÷æŒv?±.XŒv5gÅH¶É4ìöÌš‰ôuÄçÅ.8h¡Ðý¤ÿIí™Íœådk©&ÌäF¥²,¡äÛËà•£ÓT\€½„™ýi6¹j5Þ!w[Š Üsu¸I&·qž0p$kL#‘ðC«yÖà$½0Óh•~WGŠÕÆXŒ2”.xª(>f¥¾¿²òWOâõGK O°À^ÏlA5º bÀna£\ö©jÃ`eå€ÏC¤ 4}V;ÏÃÌ2lx8¼j³Mê4ý õ˦bis’FI/n¯Û5£«èƒÍ?¶½üÿÃÇÿg~ÒÕñ"ÍrÐé­tÛã6©ùåô~˜Š.¸×ÀÞxÄ„Ÿkªð¶Q>»ï…Ã_¥ýgæÿ¶äf mHWy;?Óõò´Ôî`·Ò€$@§HÀPŽ˜9ýZž9óã·°ðþñß®Wú¿¯–OþÇ¢æÿ(Q¦ƒ^À^z§2Û¦ÄdÍ-‰çÊì-p Ø·ç{±ÉÖô„>{CŸØ¿`Ë ¡Ë¡“uEÖiÌ­t;VöM(+s¦ù: Î'›e¥ÝÉ¢sé7­Vn`Ñë˜1cŒ³z(¿…©Æa·cÖÀôºCÕ`]ÝBuõ¼´˜w¯¨èŒ?Ðò‰$Žƒä$3s.p¤æÜŠ·’Jm©ŒÜI%ó6¿xAš©ÓèEK0aÍ‘‡--ë$`Н±G¤;¾8‰< Jäæ5ÀÊÞ‰®)P1ÉG£kMM÷¹¨a–¦*š2Å=é«RCˆª¹Ý®Y‰`·ÐlÅãTú9MU4?HP"q-b@iŽ*¾2“ÆSª,Ž®É\ISx5Þþ”gUÁccKËš¢¿p>)ñÿCÇÿJ€e à´Ã>Q¥J¬ó-Z`¯©©¯_$.ã`míK)-ù}sÄt€ã,ÖñÄ Un¹66ëúƒß‡þ@Ù>ÀùèTæŠHã>×ÔŒ €7ñ‰”Ï9%ÌBXÁk­ãvÇk7Ï:œ·%mµÛ'HBbÑ矂µÙ'áÍáa©”º»i®ãËäxT¨‡øë–2>wX±B*vZsªO¦c‡‡r[¨MvÇ[·TW—%h»³ÓvÉðÉršPFÖ;%Š› çJÙ³ Á¼_wò^^(jY{O!ذLuÎéJÝõS'/®ÔÁcâr¤ò²¸–”¹íšs$½¥©i.jáñó¸“ĤïÒ3kd¢K+k-¡¯´ãVqyܳx"’è…g„6Õpµ(á‡øiáA›kFqôªÎ¸Csæ±HxUSÞ«Ó]ÄÂ~ÐÏñß²SÝ–šÑúÀ]õÎ á§Šx%^šˆ?Râÿ½G¾ÿ гSo)#·ˆf_€wçžÓ^±p©7ò£á-jÉ9ðÝÜ´ÔžŸ [QÎãR%²{Åû/ʲ{`ÉÏ:ü?ÿÓ@¼:%¥'Í,XñùÔÈv·'·SÕ§:ñü «8‚›#Ø<” ìd.I>µ>jiy¤†ŒRJšÍ'ÕGÐF¼}ÉÔvJ‰5ÉD­øùi9° >Ï‚Í2j¼‡3­À‹“Ç b ¥‰ tB‘ý ‡x½óðñ±»*z¬³|FÆÈU ÀÃN@0S5fRs.)¹D%íÄó<ì÷Ïç›Í4]‚-2x(\sÝ^[Öt‹?ºšŒCeÝ6<Žy4&2½ZšAK‘,Ëîǹºº„ÿ‡ø?üXù?§ŒnHüÿ§?¢i4¼^‚ÀÞ+K—à¬,˜gG KmùÖOÞw@Ö¥Ðþ·þӷј—3n—„µ_(LV;œsòQ^ ü¥Ìjq^4± ÿ·'7Í–)£i2ƒË¦°”çÀü®ºóÜÉtæÒ3°‚Ãuuå\~ÚyEË) ÞÅx‰.;)m7?äûRù/Õ U0êþHµŠÿƒ+À3X,æ1ƒ~€Dc‰ásÖíœF¬ªºÁ“GTU爀=3&AÆpœ(^›¸ €Ž6ÛÜÛ,+±†‚÷\ÀB.<£— ¯kŒáM¬²ÐåóÎÛ ´ŸÀ\¶J]?¬ü_fѤ$¢V¦W2²ˆy}Žÿs÷ã¹÷’”ÃÿégÚŠÞÃŒÿ¿È3Ëøse›+öÚ‰,a65ÞgUÙYb¶Œnë—q7pÏáìÔ×/¡<÷–(1€ßFi…,s °$ÅSø-™å’±" ñìÇ þËOÚ’þó>óÁÿ@RÙ]$å<}ìØ:"®œH3Uü©ââËË(`sUÕ ©–hû% GÜÊ‹¯¶;è¦Å2^YÑ’³†æÑ »^;P[KÑx7);ûw8¦++[¢„À‡.*ºÀìOÄ€ÊѪg}@Ôš>tQ«e\¯'¿’*÷Íc0¼jÒ ZTÕžà„Xþ/öÌsÜ›œeÊÑ¡úIlÂ+Áý—Yn&=µƒ"GÈà  ð28uç9S{µÅŸ2ûÜšK(|>[œˆû\h÷b­ô4IÒ1ö$¿à—)ø6%'ÎÝÇ—›èÊËÿgüÿÍoVþf' +óãM~cåÃ+΋:Œdó6v° ЗA¶ þ§@ð‹ Zâ+ ½â5tñ’› À ¾b…}Óò•÷ ÇͰýÌ«øÿ«åÓÿïì|‘—ÔW5wºã§Lãæ8‚òˆwR©­ƒ“±üߪÁß_ïzWÕª{òq6ŒTN4Ç8ªÚð½ôHžá}­ãçë`þÏoÛò/íÀÅæ;D*Mt~†Ò>¤ä>Ñ¥ƒzއd5]§íš ¯w£LqÑE»}²ôäe¡ˆ7~Ìåº-I,µ¬¡“Nm–•QŽþÅGTÑL°ß1…=PÞ %T_;Å"A€.…g…ìŽÉ½iˆÌŽÂ8ÇüÊlEþMÎAß=ï&—»þ‰ÀïYÿ›ý¤ø¿ÌqÃ2T ž*¹JIP¥WãmM&š ×©¼fôèÑ÷ÚI®nØTs“>9G±Ç;¸Ùýõtùäùù"Gù\ˆù9¹ùñZÈŽjþI'#ð, Œª)»‚÷8êN¹.Øá±¢î“ݯ\üý?úë#Ç»žè.(éûƒ/ýðHáÕ²ëJ¬~wßþU`/+¹yï8¹t²…×È äs{ÙÉg¢T%çñ,åœ%HÎ^ƒlTÏ¿•8²Ö„ UERƒ¬²Åæ1^r·Qyã3ôSsôáž¶l‡ª-»¯.ÎÚ€rûqq8Ú¾Ó¡xg÷:ˆDèI¬y£C }KO&Áqj¼/­%]üYÿWTô^ü??ÿ'?ÿ‹É4\V~¸Ýb¾˜Êœ“À´Õ†!kí-x7.ÇtiÉU’D±O½*xó§}Ê뙇Ñ@o/)þ0Ü‚ou¢ð^öZó˜Ã1yôÚ­Å…§É{;è8p²Ÿ\&ÖñIÿÇÿPL×ÕÝaý‚9ÚN³S“e³3ýÎR—&Ž,RâsDj®i¿oN,'sSPÆ&ƒØ&D!‘ù"îÕÕ-² c†ÉëÈÑkaå8tB«u²Æ< IJ¹gq^®O™2V‘¬FQO„´·93oÔîU"ð8‚íŘ­èFiÙU*Û7”–v×ZÆ UCØR©Àmo‰=*.ºb K}Õ îüÉ“—q,œdé&ë`QF‘äMryX™‘Œ>ë_Ìáq”–^ÅeÂdákeå€ÿ(<FýúÀ]\Eeåõ*íõHt-^õ;AŸ´Aÿ”:ýUQêXOñÿìó®ÎÑÿ:$üÿö:3ÀF¥#áç#s‘‰–YAõó@ʧ”í*òǯoýämAõpÞþß’8?ÖÅ¿yuR@q%ØMèäýstd·øÿUüÿÕòéÁÿ] þW 6y~î#‰ *£j.#¥ÕÔŸlXŠûç“áûmÆ«ñðjÜØ—­D·žÉXè^Ìx¹5t¯Õ53^¹§âu‹­þùÖÚÑxä~{p9Xй'9휮j»·Œ$#£Ç¿.%êãõË1ËP›ör²n>n›„s‘pÏ¥ÏM÷Ó‘ ËX"ò°µ¦ÿ²o©ø?¯: ¿÷e™ŠFA$SÛÍQ*ø¥¡$Ie ‘膄Y"-_Ïþ€üò퓟¸¨ø_…ñêAS©­ü<ŸLz>lN*uŠ «Èy §úÞùç.äˆJŽ+‡t’)©GÛ†bÆÈŒ³Ð¿¶÷3´ï?b›7R¥Òmë€èsnž=µ¥–ÂIÑGZ!—N*×›Ú›FßVž}ÍO–P„&_ü"ãÿÉ?9þßÝp9g9ÈùÀlº ü/ŒLáÐýPèžÏ·àrÞÆ‚àr’ [$BGú%Ï•°ôóÓ}ü' ÆV¹5ò·«)›ûõåÇ€S^Ú†, ¹éÕ;ýcÆá‚À?ÚËÔíÚ•tz·wÁë_ò–î9oÝ’¿~Ù_¿®x >ÿ’RzùRÉØQ ~×®²ÏÜÒѵ—œóúsøŸ³JT_@9CN}癕‚2ïBöÔwîå÷ *Ö²Qxü¼Õ:a2ÝÔ”õž,¾D‰s–[ÀET{뜦€¶u¢BÓ œƒ¡=¼g Õ€>½îz•þ†A£ðMòXwMÆü«¼¬‡3¢'5¥=øoÀ§Ú8Ô@¹^°Û6øÈ¦aŸg©°à®ƒÒ¤¯Ù,·tš¾Ò’+8€\Y ©àïpôýuÞ9¯{vŸs‘ǽÉVñE¢ýq.þ¯é9v˜ù?ÊØÕ'ÕÖFÜȤ4ÁÕ¦­-’4/ù¨%ºÞÌ]7Ú¼Ö\Ž„ÄZ¡%1´?khXjjºgî-D¬u¾Xõ€±¸1t/Zm ¯†—sîgλW"J Úé8Pážø9ªay®S°±(¸·j;²W–Ú6¬ähsØ4eRÛ4Å©(_óX@:é2 dAdÉé§)°ÏPh•°÷gIM›¨[ôºçp?CM+úÊëçm8Ç”p\Ã!jËÐ Ì5\˜_ôm* .ÙS°ä¡Ð}{þ…Áp‚KfóM¿wÎå˜2[nz}³õ$5¾…®¡Ó:ì,Qç"nm»mî • ÙÆÎ)¼‘æ5áÜ«(ïmcÝ~¡®¹\·Y´}O?ùOΣTðÿGÀÿyú¿ï’þWv'%Ž{…¦rQz%¼Z:‘’tZ~’O‰Ø+ó‚ê%þ/m:¨O¨#•Z; zâ`=½•U<Ž.uçlØÉ ÿç+üÿjù”ðÿPü¿cçkŠŠÿñRe“ÏZ&}ÓÂ0uÇ5ïīεš»ú˱àݸþÃØ‰ï·?lÓþ¨¥ò¸ñbÔ?–öŒ6ëßO´®µU]ˆiÐlëŽÎ&Š¿¯îŽ–~ç—³nÀé Û_ÄëfÚÉÒwâ³­od†ËQÝÙ„o²Uw®µìÝdýtüØÛí¡…¸µ7éJ/Ç]×ãüQö þþZ×»jöQ^@þ¹ ¹‰Î½y½B?ެëô£¡¦µ"íHaÙ FwS£Ÿ,85X^5~²|4žØ¼´Ì4VéHpÄ:޽8GÈeŸTN§¶¨"¾ö–Ç3¨[8€fU"VL‰v5ÿ§ç蛇•ÿÓ‘}±¿2k7~VæGD#á‡Àÿç@õfóhC=ݱæÈZ8ô€\ªŽ]VY WD$×MÞÍ ‰„cc[ìq4²ŽýD#‰ñ ~{‹ÇˆÁLBØ-Wé.SdŒ$;„Èw^•¹TŠo$XÉQ¨!Úž¶·=ÍðQÔà@^á‹TzÇ`‚gçtN~“gš=vôƒêêa<æØ*-½¢Õö“‚¡{Öë·ÔŽ£“xY‡Ý`D›ÚÚñ²²‹å“t­G´¶>g68~~¢Í2^VÚí°M±`ú“ÒSÝøcyyo•~PSvåt· só!Hô¼f´ääe£a{Öé®cŸç$ÙFáäÙ$œïFwZkcªŸDb+Äù<{|DÉ-´ÁM#i°f‘Þ¦r-Xï¼j/ÊÞtL«”dj'™Þj ?ÀÜ^ޱì`‰±æ`:³ ’úm|DÖ…ãTÑÆÓ„7¿ÆZ;‰g—RÂ;iÖÓÌËÿÉ+f§×_øÿü_Ñó³§hÿøÿ¿èå˜|µüWÿ?ãJ£ Ì/Ég1íÙ¸g*^Ig¶Zµçâº$ªÎǃwbºó-ÖþTÍ¥tô^»î ö¸wº¥ìGQëÕ¬w,f8ŸHnÆ—Z*~1~Øj¹Óÿm‡ñR«gâ—ã”ÀSéú‹6ÃÙ”ùR»öÝDÃ\[Õ÷'ÿ}+ö있ëÏÆ+þ¶Õ6˜Ð½5]éÎÅkûÛÍ—Ú‚Ë1ó‡ÔÚ¦àÿ=² …Q9Š'Ûvä¢×¿xJ?l÷.–èFË ã_;záXi_™~¤ tà˯ŸÅõèÅÏz;±Ï_o8®~þÔ÷_³^zÍ|á+Ú±^þÃòwÿÔýwJü?ʶw[-…Ø¿¨ÒH{B-i%É'Oˆgoæ"!³y¿rƒ-抹l¨^®¬Ì¯×˜L7ß|ó½þzMõpµa§„QÌb¶Ñhº1& 7(¹-‰•‚X\¼^ÊmÆFƒžŠp,›uÒd**¼PKÌ3ãRVY]=RXpÖd¦dàÔ–ÔN Í5ð†ñ;9Y|Q§ëcÁ¦m|VªÄ¬¹™G¢r`y¡Õ^{ýÅÿy †…êwëKÀœIº]óVë$R]ÀrÊEyàÄC‚ÛØyTƒ!ÌíšÅØ Þ÷]®™$UùqjAàn°‘ê¬Ö‰(EMW€Hm–[€¸pjLÀH5Ï3çó/â_N×4ÚÔ7,[mSÑæ â ¢ªÀUŸo½ÈçY ‚©ÀR ~±%¶NÚ–Á•’’Ë!Ò­~"“Ì¢OW¸›!%èeœUv»g\qÚ8»cª®î޹æf8DBÒxšhàÜ©­½ÕÀPû‰ÆÖq-ÀøŠ³õùˆk¥½ý©N×O• ,è,¡·83è ^÷\µqØf—ªX¹^*uôÍûýw€»°Î0þ.°ëâÍP³}2Ü´šG{@ bGéÈ‘Ûïæ(R3ÛÙ¼ô_œLZ óÒÛ˜£Ì¬g)xG îe’[ Á–ŸÊ46šB+i$’»òÙ¦i/*å¯,†û¢œmšDÜ –Ú‰µøq¤iµ=þÛƒ” ¾‰kÌÇÿy2Ö9àÔÞþ8›Ù<üüŸû;óî—¶£s·Æ8¬-»†ËÇWtHá+¦×“ˆ4Ýîœ->‰=¬ä 6â]¦¹•Ž—p à.‰xŸÛ5 ‡«¸ø¼$ôsõ¼0«…(†ð⛪‡¶qtZt]´·˜ÇôÚ~—ã6Œ†¡j°¦zèä‰K05†ÊÒSW5e=5¦›M/ÝÃÌ ùÚÞšš‘“'/íOnÜ©«[äž|G$E‚ ÷€]Ñ“ñ))ô°QÁÆeÒÿMQ~N~Mðž(öoy…Äw„?’^Xz§µí :!^[±¢Í²ÀË…wÊç[`ª·{ðU=®Y@}ѦÄöXË#@kº: ;3'<`u·‰i™h“¹ÊXL:v‚-VË8<ˆÒ’ËÕÌåEÂa–±šjÊäiOùžÂ©SW*uý¸x)`« ƒX7‡°]¨pWï•”\…ñ¤´Cãð‰Â >ïÜÑ7Þ3[ÆDœŸ6û$)éø¨8îša þbª¹ «Î–ÿ[o"0aXpuúÊøÄÛŸf–oµ&KMþáúß­=üÿšÿójyµ¼Zþ³æÿìØÉçsc~9Zº°`”ÉngšçÓ­+Éø*üŒ.f“R­÷ÓíÒ‘élz3“ ÍLëJ:~/_Í4Ϧ“ÒíOÒ­²ÙítÛVÒͳ©öLb-Ù¶’ Oÿ‹3~ÀéùVÃg³¡ÏžŽýVGø7»Z>‹¥£ù³ÑßÌ6á“¿†ótÛg;"ÔŒ>©A¶ñ—Þ®%üßùŽ’ÛŸäxIí¥£m»Ç¿OlÖX§[©™¹F© ˜¨BŠ*àúzöoÿ>ùÿòG)d–j_©,N)@£ãçpÚFÃÐ×ÿüû8m§ã¶…hláäÞ nÕ’+€—xŽo’zõ&ºVE.öC#‘ü /ø;¶.xµ' Ï‹«Uͤ@þº;^ßBUåõâÂó¸çØ3ãk[ÅåÆð2l¶ KÍÍ×ÿüï º@9,ZMŸ¹†ÈoKŠ/ºp±7s—\{K•BË—±V'³òãÿ‡WÿûñüŸülI%àãÀQÚÁÉuäi¬g<‰C\ÄØÎ¾äÓ‹ž´Ä6°B³q.Å…#°à/8D‚›ŸäÑ`ÏÑTBè¾4WX÷œt@X7pƒ2Ï}óâEJŠÀsCãr0´?"ÞKÀ¿„g]xœï*Iþ‹Ø- ìL¬õ1L\KôÞ¬úú%—{–‚êõ4» ?äÒÝ-£qWÑN®:yÀóDéü¬™LâýMj<ÂuQtÛ3úl}‹n´µ=mnÞ¨ÀBÞkiÙh=†'ˆ•vJÎÁÅ®2ù3ùmÌü S ±›Ç3ç" €E¯g¾©qv²)¼ZXdÏz –ûaïe;§îà† uMê4R9À•“Lfû@NìYò[òË…¦éŸ¿üGáÿQ”rÈ_vÉË®Ùz±ÿ9Æ¡Œf¬Žñ?ÅãÏ 2çïÿ§·l¿t¦ŸXðUl‘•_=Ó¬rÉqEü _Ûڞȼ€¬HLÊ¥žr+_óQ-NqLß÷RñSDU‘c‡Ñ8Ô]‹¨á:kû.‘¨aóZ; ô[<4?í0x õõwYøq4¶— C¶´·“ÄÆ gÑ–5ÀH4`¢<Ê€Åöpd5}ˆ…UÕ¶0|SÅ\”X=q,ü¥™?“éç>,Ó!ZÉ@ßÔtlm{WB+?®ÿ+øÿPùÿ÷ë¥î«@÷ÃXÌóïëÉô6†uÖÜy„¡›™a`‰7Rú1n&³¹n ˜ÁJ²Š<ÀKQô–uV|[Ç¢¤:Cp…« ·ñPhúž3µš8} €5ã .Sc=I0A+_ˆHWDr”Tä(ù¹õQK Re”òOyï¤#K\Û nb͸4Åe²œSËÍ8•‹V¡Ñe¶´<Â9HH_%׋4^C+R!Âzgû2Êä9Jcõ ò×½¸ä¼Æ”.4þJ¨|φÔ¤Ìóå:™¹ðÌyÜsm­Ä¼$n@ Pöi®à !ò“æ ìçñwÒõ .ãþ#Íb,ÒMnZ5èñw¢±mÙÀs¤‰’ú»~Ï\¬eÝåž!ßÖr wžûÿs@+Ê<ºØjX®gØÝÇà àÜ"œ—Wö›9/öåÿWô=$ý_ë>ýßüu ž ü#§c60·ð—ï'Ö²åœTwWMÊ}€ôZm?V¢ávpjØÆÖkã쑉–(ÞîûT„™…HÉ¢~ û-RæÉšc¾þÙìP°Åï»cŒ&¾šmy•¢Íëø /B~f&ÚÃ;|õ8§KK»áQâ‘Á ÕéÈÅÆµà9 ƒð eâ BÓgÍj›4Rœî^?|á²Ò«äWk5×ЯLƬÀõ˜FÑ»|ž9ìÁÎqr»•bõp™-–ñââKfÓ(|ü²Ò‡ý¶NG{®µÜª&®~é)¸ùUU%%—q'ÆM¦Q¸“Jd†ãÿäL=Æ­c#°ÑLFòiŽó‡r6Õ:/ òs¨‡Å.ŸíÑD°+”T ©DŠ‘‹vbÄVªÖgQ ¨RÚFqÛaða„ëêî$SÏÛˆÝn›ó|¶ÕLÔ¼ÜÔ­æf!Ú9@ŒÐ•K,Tø?óòÿÿ±ðÿá˜ùWË«åÕòs–hýïî1,ñ¶'VJΜt8&kÍ·$ÁVˆ&FëÃ;"«Z‰FÖ<ž9Œ&œþÇÀ ²‚1|Ã{KyWoIúò±Ö³'Ó— ÚÎ'/–uõ§.½~÷µ¦w ÚÎÄÏkýëoDß+íèÆR?WЊíçüÙ;Ä1Õ–êë—1fy\³áÐ*Æ,aK“¼ú×^{pËá¼M†]; × 8ì“Â5”kz+u×Ý®ildç)\†|ÕUô{ÜD g6UURá¡Ó>¥ÕöÕ˜F06œ·Ù'õúúÊ5†‘’’+&ãMŒJû0XThû*+$<«¯ -K¦…'uЬUé1âÀn›cÕÆa@ "np¤ìµ“jÀñãç%aÈÆró’Õc6––\q»g){_-–Q—k-™%ƒ&ñ««±çYìÊé¢ìè¢Âó‰ö§N²1}:J§ó6åB¤¶¨`íÿcï]€ÛJ³óÀÚõÖÖîºRåªìn\Žc''¶“MÊqb;ñ®3öxÊOO÷tK£Ö‹‚A<ˆ‚xàû €Ò´ºÇñfc;ãw»§Õj©Ù”(ŠÅ÷û%Šñ!µ$êŇìĵß9¸¸¤Ô3ãTØãɰêëòâââ>þûÿß9ÿw¾“ÀX@œöéS½Þé¼¼ÎBcoá:.èCÝA²¤nèa!ë>|ŠÃ9^lR5¡}øÿ9çÿß;àüÿîËø?»huËPµ âÖâY——ߦ sÁu4²èòßÂ@‰Ü‰E×ð” |u¸™@žÑXLc -œy'Fcëb%Vî_ /£u¡åã©á+4½BòŒØ¦iÚžá ŒÊVuºk¸Ûåå·äWH¨6þ wØíövc»¿ "ß<î-•j†—ñÔОq·ƒ%]~—«t²¦ên<¹M¬†²ÙbóÒиÉ«“\V‹-”6ßàpxETAð&â_KQ?°š%^ðëeeCKh®x•ÐÔ­%$$…+ò°ü®¨˜å1#•d½ÓF+©š ûÑüðZ‰†ù•L‚”55SŒÓÚÌA`Reå ð¿×=K⺛áÈ !%„™d„º„ ‹ K’åR¹Q):´\gAÕifÝV›ÊVfÜR• üuEkK´e“«R‡gU‘rJªâÖ=ª‚ÿ[63üŸƒÌÿ+=s"±½O“S"¼§¯~åOÄ{®„º5"„dÿÐd¼Ïÿ;ö>ž‹6§ î‰ãx<3¥¥“8&:1½þšß7êäE<l,2ÝÌÓv²Òf_Nv‡Ë9x3õ‚;Æp¬ô Áñ+áVË Ž|üÍJIÉs+_w­¥õ)ZN~~vp:ÆÃáUňVø?"¿†GpºþaSóc€äX5,ÃKdªS Mµ½Ïà¥klzTÍô¼pt…(CìTâdHCó£@pI>ÅvrHÁkZâ …O?ÂpŽ1rQP_½.>é‹ðâÔØ/§ˆßéøaO#ÒQx¹Á×1\RœÙà"'‚ãà’¼}Á(µå ùÿû𿺠÷ßjdQñyi“X×ë¯ã_JÒòñ°|¬I,q ŽYTØWhè-BW:N.À€oáqÉ U`ÏS§.¢Q¹Ý38°1±eì£9šOÐbÑÎÅ4mð @ˆÂ`¼îbR †õ’’a|¡éVr!6ÎÇnBRdî‹…ž†i?ÙRámv{¦(þ²ÛУÕtó£aà|œ¬ Ì@T=²XEP6FžªÌO ¨Þ ³ãR’=ÐEc6S : ÞfÑ›4WB’#û«Ð,±8´Œ*Ä=Ã9“ò 3ÃíŽ1 zî¡¥bFˆI}e3ˆjIl?Í*lßA j1Ý<úú»8s«¥_“}Ù„m,ºŠXÛTxÃlêÃYù¼3T“˜FÕ±óHkeª³ÏŠ˜çŽ¤fÖÒÓgjwµãžøFe ÄU­©ÂÌDªŒZ!ü§ª³UJV-Í)ÿ¯ƒÂÿ‡ÿ?—+z‘ÿCÞm‚«qòm©â‚©-O±ŒTt¤>—²Äl¿NsOœ‘~ˆ¯ã156> ‚}lû$£» þ M‘ÜGσfCS]õð¦3x¾G³'Àê€Ç\ .á kò ¨}÷Ý W”,áeQTmeaýÿYt†Øî*ŠV®ÒX£ëÆ@CbP®© ]"oÝnKl{K‰9ÃÈ|¾™]¼éQ¢¢ù‘£„Ðt¹ªŠ&òôúÂöU÷S+ð•[áð|,–yçƒÁ¬xˆÃ³\Q±äv!`_q:&¥  Íyçc•롊%„ÃÍ)ü/UºÏªk7Ð%†ÂKŠžX$2•TÔÜQZ€f¯¨Æ!¸ˆØŸ§B²ÓÄ w’‹Eæ~¼SxÙy®„ØV¬ƒºH'÷tˆ –ºñ²P\r:'Å¡ÈÔ'aº ütEpÁéš Ï5fAœ*¢§ =‘- ^¸íýu)USzcUñoÆÿ+ƒÿâÿÃåpù1Êÿ«”ý܉”ÒF…xñ„Ìòï #ÂJ+×ßaXq»'Ùë>ús1ëÄÑšId›kåhJ´…Ò;ıÄÈB¶\äUôDÆh¦(<”‰â Ö®Á–º:²¾%¾ ÏG·4Ó¼*Ïq“F~¨®î¾ÌA k¢žœp?%5¼†Me–¹­õY„zþ Ñmhái\¶ñ"݆êš{Õµd()N.Š@Úì:öÖ´YûæRˆèa®t…¾B°”rgPùY·´l&Rúÿ]Ç þOÕÿîªI•jb›lq:'ðêá½+AÐZ:…Óá O@Z.h¥¼ÔèÑhÃAÀËY²xµWqŸñjà8¦Â›•ô0÷ŒÌ‰Ç^±Œ-Ìð¿Ëjüó·ë™ÉcÐ]G·À`{£‚”'Çð‘°ãؾŠÊçÑà˜‘uOXU{ê4k)Õ©¸ç†‚—„võù×ÕÒìd }š}êR©sŒÄ0[9šNªá/¯VÛiÐ]à q~^–ì¬ËÆ‚\;º)Ë`Oô±ùùÝ'N\À½<¥‹3)(¸n0ôbØÊΦŠ†|Uh{~wë º½ž)J­ëºÕæj:[¸Î‚{ ªÿ­Ž¡_'VUÕÑ¥bDïÇQK"<ô.s½®¨QB÷d•ǵûè0i Új ‰Q˸ƒ¿,jšª)£ ˆÀb¼m»­U%7Í£ “H·ñ»•¤…&¶½Þù:~F ÂYµ¥m1÷J€î*Þ(ûñÿ!ÿçp9\þ{ÇÿiýÏÝsgÕ„çûð±}B+EÆ~“¾ctUl#\F—Ž.£³x§¢ bÞN}ÃCI­ËÑ(¥ÃN»èÓ0²cÄÁ°b'ÀíºúûÔV®E«³¨ÀŠÏÐ…>P4åbÑ @ʶVNÁÀRCý&z6‘€@7^]u·¦úpom ‘~+™×ê÷ß&Æií}ÙÑ‹b)óÎhs:Š oû²N|ä´k5Ÿ”Ú'Š‹Ìæþ|]×ñò¾èýƒ/ùÿðHõŸý~ø?üG_p¿ý{ÿá÷ÿß—+þÃo{¾ù•ðå{®åëH2Îl0nø|ó¸"MöǦ¡ ¥*ÊIkc ŽIn,ìJI®.ÅCz]7›ÔQ‹Õ2n5c 4õc|ñx¦mÅC÷´^Ýhì³YGÒ£ä®>ÿz®ö ×o^¶˜HâLÆ# åå h Ø2h*ìÃà•—Gú‚ÑŒ¯db'“uú’lÄ(Œ»g4ÞÈÏ£"Ǽ¼«Vë°Ò¼ñ®hM¸(…;‡æë®‘Ý0nðJ‰uWtêäEöx§Ú¨P%#+·ª¢ª7D‘ Q4¶žvL!X!ÅÕp•M‹¨%ðÆÊÈ"}Ñ£TLiê³-ý/ ·|”JàfK ŽàÑB¤4#¥›7[5pº©ž¨G÷ëë7qbÄLkÚ¬Jyõ¦Øõ8[º-šŽbÒÞ!÷ wé$^ÉË zH¼´Ú+x ¸çR¤&œÜîÖÑ÷VFWE„ Ï./·+/¯‹ ˆ˜½‰.Ow Ô9ÑÚòD¯ëÊÕvêu×0”;ö]"¯ÚF0„aqÚFK¬#:]·.¯K®Ïç€1îı°b2ö:u' Âÿ»ûÏ=oß“ÿ?Äÿ‡Ëáòc’ÿ~VåÿµÏÛ‹ðd{<®©¬¬ÿ1¸J òIJÇáåd¡U¸\99R&PTtÓjt:'1 ”X‡ÊÊf, {Ð 9D(ìÉÍí”,ºÁЮHæ­Ï(›X0zÚþƒË€Ê@Y6"`ϵ’üC¬a±CÖ’!»ƒ4ÐåfgîÎÈàˆ®s”Ô'¦£Ñ5 8ò…œ P~Œ¼àÿQòû×#¿Ñðg@q,y½F‚Õä>Y6‹®r®rÈ?Û1ü·«ˆ´àpŒUVÞ‘"ˆæHûýsÑ*ÒÐpÑp¼T\<‰¬5]KK©o³áÓÚš{T“Ë E¦dÊ€ìiÚ¤ù±d³¥‹F}«8Å“ =Í¿5(Už&uÐÍ(:ãYÒá<_¦ã>àXŒŒT¸ZOu¾l%OÕ’J ‰Ô?BWŒ˜ÍT5ü¤™ýÔ£Œ±|ú?Ÿ•ÿÇœ°^ß±—ƒ¦Å<œ1'Ió ™L70 û|Ô0І1ŒbÜGó@¦–fÁ+c2“0‰ä”NXŠ&`ÌE $ÌXÁ³æé°)RÎôÏ£y×ÖÜÅ«OÿÝ®)“ñ~–ê4IÛð)+¯NF#«ŠÛë`EÅmœd}º¨ÄÑø×l¨Œ¬¸=Sø®WDŒÎñXÕz: ®`õÔ<]±§üâ ¡*‰þD:«ðO¨ÜšöAm:ØkêôRd,hc@AŠE@ÄìLfgIJð Žá#Ü%¼‰ØHóSåóR„‹Î¡"¸ˆW o î'R8²Lz†Mð/óúHÅ‘ËjúmV"Sù‰‚5Án°ãlÉ4©\Dè §‡}”j4• '/cˆ‘É&œY F×üå B›¤Ù^Ú>ƒ#xÜԥߎ‘úè¬|Šn*@:Ãã@Ô4âDI튵CËÂ)­àRú2Vu“wÅ…nÓ[ãQº~î;êlLºcä&­Âÿ‡øÿp9\~¼ðÿ^É”Ý}ü&ç[F!yJ8|Ä]4)a ëDA҆ĮJ¡:4áêH.{býací/¬>w_ÔT6¥˜KÔ€ èIk¥áa3ëù0=õþÒRKó"7!_Tà‡AXA¨OI+lÕVSÍ&Îퟞ¯a=ÒÊ_{«M–_moþµ·â¿~>Ž•¿ý¶ Ÿf½ŒÅTk¯ó/I7¤-t·/°} HŠ8C„„Íiô©¬\kkKQJ*#«±èºÂFPî|‘€sÆRØï´º“n×t™{¹·tÊëšö”Nû~ÊwQì´ÇGÚÞÍ‹\=èxÓõ~nðŠëìdàìâ -êsàÿŒ«õÏ©œs>¡ý(°xdŒ|ž²ñY*žáŒ¥]›'¨€}C¥[¾%Hø‡ž~Û)°B <ýX,5{¥h€ L«N³¿|eóLÉÞNù>'2–$9H1Ú>½•phI€·ÂÊKeøä+døÏG±6Û“ÀW;.íÉÕ«ˆñ™¤ý ™üDZ¢$‘ŽT¿¸›TñjÔ³ Êñ%:@³Á£ÁåH`^\@tc0ö"T/( Rˆ¬Ó—õù]ˆÐ±N3\Ù— =؈—Z—wU“ý±VÛyúôG…¬]¯Óuá[xvBÉξ,ø Ue¾ùÝRVª×ætSñ¯.+.ì€@ _ÌËéÔœé@d‡£åå]EÔ Ï¿f"áÐËF‘Fœöq…)­Š;ƒ}þ¿‹ÿUîu{¦·¤UàTMÆ^ŸwÎéO²iˆ¸un¿uˆ`=3‚?àò©ªš5$ÍæD¤]Ö´i%Nà-M4E¸þÓçŸÇòÞMl#ªeiMê-±70¾Ã<1™¬¤ÈiDp”m+AσHo&©’ŸR¹fS¹Šs2¢çIP9@%ô·¨ŸAïD<]Í!g^R2Œ=SŽW‰gÅÖA»càùô©Ä€ åæv²êÂÍS'>Ä% ¢g%ä9²-°â‰;c¢oÆ™v’ðEãDÂÏÑt"aj(hB¸K%d¤Ûcµ ·µn)âExµ±'• ‡V¼ÂmÖQÜ DIcÎÙmcˆP$ €²²rUVhBÆ;"Lâ–b]ΤEñ…W YËÒB:ÕORî6Šw|Û3E;H¡ú(„Ã6•޲}_þ_:dæ¶íîáÿt=¬ÿ=\—ÿ¾ñ¿CÑÿ'þÏÙ—à^IîÛûý·ª«È[CF°b‘µ2¥ç6Ûßj¨Hv“@ïu÷™3Ýf„ÉDªºÝñºç0j”³ñ•2u·EŒ&±ØFUÕ½ú: +š€Zž¡ TÞ ±5zH–›^T®!F¨`xZ¬ŒÜaæ.>]«­¹_½ÛÚ¶UÛÀO7ÓøŽ’{d˪i_Ùz{Œ2ù¤ZÓ«ËëÅ 1ˆ~¶ÁGþÀ»%ÖaR¶Ñuô×±ƒ½d$WÓù¯ÚÛðéËÿÀf²Û¨. _1û°'ë´ÜW,üàDQQ?F.üØÀ8‚;—×…»!¿´”ÔfØ“}((?ÿš°PxXH 'FN¦é‰~ƒ¡—Ä|`œ“<‚qãn Õ2d6ÝĽÒi¯"†¢_4õÙI°e €RÜ”;qâ%·y~Ç1õ› é´5Ù-Mqðââ!Œw&|·¨ßõK¡· À‰™½#À]ñ»®îžDšõÞï›Eúôÿ{õÒ÷ÐPqZMZ‘^O¦Ÿ‰8 t`E·kØÃdì+µCK¸½vë0š1»ªuG+WÝî)}~·×p5‹gÄU@ äm“dpÄ‚^‚µÛFqÓðÖ¢òÉ* >qâCkÊM®c\ÿ{0‘ˆ¤Üøä© ñäZK8¸lÔw×’‚:s¿ÛŸg"JÒÿÜIfÒü|aõÄ÷:óÊó}Ôw)¥sáá$˜O³}T;qŠ[w”`V™#àX@"Ž]Ù£˜tím‚¹·ÒShH¬UøŒ'°ž2%ƒ(:<õ„K0žÍg¥¢'œ– O©â¦…OSâöÉE'•ÍNn)練GM-Éð+.ál·$ bŠÑ3ìÜм ‰ø˜–oc¦ÞvkßCþWXgðkËf;ëÿ¬þ¯Þ^?‹]5sC‰L¦›ˆ’ˆÄžu9Á•)G¾gµ¾æä|b4öäh;œÎQ£ñºàR×$n¾Í>’—×™•}7¤¶î~‘éb„7Ž|Çlé×ät{Ð]dþ(VµŽgj*¼™ý1:4ÒGõÝ"C«¼.&¨lSGdD£ÓÀFß…#„cAÃfÕÜ2ÓðuÿÇþXs )¸†È”d…¡ï³Ö´K+‡ÌÍÄÕy"¬-4•úJ4µr“Žð*š\(âÆW¦ë•¤îFBÑ<Üš¶SW˜öB:UjÄ„´#L~¡–É”’@@u‰dù]SˆXÑßæçuŒ×ÆzÜÓ'_Ú'}Ûº­ætìè"ðŽ#ð4Pèš•u©¡!%õ™VûÌxD¶©Î³5(Hïù´5ž¹¶½6ôé>S<1ãüÊ¿ÀÉÜMùY¤øÿO2øÿ°þ÷p9\~<òÿìÿµsîE·Öä®,ÀK梛èáÑ3Ù:|&ûc–%=L (ÀŠ6Û¨ŽmýÌòt3ƒh$ñÕ9%Ìsòä‡uuŸž9ó1vöyfZš)±¯Õ^µ˜·‚l¿¨9sÌn©¥Â± ûˆ1ŸL$1&“ãm?ŽvìØû<âL ®c°p•Ni5Nš÷Ÿ‘ä)K° ?kY¬VTÜ&ËÈÈjuÍF¤rET…ÿóÏõ_h~û -ï|±õ›_hzû‹­€¿¿ÕxþgÎ{ðéѦ÷"a*ˆ«!¸5¢¤ÖÜ­¬¼Cî«å·øw(3F¢:wpQ¤‘‚0ø{¢KÂñ¶¹¹ -qfŒø6ˆPpÂTSP± 5Ò?³jôfz¸ÜNç¾¶ö,` KmS".P±(h°¶þS®Ø¥‘K²v2F9 'ÉçÖôäE+‹ÿDc«^Ï´$¾•5<âæ§Â5̆¯Gâwp+~â›y?¾\Y~î-?­¼]þsçý?ý¶K…ÿ3SHiüßó9ø©iÿÊ‹®yÜS^÷T¼šqZ£} ×…§Ø_SµèÏ7è'xæwÝU®ƒ·Ø±û¼³­-O¨Â±Œ¨þÁÀíÒÒq6\›&ÁO{ÝÓµ•wpd¯{ÆU:I­¶Q¼ õD»C8DyNÄØBm•##¦&I|ÿ\™äUµÄ©Þô“üà*çÿwx]Þ[ÀK€jøk´Œ†£«õ ›nïBMÝ}l EV®´Ôxp‚½¤W„WbUTÑ ŒÔØô¨¨xHÉåšÎÎëuyæ"1¼kî²[Ŷñj€áúAcòUßµØ&£1@)²–`ß»±ÚO}勈ֱî+_ŠVÝ †Wñ7/¿×í[¬­Jã9“Û©ÜÀ¯+ø¿•ÕfL¦^v1^¤§õ)^mŽƒÈ‰Œ3ÕË"0 ŒDz\å Å–!À-¢Ûù)mm£×'RyØI ˆqóiñLy}³ØÓNnbSˆËÐ’‘•:Ç)Äh}Œ>*ÆþS%%ÃöÑÊ;ˆ”ÑKØJFììT †–€ÑÕà',æþPpqá_)Äf±ômÁÿ áÿ¼y0üÿGÁlûóÿãÛUÑ ŠÈRAKm-I" ëª»·P4ÇN^ë©gª.ßÎ ‹Á¦ r[‚ìÈ4!òBdÄ:6[œô~"sLò”E:‰y›ÀÏO…OHNTÞþŒ'‚¢)â Å…ìÀ¸R;e(“Ø.2ÝÌÕ^-4’Gyžö ºñ|]W>qݯt›L7N¿ˆ&äQõM¾®;à¿e+Æ¥´ --f±D …­uÚ«êz|EH_ÖÒ«é-©hTžriÀ% P<%[¹„6 Ç·ÑÙ¢I‡B4¬ˆøOäã(½OŽáÛl2>_Q±ˆáReä»u‡ ¯ÉV’ ˜ªn=\¤&æ¶2'¯˜Å§¦ØÒ!öž;É ¯O*ý·)¾ßv"¹ý2CÆÔʾüÿ¡þÏár¸ü8áÿí½3ƒêÁsú‰xÓÚò¬¾txÐwE¢+½aw¤ š5µ÷„x#¦3Â¬Š’ÔùPx1[­e¬RÉTÉJ"Ò3Ýît•èÑ£ŠäzÈ`h™, C‹à"b0‹ÒT“ ü"ŽVÅÑî>áW0¸×To`¨ªª&B&:Ÿ––G)äÙ¾Ûœrì¢,";g­È@~@$IL¤òVõ÷ÍiŸjÿH 2 f¶`¼{šª_£1â .–W|ÚÚHŸŒGÛ¬ÃI•k/ÚÒ&_ø ô"BF¢ÏÀ³´”ù‘[HÆß2hwŽ“0£waÆJ„0”g³Ãä)·ö•ùfe‹ŠÈ4G̪µ…XÀ_Ç–:b¢iµ<ÖåvãhˆÑÈtÞJ¤tá"=à+••Ñl»Ç=ƒgÑÆ˜™¤Â9ÿÿSïã§öq„l6먽dÔa3Ð@lM¥ñÿó½úŸ;iüÿg‰ÿ÷°[÷òž«…nâi†O"Uˆú\MYO¤)^ŠJŒª v'YN}w… %ª"öNåjkJÙƒªZHУõ‰¢+%ùƆÆM²^%ÙŸ'\yàD%¤ÍÈ|ü[W{_R¦Æ’ñS¹7œî¹×Ž]WÝ;v¦ÛjýÝ7.fÜÔè®íDÇëÇ.jô7_=ÖqF?ðÅßÿóòð:0ü‘“Ÿ¼vì’?¸‚ Ô›†ÞxóÒï¼úÝ]Ožq [×÷ú± ˆ#^9ráµ£jõýÙ9ײr{~ûË߉Äî‘ñ„öú+G>øÒkŽgwù+8%qàëYÝ_zíƒcY]§r{¾øûï¾y¦ûø™kZÃÐëo~|ZÛ£1PŠÀéœ~åè‡G³®˜JÆÔSxï²².KeúÑ£ï£ß@KÓÓ|YŸN{¡}~~÷éÓô=Åæ‚ük )^ Ò ;„At> (¡šÍjÎÏ¿&¤Ž¬¬Kx#ðèËÊÈöq‚¯ì¬KÇÞ>ôgÎ|,nhŸ@òR ‚/¥©8öDX.¥€’Cˆ°»£îª9ÿÊŠZÿß`80ýO•þ¿ôêä¿à,%%#¸'9qæRrÙÒÒIQÆ[ŒÓa÷xh°¦XÌyw ;À*¹<¸§ššž À¡¸Œk á­“Ž6“*²NS÷Ù;*•  !ùì›­H›A(|6€vN¿¬‡Ù¥ˆš‹üå VBá%Õn%.ÂjDvû(ww·Ñká!`t–Ž»ÜSK©ß»É‰¦4Œ))ØœØÞ›`ßV©rm+¡Ù¼d=M³‘0A¹**ÎS%”H½Ý ‡W”Ÿ“¢ûÔY|[•´ßV, Õ¶bOÙÌ ™ÖÌ"[ÒsjÏ å2åwÓýÛŽ¢KöYÞèÔº2øÿÚÑCþÿár¸ü8é Yz/[;ÓWWi£®–ôÊò½žY—sŠÕxÆ¢*"áµú:’îমÆ@_S¨áiC=)žµ4?ÁxTË6+¡à2ð3þ}6œŒAŠ²ÓŒ¢ëj?õyçkªîQªš‡Ý1R„BK )éEt°O›65jhך55S1ŽÓžÒîÞEÿ|êø@¥¥‰ä3®îœ-4ö²ÌPÓ5‘¯»ö{¾?ü•@ÿ®Jþ‹ŠÆSÕþ›Õg%€•ä?÷×ÿ›ØÙ/4¼-Ç[쎭¶#OÛ…Ñ㾡àz¡±7Ow£p,¶®Ñ|â°æj¯ „.,¼q&«£¤dØbº¶Y‡ {NœøÀbé'pΦ`^ò<Ëξ„È£s6¥Çý] èeœ‹F¥Πo*ø*£1Ð(¤24“‰&D0t–Ѹ?/'$#é"­Îù Ä ID"K¸|®ÛBìC”ìðÓ_'0†ÐÎDˆàäê‚«tgBEÓA ÄØï~&ÇÖ xÿ¿½cüjô[¯Æ¾õ•È©{÷õêo­ïKÿZÕ·~»õòÿ;{ñÿAçÿw_Lþc!:´e¬Êò»ýDþ”˜7S|+‡D“\¬pßéòº¤V—hcÆ82n¦ÁØ‹6ƒP¦Ø2„‡ŽãPŽbp—«üü«¸¥mlŠ„gj2ö–yfm%#dÐsê’<‚¬¬‹&S¯‘ˆC£87ü–ÉØçb¡oÖz Gá¥syÈ>,ßЉÝÅz™o¡¬|±,°TÝð–Áeo¡"´â,úÊÉü+¹í  .E¢Tn@¡wý»s2JU„kѪ»ØîrÏºÊæýK>ÿBel=]õ–šZH3'\‰Ä°ÃŒ§l®¡éŽ ¯º} ¦!³uA½Ë3 ¯°µÄJ$ºZ^±\I k«¥å™×¿XIæÔwu¤)ÓÆ…¨ûRÜJ¾â}&aGÐ2ßôŒÙÏÄà˜æ"ÓXT±\Ž3”âJç”ØQ2]ƒ“ØVø<äYÜô0yv'EJoL™pû”ÒévÀûT õ¶ ýsb”j½»¨ñ’ù?o?°ü?c6 cý%ª•-fózTôfh¥LhŸäÂÕ«6û0—ΘÍ}¦ÂlÁKMÜøÂÖ’a´=t¹¹©ž*/¯S—wµ±‰f@Ðͦ~P…¤4à`»º}î0ŠÇººl$5p¤O,‘ñ‰N… jå"†ÁÏ’i6ýª¹j<¿¹-í¡É?­q–hfÚãpEN™r2=šVÜÝʈ\Å3K†Hߪ€ê§ÍiµgÅ'®Mq”KÛÊKŠ&‘®žw]Nd,w¢ %<:rdØI¤#¦V6éN&wÓ…9Ĺ­xÆ­^޳³×Ãw;‘V1RG j2Rj=}œDz: S}–Ø~¡KKî¦ð’ðÿæÿßù«wš·”/¬Ã%ºn½¦S›Ý¡ÉíÒ™nygË7›þ+Þ•¶§mes>cŸ ÇÁÑò®åõ›q xSˆ‡:\—!ÿ¯}R-ʉ¬’Ž™sÒãžAÿÄXêÏʾLrÓ."ùø8/­Õ^tÄðH,C9ª¹è&àk _ÙüéÓ—$ÕLt¶m§cB¯ï.Ðus'üé°Wjʪ¢ë×ò´$S©Í»RXØ‹#—‘7Ðe§mTR¯”¡Š¬ò¯ ïÔlºYÈ4lœ•2dQÓ=]O~Xwš)y@Ú dƒµ«Z£ Ù†û±êõht•g%V˜Ñ1åÉ…´Š5Š<‡ƒËå¤@BšÿªÜ—êæ(I@¯‹ž¹›T2ÿ6Öé4ÕKF–ee³ì±u§¼œ&/š›aÏÚÚûäwq**HÕ'©tѤX ±S á­xŠK"?TgݶÍaΓx‚”=p¨XŒ¼kSi:á<3½¹©é‘˜ÂqÕÔ~а ·ƒW4r‡YÖ©Ùm±æOŸŠ(}j¬ä¡9š\ûëðÿ(øÿåü‰Xaf7S¢ÙW—\>ËËo _K\ª½rïËø O_Äv«§,ÕÎÑ{Û4~•þRòÿ‚ÿñX€ðµWó².gÅp£°åqËø–œÿÏç]SîÏ:|p)ôy Ã÷¾:õR{¯ö©.?düÿ–èÿ¿tf0ÕçÙ¶¡á!z¿ÚêûèŸk«ªïVG7‚ìÃx-Z¹V[w7J„áGä@8y ð¦š-‚ä°À#(D+ŠmTWm¤8Ä`O1UHí¿b±’Lo×Y>ßZª$“Ù»• ™ü~âBã ±(™¹Ê\í=|h[jkîUÓL|˜¶®ö¾èáB€x½¾Y ‚õõ€Ã™¶Jº—ÑØZ}Ý}@;9œd1—ÖÄÀ¥¹ù±È‰x&¶à# µæ&Ò&"—æÇ¹,b='ž­î1÷u+Z¹^Y¹ÆÔŽg¦VuË{{f•Ü~A°zì%#-Äš±[GNŸº”ª§°ãÄxÉpU4 Éºl2Þ0zq¯kX‹‡¶Qƒ¾+cŸ6§£Ðpƒj7ôºn³¹/?·ËfÉ>ý1b.+…]dOü¥ggÎt˜ ûlÅ#8¦­däXÖ{¿ÜPõ‹õÑ_¨ÿrSÕ?¬ýR}ô—b¿þV⟵ÖýƒXÅ/5Ä~ã|âµ·¾½ÿ#9UãÁëî3ÿUÉöSA"çëHHŠ•¦ÄÞˆÈl\(Á)Ó馦‡¢©ØÜôØ_6ذ¹å1âÄq¢Rå÷ߘ˜¾¡é¡hOÕTßkhÜ$wþ”˜r6YÒ¼2º`$]vX#ZÖ=ži©|D#Ä+ƒSQ±ìvÍÄbäæœPåN4žgè;rªSoÒènèŒCy†YškYy× –Q§gîä™®3y7Üe³G²¯=Ñ ¯˜‡õ…:Cÿ«_¿tLÓ¥ÍÈÒ^{ãxGvÞõ¬ÜÞdr;±òeä€TfaiZÔVFù?]r¨è–d2¨é¢EEU ÷07çJ(¸è,7™ú ½N'…Àm„ð¸½#ãS¼ÔxDZ‘fFH(õ¶Ú”|ÏJûž<ç^ûrnçvÛÓINÉç+ }¤Zü˲³/ÿŸ ÎíñÿJ¦ëßÁF½®ëø›ï¿úÕo¡sûò—ÿã©ÐÁ*!žÚ„b¤U<梯 BVçÒ•ÖO‹€©sì*òLêÎüÞžÔôœÖöþÖ—ßÇXðå#—ç«^=Öñ¦æÚo~ñOiz}þåßyåƒWÞ¼ª/Ë-è=«÷7;¿øê»_×ô|á+~á+üÖW>x=«+K7ð{¯~ðʑίûä7ÿÝw_;Öñ•#ýî«—²uû4|™ T´ÂÝ‹òï‹Ò@méò™;÷wŸ%J*¨$ýO\—šÿs ø_Ó©ý1Àvt-öƒ öo;'J?·CâÿÃåG/ÿvGÅ)}¾Ïb†´7)…NH)Z–nlxÔPÿ°¡îA ü6‰ö4<Á϶øNsãŒ8”å&as¡GÒ¬(óüר–\#ãB›o~L;Pµéf+ûê²:ýãxb§-¾-9êdz"UzàT>3mC,Zˆéü‘ïhgM¹œƒ.·Óë%'G»mÄdº‘—{5žØ2®#²(¶ È9f±Æ&ß  =Ø9Wû‰Û=m³dŸ¹l·ÔÔÜÍÏï²Û†q@²»õß “2ÌM@”ÜÜNcA¢üük@ì$ÄòìfS?¾ž£é $ãê¶’OÖ´jnwK©Ø7'+è÷Íãžã‡Ôp-ó4îm\"ž¢tqœƒžhX‘Üô<®+ZòÇù´²ÎªÇ9‰¯CäØë÷Αfu9b¥;à"ÑhÃdÊ\Z^~«¢bÁ" ÒÔñ-ŽªVÈ(¡|ÁÇÒv8~0x 6"!óÖ0†pip&/šHçÿ¯9rpüÿqEÿ_=Æ _‚Â%ǨN{ELë 7´šWé8†ÑØCüðünl|Òã!ö•û)„,-·Y‡ ®“@ Q,üþyv‘”©Fs¹@O‚NØÈ>½–âA4'4x’o-ê·ZjXùÜa9“}û”XÉtÉOrߥ”ÒìÏÖ\Šs´H<.¶u¹&-–Šà¢Z V¡UÛÝÓ9ºæÑbûø™¼€ù}ŸÃ=Uê™óøç¬ŽIKÉh™1Ï4 -¸QU{Ïd5Û°Œk 7M¶‰çT±cÜd1™‡îiI†+‰ß}ùdµ¤&ý®ªPPVF„0CðŸÂTm[â º×19õW$€dbKÉZ‹^=MTeØ{¾¥H rW#e5ÄIdT¶Ó†ÚÛbG®~T‹2)°Ó®P€Äð÷Üó³ ìçá%øÿøw?ýOu¢ÀˆßÔ‡è>?¿ÛPГ£! 0#Ë…i²Y]Á7‡6‰¾}Úgqñº ‡}Üåœ$—.ç8n¸Í:Ìn¤äzLéV =(éuu²H‘Û¥wÄV)À¯llß+É‹Kkn&^ñ6ÙDO¿¡‰*ÈJK'pixO++ï44<¨®Ù¨®ÝˆÆÈf%ZµÖÔòDÑ›Š§%°„ù“Χù3iѪ= ÄŽ£¨es¸ me’ê|Ø}eº ŒJé[¹YÖ5<ÄOÔ’_iI54>ˆDÉ›M.VµÁÎõ1´Õ7l’;wv[ü¿ÿ|Æ:\Y‰ ‡xë/ßzû¿¼›¹S™½ ?>S¿þ{¿"Ö›²ÞµüÈjW‰£%¶å u¸X|>‡:Äÿ‡Ë"þÿ,Ã&aÛšY²Ä:D¾9n’;+uŽ[‹‡1¸hµÀEùºk•²úÕj¯ä_µÛDz²>buîKì¯4Q\<(åv“±©6¯Ó`ì)!!ò´µÙ†Ož¸$V ïÉκ¤×w Òky<Ó{Íd÷Éï*¢Üûª™$݇R¹Z{záÌ'‰ O…ÁÐxV…¢ÃÈvQÆ|%YÆN5‰6q“dnÉ¿¸!Ï–×;[ßpŸ‹ ªI“ÙDt€g9~K~ˆ—5ÜÒ}& ûÎ_IÎHMt °‰¬Æbë¸Ãø¡šª à(œ.MÐ,Mˆ$¶Ø_†üå±`·ºÚûâ€F 5wÅ_'L 5÷ª«ï‘ª*"‹jªàÆ¿i÷šøé„umì 8ˆË4UFÖ™¼M¢¬ZdOX …–±'¹¡‘`ø£™Úÿ·ûè‘wÿï«ÿ•ÆÐÂ&! `ŸbÔ®«Åã^ÃcÂЌȎn2þ]™&à‚÷ûœeݹ-ÜÃÆFÜØÒ*°ˆàŠìÕÐôwF›YÁmÁ§h´O %ĪÖÑj1îGî45?bØði WÄÄ„™Y™jçSË~Ib6±'Hg¶Ón_)HÌØ3P6e¡Û®|º#@—wHEÊgÓ©ÚÌrv7M•I•mfz%!¼¯VZwÝËÇPh â")Mv@Ø)*‘ P\“Â$@”"00JDSåÕ2“¢”U æÇÆF.)"ºZ˜-óðuô6”UHl™MÅëH»'ì¹-ÉvõÆ­è¬@#ºÀòmÙÿ ׎þOîÏÿ+m›Më†[ZŸTFV-¢çAïÄætË"‹Ähc¾²[l]7ŽŽ ·Jû­Ôo á°˜²üƒ¡EˆÉ½ÞmÉ}t =Ó+»ŸpÐôü¬Äª2üs{ÿ-hNòì`ç†àç@ÆÎ±&bE¦‡ÐÚ+¨'\‘ݰâ+›µÙFqiˆÐÑù ›BÃòG÷Éc±ü¿ƒ4݆Oe¦¿ˆ¦‚¹vd"ƒ¦b zŸ…ªØºÓ9YSýiCÃ#2ó ¯È×Ñ7â_¥7“š_%æUøöÊ]§°ö4›Ži¨i%¤Rxò|m/C×Q•WÄ÷2|Ò[¶Ô†2ñ½»}V™¶jntwù×YÖ>üŸÝ¡qÏxñn}V¾D…üýWï|Ö‰ÔÜ­Qö,è1œ{~nß­OZs®ä* Ÿõ£ÿm¥àË`ñ! =\~´òÿ/-þe®Ë*úÌŠÀí(y .D‘a˜òÒüw# †@,„å·¢UúP÷ÿñ–ãÿ|ˉåïœ/•uZù†Ëß>gÃü•þÖyÓO¼“ûSçŠ*Q,;`ãÿ~ÎŽ•Ÿ~ÛõÓ珞ô:ý=Og•¹00Ý£*1–,¡ôÊKÊŠZ±Ds®óÏGñ|LõW½Ä~éíØ¿}ëmÑXÛGŽUS.“™ÓÛC]Ø_ðg¡}¤¢¡Ä<ä´‘ÀŽë%Ãnç$„º¦´9Åæ ¬Äbk>ÏlYÒb¸Çžå¾y ñÀ¥vû8¾b.ìomyêtŒŸ>u;8JF5ÙŸ¸ìã%ÅÃè°¼îaØb¨%cMË Ï;k·b jÖ©0žj².{½d z t¤ÍBåÉî™o~àvNÓ©ê¯Ö¾€ÿŽãÿƒäÿ0ËèEŽ«(©>Œ„îÞHŒp5?™/O¡1ãnDc«M¦›€è ÌŠgw‰u´m¥tOÊ‚Áeªù刭¬~ä‹®áæP<˜ 9t ì Ø .aEœgEYX…³8*&ž•,;ÆÑ÷€Ùp’@tåìéI“>µ÷$É"®¤yΪø;)%RDyÆm~õÖI«÷Û_>ßÜò71 V›I¦5%̸IU±¤N§„ßÅR ^«kîa§:ï¬pÿ›6qDÀcÑBîÖ‰å»%H©¬lŽ<ì8^n$Ôºø½bÁ·Žù3ìo•Uÿ¼Õ:pêä‡\+Ô”NFÉVÊ$8c¹Ú΢¢›EEýØh6Ý<“u!jqñ øyY-Ç€Oœ¸€ïšL}YY—€q·Ñ† úk H8W{%[3õŸ8~j ,ƒû^„"ÓÍ7^ÿŽX (]G{jÆP´Ð™,$h?Í¢ =ÃÚ§ÿÃþ¿…ÿÕ†¿ ly£}/`0°ðÝB+!¿ÒψŠ’ÃoO>—i©}èwOŽŒ'ÎמZ°s}ýC•ýÜ®ZØG–D<…*)QOù‡u‘HU9q¤Ë($(PÍXŠðÐñ£8ÉÒÒI´½þ\µ;ÆÐW—— a­"?ÿ¶ÙԯУ/¼YTxS—{µÄ:Œ^(7÷J©sÏ÷䉓‰m ¿À†ˆˆ¾ˆ–€ã˜Í}¾²¹;˜Í%Ö‘xœâ‹ì¬K®ÒIÄçq9Çóu×òuÝèÛÆ>DønÚUyGfú<ž1+cgQiHpÈOÑDù-*Ä…o¤4kA{Æ™àeÁ;…ø+¸Î¿KLÑäN0xÛfA/-3_¢Œ$Œ8ìc·¡çÁ_ÕÍ=c"è4×ÑíP¼¥~{’û² sÃ[l0Ü é3ÕäÑ>3k~@»íɧÿm£v.߻տý_ÞÖ÷4^÷SïüÕ;ÊnäÀç/Ý-ºû¾Ôÿ†‡:Äÿ‡Ërþÿåâ`Ú§HL³:A’æXe]–í¶6EN¦àKÛ'BÑÿº%ž¶ûI Œ¤ó* ‘fϸIÄWžØM¥%·2²<,ÆIÊ\0ÌR¼ðʹ?ù¾gòóçË㪠B´QÇ2uþé¼½ù´†æ›uƒ#%ð©†bI²Ðž€$à AÏOÊÛMkëÈÒÛ+yž"Ry§žRÐøJ°b gÕÈzJÑèZmQ˜$ÕÌù´®lŠV­û}ckÎÓŒCx9['ýjÂT7+#+€¸@ž4]BþËWªk6°ƒÂÿQ…jüý€ý·_dþKŽ ˆÚMœónÄS"G‰AÖhìÕ±ó,¾«Ñ|‚QÞhì!Ô¾‹( #/p>ö1tc‡Bc>r“¡êTÖéK•«ï[êò¯r Í`€Îξ$t æc»}„­1ºÈg*±]h¼ˆëóÍrá ®j4B?³Ù† € êê#FÎ'*øÁÿ%Êý·´9WK›½yìÏm%C@,&c" ¾"·ø.䨱÷-¸™‹úNÿÀd¼‘O´¢q­¶?JŽ· cÄ}õØÑ÷þ½e³ÀÞ§O}h·° Ò ­døÍ£ï¹]Sh*¦±[òòºÐOºèvOžWiž+¶îõ̰*û~‘kê—Øm&ËÐ Ê©8h§]¥ÿ³·•¦«VUlQRK€ªù?Ç?þO ·«òçÒQ z¥“ûx±e¨©qÓaŸ°¿öꟺœÀ¨Nç9pÙÇ‹L}Ù§?J’lÂ$âÙbó€N{G(uŒc¥@×ÝžÜA 1äw“Új1ÙZ,ýxGÐ>ÑìÓªª—í¶Q„ÉäÑP2T ï1›o¢a—±] Ú 0¼Ç3öïfãlG“@ÿƒcª«håÜs‰¼7¥ #‘*XÞ“»D2E ‹DWYú^<Ô³—zJ ¨¹õ1¢]ñIaS92ïF›iá9PD²Øí}ŸJXŠè¦¡q³­• »Ä…l(kîÕ7nh| „rü"–Îö“{Wý}`f<_Ù~ˆõð‡$©ˆ§ÃÅ ‹2¸[W÷)‚ìÉÞwôÊGÀÀ8þm#®á5‰{Ú¼· z×XO±á¼0â°•0©éž;z€Px'7 ‚f†ï„päk¶(@#hÜhSbŒÍ¬dŽoÑߦDz"L¬Ë¿R>ÜÌëÊÎ"̈¯4§ÿJ§65§}š„Ô¢Z¤ 2ÉÄŒ6•­ê>Ê„òWxMJI)µá +25€å—à_ÁÿäÿUÐuPúÿ*ÿ/¥CHiþQ€ôvû8žx” ~hxd.ô h-þ9ü˲ÉèCÖ…úˆ¶á*(óÎ8ØUÄÃ%NxBñEÄáÐöD«@“¹6´.ì/õS€VqÛdì¥_q!îÅ{€«¸˜\€±'âJŽÉ_¯”L®»eÑbME} Õô~ÚjòºgBÇñ4%™2””[©”– D߸.fReVKËc¬£ªDè™­dy ¤Ê_Nò§ò/N^¦ª)×QM¯Bžrÿõ{å·Ž th¸á•DaäB£°‡eB7Æ3‡9¸.qChOó£šÉëÙHÒâ‰&æhûúóî.ˆ–‰VšhÕÙíD{ʦ­­í)%¦Tn#"ˆšªPާ̤.†u'74m χhrm¤ðŒËá¬Î#¼/™ñ²·P„ˆ†ÆD™†êÔÞ³]…Ä%®‹ü±üÐñëÓ6—ŒØ^ºwΧìó½ËÐZ•=«7ªôP‡øÿpùÑÁÿcß8·ûÖ7°<©þ’ÿGσ‘]§ír;§þ±3z\® «eÀa£¾Ýhè-*ìóº¦0¬h4è0ó£×ÿŸó G¢Éý²ÚÁžº<’ôôº)ãÊúo“.çäO¾MøÿWÑÍâëØRZ:)ùF¯{ÖhìËË»âã“à§kÜbîÏË»*Ýšµ„¦ŒÑÃcž6*®¼•ÖÿÙúÚ×?vºgŽžè4ÛfÎèûOhz¾øêû¯¿yéè©Î/½vQczåXÇï¾ú¾ãÙ×~÷•w_;þQUíýßúÊ…_ö7þ¯ŒëL_~ý»9†þ/½úÝS¹½Ùù¯¼öŠíÏÿ'öê¼H.Rª&3¡ô\À‹$uuþ=“Ýá"JÃþåvØPÐm6ð¸?Š«Æh+ü ‘9š‡}ÌçM&¨¾•«M'þù¬ÓaXÇ 7™nœ>yÉé×SÞ{ã)£¡Ç »†1ÝëÅ c0ôêò®$ãÏð €ÿ%Õl6õáÁ9“ØG;qò‚µdCì…½8&žˆ6çcaoz¬y9þ?rÀüÿ—’ð-Eó-©D‚ô¬"•wÀL9Ù@ —)ŒbòM«Ú°ZÝ®éPÅcv£‘Õ¶Bc¼1j³j¥ðRÐ,ý\øŒà á–¶±¶?î!vß3™/xg¯y<3x^¬º‰OcUUÕw[Û¶üå·p&BŠö¸fÜžš5à› ¸NÎÂ$Kµ‰h¢G._ ©[÷Σ-°*Fµ'ÀíâÝ `€RÙªä·ÕÕ4,¹—ÏŸLóåŠrZüSÊiÓJ#[jˤ–Ö” ’¨&’÷ƒm¬HI‚Dè¸3Àí8J Gîñ_å:î!n8Z Þ\Üüë`Ÿ „¢¸Þ“Žp«›Zž¹]2²ÐdGö%{ɰ¹¨¯Á~ß<ÖuÚ«ÄlôÍ;ôÜM7mÅChEhfèZµšìà´£±™ ûÎd}\ ïF …±ݬ8Pàft ú­ÅC†‚ÉÆ É!\B߈þ„†9ÛeBü·ÐÒpXö^YDˆ„›‰®À^2‚–Œ.GÀic´b=êU|ä¥Pn  ®G¦EÍ=œ®½‚E¸·‘ò+Öï[hkÛBcÆ•â½p•NÊo£c/uMVWã‹‹N¶ƒLîaöîžÝ3³#üŸ¿ ø!‘³‹‡¬/ÝÇÐkTÊ„?+ÿbz¿tÒu ‡:Äÿ‡Ë(þßG™P 'eÐAGz‰u÷E»’-#°^W‹®‰D8Ùì>À '¨I½¿˜óÿÿó;ù?{® Ëß{Ë÷÷Þòÿì7d…Ùøsçý÷\ÙO¼“‹ÿQ2r4üÞéÚKº¶.,¼rMÓÔ¡méÌiîÔ4vœ¬þPðuÍFmý§¬Ž’ò(ÅÖujjîaÄÆÖd ©oxP`I´oG«6Ê+M-OšÕÕ?¨oÜll¦¥ŽÅjÑÇÖ?hÀÞüøXüƒÿõÃÿòNÁÿôN~ ¿ø?~S»où[o›ÿÎyãÿ€’ºW¹Ê`§˜Å«uÚ㉌)’¤}’ªâ¯LgJee+Î Ožk¦¤SedUWÚÒžõ”Ûd×$ Dš¹nzÜÜL³á­mOZÙõß²e«â'’5eõTÆ•(²Þ™fV^JßsöUq´Tl(ñ»”ʦ‰õMšo~ìAßjåL,ý},>/Tþfê?ýŸ—Ê\c”ǘ T™`w-®ËbÀX‰A¼œ¦ìûΜù˜œ×’;^÷ŒÕ:üæ±÷-–A| Wá^“}ÙXÐcB(š{ÕR<€C‘±WÞU¯gZ“õ1…P ˆåĉ I¢¬ã– h®°?ëÔEò¥å¿´tÂë¦Â žÐYÎÑvX­’Ä#CgV¼4{,æ›@ˆ ÿ3`Üï_®àšúIì pRÄvfêëïËOà(@3Ý´X‰`ì%ó8…åþòŸt†y¯xcûÙ=jÉ—•ý&2ĹŒ”Ь(úêµµ÷µÚ«ÕÕ¸]ˆO‹L7ÅÞ5Ùó ¨<}ê"ú–¾œìüëpŒê½çç_ÃÁc=~ü‚¥¨_¯ënjÜÄóä³Y€)þB‹òùfsr:[[žàò=žiòÆ{E,õP^>àzêÔE¼ï8&nZ83ÁûȪ^ߣ×_4Å¿N"ÌÏzÜS9šN„Q"“…g„£± 'VlÖünZmþ/¤±á â/ÚI(¸¬T cÁE!†mOªyY©V'“n*;îKã4šÚ˜ J­ï³Dh@% F2µAWPhìÅsAOrêÄ…SÇ/õá+%Ðþ5šqiä\ÄžˆPò)o3k·:´¹±§Ï7ÓÖ¶«íD3Ƴ;òúwÿš-DÉ3ßÔœ¹œO‰²½*Šè…oœÿOñ ®}ïÍAãÿúûõ¦ýË`ö;õNv‡&eÐkü>ªM7‹îP‡øÿpùQÃÿ{ü¿^–8•Qf—xݱõ¦†GÕUw%u‰± ¶æIÇD7H´a“ÕòW%ûpb$ÿÿYUõ±&ÔsYbCý} X*Q¬Ú€ÊF™2^ ßJòø"œ  VÑeh)pòÇ¿qá?“¿ÿNpKæRñsœÛÓǦ}¸vÅŒ@!©k2³™€ç¾³óegçN»/éCÝú0-YîKš²ËG,f¬ìµT䇻… ,:lãõõ1XÞÏ,Æ fðÞ¬oxX]}ÿâçð—¤󻽞š¾.áA¸=ZsN`Tï|{fcGE«¦ º¿öÚŸ~úŸ/êÙrœH")Þp²'Œz/žòåJ l—¨m[0 þEÃC„…Hª¡é!·1IŒ+sëØyKÔ? ±óõ§)ÁÓ¨0¦„9æ>cíÜ­4rNq›SrúmÏé0p«ªzçßLì»•ÆÆ‡LKÞä AÝÄ3»c¯*N˜Ì8¢«l[š56mfô-Eäì®"æ“ܦí*PŸ Èþòv•¦bÆY)m§˜«*±€ðyX*v%P±ˆ81Z®,в böXt¹j”íÄ¿Dc«ZGŒï+›g ¬U±Xl½…éX¸cUUwçŠn‚Ù:"u?©£bäG ìëÝð»U¤¹ôˆí†Ç$DæhL²’Ίÿ>b¬©Ù(9ç4áÿùÞ–œ"˜)ù]þÕ£GÿüÀðÿþä¿bû«ä¸ªbØ}¥SíIªsw8ÇÌE7]Îqª¶.£²´ŠpxY¬èD‡ÙïŸ+#^ß,®½·ïoUlÍÁr¶¥›ýU¼YˆË<îi‰mmŽQİäxÂÁ2~"à_Åc!Ý1ªX ³Cm)ô•Yå EBŒ¸†‡~šºF|ÍÓ”cÑ!*Ä»ƒŽ‡E‡Ö…`à} M½ež©äIÄԸ̢ˆzàÂGÓ<©þ:¥Ö£k8I°±O4¨K,#øŠ¼t…ƾHx• úÑ­¹iVz ]•ü—N•yç\¥S8ì€hÏ|YF~g+#ÎÃsF”cÝ!ü–Ô(ÒRhf* è¶ 7hx©Ú©h§²=Â…kmyJóhm)2¶ž¡--M”i!†aËã”Yvãf+ÛÐ4Ö=":²#©ØÔø(]·''“QœcýÁÿúü«¯íÛ?Dü¯6ኬD^Üwèû„Ô‹îZ¾ì¬éÔÜ¡öáÿün½}Ü©¿^ ªGy]ºÂ>“w¶¬þAÃ!:=\þfá•þÏ~sÀöçM¥c6ÛЙìK^Ï4úIIHZ,43[lòzgÎd_F§j6õ57m¢ Ê>ýQ}b³¸ið¸ëƒS¾‹Îä„&Øq&xùˆí;9ÁŽW-ÿé„çB–ï"þž*»p¬ô½ÿ»êÜÏÆË~¦ÎóÏÎ×ý“s5?ßXþšÿ8^‰!þ‡­¡Ÿ­+û…¶0–Ÿ«÷ýòÙ*t•vÛȉã`h³ZÌE}}´9n÷¤Ý:têø…2ÏLš1» ¤ŠQûĉ NǘÇCØ•™0}›ÌæáºÃ7nÓ`èy­åÛö¿žŒ›«²"—ÎÄ:¾^þþÉЇšêŽìªµ±ŸþÓx6Ü©‹]óħ­¶¡òŠ…¦–G¡Èržîj8²ì,¸Ü36ÇH<¹¥Œ× ágŸÃf"±_>HºèŸøfî÷>ìNb^a w¹'q9¡ðŠÅÜÿ÷ÏWüµ‚)]äZ¾®ËHÂõn‘+0šÐ k¸QDÓ܃¸'¦ñ¹=3¸ízñ{õún‹eÀa¯¢€ë)þ%Ž.ÉèÍ«ˆ¦»é|iФ×_{å«òùäÿ÷á‰E&ªPÀÉû½s^lÖÊö•ygµg:iìÖ—s˜™@‹uÍÃçÍÕvb# jäF: (˜ã á^YÌØèóÏ•“!Â¬ÑØããÚ ÜO°ß@b5;Æ6°Ó9ávÏPiιË_¾ ËëbÒò2U ¿ÞÒú¤ÀÐÃâZ+Ê4P˜D SÕåbŠAØ#¾US}—5WS‰J)™Tÿ(Il¥y;ÏRš0’‡Ihô^uÍ]„Òx¾ ²ÞŒólZÊ,±­”ØÇ“#¤Ö6ûíêêOã)ÌŸ²O¥c†ïÔ×Þ¯a”’ øÓ¶ÞSf”„·ÏÜ~ZÛpm&ñüɘöy*Ì"áö‹à§ú2‡ÕÒúD™«ª®¹×* m­RÎOÒ$ë”Ø+–Þ¶èƒKAïÉý¬!—-E­Qe¿µ›-ÿßÍdœð¾îÊ‘ƒ)iQçÿ¥‘9ˆ½¢ôô¼¬ÖáôE=K;ÀÒºØ'ؼ=íBn×þ[RJÜ·7Eòi߉V­¥Ë¢Sqv–Žô\û_D(áÏç°G{2ùÑÊÕDb+&§k%BÁåTÏv6ULÍP3S¼l·Ö_ý‰(3“azõz™oÎëÅK1çt‹> GÛÆc≶©PøB¸LÄû^L¼VÅV¼†ãx+©rÁ;SB; Þ²ΓãMœÁk‚ _$°*ËÑ|‚7·´tc™•Š–ø¥¾¡ÕvâÜ*·ñ¯0-Æ^¥ZÜZ2Tê$µ"ª‹§)S >ï\‘±ÏKS!ä3N7$¹3Á>èyD ®T v,RD ë.ÏÅë™óûÈóŽêâËoáÄÐ_¡')&š·Øvð–Ý6ÞÆ¡Îc: ¬ãlñQyùBeäŽhVÑ Â§}ÜnSáÿ=â~©i>Öÿü¯Ó]yõÕoý°ðÿ¹ççÔ6hkß{‚à³ „ÕKQ¿YÙÿùÖê×ÿ/è5F‡Ëßüÿzæm5çw¢­íi,ºV‰‘½î~ç)•Ê™vô¢}HDRv«è– üþ9ÑëfiÐ5I½Æ('¹­Zg½¾{"J#‚êµÕbDÚ¡Ý&Ù©HþsÑ´¯©¹‹N•2„‘ îígwŠ‹ëê?­®"bR(´$uŽR§‰Ý€j—ŒÚhn”裹¹Wе¯O€}pl6*@·ŒßÒå]ýRìßÿ«æVîûÊýód C\Jýn•ýþ‹ú¦ãÇ/üãÖÊï‹®ßè}Aç'cäšÜë§©+øÿï¾íU–Ÿ9ï¡•ó´"onÙdãÁàrÝ{ˆ8~þ|ý_çkÿõ[Ieù—ÉÖ_M´üËd˯ÿÆ7’¿ñÄo¼•üÉwLس¨¡_PSŒÒÑDjhÜôúæZXRatSZ»“R~”D.J0²b€GHŒê–J¥\P“Šÿ_Ðýêkß:hþÿKƸöçòkñýììËžÐõs–Êoi5ˆ* ¤=hz'_6‹xC°&ûc–ì[(+›Å¯PÑŠ{\“݉Ýôú.¿o¶´tÊU:‘›û‰ÓA¥‹NÑöÈÎÜOå১ûø]´±ââi„À­ŠŠÛFª¦Áδ¿…öý<]—›Iìö(2-è!"½wÎåœÄ°Ž¸Ûï£Üx±yðÏMQùv pÇAœ[S}/R¹Šs(6÷c[ÉN@1^XîZmíÝ|=±k¤ yãõ¥#Ä;EEýÁŠE„$¥ôÅQD+^÷ŒÓ1YXØ€„.±“öÈ$0U~~·ÃF®R%Ö“éf¾¾»@ßm5!´‘)Üóü¼ë55÷ÎI\‘´%á„”•‘Ï/©}z)‡ EUØ•kf+œ@edUJ}e²Éå˜pÚÆ¶1|Ëëš¶Z†±'¶› ûqgpÛqÖâ\¯«tÊnÇ“š’¹) Å}ÂYÂÉ”:'NŸúˆqžÑMÞç†^ßc6ö×µïŸÙMÓo¨a·¶l¶ÇŸ$Oðè}ï ùÿŠ>°ZùSÒÈèÙHæÑØc0\GŸ†`3?ÿî Þh|àöØÑ?Ç#ÃÓ9~ì»ÀÆfÓÍ£_{¨˜‹‰úõúëØ ½° '_×7GƽÊÑtæåu!ÔÕé®z\“g²/£‡”¯‰`o‡juóóºÐ,EýùÝÔœ¸äÄR4PÍá:ðë0°®Â_ ˆ­±™é6TÇÖÑ}aI$3 I\`C#TÌË;Ĺ“I&¶Ñá y2ß+º”<]rCUz¾u+=ņðŽÜ[ š d9»D"Ý9³À]+«%xÄϵ¦q™‘þ9‘v\“hNܘ©H # •ðü(y²}A}ž¶³Šê,v¨DÎÔ‡± ¤hË;Wldù/*Ä.æ w²ÐHšÏ¤fê³Z³O„[Jü@ÜCË ©°úùøö±£ï™‹ú|àl{Ðoõ£cÉÓtàõO°¼˜© ×b|í•o9ãÉÄöK=YRühéü?ÎáµWÿô‡…ÿm£öïMþÁR­’ë÷?c¯}Þ^xŸèP]ÿ¯äç—Ãå`ñÿ[»XTõ¿{„S” jcã&FíÆ†ÍÚÒÿin~Lsèq’Mó¸gšËÄ}}ýÃHxµ±áQ†ƒËÍM™"þ”SyO…pÎ=)»F‰W߇ï´ðÜeʽåiB2-O€dÐ]×Ô~Zî_Á7â½ø¤¿n×$ k¸’ügNù[”øB—«¿0‹ƒôRæ¡DÌxŠ`•?3Ž¢ä1” iÐ7Ï}WhÿŸµàÓßyë›M›¿r¾ñ{ì)=·íŠ’çßç#/I¹„ª@©À>‚ÿí¥£@Y®Þ%~¸s\¯»f³ŽÊñ½Þi Áýu‡m´±þ¡Ç3¥9}ù§ãT˜  v¸¹[_pÝé¢jP]îU·k‹…UéLÆÞŸ;ïÇž_³~ÛÊ“8…95Rl&õ?*¾öÎhNL®©`Åípˆˆñ=GʺÚò`ŸöŽ\õ€ù?/2Û•(@òŸ).1SÛ¹†QjXÕç¡8»)—–ƒ­$Éì$“3s~ÔB1Št!¾XKnb÷Šp-éuÈËÒÊú?@û +‚$q‰·[bUÄl+Ú‡T;î±¼ÿS±ÐÅ‘+·-æ´êR×dΙH*U &sqz¾ÝlâPb6öfŸ¾d2ÞÁ§(òr¯â ……7„ /9I| 5!“¢›ˆ_ÊËçÑ9òa»ŸæÅHC†Ü«):˜] ² "äGb*êäp9ïL‹À–vûˆx‚½ª™Ä‚fqsÐѺHá§ù1uìÈ{8r©k"—)Ð.ׄÌÁ‰ P 0*zÜ%;ýè˜0üÑJ-ׇ½Þ)«•ÊŸqVÝØ"Ú§ÅѸ-lÇÜ'ü.„KÀ±ØÂ22Oð¦[ˆò1CE"+ˆûŠi2kÔV2L'ZB¥àíö´i¿,ØÒÚòHð?°ÜÑ£ªÿ¹›ÑÿOªËveb׎&v h~ *ƒ+¸“ÿ-…3¨XÄ‚"°4åÛ]SÑÈjEmævÊèªæS€FÜŠf¶ðCìOÄžÀ­òrrÎ"~ U^OÊ›’›{Eü ÙukÊëAÿ°à*Ç âb974áa´‘Rë—[¨¬†ˆ:%#ÄL†ÞM³V󉱠çÿoïÛƒÛʯóþë4ÓéLm3ý#Ó4Mí¸IÇÉ$m§SwœÔãŽk[»^-)‰E‘‚Ä@Aà øÂƒ«•´iMë&Yg½^­VÕŠ¢HI¤øâS$%Š”DQ¢Ä—l'ÓïœsqqIÉûp–ÚxF3w8àŽ?Üû{~çüÎù>½®;ïÀ)´x^ÞYÊy/…M 3û7`ÅÃ1.Ãdÿ0ú`îÁ.ƽÔWKÈ·›ÎáÆ0Gm4Öß}”ˆo §át< (œÇ8"°…dg@ï5躛"Ëù€ßÆ’KèíVÛ `¹FÏåI¤i3CSlYÆeÞ™u›Lï‹iwjXdaSÝÎɧ“,ÌX¤šb+’{%1?b¿Èš+ÌÕÄnG³ ýD\ _Üà½6Ú´¢!Å#4bù&¿ò,AFM P&þ§ó³òÿ×Þ¬Uáqþ‡ŸÖázšŠ¿j6ø‘ÅÂHU¯O¬%v©(Å@°:†x´-.xý‡¯¿ñ÷oào˃ÿteþù­ P=_ó©¾8>sü¯ÕÿÝÁÿƒ¿@à……„Ÿ €\£ú§cØí¾xSTÔ…±Î²òì}}q·ÅÜo_Ã,}0çt™árqQWnÎ)»m0ïà¬ÚSßþì“–Ò>™-1QÃc.È?_fì%BûêyÀ•Bü[rÙb"·f¶‚¼s}wiÉ%sYŸ¹Œò (â«üÜÓ´-Í+X×ÌÆ^üœŠ?I ¹N€Ö:ÔÌy X‰ŠõÝ8ðìõÞ ‰’¯‡D3G¿ÙúWéÕþÇÂôùx>gGN§\€\¬& ¸Å+`aú­#|û ÿw±”zzíÕ×lÁ!WO}jÉY3lô\1ùûlUƒzWÞÙíöËêÙáVñÿ·Býrøo¿Uû×YÑwö6~?«é¯ûþò;õo þw¹G°àâ®Pèf(|S¶›åˆ_ý·¦?Áe¯4|ÿ¥ð›/‡¿‡Ïÿ3øÿP•Vó×ßixë¥ð÷~é˜ Wî«8Iô¡µ7±î³à×(šŒYkfÄ‹²æóL„ënz™L½,±M€2æ!'· 4oÛ@Cû¹âÿL.6G×ôÛ9q] Tá,4¯ë»°ò S¡ˆÄ1ŒFDCÀø¢žf¶Xûç\G÷¶ZÐy¼žq SÙU@ p@_ £*¹äöŒíÝK¦@†@Å~?Ñ$ºØÝ]b¸ (ÒtïàAr¥*g€mp;n!B-ç(+b_€)Ö]t’dÕ¤à¬éuõ‹¨á榛ÄZKëÃg ´“U»TÀ€IÑiKh½©ù>ì/5¤X½®„uˆµ²‘TÌÏu‰=–¿òs¤”Z¿$Ñ#$"[I¤™ØQx}Ã"} sf£ /ˆgc“œ­èKííëZ”\™î$jÐx“`ºÀW)…´à|Û£fÎnà€;œ®þÐ×KPP[+‡ýðßX3)PÃ4ˆ·³ pœ Èëžõ‚Šø¸jõsµˆ™ÝÎ÷3†y’S’ëét†5¡¯Ñê%uhøÒüŸ|œJ=Öë»öfï^þï¶ø­þ¯jàEp NÅÛZQKd^±*ÜZ\¶íäÕ¸9Dg+ºÍšÑ[ø7Âò»â0O³m‘êwí‚Ðufö XY ×w‚% 5Àò”"E­d—¤:½E)åý~Ûj”òˆ7w,.e¦¾PhåHDVr¶XMpŽ´Ú#wê¤Aäj¶1r7^¨ðcŒ£o uð³.lU˜!xZÚhóOªf*ý“ẽ¡»Ò?ãóOa³˜Ý¼Ó1âv£ey!£ ¯oŠ7•®“[9Í5#ø‡}ÝØKÄûDX‡ù¼6„“×é°F,I°D0'ÀTdž!IÏ_I|_toã=ÔËPfìM,1ÔáëlÅ“éÍ)Ò˜`ÞR8¢š,‘òQ®›‚ #øë­˜€ÍUS}Ó_1ÕÞöë#ž&®’Ëæ×Å Ö…IjÐiÆçJ?ÅÁÄæÇ/âÕ¸Ìfp½žL}¸ÿ_ƒÿuÀÿŸAüóJ³š]‹£ñnä㘠Á¡#åêõ˜>w©¨sýÑQ­÷Mþd)áÇ‹ã¹àÿ'¯ý¯©²Ê¤6%Wêë1!·¶>ÄòZ¼Õ¢T˜ÊBµ·ªƒó˜“eБԩ›µ5·B]57…¸:8¬š‹Fï K9J‹4ÐJ„9\XqA-í Qü¿#1,D÷J,wšˆÓÊEÄ×`JØO¬yE6_ÒÉž•|ϸ‚4p¾#£RºMeFô¿ö¼ôægÿS[{ í=³‚iϽÑÓ°n²€Ô€Óq-"-*,ýè'&SŸÔ£¡ð-ô "‚"÷cB~ éâqrÈ»F}ã¢Ú‰«-¶ N‹F§°dß$z):|[û*‹xŽ‘Ž0ß‚óèlVë ükµ X`'5˜Á`¸hŠ5PÄír.8Ü‹‘'’"K{ÎÒc*íÅ‹äæž.wŽÂl^+{¹)Ùy &^ßc¥`ŒMR76]ÕëºJ =x¯œœS²ÁDùÞɃÏà^ÔŒîp'Fœ¾¨‹²¤9ᨰWÚ-eÆËú⋨Û-냙sˆ„zûE™HL²\ZV ó8ÇŠ H]†<ÅÛwcz<ãVÓU”C&¿eÃ_§»@:­¾©ÒÒË¥¸Ò:d·“ *à­¨ð¢¸jÇI—ª¬£Fz#Ã~e;OMÉL¨ª|‰,[ÚDZÙÍQMZ­^’6€M=ÚÛüþ/¾øjÖ‰çÀÿ/$Îs ?ÛZó•W¾/zOù‡ÎQüOA'‘ñæ-+ë…EyøðDCòp(Xš$tõÝÏêoõÔúV+¾.,ìB êŠ.èt]˜ -–«û³ÞDÄõ˜q ~‚n1ôÀˆVÞ _½¡³qfzl–~X¸VvVÅB¯†%’+ìÚÁ2‡>.ù¿çz¥*DÊÑ+ø¥…x㳆mKëjSô>‘¼¥Öëî` ŠDï²™¹†3€÷,ç½BÁ¨ÑeÌTD¹ íXSs ßR^I+lÆ•mÉ=lä[ðA݆æX µVNPϹ‰¾¶˜KÒÒÿÝ®Q ‡ÊÊ™9'iƒGׅ΀Št[(¹[¼ "I ;Sw0Àq{Aáy\) ÿO¢FÝö¡ºìŽkh|8|蜯b3Æ7¿ñÝxâ1Æéþý'm¦«ÊÄ-æ#íl¿oòpÁySi/†î >°ï$~+ïàY‡}¨´ôJVÖ;‰mñ?Û§GQKI­ ÿg±®sÏžçÿa²úà° Œ}Sþ¹ø³ÿÿ#7þþ Ë€U-Ä>ì|V_Ÿ¥þÇÿìÈùÕúÿYDþ>k‹AÍ%™]„9R¶­¡´ Ùúˆt‚j$¢R£„»%Ó,¦SNî[B`ËVb¹ÍÞ ŠÞaI¯ òbµ¬&”LÆ Qïââì¶u•Ÿ”9XTVy˜¤GÆ~Å×4»Ì˜·).”ò×Òä Í‚BQÂÁó„mR›0LT‡a«8QâUý’`ÚxM*œ'øðÅ£±D×ùíÄôøsoèñùŸ¿QúÌ㟼Q„o_>òVšƒ¸bó÷Å¿|¬õs-µ¿™hü⑦/‰áø#Í_z½ù‹¯5ýv*ú»G[Ãu·± ²ÿÿV¸Žd×êê¿~ô/¿¯ÿ­T×ÿ‡Dã¯7×àÊ/$~»#Šq/ÎÿV*Š3ùB{½+:†¥3"ú»††»Fã•€o:Òx¯.¼ØÒLi¸×POtëB,Üol¸‡K-­¶¡VË`}ýhýdá)Š 5'w‹üÿ{vÿÿšªd­íÌêJ‡ÞÅ$ ‘v©h€ÀH¡TeE¹7ÅVĥ驸˜ôU]3ëLÆ£KàL¸þv²cÃY>\K2£.÷X…w¢†å–К¸²ÂC©ÜLf8ÁEsÀ!`¸^è_`§¸ÊG\®‘r×0FJ’dq%%K²1¾éóOy}Sÿ?e Ã×srº7$\å…ªn˜ÌýVm ; —¼”1}ÉntSJÅÀ'º)J8)YR©L¼ˆbM澚ÚyCI®Ç›Èv¸^]3ïöŒ+ K E’ ­å½©žQÌUÍ$ Š‚Éù*žKçÿJޤ¢ÜÁ©¬)ÿ'éõ]ÙÙÏÿoçÿ¶á±1Q3ä‘ÜÀ¿ÕÁ9òÌTÏ‘3„EEíÃVºpu$BÊt¬™8Ç q7Haç2S¥¾«gÑÐ0rƒYrÂÔ‘©[IN›Û¸½.|[4É_¿„éÏ€©­æ¦Ø-Ò §Ôxï$ÚÔIÛšO´ü?ø‰@³¶A{Oü7(è,üHjýŸ‰øÿsàFu§#ï\>,‚xõÅñÿsþ—£¹ùAqq—NwA„È™‘ûæÉRæÙ&ÚŸ’Ë{÷þó$Vꜜ÷pA^Þûee}XMœˆ¤×_t2i5Ý/<üÍ6@ŒãK_AÁ¢2O©UÞ «µ¿¨è¼^×¥7\$¶™¢®ÂÂóÂÏÀBóž6ºI‘ªôʾì@éY¯¾m!·IŸÙÒgwR0ÖúÌÙ±ÕÜòÐP@5»¾Ž…¨L©‘¶Á6"\ã Q}a—8Ä;‰÷Âo“ÇrÔRÖ/0ŒBžš”è/IXæ—›Z>eþ¥#¶yÔ¿¿Ðaù¯Ûåÿ:æüåã.|ÞSñ½ŠŠ Áÿ&÷U?ÇåêuÝxÚáõN›ÊzÿKâ(¾ý£†?-wŽz]ãVÛ š#`,íµåæhqñE«u€Bq¼“¥¼NáXO­Ób¹Š Á‹`Áe9° Ÿo¼ àÎ#¡ÕˆÏÓ˜wÆ‚Û5Ð…Aåc$ )× Äõ¸±œ’"G‰ßÜŸ›{†2 Ë®uÚlýBÁAU¤»èrŽK.ã´NSdKpþ¡³V¢ ¤LÐü–Æ}ªÄÿìyéovÿwtlìP¯Ss'%¥· ÿœNwÑã§Pp}—ÑØ«×÷äì{ ¥ÔØ Xë°_c°MèP¤Üît7JN_°j¶ƒó“iL-à—ß¡òœH/ÙV¡* –BŸ?¯‹Ä­²Ä+öÅ<ÃÚµºº^ÓS²vœpu;…Ð,ÊPc„(}š¢ËÕÁY‰’¸db=Íjž‰ÿ‘£=þ˜¯”h%â=‘J/JD¢$!ÕÎÀéä¦@}yÍ„ÆëÎ;JùØÆÿÓÚþ¨¥ôEr‚{âëm ÉϪlHµqjyZql-žVcîšGJ¨Šê“Ê#)ÏÀø?žFøbø+–W\ãHl¨ÎŠô»(ø_5úˆ4õµÍôßÍvâÿ$ü_Lñ?»ˆÿ3qŒüŸéá8¨_é› úg`¼G#÷ÜžëÀ–±Ø}¡Á€íH‘°oñDQ̹ß?où…Ž’hTÓY½j®%nª^”4gìλ×ލHr‹Y†TÑ´­uëDùœáÿÇ]Xb1ÚO¬oXÄ#ÁŽ#ulöäkf)-±¦ìðÖ-Jƒ2uÏbmèïMËèrx#"ç.[L}ui{-‹·g½LÞEJp, ̵± ßVÏÕÔÞB±X­P¦—òfäÔ*3]ˆ¢$¢/îæU¼«„bævÌœXË0KUâ¢ML×®ršQIù®r¦¤„8‚ðj%ÆÙ°$ˆǃÙŒŠžŸ“s 룱ôòáüs õwÔÎ)¦Š¶Ç*‘æ«t@æzz/lCÛ“³vD‘ñ­à½îžo??ü®QØ¥ËøÃ¯9>RÒž²>Ó§Åÿó!E}¢ÃÔoQËiýäqD/ŽǧËÿù4þ/Š ßÄŒ*²_4sbúÞ£›šùÊÊibZ«ºQ¾…yÌÃ,:Áà;æDÃþª*Ï&5¼îZ9Z< åèº(ªÙ7±?ûu<ذæ>À tÝ‚óEeÆË”kSÅ2Sí¾m“.ý´iÚÿmJ ©4`Çέ“-­VÚQ¹™Ü¾ ¢†Ùdœ“)5þƒÃ-h§¯µ•"+$\ÇŨká ¾E—€¡8ØCtB ®V"%LX ¸)€@ôR|U/™Å‰5& Z•ÔH”ƒ~‹‰ÐÖn5Ý×Ü 8"‘S#H£dE _A…‡ˆñœáºEÎP¾'y@ÞŠÉzÞò{ŠûeSÿÿ #ù8™xþ•óG è‘#ð öøÁÜ÷`±¢6`½]@?á.щ×ÉÚûN¼}¨«(¡µ×á¸\§ë”…äé/wŽ ÛÃ~Úùó´)­=óô•ªŠÜŽÝdå³–\‚ýÿxl™ÙX z’âˆ*§i†nb’Á SbèÁ£R|]ùˆ,,¨="£AbœÛ¬ðŽÛíÄp‹-£·TçÝîQt¶’’Lbhʲ2˜ùݸó³Èd×TS@-Q É ,Xáúá*:Ozw•蜂•z«–ÒgÒù O–¥ëÆ´o2õI,*Åz<×ñ¹ àœpŸæ<ƒ_ÇIÔ¹søÕ½o{*ˆÅËTÖçt ±÷f².¼ôÌÙCÛ-ÒÄ¢*ôí`–ÞÞ”ÿsDëÿ¿°ç¥ï=üäÉ]·^E–AÛÇq†kIûmCö&íOÛÎÿÿ,ê¾)ÿÇÉtxq¼8ž þßx üÿHñ a™ðôIp…÷Ís§$ë©äº’8Æ‹ù “ ëx$Š} דߒ“ì$lF¢÷Ê5Ú0¥$ĺТdŠÃ-™ØÀR.©m!p_Nr¤¢øåÉwð_Òù»B‡\ùÚ–~QþJolªßj=Ÿ ~N"m üV‰)‘d*óË)nØ”ê ÜH‡ylvl#í§˜%5“.‘Q®ÜâIX‰ÿùðcOêMqà.ç( *ßå Õ.0“ÌF r+&,gQÁi±1³" ûE¤kÌKÙÍÃXqW©¡7¢ýzJ”sû*¦ª³hS]áE˜6樔uŒµÚ[Xݤõ³E …xÜ㬠4Jm¾É Ï$¥u4Þ¹„E­æóQË9‘<ÜS¶d†ÿøÿ¥]ÇÿÏ'דJ›*NxaRcÔéÀD:,G¶ÝUÅE««j†¨cSÝHrPh‘4›òŠî³D±_NñÑa€Ä×UÿgË>&E*v\K±Í±@wU•7ˆn7¼C¦ªjÖ_9MV6³‚ûüS•iØzÀB²þz8~c‡e¡žPCÜ“ªu =´öß•îÌ™t8Ó6·y"™©Iy#ôÉo~󯀦rrˆÎåС³ÄçY1^VzE§»˜—w–² L}0Ÿ1Q8ç÷¾ò_ü>š5?ÿæ+`*q©âJ7A‰5†Ï{÷¾mµõ›MW-æ~§ãZÁás%†nØME…hbôRt?À³¬¬w€ÐrsOët(÷'±Q¬ï.,ìdаµ¢¢Îì¬B¬Úq4Õ0LR$_cýßÔ£$Çÿdí®þ­ó†¡GTÌáÛ€1V3–¦/¹ÜT9kl›ßádêÀ \³¨šscå<úà+g‹lî #΀̴²Cå\å4VÿMng›ÜÑßÔW0{rrNZ-Wݞ똅²³~€ÖÌÏ;‹.Qpø¯wÖ ç,\33k.å×w—/ØÒç~†Ei$j ŠŠÉÃè$b¦ÂLˆæCïÛ÷Ž·âz±î×£óD"KÙÙ?(§¡ë¬fØŸývSì>À6“ñÎÚí×ò•ÝjXR¸1º‰‡äô™-¶¬&©Ô¶ðugPq²vìTÙnìG›–•(ÄT:þPcG§ˆ£Lɦ×î-&µÓKrÛ¡FäªßjòY¶¶Ûq¢È–ñÿ£º>¾hoÉeãîõÉàÙlP}ñðBø^}q|†ñÿéøŸÌüÆžÿÑßמ¥`U=8÷DZo¿ûÕò?9Üqþ«®ÿõÍš¿úŠóø×|Ž“Ù±ìù³®“€*Vs¿AOTXˆ‹ Î|šÌW1ë:%=)9qDWÔe· žO&×órÏÙÓ’xºñ2e¥Yýþ)g¬Laûé6›‰µKóQwºÝ£˜¥õ:ÒÀ¥„)û®èB™á}›}ÈbP]gÿó „h±IåÊY>ì´SÊ›ý>˜J{-¦~£á²D5ã €Ã&¦³&±˜ÊŸgÂlêç­Þ>§mÈdì¥ÌPË€‘äÏú|žñ¢‚N»mˆÒÜÌý@츘¸’‚³¥ºÜg*ëýBSýçZCÿ¦¡ò ñú_kªú|kèómá_þ]¬ús-¡_o®ùíT4+ôŽß7e0\â$ei(.ºh4^ÁIÔ xupž2UQ9¾]aQii/>‹e0/ï}b¡Ð‚^GQ=zCQRà¥JzŠI4ó2À<Ö‡íÚÞï¼ ¡Â=ŽJ²²YðØePd³ 9œ#@båÎÑe›’Î/“]\Têû‚‚N}q/¯'Z[W±hR,…bJ½xMüÏÓþÿ®=/?'ü¿Ãý;ÈZÖ/¢Z°}~„U¾¦šB€¨ÛÚý7¼ÞIV¦XZ$€%ÒßIn gRz`h!ÈlŠ~²ËnÕV߬ ÎÁªr²Õã¹ÎjÑR5Áy Z&{mÆf¤Þ‚mÅüó#Ä2D–Ô]txŸÚOžÏiÔ§Ã9l¶ôûü“¡ð‚JNN¾q5|Wy!mOHè‹h@(òÁ”Cç);[!¹Mnª^zU{:©óM*Ñø¤¶ð-ïcÎ2“ó}t“H!Š¥‰SËóñê¯ó‡2S1ÃÏ#鄸QØB&ÐÈþ A—¨¶”Vÿ7H/œT¸ Út?[Ž£Ó&³³hŸ¤rK1B¾‰6Š{Xß°„—j#Lì†_§,-j8Ú»l~Àõp—9¦V%“—cŸVx»s™½=XPl ¯[»®þvcä%£Õ-Ê4ŒA\ßÚ¶ZWw›2ƒójµ£ÞP pjK»=$®€ÚÐÂ6[»c3#ÿ” .ªÁœð ©žø2ˆšc+ý³ö®`â {òÕ4,í°»ÕÀB¶éh >ΜÃ-¬Ô¼#,SÿOÓfšÿG¯ë|é¥]ÿ9ú££Zª|,¶Ç~|ì㎌ápæà‡ßØò åÃ3 >Å¢^øÿ_?{ø»þ¯ àÿÅ3ÅôL¦>ÒƒýßSÞ««[¤ '°Í<þÅT 3m°zVBJ([“Îð¯Ï7ÁJˆ#˜Ö°HᇰÖà–­P÷jjæd2 0‰¾bí®ºÁ|¤7ð­„ áß@åt$JÑ/™¼¹Ž-’O­!Q˜µ˜zƒvë É9 a€|7S4x½êƒiŸBƒªfëËø—\âÁ9W9%ÉVUÍü7Ü壒XGù•u ÄüiÂ.Ç0ÎÓcxoP¨R-mXû}ø­ºÚ…ƒ¹§ð`®q€C¼Ž·€ðfCý<úg¾iØZZ¡ˆgjÇ"„$TÏ’á(‘NÄ8Üê¬n¨¢tû–9V<ÁEµ+4)ëRB\S­x&”`õD|]ø< @f–$:„o0½ôè§J”ÎòÞ·Åÿ<ÿÿk¯=y: ˜yËzmÖ"¶1a …B·ÉaTæäœ²˜¯Z,WQ“^÷8%¹Ø†--e::ô>^ Æ *Üb!v&Š'’ü’’K^ï„›¼—ï8`xZúX¬g &X^îi«ehÄf´˜úòòˆŽƒòËGÐ4E…¹¹gl¶tB`H }[ZJÆo±î‚ÞÐe2÷y}ãI…Tü†…·Åî ¡4ôØ@=$F DÃK ×_#ãg»xûÑå$jÂç,·“·ÿÒ&WÇ–Œ8¢:éØª¯[´˜ˆÎ”ø#Ë}Ãj`âw c£x?b3Ä’êŸÄWÌk4+¸ÌxE8ÌË $Fàr` ¨NK"£QsØLÇ;m¥…q9æ›´ôfãÿð¿¾+{ýÿ™€|­ÿ_“زU˜1DW$aט«|ô º´¥â]c¨LÚ,Ý¿ÿ$Ú gögð¸ÇJ —p—ï¢Ú‹9xVxžÑ{‹‹/ —(µÜ5–ŸÎjéßûÊÛ¢„{`ßI4ýþ}'aÕ&IývêÕ½ocpU³>ˆå«Le}è$°¯ÑQ¬Ÿxðà™arN"ν"ûª4û¦X€{ÔåÁ»A+,b<¤Ùrµ²rÚd"Öh ætb‰!‰äF5GåUTLâùyJŸw:GÑuM¦«vûp5[÷L\@S1&v#‰p H˶~Ýçk8|TìP³™BzPùÒ%]5YGò†rüe¦^ý$àGÅ„W½½i¹éC®Ät¥^Ù°Ô°«E½ˆÿqüLêÿnËÿU6mµùA©Í¯=„ÿ+Ç}¿w¬MŽ/i–_>Úú¯¹ñíWÛÿ´CåCPT–6ÄÃÆN6"m#O…šK¨ÃZsóƒhd 'Bœl+áڜʷëDË–PP% S#~¥…bÔWˆÿ'©nÂR’#q\„n)ZóüüI…_EhÖ«‚7ˆ£q©­m•}§a¤46Þ·¯Uú‰û‚1-ŸÁ-â)É'mTCRÉÊdgi†‡!ùÌÁNšèqNNïÏ&ÙÃ#/BÔ ™‰¬b¦º|×°€b‘­ôMc1ÅBl³bEÃ߆ú%_ÁN¬2" ˜Jyj&©âJÚl¯k7âéDHÑh‹@ÉžðÌ+lcøWœúFò~Ù¸ROy)µø¿û¥—¿·ÛñÿOñÿЖ÷º/¡æ°¡¢Ü—š›[ÆYu ½‹íÇèZÍ1 ;úÜÞöˆCÖ•h4Ü`ª½…¦j‘T‚´ç$z$•Z’ù4ùƺDH/•ôóDZÖ'α^’Af”ðÏÄ…ˆõº%IÔqoúECg½ú6z ´N©‘T·Š aË\*1P6¢ÃAŠ`{_ý~Èë›´Yûm–~€„ÃùçHxÔruÿ>ÊÐtê /ø+'+¼ÄYL¡/¥¥€a[ø ³©÷;/ÿ-žVƒ3ÊQ8>jEq×áü³°¾÷î}Ëí­¨ËË;m*ƒ15h0tÿ³”K^xg­©±UÍ-uº ,³u oa³wäŸ%éRS/,£ýûÞÅÍê /´´=ÀsS‰õárïßÂd"e1Jê4]jdþ&%áw=‘ŽìRÍLÚo"“D©á”BøŸÛÕˆY(ñÿ©ä£$ãÿ]ôÿkLé§ã·å…c9]FÇN²t=Q.߬§D¡% e¬®¦m,Ì´œí»#®–àî’p/Ç8Ø’ùˆàÙ*ik6É ?vë@°z.½'Å¢~:þŸã/ø^Ÿ•ÿ_ô¿:(˜_‹ÿµ.\Ì*z}Ï—šHëök 0`µ `–>pà=€R‡då¿#ëàË5-y¹gÂõ·­ÖþÜÜS%LëgÐ_<˜{º%ö ðÐyLé˜Éò–苺ª«H2 ƒxx,ƒ6뀮°S<$:ÝEL_~ÿ f9siŸ8]››WðUVÖ;e¥Wôº.ÌÌx’œìw-I/+íµ[óó?ÈÍ=£’ÿKà% T^ÞÌÒ˜W««ç•IÙÊ~ Ïï&z¢n[RÒ#í€Ó¸ØUN! €7ö4O&´’Ý>üAUSÚÔFJkƒ3“Ûãiw\™ ÀH©±Ó–r q§c¬*H⤨I'çîaÑĪ„ªpsܾÇsÝU>ŠJ¬bd¸¹-Tõ…fâ´×%©!œÒ©"tˬ‰,š¼šFîÊ$«r rA*-EúT–Ù–ÿ£¢ÿï¶ÿ󜬪¡Ð¦õ#DM™žÞIŽ4›¦ ×(kÃÍ›ÍýåÎQ@Ygù(¾É$Nå5™‰Õ ½ +{ÇÜ®q‹µ_½IÌ7AÎI­xRS=ÛËË)…<Bùc,Q[;d"æX)©Ðí?n×uâ/šÒ–. *±CþsÙýQ]ß$Æi³Ì"¨Z%‚¶ki%zóPm­™ínÙu%h¹@eµC¡sYdrtSKÇ&®gu§»LÒK@¹üœÜD[?kb¦íÁu1™I·‹sÌ)ú(©t39â¤V¶J†1!€e”Ä;æ,ñ¯¼ŠJƒ……òkjIxMí­úðbå8,44ÜÝÓñ½Ü‚üåã.ÙÛIò™Ì „ wSÆ`—(Åk!! ŠT‹';z2çÿ2þ/îÊÞ]ü¿õ“˜Ùd¬¡_£_*£ºv✩Î]'ë|Õ1V4Ü­ ÓnÅb+‡Àê¢~âÙ#ý_ ’$v/tÚÝ ­œ»LÑp>sBôêD<$h&Ü“í‹mÊ4è<1Í÷qà$Çç¬ÂÂE#jØ&•me íÊßШi EÕfZxnyî(¤¸dw¯ÊÄÛ@8|Ÿ‡3mªt¾x$AÞÆÕ™Î)KOËyUã¯Øâ±¿™ÎûVš ^òêLþ¾J«%3¡ÂLsc ï>¤‹ŒJ4V&_`Ûó(—ÁÒnTÁ H¦çs¶[×ø]ˆÛ #HK@;nšL|¿”ËÆ›?AùwKâþü_¼‹ñ?Çÿî¸Öõ­ï1¼þÃ×:}5qXºýQûG*8GÊw»¨Ëÿ¯!µ_s¼«/ŽÏ6þ§£ccí[fºHy¾Í:øŸRX^ÿÙñ’_8jÁñ‹Ç¬?ÿºùZåø¹ã”ßúóGÍÿ6UõÇë~­#ˆÔþgD¤¸•(_³Û‡±p*o`ÅÑùººÛÄ]ÏAÔ•þia¢8ß%¥²l¢×;!œoø€I¯¾žb6ÊÊ.ÛìC¤y‡ý$·…›W4âxÈèfrÂ&§Há–JâvX¡% ʼn“DïÐå,`#ßSÝÁÚ§M…Û.¡¸¥‰Ø‘—¹`[ÝSvˆ)h]‘™­Ç ÔÊZ]’&¬Ê¾ É›V–7žv ,WN‰\Q”R…&qóüÆ:Ävå_ 7ZßF\WXÖ•°ŸT&‘ö©øŸL% ^ÞEü/üŸÏÆÿ5°û =”crø<F:N×UVÖ‹¶~ùå7aA8Ió¨ß`è†yˆkd›^6Üñ-S¡ÀÞ¤½øâ‹f¢ß!*Q6c{«‚7ŠõY%¹]‚×壸Œ¯¬ÖÙG+3]ÎÏ?+›,E”É2Æ A“`œs؆p½¸ i0`u×)ï8ÊVÏ{<0f'P&ç6N¶¶>$¢uÏ8:3KÈMÀ*±;‡jkç*X€’S,ýäD&‚)°ë-CÌN¡[&bëASæç¿ç±q^- Mº]£…EðíÄþtÓbéÃy G§}Øjé7ê{þéªÀŒ(³í–KY^…˜ž=Œ¾§•9Pú'lUº C’vC¢Ë’A äWqÀô·So~ ü_.×7ÜáaƒeEp°hKëÀ¼XóŠÀ³d§%yƒ/Ù¡šç„²4¹·[i·¿â/MupþoÚÿŸ½ÿÝÝæÿWÃ2µ”MÒ½ ÎgQìÙµü¼³&DëÍzõÅkE–ÚÛçäœF£›ÊzssÞýNçˆÃq-?ÿ®,-½BéTçÅ ŽÎ¿ÿI4…JgˆëÒs=çÀ{_ÔÏ`ø‰¹\#Dbc.È'ev·s´Ì@i¹òC:Jzõ•· ”|Ô‹Ÿ+·ïàŸ,(èt»Æ,¦«:ÝET)%:éz\ÎQ]iá]ГsœjâDñÉçæž¶˜û=îëvÛ5L†‡óÞÇxI%‰Àæú0lçª*Ê{Â< ;ê`27oÅx*±i2]u»¸{ó¦mø§ÜÌቿY¼;@ÔÅ®!Rºw¡µ-ð:œÒë.¢BJ —)ªÐ6ôêÞˆN¹gï+ß׺JJzLfŠ'Ä€Â:ô~ö¾h‘ì¬wìÖA|( ”öagù°ÑH¹]9Y'Œ†K°›ò¾2†Ë"âVf¼²ßÉXÓ}´Z~Þ9»}õ /îÆ{YM¯¼ü}<°Uƒ±„:„¶èþ§c$ÿйBbºjÔ_–<…gšJRñ?ÅÿìJþïè Ô}äÉ‘Ÿz|4j¨û‹ŸU¼ª)`ŸúÉJ»ŸVQ¦«ææ•æËzøñ±ú¿?ˆØ‹ãÅñéê= ÕèoŠð¿ø4þ+Çÿ|¢ãKÇZRšCñªá. 5¾îĺêÆáßÝæ¥IiD”Ò$<ÛÔUR)­ÊG¡(o”àð §ëÅrkë*G°¯p,ÇjSt™•I`¾âà"ÝGÕÁÙf–Œ¦jn~@î,f/¤D*fã”$¸ÚÚ…$“ –i%Ÿç–‰Hã]ÑÒ嬺»µÄI)i¢zÖÞöH Á#¹á‚ ‘´o´4?f#‘{¸¦¹ùa$¢„k&I¿òfSô~kËj,ºÂšJwp Oò=÷ð¨­ÍÛZÉ_Ç §äV¥Ì‹ÈrCÃ=a_ñû§›"ˉø:Þö¯w’ŸêaUÕ< V¤a9X5—àšñÅ.åÇãUfø¤˜"·{œŸ|µ±þ.þ ‡—ðsœx‹®aÙ¯šêy’úEQhJ]q0‰Ë=¨ºa,¹dƒÉÀ¶e WyŽ(zh&@°ò ¥ªà,n VÝìGÿÁÏ¡3ÀN—­(¼8P¥‡)Ð}dã8†140pH/Ø: ß&Á&¶°ÐCÀ,¦þ²RM´'èrŽÁ w»¯ÿa€Rþsû@P‚gå£yygäðR‡òϹZFñí/¾f-1ÐîqØ†Š‹ºˆhÈx6¬¿†úÅÂÃçÍl¡×‘ ‡eÀjîÏÏ=ë°çç½ ‹  ¨8ÿ»•¦ÜßÒæ³ ÿ'éQþï®âÿ­gÒoªþÿªªY mT2-x*¸ÓF»E«œ«»ÁÄ¿«˜ÙÈUξýhô>z¦2L_èùÅB’ Zí¸7rÄËV¸~1\·9“g˜Þ™²d IrçÃá›°­•3µÌÛÌ~˜iòùs|‘xf(š¥c›<Y¬œ–¿µÉ¼¬ó>ßDÁásåè„.ªSX§0`«ˆÏŠ„Þ`¹ToÀª•‡r×&RŒ“©ÇC<üý$7_CÙý0 Ìæ«0½IÏ:ˆª ‘”ÒËxN“±£O‚*ÑóƒÁ·{íN%TÏ¢@ôv=køz+&‹‹»U·¥°U’ŽæÏ`5e¨Õ†oâ ëê—yK¥z>¦ùS:ºoŸÝ¦íÊ}›xLRïU3••S¸2à›Á`!Ì䆿‚*Õˆ‰×AÕáá1“ÛŠ7œ)ÀÉ2 ø [¾£Ãs×ÐyïD4r¯);›ø!ŒŽ{žraíÄÿGˆpôwÁÿðovªÐ·èb1¬êàÑZŠjÂè_Çÿî8¦ÌÀL ï\¾úmࣴ½>•¢rÎ$»æb±oʹÅ"pôGGñâ¯ÿðõ–‡­þéÊüój98‚sÕ/ê‹ã³ÏÿÝÆÿ³“´-A!— …íþðH’¶Þ(ù½#í¿w¤í÷_ãÃïv´üf[äK©f|øVêoŒ‰+¥©Þ¯wü\ù;GcÄ©ÒöHÔ"kˆ¿XšIœpfïÒí%*ñfË·u,ÂΪ·qf3}ý*¡P†Ù"ƒ 0 ‹Ó9*ʉ8³#JÖh¸\ábqv,"˜9ó >¨ð¢¬cáÈÉ9URr –—Æ›I¨}àС÷±"ìÛw¢¤„r»rs‰Y=7÷4@‚n (œÉÎ~xFRØø7ëDEÅV ‹™¢¯íí‡ø•ú5³Ì‰ÁRVzÕéóxÆKKÉkWXxA„¨€ouEÄzÔØ@\1¸µ ü€×òDë£Ñí0†ŽŠFD¹PMÂj…fÓÕ0ÇB?UY¯¹„¼‚BÀÜÇ,ܨö\¢¯´±ú-p‚Aßróð-é–æö¨¯_@å;œÃeeWlökZ6? çn\jgÂ`¹fÉàäk ˆÜÆ]ÞÖQÈÚqe4zÏãQò|¹&æÆyb1®—¨„Æ%ʽm^ …nñKJ›3$ñ%Vœg746ÞQØJÓaöM±œžÃ6/,E/Œ'ÌÞ° ¬Lƒ¾§°ðR¬£|Æ®¼¼Ó00pÌ\?’+úÊwÞ²˜¯Ò>Bq—¿rÒíCÍü?YåZ’vçÞÐ ¦+¾€A‡ªh)ð÷¿Ða²XªªnTfÀî È.`9\†W8|èQÀq/™®1tl€F4y¶Ý£Ù5žÚÆ%»ÃÐàâÿgWùžNigY–'b{¢ë¢»Z,¨vé·8,²ì0zÜ×õEÈáà›†3G¸€Êy&D‹+~ͺ ‰ÿ2ݰ%f âJÓŽ‰¯`–£×$(¦ /IQ”‹¤ÕAΣŒ8whfFüFH‚> stream xÚíÁ  þ©o7 àÏΖ– endstream endobj 12 0 obj << /Type /XObject /Subtype /Image /Width 353 /Height 224 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 27689 /Filter /FlateDecode >> stream xÚì½tc×™ Ù}öôÙîéÝÞéží9gçÌLO÷™ž™ÝÙí¶{låhÙ²lÉ’-9ÈV²=¶lÉAÎV(E+§’*W1ç A‘ˆHäHÈ/"ŒØÿá‘(¦"«XY¾ý‚.î»ï¾‹Ç{¿÷ÿ7=“v¢¼&¡Ùéj ÎL!EŠô\MUˆØÓ‰¿oßý9r=TÕþjf³îìY³Ó^Vg¦<û¢\†ˆH-Iµ¿J…ÙN÷„¶`>—ÍnÔšuJ8w2´u>—½c¨Z"=<|8<Õþªf;Ý%"زM{NË$–I--.–÷U C,“v˜õÓ¢ÒCŇCRí¯va¶”áã4à“ÆãuZ¡l óóó¥¹b1_,äöS‹yÈva¾ä0OÂ…àrpÑê2 EzÀz¨ªýAf+½—Ê¿®py|n°m²éT±/äsWI!ól:i3èàrpÑê2 EzÀz¨ªýfƒ^„ˆ EªÒ™)Ï´×eÒ)¦TàdÁåà¢Óg‹é–z¨ªýfKDlw£Ø^Ó)ƒáQÈÓWUYÛ.Çvù¢ŠŠôÑCUí¸0ÕºWDäsô(BÒC…ˆO¼Ú|aªKµ="¼¬ÎN{f¦ÜSÇÁÞ+\”í½AŠôàõPUûƒ/Ì6ˆ¸ø.M¯êì”ÇïuM¹ÙâQ Ì½r;à¢pi®H‘¤ªjð…©.Õ:"vq¯r4uŠôP!â¯ö_˜êRm‡ˆêžÓ^—ï`ï\ŽíÝ­* R¤¦‡ªÚ|a¶DÄîîyŠô!â®ö_˜êRm«3Sîi¯Óç¶3Å£È=é?}æ:нžU¹Wv¸(ÛusÔõ¿ÎÞ‡O]wÃMwÜñµo~óÍ·ßrÚLGôç|ï‡?„ßòìóÏ]št¯Õžýo§WXí¯¤ ‚þð©§_óÍË8‘-U".}¯hŠØ“²÷g¯g]“ˆøÙ3¿€_$—ŠøãÃ×»¿|ŸQ¯Eˆ8ˆØ}UßN¯°Ú_I}ò'?}ów.ãD¶TÛ"bjUg|îiÓç:XD¸ìpQ¸4WŒ£«"د~¯ë‹÷}bžúéOÙ›Åøü±c_¼ï¾ÏÜt zù•W\63{Èa1½úÚ«_úÊ×Ý|ëƒß|xPÐÏÆƒA9ôtuBØ S³÷yB.¯·Üñ9ÿáõ׿ýècŸ½ù–{¿úµ¾žnÈÿÆÛïæW¿ý Û!j7›Ž½È\—IöÀW?úè8wè¶»>™¼ò‡×ÿþ÷¯¿õöÏ}ñžsçÏB<äV]óáZùÑÇßsßýPø/|éÞß=û¬^«¾þj{­öKK‹;èVû+iƒñÐ7~ãí·ýÞ÷®»å¶ûzH§Ó^¨©¹ëž/ÝpÛÇ^z…$0.Ù{|É.BÄnîIìIW±Ç³®mD€ æÜx3üÆ)·ƒmw¯¿ù†Ójzîùç!üoZ+½ÿÁ‡X˜X “ª Ù«¯½v"º»¶CÄW¿þ «q’Í ôøñÍ†É›ï¼ Â u 2ÿÊׄ¯'\÷¿úc<÷\5"MÐÞêY/ r€C«VÄZJ±h¾>ðÐ×fP’3gNÓ®5Dì±_žî{Ïy•ð×þÎï»ßf³Ñ}ìåWn¸õö_y-›ÍÎwÞ}OÿÀ—ìæ;?§ÕéöŠŠÄ/©;[\»ÉášGì½ãǹdÇOœÜ0/bc©¦Ü¬ú}.0x½.ÛAÞ+¸\.ÍãèêKàgÏ<ÃżôÊˬ¿ñäé“cž=þ&{£àYÏcsž" ¬_C„B>_o® ¢¾¾ÂMM ’=‹EÄ^ÿ„ÙÌ7«L2GYD°™¸ìöÐÐà|åÁæ >òO~þs¨i\—ì+¯½z üÕUµßkavF¯ŸÏ†u“:¨xI°_½òê›o¯'ëìîfKÅ!bW÷ŠÀ/©K‹‹œ²÷§:f79\Ûˆ€6îÅ}ø |íìlcô.‡¾NjUìMô³cluòü—n‚øŽŽv_"Øë~æ¦[ØI¿tD|ÿÉ'«ÁªÝb„Ø”«ñšBÄ«ýf½Âj¿×ÂlPÐö+a<Öé*ˆXK¶Šˆµd|ô[ª=!‚$°=)[aözÖµŠvDã?þ|ý—ï3LªY³áÞ`Zî›o@Ëb{úÖÃîÀZ_ÄOÌZ)éå—Ø<ï«t#@;…SžþÙÏ.9›É±—^rÚL`ŠÔ7ÔýðÇO]¿üͯ! ¶Û÷. õÛ߈E#§UÐÏ8×ßrÛ–Ø9ºˆØk¾<Ý%".#glÚ~džu:- ‚Kvì•Wª“Ýrç]r…l'DøV•ù ë"Âic'£rÅ8ºÊ"‚5Âo¼ýŽúúëo¼á°¹l¿"@ã37Þ|÷½÷½øòËvóêQ¼òê«÷Üwÿgo¾åkßøæ@? =À€ÌOœ<±ŠÙ8ZG„ÏÝÔ¸†ˆÊY눨|µ™Àn0â—¿þ•\"f­#ÂçvÙÖ!€¯æ«ßøxIóÄ÷ÿ'øÈ õußzä üº‡}T°VÈ#­{­ö;;WXí¯¤ ^6"> =„”8$Õþjf³î l ÙB² EÝå2dóGÕéa£Äá©öW©0Ûéˆ`K²r%ÜGÝùŠH‘~âz¨ªýÕ(Ìf­FªH‘"Ý H‘"½8¹Ÿ9»ŸçòzøH‘DŒ‰FŠj®HòER•Ï1šËÑyšÊç!Lçót±HÏUP&+äó Eä@Ùø\¾+s«W.JÅB±P`RÒ4h”ªä¼3"(:÷‘ÿÒG‰Ï¾EŠôÚÖ/œøXL@?üˆ¥)š$ihÅœ²íºÌ× >¬)ÃÅoHÀ~åNÝpÇž¨O#D ýcP¨ç×¥OŒ‡c£,"à“&)’ )V«)Ÿdnµ3&D‘%rœÁ†™ÀFVìÀU¸o¶È| ’k],áy¨íPç9"X¥I@ºÚ× â}¬ZTž…CaÍB`ÝŠ£±Ê΄¨FB¡¸3"Xº¢ÊƒäDØ h!ª8«ˆ è .Ç\3¯ö2*ˆ(®[ÛèZâB±ˆÉ‘AÄEVDëÝdÅ¿ Ö,t¡&cEÌÖàP¨Ä3X T»SYH=D°}9ÖŠ sÁö<Е^ˆÂ6ºŠˆÕ¡UDÐUݛնB$G¬ÁõE¬öR®ƒ®‚bD¬‚¢’’¦òÛ8ÅBa! ’£‹ˆ ò«ˆ¨tJ°ƒžì°Å:òëpàбjEPëé«û. Ÿ¬FÙ^¶"DÐÌÔ©‹ú*׿E¬ X¬™ ,"."Åzkã¡ì «ªACbE zŽô@Ä“OÿôŸ>sÝý—n:uæÌUš:ÅjŽªŒx’ý‹ÛW¹n-ÀgµåPÌ“–LcÓ>ºzôó¢iTŒÙD¤3™šú†§ŸùÅ#ßý|ÖÔ×CÌnþ¯´5üžp¾ða5vGtþ2jÂáAÄf>púþ‡Ç¹d'N~ø±'ñØ~h°ˆàà°®«£Œrˆ`- ##mg_úöæƒt–§sì¬ 61ç\TÈPXCÄ•:v‡ã{?|òáǯVˆ±9»DÄmäòšBH·¡ZVë«o¼¹¿ˆØ @`ãe2| fo¼ýNøúíÇŸØÇ©S›Mˆu+"¿Þÿ°ên¹Ø„”~á6úùÛ¨³ß¨ø뽚«c«'æ #®l^X ,ÞýðøÌìl©Tš Þ;~œ¥D*þ¤á‰/¼*Àæ¬ýµ"² ×0"væ«W,%@Ù˜ƒ(qIïc÷}ÔÅ},6tH^4ÊIPÉ‘úù[s/ÜH½ñEšV#¢˜Ÿã> «æÃø¼D€ÁòaCüûÇ?‚ø uõˆÝðá±ÁœJ„BÁ}ž:E®aäXDä ÕcšÖƒ rD$apLðà,öÆä±és©"‹ˆãn0«> ù¹b(±:cŠ3$®?yæp«Á~Ø!þéŸ?³KDœ’R|‘ ßñ^¬SŸ‹“KôÜ2Ïœ¿íDÞ}<>ê,â…e<¿,´îú`µeM%ê”´1X*̯„°ÅŸ¶g rÌUä.ÕMV¯¢M!&Ù ß“OÿäO=ír{àëA"‚ãè‰Ó§÷¥»²'× ê¢é”U–·n+OæSf3Ñþ{fÍv.GãdÖ5IÖ?C›ºà,<KÉúSƒYQ+éw­&_ȯ{Wèh<ö½ïí.ÎÍmˆ/ÍÏCü#ßýÞe BᛃjðÍsÉϽSHü²+ ‘PÍ Â@•¾ïDª(„¹JÕé»õé[߉‘QÐv®ÛêY ɲ¹¥ÿÙ˜¾þõáGkSa|ñ¿ä|_J9HŸ‚¯ìút¨„ÇÅ$â¡m‰¨Ò[¶}x<Á³{gDìK© >°ñO·fö„ˆ½^ZYqaåÛRÛêVÊÃy:O­•çÞÊeo#Û¢ó¥Õ|¶¼ÐÎéws۹߸]V[þ–]úP É$› “Íþü׿>Dœ«©¹ >ì «Ž;]jm£˜jÍ‘tÆnÄ_þõâ¹—nÍ¿t+ýêt@ÇtT$f›Ì¥?Ækˆ»%wìö\ßsÅÕ~ ÆÍȃÓQJ\Ñ gmC#ÓñÁ‡[öEÔÔï¹/âÉæÌòJùº‹#ÔœYZ^ŸD8žel%|©¯ŽgòfD¼<°þõÙ> OPëØbÀÃtgDìK© =\‘K}Oˆ¸Œ›ð«®¬vf2X ß©ÙÈ ÈìÿÍåùaÓÌ¿ªXM[^hçô»¹íÜoÜ!«Í¿esÊÁ¡Íˆxò'?‚MO$žúùÏ›ùÀö[îó–2kÝ•ÔÚ¤ÊõAÕ ùóìs$Iîµ/B9Åxýß8—¼ó½øk^¿9T‚xh¬îê•–í:hÓånxs‹º KxŒý¸%só[±ï7¤Á¹æêꆳªu_JÏÍq÷¾5"6”¡úО.÷Ó¶Lƒš†üÌW8øòÐ67ü({të¾¹w.ôЙ$´Ä'êÓð2Ùáwí&ý·½ú7n™Õ–¿e÷Ý•@‰ÿôg À‡è®Üì_ì<äqݕհin™UD¬Ž2}ë' Œ’¹L8:ó[Ê1Nãxbð þòç°Ÿ ìJº²G%ˇ Ã÷e¸xu?ýÅ/ýÞ÷á¼P8üÜ‹/Á_áW¿û=Ž{B´Ác>I-QÅå>ÓêØÁ=% 2…e¼°<ì(pϾí*íÓì"XæÜˆ— ôãqË//,­ÀÑöÉWW7œU­ûRªê„-G46—¡úО.wÓ[±2Œ/–W <¾7sP£aË“]„{'Þñ^ŒVhÑæ¢Ä"8P€ßtgwþ]»I¿Ãmß0¢±9«-ËrKãÀ=7÷?\5D¬Î®ä¦aWëêÞS ‚ÆB!"Š[̑㿤^ü);^À)*Ç;ß!_¼õŽÜä³´|ÃZýCÄ–.Í%)æýEg–ž[¾fÖhì†3/âj b}veÅŠØÀî“U £¢Ã-ر»Égï Ÿ»‰:v©k¦‰•Å"öâÄ 7‘o~™NÇiê">pK6®Þ2.š¦÷ü ð·xöØ‹‡PŸça¿ïÅàÁýš”?½ÐkÌ_K˸vž@µ¹ý¨ ¢j6µº_DÕf2당¸%8²ë2¯~Ž|éNü•Ûˆú'rxœ&ó$N¤g¦3?Á_¼ÿÃítXMÓ²¬¸ª+=/¼ü2(BÄ!ÔÏsÁxHQKúÜ-oÇÐJÏý]ÆU­ûìhiŠ¢.Ú!Ó’®U«€ñ5È\Ü“³K(¯4GâôºoBS8‰û©„‰f¶Ñ¦/šÑ½¶6Z Ž-¿Düè'?»$~üÓŸí?"È-AS«ûEÐ,"JP4çA)‚¢qP¦‚d!aˆ‡£DžéáÜdH ]§ 9r[ʰ¯Úa_˜µú¹6´Á"‚!0rP¨xü·?ø³÷_;Ù 'ÊÇæ±gÏ<ùR}s·,•Ê´óG¿û»ýîÔ÷ž;grú6xHÝ]§rÕ³ ªš6ûÇI«Ý{ç#/<ùêÉúnzäùêú[»GozôÅê»~óÎÙ[µ¥oüLýÀM;ÑÚ_Ó?65ãNßå«v" DND0k4W"·åöt“ň–á¼òûšÏ¶Œ~î‰g¿{ìTC×èM¿¬58¢±ø·žyíG/Ÿ9ÝÀ»éñç>¬ãkÅ jC_B$G UƒžIn~¡g5"° ÞÜÅ¿á;ÏýÏc'Ÿý öùÞmèmî¹ñ±W5“Öh<ùÝß~ðÈ 'Î4÷_÷رŸ½uæ7ïÇ0ªº£òªÎ‹@‚!âêí] †Ó³Hot4ªYá”X6q÷÷òñV¯' –ê•{cÏÈõ¼"W›e ÿòêéö³üëyÞ?" r³ É‘CÛ]ITh°ïäÚlH$ÓÙg_ÿøÆïüæÆo>wã·ž·¦§µwô3ßøõßúÍÍßyáÇ8ëDÎ7ÜòÝ—fƒQv^Dµý°›5ìk-aôÚ_$×¾‰×þ²ƒž±¾Þ“ô\Gãn`¤ÅåžÐýp6‹G ›ÛgqyfÃQŒ €-‘hÌå›%Àæ¸Ø~à(±3"NŒ×¥Ù…H‘^Û õjûÉqâH z$ÍÑ`ոؖ€H‚€”ÌQ'Iœ" &†"8P«ï¥)º@­-óä”] ~IDPt(Áíòé5¬PÏPç"p‚Üàhlè·„HN ‚b•ýºe?'g9Ðt¾úMâ;#)R¤‡ÕŠ ¸yS[vG°4Àq´—DÄž^û‹)ÒÃŒˆÍÝÕÐ`áPm?l°"6¯þfõó¯ÿjá× ¿œÿBR¤Gœ£±Á}¨™«½eé–›·Vö|n¥·rúçå?ÿ“òŸ°Šé‘FÄÛàÅÒK\ë¾B½{ñîWç^Cˆ@ŠôÚp4XJ›{Z÷×óöhÝ;õQ—êw½Î7Û5Çz\oó¦?èšøêT¯ñX‡áXöé.ñ¾™Ú.ÝïÁ ]ª_õ:ÞãMŸé5üæÏW+â…ÐS QýD EŠô“Õ!®Z£±%"@YDüdö[ Ö?>õʃ­ÏÏ4¿<ñxRÕˆ™Z£Í¯¦:^JØŒ¤¦-Ú}2Üõ&–t'º^›=÷LòÂÓÚ¾hçë¹ü¯ “c¶ûŠžÍˆ@Sh ùDd÷ˆ` fˆ<ç_pϤé?RòcD„o†j#]o%4M‰Î_fç’ý/gœ–Œ¹'Ö<¥îŽž"&k¢¢S‰Æ§’¦áxÿñ¿\þ ¾oFú^Cˆ@‚ä¨ ¢ÚÑÀ.^ÆÅâ…â1hݾò³ü×½ü׳RQ.Àè߬}þÍÅ_×þiùO!“¿Xù‹¿^ù×HE+‚¼x9ÎÑ`±ŠÉQ´"’âV]qŽçDjŸµÙF}ò×<ÂW}ª¬ý¿õº»]C¯Íb^S×ó>ß°säµ@|Â-;pu¹û^ðtýÚ=ú±K~Îï®7»g 5ZÑït!¾…ÿ;\ÉEˇ*"Gy§³2hÒ&'“ݯfÒ™pûkIŸ4ÑûÎv¾š™µDû?À2™˜r,;mŒ6¾’è{#qœL&3§;“ÁÉ´ÃáBˆ@‚äh"bu¿ˆêq nu§D*7›-'NœŒÆµuçOŸ:ÙÒÒ* ···@d4=ùñ)‘H<(>súŒT"ill2 *µ¶»»÷ܹszƒyB¡Dˆ@‚äHöE 7Ö¹6/"Ïš>ß´^«ŸÔ3iL£Öõ&§Ý †|>/ Ãju æX4Áçñ Ó¤Î0&w»<&“Ùb¶Ïøg• •V«‹Dân·w—ˆXYYI$““z½`h¨¡¹ùì… §Ï«mhèîíP©¢±ØeÜl6«Òh:»»!È­¾©©—Ç3™Í¹\nOùä 8‹/@gΟ?WSÓÒÞ.šž^\\ü¤²B‚äª""Ë"W½Ä»Òc™'pŠ]ÎD˜WcÀ×D"ívûfgC@€‘Í™ Ó _Íf[6ƒ²Yؾp@Réì%‘Å0€@M}ý‰Ó§wÐö®®d*µË[±°° •Ë·Ë pa¶Xv“Ïòò²F«…¶¼]V@³H4zÀY!Ar0ŽÆfDØlö>tt´©©I4*ëì讯kìëé…6›crr²£­shhT KÏ_¨áñyƒçÏŸ 557Ÿ>uê’ˆƒag8pzêìY·Ç³>ttw_2·±ññKæÃëïßMÁ\n÷e…É9Õ›Ã,%Ö¾:ìn¸c¥R ³ œ ë„B©Ÿ4xœ^­R?3°˜l€§Ó ‡Tjz¼N7(MF»Ó®)4ªÉÝ#âä™3àeذ+J¥ÒÒÒI’§³©µ•kA& í|B!—ìy‡Ëžäž±šHzƒa‡|†GG¹”ðôWkµ™LÜù…°gd  ‹cW(>˜¬ 90G£z§ˆÍ›R’Ì6¶Œ‹a$3œƒuAqûÔU| Ë2‡À¿G#™Ê°C¥™4žNa©4‘HB ¶D@»OL€Y³e±¡) sM ˆ±´¼¼Ýoôûý\ÊÖööB¡°!A:>_[»êqœ=KmsÑéª|.ÔÖÂY›Ó„ÃaðYØ4--Û•j³B‚äj#‚Û$?»fElÞhb<_e?:ÆéÈVf>d³D*Ed3˜Ï7ÍâÌ´‡T&U™úJâN‡wf6¨Õé‰T"™Ž'Ó¾é™P(áK"B82‚ÄÎ? l€æ¶6®¡‚Áíú<[ÚÛ¹Çq:“Ù2x+—t7Ú;;¹4ÐÆ·+˜Ùjå’¥uµ³B‚äê"¢ê…}XeÐs»×þ*J»ÝY_ßFBccKWGW{+ü×#knj1Íï¾ó^<ž544 ÇÄ"iWgOG[׆‡†FÎ>×ÞÞÞÏدAOð8¸¤˜Ø:“X<Î¥Û~‡ÜšZZ¸®Ë……… GÁ´àòæìÌ® uu;¤ÜǬ 90GƒEÄf>°avÐS§›Ôé à8¨U“F£ÑjuD"1«Õn³9ô“¹L‘JgE"±ÉdŽë´z½Þ¨TªÕj­ß?«ÑèÄR‰Ñd6™­û…ˆL6˵5ð;¶L×çÒwì²Ð \Ê©éé G=^/wT©Rí\°ê~ î^VHŒ±Š‚Ü0µ’ 3ÎEód4céžIã>ïL*‰¥3ÌtJp1’Ét’q42©d6ϸ\>Ý$@ÂÏñX< îF,‘JV’í"‚àšÏÀàà–iÚ::¸^ÍͶAµÄ«ìq©tÃQ£ÉÄuº\;L79É%6mKÝǬ 9HDÅήäÜ .LÔÄ„ª·»¯¯·§£½Ïç ƒ--­}}¼aáÆÆÄéTV&U „ý|FNŸ:="Âg}C}OwÏÙ³çÁưXlÍÍ­û…° ¸æ#–H6'X^^>½6.îÿ%:7–—¹A„îÞÞ GÕZ-w-ßÔÔ%n»Å²CÏÆ>f…É"‚¤6¼ag}” ¼Þ)‡Ã©eD£PÈU*•L&•HÆ!R&“©Uªd"k2Z”J¥T*µ;œ¢Ñ1›Õ.‘H''u£~xt8‘Lû¦üf‹m¿!‘ɸæcw86'Àqü’žHµ445±‰ÏÕÔl8d0/ïÑßÙÓsõ²B‚ä@­6¦c¡a„ß?£ÑèœNO"‘ BÉdJ«›ôOÍ&âÙH$a6ÛCAp)2‘h*K‚Nù±DZ«Õ'i¥R39iÔhuƒÁë›ÚD …êé¹|~sšP•™¡P*/™g/Ç¥Ÿ+•ª¹Üîõµzç|FD¢ê1Í G÷1+$Hø6{W²ˆP(”r¹\*¯­­ ‡‚!Áà๳5Š ¡p¸¾¾\ñq xÑhüć·¶´FÂÑógχB‘~H4&‹`h_!¬êÇÛÒË(_<ý@§×_2ÏÁªVàqUÂ0¬zrÅNËÒRÍÚ0;Òº!Á>f…ÉA"‚Ý»rC_÷ž>§Ó=>.µZíbñø‹M­Öö÷ T*J¥ML¨ŒF£\!‹Dbà_ètÚh$1<< ˆ`ü¥zB®´ÛéÌ>ìnEõ³uól(Vªg;M¦Kf[ýÈÞ<|ÐÐÜÌõÏÌl—‰ÕfÛ0ƒzó¬§}Ì ’«ˆ|Ž`QkªÞÕ¶ÚŠÈf™Ù’̰E‚°€Ïx< Ö|2‰t<–ŠÇSfR%žNgÓ©,øì4*Œ]Õ…é,–e¾’Wˆˆh4Êõ+îÜĪIbÞÅÔ£±ñq.}jÓ±ê{¡®nËYX‘htó²¬ÒÅ>Ëþf…ÉÁX…"EVê½m¹ÏÊ '‹%À–H&³à@"‘b)áryÀr€0…H€„'™,žLel6G²ÎT8c·;¯Ùl–›, ªÖjwH¼¿V˜ý==Õ +4:”gqqq¡²°B>1Á±«zÝÇÊÊÊÕË ’ƒA(½æhlx³'³Þ“ L&Ë©ÓgÁ_ 0K0’éwß}ŸÏç GêjÛ›Ûº:{úûû›šš.œ?&D: {zúÞ~ïíd’¡„hL ®Çe# V×аÃì…«×Á ËU¯ ÛNõF#7ëûÜ… [^k³B‚ä@ ŠZÛ˜®Ú×àvb6¹Mg§|~µF«7Y¿C£Õ¹=^›Õ®T*uÑh2Œ ØÑvð8À¿€°Ùl’Ëå ¼ Âátš-–ËCD.—«váá‰ÉGê^G4úøüíF48øêžÒ O|Geó\M ·çÃv—ÛǬ 9Gƒªž Q­¬£ˆ,„ÃQð˜‡UÍpaàãJ8\V(”ì)ð Û#a8àâ2Q(ªmÁã~ywÕó"„##—LÏ!è’ÏëL&£ÒhºzzjêëÁ#€ÏîÞ^ƒÉ”¯Œ½Bi«‹z`Y!ArõQ¬8Ü{vªkp³§2i\¥ÒtuBuî={ö|ssKwwwKK‹X,ÖétBá°P(lkk‚/!>wöܘXE¢±®®îãǃw?44tþüù½"bnnŽ›G ÊÀ—ßÍÏ_®š0ÙÞÕµsâêÙ•]W6Iifv–+­Áh<$Y!Ar…ˆ *VDõê-nšee8³åµ×;åõzÁJå““z½Þ01¡”H¤~¿@nàÁ 7X¬V™\n±Ù"Qf8 J¥ Ç µZ .ÉžQ*•ª7Œ_`O;:î×=‰L¡à²ŠÅã‡$+$H®¤/ Š¢6,çŽx Éd:K€—îëD°žEe×Jfp“U¯ÇWñ)¿ØÂ:ÉÄ„*‘Híó `usmÂó;6óÍ¢T©öe¥çî,nÌœ£+ùóícVH\¹QÙ"#¸ÞË "2ƒI0(664öõöA°·§÷ÄÇ'x<~SSsGGÇØ˜¨¾¶¶­¥}H0¬ÑèÔj­J¥æõóðq •J¥»DX Õý‡`K\Ƭ€ËÛ/b¯ ª–ê…œæ+Ûf³B‚äÊ»++’«v1˜® *¿Þc™!¢ÑxÝ…:ð/$âqý¤Þl6CàÌ™3>ß  §§×l±9íöIͤÊ?==35å÷ù|“Zí„Rƒa˜ÇãµìnD |€k à/ÌÍÍ]ÆØÇ]§v#™L†›ïÔÔÚz%»ÜïcVH\¹£Q,P4y‘£Áj®òþ>vß¹êiQl 8V«¶ qÚçõA€Ûʲ:ÌŽhd+]^ËËËÕSZÚÚ¶›b½Ù¯½+AJåv;à•+Ó>/T-©ØùMû˜$WÛŠ> ×]yш' J³mœ ‰ÇÆÁ­‡£@€ÁÁÁÆÆ¦ÎŽÎIÝä¸H ®GsS xÁ  Ÿ/Ib‘X(îéî±ùìŒxîŽUo]›ßjçždÛ°IR¿—°ûÙ­',V+<åÁLhšžšžŽŒTÏj°Úl;i³B‚äj[«ˆ ¨êÙ×Õs,×F4Èd,©œPe2Ä;v­V럚¶Ym`B¨Õ£ÉìñxH’ÙftXd2šÕ*µT"U*•*• ♉š;"‚$É]¾D£Zkvø™Ì{4ºº®ü=l»ÞYOž9cµÛ/ù§ÙǬ 9D0ŽE¯ö?TÍÁæÖh`•lÎøg§|Óñx²²[>„X‡‚Î`¼ ‚Ä2ÌT!)p.Ɇ“`8SIyðˆ`)Q½Íæ·q™,–KN×¼d»îîíÝ®»ãêe…ÉÁXäÅ{WVƒ‚¥A:u8\Ý]íímí}ü±\®èêê‘K}]Ý|¿­©U"’œ9ufdhT6.ÕMÆDb¹LᛚþD±ÚXy§gGwwM}ýé³gÁéèáñŒ»~§g©T *µºÏonk;_[ËfÒÕÓ£T«‰Äîÿ4û˜$ƒ‚ 7ìj»y=—Ûí Êå«S­R‰ÅF£±ŸÇhT𶆦1‘Èn·‹Åb³Å$‰Ìf³ÍÆì,a2YÀÑèLMÏ 7ƒ#Ar ¶ƒÛ†D8ͤ³«FE†Y™5;Äq"‰Ä ÿÔL&C°GÙîMðGØIS,3ù4B$GÉN„¨ôäáñøš›[ôzÃä¤^£ÑBÃתµ¼>þÐpttT.g6¼«5š––VvT´¯'T©ÔXr¹L*•O(UH9D 4Á¼³3Ï!"Ÿ/18Dd2¯×ëv»JåØàPh4711!‘Hø<þ¨H¤Q©‡‡‡S©œÒß? Y,È ü¥’Ùý²«« ! ’£…–‰ÓUó®ö¹…VÏŽfF"Ѫ!UgÎÆ‘«$£c‰d<‘¤èÕYš±X<›ÍVSH-D°³§H‡VŸ[÷¬^¬Áâ³³A…bb|\*—+ “ÕjÓhtn·gjÊ'[[Z zƒ×ëK%3­íÌÏ åȨH§3*ò¾¾>§Ó‘HAGžþLwe®jjgN°1ù|Áår©Õj‘HÔÐÐM^(vwwƒgaµZý~OO@ ðù¦CáHwW—ÁhhkiU+U6‹U>¡€£à( „$HŽ "DUS§ÀŠØbF®ÀvJT, v·:ËbEãTa]ˆ$À!)¢’&™Ì0G%†¬Ä0PâÒ³+‘ Ar(­Ц֭ˆ\._Q&P(YJ`ކF£ MzÄR1>.1™,2©|R«—H¤ÂaX Ìœm‚£ÂSÙAÂíñZÍ6¹|! ’£ˆ’Âst!O*–ú*Rñ5˜Q ­J-j¨© Áwèïï7 £££uuu:ndd¤ŸÏ×£¾¾Îb±‚ý0==ÐÀqR£ÑH¥²¾>>B$G$ÆÀ!ÇØ *:W, `BpÛbSέQiÃá(øŒ«Qq"Øñ‚%ÁÞÀq*Œâ8&Ã!fYh¦òªäh ArDû"ÀÑ(æXJ0|(A+ˆ(°Ó¨¢Ñx_Ïbµƒm­^¡Pj4:ƒa•Jc2˜ôzc[sK_oŸÁ`r:]jµ¦«£Ël¶‚'2&§*[Û!D Art1šÏ‘,"(p4r…U>TàPÌÏ]Á!Âl6µ·µ·´µC«Ç1 ü‹wÞ} hø­­­MMMZ­¶¹®A:. C½½}õu ££Ãà€´··C²H$†ÉÑq4ÖVDŵî‡"£àwä k;G‘Ù,†e°T: |È2oð̤Òip+Ö÷¹ÍàéüK3‡R™D"™H¤“©À!‹ÇbÉd2ƒÉê‹ÈÑ8;uЦÉJ/Äzÿ$£ÌÆt4»Á5|!Å„jxhÄb²ØmN•Rk6Ùl6'xƒƒÂñq‰ÓéV©ÔÖjµÓ¡Rj$¹ÑdQª5p"x% %B$G 4˜ 9šbm†<]™:E2£ ‘'ñ–!ÓI,“&LFÛààPCCCKK³\¦8uêã>Fx ƒƒ‚¶¶vN«Ð ›eRÙ{o½ÙÓÓ=0 àóêêúûш$G àhòÌìJš¢àmàYp(ˆl†H'³@†T"›ˆ¥¢áD8‹F‘p"Œ€ãGCÁ0h,Gb``C±P0êtx&õ†H$G 20Öª ÆIs( …¢‹! ’#…ˆÊbð÷ŒÍî†8É‚³Q»Ý=冂±P813ž™ û§CHEDdÒéX,‹'f¡©é Ï7;5ôO=Þi·oJ>¡™Ôj.4¹§ýý"Ù¸ŠÏúàýC-BŸÏ¯Rj{:{;Z»‡‡Gff‚*ÕÐаL2!‘ñøá h´_ÔÔЂÉQADÕ¼:OSs…âü\©4Wª|”J ó¬@0«•* ?ŸÏOêt2‰L!“ŽŽè&u‚A¾Ñ`À0L«Õ‰ÇDc£Îåò& µÚnwŒ ô÷à £BáÀàÀµŠ‘X|âôiÁЪxH®!Dpƒžt.G  ‹……Ь¢8—ß$¹\°ÀÎÖN§Ó8N¦Rng vœ”ªl£'2~ÿ y©éL ·i­B©Ü®ä4M¯¿£±! ’«mE0[E0žÅbq®òß\±PÑ|1OçƒÁ Û厂©`05Ï7Õß?FƒÝfªl@§Tª†…Ç©)¿V£+Õ*í¤N/“tv´+•ÊD2 Evˆšºº¥åå-K®Óë" 9`D°s!òÌgeojU)‚v:V‹µ§«["‘jµ“âqqOO—D"áõñ:;:…B¡L*ëìèÈfq©D62$¬«­ H¥Ò±1qk[«H$²Ûn·g—ˆ¨kl„Ïi¿s±WVVš›¹4H\}DhšÌ ÈÊÎr¬2_+¯ggO…À¾Á<ˆp8Êît  †£ÑøÌÌ,H2™v»½ñÊö×^¯¾V¦Y¦ØW‚Âé»D„Z£ÏÁÁÍÅ…à Ä B$cEžÍàÙ4Že,Kâ(³Ÿ%Q ÑhbbBéñxÁ³˜P(Š ~O!“ü›Ù62$ …"Ñèù  éžJbé–Je×ghgñ]"0tòÌÐÍïô‰X†ŒK¥H"(Ì0 2$§x–bÂFƒµ©±iX0xþì¹!Á V«½pþ¼X4&—MÈUÃÃC&“e\"íç ¤Òq¹\îryâ±T"ž‰ÇÒ`N€ Á"бKD,,,°oµ3˜LÕ æJ¥ÓçÎA<Ø4["byy9‰(”Ê®žðDN={¡¶¶§¯Ïh6ÏÏÏïÜ´1745š„££\8Ñd6÷ñù«¯ñjlìåñ,Vk±XÜ2’$!HEmjiQªÕ¥R UH$G`1€Á-ÇȤÁ¢ @ÙÙ×ÉDš}u´}¤ÓpX÷4•ΰ~( ö€ÊÆCž »w4SÓÓhnm­N`µÙ Z(„·D„ÓåÚî½~ÐZ)ŠÚ–ê·„ GFØ‘hȰe†CÃÛóI$“çkk7¤lmoßPH+gö–ÄI¬B ,ËÀED&…ÇcI“Ñ Ü`ÐQñD*bv&˜I3æÄd2 ˜Ï 15åÅ’à0Ša$$»äk«±´¼|¡®±xœKÐ^yÇ·ÛãÙ¯W Âg&›››[\\„gºÙj­mh`_§»%"ÀÌ€€ÀßÒÒw¾ž9ž}m¨Ín§hJ¾I©RIe²ùðxõMMã£éLò) zƒýEÕI$G4I8E0]‹&\q4Ò)ÌnqŠFD±tlTÜÞÚ><ßtwwD"•J ]J*oà’&âŒC122*—KU*µÃá‚”*•F(¶XlR™Än·J¥ãÂá!½~ÒjµÀ§`P°'Dd2™j&È ø %`ïµ»²£»Ò›-–-›6Ò§+Wu¹Ý»ì®X;8[6íËè®Dˆ@rÍ"b+Gƒ5'àÓápéõÆæ¦@09©ëíííép~ Ÿ'‘ŒAÛ‰†o½ñú¤N#ew¸mkk’ètz¯Ç×ÝÕuˆØN6#Â75µåØÁòò2¯¿¯ˆ(ï}Ð!É"X»¢z$´2? c PÿìLåÕ¿tŽ`LHÀ&ƒ4àtTvËOU¼Œ|:“Mg³Wà†°­`{°_@ÃìîëkjmeGö„ˆtõÔ)‡~$Ð&_(0S§ÔêÍS§"\»ˆ *Ŭ’ûd5‰)•*¡pØë‹Ç­f«RÁø6“U)WŒ ÚI…\‘L¦µjd\*‘Húúú„Ba]]L*%pÂj²Gy<þUED¹j¤²Zkê롱÷ðx{ED¹2›ä¹Ë ØH®]+"·Á„à>íNWWg—\.Ÿ™™­«o—Œ›L¦þ~¾t\¬ËjúìÙsÑhœ éÉIƒÝjïïï—Je‹Ì œ m=½]W ÁPˆ/œ«©aWQÉ'&X7áòÁ¶qƒÑ¦ÈùÚÚÓgÏ645õñù;,ãBˆ@rí!‚¦ Ö§Øìh¬*½úÚ>øWb5M.G¯ ãh°Ó®(:ÇÌbd5¤òŽ`mo‹ÉQAÄæAÏjË¡òr®";Ÿ*KʤFƒ% [Íöþ F£M%Ó6«mB¡tX­`?Ø,N±H¢R©µZ½Ãá‹mV»ÍìI‹ ¤R00" 9šVÉ™ l ÂæEÀÌ›ê[š›½טHT[SÓÙÙæt¸Lã©S'G„#z½Q§›…¦ÆfáàPÍ…ñØØà€€ÏëŠDâX,qþ| B$GsE:W…ˆÕM,W_ñÉñXR§ÑQœGQ™EQL 2WjuSNÃ'˜$•ðêB0ÐP0R™E D Ar­v× ‘¯ìs „>À×X,69©·Xm^Ï´F­ûÁb°f³¸F£“ŒËÆÅR°"Àx˜Ôé}Þ™±1‰H4fµÚMF‹J¥šœœŒÇÓV«mxX¨V«" 9ŠVMuTÒ "Ø øt»ÝƒƒC¯wúÜÙó#Âцººh$ööo‹™ì¨ÕšššZ>Éêë„Â!Bc†»{zÜnŸ@ 8{öL{{;B$G´/¢z6·Lƒ‹agO…aìŠ b˜-­³Ì¦”8FVn`ÜžuÉDâ!\ÙøK&S©$Fˆ@‚äè:ÜŒkV9£š¼Ãᘜ4Tº(Íò Šdz,&ë¨P4Ð?ØÝÙ-Ë´êIvR5¡¶ÛSS3éTÑÙÑe·:Àï‹¥‡! ’£éhÕK·ªùÖ‚Ï7Íïïëëí©«­QÈe2‰¬²Æ ôŸüˆyù¯jBÙÞÚ>(Ÿ>yzddD¡P¦R‹ÅÚÔÔ,‘Œ·¶µ4·4KÄHIGãâÅà"ØFÄ¢ñD<•ª8Ñh¼²é=„™}®Ã¡H<–Gb&C‘H$'˜—ì¤Ò³àl0 …AàfD|öõ(R¤H^/c^ÛÿP½ñ‡ˆööN§Óírúv7𜎾>¾ÛåµYúI“Bª2茛Ël¶&âé` ¤7˜Æ%ã©TV­4¬v»Ë?”IH‘!Dòdõ¼ˆ V‡ƒÁÔÝÝ ®DooŸH4‰DE"1¸gOŸâõõÉåŠwÞ|·£³£·§G(zÜS±´¿»G<6öÆÛï¼3>&•Jå.··±¾q;D¼rÄÕ7¤×""Fó¹uDTgl°"@c±x2™J$’¬—GÀ•‡¼Œh$& †˜7{ÆB¡¨ÇãI§³Á`8 '“ép8ʾv'ù|Ó; ‚ ` å67ÅçæËÙô\6•'±E,¹¥HšŽbùQMP 1b>šËQÅL<›‰fr©|.9Ÿ‹—éT™L—)j1–I$)<…3Ùr!_¦ÉAÄÈt±@,Rø|žZÊ$sV³s…ü–¥)²H‘…t2“£h,›ž/ÐÙd,™)c”¤Œ§™l±T9“.¹"9Ÿ—ë7)Òk ÕV7¯róÆS8N9ì.‡Ã¥Qëbѳ'v†ŸÂápzÝ>«Ù®Ÿ4z=Óàh(dJƒÁèry˜ý±Ó8³vÃæ…v—‰K""MÍ•–Ë$U¤‰b¹T.dr+ù¥…|‰y+1],-•á(U\ ó¹âòÜB¹D–éBy(/§Ë¥œ°œ' T²XŠÐÅéù•D¡„ÁO(äJŠ,å3 …@)7CSKóñå¥t¹œËç“Ùl¸XÄçK¹9æ\|¡@ÏÑD¹Tœ§ˆ|1¸°]]ˆÀ%Vð<żg¨0¿ š4"D ý£r4X TS‚µ"ŒzK_{·hd¤»» Zû‚Î÷ßO6.€[qêÄÇ2‰L&‘ŠGFN<-C"ƤRÅðð(¸‰Œ‰}ID0[ä0,ŸL–s9ÐR2¹„c+yz1GhŒ¦°ÏåèR>Ÿezi‘”(ñÙ;‡EçðÄJ/‰rž,Ý_©(ÆóÔ”ë ÏÝïw‚¶§ª§ívÔ?ÐZÿÕ¶†¯ñº¾%è{´£á[íµOˆ?ìùnkí×@/|µ¯ã±¾®'¼ôv=Êï}¢³ùëcCOõ=ÖßõpOëC}mÎjŸN:žLO=qÝæ·Þæ·<šñŸ]&\å|ɤu DfýõWž>a7… j—t4í¶$=–2•?¢\"Êóä"™^ÉaËdºL»’¾×}Žë#Ÿžý/Ë nÉÝ“üûå 7~£¿þA^Ó]#ý·Œ nêmú,¿ùîÑÎÇD]ö·|c¨ãa^óW»¾ÎkýÊ@çWFxŒðïëm»U6rßÿŽÁÞ]Ÿö^ohú¶‹_HýYÌý_²¾ Ûnŧ•‹Ær1g×Ù"³ýp˜ùÀê·~Øx$=«§NmÞþÔ˜öƒ³ÐϨ»P;6:ÒÔÔÐÑÞ)µ´4·¶6KÅãã"qSsË€ _.Sœ8q* ž>s*‹ãétº:Û:U*¥B¡¸$" 0X:F¥âåÅùŒßg‹–ÒqÃøHÜç(Ï‘ótvŽÎÎçÉž¿£DâåÜ,1ûfÄû©Tூ–ÿÝ0ðo%uÿYtö³²Ú{%µß7>2ÒüiÿgÅÿ]Ðþ)ÅÀ×øu_ëüúx÷7¥¼oóîá5ÞÓ×p·°ó¾á®{íŸï¨¹^Ðv+¿ùÆÞúÿ1ÐrÝPûšS_Ñ\ø´­ï¯†?Ïzþ*bþÇŒëÉ2.)ÓY»ÆŠqhü‹Ãˆ÷¯¿éÈ zn舨ôU’©Tœ° ³Ù™Y«Õf³ÙÕj­Ãá´ÛœàV„B!§Ãåóz-V[(™žž±Ùí³•é¢?'F ¸à­\zD#—[bö•Ífb‰òRÙªÒ„Ý^»n2 –W–)ŠÙ»ªT*åóÅ¥…åb~®œ e=o‡]ÿœ üÄô¿Ã,Ÿ¦M_*ؾ=~þÓ’ ÷ˆkEÎû§qþ? [ÿE?ô¸´÷î‘¶Û{/\'h¹MØv—„¿ õ®ÞºÛ†;îlýB_ýíýw Û}¬ãQû‹úÇpíÍiãÿIùþræÛÿ÷>U&äe’°©\["âú7¢-ÚQXž[X‘{ç¾x<ÎÆ?x:9ê,B<¨Ø]üòljê³ÂØâ÷ÒÛ›+-oøóÝ{"±áÜ/}”¹˜ü󥡽pÇ{1öèvñ×¶¶üý_~D´üÃÿvdÜú2® ¾ "ñùZí¤ÝîRNhœN^o ‡³¡P ¬Qi,«Çã&(•ªL&[Y½•Â0ø­P‚¤r ¶Ú˜nC+#ËþX:WZ*Í-»¬n~'_:"IÄR §qº@çóóËiŒ¦ K5_&cÄÌ{ǧ£¾¿ÊxÿáügÂöÙŒéÓ.ѵ Ý¢íýÂDßM&ùg ²–ð®7Ž>¡½T>x—nü~µè^ƒìk#÷Ê…_’ ~T>t·lð.½ì>ÅÐçô’/+‡ï­·`öÿžvÿ›ôÔŸÇ\5cúTÆû\™6—óóöÉÙ-qVN%©¥ïÔ¤ mªýsÆ`‰oÓå~Ûƒ}îýøWN$TÓs–ðJ| ’ÔSdlmëáç«GìÞ•Û9`ˆDâÖÖ‘h´·§G:>.“JÛÚÚR™\&?uê”ht”Ïã···'Ì[ºØWcìKÆ™½+sÀ‡Ý "•/‘ K€ˆ,F F^ñõ·_{óý·ÞaP“Ÿ#òsôÜ"F ¥e/–çfñÀ»~ÇM³Ž¿Û?¶Ü‘2Ý1üßYï1Û}Qëw£Ž'î{g\w»&ÐŽ<,éßüy~óç:îæµ~NÐý…±Á/ >?Ðs£Fqï”û‘ÀÔ£Óî¯û]_õ»ïŸvÝ;kº7êºgÖöY¿õSÃõ.ý·²óåÂôr~Þml‰ˆ4½ôžˆdÃß8—„_ ­xÃ_X1¿¸Â}ýxœ´vsîmïÄÀ8ÆÇ7œ Í?Z›b#Á¨X)—!r»x„„ˆËë®Ü€–`h4º`0d4šÜnϬÂJ¥,«Å.†ÇãuØ33³z½ÁïŸ1Æ¿]ùÛ-õ’ˆ æ3¦ÇÊÂb!‹Åý3X$œ˜ñgÑòÊb>Gáx¶P(Ð$^F‘*,dÜó8o1÷æùübô­åÐÙròT™|u%ýûùøÛ¥xí|ª¶˜}w~cžø€ŠÄCÝq_sÊß–¶Åý épžhŠNǃ'ÈÌùu.‡Ÿ ³ïå‰÷æè÷çèw‹™ž9¬³j(eÈ®|FËh äÌ\1osNoFÄç?ˆÃOû^Cš‹—á¹>¬úO-Tá›s­?ÍÁ*ø}/¶›sßà2ÜüVlù, ©YG|ýEgv»x„„ˆËFĆ%á,%عì;tØIP•}!Ò©T†}ÿ(û®O8ª#õRþ“-õÒÝ•%š$Ò9<¹R W‡>)l ‹Ï¥Ã‹d:—ðør‘œÃSD,’O% Ij˜^¡ue\_N…ËI²œ-Å”+YébF¿’ .esiý&_¡TK˜f™ –2Ó ØÌ<6SÊΖçÓåbž -PÁ¥\x1„ÜI97³Hø )[Ê@g¨,\qOðh‘N,­PùyÚâÝ¢/âSL“ Ú¨x}ˆ`ï pö·O§¸G9¸€‚Ûßí|.«žøB³6Ç}åÎe)§VŠÉÙX /ð°â".C1›aò—ßÝdzŽ"8GcóJ®P(âñNiµ“.—'‰ã RiœN78ZÎj¶YL6—Óc³9 Ùdð €ÿ°ürÏĸC:4LL©“C­âöK"b~.SʧéT>>3£Wº'DÃhئ±¨¦ÌÄ©•:4R—F–òÚ<Ê­:µÖý î*ç¼ehÖ³f›ß¢ñÛmaW*hÏzô~ŸÑ¶ƒº¦­^ŸÉã·ú}–©ik01KÄü„Qéµë‚õ¬Aá7ÉýMØ;·Mt"·B)7­6Ë”f¡7kU‡Ã•ÈÆéyÚäu^†q]¥ÿ°Ç˜“K·¾Ã4mðt3¥Ýœûxã&±ëÃ]Òiˆ9&½ZIÈ¡£cþB&4‡EçÁœˆ–°ä7Ÿ)å2 ¹ô"3ñ [¦ñòB±œŽÍ«N§-jšœRÉmJ™Õ¤q;M3Nã´EëV[y‡Øåµô­Új2¸ío"“&J£ÛsÙ}¬ýÿí Œý/rß%vsf@u>ÕçV믺²€—̓ÛÅÿ1 ‚÷ßþjªþD>X„zïsŽåzˆìÿÔ¿ õ·—2©¹L2ÐÝÈÿÿ†ML8-ŽwEEý¸Ý‰¥Þ ‘Su/Ï—JÙt>4îc“yμ“ÖÊéiæ©oš_~!öž{…Ææ³.¶Èü–mÙŸ¿{mðk?16º¥±yô@0 3Û>°>…Z£I¥±d* ‡Á` H&SàqD"ÑP(*IHVþ³ÿ¸øAÿnéï@+á¿»$"è9*‹§ y‚JÅCn{š®Û÷9bSÎð´kÊeqYõ.«qÊn º]³N‡Íò¸‚SSþp0‹$ív§J+Õ;ERS«ÌÒ­¶Êt&«~ÒçwÅè$¹H‘ÅÜRŽœÏ‘sX–Îf¨Bq!•Îj'ufhýf­V¯Ðefë„Ý¡´Úd&˘ÆÑip N &³f’Åb!rt~¡dõNï<¢qOeTÂT}¸þ踻øHMêæ·cðX°²¹¥›ßŠÝð&üäeˆÙá\Vï|ñ)~ß»nTl8÷¸˜|ª5N|‚‰rFFíÿdžˆØØ@J%¼áï <|Çºé ­;:Êçý?ÿšÿÿý›„|4.rˆ ¦\ýÿü·  vý‡?Ýl@²\Ð?ð/ÿóõ?ü©æÇßÞòŸ!ùçÓ@Œýµ"vhÎì"X§ûQ!OU#bÃJ®ê+…ƒB¹L144„aLoÃÀ€Àh4š &ɘ80€Vãp8D"QèÿoïL€ä¸Ê;>¤Š"$\©Jp HRE„P`NpI0G€¤¸ â8Eq8T¨\1¶AŽm|I^­¤•´—V{H«]í=WOÏL÷ô=3==WÏ}OϽ«•¬ü{Þj´^)^ÙXB3þªÝóæ½îÞ*}¿þï}ィ G'Õ©çÝQÜØHFc}ž‹†¡hÖå–yÁnµ¹ÝnÞ Çõ¤O—ŠF*‘Æ#©l\O©é\¤Ò,Ä3 Z`œe“WÖäE»D9|¼Óå¹P"¢fˆ.5$‡#Á`H¥òÉd.Á^›ËJyžâDË;½ìšÛ»âö.»šB„%«´“Y]°ZWm,C¯o6[gâå BƒÃtÃhŸ[ß|zM½˜Û€7¸”Ú@a±q¸øDW|i¨.œÙµ- jTz%;Ú‚  &Ê›=)ò,å?WˆðOnöö7l/ÄWž¸õµäëüûþ_‰¿Ã÷¹ïÞCÊ!-Ìò·¾æ²ˆþç_.ëûÜ}#½0s5±£ð¯öd´ü™çA‰+›é¹…ˆí»q]ª"|>~|lÜá°=ùäápÄãa&&Žƒ0û¬«+þä‘™™‡Ã~äÈჃƒ«+Ë£Ã\]8LOp÷O<à.y†=#«‰µ=S{vO:>j4KçsÕV ¤ûM–T-¬3œ,øC4/©ñŒNx¹`4QTÃiEãô¬¦éŠSÒÅl8YtñºÕ³Ëa›ìwù5|uº¢^w@d]{Òå9ÍIŽXRNeÃz6R¨æ3¥¯ÍJ^Vu{”Srد'$ñºÈ¬ÛÓŒ#ï^‹0΀ÀˆŒ—*UôZ+ËJîŸ>»òÝtÖ¯}ÛŸ7D Rxzs“(‹…¿ãÜæ™Þ×c¿ûKøg¹øá[‰ïÓ_ûÜVù~ÑÄ äÁåAý󽯶»>”§Ve ¦@dQb]×&%ÌàeA"Ž«Ú]ùÿY­ÖUMÓü~©djà$™LŠ¢¨ÕT" óù<è‘LeTU±R­e2¹p8‹ÅËfUEUC¢¤ìh\Ø+wq»½"!|X\\¦iÎQÁOA]°¤Ãø@0”£2nƽ^–çE˜ H'à§|¾H6EˆDþ¢l6? w!‰Š@†€Š{Ⴄ!.β¬ÓéÄ=dYÆí(ŠÂ#v:š¦zDàÍþ……kßöçNEÜv þÉ‘àb‡Š˜yÇo“¯sþ¦í*âòˆÀ¿µoÜý D\¨†¨À±ýÝÇnùSE|÷ž‹ˆxf«„Ïòë 8¢Ñ;n7xV Ô"a¿´ÙðÃD")KJ&“‰ÇtµP¤fîËeöpÂIánðÖP(Œ†F­a˜)šU4 i»/)CÆXáÑh ŸÅ¥Ì@YÞ —‡ÿ ¹\¡Wt¨–J %ð}‚ 4„¿†€¾J’Ò]æBÁqDy$ÃÕІBRx!u —Ë&à!H¨ªj8Æ]_(DôíöEÌäl‹`Åžˆ×¾¨@['ÆH_DfåìRßߎˆôÂtà'÷^¸àÓçÎͼý·L\¼å•†*÷±£ÕÕ@Ä®¿>¿îJ2A㢊¨Ã.î Nöü…Á¿ŽOLRvçÄøÄ©ùùù¹ù¥Ååcã³'O..,813 B˜ûkTŒÕUëÀÀþÉÉÉÕÕ•h$V­ÖÉ ©¢øG†G®`DãLolÅï‚ pX¸*ñws“/–“e? ‚ƒ£~BM¡Òé,ñw«ÕŽBêÈÀ@}´Òõd"‘J¥28G}€úÊ ž -Ðu%çõzo÷¦DºŸB¡°¾¾xõq#h¼ñåÚÁG[)ÝшdDcúSŸFP`ŽhŒ„k?;"–ÿæöº8S«æl ;ªÁøï« å+`‚ºwO;Z½€ˆøÈ#ÙÛ˜¾ZˆØÖÑh˜ Z1µ‹;ìDà/ôH8ªH~EQŠjQ-„ÿ4ÀP‚Ñp„cy’k·9Þ¿ð_/ãƒ;ãx¡T®Â+ñʾìÎà;¼¬ÕêôäšÁ†@ Î G&Òçæø…ƒ‚ƒ“$Óa䜄'ä'Tî.”—„õN€P¬Àˆ:$¾pY¦û𸠙@ €X!n‰ë⮈›úˆègW^ûìÊK!0Í·Œö¹¯-^eD4êµ 3=·©ˆ®®hÖkM¸y*™vØ©L*Ç R&)K±¸Žoç•Å%ÖçsS´ÝfÇk×á¤vÇêÊ*ËúŒîԌ\2™.äJW°êT‹ð'@¼•ø8”àbÀ—IwÆíð?€ Ö€ãÃÇa(„›ÃÇáø„0(7º±ƒšWî@ÅíP—ˆŠ@C(4Á-ü~\q‡„¨  ˆ(—Ë F}DüLñƒÙê»»Iø$Á&VÚ¼:ˆèõE˜{}oñ|FD½ ž›;udèð‘#G¦?5{q^÷Ö5›mec¹}{÷îj?„„Íî@ð>=5ítR$UÛE¹Ož<9008>rlWD´Ûë¸)´D§³ûv¥> ¿.àÎ8"v€J.H †ƒÍæA âæ¤!ªMˆ/HÔÑ´®€ î讑enYŽÊ½ׇ‚BäR*•,h†Z÷ieÆææf}Dü Qiž{hɸí©= J²µ³Wfve¯óá²Ý•ð>ø×‰‰v›M5?!x+‘L¤à¿ù\)‹ÁIß  ç‚ ÂUákÝ7²899F¯DEÉ¡x \§÷ê‡ÁÇaD0€ pjh rBº!!hè4Ä·&Ý@A:àþð}”&¤LR#Ã"¸šã¯À-H€£iþ4ÔN\øÄãqgΜ¢è#¢¿^ÄOµ^Äë~õù!"W;{îéó•ÖÖ*"‡¨ÆUê®ÜŽˆûüng…¹­g&ŸNåJŪÙ%˜ÌfÓ…rÑŠù²¹Ão®”Ëæµ`Ä,1ׇ6_Á(1g{åK…\‘쌶»ÏÑØØ$‰ß Àµov<’@G”ƒð_¸6~"H#h—'ãP¤KÕa b8”¹´'Þ   IF1H}B€ŽDn7¢;ËVœû|>h‰>"®ûU§Þuý#âÛn~ˆøæxiû*CT¸ƒB.±±}’8û"¶§NõøÐT††îØ·¸0äС¹ÙS{ŸØ{ll|vfæá‡œ™žÜûøc““£ÃÃC‡—–ææOEõ¹¹Ó<øðôôäüüÜààÀ•äEÀg ‚$9ÀŒbÀàÚ$^ ?ø Á\@@íÄÍñ“9­ÌÇ“(ŠlA9° À-.‚ÒɉÂx<Ôàj°H$R(r¹؇£®ëõz½Ýn BíÊë×>ýÅÁaíʃϻ»ò=÷¥??—6Iáw¦+×l¦çD˜ý‡•šhöæ¹"‘p\×YºÛ¡F£p ¼Ð%]N—À <ÏÉ~Ùi·E㺇ò@{DbæÉÒés!\-²+"67Ï!Þ"Z­^ñ¤²76&ØlœÀåá餢×Ù‡@4D(Ñ3’&ÓÕQBz$À²X7‘€*8Ì…³§Óµ¶fU‰ÀÄjµRÅ0 ‡Š‚äHNG’ú+`_×öÏùêõ½öןë_´Ã…¡ 'ȹÑ>÷þç8“ëJF4Ú­úVwe½vé>;½L ĉdZO¤Á £b¦)V*¦U·¬r3}±\ǯ•’Q)×ÊÕZ¥»²D©lÄôD¹TEÛ=»\…Û"NÿÂI¡ ðŠ‡‘¼JI°ÐKv=H”Ap|"ÐŒZâ+é€×“^J’hA†-ˆŠÀ¥H^(…À qÄkkk+++4M«ª !¨*:†Ÿúˆ¸ÎíSÿxàG·½ûºê—Àà ¾x®ú˜°(¤£ë$è8­´_`D,œ¾€ˆ&±cÕ©­¾ˆî4ñX4¾°°h·ÛŽ : ¦)úäô‰ýûö >õÔá‡ÇGF&MŒzêàñÑãz,UÌ—G+— ¼‡[]ZÝ}I™ÎFïzÃðhMÀ¯{}˜¤Ï¡WŽÎ^«5H†$Ú’á ’=…j¤ß*r‚HÔ'*W ù–€¹>JH÷ëäyšŠ¿ûi4P8é#¢o7®]y_@Q¯U/ñܾöd€èq8W¢T,ó¯iáTŽ–‰Dã™L:‰§éxb>Eòé|B×ÃZ´˜¯$õd, …´h$¾+"ȼ ²€"’A ‹éÝESpsx7"ÈÙÖ‡L¸€_ÃЦš3K"$s»7ÖI""0H^D8%¿Aê“®K„P ^¯×ဨ0s¶@Œt:}öìÙh4ÚGDßnfDœž»˜€Ý¸ü¶¿½ÉàÕŠ±º¼rtthqqÁá°=þèÃãcã#G‡8zäÐðÐÐäÔÔþ}'g¦‡ÎLM¥ôôèÈá“3'¦N <4=qløèÁãǯ$»’äs$Q†—;qv’±@”‘:øƒH&‘Òº{~¡„h ðÎN~"ƒ›ä„lÖn¯‘Uõzá éñÀȬ”d³YAîÂáL&S( JCE´ÛmˆŠ>"úvs«ˆË"b;%z_«•j(¨jÁHT «`Ф(;ŽšªEÂQYÔªÈþD<Í¥n9–•Yà}hE9)ò”Ã)ùø+™Æ…;’E2É@ÄC(†Ã’.D’@…÷9™Ø…:pj‡ƒ²Ù€ütSàW2å5ñ5áï½$+’@Eæk,v»Óét‘ â$×B¡ž\Q š! ’ˆƒtWF"‘>"~c”þÎò™_nŸ·Üˆ†'wÆßõõÑÁ æ…ìÊg,Ig4jFýÂΞuøàôÄÔÂÜé¡C‡ MNÅÿGÚóÄ£ ¼0tààØèèìÉÙ£G†çNÍ2fb||éôòÉ©™ýûöÍÍÎ_‰Š ©x âÔ䵟%!I³$Ó?».lvD ZwîD*•¿“éÄHZ”ß$Ý $! ðçt3£"Àø@ҶɯD>L2ŠA&h€;8ÇI©T‚Š€®è#âÛSÔ—oP2\jO:¾z£ b½Ó$#;—¿î"j¼»êµaîêRý¿™á(Jáp$K’Ö¢8a€,É™A‚Ù«)É’ r¬)o**Å’Q©"®mȸ ø£A)*ë}œÄËŠO”¤@Pª07ëóø¸rÅhw6‘X×X?Ü4| öµÑ7"—æEôb ²iYÀGÒ‘XÈs™<Žùl!›Î庫åó%|…áÄ´m‹ç“ö …Òìé¹Y7±Y«·E¿*B@'h–” pa6–‡ö²4#0¼Ûéà¼e(›5$ô˜_‘‚þ€È p|A‚ÁÔž 9g¤TªæÄÔª¹ÃPµº¾¾ŽPÚzæ<ññ8º=Œ—ñÙ]´Ë˰‚H3,åñÚÃrõF«ˆkoˆ/n2D8ãï¾±Ñ 4¶ïÆÕ[¼¥› Pï&E%à®Vª–‹rÒ;– eÓpR¬T»“ÄM÷,ïžѬ7L/6Œr¹ÜXœnÚî¢ðîæ Îk¦=p¢ÌI" v@%ðaMõË ãñ–§lŽ÷Apš¦¬ù1G<ÉúÝ 7ÊUU…ªáEAö+x4À€ö¸9Çípd|,tJœ¸o—¸5íöR.7nTªµÎú™>"®±•6~å&CDiã¥7 "È4®K…„¹ˆDwI·žV˜p(á ¯ß:1Ì’² )ßú‰lÛÂTj»gWvðPÆ:Ȩ(ŠóxhŠv"J€k›^@P¿f°>€p8 ¸\.P¥P(Påt:Iï¢Ýtç_ȲŸ,:çñ±¼,©‘°ðÁÚê´…5›•ñyy‘ó0nQ=ÌîU\A¸ðAØb.ê˲¥R Ú£ß]yí&ã±ë[©S¦Š¸€ˆK)A¢ øxONlߓ˨š+ã"Ž %[j¡ËØdcê¾öý?lÝ»¯ýÀývGD»Þ®•×[+E¼Ïa´Ûáö8áâðË8$Y惪éx³ãÃM{38H·d70ñð'e¥\6Ade…çx/çe(‡ÓC»!N$At»h0ŠLï#¢ˆ›óaÍKÚnßœÌÎ6ÏnvÕ¨Uê8 ]ÝhV 3»^n ÜOªU£Ò¨–kŸÙøìs]$|¨—ó­:Ašq; öŽ5PBD@Åbh†€â8^‘䤞ð4=‘Qü!Q àVÈJ€¬ C.¢( 8Iö‰@>¸¼žPXÆðÃù<,ãò±´àsãîë’Çá m6ÖMs^޶•e7MáoîtZ‘ˆÖGÄÏ·¾Óòؾ>"®n >t ¢A(qé:ù&¶ÂFVâ2öåL(]š+ÄâYÉ,N§l+ÙÓ³E‰ƒWg­kùH<·4[ð‹ŸL¿X¸cý=w§>t·ñ¹»“Ûg:õv£‚cÍØR^ø¬Éç³U3déZwGQÈ•ÍL¡\©·pÌ•ð˜­Jµ·=Á IèæIš! ”€ކ#1QR\nÚË2àF¡c¼îµÕEÇÚ2ëq†R2ŒkJ4 „Nª‰p8Õ["¨QUd(§N» dõÑGÄÚÛÞnyrð†DÄŽ@ãÒiPéd,=ñD¥jT‹E}äþÜòÞôÁïf÷ýk|u$7½?õÔ·ª6=úß•J,>þpaí©ÄÈžÜÈ“+CŸÒßDÜÏ}¡–òD&)j¶ÝUD«V¯•[íZˆ8ˆDðe-†ã› ¬OP‚œä§ÎÍò~5НTd-Ïd‹/‡jt7§BQÝ)]™¡ íÁ0>²b•ËIákD ¶jF"*eSÙX¸ˆu*ù³Êzµ°iÎo46ëóíιf«Q.o¶Zç76 ˜:æ®äM>}DôqÓ#₊¨íXCf;.JåJvø?2~±Z®&ÇîOíˌߛ9þãèÄÿfc‡¿WˆÄÓÕzâØ£É’'*-ÉÔ§ÿˆØ#~¡à—õc?ŠûÜ»¯:Õª7Ûxšz«Ó&/z†åQ¦6‘ɃN7ãõI¬èÅ’8 ¢ßÌ”`x†e.Úc³;I2•Ç誹lT(Ò4-•J¥ã©\2›Œ&Ì™«1=WÒ™\<ªü‰ ?£©º_ŒpLVõ£Á0çÎÇõZ.Uüi\D–ã¡PP–ˆŠ”>"®DèyË'?cyÕ«-¯~åswYÒå­r-iùË;-/{¹å÷~ßòø€ŸdÑ,Ï×-_úŠå–ß±üÚ¯[>ðaK0¾Uÿ-oµ|çû–?½Ãò’—XÞüGV±ì=`yí-–—½ÌòO_¶4ÏmU{–æÿù=ˇ?jyëÛ,o|“eÑf~ùkæÕ^ù*Ëë^oùèßÞˆ¸TE<#»˜5¤¥jÁ«½¦ûàj5¡Õ„¹<»P–(C\¨Å¥jœoÖÕ0WW×Êi½Ê/TBŽÏVßD¼yóMwÖn½³óg¨Ý¶{6D«]©7êíâA5"J Bô«,¯xX‘òrb@s1¼Ãé HŸ™¯±¶f[]µ¢piie~~Ájµwç\°4M;ðY±Ù—­n»‹u¹]+V?Ë—É/xWWÑ€³®É”StXÛªä°ÊN›äñÒ6›ÇᨗJ DL ECê™N»Õè#âºBœú¯?fÉV-©’å/Þoyÿ·Êßu»å®°”Û&îxïEDÀUïü%ž³–o~ÛtíÆÙ-ý,.ŸÙ䳟7ÏÑ—C–W¼Ò26µuÙgiþÆ?°$ ÝüÉA“!­§oѨ—’áâ †ÑÍÇ®µ £Y5{%jÝNK5s£¿ ëæ(gÙ첨ë†Ù_P­”+Ï£»²Öéív¹V7š-'°>ƒYFxÅE3>NB!ÇË©\–Ô°b¾I¥K…b"®/..ÎÍÍ----//¯¬¬0@¶¼¼ê^sžžš]™¦OŠ.ïz¥šÅ#‚“$XʯdÕ`R‘aÅH¸˜N§¢Ñl2ñô™r>·Ñj¶šu£Zn·›ªè#â:A„6}?”Ø*g$ók4c‘4ó¤§(æW·i±½~}ÓòÒ—Z<–ÿ¾­òÙ%Ë‹^dÉ[_?ñiË·ÿ}K™>0´UÍõŒæÿEËWî1O®°y¥cÞ˜ºñUD«¹m‘üKû"z)—õjS?9P˜zLùaÖ=jdŽïÉLíÉ ß[ô-Ç'L>pW)Èžx">µ/ç]ꆤ`áüÿÌ]| endstream endobj 13 0 obj << /Type /XObject /Subtype /Image /Width 179 /Height 94 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 768 /Filter /FlateDecode >> stream xÚíÝËŠÚP€ñW©—Åd¥Tp3Ù)êBÜô AŸ¡PÁ–_c|Å…ˆnlEð²Ôwð²fþ4TÄ&6MŽñûÈb¦’sìÏä„™dÞß)àýõýéËׯÙvü+ù²ÓÂë ` ƒ€AÀ `0 Àƒ€AÀ `0 ƒ€AÀ0€ `0t-ß^^OU|y0¤·æ)Œ7Ó0¤ñx,6ä¸!Ç Q!Ÿ—0€AÀ `0 ƒ€AÀ Ç„ñ™‚0 ÃM†aÖ×ȪCM,>=>bT«Õý~ü´T*ÒÙ£V«Ù˜Ïç\•<Úc:v»]ë´"laôû}Ó43™ W%°Æ°Åbq8^¸*‘*•Êz½>\•ð½¾W õa°ø0€ÁU 0X|À0€Á GWŒ޼ìIÓbwr‹bÌùE¦{°[ ÈD£wqS³ŒóÙá¦æ[OáÂÞƒ CÒu]ñÇ Ä~?ˆ áü ‚ÛMÁÍÞƒ ÃzÓi ?8EÆöìâÁ)ÚmœâfïA…AW  ƒÔÁÆvÜøíôÏ_XÀ‹@À ÷0ØØl·jÆq endstream endobj 14 0 obj << /Type /XObject /Subtype /Image /Width 136 /Height 182 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 13728 /Filter /FlateDecode >> stream xÚí $Wy ›px0ÆØÞ#l„70ÖkAlÄ‚ÍÚF`X|` l {q€¹wI# f¦çêžž¾»«ºë¾ïû¾ïû®Ê¬»2³ŽîžÑÁþ/³¦¦¦{§KšQdé)õ*+«!ÞWÿõÞÿþ÷“Ÿ°/ôò;-ОåZ9{#j4ê“$Ñï¡QÔ€i$ÙgAPк]¢R©µ[¦ßjw;]¢P(õzDµZÅëõ\&ßņÐêõ&Ž7 Óë‘ðŽã,‘Y¸Pä`0êSC†Ó&\’ÉôÚÚºÇãu»=‡FÛiw øB™L®R©L&“ÍfÓêtv‡c}}£Ùlw:=>_ ‘Jm6;üµZm2Y"Çå²7ê /å—áp0M¸´ÛíT*•H$Äb‰ÕjiŠD"‡C X,½^/UjµÃfW(Íf¾"‰årY0„¿ú­V+KäX\4ÙëSƒ‰¤”‰Bct 5 BEö«ÕÚä&Eu|·†Õ b@?ÖÇê ¼Þ úæOaÞétX"Çâ2’À…${0Ôz§ Í„tÀL˜ÍÎ`2™½^(v8\‰D2“É)ÙXßðz¼©TºÙhoolù|~«ÅªT©].ŸÙlâóù,‘ãë1ø#»?áB]“xËÜGñxÜn·ƒ±X^^†q–Ëå;;; ¸B¡P.—ÛÝÝ•H$ét¶\©îp¹^Ÿws}Ãnµ…ƒ!“Å Ÿ²Dn‘‹ú:$/Ó…14´ìôÅ~EQ —%£Ùà&ŠŽ¤ú™F£}‡¤ï I±DŽ//TŸº./ƒÁn¨3í1hºÝè1‡Ã®Ët:\*õ{¼«Y§ÓûýA£Áävzt^o+$f³ M @|À—:‘L±DfàBR½A4ìh¹þÑ/Z•!Ìi³Ëe²åÅKr…T“H$òz½à*/--¹\.¥R) A³]¾¼ †@R²Ù<‚œ7–È,\È."2@ÒhÐmoooÂ2¼fRDtWßasBŒ j i2ZG1ÞAA#A²z=ª\ªõz}¼Ö¨”kδ;]–È öôØh´Ï4@ƒ Œö Ñ\FLŒY«áü]A0)€¡6›­àA§TªØl¿×ïñø6×Öù<>xk±8 î67¢Ó¨µ,‘[æ¢H† zl0C¡_@do¸4áø·6·Ö7·`¨{] Ô׉G‘Á°úÆÆÆêêªÓé\[Z6è´ ©\"‘ñxüËKË*•ôÛÖÖKä–õØu. /4—½k&e5Pkƒ²à=ÐNd§Óí¶»ÍV tÚ½v»Ýlµ@kµÛ]¦ÁÍVþi¡šíz½Q¯·Í&€«aìüØ1ìË ßcâÊ~Ÿ¤-ËuC5¤È>hªn—€k±X6[l ™2èFÂ1›Õð‡Ãá(4©TŽY,–°Ùì‡BNÐi6«C¯7ùüA«Ý_d‰“KcЧé— Å•$rœ)bHöÝ6ÙjtÛ-Âï K¥2*×××LFóüü)>z –—W¤RÉææ–ËåtZ\R±deeueeÅh0>úЃ»»;b±D(³DŽã‘£!Š÷!8> ÌzÐWD§M´ÀѬwêX³V©WÊX­Z¯Vê¥RôøcåRVÃ+U D©TÆÀ‹E“n·ZÅ*•*Ü,*N»×ç”ËU–Èqýd¢×-êéD!›*3åb¶ZÌÕJùZ¹ˆA+jt«–еJ/—ðB¾’Jæ²™bµŒç Õlª”NäÑÜà±R¡‰$2¹R¹„•+õ|¡Â™K»Õ°†× År&[J§ ™L)—-%SÙD:c²8Ü.ïâÂj"›‹ÔFM(ýø±SR‰lee],–§Ó907»ÞöÆŽB¡ÌçK›M&Sõ½Ò(JäR5KäøñKا Z¹²p°@_®^a^ЭT*v«M"càv¹Œz£ÙhR©”.·K"ú¼Þn·ëtº4ZZ£‚ &OyÝ^‡Ý‰D• •X$‚/°DŽ¿ô Ü0@À°¸J¿ÆTöö‡G^ƒÁX0“6­V ipŒ'+5Œk ùÔÇÁ±zlyAK/ÈGÞÛÛÛ§ÿÝßÑ œçþ°T*%â µJBáõùG:‰Ä ‘pXF¯[­6…\D2™œÓá´˜¬v›Óíòh5zÎö»^93&f¢+½@F8̱X, írwôzƒÓéÞÞÞÖê´»»\½^/à 8Û¹\^1g{ƒި”É—.-J%bƒÁ Ñh767ÔjÖ¾ÌÀ@@d9$½Ì4ô–ì3A%\AZ­ôAAŸÌä½@+•*µžÏàÕh´‰N'äRixKþMh,‘ä…$zv¯ÓêuÛD·CöºÐК?Ñ¥ Õju‹ÅšL¦@qYÌV³Ù"ä ÀôsÅp ¬”© •\ªÉå`³..,‹V³×lt[Ín³ÙafiX"3Ì'“ðÇ›œ´^‡bô}ÞÐêʪB"½xþ‚L"u: /jÕƒÎh1Ù ™ßÔé "¡Ä`ЙL¦x<‰cÍ:ÞÆ± Ëe6.  ¦&SaíÈ™„iÔ[Lž 8tZ-w:Œv‚Öl!M* C¹‚Ô@cîÃßd‰Ì$/=°,péÒhºD„áÒnöp¬á÷âE+:ÚÐA¢/µ[]¤¸Z ¯zˆi=^ª4eÔº]’%200dL ˜‚á‚ú´ ÆÔJµ^kШ´[[`Müþ@£Þø<Áæú–@ ªVq°) ÐàS½Þ¸»»#•JÍfÓ¥K‹àŒY­v–È,\Ð"ð8[ ‰Þ86AH§³;;»à$ô:ø—α4Ôq¤¯”J•Éd€ø%Ó6›C.WƒaƒQ‰„ÀÜÈ2Ç Y"3pôI&éZjå8lg"wF;B•E·N®hi¬[)ƒÃÜefÐW• Æ8Ò̢ª_¯ƒ»Üf‰ÌÆe*Uì†ôWd´Fï lmlk5:“ÁÌÙâJbÆÿY&“?8$b´:cB/ Ÿ+²˜-.—þB>_t¹\,‘Ù¸Íë£sö 6*äŠÍM àt¸¸Ü™Tîr¹ÁÑ‚SR(”P¤o0íìpý~_4U«r¹,‰^K>'X"³Ù— ŽIZ2Ã…±8àPu;àHŒÓ Œ ãW#cbÕ%ëX´óbf,éî€Î°Dn‘ËtþØ`@MR‘§1\ ¥JÈ’Šå&£I¯Ó›f­ZD„B¡Íbõ¸<\.×ãö*j6N‡F£ǬVÅw86Œ‰x’%2 —›é1Fpà ¾–Çã[[]—H$n·‹ÇãêtªÝÅ…‹b‘@¯×p¹­F-“ˆúÑÝ.‡Z£bR/67·Äb1àCÃy¾¸04í<ÓÁc—Ñ]Ðr…<;Þ§µ.x€y žF',5ÑütÈ™‰ A¯vqô§6Â@«V1«ÕI*•Ñju¡@ÈjFê+ìYMf¥LîuºÍ&3¸N» B½^ÏlÄXZZ2 DùÃ,‘YåepHX&×H,ÎåpÁýÍç K——uzßÖlB{ŽìûùóÀm#ȾÛí„""‘È`0ƒ!¨A)–È \ú}b²/ì·þ8® ©ÆÏ ýë/¤Ç˜˜”êP`‰^ã›ðb‰Ìì'OË~9Þü°Ñ`ñyƒep̱Pêp8›V8¶˜­ÑP$%ŒiÕz›Íîtz ~ÑiµáP$ˆ æ`0 °Df’rz׳SŒ^ñ߇~1_Z]ZY_[K%ãµúÒâ"‡³‹Æý^ßüü¥\ ®„™2©lÊêÊš\*[\XÔj4R±D(I¥r5›Ï|.û{ýÁ—ñBÿ8]‰ Ž5\5QXH}¡}СÉq¤Cô(¢×‡+ÝÏ|B+—Ø|Ëíþ´6¤0 @·†¹Ýž`(œJfvHJЂ`ßáï˨Ó@^@LÜ.O:•×hôjµ&Šø}A›Íæv»q¼á Kdy»ƒÅï#.Œ•k"‘Jeb±$•Ê^8Q)W-/-ÕªØÃ?zH§EÙ|v»cqñ’P „Ç._^–Ëe …|e:ŠÝÝD" )Kd6û2=3™"›ÜaBKºü 3†6ôµÐ²%Ê©è¡Ý1=èO–˜õ܇>5­V·Ñ`óaf×c“‰—IQ¦Á8ƒ‹ më“b|0AH%W‹EÒÎŽ^ktÚݧÛf±G"±L&ßjv€ g› Ëa‰Ì¤ÇÈCõ”¦gûÓé¬PÄçóv—.-šMF£ÞHÏ$÷$bÑ™'Pö¸ÍbÝÚØ’JÄ­î왳J¥Òl¶6›mˆ+WW×ôzÝÆæ:Kd=vã<ÿ„ 39ÖíX ¯ãÍ&­£ ¡S ²^*å*ŽÕ+U ž©ÖðR¹Z­b8^G}ÍV¡X*”Ê¥råžÖØm†øåhÅž —­-N,–ˆÇÒÑH €Nãó…‰x*ŠyÜ~³Áæuù¢áx ªã­R±ìñúuz]³Ù±;Ý>o(‰³Dn ³¹r¿’— ¯×¿³ÃMÅãñÁ®Vk'‚¦:v^Àç›Læ>²ÍÙæíîB\™LdôZƒhgW«Ñd=|â„Nc0L,‘[æ2ÞgÁp9TIéPá> ÃÁ§ª×Œ«Tª ©Ð~½rf‰DZFYÊX¹\K&“`îK¥J¹\g¬R©19~,‘[ç2-/“Hÿè’e¯GE#ñh4î°»°ZeÈ´ PYÑh,•H‡Û!'è1³Ñêõúâñ$Ê–iõмY8Z.¯*Kdf=ÆP˜FÃÈ‹Ïäoí¨•Ên§3Îì±G:ƒT,­5ú8iF½A«TΟ9ki@d l1Ì … ´˜^oä¾nîEloxùcïü½O|vùN±ûez~쨰0±d.WH¥2ài²B«–Í®D$ C¹\„"‰‚ⵆê•+™t°ƒk¡PÎdó Ð^\.“öùò!/Ó\¦+ÂMÛ—t*«Ñhýþ Ï,**•F&•e3¹d<C{ó‘`,K[ͶH8 „Q4Eâh€.««o.Ð>þ¹•;ÂOžŽ+&Ã@ß8›Í. ÄK —4*åêêòöG­T¯¯¯ml¬´:Z»º¶.–ˆLFóéÓóåRéì¹yˆcz]2‹s69·—ÇÞõî;ÎO>d\h£OB: ¤ X(ò…P(Gìv'ØýH8Z«\.Ç¢ñt* …ÁÄg³ùp$ „P†¨Áéóo.ëw¿òŽÑcƒëó–‡Tp)ËB¡ØétCxhµ8b±¤Çã“ËÅB¹\¬8lŽ`0”L¦„Õjk·;ôte"#¨†¤·hw f}ÿ§é1øýC ¹±±®V« x4ètFƒasssyyÙl0šŒ¦ùùyµJ%·¶¶ Ƴ2®RÎl @ëû,—çd÷qaÐÀïßáp•JeŸÏŸH$ ¹ô­V;ÈH( –L¦¢‘X>_ðx¼à¡y ߯>ó«‡Ëå9r94ÛÏ ab&aÉë£×YZ×vŠÑõÇè¼eøÔEzæ~2w¨=—a솽îüûçñ[w—‰;:u ¦<™Ê€}@ÐK6X™è0§Ã „ƒþp<–„О øƒâ”@Üýôݦ¤E5¸K^KÆþqÙýŸ{ sAè%ã£ó–ãJãFóÉÇ×jõ^¯¸loí,_^ñÅD.–^<·ÀÛ€fãls7×¶Í—€Ëo¼! óvù«Ë«6‹åIøKÇt~ ‹èÿ¾,Ú:h7÷ÛâΊð­¯a†‹ˆ£|»¦õ"~xØpÿÀÍÌÒ©§¯tZÃr¾ªà3%Ïh9MýlÒñ…¿ |ï+п?Â*© 2¤Ž~kf.áê•›`¿òÁ“øóÏE£º©¼u˜AKt½±r…QYv‡£Ùê6šír¥R,•ŠÅ"8` ÐªÕZ¹\Ó× Àåç~òs¯òõÐ~ý©_‡£¡xß›dï¾:0¤5pÞòjáÛ~¹nRázù„ •‰‹ÞŽŒüÔGÕ÷®—ýåÃcƒRNü;ÿ ½½ëeŽÏÿ¥ü÷:ð÷Å,`z~ååYưØyòOž¨?ß\Ô£!5ÍåÐÔåôâ¾\*‡€Q&“÷ D,–øÀ ðúõ-5Á`íER«Ë…2x´èYì‹ü=o„ÿué;ïbÞª>ðVxË 2 xðû_eûïø7å~ðë7ðàÿý'L#y!¸ºùÁÇñlóê hnm>yÌe:ßò¨¼¡Ý]›Írñâp· xáó€uiiÑl4œ?#‘Hl6ëææÆêò²Ñ çò·ƒýð†k›ä?ÂÔÝñl{®Çû†¿¸÷é'¯NÞò~óßÁÿí}ïdÜõÀߌï¿ñßÂ}$7ãâúÊßNÞZ>õ¡¦ÃJ T(®Žßù3à‚МÄs­«ŒB{AíþOk`eR©t6›M$T–€NµZD"éTºV©¥R©f³ Ȫ5<ÎFˆ%q¼‘ËŠÅR—.u}H^$÷¼Žy«|ÿoMËË͹„<žúô \®=J([þîOw^ÿo¼|ÿ«×¹Üø­ç ƒæY>}ý±ÉuºA%›Ï%â)‹Õ^(*•*„-8Ž—Šåp(’Íä)”y‰\pÀ+"™L¾‘>‰& ˆëöå®—µ\æŠt‡±/¸Aíè€OsÁ4âäüC7åð™§Ÿ–üî¯!F¿ý+à-L¸úÖ Áå_ýt6»ÏLŽ]——>´ë™üLÒ84_è°Úù»|…J¥RªtZ=8Zr™L«Ñ¬,/I%btª½yÙh4/-] …F£¡/DŸñ«‘?–Œ0þ˜ø¿þDzxtòÇvWa<Ÿ‹þcïë*E4,šCA ýðŸ…LÓné…Ç'\}ëyäò‘3õ÷<Œ½P\¦ìË`€~íDD5Ç®Ÿù2.6?û|®&à‰D ÙB6ÿdÉD2ž*äòAˆ™r¸2G¯/ EÚ×ß% ºsãý£#/Ƚ§¿´Õ~¹ Ðþáqì;_PåË!Ú*^ÅlV^k„ÂQÃ[íxΠ @_´: àv¸¬«ß´Ù6«Íh0úýx€ §qÆK€ËäÄ»Bbò§§êŒ'öÂp™Ø—Á¤^ßM¬L˜Je¶··•JÅæúÆææ¦X PÈe ¦À6›,ƒ)è..,\¾tDÆbµ9±Hl·;˜§Ã öK€Koøô)ù®Õ× 2Du꩘ Š÷'å¦v¿^o†ÃQ)_jµXÒ蕉Ǔè¸J ‚úf£¡e>_ôùp?K@?Ž€G š °‚çv­¿¼áfãÒ žzú™ŸôFO3wÖƒÈîOs9”(> ¥(ãM¬Öè´‰f³Uëu¬Õm“€£ÝDÕÉÚN£Þ̦òè]k•«7Ñôf³Ój´Á¹¾}¸<ú®÷ÌÆåk»ÁÁÓ“täöáf°rÚ 5sËÑÍ•ÐS¯õõÕËK‹ZjsmM)W,\XàíìÊ%’Ó§NJÄÂ…óç„|!w{{}mY§Ó(U Áîn±PV*ÕgNž‹…·ÓúþêÌvÿ½'°¿]j–:O27¿'îýÌæ“nz%zTÄt¹œù|®T.û]>ðµRÉT¡‡;±X®N»3 ‡BÁX"f·Z ¥²Çá)ËQG§ÖÜ6ù0_9îH7¦^Ùÿ8æÔå­øc{£þØî÷oR‡dÑ€jªT±r@d¢÷ FŒ½ƒaÕ‡O{¨l)Õ¥÷ÈÐN2Y,WºâŶ)¯õu\Ia€8Änº ŒNSÇ÷ž÷yËk\À=¦Ž»ŸÐG ‹…’F£µZ-›Ëë[ë[8޶[ÊÄÒË‹‹Ë—.m¬lìr8BŸ»ÅY¿´*à ÊÅØÎÆöίÛ!=ÏúÒ›iy\ût˜ó’9ÉÓ«–ðƒO'“åR±R©tÚÝP0”ÍæjX Ãð<:.ËåKµ V*ÓéT.“obÍJ¹œËÚÍ^µ\-Š,‘[·/×ça7ÏŸÌó=Ò¨7lq×µZÍf9öôîÎ6—³µ¾º²µ¹¶½¾.‰À+IÄëË‘¨VƸœ ©P"I×W×Ä|Kd–ù±y4sl:a‰è™T<áB6—N¦R‰”Ãa…k6Íç ±p4IÇc‰J©’Œ¡Œ ß Ç¡|Ëaw¸\®½ŸÌ½ˆ­{õåöÒï}…»|Gq ¯Åû7¬ “¦¼¥Ü·Xlb¾H£T¯/­m¬­ïîìù‚.ü—ësy.œ=…×WVw¸\¹L¾µ¹­TÈ}wW§ÖËD’—ˤ]´}ùNár°?dü±ÃÉ04f¿X·K¢´ðL:‘LDã¾Gs`Q ¥h4FúÝç‹ÅX4‚;í3åóf«9Š„B¡Û„ ´¸+w—ÁÑøe¢Ê&…aÛí.S“„ð ¼ ×f½UÇ :a©ÝìÀ[hÐAm* ®·{éÝw—é’J“̱é°Lú%½/©K¾&º¨~/¢Àt&×N«‹ª=Þ#èùÿÛ‡KçÊ+ï.ßRß-ÊL<2„ˆt¸öºã> “(–l÷ 1÷ÇÑK3·h·7—q\‰äå—£h&Õ­'‚3uI¢c.ûLqÅÉI1“r=ÂèÄÞ#N@c¹G^úSzlx(×b:¥§ß¢CÃzIT¯ø^Ÿ$šŠéwpŸˆAöD—úŸW>9ÉSb¹KZ‘èøªÁÍS•„±6Ô£AܪÇ3ɺNÙ*–Z±8®×,†ºZÞŽ1Ÿ»n65ó¥†NÞJDþ ûï@äÞƒ÷~ºö¡eüçwç..ß‘\é±£Sd #Xµˆñ/ô’h·ËœGúlõûõÅo–Œœ†øríÒ?y?Æý½^±´{ºeºTá<Þàü¸jXÿxùàòHð3TÍÃr™I^¨C aÓŒ:Ý^}û;x"Bt‰êÎC%Ñ"¾û.øqÿDK¾\ÜøA+_¬ˆOõÉ~…w¶*]©ÊNu4›x2ýØï—Ç#Ÿi%bÕ6fîó_š{ý¯Ï½ú—æþä¾¹Ti 4Z9A¦ŒD%K…•M¿¦u UŠ¥Ð°? rÁ~ÚÔÅÊDHÓËØ>I|¸¼íÉßúcê Ÿ?þÐ\©1G^™ûÚ7ÐxžìÝoœsæº{sŸü[ÔÿÔ?ÌÕ‰¹Hfî—enG4Ïgùú›ß2WiÑý27zæ¥ /7Ý_yÝ%#éijD‚‰§wåÑÖ¿OuQÉÄ~nö™£âàCªÝ'Ññ1à3÷¦í>pÉVçà•©Œ§ÿäÜ+_9ç ö‡'Æ÷庹—½l®AŽßþå'æ¾ñmÔyö¯?rr|ë¢Ç€Ýo_†Ãaÿ¨}™.­À˜žÄ×~PÙz(%¾ÜÔ^ìb%œ!+Y*¯}7/gÏ}«"X¬.Ï5½þh]wÞÚ·l 8›ƒíí¸€z­2i¯ùå9±r<°KëãA39Ñ€OÆðï?;÷¥¯¢Î-~½·¸D³/y §ò”ŽÚ—ëåȈaY¶Ô+s®»%€ <Ž‹Ç·jô%þÉ꣟êT’ué°A ¯n‚-oÏ¥Ëh`ms¨Ý —[üú4—ÿvÏÜ…Ëw*—+C†ËôÊþ¤Zï4—5¬ÉÏu jiGya@¶ÚQ7uÔ mÍæ4Œ žYLÿã©ÔWÏø?½¸wþâþ⎅…ýEƾ|ø£súÈXá½¹u.RG·Èå¿>Í3tûcÃþÑ4þiW™Ÿç2èQ9¢ÉffŸ1 <û$:Êœ°Rÿ^õÌ«ŽîWŠq¨¾ú5dÖaäÁ:ÿͧŽÇåV¾>ÍEo›û/ošûÅWÏ}à^ þØU”÷ Þo4ZŒ:šö·ñxr<ç DèÃ,Éb¸Üõþ_ýÄǯ~ü¯® ÆÆûÏ…Ë‘ÒÖ¨•Ë•X,vúô™DZ,–}~¿Éh2êõèøW™Ìb4r¶8:v}}C«ÕK$’W<ù à"³È§Íjçñž{½òNâB¯ï_³/ÔM ÊŒíp¼n¤_‰D"™ŒF›Õ‹EZ}"–Ká@ ™LªuZ·ÍÇ.ßI}ç¡ÔC§þ~øû'Ò³\ŽË…–ò¦Â2îã¤å\®Àè1Ç«ÕÑ Î3ôVÙÎMíËí¥}ð ·74Ÿ ÁË!=6Q_¨Ñ©}årU!Wìls…BQ4óûýÎ_0è &½‰Ãá*ÕJðà¾B)ßÚÚ–Ëå~ô¾'ï{Oë=÷Ôîë½½{ÿ ûÞÛ‡‹­øžÛ~ý/Ìü“Ì?Ù#6í3h@.J¥ŠÇí ƒ:­Ö`0X­V©Db6™ã±¸Z¥ö¸<Ý.G¬»R©ýàÀIÓjµðÖåríìì8ŽÛ‡Ë—9«3êðàfô ó‚®‹1q%-*{Ã……¾3Ž_*(—•.öŽNwíuQM’*–ØAEùÐ$L¬Vj”0èã“|ÑšÙ¯ÖðAÝ&P.X¿ò\~íÓø‚®‹Ñ\†ôy“CæP¤ëûøÐ©H^ŠåÊúʦA«óz|>ßauXVµ\®Vi|N`‡¯–«@|L“Óæp€ÆÝ/Z)WôÃí÷úU Õ‹½¦ÿ P_ÏER~¶\n˜·¼éŒp&“ãñø:.—É;œnz].'ŸÏwÚj¥F­V›ô†í­-ÆmC¤o!¥'£_/lɉ<ý3Ž+ÍöOe\×Öî f‹k ´shE³ g»Ýè¦\*w:è°Jt­?¸ š`3`ŸËzåd+ߤ€ÑÖhuf‹U ,ÞnuE"‰Édòyý½Ñb±U*µX<‰DÊØz‘X ÇÊÎήÝîôB,‘[䢽q½òб øÍ£ýû¡ÏëU*Õ‰D$euuâz³Ù¼¶¼j1[AŽ|>?ã€mmm3›-‘H"ším(1Ç÷Óc/¤?v=~.Œc|Ã,þÀ8»¯ZÅ0¬‚P\…B¤:8^o·»Lqør¹w üd*Åõz}jO§÷ÛÝ——Ÿ™?¶¿7¶/Ó#ŽçöQ~2ʇa_[] ¶³ÃS)ÕV«T–Íf‰Ä1’ƒÁ$“ÉÁ7p½ÙïD"1£ÑœË•àÓ••5·ÓÍr™m] E+SPưĠۡ‰g›ÛîôV.¯*dŠ ¹Táu{y<žÅbÑÑ/½^¿¶¶\N<#X¿?¯••¡PÈúcÇŒ÷éy˜>5º…IªD>¸ô:D”Ìvï&ÞnàLöêX¯5à‡µ:u¼‰cÖ¬Uñj¯aZ­NŸÔS«auFÖëMÖâß²ÝG\ö÷Æöeoï`Ñ=\ШÞNwÐm“íF¯R¨9,(N1è ›Ód°ZLv£Þ,Ë]ŸÇ‡øÑl0 ùBµÂM…ÍÕØsÙ¼Éh–ËàÅiÔZ–È z¬×í”Jå\¾L¡b‰T"Å"h£K8€ØìÈÒÒ2‡¾–laaA ­¯mˆÅB‘H°ºº,òŸ8ýí¤‰–—/ƒ¢S(à­>}šÏã­­®ªT Ö;>´¾šlotp°åÊ•«W®^EÿÒíÊÁ•ƒƒƒÑÞÞhÕñ')t<ïšLÛƒûû{ðµ=ÔP•™N¯×¢sH[­Öp>vo0ÁƒÃÑ>k÷g«?Æõ×VÄFhBy´·¿‡^8Žë´ÚD<át8 H øý‰D ×{=ž`  A À„P¥R*!Ì;®Ëãv8 Êò¹BÐb¹W^˜}¯“<1Æîƒ‡LÇ/È H¥SœõM¥R.‹µZ (+±@4þ´Õj¡çÃLÛÛ[†ST_"y¼“ɾ2ë«kp•HĬ?v¬xR·gz×ÄïÈ%#À%Cç‡VÐÙ‡X§Ýk6ééýv§Ñhƒëž8Zô¤գϭ×…r/›Mp«éý1$Õjµ¡ÇZü¸ h.Œ¤0\Æ{‹èý_±XÂh0»n‰DÄCÁ¨J¥ ÇR±4àÇÀÞn^¯ŸÇ¸Ý^èx"ÁÍæÁ• %,—™åeRþ}¼SmÖ£ˆ.Õiu!®/K&•?¿~/o—Ž–^o.Î/ȤòÅÅ¥v« ÁæåËËV«M.— …b¥R%“È3éÜü™sN%23—I¤?Þ»×4$È =Ö¬VñX,Ù¨·‹…joáªH ­^oÕà1fH¡ShÚ¿Þ@çâSÆ eÏI<þ|ò„ #2cëOoœ$!Àì’°»\µZk·;Ý.聾%ƒÞh³ØA¹I%r­V¯ÓàS¿?}§Óc6[=¯Ùl;‹Ýç °ç$ÎÆe:f²C|²ãì pY_ßÜÞÚ´Y-+Ë««+k6«Íe·_8wnccñ%_ ÓiŸxâ$øg2™LŒJ¥’Ë僑Ãá&–ÈlòrÓC&Tè"ÐKÍRJMT6¡×ýV%…ª+àUpÏ ÍjUÇZ bÖÀjM¤åj5X"·Î…Y¬D\~JÞøx2½jL/© ¥dĨ5.gã­F½SÇ‘•Á£PÐ[¼ \ ±\fàrã:òèІñÉj2³[œ9, é  ûôy»]teTj¢Ð¦ÙèÐ罎TBÎ@£Å™A^×êôÒmèz›@™X`d‡)¤@ê2}æd+æŠ$wÝn°þØLòzl’o‰2úè×ôò%³.3}”Òµ…3Úg»òÀMFãM7¦>Kd.£k\®¡¡'.‡û£ܤ­?Ùï3NIU¥œV8Œ{Ý­T²&¼Œ§Ò¸p«™HLê¦C_NÄJÂ…J"V±˜JBnÙfÄ|þŠ×Í™-æÆd~„eoˆ&ñÙnV„çÚn+ER`^ÒlíïTU±ÜØ](G‚ØÎ¹Ò¹ïÖEçj['ŠÜÿ‡‰.¼ª®C‘Ûýq³’¯ñΖ7d‰Ì&/‡6‹Ô .t뷛孓¸ÝØH%zD·ºy Û~°Á;ƒG|¥íÓEívGv±[ˆÕ9WV~ˆ9-Å•ÍeÊ©*ñÏ4[-\t±¸Ár™ÉOžª7ÎìÔÒIã#h ßÀæçܽj¢eŠìåT«Ò©&{õl7c¥ºm¢QEç¿T=,Fâi"ç趪½:Ö­dI’èÕòÝj†%òå…i‡¶]0ÕQ²þ`ˆþ3U2nzŠ`²²6y`™þ„}ѯÙìþ »õ¯5¬†kµz½Vo2Ôr5øW0ÎáP$‘H|t2ʤ.´ƒ/ŸÍ;Îd2…öŽ F&ƒ±X,1Ç“±Dfà2™O¾iýäZ[[݉ej¥F*£i™f›³ÍÁ9{~Þ¤3ZÍ–“?n1[¸ÎââŸÏ ‚Th4À?Fø;&“‰%2›¼L'ŠÞ>Ù#zÉÄ292G\Ñ*®k2ªÕZ©T²Zm]´ãpT¯7!¤X¯×Y"·Îe’ƒ.§œ±C\Ö FxþÎú®ÛéN%3Á@(›É§Ó™|¾\0 GLjû¼è0åJÍb¶Æbqf>'KÔjX³Ùb‰_^@R‡“Ƨ܀X,±±¾i6šÍÓ™ÓçÒÉÌ…s :£Ve‡0_­ÖØlv—ËT–ÑdÐë.^\hµ‘âñx‰ÌKd6.Gç*§·ŒU*5oг÷õR©’Igá ýr¹Ể‹e¸}Ð]`ôó…R—ž– …Âà¤ÓY–È-rѨ•×â¤Ç†GÏG¦AçŒË.§;“FÇT B¿Ï_,VÊ¥Z4óz}Á`ÈawWʵ\¶J¦ÊÅ2l6/“É#áˆËér»ÜéTŽ%ryÐ\€©ŸpC£†L+JO&•´Z=‹Å"—ÊÎÍŸ3hôàemnn‚¦rØ ¹reyU&•9íætQ£Ñ¤R(AõÍŸ>c2Y"ÇÕc‡âýCûŘ ’1ñíf·\)§i%‰GËå ˜ûB¡L4ÍòÕ*–Éä@›¥RPqÈHgéL<c‰Ìæ'£¼×Ñþô>¾iµ%Ìó•F«ƒo1ÛôS¥Œ µd"S«5Š…j4œ,+‰D:‚‰iµÚn·”[«Ñ-Ç™9®œ¸d‡Z4ßÝÝÑk f£¥Ó#ôz£N£=3?"z•\é°8àÓÅÅ%½^Ççó776Úmtð8(:>·¾ºð‡Y"Çårå`8:²¾?}Æ(x¿_D¼2’  Ù2D%O Ée™€/‹ÆSét"‘LÄ’ùb:ડ¨'õù‚Éd2›dý±™äej½ò º€RÃ`2—KàƒUBÁP£Õ®Uê š*ÅŠ×í˦³XµY(”»]²Óí×k-¬ÖŒFbní{EÑcç-gä2]vlš }°ò|_ÀãË$R£Þ`4Ï= ªL*–IÄÒÅŹL¾º¼‹¢á —6V/£ãDÏœ …óóg4ZµV«c‰<y¹©Ñ‡x$O!Ÿ×A¢Çã˜<´p(£³ xL&S:®Ñh¦ÒÛHeÖƒëwÜýÆ+o„ö›Wÿ3Kdfy¹©‰™ÿ™°DmÀ$‰ñÑ¢½.Ó¨N‡¤-z ¸àªë¦ë±DfžO¾)¸ÂhCT‹ÅK…R1_bª¾D"1¸érºc‘8ØwðÙòùb2‘µZÑhTŸ—Ž7?õfYA!+ÈY"·ÌEMoF¢úc7Î]/nI÷–×ë_^X1iŒ^š4%¶µµ^±D$TËÕ*¥j{“ÃãîZ &›Åzáü“ѸšX.o½R©DÊ™Ë åQ Ùõ²$ÌG>Ÿ/Ëà›'Cíñx¡ád!WJÆéd¦X(AÈ™J¦£áp*‘Óòòòg^þÖ½·Bc‰Ü*­úP\9­»¦å…¢†ƒ¤’)¬ZϤsN§T™ßÌç ùl1ñ~µ^­`éTÜTتÝÕªTª®šµ/Ï•Ëá¼¾½io«Õ´:µB!=7Æj6 & ³Ù" ¸®X$±Z­à9KÅþînÃëõæü©SecâG <áxBC²~ò±¹ úÉCjÚ¦L+4xÛét’‰d,=!6›GÅH‹e4iFÏOÆb±\®‰€/ z(iÙéDëe 8´ ÕÇ9€2=3¡4=€æ!ÛÝZkÆ¥Û%À%0›,õZ3Š R© ÇA­u:D»Õ Âu¬YÇ[f‡%2—éxÿ?×\¶°¼¼j±XÁïòz¼>Ÿ{k[£Ö˜Lf ÃWW×8›œÝ]0.•JuscS"–tÚ=™T~îÌYgwcumþô–Èñ¹ì!7ùf3ÉãÙKj°Ë壕L$êu…N$ÃjX©T"I2ýál6W(”èÂ}H( ‘f$‹E¢Ñp$›Í†Ãì|òŒóɇlý´¼Pd¿V«F ’ŒÅB¡ A‘ñxåÉ F®5T…‰lÔÛ‰xTAŒK•ö˜-3ä%ò\üä›Vƒã²±±¶¶¶ äc=¦R*5µP äíì^¾tY*–ò¹»?tB*•ñ‚Ó§O©TÊ .òùBNPôzãææKd6?ù(fˆF<ÁbBKÇ“Éd@pŠÅ¢Ïç …Bn·[&–€Õ‰ÆcÁpÈlµ€â B©T:‘H€à¤RVÍÊåÐþ—½½½¦AŸ («ÕÆ!¸ÕD¡“vÑ6±>…Žç# ­—Q¨f9AÕ‡jÊ‘T— ÅR§Û# |9–È öåй¢Ì¹ ÉËpâ™\rÑ»ðYõg¾áÿútŸ¿Ô_ú‚þ ß ësÚÏ}ÅñÀ×ßx¬úã/›¿tÊpÒj³êu íÍ-‘@ÁæêÒR"–d‰Ì0Ÿ<ïO¢ÊhòBX,–OŸýBû‹}äžQH­õÈO#¨r©J–ȱäeWjx¨œÂD|ªUlksûÃåÃÈ%óU•\!“ÈÄ"É©S§” •Z®ÞÝå}®Š¨ýYè#ΞK¤’2™d~þ —ÃU)Û›çÎγDfÐcƒkçòLs¡SaQ¾e§K(dŠ¿&ÿFþ—žú¥_;ø5hw]½ëµû¯}Ý•»^wð:h¯zêáÓ×¼öêž÷=õ¾wöß ÿÝúÄ›^¯Ïiw±Df‹+§Ëd“~Ÿ.¥HAŸ|æà³ÿª}9Ô>|õ#ôn>pÏØyË™ìþ”?vèdd¸v»D4’Xn­~|ô í×<óšû÷þüc£ýùþ_@ç#ýüQóƒ÷‘†Îw¨ïîôxÿEÍ¿îüú·½ßüñ§0<ðM׿|Zü÷ß |÷Sü¿û׿|Óó­ãžÅÏéF¦î_µ/3qÙô~1&„¹a'2]Žòx¼4jí—ÇÛÞe‰Ì /ýŠdÔo ×÷"‘!Ú<]â’t;ÜÉxÒï÷‹%PY‰De)§³Ñh *•Lçr…J¹šJ$ÝN—X$Êf³Éd*•Jƒb‰{ÙápЦµÖ€~!C3£¹¾‹?àÁ°7ÍR±Ç:¯Õk¬Ùè´›½Þ&º¤X(.—JTÂDZ:h9‚ ØõÊY¸ì¹ i£?ƒr—Fè08Zj€ 豋Îˤ•Byò±“"¡ ÑhË$2ÐckkëfƒáÂùs=‚\ߨäp8;\ÎÖæ†B.;uê¸B¡%r\.ûû¢*õÛ :„™º^鬿ÝnK&ét&‘ˆÃ üg¯Û !%~r<ß üdø4 {> stream xÚVKã6 ¾çWxOk£kõð«—Ål» ´h‹P,º=(±’¸c[YYAšþú’¢œd&´ðA¤D}¢¨¤?,Ÿê¨Éš’—Ñr1.³:çQ•—ãM´l£?⟽ëö½NRY•ñÆØA¹ •"V6ÌN‡ý>Iyëtûm’V¼‰3šj7ï’´`,ÎþÚogÑý킨Ý:Ia&IëŠÅcKˆfCãÚ줃í^¤¶ÉŸË£|EÄd&dÉ1*pŒ”Y“3:F‚»ŒñOjpOÃh ï^hÛÎufT=éO šŽ8ÛNxÈâãrÁ:XÄó&«š2*ò:+J­‡Å×E&üjü«¯ˆºš'~Êè{³ø ¾®Ì³œóyÓQ+‹+œê%NÊË&«Y¥WŽ}¸áŒçeɺʤ 1úœÔ"6xÂ\B\¦cÂ+x5ÝÎ38q7̬IXì`¬™èAu=Yù¸âÜ ×gT©è]iƲÂ9­÷¤9«Ö8ñDªçwî}’–E/wÚ“)…o¤ ”*éW„KèAí=²Š§µG¼®;)“!‹Ã÷²Zµj…ùƒSn§ýŠXgü£G¶OdµËÏÈ.€Y½6Û±ûGÏg ú^\bšÂX”W$Ô(8'ï.r¢ Y?¶íy½¢õš¸J†ÆpKÚutPŸ.VôN¨Òø6œ?tSÀ$·Nn×Û7÷nòØcþ01Ó$\œŸÃÙóq¨(¼ G ‹Šü$eÒÊ®qÏ2L4Ö, ,¼ Øt›óѧ€ç϶£…"³vý¼f;çôHŠï]†îç¥Äµ÷XˆR¾ E3!¹Èö2±D-Ch¾”ÚwÒ šh2‘•¢aÕ9c5p¥hÊç>¬1—ý†~ 'âÜfTˆC¯Â[øª)ròÆ µP»u „”2þHÙ¼#³ é;P;ƒ·=ޤ¬Mo¬ñï ®´ï 최¼óž@/,OòGY¬gEw‹ÔgwEÓ­¡ÑÜ·¿÷hN„Ë¡ê€Ó H]å:P|U=R±Ô~â}"D63R{õ‘&îý¿ûaúá礑á¡ç}É™´“#!º ‚»mœC©"Í‹Aó¢ÖEí)+.­ º¤ß—W«~Ù¹ ‘ ÎÎð†5Ôëk˜æ¶V2ËË;áÙ­W eƧ |×ws×á5§ìç6ß¾:8gF o΋Üg?™ÑzâËo1€€”{;‘¬ (lLÿ4½w‡!9%Õ^€ñÿgh1tæö‘ŒýÊê×3;¥M¨\ @GIÚhåô—š7Ê]’§Š}M='¦\ôìî¢ÂÂä”u„€¤žpg‡wßÒ¤¯@`·òí‚dü÷$_ÐfÞÝa>Å ~?;jÿÇËÀñ_´ÿxXIÚé~OÒ{BzFø…ð›•V%Ì B3ûÿïŠÝÊ endstream endobj 20 0 obj << /Type /XObject /Subtype /Image /Width 189 /Height 387 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 7279 /Filter /FlateDecode >> stream xÚíÝYT÷žðû2gæÌ9sî<Í™‡û2w&¹7E¨ˆ‚Q¢¢,ˆEÜ¢¸FbŒQ1˜H¢Æ%îKw£¸_\XèºiP"J³ïK¼2_økÙ¡»ŠÆÐmwóýßCUuÕ¿«¨ÿÿ¿ºÓ¿¨ÒÓTLf?³‹Á`0¥Š™L&“ÉtÎüõ¾‘ÉØ|XRäÉ;åÛøE{[kSSCcC=ž_ÚÚZZZ0³¨ûhþ|œÞ[C†ŽôuJ vG½6u[rrÔ‡1ÃFúL˜zýú5±ýé“lj7bçá¾~kÖ}jª|‚•OŸ`ã˜ñž>£Ð`±±¨l 4¸\ŽtiÎWlzV?Y±«À#VÅ?ó5ëÖMˆððùýžÝ꼜•«Wûâ#þ¶ë>ý´@k¾3¶„GF ÅŸ.xÒñcGÅKš\(â(tøØžœü•x°| ©ëéåë'í³ß妒·o8'6&`‚Õ‹ý›ú:¹Ô¨Õx»œœ«¯v´·?{ö[gG‡N§›0)äçŸO‰í“§N‡Ü¼Ü¦¦¦»¿÷3¶¡®Û1ÒÍœ5Ûh4ÖÖÖ;qòò¥ËØ8?~Ñœù JKKëëëѧáØúÚlÁFþÜNÈfÙòå–lpn]¿ŠU<÷á…-6~®ËW%¬\‰å)Ó¦‰'v†¥¬ô»çΞ~Ûcòæõ«¸À P¼´>1GÅ/^ÜÝ™$$X} ä‹ÞæåælšºšzËÁïOÖæ©²3îöɽ„\¦ÝNCS%÷KöA¢ë9xøÈâeËÅ*nýþ±±¡¾®²òiO ÅF£¡gá>¦²è(Ð_575–”±ñqy9ú±îÍMèsà LŒÛø¹6?GÌmÞÿ`ªx”æ6àtîÜ‹¹Íµk©¸ÀÀž ÉêµkujUVÆÝ}û÷¢’c³hélAŸ#š5ßG¡©ÔÔ‹‹—-½šzI¯Ë?wæÔï.¤èEŠo0ÀõÉÿôq£çÅÅ{zJCÂÂvíÙSS]ÕÐP·ïÀAß1þïxŽ˜¹iËe6X®®®úìó/0yCSk«ª*±±9)i\P0»©3#R¯\ÚÊF§ß/H—æà|Á&n¡ÕW_ÝÓ—[òs2¡OŽÑÆNÄ&7Ç|çµëÖN›1s¨—÷ø‰“Ž9$^Rçæ`»ô˜³hÉbL€åÞ/Mš2÷Û#gÍîµ\S˜"îß·÷ƒðp¼µ§¯ÕËù›ÚjåĘpŒD¿u?6µc⊇lÇBggG÷F¼ÜÒýßjŠý±žÓ¥Ã1î4Ö×b¡¡®ûuÒÙ‰…î[߳Ǣ]ÑNs㋱Œ§|ås6˜–œ& D–tÇ x³Óf›|\.Gº4×Í—l¾wÚ34gSW[í¢I6Òò2Å7 zÁ¦¦ÊE'Kß/”˜]ÓNI6Ì~¤áEŠˆõÚn6µ5U.šÝl´ùâƒbéÒ˜vHÈb½¶‡M^7›j“‹f›¼6ZéÒ˜öKü1“t6¸²q4›ŒÛU¦§5Õ&—Ë*Ó“ÜŒÛdã-/ÓˆAªPS¨ÍËÏNô°¤¦ªÒå§Ÿu—€ Áå›]s€Sÿ*Å”X›—­Îɨª|âZfpÂ8mœ¼4%fÚ3µRö|ܧ.P« 4ª{·®<0êMO+œ N§z÷f*N'ßó傯üº˜vMüµ‹ Ô˜èòsò²îÞ»™z+õüÍËg­ohÛGLHÏÌËO+» `666b¹¥¥uÓÖ$ÿÀ‰Ã}ý>Ž_TQñDjÿë”ogÅÎæís)õ ^U"ÇïÚ³÷ùóçdã¢lp¯µ:][[Ûî½û€DÜJÜèÆ›LUOž>*,+³‰_úɼ¸øòÇ›››·&o ŸùÏþS´ïç§V‹UXÖ !¡/]&esðð±ÜÐЕ&Ó£òòîºÜb{qI V«ªªä؈“TxúŒ2—ˆö¡Ñê[9v|YÂ*²qõ¹M{Gî~iÙ£l•êoC=¥}ÄvôHrlT¹y–5¥o¥¥‰öÏ_|5wJ½z ÑБ>bŸˆÙ1dã6lDoSñä‰eoƒ‘Ex@ê ‚ ö|ÛcX]}½rûÕ55ØíúÍ[Í-- =M6nÃËÑ1Í_´TÄÜó±Ï’å+0é¦Rñ$vÞ|³¹Í2ìÿki)æHº‚¬vttôj£&ÃYÙ9x)_£ÁœŠlÜŒMUuõ'+Wy‹‡©„5ëêêêÄ>舢bb=¼¼C?˜vâÇŸ$6è@’’·Á 7nýÃêþ‡;îÏ3¢gmNÚF6.ÊfÙ Ù Ù Ù Ù Ù Ù¸þà…ldà ²a ƒldà Ù ƒlÎÀ¦¾¶ÆX Î˼«JOÀDƒÆ ç½p?6Åz­*ãŽ.7³ _U¨ÈDƒÚܬ܌;Å…Þwbƒ®fL/´aiY™Ÿ@êÕk¢Y…í/užÞfýúOãâŒy?ƒ„lT½\uÐÒ²G’DfV¶XU®zðÈQ±=;GõÖ¡­­­b5aõÚä)]/ËEÊnQ¼ÔyØ$&®—ôêgl1ãfl䪃bû0oi;\ 6ÊÕA¥ÂkjC•tøºÏ6|¹5©ûÙv¸y]8g`ƒî<,ÏÜv3nÙÛXV•ëml¬*ÇÆÆÃÍÙL‹ˆr†Þr–,[jnÆÆ±É]ç6rÕAgFÏ–™Ûô]Tއ›³‰[¼3ígÏž½ñ¹¹œþšq?6rÕA¡hî‚…˜ÙOûáÐaü­0‰í²­:¨[7g“—ŸÀHê$ORófçwRiwîzù½ÇO‰Å£÷k˜¿NùvVìœaÞ>—R¯Í dƒelôôö½ÿàá¹ GWU]-öQ(õéç§VKµdÉf²A|»kw`ÈûÀ“™•m¾ƒ\©ÏÝ{÷q"ô0ïxŽˆŽùH:P¹Ôçù‹¿Í a*î;¢PoØ 'ùhþ‚EË–ûúì9±ƒ¥>ÉÆíÙ,Y¾ÓPÁä6vÞ|‰ÍÎï÷LšÖÚÚš£Â8U\RòrnÓw©O²q{6ÊË£bb=¼¼C?˜vâÇŸ›¬ìP)¹_ì³kÏÞàÉa¢ª¹-¥>ÉÆ-Ù ’ ²!²!²!²!²!²!÷cü ƒldC6 ²a ƒldà ²a ƒldà Ù ƒlƒ“MäžpXƒ;±Ùôß H²!²!²!²!²!²qËû{ðÈÑyqñí=•+Ȇll‰+×®Ç/]ÖÙÙÉÞ†l8H¹›)Ó·lû*òØ¡#}&M Óhu0ÁÓgÔú ¥šÇ/ú¿w=Þ2t\Pð®={Ÿ?.¾ã»³çÌõôö |/=Cl¯ªªÂ!؈6üÇÖÕÕuÉ×y“+:J6NË õ¸qk×'âFCK}CCiY™Ÿ@êÕkæ;C‘Þ` ½xé²t8îµV§kkkÛ½wŸïX!**&vñ'ËkjjË=š63²O6rEGÉÆiÙ`*–³sTèOD¥,DÂêµÉ;R,9rìø²„U¯?|D,744‚A¥É*X€±=#+K™BÑQ²qZ6RÁ4µF‹¡JziÝg¾Üš$–Ñí À«¢"hÄìËÃñøƒ—JËe«Tæí<®¨Pf£Pt”l\—MuMÍÛî߼ÕÜÒ‚1èÐÑcáQÑ lzõ6™YÙ«ÅHŠŽ’ë²AwÁ++;§££#_£ÁdF™ –Ñ-]‘P[[û¨¼|zd´ÄF®©\ÑQ²qéAê‡C‡G÷Žçˆѳ6'më“ f8˜âZ>IY-FÚ%_t”líç6UÕÕ~nC6dC6dC6 ²!²!²!²(6üÁ Ù0ȆA6dà Ù0ȆA6 ²!Ù0ȆA6 ²a Ù0Ȇ18Ù,ù‹Ã’܉Í÷Kÿê€$²!²!²!²!»†3üŒŽlœ“B%Os6áQÑ?Ÿ>ó$÷`£\Éó5zû•%Rdãlll¬*WÉS®"¨ù uäØñqAÁ^Þx—B½A¹A;• %›gcK¥P¹JžrA%6¿––þ}Øð¼ü|Ì^ÔmRòvåíT2”lœMŸ•Bå*y*T•Øú±^e?å´_ÉP²p6}a“«ä©PÔ|žsÄMÞÌ`4*4h¿’¡dãx6r•<*‚Z>€£ëÀ¡÷hkk“kÐ~%CÉÆñlºä+yÊU•ØÜËÈܾ#¥´ìö?{þæ9˜D)4h§’¡dóFØÈUò”«*±éììÜwà``Hè#ñ^×oÞRnÐN%CɆßI‘ Ù Ù Ù Ù Ù Ù Ùð/dà Ù ƒldà Ù0Ȇldà Ù0ȆA6dà Æ e³mÿ‡%1¸›ìGZ$Ù Ù Ù Ù Ù H8s±5²q 6V+‚:¦ø'Ù¸Soã°âŸdÃAŠl\‹Í”iá_§|;+vÎ0oŸK©W>Ž_o :.(xמ½ÏŸ?AņРý-þiµ‚(Ù¸ ?ÿ€<µÚ¼ '–õC`HèÅK—Å–>+‚võ³ø§\Q²q6»÷î³úzƒe «º,jôY­ÚßâŸV+ˆ’ ±9ñi5õê5ô¸¡¢JgÄìl´¥"èkÿ´¬ J6.ÄFªÝW]Só¶Ç°ë7o5·´`Vsèè1¨è²­"èkÿ4¯ J6®ÈÝ&ÃYÙ9ù &±‚M— A»úYüS®‚(ٸć;îÏ3¢gmNÚ&±é³"hW?‹ÊU%~'ÅÏmȆlȆlȆA6dC6dC6dC6öcü ƒldC6 ²a ƒldà ²a ƒldà Ù ƒlƒ“Í¿ýËÿ:,‰ÁØüÇ¿ú: ɆlȆlȆlȆlȆlÈÆ®Ò«Ú§ÕŠ 6ÆkûGÞŽlÞûUûœ:3âÌùóv½Vß‚l\z"÷`Ó«R¨\UOóQ‡ìønçì9s=½}ƒB'ßKÏÀÆ£'NN™>Cj¶üñã·=†=®¨0?vYÂ*©›¨œ#W˜Ô–¤VOÃò-ÈÆNlÌ+…ÊUûìÅ7Q«ÓµµµíÞ»Ïw¬?nwCCã»Ã½ EEbŸ”»>œ;ÏÒ€Õ®À²0©-H­ž{‡±‘*…ÊUõ´dsðð± -8¤ÒdÂòÒ+Ñ-`·Ï?hâ…K—ld#B*LÚeCR…Ó ǰ‘*…*TõìÅFªÛ†G-ìSZöËwîÝó~o &ÒYYPÚÛÛûdcµ0i— HNƒlÃFúã+Tõ´… º‚Ѯݸ‘°f]âÆ/¬;-"Jº§r…I»l(@ªpæoA6`Ó%_íÓ6ˆí;R0»öðòÆ”Ã*›¸ÅK¶lûêÙ³g]Š…Im)@*wæoA6Ža#WíÓF6¥eeX ›*×SååçOûÛPO!D®0©-HåN£×[ ¿\à§ÄdC6dC6dC6dà ²!²!‰ ðB6 ²a Ù0ȆA6 ²a ƒlȆA6 ²a ƒldC6 ²a N6Þÿóg‡%1¸›©ïü—’lȆlȆlȆlȆlÞHôú™ù€ïO6d3 l~--²æÓD²±Ô`´7›^—ÐÚÚ:+vNiYÙW_óãϧȆl^ûÈfÙXÖÕìU8T®’§Õ*]=õ÷°§‡—wä‡1…zƒ´óö)Ø‚ÃÂgæåç‹íým|tÀ„ôÌL±,jú566ÚX}”lìÚÛô**²’§Õ*˜Qü}Øp¨hïèPk´IÉÛ¥½üÞËÎQ577ïýဧϨÚÚÚþ6.Ǧ˶ê£dco6RáÐ^a^ÉÓj•ÎòLJŽôe<{ :èm¤ÕISÂ~J6˦W]Í^¿r•<­ÞÙÎÎÎ}¢O2b$vÀ?yiçä),ðt6eú UnÞk4ŽåGååQ1±xL ý`Ú‰’ØØR}”lø¿\ ²!²!²!²!²!²!þà…ldà ²a ƒldà Ù ƒldà Ù0Ȇldôlþ}ò_–ÄàNlþ¼ü¯H²!²!²!²!²±SØ£¶'Ù Z6áQÑæ•mȆlØÛ ÙíqôÄÉ)ÓgH«å¿í1ìqEE—|ÏæææM[“°qĨ÷?ߨÚú¢ð‘ÕÚžæƒTKK+ôœ8Ü×WT<ÁÆ;÷îIu>EJeÖÈÆiÙ444¾;ÜËPT$VSvîúpî<ó,ËxÆ-^ùaÌýß´yì„ ‘~£Ñ;IOR}²AÇ•”¼}|p>l¿që؈~ŒOR]üNŠŸÛ Ù Ù Ù Ù Ù Ù£Øð/dà Ù ƒlvÿf÷ßO endstream endobj 21 0 obj << /Type /XObject /Subtype /Image /Width 379 /Height 165 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 17269 /Filter /FlateDecode >> stream xÚí½çŸdYyçù¯,0/Лb§ABШ[’hº Y™•­†ý€Fn—A€pÝ]Ut—Oo#Ãd†÷Þ{ï½÷qmDdVk´/¤}î=·£2«JÕ¦ÐDsžÏÓñ¹qâÞs#³ó~ë÷;6òþÛ"!ï›Ξÿö¨PÈOž|Õ{•p£ ·N,}y8Þnü‡üý<ùüÉ_Éd2Îçg³Ù)¼¢<=}‰Ž]NwµXÚÝÞQ(ä@ÐérœÈvvvm6›V«Éç‹â#ñÞζN£•Ie‡‡Gö`cã¾ìXr"—~«Õ.–iuZ‘èÀj1‹Eb¥B½¹µ¶w°—H¦l6‡Ùh±Yl·oÞQ*”£Q"•©äj¥\);–n¬ß5›-÷ïÜ?‘+ÄâÃÃCµJÓmw÷vvBáZµêÜ·\)O`ààÀÀYàÌfgmpÐ+P¨R©¥R™@ ‹G;n6›‹Æcf‹©X,ÄãÉ\6ï÷¢Ñ8d8‰ÅâƒÁÈãñÅÉp$Z­Ö‹¥J$‹DB.—;‘H†ÂQ?`+€ƒV³ GáªD< „S©4û¼þL& ƒÊýþ`±XözýÑH,KDbÑH4Z*Ul6;Ôa¶Z“éL©\ …880pV 8Há m#$’$Ýj¶cÑ$M³õzs<"ºÝ^¯Ó«ÕíV·Óîw:x ‰v«7è¡p4&º½A&“ïuûív§ßt;ýá`2â®íFx-—«õF“ é~oÔí jµf¹Xô'N/M¶á²NnÔïAåÝáp<MTÜ F¤ËánÔšv/›ÍcààÀÀYEàÌ9;{é05v‡Íåö0ÌÔ ×­ß»o6믿~r|¼»³§Së^ÿ”mmlK$R›ÕN3Ó““‰X"K·¶¶\.§ìдŠZ­¥(F.W Åb ¨µvgÝj2ìïqnK©²š-R±lsmÃl6omn™ F‰H’L¤z½ÁŸÜðù¼F£qg{— «ÕjÐk7·6e2 œ•ŽÙ„,ÕeæÀ1¨‹B®P*”Aê€ð(‹ (@8\Ô“ñt&™«”ª€ÀBµTi6[pf¥RmÔ›r•øàõRÉ4\ G€0“ Ç•r® ø‚­f«\.Çãñz½‘ËåÓél0+—ÏœNºF£=.—'•Hƒár©BT£Ñj5›8μ'Àù©%ŽŸõFãÙCÆBB!<×Ix¢ãIŸ?ÏsÙB8µÛlV‹Åawp1áX<ž˜€cšLè@(̩Ղ.•+«µP¬tºýñ„ŒD rÜo&“ …"— ÊGc*l6:­f—˜ÐàÚLFK4 FcðM./œY­Ô‹… \‰Æ&Õjw#á¤\¾L¦ò¹Ò»ÎÏÚ  œÿðFãe…ƒÞB:.‹Éb·[×××'r‹Ùâp8®½öŠÙdÕ¨Ô¯¿vÍírtú[7o‘[«6wvvÀìX,VššY,6“É´¶¶ÂÄ ø)·Û}óæM°K“Y$9èOvww ÐBf8Çl¶Ú¬¶µ{÷«Õ:E²j•fg{[©Tš8Ûµ$–P4 H$K$‘H”L&år9 œ•ŽÐ.$ËÎ"‘X¯7cÐH¥ÒœðOúýa§Ó©Uë…|a0à>m4šÍ$Óh4j ®Ñw4$Z­N»ÕÍf ã11‘à’@Òt{}P&]¾Ù™¯yR(”/ ¥†²?•JU8a2¦ 6<år¥ î©Õ©7›…B™˜0ÅR¹Xâ.J ¸ÉJ'›ÿÿò?ñƒƒãÄ¿üËÿ„¿ŸÕŽÙlšÏÎ.û)œr©zd<&'x¨H8j³9âñd4?‰½Ëå u;ýH(šNgœ6w<– ‚{{û@‰L&«R«L&óÎÎÖh4±Xí^7Ž8ݳÁŽLv|"•IÍ&‹ÓéÖë´f«©ÙêØ®L&“Ïs¤Òh´‰DÊ áðžÈå~¿¿R©wzí­íT2íóúsùÜJgÐiÕJ¹ÁÌÁñöi9ƒnkÕŽiÙI ­7ÓéÜíö*ŽO¦Ó™V«ùñh4¶··¥2™T*u9÷ïßà„B‘ÃÃý“““½½]pL`vv÷½a Ðh5f“é׉1éáåP«Õ{{{J¥By¢89>‘‰$G·Ç¥×hoÞ|£Ûíy½>¨ÊjµÑ4ûÆOnªêí-0jrù‰ho¿T(‹eø'Òc›Å.KV8ÿú¯ÿ ̧à›ãÄùô 3@øûYÅFãG¶ƒÂi6Û ÍÒ—ƒá˜¤`K«Õ¹ÒïjÕ&ç}†¦¦$I(Šá[lXŠd€0Ér9¡ ’™4ø£B¾Dì„ Á1uÛÝf³E¸³~¯—T+ îä MQ\‚Y³Ûìp/ŠœÂ1ð£ABå4 ÇnüÛJŽ•‹w݆sz5èN8@Z¸œ®cÙñÖö6x+' ʼnJ¥’Éd g”Jåññq:ÚT«õÝÝ}­Vë÷Ámomƒ¼Ñ‚ÊQiŸ|–ÃáH$`‚ôzc._l¶Z …Üívƒð¤Óé¢ÑˆŽ‡!ÎXBá@*•‚6@›ÍB3¬Ïç+äó~¿Hå°Û³\äárÀAk°p-<Î`0Ȳl(J&SJ¥Ê öÌã>9–;쎷œ8q>Ó|ú^ª U pÀõZÝÙôtÆÎY†‡U¯7z‹af4=¥xÃEŒ)‚ ÁÇd»Õ¦h EM ‚!(*_(‚ᢹB:•Ê$Mqþ‹³EÜå4Y)WI’Ë× Åz½ Ì!Dt$æÏd:._>‡œNá LÙé 'ÎÎ…i›ËCqÌ&«J¥–HÄ·nÝ4`¥,Ëɉ|}}]§Óìïï­¯¯©TÊë×®«ª{÷îîíîhuV%ŒF³Lv¦©ÓíƒEzíµëà’4ݽ{÷¥ññ±ôðpÿèH,“¡F³½¹¾ur¢°Ûápn¤Õi¥R ˆ(•R½½¹¥Ñ¨].ÇÚÚ=E:vccSo02ìlgg 'ÎUŽqœ ó7Qa¹\ÍdÒ`£"‘(x™X,–LÆ=o(†r¹¼Çí)” ^·LßH$’år^»Ý^,‹ ”x$¯×Ëõ³—+@°T*Â[¨Ðéta‚Áðh<S¶ÛÝZ­îõzRéd àO&¥RÉãñEÂ!Ûév9ñx8òy=•j¾ïþáNœ«£p.ŽÃ€ à&F•kýÞ°× zÖh4ƒq«Ñn5ÛñX²^kærÅX,áv{ÇcªÓîOFd³Ùé´{Ä„6›-~¿ßårû¼^ÀAýÞ Ÿ+N§ÓP0L‘Ón·O‘ôh8¢¶ß€¥ôGýþè7ãñ.&pÜŒÀˆõúÃÑd2€ Æ“ápT©T²é,Nœ+œåõp–gnÂS¬€ zÃí›wìv+E±¯¾úªX|tt(2êõûûà‰Ž»T*½}ûödBZÌ–ý½ýƒƒ@ E1±Äæ°Ûl6VÆÊ`0šMF³ÍÚét6×7hf¦×®_»f1™h–QÊ[[[jµZ$:„[&3×®]3ô`²nߺmä;±®_¿®T*wwvÅ¢#½N‡ƒç*µáÌ.6àǽ^ßl1&c nB©2eg‰h¼Õji5êb¦X­Ôàm»Ý)JÑ`“ÝæÈeòÑP¬ÓïÀÛd,VÈfsÙ\§Û†€FªT¸yâ“1 §ÓY·ÛÍç ¥|i:?5h5…B\2‡“³™\‘ŸõËçP*…¢\.·ZÍZ­–Ïç›íf.Ÿ-WJpŒƒç*6_hÃb4­r¡,“ç Å\¡^)Oû}~·Û#—fÊžæry«ÍÆS©t¿?$˜¬r©‹ÆË¥J2™®ÖšéT¦X,m"ÑX¹R_–NgYfNS³D"Yk4{ýA2•d˜8¯t.[,–=>_:®Õõz£P(¤²ià[<ž„k‹¥R6Wh6ÛÀ*¯×‹ƒçŠv‹CgÐÁt:År¹üöÍ[6‹E§Óéõznø‹Û}|||çÛ 3…sÀæÜ½{çèàP«ÕUHŠq:­îµW^±Z,~ŸïèðP0T«Tb±X~rb4AU¸M³â#‘J!ߏ޸BÑ`0¸\.‡Ëyëæ‡ÃÂ-ÀmÁ1|0q^¯gkkC©TÀà* œ8W 8§äÐ-NädË„€ƒV£MÓ AуÁ¨ß1@“À§ä„j5Û­V›$–9M%“ý^¿Óî’Ýï&c^-‚šLˆÑhÜë÷AŸ ;V*µF­Ñï _ˆrh–Ä`0ÃEs³¦üäEÑP¼íõzÕSýÁ'Εkù¼¾(ð¤T*§Ó¿?0M|NÿÉñq8IÆSÙTÎçó—Ë•R©§¼A­^Lðú}ñ('Šà‡ÝAÑl<Óht`‹H‚ÕR¯ÖÁ‚I%²€?èt¸@ñ·>=;ãü3$@ýÂ|Ráu6›Ïæs8ÄÀÁ‰s¥z©N/4/z©æ‘HÄçó‰Å"Ðv›]rt$‰ zÝ7Àé€Íj·»¡Pøàà€eY°ZûûûR©Ôív½ñÆ P#Z­Z$©Õê~¿¿½½ vI¯Ómnn‚i’J¤¹\®V«_@ ²„Î2 ê¦_&ËNá ;›bààĹҖJxêA{ðŸrÏû¸¦?@97Zµä¯3N{ί=O’¤†ƒÑìô äÌ)ÿÊ\6Ë_@(ÔÎ#¸tö'ÎUoÃAÛÄ€cŒ iZtA ø´Ó颃|®rƒ[…¯Ûç4 B·ÓËç `»SPB3Óv›Ûù>‡u¾êΔƒW$IÃí€AÙl¶ƒT‚î",Ô³¬yà'Ε륺,r@¨€ñ‰F£‡ðhñF­vÚ7®_“ŠÅZµV§ÓA¹A§»uë¦B.7êv»ÏÞÎîÖææþÞ®Û嬭ÝÕë ’ü:†bh·Ûýúë Ãr›ßy<{ûz½^*‘ìïî™ôzF½¾¾~,•9lö£ýýí]nžH„x(G–Íäf¶¹±©QóÓÕ1ppâ\©q8ËóÄ—ENµZ‹Dc‰d ÊK¥r,½EJÅR½Vͤ¹E$’ÑD Š…¢¥r)—Í‚’ÉT:ɤ3ù|1‘H&#©ZµN3l&›Ç …Ò™œÁhä—0­å3»ÃQ­ÕàªT2 'T*5 \&“-—*üÖœ †f²Ùx<®×YR©t¡PšÏΠâP8 §aààĹZ GØÞw¹[^'²^m$â)šææ:Åb‰B®X«6ýa!_îõ•Ju2œ¸l®b¡BQl.Wh7;½î T¬º\®•+µÁ`Ðj¶¸ #~qõžÑhª×›`£üþ`4‡óÇcNˆÇÓÉdº nªÝƒçC6j­Ùœk%fÙS°füÂs†øÁÀÁ‰s•&o>¼¥ø²Ú1›­n§{ssm8ݹsÇn·Ýºù†Z­O´v÷ž^«w»6›Ín³»¬öíõJ¹ŸJEGF-·R_&“SËÝvÛíÛ7 z­ÕdÞÞØT(àËÀ499aÓ‹Ä"Ñ‘âD~°Ðîô” …R©Òj4f«yW.;6è &£[V”$ œ×óuh0ppâ\!…3ž^^ ½U­ÔšÍ(œN§Ûëõò“H$Z,–ÀÚT«õR©ÈmùÝëç²¹t2CSl*•j4š¥B±P(‚J%RN‡=ðgsÙT†›àÐjw*µZ±TÊds‚T.—¹ëõb©˜Íd@•óü@€›9U(f³Ùz£5å%Ílv ¯,ß òŽ1ppâ\à˜MàZîç,U½Éð úeèE1¢ó·ÈÝðcó á#x‹`> ‡c„…N·O/LË÷yÁ+І_}:M¸¾uþ*”è40YPÉhLÀµHáðë2ðʹ*v¯ð 1ppâ\-KµÜn³œN§;O¨TJ`Æb±ÀÛl6ïp{²¹B 4Œ€ C(ñy}.· ô 'BÖápj4 ÇdBéôÆJ¹†|>ŸÙlŽÇâ±hL§Ó}²Ù¬±X*O&ÓqˆXÌƒù\Qtt˜L&Á°yýþ`0ÖÍãñ„Â! 8)82Š`ààĹº“7äá £ÑX&“5[Ìý>7sjs}Û¨×Ú¬“Á`³ÚuZÕjeÙi¯×÷x¼¢½¨M«ÕñËOÃáÈÑÑ?7ЉDcv›C­R¯ß_s»=n—Ëb¶Ø€5V«V«•»Ü^»Ýnµ˜c‘˜X"‰Ç’{û»N§î²v-™L €`“1“̓¶‰ÅãÑh$„ƒçŠMmxôòh ˜f³ÍÏÓœòމ›âM’4¿ˆ:·$”sûFñs9AíT«u†ïKBÞ™)v1€Ë·ø92ep9ˆ¢Z½ÙnvjµI0ù7åœ_b}Ê/½Î¢»÷Êdr¨ÝrŒ-Nœ+h©.L¤âŽç·¦V1ó›àh´:½ßím#“q³8-F«L&“H$`¬4zß[=‡¢z£ñν;µZ €Óíõõ:íææŽN§ƒæ°Û.·V­±ÍZµ.O9펣C‰Ål ¸½“U¯1HEÁí- Eíf‡F¡­TëIu:=§Ó%K“±„F¡ ‚~Ÿ_&’>;àŒ†ƒÿü_>FŸüѯüúgàX©V=²ž'ú.ó •?Óû¾·ù„_5Î÷pÌKÆZŒám¡˜/–Š“ év¹Ëå2¸¿Ûçûäõôp[þ ?¦RÉh(Æ5³§ÜìrŸßáp1@óŒÆD"•ÂÉdèäõÂå^»Ó‘ˆ'£á˜Q§†|*¥Òëñ¥À"E‡…Ä(™b®ð«•:C³ÃáÈçó« ¦×ê|~ 2[Íï 8ßúöwÑ_ø7þúoÞ[àüÅ׿ÇÿôÃbà`à`àŠD#¾ÿ_yÊ¿ù÷ß~Jà @az½.*Î#ÝÂ2´ c€H€Œ· 1€o ²àX§×CùoüÖoñÓå„/ðü¯ýèCø].þêg?'<ÍO'ˆÉ'ü>}~?üò /îŠàÿ° ?Åï¯q8§cŽÓéúÂ"ÑÑþþ×ë/KÉdÊíöÖ«uŸÏŸNe,fk(‰Ã~_Ðîp¡x4åt¸2©L2™ö8ºð4ýýwÿŽAçœÎghÃá Îr+Çïþá/·r\ŽÞ`ä¾ó§_¨T* B ž8ð‘Åj(8‹QûÉK_âÚp~|íبv»¿–¯ÿÕ[ÃP 3J¯Ï't$ ªli.—ÎA MOÿÓ¡ïð¸ß'X‘òÅ ßoÐèH‚Ò©µ^Çåt[M– ¬7­+ à Ÿúøq3A°Ýh%)‡Ýi4šö÷÷‚p´SµZw:ðç‹&ÍfëþÞA(2›-`¨X*C‘Á`R­6êÎxÌ5à@Žxˆ½-àüŸ_ýsøþ«¿û»åÂoï¡ðK¿ÿp 5œrüÂîþÁ2UžðÑòÓ:ªB¢â«_û¿/| -<‰¿ù;/=÷‰O~î /½rí:áp ~¿_.‘™Œf“Ûxm‡'‹u:]$9ØÚMH™ìX&“@¡Ùl6ê µZd7Ø+Ù‘d0€?ÚÞÞѨÔ>¯×át».‡Ãqïî]“Ñü‘ˆ%¡p$ôy]>½ZçözàZ+?ßêðPT©TƒÁ ßÐh´j¶Ýê‚‚"ùŽ* /Àõlžwxü_»~ÿ*p>ëFc9h.ß©ÄN§s~u ê{bÙ)_Žº®¸‰TÂúSÔEÅòÓ©¸•%¦è4®CŠ:?ƒúžP—Ò*P3I2PÈÕÏwZ‘C‘,I²ñX‚sª¦R­qWM4‘ Ï¥zY«UA]üï¿ôË Bðoç3j4¾öú=Ð3.—Ãï÷¤Ói~¯ˆÛå~[Àù78p¼»x—³Å/(œå ÃáÈh4¥R’b‚¡°ÇçÕé ‘H4•J—Še—ÃωT.›úCáPÌd´Òô,Ÿ/ú}ñˆut¾×C¡„ök¨×P¾¬×vÚýD"i1Yb±8 k<&JÅj.[èt{à΢áàÅl´¤S)pv¹\¾Û”+µR±†Îïõô ÅR«ÓÃÀÁcU€#Ìä¾T‡Ín·ƒ j6Û^¯×år«T‰X¼»»i·X Äës;N·Ûm³Ùöö÷ÀI±ììþýû:­Ža§v‡Î1ãtØ]'¨—ÃýCµ\i³Û|>ŸÑ`P)2‰ Üð èa³X¥Gb½Vç´Ùþ ËåqÙ]Vp}:ƒÛá¼qãh‹Á°~Íïöíïíomm9­v 8V8Üz8·M I’¥b IÒ^Ÿ¤¨l6Ûîõr¹ˆr¹Žh0‚¤OË•j&›#h&—/Ôjñh’Íå[íN³ÕÎd²à˜Êåj­ZÁ“…ó²ùr©Úl´¡þ\6רÉ]PM`“:Üо.·ÝÕ„Ì$ÓíNDŽÍlíòÊ\|Ÿ|>UAýÅB ŽÕQ8ÆG6à „G;‰ÙÌ6§Õéuû‚Íæð:½4;U+5 KR‰´Å`IÅáp0¥Sé#‘8HƒEâZoÒ¹X4'r©\{¸/ŠGƒþ<Ú·A•2Îììî‰ÅÒP("L e–¦ˆ¢¦$®—œßF¾Þt±õ½XÅŽ²T‹Fã³ËÀ‰Åâûûû2™Ìï÷¿qã'¥J!?Ù¾¿ ‚gcmý`oßd4þ[?y].?¶Ù¬wîÜ‹D~oÀãô(ŽO®ß¸¡Ñh,‹R©¼óú]­V“Íäôz½ÙlÑëñx|—h4¾<qF(¹<íb6?›Â üG88p¬p·úÿÈφEüÊ• C³4¿·ZË-„Î%;çÚ+ŠþÇpç£!Ì„ ó…7&‡fÀ M #„·üª4|ÇHÏL ­3‹å/à-·Ë/oÐ1‹8å Ñòì88p¬pæóœ*ޤ…°b½˜SÀ,€pŽ~g:†‡†pX@ò¢urÐ1ÚÁ]+\…\ZugŠH²Ä¸ ªBx™ò;ožo¨Ç'+œÇ/¢Ž˜Ãò»ë¢DcÊë ¡pÙû\pdsT‰0Wbá•.ô‹¡jç§g—w9_FŸ°êò|é.P‚ƒÇJçÁã\¢5ýP¾µ/Ú{wiA?¤F˜¥ÕüЙ¶¿‹<²s¡žÙb{_¤dÎ Ô’ŸZ>m¹*8@¦o:à ŽÕ²TβÈYÞ:\P8\"÷´@ Ò-ȰüŠr”Ï,+,.ŠäÍÉ$œ …kÑGÂQà ŽUŽÙdÆá\È3xÞçoΘٌšq-&³Óq29P‹†ùìP¶IF‚m£nbÕ¶½Ö~À=”ï͘Ñ|vÆ2³¾bLøzNã8’ ÊÙ^ÀC†§‹Œ;;¢7Ȩ} ÓéèÙéÙÙé›Tµ2ÒNëµqÐ= û¹ûž¾yvú`è4Ò?vŒª•q(8щ ÷ Üæ¡fÍægpùA88p¬ŽÂ1Ϧõ;#…ƒDY-µNîÔö^¯©v6t™ ¿~ptwpû[]ÉúšÍ‰t½+¹Aôz#“lÊœÆÃIÏ(ˆ_›”‚-éöX¹Ýݎȶü>ÃPƒ[;Î¥÷þŽN¸5+àü¨Ÿ)zÇ7š{Cå.· 03#CÂ&af¢\ï…CCõÑððÇDÐ1\ÿ[Ò¸;ÖmÏiò4Îéé0`ÃÀÁcU€c4š¦ì©`a¶Tgd¿×<ø§îá?5÷&© áÓ÷ÿqì“'ׇæ½Þцâkmõ5èLlRäzH’în|ohºK‰žô‡ñ÷²õ#î¾âÖ$îo}»ñíš¡ê眦§“T¨t}â=îíÿp$¹ÁÎy§F3#Ùm"‘žl}«jQ¦JykâRŒõ¯Ï-ãöÙ”y3›Ï‡š5 8V8z½ž˜0$Á¢Æ^¡í—ePÛ씎i†`𦠆¢jÈpƒg†3jLOšÓäp<¡ÈñhXªQKQ,;isCkHªW*p+ÚÀ9“EMX²3£ºSj@š,M‚¢™S–¤gD‡™N¥ÇSv6ôÍf3z2eús¢vÊΦĶ}Ê fÌxÆs¬9Ëw:g 8V¦ Çl|óÁ??xðæ›oþ³`¦<€c:œÃºÅ¹&ßLf Ñf[/#âÁ–Y7Žo?îùüýíï½ÎNVw™úùŒ¦[9UNœNO;ã8“踬d·ÓUˈl¼ N{ÝŽÅзÈнŽñ°·ñ?>[_+DÂC½xFR³jä0u 'à½i”MRñžÍLD\ƒ`p0Ñ~!3L1ppàXà˜j(^ì-Žú€ÎÕÎb'»¡]7j·¾CEmÍýWó?ùïÃÛÕ”ÜjÞøË¾|s ¼7PlO|ò¦ôõ±IBpŽníRö¨Èɨtç›]‹´÷›ŵÖö÷›7H›”™LÇ÷¦ãáÉŠä^ýîw»’›#ãE’õ­´w¿Ó~ãkí«üú·j¢›_ï{Ì”ø']õNã[µ7¾98ºƒÇJçÍ « ÇÂ(âóNmŸ¹'y}hÜî+¶†âתʽæ¯5U½½¨·ÆªµÎñæÈqÒó¹{Û?${ÝÚÖ÷†‡?"ºíÑÉFÛaI_íì½ÚÚù~÷øÎ`ûÛͽï Äk“|±-¿ÛµÉ{Úúñ½¾èÕ¾fol³Ó?¹6V›ß„}%¸J½Ý¶[;ßí¼Ú<¸58úqoç»}ñu 8V8¦6ƒpи—ó¼IšËñˆé•‚¥–’½5lÓã9îÓÃÝŠ³½ÝIP<3,SAŽ:L¿ÎuF +t/ËÒ1¬ÑãÙŠ3£ÞtT™÷+̸15˜Q›jè~‰·¸3ëa®Õ¨_c™ÓNQÍÔ¤WÖóÃBˆèUÉ^l&Æíê¤S%Û 8V8Âò˜‘=;mµ:‰D*‰‡ã€?ˆìÚ%œK†?‹qzÔ[[9œg³Þâ&Uñ-™é|v>ëú¦ÐâÓS4…*‹ÎÏzÝálv7e¸Æê9×~Ì·¡m j•z«Ó#(nÝõÑ„¬×›Ãþ¨ÙjcààÀ±RÀyìÌM—Ó]+U<¯N§×jôì”c‹Ûí1ŒZ­îääØnwû|~‹Å Pr;Ý~¯owñ'O˜&…RôB¡Noà€3?‹„£©LZ*;=bBB 0Íd2Çbq§Ó *‰XWA…£þh~ú`0e“»ÕnÔ=N—^§;:< C6“Y«ÑbààÀ±BÀA»à]^y ‘H¦²ùœÓîˆÇãÙlÍŸJ§Óþ€?‹¶³ÙŒÏçPh4½^ Ýn7×ÃNϢѸÇë‹Å¯'•Në´F47¼Z®™ f»ÍD …Ü¥X,‘‚ÁP L$â‘HD.—g2¹d,,‚¯×l¶Aù=^¸ àÈëó) —ˈÅá¦88p¬’™=zMãóÅg.‰N9 'rf½þ Â=å½·*G8àÆsíÌœ*—«`»ÀñÆêŒ¡Ù|¾ˆV®˜só.Oû£a»Ý™ró°¸Ãpùy<;ÝÕëŽrÙüŒ‘ÈÏÕâ×çA‹ðÐ<»‰ÃÀÁc¥ÎÙåÅ%pÜnï±X njksÔÅÎöŽÑ`IÁO鴺͵ «Åê°qûU…‚aƒÎ¸±¶¡×büò}>_À¤7锉Hb0˜L“äH¬QªOÄ2½V „NÏÞ,—Ê6‹2™l¹\ÞÙÜq»@"yLzÏç5‡»{ZµÚl2¹®³ÿ ¶Ëb¶(e ¹LÊmlsŸ`ààÀ±rÀ¹ÜŒ:¤Vk‰„×ë­Õj¹\.Ž€ê‹”É¦Ágiu*ËÌ«ÕZ< cÕBµ˜/h)•*‘hÔãñD£Ñ¼©VBáP>“E¢õr#“ÉÃM‹Åb2™<;{³Õj N—Ïç¡Ú(·Ïx> úCp+øÜFŸì ì[4NF“‰TªÙn‚Ï(aààÀ±Š ç ÈÉ„äw[¨d²Ùf½ „‹åòdF£q,–hµ:Ñh¬V«fó¹h,R'™L'“©r¹”Ï …R6›‡ÃÀ%´ÿ ·„ Zb}1\­“,,n¼Ï3CgB APhAca5cn‰c–åÊ0ppàXà˜k_l,Pܰª'ËN‡ƒ18& Э;z¾ÜßìŒóAp#,ô7g€;žPð Áí³ÀÎÀjq£—< KppáØ2ž¿%œ>Ý‘$iv±® Ãõ~ñ# ùÁ<3n…ä3®WkŽƒÇê(œGG°T>_ \®ºÝ^Ç×l¶ Îçóy<­VÏmÅëò€žÓ ƒÁÈjµ…C¿/àçG&ÛíN›Åîrºõz#œÐîôŽ%ÇV«=Šó%‹Éšˆ'C¡°üD‘J¤›§h4žH¤5Á`8Oõ»øzV«5›ÍE"Ñh$f5[óÙ‚Ûå±Ûù\Ž•S8m‹À¿à€c‚ÇwoÇét‚ BÁ`@«Ñ„B!­V+‘Hì6«ßçßÙØ‰R,–$‡¢h$â°;€QIK%ÇN›S,–êTZðMÀ™“#™\";>>I'Ó;Û;‡¢C¯Ï·¾¶a5[Ç”[,6£Ñ ÚÉëõÅbq€Ùlµ˜­pßH8,:<è÷˅ƒÇJç¡­X–.V™‘Õ¨7ηÙ2 UZí׺;‡·ÃÑx2š ë <“Íö8Îeò)Ú¦ 9,zÚh´iŠ+Ær­0Üj]ì <7¸pz o:š¥õ‡£f£Ùïö¦üì*¸'Ͱõz›gÁ5ã]pàX1à<®[ä ø)™T¦V(ãјN­5ëL—W²wä÷D{¢v« <‘I”J¥ÛæbÙS¿¤G@§Ó{ÜÞím“ t‹ËãôˆÄÉhJ£ÒËÃá(| Š*Db$I»]^ÐBÝvjƒD"±Óî4h ÀœB¾àvº Ü~Á6°Q>¯*ßÙÙq»=#žr88p¬LΣz©„Åpòùb&“V(ì•Á`|±XT"%bQ«Õ:šŒ'¥Ñèvg¹\¥éi*™n·»@†d"ˆà$“©l&¨±Ylf“Y­V!Òét ;8/›ÍøI2v»C£R†Ca@APµjÃåpÙmv¸ìU:õp“ªT¡p(‘J‘0ppàXÅ6œKÌ9Íç à}|ßÓl˜n§Ç°S(§™)¸'~?ñi±XDCõšÖlzZ«5ifΗWZÍ.ô£h,A AÐ$Iu»=xÍç àHŠ)+ÅT«5šß˜¤¦ÅrC]ç,o»[ìEBQ ÔJe 8VGá<4—êáÿhHÞ¿¿&‹VÛÉÉ IÒv»î¥×iƒáÐîî.«œ‡ýÔò¾T` (nB÷^»Ý~»Ý™Mù© ÆÌP\0Ãá8—ËFÎgvócrÎNÀ‰Aàã AÓÌ„ ¡N™T¿? –Êl2·ZÍv« ê¥ÕîŽF#(‡OÁÊFD·;„ FÃ1|ñ„„&|>‚ÿ0ppàXEà ×åvcðJù|<?}Ò’ÍäÂÁX!ƒÁxq8œðH £ÎäqºÍf3|& ê©Õ` L3¸*Ð$Z>‰ƒ·BKo…¸éäA»Ía±˜<w4‡JL&³×ë7è±hœŸRáAðAa:I¦“:ƒžÛ Âå7¬Ùl>K‚!ø88p¬p.6ÝsÆ  78 ›Í¦R)ìv›ËåDSŃÁ ø#·Óe1šŽŽŽ8Á`˜ïÞJ˜ŒF°DP hžÃƒC«Ù"K'>µ[ÇÒÑáÑɉêt¹\G»‡€#›Íq¸ôù}¾ÀÎÎІ¦fà­œ·Ëå>>>jù}þããc½Þèâ–[w'âI 8VKá\n1¶úôG W¸9 ÍV«ÕžNO ¹"¿@7U|>?å–)žž¢·Å\©X(gÒÙjµÑlÀÉóózø½]ЪÅPÍÎÚÝÞ`8F[y‚ãWd†ÛÍ“ßV˜Y$Ë-ÕÅ-ó5ã§<À™ ø;~ /¬A188p¬pf³GwQ( J¥T(÷î­ÎIcµZ~ríšR©‰ì{&Óë 6‹E%—w»}‹Éær:].Z¡îwûh‹½å%/ÐÊ¢‚k"Á1À™ó%F ’{;ÓÃ9ÓãIL¸mÍá‚ ý MOáíµäŒ H 8V· g™9¹\’ËäÔrU:™øýËá°s;¿K~ O:ìà±lhÖy8‚¥l&S.WÏ—ÓáÁ‡k–¡‰&$ÈBPcÈp2ÃÑ„ Ø!¸Éž §qÇ ]ŽPƒ˜ƒƒÇêÇ4Ÿ=z¶8Úa-Y ¦‰›ýÍž¯l î %ˆ ðU {ÅmõÂ-ŠÅ]Åï¹Àˤébÿ…ó: RGØÁ=_3™_8­¯Î-ÉÅÓSŠ7VhËN$‡Ð[´â:«¨p)rv„M[P³ÌeQôÈçð‘°`)Úí…ÛëåälQ"¬+ˆ*?ß—_îÁ‰ÛâgÑ9£øó1ppàX9à ‹ÍfÂf.çÏ;ßÒ+]uÎ ^´Òˆ]ìêÂí×Àïó‚ʧü–åH±  9ÑÂãEð\_I€ÿ"i¾‘‡¦ø(ôMøÆd(ÄÀÁc•€3{Ä⢀³Ø&æœ8¦uè`ºäž„=ì…ÎLÖ[6j!TÊO€3è•à[x&üîTÈO-Ú™¹0ppàX!à,op¹œ‚V4Ì…Ý0'ÐÐAbçîI ÙÂRÍpü”€5áXhÒYÎs:ñÛêѸ ŽUÎ#;ª„G^0;Ho ýé?%x.AüÌøa’ŸøÀ.(d¯˜‡}Ö[[j.mÐ-]B"´ 'fHÍk˜,ד5!1ppàX¹6œËMÁoµâžÏ›2Kò¡FP&€…·,ر%»o™…áUƒ´Üê‹>e„ù€Qj8ZÆ zEüAýé88p¬œ¥ºØÁÄ7¿ &L—:ªˆc…^/÷p ½T3äÅøÚf‹.ªs¬-i^¡ó;N…ý‚gçÝå‹ÞpÔ¤ü–Ö ŽÕR8³‡º³…Ôn#´ÓR¼EBbFhoqA!ª°üh¤[+è…::÷V‹®mÔ4Í,nϹ¼YܪšðÂéd¬Fc‚þ7š G 8V® çÂz8Ë}Uˆ¨±å¼Ñf1Zq ™/TÕ¹(âõÌr/ÕåDJé­Êyóunµýïð ¡V %´ç`ààÀ±RÀ¹¸Î¥­~çË=VÂÁTW³èÉ:om^êŸ-¼•0Øoº0P³©ÐÈvÑX4[x+¡UG@H,¡ÁaaààÀ±J–ê1#RÐÀváqÐ+jË¥#ôÐ[¡½é4UÏyk¤ÍBÌýSç`Yˆ(’¤™… CüþhîûÇ™,â|RV88p¬pÌ&Óìô±ÛÄ »t>¨o© ÷­Þp4pi Z·ºìª¦KÓ©f‹†e¡Ñµä€bùÁ6ËÚ5ï‹Äs©pàXiKµ¬s–é #/[*¡ÇêB"¤ ©©Ð]ÎS衵L#ˆn$ÔÃ, HzÒQ„ƒÇÊ(œÅ61Ë+‹ ØYn¥Y|¡Ïúò9ç…pøÆga°jÉ™.zÀÑÌqZ˜‡µ“ƒº¨Pß7’7Üüq¾=à68V8„ñ~€!—ûÊšª°4‘ay@Žp|«…cZiƒŒÕéÙ›B2:M˜Ë9_¨ Î|QŽò|Õ¢»JhÂÀÁc…€s:ð„UF/OžZ†Ì²«š=¼îÍþ ¥*f‹+ôöty^•0ÓêÒD­ M@úÖ1ppàX¡6´ˆ:’4Ë{þ.·Õ,›)aFÃò:ËVë­Uü°Àó.4 Ýë Ã.õ¹/.¡=ç­–äE'V88p¬(p.3Gh¿]NDÔEÎ,Þ¢‡å-Y"˜#ä§atÀ(¡·}ч…p–™ƒ×ÃÁã5à|åññâ‹/\áâêcòÊË/_ŽŸðvqòù…—Nàkã“;¾zu©|ùøÊcîþV —¨*.®`ààÀ±:Àyq™0W¯>8è©¿Œô¼£üâ_N[>xùRÉ希©+ç\Z>á­Â¥š1ppàX9…óXy³Ä–+_Dxy¸•ó´A¯ü[þÌ z(ôØ‚˜óp…VPç•/±ŽÕÎÃ"炤y^¾ B>óQŠæ’Kâ_^”¼üø“_¾p#þZ 8V8g.»ª+t7óç!ȼ|¡¥å¢/{ù!Œ\nɹÀ™¥»_yHaààÀ±¢ÀyþùOøç~îüàÿö¬VbààÀ±ZÀù…_øè?ô¡|ä#ûØÇ>þÌàð,ªÅÀÁc…€ÚhóÜsÏ}ü?ëÀyáEpR m>þ쎟qà¼ðé_üÀ?øL8çÀùä~FÀÀÁç"p>…ƒ  80p0ppàÀÀyÇÀùy 8pü´€ó 8pü¯¯p>ûÙÏöû}øï9p N¨êÇÀÁ·á ÚÔëuD†÷8ˆcPÿÓ0Ž•Î;‡ó™Ï|ѦÝnîsŸ{ϳ\ÿç?ÿy 8~fÎ;£ÍÛmÃyzæ`ààÀñ~mÃyÇ´yÆOÉ 8Þ—–êÝÐæõR= s0ppàXàüü3jZyÏó8ÄaààÀñ~mÃy7ÌyFE88p¼_ón˜óŒ‹0ppàx_¶á¼Kæ<£Æ" 8Þ—m8xà8Þpžÿ(žÚ€ŽŸp^xOÞÄï3à¼ø"80p0ppàÀÀÁÀÁç©€ƒ'Îgšÿ.p~¦6ÂÉç,p>üs?÷ó?3[ýâĉó?8/~úùOè?ý§çž{'NœÏZá\¹rõ£ýè?ô¡|ä#ÏÔ[aààĉòùç?ýáøü `aµ'ÎUÎ /€Â¹Wù._}¸ü]ÆÕKÿN¼üò[¯(0ppâ\!àÀûüü>Š<ÿ.4®>ñíS^xåm1G8ÆÀÁ‰sõsõñôxKá<†TÐ0Oqæ•'bêê%Åu^ŽƒçjçÊËô8O“W.9¬÷üÇñäqXãòqŸ`ààĹBÆ_z+¾Ìçòñ—.\>óKW¯^È«‹×åƒ'c籤Zªg¹r.¹[/åààĉç3M<½?ÀÀÁ8Þ—ÀÁ‰'ΟNþÿY[í1 endstream endobj 22 0 obj << /Type /XObject /Subtype /Image /Width 96 /Height 106 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 1893 /Filter /FlateDecode >> stream xÚíûoSeÇÿ#Òib¼ÇkÔ QnCƒÄ Cä@¹ì¢¢°±`$ŠŠa@:e—ÞN»^×îÂÚîœÞok×vóÛ¾å윮ív¶ö´‡½Ë'Íöž÷}Ÿ÷|öžç}ߦ°¡»ÿ QÊ2G¿JQ?Ëö3æ°Q„~¨ ê§‚~FG¬¡I vKÅyüqØÌ„«©"ðÖ›(I~ˆ‹Q§¼«VõVv†õƒ*‹QO,)Αc33Í=7•N¥*»Ó@‡>ŽeÔý6S?ŠÊú±ð8í˜ü&³A 93Éd21Gã±H%‰GÑíL2Á¨ï!Â!¨p 5AìG|Õ>©Æ2ŒÇÊËNÅcÑX4R%й—õèT‡ Â1Ô‘ñ%áÊ‚j3‡T½Õ3#¹á´«¤$„~JÕ!ë”Õd@e<±h¸ª !Y×”å' Ë€Bü˜ H•#Öa«‰‘׃ $K×±ñU[‡Õd7­ÃÄOH²~†Eh~5Aä§D¡ŸH8$Šð#NáÈÃ.‰üý”ªCý÷cÎC6Ï&&ëÇïãd ë‡Ñ’-4?Œš òSxÕ@°™˜œMÖ—•œMÎã&ˆý¯ƒA"UÊïAæGÕ˱Ÿ—­*ëV«zëßíØç#U3íÀÝ §ÝÇMU„ÐößA8Eh›`$ò#ôSxÕ4ÉÏŒf@7¨â¦ÜÕ“ƒÎøü\[D~ ¯2<¹ý¡'T£~èέ뫉õ¸*k¢Û¾žn„@ ÜùB/CMû)Y CµuÈ í ¦¿ïNO÷­î?{®]© èݪûû"·x)ÉP~¹ŒfP¯È¢î¯ ¹ÞÐ-:¯9’üðŠ0óq ÃzuÅA·è¼~äHõCKÜNEà;$ý׉œò~ÈPKÁßQ)±&ýÔáð¨åú©ìò­P„~¨ò~r¿ŒR„P?ÔõCýÔ§ŸP8Ò~Ãÿj»û±ƒ÷W'åýœ¸ØÐÉR?¥ü¼v 9º‰$ý÷ïEý‡ôÿ ~¨ê‡úYU~‚õúY¹–ãÎtžÛÚÔüþÆF¼žéìDÉRüü+ðÐûÑ3LãG›×¬[/%:†¡~0Oˆœ£­m#G"‘p8ÇÚÚˆ¢)–­•“kæË?üiµ?x¬ˆœ‚òãmí(ÿ±£s•ûù¤©0s Ê££(ßúiÓýœú'4áO‘ïŸ=6ùKÄL‡§3—ÕѧL¢ð¥6×5CÜËø£™«úØ -.RÙê™éè Ž&bÉÙ1_jÛ…×q>s?IªuÞe«í¹ì»m›Æ¥Ù¹9DùþV¨!×ÕÂV+÷³®q<ħ§ ÊÉ$Ê‘®—áç_Ë´f<ùîiÏóÇ]‡¯¶ÿêÍr,›Âaùõ“nØÀ÷¼w(½±“}êÈäw=!Øk(6PÍIÐÅ>~h~bàûµg§Æý©½¿ù«4¶5o/:…²ó§©YêóõÆI7ÊßþÖ#,|ë”…o~“eÍSø‘¼å‚o»$åð‰r8,êöŠ>SÇ»ƒ˜9Uòsö\W6ÿ´´Í?Xè¥úÙ|žËÌÎ5ˆ ·œçÒ™ùÍÒ“_O¢-æ ¹ñý¿û…åÄíB?®Ìÿ¸ë’Ï잉ÏÌ’ah'’UòÃaýÚ¼*Ž´´ØG²ë^‘®QòÞ† çÕJæ.?Eý'“~øj/·¹ð+ØqÑûÌÑIü"Z¯ùlSЪ2ûƒ(9xݱkw0”šz­ÙüóÎiÏsÇ\‡äõXåpBòOŸ}zá ý ‰ý¬ŠÛù¹ßäZ.F=¡t(ž¹4”_¿^iwwã¬_±ÌßLìÅVWy?v±No O%¿~ñÕÀ‰›A_43“žÅÕ ÷"¼Ÿ‚VU=E£ÑE­òói8ÞùÅ(ÚµwõSJÑžõCßß ïR?ÔõCýP?JñC>Ÿ€õSÔÏÉ›õôó-%ý„Â("o:Q?ôóuôó‡ÔõCýÔ­J™¿oEÿÜÕ¢ûCê‡ú¡~¨ê‡ú¡~¨êg•ý_@F endstream endobj 23 0 obj << /Type /XObject /Subtype /Image /Width 193 /Height 86 /BitsPerComponent 8 /ColorSpace /DeviceRGB /Length 12540 /Filter /FlateDecode >> stream xÚí}[ÉÚöïøvW%g1G kØÕ]]EE‰*9çœQP˜1 J”T”4Ãd2ˆ‰3fpwÏu½ßSÝ3CƒÇ×÷x^Êûj«+uuÕÝO¨®šëkšg0ƒiàfÂL˜ 3á5¼zÑ5ƒÌ`3˜Á·‹—=3˜ÁtÐÛÝÁÆ—jgÓÄ7D¡žÎ6/ºÚü­[` «ëª[›Ágƒ=ß…ØkD¼†Z·¡£Eô‰ýgÈÓÑ"që¡îÌ"Û7z®;[ÅÓ§ÛÁÿ×_ ŠyM]mâË"†?]íb ¿qdhêά|Ùýçþ!Œ*äÃïa®»;$Ó¤BNŽAAAÛо˜×Ø.¼èjëínÙÓ1¹Pøóç )¨qMÍ`ÚøG)Ä@!§„܆ÎV‘ÆYþDÈ)r ÙáÁ~!§¡§£µ·«ý%È¢I€tÈý5<8å'72ƒéã+P0ÔßÖ‹ÆYþDLÕЕ]í-`Ýiô r›jg&ú[§h4˜ëé8rŠ˜ FŠv¶IaBÆó‚\(%5¶0ƒéãëPš…(’ЈO¤ÐTÕg0}üWPHÜÓÙÊÕl@ ¤Cî …þ‹(ÔþÙ H\#…ZÅÝí-/ÀAĤ@:äÒÂgðá«Rhüÿ-®ŸH¡©ªÏ`úø/ PG«˜qÊÔKîê·Þñ_A!“EÄÄ.^¹z›õnvº½Ã­Û·ÿmõêê(ù‘nžÞ÷JÿϧЄ)þ[ L#>™BØ7ò¶YïÂ0Ù_þÙÄmZ¸|%“¾ÏÑ)÷Î[}¯ƒCÅ“')ÐØØ´õ·.ûŒ¾}3Â1 )$êj—05é‹(4EõÀÅÃóPrògTülìÞg›|Д•qêtTl<O=ŽÉIâ_ýŤ# åÝùx³ÍÍÜÕë7ØÇÊÈ)rÓÖ_ŸTV~F·¿.…Ú>ð€hÄ'Rhªê«—wòÑ£ŸQñ³±ÇÎþNA¾Æ¬CÉ)qI‡&§ÓÊûx³é™™AaáÿöêñI‡â’’>£Ûÿ juµIz:ZÁ~fR r§O¡»m9b·?X#¿îÜÙÐPþÂ…õ›ZºzMtl<&Q;––Å–®²²¶Ù÷üù3&ýÕËÞÀÐÐÕ?n´Ú°142òíÛ×êòÇOœp<è¼dÕjó…‹Õ»…Ý7oov.Ùd ô¿OLNÞðóÖeVk¡JWg“îìîqîÂEuk—sr6nùeÑŠUÐO.—£N¿›}þO§Ðø)þ[ 0™F|*…¦¨þ()DÇalAÎ …B'¢ãâ!1ñ‰ÃÃÃ/z{×nÜ\\R¢.¶bíºú† ÃÎ_º {ý²Ò$>¾}}ïß¼}»ßÕÍÝË[]ªs¸Ü?ÿøã_ÿú ¤PaI Dà”Ý“?>|'> Y‘DŒ(Dg))Dǽýܽ}^½zW?švǤ#F(;¦L‹Dl¹t9—Ë•ËåÍͼ#©ÇÔW)P¾fÃÆÏ¨O¤P#§éä™3QW_÷(„cRøD MUý#`(ÄÄa:r®]Gž.«««›·h‰T:Ÿá‘ÑÇÒÓÕÅÒOž¢H²r æîú­›mm- 7^—èg¶µ­N_ôt3åÏž¿@’8S)²ü|IJN-ÃÄ›¸ ßçèx;/"ÝÝÐì»·o ƒ«€m²ˆÇçAtƒ)èìl_²ÊJ @®;ª«/q¿¼lÍÆMŸ1PŸ.…4²èùóR¨½EØÙ&î• HtÈý"*,.bâ 0 àe3§Ññ ÉGÆŠ¤nÁÓÏ/ýÔ©êÚšùK–ÁÌ2‰ÃÃ0×õLù‚¢"uùéP¨¶¶v‚²Ûˆ¨èfW}‰·nYïµýG)4™EŸÎ†B¦øo—I5âS)4EõQ¸AÇ… ™xCM!U1%…TÅÒ22ÔYðøßÊÍëèh‡Ùììhgù|J½/&4 °±wDÒÔ™¤ÃÉq‰IL\I!:Ž(”›‘îî.‹ÅKA·‚³¦rS&o. $TÝ$þñaô袸¤Tí`ÿ{&=6!!þÐáϨ¿k ©Yô·ø3} ɪŸH¡©ª …˜8……Lli ºXt|<»ØÊµëŸVWõõ½={þü²ÕkÞ½}³èäìêîãÓÓÓzÄÉÙÅÃÇÞ ÍÀ˜¹72<8¹3 …˜8³.ÄÄi åB¤¢_P0\E, ô÷A'½üüÞCÇ[µ~ÓlÅãÇ©ÇK$Ⱥs7ì¢÷ïû˜¦6ÿ²íéÓêϨÏ0§ëêëŸaNÿS’™w`ü°Á¼Ý€Ü¯I¡'OÙ:k§Í¾&‡¡J_ß»àðp˜GpÊÂ"£ú'7‹¸Áiúu§5h={û¿K!„Ô´4`¸àÓ=|TÁ¤ôòÑý²2ˆKG†Ï]¼øó¶íÐÂÎ={=~Âô°¶¶fËöÀïC¡ÏöÈ&Lñßñ©š¢úGðattTN1ñ?þøF2'qÙ_ý©.©ºc2šøëOpª>@ &—€âG €,XùIÍ2-Ã@AãЄΌ*(¨ÈÄ V ¤lzÕUÀ†‡ 3-PÄXËÏŸ?ßkïÀÄÁÒV–««Ê¸{y••?øŒQb¦àÛ§ ³UÔÝNY éûyú ÐR¥àë\ëox:™–㟛rÿÁjùlȤÃñ‰šªú—P(¿°àë\ë?ß …F†4šm“˜w`?³Á¼Ýhc(4Eõ/‹?>|@>ÐW¹Ö¾&…&LñßÂ7A¡ÿ›øV($ÒD!±€Y û™ fir¡ÌTÕg0}|U Ÿâ¿éð FÐâÓ§L¤Ðâ# MQ}ÓÇ×¥ä³ñq Ù¬‘B>C¡ 1œŒ¡Á÷¼†ÚO¡†Ú¡Á~-Ì`úøZŸ"R0×Ó¢ÐÐÀd¼éí4Õµ‚"ku¶‰Á~fR rœz(©±…L_‡BÃ}BNý„)þ[˜Üó¡÷Bnƒ˜ÏQ›Ó“Á˜ÓPJBù™éþF)¤Sb^(³ü‰`÷y°¿ïEgÛóª‡-¢æa3ý‚)²É —…PJÖ=}µ î̤C¢¦þ! ‰Æ)þtT=(QãéÃÒºª‡¼¦ç—vÇ>F!È…2P’ßôjA]vS3˜>þÙ_©j¨ýÕ&æM“?¯I > æsA¶|œ?Xå¡S}¬µ|6T³Ð.CB8ý)þ§Ñ*â±” õoùÃf”‡ZÚ™Át@Ï‚àgá@ÐaÐíOï9SX]WÝÚ >ì‰øÏç½Î,dƒ¡Äg`B;3˜&>{"f0ƒÌàÿf|çÌ`ÿ»PÈ©©0ó7g§„ Í„ Í„o”B/^¨xô ¢âá£GKJŠ‹Ð¿¢âÂ’âBø¿¨¨ Å‹î•@(¦ó Š ò îæ@±B”ŽP\RŒš@u àX’§àn^~QT.Fµ‹‹ náÝ¢»w ïÞÉä£ã]8Ü- QˆŽù…ùÐx}Zt•Ââ¢BèQ!„"(Íб&ZÈ/ÌÏGm@(¤tÈG¡@‰»ùª#*ŠþSÆ•"…ª ºlAŠéPBå TYèþaŠK ‹J”Ç¢{4ÐiƒU„. ºdñX„{ àXTRTXR((F£7^X\PÄ4(¯R@_®€¹.`5R Ç’Rt,--)ùâ…p¼GÇϦУ‡å 9>ª äŽc8®ü™R’$(§(ýð-E(Ä(A¿Æ"¤œ¢ ˆ&¤ä¤\A*¯¬PÈr9*I €3-$Iÿ6<ûçué&¤‹áÔ&I@û 8B1:g~ÂCMá2Ã#1 %¢€.D1Ý+PP˜€: —fz½@¡˜вÜÔ…ðaôƒ* 3V|T1ªP(XíSô°P$5Šƒ}ïÐm :‰Ñ„ÛgFc ¤º+ã©úí|8%é¡FƒL2“"‡2Œ ›" .ƒ‰ƒ¡ÀeF ‹ Çè8Î F· mRt˜D’)3} œ}9æfÑM±ÉÃÜ}_ 5˜uú„Ì©º"EÁä²K²[`75!‹=ìêª4=HÕ€«›¥ù@Qê#“ ÎãÌXî¸@Ä„bì0¹:yÜà¨{ËtuÂLÅ„˜<ÎìÛŸ0&âìÁWR¬[+üùzô€¡Ù˜ú×¹Ø,BO=©ì?ý€+ÿ8©º)uœSš†b2…!ÆÈ(ÕSÌŒ˜\5#*}û'\=Åʦ&ÏøGR4r†I¡ƒzŽØÉž”I¢&L÷T3«º5 ]U·Ízä¥ÁtuŒ¥td¬¼º«t;ãêN“B ôëM¡V ÌÃÓMk7e—pŠ!\5­Œ:£™’cˆšTr9£[˜–ËUІÎUÍ;Sl”«5¥2úwA®nY¨O ]&±ˆdMÓ8IÈ覒 ›ê¤:Áæ“+9‹3ª›‘Ë'žM![(Û©ñr›PÑrœLf̉éK¡‡´"SR'&ß,ÆBjL°H.‘š•Ñ$™,W(Í“±ˆ*(èWPr†Í:2‘SC>E˜¥Q(MNgK6Õ­‘BädQ3A±µØTúšõ(¥èxþȧRët›êÀ¾„f;AŽAäËH!šBcæýÃÉŒB’‡¡ !Wþ­6jT®"œN§@edòS¦+µÒÈ¢Q:W …ÆTÞ¨Fõ4!S³T&f²Žc?ø,á¤ùÉ,bsFm¬N¶[&›=ªˆœM!UD®â²‚-…4r‰mt±•ìøgDm *YýEl!’‘B9BŒå£ts¦€’BJ×l‚€hjœ_†!,‚)ÆøC›ÚpRs`²äQ¨ÂÇé4¡úT¶ñ;D5…Ø2gœÂšJ:±„úøƒ¦fŽZz«æM Âp‚Â`§±ïO-¸˜’_Æœ¦)¤¶…”V´ê’0ôø…”D¢K‚>…"ÓJôœŽªO)4F éµ(¦©dËdÉ3‰«ùÃ2Æ…Iæ4ÁvÜMA=•ã½iµ"#ÔFïI¢–tÖx‰1Î0cú€£ ¦®:e:ƒš¼õͲnäKRˆ&…«ÿˆ„Ê©gÜ®1ÎPcäQSK)…ð±òlÛ‰eÛŒ?Œ„QR…R*2tF[éò±G’š }Ô§ D69M Ó ô†Q(O•Wû{…*ò ù àH u ´:&£n”™޲èBZDbx€ 1åèZ•Á™ôr2¢j†—Êe)æHO%³¤…Ló´˜ ™E"ZbtH¶ÉN/ô0×…nb´CÍôÃe2t¤]k5Æl}UDI@:÷K9õWT+‡ˆc‡RŒc®üKŒê¿ˆˆ§i‰C%vè¢K‘‘lš¡#Ã1¦Êd›GE ÿ˜|•Fõ&S=G¨ dO,ÕO½HBè¡ÑHõÄ££2OuAn<Ù}ˆêJ]ñDgÑ‘€µÇáq8:&âÉx$&áñDW,ÞAt…Ýxg)qpD…;bð®h¼3Å;ãeQx{Ö–G¼- kÅÚ#°öp¬#ïˆÄ:‚ðŽi[@sU*ÖBv†àxgÞ<Ò­>†w]¾DWÑHtP¦;ïò'{ñ.È ":ƒñ.ˆàíx‡¿¬#PÖ kõHÛ|eí!X»/ÎZîÄ; }¬Nýð.¢Ûn_Y—Þ ü±vïi.-2 DåŸaë/’±¥Ç¤œù;œ*É£ 0|¤p¤«ƒ`{÷ãLDµÐsµT`›(c‹9*¯_Á.0Ù&¤/ñG²ÝôC‹Þh‹–Ъ­hÕ“·êÈÛàh oÕW´ÂQÞbHIŒ©ˆQ­ºòVCtl1$Åf¸Ð¸«Úr y )0멱â,Âùïê`ü¹ïêb|ËWu–︋q¡ÁϰŸcþºná‹ç‹zërÌ8–„ÈüMÂ7œ¥ÐÎû&‹AÞüþ&ã‘fó®·|Õ›úE„ÀB³®ê¥ï—ÈDÆ—²¶ŸÈ èçYö>7ÄÆ=uódó+gwg_río†Dóî:KL2ö5™ 4/ [ ^×/Æ%f˜À¤»nQ×óùÃ<Ó×uæÜkù&¸PWÚ¬×Q ³Ä„ƒ¦]µó»kæcbƒ>ŽqÇ‚é¿l°|Ç™Ûý|aWÅ0ÏðeÓ©PïwÞ‹º¹=µ ºªç}Œ¡†?˦ô¶Ôb$>‚½¹™9ûÓHòâ½–½´þRê Å$ž(ÆAåm©òŠq„QпÔ8® ’ZŒ· —Â¥Xë>E ðAïƒD_Ñ¢M¶Í’K´ä’9òmªM[ޏd¨¤P›Õb o1¦Ä(½ÅèDJ I¡^|®˜T·ÜëÖYÇŽJö´÷un«²òöµË»êiÿòÙ[·@ÿh·3YîO󗤧ùdžØµÝ#4úXÐýkOf9WÝYáãR”g{1ãÇ„ÔË?U쎎¶‰KuO9î(ý¬Ô-‘©¾ ©}œ…6>þQi®uÛ]œsoî ßÿ²qÙ>Ÿ¤ ç¦'›Ý#ŽxF$†ÃÔ§$;=$“˜{ú»‹öT8Ç%fîo*ß|0$$ãô®[W­1ÁËKï˜Ð—ó]ï_]åé“z®;—wß2<Ñg¨ÉÄ-8èÆÿ¤èÌóvõ%kücï­ÉÈÍÎr²ñŒ<–éõ¥–'‹ 1)DÙ?Ju†‘ïj*‰¨ÕDäj<{­ËƬn¥¦Z¤ÕlÜ"U¥ã%WŒwùÑJ±DJé˜ðwå£8ˆ ‰6H!$XÚ´©–Ù ‹H`È$ˆt(‰¾\üÑ!obC ’\dDIô`Žz*çîŠÁøf²fÓÝn>︫.dn8{ÎÁ;ÀÉ>8((bÿËšåîA~ï9Ëm=ÜžX=áñ̼B{ªÎ[x*Ë->Á¾ºô׿r ¿¸¨ó™?Úø„Ç%|P¸# bhR@eño˜ÀXÚlº×Óµ£rEuÁÖ7 +mýü³²í‡š—x†:¹G†øEù¿j\fãã›}Îv@°Ð;ì൫öná¡ï„$DxFø ‹–z» —¾xbr <üê%ûWÏØù'g¸¶Ö¬ ½zfáó¦ÎÂ9Èë÷+¼büKóº2¾‘[ ëï·~KÊô»sõ× Ä ²‚m ÷–Ú…D¤s>‘íÜö´ëã,ý"¶>Þb˜3Á`çÅËðþò»Dä*2j~x!{ɦšwÕQmÏLpŽT¦{]Hå£Q äŠñK‹ê¤b/ŽÄ”Ä`TÜÐ9´¡¡C!jAD›jÕ"%zPF.ÑUˆµåB]…ÐX.ÐUˆtåƒÎ§&ûƒÃ@g…l¼}šWæœ^—uÞÎÓwï‰t§ŸFôÖ,s òh´´óp«,X—rÂã™ø„‚ÜØZuwÉÉ3®q ŽÕ÷vŠJ—ùFGËØ”qÆm»GtYÁξçfwoløÕÙÿ}ó:ÏÔÞÕUT±Î#ØçÙýû}=jJæY„<•icíûºq•Kˆué†aþ|ïÞѾEw*o¯µ ßQS¾Ã;ÄeH°¨§RÏ'&¸ñþL`ØY½8#sGTj4ÎÓóÌÜ32êeõ\g?ïÒk«’SEVà|]B¨söÔV»ÀÐÇEÖÅ×vœ8í/®\W_´ìÈ©P— ïã§ý1‘‰_ˆý;®Å[ZÄ”.ÉPˆ”³}v9£¡d¤ìÍKˆƒâ“¾|1rx½Œ8k£À …лd‚¢]¢QÚ]š¸¢¨æ­§Æ%[ ‘^Ù•`ä’B1ª^òak=Ù‹d…Ä@ê©UK!1†Pb]9#p$z$°¥Õˆ”©€?F¤ØÉ¡ž\¨-éÈ7%…Æß ,Ö&6ÅõÂYû¬SÖ¡‡Üíý Ÿlöðµn­Þ¸ÑÁ£·vùvgÏpïSgÔ.:žî‹ ̼Bö¾lÜXuwþÉÓª‹WzFyøFxÞÉÛs!cí“{»\ïßÝkwh¿G”×0.Î7<›ý³_Œ×Á@oNŶí®Bc|žX{„9¶Õ,ûÅÅåuÃ’}!Q> ¬½ƒì­¼Â½“;U–o»{ý‰,_»ïÛwîò óɽº34Á;0ÆçòuG\¤ó¦vî.¯Ï0Ÿ«7ö•ß\ºß/ $ÚckŽ‹´ùe öøù‚…VteàÐà÷š¢œt¿yicêi?L47 ͝yåtÌi9…©>n9š%yÔïU)Œàñd·Â(´o€$¤ØpK#vÙh΃ZÒW慠J¯ ?¼u·¨H©yÂ^úSǃR æÐRJ!M †(riÏ! Œd ä ÐÆpÉ5]RÚ f}Z !³‡â€ä¡z$߀ûûÂKgmH¡.4i©Zü¶i1Î3j{ºðm£Þ¬ÛS»XÇç‹FxfíÏÌ_4Y`<#0§ûšÌq¾qo£…Œg<ÌûŠc‰ñ_5Ìïz¶ã¿o4+¸²1ç’M?g^_£yë“UC\s’gHðÀØ~Õdù¶Éê¿jœû’f­~w.ôª¯y&0Å™ûªiþ`󼾦¹¸Àà-wîë¦ùßD*4ìãš¼æ¿æš4›Áñ5êš½j2}Ñ`!˜]î½E‡3Üß4XH:Òfã7æp _ŸaB½7œ¹˜HW*Ð}Ç1zË1›|k* 4›‚˜êçÉFÓßì¡P 5S®N«—šÇQ#ßrë†b6“qVÃù)#‚ª¡¦JR&# K†½­}<ó3± _ND.ÃãדürzQL¶ÞЋÏ,þŒydc‰ÊwdpQŠ_ ˆ ýجSÓMÖ“¤ë!¶ˆ€0Z4s挊õä¢Ù4¯´)$sôI‘>!Ö­+\p!k{YÞŒ?ïFöÖ÷ –aQN©Ç]Ú*­nÿi„oþ¦VïüémgNþÖólQMþŠ#G튯lÎ:³ïtæ®üœí¹×gÞù¤ðçÞ§fE¹[eóÜKO¤ÛK¯¸{uKÉ­5gÎ8“µëyñšÀ˜ÀÔúy‹p˜>¾ñÉS»_ׯ謘ÿ¨x{ïSóâÛ¿•\Ý«ØvõÜΗ Ë^Öêf¤ÛœÈpºuu·tYÞ kB¨[pmó‰L§Â;Ûúë ¯\vìB Ëñd¦¯bUbªCêI‡~ÞBð¶Êo®>žáœ{}ç`£Qh¼\ªos…¿Ìòð1»+9{ÞÕ™ææì•‰ô¿Ï‡þ;áÐÏ_pò˜mË3«²[› ïZ÷<Ñ;š~àè‰ý]5KÏœ´û"R­œ©^¯¨VxÆ–z0bHÄ•ÆmÀc–‘±«¨ØUDÂZ¢·Ò2lDØH>ÊÆK3¥]¤Ñ+Éh+² B¡´‹0Aë0pˆo œ—TÌ9âWY°Ð94<,Ñ#õ„Â!›KÃ_?ŸïÝüûòÔ ?B¨-(_Öùl¥{„ÿÉzàç™´_.çØÄ‚ÑåäïÓüpmïóEÝ•ùð*6xDúó//¼j•˜æÊ}dÉ+1;’áãæï›}ÙÅ?Ú_Tn™ʯXÙSm–™Iê…#9F½~û*+?&¤Ò÷¥YÒ¸u#™Ž2Q-+÷èNµ=†Û±ÆÞ¸¨´ÙÖµBÓ{vzi‘‘Bzà›Ãœ, #žMG´‹tÁ¢zn,ŠHt<}Æ^Æ· zÃÍfñ‡¬ÃãªîoINÞ–`WtcCh’MHÂæ«ó¯oô‰q¼}ݦ§Ê0çœÎ3=wrcoÝšÃÇö¬ÎÉÙ=À±Ì<¹;úˆscÙÚì³öR¡yÞå­¢§«{ªŒâRâR¶U¯ìk0+Û©½jAáÐçSéÛ#S¼¯]µ• Ìp¡nù­µ¢*«—T¬J9n{8ݹöþznù’£Ç³.ìyùlÞñãû§¹”ÜÙ”œî˜~€S¶°´è—¢Üµ-ÕVÙgwöÔÌ;rÂöpÚQ¥Õ¥K¿~! )W§5þÅuåÞE mzyõJ68ÐÇç½IÀcÖaUér)ŽJûrb1VÒ„5dãïhëȤ2ìV“w¯)_½1K‘J[hÂÂk›II»Ž!']¤£›GFµ¸ZrÄŸÙrØÒ³äè‰ JG=\h@ˆŒ(¾ )|=JŽ’Å7$__Æ3i6ÇxúRž¶”kº o6Àšçÿþ‘T¨3"0¡W"} †”g.…S‘î®T0KyÆ/ê–K…sq‘)Ô…IW¿XÆ7“ñŒžˆ‘áf¸´Ñpó¼!® ¸ù#pi¡ÑÐt„g4Ì5â úëM{ëžÂ„Úà4 r͆yó¾>ÿÁ¨d÷îç+1¾Agåü¾ÆùoÖÇd„£×ßh>Œ„žÁǨ¯~nƒÁWgˆc0ÌÑæê¼«3ìk0}W?o¨ÙP*0l4x[? Átˆ£;È3"…:2žnÛ£…_È©'h%EMàŒúÈÁß–]‰Þˆ…¯Á"–ãÑk°†k„L޼á4ŒÄ¬•E-Ç’&û\ó«É;öU»•¯E”oêiR©Y¤z›¯âA wAË;$j( ŠÐQ…ô˜£€ó®Mò´(Á,J E&Ð!‘Q¹†rál¥™-Ô&ùºPk6ÞëvÐ5ÐçÜ9Û꼃<Ý‚=ß”rxWSù–‹é?>)޶߬à#îZç1 ‹th­Ù0Ì5ßåêô¬ø×à0§ DÿôSq¡Î3H=´-0ÎïzŽMH¸cg-X/Ævn¾Ý5K­=bÝ"ýø?ýæÐøh«{ GÞÕ {¢„Æ_=·Û=($*É£²hÌ÷;Æ8„×”Z‡ÅðˆŒÌ¹´ûò©m~ þñ.-UK}¢Cžå›ÛƸ„†Tÿ¾-çÔv—ðˆŒSŽùW~öŽ ©Ê]pö‚{\ÒÁ_¼ãB’½¯\tλåx:}§gTXzöÜ«›Šsá*sÒRvÅù|‘׬JEÆ;Œ!ÍŽ H‰QÃPÂ:,v­4~µì²#)í#0 “Ê{º†®xIcVI“¬ˆ×Ï5|í¢aϰB“v›ø>E®ÚÊ|ZÃì…é:J )fµ‡?Ž$"‚ï)þlНÜ£à”Jp$?PFFͦ„?Ál’§ ÇÑùùÁFÇàØÀ] å*r—G&'ÞýüþÖìô• w{í{P´ÛÖÛe˜·PÆ× ·Umæ˜îó ¾w{Gãk7ל‹NÝÏ×hjyhá)åYÈ„F‘ÑŽÝϬ0‘¾½Ohwõ2‡€°ÒÛ¿€½½×7$ê°·o¸·Ldq>ó—Òü½µ…+Gܹi=Ì7Ä…Z ÷,â’½ŽßqíŠ]H¼cÖy‡ö§Ë'íŠNñ©-ÛØ]eêV_° %Í­®xIxbÈÅ“¿Éðæ=²*¸¼~—OXÚ1»¬ ûe<ýƒnRɵ‹[¯ßØŸ™i“vê  riî•õE·w€Ûewø˜ëPdŠ ›—Èɯ\•Ré2Œìk#EOðöJýU\µîCo>G¸ÅøûfB¹W…õÆdü.M,bŸ’ÌÊ$K©¶}’* ¥ a‚´¨°9À¹`6Mž9O±âÚD èµ9 shÕ¦ƒ„xp› ¹x³¡õƒþqî÷înqÚ!x¼ºæî ï¸èC‰6Ïïí8b]EÁï§}~Wrœ1¾è¾à˜}’ÊÍ#“½Þ¡¹7~j^È´$õ˜µW´ßˆÈHà¡X\`JðBcœºj×BcG¿°žšeN!‘Ź[GD¦®¡aINŽ¡‘˜ÀòÒé÷ ÷€øª,° Kð¸|Å™ä7Ü[ì¸Û7òe㊨x§óôÑ›ú¹·®mÚåîWW²äRCÁ’Ô wÎýa‡#.enK9é.x¼¦ðê†c™;݃²Îº`,íZöõëâOçä=XîWÏ¿}×·Ç/Ñ-.ëLNár‡ˆ— ÏÞ| •ál!öÑš¿J÷‘£‚šôµ‹ò«‚îN¥ÐÊá´„"ÚGN–¸Ä’6´!d°E¤ óˆraE³ä¢9ô í;T^ô²Ž„Pò;šx³(FX¡K=˜PJ¬E‰çPb( …* i*‚Y˜#Ñ"Åú˜Ð¤øÚ¦~þÒ{·~®Ì³’‰Œ€!¸T§.)yœƒ1„:ƒMÆ‹w@³˜X‹iËÄz¸XaØöÈüö°Omp±."•XO Féâèb‚ €0?`ˆÚ˜ÐCå ™ øoùŽ„~"ÆÎÂÅß“À:ñ,E ¿§DÿÍ‚âï á÷_Ä©G{ǧøn…¡ÐÈôZ^ÑÒ}£O…§]ŒÌÌIÍÉ¿v§|™}B]£àm_¿SHšmÔɬkÅ‹í£}R²‚Á'|ÿ;Õ‡®ÍifÃÛ„æTŸýXï[ä^4ÐòG¢#ò1h^Ä_ FL ´šé¢÷-À]…x6ZÁiÑ›ˆôiM@ ¾£«k#Qƒ¦I–:HȈ (H-$Áà¡B¤h©œçÚݰ1<Á±(ךèß¹´)"Ù“S¶&ú°ÇÙKv©©{ƒâ²ÏÚÉ¿²58ÎóIÉ–àhç 8·Ϫ»;‚ý’ÓÜsÎlK9îv$Å6^m C]¦¹—^ù1üûã¢íiÉvñIožßé|áÂ~ %.Ò¢e—6rL ’G ‰,O$ΰKÜ›M?\:ôS6 ÉjDÈ9ÓwêAaªÏÆ5~˜ ‘âU5K÷†Æ¥ßhoë­¨lª­]¹[¾Ä6þés^U5g­C|™[ÙWŠÛFv¿x…>aÐ ‚4[A$ûójM_q¢w(Ò¡vŒo …TzñȯG' ”pô”RF0VF]Rh GÊ‚Ö8b] %¤i 4 Ñšöl9ß^‡Õ¦O" ŠÑH×à¨è)P7`¢Ñ:NèóE ‘¦fB®H÷Øñ½M?c"3\hçþõAQ³Ó­½bÃpLJ´«ÈÛ”xÔ15ÃçHÊo1G|o]Ý–|xïáC{ϵ-ºfíãt2c§bë~?¿CGÝZkWð îäütò¬sL´]CéæCG"¼/œÜR}ÃéãÖ’šuH£fL3£%/£×hÑÏZ¾˜ƒd,¨9>­âyè Ñ|PyßýÄ"ñ} endstream endobj 30 0 obj << /Length 401 /Filter /FlateDecode >> stream xÚmRMO„0½ó+êiK²tûÅG¯5YOšxPº(«ñßÛv`Ýáó¦oÞ¼ºÏƒÝ}†Q OP~DŒK’QŽRšÆÊ+ô‚Ç0âYŒ¿CžasÐk]AÔ™Q»(Áµn‡­ •Äs­!ãf‚³RiºaÔµî§æÓ .¬®è:í?ÍÊ0bØ> stream xÚíÝytÍwþÇq]Ì´3mM[­V;ÝÆÚÑj•¢U†.(™VCµ¶ZZ´üZª–Rj)MQ”Ú×±AH"Aˆ5²È†ˆ,²‹ì¹"ûýþÎ+ßü‘9ùIÍ/Z7<Ïs>ljœ›ï÷óý:ç}îuo Üf¬e¹(ë9U:C»ªÂÕÕÊÒLeõR—KTò?ÔÅS*2[…/VûÔñþêàTåþœÚþ–Ú¤VÔV?‡¨IjènõýcŠËð_ا¬UꢊUáJu5TYTÖ•öµJvVq}Ô…¹êL{4JxFù¼¯¼ ºþ¢^?®^˜¨žÚ®ÌY®Þ“ªQSÕr¯êtH½ßMõï¥>UcSÔ´¯ÔÜqjI©r¼KmuPn?«ýª£u•ÿRºL¯¯bËJ\¡R—«Ìz*÷•·PÌWÅQ¥µ•uª2&–e)«Ú ¼Uìµç35±‰²k®º÷Væ.¦v;«&ªmuÌSeÜ¢\WªY›UÌL•øJ}JelQ9{T^{UÐE«’e¨Œ¡e¥—uk;¬,)êlKå¼I Û¡<ªLWÿŠU-†©¹ëT@¾ºà­¾î ÚõVS6«7Å= nÛk+‡ñŠÝ¨È:HeD*ÿIji'Õ£Ÿj:E|X}ú²jÒUÙRN*j›*š¢òF©m‹ÕSß©N!Ê©¬‚¿)öÜ>¶ª9Õí¹Å'Tò¯Êç'5ËI½ž¬ZÅ©ïZªéU¯;Tù«ê•×—*uª²ºªò‡>¦ÎÍV_<¬:¯Q½)¿ʨ_ÀmÆÇOÍøIÝÚgšEÅ<¢v÷Wߪ†CTW5¼Z_OMê¯:¸«“ÕÜ]*ðNe­®õ³,Ï(ç®ÊœWþY=©âïQÜ{àv–³Cuê­Œ/ʪ¹–«ÜÞ_m(Tƒö+sÐF9öS‡W*§ujø0ÕØUÙSÿ¬¢öª¢éê7~z/ö´´]Ù;©Ž3ÕªG”åNÅ]`šó¾Š*P¶´ÖZ*}½ò¡~í§ìƨg;©ÑÓ”k²:_¤‚š«…WUÏVªüUõ¹Êk’JýQYw©ë?žìÅjíe>æ·w¨Öê@¼*±*î4€ŠJ7©¦“”íUñ‹*©:ÐQ͘©Zg—UªfÌWºª¤¦*«žò±S“ŸTf¨¿ª¹¾*ðe¯þŸ“ðV4Q}|Ÿúä¸U[ ì¦"w@ÕÂcUÙ·ÿ¡¿µ'ÿ95R¹F«ÑcÕ³-•Ý÷ê×Ï”ß×*ÝY•^UISÕ–wÔðΪñe?[m|TEù¨¢YªúG›¬–ߥêmWócUÇjÎj•£®ß”'Õåýê†=è0•£B¿SŽÕ€”ù*ö “ÊéN>Då¦)c…*é§Â«… ªgUþªúZåå Rç)«›ºQ‡_zLù-W¦F¼¨–y¨Z?ªTáFÅ]ð_k¯žxKý×ÓÚb•6Pø@ý2BuuQ G«o"TÙ/KS_å_UÇb¯|ګɨcU‹­jn˜ |\Y&«ßo3.«…VÏÆ« vjÊLÕ­­ ꩌEe .~¢~µW•ÿ¶h¶JØ¢¼²ÔÔ~ê•lõºEÍÚ¡|¨äåªØOýÇ•ýÞ̤qjKk5¼­jo«Ó ”õ¸*¥¼ª&cÕ²TÎ"ÅU¸5D_P«ýÔï÷SrWŽ(ó™Ïu»TöUþ= jY’jÜAyíR%]W àÖ³åŠh­nÔcZƒÕ顪£Â|•1¼¬2?T_}¡ú„¨³½”ù~y®€­93+Ú%)¤V%K\œÞÛ•[¸¨8Çjwý6º½²øªêUæ'jÅǪüýìÍ•eœ*ŸQO©þª}ŽúñSu¹HqelÙ®ÄÛü¾™ÝqãÁÃí\\³²*®›?ò NëjÎùáEkJ‡_Ïc¶¯¬©ë?’Ò|uêÕ#Kh§"(#¸¬2ù/¨Í•ylÛ U£âšؾüô¢¥cÍY®òZqÝz—HÆZó;¯ç‘¯ÿ;Ó¾P‹>WO§¨÷îVUÅï¼´PMóTo*ÿyÊèZj”È}ñ­S÷¬ã=/rKÕ³¨¹^ÿ„Ùl¬ªüõ’xulºê’¨Æ|¢¢ì”QªÂ3U·µ*´Põ|I¬*®@M—òuFÓÜ‹ ›º¶ èrcgÑÎm”ùçK¯«¹íUÓtå6Iå¨k=ÂðjÍ]Êr@q½n)Ï“Œ3å¯Ñw ´Ëês­)tá×¥îÇ{·Š¬{=Üï Õa­šÔE]|M±å¨èÊÏ÷Ï4'ÒEvÎ 1çÏõ=|—ÆG÷šÿÓ¦Þ›¿ÙSpxòõ?æ¾®ªp­b‡ðŠÃt©wfܾÎGGž^p²yHÔ‡¼èÂGJº³=L±µ“\Òß«üùðûÜÚ%Z?0jÛÙ%ÜX{ךï?Ù!Çñ¼×áŽÁ‡³ã*®N¾Ó͹´t—u1Ÿ@õå .X^2ñá'UžB+®›gœhštz[÷#Ø7TŸÿÈðÞÑ7=slVBzÕ³¨¹^ÿgrU;÷pŒ[²½ãIŸVQŽÌ¢ø#•¬.-1ú˜fÕSè’ »Î¶ œö_19ìn”Ä¥—'gfN¤ŠÅ–?GºãŽÀMvÓÝVLØÝÞiøÎ_÷û°Wø=XWÍ oÿˆpè%kwl{Îs©»Ýáf÷eùX ^flMʲô3¹.˜µ*{ËÇ?“3ühÔ; 'Œ#Ç(b—pcyzû†d:¸¯í°÷ÄÞmakrìM KÉI0×Õƒ=ìCÞ*§·qÖÈeÇP}9—óÖö˜‘°|kÿŠógåuý "†ø- my}@õy:ê´ngïÀá—¿­z5W> 7Ê‘Ÿ¼ÏdîØâ?æÒÌ¢ø#]*Ü^ò½9aV=….s{1Àá̘¨øÄìn”ÓÍνÛ·üSâƒsÓ5çÏ=®¡ã²ÛÏ}sà ¯ï×ûíè»/½ÀïájháÆ’oÝl}r—9—nÜ¿ë¹ý©“3ÇYF±?6äÃݸt¸ç©ÃþR«º‡ÜNÙ[wm ¶ 7L®‘o”š3çæÓ‡S/Ôö~õÜý¹I×õNÅÅ–¿ÓÇÎXlD³m¨¾¨!ñ».ëF{Ú?_y ­¸n½÷ÈQ«ü®†Ö‹l; úœJ\=¼Æx >ûxNHÕ³¨¹ò9H¸Qö}èðæÞ àsiqUO¡ûÖy-ûìÚF[›í}™}@õå?Xx°ä óÙΪgÑ©o/úØù²ß¸rO~û€%zr‚Kj¤9‘nùÈ÷Ç îæü¹-ùøª‹öæ×ÃVD†Æÿ•½°Eo–¼jmZñ³æÇm¨çÞ½âWJvZï6z×”3*M·1Vœ;³2ièÁf'::ûJtÓħKú—†osÅlbf[j]`Ì6§ÍžçîÏthjdKKJÅÕ;ç̽™Ï˜ßcÝh¼l`ßP}:‹úÊý¾ ¾É[*O¡W׋'úÅœ r8s"º6û€ê3Ÿí¬z -_œ°ŒYÛ{Ë2·óìªÏuù¾û}§ywïšñnÕ³¨G›Ó;.58ú~Àðq쪯°´Ø°ÖúgGE>hñ)S–µ™ñ9ûps×-9iXë\g{þûp]ãOÆ#ØöÏ%㣜ÞyšG¾4xÛ#‡úlmq(íœÓ’·¶;ØÕüºåØÕ¨B ×àæ*}ÊÚÅmNh¾sÎ{d'óîs%µâºÏçtlRùŽF´‘f°o¨¾Ý¯x…wðÔ™éoTžB+®›y{Ÿöˆo˜Ò0½û€ê3Ÿí¬z 5W_¯ói9÷œu(Àïaö Àœ¹72èâŠÿ»rÍ;Ά«G¦Kî=yCmÿø—þèø¶ËGƒ¢:XvV=‹ºG¬êþÕØµ\w€›ÆÎXlD›“çÞú'_¹ÐÝÿÑ‹SóÒÌõÔßcÿçÊÁ¹ë^sýáÔ°àÜsSlùTrZ]ù.ÿðo<;º!ú…+å¿«èQk”±ž[àf9¼ìäÞÓ!ÞGN/Hè_q ­¼šó[¡kñüÒQ¶|F1NýÂ<Ú-ƒÌ ñvÌÿdÜ·ëÚº½wüSóëW<ó§½ËÕ¸¹ÌÙ¬ê)Ô\}¶„Å\z$ôˆŽ1íjÊÙ]~7óóÜŸ¢GÆ'^ê“óÈ•Oò·pÅÀ-"Ǹj”œ›µ-ίâÿ±ÜéùŸ‘ù# g¯¸•fÑíB^Jjxîù¨#ñý¹ø7‹5Ú°7NšSœ×çþ›¢’‚&lºša®³b¿Îígþmô»qùÉmù\üŸ qŒxÆíÓãïíz^£/y½t¥µ„{Ô\}‹þY\î|~BL· a>™™wf§YÎÖ”ãß;z¿Ã‘µGÏŸ«“úVÅ)´òjÎo¥IVc™žLŒ‘f.?´~…Ë7öœ8þ'¿K±-®L6çÏ#—"d´5Ïâ‚×EKr3î^P#eWŒâí-Ý.zÍY²sý±‘§–FžM«²<~¸åÕ£. ð.æm|éfk„-ŸŠyœUO¡æêu: ^ô€„wRÆ¥m²ýKt©Cú¿³ûm²îüijüÝèšãŸZ´¤ÄÎz7·0·³‚¦…gЧE”DßWÿLLdý˜-Ëó¼ócjÊñ½Çïøé¾øcÔÉ3.ÉùY•×°6‰Mò+ÿýŒ·Æ,êâŸÝ2)759ã÷0·›üð‹b/ÔŽw9rBtN܈üŽáEÃjÌ ø ˦Øí)nY«?Þüôî¤Ó?D{¥e…=7-+Ï¥¹û%_ÇòOJüÕhlxÙþüv­)´âºióÞú¾smù\<|þØ ¾§ÃÏ$G^ÏkôÖ{­áÆZþ=p[˜lì6’ÍÀÙÎ5|_¿°ñ±‹ÓÜÂKâ^ÊøÌùÄÎ^ûËŸyûÜp6âmùT<ìz$ôä¼³ï&ÖŽÌKµäT^ÃÛÄÊéRSžK¼žYÔs؉—ÎÚô=ÖȘbœ5ÏÈmëÑ®á)çO¿¨ÉYMÌ¿M¨›Ò%m2ÿ(¸}¸ÔÙÙjoßÐÌØÚiO\ìñx¡¥òu±VzƒM9Û›ì`ûóÛµ¦ÐŠëò|§é®÷×€Yôäù«žEm®.od…Ñ/ÄÅ$Ï[ÙeÛ.ÊßY?ôp§“O•ÜUú‰Õ‹ÜnÌyàZShŵ¦<—x=³¨ëdïi'fÚò¹äõÍŸU¸Û<£ð]I>W+O¡Nþ»ïði8!Ôã\w2¨‰œ¶_õøôzfÑ ½·¹¹×¹5fÑšò\ba·¢â—Z×si^z{îaPsÝJÏ‹¦‡fÍÎíTõDê8vÛ _Îÿ5úñ¸F\}€›+¾$¹Vê]«»9¿çj­)tåNm·?Ø2¥Ñåz¶FWê\mTÐþZÏ%¦öLï‘eÇu°™²7åæ\k~Ë\oiÌ.n®ÿzç™` endstream endobj 31 0 obj << /Type /XObject /Subtype /Image /Width 450 /Height 100 /BitsPerComponent 8 /ColorSpace /DeviceGray /Length 66 /Filter /FlateDecode >> stream xÚíÁ1 þ©g / àgÅZ"z endstream endobj 35 0 obj << /Length1 1887 /Length2 12235 /Length3 0 /Length 13408 /Filter /FlateDecode >> stream xÚöPÚÒ ãîî îîîîî΃ î®!‚w w  î܃‡à#÷žs¿ÿ¯z¯¨‚YÝ«{¯îݽ u- k°%PììÁÂÁÊ.R‘Ôçà°³s±²³s"ÑÐhƒ<ÿ±#ÑèÝÜA`gÁ1¤Ü€o6i 7¢ Ø èéààpð rð ²³8ÙÙþC» ¤-¼@ÖV€"ØèŽD#vñuÙÚy¼óŸz+‡€óŸá ' ÈÊ báatz;ÑÊ ¶=|ÿ'½°‡‡‹ ›··7«…“;+ØÍV”à ò°hÝn^@kÀ%T-œ€—ÆŠDж¹ÿåÐÛxx[¸oGÐÙý-ÄÓÙèx; ¥  Ps:ÿEVþ‹À ø»9VŽÿ¦û;úD ç?ƒ-¬¬ÀN.ξ g[€ ÈP“Ufõðñ`X8[ÿA´pt¿Å[xY€-,ßJ·ÈJh,Þ*ü»>w+7‹‡;«;ÈñÙþHóÖfgk)°“ÐÙÃé}Ò 7 Õ[ß}Ùþ¾\g°·³ÿ ÈÙÚæ2¬=]ØtœA®ž@é¿9o&¤l¶@;;;¯è úXÙ±ýq€¶¯ ðO'Çæ·ý]À.›·2€ àÛ$w / ÀÃÍèÿoÇÿ"$€5ÈÊ` ´9#ý“ýÍ ´ù ¿Ý¿È`Äþ6~ö?~þûÉäm¬ÁÎŽ¾ÿÐÿ¼b6)}e}9¦¿Kþ¯SRìðgáá°pòp88¸|<ì€ÀÿÍ£nú[û?± Î6`€À_rßúôÉ^Ïýß Âøß\ªà·Éèÿtcvv«·_ÿŸÇýÏÿSþG–ÿ×Aÿ¿Šd=ÿôÓÿEøÿñ[8}ÿf¼M®§ÇÛ¨€ßvÁùÿRõ€­®$ØÑúÿú<,ÞvAÂÙÖñ¿m¹Ë‚|€Öê +»¿Æå/»Î‹ærªƒÝA<-vöÿã{Û.+‡·çÃým&ÿtß–ç”q¶[ÿ±eœ<¼ 77 _$ö·Qâäáøs¼­£5ÐçÏ)°±:ƒ=ÞBoÅlÀnHÜ(/?€MúÓ_HÀ&ó_ÄÇ`“ýñØ”ÿAoqªÿEüoqÿE|6‹ÐÓòôÆ´ú/ú£b6ëAðÈ `³ý¾MðôúÇÏó‡ìéö¯ø7Ší¿ 7€Íî_Àú|“éð/ø¦Óñ_ðM¨Ó?ãM¨ó¿à›Pð!÷÷í•ÿ—ûM™Ë?]}Sõöº¸ÿyËÿpÞÄýK:Ç›8÷J{sº¿½ÿ¸ßºïñûíx;7à¿zñ¦ÏÃü¯€·ê<ÿß$zÿ«³oôeç|Ëçû'üŸá²òts{{bÿ\ÿ·Éûþó=}€VHË `+¡ûúˆÎß_$ˆ½Yö&Dfiöô2Xü—ݺ<ÐàÓj?…m¸ÝJ¤|ÅXÝ‘¡¿_!ö?nk„nOÑèx x2KÒœÞë@ZšÂœ,>–høFŠH¢-¾ðì êÝÙ£H“ïêɦ^ˆýÛ{@Χá[屨…=ýZ^%ä§Ê–:qÆ¡es4–9ó”p,¤ŒXç>ès7·³Xy“¯äŠILH'¸Jü 79ãïçýÖªµ9Ý{ © H¡o°Æ¦iý%ÓñýËK£bKmHMZD»Ð-\¹ë(z–…+G'·F ~š…JU¢ïLG%XilÓHŽütÔÊë&ÀÊoà+›yæ0+Br×è>xÆó‹ý<÷É-\lÐÁãT3:³?Ù‘,â†^ ®û0ú0}‘w‰°pð›@Ð ]còk°xÒ§e‡QŸ¿…êi7ßï‹ÀÉI9g„\£kmƒSQí)’*‹ïvyBpæ§¹zÃ5X¯¢Ä¦¡”ìÇê6{üÐ^ûUs­ÂÅVL…÷ïÅQ 6]µ÷<#–¬+€ÓñYö‚Š}Î0£Jï©8µ ¿¥Ë‘´Ä«V GÔóÕ–[X§ÇÒµFÛ^—Ý©“ N4NW̼Cþi]+i0­P9õ+RÞÔû zMÕ$JZúŒ#§ŠK/¥¨7†ulêªG‘w±fŽT8C›Pe䄲I4€ž°Z5l77e;œ*[´ÅоïÖ®p¤‰)CçÅ»öõbé©‘:q·jÛxKO•Uª„^wÆøLuŸ$¿ëk+&위إ£†{_…J”zË]%rw¼¯–oùÖBå&æx¿¹€'©Küà­úöpâUO·eO»Šøù°™aé‰å‚ö>õ¹XÓ²@‚–VrØÞÞ9¤]–ò ?Æñd\ÕA·;ò%Þøá~{‚Pó#ðäh [㬩ӸV>í•xE^+‰è³Â°„ …ßó.eñ(ý˜Ëj€œeò{”ë*`‡dè v3¨Ny/¸X‹3bU‰'‰ZQÀ§ ;ú »°—¯÷Ú–­i‚ÚôI`ÖÐ0›Ô)À ]—:¦`ì¥ 䜙z´wŠr›OÈnLøl£Œ’í³´“Öª6ð„°²6~Ÿý¹Z2‚þ;ÝÊ>yèÇ>›ºpÔ'¶+½áÒCÏ„åüáß4éÑË#Ú'° a–gz²ž¨]αS(¦(IW¯â4"|†—ŸVM˜Žý€‘ºðF™ß‰àœšXº7vz7¹Kq¨—Su¥ YjÓûj2çôV”Ò]šjQ~¶6i{Þ•œ/¨7pà&US܇’YdÓòq‡ÀÆý\éùÏ,ÒÎ4Z©+‹oµÏõëË(á¿Ã7d»3ØS8ÇÜ g„Ä ‹¬½¦°–[ÕÞ!Ô¹Áó‚2£Lêñ®¥!›z°éa….ùNö÷ ”!\Us·j(ù3,‹ŒCDêIwZ‹v€‰€G+†Ù.ËiD  º¸z²ò«eB@õ-• ,%oÒ4eruýÑ ?K´Ò<Ã(«™»À×ÐS|å%%5NôµšÐíM½ê\£Nb-K#ðµË-8/îÒE³ªÍ7NÛÁO´n³^þte]`:Œ%•á¾çѳ©×“ DZÑúf—»ég«_…•²{t ÞomE8#AØj¯ ¢§Èý81½Õß±*¸Œí¨_TaAg¿”m®ldçØÊÄ‹ ÆRÁcfãù«¨Û’G&7~aÆ]øÙ°Õ멚l™nÜÅLJÇx*åéxóÙ‹²ÞÁÃg@ºx“ËàFÃ^õq2—aÈøÅÅæR·Z±aõD‹ˆô å:hâoH“V¸˜•±«w\r%Ú„tY+ νTæ¢P 3ù tù,Ù­0!ë!«²¿»½UÔ´k¥Ý3F5ˆÛúÂýáC»´×»[®9kt “jTÝ7fâ/у»i$ÃWìâ.P“,2o]‰æíG]*}\¡”Ï™¬E›CÏ´VqNHb”ëŒóÑ)ÖÑ7ŸueO_~¶âPWXKܺcuÌטƒ´‘¥±Ï+WoDâøÕágÉ9RS§²®Âä¤ÔÑ68dÃL¹ÊÆT4P+ôx›ÎWÈÆ×÷YdÌr Iò~Ó9DQ²™DÜyò•W‚ýçW»^MY/yÚ (þ‰ô…´çÔ‘‰Á‚£×v=Dw¯7 *¯ö½ðåy(KÄ'4‰²Pøº¯+ï䶇½ZÂàÄ̵7.šƒcÍ#迃·²« âòGׄ ‡?6¾Z‡Š?FÀ™ÝìÞZç?¢~è¡¢"L‰`Í;"“^جÛD¤'Äå"×`U„5¢¨{Ë4 ”ÝLR«vD¬>—¿¾£´×‡íÐw‡~Vq#Z:’©m<É™W~¢<¤8a´!`ʦ€Ô‘ˆIšü…Â,Æ…Õ»ã×~ÁKEÜójAqõ^äÝÕ0öã3òHÚˆg ~¬ea+[ʆ\OÃ*@^ýÎ¸ÂØÜrkgžúÖM¤›a\,‘­”èN ^8Œ-©ƒqt¼ÌWÚÏS±C Ù¼£©Èl(° $Ð¥ÀÞ¡%õÁä°Ý/;®vÍpHI:‰crtF}¨í\“7:«ÉÚ•µ€n×òŸ)ýlö>˜ñ¥z¶Îz…ú:z…Aãþ}#(Ûxó{Ö„>þlIpïÒ‚³½Xl{uÕ?2oG.o!A¼^p°À±úá›»Å>ÿár·\ûŒî{›ŽkEÌ΂Õîã’1Haó¶_ñ,b¿nL„X®Žñà䵨É,Pî¶À(‹ÍžtgÞÙϵ}C!d2"Ö]ú9ÉpÚR×ñ%¥&E}ŲÔÌF a;¹?b= n§ÕYÊäëšDp4Ïèžß[2‡SF+eÙ­--ˆÚO_ÇòÖm¸åLǪ’éýúÇW‘2›^ÖMX€Š-K–Di£V¡ób¸uyOcv#wîLX…Áï͚ܳsµêñsI™-<Ê}AuÓcn/m4—²\„O¶%y%ë±´…*K?ʇ¹ò¤†íÌ?ç¹yZ‹n\ÝÚ$ˆÍºÅà"eͦ3­nT³çb“;›>x-âÎ3pf¥ýÈLÞ¥¦:E彟ö9Cxª:Ø®i6–õºÑ9Ñ#Eî qü…DãkdÛ8‡qiÏT‚%…<‡»J™œlêà(Uæ‹Þ¾JCòBÎ0Eãܬ7/ûI G#Ó÷sðÎÜAЕ¡k×iÅ 9H¡02”º4OjT;›Ñ'¼ò›ÉcåA:Ã59(ÒƒÛ0;]bÎÄi/&Tw"iEí1%4¤æ¦“ÁôÒ†tIÃ¥¨3˜odóE[ŸoŽ•(Ò*/6Aæóß¿J!÷ä ¢ß¡€àÎXÖý‹“›×M¶úu<ªhr>‚eˆÏeÇŽÙ]Gé¨rë@²oUTeJø—ëIôiMq6›c ©‹À*ëï½Ë·AK;n ?)j¡¹;žó¦o:âlÔ‹À-§!=*³L¦tÌh¿xÍØ~èùÛ-œ°ÅLgÙ4hμœ*Fû!O»G½ŸoÞ}¿µ`X¾Þä—­ìï*a ¡9cGÍ+觪¥¨¼æKboš;:”LÚ™8HBÆ0£=4¥d-û Î›§¨ŽD/$°MÛ_²îÕ·múJ‰ÛÍЭÏs@,b­:f¡Š±T_Aóv{Á ŽcÕÖKì „›·/Tþ6 ï˜âåªIõú¹Ï¾p[›´¼ g¹Ûríu¯¸í¤Gì¥ïå~ÃÞÍí™ÿ•·†“á{ÅäB×V$¦¶-qä³'gæ {g'ärM9ÒZ˜Ïhµü_³~«Fâ—½æ(a¼$6(–¤¨ü†¯*¢ˆûþì€nQ‚õÖ¡×_X}øëG±=j6ËÂ+ÍÆÐ¨-çN Æðˬþ÷䫪èžfÚ9GYÍ(ä´¿aŪ¦´ež 7÷L¯ ìM”È‚È‰ÖøZð矫¾òÖèxߨQÊ,>“N_‹È&ô ’ç£OQFú°ã@`î<#gÞúû‡}è¿^'g @9å¢k6Dlì7³ ±µF êN´Ü9TÒ›«:ÖÉ÷‹º„¼-Œý®šUxˬ˜þ!@9Š6?|Þ²Ú)Šê…ebs”ÌŸÂö‹¼cÙÏGîV…ý¤‡‹­gÕá–0…ý32?N,ø«.³u¤1µPiµ‰¶f/ Ž ŸôIpë”rž»Œt#7òïpi‹ c{¡jç ëïytããJ2(ét.){(³d·«fR˜ø ÖhhOߟ,ddÐV¹){J…ŽFªaùBøh–Ú3BØ8šbè>—yC[ I¦aÝ l'!×ô8öÊú/U2ãÞ~Ú/@¦c w<&)2tuÿbŽC€#ûå3/áJÀ¥áa½çP…ÿïÖ±½}ÿk³’÷oÃí˜ÓiÔK“±*S½™ø‰¶Q‰‚•Ýã'CuI"†ÍùÍüÜ_\¼ã´s–Š÷ž¾ð'ä€Ôžß­çëÞœTßF§:y× ¹åï¿”Ì9¸])D@ÈÄ—8]Ï]dy}Ž©µdþj”åSº5Œa)Þ’±éF¢ŒßÒK÷@Î5*h^"Á'•¤Ïd¶ŸÑ­I%·+¡;àaò^zݵ»‘q=d›1Ôsö‡ßµå.þ—°Œ/ÄÇUnÓ§¥õªï¿ä5Ó\MÚ"@\éèÓÚ¿ãM\Rë>¸z؜ӛà¬3]!ø‰æ'W{ú©æÏLT=?ûÚt™i½R.‹>²ÚšßIòÊ =K¦‘= [ëÿJl¹‰oÓ— „¨ût¹ÔÃê0;ÌstÔ¨Àæ}†Ë#B“e…‰¸æ2Ÿ ¡_Ö¶UiðÖ5àL½'ÖÂcûý³ie>Ç :ˆÐc~_d‘H–×µ(”¤!åͯd×Ú(U€|J ¿üúœšZȳ\Ë AN§HšE,%Á-;nòuÇîé+1+O†e{Õ•¬0&/}&ø…Â͸v c€þ€l#yÜJÇÕ(®¡ß6¢ýѾ±àÊΠžË:Ò™­§£¯zxÁ2Nkç–zÛˆd¾òCÈÍaÌ`£Ù4–ùЇðéå£`ÄBÂÿ´ÆÒ£ãíP”(”»Qd;C¦’"§hÜÌGÝ QQj@–h1¼Í'ìîCMJâŒÕÈj¬ ÆjÅᥴ¨ÛiÁãMì¯xµ=gé ù«VÎyMLïRÏÆú;«SÂ=Ñ#³4…û6.·›)ÏY¡ƒ&2#Ð~~ŒZnÒFL…P&Vh a²˜è²(`{XŒê oDzEêþ>ûê&Pi×:9¼Oº]äÜ5Cƒ¬$¼:ꓱíék¡Ju¡a…Ï?å|OndVöõsû‹wTŒŽQŸŠõÁé±FwæËºMc üT“·àÚÕ(­É¡J»P6c oÒÍÓ¶©Ê×ßG9ë¶e’2^Šz2¥u—Í$æ¬g—><2å =i¦÷ïÖzr¼5õ¾ð–U8ðúܰJr%õT¿ø¦¸æYÜð00’¸)Q'$Ò¯–±ˆáÒ¶Èq…Xƒ ¤•æ!GWÁa†¥SBEÞ–>WÇxáO_õ؜Ҿ~ï$þ(³ÙÉáq†‡#…ïe‚Ä«2ÎdÊ{·4yg—û­›¢Q+XaSY»µ?ìÓ7ŒÅ¾r®–µæ‰e—›P×OÌuÝv»_B"qûOµÝOMmNSÇ\y®ôLj¤œÈå×q™‹× ÇÙ&81î¨é±<0è Ê–Ž¡Y*¦Fޏ­!ãÉ‘ý»xÝ0äpElû?ôñáG¼ïwØ(%cja‘éS›µ¼<öÓ.¿™êJ8UZìÑÔœ™Ô¶±°˜¨Fã,œ5'¢ê ¸Øö›8)çÓ>W7žB”Ì?p—»†Œ^A¢ô™F}T ºu’¹•ÜGXÎ}¸Ç‹ß§`žÄ jõôˆ­¡ÙJz’/cì =‹\"†Ÿd‹‡à}¨¥a½fëÌœUeF™ÚJâS# {µZ™ñ² *}ÇΧ+Š´Tž£¥±°ãÍ/ß{- Ù8!fÙjŸn¯‚QÆDš»þ€Ü3ɵרFu3ÙuûSâT‘òðôÀrÐ9¼G<.ÿ)…‚r æ¥ß‚ê7E2¿Lòg—×vƒûA [Ââ;àlÇ<”¤&ƒ]z„QÔŒ§èÖ”™f˜E?ólu~„~½õ9›Æ´-μØ}Rµ{ ÎA5z>ú¥íÑí»lH²ÇOñG|S”—*€šºd‹ç"Áïº$‚—ö¥ábUßà0ÒËïk—Íøò6÷šHË9›‘%NÒýH =òË‘ÛĔ߂ é­åá²"¤W$ Š3xïü¼®[«à7ƒ9ê)QÉR‚1!îO}p²aNìÎ…â¾µžZ˜X_زà1ª„ͤŽNšTãiUqž}Þ§Üs€&AÈç[zgµÉ¨‘›„€Eô“œ@ê yw/ãù—¸97æ0>ñZãñÒL.Äšú÷Pýk²·ò:”hôh0V™øM<ÜëR†féìp+œvá¨yÙ„`‡dÅ N² ÍÑèíB´ÛãFS<Ÿ¢Já‘m³Ô/¾/ÐȪ;¼n”£ã+ï;ÌØoqÄý%9X?nŒÔž–~u-WªœÚf§"ä€Ù¹ %*} *BªðéCØí”N8×#yT«Ž%£Ý§Þ›r>:lNÑýd¦ë’ºÆpåâ21| L[7·Ú `d$O ø – àØìþ­èC2èŒ Ìo$»cö„0&Ô$†b|Þ nÃbÄ8´h+ yc¾kˆ_œ€M[Ž®,POZGíÂ’½:Åç° íà€ËÿéO‡cY°›yÒùú­*~†\Ä9¸>+匜š:ù¤±OëbËY÷}ƒ ñ U' Yä !OC´wk±ïÂ}¢~s ™ú¥?¢Ð,¦_‘õ„1˺ÐXäpLE8©8œn3­‚*+þû0d?f@b ½‹…¯-¨“ý(žë».õ ’st­‡Îö\rö®NƘl‚¨a XÍÿ}fyNs‘Ëùv¨H¬¡«K4–‘Dëv–W÷¸âª° S £ŸUpVpê ϺЭ¢Ø™“¾Oúæfpfœ—ú.¢ÿ:$Yù†<üCŠÝa× ÷ekaø°æÌ†rLæ¨,BÁ8ÝÜ©R­—>¤fßÔ_–¤¬†þ1¸BשTÑOfp"všå̾ôiÂPöây¦-ØfÏ’ÜIJ]¿(çÀŸNâJý-¬*sÎÉ9Y5¸_B:^C+û² 8X\Ù¯ùv¯Ñä½³^ŸúI„ü"Cukmt]“¡¥ïñv tsnÖ.“ÒÞ5sv$y~õ£ï’ðq¸•_á!Þu(ËÝXIèú0ñâ;4Õžeã­ pj8B1 `éBl °†Kðp„ê𦡒çÓkœ·tlú­€8^o¹”µGx8@ç~4t°ÑÅ%Á1ÏcÐ!´tØGJÐÜcÏÌûð4Y„ë÷̈»¥L˜óãlÄÊ›p¿(£U”“0õ½ˆˆŸ˜S,™y^à'P¤UΪ? ¡»æ–GâR–|]+E ‰hø§‘!²„é“ÄÄI ¾Še'qñá‹_‰jGBÓô$-ÅŸ¥HÄ^Ýæ \š9²oØë®Î*„ä¯àéÈå)¢–¡lH’´“[;9/¹qK³QŽn}8»…ªMá|S•ÃðèʱìžX$«µúA\à‚´G#æTêïRäDÁøSS…Ò?˜cê9u™kž}þ¼¥s,ÅaÝúæ»añnQÑa:ð)3ž!OµŒG LR›Í¤¹vPŠ{p9ìã°6é GN9ú„,¢‹ ï¤)E¥­ªðcª°æi’¬G©JûÄ¥ä8ü-ëŒ5IAþÂÆéà×§…;’¨Ò”ö1"õg‘Ô ßjäX—:ÏÊe­’ Êö0@ÇÀt,s”ùµÓhr ³¾&ª·w-Hu î‹ðÅ‘§H×7žA_ ÏÔ¾h'!ª NêÝW„:àû5º‹ÂñC:{³ÐýáPÉéîž:£7Q¡§dêú} ÜÎŽ*oÚ£Á*¾,ùÐ18Ÿ³µÞk6@c±oÑ2tŸ…k^i ‚.ÍNL³YüX• îÉNÍ;¥ "Ã65”Ê% Êœ8øS—è/‹3Fè'û É;9Ë_ g«èÖĤu $¡ f„$lïÝgßë­Ò2N$ûxhV¨°#Ölû¢ž¸F¢pàâ~ľã*,—´_ÚÊÚ˜  †hŽkõæÉ5c`M^et­vY"S‚;ÛR£œwÍ¢ÕYÛÓ Ž —ì+Tº2$ŽÔÉk2›{“|yå*G`ÑÀGù€äR ØñÅŸ`O‘Œè ‹SÌ?ç:jâlÛx?Öåàó$ˆOc 5O†Û?-A(¬LØ 8„Ö¤y}åªÞšì²-Ü)Ý8ýÞï”Å£Y>Õeß&‘ }ÜFv—!:­RôM Düyäâ÷“~ý"ÀŒrù;‰»6×–ãÜñØ©„&¾ALOã]D^ñTû§¶Î€ãçÈÜWä¯Ð‚iIt$ñëLòï1r+S Ù«û2Äëô±Þ)Š3ûSðe¢ÖÄ ´¿Ëaçò?õ/™ãñ«:‡&]4½>åõÈò¡¬½‡bÊŒl‚>3(«4k­#´I2ЕÿñÈɦ@pD'7NdK”·³2|%´À“xœÁ 8õÇígŸ3¥ò0G`éâäuwL9÷sä?¦Cöh¶Ò4ÌRG7©jÈhlŒ®ö\˯õái¹]Š­ÅŒ=êõ´¼=»¡÷ŠÌVæ±:üv ‹ì|J›÷D%Úd¾5cR¹_–—Øâ“žw' 2°&ÿí¸~! ÂŒGUë¸t+€"5‚ _o76·AÔ¢ŸÌx:~_ ðŒœH,nGkFxíCImh„%¬˜OÆ@*- Ýâ Ímü«¾gIö‹&zÆlü}¥›ÑëlŒ,nâê9Õ9-ÿd°`4ŒËñ{¯›+éRêüÛ‹òáVsŒõjW»«ö²WæP¶?xÄ›Yü [4Î×s˜Tû­™£lj'¬xÏyƒôà}'Œq¡[$~~^ñ1«âBK<äüÚK3ò°.ãã¦ÞÌŸ±d•f·Ö‰áv_+v¯ü¬‘„n.K¦·² }nfÙ;– ¥ÿ~g Ö„‡ê”ær´41ÚÕVƒ/Ø´ê§yAÂ*6³7ÝäƒÆ5Üëp„?ÌâW‰8lÝp¾¸RãÆ8N« ±Dƒm- ‘ë»P1Åã0\WÑΕå‚1£f )ÍsߢˆÙ}üŸŸ>)Â^çv9nËÖÔ×—¥`8†ó¶¦À@Ä^Z‹kGúÐèJ¥Á…°ø•l,F}øÌ`n—ñûÅ’¢^*0ß–i¢ßïc±Ý D±âZ–ÏQÎó=îqiá.£°º¾e”)˜=¹åÁ9(V*n>ÃRÍ:'l?·×Ái~tã»!?3Ùs€ìàÒó޹Þí¸Ô{ü!;óů)>õXû—È^îý Éê’,±ƒ,ߥ¡²öIýómi»'Ü>¯ß¸Q™9éÁÖwûý áH„£|,"TKö½5Y†‚Õü¢è©·h–|sªÄ,^e•Ú\³¡kfá»§êðìPTEc½¹£¯i¬¹áÊ‚Û`7¥H`4:"Ÿ7–YÍ WCñj­H_uÝ*†S©33¸Òw„éèvˆêµ8ïÛÇù](]Ú£ˆ“\½É—!)M0žDî¤Ñ@‡œ;U‡Uñë®ôÁï½–^'R?Ín{5H½¥U\Ý­×ìØÌ9·#>X74çv¾>kIuUSdz {³n¿’q,ãÚÄá æBœbØÊ›ûEÊ¿÷§–ƒùÝVÖGPÊ™aÎÛÅÁá44Ro2a)öûÂæ _ÝSó¤UÔ2¬:Áù6é·¼ xäõÎ{žkœ‘äÄYdxL†ô„eœ–Bx¤[#€ËU"îC¢ ¾QŠÂ†¶P²>©§¾ƒf¦ Gç¸[V5òî›ÕF©çlÃ÷û"ÛøB|ærêá|e~È=RĉP7á*y°Mç­$ùxR@œh—ܾ|‰'[BÏRïS©õ±,!Í#]¼LûUW"è£ËÈ~(b¡7hóÛÁeuÂužf-ð“0¥Ü9ÑSÐÓGw QúÝŠÉtaF QVè¥î«(<í¯+ýŽŽÃ|ˆ“,Ìâó $¨d·sC(λ®—qàwÅu ÈùC!pA¯Äæ¹?FŒŠ·óÖ‡hGL‡­&ï¡ò;œ¹©aÜÝÛÉu;nDù+/Sì v½¹/˜C=.7ÃЙ †ð¶”ñÛdmŸs‡b­øû45$µû«ö:E?ä˜P Hì¼.Ð\ª¸dOØÏ÷0ûcÖö- Ø,úyEâ­æÖõ¢7 ‘왑…J‡›þpš‚&N±~ñö0î{•aÒÉH¦«[Û sÂW ~C(¬ëÝìŸ_oA¬·ìû9³HM†5ôª|;µ‰Ù±;…½1ZewÒÄXXûNÏÿûzQ#}wÙræw˜©||4,J“h\S¦—jãˆèñÛZïÖÙ†¤ÇÊW*êÒÕää«Zl/Ÿ°Z£íç¦É¼W>›7:bNb%=(ºÚ—"9ÍÑ'Ú¼,>¿ÍÍÄO©Äßäö£'*=>S½}9?Áb…1Å ER)¥[ûi®I<® fSêï~ÁoÙî爤jØLv+“9IžSö*®áŒýZ"|û™É©…}áÕLb¡-âñ>7ý ù‡QĪg¨äë¦Çyê@"ÚFêW¥H2É_ 5ÊŽ‹¨ý¶~™Å¤2ŽdÔ²SQÃk5`ú­„²~ó[ŠŽsM²69Ì´5Ÿ¶„S=Õs‚WñJ^FCMû± žò­ãW[êj&ù(‡=V凤¡¤£BÏW'ùäÀà2‚/1…Vêq´šýÙ'5"TÀÙ=н!¿ü×öwÝü.3nØÚÐG…––ÝÓ+b l!þÑC¥ùÄëΕS(2ùóbñ™9Ðu.p7&qÝ<ÆÚn+ú;áZ»ýM&?šßTì*¼*)íâ€ã˜l°ÄÞ2=ÛÆµ/ŸÏ…ø³OäŽÛ¯ïZ8–·Ü«LT6ùi¯•6iÍ2Њ1^f_ÓSU•꾜¤ BE[¹…U^m íÚN˜(Þ5—àùLÀ,¡ ±¨tì!ï}0XnÃv°äÍ ò¢ˆ Äã"Ó õž) ¥ýIaÕ%÷9X7tðBw.WxÙ84¿%rœÆæís¦ó³"«åPãcZ)iUÃ;¤Ú§"¤={­qô‡¦–ï¼a(ËMûRô›¨ÒZÇŠ]ÑÔ‡"(Ý{¶I­~^l¬öŠòN™PjÀzôó3laáƒzqè¦À.AƒÏ[ãr<­ð ̺¤¡eñ‘DŠÎw[PßÐü›Ël›I~j*¦óòÜ«Yœ.ºÅd‚è!‰E: ¢~³´ÃÌ@¿eÔÚ;žà.šŽò5êzqhx]ÑOEµãÉãw ‘ ÄøV·¢Çé¦"ª­Ã‘Áë›¶ÂD‡ÝŒc²:±>*ÈM8Š{§‚LÅBp'_½ÍP®F&÷w0¶ÄY)øYÄ>ÕôU»E}Цq:U\È!e¤iØpCA!QaáuD‰Aª›MøhùåE…’m’\f#å°@ÝŠ³ÍIfê;t@ÁkËÖWÛâÂ=á‡^l;„úÁfÚÒÊ„HÐcÒ†c¨ â‚õ¤Ceé¯l­9ÉËbá]¨êû_&2JÑ ÝQ¥Úà "‚ž£K¥á7lГa€î¯ µr”‹¿qÔ“7-ã@ׯzËŒŸáeL”ú&VŒn—ÛÝB©Ì{3»´©g¡ o`åUïâÇ9HŒ?'ÜozppY@Üd —!"gMqŽ_ù ¸?Ëvûý"Ó/+V‹ a””°Díõ>¿”’W"Kê+úM ÛÌøö¿—¾¥+«çV¥LÆ–: ÇUÅ€+é´i>ñ5¬Å“#¬BÿMUºçìÅWÏüÚ»¸äwÔî¤BŽ‘Üö¿äÍ”ÇúŸêݬp¿à›­æ’ƒß‰‹:AŽ"2Ðþé¶åB-ðP_º·%•0;Ål?c#L;þ­jk 9MÌïVÊ®5‘OV;ÔÂFµÎýP¦ã;¸ º“ú,ýX˜ú¼’ÆâDê:ÙÄÅE†³Í»óTÍKxŠˆDÆÁ•ÐôH8·„X‹Ë!sN }MÙÝŠ5!›àÁsžE&ô±gI`äõ~2y¨]èWóŒB)I æƒÃXÞSÏÁò•ßÙEÖSGÎ|z¼„â²t ǘB¶ZŽö(Nâ‡ÁÈËÕ›þÙj6µÔ§1RI›1:{Éo—ï“ J}ï¾¾ŒÞ5°¯™•š®&Õ·ÞåvûúJ‡ËvOk<}òº]Íþœ†~‡ëH¶~êÓCÿ‘Ärt—+lG­)röu]=.JHëŠ þg-ǻϳþ’¦çåÍj|œ¥à“ˆÄÕ€„ÕØBÛ2ŠÌÔøç'‘mYÂ`…ά ¡üá*I×xFÎ9ÐÞó|Jbýâ ÑdšaºÁCe‡H`:cÁÜ-EBi\ì-çïëŠ ßO&—i$ŸDË|C™öå¦z× Ý® ,Ég!n±’”†.šÎ –1®CŒõÁ×~b¥Ù_Û}ÁLNÖÝ83H 3ÒúD¤b{_z§ö{Ó$Eq=;¦wdHVGöNÉ7ü,óü@Â#<âo&#†Á§~xg§âòv$§­‰7ÉÛE>$-ÿTÍ(> vë.õáÉäLö*bLäBsO$fþE{êÞK+È/Äði-&õ›uþ”Ðzç«ö(ž¾åð;ÿ’KFÍdš»„4+d¤=ÑM2’ÉÞ#Úµ§ ¾Ážƒ13….ßö´`­C U=›ªUÛÌòó aØér{ñ/J­³_?WÃh‰Ç.ÆÁ`¾—@s(£ ÌŽóÅ‚é"3?çRx¶&>¿-‚µéøQ—Ĉܚ Y¶8brB¯V• ,‹eÀÚ٢ȉÚB •V›o(™ª[ô—ë stUt潸Ûu³¹ˆøhcd½wQK?}"ÏWóÇø îöû îRñ²…Ê>õ}l¼æëÁB:r’¤}¯/ȽÜ_Ȭ¾ñÝŽ¼°Ê2<ôôŽràÌ¢pqa;Ìé>E¹Yè@ü ïéc·®¨oØÜ|˜Ûs¹$ùæ}x*†$®‰*)ØÝØb$fge^…ñÍ1³ _/éH·øœØÄF®y.¢CÀÀ“Ì2õæ‹éôN šå"á 0û&±æ³–>dMØqºgsŽKœ¦ü2¢˜â‘TÃtî˜*(ÂÔ.;9:A»uccé0ì]€ÆagI¶¶²g”*é^¹;{÷. 4¾X¯ÌÖcúh_+ð›_1‡JË.rÚx‘ä‹Ö8FÒtz€a ¼ìòñüƒÖWušY÷ûÙȱúÊÃ{ú‹n3:rï"Gyz¿Ä\†õÁ¢‹3í½³>ÔüêŒèªž¢OëÌ­ Ë“µÿÉa`ãx–ýLÇ•&1ç] Y-åBU6þÿÈ· endstream endobj 37 0 obj << /Length1 2278 /Length2 18718 /Length3 0 /Length 20067 /Filter /FlateDecode >> stream xÚŒøP\ÛÚŠ"ÁCîи»»»{pm  Nãî nÁ]‚; wwwî—½dŸÿ½ª{««è5>óÓ¹º  QVc1³3JÚÙ‚X™yb ª,Ìff6FffVD uØøo1"…&ÐÑ dgËû1G 1øM&n ~³S°³È:[XØ,œ¼,\¼ÌÌVffžÿÚ9òÄ]@fF€¬-Ð ‘BÌÎÞÝda ~;æ?jS ýßî #ÈÔØ ` ¶Ú¼hjl P³3ÁîÿCAÍo Ûó21¹ºº2Û81Ú9ZÒÐ\A`K€*Ð èè4ü•0@ÑØø¯Ì)ê– §ÉÕìÌÁ®ÆŽ@À›Àd ´uzóp¶5:Þ¨ÉÈ”ì¶ÿ2–ÿ—=àßµ°0²ü—îßÞlÿv665µ³±7¶uÙZÌAÖ@€’¤<#Ø L0¶5ûËÐØÚÉîÍߨÅdmlòfðwäÆI€ñ[‚ÿNÏÉÔdvbtYÿ•"Ó_4oU–°5³³±Ú‚ÿŠOä4}+»;Ó¿:ûÙÖÎÕÖóßÀdkfþWfÎöL¶ g Œø¿MÞDˆd@0€ƒ™™™‹‡ tÝL-™þ¢Ww·þ­dùKü–·§½=Àü-  7Èøö…èédì€ÞžÿTü/Bda˜LÁ Èñû›hþ/üÖ|G@—ùmöXÌ}þû¤ÿ6^fv¶ÖîÌÿî/“¬‚–ª†Ý¿2þ¯NTÔÎ àÉÀÎ ``å`°ü5d\oÞÿK£l úwÿð•±5·ðü+Ú·2ý'b—õ¿—ƒð¿\ŠvoS Pÿr=ffÓ·?,ÿŸGýo—ÿþËÿÛÿ߀$­­ÿVSÿ­ÿÿQÛ€¬Ýÿmð6´Îà·P°{[Ûÿkªü×Ò*Í@Î6ÿW+6~[[ ëÿ–ä$ rš)ƒÀ¦–ÿš–É5þÚ2k-PÙÎ ô×µ`xkÍÿѽ­–éç·«Ãém$ÿVß6ç”°5µ3ûkÅX98ÆŽŽÆîˆoM~CO–·]4ºý=Ä&F[;ð› à-=o€¹#â_åä0‰ü%úâ0‰ýAÜ&ñ?ˆÀ$ñ_ÄÅ `’üƒØL2ûÛ,þAœ&ù?èí…?èS鿈ûSùb0©þAo'¨ýAo'¨ÿAoœZЧöÏ›ÎøzËÈäz³4ý/âxÓ™ÚY¿5â?vö¿$66üÿê“Ù? € ø_Èöã[©­mþañ–…ùøýoæÖ"øKkçìøï7‹À·€,ÿ„÷Ö:Kw{K í?,Þdÿàg~«½Õ?à[1>ÿ¾elýøVŽDþv‡0ýƒùíÒb²ûsö›íÛ;íê·Øíÿ¨ß|íßÞ+¶Ö@sð)Ë¿¥ÿºþ+~ Òþí&°ûSXö·¼í­þÁÿ&qø3‹!g Óß{óßòóü%´{ÛÝÿ¡gay«Ú?jÊòV¢?ÄoNN@Ðÿvž…å-¦?o×ØÒø'ß·ud»ÚýÃá­´Îÿ€o¥uù|;ÅõSðæíöøFïþøVJ¿áÿlº©³ã[éÀßÅo×ÀðßoV Ð hЏ0kgÊdUÔrW%‚ïʰ3*0E±£•BÃà¹àØêüð.‘¦2=`ÍñF$q óãò–õµð"ñ³ças\èx•Ÿ^O†±ª;?çDZzÇòEj{Ô…w½ž¼4ý?C7C¶ÉRd;8sPÎE¿sí–r«í)]™ÝQÙ­ä”Cz*dˆÒˆÔó/š¦È1ɘÁ!…3ÂÓ¢¹¡L_ßL¡e½ËÆÒ!zE±xꬳ~½ŸñX)SgujÇ%ÇÕÁ!„¾Fž ôÝO’Åžó,.Xîwkæ/ ÎB¦O^føÈ¸ÏšV R°mìªv^øÅ²¢ÂïEߎ¯.iÄ0t$U¬üi®fû $Üÿe.ºÒr£Ùan•L°È3Yû ˜FÖ¶<ôkêð|¬sXìe¸ Iþq7Ð8¸Õá­U$Ô#D`áÊB+a©¾¼Ä›F˜ S j×Ê`|¤_tIä~‚1æ÷ 8}ÀcÙÌgfÖá†é‚&8áÈö:ÿê]^¦øk}uÎÚM?ð5SñÕ¤-ùì,×’MÂ(=„:'M¢ãKÎj4• _ °~:°”él½‹Q¼ÄX>n“cþ¼¼€]Fªkg®b \/ÀÝêž'ñD³\ãg Gž ÉöQÃÈ~½¿h`p7ÏÙþæÍ÷vš÷gå®a¢_7Ô¹‚r¾üRõËjwRJ•‰€*¼ÝšéB0!;Vu!±iŒFÑRxØi/|r¥/•§ *XPè‘;àõZП/è­òÆúrÝèÇZÓªtG ñ>ýãÊWŠôÝ%h2ÃÖFÍó}uÀòl5;h­üÀ¾¾¾ª*Mh×Hè’+é Ép8F7ñ×%·›2?;Ë á¥xìNb™3µ¹ÉÛQΙå€íñ›† èV4¸¼fbÊûƇhöÅÇ”ˆBoÍáÔOïÇ]v%vÝ4Ã[™¹U§µ•O˜½»¦xÌk„ß/dï²´™Ë†£]<9×pfõîºPŽYßHÙpn¡2Ô'µå—åp~ÐtÐcK Êy‡‰éˆJe¶"º/Q—£ ébUbžÒL®à”Q&'·~É ¾¤ßó6 }q@(‰\„#oË¡váJYÂp8UU™)åqWÌóG Ÿ*n›zø¹EæÉRñ¡nÖs[ ð!…ZÞÅtÆT_ØNÙOªpôÛ¦[¸Qk&¤'¿ÜfÙ„‚y!†öÁèÛ!\wNüZ<“ùuW†u+…²k/‘¦š¨<Ó.)Ö z©X¦HÞÚm†5_…çP;5ÙùO0¶’°q¤ð)AÜžªóvq¨ÝêØÔÛ†ZgP&"/¾r^v H†è³SÉZ¨k/±­ÈîÛ û¯œ~ß³« ZoÁ™ÄðÂJ,‡9L’çÄ lîDd©[¦( sãR=:Ï+ºÐ6e¯?<Æ"%}aЬKï¿“vÊ VßÍkŠFk‰xïiÒļ[Vë_áÒçœú¯ª¢a5a´þ”Œêƒ.mUÎ`Üo•7áçv÷®ÇPwô“f*vßå•Jv%²ºòëµK`ö="p>Îþe/ÐÑ×2þ¡)Þë<&(ÒˆÎÚþ¨r;c(lŽÍɆ'½¦lì2á«1‚iX•5‚ѫ󅈶t»/ ­2Z®ÏÄÞ/„Ïs¥tÁ¿\… k_S“o>§e$lê2Z…£Ræ:ˆ¾…›ûû,QàQWH°E–€žÀº0©äúƒœäzŽÉcJì/Mÿ¯ÖÔÖ‹&“åQ+$Mû¥3I3CzÏ÷Æì*,ØUÃ>€ï<›šMEÀ8'ƒÏǹNf_Ól?xÄvÀÕçíåóÎÈgzàêE=+uD /È- tQÿ¡ ÅÅC.#z¡Œ™·Àß°µæt‡ •Eˆ–Tª¿à—CØ9TÉWú*"‚3èï»:iK¹W§½3WGµ0 ¡µ8¾HÙžËì/xÁÅüÆB-L:#˜dâuŠ!r÷u{ˆHÌd±A"º3^èf»5o®€YDœËK3ÞÛ‹Œ1ê²ç©Í³š¸&ЙÀ%ù'Š@<KñᚤÒT"Ÿíï|t\özù®n¸hÚ›Rˆ+#Ëûñ˜hY†ËÍIRõ·g~ÔD"ï­Ñ'NXŒ–¹/éN¶H.ùÎè}=ê&(í~V®e»A÷3§8 Îöã¢i±HºLï'¯,^lb£êÝ4ݯëQ'2HõÉ<|p’‹ì].:3CbSoæ{ŠEy¾cÚ6i‹•‹±Ý€Pk%˜’•Ý­ÄÚi—|šUë½Æu%¸÷H‰Çä5o‡T©0 }pD«‹VM…©ÐȽ4R¥!l AO%±_’¶t¤Žuµo ¸13ÌS0 ÌQ£P¯Uü!Ç] O§š:{¤ëXöÔ¯}݃~¬íôn©ž'x_q;¯ªüp…8* ©!‘{tùy6%Ø>ƒ"IUS/©£"<Š"³°¦ÈÛ~MJo×-¦áê¦üõ”m9j›ñ¾÷@›jzɸ³A½ëœê“£ïôZ*“­¡m"´¬|³KÃ0öŒuŸE‚'#ŽðÄ6…gÔòÕi8:%ÚeƶEZ7±¶pRN1#g˜Ð»©N£”ç·o{‡Ö„bþÞ«Ù'­Ž{ÿq ;©Î|´ÏýØ%xðFÔ£b04+äŠUÈeºê÷eËõ\h×'Hã<nÜ™|Ĥ¥P ×8Dø;®Imaw5}Ÿóà,¨Ôò{k;ÑÙƒ²x⤠æûýÆpÉ„€÷+k'%kƺaæwÊnì~ÒÁÙ˜^¿á´žêø–¤ˆf1>j£“²‰^q,\>íÞmHë‘N}×…½cIM=6åP¼ã)µdå’ý)ú|YïÄ}Þ`A}U↩Bÿ,¨[±É=/åÔÓäÏK¬JΣωAö`ã^AªÇ w8°ê¼Ñ*ŽïV5 T5¶n;t«5ÌžÓÎà­áP(ª|·¶{²„q‡þõg9J=¾oñ#“U~ðzÏB‰÷ªQÂÉ¡8¥_éö¬Ê§frXéµ¢=”a°L~y ‚oÿ ã‚6Á¹ð¼-æwǤ†WG¶ËþðÈ¿”ž¶À"Š0 òȶIÉB0†«X†ÁKqõ>™X½Ñ|QFDUãÇÅr¢¡«gœÀeâÊØ&DÁ„}ë6ûؼﹾS4í! ÷õLQ|pj¸Tï š¯y·Áïd«­„c¸}¯ ” f–äý¹¤âõµ¤/á³:UóYæG¾Lþ|Ûùmg°µ¼Kü§nÇ^2¢Cì\·Ãd¿Ðvĸ‹˜];Až2K—pJu‰í»l’Ââ`P¢5õùT=9<Ñà€Ê“½"‡¤Ö30Ü‹¦ki~Õ8\:©|]§yª’Ý9Jû­§{¯ëªC0A2”¤xôâždR~Z{§x* WŽbß´@¢²éˆè1M@taXFßO –å@v9õÕòð®Jˆ¼e©6ÃN€šã‹»1@AY[ªdfœˆç]þ»’ lm¬ˆ`a¿¸•µ j<Ä»ôXA¤Œ®ÀÆqi«ÐÜ[N˜Ž˜nËIˆ»Œ‚‹ã³••9cŸ“+­»ù(“*Éø÷¿U]chÌ'¶%=ÒŒû…r·dL!„Õ¤)“ø_aZâNÞ]l!¸Ñý3$ô¶4«KÙz.ËEHÜÝ[¶xϧè02MIòÜÎ`’LÆ^f¿l0™{³­%¥öm‘J•$¡–ïQ™+8MÀMÒÒxö~º©olÒî®2@ò›ž£°é#‘þu¡$ý ?0ò•Øð¾!‚o?´fôÂ7vS¶É%çC¿þ2"ù\)Ê•˜¥?G*Î3áÏ㡪Žsáørœ „oÆeu~ ©"¾¦á!ÖvZu ÔѰŽEdKFsã¶ÚžVKFl^ÖP.„F?¨d¬³Ÿ}׫Ivêžr®§”;<ra%*SNFí÷ üç-•>Ce4ž¤mÙß=¼/çvv_&w¼HZ¹LtF4÷6uè¢ãèp÷!y^ÑŸÉxÀ¿k?ú A_ù œM³ ╾Èþ¥ܽD]aTò? ”Ôüõâ0‹%X漿ÞÍ Å¶qÞ혜&­£G­qì2ßA„<î±e€³>$åN᧨¾ÙÔÀ&€Sñép]¨ÅC6î‹aŠ-è–´5'-¼ão>øü¹I•ñ0íúمʯφjDm«Süçð‚µû1WŽï°ù®}‡?ßmË8:œŠ³™‹¬i£‚œËü:W¶».Z'N&Ñ´?Š_ßðFG-šÁ©@¯âEÀ¨ïJcè1h6—æü°ÜãÑ.r~…WÛÃá‘‹Ã BíV—+1þD¾íj1ß ¨» åïИçþN†:éµÅê#‡|Q©L»i½·—%Q;y¬‡ø&ºÆXgŒëOí(ºÖç2ÞÑÓ½î±üžt–¶‹zkß`;~¤‘ó0ž×»²#bÌÙå°ýºo½‹œø'L™îFÆg9h…ýÈẕ£á& KdæuºâuÀá¿ÏñØ]Èa£y[ Ví ?æ…ïx÷øº¡ìžj5ÀÀ¥î؆:}Ma¶¥ýàù¡ÒZH§Äã2"q-B°iû˜ØžA~‚²?ïúTÎH`TWLÑi””{²Ò6àT*ôÃeèg¯ÞÓÚ8ÌÙg•ÁbEó`º¥–_«A™v¤Q E-—¿-FŒ·¿Æ8×IfO¤òw¡zp_i*-‡z mê·¸yeúĪßÃ^,ým$7mîâ›AǸƒ<Ю&=EãøÒçýmA\Ü8—àMoþeª´mL&Ôâr.ÒOñU~&Vð³BOßÕ½ÓN¡ßãg™OWqæy%éЛ¯cÏtè …Ÿ$ŽŠ’>ö3þÞ iï"¥•]Rãúо¨MT O°sjµ„LH9¹ ²/ûžîûnX[óOx´E4ë$ÅœrN—5ï)Ö(ͦb»¹ƒ8ì·M?üÁRKŒ¡¡' ”åõòr <¨¯~!cgˆ «Û ª Û,2ò!?2.Ó •dÁ’ÖýGß@)æLÉ^<Äë›Ùš#ì›cíã”:e?Ûˆ"as›Št8È:ž¥M ¬É£Ë€{sÊÏÆ`È[ TbF!Xެš5ÄEbëdÕ=ÛßÑMëœÛ»;aØI³³ºÊðÚ$ïû‘ï=Áž³ïÉâÄ:³9m,¿…Òyû*ºŠ>óß±X«òfõÓïWta&§[34“{H±#Ñ¡hè8l"vä÷K”»—Dz£xðÅlf´mTp.Ÿõ%ТCo„ȸçOØúyÝ™E­H ®Œà·sÊRÇ‘îNS^Áà”Ê2èT„¢1t¯¹r¿ƒ•÷N/‘+Á¿¹o S>7âhC.Z@žûg¥•ÄÀö7bþÙƒ$ˆÛª´LŒa¨XG°@hm˜PyŽ!MkXÎdýÎ%O¤4=Ìæ´.’Êòœwt.;Ä !mI÷ŠæÔ•NŸ&í®+p>¸þòòÌCZ"j) BÑÞt¶rK»ÆÁ裨¿?õœ`Êóu$[YnÇw,ŒµC{èâjörA ®ïýÞVµQìqdõÔaåTÚáG—Íx»6ãyRtWi=›4ðd=­[š†D¬*ÂG=cc:ÅÞ\\/§JÖŠý•ÇI¾è[„DÔoÞ¤P•eÞÍÁ¤‰–lŸ"Ë>—«sЬßåí±È`tÁ©Ç;â¾ÉŠ"âÓ“Tk¢¬KVg~±ìS˜ ÔÚ²0ýoÝæý¨üË5`ȰáMXL8°@lïÉó7Œ5‚…øÕó ŠÉŠá~8ÑeÿvÚøý%ˆHmNýb¿ƸBm;_i¸²ºµ¾~ñ¥+-ïŠAÁ8÷Ñ.úÔê¤%§Ñ•u?„ÆòÐàWðÁéL#mÀ7$WïÊ4d6ù»ÅPEã<qµ¸î&ãV§µÙ{;š¶’5’æKqü×&~?ÂæY ½ÜNÇCºDþà6¸æÓX¹­Õ¼KFÙñµ !–lŠX¢nÛ‘#:³§××6gùqE¥Þê­US5“__ÒE4‚:®ð…·ÖQ$\:ßùõÏþtv¶{ŽÖóêdšïJÂ3ô.ç•Z‘8ڄ麸p§Ó OP½ò1ð/ ÛÏ~Niæ÷‘ŠbuÓËh»tT|žã–HæX§X1^ÙÆg #„,/o¹Ñ…©KÔ4ù1éÕZCœd2à]mN2öÕAi.ÝŠRÜ(÷Œ: ¾ßôß,uä¸+±U Õ=™|]‹p±!} G÷¸ ®ëÀž_¬\øiìÒÒɤ¼sÞmóD4³ ‘¯µ ÇŠÞ32ô4å6"Ðê†$Mq¶ú]—„'˜y£|ʪ–U]ÊábÐW ÐÈÝߤ™ïï¹L«Ï·›; ~¼F¼cÀäöoN(*î{etëLü=(è“}·÷%&; ¼6 R»ÁcçU¾‡¿j=Ü…´„e‘†^ˆ,ªfè<å(ݬÙrÛCd)fé2‰$Tðž"T#|NܪZ¶¿™¡*FuY‡‚9ÑŠ$?¶×/¡ÛœX’ ƒ4·m$FLt1â0„±›à#†¡³o|Cãiª[üÌõgZ OW|…=ŒJNGОéfÆä>e§-eŽ‹ ¸þáÈéóˆy–tÚ§]‘ΫI7rŦmö«È5½})¸ºYNû­Y«½,×ÒÊo\ù"¹|<Ü A«ç.le]Q W餙B@-t ¥Þ3E8Ê@ò pAÒ,p¹-sì‘<çÊHÝ"¯ÿ¹¬ÛwsÅ®m6w$°ÔqÁ§]T³W•@8ËN=É|™fá4" eJʵC£§‘óðÀóóKêzšÚQl{=o²µM¨ØmTŸòú¡mö3ÂÏûÀdaŠÜqn«÷à°JÌDP¸ž»ôÞ×K_ ÷/ð BŒv4¨ YÖƒ±Q¢¦— EÎX\´‹ ÒßI7ôw›¡ÞÛý1«„ZÃ&Fýv «Q)2œ^†’ÌíéD,‚áÐÕLãÌ)W›jK-#Wö Ûð7IZ94Ë7egékÊ, U&³zI÷ ÎŽôð[¦Jñ ùY /ëNŽS5'‡¹lö±­'8릵‰+µRÀGëót€Ò3GúU€¦yêMa•¼½RÈäEW,zùaQí³T4–Ö”;Ö’À{Õ‹wn(-´ö¿€.z‘ßíe[xŠˆ‚£=³[zÉŸG´¬*´æÄ9ÐC[=’VØ9X÷ät¾5ðn€ÝHã#ªëÞ}4•‰Já4¼#0‡”0ãp칦\Çå+'ë°¶ûIé:M;¿Q*‚VlÊc`ãÿ»ôPÄiIíæ‘g/C­#’½GšÉ|Ï871åFšbSgœª˜r2™ƒ¾B?ÈŠH´ÇȱãH4lõÙ%<ÔàÝƒŽŸ·8Ê’&š)‹âÊ’Äè'7>Ea_¬0²=°[‰‚ q¢Öú&¶–žq`ת·SvŠÑ˜rqi Sm£y„é^Ñìè‹ùO´mWœ¸„+dHþ›T÷óï,-d*ˇ4ùAŠ!T[LíëÛIQ´QÛ™¨ˆ¦¬s_²b§ÆÛ#"]t b)÷h3Dò‘Xû.†<ý¡nèõÆt’\.yÄ»:RËk?¦S^pó|Öǧ{ïxîO‡qhž2WüÕÇÓÇyy9܃Ê|÷{ÂÚ¯ cU{XTOâÚ2N÷ü*x…0ÔÆoµˆ»³]ÅÉÿUd7àÛK×0I)$£ÇµxÎz ¼\Ѷߧ9ӶѺb0í¶ø¡kì/¼É¶»'õ³í_nì]:AH¼ˆ,£²æ—GLUí­¶üæЖäÄ ›ª7,Ff—€yðDxd¡îÐyפÔW0ïTÅÁOâ¬Ô:Ô)kûʧ;º‡×`‰Ãçïè¶úŒèè{‘Ûü¤ø­’a¤ýS’0ƒ[鄊 ÎBç.‚Ús)f{®Öñ:”—|î},‘¤µ¥:<Ö.`bÌæúkqìm÷aƒùÇà' ¦ëš™kwó•N@xMëË´jènI%”Òg£Ò§›,òÑß — 0LÔQyá7$«ƒ÷ÎáÚSW<Û˜NTËQ‡?u[ 7‹—­Ù¤N¤ Šå_• ª!¡üb,è¨Ë»¾,¼üx¥-×v…ðŠºËŠ¬Òä3ð¢{îûG|j‹q[µ+=k*;Š—©VÚ=^8UV~^v‚å^üÎö ¥È Áyd¤†žHf~Ù¥rÚÍFa™±á?9¡~}$S[±{By©¾ Ä‚êÀˆ½óF+Ûg“ú:j}˜Ù@l®^u÷ÅZ®:RKǸañLB5M˜jÉØ›ºúõA|Í҃ǥØZã#N3=RvS2¯·מ$O«;c^ËP¤ØZ{‚¢p’™H"ù½NÕZÿ`å.ueI‰ ÎNyæýÚYÐDûv8iÿs]sä Y÷\þ¬º â¾È‘·wíÒÔp#’ÊXüŒÆHßÕ $=>Ùv ‹OP”è·Y*AL"%Íf+ õgÏb.þ΀ѧÎð™¶ä‹qˆæL2jIˆ>¦4ÕûÊë h‹,ø3îÄ5Æ`-bmÇ —S£¨èZôßꉸ$æñ2¼Ä殸=ÔËšmé T<˜ª/à³q7‚å—üÅzYôמ»ó$Ú/}…OfíSþ¬â‰Žsû ?Åk2ºmÒZ¤6«„[n¦¢ŸRÒ…a¸_ùÀ*´å.qù[PóûWD<ËLˆâ3çp JNJf˜·Ô‚*”hgÄ1¨H"æ«°[[~sÐ?ØO´‰ÚŠp–§áàìÈ6˜Ú£›è†.ÍPcŠT5ÑH0ñ•žàúvjRL›š¹ÐQÙŽ«oÏ؆‰±z©`´ZkÒh\ ±ãüI–lkЧ„W‘Ö>Ç%#Žu8÷WÞÀÑP,Zň™“1)¬i…Hà²K›?Æ=Nmº»|™š®¢|{8']ä<ÔQÏ.˜m3Áï>Õ}I‡t ½2ÛŠF™íÖ¶W;\l¨¢ŠåÖ-°ÃÁÜäJèõ-¡û¤Ë‚€ÎÎT&{¬'º¾lÖ'òÍ^+0U*ïê4ôÛg H»šÇï,ÕïôW•>žB¡[!ÊÖ°kyK1{q‡)HZéÐ{ä€î–!ãþqž´ÞÖ{gCލè~öÝ8GKóŠ*\ÅO§€Éé¼ß·SUw!fªIèÒb¨ß–šu~h‹²ô.\p3×ÊtG}g¨»tL-YgûMÍ ññûÛÇéö;=›§¤ÆÃáç¹NË>¶XûÍ0‘üN©´„F™Oöˆ¹ˆŒóœW÷–iƒIجT1ˆ ‰µËù®Ø‚çµLW¥s7ôŒJv“&³¢Ï¡¤ºµœôïÑFÇ­— ôÃãÆUs§+WE¿ƒLÊÂÑ’á´Íç›i”£@Õq[M‹EÂõÏ-±Ù%÷ üò^¢qæ6=1¦±4ž_Ù\Óî~Œúù>¹–ñ%‰F÷bÊÜLÞ·U®°TxBì\g¡!ùræhi}ìÝ-š•IÊ%œúq’èÀí1K²³xNN™&¶Ò´8z,¿w?fuW,Šƒªç`êeö&žë*0³Ø“¬Âõ8®Ï¢áxc*ÙªÌ'Î=9GìœÛo>³È¸fd¬÷  $U§ûî,ÞþvƧê 5ËÏÍÒ˜±(.Ò$ôÉï§‘›~À™çP”Õ®»e7ˆ^øî|6±,ë¾UöŒ¸: uÅ&Oíˆ6Ä{«{**%Ñ[ÐÇìÿõÑLË\K‡þ®/8Úî •…§:^äôEik ÛsSL¢ðÊ{Sq”mÌýid—6û>Û ³ÈkœóA×€{jаß-ï®¶×o-I e¦8H¶§r|§B¾IIäÑ<¿‡~ð)0[ v¯Ú&çû®Z³)ò?Ó‹}æ€ï†Û´ÍJ›¡Ê€7ÛáOP\+ô0Ža’“ÐÏ-Êè!N.…pƒ‹ 0’©¯ ›®Ua¢Äó1¡¾\b>yÔê]Ç – õ.…šÆöwxµ±§GO­U°fáMæ5û( CRË8ä}ú~8›32>Ç šè¤_CáëU¨ sc-·ì7 M‡“ð}@RÀø¯»Pcz{÷̦-@„{Ó)ÒQ[-¸¡u¯î±ºŽH‰yc9Ã6|…ÕMKLÇ{X8鳿áæ{hLZ²B½ìe sWñF „ÖÔVá'¾XxF{âœeOÉrµBÍ„A™Û7­ëݲü^úð•?óÓõ1JRW4å›<í(Ä•Ð\iæA4¨¸ïÎ&göµ ˜&+D|³Ø¿””‰™}q¼ÝVH½HËÄÇ| jáCc¼s#“¬+=Nè¶hÅW"ÊÆ×T£ÓâòW }T^_2g Ö¦;˜DÛ®˜VC®Ù“å“E›ÐQs½?m;[%ŒÌgð5S§ÙÃ!;•¬ãààõݧ$eƒà̾4fßc–ÛW·£ A¯?Äìõð°ÃÊsš:S»æ •B"ûï ´k…EôXWuÆ«ÚvHÅ27 ‚rö« P¦J¾N.‡‡>ÌCBZšè»cÑ ÌÈÞöóůŸ×Z>OÓL”<•Ê}.qùÌ‚"åhýnÎ/õUk0Hž¨ Æû>>M\}¤Ô½N+c¡3 N^ꥴñ9Ñåb›”ûŠTq%$õÿü´D!>ÕPœ5W‘ ïéÔÿªç "ˆ†t°ó«ßv=&Ž "ü‚®1TÁ8¤ëvPÙ妯„™?–ÂYã’ǦP-¼iŒÄÑY˜‰DE÷Œì[ÁÖûkIøSä5>ŠT–3Eþ>öBŒG½´¦Lìo–¾1pÏSU^JtV1fT³ì'=Ì(JŽÀÔw¢oþâÚ²ä¶ÜØŠ•øø·j·³ÄöŸU„äï¾C°Ô¿—£B>cû<è1Pß!{x±5ÏÔM,ÏlÙTk}X—j0ãg=N Z«L6a]"Z&ñ(¬ª‚i);ö2îqÅØî!EAÕNAü>M!VÏ. >çìJq~UŒ%W™náørÁû{NƒaŸ7Îúèî)Úè*C¡«ö®0Õ61­˜áº—¥ôž}]u@·ÑÉÕÙç}aˆ³àWU4^3Jsãýëf ¾Øx–~µV=Ñ@PcÔ1ÔÂ.Ä=:|\;—ŒÒþz#³½sÖZú›ŒÊK.„rQîPáóËë@ Ç '¯yŠZ¶Zõ^åm =üoqýK&wÆ"õCq¹ܸQçM†öÖµXOå£ô±ÝyÞ LäYÜäUuTIÓ¼žº×gÕâã`×[ZU¯s“ÅYm“ž‹†”JËø¼d'»éI±¤Æ„o#é)lèÛŸdOUΞüLa©–`\ :#¥‘ü6!,7{w½!…¤¾Õ-¬EP-t|>„]°ÚéŠW¸بIßú25@¯a¯‘ùÜêÓê›|Û¬y.E˜4Ð[J¶ãBpÛ&ÿqEŒ†çHÒ@ypuÇÿ‘õ˜øŒ×uö·Ç·#”ϻÎH³R+‘'Jc—k í¦ Þ_ ™îÉà—™¢Ð6qÅò…ˆÎ0T³Ôc[— $ÍŠ¹§Ô³óuµ½s‚¬w·¡n†‰…€j{+« å÷X[i,¥”i»Ç[Xô¾ï¯œ:hâvgÍpâ]=5nIQ‡vV†E?º—¼y>ÄQù‘OPlI ÝFD![·>H°›yèq®‰ûÁÑ“®˜|:þcðE‹¸„鬢ÛdVp»zµâæ¨U8Ñi„é®GòQÑfió9,ð‚½™¬‹2-?\’V¤ ì¹‚bB?‡‰ HeŸ71-п, ! o÷¿³/¹ùP2ò^×°À8fÆ—Héá¨}’̹—f’u»$ÄoºCl>ÈwŰ?ÛsòžW¬eÿÕÒ«\ššà¯Xù+ºŒ¤l7?J7)2oÄ?yò[Yo²l1²ÃõWÌI[Wr²Ç@ë‡yb²H¬¨Ìn*9J$2®Ó:ûwÐëóú¥CëOr†"#0U%’ÅÉó'°2ûÛ"/&VvŽ4 êÉÐxîwÄU|ÕâYÐ7†ƒÔ¼ÌÈB5­"Ãé¾×ïeж¢ò¿Œi£† (IJ‡ÂPéP— bÁª5NZwª&°2Ä)Œ‹$±Qr&ìZJì·ó{<ŠÝ“}‚Èí:‡“úr>¤=…­Üers½f[Õ´­`ýþŦaûøösmn¶DEYMDÞÍFŸ0,™CÏwŸ=b^êž>ȃ+øðKÄIŒyýë}s1ÖY/#—V{q*v>Ùˆ2‘m3S›b4Yü~ A—„žæÆID_Q¾ý+ÍçDÆ6_u(fÑûÐ]ö…s%nÜXêËá'·ôsrÃl÷9nH8ïºÏ ±ÃÅ|$JÒ¤”ðœëcÆÚ¬‡fœÂ™ә aÅ n8e Vî bRÏK62Œ?ÝtRáSw&`çkw‘t¡¸ >BŽâË)⊴wÛ®÷eÅFtÓû¤öDO9;4q¦íWæ´}ò:™1'RÍ㸒×¶jÌýtÙiMX˜“ç?þ… §ëQ |Hg˜ÛsˆrÅ ‘Í)E‡¶Me>ö¶ë¢0wÂ0å`Œ®÷]êɽìyââyˆó¨Xaëˆ#!&Ó“ýʧJ¢•Nv8¶¸+f!n{u…œå9ñÞºÈ.>v:܆ôIB ¢;ÙÀ:ÌÉY'U=DDÔ¦‡D?Þu<+Ú¼vå«KËŒ“ âæ$õ|I•í3€Ê¥äÃ}lhг—QÜKÄê»ÁB3È:Dâ}¶ãwñ;ª˜0éXíPƒ ïÚÛK~@ É"Ϭ8·½Eà;oŸNð ' _}2¡öcà=bÀ†p§´ËЧ0¯=CFžf²mùz~tÇå"7‰ §ß$8¤@Ó±Hò½ÉjѲ*³°P^>çõà@ÛCl6²)Së¸ƒÄ ìÛÆ¨'¿~µJð. ª=vÔ lóHI…%.òN#Œ!Î󧛑贃„¨X)cŒ¬´Á)›Éty¸TÏ•µ!æé[J£E`Ó^o¯¼ö²÷¯ÃGei“i~`: ¦w`E¤.›a¹5B»¦ÀëÄôÝ]·@ÿ`ìÕÄ\ aJ4Y:ó ß/2.Uäâ@B ·,"Á·X°7«ZÚ¦9ü#F2Á}Þ ßï+pÄМ†èÌuœWå êÛÇߥ †ʤ”6ýZ3“wÕ3™".kç {ŒŸSÍNœ>g¬ûïÌ ÑÞòkÔÏÏKç2ñdRÓ›uÁ“Ë ?t¯ÇŽeïš™0¼?9Ý›g. kËEBÀ{%pAËIB§·14›Y .ò²g"ºÛ%œ’œ×h꣚s{”×ô$lU›Å¨/ÌÁ lQ´ß+›ö Èúufý@Tiò‰ŒDìêl(ó"4!RO¼+ ™3P„dЈ~@^‹ú‘5©éHk€z“×_î³hw#]µ#¶<‰ Ž„# $sø:H'v3&8?É7*=ÿÈÈqú±)~O+kd†²ïsŸiŸZDž¿½ðé“«²ŠýãSwÛw»\Sw;<µíÂB5˜Ý݉aJãÔÕoýä`¸@ªšØ~xhý ‚*„¯„Ù#`§DÏ•Qè\lv’éicØÄåeõ-¦nlj)Á$ѤØôÓ›!/ˢ:ŽÖôdýZzvCŒÚn²… Öú*…Ù¢À¤ºšQ6Ën»ü“Wø÷^Ô_0øÔŽîÛ¡úq?îø®õì ¾|Ö<ËØähz7›Ziã•VG½j°ÏµWëº6:¹Uñ]ú¥\[ûtžeÿ%+×¼‹ig?“:ažFµ†¬¢ {è1-˜M¼°¯B›3Ê0!K 1Ù]ºt-<åuð‚·KÛnŸŒ6ÚV?~„BhºóéwØ£"RÚwS·Ûª£…c7; Å0ji3ÚA-{þØ«@gs…¸ C¾êQ‰¹&͹©ï¯w—ŸÉtMªi¹ö÷{Ùpb¼úlX!4bMóÃ5xŠ9–v$ÆQ»ž*aï~w=bkäÜrõYC=‘|ÎðCÕ‚~_ #zä­-<æ_ºQ-¨jþ&ÁµTÈOÑÿ…ùÎ׋GçU}çë}S«w Ö\F?y'š[X‰bÛÍtÅå6Wï?2ÍêsMÝw¶6¸¸¯,N±ÛuŽ Ür±¿› 2.zT§‡ýZ{jÂlç^÷hq\·¹ìis%hy\;È‚ôõL„ ŠVyJó˜kÈ÷’0’äÑ)Gí4ë Ðsä(Í$símžÍ#…!Û_ùÜwÌ=OdT`’Ñ‹ (5Y½½ 0öÑPGÎW?~ð"‡Úýhsc3Î æ'5ä ²™œlªï8ipmWýÁLýìz›‡ƒãðé1#±]ó+¹£Û-ݰ 윗ÆÙÐt×—¡ºMèƒÆÊ®[šX•òµ‘o„๨OUÙ-ìû‚šŸÞuõvš:1êôŹI¼=Ü'Àëu:úaŽüÉjˆn°õÞ¢â¸{ª,Ùí%)ç+>*‘¯èN˜–•:çÙfxÎÄ„ÄÝÆá” ³Š§²Ëí¸t©C¥ñ½°mñ᪡‹záœàN™2 ˆ…5ši5ð«{w0〼„P#;t6ÖCJ]hq°YU½#!¾Ÿ¾Š4ëœréMIÕ¾¬ÈÁ†¡pRÐñÇ (:mgÛj²8¶èT WÆ»%ÌaýlŠè/Þ=CIîß¿R%Si 6#XÒ?ÚÅ6F¿RëŠûb™Á4´ ÀIñóý3õ6KÅî}à³RöSÌ«7WÁ1ñç¼qÍZãçϺºip?cÐ~›Ë%œy¿ýxtnÁ3‡Ú®îú1½‰XK8ü yú6®È^­½ÌHö€õ ÎÁ.ÆÝ ”¬×«ùºéço´>ÃJksc¨Øáãú|Ýš§øðJëS(xö0&ÈQ©»×S»t²Ä4AíñYGÜ—‚ãòíp­äu® c¯â˜yÕáÛÂ{I‚Hš™Y¹3§Ãs!˜á¬ìšäHN)ÌãG+¹g™›¥³$…Þ‘ ï8X’«]¼©Ÿ5§J3,ú?<ô+ Ûû…Eч¨ ð‰,&‰Ä¿€Ê¾˜Ï¨LÛKqÈöëo[ ¶NÒ.ê1§†GÈý‰÷‹õðòÀkg \§žD˜ÇÃVL 7˜™©oeÿÍ’óþ°žM!\lêr¼’4¹2”ôHßoödpï>¸¢!÷$Šu#Uõz¯&Ÿ†Dú½ý¦ò«e?ÓÇWÊt…&¶_A¶ÐÖ ÿÐÅ­ãI ¥ÞîfÕíÜHE²­ò*ckŽˆÏS&!2d‰‹U~'"¥^¡ìÝè-Ä' N‘GßÂ~¯n×»qöâlcÓTK÷|Õ¢¥iÄ :Ë0~‘é|Â×i^Õ~†4Æ~çØgXkí|DcNBi(],QŒS1­£oÇyj›¥…&®hJHbE¦AunS+x?¿_—Œ XÝÅ;¹!¥YƦÔ[Ò‘%Ù/Ò÷_)é¬A²ÌDi»"]j&iþîßÿ‰Ä=\ŒAåyY­ËéY•t"¯{½Õ½[èÑ0©B©õ9M@i,€rù!ið).úà„¿ëñÛÕUù¼ó|öÎÝtY ˆ Ï –ÖoŶSÆiácÏ\¿sa. fÞ B-,E)¿£ûš¢*ÓÄ«L…‡5¡œõ±• a‰(V(èBÖPßå¼{_8 _ùÆŸïÕÜ6¹ƒL—ƒöGlÖÎDãýrwqmfªáöÍ"Ücÿ7ãkeÎP ÚÚîëù˨=!¨Dæ›aªVÐ%Ät¸i¹;E8µ¼ætédawd¤8:š}|9ÝzR4µ4­§M}ñâDŸµó#Ã9IŠ 5¾±“%¿€Ä(ý*`Øw¤hŸ-~tñA`™Ô^rÌž)ÄJ´Í™X“K y64e:Kûž:m0¼ C(dsÈy;Wðgš %¥$ÂìTQµcÂèÃ)ù¬)÷nìi7eó²¦í¨ús·_ÃÑ\ð’HS•©L- ¨õöõß\È뢭lÉŒócÉóLª{·^¤ËI+~h¹²“ä[}xà­ ¿äˆRÍS }/ß²9 » Ú|…ÛVîæúT7?N@8ç‰Íª*þ õþ¶ß÷ Ï\D0YÂ÷¹’pЦ—ú¥É}T³pAª;û@×9¹Ü«›šùÿ Á >óƒTRž½ò¡¡Ì:`ärcë„aw•¹Œ³l€p¸°ªq˜ÓÍTA\ÉQ>ÁôÁ+Á#v¶~ º…)νËaVvß ¶«2ïé~ÄÓ™R—ºªHàÍ*«Cmrœ`Þ0]Ö³Òå5šæò:ª"Ô+n.yJ¸µW˜r1…«Z8§Ð_æH0‘Ç8 DëÎìú0ä÷~B·caÊldQŽ€{¾j\o8½̸r£ÙÔd¾>W‚î·W<(ãìƒß%Ò+"Üâ2Ü g¹+0¹Ö˜ÙS7tün0‰iNÓ+ëÜ¥Œ` q¼dö¼F… ™QmÎN„åù—G +*_¬&ÚF2;°…±#¦[êáñôCd®$×%Eàcë¸-è_íüE½+ó]ViT´X ¯«­ü]t†£ÅE2°ˆñ"m¾û`ö’IJG6âü¨ ðÌ%ÎEPÂ:*6Ïì"ê<#—ûšÎ[ ‘ÉI_±£_,µÅkª“TèåHާI™ÐªœO@iðô=Mâé©»>ÝÌõ,> k.Ÿog¸ÈHÎj¥¶Ù#eÒKw|u³Íªû´ÐVÓ²S %6¤ ¹7ý=ía»0™›e«ƒ_Õ*ŠQD‘{jàÛ”(€˜3MÇ@Ž„Ã6d¢}2aÚweGç”y)‚j ½Í-Ý 7`¬/¸Hçfïý7úÐ}F©œ|FÚúV O#ëÂûæˆ8ö˜ wa¼ËÕ¦Õ+òf $Fß„ëE†Ð¿åý!g\ íÿ³\©.[r¬ÿþÙC C ·ßã×%‰«þ"ýd•¤Qp!ù}'ž‚¶ ïzçà /⾤ÞXd:ÇW²!:î-ËU®J*”ì DÓg,%'VŽ‹mòÍë#çn±ù-Üzž¥©œº«Qî—nƒ}ª¯¥#bLáy4Ñ᯽O—j¨KO»¤’õô±ð¦ß•žæ…”}0\ü¬˜+ñ±Ö•ݬš‡þ>¦+ý ¬h©ƒ“aÑ“õëÖ](ç£Ï`Ž€Qû¯‰ óþ±àj‰ÊŒ…’"•ƒZeñ BUqSWŒOok"‚×D3P$á'”Ñãd©v½Å'üNSw´.¼h±÷¶K :s@¦ÐE!1 †/°þì¢ðÏß'4Û{¬!`fYtÕò»ôÀÜêýí¥Äš]îeWY,˜26¿lWÈ*Iè\¨¶yh¸®ÊÞkt0RG|ä~dêmzÆO(õTë´‹Ùg ÔQã(Üb,UÒÍëèÂ,/õÓãRä\V£ dF!ü;±"ª‚9Ã8Åä7ôu±ÆD·û*ÈÓ+2…¢ò—Ö\ªÒÇ‘‡+¢. ¸ÍWºX«P3Dsw“nêkê ÃH‰í<ó…ãJ±&F³¥þèPrÝ÷¬ÅŽ×ÅÕß,*M#hnBù," 'KCR„  T°bÖ ”iéÔù9®G^êε&¶+ûa¹T¶jM ]nÛé­ƒEÍË0\Å Þ™æà=ç¶ $/HÑ€Ù~ éJÏàŸº¼faÛ’ú•ÇÞì³§ªÒ¯«f8†êoœÜÆVJŸÖÏkËG+¯‰“i_–Ž›£ëi>i½ãŽÛÎ#Áðd (÷<Ø{MÏ/¦É.•žhÚÔµœö¹ÚXJ¹áßz˜±ùˆ%˜2ôOô¡Ä¥†ÁQ³ª]°ŠÜ_ÞD|Gí1GÝÒsž±y*}™¯($>¦o¬‚ÒSØ%?Ö Ô­é - ½^ØÜŽ9BÁ¨æ±žþ&"ïÄJ,º£n‚f §dÞó÷«¥ïîR¬×¸Tà²GCdQ¦ÌAÈݶ^s&‰Ý`k­R=È^ A‹ãìyP¯N!ˆ„Bà3ÕÝaú'qöšŽ¾/yÄ÷zpé/“ ¿g²—V¿ *Ý™ÙÆÍ°@! ã¸=q"¤•‹×(M´Io¡ïµsS9ß‘-RéiT‘ý³Ü¸Ç $Ž*|ŸI °¸2~W¬WéØÜÐs"ïSVAFQùÔ˜êï4ž D›FCäKö–ù—PÚNðôÏJØ!E½ûy' Oc´NaÙíØÃé·³d²:ÖCÓ:aHLvb—B]íZ|%ÜÐþd ’Î P;;Ãê\OQXì¦À‹Ù·nCt숗NENŠïÐä/Õçžï–KÎHç€ÿ5.z€ª€áî€à`ØÜè+”çç\ðšƒ#¯4,yÕ·ŸÒA0å>e#´õ2§RÝ$‚*oãOqÿÝVN å Áñˆ¡–v ¸àŒYë+§è`̳ÌÓϵ º¨àµ¸-xözÄÒORÑ»LDV¾* \å DÈ?_65ˆÅéè–ý=³lž™—9®ê¾Ñ(F ùåi( .¨lˆ±«u/þ;5Ô{’@œd ä[ƒk¡×bÕ5Õw?’J?gê½4Xþ•à XL-~:+²F Óç²\:8´`5ûìÞ’×ÀÊ« ˜œùGÎõþKø ·Éû’- ôÆ-±DTí‹»²hw²“Ð"»íÜãð§Mì×;šëßr;"‡òæà1Ãô¹§Ãtc·ánGióYhÛd 44"»+‰äíÒæ¿àäE£$œß8 ½ôÊ~\Â6õgM#‰¢u]ƒµ…µ/ߊNàMS‘ìJ´ðl’ËBÛÕùaÅîÆp3¹ŸªÁ ö§†ß;r_J_¢F9šQŠ:`®ÿyÏïðmSóD;äHدu?„hvžÃ~”O s¸×=ßÈöËuVJÛºvK€Âúóá• "Ùc|¦!q¡vÔ¨÷.¤ëû1äîGàòK¥ÿ˜‡ð‰ÎëgZ1È»˜c2|¬ÖU¹®jž–’N™vÍŠ>労[ç™çKd¬>aŠKòÆÊ–û²,ü‡¾xnÛz²qö=ܵëÄÈ„5‡óÂxÁ`f*•èGjÛñÚIš`Z!¾ÁëW!A×QàäùŠ0°2wøêƒ2'@MZË&§Q‰ô×ÈÐÖ2½,‡UY;7V€Ûšà¥ž[—y fÃéêM†²fŽ^n£Òu•c‡5ç#“ ‰p‰È…Tü‚uÃEð›¼3‹ÕO =Ñ—Û?t(¸ã}hƒ‰™ÊêýÂÃÛº3/MrÅ›QqUª°Jÿø±“nï–Ôå¢FqòéÌã7~ÙšiÚ-m{röWŽM‚1@š“7+C#ÿ×ÐàìÊ#›•iJÚŒ©ÉŸàÚnÓÄ ¹+úÇ†ÝæöM¯Û(‹|ÃýŠ`|ºs ¤G¿ÈøkÁÔ¦C3oãÚÐÅ> stream xÚ¶P\Û.ŒCpK€`ƒ; Ü]ƒklpww.ÁAÜ!8 îàî„Grν÷ÜûÿUïÕ®š½¿î¯{­îõõª¡¡PQg3ƒš€¥¡vÎ,ì¬@~€„’;äd9Pih4 Î6à¿Í¨4Z`G'ÔŽÿ G0ÈùÙ& r~æ)Aíò.6vNû~v~ Àòý‹uäH‚\!f%V€<Ôì„J#µ÷p„XX:?/ó¯O½)€‡ùO8@Ìì1Ù”@Ζ`ÛçMA6u¨)ììñ_)è-íùÙØÜÜÜXA¶N¬PG af€ÄÙ v;º‚Í¿ (ƒlÁUÆŠJа„8ýeW‡š;»Á€gƒ ÄlçôábgvnØv7µdû^ÃÃüÇÉþÛü\—=Ô`þ\Øb~~¡z9\ÁgG°×?ÿPÙÙfSg€ Øb‡úŸìÏf°ù_øùð!î}à³öØÀßÏ¿¿ žåeµ³ñøýÏù²iªèÊJˆ3ýUñ¿}ââPw€ ''€…ƒàãâðpñ|þ;‹ ò÷.€ÿ •³3‡øþÚìs—þµa׿ϟþïÙ`üw.eè³hÁúÿhühúüÃþÿ¬ô?!ÿÿåÿ¦ñÿÝ´‹Í7ýÿÿÇ ²…ØxüMxÖ¬‹ó³þ• ÏS`÷¿Tmð_3«6ƒ¸Øþ¯WÎô<bv6ÿn#ÄIâ6S8›Zþ%–¿ìš¿‡ÌbV:A~ß*v ð|Ï“ejý|s8=+ò ü<8ÿ½¤”)Ôì÷„qp¿€A¨Àg!qps¼ØŸGÑ ìþGÃ6V;¨ósà¹<€9Ôõ÷‰òl*¿M!›ö¿ß3ýñØLÿØŸµÈþ7|Ûó*6 Û0žÃ­ÿyl6ÿ€ÏéþA~ 6è? €Íþ ÀæøøÀæüøœÊíü¯Ö˜º8:>_ÄûÜ·á?7ì6EŸš [U·ÞTŠ»±l MÒlk§1°xÍ;¶¹Üa"¿gø’¸êx%öþ[öÒ¦ý¥èù£×~S-rXs’j˽÷ƒQ‚Úøv êÜ÷W}c…ûb5½¤/HX4Dx?:xkXÃ7Á~•§ùàà‹©’wãÖ#ã^Ó[º8:³­úãË´‡Ò –ÍèwÅS4y&ÙÓ„”HÎ,¤(Œ¸'îXS—W“¸¹cOäò L¨>1œE^zk±·ÓžËåNDÔDz„¤ð—¸Ãã´^â»)ò³^%£°Y‡8òå³ "Pçä)è ·ý»½¬F:‘%®Ö"iÝÁ¡mC?®ý}PN<¥[%jQ¢~h‡èʸw 5Ûª’@“¿á°šÂaë]}õ¾™v9”/Îx1ñǶ¯4EƾtLÅG¥ç×ÒË)÷avqWŸ+ìl?±È—êpìæ­×ÅÑÅÜ[U™y/³ÿqQ%§k9³óGª°q”ÊYk nŒ¦m àMôŒ´†ÒÆý˜VQ‰’,Ü:ÕÖ츇žL[²éi4…F¥Îzêµ…µ_¶,.ÁÆ«„K¯ŠG61¯ðá›PµÃ[ü”.ÚMíé½K®€Ý+F÷ ˉÖU®°:R9·{ŒÁDÁIÞ™]N-‚]׌þñÏrd¬!ÐïËášÕJÒÝõÌ«{ýÍÚíÑA§Ì5Óä&ý(Æ+¬ƒæHÄoîpèÍîHäÔø`DJg ~1“t¨G']û×2åZ€FÔŽ(“Oleü³üH&×k°^—w‰Á ãõº‘‚¾c•²88›¨=ÚÉŒPqÚ€·µ¨úÒšÕw´à.¥—ž|Ñá“Om/jÞ¤l7‡™¹úHhbÖíÊâ€VÀдvŽRËmøT |Ðü̆Ÿ×zóÃb‡¬Må€ê4Õèp)äùÉ€¼~yÚæ<á]ÚcQR‚W¤ÌÀõ`ä-–ë<‹ð7 >|Üþ\_ÑFä(Sìtƒù׫„C±mµB/¸P?œÎ¹ANfÉd1Š/38^)w†.¥ÌÌâ"ó³§%WPð°ÇX¼< ß«6ã'oÚ’`‘û»ÅË`Jù­¡ó·íf£z¿æï0\zy)íi$çöapÎÜ_ôþÇš¿_Å`jœöé6ƒP¹Ê±‹^âÛ78ãQ£Nncɲ„¸où”'(áªò\Åñ¢/?÷® 3˜§Øø˜ÇEˆ/Ô¼†üj³ËåLžÁ“µHŽvv!SV÷y¹â÷)ŸÐ°¶׋7D3Vn¤Pi4Ï)†B,È2Ø4Œé '¶ÎÕ¬ñº(̃Åõ/»xzS ϵanäðçúµÄ“âp|PylàÌ<õv– A|=AòÝÙߺSS4'‡ÇœÓþ’ä æ˜¹þ“u Vi‹Þ¨í¾„,»(±ô[a4´s :ƒª†£ `ÊÐÂBŸÚ ú†ÑlgT´ŒXÛÕ&VBAÑ·–÷%nÅÚº]+}A›þGÎgÞS£–LÈŒÌãs|X:–Üe~¦œ4E8–‡Ä+Ð 3kuxU‹È2]¾@°åâÜŸYî7”4èÏL]"WIzô¥KÚZýZ”{fA¶|÷wü!áùz²»ß›1¿/H; ¨0$ª‘^†V³,ó}è|Ic:è8uËú‰g¶{Š%ïã¯ø_uoÍ3Ūà5Ç%Ì¥xYk0ä´^+ý2SB’w_Ôá‰W]GŽ„ˆã©ÙSY¶,#á`î}ÝP0Z »üªtq5ï­)¹’^6Å8rÈØ;Ò9¡ânÛžSéH¶÷r=ŠwŒMgPƒè%O›Z°8› >ºÛGÀµ¯ö VT 9ÈðÚR²wVÛùœE®!P¢¿[ÀÞN6½)&×®P„§Ê~Zy°hÒ¢u ?4Q[?®ëûå[04¼Í÷DEGŒô®¸áSæšýè^y‚<7wY%’…'.^Å÷ËÒ˸(¡_MW9.M:£BjÐó)ãbä•ìÏZ·Ó¯‹Œ©ñØ„=ëMxæsé¬v䈘#¨!ÛÐ]®ûñÍ®vÖ…ÉaŽBQíŠ:eͲÍÁÈó…Ä& C)#ƒJê¼~…M-ãŒú2Ìùm¿[k–nâ«DUí)ÆG0 †rÏž©ïk|ª(ÿ® ê+a¥`y¸ì›Þœ5¿fK`?(=­ra¬Ü?_)†P€ÃtÀî/V€ùˆî+ÖçÃÖ;¦”ÚH'40dƒ Pj“œX£B“5æɧM· ënuHÛØÙoÚÜë·±tž$2r•ŽÂt7);„?¥-çÁ³IC†ꑕܸtÇ “ÛÈoM¡+_C¬LšÕÆ[ÆŒ?¤–QŽúÆ“ã$Gºv¨ÓÍsxäãŸÌÒFõØ-pl;·Z!úŸ©«ÏÖžÒŒËWILu/ŸÉù(vÄE¨ë·WÜY*d¬î&•pÑ+ö%ïUD¥âå²—SðsmR­´ÆÂ›'ªÁr÷ÌîƒÊ<~Ý‹Ziî?±–“ãCf—•±ª¬ ÖbáõÍuéä‘oc‚·j@ýežÌÉ<¿/ëïšjÝÀÅ=ïÏÝ8Ç5>¬k®sÈà!Lú Èí¿u¸Ô z?_±d‚v#€9žaó:+§è‡’6­‚µ÷÷Y:––‘ùÒ#a˜,µ*¨3/΋…•="ÓVÃWV„fÁªœöתû¨sÀ®‹p5¡n¹ïÜ¥úMš¶[%×®Ñl· ú:©‘¡?Óå\U“ÒqYò ëvX;Z“„ÞY¨d–'7œz0Ôa¼¨gDÑo·øJó=i1Š2â °à‹i3ºXᩈ—6ÊïTlÚv,…´*Ôëê £÷ô–ˆiíóð£8?È*GØÅ' o‰ÏrýŸjnÎóþ¡Êðµîƒ=²Fתqþ§oNMׇA¬ú7¢êêŒq•]âà(›ôï~‡¤ëN¼6õ€í0ŸDiÒ“\’hõ%îÖßÈä'"B×EÍ0ÜÀÃ%‚ÔÛ_h¬ÛpØS毵 ¦_#5®±£ÂæÏÓ¬“åj'؇ãzíQͦ©E3(cù{߯ʃJ’»:•³U‰­×ÊöBurQümš¯t=D²×J†æÛ•Jð‰\Y6 ¿È‹&Xˆ‘áREDjµÐclÊdô)³G$¨;üòJJèëT'ŠpQ'¸ëCW4ÊÎ;ÌÇn/2L‡%ÃøäZÄQ&ó¯õÙ$®­pߊPSdBñê¾t 8x1ÿZα)@ó¨z%ùÝ5¼™—‚º¥#ßœc"jû傞‰‡ÆC®_{ K­1«oŠ;ê:Èèjz¦}ƒã½ððcÐÉìÌ­Ë8¯á@`ÈeK¶m QJ²V°oùèD‡®Ù‘²lrƒÿ WŒ4Waú± M|š<\&’äÎí.ýÞ¯C¼Q’ñ,Ûvšì2õ¹Šh§‘cŸ¤—•Eöú¿Ñ™ŠÁ×ëO»bÜšºiŒxZè„×C,e^‘½lص‹jF ‡4·ž¤YWhÖŠê5#ôãB’±›9šc¿Ø·44Ø×-•§Og&ÍWì !Œ+l®7Šãž'VØ!ñ)õLþÈ8*2{1ÓóÆðÀäÕ6xW§²Äƒï–* v|×6‰¸º\JlT]üA¢ÐËò…ÆN|i%š­“âB5Ããôà¬Ð]À?zÛÇ }ÈÀHvŸ’#:‰í^üž&í[¯›õéN5ÖËO«¸ÉÅaɦŸ+ê‘.àQÄj…{¦SQÕ^æeøðµÅ…J¨·(uT5_îð/`î""ÊËâ§âŒ ¾–y«ÉeeVÑZcÆûM’dûÊ:¤³¡Œsƒ?U¥>u@9'õŽÃ¢¬´·B­š»ÊÆ!åu3yÏeôq°ÈôÔìÔ:œtblã Ó’m틹´ï.{Ÿ1(ìDr:M]uü™_ŒøZE@V>õ ~ ŸÁc& 28ÕôN¿¯Â>T— r[ ZD¤¶zZÑ<¢züòß’Dìγ‰A²2Î3 }…©ã®Q:ÜrmóЉû¤' ¹z5H¯,D?ë–åÍ>yú¨û1ÈERî˽÷^1žÚ»ó–ó~#ÅChõb -.oúÁU/Iê-³9ðÕ[×®U€‰éÍܪETMCË$ýAtçèêáÀ 嬒q$ ‘º¦5e_ôz)Ò¨:3iAÁ>¥„õÝKïV4 —Así’H3ÓÍâ§Þ€ÈâÃÅÈ •FÖäÁ©ë/Ë2z^Ù$ó¨61Û•´ÂP#T†Èp°égëÓîðŽ(–Ù`Ñ7:‚TχÍf%›9"åïT—Ýáð5Q‚ë8¡µ±J0è©0Ùûô€So-1Ê:„ûr°çÌTÓ‘Šjkl‹ÃP­X—뎃ïfÐì»3ãÜW7ÜËÔclݰF­K6iý˜§±-ëê É= µz7xEæ5ìúOèX#ÖAbJ]/ªæzT­qBÐýøS¿=ü‹Ímº’w½dágysçLÁî×_®íP›=ßùälÆå¿Õߪ=“œ™nÒfèâªñ#Ú]î•õ U"JÔüÄlÊÜ gÊí•|Ù±zA”—áûríKú™`däÛ¶»¤q­ƒª›y‰}J›tébãm)½|Œ(¼Ï÷.¡#q2 ã‡S†Ã‚vó§€·lPÛ®çXVµÕvüßÁ?sŠ&mŽ*êáŒ8ƒ'#$2¿ŒbzlG‰÷©SaŽ7¼ðW×å.ð…ìÊZiÅô’åÑWŸÝåÛH‡‘3uiYó?Œ°ðd4&w~ÐÍî‡c¿2¨Ïl¸1¶]/q"Ù§o]õK¡Õ@ª”Á¯ã›?ˆSëFÅûî!R¡*™à©‹]GIò²Þ,GÓ²›Š„RePD.‰ !U]üêÛ˜7 xœ ãD”áµ»«•tHÞØGzP*À+R=7ÁÍøl¨‘9Y‡Þme~ö¼¢K}YÜFÇ~¤H0€ÉoÈ´I+­f¹šŒÉÉžÜ! tÏ»'mÍŒXÑEÉPXO¿—«¯ª WòU̶–­tÏ1%™hoüa<îpý°È`¬â|ÊÍ«y²"~þ*´J—¯+wúÎÕËÛÛ¶l¥úönÌÒìBt¥ôŠïúJ8…¦!Cþ!õth1_pÂ~½Wúf”X+’º­vÍTnʨGG)×ùípª;z’ËÓ¼¬ lyúf¾ô6RùßÔ;.ñðS‡OLiÖæD Œ‡¾9_(T_;;ðª´t¸œ¢]Ê/{Œì}I0§L²~:z€€ºK'Å"#„ö§0˜²§óìxUa?óz¨ vŽÜbQÛo!¢Y6÷¹$QA®4§x2ƒò±m”¦V æeã©›lú$+7“Ñúr$ñÁ™ë­o ߌÄHÞJ’7Ø+¤~fGÔj6CU+á¤K‡ß"×绳´€ÝH{8©VÇð 0hI^Á5樻 W%.£b >@í5çg™RÃ~EÈ;–ÎÒ¤ºó&¼ÊN#³?HT¢<|„W—Çs <³MÖ®LË¥ŸKø¥â©‚/VŠ‚š»ÝgP_ àën„¨;ˆ8aÂïQ>yUï±h`¢j”ÂBº¶ÕŸ%‹1D Ÿ yT3(6§=t’û:"Ñsõ•¼«hñW’KޭԔ˥Ü8ÙÜÌÂKr…Ð_¨Ç¡‡£‰eh¡-¯†‚» !܉ŠÃ΋lo_}¯ÕÅ…yÊøÁáQ¢É…² àÕËtèeçÿó·ò=Bå+“€f`¬B}T)ÇiKpÑnOe¹,íž´ä\$ÚZŠq•2ù kÜ“DGÜÒ•^è á÷† /.ÖzÔsÒq‘ÁÈå ×AŸ>n(Ï’v)õkG©Úºb·OjßQæËØdâY©ÙO‘XÒ~û¡$ýfø½ê}¯:VfÍ1<0ÚIGŠÓñSd#ÝT†ék„müÍ©ÕäNtdsǪÇöæ½Tã«GYbéT|#î+&k¡¡l—˯ªŒöZzŠÃÆ|4®5^¤kÜO³½¯HSç$¥PGŸìWó=+9SU|X=¶G…I Ra•­³ÄW2‘£šŒiºàà}a±lº Ë7¸ÏÅ! Ù÷ï\`ᅦý¸ñ°ö;¾é?£ÍU(: pTÇŒæê‰UGk¼X2¬Ráqø M<´‡«,tskMêÝö®—Üœÿ€mµv.Í€é²||Æ+iXlë…Ò{,æ!"íäÉJ*˜·C(WôÄÙš¸Ð—]A2‘ãFÒ<[Öu á"0Då`ì¨CÝJQÇZ²&ƒÒÇžlùˆÎ\}ò®¨ûtaŒin!ÂÒŽÙ±Ý)ágËUîÞÞlḛ̈vÏ,‹ÒC¯¯7ì6ö4òÁ0 ­ù zÒ Œùíy êæõãBÆø¼4Ù€y’ŽìÈ-¯ÈD&ŒÈ2eñbê›…#F‚ý*WÀð\ÖÔ=Î-"!ÌÎUÞ4–Š©çþ\kû/žN^¬úH{®Ï¶3rY-Ãy¯ª™á¤-e¿ŸžPT°¦Ñd%s­îI/â㉒”˜À&¹Ê½ª’¶OÁ²ErúEfLÏ/ ?Y ¡žúõCs,–Â0¹±þª„?6½ñ%ž­PTÆp÷BiûZà,é’TÑjûRõ$x‘9b=TFBv˜ˆ¥¶´£HQB{(OmÍ7ïõ*4Ík{J6Ý ~Hü«ϾÐiÉÐQ¸zš@ß|^edĸQèõ.y”“MGo¸T½…KCÆÊ‰ßGÂîXûo6fÀz¥Æàœ‚ ª¶}‰ì˜yJaŽ`cZè`‰ä ¹’~pUúr¨.½$ô,ÚM;¸%Ĭ0 Úæ‘)PÊÉâ‚Ä.®XØ]©@lŸÄî¸i^vV-…HãÆZˆmt4ˆÞïÁÚ&]i–d È&ÞT¤ƒÞ–1aáLïX÷¼FïÄv—žbáçÕ§{Ä<~Ò³XÐêª-/Û|u˜¤ðù@š<ŽR{ðVó**27‚76 /ýgÜÙ •ãI5~?»^=¥¬çþY[y{hÈR¼§ÐŽ!沨—¦9ÐqvZA'@Êj>`Ѥç¾ÕmtÕ¹YŸJoÍ…Çf %˜´ÂºN>&u1ÂV»ìWP±ô•HÅ|©ÁÉL΢ɪáè6£¬eÑÊ Éu VI®Ñô°ÙÔ1 åQLYÏ%è¯XÂÂ`@3g–?E΃ðYõ ²>C¬4KÊ7‘‡g r„a-¢AÔ—åÑò¾€ž†¨yüüÎmʯ‘#¤]ž¢‡½|'ÂV¤±Œ7÷ÕЃÚß;ðô~ìõ8÷ýÜù•"íÊ£²ôÛf›¸§ß¥Ðk>m/ÌõE`µé/Œá–‡÷êÌ›í`6Ú¹:ÚŒñ(d­[ø6ö"¬ÛAÕ¦¾‹=ˆÌª^>f“:>D»2–ÇDZd[Ö<5?[šŽO4'šŽL?ŠjÚW3§³–­ËRÙ*wÖr]0H§|¤ô—–F&âãÇC´X=$‰[•xï¨ÝßÓª™3@F±P]f)ã(Že;ÂÞSîþ+¯£ŽY’i†‹cÝM)s'X'kó–ê#¦Önh††½¬Yâ@cs'Ò(A§x6Z[Ìî¨Êì PF's£’­ºÈÅfEà”oMSÏNKÄ!/<&S£µ%i3X@Fh0.hŠ•›=rv°éæ8¶ÂîÝU2žmT_K=´¦2aFŠ«a£WëŽàέ¾JèÛÞZê*³¥JüpÐö™)qQIðÊ'Æ6«›JÙŒ7i„JÐYè’*t34ô=&òøY„@kHÅÝÉ\ͽ[ÑõŒšÂd&¸0ÆÁþMLíIã{Ce)¢GüjÇT·ãÒÜÞ˜íe.úM:u÷„Q ìEW$nÚáfZáü,¾ÛÎѨ³B5ß ¤,† 7N{7¶~’¢"¬uëÈ ?ê§rsÜg›o‰-~f~«‚úºQ=ÅSèk‘ßT•êÍJàK°‘/L|î0𡛢Õ<‡+^¯6È“NãÒÓ kÞ>» ®ìö–¶d£o=ÿt ®~–ZvëŸ$·\€„æ(<¸í®ˆ[VlÅJb9€é¶ýæ:—OE)‚çF÷Ñ.+LШiϓǩ» g"Sa“%6Ѽ(VçàÃWýÀ ÛsW>Vrƒy>np‚!Ä,;Ê7*~Ú€¨¦*òí‡Ë¾7#"¢¿BÓž®äËFax4,Þ¨]eRÝ=©ÁÝ£õ#Ƨ/n/‘x·¾•RÇý@§;û݇<ýo­Õ‹Óxʨ2=º‰¶2ùKUy7ëIs×Í…{QN]ô-vÌ“¥šéHeÆOøKwDÝy±"ý|ƒSóéŠ,Ýýû,åK«[ øáã³qî5©@o×”;zX)êåþ«Yxªy°kÞñðG+:“êz ,’\Ñ/««¢efµÜÊe¹ú>âw¤œ]¦Ü[Ê ;¼AÛ¼ì£jåÇÆK´Aá÷}J‘éMÛhíAV½ø$‡ùÒ_™ì£› ™^GúíÜ ¤ÈJ§y=lôeÔYÏOŸuç4Yª}´Ò´ÀVÅU@øÜ4ZÒ}U+»>¹F:ÕPê{'Ø\qˆ×{ÎèÏZ*lmŒ©îUïÑT<ß1º2©òº Ìm…dY$”k r1DŽâ´eíúÉ›+fTrÄï@cg^ݧQPúwK„ôð‘DÉjJW2¬.ãS:ß{¤z†‚zˆ¢æh›íئB¸Õ‚%4ŸŒ1[®™xª01ÇE»‰×†~:6¯Ñ,i8P·Âà¥ß— v†p {ä¼<·ñà.5û5ÿ.IY,TλaeÐD;6ªp[S¥hòFÜX©·‘Ðyu ¸B~#ÒC÷©‚r©)F+Q^ˆ› „*·˜°Vèc²E=œysÓ=n>a÷j áô½½×Â#iÚðËå@†#_@Þ'“‘å½ÖFÌŒ|ÑeOøk…lDŸ5ú¨Ó;Œh¬‚Ó˜ÃÌEHS6ÍnIÃÏ‹,µ¸ªáèáYf³•ïÏò˜9^Ë€Š;hMõI| j§çôwbÇ ¾ßRa ö*ìZ¢! fÙovßçZHí[ 4S0v…žj#KI»üĸ4~ ò¤LÙOi=+EÌ^K–æ> endobj 8 0 obj << /Type /ObjStm /N 20 /First 142 /Length 1225 /Filter /FlateDecode >> stream xÚ­W[OÛX~÷¯˜÷ñ¹_$T© ‚²ÛnÐ-]ă,È ŠÃªý÷ûÍ9Nr’@-çÌí›û¤HŠHš¤ã‹”$-i/IY²CNR‘¼Ž¤+H+Š:T6ÖÒX—|g÷EçÉ@SXC"…OZ;K!Â:©ÉHܽ«vw«úôç}KõQsÕVõhz7oïæY¤y\ÕÇm7}˜ÛÙ&Á§örÒ §?è\@`£(ï(9ñ¢‚—Ì%)̦÷@ËïÞ!XŠÕ‹ë“útÖÜu÷l2þIõè¤ÞkÿŒÛãƒ!Õ‡4Ÿ=´Éªª÷‘íîR½/ ü €Ætê³ÏßÿiÇYçðV’\®ͦã“vN瀸·OõiûcÎ:€;¢‹ªðh ¤ß,‚´oQ…¶Ü¨ça`2"ðh¿Zðè²^ðpdÞµr›¨•y=ê-  p%äm ˜e±ä1ß ³½B¿P-¶€†·nï/fŸÿ çß¾¢öƒÕR15zàÉ:柢ÁDæàx3’eð‹u)dà›„¯,_øVG6È>bÖÎüJˤgSh–ܯ3| í=™%ZTOù9cõ1Â'¬5¾¥a`È ÏzÁ@|„#cB‚€…óvQç¹LI!‘w!’ù #V¹>(8 Î$½˜jèTÏfêªW§¬F‰È×Nå>¥»ÔȲì/K׺™fIîJ²[êæuc9‹Ðwiµ–+”ùD/ªsk-w=Ñ 9‡L•÷ð€í…Wy–6.mÊ @&?)…JûdÃÏQ(p˜4ÍÕLbUPVÉaV\©¥C€]¦É}¹V¤÷XbO]j+‹ìÕxN=Ó,ah^Î)ÃrŒÂad9ËÀ‘¹Õeæ¢Ì<>ž9,¾ÏÓ# vØtm:umÍÍPþYJ‡¶ýɬ›®›±ÒÇfù__'—ó뎷^|£ï±Ã3±Õ*¶~}ìÆ­Ç6b3¶ÖelW±Ívl>9w|t~@$4ùÉeGçùwCæÿ1eó-µlãà=jÐ÷éU•ý¬þþ;ñwF endstream endobj 43 0 obj << /Type /XRef /Index [0 44] /Size 44 /W [1 3 1] /Root 41 0 R /Info 42 0 R /ID [<01A84DEEC3BC5545350F3FFC3626F108> <01A84DEEC3BC5545350F3FFC3626F108>] /Length 164 /Filter /FlateDecode >> stream xÚË?að÷¾ewXký¹µB¡t ¡ÕI(èU"Q­è Ð‰()è´î J¾™æ—7ïeàG+8@¨8RëªJ…r?ÙY£õA7›ƒáuFíÌÓéÚšSºÉÂΔáåì×鯓=·çõµ5TòŒÆkP’¥u¢D”xë»ÆÐº‚RTbJ³g]‰2hYJ(;±TVê”ÛÁÿ>?ø¬”— endstream endobj startxref 578293 %%EOF paperwork-2.2.2/paperwork-backend/tests/model/simple_doc.pdf000066400000000000000000000230121456262201400242010ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xœmŽË Â0E÷ùŠY 3Ió‚2`k»pW¸w>v‚ÝøûæbQ3“››¹%ÁK<%*&©œß’ô–`¹ŠãÕ‘Îr}ÆJÎi|€xíD@ âíÔ!±êP¡Î­å&U³¾X¦Ü\Ö|žëƒãÆd=°ípW¤ž›bê‚}q”/#ŸãAŒQÌÉ,Jú%›¸Õa]Vã>DhH‘Nµâ )nH&ê;z†7NÃD endstream endobj 3 0 obj 181 endobj 5 0 obj <> stream xœåzkxU–à=UzX–l=,•$+’JQœÄñCŽIœ—+~ȱ۴B,Ù’`[B’ÂcãéæÕiÒÀÐ<²Kš… Ý]Ê$ô„^¶cXèž^–f€–fHMÏ4_“!ͤóõ–÷Ô­’b›G;ßþÛ’«êÜóºçžsî½çJΤ¦âÄ@¦ K„¡‰h²oÛ¦ZBÈÿ",C2ü¶.Û„ÏÂüíprdâ‘¿Þw‰ÕB´gFÆ ?ÞòGˆa”ë­£ñhìYûB !ü¨cÃ("öei ñ­ÀöªÑ‰ÌMµ:±-`»<1ý]Ãßb¾‡°]=½)éSu2Øþló“щøÊ&M¶Gˆþ@2‘ÎÄȪBª"=™Š'w=2ø2¶§ a!ð#]5R›aUj¶@W¨7MfK‰ÕFþ?ºÔG‰t¨·#IÒç’‹=EœäaB>’ZWžÙ] Ÿþ¿´¢@~=DN’3ä(y‡\§‚$DÆÈb_/7+]!²—üÌ|…ÚSä,Òe¾¹WÉ—^!ò=ršü|I/!2AnA[ž%ïÀzò L•ù È_—Që'ˆ»úËT1Åø¦àð"ì»äQ湊‘òþa‰Ây‰‡ý¨9ƒã<šñÖ/(½‹Ü†Ï2J L/õ¶Ïÿ7Ñ-ü+Žê6rù&ÙAÆI<±…¿^òúôŠ äˆÚözæÇ 3?6¾KFðŽŽ9Êîø ý__l)‚r¶Œè¾ŒÊÔcöS¦vỊ’¾…‹9ÜB翲Ñì¤j@µB½MõÊ×õ¡ù®j¥ÉÂo³·dcêÝê“­§Ú¯ÝîïëíÙÓêÚ}õ®Î«vv´ÛZ[šwMÛ·mݲ¹qÓÆ ëkÕU•k׬.[å_éó:¬f“±¸H_¨+ÐjÔ*–RÉ‹iÙ2ÞŒúÛüÑŽªJ¾Í1ÚZUÙæFD>Ê‹øR­öwtP”?*ò^\¯è"tDsx§ s yN0ñ[ÉV© ?/¾ÚêçÏÂÞî~„¶úüxÂWSXµš6аáó¡µJ²–oƒFgÚ"h#Ìê [ü-ñªJ2[¨GP¸ÖŸœ…µÛÌڶͳ )(’ºÅ‘¶Ecb¨»¿­Õåó…«*wŠÅþVJ"-T¥¨iµT%?&™NŽð³•s3÷œ5‘ÁH…!æE÷õ‹legض™™»Ds…XîoËoþÀ#‹•þÖ6±BÒÚ¹'ßOç•.AT—™üüÌ Çᣥ˜¨‚Ñ”™þH$PdZDØÓï“.W}=3ôóÁ™ÈLôìÂô Ÿ7ùgf †™dº›„úQÅÙ…Ÿq‰Á{¢)2 ›ÃÊЃ{:Å’îkûE¦,ÈFƒM~ß&—Ïœç }™ [Ð9èaŸOrѳĆ8ÝÝ/·y2èz†аÈD$Ê\Žbë“(Ó9J^<âÇØvöôψª²1züHTœÄìº^ Œß$_vùü33ßS^­ÚãEõjtJ-À¼‘DfL´Q|Y~]pa«Í¾Ñj$=mþ¶ˆòw`Ô xttG…œ½ý¢ÐŠ€U"Ö6[@‰h6ÖJƒ)üIÑêoÎGW2«m¬§ŸŠ(b¢µE$‘!EJ ´ÑyÅ·ÍDZe$]þîþçHÝÂùÙzÞuºŽÔ“p«Ä̵`–­n›é ‹Þˆ+†ón˜ïwùD!Œûûãa)íÐCåç]49Â4Wzû;{üÝ{û7)†ÈIª¬m™¿KVƒ (”ðýŒ‹ #£ |óV|ŠÚ²¼MèpŠ•·y+ß.’ãF3Är¾-ÞªðIí%JÕR:µtä´i¤&êiépùÂ>ùªªdÌ+£DäÔŽ —)$`~¶tP”äK‡”ô|¿?îûGyQõKc“ÜC½¬8ƒú\‰Uï’Ö"g¡›ˆɹ†äL1XáZì\±¶óÍŽeä92?Sàï왑”û…-ß))……Mf] ¤ íǵ—7ᔦzfV¤É<ºYRâß›ñ÷ôo¥Ü¸žÜæºYêËB:¡³·¹ª—¶æY?ÜÝ=+ÀÝ={ûŸ3a]xwoÿ3 0-‘æðì*¤õ?Çã¦A±Œ„•Rƒ—’¦=Ø( ü®çB¦)UE´=tÅäp@†Î22Î$w´šv$)*™"ä¸Uˆ+qÓG¯Y"¹L(T ‚N00EŒk$Ô3ˆù Ö±: § P®Y”ÚCÑgazV'¸dŽiäd ïî»ÒußÞþÓÜ]ô‰5K¦‹cƒÛJ“åÖðèL$,M6ÂahðDðoÇ0ù·£!ƒXè7‹z³„o’ðM2^#ᵘ¢ÀŠOcìC"Hpm¿§$_ú ׌é‚©0.*3¦ßV¡ÇÊðÜðÖ VØ*¼gaôLkã ¤tlAÎÌêØHXÇZ „‰¥‰#ç98ÇÁ½æ`€DòÃE^ãà¥%9èâÀK 2^äà1JJP1ƒÊ@8xŸR§)¾†b¶,Ð~d±{)¡‹Ò.R¼˜ëCà©ÌEªhŽv3M©hZ ×ÇuùëÆÜ•R®ýËð_ H4ÒTa&uú4×9û¯«3[ÀÞh®[_ãkØhö¯4‚ßì3û×TC˜í6ØòVÝüu®ÕñV—çÞ´þ­—ê{Ö7`Köå7´úÏnp5H+Vn¿Å3›üD8D¬VgQq±Î©óxÝ¥¡°›X±aw†Â»­„aÔjóž°Út ç½0瓈±qÌ I/D¼ò‚à…/ð^ðR2’¦sT$½N%E/œX„_ìœTj‰”±ã¨›ê$ ŽºÁ8vù³¾¬ÚíPWËÙpà’7êý+µ ¸¦ÁAmÇ_7Ý|k*{Ãm'÷ëp6vð¨e/V—oýÎ]ó:«ªœÌþSîù R3Ž*œ8XŸZÔ»ˆOKÿQ&ƒÆl¶s¬®'LX0±¬M°YBa›Ñ`6šCa£Íj•/Ùᘘ¤"vÙA°ÃœD;œ MÞ&;;\¤d]̹4G$ P/äÃOJ¦_bð©ÌuÊà5þ•«ê7 Ø+ƒ¾E¨ª„Ê*¡ðûYç‰; Bõ¾Ü>Û,“åÒì]øˆù;öe²–„…zŸÖZZ„)Q¾®ÈÇÚížPØe7±úPXËrÓë ¹"ë ´øuðô:X]ë g/Áð# ÁØÈBó®i¨³suµ õ¨f¨¹v›ÍjÿJÍÊÙ=,ów³ÿ%øƒšªõ7½øp8¾¯öÇF ¬kHu÷]½ûþ½M~(¸ç˜ÛòÏßj=ys½Û×:¼õ^ï«PkãîÒÚê–k¤céXøˆ½‘}¸pu™šÌee*Þ`pªX,ûW®ì;lfó Œ˜Ùkf ¬ÙL 9­ Çh#¶P˜˜¦×ÀÀÖ×aÐùÄAï:Kc@v>i¤9)Ï@³2J%ÿÖà`ÍõÛ¡ êWÓyÙ°´Å`³ÖÕnØo<òÝ©l¶$5û‡':Ú~U¬gå¦Ç|ëÎ{[‡jÙþÃ7çïpVíOcÿ-;XÕýÑ}©WýYJ½Rô:èœÅ˜U©þ‚p¤]XSX\¬-aY»CeÐBaVoÄ9mîî1ˆhr@À!…)•K£º:ÅúFKcm­”CjL ³¿¡ êlu6¿ÙŠqÚh+ظå¶xÓßÿý–šÍ=þÛ­©æþª5o½Õ;xG³i‡ÃK}BŸ1‡ld9*ìuK lF›Ûã$èh§×‰Žv:   [LuwØÀÍy@ôÀ óÀ´’ˆx äâíøòãÁÑ|?»û­ùW;ŸÂGÿö!+>ùù;¹”mv5ànòŸJ²S¿|[òÉÂçê)ô‰ŽØÉ.! ¶’"k‘Ãi· „íªHØÎš¬a“66Yˆš'ðN8ï„NH:邦£¥4”W,DûLÄç7c2Z€'fl”ù©‘ª'²odÿùÌMO^þpþO†áì_e]yêÔ)æ)pÂÊÏn)€•ìËÙg³g²bö¤J¶–îwRüÊÑV;¹$œä,«@£±êY§ÃL"ásÂÌT™ÅîÌŒNm6kt:FV;€¥hTš°ÊrÆ O8á'L;!ㄘTN¸è„œð&Å#2â„^'´:áu'¼ä„¼Èí9¤¢'j¨3¬TCã%ªBæÃöœÑ 7,Ïú%ƒ²Y.4N†ëè|°/Þ)¯k)ú¾uÁSïÏ¿ðØ)ö_šùä›ïÂï¶m^fïüå|¤Ï½S<ÿƉlìqôaN„ª'.Ø üƒ…ãX—Ë^R¨r¯à\NW(ì´k‰5fKŒÚâPX¯—Tn¸ä†ÿæ†ÛÝqCÌ nÃnxÓ /¹áŒ Hî\$ó#Š¿–ÊX)þ•uõº¡5‡ßü{ªè 7[ÔU½VQâæ¢λáu7œpô’nÜÀ»Áä‘6M”oIQ6ZV•|I–l¹Ý0_¶É Q(Á4^²ºAZvih~ýøãOþåÕÍë«VÖ4Õúé+YÕ¶ýšæ×Ï—¼z‹-ùÈñÞÏ/ûªª|‡rŒƒ k7y\Hªõ…: ®ÿ„¨Y5:ßö¦^ÒÃ=<¡‡ôp»2zˆéa•¬zPé1Ý(Ç1=–+zˆè!¤Aszõp‚6Mz z¸H›È·˜m‰”ReIŠ^©YqB¯¯)»Rš$¤Šäƒùz È] ¿Cä-¬·‚žh4†"V÷èµl iRjÔ°¨ÐCmõõmÁººà¾õëë‚AÔÁ,üZûmzžèx£µPmUs6¦ °¨ƒ1ŠŠ¬ÆBµV=6kÙb½þ쟄—¤g¨Jb\Ãdžƒ9x—ƒŸqp’ƒ9¦¤ 8XMÆ.sðO¼ÍÁs|“©ÚGpð&?âàQŽp ²—6ê9XÅ•2¼ÄÁž ò˜®Üñ⋵3Fa`ùqƒ¾°Ž(•[TÔå l<`Ôê/Äj¿ü€±³iuP§“!õþ†ìÙG²­S yë±*Ø5oÀóS^öøç1uQiCCéç]ìãŸïgg%XÉÙ‡°V°’n¡Ê¬Õ‚Á`ã4fºÜ«Í,c5™ŠBa“Qk(Är¦Ð6@‰^ºqÑ'M­º:\â̹2FÞíýkVjUþv<0Ul®ýví÷³Í‚E·õÕ­¸1Lº¸ùæ\ ð,ôk´mîì·‘’‡Þ`Ð:´nÏ <­0–`ƒs MœÍ‚œ¬iO˜5=á<ð’°ÐPy x ã˜z=Ðêz¬ò€‹’±âa×;Xå¼î|)”Ç/ŽÞÀ¿ëD´ô<´zé¨õêÿºY>u÷íÅÑõ7Þ6RÙ˜?õ÷ (ç!zN`¤_Øgp­ÑãIqZè¶hµnbwÛ=ÞR](\Êip'µ²Ýa«ÉˆQ3î¤Ãá1zL<Ÿ;õɧAù(8—ƒyïâå–3Wv+ýBÝâ—•Á)ÍV­´(جŒtÎ`²ÓwnÉ”öNÍÜ:äÛÐÄš{õ×o]óÚn¸xöŒÍ0o7ýƒªÚQ•7ÛýáGóÙ[í¥ñwfƒìŸØSdüFX0J‡ÇÉX HeÑ»%fC1ŽÍVl$Úî0KV`‡=p †ÔŸÐ4xÓ?óÀ=ðmšrAÛìZš˜!Œ^öÀÛxÑÏx³ç>ÜN¹‡iÂ)÷JXhÂ\òÀ?Q~̰38™ãOy`Ð{r ¶Ú\Ž?oÇ™¥ú—ñËÖlºL¹óÖ<Ó.|c±=«¨=Rm޵øyš´²Aä´ÇèXeí—(#§u>Ý»<`ôä+Vi…Z²8-Þb¿Xì,e^ú5ÁWG¤©6¿Ó“¨ô­É•5­d¥r"ÝåÍ%¿ ˜ùùî]Ÿwc}ÿÎÙG"pæìåûaÿ`ö»;"™lÐòJľõÀClç‡k>ÁÜoÛç×>yì*y©ÀóÙ'Ò>DDá&«A£ál…–HØXì-f ÙââÂ5Ψ0ÃÊßcå¿«Z ÀÓ¹ïªç–ø÷!”sëÇt£HЯ™äMãàé×Rô+§¼›–}Å´¤\¬ËŸšpÅ™E=`¶JÇ%É=Òé©9ŨÚóW#Ó]Íž’àº{TÿBWöïüÅ”çÒ{éOåqïÆ5b7®Ÿ‰[Íj=§æìŽc(l(0qVÖŠ³†#Ø.8 Æ¼L¸è€×pÂÓ@üÓp,µ=oéâ © äÍ´„’êX„陕ݽþÔÞìÆß¹ëÄÆŠžLöÒþÑ}ã«Ê῟÷f?=ÈŽ¾ù¬Ðÿ À5íÀÊÌÆ­d¼òïÑÓúú/¯üÚ˜ b5ñ8ÉÿXMÇH´¾lùÆbÌ’‹Ó4â ã7¤LEˆ•i$¬›ô2Òï£GI¶­ø©Òd‹úçd‹ôf~Hš_ŽÍDù¡DòPjld4ï*çkkÖ×ðí‰ÄÈxœoI¤’‰T43–˜¬.lYÎVËïAÑL%¿sr¨zר`\æå{⩱á=ñ‘©ñhjGz(>‹§ø*~9Çòö5ñTZjÔV×ÔT7\¡.gKóQ>“ŠÆâÑÔ |bx©!|*>2–ÎÄSˆ›äûª{ªùP4ŸÌðÑÉß›ìŠSäP<•‰"s"3Ц^?•KÇÆ†¤ÞÒÕù,rGO&~ Î_ÍdâéÄds4}¡e½c“‰t%ptlh”?Mó±xzld‰ƒ‡ø¥2- Y‘æ3£ÑŒ4è‰x&56?„1›H¢Ô éàXf;žˆ§ùÝñƒüžÄDtò‡Õ²)è›at*?6‘L%P«ÒC©x|;‹Æ¢ƒcãcÔ6ME‡Ðcè¶±¡4õ:‚OF'«Ú¦R‰d-ýFû®+Œh ìÍtbüö,qOÆã1©G4û@|…°ãñDâi<ÉËŒV-²|81™AÑÅpàè­ÄÐÔ„'ts&g\t(•@Zr<šA-éêÑL&¹98xð`uT ÍF¦5¾Ž–9”Œ+ñHIZ&Æwaø'¥ÐMÑøJƒèÙ¹‹ïJ¢‚h¯0Tò¹Ô\_½^éÝ8–̤«ÓcãÕ‰ÔH +¸‹´’12‚wï›IœÄwÛQ„†H‚$É!’¢\£ˆåÉZÄ–ã»–Ôõxó¤¹HGyž´ œB)é¥zd’T“BJùzmµíQ¬è Ò•íDù!Ô° 呺X/Oz(f ×YIr„L¡QÄì i”Š#OŒrð¤ ï?§ãÏѯ¡P:O©E»jðSM¾TöÏiC]<õu†R$['¨ý7 .r_çùâ4~i¤Äi+FµJºû£‡r…¨¤ä‹ ím’rõ~I]Øã0ÊÑXæ8‡¨n)'dÍ „G¯^OQ bT.7¶4öüÅ|yvôPëÐ>¯¦x©¦´fl§•qÉ>ë¥V$+ùâ Z"õ;Já(õgŒJKY6©HbÞñ_Û¯ÈF•¸LÒ>(VJ2•Š¿‡é3MûÄ>xjŸå¥}óÔOQêu9ÒHÍPÞ!Äãç2Ï&Ð+r_ƒÊL:Hçå¨2â ª—ÇJ&Ž)+4n“¾•4ÆW¼"çͰ’©<•M"œ £Èù±ŠÆFIœZ*AQ:÷Qbœö-Û6J³#JcWb¡#Èù+¦ŒT²:I1U¤æ…4ããŠO¿+Å®/Õ({pqnJ1§ö¦éž¤ÖÆòc”½-q+=É#§+Ò ùø Ó|“=£Úª¾ÂçÃÔ7¥×µ(†9ârn%PvŠÆCžOr6g¾à¹(õoB‘KÒu)£Ø2AçÇ(ÍÀ$ÙŒµe­“>Õ4Ïš!eÎT+6þÝr’]IêÁÅó#•·emÜ¥ÌþÉü¬›Z4s‘èÁ5h]/’JþÏñË4H³fùª¹û[¿lr6Ža;CíIS_VÓ1Œ ½ {ØEëhz-øÐ¦/¹fu¡ƒ'£0BJˆ"d7 >ØA¶€oiÍønÁ¶ô®†mdù¶!~;¶·"~ .ž^|6áÝ…÷½x«ð–9j#€ï€Ò®Âv%J¼†O ·„mB¬ô¾ ÛønWÞAÄ·á»MiïÄ6¾I´ÒôyTÂi8?¯Í?‡?ƒÐg0ýɱO˜?\,÷>}ñÜE¦ëãŸþ˜­ùŒC¹`ºº¹¼pâ‚¦ÐøÈïÁü›ó›¼ïo{¯ï·ýª¼‡#{¯æ½Ð{Óï‰ï©ß¶ïW,ç5Íñs5sɹé¹×çÎÏ]œ+˜þ鱟2ÿýù€×ø¼÷yÆ{ºëôáÓlä)0>å}Š =y”9vŒÇ½ÇÇÙG®ö>Üîñ~ïÁ5Þó^|9»0wúÁ"sðyè‚]dúp÷ivÁûô\Ã2âÓ‹wï.¼xß‹7ž{Ý‹wv ›Ø¿ý}®û*î»å¾#÷©“wNßyìNvúŽcw0O8w€I‡Ê½‰É ïdû:¯³Îѧ­cû4Ø ö.ì,[Œ Þdºvowo{¹·¤ÎÒ§Æ«ÑÈzÙ&¶‹M°÷²çXmÁžÇÛ÷ùÐÅ#„t† ±ËÛèbÏ.œâ>ÔvUòªé«ØÁroGû&¯±ÝÛh­ýýöÛ5íðþŸž ²B°<‚_pE‡««³õ™ÁØgª3ö1€®#}ã‚‘1Œ‡¬‘4fš5œ…c³½=gµ {:łе"Ü-–õHO¡{¯¨¹[$}{¯íŸøNøŽ£GI³»S¬íé#îp§C@€iLîYŽ4‡ÓéL½ ¢á)|’Š© DîOËX’§“Š4¤qJS!¨ä6à³B¢!B’”ÞŸ&ÒC"VÈB’tZQG…åûÿ¶g– endstream endobj 6 0 obj 7404 endobj 7 0 obj <> endobj 8 0 obj <> stream xœ]’Mnƒ0…÷œÂËt DBH)I$ýQiö"c²àöõÌÐVêëûÍøé™°¬Î•éçðÕª†Yt½Ñ¦ñîˆn½ d,t¯æµ¢U Bß[/Ó Ceº1σðÍŸM³[Äæ¤Ç‚ðÅip½¹‰ÍGYûº¾[û˜YDAQ ŸóÔØçf€º¶•öÇý¼l}ËŸà}± bª%[Q£†É6 \cnäQTˆüz-0úßY¼¶´úlœ—J/¢}RxމÓòŽùˆœg;ä=q!§¬‘ÈkhÎ÷÷ÈGžOúqBšGæ¹d=ñ™¹D¾ð]ä+ÏÉ<ˈÙŠ¹ú§}öŸ¡Éþ“2ûOwΚÆ„ïø¿Pwç|ôôØ”9¦Ýøýìh±‹¾oˆ’œ; endstream endobj 9 0 obj <> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer /CreationDate(D:20190902205629+02'00')>> endobj xref 0 14 0000000000 65535 f 0000008715 00000 n 0000000019 00000 n 0000000271 00000 n 0000008884 00000 n 0000000291 00000 n 0000007780 00000 n 0000007801 00000 n 0000007996 00000 n 0000008384 00000 n 0000008628 00000 n 0000008660 00000 n 0000008983 00000 n 0000009080 00000 n trailer < ] /DocChecksum /72B44A81E5EEF3D98178B73CE31BA672 >> startxref 9255 %%EOF paperwork-2.2.2/paperwork-backend/tests/model/test.docx000066400000000000000000000100731456262201400232310ustar00rootroot00000000000000PKf“0R _rels/.rels­’MKA †ïýCîÝl+ˆÈÎö"Bo"õ„™ìîÐÎ3i­ÿÞA ºPŠ Ç¼yóðÒmÎþ Nœ‹‹AêiAq0Ѻ0jxÛ=/`Ó/ºW>ÔJ™\*ªÞ„¢aIˆÅLì©41q¨›!fORÇWeS.“ICŸð ižÍºWó‚Ñ)ŒíD çŒÞ ¶·^¾dôV°§Nx!1þ_Ä»9±ö»7'd,–Ó¦‰“¼h½p]àÅ5nTQŒ‹æ?PK™]À#þPKf“0RdocProps/core.xmlRËNÃ0¼ó‘ï‰ãT*`%©¨'*!(q3ö65ÄŽe»-ý{œ¤I ôÀmgg<ûr>ûRu´ëd£ D’E y#¤® ô¼œÇW(ržiÁêFCöàЬ¼È¹¡¼±ð`ÖKpQ0ÒŽrS µ÷†bìøsIPè@®«˜ÐVØ0þÉ*ÀYšN±Ïó ·†±ÑÁRðÑÒllÝŽ¡Ú;L‚ZV¹³:æD©¤ß8+ÈQýåä(ÜívÉnÒICÿ¿.Qc©ÛUq@e~h„r ̃ˆ‚íË ÌËäön9Ge–f$NIL¦KrM³)ÍÈ[޽o û¸±eËAˆ8n¥ñá†=ù#pÍtµ /W6ž?v’1Õž²fÎ/ÂÑWÄÍ>xœÉ ©Cîÿ#]R29i0è*[ØÊö+:¶k·yÿîû‘Fb/} }zÿüÇòPK ¬çaÛPKf“0Rword/_rels/document.xml.rels­‘M Â0…÷ž"ÌÞ¦U‘¦nDp+õ1¶Á6 É(z{ŠZ(âÂåü}ï1/__ûŽ]Ðm€,I¡Q¶Ò¦p(·Ó%¬‹I¾ÇNR\ ­vÅ´DnÅyP-ö2$Ö¡‰“Úú^R,}ÃT'Ù Ÿ¥é‚ûO&ÛUü®Ê€•7‡¿°m]k…«Î=‘àn†H”¾Að¨“È>.?û§|m •òØáÛÁ«õÍÄü¯?@¢˜åçž§…IÎáwPKù/0ÀÅPKf“0Rword/settings.xmlEŽKÂ0 D÷œ"ò’²àS‘²ãÀBk RbG±¡Àé +–£73z»ý+EóÄ"#“‡fáÀ õ<Œtóp>æ0¢†™ÐÃöÝl7µ‚ªµ%¦>´“‡»jn­•þŽ)È‚3ReW.)håf'.C.Ü£H¦h—έl #AW/?ÌÉLmÆÒ#iÕiØðQOárTεò ÑÃÚmØþ]º/PKeúÖ"¥ÐPKf“0Rword/fontTable.xml­PANÃ0¼ó Ëwê´„¢¦â„z å[gÓX²×‘×$ô÷¸N+!È¡ ÞìÙ™ÙY®?=6ž*9ŸR i_:Tò}÷rÿ(G ¬'¬äY®WwË¡lÔ]𙓺³jQÊ!y– ×Èø¦1Ÿ½þpHq h!¦ ¸5ËÕ9J—BïŒCÄ›w@™ [Œ'N¶’E!UÞgìñ2 ™žÎDÝ^æ={‹'Hf¿L·G·÷vÒkqk¯§D™¶š<‹ÃüO«W³ÇË[ ¦É®`ã&¡Ÿ}«©dó[—ð=O{º>ΟŠ:?xõPKÁÇÙUPKf“0Rword/document.xml½TÛŽ›0}ïW ¿'†îj•¢%«¶Q«ªê*RÒ0Æ€µ¶Ç²MXúõµƒ½HUÔUûÂ`ÎÌ9gÛ·wR$'f,U l¢„) WM~¿¬6(±Ž¨ŠP¬@³ènûî¶Ï+ dÊ%žAÙ Ô•[Ú2IìJrjÀBíVduÍ)‹Å S Ö9c‹Ö ™òX Fç—¦ÁcÉ.já÷izƒ Äy¿¶åÚNl§?韤˜òúKT{0•6@™µ~RŒº’p5Ódé ž¹B_¢\Ò?‘|nd7‚ £}E9ÛX{qzgÏ—¥/ø-ÑlakÞÆöÕ@§'6I/éVóÐé01íÿhÉwùñÅTvý6W/göw|aÿHškR t-ˆ x‰±À¼ÂúÜm¿³!ø˜<Œ/ŸêÆœ±ú G½Ï“ðî?'·ŒºhgÐ3±bnO6RëæðË#þXgÙ‡°qú¼õï7›«Í”ðƒÿU°Ú…¤«ëcxÓ>Y¶ŒTÌ_HiX8Ð R¸)Á9 Øt.‚Q꾓ÇÑj-=}Å(Ÿ‡6þÞ€›ú¨‰°± ç[ÚqãÛõ×Ú„ s,Œ—Aài«áåþÝþPKØI zðÄPKf“0Rword/styles.xmlÍUmOÛ0þ¾_ù{IAˆ¡j± JÝP7û×ä’Z8¶çs(å×­´)†´}iâç|—çžçì~:(UtޤÑcqx0êÔdRcñãv28yÐ(£q,VHâüìçåˆüJ!Eœ¯i´‹…÷vÇ”.°:05ÇrãJð¼tE¼4.³Î¤HÄåK ‡'q R‹®ÌáñV¡R¦ÎÉýAjÊØä¹L±.Åé‡Ãú­T]2} ‘Ü]e\Ï‚—s©¤_ÕdDT¦£i¡ƒ¹ân™8ã^3“^b•ò–î»k—íª~LŒö-G@©”cq%ç踼ÑÑ :™ -.4í!¿ c13Þ4x”|ùÝ$!œRMÑ%Þƒ†œqøö:Í›îAÅQÑãoà¸CÚÄè¢Ãr7˜\?¥ò¸$³ÍeƼr0…ĸí:ÞÔÂn®Âc)3³LXgT“lÛäõíñ–Ìõ„ñÇýʲì"ð©CÓ,h¶ªÚ$ %v½´pÝãÏIm}¼ŸÑáej”q]PyóÏ-®Å~©!·Ò;Üò£Ak>s ̾é>§4>øOŒ³”¡gwúx‡hgkIÞUíf²Êºñ9òÑÇ Ç0…Ü£ã›îh(^ë<»µÃø6²é{°·±=ºÆ¢RàöÛ¿fêi©§ãÍM7-úl²UtË¡½6µŠý‘XI×U¸0ëymfûñD¬9ðDÿã>ýßÚØ•¤žŽÚÛÌöl­]H}Ãðœeoæ\ Î¶I'`ÃLí5¡ç4Pe­ã?×+V•<ž´ã,„éÅYx~beó›Ð‹/¥·J6eÁ¶kÐwÓ뽦 {£³_PKíÑ-‘†e PKf“0R[Content_Types].xml½T9OÃ0Þû+"¯(qa@%íÀ1B‡0#c¿$†øí–ößóœBUh Æø½ï´œ|ºTm²ç¥Ñ9ÏÆ$ͺ.ÈSyŸ^‘éd”—+ >Á]í Ò„`¯)õ¼Å|f,hœTÆ)ðÓÕÔ2þÆj ãñ%åFÐ! ‘ƒLò[¨Ø¼ ÉÝ׺'ÉÍz/J„YÛJÎŽiœÒ^œƒÖ.´Øs—nœeˆìv|#­?ûZÁêzO@ª˜,ž÷#^-ôCºb±n'$3æÂS¸@Ÿcš8OŸ’0|æŒõ‰³Ã½÷È™ª’c®’AŒ-@¤)Á ÇisãàûâÛ¬}¤â»qbSîÎ4®ÿGÑ´‡ð)ù_7Ù02ï‘l™-T(Z²—ö…yØQšø\þi=ì&ŠI=|aÕÂ_ÜFÇ»‘å´û_N>PKB¿ôS^PKf“0RèÐ#Ù= _rels/.relsPKf“0R™]À#þdocProps/app.xmlPKf“0R ¬çaÛsdocProps/core.xmlPKf“0Rù/0ÀÅword/_rels/document.xml.relsPKf“0ReúÖ"¥Ð"word/settings.xmlPKf“0RÁÇÙUword/fontTable.xmlPKf“0RØI zðÄcword/document.xmlPKf“0RíÑ-‘†e ’ word/styles.xmlPKf“0RB¿ôS^U [Content_Types].xmlPK <é paperwork-2.2.2/paperwork-backend/tests/model/test_img.png000066400000000000000000000107061456262201400237170ustar00rootroot00000000000000‰PNG  IHDRÈdÆ bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEã Šv°­tEXtCommentCreated with GIMPW.IDATxÚí{LSgÇ¿U£»ˆó‚,ËØE§Î`Vo+ÃédØéTQ§Sücj†:¶™ÇܘºH¼y™™&ÌBp@ âP§"rS¬N[ÑV Š”~ïïÛ¾@O¡=¥Pô÷Išè9çyžßóœómŸ Ï÷HˆˆÀ0Œ ½¸ †Â0,†a0 „aX Ãað@†Â0 „aˆ^¯‡D"õÑét€°°0H$TWWÛÔ矉DFã´ŠwEÎ`åÊ•H$¨¨¨àXø„a\P ýúõY|êêêÌ×TUU ^ãææÆ­Êð/ˆ3‰ÁÓÓ³G—Áô|útE! …éééP©TÀ¼yóàëë ‰D"8>غu+Ôju«X¯×ãäÉ“ÈÈÈ@^^@&“aܸqðóóÃðáÃíƒ8»ŒG¡¨¨§OŸFqq1òòòðÊ+¯`Ú´ix÷ÝwñÆoØœWAAÆoþÿ‹/¾Øêü‰'0uêÔVÇŠ‹‹¡T*‘ÒÒRL˜0AAAÆóÏ?/8ö´¥îbbé±ÔÕÕ@UUUí^J(%%…<<<ÌéZ~8 ˜ö³Ï>#¤V«ÍÇôz=EDDæcúüûï¿6×¥+ÊøñÇÛÍë÷ß·9¯‹/¶›×‰'Ì× Úµk—Õk‡N………­ò·§îöÄÒÓqº@PLL ©ÕjÒëõT[[K …Â|®²²Ò¦‡7''‡ÐÂ… ©¬¬ŒêëëÉh4’V«¥’’Ú¾}»`^ö¤³Ë8x𠥤¤F£!NGƒ´Z-eee‘T*%tõêU»nØŠ+ݾ}Ûê5‡2×ãܹsT[[Kƒª««é?þ $•JI«Õ:Tw[bat ¨¨(jnn¶8M(''Ǧ‡7!!ÐÙ³g;¥â]QF{œ>}šÐž={:U Z­–<<<ÈÏϯ•„”œœìPÝŸ8}nZi‹L&3φÙÂ!C7oÞtZ¬]Q† ///0÷õ;‹ÂÂBTVVbÉ’%4hà5>>>€3gÎtKÝy«C‡<þÜsÏlÊÇÛÛR©¡¡¡X·n”J%nܸƒÁÐi±:£Œ’’ìÚµ }ôÆŽk^P8p àÒ¥KÚÞ7nÜ„‡‡[]Ì}ùå—[]ÛUí˃t.–µëòòò%$$ØÔý!"R«Õ´qãF‹çŽ;H£Ñ8ÜÅêì2~ýõ×v³¦Ogv±vìØaS™hÖ¬YÕ»X.†§§'¢¢¢ ÓéP\\ …B¹\Ž5kÖÀÇÇjµÚeÊ(//Gxx8<==‘••…ªª*èõz477ƒˆP__ï”6zæ™giii‚ ¹-?Gíòöå.VпxyyaöìÙˆ‹‹Cbb"4Å ïÎ2JJJ[·n…¿¿?ÜÝÝÑ·o_óxìþýû¢âϵĴVqîÜ9§×½£XX .Â믿îô¦½e˜úîO=õ”ày±b6ý)µ±›T*…››¾ùæ:µîÅÂéBâããqäÈ\¿~555hjjBCCT*vîÜ v­L;»ŒaÆ6n܈‚‚|hqÞÝÝ?ÿü3`Á‚ÈÈÈÀ½{÷ÐÔÔ½^êêjaïÞ½øû↑{G±ð ½ é[¶liwÀ¹hÑ"ª­­uhÞ™e Z»v­Õ¼Ž=*j^VVÖáêµÑh¤}ûöu8HÏËËs¨î¶ÄÒÓéÓS„¼jÕ*øûû#??EEEÈÏχ››¦L™‚iÓ¦Á××O?ý´Ë”ѧO|÷Ýw˜4i’’’——‡1cÆÀßßr¹Ü<Õ*¦»SPP€#GŽ ;;¹¹¹×ôîÝË–-ÃÔ©S‘“'OâÂ… 6l¼¼¼ •J!“ÉðÚk¯9Tw[bééHؼšaóA:ð@†Â0,†a0 „aX Ãa†Â0,†é:ôT[ÆqºÓ{W¡P@"‘ ##ƒA†»X ó8 „=l™'™÷ƒXó° ÃáÇQUUN‡ääddff¢®®Ó§OÇ‚ 0zôhÿõ¾JIIÁŸþ‰¢¢"aáÂ…xóÍ7-ÊsÄÏöáÇHKKCrr2 àíí ¹\Žàà`(•JÌ™3ééé˜1c†`z{½lm¡¤¤ÙÙÙæ<}||0qâDbĈ­öu·lÓ 55YYYÈËËCRRÞ~ûmQqÚÛ¦]á õõõ8~ü8’““qáÂx{{ã½÷ÞCpp°ë(D¬=ŽiÇ`RR’Õ]h¤R©H&“ ž?uêT§ùÙjµZš?¾`šùóçÓÞ½{ ¥§§ îþ³×ËÖ–…Õ¥­]N{mzêÔ)ÑqÚÛ¦Îö&"ª©©¡Å‹‹º_.e=Ú‘@P\\ݹs‡©ººšbcc Í;—‚ƒƒé믿¦›7o’^¯§ššÚ¿? É“'“^¯ï?[“•é’%KèÊ•+d0¨¡¡.\¸@þþþæX…\Œ—mG˜¬À¦‰ÈÈHܽ{W°»·oß>H[ÄúÙ¾ôÒKˆŽŽ†N§ÃºuëP^^£Ñ½^K—.áÓO?m·¯+ÆË¶£‰‹Ý»w>øàdee¡¦¦ÍÍÍÐét(//ÇîÝ»qçλ&CÄÄéˆG°³|€===±iÓ&ÀÚµkqåÊóý:þ<>ùä×y(]±æ½»iÓ&@eeeí.¤åæævŠŸ­V«5¯­@`eö§Ÿ~"¤T*-ÒŠñ²µe%=..NÔJºµ6§#mê,`"¢û÷ïÓÂ… ]~%Ý¥¼yñ³4h~ùå„„„ )) ………ÉdËå˜9s&’““@Ð[WŒ—­-u‰ˆˆ€ŸŸŸùo”T*&OžŒñãÇ# @p  =ÄÄéH›:ËØ4ƒµwï^Ì™3Çü·s2™ 3g΄\.‡R©t‰gò‰ñæýâ‹/‹òòrŒ1 Ãù×®]ÃÈ‘#!•JqæÌ«V†qéAº#ܽ{ñññP©TÐétæñéÓ§±téRó,‹ƒ±«Ûÿ¸T¤¹¹¹ÝÕâõë×ãý÷ßç;Î<™],"BII Nœ8ÂÂBäççÃÝÝï¼óàããÓ៽0Ì;Hg˜'z Â0,†a0 „aX óØ $,, ‰Äe6°ÄÄÄXÝÞiú,^¼¸Ušžè/ìjíÎaÆ‚»r–––æZ| ÿ‚0 ÿ‚´ƒJ¥‚B¡€R©Duu5ba©SWW‡‘#GbàÀ¸xñ¢ys[rssáëë‹mÛ¶µ»ëÏÙØë+«×ëqòäIddd˜ý¤d2Æ???ó^í¶ØãÓÛF…Bôôt¨T*`Þ¼yðõõípß8ã ¶ºý%&&ZÝ-vðàA‹tÛ·o·Ø1Ø–Õ«WÛí>¸eË@iii6§±¶+RŒ¯¬^¯§ˆˆˆvwϵuwtħ7%%…<<<Ó8p€˜n¶méûí·ßÒíÛ·Éh4R]]¥¦¦šÏµ}JKK ­^½Z0_“ýäܹs[ùÏv¥@ÄøÊæää˜Ó”••Q}}=FÒjµTRRBÛ·o§ÊÊÊNõ鉉!µZMz½žjkkI¡P˜Ïµ-‹é&Ì;×ÂhºåCÙêxSS“y¸F£±HwàÀ@ÇŽ³+`“@Úû´ÝÓ-$±¾²¦‡ýìÙ³]âÓEÍÍÍVͺsrrø)voÞˆˆôíÛ×âxPP€ÿú¬¶tÚëÕ«—yF۽̃ÁìúazçEW#ÖWvÈ!€›7oÚ\Ž#>½¦õ¶Èd2´9bºaËÚæþ`Ö¬Y,Ýð&Mš777ìÚµËìÏ—/_Fnn.6oÞlÕÔ–i^k.~¶ØVŠõ•õöö†T*Ehh(Ö­[¥R‰7n´ª_Kõé:t¨àq“ͪ5Ï*¦‹b²ÓÂ䟤×ë-nbtt4rssqùòeóñÔÔT€\.ï¶Š‹õ•vìaGîÑ£G#$$6lÀ½{÷ð×_–/_Þ­[`;Ó·ÿþðòòÂìÙ³‡ÄÄDh4šV‚r†O/ã‚i;Ž0azÑ{dd$ `Y@¯^æ—¡äææbÿþý€)S¦tkÅáÉkzßE˼3|zHbb"¶lÙ‚ŠŠ 455A§Óáøñã ³µŽ¦ÁúòåËqøða¬_¿^ô[c; ±¾²ñññ8rä®_¿Žšš455¡¡¡*• ;wî€Vou†O/Ó…tÆJúo¿ýÖá|ò?ü`¾ÞÖ5g/Šñ•íhfÑ¢ET[[ëtŸÞ¼¼<@ ¼Xá Þ¼¾¾¾(//GRR233qïÞ=!$$'Nì0ýŒ3°víZøøø@*•ºÄ—ƒ_ÙU«VÁßßùùù(**B~~>ÜÜÜ0eÊL›6 ¾¾¾þ¿Îðéeº†.³ýÉÌÌÄŒ3€?ü[žy¼Æ Ž`4Íýý©S§r«3=§Ï³644àØ±c8tè¾üòKóëÒæ‰îbUVVZÌT]»vÍ®wl0ÌcßÅ5j"##qùòeÿ ÿ Ãa†Â0,†a0 „aX ÃaÃôhþ›…ý dARIEND®B`‚paperwork-2.2.2/paperwork-backend/tests/model/test_password.pdf000066400000000000000000000214351456262201400247730ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream œ¨{àtJ©ÏCžPÊ$Ü N¢$çeFY/ÉJÍÂC†$þÝùÑ_‹ž¢íà§4í¦Jw.ɃÄî%Fðá4sÀÐ$ÞYþpƒ“–qêêYY¼½ònÜlj’í8Ȧë—τڥi†¯ŒÕGˆAåY¸¼‘hàs|_<݈×BÃW‡ß‘ÝûÑ· endstream endobj 3 0 obj 146 endobj 5 0 obj <> stream `fyá ¹”³I£ŒN’ü¼W¥NˆvONœŒô5e»¥î—ᡪ´\&ù ¯a“$ÒÒ?r>’dbRÏL!§lÊ0¸cÄcìó§£ýúéO!–Äçvõƒ¸ú7ý@ìP4;~‘}Ö¡e"òÜò/ŽséíÔ>TÈK„Ä\3÷ ¸šûçÞƒëªî°Åì,kçW0ñ‡G‰?m5\?ùƒå¸±fLÄ5ý=!{UÁ÷œ…ÃŽ^#ðb%“{/‹†¥r\’z™cýû«5¤©§[›ÎÍ/«­K™‹ÉÊuYúáW!<À¨ˆcŠ•šô u¥Ü£šD¯I£°">´8tüÕ•cÄMb[²dq[-óK¤ô%íaJ´…Lü³ MS3Ô¼ŒöaªÞÝ×<Š%†LÌmìç£At5¤ (õÅqñyœ|ˆ%è.åÏloŒ›³ ºõXw*—<ÞSÃb´ ˆx\Wn~Ûå8F'ÎMA9–óšqDx> a!I¯O¬©ù,Úø]‰Ìð}I@ öÎlæ‚#ƒÏ<"æÄ·cf¢¸,ŠýÆ'Á­,vSP>Œ—×jjøÝ’»jÌcõúᘇk«pvñˆõû4f]ž»o`C>í¯_ΉˆÀþ6Ãô° ¾ßãÛüƒ ÞƒÍBÜþ“7 ð†ŒÞ"¿¶Ï‚Ù‘òªdtg£St„©z&[;»÷qr´e\\Ð3Ì¿’§bµõ åÓO¡! üÏZ­È6 ôÛ9³ð³Ù@z9³¢„ñ©èí•Gt¤Ã€CLŠ÷FÆ÷£®¾&C<, ².ýþémÓz4`3üDzï(+æM,Âß“—ÆþGœ/±§}VòÒU¡#ìŸä «§ºþ?„‚où ¶X¸XÍýÌB4ïÌÔcqD§qKCÕÐoS’’ØY8±Ý¤ØZo‡â¹è'Æ¥ÂZP‰!M–øJŸ,ßúíÌF˜Iø+%uÙ1e!dëß¶{x€í.ÍBÑ7àÐ ÉÄe“–.KªC¬A µBð‚îÃDò9K"âýîÕÏ9že®˜1äée0`šH;k™‡ZO†EÖnü;J[Š)DVnÖÍ”* AÙ.ùw¦$¬«¯LfÆ®<ô‡àëö²R‡YŽ—X5Àm‚y÷Wµ$,à^É/þloø‰·ÙÈû6^¸k91¡»d!g–1x‡ ç¾ó€çÁõ@ZÃä§dµ6Y”Ö Vä&”W±EÇQôÙ ' šHüyeb£„½7¥~†=Œ,R©€y‰öqŠ]™KÔÈ1ŸteÁ£È*ÈÐ2_zQBÁñtÕBÚWM"+Æí+Ÿùèž°#à˜„5`5°Éþh #ùÈ[|ffÿôêÓ»31ñ/uô™Ç+ÅĹL Æq O=+Ê@«ó¿$æáõ]ØUHp§¸ˆ x¯;š›DÂ)ñ„ÕUÍ?)·¶¿wÁšåD¨X]•§ l­`ŽÁ–I¦ÏDžÿWã?ð ëºÑTó¬Ü^{‘.v”FGOžÃ>|Sãï`›>ot«2¸8Èê4‹‰Øê¾y¯6,7Nà)埿x4?0Ãu#)Úr¸[*îé¹v†Eª=MƒÞ÷ôú³iÒx»hL7Ü•&ªÛþ´ÒìwÑ6áj·ZuÿBtÐÜØ…/7æ!¤xXÝ“N@YRAÓ¹•òo屮$G£m\ B9Od0K‹6±vAH½_‰½ñnŠ$Þ¼MuèÕl¾M<#~PAöLî ìÇÑZ¡bÇš2yyH{ðñD–Ýìûñßµª{kÅÍuˆØMƒ‚‚ÿÛ0êy' «¬ß}I8¡Oš~ê©cY »N¶X@Ct.—•ÕŒ=·ÛÜg „!ª„ ÿLÄKJW5Güé/&s ê y3Äñ¬ß¥Gö–E¬ åó!’M‚õõ¡0â—äôÄ0è]³ÔÇU¤E±™ôŽ0™Ì͸6¦=äbÔ•c+¹P¶*B³+@c’>pG‚(¾bÒgäM$A›‘tR<³.k?•»w°]ÂX}ö±í›È‹u¥ÒIêeà©IƒSç„m80xµ`ê\kóè¯ë8Øèr¤Küï–ÿöTiáh4¢S}¬ÑBõ9ší ­ÚÓ¼~–—sÁo4ÃPè'i ?ËêóÏtÚ`³R-ºAÀ‘ Û5Í\³ hwf&T‹ªäݼ§jw=¼ppƒ9¯†´X‘/r«îD*\yx&ËtøºÙž}rvm¥´€¢c­3xÚ ˜Ë³ˆ¦“3cÀд[—4›qè´–Ey¦fô=ÚÇø°ãÏÜDjK:yiãO9>?þ²Þe¼îÈʯßseó+[†ûn@„Ž«I'll’Ç“²žu—î—Ñîò§Ç¹3LëK=‘ÿ‰m­h®-¦4Å>'˜•û#Žë¶½bÔ€É$Ôô­{uÒ›¶¹ï{S¢zã4UÍdˆ¸T-Y¸‹IùÕ‡E}M;mÑ}`àIìô¤xùsSfÊœ7EòÞ² ï ô`]>ï(™2®ó’[úWƒGU‹Í„mdz½¨wþø©_hI+¶Qu·GŸDRjB®gœ,ùʨ… •ÖýÝ€Å% ìš~²w÷¸|¿5ƒD­8Qã&"¥M9F ÇîeRö­¬ÎU_8›ü,^äN€±*˜™ðp=¥¾Ÿ¥—fûæà¥6UÎ.¼Ç° Ôí®5ÄÇx9xã 2¨ô’ÍÓuR]7øØñ@“#g Ù÷{ ®kU±ÇÿFÍ ¹v`üÚ¬Dºý‰QY„»î|1<ðesب¶ý+œé8ä66 Ý»P°ÜSWt›ß·wOJÝOÊE{^uijP[ÈF¦g/2go–LF ‚a»`ö™eQr”ÿÞ^.k€·’2·ØÝŒtôÂK:™S^ÑÏ̼èÓl.8é•àáÍ{„¿³œ|y6ÌíP½åµ¬bÀ¹%}y#x“šO%O x”Z Ì0Ñ}ìg ®0ƒÛÇCok;-¯ÍC]¸ø*o¨X Ò8eÜÚRWžWêðø>I v×¼uôO‰ÂÎÔÎÚ/â›o='Ï-æN 'ÿÕ9¡™ä {.lûý?ÚU®Vl²6é¥HœþW…#À¡Ò&Aôª×ÌS xWÿ.æl©^rwؤ£hm!éØI Ñý Å7Ø—8¡ðÐeÔ*¾þ"åzùë£í“E‡íI²jhj“åoÈŽ L”دL2úH £añÆÖÑW†Ó:ùdÐAÉ¢!ù g°ˆÿ×ݽ~mš[7y ”­ÑÌ10MÈ]C§¿ý/òŠíÞ0-¬Î¼Ï,˜ ½ÎÁáTômô2 y’qÏÓ[s´3‹£ìu¤¶4ÿ~^®Â=&–.•ĺðm_˜Ì.H•Pé1Þa°”Ó€k2¿xàÄî7Åa¯ƒ¦§7ô¢±ÅÓ¥uo瀰xfsÅãñ{Š®Gh¿ÍIIìÝ,DÏô˜J«hxZ֕ͧ‰j|ÚÂÌ;6¦Ë;&RL>KMCÃé?AL×Kà'µ”û0CTíÕ‹ŸoÅÙà}”¾¥tc±Ò«|5äõ²´•ÄØ>‘¼Æ­-¸QwÜñw缇(nøÒ:´Ô– ª”ØáSªn«.Z<éZ¿n z`—›`0I–Àà–ÄβÜ* þµ œIY«z{T´ÔŒŠ3PçÂëîî ‘ÖâÄ»˜q —hüÐq"`s;Ãô7#œ8ª@©ïrLsÿ¢”ý”ª™° #]T›<ÿîåÇ(û³ÐºDW€ÕEèšx‘ ®¢S ´™çéGº äG‚ÒX,d5ÝȶÙ&£/ÔÑúE£î¿£Ì&åAÏ,vx QôâF–ï]"1ÓÆ }rMòúâÁ‚4^ŒGKÝ1œ¢¹´ªv«ô´"Ð˺¼[Šb„Ù¼åþåfNVuð) ÒƒoðÏ—DûG¦®ø¹Öep~ϯa,« ¿¬Öª¸+P¬0ò)…¨ ÅöyY5Œš‰¥lû£‹o^‰•TòJnVÑãmšãy@‰Ä)?*´ õf­QMÒŽ¬v’aarG\&å{ïÊ/-æ‡=̶ûOQb7#e×tÐ6cž‡[u†‰jV'/nY·Ô7{qCë9qÝ}R/èä.Ú}ÔMÄé!÷o+rÌ·˜²…G#·JØ‹ãþøG—§çŽG9×»¨ª_”÷âµÓ±mßq¤uô{ÝnD#›f‘|›gäè˜qh’¹·Š|w} ÒÆQ0K! [èkÜ]¯ hM‘T! ŠÏ¿È—FÓ/p²Úž\$Roõ*wÿ¬“å;·†À4ú4k$ÉÓr¥:³\3â5ž#›rzüE•c&¹ÃrÒ"Ķ© MÚvØ÷c—´ï*3Z¾é,_üÅl3ÞdÖpØ÷Tµz6ö'°oCgxy"àû—@”çâì¾hãåÄzdÜôŰ&üd«ªp§=2MÈ9ð‰sÄ[}}§-›)cfÕ‰uÂÓâ F*ãÉç‘Dh»ÿ[†ŒEÛM@*ðÉîšH©PÉÝ9¤L+‰"ehHc¾8‚4Õky‚~ÞÁ:Qæ¸]€¢IæÔ9D8åFÚÈ£>Ö†“ßy} Õ´ÑSùÊ…íØ'³ ú7äµ:;h\4lLa‘¦>ÅÝLH dÇJѰÚ0°Þ…iëˆÃE|]6ºbÖ ©ŒŽ„²‚õ€“pŠ• N%Ú[Õ`ªÜhÀ?þ¦~v„‘oN`Q"æÀÔÝŠwÎÜ&IcKaJ´)eœÖ Û·Õÿn¯sY%0\/ô`r’G,sÿDWíï8üÀÿ}=ç ‘f@”¶Zê“ϳ˜†œ+GÙ¢x6Ÿ¶6Å ó¶GÎÝŒ ç<k\ÑS¤u¨æ!ÛÍâ€PÄO9¾` ßJ8lSgźƒÅ©œûR[úÀW—AÔöG<•ub@žØßð‚‡ë)±òu!›“·A;] ÒæI´Ëg ÝCóÎÊr “ÌÍQ°Ý¤Ä/Ÿ’âZ³N‹l8XñKõ¯µµ´~÷€ûŒü]HØÑr*d=›¯ÂS‚ßwчI¤ÂX š˜Ú”%0†š ¨$'ž®âÿ —då(t'o»@‰%œ° ‹€Õéjcn€Ü}*N..uj•«üŠSô ŠLâ‰ü4Òh¤Õ[´áB#âpÑuòµzpPžÏn可ÊHg';z™_QS"éœoäÔç9Ìf§qxÊý!î`súQi—žÌ/ɲò'©¸õ €Áe³õ”•ÅPu´»ï5pˆŠLD:½…Sk+ëv–ðJò_·ð‚û”Wô¥@Т§èª=êÏ“©VÜâùp$ƒ¡k›‡¦Uò¥± ÌŒF×5¶vJ²™àS¦û«3OŠS6éÊȧˆêk¥P›2C‡`Šj&}%1d$i¦Ññ6<“^뉴L¾ ?Z8àÕœ\ªjt,,ÖSk#X£Ã7ÁßåÛ»šûJØ=®—°¼}ññ(¨Ì<^àiKx¥›âvÃäÛGjg¿”b¯8@·›Á¾³Â¼çf± [,NñÆîczYúvSs»>´ûôÄÎ>£pÀ²Ï„jxѸàx N3)ü‘{4dqñ‹FD {+'(ÃöñÿO®Þ¬mk–M.(UXý8ÞšÔ]jPJH„þúmDÑ£­‚S´ÁžÂÂ]ÿSô¯B=ݳ΃8¦£.æ'µ‰y¡ŽÓ_ãp–9=¸ëêïxãG1éÐ÷ÿÔ¨P“m®¿;Þ;üEXwô»ã¬ïfp‹×ÅÄÙÊ5“ÄÕð‡M´ÈC&"k p~¹éßÓn)ë=£Q^õ|žã ’…øEJDÇû'QvÄ1ùæñ QÉhÏÚ'ñZ+Ê¢+ Šyt¢Ï OxqZRãÛÀt¥ä˜Ý’Ú©QUÄ,—ñ­   4KC™(Ãök ãÖ|‹Ÿíó•¼~bx{jûCÐ[^w¶Pæp2‰â?ò£›ð?ú”yA>’%D3o)²{ö3ôòÅåZ}ÀJë 2VöB’ß*ªlqsË¢¡×g6d,ÞŸ¥®BžnÈ(O ³k†T¨6{ÑLÔuâ0õjaøBîèQQKÓùÙ’ÉÀýÃŒ³V9 xÏ!DμÚôˆ*½¦ŸV¡&(g¶¬Oã³Ô¶Ôõ舮ò§ìά¼*Œ¸ÉÒ"Þ¹!°¯ 'w`>.E7ÿèòÙ‚EUÛÚ1%3>d _YŒ¶~·ì×&»+h ²ësšžˆá±­|KZi‰CUªÉ>Š1ÇÞ¤ÈӚĮPL’ÎÒºª¾È]BÌŒÈìKH±´Ð6bê¾õÉÛ”W©ÁI:´œô•{Üâga}µò þ²~mŒ¶3ÃR5»Û.£ÃÄ‚Ù7À´½,M|9%4oðòòŽªOÂ0°:¦˜A™ùöB‰:Ë˶×ÿÐøíÅU?ïþ†‚©Rd=á}ãí·Á·ŠPW Çû–d7‹éžòç™­}N{ª¤®~}ÍþTÛˆ’¯j²ö™%¬Æ™“Ç­Y}U_ÎèûD"à~¨Jà4RjJƒûιƒáoµš8q¼ßÜ%`,®Ú(2ÌÏþ“ŠûDÕ{k0 ˆŠfyœÛ·xè°ÙZ8ìEäêþêvã!ÖµL B8>n/Øá~º\O4É_yåãšÒþ˜²dD[ñ†’ä©pîXM¼ö•}ˆöu¢g+\;ïWü°„r‡:àr ºýöZ?ö’?%¸Š{‹ŸDÖ©Xð!/OáHŠšv¨0gÒ›?•E´…HU]_×ÛížKv1B§ö‰hN_Ð7Y!?Æ?ï g›‘[úéG‘–¢úÅÔšl=nfàHÃÒ€Æêû# ¯ÏDà!Ç…!ŠªŽ“xåZf8ýÑ·o÷5™¤QLÇE!BžóY¤|­ÞùóEú+kÞëÇ-#®ü¯ÆùGÎueQ,O^GjØû¡¬ßZ…-›á¹ô2ƒ+³1é熕¾¼ì¨>¯I‘H˜=ÆY»03Ø"á´ 1Ã?ÅAÄlb‘ûî…=8¶Ô%eº‡ßÂ\ä¥ZðÖz}a’èË0·þwØÈú’ñÁû$ ™cø46Q)NO—Ûp5d¹zÕRg…ýµŽ²ùrÛ]á´e<5‘¹¦UÚ'sAÙ|=ÚØO¶A$5ñ¥&ÒN$ºáÜ®´õ³úXwƒÉϤ°Y|ÍÅ£«S „X ä·õͳµÊoyw¥&§ÑÍVãjXm,8æ©i”èü|-ßQ4±Sµñ ß9´uþ¥¼aÞ8(ý«ê5K Z ¬ù‰Ë‹_–4jb•ªF8Il‰¶€9‚ðù¥°ù¨z^6ܧ¢À†BX;üÅð9BˆÙá@-pÇçà(i@§ø#©ÍP*R@ø‡„éýÒJyƒÆ?‰å7HN–,¬,²ºe…¡´ì³­o¾=/ ÙU¦ÄÙ"C]ýÁ£FžÖÙM§äÝÛq××(ßµ¶Æ’@¾ŠÓý¸éL nBkAyr·üúd™­j9î<Û ×áË‘‰\î¢N{+ý+\Åg Ó€”ï™eXZxý'Ùnù4_$2»Žµ&é`÷¦Ë"1V9)}qWŽQ¦8Æ•^§xy ŸÔUמ$•@àTüô5²ê›ü„y)6"w™™âžìÎPí´îéG•k“´Æ»³Ý¦>K°æ¢P8Q&j&7ø¨ÃŒÝÓWzí’w`l5Ø¡ÉÙ)ßÀìCŒ¾'€Š%ZÔ½Rp|Ëx1-aFÕfNâšPA òÙF<ŠÔÀk´Ív.c"¦NèÏ­Ô7M…„ÐnVXˆ½ååN‘ ›šS0I’ÒVØÖZº†¾ `o*ÒxRÚîL’’zäµúÓÆL‚¹$æ‹ãËsãÞ-\Œ¤U‹ÑÊp‰G²:üV?Â;7–æ7&ö†X7PµÑGõxßKÅ`âà“ÑW¬ÕËdwÀ{ŽãçÞXYáù?ƒñ@ˆW?~__½¿Íêñhð7«2ÅѤ\?oIíPí§è…ûdw¼¯ù×rl0ò×TÄgÏÒ ITÌÝÞAÏ1/„• ãlçËøó‚!)4á6 ÝÆBq4árwÓ2ŸÂ µßm)6‘{†-ô”V­OèpuœüË$Ž—ïghaMJÏJ âziè*Ÿ'6 .±Y9St‰it>í«¾Ím%xꉾè–Ê"<ºË? endstream endobj 6 0 obj 6557 endobj 7 0 obj <> endobj 8 0 obj <> stream –“´]­U´ÁÿZë¸ ÁOÄûiѼµñô6z ÐÖO]ùÉ"À’ù¶¥+êÈE)hÆòœ RUQè&‘¾QJÒcG$’E6­­yÈr/(Ja2=­S€ÝÃ’ïå[-X(âd,¾ÞÚk"¹½¶¬Ì‡î‹­‹ý/ejpéÒþ‘Bž!•y9}kH²CÐö€dªË:—”œüóµeÁNú• 9»û6Ûª@ëÀ†5|oÁ“.EêóÑ 1%èÈßÛ"÷ ½”-p<›®a ¥ouˆA›ž¾ — ÑT–¦_08gŸßz5bÔ†xV©>^C¨5#c> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer<0F4AD7BD3225496D4174E8D76D12897CC877CEED24DC9DB568A5637A671CE5E2> /CreationDate(µåÁ}y:s5Ú€\\d½"ã!ü£º)>> endobj 14 0 obj <> endobj xref 0 15 0000000000 65535 f 0000007789 00000 n 0000000019 00000 n 0000000236 00000 n 0000007958 00000 n 0000000256 00000 n 0000006898 00000 n 0000006919 00000 n 0000007114 00000 n 0000007478 00000 n 0000007702 00000 n 0000007734 00000 n 0000008057 00000 n 0000008154 00000 n 0000008330 00000 n trailer < <4CC2DA594C5DCB199E0D108A41E1AA2B> ] /DocChecksum /4234D31F6DCF9FDC719B74544277637C >> startxref 8470 %%EOF paperwork-2.2.2/paperwork-backend/tests/model/tests_all.py000066400000000000000000001025751456262201400237500ustar00rootroot00000000000000import itertools import os import shutil import tempfile import unittest import openpaperwork_core import openpaperwork_core.fs class BaseTest(unittest.TestCase): def setUp(self): self.int_generator = itertools.count() self.pdf = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "doc.pdf" ) ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.extra_text") self.core.load("paperwork_backend.model.hocr") self.core.load("paperwork_backend.model.img") self.core.load("paperwork_backend.model.img_overlay") self.core.load("paperwork_backend.model.pdf") self.core.load("paperwork_backend.model.workdir") self.core.init() self.work_dir = tempfile.mkdtemp(prefix="paperwork_tests_all_") self.work_dir_url = self.core.call_success("fs_safe", self.work_dir) self.core.call_all("config_put", "workdir", self.work_dir_url) def tearDown(self): shutil.rmtree(self.work_dir) def _copy_pdf(self, out_pdf_url): dirname = self.core.call_success("fs_dirname", out_pdf_url) self.core.call_success("fs_mkdir_p", dirname) self.core.call_success("fs_copy", self.pdf, out_pdf_url) def _make_file(self, out_file_url): dirname = self.core.call_success("fs_dirname", out_file_url) self.core.call_success("fs_mkdir_p", dirname) with self.core.call_success("fs_open", out_file_url, 'w') as fd: fd.write("Generated content {}\n".format(next(self.int_generator))) class TestAll(BaseTest): def setUp(self): super().setUp() self.doc_pdf = self.core.call_success( "fs_join", self.work_dir_url, "20200525_1241_05" ) self._copy_pdf(self.doc_pdf + "/doc.pdf") self._make_file(self.doc_pdf + "/paper.2.edited.jpg") self._make_file(self.doc_pdf + "/paper.2.words") self._make_file(self.doc_pdf + "/extra.txt") self.doc_b = self.core.call_success( "fs_join", self.work_dir_url, "19851212_1233_00" ) self._make_file(self.doc_b + "/paper.1.jpg") self._make_file(self.doc_b + "/paper.1.words") self._make_file(self.doc_b + "/paper.2.jpg") self._make_file(self.doc_b + "/paper.2.words") self._make_file(self.doc_b + "/paper.3.jpg") self._make_file(self.doc_b + "/paper.3.words") self._make_file(self.doc_b + "/paper.3.edited.jgg") self._make_file(self.doc_b + "/paper.4.jpg") self._make_file(self.doc_b + "/paper.4.words") self.doc_c = self.core.call_success( "fs_join", self.work_dir_url, "19851224_1233_00" ) self._make_file(self.doc_c + "/paper.1.jpg") self._make_file(self.doc_c + "/paper.1.words") self._make_file(self.doc_c + "/paper.2.jpg") self._make_file(self.doc_c + "/paper.2.words") self._make_file(self.doc_b + "/paper.2.edited.jgg") self._make_file(self.doc_c + "/paper.3.jpg") self._make_file(self.doc_c + "/paper.3.words") def test_basic_nb_pages(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 3) def _get_page_hash(self, doc_url, page_idx): return self.core.call_success( "page_get_hash_by_url", doc_url, page_idx ) def test_img_page_delete(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] self.core.call_all("page_delete_by_url", self.doc_b, 2) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 3) new_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 3) ] self.assertEqual(hashes[0], new_hashes[0]) self.assertEqual(hashes[1], new_hashes[1]) self.assertEqual(hashes[3], new_hashes[2]) def test_img_page_move_internal(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] # 0 becomes 2 # --> 1 becomes 0 # --> 2 becomes 1 self.core.call_all( "page_move_by_url", self.doc_b, 0, self.doc_b, 2 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) new_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] self.assertEqual(hashes[0], new_hashes[2]) self.assertEqual(hashes[1], new_hashes[0]) self.assertEqual(hashes[2], new_hashes[1]) self.assertEqual(hashes[3], new_hashes[3]) def test_img_page_move_internal_reversed(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] # 2 becomes 0 # --> 0 becomes 1 # --> 1 becomes 2 self.core.call_all( "page_move_by_url", self.doc_b, 2, self.doc_b, 0 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) new_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] self.assertEqual(hashes[0], new_hashes[1]) self.assertEqual(hashes[1], new_hashes[2]) self.assertEqual(hashes[2], new_hashes[0]) self.assertEqual(hashes[3], new_hashes[3]) def test_img_page_move_external(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 3) doc_b_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 3) ] # doc_c p1 becomes doc_b p2 # --> doc_c p2 becomes doc_c p1 # --> doc_b p2 becomes doc_b p3 # --> doc_b p3 becomes doc_b p4 self.core.call_all( "page_move_by_url", self.doc_c, 1, self.doc_b, 2 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 5) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 2) new_doc_b_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 5) ] new_doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 2) ] self.assertEqual(doc_b_hashes[0], new_doc_b_hashes[0]) self.assertEqual(doc_b_hashes[1], new_doc_b_hashes[1]) self.assertEqual(doc_b_hashes[2], new_doc_b_hashes[3]) self.assertEqual(doc_b_hashes[3], new_doc_b_hashes[4]) self.assertEqual(doc_c_hashes[0], new_doc_c_hashes[0]) self.assertEqual(doc_c_hashes[1], new_doc_b_hashes[2]) self.assertEqual(doc_c_hashes[2], new_doc_c_hashes[1]) def test_pdf_hashes(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] # just make sure all the hashes are different from one another for (e, h) in enumerate(hashes): for i in hashes[e + 1:]: self.assertNotEqual(h, i) def test_pdf_page_delete(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.core.call_all("page_delete_by_url", self.doc_pdf, 2) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 3) new_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 3) ] self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertEqual(hashes[0], new_hashes[0]) self.assertEqual(hashes[1], new_hashes[1]) self.assertEqual(hashes[3], new_hashes[2]) def test_pdf_page_move_internal(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] # 0 becomes 2 # --> 1 becomes 0 # --> 2 becomes 1 self.core.call_all( "page_move_by_url", self.doc_pdf, 0, self.doc_pdf, 2 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) new_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] self.assertEqual(hashes[0], new_hashes[2]) self.assertEqual(hashes[1], new_hashes[0]) self.assertEqual(hashes[2], new_hashes[1]) self.assertEqual(hashes[3], new_hashes[3]) def test_pdf_page_move_internal_reversed(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] # 2 becomes 0 # --> 0 becomes 1 # --> 1 becomes 2 self.core.call_all( "page_move_by_url", self.doc_pdf, 2, self.doc_pdf, 0 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) new_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] self.assertEqual(hashes[0], new_hashes[1]) self.assertEqual(hashes[1], new_hashes[2]) self.assertEqual(hashes[2], new_hashes[0]) self.assertEqual(hashes[3], new_hashes[3]) def test_img_to_pdf_page_move_then_delete(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 3) doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 3) ] self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 0 ).endswith("19851224_1233_00/paper.1.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 1 ).endswith("19851224_1233_00/paper.2.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 2 ).endswith("19851224_1233_00/paper.3.jpg")) # doc_c p1 becomes doc_pdf p2 # --> doc_c p2 becomes doc_c p1 # --> doc_pdf p2 becomes doc_pdf p3 # --> doc_pdf p3 becomes doc_pdf p4 self.core.call_all( "page_move_by_url", self.doc_c, 1, self.doc_pdf, 2 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 5) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 2) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 5) ] new_doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 2) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_pdf_hashes[1], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[3]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[4]) self.assertEqual(doc_c_hashes[0], new_doc_c_hashes[0]) self.assertEqual(doc_c_hashes[1], new_doc_pdf_hashes[2]) self.assertEqual(doc_c_hashes[2], new_doc_c_hashes[1]) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/paper.3.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 4 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 0 ).endswith("19851224_1233_00/paper.1.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 1 ).endswith("19851224_1233_00/paper.2.jpg")) # we delete the added img page self.core.call_all("page_delete_by_url", self.doc_pdf, 2) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 2) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] new_doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 2) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_pdf_hashes[1], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[2]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[3]) self.assertEqual(doc_c_hashes[0], new_doc_c_hashes[0]) self.assertEqual(doc_c_hashes[2], new_doc_c_hashes[1]) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 0 ).endswith("19851224_1233_00/paper.1.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 1 ).endswith("19851224_1233_00/paper.2.jpg")) def test_pdf_to_img_page_move(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 3) doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 3) ] # doc_pdf p3 becomes doc_c p2 # --> doc_c p2 becomes doc_c p3 # --> doc_c p2 becomes doc_c p3 # --> doc_pdf p4 becomes doc_pdf p3 self.core.call_all( "page_move_by_url", self.doc_pdf, 2, self.doc_c, 1 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 3) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 4) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 3) ] new_doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 4) ] # in that case, an image page has been generated from the PDF page # --> hash of the new image page won't match the PDF hash self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_pdf_hashes[1], new_doc_pdf_hashes[1]) self.assertNotEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[2]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[2]) self.assertEqual(doc_c_hashes[0], new_doc_c_hashes[0]) self.assertNotEqual(doc_c_hashes[1], new_doc_c_hashes[1]) self.assertEqual(doc_c_hashes[1], new_doc_c_hashes[2]) self.assertEqual(doc_c_hashes[2], new_doc_c_hashes[3]) def test_img_to_pdf_complex(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 3) doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 4) ] doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 3) ] self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 0 ).endswith("19851224_1233_00/paper.1.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 1 ).endswith("19851224_1233_00/paper.2.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 2 ).endswith("19851224_1233_00/paper.3.jpg")) # doc_c p1 becomes doc_pdf p5 # --> doc_c p2 becomes doc_c p1 self.core.call_all( "page_move_by_url", self.doc_c, 1, self.doc_pdf, 4 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 5) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 2) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 5) ] new_doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 2) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_pdf_hashes[1], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[2]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[3]) self.assertEqual(doc_c_hashes[0], new_doc_c_hashes[0]) self.assertEqual(doc_c_hashes[1], new_doc_pdf_hashes[4]) self.assertEqual(doc_c_hashes[2], new_doc_c_hashes[1]) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 4 ).endswith("20200525_1241_05/paper.5.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 0 ).endswith("19851224_1233_00/paper.1.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 1 ).endswith("19851224_1233_00/paper.2.jpg")) # doc_pdf p5 (previously doc_c p2) becomes doc_pdf p2 # --> pdf_pdf pages shift self.core.call_all( "page_move_by_url", self.doc_pdf, 4, self.doc_pdf, 1 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 5) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertEqual(nb, 2) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 5) ] new_doc_c_hashes = [ self._get_page_hash(self.doc_c, page_idx) for page_idx in range(0, 2) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_c_hashes[1], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[1], new_doc_pdf_hashes[2]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[3]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[4]) self.assertEqual(doc_c_hashes[0], new_doc_c_hashes[0]) self.assertEqual(doc_c_hashes[2], new_doc_c_hashes[1]) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/paper.3.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 4 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 0 ).endswith("19851224_1233_00/paper.1.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_c, 1 ).endswith("19851224_1233_00/paper.2.jpg")) # kill doc_c by remove its last 2 pages self.core.call_all( "page_move_by_url", self.doc_c, 0, self.doc_pdf, 5 ) self.core.call_all( "page_move_by_url", self.doc_c, 0, self.doc_pdf, 6 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 7) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertIsNone(nb) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 7) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_c_hashes[1], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[1], new_doc_pdf_hashes[2]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[3]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[4]) self.assertEqual(doc_c_hashes[0], new_doc_pdf_hashes[5]) self.assertEqual(doc_c_hashes[2], new_doc_pdf_hashes[6]) # remove a page in the PDF, just for fun self.core.call_all("page_delete_by_url", self.doc_pdf, 2) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 6) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertIsNone(nb) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 6) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_c_hashes[1], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[2]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[3]) self.assertEqual(doc_c_hashes[0], new_doc_pdf_hashes[4]) self.assertEqual(doc_c_hashes[2], new_doc_pdf_hashes[5]) # remove another page in the PDF, just for fun self.core.call_all("page_delete_by_url", self.doc_pdf, 1) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_pdf) self.assertEqual(nb, 5) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_c) self.assertIsNone(nb) new_doc_pdf_hashes = [ self._get_page_hash(self.doc_pdf, page_idx) for page_idx in range(0, 5) ] self.assertEqual(doc_pdf_hashes[0], new_doc_pdf_hashes[0]) self.assertEqual(doc_pdf_hashes[2], new_doc_pdf_hashes[1]) self.assertEqual(doc_pdf_hashes[3], new_doc_pdf_hashes[2]) self.assertEqual(doc_c_hashes[0], new_doc_pdf_hashes[3]) self.assertEqual(doc_c_hashes[2], new_doc_pdf_hashes[4]) def test_img_page_move_new_doc(self): self.new_doc = self.core.call_success( "fs_join", self.work_dir_url, "19871224_1233_00" ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 4) doc_b_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 4) ] self.core.call_all( "page_move_by_url", self.doc_b, 1, self.new_doc, 0 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 3) nb = self.core.call_success("doc_get_nb_pages_by_url", self.new_doc) self.assertEqual(nb, 1) new_doc_b_hashes = [ self._get_page_hash(self.doc_b, page_idx) for page_idx in range(0, 3) ] new_doc_hash = self._get_page_hash(self.new_doc, 0) self.assertEqual(doc_b_hashes[0], new_doc_b_hashes[0]) self.assertEqual(doc_b_hashes[2], new_doc_b_hashes[1]) self.assertEqual(doc_b_hashes[3], new_doc_b_hashes[2]) self.assertEqual(doc_b_hashes[1], new_doc_hash) def test_img_in_pdf_move(self): # Bug report #245 on openpaper.work # JPEG goes at the end of the PDF self.core.call_all( "page_move_by_url", self.doc_b, 1, self.doc_pdf, 4 ) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=4")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 4 ).endswith("20200525_1241_05/paper.5.jpg")) # Move the JPEG around self.core.call_all( "page_move_by_url", self.doc_pdf, 4, self.doc_pdf, 3 ) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/paper.4.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 4 ).endswith("20200525_1241_05/doc.pdf#page=4")) # Move the JPEG around again self.core.call_all( "page_move_by_url", self.doc_pdf, 3, self.doc_pdf, 1 ) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 0 ).endswith("20200525_1241_05/doc.pdf#page=1")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 1 ).endswith("20200525_1241_05/paper.2.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 2 ).endswith("20200525_1241_05/paper.3.edited.jpg")) self.assertTrue(self.core.call_success( "page_get_img_url", self.doc_pdf, 3 ).endswith("20200525_1241_05/doc.pdf#page=3")) self.assertTrue(self.core.call_success( # bug #245: returned None here "page_get_img_url", self.doc_pdf, 4 ).endswith("20200525_1241_05/doc.pdf#page=4")) class TestBug1(BaseTest): def setUp(self): super().setUp() self.doc_a = self.core.call_success( "fs_join", self.work_dir_url, "20200525_1241_05" ) self._copy_pdf(self.doc_a + "/doc.pdf") self._make_file(self.doc_a + "/paper.1.edited.png") self._make_file(self.doc_a + "/paper.1.words") self._make_file(self.doc_a + "/paper.2.edited.png") self._make_file(self.doc_a + "/paper.2.words") self._make_file(self.doc_a + "/paper.3.edited.png") self._make_file(self.doc_a + "/paper.3.words") self.doc_b = self.core.call_success( "fs_join", self.work_dir_url, "20200525_1441_05" ) self._make_file(self.doc_b + "/paper.1.png") self._make_file(self.doc_b + "/paper.1.edited.png") self._make_file(self.doc_b + "/paper.1.words") def test_bug_1(self): nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_a) self.assertEqual(nb, 4) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 1) self.core.call_all( "page_move_by_url", self.doc_a, 1, self.doc_b, 1 ) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_a) self.assertEqual(nb, 3) nb = self.core.call_success("doc_get_nb_pages_by_url", self.doc_b) self.assertEqual(nb, 2) paperwork-2.2.2/paperwork-backend/tests/model/tests_converted.py000066400000000000000000000054601456262201400251640ustar00rootroot00000000000000import os import os.path import shutil import tempfile import unittest import openpaperwork_core import paperwork_backend.sync class TestConvertedPdf(unittest.TestCase): def setUp(self): self.test_doc = os.path.join( os.path.dirname(os.path.abspath(__file__)), "test.docx" ) self.upd_docs = set() self.nb_commits = 0 class TestTransaction(paperwork_backend.sync.BaseTransaction): priority = 0 def upd_doc(s, doc_id): super().upd_doc(doc_id) self.upd_docs.add(doc_id) def commit(s): super().commit() self.nb_commits += 1 class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def doc_transaction_start(s, transactions, expected=-1): transactions.append(TestTransaction( self.core, expected )) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core._load_module("fake_module", FakeModule()) self.core.load("openpaperwork_core.config.fake") self.core.load("paperwork_backend.model.converted") self.core.init() self.config = self.core.get_by_name("openpaperwork_core.config.fake") def test_on_page_get_img_url(self): with tempfile.TemporaryDirectory() as tmp_dir: self.config.settings = { "workdir": self.core.call_success("fs_safe", tmp_dir), } doc_dir = os.path.join(tmp_dir, "some_doc") os.makedirs(doc_dir) docx = os.path.join(doc_dir, "doc.docx") pdf = os.path.join(doc_dir, "doc.pdf") shutil.copyfile(self.test_doc, docx) self.core.call_all( "page_get_img_url", self.core.call_success("fs_safe", doc_dir), 0, # page_idx write=False ) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertEqual(self.nb_commits, 1) self.assertTrue(os.access(pdf, os.R_OK)) def test_sync(self): with tempfile.TemporaryDirectory() as tmp_dir: self.config.settings = { "workdir": self.core.call_success("fs_safe", tmp_dir), } doc_dir = os.path.join(tmp_dir, "some_doc") os.makedirs(doc_dir) docx = os.path.join(doc_dir, "doc.docx") pdf = os.path.join(doc_dir, "doc.pdf") shutil.copyfile(self.test_doc, docx) self.core.call_all("transaction_sync_all") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.assertTrue(os.access(pdf, os.R_OK)) paperwork-2.2.2/paperwork-backend/tests/model/tests_extra_text.py000066400000000000000000000014021456262201400253520ustar00rootroot00000000000000import unittest import openpaperwork_core class TestExtraText(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.extra_text") self.core.init() self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_get_boxes(self): self.fs.fs = { "some_doc": {}, } self.core.call_all( "doc_set_extra_text_by_url", "file:///some_doc", "some\ntext" ) text = [] self.core.call_all( "doc_get_text_by_url", text, "file:///some_doc" ) self.assertEqual(text, ['some\ntext']) paperwork-2.2.2/paperwork-backend/tests/model/tests_hocr.py000066400000000000000000000054661456262201400241340ustar00rootroot00000000000000import re import unittest import openpaperwork_core TEST_XML = """ OCR output

ABC def

""" class TestHocr(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.hocr") self.core.init() self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_get_boxes(self): self.fs.fs = { "some_doc": { "paper.4.words": TEST_XML, }, } lines = self.core.call_success( "page_get_boxes_by_url", "file:///some_doc", 1 ) self.assertIsNone(lines) lines = list( self.core.call_success( "page_get_boxes_by_url", "file:///some_doc", 3 ) ) self.assertEqual(len(lines), 1) self.assertEqual(lines[0].position, ((10, 20), (30, 40))) self.assertEqual(len(lines[0].word_boxes), 2) self.assertEqual(lines[0].word_boxes[0].position, ((1, 2), (3, 4))) self.assertEqual(lines[0].word_boxes[0].content, "ABC") self.assertEqual(lines[0].word_boxes[1].position, ((5, 6), (7, 8))) self.assertEqual(lines[0].word_boxes[1].content, "def") def test_get_text(self): self.fs.fs = { "some_doc": { "paper.4.words": TEST_XML, }, } lines = self.core.call_success( "page_get_text_by_url", "file:///some_doc", 1 ) self.assertIsNone(lines) txt = self.core.call_success( "page_get_text_by_url", "file:///some_doc", 3 ).replace("\n", " ") txt = re.sub(" +", " ", txt) txt = txt.strip() self.assertEqual(txt, "ABC def") def test_has_text(self): self.fs.fs = { "some_doc": { "paper.4.words": TEST_XML, }, } self.assertIsNone(self.core.call_success( "page_has_text_by_url", "file:///some_doc", 1 )) self.assertTrue(self.core.call_success( "page_get_text_by_url", "file:///some_doc", 3 )) self.core.call_all("page_set_boxes_by_url", "file:///some_doc", 3, []) self.assertFalse(self.core.call_success( "page_has_text_by_url", "file:///some_doc", 3 )) paperwork-2.2.2/paperwork-backend/tests/model/tests_img.py000066400000000000000000000047511456262201400237510ustar00rootroot00000000000000import unittest import openpaperwork_core class TestImg(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.img") self.core.init() self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_get_png_img_urls(self): self.fs.fs = { "some_doc": { "paper.1.png": "put_an_image_here", "paper.2.png": "put_an_image_here", }, } nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", "file:///non_existing" ) self.assertIsNone(nb_pages) nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", "file:///some_doc" ) self.assertEqual(nb_pages, 2) img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1 ) self.assertEqual(img_url, "file:///some_doc/paper.2.png") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 2 ) self.assertIsNone(img_url) img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 2, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.3.png") def test_get_jpg_img_urls(self): self.core.call_all("config_put", "model_img_format", "JPEG") self.fs.fs = { "some_doc": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, } nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", "file:///non_existing" ) self.assertIsNone(nb_pages) nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", "file:///some_doc" ) self.assertEqual(nb_pages, 2) img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1 ) self.assertEqual(img_url, "file:///some_doc/paper.2.jpg") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 2 ) self.assertIsNone(img_url) img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 2, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.3.jpg") paperwork-2.2.2/paperwork-backend/tests/model/tests_img_overlay.py000066400000000000000000000146731456262201400255160ustar00rootroot00000000000000import unittest import openpaperwork_core class TestImg(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.img") self.core.load("paperwork_backend.model.img_overlay") self.core.init() self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_get_png_img_urls(self): self.fs.fs = { "some_doc": { "paper.1.jpg": "put_an_image_here", "paper.2.png": "put_an_image_here", "paper.3.png": "put_an_image_here", }, } img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=False ) self.assertEqual(img_url, "file:///some_doc/paper.2.png") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.2.edited.png") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 3, write=False ) self.assertEqual(img_url, None) img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 3, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.4.png") def test_get_png_edited_img_urls(self): self.fs.fs = { "some_doc": { "paper.1.jpg": "put_an_image_here", "paper.2.png": "put_an_image_here", "paper.2.edited.png": "put_an_image_here", "paper.3.png": "put_an_image_here", }, } img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=False ) self.assertEqual(img_url, "file:///some_doc/paper.2.edited.png") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.2.edited.png") def test_png_reset_img(self): self.fs.fs = { "some_doc": { "paper.1.jpg": "put_an_image_here", "paper.2.png": "put_an_image_here", "paper.2.edited.png": "put_an_image_here", "paper.3.png": "put_an_image_here", "paper.3.edited.png": "put_an_image_here", }, } self.core.call_all( "page_reset_by_url", "file:///some_doc", 1 ) self.assertEqual(self.fs.fs, { "some_doc": { "paper.1.jpg": "put_an_image_here", "paper.2.png": "put_an_image_here", "paper.3.png": "put_an_image_here", "paper.3.edited.png": "put_an_image_here", }, }) self.core.call_all( "page_reset_by_url", "file:///some_doc", 1 ) self.assertEqual(self.fs.fs, { "some_doc": { "paper.1.jpg": "put_an_image_here", "paper.2.png": "put_an_image_here", "paper.3.png": "put_an_image_here", "paper.3.edited.png": "put_an_image_here", }, }) def test_get_jpg_img_urls(self): self.core.call_all("config_put", "model_img_overlay_format", "JPEG") self.fs.fs = { "some_doc": { "paper.1.png": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "paper.3.jpg": "put_an_image_here", }, } img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=False ) self.assertEqual(img_url, "file:///some_doc/paper.2.jpg") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.2.edited.jpg") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 3, write=False ) self.assertEqual(img_url, None) img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 3, write=True ) # paperwork_backend.model.img remains configured to use PNG self.assertEqual(img_url, "file:///some_doc/paper.4.png") def test_get_jpg_edited_img_urls(self): self.core.call_all("config_put", "model_img_overlay_format", "JPEG") self.fs.fs = { "some_doc": { "paper.1.png": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "paper.2.edited.jpg": "put_an_image_here", "paper.3.jpg": "put_an_image_here", }, } img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=False ) self.assertEqual(img_url, "file:///some_doc/paper.2.edited.jpg") img_url = self.core.call_success( "page_get_img_url", "file:///some_doc", 1, write=True ) self.assertEqual(img_url, "file:///some_doc/paper.2.edited.jpg") def test_jpg_reset_img(self): self.core.call_all("config_put", "model_img_overlay_format", "JPEG") self.fs.fs = { "some_doc": { "paper.1.png": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "paper.2.edited.jpg": "put_an_image_here", "paper.3.jpg": "put_an_image_here", "paper.3.edited.jpg": "put_an_image_here", }, } self.core.call_all( "page_reset_by_url", "file:///some_doc", 1 ) self.assertEqual(self.fs.fs, { "some_doc": { "paper.1.png": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "paper.3.jpg": "put_an_image_here", "paper.3.edited.jpg": "put_an_image_here", }, }) self.core.call_all( "page_reset_by_url", "file:///some_doc", 1 ) self.assertEqual(self.fs.fs, { "some_doc": { "paper.1.png": "put_an_image_here", "paper.2.jpg": "put_an_image_here", "paper.3.jpg": "put_an_image_here", "paper.3.edited.jpg": "put_an_image_here", }, }) paperwork-2.2.2/paperwork-backend/tests/model/tests_labels.py000066400000000000000000000126451456262201400244400ustar00rootroot00000000000000import unittest import openpaperwork_core class TestLabels(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.labels") self.core.init() self.config = self.core.get_by_name("openpaperwork_core.config.fake") self.config.settings = { "workdir": "file:///some_work_dir" } self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_label_color_from_rgb(self): self.assertEqual( self.core.call_success( "label_color_from_rgb", (0.9607843137254902, 0.4745098039215686, 0.0) ), "#f50079000000" ) def test_has_labels(self): self.fs.fs = { "some_work_dir": { "some_doc": { }, }, } self.assertTrue( self.core.call_success( "doc_has_labels_by_url", "file:///some_work_dir/some_doc" ) is None ) self.fs.fs = { "some_work_dir": { "some_doc": { "labels": ( "label A,#aaaabbbbcccc\n" "label B,#ccccbbbbaaaa\n" ) }, }, } self.assertTrue( self.core.call_success( "doc_has_labels_by_url", "file:///some_work_dir/some_doc" ) is not None ) def test_doc_get_labels(self): self.fs.fs = { "some_work_dir": { "some_doc": { "labels": ( "label A,#aaaabbbbcccc\n" "label B,#ccccbbbbaaaa\n" ) }, }, } labels = set() self.core.call_success( "doc_get_labels_by_url", labels, "file:///some_work_dir/some_doc" ) labels = list(labels) labels.sort() self.assertEqual( labels, [ ("label A", "#aaaabbbbcccc"), ("label B", "#ccccbbbbaaaa"), ] ) def test_load_all_labels(self): self.fs.fs = { "some_work_dir": { "some_doc": { "labels": ( "label A,#aaaabbbbcccc\n" "label B,#ccccbbbbaaaa\n" ) }, "some_other_doc": { "labels": ( "label B,#ccccbbbbaaaa\n" "label C,#000011112222\n" ) }, }, } core = self.core class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def is_doc(self, doc_url): return True def on_label_loading_end(self): core.call_all("mainloop_quit_graceful") self.core._load_module("mainloop_stopper", FakeModule()) self.core.init() promises = [] self.core.call_all('sync', promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) promise.schedule() self.core.call_one("mainloop") labels = set() self.core.call_all("labels_get_all", labels) labels = list(labels) labels.sort() self.assertEqual( labels, [ ("label A", "#aaaabbbbcccc"), ("label B", "#ccccbbbbaaaa"), ("label C", "#000011112222"), ] ) def test_doc_add_labels(self): self.fs.fs = { "some_work_dir": { "some_doc": { "labels": ( "label A,#aaaabbbbcccc\n" "label B,#ccccbbbbaaaa\n" ) }, }, } self.core.call_success( "doc_add_label_by_url", "file:///some_work_dir/some_doc", label="label C", color="#123412341234" ) labels = set() self.core.call_success( "doc_get_labels_by_url", labels, "file:///some_work_dir/some_doc" ) labels = list(labels) labels.sort() self.assertEqual( labels, [ ("label A", "#aaaabbbbcccc"), ("label B", "#ccccbbbbaaaa"), ("label C", "#123412341234"), ] ) def test_doc_remove_labels(self): self.fs.fs = { "some_work_dir": { "some_doc": { "labels": ( "label A,#aaaabbbbcccc\n" "label B,#ccccbbbbaaaa\n" ) }, }, } self.core.call_success( "doc_remove_label_by_url", "file:///some_work_dir/some_doc", label="label A" ) labels = set() self.core.call_success( "doc_get_labels_by_url", labels, "file:///some_work_dir/some_doc" ) labels = list(labels) labels.sort() self.assertEqual( labels, [ ("label B", "#ccccbbbbaaaa"), ] ) paperwork-2.2.2/paperwork-backend/tests/model/tests_pdf.py000066400000000000000000000167561456262201400237560ustar00rootroot00000000000000import os import shutil import tempfile import unittest import openpaperwork_core class TestHocr(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.model.pdf") self.core.init() self.simple_doc_url = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "simple_doc.pdf" ) ) self.full_doc_url = self.core.call_success( "fs_safe", os.path.dirname(os.path.abspath(__file__)) ) mapping = self.full_doc_url + "/page_map.csv" if self.core.call_success("fs_exists", mapping): self.core.call_success("fs_unlink", mapping, trash=False) def tearDown(self): mapping = self.full_doc_url + "/page_map.csv" if self.core.call_success("fs_exists", mapping): self.core.call_success("fs_unlink", mapping, trash=False) def test_is_doc(self): self.assertTrue(self.core.call_success("is_doc", self.simple_doc_url)) self.assertTrue(self.core.call_success("is_doc", self.full_doc_url)) def test_hash(self): h = self.core.call_success("doc_get_hash_by_url", self.simple_doc_url) expected = ( 0x7d2ffb0e8ddce8f7dfbb4a8dfc14d563b272bd47b1bafb9617fbfd228bf2eecd ) self.assertEqual(h, expected) def test_get_nb_pages(self): self.assertEqual( self.core.call_success( "doc_get_nb_pages_by_url", self.simple_doc_url ), 1 ) self.assertEqual( self.core.call_success( "doc_get_nb_pages_by_url", self.full_doc_url ), 4 ) self.core.call_all("page_delete_by_url", self.full_doc_url, 2) self.assertEqual( self.core.call_success( "doc_get_nb_pages_by_url", self.full_doc_url ), 3 ) def test_get_text(self): text = [] self.core.call_all("doc_get_text_by_url", text, self.simple_doc_url) self.assertEqual(text, [ 'This is a test PDF file.\n' 'Written by Jflesch.' ]) def test_get_boxes(self): lines = list(self.core.call_success( "page_get_boxes_by_url", self.simple_doc_url, 0 )) self.assertEqual(len(lines), 2) self.assertEqual(lines[0].position, ((227, 228), (656, 281))) self.assertEqual(len(lines[0].word_boxes), 6) self.assertEqual(lines[0].content, "This is a test PDF file.") self.assertEqual( lines[0].word_boxes[0].position, ((227, 228), (312, 281)) ) self.assertEqual(lines[0].word_boxes[0].content, "This") self.assertEqual( lines[0].word_boxes[1].position, ((324, 228), (356, 281)) ) self.assertEqual(lines[0].word_boxes[1].content, "is") self.assertEqual( lines[0].word_boxes[2].position, ((368, 228), (389, 281)) ) self.assertEqual(lines[0].word_boxes[2].content, "a") self.assertEqual( lines[0].word_boxes[3].position, ((401, 228), (468, 281)) ) self.assertEqual(lines[0].word_boxes[3].content, "test") self.assertEqual( lines[0].word_boxes[4].position, ((480, 228), (568, 281)) ) self.assertEqual(lines[0].word_boxes[4].content, "PDF") self.assertEqual( lines[0].word_boxes[5].position, ((580, 228), (656, 281)) ) self.assertEqual(lines[0].word_boxes[5].content, "file.") self.assertEqual(lines[1].position, ((227, 284), (588, 337))) self.assertEqual(lines[1].content, "Written by Jflesch.") self.assertEqual(len(lines[1].word_boxes), 3) self.assertEqual( lines[1].word_boxes[0].position, ((227, 284), (371, 337)) ) self.assertEqual(lines[1].word_boxes[0].content, "Written") self.assertEqual( lines[1].word_boxes[1].position, ((383, 284), (431, 337)) ) self.assertEqual(lines[1].word_boxes[1].content, "by") self.assertEqual( lines[1].word_boxes[2].position, ((443, 284), (588, 337)) ) self.assertEqual(lines[1].word_boxes[2].content, "Jflesch.") class TestMapping(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.model.pdf") self.core.init() self.pdf = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "doc.pdf" ) ) self.work_dir = tempfile.mkdtemp(prefix="paperwork_tests_all_") self.work_dir_url = self.core.call_success("fs_safe", self.work_dir) self.doc_url = self.core.call_success( "fs_join", self.work_dir_url, "20200525_1241_05" ) self.core.call_success("fs_mkdir_p", self.doc_url) self.core.call_success( "fs_copy", self.pdf, self.core.call_success("fs_join", self.doc_url, "doc.pdf") ) self.mapping = self.doc_url + "/page_map.csv" def tearDown(self): shutil.rmtree(self.work_dir) def test_crappy_mapping(self): with self.core.call_success("fs_open", self.mapping, "w") as fd: fd.write("original_page_index,target_page_index\n") fd.write("0,-1\n") fd.write("1,2\n") fd.write("2,-1\n") fd.write("3,-1\n") self.assertEqual( self.core.call_success( "doc_get_nb_pages_by_url", self.doc_url ), 3 ) self.assertIsNotNone( self.core.call_success("page_get_img_url", self.doc_url, 0) ) self.assertIsNotNone( self.core.call_success("page_get_img_url", self.doc_url, 1) ) self.assertIsNotNone( self.core.call_success("page_get_img_url", self.doc_url, 2) ) self.assertIsNone( self.core.call_success("page_get_img_url", self.doc_url, 3) ) class TestPassword(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.model.pdf") self.core.init() password_doc_url = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_password.pdf" ) ) self.tmp_doc_dir = tempfile.mkdtemp() self.tmp_doc_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_doc_dir ) doc_pdf = self.core.call_success( "fs_join", self.tmp_doc_url, "doc.pdf" ) passwd_txt = self.core.call_success( "fs_join", self.tmp_doc_url, "passwd.txt" ) self.core.call_all("fs_copy", password_doc_url, doc_pdf) with self.core.call_success("fs_open", passwd_txt, "w") as fd: fd.write("test1234") def tearDown(self): shutil.rmtree(self.tmp_doc_dir) def test_open_page(self): boxes = self.core.call_success( "page_get_boxes_by_url", self.tmp_doc_url, 0 ) self.assertNotEqual(len(boxes), 0) img_url = self.core.call_success( "page_get_img_url", self.tmp_doc_url, 0 ) self.assertIn("password=", img_url) paperwork-2.2.2/paperwork-backend/tests/model/tests_thumbnail.py000066400000000000000000000020031456262201400251440ustar00rootroot00000000000000import io import os import unittest import PIL.Image import openpaperwork_core class TestImg(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.thumbnail") self.core.init() with io.BytesIO() as fd: img = PIL.Image.open( os.path.dirname(os.path.abspath(__file__)) + "/test_img.png" ) img = img.convert("RGB") img.save(fd, format="JPEG") fd.seek(0) self.raw_img = fd.read() self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_get_img_urls(self): self.fs.fs = { "some_doc": { "paper.1.jpg": self.raw_img, }, } thumbnail = self.core.call_success( "thumbnail_get_doc", "file:///some_doc" ) self.assertEqual(thumbnail.size, (64, 32)) paperwork-2.2.2/paperwork-backend/tests/model/tests_util.py000066400000000000000000000067351456262201400241560ustar00rootroot00000000000000import unittest import openpaperwork_core import paperwork_backend.model.util class TestUtil(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.fake") self.core.init() class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def doc_get_nb_pages_by_url(s, doc_url): doc_url = doc_url[len("file:///"):] return len(self.fs.fs[doc_url]) self.core._load_module("fake_module", FakeModule()) self.core.init() self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_delete_page_file(self): self.fs.fs = { "some_doc": { "paper.1.words": "abcdef", "paper.2.words": "ghijkl", "paper.3.words": "mnopqr", "paper.4.words": "stuvwx", }, } r = paperwork_backend.model.util.delete_page_file( self.core, "paper.{}.words", "file:///some_doc", 1 ) self.assertTrue(r) self.assertEqual( self.fs.fs, { "some_doc": { "paper.1.words": "abcdef", "paper.2.words": "mnopqr", "paper.3.words": "stuvwx", }, } ) def test_move_page_file(self): self.fs.fs = { "source_doc": { "paper.1.words": "Aabcdef", "paper.2.words": "Aghijkl", "paper.3.words": "Amnopqr", "paper.4.words": "Astuvwx", }, "dest_doc": { "paper.1.words": "Babcdef", "paper.2.words": "Bghijkl", "paper.3.words": "Bmnopqr", "paper.4.words": "Bstuvwx", }, } r = paperwork_backend.model.util.move_page_file( self.core, "paper.{}.words", "file:///source_doc", 2, "file:///dest_doc", 1 ) self.assertTrue(r) self.assertEqual( self.fs.fs, { "source_doc": { "paper.1.words": "Aabcdef", "paper.2.words": "Aghijkl", "paper.3.words": "Astuvwx", }, "dest_doc": { "paper.1.words": "Babcdef", "paper.2.words": "Amnopqr", "paper.3.words": "Bghijkl", "paper.4.words": "Bmnopqr", "paper.5.words": "Bstuvwx", }, } ) def test_move_page_file_same_doc(self): self.fs.fs = { "source_doc": { "paper.1.words": "Aabcdef", "paper.2.words": "Aghijkl", "paper.3.words": "Amnopqr", "paper.4.words": "Astuvwx", }, } r = paperwork_backend.model.util.move_page_file( self.core, "paper.{}.words", "file:///source_doc", 2, "file:///source_doc", 1 ) self.assertTrue(r) self.assertEqual( self.fs.fs, { "source_doc": { "paper.1.words": "Aabcdef", "paper.2.words": "Amnopqr", "paper.3.words": "Aghijkl", "paper.4.words": "Astuvwx", }, } ) paperwork-2.2.2/paperwork-backend/tests/model/tests_workdir.py000066400000000000000000000124131456262201400246500ustar00rootroot00000000000000import datetime import unittest import openpaperwork_core class TestWorkdir(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.load("openpaperwork_core.fs.fake") self.core.load("paperwork_backend.model.img") self.core.load("paperwork_backend.model.workdir") self.core.init() self.config = self.core.get_by_name("openpaperwork_core.config.fake") self.config.settings = { "workdir": "file:///some_work_dir" } self.fs = self.core.get_by_name("openpaperwork_core.fs.fake") def test_storage_get_all_docs(self): self.fs.fs = { "some_work_dir": { "some_doc_a": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "some_doc_b": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, }, } all_docs = [] self.core.call_success("storage_get_all_docs", all_docs) all_docs.sort() self.assertEqual( all_docs, [ ("some_doc_a", "file:///some_work_dir/some_doc_a"), ("some_doc_b", "file:///some_work_dir/some_doc_b"), ] ) def test_storage_get_new_doc(self): def now(): return datetime.datetime( year=2019, month=9, day=4, hour=13, minute=27, second=10 ) self.fs.fs = { "some_work_dir": { "20191010_1327_10": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20191010_1327_10_1": { "doc.pdf": "put_a_pdf_here", }, }, } (doc_id, doc_url) = self.core.call_success( "storage_get_new_doc", now_func=now ) self.assertEqual(doc_id, "20190904_1327_10") self.assertEqual(doc_url, "file:///some_work_dir/20190904_1327_10") def test_storage_get_new_doc_2(self): def now(): return datetime.datetime( year=2019, month=9, day=4, hour=13, minute=27, second=10 ) self.fs.fs = { "some_work_dir": { "20190904_1327_10": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20190904_1327_10_1": { "doc.pdf": "put_a_pdf_here", }, }, } (doc_id, doc_url) = self.core.call_success( "storage_get_new_doc", now_func=now ) self.assertEqual(doc_id, "20190904_1327_10_2") self.assertEqual(doc_url, "file:///some_work_dir/20190904_1327_10_2") def test_rename(self): self.fs.fs = { "some_work_dir": { "20190904_1327_10": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20190910_1328_10_1": { "doc.pdf": "put_a_pdf_here", }, }, } self.core.call_all( "doc_rename_by_url", "file:///some_work_dir/20190910_1328_10_1", "file:///some_work_dir/20200508_2002_25" ) self.assertEqual( self.fs.fs, { "some_work_dir": { "20190904_1327_10": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20200508_2002_25": { "doc.pdf": "put_a_pdf_here", }, } } ) def test_rename2(self): self.fs.fs = { "some_work_dir": { "20190904_1327_10": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20190904_1327_10_1": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20190910_1328_10_1": { "doc.pdf": "put_a_pdf_here", }, }, } self.core.call_all( "doc_rename_by_url", "file:///some_work_dir/20190910_1328_10_1", "file:///some_work_dir/20190904_1327_10" ) self.assertEqual( self.fs.fs, { "some_work_dir": { "20190904_1327_10": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20190904_1327_10_1": { "paper.1.jpg": "put_an_image_here", "paper.2.jpg": "put_an_image_here", }, "20190904_1327_10_2": { "doc.pdf": "put_a_pdf_here", }, } } ) paperwork-2.2.2/paperwork-backend/tests/pageedit/000077500000000000000000000000001456262201400220545ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/pageedit/__init__.py000066400000000000000000000000001456262201400241530ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/pageedit/test_img.png000066400000000000000000000107061456262201400244010ustar00rootroot00000000000000‰PNG  IHDRÈdÆ bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEã Šv°­tEXtCommentCreated with GIMPW.IDATxÚí{LSgÇ¿U£»ˆó‚,ËØE§Î`Vo+ÃédØéTQ§Sücj†:¶™ÇܘºH¼y™™&ÌBp@ âP§"rS¬N[ÑV Š”~ïïÛ¾@O¡=¥Pô÷Išè9çyžßóœómŸ Ï÷HˆˆÀ0Œ ½¸ †Â0,†a0 „aX Ãað@†Â0 „aˆ^¯‡D"õÑét€°°0H$TWWÛÔ矉DFã´ŠwEÎ`åÊ•H$¨¨¨àXø„a\P ýúõY|êêêÌ×TUU ^ãææÆ­Êð/ˆ3‰ÁÓÓ³G—Áô|útE! …éééP©TÀ¼yóàëë ‰D"8>غu+Ôju«X¯×ãäÉ“ÈÈÈ@^^@&“aܸqðóóÃðáÃíƒ8»ŒG¡¨¨§OŸFqq1òòòðÊ+¯`Ú´ix÷ÝwñÆoØœWAAÆoþÿ‹/¾Øêü‰'0uêÔVÇŠ‹‹¡T*‘ÒÒRL˜0AAAÆóÏ?/8ö´¥îbbé±ÔÕÕ@UUUí^J(%%…<<<ÌéZ~8 ˜ö³Ï>#¤V«ÍÇôz=EDDæcúüûï¿6×¥+ÊøñÇÛÍë÷ß·9¯‹/¶›×‰'Ì× Úµk—Õk‡N………­ò·§îöÄÒÓqº@PLL ©ÕjÒëõT[[K …Â|®²²Ò¦‡7''‡ÐÂ… ©¬¬ŒêëëÉh4’V«¥’’Ú¾}»`^ö¤³Ë8x𠥤¤F£!NGƒ´Z-eee‘T*%tõêU»nØŠ+ݾ}Ûê5‡2×ãܹsT[[Kƒª««é?þ $•JI«Õ:Tw[bat ¨¨(jnn¶8M(''Ǧ‡7!!ÐÙ³g;¥â]QF{œ>}šÐž={:U Z­–<<<ÈÏϯ•„”œœìPÝŸ8}nZi‹L&3φÙÂ!C7oÞtZ¬]Q† ///0÷õ;‹ÂÂBTVVbÉ’%4hà5>>>€3gÎtKÝy«C‡<þÜsÏlÊÇÛÛR©¡¡¡X·n”J%nܸƒÁÐi±:£Œ’’ìÚµ }ôÆŽk^P8p àÒ¥KÚÞ7nÜ„‡‡[]Ì}ùå—[]ÛUí˃t.–µëòòò%$$ØÔý!"R«Õ´qãF‹çŽ;H£Ñ8ÜÅêì2~ýõ×v³¦Ogv±vìØaS™hÖ¬YÕ»X.†§§'¢¢¢ ÓéP\\ …B¹\Ž5kÖÀÇÇjµÚeÊ(//Gxx8<==‘••…ªª*èõz477ƒˆP__ï”6zæ™giii‚ ¹-?Gíòöå.VпxyyaöìÙˆ‹‹Cbb"4Å ïÎ2JJJ[·n…¿¿?ÜÝÝÑ·o_óxìþýû¢âϵĴVqîÜ9§×½£XX .Â믿îô¦½e˜úîO=õ”ày±b6ý)µ±›T*…››¾ùæ:µîÅÂéBâããqäÈ\¿~555hjjBCCT*vîÜ v­L;»ŒaÆ6n܈‚‚|hqÞÝÝ?ÿü3`Á‚ÈÈÈÀ½{÷ÐÔÔ½^êêjaïÞ½øû↑{G±ð ½ é[¶liwÀ¹hÑ"ª­­uhÞ™e Z»v­Õ¼Ž=*j^VVÖáêµÑh¤}ûöu8HÏËËs¨î¶ÄÒÓéÓS„¼jÕ*øûû#??EEEÈÏχ››¦L™‚iÓ¦Á××O?ý´Ë”ѧO|÷Ýw˜4i’’’——‡1cÆÀßßr¹Ü<Õ*¦»SPP€#GŽ ;;¹¹¹×ôîÝË–-ÃÔ©S‘“'OâÂ… 6l¼¼¼ •J!“ÉðÚk¯9Tw[bééHؼšaóA:ð@†Â0,†a0 „aX Ãa†Â0,†é:ôT[ÆqºÓ{W¡P@"‘ ##ƒA†»X ó8 „=l™'™÷ƒXó° ÃáÇQUUN‡ääddff¢®®Ó§OÇ‚ 0zôhÿõ¾JIIÁŸþ‰¢¢"aáÂ…xóÍ7-ÊsÄÏöáÇHKKCrr2 àíí ¹\Žàà`(•JÌ™3ééé˜1c†`z{½lm¡¤¤ÙÙÙæ<}||0qâDbĈ­öu·lÓ 55YYYÈËËCRRÞ~ûmQqÚÛ¦]á õõõ8~ü8’““qáÂx{{ã½÷ÞCpp°ë(D¬=ŽiÇ`RR’Õ]h¤R©H&“ ž?uêT§ùÙjµZš?¾`šùóçÓÞ½{ ¥§§ îþ³×ËÖ–…Õ¥­]N{mzêÔ)ÑqÚÛ¦Îö&"ª©©¡Å‹‹º_.e=Ú‘@P\\ݹs‡©ººšbcc Í;—‚ƒƒé믿¦›7o’^¯§ššÚ¿? É“'“^¯ï?[“•é’%KèÊ•+d0¨¡¡.\¸@þþþæX…\Œ—mG˜¬À¦‰ÈÈHܽ{W°»·oß>H[ÄúÙ¾ôÒKˆŽŽ†N§ÃºuëP^^£Ñ½^K—.áÓO?m·¯+ÆË¶£‰‹Ý»w>øàdee¡¦¦ÍÍÍÐét(//ÇîÝ»qçλ&CÄÄéˆG°³|€===±iÓ&ÀÚµkqåÊóý:þ<>ùä×y(]±æ½»iÓ&@eeeí.¤åæævŠŸ­V«5¯­@`eö§Ÿ~"¤T*-ÒŠñ²µe%=..NÔJºµ6§#mê,`"¢û÷ïÓÂ… ]~%Ý¥¼yñ³4h~ùå„„„ )) ………ÉdËå˜9s&’““@Ð[WŒ—­-u‰ˆˆ€ŸŸŸùo”T*&OžŒñãÇ# @p  =ÄÄéH›:ËØ4ƒµwï^Ì™3Çü·s2™ 3g΄\.‡R©t‰gò‰ñæýâ‹/‹òòrŒ1 Ãù×®]ÃÈ‘#!•JqæÌ«V†qéAº#ܽ{ñññP©TÐétæñéÓ§±téRó,‹ƒ±«Ûÿ¸T¤¹¹¹ÝÕâõë×ãý÷ßç;Î<™],"BII Nœ8ÂÂBäççÃÝÝï¼óàããÓ៽0Ì;Hg˜'z Â0,†a0 „aX óØ $,, ‰Äe6°ÄÄÄXÝÞiú,^¼¸Ušžè/ìjíÎaÆ‚»r–––æZ| ÿ‚0 ÿ‚´ƒJ¥‚B¡€R©Duu5ba©SWW‡‘#GbàÀ¸xñ¢ys[rssáëë‹mÛ¶µ»ëÏÙØë+«×ëqòäIddd˜ý¤d2Æ???ó^í¶ØãÓÛF…Bôôt¨T*`Þ¼yðõõípß8ã ¶ºý%&&ZÝ-vðàA‹tÛ·o·Ø1Ø–Õ«WÛí>¸eË@iii6§±¶+RŒ¯¬^¯§ˆˆˆvwϵuwtħ7%%…<<<Ó8p€˜n¶méûí·ßÒíÛ·Éh4R]]¥¦¦šÏµ}JKK ­^½Z0_“ýäܹs[ùÏv¥@ÄøÊæää˜Ó”••Q}}=FÒjµTRRBÛ·o§ÊÊÊNõ鉉!µZMz½žjkkI¡P˜Ïµ-‹é&Ì;×ÂhºåCÙêxSS“y¸F£±HwàÀ@ÇŽ³+`“@Úû´ÝÓ-$±¾²¦‡ýìÙ³]âÓEÍÍÍVͺsrrø)voÞˆˆôíÛ×âxPP€ÿú¬¶tÚëÕ«—yF۽̃ÁìúazçEW#ÖWvÈ!€›7oÚ\Ž#>½¦õ¶Èd2´9bºaËÚæþ`Ö¬Y,Ýð&Mš777ìÚµËìÏ—/_Fnn.6oÞlÕÔ–i^k.~¶ØVŠõ•õöö†T*Ehh(Ö­[¥R‰7n´ª_Kõé:t¨àq“ͪ5Ï*¦‹b²ÓÂ䟤×ë-nbtt4rssqùòeóñÔÔT€\.ï¶Š‹õ•vìaGîÑ£G#$$6lÀ½{÷ð×_–/_Þ­[`;Ó·ÿþðòòÂìÙ³‡ÄÄDh4šV‚r†O/ã‚i;Ž0azÑ{dd$ `Y@¯^æ—¡äææbÿþý€)S¦tkÅáÉkzßE˼3|zHbb"¶lÙ‚ŠŠ 455A§Óáøñã ³µŽ¦ÁúòåËqøða¬_¿^ô[c; ±¾²ñññ8rä®_¿Žšš455¡¡¡*• ;wî€Vou†O/Ó…tÆJúo¿ýÖá|ò?ü`¾ÞÖ5g/Šñ•íhfÑ¢ET[[ëtŸÞ¼¼<@ ¼Xá Þ¼¾¾¾(//GRR233qïÞ=!$$'Nì0ýŒ3°víZøøø@*•ºÄ—ƒ_ÙU«VÁßßùùù(**B~~>ÜÜÜ0eÊL›6 ¾¾¾þ¿Îðéeº†.³ýÉÌÌÄŒ3€?ü[žy¼Æ Ž`4Íýý©S§r«3=§Ï³644àØ±c8tè¾üòKóëÒæ‰îbUVVZÌT]»vÍ®wl0ÌcßÅ5j"##qùòeÿ ÿ Ãa†Â0,†a0 „aX ÃaÃôhþ›…ý dARIEND®B`‚paperwork-2.2.2/paperwork-backend/tests/pageedit/tests_pageeditor.py000066400000000000000000000144041456262201400257760ustar00rootroot00000000000000import os import unittest import PIL import PIL.Image import openpaperwork_core from paperwork_backend.pageedit import AbstractPageEditorUI class FakeUI(AbstractPageEditorUI): CAPABILITIES = AbstractPageEditorUI.CAPABILITY_SHOW_FRAME def __init__(self, tests): self.tests = tests def show_preview(self, img): self.tests.ui_calls.append(('show_preview', img)) def show_frame_selector(self): self.tests.ui_calls.append(('show_frame_selector',)) def hide_frame_selector(self): self.tests.ui_calls.append(('hide_frame_selector',)) class TestPageEdit(unittest.TestCase): def setUp(self): self.test_img = PIL.Image.open( os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_img.png" ) ) self.pillowed = [] self.ui_calls = [] self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.imgedit.color") self.core.load("paperwork_backend.imgedit.crop") self.core.load("paperwork_backend.imgedit.rotate") self.core.load("paperwork_backend.pageedit.pageeditor") class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999 def pillow_to_url(s, img, dst_uri): self.pillowed.append(dst_uri) return dst_uri self.core._load_module("fake_module", FakeModule()) self.core.init() self.model = self.core.get_by_name("paperwork_backend.model.fake") def test_all(self): self.model.docs = [ { "id": 'some_doc_with_text', "url": 'file:///some_work_dir/some_doc_id', "mtime": 12345, "labels": [], "page_imgs": [ ("file:///paper.0.jpeg", self.test_img), ("file:///paper.1.jpeg", self.test_img), ("file:///paper.2.jpeg", self.test_img), ], "page_boxes": [[], [], []], }, ] fake_ui = FakeUI(self) page_editor = self.core.call_success( "page_editor_get", "file:///some_work_dir/some_doc_id", 1, fake_ui ) self.assertEqual(self.pillowed, []) self.assertEqual(len(self.ui_calls), 2) self.assertEqual(self.ui_calls[0][0], 'show_preview') self.assertEqual(self.ui_calls[0][1].size, (200, 100)) self.assertEqual(self.ui_calls[1][0], 'hide_frame_selector') modifiers = page_editor.get_modifiers() modifiers = [e['id'] for e in modifiers] modifiers.sort() self.assertEqual(modifiers, [ "color_equalization", "crop", "rotate_clockwise", "rotate_counterclockwise", ]) # rotate 90° self.pillowed = [] self.ui_calls = [] page_editor.on_modifier_selected("rotate_clockwise").schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertEqual(len(self.ui_calls), 2) self.assertEqual(self.ui_calls[0][0], 'show_preview') self.assertEqual(self.ui_calls[0][1].size, (100, 200)) self.assertEqual(self.ui_calls[1][0], 'hide_frame_selector') # ACE bilinear = getattr(PIL.Image, 'Resampling', PIL.Image).BILINEAR avg_color = self.ui_calls[0][1].resize( (1, 1), resample=bilinear ).tobytes() self.pillowed = [] self.ui_calls = [] page_editor.on_modifier_selected("color_equalization").schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertEqual(self.pillowed, []) self.assertEqual(len(self.ui_calls), 2) self.assertEqual(self.ui_calls[0][0], 'show_preview') self.assertEqual(self.ui_calls[0][1].size, (100, 200)) avg_color2 = self.ui_calls[0][1].resize( (1, 1), resample=bilinear ).tobytes() self.assertNotEqual(avg_color, avg_color2) self.assertEqual(self.ui_calls[1][0], 'hide_frame_selector') # crop self.pillowed = [] self.ui_calls = [] page_editor.on_modifier_selected("crop").schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertEqual(self.pillowed, []) self.assertEqual(len(self.ui_calls), 2) self.assertEqual(self.ui_calls[0][0], 'show_preview') self.assertEqual(self.ui_calls[0][1].size, (100, 200)) self.assertEqual(self.ui_calls[1][0], 'show_frame_selector') page_editor.frame.set((0, 190, 10, 200)) self.assertEqual(page_editor.frame.get(), (0, 190, 10, 200)) # rotation again (180°) self.pillowed = [] self.ui_calls = [] page_editor.on_modifier_selected("rotate_clockwise").schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertEqual(len(self.ui_calls), 2) self.assertEqual(self.ui_calls[0][0], 'show_preview') self.assertEqual(self.ui_calls[0][1].size, (200, 100)) self.assertEqual(self.ui_calls[1][0], 'show_frame_selector') self.assertEqual(page_editor.frame.get(), (190, 90, 200, 100)) # .. and again (270°) self.pillowed = [] self.ui_calls = [] page_editor.on_modifier_selected("rotate_clockwise").schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertEqual(len(self.ui_calls), 2) self.assertEqual(self.ui_calls[0][0], 'show_preview') self.assertEqual(self.ui_calls[0][1].size, (100, 200)) self.assertEqual(self.ui_calls[1][0], 'show_frame_selector') self.assertEqual(page_editor.frame.get(), (90, 0, 100, 10)) # and save ! self.pillowed = [] self.ui_calls = [] page_editor.on_save().schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_all("mainloop") self.assertEqual(len(self.ui_calls), 0) self.assertEqual(self.pillowed, ["file:///paper.1.jpeg"]) paperwork-2.2.2/paperwork-backend/tests/pillow/000077500000000000000000000000001456262201400216005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/pillow/__init__.py000066400000000000000000000000001456262201400236770ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/pillow/test_doc.pdf000066400000000000000000000230121456262201400240750ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xœmŽË Â0E÷ùŠY 3Ió‚2`k»pW¸w>v‚ÝøûæbQ3“››¹%ÁK<%*&©œß’ô–`¹ŠãÕ‘Îr}ÆJÎi|€xíD@ âíÔ!±êP¡Î­å&U³¾X¦Ü\Ö|žëƒãÆd=°ípW¤ž›bê‚}q”/#ŸãAŒQÌÉ,Jú%›¸Õa]Vã>DhH‘Nµâ )nH&ê;z†7NÃD endstream endobj 3 0 obj 181 endobj 5 0 obj <> stream xœåzkxU–à=UzX–l=,•$+’JQœÄñCŽIœ—+~ȱ۴B,Ù’`[B’ÂcãéæÕiÒÀÐ<²Kš… Ý]Ê$ô„^¶cXèž^–f€–fHMÏ4_“!ͤóõ–÷Ô­’b›G;ßþÛ’«êÜóºçžsî½çJΤ¦âÄ@¦ K„¡‰h²oÛ¦ZBÈÿ",C2ü¶.Û„ÏÂüíprdâ‘¿Þw‰ÕB´gFÆ ?ÞòGˆa”ë­£ñhìYûB !ü¨cÃ("öei ñ­ÀöªÑ‰ÌMµ:±-`»<1ý]Ãßb¾‡°]=½)éSu2Øþló“щøÊ&M¶Gˆþ@2‘ÎÄȪBª"=™Š'w=2ø2¶§ a!ð#]5R›aUj¶@W¨7MfK‰ÕFþ?ºÔG‰t¨·#IÒç’‹=EœäaB>’ZWžÙ] Ÿþ¿´¢@~=DN’3ä(y‡\§‚$DÆÈb_/7+]!²—üÌ|…ÚSä,Òe¾¹WÉ—^!ò=ršü|I/!2AnA[ž%ïÀzò L•ù È_—Që'ˆ»úËT1Åø¦àð"ì»äQ湊‘òþa‰Ây‰‡ý¨9ƒã<šñÖ/(½‹Ü†Ï2J L/õ¶Ïÿ7Ñ-ü+Žê6rù&ÙAÆI<±…¿^òúôŠ äˆÚözæÇ 3?6¾KFðŽŽ9Êîø ý__l)‚r¶Œè¾ŒÊÔcöS¦vỊ’¾…‹9ÜB翲Ñì¤j@µB½MõÊ×õ¡ù®j¥ÉÂo³·dcêÝê“­§Ú¯ÝîïëíÙÓêÚ}õ®Î«vv´ÛZ[šwMÛ·mݲ¹qÓÆ ëkÕU•k׬.[å_éó:¬f“±¸H_¨+ÐjÔ*–RÉ‹iÙ2ÞŒúÛüÑŽªJ¾Í1ÚZUÙæFD>Ê‹øR­öwtP”?*ò^\¯è"tDsx§ s yN0ñ[ÉV© ?/¾ÚêçÏÂÞî~„¶úüxÂWSXµš6аáó¡µJ²–oƒFgÚ"h#Ìê [ü-ñªJ2[¨GP¸ÖŸœ…µÛÌڶͳ )(’ºÅ‘¶Ecb¨»¿­Õåó…«*wŠÅþVJ"-T¥¨iµT%?&™NŽð³•s3÷œ5‘ÁH…!æE÷õ‹legض™™»Ds…XîoËoþÀ#‹•þÖ6±BÒÚ¹'ßOç•.AT—™üüÌ Çᣥ˜¨‚Ñ”™þH$PdZDØÓï“.W}=3ôóÁ™ÈLôìÂô Ÿ7ùgf †™dº›„úQÅÙ…Ÿq‰Á{¢)2 ›ÃÊЃ{:Å’îkûE¦,ÈFƒM~ß&—Ïœç }™ [Ð9èaŸOrѳĆ8ÝÝ/·y2èz†аÈD$Ê\Žbë“(Ó9J^<âÇØvöôψª²1züHTœÄìº^ Œß$_vùü33ßS^­ÚãEõjtJ-À¼‘DfL´Q|Y~]pa«Í¾Ñj$=mþ¶ˆòw`Ô xttG…œ½ý¢ÐŠ€U"Ö6[@‰h6ÖJƒ)üIÑêoÎGW2«m¬§ŸŠ(b¢µE$‘!EJ ´ÑyÅ·ÍDZe$]þîþçHÝÂùÙzÞuºŽÔ“p«Ä̵`–­n›é ‹Þˆ+†ón˜ïwùD!Œûûãa)íÐCåç]49Â4Wzû;{üÝ{û7)†ÈIª¬m™¿KVƒ (”ðýŒ‹ #£ |óV|ŠÚ²¼MèpŠ•·y+ß.’ãF3Är¾-ÞªðIí%JÕR:µtä´i¤&êiépùÂ>ùªªdÌ+£DäÔŽ —)$`~¶tP”äK‡”ô|¿?îûGyQõKc“ÜC½¬8ƒú\‰Uï’Ö"g¡›ˆɹ†äL1XáZì\±¶óÍŽeä92?Sàï왑”û…-ß))……Mf] ¤ íǵ—7ᔦzfV¤É<ºYRâß›ñ÷ôo¥Ü¸žÜæºYêËB:¡³·¹ª—¶æY?ÜÝ=+ÀÝ={ûŸ3a]xwoÿ3 0-‘æðì*¤õ?Çã¦A±Œ„•Rƒ—’¦=Ø( ü®çB¦)UE´=tÅäp@†Î22Î$w´šv$)*™"ä¸Uˆ+qÓG¯Y"¹L(T ‚N00EŒk$Ô3ˆù Ö±: § P®Y”ÚCÑgazV'¸dŽiäd ïî»ÒußÞþÓÜ]ô‰5K¦‹cƒÛJ“åÖðèL$,M6ÂahðDðoÇ0ù·£!ƒXè7‹z³„o’ðM2^#ᵘ¢ÀŠOcìC"Hpm¿§$_ú ׌é‚©0.*3¦ßV¡ÇÊðÜðÖ VØ*¼gaôLkã ¤tlAÎÌêØHXÇZ „‰¥‰#ç98ÇÁ½æ`€DòÃE^ãà¥%9èâÀK 2^äà1JJP1ƒÊ@8xŸR§)¾†b¶,Ð~d±{)¡‹Ò.R¼˜ëCà©ÌEªhŽv3M©hZ ×ÇuùëÆÜ•R®ýËð_ H4ÒTa&uú4×9û¯«3[ÀÞh®[_ãkØhö¯4‚ßì3û×TC˜í6ØòVÝüu®ÕñV—çÞ´þ­—ê{Ö7`Köå7´úÏnp5H+Vn¿Å3›üD8D¬VgQq±Î©óxÝ¥¡°›X±aw†Â»­„aÔjóž°Út ç½0瓈±qÌ I/D¼ò‚à…/ð^ðR2’¦sT$½N%E/œX„_ìœTj‰”±ã¨›ê$ ŽºÁ8vù³¾¬ÚíPWËÙpà’7êý+µ ¸¦ÁAmÇ_7Ý|k*{Ãm'÷ëp6vð¨e/V—oýÎ]ó:«ªœÌþSîù R3Ž*œ8XŸZÔ»ˆOKÿQ&ƒÆl¶s¬®'LX0±¬M°YBa›Ñ`6šCa£Íj•/Ùᘘ¤"vÙA°ÃœD;œ MÞ&;;\¤d]̹4G$ P/äÃOJ¦_bð©ÌuÊà5þ•«ê7 Ø+ƒ¾E¨ª„Ê*¡ðûYç‰; Bõ¾Ü>Û,“åÒì]øˆù;öe²–„…zŸÖZZ„)Q¾®ÈÇÚížPØe7±úPXËrÓë ¹"ë ´øuðô:X]ë g/Áð# ÁØÈBó®i¨³suµ õ¨f¨¹v›ÍjÿJÍÊÙ=,ów³ÿ%øƒšªõ7½øp8¾¯öÇF ¬kHu÷]½ûþ½M~(¸ç˜ÛòÏßj=ys½Û×:¼õ^ï«PkãîÒÚê–k¤céXøˆ½‘}¸pu™šÌee*Þ`pªX,ûW®ì;lfó Œ˜Ùkf ¬ÙL 9­ Çh#¶P˜˜¦×ÀÀÖ×aÐùÄAï:Kc@v>i¤9)Ï@³2J%ÿÖà`ÍõÛ¡ êWÓyÙ°´Å`³ÖÕnØo<òÝ©l¶$5û‡':Ú~U¬gå¦Ç|ëÎ{[‡jÙþÃ7çïpVíOcÿ-;XÕýÑ}©WýYJ½Rô:èœÅ˜U©þ‚p¤]XSX\¬-aY»CeÐBaVoÄ9mîî1ˆhr@À!…)•K£º:ÅúFKcm­”CjL ³¿¡ êlu6¿ÙŠqÚh+ظå¶xÓßÿý–šÍ=þÛ­©æþª5o½Õ;xG³i‡ÃK}BŸ1‡ld9*ìuK lF›Ûã$èh§×‰Žv:   [LuwØÀÍy@ôÀ óÀ´’ˆx äâíøòãÁÑ|?»û­ùW;ŸÂGÿö!+>ùù;¹”mv5ànòŸJ²S¿|[òÉÂçê)ô‰ŽØÉ.! ¶’"k‘Ãi· „íªHØÎš¬a“66Yˆš'ðN8ï„NH:邦£¥4”W,DûLÄç7c2Z€'fl”ù©‘ª'²odÿùÌMO^þpþO†áì_e]yêÔ)æ)pÂÊÏn)€•ìËÙg³g²bö¤J¶–îwRüÊÑV;¹$œä,«@£±êY§ÃL"ásÂÌT™ÅîÌŒNm6kt:FV;€¥hTš°ÊrÆ O8á'L;!ㄘTN¸è„œð&Å#2â„^'´:áu'¼ä„¼Èí9¤¢'j¨3¬TCã%ªBæÃöœÑ 7,Ïú%ƒ²Y.4N†ëè|°/Þ)¯k)ú¾uÁSïÏ¿ðØ)ö_šùä›ïÂï¶m^fïüå|¤Ï½S<ÿƉlìqôaN„ª'.Ø üƒ…ãX—Ë^R¨r¯à\NW(ì´k‰5fKŒÚâPX¯—Tn¸ä†ÿæ†ÛÝqCÌ nÃnxÓ /¹áŒ Hî\$ó#Š¿–ÊX)þ•uõº¡5‡ßü{ªè 7[ÔU½VQâæ¢λáu7œpô’nÜÀ»Áä‘6M”oIQ6ZV•|I–l¹Ý0_¶É Q(Á4^²ºAZvih~ýøãOþåÕÍë«VÖ4Õúé+YÕ¶ýšæ×Ï—¼z‹-ùÈñÞÏ/ûªª|‡rŒƒ k7y\Hªõ…: ®ÿ„¨Y5:ßö¦^ÒÃ=<¡‡ôp»2zˆéa•¬zPé1Ý(Ç1=–+zˆè!¤Aszõp‚6Mz z¸H›È·˜m‰”ReIŠ^©YqB¯¯)»Rš$¤Šäƒùz È] ¿Cä-¬·‚žh4†"V÷èµl iRjÔ°¨ÐCmõõmÁººà¾õëë‚AÔÁ,üZûmzžèx£µPmUs6¦ °¨ƒ1ŠŠ¬ÆBµV=6kÙb½þ쟄—¤g¨Jb\Ãdžƒ9x—ƒŸqp’ƒ9¦¤ 8XMÆ.sðO¼ÍÁs|“©ÚGpð&?âàQŽp ²—6ê9XÅ•2¼ÄÁž ò˜®Üñ⋵3Fa`ùqƒ¾°Ž(•[TÔå l<`Ôê/Äj¿ü€±³iuP§“!õþ†ìÙG²­S yë±*Ø5oÀóS^öøç1uQiCCéç]ìãŸïgg%XÉÙ‡°V°’n¡Ê¬Õ‚Á`ã4fºÜ«Í,c5™ŠBa“Qk(Är¦Ð6@‰^ºqÑ'M­º:\â̹2FÞíýkVjUþv<0Ul®ýví÷³Í‚E·õÕ­¸1Lº¸ùæ\ ð,ôk´mîì·‘’‡Þ`Ð:´nÏ <­0–`ƒs MœÍ‚œ¬iO˜5=á<ð’°ÐPy x ã˜z=Ðêz¬ò€‹’±âa×;Xå¼î|)”Ç/ŽÞÀ¿ëD´ô<´zé¨õêÿºY>u÷íÅÑõ7Þ6RÙ˜?õ÷ (ç!zN`¤_Øgp­ÑãIqZè¶hµnbwÛ=ÞR](\Êip'µ²Ýa«ÉˆQ3î¤Ãá1zL<Ÿ;õɧAù(8—ƒyïâå–3Wv+ýBÝâ—•Á)ÍV­´(جŒtÎ`²ÓwnÉ”öNÍÜ:äÛÐÄš{õ×o]óÚn¸xöŒÍ0o7ýƒªÚQ•7ÛýáGóÙ[í¥ñwfƒìŸØSdüFX0J‡ÇÉX HeÑ»%fC1ŽÍVl$Úî0KV`‡=p †ÔŸÐ4xÓ?óÀ=ðmšrAÛìZš˜!Œ^öÀÛxÑÏx³ç>ÜN¹‡iÂ)÷JXhÂ\òÀ?Q~̰38™ãOy`Ð{r ¶Ú\Ž?oÇ™¥ú—ñËÖlºL¹óÖ<Ó.|c±=«¨=Rm޵øyš´²Aä´ÇèXeí—(#§u>Ý»<`ôä+Vi…Z²8-Þb¿Xì,e^ú5ÁWG¤©6¿Ó“¨ô­É•5­d¥r"ÝåÍ%¿ ˜ùùî]Ÿwc}ÿÎÙG"pæìåûaÿ`ö»;"™lÐòJľõÀClç‡k>ÁÜoÛç×>yì*y©ÀóÙ'Ò>DDá&«A£ál…–HØXì-f ÙââÂ5Ψ0ÃÊßcå¿«Z ÀÓ¹ïªç–ø÷!”sëÇt£HЯ™äMãàé×Rô+§¼›–}Å´¤\¬ËŸšpÅ™E=`¶JÇ%É=Òé©9ŨÚóW#Ó]Íž’àº{TÿBWöïüÅ”çÒ{éOåqïÆ5b7®Ÿ‰[Íj=§æìŽc(l(0qVÖŠ³†#Ø.8 Æ¼L¸è€×pÂÓ@üÓp,µ=oéâ © äÍ´„’êX„陕ݽþÔÞìÆß¹ëÄÆŠžLöÒþÑ}ã«Ê῟÷f?=ÈŽ¾ù¬Ðÿ À5íÀÊÌÆ­d¼òïÑÓúú/¯üÚ˜ b5ñ8ÉÿXMÇH´¾lùÆbÌ’‹Ó4â ã7¤LEˆ•i$¬›ô2Òï£GI¶­ø©Òd‹úçd‹ôf~Hš_ŽÍDù¡DòPjld4ï*çkkÖ×ðí‰ÄÈxœoI¤’‰T43–˜¬.lYÎVËïAÑL%¿sr¨zר`\æå{⩱á=ñ‘©ñhjGz(>‹§ø*~9Çòö5ñTZjÔV×ÔT7\¡.gKóQ>“ŠÆâÑÔ |bx©!|*>2–ÎÄSˆ›äûª{ªùP4ŸÌðÑÉß›ìŠSäP<•‰"s"3Ц^?•KÇÆ†¤ÞÒÕù,rGO&~ Î_ÍdâéÄds4}¡e½c“‰t%ptlh”?Mó±xzld‰ƒ‡ø¥2- Y‘æ3£ÑŒ4è‰x&56?„1›H¢Ô éàXf;žˆ§ùÝñƒüžÄDtò‡Õ²)è›at*?6‘L%P«ÒC©x|;‹Æ¢ƒcãcÔ6ME‡Ðcè¶±¡4õ:‚OF'«Ú¦R‰d-ýFû®+Œh ìÍtbüö,qOÆã1©G4û@|…°ãñDâi<ÉËŒV-²|81™AÑÅpàè­ÄÐÔ„'ts&g\t(•@Zr<šA-éêÑL&¹98xð`uT ÍF¦5¾Ž–9”Œ+ñHIZ&Æwaø'¥ÐMÑøJƒèÙ¹‹ïJ¢‚h¯0Tò¹Ô\_½^éÝ8–̤«ÓcãÕ‰ÔH +¸‹´’12‚wï›IœÄwÛQ„†H‚$É!’¢\£ˆåÉZÄ–ã»–Ôõxó¤¹HGyž´ œB)é¥zd’T“BJùzmµíQ¬è Ò•íDù!Ô° 呺X/Oz(f ×YIr„L¡QÄì i”Š#OŒrð¤ ï?§ãÏѯ¡P:O©E»jðSM¾TöÏiC]<õu†R$['¨ý7 .r_çùâ4~i¤Äi+FµJºû£‡r…¨¤ä‹ ím’rõ~I]Øã0ÊÑXæ8‡¨n)'dÍ „G¯^OQ bT.7¶4öüÅ|yvôPëÐ>¯¦x©¦´fl§•qÉ>ë¥V$+ùâ Z"õ;Já(õgŒJKY6©HbÞñ_Û¯ÈF•¸LÒ>(VJ2•Š¿‡é3MûÄ>xjŸå¥}óÔOQêu9ÒHÍPÞ!Äãç2Ï&Ð+r_ƒÊL:Hçå¨2â ª—ÇJ&Ž)+4n“¾•4ÆW¼"çͰ’©<•M"œ £Èù±ŠÆFIœZ*AQ:÷Qbœö-Û6J³#JcWb¡#Èù+¦ŒT²:I1U¤æ…4ããŠO¿+Å®/Õ({pqnJ1§ö¦éž¤ÖÆòc”½-q+=É#§+Ò ùø Ó|“=£Úª¾ÂçÃÔ7¥×µ(†9ârn%PvŠÆCžOr6g¾à¹(õoB‘KÒu)£Ø2AçÇ(ÍÀ$ÙŒµe­“>Õ4Ïš!eÎT+6þÝr’]IêÁÅó#•·emÜ¥ÌþÉü¬›Z4s‘èÁ5h]/’JþÏñË4H³fùª¹û[¿lr6Ža;CíIS_VÓ1Œ ½ {ØEëhz-øÐ¦/¹fu¡ƒ'£0BJˆ"d7 >ØA¶€oiÍønÁ¶ô®†mdù¶!~;¶·"~ .ž^|6áÝ…÷½x«ð–9j#€ï€Ò®Âv%J¼†O ·„mB¬ô¾ ÛønWÞAÄ·á»MiïÄ6¾I´ÒôyTÂi8?¯Í?‡?ƒÐg0ýɱO˜?\,÷>}ñÜE¦ëãŸþ˜­ùŒC¹`ºº¹¼pâ‚¦ÐøÈïÁü›ó›¼ïo{¯ï·ýª¼‡#{¯æ½Ð{Óï‰ï©ß¶ïW,ç5Íñs5sɹé¹×çÎÏ]œ+˜þ鱟2ÿýù€×ø¼÷yÆ{ºëôáÓlä)0>å}Š =y”9vŒÇ½ÇÇÙG®ö>Üîñ~ïÁ5Þó^|9»0wúÁ"sðyè‚]dúp÷ivÁûô\Ã2âÓ‹wï.¼xß‹7ž{Ý‹wv ›Ø¿ý}®û*î»å¾#÷©“wNßyìNvúŽcw0O8w€I‡Ê½‰É ïdû:¯³Îѧ­cû4Ø ö.ì,[Œ Þdºvowo{¹·¤ÎÒ§Æ«ÑÈzÙ&¶‹M°÷²çXmÁžÇÛ÷ùÐÅ#„t† ±ËÛèbÏ.œâ>ÔvUòªé«ØÁroGû&¯±ÝÛh­ýýöÛ5íðþŸž ²B°<‚_pE‡««³õ™ÁØgª3ö1€®#}ã‚‘1Œ‡¬‘4fš5œ…c³½=gµ {:łе"Ü-–õHO¡{¯¨¹[$}{¯íŸøNøŽ£GI³»S¬íé#îp§C@€iLîYŽ4‡ÓéL½ ¢á)|’Š© DîOËX’§“Š4¤qJS!¨ä6à³B¢!B’”ÞŸ&ÒC"VÈB’tZQG…åûÿ¶g– endstream endobj 6 0 obj 7404 endobj 7 0 obj <> endobj 8 0 obj <> stream xœ]’Mnƒ0…÷œÂËt DBH)I$ýQiö"c²àöõÌÐVêëûÍøé™°¬Î•éçðÕª†Yt½Ñ¦ñîˆn½ d,t¯æµ¢U Bß[/Ó Ceº1σðÍŸM³[Äæ¤Ç‚ðÅip½¹‰ÍGYûº¾[û˜YDAQ ŸóÔØçf€º¶•öÇý¼l}ËŸà}± bª%[Q£†É6 \cnäQTˆüz-0úßY¼¶´úlœ—J/¢}RxމÓòŽùˆœg;ä=q!§¬‘ÈkhÎ÷÷ÈGžOúqBšGæ¹d=ñ™¹D¾ð]ä+ÏÉ<ˈÙŠ¹ú§}öŸ¡Éþ“2ûOwΚÆ„ïø¿Pwç|ôôØ”9¦Ýøýìh±‹¾oˆ’œ; endstream endobj 9 0 obj <> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer /CreationDate(D:20190902205629+02'00')>> endobj xref 0 14 0000000000 65535 f 0000008715 00000 n 0000000019 00000 n 0000000271 00000 n 0000008884 00000 n 0000000291 00000 n 0000007780 00000 n 0000007801 00000 n 0000007996 00000 n 0000008384 00000 n 0000008628 00000 n 0000008660 00000 n 0000008983 00000 n 0000009080 00000 n trailer < ] /DocChecksum /72B44A81E5EEF3D98178B73CE31BA672 >> startxref 9255 %%EOF paperwork-2.2.2/paperwork-backend/tests/pillow/test_doc.png000066400000000000000000001263371456262201400241260ustar00rootroot00000000000000‰PNG  IHDR L $¶È¬¦IDATxœìÝg˜U塸í5•™‘^DT"R”¢R4ö^4ŠL +*1ösŒQcþ»49Ñ(VD;⨈H3€à(‚ "½Ã~?ì÷¬kŸa¦Á̃÷ýÁk•g¯õì2øáw­µÒ‰D„#½º'”Èù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"&³º'ÕiöìÙóæÍ+¶±Y³f:t¨ŽéUoñâÅ/½ôÒ„ –.]š““Ó¬Y³îÝ»_~ùåeymQQQ~~þ¶Û÷Ýwß¶mÛVõLÊ!-‘HT÷ Ú<üð÷ÞzëºuëR7öíÛ÷¹çž«®)UhàÀ7ß|óúõëS7ÖªUkãÆeyù† :è o¿ý¶¨¨(u{ÿþýÿñTåDÊÉ•|„aõêÕ/¼ðBÕ³k×®×^{í5×\3wîÜaÆÝ|óÍUrØ+VÜu×]³gÏîÑ£Çå—_ž––V%‡ nT‰üüü¯¾úªô1YYYuêÔ©[·îþûïߦM›ôôíÞ‡¹,GKJKKËÎÎÎÍÍmÔ¨Ñ^{íÕºuëÜÜܪöÕªU뢋.ªÌî½÷Þäßõµ×^Û¿ÿ7¾øâ‹÷Þ{o±a¥ü½äææÎ™3góæÍ³gÏ:tèwÜQ™ùT!‘0,]ºôÊ+¯¬ÚcþùÏîÚµkZZZË–-»wï^%ÇL$§Ÿ~ú„ ¢(9räš5kn¼ñÆ*9rXs ªŒ5êïÿ{±ËÈJ‘——÷óŸÿ¼_¿~çwÞ{ìQÉ£ÅÒÓÓ[µjuôÑGŸ~úé={öÌÉÉ©Úi—¨^½z•‰|Ó§OÿãÿEÑQGõÐC%7rÈ!Ï?ÿü²eËâaeù{ÉÎÎnß¾}×®]+<€*çv„aöìÙmÚ´‰¢(##£yóæ{î¹gÆ sssóòò222222ÒÓÓ?øàƒ9sæ$Ççææžy晉DbË–-EEE6lX·nÝÚµkW¬X±téÒäúþüç?ß~ûíÉñ|ðÁñÇŸ\®Ìí:ç̙ӺuëxµsçΟ}öYEßtÕ„9P…’—‘}õÕW<ðÀ¸qã’333O=õÔ(жlÙ²zõê%K–Ì›7/õßó}öÙçïÿû9çœS®£Åc–/_¾|ùò%K–lذ¡ØêÕ«wå•WÞxã5ªð´c‰D¢¨¨¨¨¨hÓ¦M7n\µjÕòåËüñÇD"Q¯^½•+W–ùs*®W¯^¯¿þzE÷ßÿ 7Üo¿ùæ›y䑸veÿ{yýõ×{õê•\v»N Ú¹’ddd¬^½://¯Ä½ýúõ‹#_Æ ‡ ²½ãœsÎ9#FŒØ3lذaffæ–-[’«{î¹çÎ8KÍŸU(yYûöíßy縖í±ÇÉ‚[µjÕk¯½öÀLŸ>=Š¢ï¾û®wïÞ>øàu×]W£%þç?ÿ7nÜ /¼0yòäøD÷ÜsÏO<1pàÀ>}úTrÚ%zçwN;í´+ŲeËÞ~ûíärÛ¶mSw]yå• 4ˆWý½Ú ÚgŸ}¶WøÊ%õªՠAƒ¿ýíoɇ¢5iÒäî»ïÞI'ªás`׫W¯Þ\0iÒ¤~ýúů¿þú·Þz«ÂÇÌÊÊêÞ½ûu×]7iÒ¤üüü£Ž:*ÞµlÙ²óÏ?ÿOúS¥&½p@%ŸŸ¿½n×¢E‹?üáñª¿ P"!ÙÿýkÔqJtýõ×õÕWï¼óάY³:wî¼óNTÃç°kÜ}÷ÝiiiüquO¤d»~zÙÙÙO>ùdj$»þúë+ùl¼¤ãŽ;îƒ>øãÿ˜––o¼ë®»î¹çžÊ¼˜ýöÛ¯V­Z•9´iÓâåÜÜÜÒÿtþ^€Ý‰ÈGHZ´hQ£Ž³=­[·>å”Sêׯ¿SÏRóç°³mذáᇮîYlWuM/;;ûw¿û]¼úå—_N˜0¡JŽœ‘‘ñ׿þõñÇOÝxë­·Ž;¶JŽKOOoÕªUeŽðí·ßÆË™™;¾1õOáïØÍˆ|„!---##£eË–Ur´–-[fdd$oÐG¸žx≥K—V÷,¶«§wâ‰'¦®¾óÎ;Uxðþýû_uÕUñjQQÑoûÛ­[·Vá)¢Jß±sõêÕU5€šiÇ×7@MЪU«ø [•wà–r´Ô»RcÞÿýÕ=‹íªÞéxàéééqx›;wnÕÿÁ1bÄâÅ‹“«Ó§Oíµ×Î>ûì*<ÅSO=µ~ýú ¿¼2¯‚ÈÅ¥ÞÜoëÖ­“'O?~üÂ… ‰DË–-{ôèQâÝ>‰Ä¶O>KOO/åzÁD"1qâÄO?ýô»ï¾[¿~}nnn“&M~ö³ŸpÀíÚµÛáƒÄjæŠùñÇgΜ¹xñâ+V¬X±"==½aÆ:tèÚµkvvveŽüÜsÏÍŸ??¹\TT”Zm322¶Wj Ç7eÊ”¥K—nÚ´©Q£FmÚ´9þøã›6mZúéÊûAUlzU%--­^½z+V¬H®þðÃU{üZµjÝxã7ÜpC¼åþçª6òÕ¯_¿Â7ÏL$›7oŽW‹}þÑÿþWà良*ü{Ø!‘ŠËËË‹¢hÒ¤IO=õÔK/½´|ùòÔ½×]wÝßþö·b%àùçŸÿõ¯]ìP}ûö}î¹çJ<˨Q£n¼ñÆY³f•¸7##ã•W^9묳Ê5óš0‡ØUW]5bĈ%K–”¸·qãÆ7ÜpÃM7Ý”‘‘Q®Ã~ÿý÷¯¼òʈ#>øàƒxãqÇ—:fôèÑ'tR±nذáÁ¼ï¾ûV­ZUlWZZÚ¹çž{÷Ýwoï9peÿ *<½*—šµ²²²ªüøýû÷¿å–[â––ŸŸ¿víÚÚµkWù‰Êî›o¾9räG}4vìØeË–ÅÛ:è b# 333Ëû÷R.•ù½”…ÈÅ-X°à„NÈÏÏ/qoQQÑý÷ߟý׿þ5uûyçwàN:uôèÑ/¿ür駸ï¾û~ÿûßGQ”žžþË_þòè£Þ{ï½W¯^=}úô!C†ÌŸ?¿¨¨hÆ åyM˜Cì³Ï>K¾<ðÌ3Ï<äCêׯ¿dÉ’ÿûßãÇ_¶lÙ-·Ü2sæÌgŸ}¶\‡}ì±ÇxàbsssS›k굘IK–,9õÔS§OŸEQNNÎ\pì±ÇæääL:õñÇ_¶lÙË/¿ÈرcK¹aÆvíÚ%G6jÔhÚ´i©{çÏŸ¿Ï>û$÷6mÚtÙ²e©{+üA•}ze׿ÿø˜õêÕ+eäÔ©SSÿ¿÷Þ{+s´íùïÿþïÔ³<øàƒ•œöôéÓ÷ØcaÆU`2Åœxâ‰ñI J¼Ã¿—¤Q£FÅÃú÷�a•ù½”]•=yv§Ÿ~ú°aÃn»í¶Þ½{sÌ1:t8òÈ#¯ºêªÏ?ÿ<¾"ª°°ðÕW_­Øñï¿ÿþD"EQÏž={ôèQloNNÎÕW_]‰é× 9äææ^tÑEÅ6fff&/ŒKzá…*¢ÒÝvÛmÉåýë_‡rHêÞæÍ›Ç—}ÿý÷wÞygêÞšðeUÀû￟ºzꩧ´mÛ6uuÞ¼y•<àgŸ}¶nݺÂÂÂJ§zUæ÷Pv"”UÆ ¯»îºxuÚ´i;Nü´¶Î;—8 W¯^-[¶ÌÎήØñkÎŽ;î¸ÜÜÜm·wëÖ-^®ðÇXF«V­8p`r¹}ûögŸ}ö¶cz÷î?Lî™gžÙ¸qc¼«&|YåUXX8hРxµk×®Å:SUiÔ¨Qêê÷ß_Éþç?ÿ©äª]%oeç™|P|p¼üã?Và[·n_¸téÒÇdeeÍ™3§¯Qs1bDNNN‰»RãЊ+*s–2dHüÀ¼³Î:«Ä1™™™‡~ø{ï½EÑÊ•+'Ož|ÔQGE5ã˪€k®¹&žRZZÚ½÷Þ»“NÔ°aÃÔÕ²<Á±¨¨hòäÉÛÛûÉ'ŸTÁ´ªUe~oåâJ>(‡½öÚ+^Þ´iSŽžž¾Ç{$—‡ºdÉ’ª™YÍ›C³fÍ4hP⮌ŒŒx¹¨¨hgœ=–zãÊN:moXË–-ãå)S¦$j—U._|ñE¯^½üñx˽÷Þ{üñÇï¤Óeee¥®&^Xºµk×vÛ¾I“&í¤©î2•ù½”‹+ù`W;äCÆEÑòåË=öØçŸ¾k×®?Á9ìŸ}öY¼¼ÿþûooXÓ¦MãåÅ‹ÇË5öƒÚ¼ysò¶[·n]½zõÂ… 'L˜0uêÔxÀ{ìñÀôïßçÍaÍš5©«Ûkº©ÒÒÒöÜsÏííýñÇ·lÙR3«>•ü½”È»Ú%—\’ìFQÍš5«[·n'žxâe—]Ö«W¯¼¼¼ŸÎvD"ñÍ7ßÄ«ñƒÐ¶•úìÀ•+WÆË5öƒÚ°aÃÕW_]â®úõëÿú׿¾þúë[´h±SçPÈW·nÝR.ˆìÕ«×믿^3«&•ÿ½”È»ÚÅ_üꫯ¦ÆŒ1cÆŒ3¦víÚ½{÷¾ä’KŽ>úèÝcëׯÏÏÏŸ2eÊܹsøá‡5kÖlܸqÓ¦M»Ói¬Y³fëÖ­ñj×®]·wKÉÂÂÂxyãÆñrMø²J”™™yÆg$—322êÔ©S¯^½–-[vëÖ­K—.Û{bÕ*öXÊÔG-VL§N‚Ž|•ÿ½”È»ZZZÚðáï»îºüã©O¤[»víàÁƒܽ{÷AƒíÔÛBîì9¬_¿þŽ;îxì±ÇÖ®]›Ü’žžÞ¸qã:uêäääĺÛÙŠ]j–““³½è’ZÅêÔ©/ׄ/«D{ì±Ç«¯¾º‹OZÌÌ™3SW>øàJ°”‡Ø¡ò¿7€²ù dee 8ðšk®4hЋ/¾¸téÒÔ½'N<òÈ#‡zÖYg…8‡µk×wÜqS¦L‰¢(==½ÿþ^xaçγ³³ã1Û‹U+3óÿü7cÆŒfÍš•÷ 5á˪™¦OŸ/§¥¥yä‘•<`÷îÝÏ8ãŒ}öÙ§’Ç©.Uò{(£ôêžütµiÓæá‡^´hј1c P·nÝx×æÍ›ûõë·páÂçpçw& _E=öØc=vØa‡¥¾]¦Ø5R•¹MhMø²j”-[¶Lž<9^m×®]åo×Ù¼yó×_½ºî€ZyUø{Ø!‘ªYFFÆ 'œ0pàÀ ÜtÓMñöµk×>òÈ#ÁÍ¡°°ð©§žJ.ï³Ï>—]vYUN´œòòò²²²âÕåË—Wò€5á˪!Þ~ûíÔgòõéÓ§'SCTùï  "ÔuëÖ½÷Þ{ï¹çžxË{ï½Ü¾þúëeË–%—?üðôôjþGæÀŒ—çÍ›WU‡­ _Võzæ™gâå¼¼¼TãdjŽô{ؖȻںuëJÙ{à 7ìµ×^ÉåÅ‹7‡ï¾û.^nܸqæVµ:vì/Oœ8±¼/¯ _V 4nܸaÆū—]vYåïÕ¹{¨äï  ìD>ØÕêÕ«WÊU_™™™q'ÈÉÉ nEEEñòæÍ›+6½*t 'ÄË/¿üraaa¹^^¾¬šfÍš5ýû÷O$ÉÕöíÛßu×]Õ;¥š£’¿7€²ù <ýôÓ¥ìÝ´iSraÿý÷nMš4‰—gΜYþy•UFFF¼¼bÅŠí ;÷Üssss“Ëß|óÍ£>ZÞUìƒ*ãô‚³bÅŠ“O>9þfëÔ©3|øðÚµkWï¬jŽÊÿÞŠŠŠn»í¶æÍ›7oÞüÎ;ïܺukUÏØMˆ|P †¾zõêw­\¹rÒ¤IÉå=z7‡:dee%—'Mš4yòämÇL:µ\Ç,QÆ ãåO>ùd{ÃêÖ­{õÕWÇ«·ÜrË /¼P®Uìƒ*ãô’H$^|ñÅ.]ºL˜0!¹¥yóæcÆŒI} •ÿ½=øàƒùË_.\¸páÂ?ÿùÏÈ„ÀO„ÈÕ`Æ guÖܹs·Ý~饗&Ÿ׬Y³+®¸"¸9äääôìÙ3¹œH$zöìùÔSO}ýõ׳gÏ7nÜÃ?Ü­[·.]ºdggWrþÝ»w—ÿþ÷¿¿ôÒK7nܲeË¢E‹òóó·lÙï½ãŽ;:tè\Þ¼ys¿~ýzõê5räÈùóç'‡­_¿þ›o¾ÉÏÏÿç?ÿùÈ#;QÅ>¨²O¯&(**š9sæüùó—-[¶fÍšM›6þðÃo¾ùæõ×_ß®]»_ýêWóæÍK¾äÔSOýì³ÏºuëV­¯‰*ù{1bDêê+¯¼²k¦ '-~®gæÌ™“&Mšû¿¦M›¶f͚䮌ŒŒÎ;ïÿ¿Ú¶m{ÜqÇ•x‚‚‚‰'¾þúëÆ Kniݺõ¥—^z衇víÚµ~ýúQmݺuæÌ™S¦L=zt|]Î~ûí7`À€Ÿÿüçݺu«U«Ö¼yó¾üòË‚‚‚>úèÕW_MŽiÕªUß¾}Ûµk×¶mÛ¶mÛ&Û–™™™|p]FFÆ)§œrÄG4mÚ´°°ð«¯¾zå•W¾ûî»(Š7nüî»ïvîܹ\HM˜CE_~ù塇º~ýú÷æåå <øÉ'Ÿ|ûí·“«7Þxãa‡vøá‡§^ý¶Ck×®mӦ͒%Kâ-éééñ½ ׬Y“zÉeË–yæ™ãÇ/v´´´ôôôÔçöéÓgÈ!ñj…?¨rM¯Ë–-{ã7f̘1cÆŒO?ýtåÊ•ñÑ:uêÿÂÛ´isòÉ'ïðhŸþùÇ\PPðå—_Nš4)>ZÙ¥¥¥õêÕ릛n:ꨣ*6íŽ;¶hÑb¿ýöKþ÷ÔSOïoYyÉÿرcGŽÿkеk×N:µoß¾}ûö:tØwß}“ÛËø÷2wîÜä'6f̘7ß|39¬mÛ¶çŸ~<¬X´®ðï-Š¢ÓN;íwÞ‰W{öì9jÔ¨Ê2Àn(ÁºðÂ Ëø;ßo¿ýJÀîÄ•|P=6nÜXPP0wîÜï¿ÿ~ݺuÙÙÙ 4hß¾ýÁ\ù[YÖ„9}úé§3fÌX·n]£FößÿŸÿüçñãúªÊúõëß{ï½9sædffî³Ï>:ujÙ²eé/ùá‡&Nœ¸téÒ+VÔªU«aÃ†É ¼¶Wò¢J|P˜Þ®TTT´õÿJÝEQ:uªð2»Ÿ¦ üÞ&L˜ðÌ3Ϥ¥¥]xá…nˆ lÈI¯î å#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>LfuOø‰zï½÷¶ÝxÌ1ÇdggïúÉT£Å‹¿ôÒK&LXºtiNNN³fͺwï~É%—äçço;xß}÷mÛ¶í®ŸdÕš={ö¼yóŠmlÖ¬Y‡ªc:AJK$Õ=২eË–óæÍ+öOÐâÅ‹÷Úk¯êšÒ®7pàÀ›o¾yýúõ©kÕªµbÅŠƒ:èÛo¿-**JÝÕ¿ÿüã»vŽUïᇾõÖ[×­[—º±oß¾Ï=÷\uM 8®ä# O>ùdaaaéc.»ì²ŒŒŒÊœeéҥÇ/eÀyçרQ£òvÅŠwÝu×ìÙ³{ôèqùå—§¥¥UbŽ»o¾ùfíÚµ3fÌèׯߜ9sª{:1sæÌ±cÇ–>¦uëÖ'tR‰»î½÷Þ›o¾9Š¢k¯½¶ÿþ7n|ñÅï½÷Þ(ŠrssçÌ™³yóæÙ³g:ôŽ;î¨òÉW£k¯½öšk®™;wî°aÃ’Ÿå%ò†?ýéO‹/.e@“&M.¾øâJF¾E‹ÝrË-+W®,qo­ZµŽ=öØòF¾D"qúé§O˜0!Š¢‘#G®Y³æÆo¬Ì$w'µk×>üðÃëׯ_Ý© )S¦\{íµ›6mÚÞ€´´´þýû—ù¦OŸþÇ?þ1Š¢£Ž:ꡇJn<äCžþùeË–%W³³³Û·oßµk×0÷j–––Ö²eËîÝ»W÷DB•^Ý€2ùî»ïf̘qß}÷¥n<ýôÓGŒ1mÚ´5kÖ,]ºt‡Ïr›3gÎ÷ß_Ê€N:­X±bÕªUS§N}õÕWÏ?ÿüäöK/½tüøñ«W¯n×®]ygþÍ7ß$ _Ò /¼PÞ#Pc]pÁëÖ­›={ö›o¾Ù¯_¿Ô]?üð§Ÿ~ºzõêǼÄ×þ÷ÿwòVœ¿øÅ/âééé}ûöÝ™S`7áJ>––Ö¡C‡:üóŸÿœ={vrãÊ•+SIéŠŠŠŽ>úè#<òå—_.}dݺu;vìØ±cÇçŸ>Š¢ôôô»îº«iÓ¦›yÆ 333·lÙ’\ÝsÏ=+vj¦ŒŒŒV­ZµjÕê»ï¾K}¤\Ÿ>}Jy¸à²eËÞ~ûíärÛ¶mSw]yå• 4ØI³`·áJ>Ó§OŸxùÓO?]°`A_øÆo,^¼xÔ¨QË—//Ëø7¾õÖ[Q{ì±.|Q5hÐàoû[zzzEMš4¹ûî»+|(vùùùÛë¾-Z´øÃþP“ $"‰o¡EQ"‘:th_øä“OFQ´iÓ¦_|±,ãßyçµk×Fÿ7+VÌõ×_ÿÕW_½óÎ;³fÍêܹs)#ï¾ûî´´´?þx‡Ç,ûHj iÓ¦Å˹¹¹Õ8%ò˜ƒ:¨C‡ñj#ß’%KÞ|óÍäòàÁƒËò’áÇGQ”™™Ù»wïòO³¸Ö­[ŸrÊ)õë×/ĕ ~øá²­ì#ƒ“––VÝSؾýöÛx93Óm“(7‘ð¤^Ì7qâÄyóæíð%O?ýt|wÄI“&}ñť߲e˨Q£¢(:þøã7n\ñ¹–ÇO<±téÒªœŸHñZ½zuuO€°‰|„'5òEe»˜ïßÿþwêêÓO?]úø÷ßÅŠQUÜ«³Œ ï¿ÿþª¢ìììêžÂ®°~ýúêžB󹈠ªü$.ša7ÓºuëC=tÊ”)ÉÕ¡C‡þþ÷¿/eü‡~øõ×_§nyî¹çî¾ûŒí½$y¯Î¬¬¬³Ï>;Þ_ ËÈÈH-›6mzï½÷>ýôÓÎ;ŸsÎ9‰D¢¨¨¨ØKÒÓÓÓÓKˆëÏ=÷Üüùó“ËEEE©ç*v–²ŒŽ7nÊ”)K—.Ý´iS£FÚ´isüñÇ7mÚtÛÁEEE‰Db{osëÖ­S¦L7nÜ‚ 222Ú´isÆgì½÷ÞÛ§b’¨[²dÉØ±c¿øâ‹+Vdgg7iÒ¤cÇŽÇsLNNζ/)ñsŽ¥¥¥¥~ÑÛ\lØN•H$6oÞ¯û£J_ÎX®¯»ØÄ&Nœøé§Ÿ~÷ÝwëׯÏÍÍmÒ¤ÉÏ~ö³8 ]»veyvàúõë?úè£/¾øbÙ²ekÖ¬Ùc=êÖ­[¿~ý-ZpÀûï¿)rê»ÞºuëäɓǿpáÂD"ѲeË=z´hѢ̟ÀO@tß}÷¥þŒgÏž]Êà~ýúmûËã7¶7¾¨¨h¯½öŠ¢¨GñÆ5kÖl{Aƒ%÷.^¼øúë¯oРArû 7ÜH$ž}öÙm_Ò·oßÔs-Y²dРA'tR)]gôèÑå™jýúõwÝuW½zõ¶œ––vÞyçmûÑm›‚~øáD"1mÚ´ßýîwÛÞ¼´V­Zÿïÿý¿~e¥8ôÐC“‡ÊÊÊš5kÖ9çœSb ÊÍͽá†~üñÇb/ôÑG·÷DQt衇¦~üñÇË2¬þõ¯¥pñâÅÅÌ™3硇:ûì³wxØÂÂÂÔ&ï›Ô¿ÿRæP¯;6räÈ8`{SÊÈÈxõÕWK9uAAAŸ>}J¿3;;;???õUùùùñÞ«®º*‘HLœ8ñÊ+¯lذᶸñÆ“€D"áJ>‚Ô§OŸßÿþ÷‰ÿ½àlèС·ÜrK‰#W®\ùÊ+¯DQtúé§3&¾‚êé§ŸîÑ£G‰/7nÜ’%K¢(ú¯ÿú¯xcíÚµ¿øâ‹I“&½ñÆñ B—-[¶~ýú;î¸ãÑGݰaC±ãœwÞyxàÔ©SGýòË/—x®Ç{ì(¶1777õj¿dÕ+ûÈØ’%KN=õÔéÓ§GQ”““sÁ{ì±999S§N}üñÇ—-[öòË/3fÔ¨QGqDüªñãÇòÉ'£Fz饗’[Þÿýüüü×^{­Ä·°iÓ¦?þñµk×¾úê«KPvEEE‡rÈÆ£(J^À·qãÆåË—'¿è 6<ðÀÆ {ûí·Û¶m¿êâ‹/nÕªÕ[o½•ZûŽ>úèž={rÈ!:uJ=Åo~ó›nݺ͜9óóÏ?OÞõ´W¯^^xáá‡^ÉÉïÐàÁƒão0###¾ 0//¯Øõ—»qežî¤ûî»/y9lzzú/ùË£>zï½÷^½zõôéÓ‡ 2þü¢¢¢m᱇z覛nJ¾£½öÚë—¿üe§N6l¸zõêY³f½ÿþûüq"‘ؼysòË-Ñ‚ N8á„Ôì—ª¨¨èþûïÏÎÎþë_ÿZ`7T½*ìÈ#ŒÆ;vÜÞ°Aƒ%ÇäççŸsÎ9ñKjÕª•¬GÛºöÚk£(ÊÎÎ^¹rå¶{S#ĉ'žØ¦M›är£F:è :uêDÿ{%_‰/)v%_,õácÇŽ-å—qä† ÚµkÏmÚ´i©{çÏŸ¿Ï>û$÷6mÚtÙ²e¥¼Í† öîÝûÎ;ï|å•W>ú裙3gNž<ù¡‡jÒ¤I<¦~ýúëÖ­+eÚ¥ˆ¯ä‹¢èæ›o;vlêåz?üðÃc=–zõ[Ó¦M—.]ºíq9äx̯~õ«ÒOúÖ[oEQ”––6wîÜŠM»˜^É—êÄOŒG”~ä²\ÉW™¯{üøñɬ˜––¶í®6l8î¸ã¢(zñÅK<õ­·ÞOï¿þë¿V­Zµí˜‚‚‚¼¼¼(ŠÞzë­ÔíÛþÌî¸ãŽaÆ}øá‡3fÌøøã ”z3ج¬¬%K–”þqüD”ðl0ÂùçŸ/O›6mÖ¬Y%{â‰'¢(jݺõ±Ç{ÑEÅÛ7mÚ4dÈ_2bĈ(ŠN;í´o{˜jâĉÇsÌðáÿÿþûeË–}þùçùË_ÊûFv’Ûn»­   ¹ü¯ý+5€EQÔ¼yóøª²ï¿ÿþÎ;ï,åP§Ÿ~ú°aÃþô§?sÎ9G}tûöí=ôÐk¯½öÃ?ÌÊÊJŽY¹råèÑ£+?ík¯½ö¨£ŽJ½[cãÆ¯¼òÊÏ>ûìg?ûY<álûÚ+®¸"^>|øŠ+J9ÑÓO?EÑÉ'Ÿ¼{<é­2_÷ý÷ߟH$¢(êٳ綗·æää”ræ»ï¾_ZwÌ1Ç<ÿüóuëÖÝvXÛ¶mS«|‰’?³Ûn»­wïÞÇsL‡Ž<òÈ«®ºêóÏ?sraa᫯¾Zúq~"D>BuÞyç¥>¹-¾…fª©S§þç?ÿ‰¢èâ‹/NKK;í´Ó’ÛKJfžb¦L™òí·ßFÿ÷^Ûsæ™g>ñÄgŸ}öž{î™ÜrÅWÄ-ª­ZµjàÀÉåöíÛŸ}öÙÛŽéÝ»wíÚµ“ËÏ<óL)÷QÜžvíÚýú׿ŽW§M›V¡É–IóæÍ“½6iذaß|óM±1ýúõ‹ßÑÆ_xá…ímÕªUÉ»^vÙe;a²»Z%¿î>ø ¹Ð¹sçß«W¯–-[nû¼½D"qõÕW'aZZÚ#û,^Þÿý·7¬iÓ¦ñòâÅ‹+p¢´´´ ¼ªÂRï'™úc:u:ì°ÃâÕ/æ›5kÖøñã£(ºôÒKw«A%¿îø~Ë—/?öØcË~Mç'Ÿ|/wìØ±ôÁ'tR£FÊxpJ'ò° œrÊ)ñj±Çò%OÓ¦M{ö왺ý7¿ùM¼¼hÑ¢wß}7^>|xEyyyÅ^–D"‘ú¼ºøIlÛÊÍÍ—“A´†kݺu¼¼råÊuëÖm;æŠ+®ˆ—ŸþùmŸ5˜¼|ó˜cŽ9ðÀwÊ,w­ÊÝ©|Ö¬Yݺu;餓^zé¥õë×—rÞ¯¾ú*^MýjØD>–zÇ΂‚‚3f$—çÌ™óá‡FQtÁdff¦¾äW¿úU­ZµâÕÔ;v&o?سgÏø†!Z³fÍÖ­[ãÕ®]»ÖÞŽÛo¿=¶m «ŠÝCuÕªUÛŽéÓ§Oƒ ’Ë+W®L†ÛØÖ­[Ÿ{î¹h7ºŒ¯ò_÷Å_\¬j3æüóÏoÚ´éo~ó›±cÇ–xÞ+V$‰xµ~ýúUô†(‘°uÖY©×'Åwì|òÉ'“"õ*¥¤ œyæ™ñêk¯½–¼ªiîܹS§N¿Wçš5kRWs¶¯N:þW…ŸA¸+åä䤮nذaÛ1¹¹¹^xa¼ZìŽcÆŒY°`AýúõÏ=÷Ü4É]¬ò_wZZÚðáà ‘‘‘z¨µk×<ø˜cŽ9ì°Ã¶½‡g±K?ƒîâ!ù[:uzôè¯&ïØYTT4xðà(ŠŽ:ê¨oÉxÑEÅË›6m2dHô¿÷ê¬]»vêCTìÊÅ3f,+ƒG}´º&\vŪÞöÂdê;óóóSïf™üaôë×/µ ï »ìi…Uòugee 8°  àšk®ÙsÏ=‹bâĉGyäk¯½VÊy «ôm°"ÁK½cç¬Y³¦Núæ›o.Z´(*é2¾¤SN9eï½÷ŽW“wìLF¾3ς׳gÏÔÎ1tèÐ'žx"Š¢:uêœwÞy%¾$##£_¿~ñê„ òóóÇEQŸ>}vò|wº¼¼¼¬¬¬xuùòåÕ8™ª•™7nœúlÅbR/æ{úé§“O­:tèúõë»uëÖ±cÇ:ϼ¼¼¼¼¼zŠÔsUíב‘q ' 8pÁ‚7ÝtS¼}íÚµ<òH¼Z¯^½Ô‹ù’Y€]Fä#x999©ÏØù$^>üðÃK™••uñÅÇ«O>ùäœ9s>þøãÚµk§þZv’ÔŸÖ.Pɯ{ݺu¥ì½á†öÚk¯äòâÅ‹Sw¥¾ÍÔþÀ. ò±;8õÔS4hºå ƒÚahùÍo~SlËnp¯Î¤N8!^~ùå— «q2U¥¨¨èÝwßM.§¥¥¥ÞpµD—_~yzúÿÿOÜÈ‘#ï»ï¾(ŠúôéSɧåÕ®];5ÆR†wúé§WæåUɯ»^½z¥$ºÌÌÌ8"æää¤î:÷Üsãå×_}éÒ¥å:/•!ò±;ÈÊÊ:çœsR·”~_Òù矟-4hpòÉ'WýäÊ&###^^±bE%Gž{î¹¹¹¹Éåo¾ùæÑG­Š9V³#F|÷ÝwÉå“O>¹uëÖ¥oÑ¢E|óÕÂÂÂþóŸQUÜ«sݺucÇŽÝv{üPºÚµkŸqÆ•øà¾ûîûãÿX¥ïûÿ7bĈÔÕW^yegœ FIK$Õ=¨¿ýío EÑÛo¿ß§±t[·nÝo¿ý.\ظqãÅ‹gff–2¸  `âĉ¯¿þú°aÃ’[ZµjÕ·oßvíÚµmÛ¶mÛ¶ÅžX6oÞ¼/¿ü²  à£>zõÕWKÉÚµkÛ´i³dÉ’øåéééqFZ³fMíÚµË;rÙ²egžyæøñ㋽‘´´´ôôô¢¢¢xKŸ>}† ’\ž;wî¸qãFŽùòË/'·´nÝúÒK/=ôÐC»víZ¿~ý(жlÙòùçŸOžï¼óÊ~ð¿üå/·Ýv[E999‹-*öìÆ ˆ/\Ûÿý=öغuëN›6íÃ?Œ¢¨{÷îo¿ýv)§HþÆŽ;räÈ5kÖ$7víÚµS§NíÛ·oß¾}‡öÝwßäö¹sç|ùå—cÆŒyóÍ7“Û¶m{þùçÇ¿Ÿìììøàûº£(ÊÌÌLîÍÈÈ8å”SŽ8∦M›~õÕW¯¼òJò©7~÷Ýw;wî\âûúÇ?þqíµ×n{ _zzz"‘Hý¿Ìi§öÖ[oE%ý5mû3ÛºuëÌ™3§L™2zôèøÚÄýöÛoÀ€?ÿùÏ»uëV«V­ø°ï¼óN|–ž={Æ?K€ÝVvÉ'¥5oÞ¼¨¨¨ì¯ºå–[¢(ºüòËK'™íyüñÇ‹½d‡}Å^2~üøfÍšÓªU«{î¹§Ø;*ûÈ-[¶ <¸cÇŽqšJ•——wî¹çŽ92õ%ñ‘Ûºä’KR?êí=ztÙ?ÿD"±yóæ7Þx㪫®êرczzÉ—7iÒdÀ€K–,)ב‰Ä¢E‹’í¶oß¾å}m‰öÜsÏm§W§N›o¾yíÚµ¥¿6õyŠ%jÚ´iräoQ=ûì³ÅŽ_¯;‘HÜzë­]ºtÙ^á®_¿þ€–.]Zú[[¸páï~÷»½öګădffžtÒIO=õÔ–-[vøîâŸÙ×_]Æ·ÿÞ{ïÅŸmFFÆ|°£¯ x®äc÷‘H$úôésâ‰'öï߿쯚={öoûÛÛo¿ýðÃßys+£õë׿÷Þ{sæÌÉÌÌÜgŸ}:uêÔ²eËJŽLúá‡&Nœ¸téÒ+VÔªU«aÆÉëÆJ¿xq×[¿~ýìÙ³çÌ™óÃ?¬]»6;;»I“&­[·îÒ¥K‰áj‡‰Ä¾ûî»hÑ¢>øàØc­ü ·nÝZPPPPP°dÉ’ 6äääpÀG}t^^^å^U*ðuoܸ±  `îܹßÿýºuë²³³4hо}ûƒ>8õzÁJ~8?þøãªU«òòò4hpÀ´oß>77·*ÞÙvM˜0á™gžIKK»ð »uë¶SÏPˆ|Àî,??ÿ„N8à€¾úê«êž T™’{øŸÿùŸ(ŠÊuq'Ô|®äv[‹/nÑ¢EVVÖ‚ 4hPÝÓ€*ãJ>`·uÿý÷oÞ¼ù¢‹.RøØÍˆ|@ðºwïþÑGÛ8uêÔAƒÕªUëæ›o®–YÀÎ#òÁûâ‹/ž}öÙÔ- ,8ï¼ó6mÚtýõ×ï»ï¾Õ51ØI<“^íÚµ³²²ž~úé#Ž8bãÆo½õÖí·ß¾xñâÃ;ìÃ?¬U«VuOª˜È¯víÚëÖ­+¶±}ûö£GÞ{ォeJ°S¹]'¼¬¬¬ÔÕœœœË/¿|üøñ »+WòÁÛ¼yóW_}µhÑ¢µk×6mÚ´C‡ 4¨îIÀN$ò@`Ü®#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘#ò@`D>ŒÈù 0"Fä€Àˆ|‘€ÿ=; ôÿu;½!3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$@ìÙ € ÿ¯Ûè `FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒäjÏHýÝŽ@oÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€É3’f$ÌH>˜‘|0#ù`FòÀŒä€™Ñi³ßÔà÷IEND®B`‚paperwork-2.2.2/paperwork-backend/tests/pillow/tests_pdf.py000066400000000000000000000015741456262201400241540ustar00rootroot00000000000000import os import unittest import PIL.Image import openpaperwork_core import openpaperwork_core.fs class TestPillowPdf(unittest.TestCase): def setUp(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("paperwork_backend.pillow.pdf") self.core.init() self.pdf_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_doc.pdf" ) ) + "#page=1" self.img_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_doc.png" ) def test_pdf_url_to_pillow(self): pdf_as_img = self.core.call_success("url_to_pillow", self.pdf_url) ref_img = PIL.Image.open(self.img_path) self.assertEqual(ref_img.size, pdf_as_img.size) paperwork-2.2.2/paperwork-backend/tests/poppler/000077500000000000000000000000001456262201400217535ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/poppler/__init__.py000066400000000000000000000000001456262201400240520ustar00rootroot00000000000000paperwork-2.2.2/paperwork-backend/tests/poppler/test_doc.pdf000066400000000000000000000230121456262201400242500ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xœmŽË Â0E÷ùŠY 3Ió‚2`k»pW¸w>v‚ÝøûæbQ3“››¹%ÁK<%*&©œß’ô–`¹ŠãÕ‘Îr}ÆJÎi|€xíD@ âíÔ!±êP¡Î­å&U³¾X¦Ü\Ö|žëƒãÆd=°ípW¤ž›bê‚}q”/#ŸãAŒQÌÉ,Jú%›¸Õa]Vã>DhH‘Nµâ )nH&ê;z†7NÃD endstream endobj 3 0 obj 181 endobj 5 0 obj <> stream xœåzkxU–à=UzX–l=,•$+’JQœÄñCŽIœ—+~ȱ۴B,Ù’`[B’ÂcãéæÕiÒÀÐ<²Kš… Ý]Ê$ô„^¶cXèž^–f€–fHMÏ4_“!ͤóõ–÷Ô­’b›G;ßþÛ’«êÜóºçžsî½çJΤ¦âÄ@¦ K„¡‰h²oÛ¦ZBÈÿ",C2ü¶.Û„ÏÂüíprdâ‘¿Þw‰ÕB´gFÆ ?ÞòGˆa”ë­£ñhìYûB !ü¨cÃ("öei ñ­ÀöªÑ‰ÌMµ:±-`»<1ý]Ãßb¾‡°]=½)éSu2Øþló“щøÊ&M¶Gˆþ@2‘ÎÄȪBª"=™Š'w=2ø2¶§ a!ð#]5R›aUj¶@W¨7MfK‰ÕFþ?ºÔG‰t¨·#IÒç’‹=EœäaB>’ZWžÙ] Ÿþ¿´¢@~=DN’3ä(y‡\§‚$DÆÈb_/7+]!²—üÌ|…ÚSä,Òe¾¹WÉ—^!ò=ršü|I/!2AnA[ž%ïÀzò L•ù È_—Që'ˆ»úËT1Åø¦àð"ì»äQ湊‘òþa‰Ây‰‡ý¨9ƒã<šñÖ/(½‹Ü†Ï2J L/õ¶Ïÿ7Ñ-ü+Žê6rù&ÙAÆI<±…¿^òúôŠ äˆÚözæÇ 3?6¾KFðŽŽ9Êîø ý__l)‚r¶Œè¾ŒÊÔcöS¦vỊ’¾…‹9ÜB翲Ñì¤j@µB½MõÊ×õ¡ù®j¥ÉÂo³·dcêÝê“­§Ú¯ÝîïëíÙÓêÚ}õ®Î«vv´ÛZ[šwMÛ·mݲ¹qÓÆ ëkÕU•k׬.[å_éó:¬f“±¸H_¨+ÐjÔ*–RÉ‹iÙ2ÞŒúÛüÑŽªJ¾Í1ÚZUÙæFD>Ê‹øR­öwtP”?*ò^\¯è"tDsx§ s yN0ñ[ÉV© ?/¾ÚêçÏÂÞî~„¶úüxÂWSXµš6аáó¡µJ²–oƒFgÚ"h#Ìê [ü-ñªJ2[¨GP¸ÖŸœ…µÛÌڶͳ )(’ºÅ‘¶Ecb¨»¿­Õåó…«*wŠÅþVJ"-T¥¨iµT%?&™NŽð³•s3÷œ5‘ÁH…!æE÷õ‹legض™™»Ds…XîoËoþÀ#‹•þÖ6±BÒÚ¹'ßOç•.AT—™üüÌ Çᣥ˜¨‚Ñ”™þH$PdZDØÓï“.W}=3ôóÁ™ÈLôìÂô Ÿ7ùgf †™dº›„úQÅÙ…Ÿq‰Á{¢)2 ›ÃÊЃ{:Å’îkûE¦,ÈFƒM~ß&—Ïœç }™ [Ð9èaŸOrѳĆ8ÝÝ/·y2èz†аÈD$Ê\Žbë“(Ó9J^<âÇØvöôψª²1züHTœÄìº^ Œß$_vùü33ßS^­ÚãEõjtJ-À¼‘DfL´Q|Y~]pa«Í¾Ñj$=mþ¶ˆòw`Ô xttG…œ½ý¢ÐŠ€U"Ö6[@‰h6ÖJƒ)üIÑêoÎGW2«m¬§ŸŠ(b¢µE$‘!EJ ´ÑyÅ·ÍDZe$]þîþçHÝÂùÙzÞuºŽÔ“p«Ä̵`–­n›é ‹Þˆ+†ón˜ïwùD!Œûûãa)íÐCåç]49Â4Wzû;{üÝ{û7)†ÈIª¬m™¿KVƒ (”ðýŒ‹ #£ |óV|ŠÚ²¼MèpŠ•·y+ß.’ãF3Är¾-ÞªðIí%JÕR:µtä´i¤&êiépùÂ>ùªªdÌ+£DäÔŽ —)$`~¶tP”äK‡”ô|¿?îûGyQõKc“ÜC½¬8ƒú\‰Uï’Ö"g¡›ˆɹ†äL1XáZì\±¶óÍŽeä92?Sàï왑”û…-ß))……Mf] ¤ íǵ—7ᔦzfV¤É<ºYRâß›ñ÷ôo¥Ü¸žÜæºYêËB:¡³·¹ª—¶æY?ÜÝ=+ÀÝ={ûŸ3a]xwoÿ3 0-‘æðì*¤õ?Çã¦A±Œ„•Rƒ—’¦=Ø( ü®çB¦)UE´=tÅäp@†Î22Î$w´šv$)*™"ä¸Uˆ+qÓG¯Y"¹L(T ‚N00EŒk$Ô3ˆù Ö±: § P®Y”ÚCÑgazV'¸dŽiäd ïî»ÒußÞþÓÜ]ô‰5K¦‹cƒÛJ“åÖðèL$,M6ÂahðDðoÇ0ù·£!ƒXè7‹z³„o’ðM2^#ᵘ¢ÀŠOcìC"Hpm¿§$_ú ׌é‚©0.*3¦ßV¡ÇÊðÜðÖ VØ*¼gaôLkã ¤tlAÎÌêØHXÇZ „‰¥‰#ç98ÇÁ½æ`€DòÃE^ãà¥%9èâÀK 2^äà1JJP1ƒÊ@8xŸR§)¾†b¶,Ð~d±{)¡‹Ò.R¼˜ëCà©ÌEªhŽv3M©hZ ×ÇuùëÆÜ•R®ýËð_ H4ÒTa&uú4×9û¯«3[ÀÞh®[_ãkØhö¯4‚ßì3û×TC˜í6ØòVÝüu®ÕñV—çÞ´þ­—ê{Ö7`Köå7´úÏnp5H+Vn¿Å3›üD8D¬VgQq±Î©óxÝ¥¡°›X±aw†Â»­„aÔjóž°Út ç½0瓈±qÌ I/D¼ò‚à…/ð^ðR2’¦sT$½N%E/œX„_ìœTj‰”±ã¨›ê$ ŽºÁ8vù³¾¬ÚíPWËÙpà’7êý+µ ¸¦ÁAmÇ_7Ý|k*{Ãm'÷ëp6vð¨e/V—oýÎ]ó:«ªœÌþSîù R3Ž*œ8XŸZÔ»ˆOKÿQ&ƒÆl¶s¬®'LX0±¬M°YBa›Ñ`6šCa£Íj•/Ùᘘ¤"vÙA°ÃœD;œ MÞ&;;\¤d]̹4G$ P/äÃOJ¦_bð©ÌuÊà5þ•«ê7 Ø+ƒ¾E¨ª„Ê*¡ðûYç‰; Bõ¾Ü>Û,“åÒì]øˆù;öe²–„…zŸÖZZ„)Q¾®ÈÇÚížPØe7±úPXËrÓë ¹"ë ´øuðô:X]ë g/Áð# ÁØÈBó®i¨³suµ õ¨f¨¹v›ÍjÿJÍÊÙ=,ów³ÿ%øƒšªõ7½øp8¾¯öÇF ¬kHu÷]½ûþ½M~(¸ç˜ÛòÏßj=ys½Û×:¼õ^ï«PkãîÒÚê–k¤céXøˆ½‘}¸pu™šÌee*Þ`pªX,ûW®ì;lfó Œ˜Ùkf ¬ÙL 9­ Çh#¶P˜˜¦×ÀÀÖ×aÐùÄAï:Kc@v>i¤9)Ï@³2J%ÿÖà`ÍõÛ¡ êWÓyÙ°´Å`³ÖÕnØo<òÝ©l¶$5û‡':Ú~U¬gå¦Ç|ëÎ{[‡jÙþÃ7çïpVíOcÿ-;XÕýÑ}©WýYJ½Rô:èœÅ˜U©þ‚p¤]XSX\¬-aY»CeÐBaVoÄ9mîî1ˆhr@À!…)•K£º:ÅúFKcm­”CjL ³¿¡ êlu6¿ÙŠqÚh+ظå¶xÓßÿý–šÍ=þÛ­©æþª5o½Õ;xG³i‡ÃK}BŸ1‡ld9*ìuK lF›Ûã$èh§×‰Žv:   [LuwØÀÍy@ôÀ óÀ´’ˆx äâíøòãÁÑ|?»û­ùW;ŸÂGÿö!+>ùù;¹”mv5ànòŸJ²S¿|[òÉÂçê)ô‰ŽØÉ.! ¶’"k‘Ãi· „íªHØÎš¬a“66Yˆš'ðN8ï„NH:邦£¥4”W,DûLÄç7c2Z€'fl”ù©‘ª'²odÿùÌMO^þpþO†áì_e]yêÔ)æ)pÂÊÏn)€•ìËÙg³g²bö¤J¶–îwRüÊÑV;¹$œä,«@£±êY§ÃL"ásÂÌT™ÅîÌŒNm6kt:FV;€¥hTš°ÊrÆ O8á'L;!ㄘTN¸è„œð&Å#2â„^'´:áu'¼ä„¼Èí9¤¢'j¨3¬TCã%ªBæÃöœÑ 7,Ïú%ƒ²Y.4N†ëè|°/Þ)¯k)ú¾uÁSïÏ¿ðØ)ö_šùä›ïÂï¶m^fïüå|¤Ï½S<ÿƉlìqôaN„ª'.Ø üƒ…ãX—Ë^R¨r¯à\NW(ì´k‰5fKŒÚâPX¯—Tn¸ä†ÿæ†ÛÝqCÌ nÃnxÓ /¹áŒ Hî\$ó#Š¿–ÊX)þ•uõº¡5‡ßü{ªè 7[ÔU½VQâæ¢λáu7œpô’nÜÀ»Áä‘6M”oIQ6ZV•|I–l¹Ý0_¶É Q(Á4^²ºAZvih~ýøãOþåÕÍë«VÖ4Õúé+YÕ¶ýšæ×Ï—¼z‹-ùÈñÞÏ/ûªª|‡rŒƒ k7y\Hªõ…: ®ÿ„¨Y5:ßö¦^ÒÃ=<¡‡ôp»2zˆéa•¬zPé1Ý(Ç1=–+zˆè!¤Aszõp‚6Mz z¸H›È·˜m‰”ReIŠ^©YqB¯¯)»Rš$¤Šäƒùz È] ¿Cä-¬·‚žh4†"V÷èµl iRjÔ°¨ÐCmõõmÁººà¾õëë‚AÔÁ,üZûmzžèx£µPmUs6¦ °¨ƒ1ŠŠ¬ÆBµV=6kÙb½þ쟄—¤g¨Jb\Ãdžƒ9x—ƒŸqp’ƒ9¦¤ 8XMÆ.sðO¼ÍÁs|“©ÚGpð&?âàQŽp ²—6ê9XÅ•2¼ÄÁž ò˜®Üñ⋵3Fa`ùqƒ¾°Ž(•[TÔå l<`Ôê/Äj¿ü€±³iuP§“!õþ†ìÙG²­S yë±*Ø5oÀóS^öøç1uQiCCéç]ìãŸïgg%XÉÙ‡°V°’n¡Ê¬Õ‚Á`ã4fºÜ«Í,c5™ŠBa“Qk(Är¦Ð6@‰^ºqÑ'M­º:\â̹2FÞíýkVjUþv<0Ul®ýví÷³Í‚E·õÕ­¸1Lº¸ùæ\ ð,ôk´mîì·‘’‡Þ`Ð:´nÏ <­0–`ƒs MœÍ‚œ¬iO˜5=á<ð’°ÐPy x ã˜z=Ðêz¬ò€‹’±âa×;Xå¼î|)”Ç/ŽÞÀ¿ëD´ô<´zé¨õêÿºY>u÷íÅÑõ7Þ6RÙ˜?õ÷ (ç!zN`¤_Øgp­ÑãIqZè¶hµnbwÛ=ÞR](\Êip'µ²Ýa«ÉˆQ3î¤Ãá1zL<Ÿ;õɧAù(8—ƒyïâå–3Wv+ýBÝâ—•Á)ÍV­´(جŒtÎ`²ÓwnÉ”öNÍÜ:äÛÐÄš{õ×o]óÚn¸xöŒÍ0o7ýƒªÚQ•7ÛýáGóÙ[í¥ñwfƒìŸØSdüFX0J‡ÇÉX HeÑ»%fC1ŽÍVl$Úî0KV`‡=p †ÔŸÐ4xÓ?óÀ=ðmšrAÛìZš˜!Œ^öÀÛxÑÏx³ç>ÜN¹‡iÂ)÷JXhÂ\òÀ?Q~̰38™ãOy`Ð{r ¶Ú\Ž?oÇ™¥ú—ñËÖlºL¹óÖ<Ó.|c±=«¨=Rm޵øyš´²Aä´ÇèXeí—(#§u>Ý»<`ôä+Vi…Z²8-Þb¿Xì,e^ú5ÁWG¤©6¿Ó“¨ô­É•5­d¥r"ÝåÍ%¿ ˜ùùî]Ÿwc}ÿÎÙG"pæìåûaÿ`ö»;"™lÐòJľõÀClç‡k>ÁÜoÛç×>yì*y©ÀóÙ'Ò>DDá&«A£ál…–HØXì-f ÙââÂ5Ψ0ÃÊßcå¿«Z ÀÓ¹ïªç–ø÷!”sëÇt£HЯ™äMãàé×Rô+§¼›–}Å´¤\¬ËŸšpÅ™E=`¶JÇ%É=Òé©9ŨÚóW#Ó]Íž’àº{TÿBWöïüÅ”çÒ{éOåqïÆ5b7®Ÿ‰[Íj=§æìŽc(l(0qVÖŠ³†#Ø.8 Æ¼L¸è€×pÂÓ@üÓp,µ=oéâ © äÍ´„’êX„陕ݽþÔÞìÆß¹ëÄÆŠžLöÒþÑ}ã«Ê῟÷f?=ÈŽ¾ù¬Ðÿ À5íÀÊÌÆ­d¼òïÑÓúú/¯üÚ˜ b5ñ8ÉÿXMÇH´¾lùÆbÌ’‹Ó4â ã7¤LEˆ•i$¬›ô2Òï£GI¶­ø©Òd‹úçd‹ôf~Hš_ŽÍDù¡DòPjld4ï*çkkÖ×ðí‰ÄÈxœoI¤’‰T43–˜¬.lYÎVËïAÑL%¿sr¨zר`\æå{⩱á=ñ‘©ñhjGz(>‹§ø*~9Çòö5ñTZjÔV×ÔT7\¡.gKóQ>“ŠÆâÑÔ |bx©!|*>2–ÎÄSˆ›äûª{ªùP4ŸÌðÑÉß›ìŠSäP<•‰"s"3Ц^?•KÇÆ†¤ÞÒÕù,rGO&~ Î_ÍdâéÄds4}¡e½c“‰t%ptlh”?Mó±xzld‰ƒ‡ø¥2- Y‘æ3£ÑŒ4è‰x&56?„1›H¢Ô éàXf;žˆ§ùÝñƒüžÄDtò‡Õ²)è›at*?6‘L%P«ÒC©x|;‹Æ¢ƒcãcÔ6ME‡Ðcè¶±¡4õ:‚OF'«Ú¦R‰d-ýFû®+Œh ìÍtbüö,qOÆã1©G4û@|…°ãñDâi<ÉËŒV-²|81™AÑÅpàè­ÄÐÔ„'ts&g\t(•@Zr<šA-éêÑL&¹98xð`uT ÍF¦5¾Ž–9”Œ+ñHIZ&Æwaø'¥ÐMÑøJƒèÙ¹‹ïJ¢‚h¯0Tò¹Ô\_½^éÝ8–̤«ÓcãÕ‰ÔH +¸‹´’12‚wï›IœÄwÛQ„†H‚$É!’¢\£ˆåÉZÄ–ã»–Ôõxó¤¹HGyž´ œB)é¥zd’T“BJùzmµíQ¬è Ò•íDù!Ô° 呺X/Oz(f ×YIr„L¡QÄì i”Š#OŒrð¤ ï?§ãÏѯ¡P:O©E»jðSM¾TöÏiC]<õu†R$['¨ý7 .r_çùâ4~i¤Äi+FµJºû£‡r…¨¤ä‹ ím’rõ~I]Øã0ÊÑXæ8‡¨n)'dÍ „G¯^OQ bT.7¶4öüÅ|yvôPëÐ>¯¦x©¦´fl§•qÉ>ë¥V$+ùâ Z"õ;Já(õgŒJKY6©HbÞñ_Û¯ÈF•¸LÒ>(VJ2•Š¿‡é3MûÄ>xjŸå¥}óÔOQêu9ÒHÍPÞ!Äãç2Ï&Ð+r_ƒÊL:Hçå¨2â ª—ÇJ&Ž)+4n“¾•4ÆW¼"çͰ’©<•M"œ £Èù±ŠÆFIœZ*AQ:÷Qbœö-Û6J³#JcWb¡#Èù+¦ŒT²:I1U¤æ…4ããŠO¿+Å®/Õ({pqnJ1§ö¦éž¤ÖÆòc”½-q+=É#§+Ò ùø Ó|“=£Úª¾ÂçÃÔ7¥×µ(†9ârn%PvŠÆCžOr6g¾à¹(õoB‘KÒu)£Ø2AçÇ(ÍÀ$ÙŒµe­“>Õ4Ïš!eÎT+6þÝr’]IêÁÅó#•·emÜ¥ÌþÉü¬›Z4s‘èÁ5h]/’JþÏñË4H³fùª¹û[¿lr6Ža;CíIS_VÓ1Œ ½ {ØEëhz-øÐ¦/¹fu¡ƒ'£0BJˆ"d7 >ØA¶€oiÍønÁ¶ô®†mdù¶!~;¶·"~ .ž^|6áÝ…÷½x«ð–9j#€ï€Ò®Âv%J¼†O ·„mB¬ô¾ ÛønWÞAÄ·á»MiïÄ6¾I´ÒôyTÂi8?¯Í?‡?ƒÐg0ýɱO˜?\,÷>}ñÜE¦ëãŸþ˜­ùŒC¹`ºº¹¼pâ‚¦ÐøÈïÁü›ó›¼ïo{¯ï·ýª¼‡#{¯æ½Ð{Óï‰ï©ß¶ïW,ç5Íñs5sɹé¹×çÎÏ]œ+˜þ鱟2ÿýù€×ø¼÷yÆ{ºëôáÓlä)0>å}Š =y”9vŒÇ½ÇÇÙG®ö>Üîñ~ïÁ5Þó^|9»0wúÁ"sðyè‚]dúp÷ivÁûô\Ã2âÓ‹wï.¼xß‹7ž{Ý‹wv ›Ø¿ý}®û*î»å¾#÷©“wNßyìNvúŽcw0O8w€I‡Ê½‰É ïdû:¯³Îѧ­cû4Ø ö.ì,[Œ Þdºvowo{¹·¤ÎÒ§Æ«ÑÈzÙ&¶‹M°÷²çXmÁžÇÛ÷ùÐÅ#„t† ±ËÛèbÏ.œâ>ÔvUòªé«ØÁroGû&¯±ÝÛh­ýýöÛ5íðþŸž ²B°<‚_pE‡««³õ™ÁØgª3ö1€®#}ã‚‘1Œ‡¬‘4fš5œ…c³½=gµ {:łе"Ü-–õHO¡{¯¨¹[$}{¯íŸøNøŽ£GI³»S¬íé#îp§C@€iLîYŽ4‡ÓéL½ ¢á)|’Š© DîOËX’§“Š4¤qJS!¨ä6à³B¢!B’”ÞŸ&ÒC"VÈB’tZQG…åûÿ¶g– endstream endobj 6 0 obj 7404 endobj 7 0 obj <> endobj 8 0 obj <> stream xœ]’Mnƒ0…÷œÂËt DBH)I$ýQiö"c²àöõÌÐVêëûÍøé™°¬Î•éçðÕª†Yt½Ñ¦ñîˆn½ d,t¯æµ¢U Bß[/Ó Ceº1σðÍŸM³[Äæ¤Ç‚ðÅip½¹‰ÍGYûº¾[û˜YDAQ ŸóÔØçf€º¶•öÇý¼l}ËŸà}± bª%[Q£†É6 \cnäQTˆüz-0úßY¼¶´úlœ—J/¢}RxމÓòŽùˆœg;ä=q!§¬‘ÈkhÎ÷÷ÈGžOúqBšGæ¹d=ñ™¹D¾ð]ä+ÏÉ<ˈÙŠ¹ú§}öŸ¡Éþ“2ûOwΚÆ„ïø¿Pwç|ôôØ”9¦Ýøýìh±‹¾oˆ’œ; endstream endobj 9 0 obj <> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer /CreationDate(D:20190902205629+02'00')>> endobj xref 0 14 0000000000 65535 f 0000008715 00000 n 0000000019 00000 n 0000000271 00000 n 0000008884 00000 n 0000000291 00000 n 0000007780 00000 n 0000007801 00000 n 0000007996 00000 n 0000008384 00000 n 0000008628 00000 n 0000008660 00000 n 0000008983 00000 n 0000009080 00000 n trailer < ] /DocChecksum /72B44A81E5EEF3D98178B73CE31BA672 >> startxref 9255 %%EOF paperwork-2.2.2/paperwork-backend/tests/poppler/tests_file.py000066400000000000000000000046661456262201400245020ustar00rootroot00000000000000import cairo import gc import os import psutil import unittest import openpaperwork_core class TestFileDescriptorLeak(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', reason="Linux only") def test_fd_leak(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.python") self.core.load("paperwork_backend.poppler.file") self.core.init() self.simple_doc_url = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_doc.pdf" ) ) gc.collect() gc.collect() current_fds = list(psutil.Process().open_files()) doc = self.core.call_success("poppler_open", self.simple_doc_url) self.assertIsNotNone(doc) new_fds = list(psutil.Process().open_files()) self.assertNotEqual(len(current_fds), len(new_fds)) doc = None gc.collect() gc.collect() new_fds = list(psutil.Process().open_files()) self.assertEqual(len(current_fds), len(new_fds)) @unittest.skipUnless(os.name == 'posix', reason="Linux only") def test_fd_leak2(self): self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.python") self.core.load("paperwork_backend.poppler.file") self.core.init() self.simple_doc_url = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_doc.pdf" ) ) gc.collect() gc.collect() current_fds = list(psutil.Process().open_files()) doc = self.core.call_success("poppler_open", self.simple_doc_url) self.assertIsNotNone(doc) page = doc.get_page(0) new_fds = list(psutil.Process().open_files()) self.assertNotEqual(len(current_fds), len(new_fds)) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 200, 200) ctx = cairo.Context(surface) page.render(ctx) new_fds = list(psutil.Process().open_files()) self.assertNotEqual(len(current_fds), len(new_fds)) page = None doc = None gc.collect() gc.collect() new_fds = list(psutil.Process().open_files()) self.assertEqual(len(current_fds), len(new_fds)) paperwork-2.2.2/paperwork-backend/tests/poppler/tests_memory.py000066400000000000000000000031371456262201400250630ustar00rootroot00000000000000import cairo import gc import os import unittest import openpaperwork_core class TestMemoryDescriptorLeak(unittest.TestCase): @unittest.skipUnless(os.name == 'posix', reason="Linux only") def test_leak(self): self.tracking = False self.disposed = False class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): def on_dispose(s): self.disposed = True def on_objref_track(s, obj): self.tracking = True obj.weak_ref(s.on_dispose) self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.fs.python") self.core.load("paperwork_backend.poppler.memory") self.core._load_module("fake_module", FakeModule()) self.core.init() self.simple_doc_url = self.core.call_success( "fs_safe", os.path.join( os.path.dirname(os.path.abspath(__file__)), "test_doc.pdf" ) ) gc.collect() gc.collect() doc = self.core.call_success("poppler_open", self.simple_doc_url) self.assertIsNotNone(doc) self.assertTrue(self.tracking) self.assertFalse(self.disposed) page = doc.get_page(0) surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 200, 200) ctx = cairo.Context(surface) page.render(ctx) self.assertFalse(self.disposed) page = None doc = None gc.collect() gc.collect() self.assertTrue(self.disposed) paperwork-2.2.2/paperwork-backend/tests/tests_datadirhandler.py000066400000000000000000000050171456262201400250370ustar00rootroot00000000000000import shutil import tempfile import unittest import os import openpaperwork_core class TestDirHandler(unittest.TestCase): def setUp(self): self.tmp_paperwork_dir = tempfile.mkdtemp( prefix="paperwork_backend_tests" ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999999999999 def paths_get_data_dir(s): return self.core.call_success( "fs_safe", self.tmp_paperwork_dir ) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.datadirhandler") self.core._load_module("fake_module", FakeModule) self.datadirhandler = self.core.get_by_name( "paperwork_backend.datadirhandler" ) self.core.init() def tearDown(self): shutil.rmtree(self.tmp_paperwork_dir) def test_init(self): data_dir_hashed = self.core.call_success( "data_dir_handler_get_individual_data_dir") self.assertTrue(self.core.call_success("fs_exists", data_dir_hashed)) self.datadirhandler._delete_old_directories( days_to_data_dir_deletion=2) # after deleting old directories with the default value, # the created directory should still be there self.assertTrue(self.core.call_success("fs_exists", data_dir_hashed)) self.datadirhandler._delete_old_directories( days_to_data_dir_deletion=0) self.assertFalse(self.core.call_success("fs_exists", data_dir_hashed)) def test_dir_hash(self): data_dir_hashed = self.core.call_success( "data_dir_handler_get_individual_data_dir") self.assertTrue(self.core.call_success("fs_exists", data_dir_hashed), "directory %s should exist but it does not" % data_dir_hashed) workdir = self.core.call_success('storage_get_id') self.assertEqual( os.path.basename(workdir), os.path.basename(data_dir_hashed).split("_")[0] ) data_dir_wo_hash = self.core.call_success("paths_get_data_dir") self.assertEqual(os.path.commonprefix( [data_dir_wo_hash, data_dir_hashed] ), data_dir_wo_hash) data_dir_hashed_again = self.core.call_success( "data_dir_handler_get_individual_data_dir") self.assertEqual(data_dir_hashed, data_dir_hashed_again) paperwork-2.2.2/paperwork-backend/tests/tests_pagetracker.py000066400000000000000000000064621456262201400243660ustar00rootroot00000000000000import shutil import tempfile import unittest import openpaperwork_core class TestPageTracker(unittest.TestCase): def setUp(self): self.tmp_paperwork_dir = tempfile.mkdtemp( prefix="paperwork_backend_tests" ) self.core = openpaperwork_core.Core(auto_load_dependencies=True) class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 999999999999999999999 def data_dir_handler_get_individual_data_dir(s): return openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_paperwork_dir ) self.core._load_module("fake_module", FakeModule) self.core.load("paperwork_backend.model.fake") self.core.load("paperwork_backend.pagetracker") self.fake_storage = self.core.get_by_name( "paperwork_backend.model.fake" ) self.core.init() def tearDown(self): shutil.rmtree(self.tmp_paperwork_dir) def test_tracking(self): self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'page_hashes': [ ('file:///somewhere/test_doc/0.jpeg', 123), ('file:///somewhere/test_doc/1.jpeg', 124), ], }, { 'id': 'test_doc_2', 'url': 'file:///somewhere/test_doc_2', 'page_hashes': [ ('file:///somewhere/test_doc_2/0.jpeg', 125), ('file:///somewhere/test_doc_2/1.jpeg', 126), ('file:///somewhere/test_doc_2/2.jpeg', 127), ], }, ] tracker = self.core.call_success("page_tracker_get", 'test_tracking') out = tracker.find_changes('test_doc', 'file:///somewhere/test_doc') self.assertEqual(out, [('new', 0), ('new', 1)]) tracker.ack_page('test_doc', 'file:///somewhere/test_doc', 0) tracker.ack_page('test_doc', 'file:///somewhere/test_doc', 1) out = tracker.find_changes( 'test_doc_2', 'file:///somewhere/test_doc_2' ) self.assertEqual(out, [('new', 0), ('new', 1), ('new', 2)]) tracker.ack_page('test_doc_2', 'file:///somewhere/test_doc_2', 0) tracker.ack_page('test_doc_2', 'file:///somewhere/test_doc_2', 1) tracker.ack_page('test_doc_2', 'file:///somewhere/test_doc_2', 2) tracker.commit() self.fake_storage.docs = [ { 'id': 'test_doc', 'url': 'file:///somewhere/test_doc', 'page_hashes': [ ('file:///somewhere/test_doc/0.jpeg', 256), ('file:///somewhere/test_doc/1.jpeg', 124), ('file:///somewhere/test_doc/2.jpeg', 257), ], }, ] tracker = self.core.call_success("page_tracker_get", 'test_tracking') out = tracker.find_changes('test_doc', 'file:///somewhere/test_doc') self.assertEqual(out, [('upd', 0), ('new', 2)]) tracker.ack_page('test_doc', 'file:///somewhere/test_doc', 0) tracker.ack_page('test_doc', 'file:///somewhere/test_doc', 2) tracker.delete_doc('test_doc_2') tracker.commit() paperwork-2.2.2/paperwork-backend/tests/tests_util.py000066400000000000000000000007741456262201400230530ustar00rootroot00000000000000import unittest import paperwork_backend.util class TestUtil(unittest.TestCase): def test_levenshtein_distance(self): levensthein = paperwork_backend.util.levenshtein_distance self.assertEqual(levensthein("abc", "abc"), 0) self.assertEqual(levensthein("abc", "abce"), 1) # insert self.assertEqual(levensthein("abc", "ab"), 1) # delete self.assertEqual(levensthein("abc", "abd"), 1) # replace self.assertEqual(levensthein("abc", "defg"), 4) # combo paperwork-2.2.2/paperwork-gtk/000077500000000000000000000000001456262201400163265ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/.flake8000066400000000000000000000001071456262201400174770ustar00rootroot00000000000000[flake8] exclude = src/paperwork_gtk/_version.py max-line-length = 100 paperwork-2.2.2/paperwork-gtk/AppImageBuilder.yml000066400000000000000000000055611456262201400220520ustar00rootroot00000000000000version: 1 script: - rm -rf AppDir - rm -rf appimage-build - git submodule update --recursive --remote --init - make download_data -C .. - make version -C ../sub/libpillowfight - make l10n_compile -C ../openpaperwork-core - make l10n_compile -C ../openpaperwork-gtk - make l10n_compile -C ../paperwork-backend - make l10n_compile -C ../paperwork-gtk - make -C ../sub/libinsane clean - unset DESTDIR && make install PREFIX="$(pwd)/AppDir/usr" -C ../sub/libinsane - pip3 install --ignore-installed --prefix=/usr --root=AppDir ../sub/libpillowfight ../sub/pyocr ../openpaperwork-core ../openpaperwork-gtk ../paperwork-backend ../paperwork-gtk - mkdir -p AppDir/usr/share/icons/hicolor/48x48 - mkdir -p AppDir/usr/share/icons/hicolor/scalable - cp src/paperwork_gtk/data/paperwork_48.png AppDir/usr/share/icons/hicolor/48x48/paperwork.png - cp src/paperwork_gtk/data/paperwork_halo.svg AppDir/usr/share/icons/hicolor/scalable/paperwork.svg AppDir: path: ./AppDir app_info: id: work.openpaper.Paperwork name: Paperwork-gtk icon: paperwork version: latest exec: usr/bin/python3 exec_args: "$APPDIR/usr/bin/paperwork-gtk $@" apt: arch: - amd64 allow_unauthenticated: true sources: - sourceline: deb http://deb.debian.org/debian/ testing main contrib include: - bash - coreutils - dash - gir1.2-gtk-3.0 - gir1.2-handy-1 - gir1.2-poppler-0.18 - gobject-introspection - libexpat1 - libgirepository1.0-dev - librsvg2-common # for libpixbufloader-svg.so - libwayland-cursor0 # missing Debian dependency for GTK ? - libwayland-egl1 # missing Debian dependency for GTK ? - locales - python-is-python3 - python3 - python3-gi - python3-gi-cairo - python3-pip - python3-pkg-resources - sane - shared-mime-info - zlib1g files: include: - usr/lib/mime/**/* - usr/share/mime/**/* exclude: - usr/share/doc/*/changelog.* - usr/share/doc/*/NEWS.* - usr/share/doc/*/README.* - usr/share/doc/*/TODO.* - usr/share/gtk-doc/**/* - usr/share/man runtime: env: PYTHONHOME: '${APPDIR}/usr' PYTHONPATH: '${APPDIR}/usr/lib/python3.11/site-packages' test: fedora-30: image: appimagecrafters/tests-env:fedora-30 command: ./AppRun use_host_x: true debian-stable: image: appimagecrafters/tests-env:debian-stable command: ./AppRun use_host_x: true archlinux-latest: image: appimagecrafters/tests-env:archlinux-latest command: ./AppRun use_host_x: true centos-7: image: appimagecrafters/tests-env:centos-7 command: ./AppRun use_host_x: true ubuntu-xenial: image: appimagecrafters/tests-env:ubuntu-xenial command: ./AppRun use_host_x: true AppImage: arch: x86_64 update-information: guess paperwork-2.2.2/paperwork-gtk/COPYING000066400000000000000000001045131456262201400173650ustar00rootroot00000000000000 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 . paperwork-2.2.2/paperwork-gtk/ChangeLog000066400000000000000000000464441456262201400201140ustar00rootroot000000000000002024/02/13 - 2.2.2: - Make it possible to edit help documents - doc list layout: do not let a big lengthy label increase the horizontal size of the document list. - Handle more gracefully the lack of Notify 2023/09/17 - 2.2.1: - Add build-system.build-backend to pyproject.toml - Fix Windows executable build 2023/09/16 - 2.2.0: - setup.py has been replaced by pyproject.toml - doclist: optimization: Now that Gtk.Template are available. Use them instead of reloading Gtk widget trees. - doclist: optimization: only load thumbnails and labels of documents actually visible in the document list. - settings.storage: try to warn users that using an already existing folder with Paperwork is a bad idea (unless it has the file structure expected by Paperwork, of course) - fix uncaught exception when the user clicks many times the button 'next page'. - fix import of password-protected PDF files. - doclist thumbnails: handle gracefully corrupted thumbnails/documents. - Flatpak workaround: when running in Flatpak, always run first 'fc-cache -f' to make sure that text will be rendered correctly in PDF pages. - Import dialog: remember last import location (thanks to Guillaume Girol) - Export dialog: fix title (thanks to Guillaume Girol) 2023/01/08 - 2.1.2: - Optim: mainwindow.docproperties: optim reload doc properties only if the doc properties are actually visible (it was a huge CPU waste) (thanks to pie@#openpaperwork) - Fix: docview: make sure the currently-active page is always the currently-highlighted one - Fix: docview: remove an obsolete workaround preventing 'doc_goto_page()' to work correctly right after a call to 'doc_open()' - page editor: when clicking apply, make it obvious the user may have to wait. Sometimes Paperwork has already jobs queued and cannot apply the changes immediately --> user has to wait - mainwindow.pageview.boxes: Fix crash: in some rare cases, we may have 2 word boxes with the same coordinates --> when sorting the boxes by position, we may have to implement __lt__ on NBox. 2022/01/31 - 2.1.1: - drop unused dependency on dateutil - Doc deletion: Fix broken spanish translation: Wrong Python formatter has been used - model.help.intro: Handle gracefully the case where the package maintainer forgot to include the introduction documents 2021/12/05 - 2.1.0: - Responsive UI (thanks to Mathieu Jourdan) - Add support for password-protected PDF files - Export: add a button sendig the document by mail instead of exporting to disk (thanks to Guillaume Girol) - Add confirmation when deleting label from all documents - Add option to redo ocr on many documents in one shot - Add option to move a page from one document to another (drag'n'drop isn't obvious to all users) - Page menu: add an option to move pages inside a document (drag'n'drop isn't obvious to all users) - Mouse middle button can now be used to scroll in a document (auto-scrolling) - Add dependency on Libhandy 2021/05/24 - 2.0.3: - GTK: (may be important for package maintainers): "make data" --> "screenshot.sh": Download the test documents from a Git repository instead of a .tar.gz. See Gitlab issue #961. - GTK: Doc/page export: Work around bug in Gnome platform 40 (Flatpak) (caused a full crash of Paperwork ; Segfault) - GTK: Doc/page export: Fix use of GtkFileChooserNative so Paperwork can exit correctly after its use. - GTK: Doc renaming (date change): Prevent the user from giving an invalid name to a document - GTK: Doc/page export: Handle gracefully errors (for instance Permission Denied) - GTK: word boxes loading: Add missing progress notification - GTK: Import: When importing in an existing document, refresh correctly the GUI is the target document is currently opened. - GTK: LaTeX User manual: various fixes suggested by tomf on Weblate - Swedish translations added 2021/01/01 - 2.0.2: - pageview.boxes: add workaround regarding unexpected Poppler exceptions on some PDF documents (see https://gitlab.freedesktop.org/poppler/poppler/-/issues/1020 ) - add a command "paperwork-gtk import": Open the GUI and import the documents given as arguments (thanks to Guillaume Girol) - desktop file: associate "paperwork-gtk install" to PDF and images files, so users can import files directly from their file browser (thanks to Guillaume Girol) - add plugin 'sync_on_start': Start the full synchronization when the GUI is started, but only if the configuration allows it. (Before this plugin, synchronization was started directly in the 'main.py') - advanced search: prevent the user from opening the dialog twice (not supported) - Help documents: Fix for people who seem to have no locale configured (?!) - settings/scanner/flatpak: Fix the dialog explaining how to enable Flatpak: Once the dialog has been closed and destroy, it could not be opened correctly again. - drawer.scan: Workaround regarding scanners reporting an image too big for Cairo ImageSurface (some Fujitsu scanners) - settings/storage: when opening the file chooser to select the work directory, pre-select the current work directory - GTK: boxes.search: do not highlight the keywords "and" and "or". They are used in Whoosh query syntax, but it's useless to highlight them in documents. 2020/11/15 - 2.0.1: - take into account that document IDs may not be the expected date+time format (no uncaught exception should be raised in that case) - doclist: Fix: When the document list, scroll to the currently-opened document. - settings/calibration: Disable the calibration settings button if no scanner is selected - update notifications: make sure the funny strings are displayed translated - Include tests in Pypi package (thanks to Elliott Sales de Andrade) 2020/10/17 - 2.0: - Full rewrite - Use of plugin system of openpaperwork_core to split features - PDF can be edited - Pages can be reinitialized to their initial states (reset) - Settings dialog have been revamp - Scan source selection is done in the main window now instead of the settings dialog - No multi-scan dialog anymore: clicking "scan" always scan until the end of feed - An automatic bug report submission system has been added 2019/12/20 - 1.3.1: - Add spanish translations (thanks to Iñigo Figuero) - Frontend: Fix multi-scan dialog / scanning from feeder - Frontend: When looking for the scanner, if the exact ID is not found, fix fall back code - Frontend: About dialog: Add patrons 2019/08/17 - 1.3.0: - Switch from Pyinsane2 to Libinsane - Replace application menu by primary menu (new Gnome recommendation) (thanks to Mathieu Jourdan) - Remove documentations 'hacking' and 'translating'. They are in the Wiki now. - Fix: Make sure the main window is restored at its previous size correctly each time Paperwork starts. - Settings window: If no scanner has been found and we are running inside a Flatpak container, show a popup to the user explaining how to enable and configure Saned. - Drop custom heuristic page orientation detection. Only use tool orientation detection. If it fails, default to the original orientation. - Fix: Ignore word boxes starting at (0, 0) (Tesseract bug ?) (thanks to Jonas Wloka and Balló György) - Install icons in the correct hicolor sub-directory (thanks to Elliott Sales de Andrade) - Fix warnings related to regexes escaping + various other cleanups (thanks to Elliott Sales de Andrade) 2018/03/01 - 1.2.4: - Main window/pages/mouse handlers: Fix infinite loop in signal handling when the mouse goes over buttons drawn over pages. 2018/02/01 - 1.2.3: - Flatpak: Fix support of other GTK themes (Dark Adwaita, etc) - French translations: shorten the translation of "Matching papers" because otherwise it messes with the UI - Export dialog: Clicking on export->{document|page} a second time will first close the first export dialog. 2017/11/14 - 1.2.2: - DnD: Fix double-delete: when moving the last page of a document to another, don't delete the source document (it's up to the backend code to delete it) - Flatpak support - CSS: Add border around application button to make it more visible 2017/08/26 - 1.2.1: - Add source code of Windows installer (NSIS installer) generator - Scanner support / Multi-scan: Cancel also successful scan session. Otherwise some scanner won't allow new scan sessions later. - Remove gi version warnings when starting (thanks to Matthieu Coudron) - Documentation: Add missing stdeb dependencies (thanks to Notkea) - paperwork-shell: Fix command 'scan' - paperwork-shell install: add docstring - Fix dialog 'about' 2017/07/11 - 1.2.0: - Installation: A new command has been added: "paperwork-shell install". This command installs icons and shortcut in the desktop menus. - Add integrated documentations: + Introduction to Paperwork (added to the documents when Paperworks starts for the first time) + User manual (not complete yet) + Developer's guide + Translator's guide - Text in pages can be selected - Text in pages can be copied in clipboard - Automatically look for updates (disabled by default ; see settings) - Send anonymous usage statistics (disabled by default ; see settings) - Export: Add simplification methods 'grayscale', 'black and white', and 'grayscale + soft'. They produce much smaller documents - setup.py: Properly package resources files (glade, images, css) and load them using pkg_resources. (thanks to Alexandre Vaissière) - Import: After import, propose the user to move files to trash after import (thanks to Mathieu Schopfer) - Import: Allow selecting multiple files in the file chooser dialog - Import: Clearly show in the file chooser dialog which file formats are supported - Import: Use notifications instead of popups - Virtualenv: also look for translation files (thanks to Alexandre Vaissière) - Export: Remove the text field + save button ; request the target file location when the user actually clicks on 'export' - Export: Display a notification when exports are finished - Search: When searching, display a search bar to browse the document(s) - Search: new keyboard shortcuts: F3 (next) + Shift+F3 (previous) - Settings: Remove "Disable OCR" from the language list. It's redundant with the check box above the language list - non-Gnome / non-Unity environements : Move the application menu to the left headerbar (top left of the main window) - paperwork-shell chkdeps: look for libsane too - localize.sh: Also include the translations for paperwork-backend - Settings: Use pycountry to translate the language names + remove 'equ' and 'osd' - GUI: change the way left panes are switched to reduce issues with GTK+ - Internal: Switch everything to URIs (required for correct Gio use) - Devel: Add basic command line arguments (thanks to Mathieu Coudron): + -d for debug output + -v for version 2017/02/09 - 1.1.2: - Doc date changing: Fix for Windows: Don't display the document while renaming its folder --> it keeps a file descriptor opened to its PDF file and prevent the renaming 2017/02/05 - 1.1.1: - Fix document list refresh problem (mostly visible on Ubuntu) 2017/01/30 - 1.1.0: - Windows: Activation mechanism has been disabled for now - Workarounds for Gtk-3.20.x / GLib 2.50 (Ubuntu): - Work around weird behavior of GLib.idle_add (multiple calls) - Work around lack of refresh of document list - Import: Display how many image files, PDFs, documents and pages have been imported. - Automatic Color Equalization: Reduce the 'circle side-effect' by increasing the number of samples used. - paperwork-shell scan: Quit after scanning - Settings window: "Source" becomes "Default source" (cosmetic) - Export: Don't lock the UI - Export: Display the progression of the export - Improve keyword highlighting: Highlight words identical to search keywords (as before) and also words close enough (example: 'flesh' when 'flesch' is being search) - Optim: Document list: Only display display the first 100 elements of the list, and extend it only when required. Reduces GTK latency (GtkListBox doesn't scale very well above 100 elements). - Optim: Improve PDF rendering speed: Let the libpoppler take care of the rendering size (see backend:page.get_image()) - Optim: Reduce the number of useless calls to redraw() 2016/12/04 - 1.0.6: - Diagnostic: Limit the number of lines kept in memory (avoid running out of memory in case of endless loop) - Diagnostic: Log all the uncaught exceptions - PDF import: When importing a big PDF, clearly show the progression of the import - Multiple document selection: Fix the way Ctrl/Shift keys are handled (bug was that multiple selection mode remained stuck sometimes) 2016/11/22 - 1.0.5: - Setting the resolution on the scanner may not actually work. If it is not possible to set the resolution, fall back on the current one. - Improve tolerance to crappy scanner drivers: don't stop if pyinsane2.maximize_scan_area() fails 2016/11/18 - 1.0.4: - Windows: Fix import error dialog - Windows: Fix GtkLinkButtons (didn't do anything when clicked) 2016/11/17 - 1.0.3: - Windows: Fix opening of export dialog - Application menu button: Make its style consistent with the other buttons in the header bar - Label list: Add a button to delete labels - Label editor: Fix the reloading of the label list when a label has been changed - Label editor/Color picker: Fix the switch of the mouse cursor to a pipette - Small Paperwork icons: add a discrete blue background to make the icon more visible - Main window: When on "new document", disable the page number entry field + the view settings button - Fix icons (application icon, main window, about dialog) 2016/11/13 - 1.0.2: * Fix export dialog: - Don't use GtkWidget.set_visible(False) / GtkWidget.set_visible(True) anymore to avoid weird GTK behavior when reopening - Fix endless loop that occured with some versions of the GLib * French translations: "Scanner" --> "Numeriser" * Windows support: Fix translations support * CSS: Add small padding to make sure the GtkEntry and GtkButton in the header bar all have the same heights on all environments. * Fix menu icon: Add PNG versions of the PAperwork icon. 2016/11/10 - 1.0.1: * Config: Fix pycountry db lookup (prevent Paperwork's first start) * Pyinstaller: Add .ico + .png in the package 2016/11/09 - 1.0: * Export: generated PDF now includes the text from the OCR * New command 'paperwork-shell scan' that starts Paperwork and immediately tries to scan a page * 'paperwork-chkdeps' has been replaced by 'paperwork-shell' * Export: Add an option to automatically simplify the content (makes it smaller in size) * Import: Display a popup when the import fails * Page editing: Add an option to adjust automatically colors * Page editing: Fix display when making many edit operations at once (Rotation Cropping + ...) * When starting, instead of displaying an empty document, display Paperwork's logo and the version (if different of "1.0") * Improve zooming/unzooming with Ctrl+MouseWheel (try to target the mouse cursor) * Allow scrolling using the middle click * Support for pyinstaller packaging * Fix running the OCR while scanning at the same time * Split backend and frontend (separate Python packages and separate Git repositories) * Handle very long label names more gracefully * Word box highlighting: Highlight correctly all the boxes * Fix spinner animation when getting an icon size other than the expected one * Switch to Python 3 * Switch from Pyinsane to Pyinsane2 * Fix file descriptor leak related to PDFs * Add a dialog to help bug diagnostics * Replace gnome spinner by a custom spinner 2016/04/06 - 0.3.2: * paperwork-chkdeps: Fix check for python-gi-cairo. When python-gi-cairo is not installed, sometimes, an exception pops up at an unexpected moment and the script remained stuck. * Add Dockerfile to generate a docker image+container to test Paperwork 2016/02/25 - 0.3.1.1: * Fix crappy dependency list 2016/02/25 - 0.3.1: * Fix label learning * Fix headerbar widget sizes 2016/02/16 - 0.3.0.1: * Fix Paperwork packaging (.css files were not included) 2016/02/15 - 0.3.0: * Whole GUI redesigned * Added: dialog to make advanced searches * New dependency: simplebayes * Removed dependencies: - scikit* (replaced by simplebayes) - numpy* (replaced by simplesbayes) - gir1.2-gladeui (obsolete) 2015/11/25 - 0.2.5: * Scanner support: Fujitsu scanners: handle options 'page-height' and 'page-width' * Scanner support: Brother MVC-J410: set mode correctly (value = '24bit Color' instead of 'Color' ...) * Documents: add support for new label format that will be used in Paperwork >= 0.3.0 * paperwork-chkdeps: look for required icon themes * Fix: work even if the spinner icon is not available * Fix: paperwork-chkdeps: work even if Gtk is not yet installed * Fix: PDF: reduce file descriptor leak * Fix: With Pillow >= 3.x, calls to Image.rotate() must specify expand=True * Fix: At startup, when updating the index, prevent infinite loop 2015/04/21 - 0.2.4: * Fix python-whoosh 2.7 support 2015/04/03 - 0.2.3: * Whenever possible, page orientation detection is now done using OCR tool feature (Tesseract >= 3.3.0). It's much faster and reliable. * Fix doc indexation: last and first words of each lines weren't split correctly 2015/01/11 - 0.2.2: * PDF + OCR: text wasn't indexed correctly * Img doc: indexed text contains extra and useless data. As a side-effect, label prediction accuracy was strongly reduced. Rebuilding your index is strongly recommended ("rm -rf ~/.local/share/paperwork" + restarting Paperwork) 2014/12/19 - 0.2.1: * Settings window : add help links * Install process : - Extra dependencies are now detected by another script than setup.py - More missing dependencies are detected (aspell, tesseract, language packs, etc) * Bug fixes : - Button 'open parent directory' doesn't remain stuck anymore when using the file manager Thunar - Settings window : Fix the way the file chooser is used (avoid selecting the wrong work directory by mistake) - Scanners support : Make it possible to use scanners even if some basic options are missing (source, resolution, etc) - When starting, don't remove empty directories anymore - Searching : Make sure diacritics characters are not a problem anymore - Import : accept file path containing spaces 2014/09/21 - 0.2: * Improved search : whoosh.FuzzyTerm is now used * Label look has been improved * Menubar has been removed and replaced by an application menu * Label prediction : when a new document is scanned, predicted labels are automatically set on it * Pages are not displayed separately anymore * New settings: scan source, number of orientations to try, OCR can be disabled * Scans are displayed in real time 2014/07/08 - 0.1.3: - Fix scanner support : don't try to set scanner options that are not active 2013/12/29 - 0.1.2: - Improve scanner support: option names and values cases are not always the same on all the scanners - Multiscan: fix multiscan end - Translations: add german translations - Settings window: display correctly Tesseract languages like 'deu-frak' 2013/10/03 - 0.1.1: - Page list: fix display of page list longer than 100 pages - Scanner support: - Fix support of scanners returning the supported resolutions as a range instead of an array - Fix: Always make sure the scan area is as big as it can be - Fix: When OCR is disabled, fix scan and page editing - Fix "no scanner found" popup (partial backport only, still slightly buggy) - Scripts: - Add script scripts/obfuscate.py - Fix/Improve the output of scripts/stats.py 2013/08/08 - 0.1: - Initial release paperwork-2.2.2/paperwork-gtk/MANIFEST.in000066400000000000000000000002421456262201400200620ustar00rootroot00000000000000recursive-include src *.py *.glade *.xml *.css *.svg *.png *.pdf *.mo recursive-include tests * include *.markdown include example-paperwork.conf include COPYING paperwork-2.2.2/paperwork-gtk/Makefile000066400000000000000000000076571456262201400200050ustar00rootroot00000000000000VERSION_FILE = src/paperwork_gtk/_version.py PYTHON ?= python3 build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: l10n_compile ${PYTHON} ./setup.py build build_c: ${VERSION_FILE}: echo "# -*- coding: utf-8 -*-" >| $@ echo -n "version = \"" >> $@ echo -n $(shell git describe --always) >> $@ $(eval branch_name = $(shell git symbolic-ref HEAD 2>/dev/null)) if [ -n "${branch_name}" ] && [ "${branch_name}" != "refs/heads/master" ] ; then echo -n "-${branch_name}" >> $@ ; fi echo "\"" >> $@ doc: upload_doc: data: $(MAKE) -C src/paperwork_gtk/icon data $(MAKE) -C src/paperwork_gtk/model/help data check: if ! hash flake8 ; then PIP_DEPS=[lint] $(MAKE) install_py ; fi flake8 --append-config $(CURDIR)/.flake8 $(CURDIR)/src/paperwork_gtk test: if ! hash pytest ; then PIP_DEPS=[dev] $(MAKE) install_py ; fi python3 -m pytest -xv tests/ windows_exe: install ${PYTHON} ./setup_cxfreeze.py build_exe mkdir -p $(CURDIR)/../build/exe mv $$(find $(CURDIR)/build -type d -name exe\*)/* $(CURDIR)/../build/exe # ugly, but "import pkg_resources" doesn't work in frozen environments # and I don't want to have to patch the build machine to fix it every # time. mkdir -p $(CURDIR)/../build/exe/data # We need the .ico at the root of the data/ folder # The installer makes a desktop icon that expect paperwork_64.ico there, # and since we use the same installer for all versions (master, testing, # unstable, etc), we can't change this path yet. cp $(CURDIR)/src/paperwork_gtk/data/*.ico $(CURDIR)/../build/exe/data (cd $(CURDIR)/src && find . -name '*.css' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.glade' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.mo' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.pdf' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.png' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) (cd $(CURDIR)/src && find . -name '*.ico' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) linux_exe: appimage-builder --skip-tests --recipe AppImageBuilder.yml release: ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" exit 1 else @echo "Will release: ${RELEASE}" @echo "Checking release is in ChangeLog ..." grep ${RELEASE} ChangeLog | grep -v "/xx" @echo "Checking release is in work.openpaper.Paperwork.appdata.xml ..." grep ${RELEASE} src/paperwork_gtk/data/work.openpaper.Paperwork.appdata.xml endif release_pypi: @echo "Releasing paperwork-gtk ..." rm -rf /tmp/venv virtualenv /tmp/venv . /tmp/venv/bin/activate && pip install build . /tmp/venv/bin/activate && ${PYTHON} -m build -s rm -rf /tmp/venv twine upload $(CURDIR)/dist/*.tar.gz @echo "All done" clean: rm -rf build dist src/*.egg-info rm -rf AppDir appimage-build rm -f *.AppImage rm -f src/paperwork_gtk/_version.py $(MAKE) -C src/paperwork_gtk/model/help clean $(MAKE) -C src/paperwork_gtk/icon clean # PIP_ARGS is used by Flatpak build install_py: ${VERSION_FILE} l10n_compile ${PYTHON} -m pip install ${PIP_ARGS} .${PIP_DEPS} install_c: uninstall_py: pip3 uninstall -y paperwork uninstall_c: l10n_extract: $(CURDIR)/../tools/l10n_extract.sh "$(CURDIR)/src" "$(CURDIR)/l10n" $(MAKE) -C src/paperwork_gtk/model/help l10n_extract l10n_compile: $(CURDIR)/../tools/l10n_compile.sh \ "$(CURDIR)/l10n" \ "$(CURDIR)/src/paperwork_gtk/l10n" \ "paperwork_gtk" help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release || make release_pypi" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ l10n_extract \ release \ release_pypi \ test \ uninstall \ uninstall_c paperwork-2.2.2/paperwork-gtk/README.markdown000066400000000000000000000000731456262201400210270ustar00rootroot00000000000000## Paperwork-gtk All the code dependant on GTK goes here. paperwork-2.2.2/paperwork-gtk/l10n/000077500000000000000000000000001456262201400171005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/l10n/ca.po000066400000000000000000000607771456262201400200440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-30 11:53+0100\n" "PO-Revision-Date: 2022-04-03 06:08+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "Instal·la les icones i dreceres de Paperwork" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "Instal·la-ho tot només pel compte d'usuària actual" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" "Executa el Paperwork i importa els fitxers ja introduïts com a arguments " "d'un nou document" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "URLs o adreces de fitxers a importar" #: paperwork-gtk/src/paperwork_gtk/main.py:201 msgid "command" msgstr "comanda" #: paperwork-gtk/src/paperwork_gtk/docimport.py:86 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "No sé com importar '%s'. Ho sento." #: paperwork-gtk/src/paperwork_gtk/docimport.py:105 msgid "PDF password" msgstr "Contrasenya del PDF" #: paperwork-gtk/src/paperwork_gtk/docimport.py:123 msgid "No new document to import found" msgstr "No s'ha trobat cap document per importar" #: paperwork-gtk/src/paperwork_gtk/docimport.py:163 msgid "Imported file(s) deleted" msgstr "S'han eliminat els arxius importats" #: paperwork-gtk/src/paperwork_gtk/docimport.py:170 msgid "Imported:\n" msgstr "Importat:\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:176 msgid "Import successful" msgstr "La importació ha estat un èxit" #: paperwork-gtk/src/paperwork_gtk/docimport.py:185 msgid "Delete imported files" msgstr "Elimina els fitxers importats" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "Carregant {doc_id} p{page_idx} per imprimir" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "Imprimint %s" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "Imprimint {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 msgid "Page" msgstr "Pàgina" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgid "Copy selected text to clipboard" msgstr "Copia el text seleccionat al porta-retalls" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "Edita" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "Global" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "Busca" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "Document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "Edita les propietats del document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "Llista de documents" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "Obre el document següent" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "Obre el document anterior" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "Imprimeix" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "Crea un nou document" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "Imprimeix la pàgina" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "Reinicia la pàgina" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "Elimina la pàgina" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "Una altra posició" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 msgid "Move page to" msgstr "Mou la pàgina a" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "Un altre document" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "Copia el text seleccionat" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "Exporta la pàgina" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "Torna a passar l'OCR a la pàgina" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "Canvia les etiquetes" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "Elimina" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "Selecciona-ho tot" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "Exporta" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "Torna a passar l'OCR" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "Configuració" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "Ajuda" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "Dreceres del teclat" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "Envia un informe d'errors" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "Sobre" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "Propietats del document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "Imprimeix el document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "Elimina el document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "Afegeix a la selecció" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "Exporta el document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "Obre la carpeta" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "Torna a passar-hi l'OCR" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "Segur que voleu eliminar la pàgina {page_idx} del document {doc_id}?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "Mou la pàgina %d, però... A quina posició?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "La posició de la pàgina no és vàlida: %s" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "" "La posició de la pàgina no és vàlida: %d. Queda fora del document (1-%d)." #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "No s'ha pogut canviar la posició de la pàgina" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "Passant l'OCR pel document {doc_id} p{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "Segur que voleu eliminar %d documents?" #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #, python-format msgid "OCR on %s" msgstr "Passa l'ORC a %s" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "Segur que voleu eliminar el document %s?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "Mida del fitxer estimada: %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "Seleccioneu un fitxer o carpeta per importar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "Qualsevol fitxer" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "L'exportació ha fallat" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "Paraules clau" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "Sense etiquetes" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "Etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "Des de:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "Fins a:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "Data" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "i" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "o" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "no" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "Eliminar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "Escanejant des de %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import image or PDF file(s)" msgstr "Importa una imatge o fitxer(s) PDF" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "Importa els fitxers" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "Tots els formats acceptats" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 msgid "New document" msgstr "Nou Document" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "Buit" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:83 msgid "Loading text ..." msgstr "Carregant el text..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "Carregant la pàgina {}/{} ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "%d documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "Carregant les miniatures dels documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "Reanomena l'etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "Segur que voleu esborrar l'etiqueta «%s» de TOTS els documents?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "Transformant l'etiqueta {old_label} en {new_label} al document {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "Eliminant l'etiqueta {old_label} del document {doc_id}" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "Actualitzacions" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:84 msgid "Storage" msgstr "Enmagatzematge" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:90 msgid "Work Directory" msgstr "Carpeta de treball" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "OCR - Reconeixement Ã’ptic de Caràcters" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "OCR desactivat" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "Carregant..." #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "Cap escàner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "{} dpi" msgstr "{} dpi" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} dpi (recomanat)" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "Color" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "Escala de Grisos" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "Blanc i negre" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "No s'ha seleccionat cap escàner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "No s'ha establert la resolució" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "No s'ha seleccionat cap mode" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "Escàner" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "Ajudeu a millorar el Paperwork" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "Ara amb un 10% més de llibertat!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "Compreu-lo ara amb un 100% de descompte!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "Noves millores i errors disponibles!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "Nou gust!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "Hem canviat els teus errors antics per uns de nous. Gaudeix-los." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "Més intel·ligent, més fort, millor" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "És millor quan és lliure." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "Hi ha una nova versió del Paperwork disponible: {new_version}" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "Introducció" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "Manual" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "Documentació" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2021" msgstr "© 2021" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "Ordenar paperassa hauria de ser una feina per a les màquines." #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "Seleccioneu el document de destinació" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "Paràmetres de l'exportació" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "Qualitat" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "Format del paper" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "Opcions d'exportació" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "Envia per correu electrònic" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "Dona-hi una ullada" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "Busca" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "Voleu dir ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "Cerca avançada" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "Afegeix pàgina" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "Subratlla les paraules" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "Documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "Selecciona" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "Més paraules clau" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "Propietats" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "Canvia el color de les etiquetes" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "Elimina l'etiqueta de tots els documents" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "Actualitzacions\n" "Cerca periòdicament si hi ha noves versions del " "Paperwork disponibles" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "Comprova més o menys cada setmana si hi ha noves " "versions del Paperwork.\n" "Us notificarem si hi ha una nova versió disponible, però no s'instal·lara " "automàticament.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "Envia mètriques d'ús\n" "Doneu-nos pistes sobre com feu servir el " "Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on
openpaper.work.\n" "" msgstr "" "Aquestes pistes ens ajuden a millorar encara més " "el Paperwork i adaptar-lo a les vostres necessitats. Les estadístiques ens " "mostren que la gent fa servir la nostra eina i ens motiven a millorar-la.\n" "\n" "Aquí el que recollim:\n" "- Maquinari: CPU, RAM, resolució de pantalla.\n" "- Programari: Versió del Paperwork, sistema operatiu, entorn d'escriptori, " "idioma del sistema.\n" "- Mètriques de dades: nombre de documents, màxim i mitjana del nombre de " "pàgines, nombre d'etiquetes.\n" "- Vegades que has utilitzat cada funció del programa.\n" "\n" "No recollim el contingut dels documents ni cap altra informació personal " "sensible, però ens sembla just demanar-vos permís ;-)\n" "\n" "Les mètriques recollides poden ser consultades a openpaper.work.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "Idiomes" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" "Feu servir el Paperwork des d'un contenidor Flatpak. El Paperwork necessita " "Saned per accedir al vostre escàner.\n" "\n" "Important: això funcionarà només per escàners locals (però no per escàners " "de xarxa)!\n" "\n" "Per activar Saned al vostre sistema, heu de copiar i enganxar aquestes " "comandes al terminal:" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "Maximitza" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "automàtic" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "Escaneja" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "Calibratge de l'escàner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "Dispositiu" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "Resolució" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "Mode" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "Calibra" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "Re-calibra" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "Carpeta de treball" paperwork-2.2.2/paperwork-gtk/l10n/de.po000066400000000000000000000655731456262201400200500ustar00rootroot00000000000000# German translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-07-31 15:26+0000\n" "Last-Translator: Jannik Wilhelm \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.18.2\n" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "Jetzt mit 10% mehr Freiheit darin!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "Kaufe jetzt und bekomme 100% Rabatt!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "Neue Funktionen und Fehler verfügbar!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "Neuer Geschmack!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "Wir haben Deine alten Fehler durch neue Fehler ersetzt. Geniesse es." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "Smarter, Besser, Stärker" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "Es ist besser, wenn es frei ist." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "Eine neue version von Paperwork ist verfügbar: {new_version}" #: paperwork-gtk/src/paperwork_gtk/main.py:203 msgid "command" msgstr "Kommando" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "Label umbenennen" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "" "Sind Sie sicher, dass Sie das Label %s von allen Dokumenten löschen möchten?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "Ändere im Dokument {doc_id} das Label {old_label} nach {new_label}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "Lösche das Label {old_label} aus dem Dokumen {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "Geschätzte Dateigröße: %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "Wähle eine Datei oder ein Verzeichnis zum Import" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "Alle Dateien" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "Export fehlgeschlagen" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 msgid "New document" msgstr "Neues Dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "%d Dokumente" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "Lade Vorschaubilder" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import document or image file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "Importiere Datei(en)" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "Alle unterstützten Dateiformate" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "Scanne von %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "Leeres Dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "Lade Seite {}/{} ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:88 msgid "Loading text ..." msgstr "Lade Text ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "Suchbegriff(e)" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "Keine Labels" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "Label" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "Von:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "bis:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "Datum" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "und" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "oder" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "nicht" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "Entfernen" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgctxt "keyboard shortcut categories" msgid "Page" msgstr "Seite" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:31 msgctxt "keyboard shortcut names" msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:32 msgctxt "keyboard shortcut names" msgid "Copy selected text to clipboard" msgstr "Ausgewählten Text in Zwischenablage kopieren" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "Global" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "Suchen" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "Dokument" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "Dokumenteneigenschaften bearbeiten" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "Neues Dokument" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "Drucken" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "Dokumentenliste" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "Öffne nächstes Dokument" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "Öffne vorheriges Dokument" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "in ein anderes Dokument" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 msgid "Move page to" msgstr "Verschiebe Seite" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "Seite zurücksetzen" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "Kopiere ausgewählten Text" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "Seite exportieren" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "Seite drucken" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "Seite löschen" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "an andere Position" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "Wiederhole OCR auf Seite" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "Hilfe" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "Über" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "Tastenkürzel" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "Fehler melden" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "Einstellungen" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "Dokumenteneigenschaften" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "Zur Auswahl hinzufügen" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "Ordner öffnen" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "Dokument exportieren" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "Dokument drucken" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "Dokument löschen" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "Wiederhole OCR auf Dokument" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "Labels ändern" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "Alles auswählen" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "Exportieren" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "Löschen" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "Wiederhole OCR" #: paperwork-gtk/src/paperwork_gtk/docimport.py:87 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "" "Es tut mir leid, ich weiß nicht wie ich die Datei '%s' importieren soll." #: paperwork-gtk/src/paperwork_gtk/docimport.py:106 msgid "PDF password" msgstr "PDF Passwort" #: paperwork-gtk/src/paperwork_gtk/docimport.py:124 msgid "No new document to import found" msgstr "Keine neuen Dokumente zum importieren gefunden" #: paperwork-gtk/src/paperwork_gtk/docimport.py:167 msgctxt "import dialog" msgid "Imported file deleted" msgid_plural "Imported files deleted" msgstr[0] "Importierte Datei wurde gelöscht" msgstr[1] "Importierte Dateien wurden gelöscht" #: paperwork-gtk/src/paperwork_gtk/docimport.py:177 msgid "Imported:\n" msgstr "Importiert:\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:183 msgid "Import successful" msgstr "Import erfolgreich" #: paperwork-gtk/src/paperwork_gtk/docimport.py:192 msgid "Delete imported files" msgstr "Lösche importierte Dateien" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "Einleitung" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "Benutzerhandbuch" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "Anleitung" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "Updates" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "Texterkennung" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "OCR deaktiviert" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:101 msgid "Storage" msgstr "Verzeichnisse" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:108 msgid "Work Directory" msgstr "Arbeitsverzeichnis" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "Farbe" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "Graustufen" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "Schwarz-Weiss" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "Kein Scanner ausgewählt" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "Keine Auflösung ausgewählt" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "{} dpi" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "Kein Modus ausgewählt" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "Scanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} dpi (empfohlen)" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "Lade ..." #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "Kein Scanner" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "Hilf, Paperwork zu verbessern" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "" "Sind Sie sicher, dass Sie die Seite {page_idx} des Dokuments {doc_id} " "löschen möchten?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "An welche Position soll die Seite %d verschoben werden?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "Ungültige Seitenposition: %s" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "Ungültige Seitenposition: %d. Ausserhalb des Dokuments (1-%d)." #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "Seitenposition unverändert" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "OCR auf {doc_id}p{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "Sind Sie sicher, dass Sie das Dokument %s löschen möchten?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #, python-format msgid "OCR on %s" msgstr "OCR auf %s" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "Sind Sie sicher, dass Sie %d Dokumente löschen möchten?" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" "Führe Paperwork aus und importiere die als Argument übergebenen Dateien in " "ein neues Dokument" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "URLs oder Pfade zu Dateien für den Import" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "Installiere Paperwork Icons und Shortcuts" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "Installiere alles nur für den aktuellen Benutzer" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "Lade {doc_id} p{page_idx} zum Drucken" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "Drucke %s" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "Drucke {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "Zusätzliche Schlüsselwörter" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "Eigenschaften" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "Ändere die Farbe des Labels" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "Lösche das Label für alle Dokumente" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "Export Schritte" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "Qualität" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "Seitenformat" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "Exporteinstellungen" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "Per Email senden" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "Vorschau" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "Dokumente" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "Auswahl" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "Seite hinzufügen" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "Bearbeiten" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "Wörter hervorheben" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "Suche" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "Meinten Sie ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "Erweiterte Suche" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "Updates\n" "Überprüfe regelmäßig auf neue Versionen von " "Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "Überprüfe ungefähr einmal pro Woche auf eine neue " "Version von Paperwork.\n" "Sie werden benachrichtigt wenn eine neue Version verfügbar ist, aber sie " "wird nicht automatisch installiert.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "Sprachen" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "Nutzerstatistiken senden\n" "Geben Sie uns einen Einblick, wie Sie Paperwork " "verwenden" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" "Dieser Einblick wird uns helfen, Paperwork noch " "besser für Sie zu machen. Die Statistiken zeigen auch, dass die Leute unsere " "Arbeit wirklich benutzen, was uns motviert sie weiter zu verbessern.\n" "\n" "Folgende Daten werden erfasst:\n" "- Hardware: CPU, RAM, Bildschirmauflösung.\n" "- Software: Version von Paperwork, Betriebssystem, Desktop-Umgebung, " "Systemsprache.\n" "- Datenmetriken: Anzahl an Dokumenten, maximale und durchschnittliche " "Seitenzahl, Anzahl von Labels.\n" "- Nutzungshäufigkeit für jedes Feature.\n" "\n" "Wir erfassen keinen Dokumenteninhalt oder sonstige vertrauliche oder " "persönlichen Informationen. Wir denken trotzdem, dass es fair ist, Ihre " "Zustimmung zu erfragen ;-).\n" "\n" "Die erfassten Statistiken sind auf openpaper.work sichtbar.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "Arbeitsverzeichnis" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:2 msgid "" "Do not use an already existing directory !\n" "(unless it comes from another Paperwork instance)\n" "\n" "Paperwork uses a custom file structure to store documents. Unless the " "directory you specify has the exact file structure expected by Paperwork, it " "won't work !\n" "\n" "If you want to build a new work directory from existing documents, please " "use the import feature instead.\n" "\n" "[More information]" msgstr "" "Verwenden Sie kein bereits vorhandenes Verzeichnis!\n" "(es sei denn, es stammt von einer anderen Paperwork-Instanz)\n" "\n" "Paperwork verwendet eine eigene Dateistruktur zum Speichern von Dokumenten. " "Wenn das Verzeichnis, das Sie angeben, nicht genau die von Paperwork " "erwartete Dateistruktur hat, wird es nicht funktionieren!\n" "\n" "Wenn Sie ein neues Arbeitsverzeichnis aus vorhandenen Dokumenten erstellen " "möchten, verwenden Sie bitte stattdessen die Importfunktion.\n" "\n" "[Weitere Informationen]" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "Maximieren" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "Automatisch" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "Scanne" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "Scanner Kalibrierung" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "Gerät" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "Auflösung" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "Modus" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "Kalibrierung" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "Rekalibrieren" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" "Sie verwenden Paperwork aus einem Flatpak-Container. Paperwork benötigt " "Saned, um auf Ihre Scanner zuzugreifen.\n" "\n" "Wichtig: Das folgende Verfahren funktioniert nur für lokale (Nicht-" "Netzwerk-)Scanner!\n" "\n" "Um Saned auf dem Hostsystem zu aktivieren, müssen Sie die folgenden Befehle " "kopieren und in ein Terminal einfügen:" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "Wähle Zieldokument" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2023" msgstr "©2023" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "Dokumente zu sortieren ist die Arbeit einer Maschine." #~ msgid "Imported file(s) deleted" #~ msgstr "Importierte Datei(en) gelöscht" #~ msgid "Page" #~ msgstr "Seite" #~ msgid "Copy selected text to clipboard" #~ msgstr "Markierten Text in die Zwischenablage kopieren" #~ msgid "Import image or PDF file(s)" #~ msgstr "Importiere Bild- oder PDF-Datei(en)" #~ msgid "©2021" #~ msgstr "©2021" #~ msgid "" #~ "You are using Paperwork from a Flatpak container. Paperwork needs Saned " #~ "to access your scanners. To enable Saned on the host system, you must " #~ "copy and paste the following commands in a terminal:" #~ msgstr "" #~ "Sie benutzen Paperwork in einem Flatpak Container. Paperwork benötigt " #~ "Saned, um auf Ihre Scanner zuzugreifen. Um Saned auf dem System zu " #~ "aktivieren, kopieren Sie die folgenden Kommandos in eine " #~ "Eingabeaufforderung und führen Sie sie aus:" #, python-format #~ msgid "Are you sure you want to remove label '%s' from ALL documents ?" #~ msgstr "" #~ "Sind Sie sicher, dass Sie das Label '%s' von allen Dokumenten löschen " #~ "möchten?" #~ msgid "©2020" #~ msgstr "©2020" paperwork-2.2.2/paperwork-gtk/l10n/es.po000066400000000000000000000641751456262201400200640ustar00rootroot00000000000000# Spanish translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-02-24 02:42+0000\n" "Last-Translator: andres felipe santamaria \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.2\n" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "¡Ahora con un 10% más de libertad!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "¡Cómpralo ahora y obtén un descuento del 100% !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "¡Nuevas funciones y correcciones a errores disponibles!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "¡Nuevo sabor!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "Hemos sustituido tus viejos bugs con nuevos. Disfrutalo." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "Más inteligente, mejor, más fuerte" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "Es mejor cuando es libre y aun mejor gratis." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "Hay una nueva version disponible: {new_version}" #: paperwork-gtk/src/paperwork_gtk/main.py:203 msgid "command" msgstr "comando" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "Cambiar el nombre de la etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "" "¿Seguro que quieres eliminar la etiqueta \"%s\" de TODOS los documentos?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "Cambio de etiqueta {old_label} a {new_label} en el documento {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "Eliminando etiqueta {old_label} del documento {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "Tamaño estimado del archivo: %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "Seleccione un archivo o una carpeta para importar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "Cualquier archivo" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "La exportación ha fallado" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 msgid "New document" msgstr "Nuevo documento" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "%d documentos" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "Carga de miniaturas de documentos" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import document or image file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "Importar archivo(s)" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "Todos los formatos soportados" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "Escaneando de %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "Vacio" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "Cargando pagina {}/{} ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:88 msgid "Loading text ..." msgstr "CArgando texto ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "Palabra(s) clave" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "Sin etiquetas" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "Etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "De:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "a:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "Fecha" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "y" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "o" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "no" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "Eliminar" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgctxt "keyboard shortcut categories" msgid "Page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:31 msgctxt "keyboard shortcut names" msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:32 msgctxt "keyboard shortcut names" msgid "Copy selected text to clipboard" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "Global" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "Buscar" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "Documento" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "Editar las propiedades del documento" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "Crear nuvo documento" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "Impresión" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "Lista de documentos" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "Abre el siguiente documento" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "Abrir el documento anterior" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "Otro documento" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 msgid "Move page to" msgstr "Mueva la página a" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "Reiniciar la página" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "Copiar texto seleccionado" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "Exportar pagina" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "Imprimir página" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "eliminar pagina" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "Otra posición" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "Rehacer OCR en la página" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "Ayuda" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "Acerca" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "Atajos" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "Reportar una falla" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "Configuración" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "Propiedades del documento" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "Agregar a la selección" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "Abrir carpeta" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "Exportar documento" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "imprimir documento" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "eliminar documento" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "Rehacer el OCR en el documento" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "Cambiar la etiqueta" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "Seleccionar todo" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "Exportar" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "Eliminar" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "Vuele a pasar el ORC" #: paperwork-gtk/src/paperwork_gtk/docimport.py:87 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "No sé cómo importar \"%s\". Los siento." #: paperwork-gtk/src/paperwork_gtk/docimport.py:106 msgid "PDF password" msgstr "Contraseña del PDF" #: paperwork-gtk/src/paperwork_gtk/docimport.py:124 msgid "No new document to import found" msgstr "No se encontró ningún documento nuevo para importar" #: paperwork-gtk/src/paperwork_gtk/docimport.py:167 msgctxt "import dialog" msgid "Imported file deleted" msgid_plural "Imported files deleted" msgstr[0] "" msgstr[1] "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:177 msgid "Imported:\n" msgstr "Importado:\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:183 msgid "Import successful" msgstr "Importación exitosa" #: paperwork-gtk/src/paperwork_gtk/docimport.py:192 msgid "Delete imported files" msgstr "Eliminando archivos importados" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "Introducción" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "Manual de usuario" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "Documentación" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "Actualizaciones" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "OCR - Reconocimiento óptico de caracteres" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "OCR desabilitado" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:101 msgid "Storage" msgstr "Almacenamiento" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:108 msgid "Work Directory" msgstr "Directorio de Trabajo" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "Color" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "Escala de Grises" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "Blanco y Negro" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "No ha seleccionado scanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "No ha seleccionado una resolucion" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "{} dpi" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "No ha seleccionado modo" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "Escáner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} dpi (recomendado)" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "Cargando ..." #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "No Scanner" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "Ayud a a mejorar Paperwork" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "" "¿Está seguro de que desea eliminar la página {page_idx} del documento " "{doc_id}?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "Mueve la página %d: ¿A qué posición?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "La posición de la página no es válida: %s" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "" "La posición de la página no es válida: %d. Queda fuera del documento (1-%d)." #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "No se ha cambiado la posición de la página" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "OCR en {doc_id} p{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "¿Está seguro de que quiere eliminar documentos %s?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #, python-format msgid "OCR on %s" msgstr "OCR en %s" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "¿Está seguro de que quiere eliminar %d documentos?" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" "Ejecuta Paperwork e importa los archivos introducidos como un nuevo documento" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "URLs o caminos a importar" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "Instalar iconos y accesos directos de Paperwork" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "Instalar todo para el usuario actual" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "Cargando {doc_id} p{page_idx} para imprimir" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "Inmprimiendo %s" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "Imprimiendo {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "Palabras clave adicionales" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "Propiedades" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "Cambiar el color de la etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "Eliminar la etiqueta de todos los documentos" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "Pasos de exportación" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "Calidad" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "Formato de papel" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "Exportart configuración" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "Envía por correo electrónico" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "Previsualizar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "Documentos" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "Selección" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "Agregar pagina" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "Edicion" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "Resaltar palabras" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "Buscar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "¿Quieres decir que...?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "Busqueda avanzada" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "Actualizaciones\n" "Comprueba periódicamente si hay nuevas versiones " "de Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "Busque aproximadamente una vez a la semana nuevas " "versiones de Paperwork.\n" "Se le notificará cuando haya una nueva versión disponible, pero no se " "isntala automaticamente.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "Lenguajes" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "Enviar metricas\n" "Danos pistas sobre cómo utilizas Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" "Esas pistas nos ayudarán a hacer de Paperwork una " "mejor pieza de software, para usted. Las estadísticas también nos muestran " "que la gente está tilizando realmente nuestro trabajo, lo que nos mantiene " "motivados para mejorarlo.\n" "\n" "Estos son los datos que recogemos:\n" "- Hardware: CPU, RAM, resolución de pantalla.\n" "- Software: Version de Paperwork, Sistema operativo, entorno de escritorio, " "leguaje del sistema.\n" "- Métricas de datos: número de documentos, número máximo y medio de páginas, " "numero de etiquetas.\n" "- Número de veces que ha utilizado cada función.\n" "\n" "No recogemos el contenido de los documentos ni ningún otro dato sensible o " "información personal. Aun así, creemos que es justo solicitar su " "autorización ;-).\n" "\n" "Las estadísticas recogidas son visibles en openpaper.work.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "Directorio de trabajo" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:2 msgid "" "Do not use an already existing directory !\n" "(unless it comes from another Paperwork instance)\n" "\n" "Paperwork uses a custom file structure to store documents. Unless the " "directory you specify has the exact file structure expected by Paperwork, it " "won't work !\n" "\n" "If you want to build a new work directory from existing documents, please " "use the import feature instead.\n" "\n" "[More information]" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "Maximizar" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "Automatico" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "Escanea" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "Calibrar scanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "Dispositivo" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "REsolución" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "Modo" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "Calibrar" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "Re-calibarar" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" "Utilizas Paperwork desde un contenedor Flatpak. Paperwork necesita Saned " "para poder acceder a tus escáneres.\n" "\n" "Importante: ¡Esto funcionará sólo para escáneres locales (no escáneres de " "red)!\n" "\n" "Para activar Saned en el sistema anfitrión, debes copiar y pegar el " "siguiente comando a la terminal:" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "Elige un documento de destino" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2023" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "La clasificación de documentos es un trabajo de máquina." #~ msgid "Imported file(s) deleted" #~ msgstr "Archivo(s) importado(s) ha(n) sido eliminado(s)" #~ msgid "Page" #~ msgstr "Pagina" #~ msgid "Copy selected text to clipboard" #~ msgstr "Copia el texto seleccionado al portapapeles" #~ msgid "Import image or PDF file(s)" #~ msgstr "Importar imagen o archivos PDF" #~ msgid "©2021" #~ msgstr "©2021" #~ msgid "" #~ "You are using Paperwork from a Flatpak container. Paperwork needs Saned " #~ "to access your scanners. To enable Saned on the host system, you must " #~ "copy and paste the following commands in a terminal:" #~ msgstr "" #~ "Está utilizando Paperwork de un contenedor Flatpak. Paperwork necesita " #~ "Saned paraacceder a sus escáneres. Para habilitar Saned en el sistema " #~ "anfitrión, debe copiar y pegar los siguientes comandos en una terminal:" #~ msgid "©2020" #~ msgstr "©2021" paperwork-2.2.2/paperwork-gtk/l10n/fr.po000066400000000000000000000652341456262201400200610ustar00rootroot00000000000000# French translations for PACKAGE package # Traductions françaises du paquet PACKAGE. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-03-28 16:19+0000\n" "Last-Translator: Jérôme Flesch \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.16.4\n" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "Maintenant avec 10% de libertés en plus dedans !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "Achetez-le maintenant et recevez une réduction de 100% !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "Nouvelles fonctionnalités et nouveaux bugs disponibles !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "Nouveau goût !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "" "Nous avons remplacé vos anciens bugs par de nouveaux. Amusez-vous bien !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "Smarter, Better, Stronger" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "C'est meilleur quand c'est gratuit." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "Une nouvelle version de Paperwork est disponible : {new_version}" #: paperwork-gtk/src/paperwork_gtk/main.py:203 msgid "command" msgstr "commande" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "Renommer l'étiquette" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "" "Êtes-vous sûr de vouloir supprimer l'étiquette '%s' de tous les documents ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "" "Changement de l'étiquette {old_label} en {new_label} sur le document {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "Suppression de l'étiquette {old_label} du document {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "Taille estimée du fichier : %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "Sélectionnez un fichier ou un répertoire à importer" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "N'importe-quels fichiers" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "L'export a échoué" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 msgid "New document" msgstr "Nouveau document" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "%d documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "Chargement des miniatures des documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import document or image file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "Importer" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "Tous les formats de fichiers supportés" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "Scanner depuis %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "Vide" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "Chargement de la page {}/{}…" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:88 msgid "Loading text ..." msgstr "Chargement du texte…" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "Mot(s)-clé(s)" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "Pas d'étiquette" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "Étiquette" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "Du :" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "Au :" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "Date" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "et" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "ou" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "non" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "Retirer" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgctxt "keyboard shortcut categories" msgid "Page" msgstr "Page" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:31 msgctxt "keyboard shortcut names" msgid "Edit" msgstr "Édition" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:32 msgctxt "keyboard shortcut names" msgid "Copy selected text to clipboard" msgstr "Copier le texte sélectionné vers le presse-papier" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "Global" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "Trouver" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "Document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "Éditer les propriétés du document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "Créer un nouveau document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "Imprimer" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "Liste de documents" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "Ouvrir le document suivant" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "Ouvrir le document précédent" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "Un autre document" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 msgid "Move page to" msgstr "Déplacer la page vers" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "Réinitialiser la page" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "Copier le texte sélectionné" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "Exporter la page" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "Imprimer la page" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "Effacer la page" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "Une autre position" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "Refaire la ROC sur la page" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "Aide" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "À propos" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "Raccourcis" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "Signaler un bug" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "Réglages" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "Propriétés du document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "Ajouter à la sélection" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "Ouvrir le dossier" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "Exporter le document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "Imprimer le document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "Effacer le document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "Refaire la ROC sur le document" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "Changer les étiquettes" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "Tout sélectionner" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "Exporter" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "Effacer" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "Refaire la ROC" #: paperwork-gtk/src/paperwork_gtk/docimport.py:87 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "Ne sait pas comment importer '%s'. Désolé." #: paperwork-gtk/src/paperwork_gtk/docimport.py:106 msgid "PDF password" msgstr "Mot de passe du PDF" #: paperwork-gtk/src/paperwork_gtk/docimport.py:124 msgid "No new document to import found" msgstr "Pas de nouveau document à importer trouvé" #: paperwork-gtk/src/paperwork_gtk/docimport.py:167 msgctxt "import dialog" msgid "Imported file deleted" msgid_plural "Imported files deleted" msgstr[0] "Fichier importé effacé" msgstr[1] "Fichiers importés effacés" #: paperwork-gtk/src/paperwork_gtk/docimport.py:177 msgid "Imported:\n" msgstr "Importé(s) :\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:183 msgid "Import successful" msgstr "Import réussi" #: paperwork-gtk/src/paperwork_gtk/docimport.py:192 msgid "Delete imported files" msgstr "Effacer les fichiers importés" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "Introduction" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "Manuel utilisateur" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "Documentation" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "Mises à jour" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "Reconnaissance Optique de Caractères" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "ROC désactivée" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:101 msgid "Storage" msgstr "Stockage" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:108 msgid "Work Directory" msgstr "Répertoire de travail" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "Couleur" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "Niveaux de gris" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "Noir et blanc" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "Pas de scanner sélectionné" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "Pas de résolution sélectionnée" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "{} ppp" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "Pas de mode sélectionné" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "Scanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} ppp (recommandé)" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "Chargement…" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "Pas de scanner" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "Aidez à améliorer Paperwork" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "" "Êtes-vous sûr de vouloir effacer la page {page_idx} du document {doc_id} ?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "Déplacer la page %d vers quelle position ?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "Position de page invalide : %s" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "" "Position de page invalide : %d. En dehors des limites du document (1-%d)." #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "Position de la page inchangée" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "ROC sur {doc_id} p{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "Êtes-vous sûr de vouloir effacer le document %s ?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #, python-format msgid "OCR on %s" msgstr "ROC sur %s" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "Êtes-vous sûr de vouloir effacer %d documents ?" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" "Exécute Paperwork et importe les fichiers passés en arguments dans de " "nouveaux documents" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "URLs ou chemin des fichiers à importer" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "Installer les icônes et raccourcis de Paperwork" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "Tout installer seulement pour l'utilisateur courant" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "Chargement de {doc_id} p{page_idx} pour l'impression" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "Impression de %s" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "Impression de {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "Mots-clés additionnels" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "Propriétés" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "Changer la couleur de l'étiquette" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "Effacer l'étiquette de tout les documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "Étapes d'export" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "Qualité" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "Format de papier" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "Réglages d'export" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "Envoyer par email" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "Aperçu" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "Documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "Sélection" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "Ajouter une page" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "Éditer" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "Surligner les mots" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "Recherche" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "Vouliez-vous dire … ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "Recherche avancée" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "Mises à jour\n" "Vérifier périodiquement si il y a de nouvelles " "versions de Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "Cherche de nouvelles versions de Paperwork environ " "1 fois par semaine.\n" "Vous serez notifié quand une nouvelle version sera disponible, mais elle ne " "sera pas installée automatiquement.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "Langues" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "Envoyer des métriques\n" "Aidez-nous à comprendre comment vous utilisez " "Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" "Ces métriques nous aideront à faire de Paperwork " "un logiciel encore meilleur, pour vous. Ces statistiques nous montre aussi " "que des gens se servent effectivement de notre travail, ce qui nous garde " "motivé pour l'améliorer.\n" "\n" "Voici les données que nous collectons :\n" "- Matériel : Processeur, mémoire vive, résolution d'écran.\n" "- Logiciel : Version de Paperwork, système d'exploitation, environnement " "graphique, langue du système.\n" "- Métriques : nombre de documents, nombre maximum et moyen de pages, nombre " "d'étiquettes.\n" "- Nombre de fois que vous avez utilisé chaque fonctionnalité.\n" "\n" "Nous ne collectons pas le contenu des documents ni d'autre informations " "sensibles, mais nous considérons tout de même normal de vous demander " "avant ;-).\n" "\n" "Les statistiques collectées sont visibles sur openpaper.work.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "Répertoire de travail" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:2 msgid "" "Do not use an already existing directory !\n" "(unless it comes from another Paperwork instance)\n" "\n" "Paperwork uses a custom file structure to store documents. Unless the " "directory you specify has the exact file structure expected by Paperwork, it " "won't work !\n" "\n" "If you want to build a new work directory from existing documents, please " "use the import feature instead.\n" "\n" "[More information]" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "Maximiser" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "Automatique" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "Scanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "Calibration du scanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "Périphérique" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "Résolution" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "Mode" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "Calibration" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "Recalibrer" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" "Vous utilisez Paperwork depuis un conteneur Flatpak. Paperwork a besoin de " "Saned pour accéder à vos scanners.\n" "\n" "Important : la procédure qui suit ne fonctionnera que pour des scanners " "locaux (non-réseau) !\n" "\n" "Pour activer Saned sur le système hôte, vous devez copier et coller les " "commandes suivantes dans un terminal :" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "Sélectionnez le document cible" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2023" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "Trier des documents est un travail de machine." #~ msgid "Imported file(s) deleted" #~ msgstr "Fichier(s) importé(s) effacé(s)" #~ msgid "Page" #~ msgstr "Page" #~ msgid "Copy selected text to clipboard" #~ msgstr "Copier le texte sélectionner vers le presse-papiers" #~ msgid "Import image or PDF file(s)" #~ msgstr "Importer un ou plusieurs PDF(s) ou image(s)" #~ msgid "©2021" #~ msgstr "©2021" #~ msgid "" #~ "You are using Paperwork from a Flatpak container. Paperwork needs Saned " #~ "to access your scanners. To enable Saned on the host system, you must " #~ "copy and paste the following commands in a terminal:" #~ msgstr "" #~ "Vous utilisez Paperwork depuis un conteneur Flatpak. Paperwork a besoin " #~ "de Saned pour accéder à votre scanner. Pour activer Saned sur le système, " #~ "vous devez copier et coller les commandes suivantes dans un terminal :" #, python-format #~ msgid "Are you sure you want to remove label '%s' from ALL documents ?" #~ msgstr "" #~ "Êtes-vous sûre de vouloir retirer l'étiquette '%s' de TOUS vos documents ?" #~ msgid "©2020" #~ msgstr "©2020" paperwork-2.2.2/paperwork-gtk/l10n/messages.pot000066400000000000000000000503721456262201400214420ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/main.py:203 msgid "command" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 msgid "New document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import document or image file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:88 msgid "Loading text ..." msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgctxt "keyboard shortcut categories" msgid "Page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:31 msgctxt "keyboard shortcut names" msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:32 msgctxt "keyboard shortcut names" msgid "Copy selected text to clipboard" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 msgid "Move page to" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:87 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:106 msgid "PDF password" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:124 msgid "No new document to import found" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:167 msgctxt "import dialog" msgid "Imported file deleted" msgid_plural "Imported files deleted" msgstr[0] "" msgstr[1] "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:177 msgid "Imported:\n" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:183 msgid "Import successful" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:192 msgid "Delete imported files" msgstr "" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:101 msgid "Storage" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:108 msgid "Work Directory" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #, python-format msgid "OCR on %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:2 msgid "" "Do not use an already existing directory !\n" "(unless it comes from another Paperwork instance)\n" "\n" "Paperwork uses a custom file structure to store documents. Unless the " "directory you specify has the exact file structure expected by Paperwork, it " "won't work !\n" "\n" "If you want to build a new work directory from existing documents, please " "use the import feature instead.\n" "\n" "[More information]" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2023" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "" paperwork-2.2.2/paperwork-gtk/l10n/oc.po000066400000000000000000000634321456262201400200510ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2022-01-05 18:30+0000\n" "Last-Translator: Quentin PAGÈS \n" "Language-Team: Occitan \n" "Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "Ara amb 10% mai de libertats dedins !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "Crompatz-lo ara e recebètz una reduccion de 100% !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "Nòvas foncionalitats e nòus bugs disponibles !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "Nòu gost !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "Remplacèrem vòstres ancians bugs per de nòus. Divertissètz-vos ben !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "Smarter, Better, Stronger" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "Es melhor quand es gratuit." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "Una version novèla de Paperwork es disponibla : {new_version}" #: paperwork-gtk/src/paperwork_gtk/main.py:203 msgid "command" msgstr "comanda" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "Renomenar l'etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "" "Volètz vertadièrament suprimir l’etiqueta « %s » de totes los documents ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "" "Cambiament de l'etiqueta {old_label} en {new_label} sul document {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "Supression de l'etiqueta {old_label} del document {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "Talha estimada del fichièr : %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "Seleccionatz un fichièr o repertòri d'importar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "Quin que siá fichièr" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "L’export a pas reüssit" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 msgid "New document" msgstr "Document novèl" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "%d documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "Cargament de las miniaturas dels documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import document or image file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "Importar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "Totes los formats de fichièrs compatibles" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "Numerizar a partir de %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "Void" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "Cargament de la pagina {}/{}…" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:88 msgid "Loading text ..." msgstr "Cargament del tèxt…" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "Mot(s)-clau" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "Cap d’etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "Etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "A partir de :" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "Al :" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "Data" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "e" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "o" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "pas" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "Levar" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgctxt "keyboard shortcut categories" msgid "Page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:31 msgctxt "keyboard shortcut names" msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:32 msgctxt "keyboard shortcut names" msgid "Copy selected text to clipboard" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "General" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "Trobar" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "Document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "Modificar las proprietats del document" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "Crear un document novèl" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "Imprimir" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "Lista de documents" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "Dobrir lo document seguent" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "Dobrir lo document precedent" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "Un autre document" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 msgid "Move page to" msgstr "Desplaçar la pagina a" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "Reïnicializar la pagina" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "Copiar lo tèxt seleccionat" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "Exportar la pagina" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "Imprimir la pagina" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "Suprimir la pagina" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "Una autra posicion" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "Tornar far la ROC sus la pagina" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "Ajuda" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "A prepaus" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "Acorchis" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "Senhalar un bug" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "Paramètres" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "Proprietats del document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "Ajustar a la seleccion" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "Dobrir lo dossièr" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "Exportar lo document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "Imprimir lo document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "Suprimir lo document" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "Tornar far la ROC sul document" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "Cambiar las etiquetas" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "Seleccionar tot" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "Exportar" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "Suprimir" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "Refar la ROC" #: paperwork-gtk/src/paperwork_gtk/docimport.py:87 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "Sap pas cossí importar « %s ». Desconsolat." #: paperwork-gtk/src/paperwork_gtk/docimport.py:106 msgid "PDF password" msgstr "Senhal del PDF" #: paperwork-gtk/src/paperwork_gtk/docimport.py:124 msgid "No new document to import found" msgstr "Cap de document novèl d'importar pas trobat" #: paperwork-gtk/src/paperwork_gtk/docimport.py:167 msgctxt "import dialog" msgid "Imported file deleted" msgid_plural "Imported files deleted" msgstr[0] "" msgstr[1] "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:177 msgid "Imported:\n" msgstr "Importat(s) :\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:183 msgid "Import successful" msgstr "Importacion capitada" #: paperwork-gtk/src/paperwork_gtk/docimport.py:192 msgid "Delete imported files" msgstr "Suprimir los fichièrs importats" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "Introduccion" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "Mòde d'emplec" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "Documentacion" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "Mesas a jorn" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "Reconeissença Optica de Caractèrs" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "ROC desactivada" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:101 msgid "Storage" msgstr "Emmagazinatge" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:108 msgid "Work Directory" msgstr "Repertòri de trabalh" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "Color" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "Nivèls de gris" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "Blanc e negre" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "Cap de numerizador pas seleccionat" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "Cap de resolucion pas seleccionada" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "{} ppp" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "Cap de mòde pas seleccionat" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "Numerizador" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} ppp (recomandat)" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "Cargament..." #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "Cap de numerizador" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "Ajudatz a melhorar Paperwork" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "" "Volètz vertadièrament suprimir la pagina {page_idx} del document {doc_id} ?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "Ont desplaçar la pagina %d ?" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "Posicion de pagina invalida : %s" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "Posicion de pagina invalida : %d. Defòra limitas del document (1-%d)." #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "Posicion de la pagina pas cambiada" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "ROC sus {doc_id} p{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "Volètz vertadièrament suprimir lo document %s ?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #, python-format msgid "OCR on %s" msgstr "ROC sus %s" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "Volètz vertadièrament suprimir %d documents ?" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" "Executar Paperwork e importar los fichièrs donats en argument cap a un " "document novèl" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "URL o camin dels fichièrs d’importar" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "Installar las icònas e acorchis de Paperwork" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "Tot installar sonque per l'utilizaire actual" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "Cargament de {doc_id} p{page_idx} per impression" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "Impression de « %s »" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "Impression de {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "Mots-clau addicionals" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "Proprietats" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "Cambiar la color de l'etiqueta" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "Suprimir l'etiqueta de totes los documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "Etapas de l'export" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "Qualitat" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "Format pagina" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "Paramètres de l'export" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "Enviar per corrièl" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "Apercebut" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "Documents" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "Seleccion" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "Ajustar una pagina" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "Edicion" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "Suslinhar los mots" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "Recercar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "Voliatz dire… ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "Recèrca avançada" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "Mesas a jorn\n" "Verificatz de temps en temps se i a de mesas a " "jorn per Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "Cèrca las versions novèlas de Paperwork cada " "setmana.\n" "Seretz avisat quand una version novèla es disponibla, mas serà pas " "installada automaticament.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "Lengas" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "Enviar las estatisticas\n" "Ajudatz-nos a comprendre coma utilizatz Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" "Aquestas estatisticas nos ajudaràn a far que " "Paperwork sia un logicial encara melhor. Nos mostran tanben que monde " "utilizan vertadièrament de nòstre trabalh, nos garda motivat per lo " "melhorar.\n" "\n" "Vaquí las donadas que reculhissèm :\n" "- Material : processor, memòria viva, resolucion d’ecran.\n" "- Logicial : version de Paperwork, sistèma operatiu, environament grafic, " "lenga del sistèma.\n" "- Estatisticas : nombre de documents, nombre maximum e mejana de paginas, " "nombre d’etiquetas.\n" "- Nombre de còp qu’utilizatz cada foncionalitat.\n" "\n" "Collectam pas cap de contengut dels documents nimai informacions sensiblas, " "mas pensam qu’es normal ça que là de vos demandar abans ;-)\n" "\n" "Las estatisticas collectadas son visiblas sus openpaper.work.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "Repertòri de trabalh" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:2 msgid "" "Do not use an already existing directory !\n" "(unless it comes from another Paperwork instance)\n" "\n" "Paperwork uses a custom file structure to store documents. Unless the " "directory you specify has the exact file structure expected by Paperwork, it " "won't work !\n" "\n" "If you want to build a new work directory from existing documents, please " "use the import feature instead.\n" "\n" "[More information]" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "Maximizar" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "Automatic" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "Numerizar" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "Calibratge del numerizador" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "Periferic" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "Resolucion" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "Mòde" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "Calibratge" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "Recalibrar" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "Seleccionar lo document cibla" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2023" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "Triar los documents es un trabalh per las maquinas." #~ msgid "Imported file(s) deleted" #~ msgstr "Fichiè(s) importat(s) suprimit(s)" #~ msgid "Page" #~ msgstr "Pagina" #~ msgid "Copy selected text to clipboard" #~ msgstr "Copiar lo tèxte seleccionat dins lo quichapapièr" #~ msgid "Import image or PDF file(s)" #~ msgstr "Importar un o mantun PDF o imatges" #~ msgid "©2021" #~ msgstr "©2021" #~ msgid "" #~ "You are using Paperwork from a Flatpak container. Paperwork needs Saned " #~ "to access your scanners. To enable Saned on the host system, you must " #~ "copy and paste the following commands in a terminal:" #~ msgstr "" #~ "Utilizatz Paperwork d’un contenedor Flatpak estant. Paperwork requerís " #~ "Saned per accedir al numerizador. Per activar Saned sul sistèma, vos cal " #~ "copiar pegar las comandas seguentas dins un terminal :" #~ msgid "©2020" #~ msgstr "©2020" paperwork-2.2.2/paperwork-gtk/l10n/sv.po000066400000000000000000000524211456262201400200740ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-01-04 15:31+0000\n" "Last-Translator: Ã…ke Engelbrektson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:82 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "Vet inte hur man importerar \"%s\", tyvärr." #: paperwork-gtk/src/paperwork_gtk/docimport.py:99 msgid "No new document to import found" msgstr "Inga nya dokument för import hittades" #: paperwork-gtk/src/paperwork_gtk/docimport.py:139 msgid "Imported file(s) deleted" msgstr "Importerad(e) fil(er) borttagna" #: paperwork-gtk/src/paperwork_gtk/docimport.py:146 msgid "Imported:\n" msgstr "Importerat:\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:152 msgid "Import successful" msgstr "Import slutförd" #: paperwork-gtk/src/paperwork_gtk/docimport.py:161 msgid "Delete imported files" msgstr "Ta bort importerade filer" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "Läser in {doc_id} s.{page_idx} för utskrift" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "Skriver ut %s" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "Skriver ut {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:9 msgid "Now with 10% more freedom in it !" msgstr "Nu med 10% mer frihet i det!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:10 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "Köp den nu och fÃ¥ 100% rabatt!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:11 msgid "New features and bugs available !" msgstr "Nya funktioner och fel tillgängliga!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:12 msgid "It's better when it's free." msgstr "Det är bättre när det är fritt." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:13 msgid "New taste !" msgstr "Ny smak!" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:14 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "Vi ersatte dina gamla fel med nya fel. HÃ¥ll tillgodo." #: paperwork-gtk/src/paperwork_gtk/update_notification.py:15 msgid "Smarter, Better, Stronger" msgstr "Smartare, Bättre, Starkare" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "En ny version av Paperwork finns tillgänglig: {new_version}" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "Uppdateringar" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:84 msgid "Storage" msgstr "Lagring" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:90 msgid "Work Directory" msgstr "Arbetsmapp" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "Optisk teckenidentifiering" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "OCR inaktiverat" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "Färg" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "GrÃ¥skala" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "Svartvit" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:27 msgid "No scanner selected" msgstr "Ingen skanner vald" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:31 msgid "No resolution selected" msgstr "Ingen upplösning vald" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:31 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "{} dpi" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:35 msgid "No mode selected" msgstr "Inget läge valt" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:104 msgid "Scanner" msgstr "Skanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "Ingen skanner" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:154 msgid "Loading ..." msgstr "Läser in..." #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} dpi (rekommenderas)" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "Hjälp till att förbättra Paperwork" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "Installera Paperworks ikoner och genvägar" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "Installera endast för aktuell användare" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgid "Page" msgstr "Sida" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "Redigera" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgid "Copy selected text to clipboard" msgstr "Kopiera markerad text till urklipp" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Global" msgstr "Övergripande" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "Sök" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Document" msgstr "Dokument" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "Skriv ut" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "Skapa nytt dokument" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "Redigera dokumentegenskaper" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Document list" msgstr "Dokumentlista" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "Öppna nästa dokument" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "Öppna föregÃ¥ende dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:372 #, python-format msgid "Estimated file size: %s" msgstr "Beräknad filstorlek: %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:593 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:104 msgid "Select a file or a directory to import" msgstr "Välj en fil eller mapp att importera" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:602 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:124 msgid "Any files" msgstr "Alla filer" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:613 #, python-format msgid "%d documents" msgstr "%d dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:23 msgid "New document" msgstr "Nytt dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:113 msgid "Loading document thumbnails" msgstr "Läser in dokumentminiatyrer" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:78 msgid "Keyword(s)" msgstr "Nyckelord" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:131 msgid "Label" msgstr "Etikett" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:143 msgid "From:" msgstr "FrÃ¥n:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:149 msgid "to:" msgstr "till:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:259 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "Datum" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:291 msgid "and" msgstr "och" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:292 msgid "or" msgstr "eller" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:309 msgid "not" msgstr "inte" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:333 msgid "Remove" msgstr "Ta bort" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "Byter namn pÃ¥ etikett" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:378 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "Ändrar etikett {old_label} till {new_label} pÃ¥ dokument {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:444 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "Tar bort etikett {old_label} frÃ¥n dokument {doc_id}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "Tom" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:88 msgid "Loading page {}/{} ..." msgstr "Läser in sida {}/{}..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:83 msgid "Loading text ..." msgstr "Läser in text..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "Skanna frÃ¥n %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:75 msgid "Import image or PDF file(s)" msgstr "Importera bild- eller PDF-fil(er)" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:76 msgid "Import file(s)" msgstr "Importera fil(er)" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:118 msgid "All supported file formats" msgstr "Alla filformat som stöds" #: paperwork-gtk/src/paperwork_gtk/main.py:197 msgid "command" msgstr "kommando" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "Introduktion" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "Användarmanual" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "Dokumentation" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "Vill du verkligen ta bort sidan {page_idx} frÃ¥n dokument {doc_id}?" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 msgid "Redo OCR on page" msgstr "Gör om OCR pÃ¥ sida" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "OCR pÃ¥ {doc_id} s.{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "Vill du verkligen ta bort %d dokument?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "Vill du verkligen ta bort dokument %s?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #, python-format msgid "OCR on %s" msgstr "OCR pÃ¥ %s" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "Skriv ut sida" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "Exportera sida" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "Ta bort sida" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "Ã…terställ sida" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "Kopiera markerad text" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:62 msgid "Help" msgstr "Hjälp" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "Rapportera fel" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "Genvägar" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "Inställningar" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "Om" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "Exportera" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "Markera alla" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "Ta bort" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "Ändra etiketter" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "Skriv ut dokument" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "Exportera dokument" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "Ta bort dokument" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "Gör om OCR pÃ¥ dokument" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "Dokumentegenskaper" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "Lägg till samlingen" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "Öppna mapp" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "Uppdateringar\n" "Sök med jämna mellanrum efter nya versioner av " "Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "Kolla ungefär en gÃ¥ng i veckan efter nya versioner " "av Paperwork.\n" "Du meddelas när en ny version finns tillgänglig men den installeras inte " "automatiskt.\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "Arbetsmapp" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "SprÃ¥k" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "Maximera" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "Automatiskt" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "Skanna" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "Skannerkalibrering" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "Enhet" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "Upplösning" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "Läge" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "Kalibrering" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "Kalibrera om" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners. To enable Saned on the host system, you must copy and " "paste the following commands in a terminal:" msgstr "" "Du använder Paperwork frÃ¥n en Flatpak-behÃ¥llare. Paperwork behöver Saned för " "Ã¥tkomst till dina skannrar. Du mÃ¥ste kopiera och klistra in följande " "kommandon, i en terminal, för att aktivera Saned pÃ¥ värdsystemet:" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "Skicka mätvärden\n" "Ge oss ledtrÃ¥dar om hur du använder " "Paperwork" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" "Dessa ledtrÃ¥dar hjälper oss att göra Paperwork " "till en ännu bättre mjukvara för dig. Statistiken visar oss ocksÃ¥ att " "människor faktiskt använder vÃ¥rt arbete och hÃ¥ller oss motiverade att " "förbättra det.\n" "\n" "Detta är data vi samlar in:\n" "- HÃ¥rdvara: CPU, RAM, skärmupplösning.\n" "- Mjukvara: Version pÃ¥ Paperwork, Operativsystem, skrivbordsmiljö och " "systemsprÃ¥k\n" "- Datamätvärden: Antal dokument, max och medel sidantal, antal etiketter.\n" "- Hur mÃ¥nga gÃ¥nger du använder varje funktion.\n" "\n" "Vi samlar inte in dokumentinnehÃ¥ll eller nÃ¥gon annan känslig eller personlig " "information. ÄndÃ¥ tycker vi att det är rättvist att be om ditt tillstÃ¥nd. ;-)" "\n" "\n" "Insamlad statistik kan ses pÃ¥ openpaper.work.\n" "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "Exportsteg" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "Kvalitet" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "Pappersformat" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "Exportera inställningar" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Preview" msgstr "Förhandsvisning" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "Dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "Markering" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "Menade du?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 msgid "Search" msgstr "Sök" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "Avancerat sök" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "Egenskaper" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "Ändra etikettfärg" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "Ta bort etiketten frÃ¥n alla dokument" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "Ytterligare nyckelord" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "Markera ord" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "Lägg till sida" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2020" msgstr "©2020" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "Sortering av dokument är ett maskinjobb." paperwork-2.2.2/paperwork-gtk/l10n/uk.po000066400000000000000000000505021456262201400200610ustar00rootroot00000000000000# Ukrainian translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2020-05-03 15:27+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:33 msgid "Now with 10% more freedom in it !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:34 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:35 msgid "New features and bugs available !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:36 msgid "New taste !" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:37 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:38 msgid "Smarter, Better, Stronger" msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:40 msgid "It's better when it's free." msgstr "" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/main.py:203 msgid "command" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:294 #, python-format msgid "Are you sure you want to delete label '%s' from ALL documents ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:396 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:462 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:405 #, python-format msgid "Estimated file size: %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:628 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:108 msgid "Select a file or a directory to import" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:637 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:128 msgid "Any files" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:715 msgid "Export has failed" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:33 msgid "New document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:622 #, python-format msgid "%d documents" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:116 msgid "Loading document thumbnails" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:77 msgid "Import document or image file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:78 msgid "Import file(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:122 msgid "All supported file formats" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:93 msgid "Loading page {}/{} ..." msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:88 msgid "Loading text ..." msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:81 msgid "Keyword(s)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:102 msgid "No labels" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:142 msgid "Label" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:154 msgid "From:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:160 msgid "to:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:270 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:302 msgid "and" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:303 msgid "or" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:320 msgid "not" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:344 msgid "Remove" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgctxt "keyboard shortcut categories" msgid "Page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:31 msgctxt "keyboard shortcut names" msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:32 msgctxt "keyboard shortcut names" msgid "Copy selected text to clipboard" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Global" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Document list" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:50 msgid "Another document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py:53 #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:53 msgid "Move page to" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py:50 msgid "Another position" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 msgid "Redo OCR on page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:64 msgid "Help" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "" #: paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py:51 msgid "Redo OCR" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:87 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:106 msgid "PDF password" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:124 msgid "No new document to import found" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:167 msgctxt "import dialog" msgid "Imported file deleted" msgid_plural "Imported files deleted" msgstr[0] "" msgstr[1] "" msgstr[2] "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:177 msgid "Imported:\n" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:183 msgid "Import successful" msgstr "" #: paperwork-gtk/src/paperwork_gtk/docimport.py:192 msgid "Delete imported files" msgstr "" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:101 msgid "Storage" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:108 msgid "Work Directory" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:62 msgid "No scanner selected" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 msgid "No resolution selected" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:66 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:70 msgid "No mode selected" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:113 msgid "Scanner" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:168 msgid "Loading ..." msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:116 #, python-format msgid "Move the page %d to what position ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:135 #, python-format msgid "Invalid page position: %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:147 #, python-format msgid "Invalid page position: %d. Out of document bounds (1-%d)." msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py:156 msgid "Page position unchanged" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:92 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #: paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py:83 #, python-format msgid "OCR on %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:35 msgid "Run Paperwork and import files passed as arguments into a new document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/import.py:39 msgid "URLs or paths of files to import" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Send by email" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:6 msgid "Preview" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 msgid "Search" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:2 msgid "" "Do not use an already existing directory !\n" "(unless it comes from another Paperwork instance)\n" "\n" "Paperwork uses a custom file structure to store documents. Unless the " "directory you specify has the exact file structure expected by Paperwork, it " "won't work !\n" "\n" "If you want to build a new work directory from existing documents, please " "use the import feature instead.\n" "\n" "[More information]" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners.\n" "\n" "Important: the following procedure will only work for local (non-network) " "scanners !\n" "\n" "To enable Saned on the host system, you must copy and paste the following " "commands in a terminal:" msgstr "" #: paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade.h:1 msgid "Select target document" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2023" msgstr "" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "" paperwork-2.2.2/paperwork-gtk/l10n/zh_Hans.po000066400000000000000000000512621456262201400210400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-09-01 22:01+0200\n" "PO-Revision-Date: 2021-02-06 06:20+0000\n" "Last-Translator: 玉堂白鹤 \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.4\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:82 #, python-format msgid "Don't know how to import '%s'. Sorry." msgstr "对ä¸èµ·ï¼Œä¸çŸ¥é“如何导入“%sâ€ã€‚" #: paperwork-gtk/src/paperwork_gtk/docimport.py:99 msgid "No new document to import found" msgstr "未å‘现è¦å¯¼å…¥çš„æ–°æ–‡æ¡£" #: paperwork-gtk/src/paperwork_gtk/docimport.py:139 msgid "Imported file(s) deleted" msgstr "已删除导入的文件" #: paperwork-gtk/src/paperwork_gtk/docimport.py:146 msgid "Imported:\n" msgstr "导入:\n" #: paperwork-gtk/src/paperwork_gtk/docimport.py:152 msgid "Import successful" msgstr "导入æˆåŠŸ" #: paperwork-gtk/src/paperwork_gtk/docimport.py:161 msgid "Delete imported files" msgstr "删除导入文件" #: paperwork-gtk/src/paperwork_gtk/print.py:42 #, python-brace-format msgid "Loading {doc_id} p{page_idx} for printing" msgstr "真正加载{doc_id}页{page_idx}以打å°" #: paperwork-gtk/src/paperwork_gtk/print.py:144 #, python-format msgid "Printing %s" msgstr "打å°%s" #: paperwork-gtk/src/paperwork_gtk/print.py:179 #, python-brace-format msgid "Printing {doc_id} ({page_idx}/{nb_pages})" msgstr "æ‰“å° {doc_id} ({page_idx}/{nb_pages})" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:9 msgid "Now with 10% more freedom in it !" msgstr "现在有了 10% 的自由度ï¼" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:10 #, python-format msgid "Buy it now and get a 100% discount !" msgstr "现在购买,å¯ä»¥äº«å—100% 的折扣ï¼" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:11 msgid "New features and bugs available !" msgstr "新增功能和 bugï¼" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:12 msgid "It's better when it's free." msgstr "å…费的时候更好。" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:13 msgid "New taste !" msgstr "新体验 !" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:14 msgid "We replaced your old bugs with new bugs. Enjoy." msgstr "我们用新 bug 替æ¢äº†æ‚¨çš„æ—§ bug。好好享å—。" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:15 msgid "Smarter, Better, Stronger" msgstr "æ›´èªæ˜Žï¼Œæ›´å¥½ï¼Œæ›´å¼º" #: paperwork-gtk/src/paperwork_gtk/update_notification.py:45 #, python-brace-format msgid "A new version of Paperwork is available: {new_version}" msgstr "Paperwork 新版本å¯ç”¨: {new_version}" #: paperwork-gtk/src/paperwork_gtk/settings/update.py:60 msgid "Updates" msgstr "æ›´æ–°" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:84 msgid "Storage" msgstr "存储" #: paperwork-gtk/src/paperwork_gtk/settings/storage.py:90 msgid "Work Directory" msgstr "工作目录" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:64 msgid "Optical Character Recognition" msgstr "光学字符识别" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py:76 msgid "OCR disabled" msgstr "å·²ç¦ç”¨ OCR" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:15 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:1 msgid "Color" msgstr "彩色" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:16 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:2 msgid "Grayscale" msgstr "ç°åº¦" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:17 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade.h:3 msgid "Black & White" msgstr "黑白" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:27 msgid "No scanner selected" msgstr "未选择扫æä»ª" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:31 msgid "No resolution selected" msgstr "未选择分辨率" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:31 #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:123 msgid "{} dpi" msgstr "{} dpi" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:35 msgid "No mode selected" msgstr "未选择模å¼" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py:104 msgid "Scanner" msgstr "扫æä»ª" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py:67 msgid "No scanner" msgstr "无扫æä»ª" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py:154 msgid "Loading ..." msgstr "加载中 ..." #: paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py:125 msgid "{} dpi (recommended)" msgstr "{} dpi (推è)" #: paperwork-gtk/src/paperwork_gtk/settings/stats.py:60 msgid "Help Improve Paperwork" msgstr "帮助改进 Paperwork" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:40 msgid "Install Paperwork icons and shortcuts" msgstr "安装 Paperwork å›¾æ ‡å’Œå¿«æ·æ–¹å¼" #: paperwork-gtk/src/paperwork_gtk/cmd/install.py:44 msgid "Install everything only for the current user" msgstr "åªä¸ºå½“å‰ç”¨æˆ·å®‰è£…所有内容" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgid "Page" msgstr "页é¢" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py:30 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade.h:1 msgid "Edit" msgstr "编辑" #: paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py:30 msgid "Copy selected text to clipboard" msgstr "将所选文本å¤åˆ¶åˆ°å‰ªè´´æ¿" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Global" msgstr "全局" #: paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py:30 msgid "Find" msgstr "查找" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Document" msgstr "文档" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py:30 msgid "Print" msgstr "打å°" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py:30 msgid "Create new document" msgstr "创建新文档" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py:30 msgid "Edit document properties" msgstr "编辑文档属性" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Document list" msgstr "文档列表" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:30 msgid "Open next document" msgstr "打开下一文档" #: paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py:35 msgid "Open previous document" msgstr "打开上一文档" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:372 #, python-format msgid "Estimated file size: %s" msgstr "估计文件大å°: %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:593 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:104 msgid "Select a file or a directory to import" msgstr "选择è¦å¯¼å…¥çš„æ–‡ä»¶æˆ–目录" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py:602 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:124 msgid "Any files" msgstr "所有文件" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py:613 #, python-format msgid "%d documents" msgstr "%d 个文档" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py:59 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py:23 msgid "New document" msgstr "新建文档" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py:113 msgid "Loading document thumbnails" msgstr "加载文档缩略图" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:78 msgid "Keyword(s)" msgstr "关键字" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:131 msgid "Label" msgstr "标签" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:143 msgid "From:" msgstr "从:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:149 msgid "to:" msgstr "到:" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:259 #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade.h:1 msgid "Date" msgstr "日期" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:291 msgid "and" msgstr "å’Œ" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:292 msgid "or" msgstr "或" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:309 msgid "not" msgstr "ä¸åŒ…å«" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py:333 msgid "Remove" msgstr "移除" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:247 msgid "Renaming label" msgstr "é‡å‘½å标签" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:378 #, python-brace-format msgid "Changing label {old_label} into {new_label} on document {doc_id}" msgstr "将文档{doc_id}上的标签{old_label}更改为{new_label}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py:444 #, python-brace-format msgid "Deleting label {old_label} from document {doc_id}" msgstr "从文档{doc_id}中删除标签{old_label}" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py:89 msgid "Empty" msgstr "空白" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py:88 msgid "Loading page {}/{} ..." msgstr "æ­£åœ¨åŠ è½½é¡µé¢ {}/{} ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py:83 msgid "Loading text ..." msgstr "正在加载文本 ..." #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py:118 #, python-format msgid "Scan from %s" msgstr "扫æè‡ª %s" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:75 msgid "Import image or PDF file(s)" msgstr "å¯¼å…¥å›¾åƒæˆ– PDF 文件" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:76 msgid "Import file(s)" msgstr "导入文件" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py:118 msgid "All supported file formats" msgstr "所有支æŒçš„æ ¼å¼" #: paperwork-gtk/src/paperwork_gtk/main.py:197 msgid "command" msgstr "命令" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:64 msgid "Introduction" msgstr "介ç»" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:65 msgid "User manual" msgstr "用户手册" #: paperwork-gtk/src/paperwork_gtk/model/help/__init__.py:67 msgid "Documentation" msgstr "文档" #: paperwork-gtk/src/paperwork_gtk/actions/page/delete.py:85 #, python-brace-format msgid "Are you sure you want to delete page {page_idx} of document {doc_id} ?" msgstr "确实è¦åˆ é™¤æ–‡æ¡£ {doc_id} 的第 {page_idx} 页å—?" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:62 #: paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py:50 msgid "Redo OCR on page" msgstr "é‡åšé¡µé¢ OCR" #: paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py:100 #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:105 #, python-brace-format msgid "OCR on {doc_id} p{page_idx}" msgstr "OCR {doc_id} 页{page_idx}" #: paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py:72 #, python-format msgid "Are you sure you want to delete %d documents ?" msgstr "您确信è¦åˆ é™¤ %d 文档 ?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py:78 #, python-format msgid "Are you sure you want to delete document %s ?" msgstr "你确信è¦åˆ é™¤æ–‡æ¡£ %s?" #: paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py:97 #, python-format msgid "OCR on %s" msgstr "OCR 于 %s" #: paperwork-gtk/src/paperwork_gtk/menus/page/print.py:49 msgid "Print page" msgstr "打å°é¡µé¢" #: paperwork-gtk/src/paperwork_gtk/menus/page/export.py:49 msgid "Export page" msgstr "导出页é¢" #: paperwork-gtk/src/paperwork_gtk/menus/page/delete.py:49 msgid "Delete page" msgstr "删除页é¢" #: paperwork-gtk/src/paperwork_gtk/menus/page/reset.py:49 msgid "Reset page" msgstr "é‡ç½®é¡µé¢" #: paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py:50 msgid "Copy selected text" msgstr "å¤åˆ¶æ‰€é€‰æ–‡æœ¬" #: paperwork-gtk/src/paperwork_gtk/menus/app/help.py:62 msgid "Help" msgstr "帮助" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py:49 msgid "Report bug" msgstr "报告 bug" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py:45 msgid "Shortcuts" msgstr "å¿«æ·æ–¹å¼" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py:43 #: paperwork-gtk/src/paperwork_gtk/settings/settings.glade.h:1 msgid "Settings" msgstr "设置" #: paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py:45 msgid "About" msgstr "关于" #: paperwork-gtk/src/paperwork_gtk/menus/docs/export.py:51 msgid "Export" msgstr "导出" #: paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py:51 msgid "Select all" msgstr "全选" #: paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py:51 msgid "Delete" msgstr "删除" #: paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py:56 msgid "Change labels" msgstr "更改标签" #: paperwork-gtk/src/paperwork_gtk/menus/doc/print.py:41 msgid "Print document" msgstr "æ‰“å°æ–‡æ¡£" #: paperwork-gtk/src/paperwork_gtk/menus/doc/export.py:38 msgid "Export document" msgstr "导出文档" #: paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py:40 msgid "Delete document" msgstr "删除文档" #: paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py:40 msgid "Redo OCR on document" msgstr "é‡åšæ–‡æ¡£ OCR" #: paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py:43 msgid "Document properties" msgstr "文档属性" #: paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py:41 msgid "Add to selection" msgstr "添加至所选" #: paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py:36 msgid "Open folder" msgstr "打开文件夹" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:1 msgid "" "Updates\n" "Check periodically for new versions of Paperwork" msgstr "" "æ›´æ–°\n" "定期检查 Paperwork 新版本" #: paperwork-gtk/src/paperwork_gtk/settings/update.glade.h:3 msgid "" "Look about once a week for new versions of " "Paperwork.\n" "You will be notified when a new version is available but it won't be " "installed automatically.\n" "" msgstr "" "æ¯å‘¨æŸ¥çœ‹ä¸€æ¬¡ Paperwork 新版本。\n" "当有新版本å¯ç”¨ä½†ä¸ä¼šè‡ªåŠ¨å®‰è£…æ—¶ï¼Œç³»ç»Ÿå°†ä¼šé€šçŸ¥æ‚¨ã€‚\n" "" #: paperwork-gtk/src/paperwork_gtk/settings/storage.glade.h:1 msgid "Work directory" msgstr "工作目录" #: paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade.h:1 msgid "Languages" msgstr "语言" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:1 msgid "Maximize" msgstr "最大化" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:2 msgid "Automatic" msgstr "自动" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:3 msgid "Scan" msgstr "扫æ" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade.h:4 msgid "Scanner Calibration" msgstr "扫æä»ªæ ¡å‡†" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:1 msgid "Device" msgstr "设备" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:2 msgid "Resolution" msgstr "分辨率" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:3 msgid "Mode" msgstr "模å¼" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:4 msgid "Calibration" msgstr "校准" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade.h:5 msgid "Re-calibrate" msgstr "釿–°æ ¡å‡†" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:1 msgid "Flatpak" msgstr "Flatpak" #: paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade.h:2 msgid "" "You are using Paperwork from a Flatpak container. Paperwork needs Saned to " "access your scanners. To enable Saned on the host system, you must copy and " "paste the following commands in a terminal:" msgstr "" "您使用的是 Flatpak 容器的 Paperwork 。它需è¦ä½¿ç”¨ Saned 访问你的扫æä»ªã€‚è¦åœ¨ä¸»æœºç³»ç»Ÿä¸Šå¯ç”¨ " "Saned,必须在终端中å¤åˆ¶å¹¶ç²˜è´´ä»¥ä¸‹å‘½ä»¤ï¼š" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:1 msgid "" "Send metrics\n" "Give us clues about how you use Paperwork" msgstr "" "å‘逿Œ‡æ ‡\n" "给我们一些关于您如何使用 Paperwork 的线索" #: paperwork-gtk/src/paperwork_gtk/settings/stats.glade.h:3 msgid "" "Those clues will help us to make Paperwork an even " "better piece of software, for you. Statistics also show us that people are " "actually using our work, keeping us motivated to improve it.\n" "\n" "Here are the data we gather:\n" "- Hardware: CPU, RAM, screen resolution.\n" "- Software: Version of Paperwork, Operating system, desktop environment, " "system language.\n" "- Data metrics: number of documents, maximum and average number of pages, " "number of labels.\n" "- Number of times you used each feature.\n" "\n" "We do not collect document content nor any other sensitive or personal " "information. Still we think it's fair to request your authorization ;-).\n" "\n" "Collected statistics are visible on openpaper.work.\n" "" msgstr "" "这些线索将帮助我们使 Paperwork " "æˆä¸ºä¸€ä¸ªæ›´å¥½çš„软件,奉献给您。统计数æ®è¿˜å°†æ˜¾ç¤ºï¼Œäººä»¬å®žé™…上在使用我们的作å“ï¼Œä½¿æˆ‘ä»¬ä¿æŒæ”¹è¿›å·¥ä½œçš„动力。\n" "\n" "以下是我们收集的数æ®ï¼š\n" "-硬件:CPU,RAM,å±å¹•分辨率。\n" "-软件:文件版本,æ“作系统,桌é¢çŽ¯å¢ƒï¼Œç³»ç»Ÿè¯­è¨€ã€‚\n" "-æ•°æ®æŒ‡æ ‡ï¼šæ–‡æ¡£æ•°ã€æœ€å¤§å’Œå¹³å‡é¡µæ•°ã€æ ‡ç­¾æ•°ã€‚\n" "-使用æ¯ä¸ªåŠŸèƒ½çš„æ¬¡æ•°ã€‚\n" "\n" "æˆ‘ä»¬ä¸æ”¶é›†æ–‡ä»¶å†…å®¹æˆ–ä»»ä½•å…¶ä»–æ•æ„Ÿæˆ–个人信æ¯ã€‚我们ä»ç„¶è®¤ä¸ºè¯·æ±‚æ‚¨çš„æŽˆæƒæ˜¯å…¬å¹³çš„;-)。\n" "\n" "收集的统计数æ®ä½äºŽ openpaper." "work。\n" "" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:1 msgid "Export Steps" msgstr "导出步骤" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:2 msgid "Quality" msgstr "è´¨é‡" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:3 msgid "Paper format" msgstr "页颿 ¼å¼" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:4 msgid "Export Settings" msgstr "导出设置" #: paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade.h:5 msgid "Preview" msgstr "预览" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:1 msgid "Documents" msgstr "文档" #: paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade.h:2 msgid "Selection" msgstr "选择" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade.h:1 msgid "Did you mean ?" msgstr "ä½ çš„æ„æ€æ˜¯ ?" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:1 #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade.h:1 msgid "Search" msgstr "æœç´¢" #: paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade.h:2 msgid "Advanced search" msgstr "高级æœç´¢" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade.h:1 msgid "Properties" msgstr "属性" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:1 msgid "Change the label color" msgstr "更改标签颜色" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade.h:2 msgid "Delete the label from all documents" msgstr "从所有文档中删除标签" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade.h:1 msgid "Additional keywords" msgstr "其他关键字" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade.h:1 msgid "Highlight words" msgstr "çªå‡ºæ˜¾ç¤ºå•è¯" #: paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade.h:1 msgid "Add page" msgstr "添加页é¢" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:1 msgid "©2020" msgstr "©2020" #: paperwork-gtk/src/paperwork_gtk/about/about.glade.h:2 msgid "Sorting documents is a machine's job." msgstr "æ•´ç†æ–‡ä»¶æ˜¯æœºå™¨çš„工作。" paperwork-2.2.2/paperwork-gtk/pylintrc000066400000000000000000000156461456262201400201310ustar00rootroot00000000000000[MASTER] # Specify a configuration file. #rcfile= # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). #init-hook= # Profiled execution. profile=no # Add files or directories to the blacklist. They should be base names, not # paths. ignore=CVS # Pickle collected data for later comparisons. persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= [MESSAGES CONTROL] # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time. #enable= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). disable=W0511,R0903,R0902,E0611,C0111 [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs # (visual studio) and html output-format=text # Include message's id in output include-ids=yes # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". files-output=no # Tells whether to display a full report or only the messages reports=yes # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Add a comment according to your evaluation note. This is used by the global # evaluation report (RP0004). comment=no [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME,XXX,TODO [VARIABLES] # Tells whether we should check for unused import in __init__ files. init-import=no # A regular expression matching the beginning of the name of dummy variables # (i.e. not used). dummy-variables-rgx=_|dummy # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= [SIMILARITIES] # Minimum lines number of a similarity. min-similarity-lines=4 # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes [BASIC] # Required attributes for module, separated by a comma required-attributes= # List of builtins function names that should not be used, separated by a comma bad-functions=map,filter,apply,input # Regular expression which should only match correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ # Regular expression which should only match correct module level names const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ # Regular expression which should only match correct class names class-rgx=[A-Z_][a-zA-Z0-9]+$ # Regular expression which should only match correct function names function-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct method names method-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct instance attribute names attr-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct argument names argument-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct variable names variable-rgx=[a-z_][a-z0-9_]{2,30}$ # Regular expression which should only match correct list comprehension / # generator expression variable names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Good variable names which should always be accepted, separated by a comma good-names=i,j,k,ex,Run,_ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata # Regular expression which should only match functions or classes name which do # not require a docstring no-docstring-rgx=__.*__ [TYPECHECK] # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # List of classes names for which member attributes should not be checked # (useful for classes with attributes dynamically set). ignored-classes=SQLObject # When zope mode is activated, add a predefined set of Zope acquired attributes # to generated-members. zope=no # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E0201 when accessed. Python regular # expressions are accepted. generated-members=REQUEST,acl_users,aq_parent [FORMAT] # Maximum number of characters on a single line. max-line-length=80 # Maximum number of lines in a module max-module-lines=1000 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' [DESIGN] # Maximum number of arguments for function / method max-args=5 # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.* # Maximum number of locals for function / method body max-locals=15 # Maximum number of return / yield for function / method body max-returns=6 # Maximum number of branch for function / method body max-branchs=12 # Maximum number of statements in function / method body max-statements=50 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=7 # Minimum number of public methods for a class (see R0903). min-public-methods=2 # Maximum number of public methods for a class (see R0904). max-public-methods=20 [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,string,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= [CLASSES] # List of interface methods to ignore, separated by a comma. This is used for # instance to not check methods defines in Zope's Interface base class. ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp paperwork-2.2.2/paperwork-gtk/pyproject.toml000066400000000000000000000016311456262201400212430ustar00rootroot00000000000000[project] name = "paperwork-gtk" description = "Paperwork's GTK interface" dynamic = ["version"] authors = [ {name = "Jerome Flesch", email = "jflesch@openpaper.work" }, ] license = {text = "GPL-3.0-or-later"} readme = {file = "README.markdown", content-type = "text/markdown"} dependencies = [ "openpaperwork-core", "openpaperwork-gtk", "paperwork-backend", "distro", "pycountry", "pyocr >= 0.3.0", "pyxdg >= 0.25", ] [project.optional-dependencies] dev = [ "pytest", ] lint = [ "flake8", ] # Jflesch(2023/09/17): # Don't use gui-scripts here: it breaks the Windows build [project.scripts] paperwork-gtk = 'paperwork_gtk.main:main' [tool.setuptools_scm] root = ".." relative_to = "__file__" write_to = "paperwork-gtk/src/paperwork_gtk/_version.py" version_scheme = "post-release" [build-system] requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta" paperwork-2.2.2/paperwork-gtk/setup_cxfreeze.py000077500000000000000000000061741456262201400217460ustar00rootroot00000000000000#!/usr/bin/env python3 import glob import os import sys import cx_Freeze quiet = '--quiet' in sys.argv or '-q' in sys.argv freeze = 'build_exe' in sys.argv kwargs = {} common_include_files = [] required_dll_search_paths = os.getenv("PATH", os.defpath).split(os.pathsep) required_dlls = [ 'libatk-1.0-0.dll', 'libepoxy-0.dll', 'libgdk-3-0.dll', 'libgdk_pixbuf-2.0-0.dll', 'libgtk-3-0.dll', 'libhandy-1-0.dll', 'libinsane.dll', 'libinsane_gobject.dll', 'libintl-8.dll', 'libnotify-4.dll', 'libpango-1.0-0.dll', 'libpangocairo-1.0-0.dll', 'libpangoft2-1.0-0.dll', 'libpangowin32-1.0-0.dll', 'libpoppler-*.dll', 'libpoppler-glib-8.dll', 'librsvg-2-2.dll', 'libsqlite3-0.dll', 'libxml2-2.dll', ] for dll in required_dlls: dll_path = None for p_dir in required_dll_search_paths: p_glob = os.path.join(p_dir, dll) for p in glob.glob(p_glob): if os.path.isfile(p): dll_path = p break if dll_path is not None: break if dll_path is None: raise Exception( "Unable to locate {} in {}".format( dll, required_dll_search_paths ) ) print(f"Found {dll} = {dll_path}") common_include_files.append((dll_path, os.path.basename(dll_path))) # We need the .typelib files at runtime. # The related .gir files are in $PREFIX/share/gir-1.0/$NS.gir, # but those can be omitted at runtime. required_gi_namespaces = [ "Atk-1.0", "cairo-1.0", "Gdk-3.0", "GdkPixbuf-2.0", "Gio-2.0", "GLib-2.0", "GModule-2.0", "GObject-2.0", "Gtk-3.0", "Handy-1", "HarfBuzz-0.0", "Notify-0.7", "Pango-1.0", "PangoCairo-1.0", "Poppler-0.18", "freetype2-2.0", "Libinsane-1.0", ] for ns in required_gi_namespaces: subpath = "lib/girepository-1.0/{}.typelib".format(ns) fullpath = os.path.join(sys.prefix, subpath) assert os.path.isfile(fullpath), ( "Required file {} is missing" .format( fullpath, )) common_include_files.append((fullpath, subpath)) common_packages = [ "gi", # always seems to be needed "cairo", # Only needed (for foreign structs) if no "import cairo"s # XXX(Jflesch): bug ? "pyocr", "pyocr.libtesseract", "setuptools", "openpaperwork_core", "openpaperwork_gtk", "paperwork_backend", "paperwork_gtk", "paperwork_shell", ] kwargs['executables'] = [ cx_Freeze.Executable( script="src/paperwork_gtk/main.py", target_name="paperwork.exe", base=("Console" if os.name != "nt" else "Win32GUI"), ), cx_Freeze.Executable( # UGLY script="../paperwork-shell/src/paperwork_shell/main.py", target_name="paperwork-json.exe", base="Console", ), ] kwargs['options'] = { "build_exe": { 'include_files': common_include_files, 'silent': True, 'packages': common_packages, "excludes": ["tkinter", "tk", "tcl"], }, } kwargs["setup_requires"] = [ "setuptools_scm", ] kwargs["use_scm_version"] = True cx_Freeze.setup(**kwargs) paperwork-2.2.2/paperwork-gtk/src/000077500000000000000000000000001456262201400171155ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/000077500000000000000000000000001456262201400217745ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/__init__.py000066400000000000000000000001131456262201400241000ustar00rootroot00000000000000import gettext def _(s): return gettext.dgettext('paperwork_gtk', s) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/about/000077500000000000000000000000001456262201400231065ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/about/__init__.py000066400000000000000000000061041456262201400252200ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.windows = [] def get_interfaces(self): return [ 'gtk_about', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'authors', 'defaults': ['paperwork_backend.authors'], }, { 'interface': 'app', 'defaults': ['paperwork_backend.app'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'icon', 'defaults': ['paperwork_gtk.icon'], }, ] def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _set_authors_str(self, method, authors): out = "" for (email, name, line_count) in authors: if line_count > 0: out += "{} ({})\n".format(name, line_count) else: out += "{}\n".format(name) method(out) def _set_authors_list(self, method, authors): out = [] for (email, name, line_count) in authors: txt = name if line_count > 0: txt += " ({})".format(line_count) out.append(txt) method(out) def _on_close(self, dialog, *args, **kwargs): LOGGER.info("Closing dialog 'about'") dialog.destroy() self.core.call_all("on_gtk_window_closed", dialog) def gtk_open_about(self): LOGGER.info("Opening dialog 'about'") widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.about", "about.glade" ) authors = {} self.core.call_all("authors_get", authors) documentation = authors.pop("Documentation", []) translators = authors.pop("Translators", []) version = self.core.call_success("app_get_version") icon = self.core.call_success("icon_get_pixbuf", "paperwork", 128) about_dialog = widget_tree.get_object("about_dialog") about_dialog.set_logo(icon) about_dialog.set_version(version) for (k, v) in authors.items(): self._set_authors_list( lambda authors: about_dialog.add_credit_section(k, authors), v ) if len(translators) > 0: self._set_authors_str( about_dialog.set_translator_credits, translators ) self._set_authors_list(about_dialog.set_documenters, documentation) about_dialog.set_transient_for(self.windows[-1]) about_dialog.set_visible(True) about_dialog.connect("close", self._on_close) about_dialog.connect("response", self._on_close) self.core.call_all("on_gtk_window_opened", about_dialog) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/about/about.glade000066400000000000000000000031541456262201400252210ustar00rootroot00000000000000 False dialog Paperwork ©2023 Sorting documents is a machine's job. https://www.openpaper.work/ image-missing gpl-3-0 False vertical 2 False end False False 0 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/000077500000000000000000000000001456262201400234345ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/__init__.py000066400000000000000000000000001456262201400255330ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/000077500000000000000000000000001456262201400242145ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/__init__.py000066400000000000000000000000001456262201400263130ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/find.py000066400000000000000000000024061456262201400255100ustar00rootroot00000000000000import logging try: from gi.repository import Gio GIO_AVAILABLE = True except (ImportError, ValueError): GIO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'action', 'action_app', 'action_app_find', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_search_field', 'defaults': ['paperwork_gtk.mainwindow.search.field'], }, ] def chkdeps(self, out: dict): if not GIO_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GIO_AVAILABLE: return action = Gio.SimpleAction.new('app_find', None) action.connect("activate", self._focus_on_search_field) self.core.call_all("app_actions_add", action) def _focus_on_search_field(self, action, parameter): self.core.call_all("search_focus") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/help.py000066400000000000000000000027001456262201400255150ustar00rootroot00000000000000import logging try: from gi.repository import Gio GIO_AVAILABLE = True except (ImportError, ValueError): GIO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'action', 'action_app', 'action_app_help', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'help_documents', 'defaults': ['paperwork_gtk.model.help'], }, ] def chkdeps(self, out: dict): if not GIO_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GIO_AVAILABLE: return for (title, file_name) in self.core.call_success("help_get_files"): action = Gio.SimpleAction.new('open_help.' + file_name, None) action.connect("activate", self.doc_open_help, file_name) self.core.call_all("app_actions_add", action) def doc_open_help(self, action, parameter, file_name): doc_url = self.core.call_success("help_get_file", file_name) self.core.call_all("doc_open", "help_" + file_name, doc_url) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/open_about.py000066400000000000000000000021351456262201400267220ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'action', 'action_app', 'action_app_open_about', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'gtk_about', 'defaults': ['paperwork_gtk.about'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new('open_about', None) action.connect("activate", self._open_about) self.core.call_all("app_actions_add", action) def _open_about(self, *args, **kwargs): self.core.call_success("gtk_open_about") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/open_bug_report.py000066400000000000000000000021641456262201400277620ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None def get_interfaces(self): return [ 'action', 'action_app', 'action_app_open_bug_report', 'chkdeps', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new('open_bug_report', None) action.connect("activate", self._open_bug_report) self.core.call_all("app_actions_add", action) def _open_bug_report(self, *args, **kwargs): self.core.call_all("open_bug_report") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/open_settings.py000066400000000000000000000021711456262201400274500ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'action', 'action_app', 'action_app_open_settings', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'gtk_settings_dialog', 'defaults': ['paperwork_gtk.settings'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new('open_settings', None) action.connect("activate", self._open_settings) self.core.call_all("app_actions_add", action) def _open_settings(self, *args, **kwargs): self.core.call_success("gtk_open_settings") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/app/open_shortcuts.py000066400000000000000000000022001456262201400276370ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'action', 'action_app', 'action_app_open_shortcuts', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'gtk_shortcut_help', 'defaults': ['paperwork_gtk.shortcutswin'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new('open_shortcuts', None) action.connect("activate", self._open_shortcuts) self.core.call_all("app_actions_add", action) def _open_shortcuts(self, *args, **kwargs): self.core.call_success("gtk_show_shortcuts") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/000077500000000000000000000000001456262201400242015ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/__init__.py000066400000000000000000000000001456262201400263000ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/add_to_selection.py000066400000000000000000000032511456262201400300530ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_add_to_selection" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = (None, None) self.active_windows = [] def get_interfaces(self): return [ 'action' 'action_doc', 'action_doc_add_to_selection', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_selection', 'defaults': ['paperwork_gtk.doc_selection'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._add_to_selection) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = (None, None) def _add_to_selection(self, action, parameter): self.core.call_all("gtk_switch_to_doc_selection_multiple") self.core.call_all("doc_selection_add", *self.active_doc) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/delete.py000066400000000000000000000063331456262201400260220ustar00rootroot00000000000000import gc import logging import os try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_delete" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = (None, None) def get_interfaces(self): return [ 'action', 'action_doc', 'action_doc_delete', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_dialog_yes_no', 'defaults': ['openpaperwork_gtk.dialogs.yes_no'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._delete) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = (None, None) def _delete(self, action, parameter): assert self.active_doc is not None active = self.active_doc LOGGER.info("Asking confirmation before deleting doc %s", active[0]) msg = _('Are you sure you want to delete document %s ?') % active[0] active_doc = self.active_doc if os.name == "nt": # On Windows, we have to be absolutely sure the PDF is actually # closed when we try to delete it because Windows s*cks pony d*cks # in h*ll. self.core.call_all("doc_close") # there is no "close()" method in Poppler gc.collect() self.core.call_all( "gtk_show_dialog_yes_no", self, msg, active_doc ) def on_dialog_yes_no_reply(self, parent, reply, *args, **kwargs): if parent is not self: return if not reply: return (active_doc,) = args (doc_id, doc_url) = active_doc LOGGER.info("Will delete doc %s", doc_id) self.core.call_all("doc_close") if os.name == "nt": # there is no "close()" method in Poppler gc.collect() self.core.call_success( "mainloop_schedule", self._really_delete, doc_id ) def _really_delete(self, doc_id): self.core.call_all("storage_delete_doc_id", doc_id) self.core.call_all("search_update_document_list") self.core.call_success("transaction_simple", [('del', doc_id),]) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/export.py000066400000000000000000000031571456262201400261020ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_export" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_windows = [] def get_interfaces(self): return [ 'actions', 'actions_doc', 'actions_doc_export', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_exporter', 'defaults': ['paperwork_gtk.mainwindow.exporter'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._open_exporter) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def _open_exporter(self, *args, **kwargs): assert self.active_doc is not None self.core.call_all("gtk_open_exporter", *self.active_doc) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/new.py000066400000000000000000000023501456262201400253440ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'action', 'action_doc', 'action_doc_new', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_open', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new("doc_new", None) action.connect("activate", self._open_new_doc) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def _open_new_doc(self, *args, **kwargs): self.core.call_all("doc_open_new") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/open_external.py000066400000000000000000000035211456262201400274170ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_open_external" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_windows = [] def get_interfaces(self): return [ 'action', 'action_doc', 'action_doc_open_external', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'external_apps', 'defaults': [ 'openpaperwork_core.external_apps.dbus', 'openpaperwork_core.external_apps.windows', 'openpaperwork_core.external_apps.xdg', ], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._open_external) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def _open_external(self, action, parameter): assert self.active_doc is not None (doc_id, doc_url) = self.active_doc self.core.call_success("external_app_open_folder", doc_url) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/prev_next.py000066400000000000000000000026241456262201400265710ustar00rootroot00000000000000import logging try: from gi.repository import Gio GIO_AVAILABLE = True except (ImportError, ValueError): GIO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'action', 'action_doc', 'action_doc_prev_next', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GIO_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GIO_AVAILABLE: return action = Gio.SimpleAction.new('doc_prev', None) action.connect("activate", self._goto, -1) self.core.call_all("app_actions_add", action) action = Gio.SimpleAction.new('doc_next', None) action.connect("activate", self._goto, 1) self.core.call_all("app_actions_add", action) def _goto(self, action, parameter, offset): self.core.call_all("open_next_doc", offset) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/print.py000066400000000000000000000031011456262201400257020ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_print" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_windows = [] def get_interfaces(self): return [ 'action', 'action_doc', 'action_doc_print', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_print', 'defaults': ['paperwork_gtk.print'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._print) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def _print(self, *args, **kwargs): assert self.active_doc is not None self.core.call_all("doc_print", *self.active_doc) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/properties.py000066400000000000000000000034051456262201400267510ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_properties" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None def get_interfaces(self): return [ 'action', 'action_doc', 'action_doc_properties', 'chkdeps', 'doc_open', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_doc_properties', 'defaults': ['paperwork_gtk.mainwindow.docproperties'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._open_properties) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def _open_properties(self, *args, **kwargs): assert self.active_doc is not None active = self.active_doc LOGGER.info("Opening properties of document %s", active[0]) self.core.call_all("open_doc_properties", *active) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/doc/redo_ocr.py000066400000000000000000000073741456262201400263620ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_redo_ocr" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = (None, None) self.action = None def get_interfaces(self): return [ 'action', 'action_doc', 'action_doc_redo_ocr', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'ocr', 'defaults': ['paperwork_backend.guesswork.ocr.pyocr'], }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return self.action = Gio.SimpleAction.new(ACTION_NAME, None) self.action.connect("activate", self._redo_ocr) self.core.call_all("app_actions_add", self.action) self._update_sensitivity() self.core.call_all( "ocr_add_observer_on_enabled", self._update_sensitivity ) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = (None, None) def _update_sensitivity(self): enabled = self.core.call_success("ocr_is_enabled") self.action.set_enabled(enabled is not None) def _redo_ocr(self, action, parameter): assert self.active_doc is not None (doc_id, doc_url) = self.active_doc nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None: LOGGER.warning("No pages in document %s. Nothing to do", doc_id) return LOGGER.info( "Will redo OCR on document %s (nb pages = %d)", doc_id, nb_pages ) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_progress", "redo_ocr", 0.0, _("OCR on %s") % doc_id) ) promise = promise.then(lambda *args, **kwargs: None) for page_idx in range(0, nb_pages): promise = promise.then( self.core.call_all, "on_progress", "redo_ocr", page_idx / nb_pages, _("OCR on {doc_id} p{page_idx}").format( doc_id=doc_id, page_idx=(page_idx + 1) ) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("ocr_page_by_url", doc_url, page_idx,) )) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "on_progress", "redo_ocr", 1.0 ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_success( "transaction_simple_promise", [('upd', doc_id),] )) self.core.call_success("transaction_schedule", promise) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/000077500000000000000000000000001456262201400243645ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/__init__.py000066400000000000000000000000001456262201400264630ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/delete.py000066400000000000000000000056521456262201400262100ustar00rootroot00000000000000import gc import logging import os try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_delete_many" class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'action', 'action_docs', 'action_docs_delete', 'chkdeps', 'doc_action', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_selection', 'defaults': ['paperwork_gtk.doc_selection'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_dialog_yes_no', 'defaults': ['openpaperwork_gtk.dialogs.yes_no'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._delete) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def _delete(self, action, parameter): docs = set() self.core.call_all("doc_selection_get", docs) LOGGER.info("Asking confirmation before deleting %d doc", len(docs)) msg = _('Are you sure you want to delete %d documents ?') % len(docs) if os.name == "nt": # On Windows, we have to be absolutely sure the PDF is actually # closed when we try to delete it because Windows s*cks pony d*cks # in h*ll. self.core.call_all("doc_close") # there is no "close()" method in Poppler gc.collect() self.core.call_all("gtk_show_dialog_yes_no", self, msg, docs) def on_dialog_yes_no_reply(self, parent, reply, *args, **kwargs): if parent is not self: return if not reply: return (docs,) = args self.core.call_all("doc_close") for (doc_id, doc_url) in docs: LOGGER.info("Deleting document %s", doc_id) self.core.call_all("storage_delete_doc_id", doc_id) self.core.call_all("search_update_document_list") self.core.call_success( "transaction_simple", [ ('del', doc_id) for (doc_id, doc_url) in docs ] ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/export.py000066400000000000000000000034231456262201400262610ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_export_many" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = (None, None) self.active_page_idx = 0 def get_interfaces(self): return [ 'action', 'action_docs', 'action_docs_export', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_selection', 'defaults': ['paperwork_gtk.doc_selection'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._export) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def on_page_shown(self, active_page_idx): self.active_page_idx = active_page_idx def _export(self, action, parameter): docs = set() self.core.call_all("doc_selection_get", docs) self.core.call_all( "gtk_open_exporter_multiple_docs", docs, self.active_doc[0], self.active_doc[1], self.active_page_idx ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/properties.py000066400000000000000000000037751456262201400271460ustar00rootroot00000000000000import itertools import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_change_labels" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.menu_add = None self.menu_remove = None self.idx_generator = itertools.count() def get_interfaces(self): return [ 'action', 'action_docs', 'action_docs_properties', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'doc_selection', 'defaults': ['paperwork_gtk.doc_selection'], }, { 'interface': 'gtk_doc_properties', 'defaults': ['paperwork_gtk.mainwindow.docproperties'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._open_editor) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def _open_editor(self, action, parameter): selection = set() self.core.call_all("doc_selection_get", selection) if len(selection) <= 0: LOGGER.info("No document selected") return LOGGER.info("Opening properties for %d documents", len(selection)) self.core.call_all("open_docs_properties", selection) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/redo_ocr.py000066400000000000000000000104311456262201400265310ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_redo_ocr_many" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -40 def get_interfaces(self): return [ 'action', 'action_docs', 'action_docs_redo_ocr', 'chkdeps', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_selection', 'defaults': ['paperwork_gtk.doc_selection'], }, { 'interface': 'ocr', 'defaults': ['paperwork_backend.guesswork.ocr.pyocr'], }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._redo_ocr_many) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def _redo_ocr_single( self, doc_id, doc_url, progression_start_page_idx, progression_total_pages): nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None: LOGGER.warning("No pages in document %s. Nothing to do", doc_id) return LOGGER.info( "Will redo OCR on document %s (nb pages = %d)", doc_id, nb_pages ) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=( "on_progress", "redo_ocr", progression_start_page_idx / progression_total_pages, _("OCR on %s") % doc_id) ) promise = promise.then(lambda *args, **kwargs: None) for page_idx in range(0, nb_pages): promise = promise.then( self.core.call_all, "on_progress", "redo_ocr", (progression_start_page_idx + page_idx) / progression_total_pages, _("OCR on {doc_id} p{page_idx}").format( doc_id=doc_id, page_idx=(page_idx + 1) ) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("ocr_page_by_url", doc_url, page_idx,) )) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "on_progress", "redo_ocr", (progression_start_page_idx + nb_pages) / progression_total_pages, ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_success( "transaction_simple_promise", [('upd', doc_id),] )) return (promise, nb_pages) def _redo_ocr_many(self, action, parameter): docs = set() self.core.call_all("doc_selection_get", docs) total_pages = 0 for (doc_id, doc_url) in docs: nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) if nb_pages is None: nb_pages = 0 total_pages += nb_pages promise = openpaperwork_core.promise.Promise(self.core) nb_all_pages = 0 for (doc_id, doc_url) in docs: (p, nb_doc_pages) = self._redo_ocr_single( doc_id, doc_url, nb_all_pages, total_pages ) nb_all_pages += nb_doc_pages promise = promise.then(p) self.core.call_success("transaction_schedule", promise) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/docs/select_all.py000066400000000000000000000030061456262201400270440ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_select_all" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.visible_docs = [] def get_interfaces(self): return [ 'action', 'action_docs', 'action_docs_select_all', 'chkdeps', 'search_listener', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_selection', 'defaults': ['paperwork_gtk.doc_selection'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._select_all) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_search_results(self, query, docs): self.visible_docs = docs def _select_all(self, action, parameter): for doc in self.visible_docs: self.core.call_all("doc_selection_add", *doc) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/000077500000000000000000000000001456262201400243505ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/__init__.py000066400000000000000000000000001456262201400264470ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/copy_text.py000066400000000000000000000041141456262201400267400ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_copy_text" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.selected_text = "" self.windows = [] def get_interfaces(self): return [ 'action', 'action_page', 'action_page_copy_text', 'chkdeps', 'selected_boxes_listener', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._copy_text) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def on_page_boxes_selected(self, doc_id, doc_url, page_id, boxes): self.selected_text = " ".join([b.content for b in boxes]) def _copy_text(self, *args, **kwargs): LOGGER.info( "Copying %d characters to clipboard", len(self.selected_text) ) clipboard = Gtk.Clipboard.get_default(self.windows[-1].get_display()) clipboard.set_text(self.selected_text, -1) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/delete.py000066400000000000000000000060421456262201400261660ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_delete" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 def get_interfaces(self): return [ 'action', 'action_page', 'action_page_delete', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_dialog_yes_no', 'defaults': ['openpaperwork_gtk.dialogs.yes_no'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._delete) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _delete(self, *args, **kwargs): assert self.active_doc is not None LOGGER.info( "Asking confirmation before deleting page %d of document %s", self.active_page_idx, self.active_doc[0] ) msg = ( _( "Are you sure you want to delete page" " {page_idx} of document {doc_id} ?" ).format( page_idx=(self.active_page_idx + 1), doc_id=self.active_doc[0] ) ) self.core.call_success( "gtk_show_dialog_yes_no", self, msg, self.active_doc ) def on_dialog_yes_no_reply( self, parent, reply, *args, **kwargs): if parent is not self: return if not reply: return (active_doc,) = args (doc_id, doc_url) = active_doc page_idx = self.active_page_idx LOGGER.info("Will delete page %s p%d", doc_id, page_idx) self.core.call_all("page_delete_by_url", doc_url, page_idx) self.core.call_all("search_update_document_list") self.core.call_all("doc_reload", doc_id, doc_url) self.core.call_success("transaction_simple", [('upd', doc_id),]) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/edit.py000066400000000000000000000031361456262201400256520ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 def get_interfaces(self): return [ 'action', 'action_page', 'action_page_edit', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_page_editor', 'defaults': ['paperwork_gtk.mainwindow.pageeditor'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new("page_edit", None) action.connect("activate", self._on_edit) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def on_page_shown(self, page_idx): self.active_page = page_idx def _on_edit(self, *args, **kwargs): self.core.call_all( "gtk_open_page_editor", *self.active_doc, self.active_page ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/export.py000066400000000000000000000034151456262201400262460ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_export" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 self.active_windows = [] def get_interfaces(self): return [ 'action', 'action_page', 'action_page_export', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_exporter', 'defaults': ['paperwork_gtk.mainwindow.exporter'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._open_exporter) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _open_exporter(self, *args, **kwargs): assert self.active_doc is not None self.core.call_all( "gtk_open_exporter", *self.active_doc, self.active_page_idx ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/move_inside_doc.py000066400000000000000000000122601456262201400300510ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False try: from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk import openpaperwork_gtk.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_move_inside_doc" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 self.windows = [] def get_interfaces(self): return [ 'action', 'action_page', 'action_page_move_inside_doc', 'chkdeps', 'doc_open', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'pages', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.img_overlay', 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'gtk_dialog_single_entry', 'defaults': ['openpaperwork_gtk.dialogs.single_entry'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._start_move_inside_doc) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def on_page_shown(self, page_idx): self.active_page_idx = page_idx def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _show_error(self, msg): flags = ( Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT ) dialog = Gtk.MessageDialog( transient_for=self.windows[-1], flags=flags, message_type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK, text=msg ) dialog.connect("response", lambda dialog, response: dialog.destroy()) dialog.show_all() def _start_move_inside_doc(self, *args, **kwargs): assert self.active_doc is not None assert self.active_page_idx is not None msg = _("Move the page %d to what position ?") % ( self.active_page_idx + 1 ) self.core.call_success( "gtk_show_dialog_single_entry", self, msg, str(self.active_page_idx + 1), active_doc=self.active_doc, active_page_idx=self.active_page_idx ) def on_dialog_single_entry_reply( self, origin, r, new_position, *args, **kwargs): if origin is not self: return None if not r: return None try: new_position = int(new_position) - 1 except ValueError: self._show_error(_("Invalid page position: %s") % (new_position)) return True active_doc = kwargs['active_doc'] active_page_idx = kwargs['active_page_idx'] nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", active_doc[1] ) if new_position >= nb_pages or new_position < 0: self._show_error( _( "Invalid page position: %d." " Out of document bounds (1-%d)." ) % ( new_position, nb_pages ) ) return True if new_position == active_page_idx: self._show_error(_("Page position unchanged")) return True promise = openpaperwork_core.promise.Promise(self.core) promise = promise.then( self.core.call_all, "page_move_by_url", active_doc[1], active_page_idx, active_doc[1], new_position ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "doc_reload", *active_doc ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_success( "transaction_simple_promise", [('upd', active_doc[0])] )) self.core.call_success("transaction_schedule", promise) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/000077500000000000000000000000001456262201400266455ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/__init__.py000066400000000000000000000130611456262201400307570ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_move_to_doc" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 self.waiting_for_target_doc = False def get_interfaces(self): return [ 'action', 'action_page', 'action_page_move_to_doc', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_search_field', 'defaults': ['paperwork_gtk.mainwindow.search.field'], }, { 'interface': 'pages', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.img_overlay', 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.actions.page.move_to_doc", "move_to_doc.glade" ) if widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return widget_tree.get_object("move_to_doc_cancel").connect( "clicked", self._cancel_move_to_doc ) self.core.call_all( "mainwindow_add", "right", "move_to_doc", -9999999999, widget_tree.get_object("move_to_doc_header"), widget_tree.get_object("move_to_doc"), ) action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._start_move_to_doc) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): new_active_doc = (doc_id, doc_url) if self.waiting_for_target_doc: self.waiting_for_target_doc = False self._move_to_doc(new_active_doc) self.active_doc = new_active_doc def doc_close(self): self.active_doc = None def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _start_move_to_doc(self, *args, **kwargs): assert self.active_doc is not None if self.active_page_idx < 0: return LOGGER.info("Starting 'move to doc' process") self.core.call_all("mainwindow_show", "right", "move_to_doc") self.core.call_all("mainwindow_show", "left", "doclist") self.waiting_for_target_doc = True def _run_transaction(self, original_doc, target_doc): nb_remaining_pages = self.core.call_success( "doc_get_nb_pages_by_url", original_doc[1] ) if nb_remaining_pages is None: nb_remaining_pages = 0 self.core.call_success( "transaction_simple_promise", [ ('upd', target_doc[0]), ( 'upd' if nb_remaining_pages > 0 else 'del', original_doc[0] ), ] ) def _move_to_doc(self, target_doc): promise = openpaperwork_core.promise.Promise(self.core) promise = promise.then( self.core.call_all, "page_move_by_url", self.active_doc[1], self.active_page_idx, target_doc[1], 0 ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_one, "mainloop_schedule", self.core.call_all, "doc_reload", *self.active_doc ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_one, "mainloop_schedule", self.core.call_all, "doc_reload", *target_doc ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "search_update_document_list" ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self._run_transaction, self.active_doc, target_doc ) self.core.call_success("transaction_schedule", promise) def _cancel_move_to_doc(self, *args, **kwargs): LOGGER.info("Canceling 'move to doc' process") self.core.call_all("mainwindow_back", "right") self.waiting_for_target_doc = False paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/move_to_doc/move_to_doc.glade000066400000000000000000000063011456262201400321400ustar00rootroot00000000000000 True False True :close True False center center vertical 10 True False end 50 True False gtk-go-back 5 False True 0 True False Select target document False True 1 True True 0 True False end gtk-cancel True True True True False True 1 False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/print.py000066400000000000000000000033441456262201400260620ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_print" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 self.active_windows = [] def get_interfaces(self): return [ 'action', 'action_page', 'action_page_print', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'doc_print', 'defaults': ['paperwork_gtk.print'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._print) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _print(self, *args, **kwargs): assert self.active_doc is not None self.core.call_all( "doc_print", *self.active_doc, [self.active_page_idx] ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/redo_ocr.py000066400000000000000000000066061456262201400265260ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_redo_ocr" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = (None, None) self.active_page_idx = -1 self.action = None def get_interfaces(self): return [ 'action', 'action_page', 'action_page_redo_ocr', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'ocr', 'defaults': ['paperwork_backend.guesswork.ocr.pyocr'], }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return self.item = Gio.MenuItem.new( _("Redo OCR on page"), "win." + ACTION_NAME ) self.action = Gio.SimpleAction.new(ACTION_NAME, None) self.action.connect("activate", self._redo_ocr) self.core.call_all("app_actions_add", self.action) self._update_sensitivity() self.core.call_all( "ocr_add_observer_on_enabled", self._update_sensitivity ) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = (None, None) def _update_sensitivity(self): enabled = self.core.call_success("ocr_is_enabled") self.action.set_enabled(enabled is not None) def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _redo_ocr(self, *args, **kwargs): (doc_id, doc_url) = self.active_doc page_idx = self.active_page_idx promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=( "on_progress", "redo_ocr", 0.0, _("OCR on {doc_id} p{page_idx}").format( doc_id=doc_id, page_idx=page_idx ) ) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("ocr_page_by_url", doc_url, page_idx,) )) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "on_progress", "redo_ocr", 1.0 ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_success( "transaction_simple_promise", [('upd', doc_id),] )) self.core.call_success("transaction_schedule", promise) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/actions/page/reset.py000066400000000000000000000045321456262201400260500ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_reset" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = -1 def get_interfaces(self): return [ 'action', 'action_page', 'action_page_reset', 'chkdeps', 'doc_open', ] def get_deps(self): return [ { 'interface': 'app_actions', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'page_reset', 'defaults': ['paperwork_backend.model.img_overlay'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) if not GLIB_AVAILABLE: return action = Gio.SimpleAction.new(ACTION_NAME, None) action.connect("activate", self._reset) self.core.call_all("app_actions_add", action) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _reset(self, *args, **kwargs): assert self.active_doc is not None (doc_id, doc_url) = self.active_doc page_idx = self.active_page_idx LOGGER.info("Will reset page %s p%d", doc_id, page_idx) self.core.call_all("page_reset_by_url", doc_url, page_idx) self.core.call_all("doc_reload", doc_id, doc_url) self.core.call_success( "mainloop_schedule", self.core.call_all, "doc_goto_page", page_idx ) self.core.call_success("transaction_simple", [("upd", doc_id),]) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/cmd/000077500000000000000000000000001456262201400225375ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/cmd/__init__.py000066400000000000000000000000001456262201400246360ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/cmd/import.py000066400000000000000000000046661456262201400244370ustar00rootroot00000000000000import logging try: from gi.repository import Gio HAS_GTK_GLIB = True except (ImportError, ValueError): HAS_GTK_GLIB = False import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['shell'] def get_deps(self): return [ { 'interface': 'gtk_doc_import', 'defaults': ['paperwork_gtk.docimport'], }, { 'interface': 'gtk_init', 'defaults': ['openpaperwork_gtk.gtk_init'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser('import', help=_( "Run Paperwork and import files passed as arguments into a new " "document" )) p.add_argument("files", metavar="URLS", type=str, nargs="*", help=_( "URLs or paths of files to import" )) def cmd_run(self, console, args): if args.command != 'import': return None if not HAS_GTK_GLIB: LOGGER.error("Cannot import file without gtk and glib") return None self.core.call_all("gtk_init", self._cmd_run, args) def _cmd_run(self, app, options, args): app = self.core.call_success("gtk_get_app") # when no file is specified, we still start the GUI, because the # desktop file always calls paperwork-gtk import (see install.py for # the rationale). if args.files: files = [self.core.call_success("fs_safe", f) for f in args.files] giofiles = [Gio.File.new_for_uri(f) for f in files] LOGGER.info("Will import files %s", " ".join(files)) if app.get_is_remote(): LOGGER.info("Passing control to main paperwork instance") # open the files, possibly in another process app.open(giofiles, "") else: # possibly in another process if app.get_is_remote(): LOGGER.info("Passing control to main paperwork instance") app.activate() return 0 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/cmd/install.py000066400000000000000000000120001456262201400245500ustar00rootroot00000000000000import os try: import pkg_resources PKG_RESOURCES_AVAILABLE = True except Exception: PKG_RESOURCES_AVAILABLE = False import shutil import xdg.BaseDirectory import xdg.DesktopEntry import xdg.IconTheme import openpaperwork_core from .. import _ ICON_SIZES = [ 16, 22, 24, 30, 32, 36, 42, 48, 50, 64, 72, 96, 100, 128, 150, 160, 192, 256, 512 ] class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [] def cmd_complete_argparse(self, parser): p = parser.add_parser('install', help=_( "Install Paperwork icons and shortcuts" )) p.add_argument( "--user", "-u", help=_("Install everything only for the current user"), action="store_true" ) p.add_argument("--icon_base_dir", default="/usr/share/icons") p.add_argument("--data_base_dir", default="/usr/share") def _install(self, console, icondir, datadir): assert PKG_RESOURCES_AVAILABLE png_src_icon_pattern = "paperwork_{}.png" png_dst_icon_pattern = os.path.join( icondir, "hicolor", "{size}x{size}", "apps", "work.openpaper.Paperwork.png" ) desktop_path = os.path.join( datadir, 'applications', 'work.openpaper.Paperwork.desktop' ) appdata_path = os.path.join( datadir, "metainfo", "work.openpaper.Paperwork.appdata.xml" ) os.makedirs(os.path.dirname(desktop_path), exist_ok=True) to_copy = [ ( pkg_resources.resource_filename( 'paperwork_gtk.data', png_src_icon_pattern.format(size) ), png_dst_icon_pattern.format(size=size), ) for size in ICON_SIZES ] to_copy.append( ( pkg_resources.resource_filename( 'paperwork_gtk.data', 'work.openpaper.Paperwork.appdata.xml', ), appdata_path ) ) for icon in ['paperwork.svg', 'paperwork_halo.svg']: src_icon = icon dst_icon = icon if icon == 'paperwork.svg': dst_icon = 'work.openpaper.Paperwork.svg' to_copy.append( ( pkg_resources.resource_filename( 'paperwork_gtk.data', src_icon ), os.path.join( icondir, "hicolor", "scalable", "apps", dst_icon ) ) ) for (src, dst) in to_copy: console.print("Installing {} ...".format(dst)) os.makedirs(os.path.dirname(dst), exist_ok=True) shutil.copyfile(src, dst) console.print("Generating {} ...".format(desktop_path)) entry = xdg.DesktopEntry.DesktopEntry(desktop_path) entry.set("GenericName", "Personal Document Manager") entry.set("Type", "Application") entry.set("Categories", "Office;Scanning;OCR;Archiving;GNOME;") entry.set("Terminal", "false") entry.set("Comment", "Grepping dead trees the easy way") # It's possible to add several actions to a single desktop file. # Ideally, we want a main "Open paperwork" and a secondary "Import # these files to paperwork". Unfortunately, the specification does # not allow specifying different MimeType= for the main and secondary # actions. So we always import (possibly 0) files. # https://specifications.freedesktop.org/desktop-entry-spec/1.5/ar01s11.html entry.set("Exec", "paperwork-gtk import %U") entry.set("Name", "Paperwork") entry.set("Icon", "work.openpaper.Paperwork") entry.set("Keywords", "document;scanner;ocr;") # PDF and all image formats supported by pillow entry.set( "MimeType", "application/pdf;" "image/bmp;" "image/gif;" "image/ico;" "image/icon;" "image/jp2;" "image/jpeg2000;" "image/jpeg;" "image/jpg;" "image/jpx;" "image/pjpeg;" "image/png;" "image/tiff;" "image/webp;" "image/x-bmp;" "image/x-MS-bmp;" "image/x-png;" "image/x-portable-bitmap;" "image/x-portable-graymap;" "image/x-portable-pixmap;" "image/x-tga;" ) entry.validate() entry.write() console.print("Done") def cmd_run(self, console, args): if args.command != 'install': return None icon_base_dir = args.icon_base_dir data_base_dir = args.data_base_dir if args.user: icon_base_dir = xdg.IconTheme.icondirs[0] data_base_dir = xdg.BaseDirectory.xdg_data_dirs[0] self._install(console, icon_base_dir, data_base_dir) return True paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/000077500000000000000000000000001456262201400227055ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/__init__.py000066400000000000000000000000001456262201400250040ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/make_icons.sh000077500000000000000000000006301456262201400253530ustar00rootroot00000000000000#!/bin/sh for size in 16 22 24 30 32 36 42 48 50 64 72 96 100 128 150 160 192 256 512 ; do echo "Generating icon ${size}x${size} ..." source=paperwork_halo.svg if [ ${size} -ge 96 ]; then source=paperwork.svg fi inkscape -w ${size} -h ${size} -e paperwork_${size}.png ${source} if [ ${size} -lt 256 ]; then # max size for .ico files convert paperwork_${size}.png paperwork_${size}.ico fi done paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork.svg000066400000000000000000000056651456262201400254540ustar00rootroot00000000000000 image/svg+xml paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_100.png000066400000000000000000000066251456262201400260160ustar00rootroot00000000000000‰PNG  IHDRddpâ•TsBIT|dˆ pHYsÓÓ'œb6tEXtSoftwarewww.inkscape.org›î< IDATxœíÜ8TéðW»›mµÕFjwÑ/mZõÔµ¤Ómó`Í>f<ƒ(ÜÒÆ>.Úð¸%?—¡n¥®’vY2¥z´Ïr’¨Ö–üÚ%„±2cŒÉ˜ç{ÿh¹aÌÌ¡ÎçÏcÎ{Þ÷ûuÎ;ç=ß9‘H$‰D"‘H$‰D"‘H$iúS#º¤ç>þøã jjjÿ"B0êüùóÃD"‘‘D"‰#BŒ e—¾¾þ.uuõÏd2™ºH$ªHKKÛ8ƒèž½aÔ­­­ÿTúÝwßÕÐÐ0ž?¾º‹‹‹¨¦¦æ0Bˆîà›BËÒÒ2òèÑ£x<ÞÙÙ‰ïܹ³/33³_&“NÏ"ºƒo„¥K—®tppø>!!¡íÙ³gŸŸß»}ûvqii© 99™£««»œè¾¾Ö )žžž™ééé\©T 8ŽÃ·ß~‹Ñétq{{» @(‚­­í ¢ûûºš±nÝ:¦‡‡GÎÍ›70ŸÏggg¾¯¯¯dàL8räHBhÑÝÌ433ó÷öö®¨­­•À0wïÞí³µµ„……IqÜÞÖÖ&ݺukÑÌÙ±cÇáðððOŸ>Ň' %%Û³gO_ZZštøß¼½½KBo=ˆioîܹˬ­­“X,V£P()Ð××û÷ïçKKKKe#œ5BccãDeZ344Üììì|åüùóƒõHêêêúœœ°£GBSSÓˆg“ɼNôx¦- …bëããs½¸¸˜?jþrùòe¾››[OTTôööŽø™ôôôŽåË—¯&z\ÓÍLSSS_OOÏ’êêjÑX‰H$pèÐ!^DD„(..d²—®RÐßß4í,у›NæØÙÙ yÈápF¼Ü ×ÚÚ*uvvÆ222𬬬W~6::ºáý÷ß×"zSž¦¦æÇt:=áøñã £MÔ#ÉËËëuwwïNMM…ÂÂÂW~öÉ“'2ssó=Ö)mÕªU3Ï;×.‘¼t 1*Ç!""‚/ˆ…G¹¯¯ï„Ð;DyJÚ´iÓvœ«W¯öŒ; yúô)îææ†J###¡»»{Ì}ªªªú(Š ÑãžjÞÙ¼yó?||| «ªªú&š€²²²g...Xee%ÄÅÅÁxÏ*—<¢?•¼O¥R#üüüî·µµ~1†'N`aaaüüü|HMM÷~×®]{jhh¸žè NKKë#‡c111 㹬ŒF À¾}û°7nHØl6{_‰D;wîüžèXJOOï3ƒq!%%¥m"õHªªªúœœ0.— ÇŽƒÚÚÚ íüøñÇZZZB¬_¿Þ–Á`ü”••Å›Tþ’œœÜíïïuuuÁáÇËåNhÿ®®.°°°ˆ&:.ª6ÃÌÌÌí믿¾QYY)×D=œH$‚ÀÀÀ®+W®ˆêëëÅbX,žp;ü !ô.ÑR•ÙA,oii‘{¢®¹¹YÊd21‡¥¥¥œœ,W;õõõâ-[¶ì%:HJ·`Á‚E4íThhh†aŠÊdeeõxxx`8ŽÃÅ‹!77Wî¶ÜÜÜŠÐë\„¸xñâU»ví:wáÂ…Vy.¯"•J!,, KNN~&•JáÌ™3PUU%w{ùùùØÚµk·3¥000 :;;_¹zõ*oèãOEéììÄ]]]±ºº:™@ €¨¨(xòä‰ÜíÉd2`0™DÇMÑfP(÷Ý»w—–••=; òÉÏÏïe2™˜X,†ÖÖVˆ‰‰¾¾É}/HJJâèéé-#:€Š¢nccãwèС²ÇOîâp‹Å‹í¸}û6$&&Nº]@ÖÖÖÿ&:ˆ“6{ölm*•z,$$ä!§[ˆQñù|ÜÍÍ­«¼¼\ 999 i;44´ !¤At<å¶dÉ:þ}BBg²—Šñ¸sçNNïêííÇ!)) îÝ»§¶[[[%Û¶mó#:¦rY³fÍß===3¯]»ÆUÆD=’³gÏv…„„tôööBXX´´´(¬}//¯[¡iU¸>ÃÈÈÈÙÅÅ%¯¤¤D0öc '''GÀáp ::&òTp,·nÝê122²%:Àã¥neeåçççw·®®NiõHjjjÄ £«³³îß¿'OžµA8Ž“ɼFtÇc°ü~´ª>eb³ÙÝÞÞÞƒkîÙÙÙ0V‚<ÒÒÒ:ôõõ ‰ö¨tttVÐh´ó,«ihQ±ª ”ãüðÃÏžÿŸ;wJJJ~¬¾¾>°µµM":æ#(¿ÏÈÈxeUŸ2µ´´HœœxMMMð|Õ666š››•r¼¨¨¨ßBóˆŽýPj¦¦¦ö>>>×oÞ¼9ábEÊÉÉéÙµkW÷À?—Ë…ÈÈHàóÇ,6”KGG‡ÌÜÜ<„è ˜iffæ¿wïÞòššš1«ú” ÇqˆŒŒì:uêÔàצÊÊJˆWèä=Üî „Þ&:sìììŽ?looWùD=—ËÅ]]]± F¾  @)“÷PB:aY˜;wî2vr¢U}ÊTZZ*¤Óé˜Hôÿ455uBòb2™ÿ%$«W¯Þ4žò{U;yò$>xs)‘H !!~ÿýw¥;++‹»råJc•&bÓ¦MÛ}||®çææ:Q×ÓÓžžžXQQÑàǃÈÈHPôÓшÅbøâ‹/TVÒ3ÓÔÔÔ×ËËëfuuµòWú&¨ºººÏÞÞ¾{h}Õü!w‚<âââ544);oëëëï–H$a[¶lA .”p[ZZæ~òÉ'stuuÑ;ï[|þüùîG͸téÒÜm¿üò âp8ÈÏO5 ¬†A^^^†P(ìPö±FzÿBHgÅŠ«?üðÿéêê.]ºtéÊO?ýt…¥¥¥¶¦¦¦²û„BH$¡€€ÌÂÂâ½;v¨lÏÈÈ@šššÈÒÒR%ý@!ÿßX,ÖF„P¿Ê:Z¦¦¦û÷íÛw=55õOe>误;99uutt n“J¥pìØ1¨©©QÚqGR[[+Ú¸q㢃ÿJ‹¨TjtHHHÅÀ[ …Ífó‡. <ŸÐ£¢¢``åV•\\\ Ñ4*éy›B¡ø”566Njy]"‘@PP/%%å…UɆ†`±XÐßß?¹ÈÊ!//[³fÍV¢ƒ,5 …âü+†a¾‹ooo—:;;c /ì{ûöm¹«'K*•‚½½ý´/éy—J¥F'&&6Žw-é矸»»cÃ+Õ333V€ ÄÄÄÇ‹-ZBt@BKKë#GGÇÌòòò‘¬ Ïãããy,K0|ûÙ³g¡¢¢BùQEOOX[['G…[¿~½S@@ÀoÁ‹Ñù|>îîîŽÝ¹sç…5™êÁ¡ß®ˆüMç’ž1ÌúòË/O\¾|¹ ¼¼¼ÏÑÑ‘?|¡²­­ bbb€ˆ'C566J?ÿü󯉚ҭ[·n3ƒÁ¨ i¬¬¬ NŸ> ª* z•={ö” iVÒ#7vzxØl6dddû—÷Û#•>õ€ÞºyéÒ%À0LmöìÙ()) Íœ9‰ÅbôðáC¾ººz­––Ö{zzz‹ÌÍ͵µµµ•Ý7”˜˜xãÞ½{?)õ@cPiBÔÔÔ^¸ãmjjÂ_â%“ÉP@@@Evv¶CKKKã_›çÑV­ZEY¼xñеkרÙÙ-˜5k–Bû–––ögII‰¿Bê†^²ŠŠŠÄÅÅŃkç"‘¼¼¼JµµµŽÑ̇6lúꫯ~d³Ù*â^(‚Í•a*šÁH puu-D|!ä| gccúkss³ÜK7oæË(R]]-¹xñ¢€Çãá?¢Éýbõ-·½{÷æL¨ö‡ÃáH·nݤ¨1N+ ùæ›o„‰šššÄ–––Hs™ÁFƒq133“3žå›ÜFoêË(i4ÚéÖÖVi||¼ ººú™••Õ)¤¤¥m}GGÇ´ôôô?GKÌÝ»w…&&&ŽÊ8þ´@£ÑNb¹¹¹=ª8æ¼yóÛÛÛ']¸p¡}xõ “É$ô+.á¨Tjб±q………Êm4<1l6›k``ð™ªû1¥èèè711q'²zzzËìííÓ¬¬¬þCd?H$‰D"‘H$‰D"‘H$‰D"‘H$‰4åýUàòÆ\ñIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_128.png000066400000000000000000000107071456262201400260240ustar00rootroot00000000000000‰PNG  IHDR€€Ã>aËsBIT|dˆ pHYs,,ÄgñÏtEXtSoftwarewww.inkscape.org›î<DIDATxœíÝyXS×¶ð-EÄ ´…‚×|¢ B$PÆ„¦ŒjlµöøŠ `W¼¥EEÊëí+ ꫵT-(ôõ£J©öŠ–A¥È¤ ‚@B²Þ “lÄýû3ÉÉYg­“䜳÷ÊAˆ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ˆécî<”••³fÍò%;ÀFCCÃQAA!žÏç/Ÿ5kVÙÞ rºººÛ—-[æ-Þ›9sæÌÎÎÎûyyyzr¸##¤jžŽŽN„Ýío¿ýöÄìÙ³ (Š<‹ÅêjllôGî éP366þŸO>ùäAUU•¸®®Nljj*üæ›o„<ÌÌÌ2qHHÁüùóWYXXüRÛÖÖçÏŸçéëë÷fee •””V⎕ †™™Yvttt3Ç‘Hþþþ+++ÑÇÅMMM°nݺ$Üñ’!§££ãnooÿWJJJ—H$‚>---À`0x,«·£££ÿñ;vT „”qNLÎ,ƒÀ-[¶Üºqã¹zõ*ßÔÔ´ÛËË«W(ö?^\\, R©¡¸ƒ'&NÕÈÈ(ÑÕÕµ²¢¢B4¸ðb±¢££ÙL&³'66¶wðóvvvE!yÜAŒ“’’ÒJ ‹3¡¡¡Z[[×:;;aË–-ìmÛ¶õ^ºtI<øùsçÎu®X±b îm!ÆaÉ’%&666£££›¸\î°…¸uë–À‚ëááeeeCŠßÓÓÙ¸·‡9wkkëÉÉÉÏØ '))‰kccÃÛ³g¼êÛ!22²iáÂ…z¸7ŒÙ,¶ëÖ­·rrrºG¬:twwÃÎ;9~~~=!!! †}][[˜˜˜ü€{ãˆWS144<¶}ûö{ååå#Ü_¨ªª1 nTT”866vÄ×zxx<@½ƒ{#‰A”””4ÍÌÌ~ôóó«nllKÝàùU=[[[NLL dddŒøÚòòr‘¾¾~$îm%X²d‰1ƒÁH‰‰yÂápÆ\x¡P~~~]AAA<())u{{û„îm&š±lÙ2›?’““Û^œ‹††±­­-755µ×ÇÇšššF]&++‹­¥¥µ÷†¿éÖ®]àèèx'##cÔ»W’Ï`0¸ÙÙÙ°oß>è»Î?‘H9¸7þM¦dll|ÈÝݽ´¬¬lLvƒ‰Åbg{yyq~þùgˆ‰‰ó²qqq­K–,1Æ„7Ž¢¢"ÅÄÄ䤗—WUCCÃDêOŸ>…Í›7sÓÒÒ„G…ôôô1/ÛÕÕ6løw.Þ(êêêëètzÆ_|ñdàÈÛDäçç èt:§ºº‚ƒƒ¡¨¨h\ËûùùÕ „áÎÉA[[›ioo999¹m¼vÉ‹‹c;;;³ÀÃÃêêêÆµ|uuuï{g;/Ó‚žžÞ~ƒq;==}ìçq#`³ÙàââÂ=~üxÏ;w`ÿþý0ÒµÿWa±X÷Bsp'hºšoddthçÎ¥%%%“ÿ¸¿pÿþ}ƒÁàTTTÀ…  ""z{‡ŒäŽêúõë</ÜIšŽÔMLLþåíí]YWW7d¤m2Ž?ε··g HLL„””” ½Ooo/0Œ|Dš|$GEEÅÀÄÄ$#88¸áÙ³g’¬;ðù|Ø»w/çðáÃÝ|>!''gÂï—””Ô¦¡¡AdziASSó};;»ß“““Û^5Â6µµµâ÷ߟ[PPÐÛÚÚ ¾¾¾ðèÑ£ ¿ǃ7þî¼½îfjkk{ØÚÚæ]¼x‘-Kô›¾_ZZN§s8”––‚··7tvvNê=CBBê—ãNàëj¾A”££cY~~~„ê<„H$‚ÐÐPvPPàÒ¥K>¡ƒ½ÄFFF‰¸“ø:R311ùvïÞ½•µµµÒù¸¿ÐÒÒ"¶µµåüöÛo½ púôi‰¼·››Û}„îd¾6æÎ»ÖÔÔô\HHH]_׌4]¹r…ommÍiii¡PáááðçŸJä½‹ŠŠztuuqçôµ@¡PlètúŸGŽiëîžÐ Ü¸ˆÅb8tèP×Î;9ϧeyyyAee¥ÄÖñÁ"„HcïätuuwØÛÛç^¼x±KZvƒuvv‹Åâœ9sFðàÁøôÓOA’§’))) Å w‚§ªyT*5lóæÍʹ¹R;°NQQ‘€N§skjj ;;>ûì³WNØœˆžž077¿Œ;ÉSÑ»}íЕ••²ù¸ÀÞ´i§o÷É“'!!!Aâ뉈ˆh|çwVãNö”ñ¢úLHHHíÓ§O%žðÑôMÏŽïx~Ê ™™™_Wss3¬_¿þ4îœO jjjÖ–––¿ÆÄÄ4eš”4TVVŠèt:÷îÝ»ð|2ƾ}û ¼¼\*ëÛ½{wBèmܹÇINGGÇÝÁÁaH;´¬¥¤¤p™L&§ï¬¢ºº<==¡¥¥E*ë»wïžpíÚµq—Y4m?‹Åºuýúõ!íвôbz6;<<¼ÿ|ò¯¿þ‚ÐÐPèé‘Þ1§““Óm„ÐLÜ…5Õµk×þËÙÙ¹|¸vhY«¯¯3™Lîµk×ú¯áž?âã㥺ތŒ öªU«\pCf”””Vš››ÿ8R;´¬]ºt‰gaaÁí›ó'‹!66~ùå©®W(‚¹¹ù¿q×D&úÚ¡cbbFl‡–¥¾éÙ>>>ýGš|}}¡¸¸Xêë?räH“ªª* wm¤INKKkûXÛ¡e©µµ¹éééýA544ÀX»s&«½½ŒÏá.´ô·Cgeea=°N^^ßÒÒ’óøñãþÇòóóÇÜ# >>>#„ÔqJÒ”MLL§ZÖâââØ.../U955bbb@Vc >ì544<‚»X£¬¬¼ÂÔÔôœ§§gÍxÚ¡e©«« >úè#NrrrÿùœX,†øøx8{ö¬Lca±X¥!EÜu›455µõt:}ÜíвVZZ*´¶¶æ ²íîî†àà`¸yó¦Lcùã?¸kÖ¬ñÀ]»É˜A¡Pœ.O¤ZÖ’’’¸Üq>~ü<<< ¶¶V¦±ôöö‚µµu.zM§x+P©TÿÉ´CËŸÏOOOvTTÔK±Þ½{&Ô3Yß}÷]…B1Ã]ÈñRZ¿~ýá;v”–––NÉ»Á=z$b0Ü‚‚‚—Žê233áóÏ?Ÿô„͉`³Ù`jjš»˜ã±ÜÐÐ0ÉËË«²¾¾^æ ›¨ÔÔTNç þ„'$$À™3g0ET§¨¨øÜEÕÀvhIwÍH“P(„°ƒ‚‚^:ÅëééÀÀ@¸ví®Ð ¾¾^lddôîÚŽH[[›igg—%©vhYjnnÛÙÙq²²²^ú‰zúô)øúúBß4.\ÜÜÜÊBsq×x8 +W®ô³²²*LOOçÈêBˆ$eggó­­­¹ƒ–îÝ»ÞÞÞ0Ù?u˜¬ÜÜ\¾žž^îB6ßÈÈè³³sÙÍ›7_¯û b±"##Ù»vír8Ÿ••Ücb±˜LæM4…¦xK­Z–:::€ÅbqΞ=;dç=yò$$%%ákˆï¿ÿ¾cÅŠà.:RQQyÏØØø—ààà†öövÜy™”ÂÂBNç>3 …pðàA¸zõ*¦È^ÖÝÝ 7n¼„»ö3–.]Ê’——ÿbõêÕí³gÏÊË˃¼¼ülEEÅ9 ó)Ê­ªª ÂÇh¦Ò€B0øøøxPSS›ñöÛo£ÂÂBÄf³Bµ··£ÖÖVxðàA‡ªªjý»ï¾»@__¡™™ÙüÅ‹Ë<𺺺PJJÊÆÆÆ|¬ŒÁ”Úf ÄG‰D"T__/>pàÀ[ƒ_{ëÖ-··wVaaáV„=ï¥[µzõêM‹/6X´hÑ2sss [[[•¥K—Êh žûꫯêîܹã+Ó•N®®®ùGøááÀ¿désåʶ¾¾þ÷hô¹tZT*õ ‡ùå— ²hõª©©é¥Ñhÿ-ƒtM?ƒw€Ý»w9¼páÂ3*•:‘¿«§§wÐÉÉéÚ‘#G&}‹·Wqqq)CäæM3pÈÌÌüøã/]Ü?qâD F ‘Àª¯[·.vëÖ­wsrr$ö7nÜàëêê~*øÞLwgggþÀ‰±±±õôô$Ý6­°jÕ*;;»œS§NMª“Y,ƒMzM;{§„¾   @pøðav_bë׬Y#ÕqôE‹ÒéôŒˆˆˆ¦‰ü<œ8q¢]CCƒ!ͧ½¾ÀÕÕ•ÛÑÑ"‘vïÞýpùòå–²ŠAIIIóÅ%jÇ:EžÇãÁ† ~“UŒÓ–››[ÁÇÅ~~~l>Ÿ®®®åêêêk0…£j``ìçç÷÷h3 Ã•””VbŠsúpss+صkWGII‰ØÑÑñ΂ ¦B»ôˆ;Bcc#¬[·.wÓƒÁ(µ´´äØØØ#„ÞÁÏ ÃîîîîˆÜ¼I2TTTê)Ê]„Ð<ܱŒ@F£®ÎÎÎR©Ô0ÜM ,ˆ@)àŽcŒÔ455cBC.SAAAAAAAAAAAAÈÂÿyd›(oltfIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_150.png000066400000000000000000000123561456262201400260210ustar00rootroot00000000000000‰PNG  IHDR––<qâsBIT|dˆ pHYs<<*Æ€†tEXtSoftwarewww.inkscape.org›î<kIDATxœíÝ{\“×ùð£Cƒa ´¢ ! # ˆ‚Ú"ke/UCG­­m•­¨íçkµ›VÜD†£2üQ¬³x«ý¨€X,Årå"r'JÞ7äòüþ¨P@K.'àùþ™„¼OÎy ‡÷}Ÿç DAAAAAAAAAAAñ™„;b±522Zý+ÜQ†£Í™Læ§ £›üÅ"ÔbjjºhÖ¬Y± …ÂËÀÀÀ°«««µªªj&ù‹EŒÅä™3g®b±X'£¢¢Þžÿ{D. ¾Ø˜L¦»‹‹Ëב‘‘ µµµCådddȸ\.EEEƒ¾&..®ÅÂÂÂ÷ç"0±´´\Ìãñ¾ÝµkWK{{ûsJ.—ÃöíÛ»h‘H=ôuMMMàììü îÏFèÞÔ9sæl …E'Nœx{ö¬rçÎpêÔ©Qý|TTTÃÔ©Sp¡###W>Ÿÿb±¸¦¦¦F|€ÔÔTjþüùTEE¬]»nÞ¼9ªŸ¯¬¬Tq8œãbŒ,,,üÝÜÜ®ÆÄÄ4µ¶¶ªPr¹¶lÙ"ˆˆ +++A$ÁXuùòåU!sÜãCŒÎäY³f…ñùüï:¤R©Ú ðàÁðññ¡¿øâ ŵk×`ýúõÐÙÙ9ê÷¹|ù²ÌÁÁ!÷ #÷k‡}>>>e™™™ÔXäƒÉÎΦ=<<¨êêjHJJ‚;wŽx‘Þ—R©OOÏb„ÐT܃E ï·'qéÒ¥•999j-ÈR©T°wï^髯¾JÉd2øÓŸþ)))c~¿cÇŽuΞ=[„{Àˆçsàp8ÿ ¹_^^®¹lzª¹¹üýý©¿ýíoÝ?†7·ß~;æ÷{üø1¸¸¸R.}eaaá/.îÚµëQKK‹æ2©¼¼¼n@@ÿøãP[[ aaa nònß¾½‘Édzà?¢¿žù­„„„vM-ÈsèÐ!©ŸŸEQäääÀºuë`¸{®†S[[ ÎÎÎgp"ñ ‹ÅŠž?~Qrrr—B¡Ñ%T?‰V¬XAíÝ»—HKKƒmÛ¶Á`…£µråÊDJ¹ôÂoØlvâ²eË*¯_¿®þÌ£¤¤D! é«W¯öÜöGŽÑÈ{çææÊY,ÖǸôEgÏápRCBBjJKK5w¾à9þñPžžžtGGPQQQpîÜ9¼·J¥ooï2DJ¹ð077ŸïééyvëÖ­ ™ÔáPo¼ñ†ô­·Þ’Ô××CXX”””hì§Nz2gΜHÜãû¢™‡{À'ºÞ¶=ÅÅÅ:YTWW¾¾¾ô‰'ä?—¹oÞ¼¾úê+­/""¢!dƒ{à'¤>m{êêê´2#qñâE9Ç£{Μ777CDDܾ}[+Ç+,,T:::&âÿ‰f’••Õ*¡P˜;XÛ]R©T°gÏi@@ݳŽ+**‚Õ«WCcc£ÖŽëïï!dŒ{"&ŠÞ*a òZZZ 00Žï-W>þ<üám^:sæŒÔÎÎn;îɘL,X° b¨¶=ºvëÖ-¥»»»¬ï퇆ýû÷ƒ&ïѨ»»x<ޡɸ'e<³uuuM ½{çÎÑßñ¦%¤,X@÷|Ëårرc¤¦¦jýØñññíVVVA¸'f\b2™|—¯ÅbqýH 2uåñãǰråJzçÎtÏc­­­°fÍšU#««­­ ¸\îeÜó3î<­þ6&&¦YÝ[H4íi–,;;»÷{®¢¢D"Œ¶D~¬"##ë Æ\Üó4^Lµ±±Ù2š¶=º–œœL º¹¹¹÷± .€X,q5²ºÊÊÊTç_¸'k<0îÓ¶gÌUÂÚDÓ4ˆÅbjíÚµtßÇ?±±±c*t«ÀÀÀ{!3Ü“¦Ï¬zÚöäççëÍ‚| €···ì?ÿùOoŒ …bbbàóÏ?×i,/^¤Y,V,î‰ÓKFFFn...ç6mÚTwÿþ}NÌheffÊ<<<è¾ÿ8H$xã7à»ï¾Ói, …A1Bh î9Ô+ê¶íÑ%…Bï¾ûnWPPÕ÷kîÞ½{ ‰ ººZç19r¤ÓÚÚ:÷<ê‹Þ¶=‡nkÛ]jjj‚E‹чîw:ÿúõë°~ýzèèèÐyL‰œspO¦>ÐHÛ]»zõj7ŸÏ§ÞÕ™œœ ;wîmW©««K@ɰ¢E¿e³ÙG—.]ZyãÆq³ LEE…J ÐçÎëw¦¿§Ð!!!WhýH¥Ràr¹vW®Þ¶=¸×šðå—_R|>Ÿzøða¿Ç{ª‘Ïž=‹)²g½ÿþûMfff p'€F=mÛsI›m{t©§ kÕªUôÀç ,, Š‹‹q„6¨ÆÆFpvvΚÒ[%œÐ®Ë*amª««úÔ©SÏ|…BxxøÛ®á"‰jB³q'„ºöööïè¢m®eggË\]]銊ŠgžËÈÈ€­[·j¼Y]?üðƒÒÉÉé3ÜI¡Žß8::]¶lYåµk×ð–¸h˜J¥‚ØØX髯¾J ö‹ÒSè üýýËBF¸“c,zÛö”””Œ x£ÐÒÒK–,¡:ôÌí§4MÖ-[ 33GhÃJOO—ÚÛÛoÅ £Ò·mO}}=î1ÔŠ¼¼<¹@   Ÿy®¥¥"""   CdÓÉdÀãñ Ñ8)åêYçëºm®:tˆZ´h5Øm9wîÜÕ«WÃÀÓ úäÀ­æææ‹q'Ìp°¶íÑ¥ÇCpp0µgÏžgN%|óÍ7ðæ›ojµY]­­­àêêzwÒ<Ït6›½ßÏϯD_ª„µ©¤¤DÙÓÇs0=Û®éû½`6lh`0,ÜÉ3˜I&&&Ë•Jeª½½}—­­mç”)STr¹|Ú´iÓ¹¹¹áìÙ³ ííí§Ï›7o ‹ÅÂ~L]IIItJJ :þ¼áôéÓû=§P(Ð{gx<Z³f ¦G¦´´TúyIIÉ&ܱ f¸ëI&¡™ÖvvvÞ†††ü3fX½ôÒKK–,±X¶l™ñ¬Y³t§ÚhšF‘‘‘”±±ñ¤cÇŽ|¾­­ EGG£mÛ¶!@€#ÄQ ¼wéÒ%w„P'îX4‰a``à=oÞ¼c .Ìߺuk&­jZUU•ÊÓÓ“ÎÈÈ´TìîÝ» ‰@ß+z\¸pvppxwèÂKl6ûC¡PXôÁ´j²ñªºÎœ9#sww§‡:UrñâE‹Å€³?Öh( ðððø éî–'ý0mÚ´ù\.÷¿¯¿þzeAA¶bÒž CCC¥C-Â?>æm×pùôÓOÛ_~ùå×pÏ3N¿f±Xû½¼¼ÊuýŸfSS,Y²„>~üø çK üùφ“'Oê2,µI$pssû÷Äê †Ýn__ßâóçÏk½8ðÒ¥KÝ|>Ÿj,‰D6l€¡N5è³-[¶4¹àžP}c`mm½mñâÅ%EEEÿîéÙréÒ¥Ò¡ºÍTUUAXXTUUiúðZWUU' ÷$ê3¦““ÓÇaaa5šÚ2¤³³‚ƒƒûõñèÆ°nÝ:,ÕÈš°bÅŠ*„îÉf:;;gÅÅÅ5©ÓÏ*??_ÁçóéçuÃKMM…èèhl»†Ãõë×»?Ä=a㊩©©Ÿ»»{á7F]‰‰‰Roooj¨S=ÕÈŸ}ö™Ú“‹‹R©¡PXŠ0–rgSØlö~‘HT;’{å)Š‚ððpjÇŽƒ^@xòä lÚ´ ._¾¬Ñ‰Öµ¤¤$‰µµuî × †=—˽vâÄ ÉP]^^®²óçÏy…¸§¹´´T;³­#R©ÜÜÜȦߚbkk»1  ¼ººº_ò¤¥¥QB¡°_Ïnß¾ áááð¼×Œ111M&&&ž¸çc¢1uqqùb÷îÝÍ]]]ðöÛo?ÓÇs Ó§OCtt4ècsÛѪ««‡“‰{&,KKËGGÇÎ/¿ürÈs_ÚÜv —ÐÐÐD6ýÖ.//¯›CM@϶kYYYºœw­*((P°Ùì¿âwuŒë+äwîÜA‘‘‘ÈÐÐ)•Jôõ×_£éÓ§#SSS4cÆ dmmlll xSŸ>Û¾}û½ÒÒÒ÷qÇ¡ŽqXIIIžž>iöì_Š)ŠBííí¨½½]»vMSo``clll9cÆ ‹—_~yzPP¥ŸŸßT33ýkyž––ÖU[[û)BˆÂË„7ØWaKK ˆÅâ!˯óòòdç BhÚ€·3a2™ÁsçÎMY¸pá͵k×ÞKKK{¢½&hšG6ýÖ•ÁkÏž=²›7oº ¿pá‚ÔÉÉé+4²¿ÈFL&ó—Ô€€€â£GvàJ²}ûöµXXXM¿ue`buuuÁÊ•+=§’’Òaooÿ9Ûoý¤iÓ¦ys8œÔÀÀÀŸþþ÷¿wH$Cž«Õ¨§›~gkzìˆçðööÎï; ”eee=sEùàÁƒ­ŽŽŽ :ìdCCCßyóæ}µzõêŠÂÂB­Þfº~ýúZ„­†b'F¢obuwwƒ¿¿¿làíÄqqq,+FK!˜988|äëë[”œœ,ÑôfwîÜQ²ÙìZŠJßÄJII¡=Ú;³*• 6oÞÜ`gg·Q¡L233[Îçó¿Û»wï#Mm¿@6ýÆ¡ob-\¸°÷6™L!!!õ³fÍú®cb0¬§ýékÔ)ËÊÊ¢æÌ™óG]ÇO _ëìÙ³²Ý»wK~^À/[¶¬ÊÜÜ÷EZk‡ó/‘HTU^^>ªš|¹\E¡ñ×Bz"èI,__ß®‡B[[øúúV;Ꭽ3GGÇ£ÁÁÁ÷ÊÊÊF”`Ÿ|òI»¥¥å Ü¿°¼½½óóóó•kÖ¬élhh¡PX‚²Æ×F”`íííÀår¯âö…æíí¿|ùòެ¬,ÕÓ3Ó㡨๠ÕÀ`0qùBc³ÙeVVV²yóæ}‡Æ_ŸÍÞ+--UTVVª8οqö›1cÆO³gϾ„šŠ;5˜±X¬c+W®¬ô÷÷¿È¦ßø™™™mBã¤Çæ˜úâ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚ ‚Ð_ÿîÑ7Œô˜IEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_16.png000066400000000000000000000016461456262201400257420ustar00rootroot00000000000000‰PNG  IHDRóÿasBIT|dˆ pHYsÆÆ°t›ÅtEXtSoftwarewww.inkscape.org›î<#IDAT8M“ÛN\e†ßïûÿ5k3³Ö0æH›vZ ‚›hŒÕxì ¨1ñ><ô¼ õ̃zb‚¦1¡*iÒÖ–"²  ³ß¬µþ׃ªñ9Ÿ“7À:i6ÓaÆ<f¹ñ 2* P›+\êœA²AV`Ç®Î4>ÉÍýûô;­Ö‚R'i´ hE +ªZHYDb–@‘ˆñ 6“‚ÖG>/OCùf³U3Š È²#8”  !RaDNáH>TºƒÎeZêîtvôç’5Š ]V¥“ eˆÆŠt °"JªËàdØï]䝨ÞÚíª÷ž™šó‚âÔ—Ö‘‰À”)®"@‚²ˆÄ "‚@fã!‹Ù¥›So¶;ÁÈ÷=Ó¤[í¢¿g é$AB`d•À„¥l<,ΗòÙ•[Éüd9 žn=¿œ¬–£©j¥°ñËþ÷¶GV)ƒ ©Á±$* ǃ™ªíÕVk•ékSU›¦)lüÖ}e).'±÷û‹ãGŒfÎAÖÑYQ±€x.í'×c·¶|sâV¥<ë@¯?äîþAþÖÚJP*F:òízºÁ€ÅY ã~³T«Ú÷ïÔ*ïNÄ¥ÿp\?wõú –—n›( ¶[Œ&BR`hG‡›|øÎòǯÎ_ŸÁÿxqp2°Èü7V_Sk_¾Ùë²½K÷+ :&˜ÌÌç_|eö›|xZ?í%¡Y ?xº½wá[/.,¨1æ?éãÝ“ÇMW~Da[mçØ¶®çy^ëŠÕŸ~Øêü1ïýõÙtâß Ãd¬ªþ¿ãN·?Ø»”%tWâØVÑŽéZÀ¶H±€•8ôŽ;g^üÝ“®÷Äìîܸ;¿]›Ÿ¾»sØøY‚dŸÎuDõ*‡´ lÛ\ý ƒè‹áøùÙèëÙ¸ÚE!®=kòáÎÑîÂH£Ciƒd‚6„-H~.ëë´çñp”¡, L$"~ž»‚ ^ÖèÃèXyNº.ãÕ³{“'$õÛõIjœ›(PÍ|—ªgš"ƒ§6ÏáRçòÇf`Ømro¾)"üO—<7x˜IEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_160.png000066400000000000000000000131561456262201400260210ustar00rootroot00000000000000‰PNG  IHDR  ‹Ïg-sBIT|dˆ pHYs··†Æ%tEXtSoftwarewww.inkscape.org›î<ëIDATxœíÝ{\TÕöðꤦH¢ È>^-‹!33S;eÊ”¡çqHôO£Äbñ—Ó§OW¤¦¦6i4 ¥$ ”””À‘#Gh;;»OpIô?|''§ýAAA%W¯^eÊÊÊ@*•j¦M›ÆÔ×׃Z­ggç„)î`‰~ÂÂÂâ%‰Dræ7Þ¸[QQÍRSS5|>_»páB­V«€M›6ÕY[[ÏÅ3aüØØØÌ“Édbcck[ aøè£”ŽŽŽÚ;vh›¯©©¡P˜;p¸ ár¹ïËåò+{öìy Ñh µêêj˜4iíîîΤ¥¥1­·…‡‡Wr89î Œ“•P(Üáåå¥HJJRC²³³µb±Xííí …â±mÀçóqïa|xb±xPPPÉ•+W˜Ž  ..Nåè訞3gSWW×n»O BèÜ;C‰AƒM‹Å©ááá·ËÊÊ:«;¨¯¯???Ú××·)""‚iû“ žž®qppø÷>†o€µµuˆD"ùóÃ?¬«­­í´ð®^½Ê¸ººªçÎË|ñÅ~;655T*-Bqpïa¸:88¼õèÄ¢Q­îðï1»wïVI$*44RSS;ýiÞ¾}{½Í"Ü;H¦‘\.w›\.W$%%Ñ Óiµ ( -Z¤š>}ºÚßß®^½ÚésëëëA,ç 2ãŠhÃA,ï÷óó+ËÎÎ~rÕ=RRRtLLŒ6((ª««»|þÛo¿]=dÈ)¸w–0çEggçä%K–Ü*--ínÝ@bb"íèèH}öÙg°bÅ xÒÏtii)…ÂÿáÞg¿ÖÖÖ!b±øBTTÔÝšššžF£wß}WåííM­]»>ûì³n½ÎÏϯ !ÄŽó>íííß”ËåW¶oßÞ¨R©zTx•••àååE¯_¿^ýÚk¯ÁÑ£G»õºÓ§O7ñx¼/q‡¹P(üÔÓÓóZwO,:’‘‘¡–H$trr2Õ+Wºõ:†a`üøñ „ÐPÜA°Ë^,ÿ0mÚ´Ò¬¬,í“K¥óúÇ?þ¡?~<•‘‘¯¾ú*ܹs§Û¯ÿæ›oŒ3æ-܃A°„ÃáÈ“ÃÃÃ+nÞ¼ÙÛº€ºº:xå•W¨÷ߟþá‡`ñâÅ T*»ýz¥R ŽŽŽWBd™G?gbii9ÓÅÅådTTTõ½{÷úTxçÏŸ×:;;Ó))) ëÖ­ëñ{DGGß³´´œ‰{pý1ãr¹+%IÞ?ÿùÏû=ùvêJ||¼ÊÝÝ®¨¨€¥K—BbbbßãÎ; ‰2p¡Ãø|þú‰'&%%Q½=±hK©TÂܹs©ùóçS·nÝ‚ÀÀ@8þ|¯Þ+$$¤!ÄÇ=P„nÙ …ÂÅÙ³g{}bÑ‘‚‚ÆÕÕ•>pà€677 §§›åäähy<Þ^܃Eè‡ÃqsttL ¬(,,ÔeÝÀÁƒi™LFß¼y~úé'X¸p!1bÄ4—ߢ¢¢ªîÞ½«Ã’{H£Ñ@dd¤200PÉ0 lݺ¢££¡yÁPo>|XÅårcpÑ{fVVVËÄbñ¥ØØØ:]X´UZZ 'N¤¿þúk EQ°téRøþûïûôž4MƒD"ÉGd‰¥QÊçó×Ëåò¢„„ª©©IG¥ÖÞñãÇ52™ŒÎÏχ»wïBpp0üþûï}~ß 6ÔYYYâH¢g¬¿zùå—§NÒ_ÕÁÃ5bbb”>>>”Z­†Ë—/C@@ôõ‚5À½{÷@ dâL¢›LMMeà¥ùùù:(¯®UWWƒ··7½aÃ5@JJ „……Áýû÷uòþ¯¿þúm333)îq%ž`ĈÓd2Ùïo½õVõ­[·t’ü'ÉÊÊÒº¸¸ÐgÏž€øøxxï½÷út²ÑZ~~># Ä=¶DçŒ;6T&“]Œ­íË%ŽžŠ‹‹SyzzR Ñh`ÕªU ÓϘ:uj BÈ÷ í inGÖQ×}z´<’úÛßþF<Ÿÿ¹§§çõ¾t ЧsçÎie2}òäÉ–ÇÊËËaΜ9páÂÖâˆŠŠºknnî;aýŸ޴#cÛ_|¡rss£Z \¼xBBBzÔ ¯ÊËËA ¤ãNšÑkÝŽ¬¤¤„µöTCCøûûÓË–-£Z?~èСw'Ð…   [!îü«Ç–H$§?øàƒ·#c[AAãææ¦NLLl™¬Ç0LKw¶.^¼¨ßàN¢1ês;2¶íÙ³‡’J¥TëÛ[Qo¼ñìÛ·KL&L(F™ãN¦11 …ŸN˜0¡OíÈØô¨Ï2øX¼ÍÝ ²³³±ÄuàÀ¥Ý‡¸j,ìy<Þ¾©S§ÞÈÌÌÔi×}*--zçÎ-HúóÏ?! p«Ò4 NNNWBÏâN¬Aãp8îÎÎÎÿÓE;2¶%%%ÑNNNTAAÁc'''ÃâÅ‹ûÔ ¯Ö­[W;jÔ¨Üù5T:oGƦ¦¦&xï½÷TÞÞÞTÛ‹Þ[¶lU«VélÁPoTUUP(<…;ɆH/íÈØTUUS¦L¡7nÜøXåÑ4 Ë–-ƒ½{÷â ­Å‚ n›™™Ip'Û´´#;xð ^»èÓÉ“'5‰„ÎÌÌ|ìñæî¿ýö¦Èþ_^^# ÀpCÁmnGvúôiã¬:xxoÆ TóòÈÖ !((nܸ'¸6^z饛¡¸‡ÃqmnGÖöÝØÜ¿fÍšE¿ûî»íæJ?~ £Û™âpìØ1ÚÞÞþSÜùÇFßíÈØ–““£•J¥tJJJ»mÍÝ åpB£Ñ€L&+DOáKSkkë×u ¨ÃyéA—¾þúkÊÝÝn{ÿ´æî;vìÀYÇâââêG=w1°i(Ç[ÇF;26©T* ¥æÏŸOµÝVSS!!!‘‘#´NÕÖÖ‚H$:‡» ØÒÒŽì?þèU÷ȵk×WWWzß¾}í.â¿¿?â1íÒ¥K+9΋¸ CߤB¡ðÇÀÀÀ}¯ÚÂáðáôL&£;:›ýã?`þüùzéNÐWEEE ‰Žá.½iÝŽ¬õ,þ¢õòÈŽþ½Øµk—ÞºèÂŒ3JB/à®]knGvívdlj^¹uëÖv«Ó›»°µ`¨72224ãÆÛŒ»XtiÈØ±c?–Édùl·#c[ZZšF*•Ò—.]j·­¡¡^{í5øïÿ‹!²îÑjµàææv!ÄÁ]4º0J,9uêÔ›GíW'mµ^IQíNt¡¬¬ ‚ƒƒ!//CtÝßhkk»wáôövdlj^ùñÇwx@wæÌxõÕW¡¹5š¡jhh±Xü'2ÖÎV†ÐŽŒmÙÙÙZúÌ™3n?x𠄇‡ƒ1Lý_µjÕ] ‹—p×QOµ´#[»vm­¡üɆ¸¸8•»»;ÕQGy†a`ݺu°víZ ‘õ\YY…Â㸋©' ª›`öìÙtddd‡MWT*DDDÀ‘#GØ­×+Bv¸‹ª;¬ø|þ—†ÒŽŒmùùùŒ»»{KŸå¶***`Μ9½¾)™™™Z· wa=‰Éðáç«TªFÝ4nܸ;&&&&MMM9ŽÉ3ÏÜøîÖIQZ¼x1mbb‚.^¼hÖÑs~úé'ôóÏ?£½{÷¢Áƒ³b¯íß¿_UUUõ%2ðâë«Qæææ!ŽŽŽG¼¼¼®FGGW) Ü¿<ÝR\\ r¹¼¥Ïr[ÍÝ ¢££YïNÐW*• œœœòBÏà.¶9ÙÛÛïòôôÌÛ¹sg}CCî\t(11‘–J¥tQQQ‡Û)Š‚ˆˆøÏþÃrdº±fÍšKKËY¸‹§g,,,œœœÒƒ‚‚J²²² bá¸F£+V¨fΜ©êl>buu5Ì›7²²²XŽN7*++A$ý†» ‰%—ËýÜËË«0-- ÛÙõíÛ·aÒ¤IõYnëÒ¥KX»èBXXØm333'ÜI7D¹\îûR©´ !!AÉæŒè_ýU#‘HÔ]õ\ùå—_tz;Srss>Ÿ¿w¢ Ù˜1cÞvww¿vâÄ ½NšcÖ¬Y£š˜>}zYëÙØ"##U~~~TW—Oêëëá¯ý+¤§§³Q¬zùå—ûåKCe'Noß¾½¾´´<==ÕÛ·oïòj¶B¡ÈÏÏg«&X“žž®qppøwRž:cÇŽ]áàà@v™ S§N±r;S´Z-¸ººö›%–ÆæÙ™3g–v• ={öÀŠ+ ¶;A_íØ±£~ôèÑ‹q'BWŒmjó3¾¾¾7~ùå—±m7h4Nž<‰ÂÂÂB 6 YZZ" ôüóÏ#[[[Äårjrik ÈÃÃ#7??ß !¸ãÑc»/„IgË:ÄŒ?ÞdóæÍ&µµµ!„†Auuu¨¶¶UUU¡ääd&--­~РA×,--‡ÚØØ 4i’åÔ©SŸ‰DlîG¯¬Y³¦º¼¼üMÔOŠÏuúìëë«íjÒÁ±cÇTãÆ;Ôêý,BSìííã$É©3füë_ÿª¹råŠÁÍ„¾qãðùüLãN<Òa?~\»aÆNÏŠ÷îÝÛ ¡'߀ùY„Ð>Ÿÿ¹T*Í )IIIÑÂÅ뀀€2„­þ‡˜èJ‡8kÖ,ug}¦ãââêz»<ÑÂÆÆ&R*•ž (9zôhŽ“›3gÎ4988|¥Ó‘$zÅtÖ¬Y`nn.³|ùòöƒà“O>©âr¹ºêÿ¼Í;ÎÎÎÙo¾ùæ¶&30 /¾ø¢!4DGûAôA» V^¿~½]Ò–.]zÛÖÖöm=ÅÁ … “'O.:xð ¥ÏŸèo¿ýöÁ˜1cÞÒÓ~=ôXÜ9s;ó ioÙÚÚÎe!žA666‘2™,gõêÕ:¿A¶R©GGÇ+èÉÇ®K+À%K–}úÌfYöqLLLIFF†žZýM<ÏÃG}¤0`€¶  :#FŒ€ôôôv}nJJŠÈ²ì1Ú;™†aV8;;§¯]»¶¢¤¤DO­^_ff&øúú ÑÑÑ<@||ø–.] u¬·Å¶mÛ42™ìhïPd×MM3$QaõêÕZWWWþÙ³gPXX˜˜¨—Ï/++…B‘I0â5¥{÷î!jµúò˜1c Ú{²ÙR………ÄGDDð:nß¾ C‡… .èíw,^¼¸¬wïÞÒÞ¿È8YØØØD+•Ê»111Åí=ÑlŸ~úItvv¶lÙ"œ:u ‚‚‚àÙ³gzûéééÀ0Ì}‚'¨k†aV(ŠŒO>ù¤¼¸¸XoM×[·nÕ:99ñ?ÿü3lß¾~÷»ßAii©^ÏØ±c ÍÍ̓iïld<Þˆo(5ÍÊËËaܸqÚÀÀ@­F£©¹ä .ÔËÉnmW®\Y–=C{‡#ã0H©T >œŸ4iÒëÿâ?~ þþþPó—ÀÒÒÒ€eÙK´ÇFWkkëw ލ¨¨’æâÀ¥váÂÇqBbbâë?C—.]‚€€ÐÇBø–>|x!díBúÕê8p)ÕÄ“899ñµÊýû÷Cxxx‹ÓÙÚëðáÃÃ0{iÒ‡Çenܸ±²-‹¿ ­´´Þ~ûm~Ô¨QÚšp+Q!..fÍšÕÕÕ’ÔQ]] NNN9„;Úƒ†ÚÏE¥Ríë߿ޞ={Z.µ´´4ÑÙÙYØ´iÓë¯xãhÍÎΆØ·o­Ò@puuÍ%„0´Õ×ÕÌÌì¿ ŵÈÈÈ‚_~ù…Z£´Õ™3gtJ¥R8pàÀÿ~ëÖ-ð÷÷‡«W¯Rªì•­[·V1 ³Žö@£7u«ž™™IµIÚBEXµjUµ«««¶nýß|ó ÃóçÏ)U÷JYY°,›A±¢=àèƒÅK©&ždìØ±|ݵ¹ñññðÞ{ïµ;M,XðÂÆÆfíAG„¨kÅW›Ê‰mC®]»Vóœ­7ÎSª««aæÌ™Y°ÞOž<†a~!„t¡=ø™Çqßùøø"\j›7oÖªT*¾îòÄÂÂB=z4ìÝ»—ReõEDDš››Ñn€Îè8ðÛ·oÓî…v+++ƒ±cÇò|ÝIk<€ÀÀ@8þ<¥êê»|ù²(—Ë¿£ÝM7++«ÿ–Éd¿2\j÷îÝWWWaõêÕõfÚ}ÿý÷OŸ>¥PYÃDQ„æBT´¢³°afÇqYË—/¯4än©íÚµ‹W(Bjjj½×¶oß&L€/^P¨¬q»wï®–ÉdÿK»):†ã¸ÍRÅK©&žÄ××W[^^þÆk<ÏÃÿøGˆc;™¯¬¬¥R™E±¡Ý™¤qàR{þü9 4HX¼xq½î...†Ñ£GÃÖ­[i”Ö¬O>ùä¥Ý|Ú Ò!ÕŽ§}wÓPŽ=*(•JáÔ©Sõ^{ôèÂÙ³g)TÖ¼ÌÌLËå¿BÌh÷JGòF8í;›†"üùÏÖ0@Ûк܋/B@@󄨨¨"ssówh7LGaíè踜V¸”òóóÁßßŸŽŽnð$&!!ÆƼnܸ,Ë^¤Ý4Õ8p©?^Çqœðõ×_×{­&möìÙMgÓŸ>¾Á?q—/_†€€0ÔÓÜõí¯ýk…ƒƒÃÿ£ÝP¦Â¨âÀ¥–À;;;ó7oÞlðõÀÛo¿ yyyWÖ6ùùù —ËŸB,h7–±s¨nŒ©i†TYY “'OÖúûûó¦Þë5élÑÑÑ`J'ý3fÌ(¶¶¶žH»¹ŒY¿š8ðƒmjš!=xð<<<„•+W6¸ñUUU-y:[{ݽ{†¹N»ÁŒU˲g‚ƒƒsjž1Õ:tHP©TÂ?üÐàëYYY ÿþ÷¿%®¬ýFŒQHñ¢ÝhÆä8pC=OÊÔŠ'á›™š––þþþðÓO?I\]û|ø°nñâÅäË/¿4 oô};vì Ç'ûöí#½zõ’°BÃÊÌÌ$Çÿ5;;Ûƒ"Ò®§=Ì+**Bü!U©©©òjƒº’W Þ"¯îì1ffflß¾}]ºwï>Ü»uëf£T*-ÂÃ탃ƒ{2„ôèуޖH@²`ÁþÒ¥KäÖ­[¶¶¶ ¾O§Ó‘+V’’rôèQbnn.q¥†µ`Á‚’âââXbâͯ„ßq÷Žãîx{{g­Y³¦¼±UM¦,++ |}}…˜˜˜&/ƒ•••ÁĉaË–-R•&©ÔÔT`YöíÆ3V=ÍÌÌ&ªTªCNNNóæÍ+2Å)½u%''ë8Ž’’’š|ßãÇaĈpæÌ‰*“ž··w!Ä•v£™‚®„Žãöë×/síڵ妲žµ†(аbÅŠj77·zÏÙªëÇ„€€¸{÷®DÕIïŸÿü'/—Ëh7–)êÖ³gÏéJ¥òæ˜1còLaîKQQó'Nlt"[]»vAXX4[ØQTUUJ¥Ê&„ô¦ÝL¦ÎS.—2dHæÙ³gòvèÕ«WEgggá‹/¾h²¾šë111FŸÎÖ^kÖ¬yiooÿ1íæéH8™L¶ÇÝÝ=gÏž=‚±L HHHà]\\øæn–——CTT”I¤³µW^^0 ó„Ò±.g ¹\¾ÕÝÝ=ûðáÃÔ&•——Ãøñãµ#GŽÔÖ}ÎV]™™™ÇŽ“¨:º¢££K¬¬¬ÆÓn”Ž®·££ã?|||²¯]»&éÜ£š‰lk×®mv Û•+WÀÏÏnܸ!EiÔݺu X–M¥Ý‰R¡Pœ3fLÁ“'O >ÀIII‚Z­ZÑrðàA ƒÜÜ\ƒ×e,ò !i7E§cnnÀ²ìí?ýéO%eeezØßÖáj}}}µÍ}~Í‚õiÓ¦AgJ®;vì˜À²ì?i÷BgÖÅÆÆf:ÇqÐÛe–gÏž———°páÂfÏ9ªªªà÷¿ÿ=ÄÅÅAGe¯çypqqÉ!„8ÒnDˆÇq›‡ –ß޵ǧOŸœœ„“'O6ûÞììl ýû÷·ëwš¢7V:88¬¢=ðèMî,Ë^_´hQikƒbEQ„•+WjÝÝÝù–„NݼyüýýáÚµkmí!“U\\ r¹ü9!Ä’ö€£úºØÙÙÍwqqÉ>}út‹‚‡òòò`ذaBcÏÙªëðáÃéééíë$û¢W¯^Sh4jš\.?UÐTäâÅ‹EµZ-´4w'>>¦L™b²élíõèÑ#Éd?“NqbòÞzë­Q,Ë>ýâ‹/ÞׯyΖ““ÿðáÃfþ·§¯›t:›>„††WëC éÁ0̶àààügÏžAYYDDDðaaaÚ–Ä3BDD$&&JÐbÆ+%%EdYö8íÁDmdaaáDzìcŽã„Í›7·èšåíÛ·ÁÏÏ.\¸`èþ2j:<==s !JÚãˆÚgÄôéÓ[ôÔèï¾û‚‚‚ ¡G‘v6Û¶mÓÈd²ÿ¡=x¨ýücbbš}ÁöíÛ;L:[{•——ƒB¡È$$â¤5:äôVhô5QIhh(¹sçqqq!“&M"„¼ZÈniiIlmmIïÞ½‰L&#jµšpG8Ž#*•Š˜™™Iµ ’Š‹‹++//#„TЮEjòèÒ¥ñ+xçθpáB׺¯UWW“’’RRRBrrrÈ‘#G„åË—wëÖí¦(Š*++«·ÜÜÜÌl‚‚‚¬|}}M> ãùóçäÀ9¥¥¥ø4÷¢É¯@º–$Þ%$$T0 sR»Ã»Bœ!9ŽÛÎqÜdÆÆÆž:uÊ$ïL˜0¡ÐÜÜ<˜ÎP!Chô¸uëŒ7®Ùë¢ùË_ÊärùIÒ²‡<›B†Ëd²¿«Tª;C† ÉÞ´iS¥)ÄÆ_¾|YdYö¬ÇI, 66¶Á`Ê”)üÙ³g½<*Š"|ôÑG/†ÙK^¥Z´………Å –eôññÉŽ¯4ÆÞ‰¢^^^yäÕ_4Ô4xþþ÷¿W:::® ]8’ƈ¹sç 6¬ô_ÿú—°fÍšR¥Ry´}jƒ±jÑPTT„'LàСC+†ÑLŸ>½D.—ÿ/í‚ ¬ÉáÃ?,éѣǻ´‹DÒAKKKÃ0Ëi#¡z½{÷@.—§Ñ. I+´k×®‚½½} íB(ééàà°ÊÉÉ)ËÝݽ„âM» $¡îÝ»;Ëd²?ЮÃô$„КâB!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„ê¤þ?½‹bf ˜ aIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_22.png000066400000000000000000000026741456262201400257410ustar00rootroot00000000000000‰PNG  IHDRÄ´l;sBIT|dˆ pHYsÄgítEXtSoftwarewww.inkscape.org›î<9IDAT8eÕMO]çàµ÷ûž{Î=ç^ÀpÀ€1àHh‚S«rœÕ“¨ê¼$¤³ü†Jýt`©ê ’¥6“¤©£ªMj\‡0±Íå+sÏý:çÝ«ƒ:©k¯áÚÒ3Ùƒ%x–ß\[§§Æ‡Ê¢HD] )+Ö—¨¤z¯P ¥:ïI‚P–*¾­o!ô Qgô¸vt劔 pu•5tŽˆ|ªf–D¢ƒDdˆT½Ò‚€ ê¥(AíÓ¹ž™õ ®‰oWÓêþ/~$=÷»›Í,î†W(¬«IÊzDW+É:au¡dd¤d„¤pR%-"µ¢Þ«8ÎúíXŽ¿ý•üñÖ“¹¢Ãº‹˜YÐLÀÊ*)‰‘±B"  "jK1T鉱«NÚ€´;W]ëàüÓ:ð,Xƒ²&æjTÖÄ™!PUh a„¡‚š”&ì Ð…j')𦇢ŸÔÝÈäk?‰?]yø±b™ŠÏ˺@kTÔ`ÈHEP“ŒP%˜° çòo§&3üôÍåWg?ÿÛ{/¾5´vÿំæÞ8ò «E&Î¥$j ë¢Z˜Ñ˜LT4"é@eÜÙ==9$ .,9iåÅgŸ_òÎÛ—†{ý~wm/\«ŽXêi–š00Õ `D](U b#=ŽÎ¿R\¾0?$"ØÝ?ìnnm…Ÿ½ÿîPEòÕêÆ§éèÙ6 ±‡HÅ)*fˆA&ª 2ÉH‘%ý£±Ùa?þÚ[K™ˆî~½‘î7+—ß¾”¨*v÷[[y|=”J€U¼P< a‘@*b !­KkêÜ gÏÏTñ\nßÛl;É»ï\v?t»Oêgú„EBxOPU4„à£öãÙó ¿´¼´Pì÷ |òÙÅÂÜÙdnöUý¾ÔÜ?Þ E^”%ƒz Xišuw~<7^¿´pqi/两ŕ[wìÍÅ9?99)Ïßþ½±¿â“ñ uŽÞº¹ÈÉöååóÌÏ-½ÀÃý²¹³ƒùÙ³n|lìÿÐvŸkã–‡”"#MO6W.O>M‘~Y–|]»¿ÝÎ[Oefzâ%nmÞð•j> } ‚¥ûè׿•§¬ÝÛïUÿ±v÷›GjÝÑ‘ÆÐI|ysõ»4ªŒ kãÔ©—Ð{÷>§þ h.‚œDNrQɽ¨v•¬ÐIcêöÃr{ûàö•”Ýå¹s£õúkµì%Ö›ëLO@æ´!옡ë%êzi‚7À9ª¸ÈãSŸ ËÖ{;»{ùõÛþ962R›hTgg¦'ߣwï?Øî&c_Š¡-@ e”<É)Öñ!r¹„R58PH ,667O¬1ÿ{?|n¿Iúï kÍõÅ™ÿÞüÌôØ7Íö_ >¬c¶˜äê¤e&¹QsùãéÐŽ ½šÀ¥BK­nÜüëÂÌï?&,RE  †½µÅxìõ¯T¥g¦]ˆui 5‡Ó–3=’«««•Ð?sÆÑ§Š’VuªI0P'&Žüß‚eh²/ª]ëA;eÛ|z‚¯«M€këëq+ŸÑn+5ïUC°X!‘:ñ¦P†g0AX²„w}°×× ]I\ÇK/¿qpçðã+Wʾ}õ*ÝÀëOó²L‹â¿cꡜ8ôJWŠˆ÷žölL½ú² Àúqˆz½Á^þËÙSOE„ðlSÃ%¯þÇIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_24.png000066400000000000000000000032311456262201400257310ustar00rootroot00000000000000‰PNG  IHDRàw=øsBIT|dˆ pHYs((ûr^ÖtEXtSoftwarewww.inkscape.org›î<IDATH‰u–Ûo\WÆ¿oí}ÎœËØã±cÇNãLÝ\Ô¤ ¹T…’PÂRRßü¼ów ñTyÂK^(4mp¢8±rÜ$ÄvƱǗ33gÎ^‹Ǩ%a½~{ý–öZkëÛÄ˸|ÙÞÙl¸­*Cæb+%ÖX"-»”Î ¤" ÞÌ > XPZ…È—€–µõµS}8Ò!i@¸¹ J ª:/AÕTžÞºréTkø''GNþ?øÃ…¥ÞÚó¶ÎLO½þlµ½³<ÈoRš† ©T«ÜÏõÛ°úìýu®/}µ¸‹ío6†³½ä·ïuêI”Ž6›~rrÿëêãÚÅ[–N<2³®É" tt½é«UýddtcÀæg_>)æžÌýèì‰Öûwî>è¼}´µ/ŠbŒ¾þøÙJgÍÙV,@íªI”žSô}PíQ$£3@jIÆ fW®~>§ï«õýçí¶º(ÙòQTo ½Ò¹…•ëq~è…) v ,íRµ=J×`N4£š6÷57·¶wÊÅøý`hüÑìì“æd޼59têØáÖ8,.=]Ù’ñϽaD—` 'ÜQXŠ]~r«}ÜÓç Ë ÉË`š.ݸòÓ­™hâ9€„3S UÅhkéô™£SæW®‡¿¬¯j=q,Œ,¬ÒBŒ;ð²Í+ó«“Ýn2Bh œ¤¢’çCi£I#z(ÜžeÒ ;;›’$Y"¥ˆôu·Õ=)ª*t%’dÛÚ43ùäZ{2ÊãR˜¦W d Ac#'tÁ‚#ö 8-@ब4•¾ˆöª =pÐÍ:?>7µ¶kú—ÍáÈöh`•G!$•¸ZD‰«*Ätô0:G VœÁ öÒôÝ@ý:××úâ\/rÍÍN£CÒ¸· fÆO¢^m·ë%V«"1z( EÐEÔt÷Û¢UÍ|ÉZ\;[å–[¿8w Øãþe ·{hIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_256.png000066400000000000000000000236111456262201400260240ustar00rootroot00000000000000‰PNG  IHDR\r¨fsBIT|dˆ pHYs X X¶`ØrtEXtSoftwarewww.inkscape.org›î< IDATxœíÝytÕ¶0ðMš$Õ5vwÒéL‰0Q/H)ps‘€ˆ‚Š‚à]ácX¬ËuÈ{ â{Åçˆ3QEˆˆ×! *£ B@I IO¡»j`s2vŸtgÿÖ⺪³«jŸJ÷É©½!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„Bi½Ú³€â{Iz½¾€ã8ÔétKXCñÞ&“)?((HÓëõê€0ÖAB¼'²EùYQ‡N§CAã8­mÛ¶ÿd!Ä;Bt:ÝDI’NuèÐáÒìÙ³Ñl6k‘‘‘øüóÏ£ ç „u„æ%‡††þS„²ôôtëºuëpõêÕš$IسgO,..ÆØØX+d±”Ò|âEQ\¤×ë«ÆŽk;xð º\.ÌÎÎvK’„£GF‡Ã .TeYÞÉ:XBHóH5™Lù<Ï;¦OŸ^}æÌDDmÚ4gQQQ­qñâÅÇqŽ?þ8ªªzÍën·;tè`Óét²>(BÈ­¥›L¦-ƒÁ6gÎwyyùM~ee%Ž5Ê-Š¢f4ñý÷߯u»¼¼HBȵĠ  ð<¾W¯^UµMìÕfÅŠš Ø­[7ìÞ½;ž:uê¦Û>ñÄ—EùŒõBþÃ" z½Þ:tèPûÍ~{_Ïétâ”)SÜ’$i={öÄaÆaEEÅM·ÿí·ßã8ı>`B@²Á`x‡çyÛÔ©S·úÍ}½Ó§Oc·nÝ´ØØXwRRΘ1ã†É¾ë5Ê®×ë_d}Є´v銢lTÅ6gÎWYYY½>"âºuëP’$ìÓ§ï½÷^ûlÛ¶ õzý%Yù$véÒ³³³±æÃ>uyî¹çÜŠ¢|Ãú¤èÒFãÏÄ^iii£>"bEE>\ Sßy猊ŠÂW_}µAïqöìYÔëõèÈúäˆ<{"##«-Z¤Úíö& |DÄ={ö`dd¤Ö£GõÍ7ßݰ0üòË/ü>ãÇwˆ¢ø:ë“DH  ý³¸fq—.]ª–/_Žn·»ÉqéÒ¥š(Š˜““ƒ999˜””„……… ~Ÿ½{÷"ÇqU`b}² æqW9dȪ­[·6Ë G¼2Y7~üxUQmíÚµ8räHLOOÇóçÏ7êýúõëg žÉú„Ey›ã8û¸qãì¿þúk³ |Ä+•y’’’´Î;«À^½zác=†ÕÕÕz¿O?ýEQ,‚+B)Íd2å+Šb{â‰'.Ÿ;w®Y>"b~~¾&IN˜0AÛ¾};FGGã‹/¾Øè÷«®®Æ˜˜+ g}òñGAe2™vZ,–ªE‹©×WÓi.— gÍš¥Š¢¨­Zµ ?üðC4›ÍøùçŸ7é}_zé%U–å¬O"!þ&T§ÓM”e¹¨S§N•Ë—/oÐßÛ¢¨¨{ôè¡ÆÅÅ©EEE8wî\l×®þüóÏMzß²²2O‰ïÖ'“¡xºæ 2¤êÛo¿m¦a^»‚‚4Zff¦f³Ù𡇾}ûâüÑä÷ÎÎÎvJ’´”õ %Ä$ð<ÿVhh¨mܸqöC‡5Ãð¾¹å¹µ×^{ Ïž=‹·ß~;Ž7›cí@aa!†††Ú ’õ‰%¤%ëU£kÎåâââfÞ·váÂLOOW###ÕÂÂBÜ·oÆÅÅáܹsõ`Pm dã8îiÖ'—–¨ d„‡‡QµhÑ"Õjµ6ËÀ«Ë®]»0""BëÓ§êt:ñ“O>A“É„«V­j¶ŸñÝwß¡ ÇúDÒ’xÚaŸìСÃ%oNìÕfñâÅÏóøì³Ï""bnn.ÆÆÆâÍjù7†ÛíÆÄÄD+ÜÇúdÒR\m‡íéšãK•••˜••¥†……©Û¶mC§Ó‰&LÀÔÔT¼U=ÿÆxã74I’ö•ø&â®o‡ík………§uíÚU­¨¨À .à]wÝ…cÆŒ¹¡;OSUVV¢Á`°Àí¬O!¬¤›L¦-F£Ñþì³Ïªõ­’ÓÜN™2Å­(Šæyl÷«¯¾Âˆˆ\¾|¹W~æ‰'<%¾Û³¾„øR0L$éj;ìË—/{eÕÇ©S§°k×®Zbb¢úûï¿#â•ɾˆˆܲe‹×~îˆ#ì<Ï?Ïúbâ+ÒŸ{¥ éšãMŸþ9J’„cƌѯ¬ïŸ6m¦¤¤àÉ“'½ös·nÝŠ<Ï—€Àú¢âm×´ÃÞµk—×V}Õ,ÏíiÀYVV†ƒ ÂÌÌL¼té’×~¶ªªØ­[7«N§›ÈúÂâM= à žçmuµÃö¥ââbLKKS£££Õ£G""â±cǰS§N8sæÌf« t3K—.Õ$I:WžZ$$à¤ÆÍžâš·j‡ík›7oF£Ñ¨ 8Pó ôo¿ýÃÃÃñ7ÞðúϯQâû.Ö‰æYŠ¢&&&VÖ§¶/iš†Ï?ÿ¼*‚¶hÑ¢«ÿŸ——‡‹7nÜè“8fÏží’eyë‹EHsiT;l_*--ÅÁƒ«áááêîÝ»ñÊòÛœœLNNÆÃ‡û$ŽââbO‰ïdÖ¦º¦öŽ;|2ˆjÏž=h±X´^½z]-÷]YY‰#FŒÀ¡C‡Ö»;Os7nœC„\Öަht;l_ó<ÈóôÓO_ý¿'N`×®]1;;}¹ö`Ïž=Èó|(¬/ !ѤvؾTUU…£Gv+Š¢Õ¬ôã?bTTT“ v6Öm·Ýf žÎú"ÒWÛaGGG[sssµæ¨|ãM‡Æ„„­sçÎ×,+^²d †……á_|áó˜Ö¬Yƒ¢(ž€¶¬/(!õ!Ôl‡½fͯÿm¼9¬\¹R'NœxuRÓ4œ;w.&%%¡·K†Õ¦ºº£££­Éú¢R—OלŒŒ ë¶mÛ|>`Ãétâ”)Sܲ,kùùùWÿ¿ªª ï¹çìׯ–””0‰mþüùnEQ¶°¾°„ÜJ’¢(oëõzÇ<àôÕŸÅšCQQ¦¤¤¨ñññjÍÚ€®öÃÉ“'7º;OS•”” ÏóèÎúR›´°°°Ï𫶝­_¿eYÆ‘#Gª5×ìØ±£¢¢pîܹì‚CÄÉ“';%Iz—õE&¤&ÏŠ½ý‹¥Ò[]s¼Éív_}çí·ß¾æµ5kÖ ÙlƵk×2ŠîŠC‡¡^¯·@8ë NÀÚaŸiîvؾtþüyìׯŸ¥Öüª¢i¾øâ‹Ø®];ܳgï0`€5$$ä)Ö3ÇqÏ‚P>dȪü‘õØh´ï¿ÿM&“–žž®Ö\Äãp8püøñاOôô`iýúõ(ÂïÊúâ“ÖË«í°}IÓ4\°`*¾ð ׼vîÜ9¼ãŽ;pìØ±ÍÒ§©\.&$$X`4ë ­Ó5í°Ïž=ËzL4IEEŽ1B S¯Þ`ÿþý‡999-æ¤W^yE•eù'ÖI@Z— È2;<]sümb¯6{÷îÅèèh­G7túòË/Ñl6ã|À(º•——£$I¸uBÖ!D§ÓMTÅëí°}mÙ²eš 8kÖ¬^ËÍÍŘ˜l ¥Åjš9sfµ,Ë«Y' |WÛa§§§[}Ý5Ç›N˜0AUEûꫯ®yÍétâĉ±GxúôiFÖîøñãj€v¬“ƒ®«í°ÇŽkc±¶Ý›Ž=ŠIIIZ‡ÔóçÏ_óZii)0‡Ž•••Œ"¼¹ÌÌLÇqÿÃ:AH`òy;l_[»v­&I>øàƒ7Ìæ8ppæÌ™^éÎÓT›6mBžçKJ|“fÔ2L&Ó³Ù\5þ|Õ›¥ªYq¹\8kÖ,UEmåÊ•7¼þïÿ#""pÙ²e ¢«›ªªØµkW«N§{˜uÂÀAø­C‡4±w½ââbLMMUÛµk§ÖÖ„ÃS°sóæÍ¾®žÞ}÷]M’¤Ã@%¾I1m‡ík›6mB“ɤeffj׬w¹\8cÆ ìÞ½;þöÛoŒ"¬[UUšL&;¤³Nâ¿¢$Išïi‡}àÀÖyíUžòÜ<Ïk¯¼òÊ ¯———ã!Cð¯ý«W»ó4‡ÿþïÿvɲ¼ŽuÿÔS’¤õz½e;l_ús&_µX,jmÁ8vìvîܳ³³[üמ3gÎxJ|'±N$â_ZD;l_Û½{7FFFj}úôQNç ¯ÿðɯ¿þ:ƒèn̘1v½^ÿ2ëd"þ!î—e¹011‘y;l_ó”çž={v­¯¿óÎ;h±X°  ÀÇ‘5ÎŽ;¨Ä7©—×Û—þ¬É§šL&uëÖ­7¼îéÎÓ¡Cô—§5MÃÞ½{[u:]6ëä"-W‹k‡ík¿þú+&$$hݺu«uýBUUfeeaÿþýñÂ… "lœU«V¡ 'J|“Z¤È²ü¾§vK[¯î+|ð&N™2¥Ö;gΜÁÔÔTüûßÿîÓîÝ»wWÔsçÎÕºÍêÕ«Ñl6£?.rªQâ»ëÄ#lyÚa—¤¦¦V¶¶‰½Ú|ñÅ(Ë2Þ{ï½ZmçÂÓ'11<È Â¦›0a‚CÅŬ“°cáŽãª222¬-µ¶/Õ,Ͻ|ùòZ·±Z­8zôhìÛ·/þñÇ>ްyìÛ·9޳@ë$$¾×AQ”·yž·Mž<ÙyäÈÖùØ"œ?ï¼óN5**J½Ù99{ö,ÞvÛmøÀ´ˆ‚Õ¿kppð,Ö‰H|+]Q”²,·øvؾ¶eË4™LÚÀµ›-ÙÝ»w/¶oßžywž¦Z»v- ‚p®<¥IÜÕvØQQQU‹-Rýù7Ws«Qž[[°`ÁM·ûøãÑl6cÍFþèòåËØ®];Œd˜Ä»<]süª¶/UTTàÝwß­†‡‡«;wî¬uOwžØØXܽ{·#l~ .TeYÞÉ:9‰÷˜=í°‡ Rå/í°}íçŸƨ¨(­wïÞ7ýDät:ñ‘GÁÔÔT,**òq„ͯ¼¼EQ´@ë$%ÍÏoÛaûÚ²eË4Qñ¿þë¿nºÍ… °ÿþxß}÷a ô#@Dœ:ujµ,˰NTÒ¼®¶Ãž={öeZƒîk‡yäUQí믿¾év¿üò ÆÇÇcNNN‹,ØÙ‡FŽãìÅ:aIÓyÚaï³X,Ó5Ç›Ž9‚IIIZçÎÕ[-kÞ°ašÍf\±b…£ó¾¡C‡Ú8Ž{–uâ’¦ ˆvؾöÙgŸi²,ãĉo¹¼177- ~ÿý÷¾ Í' çù À³N`Ò8áÒÛ—j–ç^µjÕM·«®®ÆI“&aJJ ž:uʇzŸÛíÆääd›N§{u“†»¦vaa!ë|ògΜÁž={ªñññê­j–••áÀñoûVTTø0BßÈËËÓ$Iú®ôd ~¢wÍ®9þÞÛ×6n܈F£±ÖòÜ5=z;uêÔb»ó4Uee%F;ôcФnmàºvØ×·&·æ)Ï-‚öÚk¯ÝrÛo¾ù#""ð½÷ÞóQt¾÷ÄO\Vå3Ö‰Mn-äω½S:t¸È]s¼éÂ… x×]w©‘‘‘j]_•<Ýy6mÚä›à8yò$rç€8Ö Nj'j;l_ûé§ŸÐb±h}ûö­µ<·‡ÛíÆ™3gbrr2ú÷Üs]¯×ÿë$'7ŠEq‘§kŽ¿“h)<幟}öÙ[nWYY‰wß}76 ½oÁ¶mÛçùK ³Nvò©5&öª±¶/UVVâ¨Q£Ô°°0µ®çŽ?Ž]ºtÁììl¿*ØÙš¦aJJŠU§Ó=Æ:áÉéÞÛ× 1>>þ¦å¹kúñÇ1** _}õUEÇÖŠ+P’¤c cø­YLEñD ·Ãöµ+Vh‚ à´iÓêÜvÉ’%†ëׯ÷AdìÙív4›Í6È`=Z+éúvØ­½¸fsñ”çVEÛ°aÃ-·õìLJJÂÖ´xê¹çžs+Šò ëAÐ]íš3vìXk ·ÃöµÓ§Oc·nÝ´„„µ®"œUUU8jÔ(ìׯž?ÞG²÷Ç ÏóvèÈz0´&״Ä¢-ͺuëP’$¼ï¾ûêü(uæÌìÝ»7>öØcX]]í‹ðZŒñãÇ;DQ|ƒõ€h-Ze;l_r¹\WËs¿ÿþûun¿}ûvŒŽŽöËåéׯŸ588x&먤?»æœoí°}mË–-h4µÞòAÄÿLöÅÆÆâž={|aËòé§Ÿ¢(ŠEpåiFA^ÐëõÖ¡C‡ÚoV5–4šå¹-ZTçö‡zè!ìÓ§ßvçiªêêjŒ‰‰±ÀpÖƒ%$ †wxž·M:ÕÑZÛaûREE>\ WëSzûìÙ³xûí·ã¸qãüº;OS½ôÒKª,Ë;X˜@‘®(ÊFO;lêšã{öìÁÈÈH­W¯^j}:ïÛ·ãââpîܹ­ú«XYY™§Äw ëãϨ6CK—.ÕDQÄgžy¦^ÛòÉ'h2™påÊ•^ެåËÎÎvJ’´ŒõòWbPPÐQÏR;lß³Ûí8~üxÕ`0hß~ûm½öÉÍÍÅØØXܵk——£kù 144Ô‘¬’¿‰ø³veFF†uûöí¬¯e«säÈLLLÔºuëV¯õN§'L˜€={öDš¹bРA6Žãžf=˜üÉÕvØ“&Mrz1ˆ–*??_“e'MšT¯[¥¥¥x×]wá˜1c¦;OS}÷Ýw(ÂÀ±Tþ Ýh4nðLì•––²¾~­’§<·$IÚ§Ÿ~Z¯}8€ñññ[°³1Ün7&&&Zà~Ö«%óL숌Œ¤vØŒ9s{ôè¡ÅÇÇ«õ­nüÕW_aDD._¾ÜËÑù—7ß|S“$i?P‰ïZQ;즠 F#Ž9²ÎU}yyy‰[¶lñrtþ¥²² ƒ î`=ÐZškÚaoݺ•õµjõ4MÃyóæ©‚ hyyyõÚÇåráôéÓ±{÷îxòäIïè‡fÍšuY’¤Y¶–äšvØ¿þú+ëkDðj[m5**J­o‹ò²²2ðBd­ËúõëQ„߀ªÔ«Q‹¢h_´hQƒþ_§Ó‰S¦Lq‹¢¨åçç7xÿÜÜ\Œ‰‰Aê”Üt.— ¬0šu‘–)U’¤_z÷î]uàÀ&'\QQ¦¤¤h jC^ª®®ÆG}{ôèAÝyšÉ+¯¼¢Š¢¸¨Ä7¹…    éÇU>þøãÕ펳~ýz”eǧ5ô;{ii)8‡Ž + µ»xñ"J’ä€ÛX'ñEQò###m yßívã“O>©Š¢¨5¦ÉÆ‘#G°cÇŽÔ§™Íœ9³Z–åY'ñ?™‚ ”Œ5Ê^×$áùóç1==]ŠŠRÓ ñ믿ƈˆ\ºti#ÓœÔæøñãj€v¬“‰ø'^ÅE¢(Úóòòjý<ÿý÷ߣÉdÒ ¤5¦;R^^Z,ܼys“ž\+33ÓÆqÜÿ°N"âÿReY>>¾ ‡vîÜ 6lpÙíöçXÇBœ¢(½ñÆuNHýãÿp?úè£ ZT]]cÆŒqȲ¼®´I»ž®t\þ§¢(_ ‚P¦(Š-##ãâË/¿¬íß¿¿ÕÕ Ð4 {õêe ú¾ÍÒ*ÕçpéÒ%”eYÛ¿½Ùf³áàÁƒmŠ¢€¾!ÅÀýÇ-E±XQÛ}÷ÝWõþûï·Š^«W¯FI’NÀ•^„xW}nóæÍS‡ Vïßþåå嘖–f“$énbˆqðw“É´ã8[¯^½.½üòËj ®8t8h±Xl0´éW–zPeÍ›o¾yÓ¤t:h±XÔo¾ù¦^I|îÜ9LNN¶ò<ÿ4ÿâ•ø«,ËËA¸”””T1oÞ<÷É“'›i²õüóÏ»EÙÔÌ猛«ë°xñb­K—.®ú|?qâFGG[9Ž›çƒÐƒàNQßæ8®¢gÏžßzë-­´´´9ǤÏüþûïžß}pî¹âV7·Û ——-[Vçèß³gF{pp0‹É«¶0Ü`0¬å8Î~ï½÷Z·lÙÒìƒÔ›&NœèE1Á¹#­Ù­nkÖ¬Áððpw]Ï lÞ¼EQ´ëtº±¬ä   )²,Ÿˆ‰‰©œ?¾ZVVæ1ÛlöíÛ‡ÇY ŒõÉ#­Ì­niiiÕóæÍ»åäߺuë4žçm0Œõ±Ô"Í`0¬à8Î>jÔ(û?þè•ÜTýû÷·¶mÛöŸ¬Oi…Eùø­·Þº!) ã8õVß©—/_®êõúJèÃú8êòŒ(Š%]ºt©X²dI£ž~ô†uëÖ¡ Åpe‚“ß2 ŸÔv4hcÊ”)Λ%îÂ… ]¢(ž€N¬¡‚àoƒa“Á`°ýë_ÿr•——{u€ßÊåË—166Ö £XŸÒJÕvØ¿?iÇŽ»!i5MÃ'žx¢úÏ~ôþ\Ÿ®ƒ¢(oóBà?7€W_}UãyÞuéÒ%ܵk*Šb×ét±Ž¯jô //O“$é Î¾¤¥0 ùo¾ù&ÆÄÄØgÍšu¹  A°õŸ¯Kƒn•••h4íÐuà„\e0ò €:NËÍÍÕA¨€tÖqù‘zÝžzê)—,ËkYKÈ5 C> Ïóš åЃuL~Ês#8}ýàäÉ“Èqœ®T7"¤åðÜA8‰¬ã Að(Ч{÷î]ùí·ßâèÑ£íz½þ%Öržç>‘¬c 0Að,ËEÇ•C`®ž$þN„žÐ…u,:°‚B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!þçÿy°”¼$œ\°IEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_30.png000066400000000000000000000045321456262201400257330ustar00rootroot00000000000000‰PNG  IHDR;0®¢sBIT|dˆ pHYsrr3À™tEXtSoftwarewww.inkscape.org›î<×IDATH‰…—]o_UvÆŸgí}Þœ?±lj_â@œ„@  %´R5bŠ tFªÊ'¨Ô‹~^òzÓûQ¥ŠQ5š¡t¦T3¢ Ó!„ÁL^Hˆ!‰“8±ã8öÿüÏ9{=½0¡)t]míµ÷þi¯µô콈ìµ×æó­ÇöÖol°&O²ÌÄhY‘ò ï‚ F’© DH’:‡Ã”¢ÅΩÎ[ï ÞÂó&ËÚº½ð˵W^y%Ýgñþàõ÷® ÝA6ó쑉7—ê}ãçkÇlåÎÝ»Ÿ®…Ùö—1Ñ Â %•tU2–¨U4–K¹— ådÈ\ÊÊ89„”¼N¼óùì¾íÕá#/=7çÎ]X;wþœýðÇGbŒ8ñ›Sÿ1ºëà:B–G9“c.W©T¬@T’W K@…€@fddÐ6}æë‹“OÌ ÏPNüêÍÕñm#Ã/¾ø½pþý³—=:~xÜó`l¢:ÏDe¢e2H¹ ‚ÆœŽBd GE²"TÖu¿ÂËSGLØûdþ äÞ»·î?ùéõ3O?Ñ;øøã_B?¹¼°|·˜~»)D!e†Bò, ‹pÏÌ) ‹A}¯×ë–gžÝ5<±ÿùc¾bKK·Ó;§NwÇž{¦Ü·w¯=è;snñíÞøcÉ¥ø…†(§%ó` &)@ "hò8¨ïU½nyßS»Ggöíy¢ø*Î_\hoß¾ÅïÌʧ¦&ù oþì…[íÈìé(3š&ƒE@É$AëµÕ2l|vèÈþ©ýö=Y}Þüí»©Œ {vÏpbb'¿êÿhaåTØ1.j“C‚Tbi„þêíj4¬=ºwçwvïú“o¦”ð›w>ð©ñmaûö1ŒŒŒüÁš÷?<»„±}ópÀ ÀÁCP” ðÕÅË[G¹úgßÛwdzj¶÷M@¸·¾¡¿~ËÛ»;LLìD¯÷‡ËÝonœ£tÊ]›o7DÅåÅKà ûñçŸzø»““s[¿ W®]ï.~º Ãf³™™Åצ'OÏ/rtÏ9… *1¹»ÛÊg¸W77>¾tåäüïÏ_O)}íAð»ÏÕKKKÚ>ÒËfgg¿Ú´->¹98-°%ØÂØ êë’ºdÑ:þøýÕ—m1×A[Ö>ÿð™¹=ã/<=÷øÃäÿÖÊ[ÿýîÝÝÓ“[ÖC‡}kTÞ>õÑgW±ë'„6nX—kƒ†u×)_7Oj¬©1³ÁC?ùÁ¥nòÿù·þíêâ¦iñÆ/N,?º÷‘­ýõÿÚï׺´T¿¨/°XK6q Rƒ`M4³AR»)ð@˜ °lzîÍ]ýdksæ¯þøèSÓ‹×®annî[¡pjþÂùrÇþó jIµ ÚÈÚ“Þ±‰ Pdô$šÉ¥ÞØô•GòÐݾ}[­cå~ô󷧦vô¦·ížÚ¹k玱ÿ#™w×ÖÒ…›Í=4u8FÔ ûîªCdî›pDwd2Cp „@¢Óàrv7566²üñ-û§©Ãϯ@WvþÃÅ­;ó…§ïœÛ5=Ù€ÓóŸœéMÌž—Ô4 ±î: Ù‡[ŸDŸ´Z´:æúð%C’ÃLè„’ƒÝÉ“'×ö}éGCÛwß&Ö›\[s¿zâ÷K¿ÜvöòsûgÆÿèâJúÅð„­¹£…Ù ó®a°ZÎÚè5h}šõ­M5zvi*ÕE¯¤*†TÒBáî%˜åî^¬ÞZ|hlçDê’gÁBHòÌ(÷>{ð•‹ùØÎ©5AC-`™ $ ä>0³ºK^´~Ûp%^¿·°4Ò¢Ü\©;†¬ó” ˜·£;vDÄB„iSÕ¿H­ÈàÛ¦¦“I ­Ã[2¨¦‘l` u†Á µ¡µ¿>Ö[!¼6?Ÿ§ÁŽí!d…µVt)`ÊCÆL²Œ`¤RÜì$`D¤3L-¸+9\I á­!´ Mc9hêºIYpËÈúùG±ü*é_*ᤏtúúhÃEÛ®Uæ¹e¡é²$Æ:ïB0š'"€P€(2$¸R›ÚdÙf “g±¡RcêgÜøáS#«$<Ð;À«¯Êö½´ÜªòRý&O ™åŒ·n!Znn­yê,Ãæ_@Qò²°h/².3ï¼U× k{^4À½ãG¦ú›%±iÿò”ÙZ¤êIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_32.ico000066400000000000000000000102761456262201400257250ustar00rootroot00000000000000  ¨( @ ‹‹ÿ㪠ò̦õÌ­î̪ðÒ­"òЮ&óÍ®)îÑ®,ïɨ/ïϪ0ïЬ1ð̨2ð̨2ïˬ1ïʪ0îͬ.óЬ+ò̬(êϬ%ðɪ!íÑ­ôÓ±ñƪÿÌ™€€€ïϯëΧïέñϬ%íΪ*ôͬ.ëͪ3ñ˪6íΪ9òÏ­;îÍ«=ïέ>ïΪ?ïʪ?ïέ>îÍ«=îË©;íÍ­8ìʨ5ïˬ1î̪-ò̬(ð̨#íʰôӱ蹢 ÿÿÿçžî̪ñͪ$íʬ+ïϪ0ì˪6òÏ«:ïʪ?ìÊ«CíÌ«FñͪHñϬJñÏ­KîÍ«LîÍ«Lî̪KîË©JñͬGí˪EïÌ­AîÍ«=íΪ9ëά4îͬ.ò̬(ðË­"öЪíȶ€€€óÅ®ðɪ!ò̬(ïΨ/ñÏ­5î̪<ïÌ­AðЫFî̪KïË«OïÍ«RðÌ«UðͪWñΫXîάYîˬYñΫXðͬVðΪTïͪQï˪NñΫIðέDïΪ?òΪ9ðͪ3óÑ®,ñϬ%î̪íÛ¶ÿ×®ę́#óΪ*ðÌ­2òΪ9ïÏ«@íÍ©GîÍ©MïÍ«RíͪWñÍ«[ï̬_ïάbðÌ«dîͪfðÍ­fðͪfðͬeðέcïÍ«aïË«^î̪ZðÌ«Uï̬PñϬJðέDïΩ>ì̬7ïή/ì̬(ïǧ ÿ̳ ð̨#óЬ+ëά4î̪<ðΫCñϬJïͪQîË«X¦•„‡©šŠ—ðÍ«gñͬkï̪oïͬqíÌ«sïΫsïΫsïάrεœƒÇÀ¸ÅñŒîͪfïÍ«añÍ«[ðÏ«UïË«OíͪHïÏ«@íΪ9ïˬ1ò̬(ïέíЬ+ðά4òЪ<í˪EîÍ©MðέTîÍ©\ïάb¼«™”¾¾½õƶ¢î̪xîͬ{ï̪~ïÍ«€ïÍ«€Ò¸Ê¿¶ÄêèçöÿÿÿÿÐÉÃÕí̪rñͬlðÍ­fïͪ`îάYìÍ«RîˬJðͪBòΪ9ïˬ1ì̬(ëͪ3î̪<í˪EîͬMíÍ©VïË«^ðϬeïÌ«m¿®››ÙÙÙþîíì÷맨îÌ«ˆéȨŒÃ®š®ÍÄ»ÑêéçøÿÿÿÿÿÿÿÿÿÿÿÿøøøþƳŸ î̪xïͬqñÌ«jð˪cîÍ«[ðάSñϬJìͪBíɪ9ïή/íÊ«:ðΫCîÍ«LðÏ«UïΫ^îÍ«gï̪oîÌ«w¯œ¢þþþÿÁÁÁÿÖÕÓüËÅÀæÛÙ×óþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÌÆàïΫ‚ðͬ{ðÌ«tîͪlðÌ«dîÍ«[ïÍ«RñΫIïË«@ñЪ6ïË«@îË©JðάSïΪ]ðͪfï̪oî̪xεŸ—ËÇÁ⺷´íõõõÿÓÓÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÿȶ£±ðÍ«…ïΫ}îͪuîͪlð˪cî̪Zï̬PðЫFòЮ<ðÏ®EïÌ©Pî̪ZðέcïΫmàÁ |ĸ¬¾ëéèøÿÿÿÿýýýÿÀ¼·îêêéþÈÈÈÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÌÇçëʨîÌ«†ïÌ«}ïΫsîÌ«jïͪ`ðͬVîÍ«LðͪBñϬJíÌ«Uï̬_Ò¶šwø©¯ÛØÖëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏËÇóàÞÜûÓÓÓÿúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÉ·¥¼ï̬îͪ„îÍ«zïÍ«pîͪfîÍ©\ïͪQíÍ©G…z˜É¼¸ÒÍÊÓéèèùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÛØøÎÊÉúÝÝÝÿ÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÑÍîçɧ–îͪŠïÍ«ðͪuîÍ©kïͪ`ðÏ«Uî̪KìʨRÀ²¢’ÌÈÄÙüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêéèüľºùØØØÿïïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿʺªÁïÍ«Žîͪ„îÌ«yïάnðέcîË©YïΪNðάSïΫ^ðάiͼªŸÎÉÅßûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷öÿµ°¬üÛÛÛÿëëêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÝÛ×ðäÄ£–î̪‡ïΫ|ïͬqðͪfîÍ«[ï̬PðέTïͪ`îͬkîÍ«vïΪð®ÈÁ»âûûúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿÏÉÃýÖÖÕÿäääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿŸªÅðέˆñΫ}ïάrðÍ«gîͬ\ïͪQíÌ«Uïͪ`îͬkîÍ«vïΪïΫŒðÌ«—Ñ»¦»ÒËÅèúúùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÎÉüÊÈÇýÞÝÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÞÛÙóܾ ‘ï̪~íÌ«sðÍ«gñͬ\ïͪQí˪Tï̬_îÌ«jîͪuïÍ«€îÍ«‹î̪–ïÌ«¡ïͪ¬Ò»£ÊÍżìöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæãÞûÊÆÅúßßßÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÇ»¯ÃïÌ«}í̪rîË«gñÏ«[ïϬPïÍ«RïΪ]îÌ©hïάrïΫ}îÌ«ˆîͪ“ïÍ«îͪ¨ïͪ²ïÍ«¼Ï¹¢ÖØÎÅïöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðïîý»·³öÔÓÓþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæäãô׺ †ï̬oðÏ«dî̪ZïË«OïË«Oî̪ZðÏ«dï̪oîÍ©zðͪ„ïÍ«ŽðÍ«˜ïͬ¢ïͪ¬ðΪµï̪¾ïΫÅÌ´žÚÍÄ»ñöööþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøø÷þ¯¬§óÇÇÆýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿȾ³¿îͪlïÍ«aíͪWîÍ«Lñ̪KíÍ©Vïͪ`ñÏ«jîͪuïÍ«ðέˆïÌ«’ðΫ›ïÍ«¤ïÍ«­ïÍ«´ïͪ»ïΫÀïΪÄȱšÕ̹ìöõõþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆÃ¿ïÅÄÄýýýýÿÿÿÿÿÿÿÿÿéèçõÏ´›zïέ]ðάSñͪHíÍ©GïͪQîÍ«[ðͬeï̪oðάxíÌ«‚îÌ«‹ïͬ“ðΫ›ïÍ«£ïÌ«ªïÌ«°ïÍ«´ðÍ«·îÍ«¹ðͬ¸Ò»¡ÆË¹æòòñýÿÿÿÿÿÿÿÿÿÿÿÿÙÖÒðÄÃÂúúúúþÿÿÿÿÿÿÿÿÇÁ¸¼ñΫXïΪNðΩDïÌ­Aî̪KðÌ«UñΫ^î̬hïͬqîÍ«zïΫ‚ðͬŠïÌ«’îͪ™ïͪŸîÍ«¤îͪ¨ðΫªïͪ¬ðΫ«ïÌ«ªîÍ«§Ñ¹¡µÒÈÀÛññðüÿÿÿÿÿÿÿÿááßõ±¯®õóóóýÿÿÿÿìëëøÁ¬˜oñÍ®Hïʪ?îË­;í˪EïΪNðÍ­WïÍ­`î̪iïͬqðÌ«yï̪ðά‡ïÍ«Žïͬ“îÍ«˜ïΫ›ðάï̪ŸïÍ«žïÍ«ðÍ«šîÌ«—ïÌ«’ͶŸ¤ÑÊÁÒòññûÿÿÿÿñððù¬¬©ðíììúÿÿÿÿɽ¹ðͪBíɪ9ðά4ïÊ©>íÍ©GïÏ«OîΫXïͪ`îάhïϬoðÍ«vïÌ«}ïΫ‚ðά‡ðÍ«‹ïÍ«Žïͬïά‘ïΫ‘ïͬïÍ«ŽðͬŠðΫ†ïΪîͬ{Á­”޶Æððïúûûûþ¤¢¡íäãã÷òòñù¸¨˜að̨2î̪-ì˪6óέ>íͬGïÏ«OíͪWïΫ^ðͬeî˪lïͬqîÌ«wîͬ{ïÍ«íÌ«‚ïΫƒðͬ„ðͬ„ïÌ«ƒïΪï̪~îÍ«zðͬuïÍ«pîÌ«jðέcɳœv½·½ìëëù¹¸¶çÛÛÛñÈÄÁ¹íʬ+ñϬ%îͬ.ì˪6ïέ>íÌ«FîͬMðΪTñÏ­ZïÏ­`ðͪfîͬkï̪oïάrîͪuðÍ«vðΫwðΫwðÍ«vðÌ«tïͬqï̬nîÌ«jíÍ©eï̬_îˬYïÍ«Rî̪KÀ«–a¿¹´®±±°éÉÉÉ쟗‹XëΧêϬ%î̪-ðά4î̪<ðΫCñΫIòÏ«OðÌ«Uñ̪ZïÌ©_ïάbîͪfî̬hðάiîÌ«jîÌ«jî̪iðÍ«gðͬeíË©bïË«^îάYð˪TïΪNíͪHïÌ­AíÏ«:ëͪ3´ ’K“µvttÌÌÌ™ìÆ³ð̯#íʬ+ę̈2ñÍ­8óέ>ðέDñΫIïΪNïÍ«RðͬVîˬYîÍ«[ñͬ\ïΪ]ïΪ]îͬ\ñÏ­ZñΫXðÌ«UïÍ­QîͬMñͪHðΫCîÍ«=ì̬7ïϪ0ìͨ)ðѪ!èÑ¢<<ðͪBðÌ«FñΫIîÍ«LïΪNïÏ«Oï̬Pï̬PïÏ«Oï˪NñÏ­KîË«IðϪEïÌ­AîÍ«=íͨ8ðÌ­2î˨,ëɨ&ïέóΪÿÿ€ÌÌ™óζöÑ­ðÒ­"ì̬(î̪-ð̨2ñ˪6íÊ«:îÍ«=ïΪ?ïÌ­AðͪBðΫCðΫCðͪBïÌ©Aïʪ?î̪<íΪ9ñÏ­5ïˬ1î˨,ë˪'ðѪ!ìЪÿÒ´ÿÿ€ÿªªîÌ»ôȦöÑ­ðѪ!ëɨ&íȪ*î̪-ïʪ0ðÌ­2ðά4ñÏ­5ì˪6ì˪6ñϨ5ëά4ð̨2ïή/óÑ®,ìͨ)êϬ%ïϯ ìЪèÑ®꿪 ÿÿÿðÀ€€Ààpaperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_32.png000066400000000000000000000051171456262201400257350ustar00rootroot00000000000000‰PNG  IHDR szzôsBIT|dˆ pHYs‹‹áÐÒ¼tEXtSoftwarewww.inkscape.org›î< ÌIDATX…}—ÛW×uǿߵ÷¹üæÆ0Ã5 6ƒÝ¸¦1ØM­8ÈÆí[þ†HU¥ü ùúÐG?UêC›"5Š¥ÖiR;µ;0`n¾qÇ€™ÃÜÎm¯o,ìb–t¤#íµÎç«}Ö^k/â;|XaõøìÀ­./‹že MæU›™,"2À‚Ñd0’L]Kð˜)ªQç™ç¦„SÓÕ)šwYÛ2µ‘]Û}mK?;°v‘¤î3yÿå͉‰l³í^¡›\M—;,sXfb¤ºˆÀ Ò‚ÃIr%^‚$‰‡)Á”c§Î»j ©Ež5P×ôÙèÒÄÓ˜û%éß8ü‰ò°¼4j¡)Ú. å`—ƒ),£)D”‚H#A¦{¤ Ñ’wÉ­ IS]‚ÚL¡iå <5Y넸ôé³3¿$=¼91‘,ëÐKÉû’u½HëCÏ€`%¨’@®DI…ÂM…ˆÂ¤ÜBÈ\ÈfŠ¢¢‚‘AðàY´¤dŒ´Á©¹ìÖÙöÇ![[÷¼Ï“—CaÎÒ©ð´ÉsÀ2‡gÁÜM0˜H×J¢Ë xRJu h‘Ô*¨”B$<&?~¼½sùï÷í{a}̘÷ÃSò’`I¨¤¼pZ€AyräÊÜÍ 3ApP)Ð’ .Im $e2‹ ·/œÙòøþöñÕéÅ»~þ÷ÄÀ?DO©„¼ ¡(¥¦‡`¥»—„ 9 wfÈ$äFE‰‘R€‰ï%¡$ƒË‘Hu„µµ‚2 ïÜøbó¦¾úàËöüõ±ãÇ¿ÞýÔSåWS3m}îïÎD3+RDzSÓ3³R°’P CAX!©€1˜Aˆ  ŠZÉdAp’ÈΡ֤fòê™±ñáøü+?Þ½w ¿?þë¿ýûì+/Z5d8~ñWÃO„"2yAª­0g  LR`)g)¨4c.©”Ê@€æ.#!˜$OÛÅéK#ãkâ3¯þäÙ]CCƒqnînóë·Þº{èõ×GGG²#ïýýÈ“û®¢KE™Èé,ÜXн4²Ôƒ¡4±”«UÌ d’"Ha —@OK3׆ÆVqû«/>±uÕÐP€+_~¹ôñ‰“xýàÁÁ»}{¦>?]½½n+óŽ–bGÏ ËÏ)+,Œ,à^Bè(a,)” €9‰!2ŠZœ½6´¡¨·ütÿŽõCƒƒv¿¸ùìÜÜ™[}oz-fYF8þéù÷GÇ8ÕÁsEv‘ŠQì2À23¸ç ³»«y//ÐQ(Hd‚âkçV­Žë_{á©‘¾¾Þ7UÞ}ÿÃ;5ôâ ûÍlEÓäÔôÒµùòÈÈ g3c¤<Œ ŒJž‰Èf.å sJ…%È® ÅüW×næú7^}f°×û6¸ªkýæ?»8¶iÃÐþ}ûíÁµ‰O/]µqû]¢"Áa ƒ'Á¸GÌ¡X²8vÊG‹°jÝ(6mÚôP¿Sož\·{ÙAq% @@D"္¾¾¸kÓ üèо-ñ`X®*¼ý»#é/vo«†‡±vÍš‡ú}~áÒ\=0vªpm¥k¬.ÈÅ®ëÔLžÝ;¾nàà¾?ÜBx$¦¦o¥ÓŸœK{vnË׬Yƒáááïõ=syæT9úd%(Á•`LH]‚3ÀÃö-ñÌŽñm}eÙŸE褂/.\ª§&oá±kòÍ›7c``à{}OœþtövÜð-T+Ñj‡µ«ájÂ/þñ°/Çá³w1|ìä…¯Ž]¼t~ÁR³fíš‘¾ï~𣉓 ƒý}9Õeããã(Šâ{á’ðîÉ+ÊÖ_Q+€Z@ ¡U›A­ÃZ‡ÚÑ ß¶u{ŽÊþé?~÷Á;SÓ·kpwü÷þ8;>¶©ÿöôdܽ{7²Gœ øó‰³“atüŒ šb ²†Ôl¬!Ô¡©S ¨±`!Abèë_5ïýC¿ÿíÄ•/ÆG®š¿3Ûÿòß¼8réÒ%<ÿüó@J ¦—Ž–ë³%P•¤ B Y x A´&ƒ¼±`µä5ÉŠTEª¸<°~Ë•ó“Ëï¾~ð'#€…ôÇ?MÜüüÜ…}çè>hGO~rµÜ°ã%8—,SVѼ"YɬF«¦ƒš¨à5œÉ ÎÑÜ`‘®—R}þüyíÞótý?'®¼Wo»29ÛÆ÷~óÁøÖu}Ûö<¹ydžuk¿I†º®õÅÍÅwû7j‰D X ·æiÈʽ­á¬££Ž¬‚Ý Þ¶€è»cò”êë7n,ÿùâ̯Êu;Ï“ó°zlÏé;Àé·?¾¶jcq寞ݵå/7¬_Û;vêóÏú7î8m ¡Æé™jÉk$TnVù²YªÜS».T1˜WpÍE&ŠIIÝ­ééù¹Ùð/[Ÿ;x’`ty4Â$7˜ahÝæù%àÚ¿üÎcý_¹1×}8øokhhÔ¡‘±Fd¥Ú’*0,Ó°Ì_¦Ñfqzج¯žÊdV©p÷`n`&xFÜk݆ §‰n†ÀîUS—ޤ{SB-‚5ÔÊÿžj³P¹§ºmC5 O‡]kYÿ`ì¥èH¤™“"Íåò&E&8…†b+¢%­½¡«‘Ù½sÍD±f°ÊˆÊ¡J…*dÙ²• ÕЈfßxºoáþµÚþù½ÉѾ¢†ÜRWxfº”3æQmʈa b43º§fC(XHîZçT'ª3x …Š åMÊòz Zž}ßè]¬ì@Ò¿<òæLx7±Yb´ƒ-"pn Ý‚˜ÍË0Œóò4ù¼Èy%Îã¼æ“§…`˜o=-йç¼Xèd‹ÑÛÅXÆÅjêîûpàéø¾¾¦^75ß_ d ur‹t‹H ˆmh*ËA#Øu+ƒI”ä‚,Ȳ„N ¡JÞä](S­hëùÔÎæCó?ßËöAÞÿˆ:úêÓ+FùáC›î}y×ËsÛØ6ûÜ¡sÿÍBå>ס••Ì:îVAmd±„±t¨$PÀX ¡04Ñ ÒL&( 2*ÑE&šÁ²Æ‘㥮]1¿ý·o½çãß}ríС7üÇ?þ»‰'þ?¿fý)‚VÆ"–©m;DQ‰Þ‘±·Šô Dé®ÊŒ¡BdAõ Â7ˆ‚ Ì g@ `ëP{éôáUScqëÃÞ½~dx8¼´s×ùœRõ—Ûÿbèà¡Ã'Ûñ[Ÿ+R®¢hev¯@–¤W«@«dÞé¿°ªŒ¬•’õ¡€¢!  ùì¶gOX²|˜wmÿöŸ¬6IøÅÓÿ}nÙ²¥ƒ[þtsWö¿}ò™á[·1{.#R.ƒY‘ÈÒÝ+3VîVÑXQêÐX ¬ TJ %É)‚ ’Òæ³K’LO]¼zQgݣݻ¼Ûíôz=ý䩟]Ú²iÓðú;ï(`ï¾ï MÝ» ÙË@æ(x‘%ÌK V@,^™«¢±’Ô!P êÌ_çRê_kI‘¤9A8@Ò/y{bj¼XùÈ÷6-èv?OšŸœ=×ìܹ³~`ëÖkV¯ŠsÆ‘÷Ïÿjxju¼,EFˆQP°0 QÊU©\ˆP•Ô?> É Y}áÔÂÅvé£ß5ÖítnÈÞo½s¼÷Þ‰üæÖo ,]º$|öý+»_;>¸rÓAÁ l‘£ 1€æÑ³  ƒ À ÉRb z%±C²Їc}áñEUoñ7·­®ªê÷k5^ݳ÷Z=ûiwË–Í691ñ9hÓ4:9SﺅÁ¤˜å1B 0Oˆf¤FÀ €0ŸyÁÒŒ¥»:4T×>>qÓ²!¿é[Ûî*æ«ýõ& /îüõµåà†Í›9<¼àFн/X¹ñÉàòhê×Èh„eåÌÌå@€!À@†ù+*”syùãËn+—þðáMC1Æ/€ÀµO?ÕÓ¿|¾YÛš¡uëÖ¡ÛíÞøüÚ§:qvnÏØ-4—#M !çI’@_1怙h¢ ðà@ ê™7¯ SöØ}£_ÒygüÀ¡7ÓúÛÖTëׯ‡™}Áç7Ž›Úð¾#åÉ™‘Œy^×Ài P_Ðs¶æüÉ[–Ûí[¿{×Dá‹×Ùá·ŽùÌÌY”7nüRŸK—/ç“ç}ߨH§BÝé#æõZh€”gϹõæÑ°ù¡ïÞ7ùu °ã׿õ…ƒ].ž³ééé¯ôÛsàwÇ–ßþ1¸; `$¸¢ÈY†ÚœÐ~|äîU7 ~óþl[Dò+ÿø3Ë9ãW/ìÌÓk§BÎ ëÖ­ûJß /µÍuö Ó9É ©¯²‘’׳W8{úÐ7î˜Züû`ÉW®^ÕÿþßÎv뽛˦i°zõª?è¿{ÿÛïßtیܠ;á}©—»èñµgÿáwM¯~ðo~ôØŠ/Ë#_e§?ü(½õÎq¿gÓÆÒݱråÊ?èæwŸ´3iÁa –ž L ²;Üh9™?{ýÂcu¯<óîë«–,(ïX¾xd÷®ºmb|ü‹ÉeÞö>:—ë&,]PŒŒŒ`rròk7ðô »§‰é{æ õ`aTî=€=Áf£ Tv«fêÎûNÁììŒ|Ͼ|djÍXñж-7t¯«G°ã•ÝWWÞ¼d Ž&&&0::úµ0§NØ»àcû†¥òdC²qÏ d”àL!(Z"´„µÌj¬Y´býé«Ã·ÿôÉç÷þÇ‘·Ž€¦iñóg~yñžMw ÍõzaÅŠ ì{óÔ‘áÉ%ç«aV÷ÅZ_Îê¯ÔzVеB3,ZPÈ‚™Ñ$qtņ7^ûèÜéc'_zÄÒÜò=þèÂ7ÞxÓÓÓø²rñeöÞ©¯^­ï’æh¨%Õ4Ô&«3ÔPj@4ž½°Ö2¼¥¬1³ÚÄÚhµ¤þɹ ]8q¶Þýøcß[¸sçN à¥]¯^Úõ›}§ß?ýAóu@{¿·pxü"Èœs$ç$Õ¢úëÍG !4ˆ¡‰!„:e7Ck²‚r'i0s¹Ó)yöÔ\¼xÑ׬Yƒ£ï~pìüàíÏ–U…“Çg¸×Úå“C«6oX75¼`Á ôè[Ç.ÔC+_4Îö#¡&K¹Õ,ú`p«ƒyÍ`5³7±m¼‰!YÁå Ü]„ÂeÌÊyîý÷OiærïÍ UOUe¤Ùàè¢G]¸ßûÓ,™Z6oÞ°nzláh¯¿yz÷Ъ͵ Z€MEÖt«!Õr¯eV£ñ¦±ÜÄSmÖ…ç ËŽl&º„H˜áž%ï=÷ÂŽ·Woûë,»]xöh€õ«4’ã+o;~Evì¿v]ºj<|« Xßþ"\sfÖ:ÐïË‚5îÞ@¨eªƒY-÷Ú,ÎΚÏœ]VëÚ@J±2³*ÒÊœs²½X\9v¨3бNg0ˆò `¾·2dAÊY$üÜ™“ËV]‘,+y°–T¿Êmkf5å‡P»çºðXŒ\Š'?:snrblQI`×=''³‹–K#ã“-ÅèÆ„åÁ ó=Y¿·',»Ì‚'eMÞ‹€'Õ™¹|~Œ¥µ©rt 0•a~úaÑ“° à 2˜Üû=©$Qp78\T ɳ’Amþ|úá ÔŸ€0Ä^zgèüöíÌŸgá§vÐÅÈÂôš e„޶$Æ,‹10À’r(b¤;Í‘‘ ÁÕfQr0ô§Œ)PIÉS‚ZCnQMèå¶Œõ\ï½%·oï®n( O=Z¢ɈE‰XdYab´"ÅT3"0ÀSV˜[2CÁœA2ÍcúR‚!º¹Ù{óßpõ‰'èŸ1|Ags†á6Ü`FFXH`S$XVâȮȮÄÖƒ§RNUžò¤*?ç%/©ÊÅ/Ž+2¶*NJvLY2–„d „daFXBÜÌu€™Ùݽ¾<ìF2º¸_ö™Ù}öþÕk­îõ-âcû³Gû“ÃI)Æ¡³‡8TPà9¸Ñ¢Ñ¼ÂH²4‚¿}J†+ÉY{Û]aª©¢¨"ª"{­VKo²÷ÚSõµËsÏ=ùÝL¼þIüîÞs³bJ½¢éT'C MŽ&‹ˆ eÚ"B Ñ’ÁKp£©ÒHd<«0IÄÝ\^ܦ[‡Å Su¦ME楶^ªÕ0”1uþÒ7/Ÿ¼!¨$ûæîcs›Ôë5ˆ©*'ÓP´ÄX¼DcQÉJ`0  ‘îU…ÀoQÈ™¯‚Ó5UVUg,‘*n^<{ H9 ÕÜNö2._¹ôÅm /½ôk’íí¥<„6499BŠ(‰±«©Æ 1ÀkE«™Ãœ ß±BB ®Ñä`¨0U8*ªª¨ŠØCÌ1=gx“5O¸.~uË‚  $>¶wbÞ$Ê0šK-KÁä¨IÅ#…Hy„Åà¨ÑHëHÜä0t€á&`€Èà”Ü î¥:hÕ XªªQ…P6„L(Wx6x¦b‹¦¶—‘ÏýýŸ~lÛw~îtÑ,Ѱ4ÈÖ„d)—Ú09<1Ĩâ‰ÑU#Äc€Œ0¹@IÀf€ÎG%§à *ˆ*Z«ÊQ” ÖA2äšÛÜÄÐB±=ôóŸ6'÷?ý·GÙÆG_<·"çÒk,4,ЛRkcÁ’Àd`¢OÆÀ²ÁD»Þª×|Ê ’C¤´ ¢BªŠÑм³¦¬éP†¼=~ô`oŸz°^¹ôù¦× ¿yâô?ÄœK¯ M)Ö­j²!­‘ؘ€‰fÕ“`AðH÷h„Û;‚&r¸Ì¬ªÊT£ `¥B…T,öÖ¥#ýh1¾Ê[ÿðG ` h kíÑÙ£[d´ž\C¢ 9©oä >¤>Ìú‚† ›±/`˜°aÁ†¡Áÿɾª†êêKÖÔ7qU}ɇ.œ<6¯¼½ç¡mkfüóW¿üçùâÏ_ ###ÍÖ­[Gö>öpD?Ř˜PØ€%Þ DXzcCy#0q`] ÆÎW‰@÷àf$`‚Àδ’C¢ÜÌ*ÄAÄ«ÌòO³7cêØ–¯_óñÛÆîŸ===­ý÷¯ŸÝö0s||lèÿ÷ãç—oxðÙ.¸KmŠ¡aeó¦[~6.ï±Ø€läj`H“K,á €¤ä¹IpYåršÈ+hùì±7ç M»û¾;WoûÌL8qòdûío?<ýùÏ}næªU+Ó¥K—Ê¡cç¾»b “‰ÖKd"™<{ãÆ^§z€—zF&ˆ "J€âÕèdØ¥S@Œt]v¨\<ýV®.®½ÿΛï¸åæu3®úó¡ÃG.ïya7¿ò_î/X° ÀSÏîÞ½lç8jÜ#£¼&Ð’Wo,X¢˜o6z6’zÁ É‘®#"®.=ä¤Õ § M¾=¶íÎÕ·®Z¹nèú­qç“Ï\øÍé3>û'„Ù³gΜ9›Ÿøá²ùL+•j41:ØåI‹QU dÔPè–]ê™ `…@r©1Z!E&À:‹:è܉7û#õìò­kWݼzÕ}Í»ÎxlÇÏDøÜÏ~æë÷û×î=³ç¥=ËÖn=B0RŒB›bUíQòDc”< L R ØÕ˜YryCX!–ÿü‰cýY8³ôþܺxåÍë#Þ5&'§ôßzxâ¶±Uó¶nÝ 3»vïø‰“íëçñÄ’EŒtF¢FY,ЦYT|ш”w‘îhÀκ€=ȈM竈‚âÄÉ·fÌÔùÅ÷¯[9ºbùG»àäÉSåñON¯[;>ëŸøÄïÜæ…_ì½i|ãÛ”‚nÅaº4Ó]]Œ”"ɳ )vVÖ =¡ÔÀ¬ÔÔLœ>6k¦Ÿ[üéŽÍ^ºdÝ àå}ÚW½ª5«VÌØ´iÓïÜ?úÖÛ“'óÈS‹iB ¢9LFƒª<i23ÔtÍG< Œp%"¨¹röÄœÑ0±tË7.Yò»Ûµñô³»§=O…ñ5·Æõë×ßpÎ3/¾òò¢ÏB*è Š4#,Š0y53v ›0T1)ë’8ƒ‘APÏ;2w~seÅ­›¿dñmï ( ÿýئW.[ÒÌ\8ÊÕ«WßpÞ¯^ûõ•‹œÿܼAPJ0‹ {5¸YdÇGy1‘„dÝ„` M.ÜÎ=4:¯7=öà¦Û/Z´ð}àâÄùî÷Ë–{ïîõû}¬\¹ò=ç>ÿ‹Ã¿]±qBòk遼$éDW9• ¬"I8Ä®¼0¨Vž}ëÕ…·Ì w|rëøòѹsÞÓ¯o¿}B»žÛí[7oŒsçÎÅ¢E‹Þsî+].3W¼w‚.ÑÌà€ïê† Àj÷%@3'_;pÓM#uö®_ùa`߃ºpþ¼V._.\ˆÑÑÑ÷¿{ÿëûGVmœ4R. ï|]¬µÂŒ2ƒª$Š:÷Æþå7ÚÇ?uߺÛçÌ™ý¡à;žðe‹rx(Ùøø8FFFÞÿGí?x o{I€Ü@Qºƒ7k…"£™WI¢tlÿÏV¯^<üÉ/|ò®µsfÏþ@¼~ÔZñØŽ'ÊÇ6¬¯½v›6mBJé¿·÷Õ£f­Ü8-ÉAs‡ .‰23wIÑ-øÑ—¿cléìOÿÕƒ[îš={Öï'&ôï}¿|é¡?K/¾ø"6oÞüŽÝæ½Æ®ç_8ß¿iÝ>° ªRp¼+_è|#6ùwwޝÜ0tÞŒ‹—.„óæ ‡ðáWûÈGËsÏï)ŸýôýͰyóæ.f?`¸;žØ}p÷ð‚›¹”)d@™D†+Ó, ʲ;2¿÷Ò…ä>dfCm;ÝcßÓëo]<ûîõw¬Z¿fÕÊï÷²={_žº|y"¬½}<=z6løÐ?ð©g÷üæxºe»Yš"9%išäàs¦8åô)ºM¹ù”ÁK…£V/5¦”Wm¸o?nÚøÈO^ú§Gþ÷ÇÏ8yª½Ñ‹~òÔ®K³gÍH·­NçÎû½ K)8tâòK!¤i3¶€2¡,©ÈQä*¢Š1‹Ö]Å0¨­-_­ åµÌ]¼üL\~Ï÷Ýuð;vîzC m3¾õðw.ܽ~ÝŒ,LLL`llìCCÀOwí96wÕG÷Clåu°Ä– deËB+GAU**4ËrÒ2áffæNÎ…·¬ûõ™œ¿ñõG~°uÓ+îÝ·ÿ•é¯|é¡9‡Æðð0–.]ú{ANMMé×g¦^ÍišZˆ­€–P+²uW6^·,ªX 92y6šyVpÀ« „‹F¢éõ4:¶eç ¿|²ÿ×_zèÞ;wBæÍ›‡”’,XðÁÑ3Oþì…×ç®Üp@RØÂØšÔBj´Á¬­¥dr‚² ¬Ú–hˆ¹–j fNw£áE € €HúœÙs¦&''µdÉ,YºÔùáÓOO¿6ýZj_Z¾xthéòùsVÜ}׺™ïõ/^ô禟]4GS³\B+±ÑW­ ð¶eÏŽ˜cÍžSXj%ÑAVïl J¨&3¸ÀJWyùå}ºýöÛõÈcO=>o|ËnPAÂéJüüà•+qï#;ÖŽ-Ÿ³nËÇî^úî„¿k÷Ë­Þp@RIeò5KJm…Z3›¦Ð*†ζI¡ˆÞÖœIöXèŒÌªp™Ñ)VµªÖóÎçÿzlçŽùã[ŸŒÁ††gphüÞçÎÏýÛöÇï[:kã¶-›nI)áìÙsåÈ™ü“Å£œ4¨@*næäUYTkò-åm‘Ú o¥Ø–v2sûÞS«Á~cµôÀ:П¬AõF¡Ó4žúÏüꪱµ§—ÝóÀOŒ®N'a’¬“»‰lêä/ïX³°÷©ã§Ïž¬‹6|C°bÄ ¢»lãPf­Weµ€·Th!oÝã4Ü[>úò•eµ\CXjÚ@Éã@$늾×ퟷbͺË äÁ4¨>²£¡;‚$H¨j'/ñÂÙý…ËÖœý­P6H‰D'”UË1¨­ðŒ$[¸·v‘ÛŸ=Ú¯qx>-4`i"†X‡¥€ÚÁª&‚ÑÅŒÁU£1TƒH“:¾^Í“ 3HòÁ~ † WKCQUIÑr®W5Rψ¡-Y)¶RmÛÉCþËiÀö gçÔ~Hhs’'&Ï–„Ú ¹è´Ñ`1Àk€D˜ @èÎâWÏ‘µB&QÁip—œ¿ª8 VUœ*†Å¶Äl­g¤Øz®%O/¸¼à7Û¶±\³Àÿì:=óÊ0fvú½¥ˆœ–(‹5vÒ¸Ëbt„b f0db·ìD×l¸âIÑ‚—R;iÜBŽZ¨ W ƒ]Ñ©bŒÙóT HMÓµ=_=wµCòŽ„÷Í'fÄ¥##=ŸNu*$kÍ-1šrD`(ª1 º"".I‚vÝóJ-°%у[€×«Í†ÚuEºFC,NÏ^ ž«Õ"Ïí’‰%ç·mc¹ú¼ßÉÌ?ü•zç/Ÿ}V¬˜NA!"2˜rDìÔà n´`4Õ΢•$™»JÈ€"}¦®}C¿¶¨Æ¡TÚ2Y“5%¢É5x)9O¿r÷܉¯‘~=× ·íÛFî:;ãü…ÔDŸŠhFBðéˆÊ Ø·!Ãdh6h„Ér}C,¡(ÉbrŸn…¡TÍá,^T™½NF¯½ÉZ û˜5ùÅ͘¨w3ý?´c\Vÿ‹IEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_48.ico000066400000000000000000000226761456262201400257430ustar00rootroot0000000000000000 ¨%(0` $QQ¿¿€íȤòÉ®óÑ®ëΧíʧïǧ ðÒ­"êȬ%ë˪'ìͨ)íʬ+îË®,î̪-îͬ.ïΨ/ïή/ïʪ0ôή/ïή/ïɨ/îͬ.î̪-íЬ+íȪ*ì̬(ëɨ&ð̯#ðɪ!î̪ìЪêʪò̳ðÒ¥ã㪠ÿÿߟòÉ®éȦìÆªî̪éË­"êϬ%ì̬(óΪ*î̪-ïή/ïЬ1ðͪ3ìʨ5ñ˪6ì̬7íͨ8ñÍ­8ñÍ­8ñÍ­8íͨ8ñ̬7ñЪ6ñÏ­5ðά4ðÌ­2ïϪ0îͬ.î˨,ìͨ)òШ&ð̨#ïǧ íÑ­ëÌ£çΪªªª꿪 óÑ®õαî̪ðÒ­"òɨ&óÍ®)î̪-ïʪ0ëͪ3ñÏ­5íͨ8íÊ«:î̪<îÍ«=ïʪ?ïË«@ïÏ«@ïÌ©AïÌ­AïÌ­AïÌ©AïË«@ïΪ?ïΩ>ò̪<îË©;íɪ9ñЪ6ëά4ïˬ1îͬ.íʬ+òѪ'ñͪ$ïϧ íÑ­êʪäÉ¡ÿÿ¿ÿÿÿî̪ëÌ­íʰéË¥"ëɨ&íΪ*ôÒ°-ïˬ1ìʨ5íͨ8îË©;òÍ«=ïË«@ðͪBðέDíÌ«FñͬGñͪHîΫIîË©JîË©JîË©JñΫIîË«IíͪHðЫFð˪EðΫCïÌ­Aïʪ?î̪<íΪ9ñ˪6ëͪ3ïή/óЬ+òѪ'ð̯#ïέìÆªóÑ®ÿÕªßϯìÆª÷έñͪ$ìͨ)î̪-ïˬ1ñÏ­5íΪ9ò̪<ïË«@ðΫCíÌ«FñͪHñϬJîÍ©MïΪNïÌ©PïͪQïÍ«RïÍ«RíË©SïÍ«RïÍ«RïÍ­QïϬPïË«OîͬMñÏ­KñΫIíÍ©GðέDïÌ­AïΩ>òÏ«:ì̬7ðͪ3ïΨ/óΪ*òЮ&éË¥"íʧêʪÿÕªî̪íÑ­ðѪ!òЮ&íЬ+ïʪ0ðά4ñÍ­8òЪ<ïÏ«@ðέDñͬGî̪Kï˪NïϬPðάSðÌ«UíͪWñΫXî̪ZñÏ­ZîÍ«[ñÍ«[îÍ«[îÍ«[î̪ZîˬYîË«XíͬVð˪TïÍ­QïË«OîÍ«LîΫIíÌ«FðͪBïέ>íÏ«:ñ˪6ę̈2î̪-ò̬(ð̯#÷̪ôʪÌÌ™èÑ¢ íʧðÒ­"ì̬(î̪-ę̈2ñЪ6îË­;ïή?ìË©DíͪHîÍ«LïÏ«OíË©SíÍ©VîË©YîÍ«[ïέ]ïϬ_ïÍ«aïάbðΪcðÌ«dðÌ«dðÌ«dðέcí˪cíË©bïͪ`ïΫ^îͬ\î̪ZðͪWðΪTïͪQîͬMñΫIíÌ«FïЭAîÍ«=ñÍ­8ëά4ïΨ/íΪ*êϬ%ïέêÊŸÿÿ€öÛ¶ð̨#ò̬(îͬ.ðͪ3ñÍ­8îÍ«=ðͪBðЫFî̪KïÏ«OðάSíͪW¼¢ˆkïË«^ïÍ«aðέcîͪfî̬hðάiîͬkîͪlñͬlïÌ«mïÌ«mîͬlñͬkîÌ«jî̪iÄ«‘yâ iïάbï̬_îͬ\ñΫXíÌ«UïͪQîÍ©MñÍ®HðέDïΪ?òÏ«:ñÏ­5ïϪ0íʬ+ñϬ%ïϧ òÉ®ð̨#ìͨ)îͬ.ðά4òΪ9ïέ>ìË©DñÍ®HîͬMïÍ«RðͬVñÏ­ZïΫ^WURầ‘†î̪iñͬkï̬nïÍ«pïΪrïΫsîͪuðͬuîË«vðͬuðͪuðÌ«tÙºz²§›³ØÖÓ𬡕°îÌ«jðÍ«gíÌ«dïͪ`îͬ\ñΫXð˪TïÏ«Oî̪KíÌ«FïÌ©Aî̪<ñЪ6ïˬ1óЬ+ëɨ&ïϧ ò̬(îͬ.ðά4íÊ«:ïΪ?í˪EîË©JïË«Oð˪TîË©Yïέ]ïË©bîͪfš˜–æ¸¶µí½¨íÌ«tðÍ«vîÌ«yî˪{ïΫ|ïΫ}ï̪~ï̬~ï̬~Þ½ž„«Ÿ“ºÎËÈîÿÿÿÿÿÿÿÿÍÊÈëÙ¼œyï̪oñͬkîÌ©híÌ«dïϬ_îÍ«[ðͬVïͪQîÍ«LñͬGðͪBî̪<ì̬7ïˬ1íЬ+ñϬ%ô̪-ðͪ3òΪ9ïΪ?ð˪EñϬJï̬PðÏ«UñÏ­ZïϬ_ðÌ«dî̪iïΫmÅþ侾½üÕÓÑîÀ¨“™ñά~ïΪïÌ«ƒîÍ«…îΫ†î̪‡Ù»œŽ´¨›¿ÆÄÂïþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯¥™¼îÌ«wïÌ«sï̪oîͬkðÍ­fíË©bïΪ]îË«XïÍ«RîͬMñͬGðͪBî̪<ñЪ6ïϪ0íΪ*ðÌ­2ñÍ­8óέ>ðέDñϬJï̬PíͬVñÍ«[ïÍ«aîͪfîͬkïÍ«pðÌ«tÆÂ¾åÇÇÇýúúúÿÖÒÑðÁ«•¡ðÍ«‰ðÍ«‹ëË©Ž´ ‹®¸°¦ÑÒÑÏôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÏÎñÒµ™‰ðÍ«zðÍ«vï̪rïΫmðάhðΪcïË«^ñΫXðάSîͬMñͬGïЭAòÏ­;ñÏ­5ïΨ/ì̬7îÍ«=ðΫCîË©JïÌ©PíÍ©VñÍ«[ïÍ«aîË«gîͪlïͬqðÍ«vîͪ{Å¿æüüüÿ°°°ÿÉÉÉÿ°¯­ö©¡—Ö½´¬ÚÇÄÁðõôôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²¨žÇíÌ«‚ïΫ}îÌ«yíÌ«tï̪oðάiíÌ«dïΫ^ñΫXïÍ«RòÍ«LðЫFïÏ«@íÏ«:ëɬ4îÏ­;ìͪBíͪHïέNíÌ«UîÍ«[ïÍ«aîË«gñͬlïΪrðΫwïÌ«}γ—‘š—ëÿÿÿÿåååÿÍÍÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÚ×õγ˜—ðͬ„ïÍ«îÍ«zîͪuï̪oðάiíÌ«dïË«^îË«XïÍ­Qî̪Kí˪Eïέ>íͨ8ïΪ?íÌ«FîÍ«LðΩSñάYïϬ_îͪfîͪlï̪rî̪xïΫ}­ž²ÐÎËðíííü•“ñüüüÿíííÿÅÅÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿµ¬¡ÏîÌ«‹ðÍ«…ïÍ«€ðÍ«zîͪuï̪oî̪ií˪cîͬ\ðͬVïÏ«OîΫIðÍ®Bî̪<ðΫCîË©JïϬPíͪWñέ]ðÌ«dñÌ«jïͬqîΫwÆ­”²«¥Ôõõõþÿÿÿÿÿÿÿÿúúúÿž›™òìììþôôôÿ¿¿¿ÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿßÝÜøÈ­”¢ðÍ«‹îÌ«†ïÍ«€îÍ«zíÌ«tñΫmðÍ«gïÍ«aî̪Zí˪TîͬMðÌ«Fïή?ðÌ«FîͬMð˪TîÍ«[ïÍ«aîάhï̪oÞ½ {³©½ÛØ×õÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹¶³ôÑÑÏúùùùÿ¸¸¸ÿûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹¯¦ÖïΫ‘îÍ«‹ðÍ«…ïÍ«ðάxïΪrñͬkíͬeïΫ^ðÍ­WïϬPîË©JðΫCñΫIï̬PðͪWïΫ^ðͬeÅ­|­¢˜¸ÌÈÇëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÉÅø¼º¸ùþþþÿÂÂÂÿöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèèçúÆ®•«ïͪîͪŠïÌ«ƒïÌ©}îÍ«vï̬oðάhíË©bîÍ«[í˪TîÍ©MíÌ«F„wmž”‡‘¨’¢´¬¤¸¿»·×ÝÜÛ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿàÝÜû©¦¢øÿÿÿÿÈÈÈÿíííÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹°¨ÜïÍ«”ïÍ«Žðά‡ïÍ«€ðÏ«yíÌ«sî˪líÍ©eïË«^íͪWïÏ«OñÍ®H±ž†i¶®§¶àßßõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿòññþš—’ùûûûÿËËËÿçççÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿìëêüÁ«”°ïΫ‘ðͬŠïΫƒñΫ|ðͬuïάnðÍ«gïͪ`îˬYïÍ«Rî̪Kï̬PðͪW¸£‹w­¦žÀÞÝÝöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÿ­©¥úæææÿÑÑÑÿáááÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ½µ­ßïÍ«”ïάðΫ†ïÍ«î̪xïͬqðάiïάbîÍ«[í˪TòÍ«LïͪQîË©Yïͪ`ðÍ«g¿¨„¬¤›ÄÝÜÚõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿº·³üÐÎÍýÚÚÚÿÙÙÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðïïý·¢ŽµïÍ«ðÌ«ˆïΪîÍ«zïάrîͬkíÌ«dñͬ\ðÌ«UïΪNïÍ«Rî̪ZïÍ«aðάhïÍ«pðΫwÍ´—ޝ¥œËÖÓÑöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÐÍý·µ°ýàààÿÓÓÓÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¹³­ãïΫ‘îͪŠïΫ‚îͪ{íÌ«tîͬlðͬeïË«^ðͬVïË«OðË©Sî̪ZïÍ«aî̪iïÍ«pî̪xïÍ«ðΫ†Ï´—š°¥™ÎÕÒÑ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæäãÿ«§£ýéééÿÊÊÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöööþº¦•µðͬŠïÌ«ƒïÌ«|ðÌ«tïΫmðϬeïΫ^íͪWïÏ«OðάSñ̪ZíË©bî̪iïÍ«pî̪xïÍ«î̪‡ïÍ«ŽðÍ«•Ö·›¦»¯¢Ó×ÕÓ÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóòòÿš–“üèèèÿÄÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¹´äíÌ«‹ïÌ«ƒïΫ|ðÏ«tïΫmîͪfïΫ^íͪWïÏ«OïÍ«Rî̪ZïÍ«aî̪iïÍ«pðΫwïÍ«ðΫ†ñάîÍ«•ïάœïͬ£Ö¹›³²¥—ÚØÓÑöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ¯«§ûÙØØþ¹¹¹ÿýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÿ³£“µïÌ«ƒðͬ{ðÌ«tïÌ«mðͬeïË«^íͪWïÏ«OìÍ«RîάYïÍ­`î̬hï̪oðÍ«vï̪~ðÍ«…ïΫŒïά“ïÌ«›ïͬ¢ðÍ«©ïΫ°ÝÀ¡½¾¯ ßÖÒÐøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ½ºúÆÄÂûÀÀÀÿúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¹¶çèŦ„ðÍ«zïΫsîͪlðÏ«dïΪ]íÍ©VïέNïϬPîË«Xï̬_ðÍ­fñΫmîͪuïΫ|ïÌ«ƒðͬŠîÌ«’îͪ™ïÌ« îÍ«§ïͪ®î̪µðά»àÁ¡Æ¶¨™äÍÉÆùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÐÎû³±®ùÄÄÄÿñññÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÿ­ž‘µîÌ«yí̪rñÌ«jðΪcîͬ\ðέTîͬMïË«OðͬVïΪ]ðÏ«dî˪líÌ«sîÍ«zïΪîÌ«ˆïÍ«î̪–ïÍ«îÌ«¤ðΫªïÍ«±ðÍ«·ðÍ«½ïÍ«Ãá£̾¯žåÈÅÁùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæååý¢Ÿ›öÆÆÆÿëëëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿžêà¿¢|ïÍ«pðάhïÍ«aî̪ZðάSîÍ«LîÍ©Mð˪TîÍ«[ïάbî̪iïÍ«pðΫwï̪~ðÍ«…ïÌ«ŒïΫ’îͬ™ïÌ« ðÌ«¦ïͬ¬ïͬ²îͪ¸ðÍ«½î̪ÃðͪÇäã;¯žåÈÅÁùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷öÿ¡ž›õÆÆÆÿäääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ¯¢–³ïΫmðͪfï̬_îΫXïͪQîË©JñϬJïͪQñΫXïϬ_ðͪfïΫmðÌ«tîͪ{ïάîÌ«ˆïÍ«ŽîÍ«•ïΫ›ïΫ¡ðÍ«§ïÍ«­ïͪ²ðÍ«·ïÍ«¼ïͪÀïÍ«ÃîͪÆääɻª™áÉÅÀöþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ²°¬óÀ¾½ýÜÜÜþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿËÉÇëÙ»œqðέcîͬ\ðÏ«UïΪNñͬGñͬGïΪNðÌ«Uîͬ\ð˪cðάiïÍ«pîÌ«wïΫ}îͪ„îͪŠïͬðά–ï̪œïΫ¡îÍ«§ïͪ¬ïΫ°ïÍ«´îͪ¸ïͪ»ïÍ«½ïÌ«¿ïΫ¿æÆ¤Á·¨˜ÜÁ½¹ôþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀ¾¼ô®­¬úÔÔÔþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¬£˜²ïͪ`ñάYïÍ«RñÏ­KðέDðέDî̪KìÍ«RñΫXï̬_îͪfîͪlïάrîÌ«yïÍ«ðÍ«…îÍ«‹ïͬðά–ïΫ›ïΫ î̪¥îÍ«©ïÍ«­ïÌ«°îÍ«³î̪µðÍ«¶îͪ·ðΫ¶îÍ«¶çÇ¥¶³£’Ó¾¹òþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØ×Õ÷ žœõÊÊÊýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÏÎîÈ®–kíÍ©VïË«OñͪHïÌ­AïÏ«@ñͬGïΪNðέTîÍ«[ïÍ«aðÍ«gï̬níÌ«tîÍ«zïÍ«ðÍ«…îÌ«‹ïͪîÍ«•ðͬ™ïÍ«žïΫ¡ðά¥îͬ¨ðΫªïͪ¬ïÍ«­ïÍ«®ïÍ«®ïÍ«­ðΫ«ðͬ©åƤ©¸©˜É¾»·ðüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéèèúŽŒ‹ñÂÂÂýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª£™±ïÍ«Rî̪KðέDïΩ>îÍ«=ðΫCîË©Jï̬PðͬVï˪]í˪cî̪iñάnðÌ«tîÍ«zïÍ«ðͬ„ðÍ«‰ïÍ«ŽïΫ’ðά–îÍ«šïÍ«ïÌ« ïͬ¢îÌ«¤î̪¥ðά¥ðά¥ïÍ«¤ïÍ«£ïΫ¡ïͪŸï̪œèÈ¦š³¢’¾À¼¸éüüüÿÿÿÿÿÿÿÿÿÿÿÿÿøøøþ•”’î±±±üÿÿÿÿÿÿÿÿÿÿÿÿÚÚÙð¾§bñͬGëÌ©AíÏ«:ñÍ­8ïʪ?ðϪEñÏ­KïÍ­QðÍ­Wñέ]ðέcî̪iïάníÌ«tîÌ«yï̪~ïΫ‚î̪‡îÍ«‹ïÍ«ïÌ«’ðÍ«•ðά—ðͬ™ïΫ›ï̬œðάœïάœï̪œðͬšîͪ™ðά–ïÍ«”ïÌ«‘ï̬íÉ¨Šº©˜²Á¼¸åûûûÿÿÿÿÿÿÿÿÿÿÿÿÿ­¬«ìª©¨úýýýÿÿÿÿÿÿÿÿÿª¤ž±ìΫCî̪<ì˪6ðά4íÏ«:ïÏ«@ðЫFòÍ«LïÍ«RîΫXïË«^ðΪcðάhïΫmïάrîΫwðͬ{ïÍ«ïΫƒî̪‡îͬŠï̪ïÍ«ïΫ‘ïΫ’ïͬ“îÍ«”îÍ«”ïͬ“ïÌ«’ïͬïÍ«ŽïÌ«ŒîÍ«‰îÌ«†ïÌ«‚ï̪~êɨ{­Ÿª·³¯ÞûûûÿÿÿÿÿÿÿÿÿÃÂÁï““’÷öööÿÿÿÿÿßÞÞò®š‰[íͨ8ïЬ1ïή/ñÏ­5òÏ­;ïÌ­AíͬGîÍ©MïÍ«RîË«XïΪ]ïάbîÍ«gñͬkïÍ«pðÌ«tðΪxïÌ«|ïÍ«ïÌ«‚ðͬ„î̪‡ðΫˆîͪŠîÌ«‹îÍ«‹îÍ«‹ðͬŠðÍ«‰îÌ«ˆîΫ†îͪ„ïΪï̪~ðÍ«zîÌ«wíÌ«sïάnêȧk±¢•¶²¯ÛøøøÿÿÿÿÿØ×Öô”““óðïïýÿÿÿÿ¬¦¢²ðͪ3î̪-íΪ*ïϪ0ñ˪6î̪<ïÌ­AíÍ©GîÍ«LïÍ­QðͬVñÍ«[ïͪ`ðÏ«dî̪iïÌ«mïÍ«pðÌ«tðΫwîÍ«zïΫ|ï̬~ïÍ«€ïάïÌ«‚ïΫ‚ïΫ‚íÌ«‚ï̪ïÍ«ñΫ}ðͬ{îÌ«yîÍ«víÌ«sï̪oñͬkðÍ«gð˪cïΫ^éǨ[©Ÿ‘’·³±×÷÷÷þííìú………òêêêúãããö˜Œ~Yì̬(ñϬ%íʬ+ïϪ0ñ˪6òÏ­;ïÌ©AðÌ«Fî̪Kï̬PíÌ«UîάYïέ]ïÍ«aðͬeî̪iîͪlï̪oí̪rðÌ«tîÍ«vðΫwðάxðÌ«yðÏ«yðÏ«yîÌ«yî̪xîÌ«wðͪuïÌ«sïͬqï̬nîͬkðÍ«gðÌ«dïͪ`îͬ\ðÍ­WðάSïΪNîË©JŸ“‡‚¶²°Îóóóý‹Š‰îÞÞÞö«ª¥³ę́#ïέñϬ%íʬ+ïϪ0ñÏ­5òÏ«:ïË«@ðέDñΫIï˪NïÍ«RðͬVî̪ZïË«^ïÍ«aðÌ«dîÍ«gðάiñͬkïΫmï̪oïÍ«pïÍ«pïͬqïͬqïÍ«pïϬoïάnïÌ«mîͬkðάhîͪfð˪cïͪ`îͬ\îË©YíÌ«UïϬPîÍ«LñͬGìΫCïΩ>íΪ9™…u«§¦Æ——–í¼¼¼ò‡{Qò̦ïέêȬ%íΪ*ïή/ðά4íΪ9ïΩ>ðͪBíÍ©Gî̪KïË«OïÍ«RíͬVîάYîͬ\ïÌ©_ïÍ«aðΪcíÍ©eðͪfðÍ«gî̬hîάhîάhðÍ«gîÍ«gîͪfðÌ«dïάbïͪ`ïË«^îÍ«[îΫXíÌ«UïͪQîͬMñΫIð˪EïÌ©Aî̪<ñ̬7ðÌ­2î̪-ò̬(Œ„}jccbÛ___ÒÿÿÿôÓ±÷̪êͪ$ìͨ)ôÒª-ðÌ­2ì̬7îÏ­;ïΪ?ðΫCñͬGî̪KïΪNïͪQð˪TðͬVîË©YñÏ­Zîͬ\ïέ]ïΫ^ï̬_ïϬ_ï̬_ï̬_ïΫ^ïΪ]îÍ©\î̪ZîΫXðÏ«UðάSï̬PîÍ©MñΫIíÌ«FðͪBïΩ>íÊ«:ñÏ­5êˬ1î˨,ë˪'ðË­"íʧÿر 666„ÿ¿¿ôȦíʰðË­"ë˪'óЬ+ïʪ0ðά4íͨ8î̪<ïή?ðΫCðÌ«FîΫIîÍ«LïΪNï̬PïÍ«RðάSíÌ«UíÍ©VðͬVðЬVðͬVðͬVðÏ«UðέTðάSïÍ­QïÏ«OîͬMî̪KíͪHð˪EðͪBïέ>òÏ«:ì̬7ðÑ­2îͬ.íΪ*ñϬ%ïϯ öЪÿÝ»ÿÌ™óÑ®öЪïϧ ñͪ$òÒ¬(î̪-ïϪ0ðά4íͨ8îË­;ïέ>ïÌ©AðΫCíÌ«FíͪHñΫIî̪KîÍ«LîͬMòͬMï˪Nï˪NîͬMîÍ©MîÍ«LñϬJîΫIñͬGð˪EðÍ®BïË«@îÍ«=íÊ«:ñЯ6ðͪ3ïή/íЬ+ò˪'ð̨#î̪ëΧïϯÿÿ¿¿òÉ®ëÌ­íʧðѪ!ñϬ%ìͨ)óÑ®,ïʪ0ðͪ3ñ˪6íΪ9îË­;îÍ«=ïΪ?ïÌ©AðͪBðΫCðέDí˪Eð˪Eð˪Eí˪EðέDðΫCðͪBïÏ«@ïʪ?îÍ«=òÏ«:íͨ8ñÏ­5ð̨2ïΨ/óЬ+ì̬(ñͪ$ïϧ íÈ­ôÓ±íȶÿÿÿÿªªïϯèÑ®ëΧî̪ðѪ!êȬ%ì̬(íЬ+îͬ.ïϪ0ðͪ3ñʨ5ì̬7ñÍ­8íÊ«:îË©;òÏ­;î̪<î̪<î̪<î̪<òÏ­;òÏ«:òΪ9íͨ8ñ˪6ðά4ðÌ­2ïʪ0î̪-íΪ*ë˪'êͪ$ïϯ öÑ­ëÌ£ò̳æÌ³ ÿÿÿÿæ³ ñÕªóÑ®ëΧíʧïϧ ð̨#ëɨ&ò̬(óΪ*óÑ®,îͬ.ïʪ0ïˬ1ðÌ­2ðͪ3ðͪ3ðͯ3ðͯ3ðͪ3ëͪ3ð̨2ïˬ1ïή/îͬ.î˨,íȪ*òѪ'êϬ%ðË­"ïέíÈ­ôÕªóΪï߯ÕÕªü?øðÀÀ€€Ààðø?paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_48.png000066400000000000000000000114751456262201400257500ustar00rootroot00000000000000‰PNG  IHDR00Wù‡sBIT|dˆ pHYsQQ d¤tEXtSoftwarewww.inkscape.org›î<ºIDAThZY°]Åu]kw÷½oЬ'4"  …% Ær°ËvbÇJpRI%6vBR¾œÏü¤*ßN¥Rq%åÄNpŒ‡‡Ä.Œ,À ÀO‰ALI h@ÃÓîíî½òqî“e±ì®º÷Ü{Ïés×Ú½{÷î½q‘&‰Aÿø©³}±XìÔ‰ˆbÉ+j1´ÍÌK6¯4#H’• ¤ÞýrïÝ•%Y€»¤âp«rô§j>á,­Š Š®×:µ]ÐQM3KÎc‡Ç¶®^ݽV¾ó‡ûîSH+OO•uZbð‘,Øx7"Z@d@ep£Á¼Ò¢e#½s’1FÔZ~îÞ!D9 re™G· §Ã«Ëaª0UT¯0Õd©¸µËX­3ÐÎÀ¹±­_0öÿؾ]ñÔÀÈt…N«ëC;DsÆâ9¶b;”N‰ p„B¥¹ÁDšF’$hk­BïÎ!„óhreˆA‹µzöd±æÚˆ J§:S©æ¥ÕñÛ9vÆï¼iÖI½‹À?íTš“ÎÍ, ©ª“‚[´ÄèÝ’LŒE5&g@`(Ž`Fƒ× ÂÈHy5$@ ½̤ ÀÑ‚KUTpwy4Ôó#PUc+–\U#UܼxNÅéÅà¹Z-}Œc¿yÃŒ3@C‚“–?Ò?:{À:­Ê*r²Ô½[’Ÿ‰1C#æBiæ°†)¯æB3µ7¯ 2ADÉÝàt¹ ªÂC…¡ª8CaíV¦˜U¼8UŒ1xÎlç™SûÏ}h9Ï%Ù÷žÓé„68ÒrX²ÔC·$¡$‹UŒ#ÅèªÆ!ÀÌ`Õ=Äz#@:@:øN$Iœ­Rp¸j¥ª1x©b(¢Š/–bV锂˜ 5¤ÜUÍÓfþÛ߿鋼wçÙ¡¶ÕAusË[!EXr09j,QŒBMTC†@xU ÆÞÑû$ö¹×~Iýúiì#Ù±_Æ>û õ{U¿\ý"û¤æ7û̼`[²>›û;Û¤µÞöjí×ÿî­7Ÿú‡?ÿìgþî§?=pÕ¯øÃýo½}ê‘k?úGÏFWI˜ÏÚBe½00 L@L.O4F¹'‘d@Ï¥ PF§ Í Î;0p’NÀ%wRTŒVwYítã[/=|ëÒ¡iúËÏýΪѱ±ò¥/}iôî»ïžÒétÊËoœ¼wí²bDã6ˆL¨LjÀ·&wµ JÝ"È1Šˆ”"Ô h¤ÑåÆ A¹Àê8ŒŽJZ¡±qÁŒ´ù w}bE»ÝÆ‹/½<ºí¡‡tÏ=:8cÆtûÚ׿ýƒ5·ýÎ+.OÑÁ$”„ó$R2Ôê< D<J#¤C”+\$ P³ t~@I—àPP!Åk‰GŸ{ø¦%Cë?×G®ˆ1ýñc§÷ìÙÝ÷¹Ï~¶¯¿¿û÷9rξ±5ÅhÞ„Æb ‰)ˆ ¨©m A©º·`LpoiÒ¥LQ®ÄÆ•¢ð„A0Q4 ¸FºÃe´*È!V¥T§<}ÕÒÙíuŸú½/˜ßúöwNÖZ§ýé=÷$³&¤=¼cxû²õ·•3z®51ZôâId×j dË,$¹Z`3& ‰D FÁ#€ GCÂeÐzSlBIwÉ!ÔR:~â•áW.˜ºú·>uûe!„óÀ;޾üÏÿrzÉå‹f|üSŸ<â•W_=s& Ý?M):ºnÑ<ÂèŒ Íb59Y)%y9`Kò–ÈD(Q%`<ˆfŒÍ"9™ª¤SðNgç~úÜÒ%³Z«¶~æÎ逷Þ:–¿öïÿ1~Ó†õÓ7mÚdž{ø©Ý,ºæC§]5FKµH1š«j$<:SãRTãëÆgšx‹d"Ù¥IW!À‚“4AŽng'÷í¼|ÕÂéK>óé-SÉw%ÂØûÒËO<ñ¤ßºùýSn¼ñÆŸÿÌîgOÕÁÅ:<š¬V±F©F‰ƨÑeÑŒAjüÆ(5„ L [îjÑ µ@&Bɹ £‰1;÷Æž…W̘w×ï~tðbÀ`ÛöGFOŸz»uó†õíÕ«W¿ë¢Ÿ<ÿêcC×|pÔhAæ!ôÂwÇ 2‚b* 8»©Ï€€1J#›þ¡;>F¼8oÕÂis6oýpÿ{—„ï|ïs3§M¸þºµ\¾|ù».|ò';OÄy×ndj€Y¨ò`²«×@·«`€¼9Z“¬ Œ"ˆH!Ê‘&²!#¨0Ij'ÆÎµò‰Wæ-¿l`hó§ïh]u¯OLà?¾~ߨê«VNY¼x1.\xQ‚ϼüæ“sÖ| T!˜zÅP½†hN£Áœ4©ñcLº–A®2Š[õˆ€ P«36ÒŸO¾6ùeC›ã¶ÿ8>|Äÿ÷Á‡:«¯Z9°råJ ]ôº‡{âø”Ëox B“4&‡™Ñd²Èª¸i$ÌC T¤Ña¤™äD“BAR„ÍGGN÷OÙ»øÚ+æÎyß%€gö<_<àW¯\Ö¿zõjL›6í¢×ÕZñܾ£Ã Ö^]%7(š fP³ÒŒòj F ”Ü$i”ËH𨬬p ÌHÙØÈ©>:¸ìúåóæ_·ùÎö¥€þè‘Ü×nqÖô©­ 6 ¥ôž×>¸íÑ£sVÝò h$Õ3¬ÑAJÕb/ÞÃ]l²_1¹-$HXÓÑH<}âð@9±oÕÆµW.Z{ëmý— \¾ñíûË ×^<À;«ëÅZίÝ5ov[(oÒ:a Œ$)Ü '#…ÜIr'H†SohOºöæ+­X³åc}— FFÎáßþýëõÓŸüxÜ·o¶lÙò û<¸ý±Có®Þ¸DF@€ËÉÐ|€X+@V˜™$ýÜMh¦‡÷O±3×ß|íÊ«×^{Ç/Þð+YhBß7¾}¾mÓûÒñãÇÑn·±xñâKîÿ£O¿qùê›÷“p±Ù;HpÍI¹T{£’<¾òì£ó¯˜‘>ö[ï¿æÖ¥K—üÊ€³gGôo÷þgþ“Ïýak÷îÝX´hæÍ›wÉýŸ8YŒÅ=s‰ ±‚ª Uƒ*¨*Á¸9f.…k®ZsW5žÞÿæ[û÷½~ðèáÇ äSfÍšñ_þ¬½öúÁòÐö‡ËÝøûíááa¬X±sæÌù¥ ðÀÛ?ué¯íPHf† ¯EŽ"z1g‘©Ð˜#Bæ7w¹“îm'›ªƒØ~óÀ sûF¾ÿº+—¬»ù¦u_ã/h;~²³3ræ ·Üq{ë±ÇÃúõëÑßÿËyáÑ·ÞÊßÙñúýs–\}P—bÇ®QŠ;µÖ®;rudì˜Ô [ïþëe¤LN#e8}æP·ohÙþ£#ܵkøqôG›;44ë¢Kæßptö¬éqÃúu­mÛ¶aóæÍh·/ya>ßþû¡¯L[zýB™° "›±+¢ùŽZh– –˜UQB6juT‹*“å ¹Âò”3Ǧ­¼åÁm/ÿò½ßúïÆÆÆÎàœ3¾üÏ_y߆u+—/O;vìÀ–-[pážöRÛk¯è¼íÓwBìBÈ€2 ,¯…°,¨Vä*Õk…«­¨„Oá‹‹ å›*a/‚›BäàŒ¡‰8{ɋ۷ýp4¢;¯¯ÝJÿò¯_=÷ÇwvZ§Óá /¼€M›6á½rþ_ÔøÑŽçg.½þ9]`WP,Cž!ÏFtIËìÈÌE*1P¥R€EÈÜ«4‚i§ ­½}xç¡ýûwîüîgþâÏî:|ø0Ž=Š7þJÀà¥W_oÏrÖÑ¤å¡ ±kÆ®Ü3`Y®b¦ìURQPq¨DU/¤h,Õ 4œ†˜C^H¤f/XzlÎôñ\kÅðð0æÏŸï|÷þñcg;æÌŠsf \¶îúµÓ/-"?±kï³³WÜr\T†« gù|Í0ëÖ…¼ë™Ñ3¤ìð³—HÄÜ$ŸF MQ „˜½Ê8zÕeö|ä#öâKûÎ-÷_¶æº£ì¨çðßÚ¾tጸüê+,¿~íµƒïþ™ÝÏŸÍS—> †‰¦À…Bc60;)Ë€uÙ@¹ù2`9'ϱ"f hVlТ5$‚d0 îªtÁ† JcãzñåWO=º÷ø7ç_yÃ!‡:Ì,ØÒµ_’ãå§oïüÆÿܰjѬëß¿ñæïœ#Ã{÷ ÏZuëÛŠ€bT¡,¯…ÁÐòn>tÊ(ʈjæ<‡ßþü_Ï"k³(NDBµ6^ï€;à.„¹7Ûž7v?rÛ”Á)åé7Ç¿º`ÅuVJ.¡ÒXšácéïœèŸµøÀ‘ѸëñG·uT:³-˜ßO ï:q"-¼·Ý7eÜh]‡7Ö ìÈëŠè6a5dï‘1xfefðLÄ>ùù/NwV†f× r9¢E®FT£B0àßûêßß:mÙº¯,X¹n¿1VJÞääM¹PͨHª4Ë©¯¿3õ²å¯½yªûÔÓÃ;Æ[sŸÜóÊg/^³—´ Õ Z׈®²œA]xã24äbè²2#Ånéä\3ÿ÷Õ±EgÏtÛ–ÀÒrX *4QÅÃÏ$¦×_xfhùÕëF`FZSâ€ÁŒ÷ÊŠ’H ’ªèÈþ½3¦Ï]|zÊ”©8š<ç¼¼dEPIYT©P&C¶I…&{FŠÝ ÏínáW÷L4«Õ’º GM[1äšs­‰Ö”a ^þÍöíqEÿÚ¦„>†óÜT ­AšÆºÁ›Gn*ÍH‚F°l(Œ1 Èèf FÉY”ûDs,UÞ©æ GðŠè]¯ýÖWζ¼¦™#[/_41ùlÄ;Ûÿ:Å…6òw òIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_50.png000066400000000000000000000121501456262201400257300ustar00rootroot00000000000000‰PNG  IHDR22?ˆ±sBIT|dˆ pHYsiiåº]ŸtEXtSoftwarewww.inkscape.org›î<åIDATh¥z[°]Å™Þ÷ý÷Þçèv$¡ÛIÈ$q“æ6XØ€ÍØ¶Ž±ÍŒ+SyH*©ä·ÌSªrq&•ªÄ›qlŒ ²Ép1˜‹@€ÅE $GGG{¯îÿËÃÚGwpºjÕÚ{í^½ûëïïþ¯ÄG´ßíØÑ}grþ´\&ÊLGÇå¨#›£Ð}£%§E¡;ŒÚ˜$Éʆ@~Ϙž ¦’$sDH²„(5‡…¢Ô^t=W¸*S·²Qè®C#ÃeèPÓ~ýþ‰n¸¡~Ø|ùþ’ø‹ç1}xr|h2,yô:æM0!™£öaž † ‡ÑÂh©6FfV’$h¥°òøøîI¥X’$(Y¤0W0Õ TU˜*·tÓPU/{X 4ÙdÉe©ª$Xv65ÁéˆêÎdEÕ0M#Ú=•€Ì ZsH’( ò •ˆP Pa^QU=«È¼ ök”T‚*ÖIM4Q ÑT«ÅçÏ{ç†%œµiÏ܇§y×S’å@“-,˜)¦ªš(¦@MnÙapV¢+вÂ0ÒY¢šÃ ú`Å*“$@S¬ÐÚýRÀP^AU„ªˆ‚ª*ª8£©£r3ÙLSn\µ™1ÿ¤ÿæ/O_Í[׬ÓÇFª<«_:–»)Tr4–™˜¤š ¶@€`pˆÇDL¤a ˜¢CVÂA0˜**=‰D” 9UCÐjˈªAEô‚(Õ’5QUDƒ7QT ÑEóÄÝ·Í;´{ë¿Û·w÷ÚÔIïÌ>Úóœ`9:C9šÉŽ¥Nk¶ÊLgŠ9œ‰`"#É#"Ar„ÜÌL‚‘0 ŠFVÑÛ°B0!Ê#PeBÈ­2TC 3+`´+Àp1—Ze 9]&Á¾í|zãèt¾}Ó²¹õª9+.ë¼ðòΟ–,ƒ¥ƒÆ²£“£0'Z0GÔÌÄęưDE"éL.†3`L¤$J˜ÌŽ*6cˆ¢EPÌjD £UU¡d‰%‚n‚ƒá¨rKfpë¦{–Ì.c×}uý%—o}ö0­XšzwÛê+þîž”P2h€e°vË3ÄöæfzJ‘)&"hŠ“Cr˜cÀ2‘$tìT$!Á†b°ÙUJ¨J¨FFËF®“f;žùÃÉs1~õMW\øÅåË—ü×þðíK.¹døÌ3Îúÿð£[Ï\|iJË€e3`¹ÔÚ1·\ÈlƒgŽÈ’²IŒb¢J"½#:!#ÚMÐHP´+ZeA¤ zQ T”+èÆê¯½°eñ)Óš/ÝxùÙ—._¶lúøøxýÿ÷ïþõu×ÍXµjU÷wüúÑÕ_ùÞ#ÖDNše"g€Ùܲ¹VvàÌ@ ˜Aªe„Ê“¤äFè \„¡Êi"Ø+-+$¡eƒ !ZE¨¨$ @GÀßøÓÓ‹gjì/¾yѹç¯X±bvî|mòŽ wÖ¿¹ùo†O9åä|àÀò«oݾf¹e&(™: ¨IŒ Õ Z®5:æ)#¢0˵`¤Ló¤ˆL*©Õ ­Â0P.ÕÐ*Æl™ ª¤ YBQ)ú¾Ï-žQö_øWž»zÅi—M‰åS›·ŒoÙ²¥ó½›nêÌ›7Ïà¾ylÕ¯&š’©Pbb˜"j»òµe@ǘˆN3Á G6CVD6cR KJF8H‡à!8)#IÇp(ÚMA2(„ÈŠLÚóÂÓ󿿉³¯½äó+—œriçDÓcÃo7vdüÐÈwoúŽM›6ðÆÞ½½—ޚذz`Ñ‘L5µbÂ2Á,JÂq±¢³e'‘%eC0—”Ђp&3R œÚìDZêî—ž™» 9óÆ/¯]>::šNPJÁ­?½mlƴΜ믿ž9·¤ï{è±M«/þúŽ*&‘-×Ô~i0#¥Pd?ÆŒØQ§±vÏPÊ0K¡ÈFsµ§™r„,ˆ)“ b«Ñ!Å›¯nY4½9íÆõgž:ºh‘ã}mlìú?þ×&V¯üÜœk®¹†Çåx}×îÉ·&»¿›&$¢†›Õ¢š Ψ Fˆä`‚31”‚HO¨Ê s@Yb‡lœf–L-‚r±µ»$’¤±]/ŽŒðÐÒë.=oþ袅/¿òjÿþûß¿ø‚óg®_¿þnÆ}?ñäòs®Ü”$³Z ²:0ËéHt‡Z]™H&ˆIT2C E»O¦¡:ÇN3)ShEJh€àÞ—ž™=KïŽ^»þ sG-´™?`ããOÙ³{—¯=ïœ\pÁ~áÅGÞµ9÷ÍD$cªQJ2c…ÁTÝ2-‚û np—ÂápRIB2"–¦ÀD¨CC62 ÊlO¯Â!ù;ž™³`¨ÎûΟŸsÒIs?°º'¶»î¾çÈPÇ;+WžžÎ=çœíóÈ“[ŸZ²æÊQá°ê–ÜPä@õd„Õ†N«^%wsC„ƒrT$.D2²ÝÐD‚”!d™`©C" È ÓþÛæœ< ¾ûÕµ³æÌžý±zý>þç~|ä¼³WŒŒpÍš5ÚoësÛÆN;õ¡p3³*º•pÍ‚–4³jA3£¬*ÜI#ÍÈ3…Ö¶h.(H‚2 ©³ÿµí'ÍË“ ¿ý¥ó?ì?ð¶nÿÕ½K.\7mΜ9XºtéGöݸåù§GÏúÊ8(«n¤i`ÛÉd‰ d8 ’NzbÖ¬ÐÞ)#QÒ)¸ dbzçõí fÙøÉ7]qÑÌY³f}"xáÅõé­[뺵ç -Z´‹-úȾ›ŸÙz¨³`ÍFÁÜŒ€8‘“¢Z kÍoÉ(š DÀÄ< #h ­Ûío¾üÌ¢ùÝÞ©ßùÊgO)«OÓ~ôñÒoz<íÔS:+W®ÄÈÈÈÇöß´õ¥?.8ëË=D˜ Ð&™‡» ” í…O°`I€"ß|é©Sæwú+~pÍå'Mþ´ól¸ëŸÊŠeK|Ïî]<çÂ/`øÞÿÃ#/9o³Ôþ¿ÓZ? hA†)"ÈvÊt"ÀLíç`÷nrÙ’Ù¶êo¯¹tÁgÐëõð¿oýyýÖµ™6oÞŒ+¯¼)¥}'"ðì«þ¸hõš>­5™ X©Þ;R|p°R+Ç^yjåâ<÷_\÷Å…ÃCCìô í½ûpǯ7ßômß´i®¾úêOõÞ½<üöœÓÖm)!€ ,ù†ˆY»ñ©PÐdl ‰¦ö=ûày£³ÓÚ|ó«‹»ÝîgÛžQÏ=¿]7\÷ Û¶m®¸âŠOõ^­;öŽ?·hõ´ÒºÇL&I¨VÚ€“Y@ýÒ`ß³~aÙ‚Y_ø×ß¿öÔO¢ÿãÚ½¿(†ºqñ¶{÷n\xá…ŸúÝ»ïûÃ[óϸx›!€ @’Ð$‡’ ˜°·¶?réšÓ¯¿þûßZúÿ@~¹á®fíÙ«S) 8€µk×~ê÷''â•·&·-žçTP¢‚°€´©»¤€,ÒÄäaŽ=ÿÐúUËG¯þç?¸a¹û‡ÚrŸº=z?þéÏ›ï~ûŸå;wbhhgœqÆgãîûÚ;ºú¢@TЪ¢†À 2„ C”ReFIE¾pV¾eõ™+öûåðk»wM8°?/\°`øÏ´{Ïžú«_ßÕüÝß~¿³mÛ6|’¶þ°6~ø°ÞúúÆ™ó–ìP6 dQ ¡"±ˆ(NkB(&þüɱ¯yb'‚]†ºG{ï>ýÀçWŒŽ¬=oÍÊ5«Ï¬_¿C†®€ŸÝq÷+¾ôâߨ¢؇؇©c ±œ ëêË¢gAµ1Ö© ×`U¤²dõE/sñÅ?ùáï¼ç¹mÛ'`|ü°þËÿûáïÜxýÌ… Ø#<‚«®ºêϱwï¾òf¯³Ù ¾€`¨£Q (4¸ÚÏ6˜·¨‚På/6]Z`ŒöFÀÔ:OêÌû^ݾxVÏ×T{snþÞM3<ˆÍ›7jE÷QíÖ_Þµ}hù%¿!¬Ôj4&öÛï6`ÆúPôõ!ëCê˽g¢Ú•¯ƒ+T„RkH5 û 4°–âEËWíÙ?É-7蓮ûöíÆ 0<<ŒG}T=¾©?11ñ™A¼ºóµþXŒlÙ ©'Yÿ·>¡†°†PËÐ äTIoD#R%ªh Ä€€:p¡ 6ü d˜T`ÇŽºùæ›ùÖ[û›ÛïÝôÀìÓÎßþðíž<ÒÑ’Ñ9Ë׳ztñâÑOÔ¬?¹uÛâ—íF ÐØ Thñ"V51`‰U…®ðІðF%JŠ¢ö 4s€¢¡¢B€(€m~FmL*¥”‚”’öìÙ[~þ7Þ»dí—Ÿ&a§uÉËp{¥_Ãn{èÙù³ðä9ëÎZ±òœ³ÖLÿ0/¾ôò‘wÓü§“GQ¥V? j cC©Ùˆný¨M“œ àMe¿^üÆõoOb8Sv”¦d¨ªƒH’0‚U˜Ac{^:¥LŒ­:eÉ©ºýžÇ~{êÚ«'k›áAYfÍ]ønwþÒÚ}ð¹§6=Ñôfž¼xô=§Áw?øäIŸ[÷&ÄÆ F‘q\œ †fM@M²Ü¯(ÀÆÀ†ˆ&rÓG!Z­ÏZ †…6¬d*r QËK;^ê?õ§=–ÿõ'H™Nžco3T!¦dt "’ˆê2®cr*ª‘dTð=t­»$ XiÓÒm®á´ÊAV·êñÔ´— Ú<;RÍÑbC¹qtv†'¿u&ÆÚ Æ ýæ©7¦õ‘G¼;=Õ£ý|bÕñ‚ï8U‚îF+· Õ¨žŽHmå*#N,©0yëÑ¢µŽQ[ù  X±„Ó ¬_ƒ©¤¢ŒŒâÌMµZJéôþtþ̱[ÈÞW‹rÛ. —=oÍJC3סdkK8z–àôìm-J º kd-U9UùP˜P£ÒÍ[ Z äP6 ªBÐ&D ,µí „#Y*ýÒ«Ér S©½Z:¥ö;=ìþ§C'V } ¨ö»;ºõЙÑËÓòt·è¥&¬Ú{µGm|ŠÌ*M,‹6›AÖÁØSz½rÈÑæ%ˆžÂBQme©–^»ñS7T«êZ-Õ‡JišÞó¿ýÏã·ÜrË{b>|à¥7Òë3óô¹ÉãhBžîýè%ÖˆDoë´º–¬±0XTšŒZÌ…娸)%¡iÊŠ¥~_ô|¬¼©ªÖ©Hªh¢v­[&ú‡ë‡Kö™“לIzÿœ?2Ì)‰?Ùúæ´¡‰á.†ÅfSÅgÕ<;¬ú V«Ð¢öÍH–A>·ì¼oÌPÐG²”#¢/‹mñ™ÂCW…w+Uæ¨8ªzèH­gÏœ=±n?ÒÁûHÍŒ8±ÇíIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_512.png000066400000000000000000000566141456262201400260300ustar00rootroot00000000000000‰PNG  IHDRôxÔúsBIT|dˆ pHYs±±€)iìtEXtSoftwarewww.inkscape.org›î< IDATxœìÝy|TÕý?þWB6²BÈÊš@X¢¨°JÑP­5Ö5Z­cíWÓ~ôó?V}¤Ÿ~>u\j;.­¸1@] „M@Y’€ ²…™Ìû÷Ç̽¿€Yfr&“×óñðÑjfÎ93sïyŸ{îûžQ¯ààQ×ÿ‘ ð€¸@€Ú&‘§ ð4€JÒîŸÓà€ˆˆÈç$x @#ÎüÚ?³”µŒˆˆˆÜn"€l8à_*k¹€¬ÁO}???íÿÛŒUÔN"""rƒ wØ W ˆˆë¯¿^ÂÂÂôàå•WÊÈ‘#µM]s‰ˆˆ¨;"< ® Ÿ &“IÞzë- уÿm·Ý&V«Uû÷zñÊZMDDD]’à'á ð™™™bµZ¥©©Ižx≳¦üM&“´´´HZZšöߟPÖr"""ê´ñp&ö+ÀgggKQQ‘8)++“K/½Tþaaa²dÉ),,Ôþû!ÁÊ>uØTË8ˆ¿¿¿äææÊ–-[Dóå—_Jtt´ü,Û¶m‘'NHTT”ö·9 ?]D €<[à êáááb0äÈ‘#zàw8RXXØ>»_&L˜ eeeúk ´¿m€óI"""ò2p&ö•ÁÐãããÅd2Imm­´WUU%×]wÝYùÍ;WNŸ>­¿fÏž= Ú\¦ìSÑy%À™ØW W0OOO³Ù,ÍÍÍr®ÿûß2xðà³’ýŒF£´µµõºv„·U}0"""ú±q,šqžÄ¾s91›Í¨ÿàà`Y¸pá^»|ùrí5M†)û„DDD¤;ob_qqñ¹¦¾¾^òòòΚò‰‰‘uëÖýèµ6›M222´×™Ô}L"""ò0À&´Kì+((}ûöýdàÙ±cGûçø€Œ7N>|Þ׿üòËÚë*„©úÀDDD}Y8œ‰}‡á Þqqqb2™¤ººú‚_DÄjµJhhèYkùÏš5KêêêÎûúÚÚZ‰‰‰ÑùÊ>5Qgb_ \?--MÌf³455]4ð777·„OÿÇ`0ü(Ù¯½ßüæ7Úk·Ã9ë@DDD= ÀKp&ßé‰}‹/»Ý~ÑÀ/"òÝwßÉøñãÏ üAAAò÷¿ÿý‚ï;pà€kì ""êC¦X ç3÷zb߆ :ô5Ÿ|ò‰ 0à¬)ÿèèhY³fÍEß{ÓM7iÁ±ÂÈçi‰}Ñî±¼üü|)--íTà·Ùlb4õ ß¯_?}=€Ž”µfÍ-ø·Â9 ADDDn à.¥pþØØX1™LRUUÕ©À/"RQQ!ÙÙÙút¿ü¯»î:9yòäEßßÖÖ&YYYÚûÿ¨ì[!""òQ±p&öUìSRRÄl6Ÿµog¬Y³F®ÛZ¹ræÌ™•ñæ›ojï«¥è»!""ò9©8'±/++K¬Vk‡ûÎ¥mä£]íéWÿ/¿ür‡ËihhÄÄDm𠺯ˆˆˆÈwdXÀŽv‰}+W®ìRÐ×TWWˬY³ô«ýˆˆý—/_Þ©²žzê)­œ=”}SDDD½œ–Ø·ç$öíÝ»·[_DdÛ¶m’œœ¬OùkÁ?55µÓå———님©î+#""꽴ľ¸TT” 9zôh·¿ˆˆÅbѧúû÷ï¯?³Ÿ-•••.oþüùZð_®îk#""êbƒ+ð'''‹Ùl–ÆÆF·þ††¹í¶Ûô)ÿÁƒëûÝwß}ÒÚÚÚé27mÚ¤•a¡ìÛ#""êeRàLì; W`ž8q¢X­V±Ùln ü""%%%2vìX}am—>???1™L]*Óáp´lðu_!Qï1 ÎÄ>\8''GŠŠŠÜô5‹-’°°0=`Ô¨Qú.€K—.ír¹ï¾û®üOÂ9ƒADDDçágbßJ´[[???_vïÞíÆïÔÒÒ"ƒAŸò>|¸ :TÈСCå믿îrÙÍÍÍ2bÄ­ìÇ•}£DDD^,Îľ=pãÈÈH1 R^^îÆÿÿ+++“+®¸BŸæŸ1c†DFF ¹âŠ+äøñãÝ*ÿùçŸ×‚ÿ8‰ˆˆÈ%Àc*à ü#FŒÂÂÂ-­ÛUË—/—èèh ’ŸŸ¯¯îwë­·vhà 9qâ„>˜p³º¯—ˆˆÈ»$(p ®À?~üx·'öËn·‹ÉdÒƒýàÁƒ%//ï¬d?‡ÃÑízî»ï>-ø¯Qö y‘ h—Ø׳õEEEn ¼RYY)×^{­~¿ÆŒrÕUW ‘wÞyÇ-õìܹS[6¸ Î ‰ˆˆú¬©–Á|%//O¶nÝê– {1ëÖ­“Áƒëkøÿþ÷¿×WùV«Ußy/<<\>ÿüs™1c†¾ÊŸÕju{µµµ2hÐ mp»ºŸ‚ˆˆÈó´Ä>\[ææææÊæÍ›Ý`;¢¹¹Yî¿ÿ~ý*ôèѲ}ûv=z´˜˜Y»v­Gê~ôÑGµz7Á¹š!‘O ` \6<<\ ƒ[“é:kÿþý’™™©OùÿêW¿’ÿûß+dìØ±òý÷ß{¤îÒÒR-ÉÐç ˆˆˆÈgh‰}Gà üñññb2™¤¦¦Æ#µ£–.]* ЧøW¬X!o¼ñ†žùýõ×Ë©S§p¿ºŸŽˆˆ¨óÂØWà‹‹“É$ÕÕÕ¢Q]]-×_½>åÕUW‰Ýn—÷Þ{Oú÷ï/$''Ç£[·×.Ï`'€~ª~@""¢Îˆƒ3±¯®€ššš*f³Yšššz$€vÆÖ­[õ{üýýåÏþ³81™Lz`AAœ9s¦GÚsèÐ! Ñ×*û‰ˆˆ:( ÀKšà üYYYbµZ=š)ß‹E‚‚‚ô„¶lÙ"ò‹_üBßÙ¯°°°GÛ4oÞ<-ø¢î§$""º¸©°£]b߆ z4pvF}}½Üzë­ú”ÿ„ ¤¹¹YŽ=*—^z©> X¶lY¶kãÆÚ¬Ã#Õý¤DDDç§%öm„+ˆK~~~$ÉuGII‰dddè«úýÇü‡ˆ87ø6l˜””Ù³gO¶ËápÈäÉ“µA‰YÝOKDDôcÁîP Wà‰‰£Ñ(ÇŽëÑ€Ù .”°°0 !!!òÅ_ˆˆÈ| oð3eÊ9qâ„’¶¹¾ÓZƒ”ýÂDDDíÄ™ØWWàOII³ÙìÖ=ï=¥¥¥E ƒ>埞ž.µµµú£þþþ@æÏŸ¯d¦¦&>|¸Ö>ƒª™ˆˆH“ gbßi¸‚ç¤I“¼:±ï\GŽ‘Ë/¿\Ÿò¿ûî»EÄ9(ÈÏÏ×ÿ»ÉdRÖÆÿþïÿÖ‚)œ")‘`ÎIì[¹r¥² ÙË–-“ ’?üPDDªªªdÚ´iú¢Dü±²6?~\"""´@®Âßœˆˆú(-±o=\WûAAA’ŸŸßã qÝe·ÛÅd2éSûC‡•£GŠˆÈ·ß~+#FŒ2dÈÙ¶m›Ò¶Þ}÷ÝZð_¥î§'"¢¾HKìÛ WàŠŠƒÁ JƒcWTVVJNNŽ~¿?77WÚÚÚDDä_ÿú—DFF ¹üòËå‡~PÚÖ;vhƒ”6“”DDÔ§Dx ÀQ¸‚eRR’˜ÍfillT»jíÚµ’˜˜¨/âc±Xô¿™Íf}F //Ï+’g̘¡ T^WwQ_‘ gb_#\âĉbµZÅf³©Ž‰]âp8Äl6K`` AƒIii©ˆˆØl6ùÕ¯~¥'ûF}F@¥>úH þõ• DDäó&Á™Øgƒ+æääHQQ‘êXØ-uuu2gÎ}Ê?;;[Z[[ED¤¦¦F®¾újý¹ÿ… *n­Skk«¤§§kmþºC‚ˆˆ|•€ËpNbßîÝ»UÇÁnÛ¾}»¤¦¦êù<÷Üsúßöïß/£F’˜˜(›7oVØÒ³ýéOÒ‚€PeGùœ 8ûvÃø###Å`0Hyy¹êøçV«Uߪ7<<\Š‹‹õ¿}ñÅ2`À ™™™räÈ…-=[MMDGGk€yê""ò%‘p&öUÀøÅd2õØ^öžÖÜÜ,÷ÝwŸ>埑‘! úß-‹ž pà 7H]]ÂÖþØÃ?¬µ½Î""¢.KPà\qüøñbµZ{lûž°oß>7nœžÐ÷Øcé³Ûíg-÷k0¼"Ù¯½½{÷jƒ€lU õ~Ð.±®$¸¢¢"q8ªã[}üñÇ¥'ô}úé§úßêëëåÆoÔsþñ¨kè\ýõÚe‘ºC†ˆˆz³©p&ö9H`` äååÉ–-[TÇ8·³Ùlb4õ+û¤¤$©¬¬Ôÿ~àÀ¹ä’KôÇÿ¾úê+…­ýi_~ù¥öšŒPväQ¯£%öí‚+FDDˆÁ`²²2ÕñÍ#ÊËËeÊ”)zðŸ?þY_¿~½ÄÆÆ 9r¤ìÛ·OQK/Ìn·ËرcµÏñ¬²#ˆˆˆz•8ûÊà „ b2™¤¶¶Vuló˜Õ«WK||¼À5ñhÑ¢³þþÖ[oIPPë®»NN:¥¨¥÷Úk¯iÁÿ¸ë÷$""úI žp®À?nÜ8±X,Jö¬ï)‡C õe{ãããåСCgýÝd2é³^½‚a}}½>pªƒ‰ˆˆ¼_&œ‰}gàã‰}窪ª’™3gêÁ}ÆŒgeò744ÈM7Ý$$ @^yå…­í˜'žxBû<;àÜq‘ˆˆè,g%öùûûKnn®lÚ´Iu ë[·n•¤¤$}#³Ù|Öß+**dÒ¤I@(_~ù¥¢–vÜÁƒ%88Xä(<¶ˆˆÈËø˜ `3\W½áááb0äðáêãW±X,úýü¨¨(Ù±cÇY/..–„„ ©©©²wï^E-íœ[n¹E þKÔbDDäMÂáLì;Wà‹‹“É$555ªãV©¯¯—yóæéSþYYY?Êoxÿý÷õ%§NzÖ#€ÞlÆ âçç'Z¤+;ÒˆˆÈ+ÄÙØWWÐKKK³Ù,MMMªcVÚ»w¯Œ3F_Õïé§Ÿ>ëïZ²Ÿ+ˆÊý÷ßßkV5lkk“Ë.»LØü¯²£ˆˆ”Kð€f´Kì[¼x±×-WÛ,X aaa@BCCeÍš5gý½¹¹Yn¿ýv= °°PMC»èí·ßÖ‚ €heG)sÞľ7ªŽQJ477Ÿµ^ÿèÑ£´IÑÑ£Gõ«çððp)**RÔÚ®ijj’aÆiŸñu‡õ4-±¯®@,ùùùRZZª:>)søða™åÏ=÷üè5;wî”áÇ :t¨lß¾]AK»ç¿þë¿´à_ PÙQHDD=& @€}pþØØX1™LR]]­:.)UTT$Ô7ëùè£~ôš?üPBCC€\yå•rüøq-ížŠŠ ýÖ€YêE""ê qp&öUÃøSSSÅl6ËéÓ§UÇ$¥l6›˜L&}U¿¡C‡Ê±cÇ~ô:³Ù¬¿æ¶Ûnëµ ‘ùùùZðÿRÙÑHDD—gb_Ú=ÆfµZÅn·«ŽEÊ8qBf̘¡ßïÿùÏþ£„Ç––¹ë®»ôÛ&“©×®v¸}ûvmc0NÙQIDD3Àb8;z=±oýúõªc×øê«¯$11QÏâã7~ôšêêj™>}º°°0Y²d‰‚–ºÏ´iÓ´ÁÎk M""r3-±oÎIì+))Q{¼†Ãá³Ù,@bbbΛø¸k×.}ÙßÁƒËÖ­[´Ö}/^¬ÿz87q""¢^.À]pftëAÍh4ÊÑ£GUǯrêÔ©öKßJvvöyîùì³Ï$**JÈ„ ¤¬¬LAkݧµµUÒÒÒ´Ïý¤²#•ˆˆÜ"€À1¸Zrr2û~Â×_-)))×-‘^xἯ³X, dîܹ>ñ]jÁÿœF""ê…RàLì; WàŸ4i’X­V¯Þs^%«Õª¯Õ!›7oþÑkl6›<òÈ#z²ŸÑhô‰+++õÙ sÔ¶DDÔUYÀ•Øççç'¹¹¹²råJÕ1Æk555ɽ÷Þ«OùgddHccã^WSS#×\sž7±`Á­õŒ|Pûüø);z‰ˆ¨S´Ä¾•p±   ÉÏÏ—={ö¨Ž-^­´´TƧ_Ñ?þøãç}Ýwß}'£GÖs'Ö­[×Ã-õœ={öh·3.SwQGi‰}{á ü‘‘‘b0¤¢¢Bu\ñzK–,ѧ½CBBä³Ï>;ïëV®\©¯þ7nÜ89|øp·Ô³fΜ©]ý[ÕÊDDÔQp®ÀŸ””$………rêÔ)ÕñÄëÙl61Òþ»«¬¬<ïk_ýuýQÀY³fI]]]·Ö³–/_®}M†«: ‰ˆèÂ’áLìk„+xM˜0‰}PVV&W^y¥üo¿ýöó¾În·Ÿ5H0 >‘ìמÍf“ŒŒ í3šTÔDDôÓ&™ØgC»gÓ{Ûö²ª­ZµJâââ€Ê;ï¼sÞ×Õ××Knn®€€yíµ×z¸¥=ãå—_Ö‚œ@‘ð`ÎIìÛµk—êØÑ«8),,Ô7éIHHøÉûø”1cÆ‰ŽŽ–Õ«W÷pk{ÆÉ“'%&&Fä«;̉ˆHgbßn¸DD„ )//W7zªª*¹îºëô©ü3füäTþ† ô‚ôôôó.ýë+üqí;ÙçS$DD¤H$œ‰}åp«„„1™LròäIÕñ¢WÚ²e‹Œ1BßÈç•W^ùÉ×¾ûî»"äÚk¯õéïüÀ¬ ¦«;䉈ú¶ œ„+ðgffŠÕj=ïúóÔ1‹E‚‚‚€ 0@¾ùæ›ó¾ÎápˆÉdÒg |þ{¿é¦›´Ïû²£žˆ¨gbßœ“Ø×[÷‘÷õõõ’——§ô¬¬,iii9ïkåæ›oÖg^zé¥nmÏ[³föÝ´HSuðõESáLìsÀ•ž——'[¶lQz½={öÈ%—\¢oäóì³Ïþäk+**$++KϱX¾|y¶T¶¶6ý3ø£Âs€ˆ¨Ï`+ÎIì;räˆê¸à¬V«„†† »àR½Û·o—¡C‡ IIIé3Ë%¿õÖ[Zð¯„s1)""ò8ûÊà üñññb2™¤¶¶Vu<ð ÍÍÍRPPpÖF>õõõ?ùúÅ‹ë…ììl9qâD¶V††ILLÔ¾§‡”DD>.À3já Léééb6›¥¹¹Yu,ðß}÷Œ?^ßÈçÑGýÉמ»À½÷Þ+­­­=ØZµžzê)-øï êÄ "òU™,šÁÄ>úä“OdÀ€úÖ¼+V¬øÉ×¶´´ÈwÞ©L&SÏ5Ô ”——ë³fª;=ˆˆ|ÏY‰}þþþ’››+›6mRÝ÷ûm#??? #FŒ¸à4þ±cÇdòäÉ@ÂÃÃeéÒ¥=ØZï0þ|-ø¯PxŽù ³l†ëj?<<\ dÿþýªû|ŸTQQ!ÙÙÙúýþùóç_pfå›o¾Ñ2dˆ|ýõ×=ØZï°iÓ&m°d¡ìl!"òáp&ö†+ÅÅʼnÉd’ššÕý½ÏZ³f$$$èô,X°à‚¯_±b…DFF ¹âŠ+ä‡~è¡–z‡Ã!S§NÕL¯(;cˆˆz¹x8ûjà üiiib6›¥©©Iu_ï³´ä½~ýúéOQaÛ¶m’œœ¬¯ê÷ç?ÿù‚¯¯®®–Ÿýìg@BBBäwÞé¡–z§çŸ^ þ«;ˆˆz-±¯®«Îàà`ÉÏÏ÷é­a½Mû|¢¢¢dûöí|ý¾}ûdäÈ‘@ûü²Ê'NœÐóܬît""ò~!î°®À+&“IªªªT÷ç}FCCCûGÖ$++ë¢ '}þùçúzãÇçÒÊ"rÿý÷kßáeg‘—‹ƒ3±¯® “’’"f³YNŸ>­ºïSJKKeìØ±úýûßÿþ÷}Åb‘€€ ·Ür‹466ö@K½ÛÎ;µ„É6YÊÎ,""/• gb_Ú]mZ­V&ö)ðÎ;ïHxx¸þýû˪U«.øz›Í&>ú¨>S`0¤­­­‡ZëÝ®½öZí{yKÙÙEDä…²,`G»Ä¾õë׫î·û¤––1 z 5jÔE7Iª­­•3fèùo¿ývµÖû}òÉ'ÚwÙ QÙYFDä%´Ä¾ 8'±oïÞ½ªûì>«¬¬L®¸â }Êÿž{î¹è{8 —\r‰AƒÉÚµk{ ¥½Ã™3gôDHO«;݈ˆÔ †3±¯®À%ƒAŽ=ªº¿îÓ–/_.ÑÑÑ@‚‚‚äÃ?¼è{þýïKll¬±cÇÊ÷ßïù†ö"/¾ø¢üË„*;눈Š`p ®ÀŸœœ,f³™IbŠÙív1™Lú*}C† ‘ŠŠŠ‹¾ï7ÞÀÀ@ 3gΔS§Nõ@k{ÚÚZ4h6¸]Ý©GD¤F œ‰}§á ü'N«Õ*6›MuÝçUVV¶OP“Ù³g_4qÏn·‹ÑhÔßSPPÀßò<ÚåQlà§èü#"êq“àLì³Áu?9''GŠŠŠT÷Ëä²nÝ:Ï=÷\‡Þ÷þûïKÿþý€äää\tM€¾Ìn·Kff¦6xAÝ©IDäIp&ö5Âø'L˜ÀÄ>/fµZ%44THxx¸lÚ´é¢ïq8b2™ÄÏÏOÈ< gΜéÖö^‹E þ'à ù„‰h—Ø×rQQQŸÝßÝÛ577·ß„F222¤¡¡¡CïÓ6êׯŸö@k{·úúzILLÔ¾ëû•¥DDn4À2¸‚H`` äü4Ïó IDATççË®]»T÷¹tû÷ï×§£ýüüä7¿ùM‡ÞwôèQ¹ôÒK€DDDðÉúÝï~§ÿú©;]‰ˆºGKìÛWàˆˆƒÁ eeeªûZºˆ¥K—êÛñ†„„ȧŸ~Ú¡÷íØ±C† ¦/Ôħ7:¦¬¬L¿ÅàZu§-Q×i‰}åpþ„„1™LròäIÕý,]„Íf£Ñ¨ß·OJJ’'Ntè½|ðĦL™Òá÷‘ȼyó´à_¤îÔ%"êšDÏ8 WàÏÌÌ‹Å"---ªûWê€ŠŠ ÉÎÎÖï÷ß~ûíÊÍp8RXX¨/<þ|innîû†7j.€1ªN`"¢Îgbß0±¯×Z½zµ$$$è9‹-êÐûZZZ$??_Ï0™Lžm¨q82eÊmÐeVwuœ–Øç€ë¹ðÜÜ\Ù¼y³ê>•:A»zïׯŸ~»æàÁƒzoUU•L›6MHXX˜|üñÇn­ïY´h‘ük Rw:]X €<[àºÚƒÁ GŽQÝ—R'UWWËõ×_¯OùϘ1Cìv{‡Þûí·ßJRR’¾ûß¶mÛ<ÜZßÓÔÔ$#FŒÐ¾ƒ²³šˆè"àLì;W°ˆ“É$555ªûQê‚­[·Jrr²þœ¾Ùlîð{?ýôS‰ŒŒÔwf,//÷`K}׳Ï>«ÿp>5CDä5àLì«…+ð§§§‹Ùlf’W/f±X$((HÈ€dÇŽ~¯ÙlÖoäååÉéÓ§=ØRßuüøq‰ˆˆÐ³•áDDçÀçf$Lìó rÛm·éSþYYYÈÙl6yøá‡õd?£Ñ(mmmn±ïºûßaµ²³œˆ¨ó&ö«î/©›JJJ$##CàO=õT‡ß[SS#W_}µàà`Y¸p¡[êûvìØ¡=2Ù`’Âóˆú88§ 7Áue&²oß>Õ}%¹Á¢E‹$,,LHhh¨¬Y³¦ÃïÝ¿¿Œ5JHbb"Ÿòpƒœœíêÿuu§=õeáp&ö†+ðÇÅʼnÉd’êêjÕ}$¹AKK‹ }ÊÔ¨QÚfù‹/¾Ð—ÎÌ̔Ç{°µ}Ã’%K´ß£ÎųˆˆzLœ‰}5p†´´41›ÍÒÔÔ¤º$79räˆ\~ùåú”ÿ½÷ÞÛ©÷[, 2kÖ,©««óPKûŽÖÖVIOO׿WÖQŸ“à%Mh—Ø·xñâ?ûM½Ã²eË$::ZHPP|ôÑG~¯Ýn£Ñ¨Ï &û¹Éÿþïÿjßk€PUõS,`G»Ä¾ 6¨îÉÍìv»˜L&}MþáÇ˱cÇ:üþúúzÉÍÍÕÿøÇ?<ר>¦¦¦F”¸Ua@D>NKìÛו\pp°äççKII‰ê¾< ²²²}r™Ì™3§SWî”1cÆ4hP§éâyäí·)৪c "ß à.¥p‚ØØX1º¤ÞeíÚµ’˜˜¨¯ê÷Æotêýëׯ—¸¸8 #GŽäÓnVRR¢åS8d«ëˆÈÅ™ØW WàOII³ÙÌ•Ú|˜Ãá³Ù¬'ëÅÅÅÉþýû;UÆ[o½¥¯ xÝu×ÉÉ“'=ÔÚ¾kÖ¬YÚÕÿ"e=ùœT8ûN£ÝênV«•‰}>®®®NæÌ™£OùOŸ>]Μ9Óá÷;1™Lúû Äf³y°Å}Ó—_~©}ÇMF(ê'ˆÈ‡dX€sûV®\©º¿£°}ûvIMMí·á…:õþ††¹é¦›€ÈË/¿ì¡–ömv»]Ƨ þ °¿ ¢^NKì[×U[PPäççËÞ½{U÷uÔC¬V«ôïß_Hddd§·á­¨¨I“&éï_±b…‡ZJ¯½öšüˆTÖsQ¯¥%öí…+ðGEE‰Á`£Gªî㨇477Ë}÷ݧOÙgffJccc§Ê(..–„„ ©©©8zP}}½ÄÇÇk¿×=Êz"ê•b…«ÓONN³ÙÜ鎟z·}ûöéSÉ~~~òÛßþ¶ÓeüóŸÿÔg¦N*•••h)iž|òI-øï€söŽˆè¢’qNbßĉÅjµ2I«úøã%**JHÿþýeÕªUz¿ÃáÂÂBñóórß}÷Ikk«‡ZK""‡’àà`m£®+!¢Þbœ‰}6¸®ôrrr¤¨¨HuF Øl¶³–äMMM•ªªªN•ÑÜÜ,wÜq‡¾>@aa¡‡ZKíµ{:c‰ºî„ˆ¼œWËpNbßîÝ»U÷c¤Hyy¹L™2EþwÜqG§Ë8vì˜\vÙe@ÂÃÃå“O>ñ@Ké\6lÐf[ZŒTÖ³‘× ‚3±o\|dd¤ )//W݇‘B«W¯Ö“ÇeñâÅ.ã›o¾‘áÇ :t¨lß¾Ý-¥sµµµéƒ.ÿ§®{!"o à1pþÄÄD1™L\­ÓîÕkù$$$È÷ßßér>úè# rÅWÈñãÇÝßX:¯·ß~[ þ5¢•õ2DäU’8Wà?~¼X­ÖN­ÞF¾©ªªJfΜ©Où_ýõ]Ú‚×l6ëˆ[o½Uššš<ÐZ:Ÿ¦¦&}ÖÀ#ª:"òÐ.±€dggKQQ‘8Õ}y­[·JRR’ž¨÷׿þµÓe´´´È/ùKý1A“ÉÄ㫇µ[V¹@ ²‡ˆ”›Šv‰}’——'[¶lQÝO‘±X,úF< o¾ù¦ÓeTWWËUW]%$$$DÞ}÷]´”.¤¢¢B¿íà…ý)¢%öí‚+ðGDDˆÁ`²²2Õ}y‘úúz¹õÖ[õ)ÿÉ“'KKKK§ËÙµk—$'' Û¥r>ûì3}  &p©ÈöíÛµ¼ ;€qêº!"êI žp®À?nÜ8±X,ÒÜܬº_"/´páB}ª844TÖ­[×¥r,‹™3gŽœ>}ÚÍ-¥Žš6mšvõÿWe=õ˜L8û΀‰}Ô---b0ô)ÿŒŒ ©««ët96›Myä=ÙÏh4véir>ø@ûMëá¼ "¥%ö9àš¾ÍÍ͕͛7«î‡È‹9rD&Ož¬í|°KåÔÖÖÊ5×\#$88X¬V«›[JÑÚÚ*iiiÚàI…ýyH €<[àºz ƒÁ ‡VÝ‘—+**’êKå?wîÜ.ß§ã7$00P_ðÔ©Snn-uŃ>¨ÿpnèED½X:€—4ƒ‰}ÔEk×®•ÄÄD òæ›ov©»Ý~ÖVÀƒAìv»›[K]±wï^í €Ë”õXDÔmçMì+..VÝÏP/âp8Äl6ëWëqqqràÀ.•U__/³gÏÖùË_ÜÜZêŽv{6Xö[DÔEþfØ×Vpp°äçç˾}ûT÷/ÔËÔÕÕÉ-·Ü¢_­OŸ>½Ë<:tH222€DGGËêÕ«ÝÜZêŽ+Vh¿s€áª:0"ê¼pöÁÕYÇÅʼnÉd’êêjÕ} õB_ýµ¤¤¤è«úv¹¬ 6H\\œžwRZZêÆ–RwÙl6}pÀ¤®#¢Îˆƒ3±¯®ÀŸššÊÄ>ê«Õ*ýû÷%Û·oïrYï½÷ž„„„¹öÚkåäÉ“nl)¹Ã+¯¼¢ÿ aª:3"ê˜48ûšà üYYYbµZ™PE]ÖÔÔ$÷Þ{¯>埙™)]*Ëáp´ßFV º|û€<çäÉ“ú£˜pnøED^j*€ÅpnΡ'ö­_¿^u?B½\ii©Œ7NÄï‰'žèrYò‹_üBH¿~ýºuû€<ë·¿ý­ü·Ã™CDD^DKìÛˆsûJJJT÷ä–,Y¢/þ*«V­êrYG•¬¬,}ËèeË–¹±¥äN”àà`m0]]GDç †sJ®®À#F£QŽ;¦ºï `³ÙÎz&?55Uªªªº\ÞŽ;dذa@RRRdÏž=nl-¹ÛÍ7߬ýö(ëåˆè,±p&öUÁÕ1§¤¤ˆÙlæÖ¨ä6eeerå•WêÁÿÎ;ïìVy|ð„††ê M8qÂM-%OX³fö۷™SDD ¥À™Øw®NyÒ¤IbµZÅf³©î/ȇ¬ZµJ,/((H>üðÃ.—åp8¤°°PßàÞ{ï•ÖÖV7¶–Ü­­­M¿Màêº<"ʰ®Ä>???ÉÍÍ••+Wªî'ÈÇœ¬äÈ‘#].¯¥¥Eî¼óN=qÐd2¹¯±ä1o½õ–ü+D©ëúˆú&-±o%\WûAAA’ŸŸÏû¦äUUUrÝu×éSþ³fÍêòF>ZyÓ¦MÓ·‘þøãÝØZò”††}O)ë‰ú -±o/\qdd¤ ©¨¨PÝ7Ú²e‹Œ1B,Ïb±t«¼o¿ýV/oÈ!²mÛ67µ”<íé§ŸÖ‚ÿ^ÊzB¢>$ ÀcŽÂø“’’¤°°Û ’GY, 2pà@ÙµkW·Êû׿þ%‘‘‘@.¿ürùá‡ÜÔRò´òòr=QÀLuÝ!Qß gb_#\„ Lì#«¯¯—¼¼<}ÊòäÉÝNÎ3›ÍzþÀ¼yó¸Üt/sûí·kÇà e="Q0ÎÄ>\pvv¶©î¨Ø»w¯\rÉ%úF>Ï?ÿ|·Êkmm•»ï¾[Oö3âp8ÜÔZê ›6m???3Ù8C]×Hä›üäX†sûº;íJÔQV«UŸæ —ââân•W]]-?ûÙÏ€„„„È¢E‹ÜÔRê)‡C¦Nª]ý¿ª®‹$ò=Ap&öíÆ9‰}åååªÏ}ê#š››Å`0œµ‘OCCC·ÊÜ¿¿Œ9RHbb¢lÙ²ÅM­¥žôÞ{ïiÇÅI1ª:J"_ gb_9\nbb¢˜L&nyJ=êðáÃrÙe—éSô=ôP·ËüüóÏeÀ€ú`¢;ë:ÍÍÍ’””¤ ~«®»$ò #Â9š2~üx±Z­Üî”zÜ'Ÿ|"Ô7‰Z±bE·Ë´X,(ä†núúz7´”Txá…´àÎlj¨ Æã'û˜E=Íf³‰ÉdÒ»$%%¥ÛëïÛívyôÑGõÛƒ¡[‹‘Z'NœÐÙp³²ž“¨› gbŸ€J^^2zR—ŸŸŸäååu{Z__/7Þx£>“ðöÛo»©µ¤Êý÷߯ÿ¯ÔuŸD½O €<[ẊˆˆƒÁÀ{¡¤ÔW_}% @dÁ‚Ý.óÀúcƒƒ ’¯¾úÊ -%•vîÜ)ýúõm.Uוõp&ö•ÁøãããÅd2Imm­êsšú0m#W§.ñññrèСn—»~ýz‰2vìX·”Iê]{íµÚÕÿßÕu§D½C€gÔÂøÇ'‹Eš››UŸËÔÇUWWË 7Ü ß›¿æškܲ’ä›o¾©/ùäíXi0XQŸJäõ2X4ƒ‰}ä…¾þúkINNÖ7òyõÕW»]¦Ýn£Ñ¨( ¸4µ8s挌5JûmŸVÖ³y±³ûüýý%77W6mÚ¤úü%ÒY, %;wîìv™ òóŸÿ\Ï!xå•WÜÐRòf³Y þåBÕu±DÞÅÀl›áºò —‚‚Ù¿¿êó–H×ÐÐ óçÏ?k#wÜŠ*//—‰'ê;~ùå—nh-y‹ÚÚZ4hvÜÜ¡¬§%ò"áp&ö«C‹‹“É$555ªÏY¢³”––ÊØ±cõ|žyæ·”[\\,ñññ@ÒÒÒ¤¤¤Ä-å’÷h·ôf8÷&!ê³âáLì«+ð§¥¥‰Ùlæ6¦ä•Þyç *kÖ¬qK¹ï¿ÿ¾ôïß_È´iÓ¤ªªÊ-å’÷øî»ïô„N8oqõIé^Â9‰}‹/»Ý®ú<%ú‘–––³6ò3fŒ[2òÇY«Þÿý\®ÚGÍž=[;~ÞWÖó)tÞľ7ª>7‰~RYY™\qÅúª~>ø [Êmnn–Ûo¿]z °°Ð-å’÷Y½zµü[¤ªë‚‰z––ØW ×ÕSpp°äççKii©êó’è‚–/_.ÑÑÑ@‚‚‚ä£>rK¹GÕw —¢¢"·”KÞ§­­M&Mš¤ ^P×õœ0öÁøcccÅd2Iuuµês’è‚ìv»˜L&ñ÷÷2|øpùá‡ÜRöÎ;eøðá@’““e÷îÝn)—¼Ó믿®ÿpnQNä³âàL쫆+𧦦ŠÙl–Ó§O«>‰.ª²²²ý2­2wî\·í¸÷á‡Jhh¨+¯¼RŽ?î–rÉ;Õ××Kbb¢v,= ªS&ò´T8ûšàê8³²²Äjµ2±zuëÖÉàÁƒõEx^ýu·•m6›õ…Ûn»Oºô¿ûÝï´à¿@€²Þ™ÈC²,`G»Ä¾õë׫>÷ˆ:ÌápˆÙl–ÀÀ@}Šï¾ûÎ-e·´´È]wÝ¥'šL&·”KÞ­¬¬LŸípÂ>šÈ­´Ä¾ 8'±oïÞ½ªÏ;¢N©««“¹sçêSþÓ§OwÛ£xUUU2}út aaa²dÉ·”KÞïÖ[oÕŽ©"e=5‘¸ @ \eLLŒF9zô¨êó¨ÓvìØ!iiiúª~Ï?ÿ¼ÛÊþöÛo%))IÈàÁƒeëÖ­n+›¼[qq±¶¶ƒ Àu]6Q÷Å08WàONN³Ù,ªÏ5¢.±Z­úmdd¤lÛ¶Ímeúé§%d„ RVV液ɻ9ÉÎÎÖ®þÍêºm¢îI3±ï4\Ò¤IbµZ¹5)õZÍÍÍòÀèSþ™™™ÒÐÐà¶òÍf³ôë×O‚€O¿ô-‹-ÒŽ­ZƒTuÞD]5 íûüüü$''‡‹•P¯·ÿ~ÉÌÌÔòüq·•m³Ùäá‡ÖË6n{|z‡¦¦&1b„6xLaNÔ)ZbßJ¸®Œ‚‚‚$??_öìÙ£ú¼"ê¶¥K—Ê€€ôïßß­[íÖÔÔÈÕW_­'Ä.\¸ÐmeSïñì³ÏjÁÿ€ e½9QÁ™Ø·®À)ƒA***TŸODÝf³ÙÄh4ê¤Hee¥ÛÊÿî»ïdÔ¨QzRìºuëÜV6õÇ—ÈÈHm0[]—NtqQpNQUÀø“’’¤°°Ð-»œyƒŠŠŠö YrçwŠÃáp[ù+W®ÔgÆ'‡v[ÙÔ»ÜsÏ=Úq¶ZY¯NtIp&ö5ÂÕ)N˜0‰}äsÖ¬Y# úí¬Å‹»µ|‹Å¢/4kÖ,©««skùÔ{ìØ±C[å± Î*"¯2ÎÄ>\?;;›‰}äs‡ê™øñññòý÷ß»­|»Ý.F£QŸU0 Löëãrrr´ãá e=<Ñ9üäX†sûvíÚ¥úœ!r»êêj™5k–œgÍšåÖ½(êëë%77W?—þþ÷¿»­lê–,Y¢o UuöD-±o7\aDD„ .HB>kÛ¶m’œœ,¤_¿~òÚk¯¹µüƒʘ1c€DGGËš5kÜZ>õ>­­­’žž® ~¯®Ë'rî5ý€r¸BB‚˜L&9yò¤ês…Èc,‹ 0`€|óÍ7n-Æ '$==]JKKÝZ>õNÿ÷ÿ§ÿ2¡Êz~êÓ<à$Ú­nfµZݶ© ‘7jhhÛn»MŸòŸfÌ©¯¯wk’••¥'Ï._¾Ü­åSï×îI“w”Eê"àLì+ƒ«Ó‹“É$555ªÏ¢säȹüòËõÍvzè!·×±iÓ&}ñ ÔÔTÙ»w¯Ûë ÞmÕªUZðo0BYd Ÿ–gb_-\?==]Ìf³477«>ˆzÔ²eËô„«   Yºt©ÛëX¼x±ôïß_Ï¥qç~äìv»Œ7NüAYt Ÿ5€@3˜ØG}œÝn“ɤ-³*Ç—ãÇ»µmå@m³ ûî»ÏíOoøë_ÿªÿãp>vMäçMì+..V}Ì)QYYÙ~‰UÉËËsû’»ÍÍÍrÇwè·L&“[Ë'ßQ__¯ßpºPA¾ÂÎm#7¡]b_AAìÛ·OõñN¤ÌÚµk%11QH@@€¼ýöÛn¯ãرc2yòdý¼óÄmòO>ù¤üwºún¢. ‡3±ï0\?..NL&“TWW«>Ή”q8b6›õ]öâââäÀn¯ç›o¾‘áÇ :t¨|ýõ×n¯ƒ|Ç¡C‡$88Xä(‹Ô«ÅÁ™ØWWàOKK³Ù,MMMªq"¥êêêdΜ9ú”ÿ5×\ã‘…wV¬X!‘‘‘@®¸â ·çï™;w®v\~¬*xPï•à%8Ñû/^ìÖʈz«íÛ·Kjjª¾ªßŸþô'Ôc6›õ„Â[o½•oº¨7j ¢­Fª #ÔÛL°@Ú%ömذAõ1Mä5¬V«þø]TT”lß¾Ýíu´¶¶ÊÝwß}V²Ÿª¡‹q8rÙe—iWÿÿ§0–P/¡%öm„ëj?88Xòóó¹ƒQ;ÍÍÍrÿý÷ëSþ“&M’ÆÆF·×S]]-W]u•yçwÜ^ù&«ÕªŸ5¢Uò~ÁîP W‡+&“IªªªTÇD^eß¾}’™™©_‘FÔ³k×.INN’˜˜([¶lñH=ä{šššôDQ¿VZțřØW WàOII³Ù,§OŸV} y?þX  ¤ÿþ²jÕ*ÔóÙgŸITT”ñãÇsÏ ê”v;A–À¹ õqí·| àÿÁyÕÆ ïýk\}õÕð÷ÿñc¢‘‘‘èׯ`À€ Cpp°ç[MäΜ9ƒ'Ÿ|/¿ü2`ôèÑ(..Æ€Ü^×믿ŽGyv»sæÌÁ‚ êözÈ7=z£FÂéÓ§àFÿRÜ$òÚ @ܰD`` ÂÃÃ1pà@DGG#66111ˆE||<Œ¤¤$ :C† A` ¢Ôû”——cÞ¼yØ´iüüüPPP€¿ýíon¯Çn·ãñÇÇ«¯¾ 0 xñÅÏ; 'ú)¿üå/±`ÁX `†âæ—Ðgüýý:Ž8×ìop ÀigÎyÏiaíþ=Î|þp.ÑÑÊýýý1dÈŒ=cÆŒÁ˜1cpÉ%—`̘14hP×>‘‡}þùç¸óÎ;Q]]   ¼û3gŽÛë9yò$òòò°jÕ*ãõ×_Ç]wÝåözÈ·íØ±—^z)G€‰v©ny‡ö·Â4º©Ü®òˆ‡3¯ Î…ƒ†Á¹åäP×?Aç+ 66=z4222p饗bÒ¤I :ïˉ<ÎápàÙgŸÅþð8 :›7oÆàÁƒÝ^×0{öl”––"&&}ô¦OŸîözÈ÷]uÕUX·nü À¯7‡¼ˆßÅ_âñú‡ ` €KÚýïQ AVV®¼òJL™2W^y%z´ÁÔ7UUUáÎ;ïÄ_|˜;w.þùÏzd*~ýúõ¸å–[PUU…±cÇbÙ²eHJJr{=äû>üðCäåå@œy^ÇÕ¶ˆ¼‰êÀ…ÄÃ9 À•Æè×þEÉÉÉú``ÆŒ=ztÏ·”|Zqq1æÍ›‡ŠŠ ôë×ýë_ñÀx¤®7ß|?ü0l6®¿þz¼ÿþûˆŠŠòH]äÛΜ9ƒŒŒ 8pŒþGq“ˆº% ÎÕpn5\×£ŠÚ?IIIRPP ‹/–ºº:ÕOÞP/g±X$((HÈ AƒdÏž=©Çn·‹ÑhÔcƒÁÀeµ©[þøÇ?jÇÓ!¸žì"òsDŽýñIDAT%~pÎÜàm? Ý` $$DfΜ)f³Yöï߯ú|¤^¤®®®ý†)rÕUWyd#‘††™={¶¾U𫯾ê‘z¨ï¨¬¬Ô׌0WIïLÔÃüLð€õìh7 HKK£Ñ(;vìP}~’ûöÛoeäÈ‘úF>Ï?ÿ¼Çê*//—‰' ‰ŽŽöØ"BÔ·<ôÐCZ¿·Þ}«—ÈcÂáÜÇÀç:ú` 99YŒF£”””¨>WÉ‹,\¸P€„‡‡{t£«7J||¼>8å±Hî°wï^ —©ê|‰¼‰?œ‰„/áœ[“&M’ÿùŸÿáÒª}Xss³<ðÀú11~üxihhðX}ï½÷ž¾c`NNŽÔÖÖz¬.ê[fΜ©ÇVE}-‘WëçjXoÀ¹+–¾‰Ë´iÓdÁ‚ÒÜܬú<¦rðàA}ÞÏÏOüqÕåp8Äd2iû±Ë<à±Üê{V¬X¡ÿ&8±&¢ è Àõp ¢¢¢¤  @¾ýö[Õç4yPQQ‘ 8PßæzÅŠ««±±Q~ñ‹_éׯŸz¬.ê{ìv»dddh€gTu¨D½U€{lB»Y«®ºJÞ}÷]iiiQ}Ž“›Øl6yòÉ'õ+ñ””©¬¬ôX}G•K/½THDD„,[¶ÌcuQßôꫯjÁ¿g/×ND4Àkêà ÄÄÄÈOø@BCC€L™2ENœ8áÑú¨oúío«ÿípî®DôcYþ ®ÁÀôéÓ¥¨¨HÚÚÚT÷t‡C^xáéׯŸøøxùþûï=Z_aa¡øûû ™?>KÉ#<(ÁÁÁÚ€;FyXœI6Õp RSSÅl6ËéÓ§U÷tŽºº:¹å–[ôGüf̘áÑÌû––ÉÏÏ×o1˜L&ÕEtóÍ7kÇö‡ª:D¢¾(€ε¶€ÄÅÅÉsÏ=Ç}¼ÄÖ­[%))Iϼå•WêÛÚÚÚô'KÀþˆ¼ÂϬA»ÀsÏ='õõõªû‹>£±±Qî¸ã}ÊÿòË/÷ø#œÿú׿$22R¯ï‡~ðh}Dÿûßµc¼ÀUýØT8·,æŒ@Ú·oŸŒ7N¿ÿþûßÿÞãušÍf=Ù///y äq 2xð`mð+…ý]ÀUh7#0hÐ yþù祱±QuâsÞ{ï= *k×®õh}­­­rÏ=÷èƒ £ÑȧA¨G<ýôÓZðß @]÷FDqÖŒ@ll¬˜Íf±Ùlªû’^Ïf³‰ÑhÔ§üÓÓÓ=¾¹NMMüìg?Ó—^¸p¡Gë#Ò”——ëkK¸^]—FDu5Ú-5|Øãui6oÞ¬í_a0VaÿEDÝgÏp fÏž-»wïVÝÏx5»Ý.ÿùŸÿ©'Þ 6LŽ;æñz-‹ ¹á†¸Öõ¸©S§jWÿQ×m‘;…08×^ùùù\7þ<ªªªdæÌ™úýþ›nºÉã‰wv»] ƒ^§Á``²õ¸÷ß_;OˆQÕY‘gÄx€ € 8P^|ñE.[Û›¬_¿^† ¢oäóæ›oz¼Îúúz¹ñÆõÛ ÿøÇ?<^'ѹZZZ$55Uü?…}yØ(Ëáºâ9rdŸß?Þb±HPPþ(eII‰Çëþ# bµZ}vý€ è‹DDDHqq±Çët8b2™ôÙ†‚‚.ÔDJíÙ³G@€KÕu?Dä &ÿ_{÷]Uyæqü—›!rK bÊ¥4B!á*S4‘Šb-…xAµjÔ¥8ÚfÐeÑv–2Ú鄊,£Öo JqJ¬Ø¥r±Z»p”D Q’h Î3œ³wrË圳OÈ÷³V–"ñìwïýžç}ö~ozGÁFj̘1§T·@}}½ýìg?sá‘#GFemýºº:»âŠ+܆‘Þ6hŠ &8ß…?xrÄ’8I3$U*Ø`Íœ9³ÍÏKß±c‡5Ê]ÕoÖ¬YQ9nEE…1œyQRR•ã'²jÕ*§ñß/élï €X”ªnÌÌÌ6Û-°råJKKK3IÖ¡C[³fMTŽ»~ýzËÈÈ0IÖ¿ÛºukTŽ œHcc£ 4ÈIî÷0ƈq#$­Wðµùرc£2M.íî»ïv–7µ¬¬,«©©‰Ê±_xáKII1I–——gÕÕÕQ9.p2EEENã_¡ÀBap\N·@•‚³ íÀ^Dz㪪ª²‹.ºÈ}åíµ×Fe…=g°Ÿ“tÜ|óÍ,¶„˜±{÷nëÞ½»“\çaLÐÆt“ô´$¿‚OԱاýæ›oZ=LÁdåÅ_ŒÊq8`Ó§O7I–µ©…@SÍš5Ëiü?ï](ÐVå)d¡üüü˜Ø[Àï÷[QQ‘3µÉ233í‹/¾ˆÊ±¿üòKwa§NlåÊ•Q9.ÐTÛ·ow× t‡ñ@—$i–¤o%Yjjªy¶‘Íž={lÊ”)'FmžýG}d½{÷6IvÖYgÙ‡~•ãÍ1yòdçûñ¢waÀ©¤¿¤ÿU°áÍËË‹úh÷M›6YŸ>}ÜWï .ŒÚ±—/_î.*tÞyçYeeeÔŽ 4Õ_þò§ñ?üÎ@ØL–´S!ƒ"ØŠ‹‹-99Ù$Y·nÝ¢ºpQQQ‘ÅÇÇ›$»úê«­¾¾>jÇšêðáÃîZ’ö2H8u¥IzJÁA‚ƒ ²wß}7"A­®®Î®¹æ÷•^^^T³Àö©3fÌpgÌ;·M®€öá©§žr¾'U’ºz´ y’¶)Ø@„u%ÁO>ùIJ³³Ýø¾ûî ÛgŸÌ7ß|ccÆŒ1IÖ±cG[±bEÔŽ 4W]]eff: @—A@ûÑAÒ ô9Zff¦½üòË­hK—.µN:¹ ð;&0Ù4›7o¶¾}ûš$ëÙ³§½ÿþûQ;6ÐsæÌqÿ-’=‹Ú¥I|U?iÒ$«¨¨hv khh°™3gº¯üh»wïŽ@È<¶7Þxúvíj’lذaV^^µc-Q^^îP•4Á» =‹Wàõã>§ 7¹ß¼¼¼ÜFí¾ò¿é¦›":T\\ì®-0mÚ´¨ì ´ÖUW]å4þ¯yøÝIR/I¯(øÁœt_Õ«W[·nÝL’%''Ûk¯½¥ðØKàŽ;îpÂÂBÏÖ9šcýúõÎrÔ’{ø€#äKª–d)))6wî\;xðàÌçóÙܹsÝiv}ûöêûššw/ääd[¼xqÔŽ ´†ßï·ÜÜ\çé¾—_t8–4IÅ N2dˆmܸÑÌ̪««m„ n~~~TŸ¼?ûì38p I²ôôtûë_ÿµc­µtéR绳[Rºgßp8‰K$•)¸Š_AAõìÙÓ$Ybb¢=ûì³Q žk×®µ´´4“d999öùçŸGõø@kÔ××»«bJšíå𢣤ÿ–tXÁ§þŒŒ +++‹jð|òÉ'-))ÉÝK œkÑðë_ÿÚiü·KJöî+ Ís£‚³:µ éóù¬°°Ðír˜9s¦ù|¾¨‡ÊÊJëÒ¥‹S/÷ô›ŒvE'Ð\Û%)33SIIIQ9`]]¦OŸ®×_]‰‰‰úÝï~§Ûo¿=*ÇÂéÞ{ïÕ¾}û$é-I«<.Ú9Ä´²²2MžýôSI*—ô?pEæ1§²1’Þ4h¶lÙ¶ýøã5tèPùýþ°}æwÅÅÅ)##C}úôQï޽ݟ¾}ûºÿî$@8ÔÔÔ(++Kµµµ’4]Òó pñ1aÙ²eòûý:t¨Þzë­#þ®K—.JHHÐÞ½{å÷ûefÚ³g$iß¾}Ú³gjkkU[[{ܯ©©Qyy¹víÚ¥]»viÆ Ç,G—.]4pà@åäähðàÁÊÉÉQvv¶222"~ pêyðÁƃ¤<.pÞ ¹~$i]8ß444¨_¿~ª¬¬Ô’%Ktíµ×†ås¥²²RåååÚ±c‡~ûÛßjãÆR [c§«v?Öÿ×½{÷£’‚aÆ©cÇŽ++Ú¶O>ùDC† Qcc£IÊ•´Þë2@küH’ <8l«£-\¸Ð$Y¯^½ŽÚq0lÚ´iÎjl ’~r~]$–t‹»´•Hª þî?‰‰‰6bÄ»ãŽ;lÉ’%¶}ûöˆ—mÇe—]æÔ^û8%„5ðù|–••e’ì‘G ËgžH]]]|ñÅN`®•tAÏû IIš)éII%Ôw’‚3Ï<Ó®¸â ›7ož½ýöÛ¶ÿþˆŸbÏŸÿüg§NÔKêÎ/ x%¬ À‹/¾h’¬sçÎV[[–Ï<žÊÊJ>|¸˜+% kåµH”4RÒ,I‹Ü11ô'!!ÁFŽi………¶víÚ¨îŸoø|>ËÉÉqêÀ¶²Ž@ÌkðÃþÐ$ÙìÙ³ÃòydzcÇ;çœsœ ü¹¤¬]ŸÞ’®’T¤ÀÀ¯C IÒÒÒlêÔ©öÄOXiiiDÏÞxâ‰'œû½KRçÕ3ˆº ¦ ¤¤Ä}JŽdc¸eË;묳œ ü±¤^Q¼^$MR`<ÁV}ç Aÿþýí¶Ûn³W^y…î‚SÀÞ½{­GÎý½9Šõ "îBI–Ýê`9a“dùùùa½Ç¶iÓ&KOOwòg”))_R±¤ …$)))6iÒ$+..¶ªªªˆ]DÎ/~ñ ç~~$)Á³Zp¡Â|ôÑGg’lýúõa ¿G*))±N:ùȯK:ÝË w ñ’†K*”ôŽ¤Ã ™a0nÜ8[°`íܹ3"×áUVVf:tp€‹¼«V* À5×\c’,777Lá÷HÏ=÷œ%%%9Áx‰¤$//ZeH*´F!3 âââlÔ¨QöÐC1n †åçç;õm¥‡u"æBµ2(++³ÄÄD“d+V¬cxüñÇ->>Þ Æ©mnzuº¤É Ì.Ø«®‚‘#GZQQ‘UVV†ýÚ¡eÞ{ï=çÖ!IçxWm rÆJ²œœœË;ï¼Ó$Y¿~ýÌçó…1 ›Í›7/tÝèÔ½OÔ6š@‹µ8˜?¾ÛwŽ©m»wï¶ÜÜÜÐׯçyzebÇHÖ¨S0HMMµ‚‚ûûßÿÞêëŽ€ŠŠ ·;K1pJ»H’ 2¤YÁ²±±Ñúôéc’lÆŒ­¾_}õ• :Ô ¾_IÊñôªÄ¦.’n•ô¾BfœwÞyöûßÿÞêëë[}ڳ믿޹¦k=¼Ç5-J–,Yâ6@­} ---µþýû;Ÿ·Mõ÷qbƒ˜ñµ‚÷¡k×®6sæL+++kÕýh>üðCgª©O$ŸÚ‰%Î.|_|q«ïæÍ›­gÏžNãÿ7¶éEÓ¥HúWIë²cáO~ò+))1¿ßߪûÓ^Œ3Æ©ƒÅ^ÞLˆ¦f'kÖ¬qŸþ׬YÓâ »nÝ:ëÚµ«óYo)ðŠ-7B¬^ÁûsÎ9çØ¼yó"¾5s[¶|ùr§îS`õFhšŒ;Ö$Ù€Zü„¹jÕ*KIIqï« Ì‡Gxœ¡À ‚ é˜={6ÝßÑÐÐÚýô^Þ4ˆ¶q’lèСM ˜›6mrŸþŸ~úéÝÅ‹»KKú£¤DÏÿT¯À"Cîºñññ6iÒ${÷Ýw[tïN5<òˆSËD  iV0uêT“d=zô°4;àΟ??t]ÿù’â<=ûöcˆ¤g$5(˜ÀåååÙ+¯¼b‡nö}<TWW‡vA]éåÍ/49(--µ„„“d¿úÕ¯šlý~¿»j O£?÷ô¬Û¯’ô‚‰À÷¾÷=+**jwûÜvÛmN}|O$¢Ú¡&'î:õ_ýu“­Ïç³[n¹%t]ÿ›<=cHRGIwJ*U0HOO·_þò—V]]ÝšvµMøøãn(¿¤ñòF€Wš”TUU¹ƒön½õÖ&Ú††›6mšÓø7HšêéÙ⻜qï(˜$''[AA}ñÅ­mgcÖĉ:¹ØË‹^ºX’ 6ì„sΜ9îzô[·nmR­««³ñãÇ;¶.x,Ä®\I+0˜””d7ÜpƒmÛ¶-mn̙ƺ_ÒÙ^^pðÒI€}ûöYjjªI²É“'7)ÈÖÔÔØèÑ£@[)i¸§g‰æÈVàɸQ!36lØ®6Ø3>ŸÏ²³³zù §Wûl'Èn‘t–§g‡pÈô_’ö*˜œþùöÆo„»}ލÚÚZ;ãŒ3œºyƒ‡×bÂx xæ™gܧÿ¥K—ž0ÀnÚ´ÉÒÓÓßß(©»—'†°K•tŸ¤jëÄèÑ£mõêÕ‘h¯Ãîž{îqêæ ~€vm¼$>|øQÓï÷ÛàÁƒM’õêÕË:tÜàúæ›oZçÎ["©“§g…Hê(i–Û6›‚³H^z饘Ý|¨´´Ô’““ú9ÆË‹±â¸ ÀÊ•+ݧÿG}ô¸ÁuÅŠ–œœìþîRII^ž¢&YRýé¦àž±˜L™2Å©Ë/{yÁ –7ÈÍÍ5IÖ¹sçãî&·páÂÐ¥}ˆW«í‘“T(˜ää䨢E‹bb™áuëÖ9õó  ®c&6lpŸþïºë®cÖyóæ¹¿#iž—'˜pš‰€» avv¶-Z´È|>_4Úú£>|ØÎ=÷\§Ž>êåÅ€X3AÇáùå—›$KHH°ÒÒÒ#þÎï÷ÛÝwߺ®ÿlOϱæ4I3$mW04h'‰@È ÖIÝ<¼&sŽJ¶mÛæ¾Ö¿òÊ+¨vã7†¾R½ÚÓÒ#–%)|¦‡Š‹‹­±±1âÿþýûC§¤Þîå…€XtTÒÀÛúõë¨?þñ¿ûVÒD/ Ž6ÃI>Uûï¿ß©«[%%zxþ“ŽH***ì´ÓNs÷‹wÔÖÖZ^^žPwK:ßÓR£-J’t£Bº²²²lñâÅaïعs§~úéN}½ÔË“€XuD²XŠ­X±ÂÌÌvíÚeC‡uþûW’†xY`´y‰’®WÈØ’%K–\wÝuN}}ÃË€Xv‰$9r¤íݻ׺víj’¬_¿~æóù¬¬¬Ì¾ÿýï;Á´TROK‹SI¼¤|Iÿ§ït ´&øàƒœ1,>66ƒ›<ôÐCîÓÿ‚ lóæÍÖ³gOç¿ýMR/ ŠS–“¸o~ðƒ´xÖ@HWÕã^žĺKœ¯™™i’,--Íþô§?¹o$­“ÔÅËB¢]8jÖ@s§¾ð NÝ+éLÏbÞ%úçb>îr®)))ΟWHêàaùÐþ• <ø¤+ ïΪ?ïË«@ïÌ©AïЭAðͪBðͪBðͪBðͪBðͪBïЭAïÌ­AïÏ«@ïΪ?ïέ>îÍ«=î̪<òÏ«:íΪ9ñ̬7ñÏ­5ðͪ3ïˬ1ïɨ/îÑ®,íȪ*ò˪'ñͪ$ðѪ!÷ÕªöЪôÕªóΪíȶÿÿÿèÑ¢ óÑ®ëΧíʧïϯ ð̯#òЮ&óÍ®)îË®,ïΨ/ïЬ1ðά4ñЪ6íɪ9îË©;îÍ«=ïʪ?ïÏ«@ðͪBðΫCðέDíÌ«FíÍ©GñͬGíͪHñÍ®HîË«IîË«IîË«IñÍ®HíͪHñͬGíÍ©GíÌ«Fí˪EìË©DðͪBïÌ©AïΪ?îÍ«=îÏ­;òΪ9ì̬7ìʨ5ðÌ­2ïή/î̪-íΪ*ò˪'ñͪ$ðɪ!î̪õαéȦï߯ÿÿ€èÑ¢ êʪìЪïέðË­"ñϬ%ìͨ)î˨,ïΨ/ð̨2ìʨ5ñ̬7íÊ«:î̪<ïʪ?ïÌ©AðΫCí˪EíÍ©GñͪHîË©Jî̪KîÍ«LîͬMïΪNïέNïË«OïÏ«OïÏ«OïÏ«OïË«OïË«OïΪNîͬMîÍ«Lî̪KîˬJñÍ®HíͬGðϪEðΫCïÌ­AïΪ?îÍ«=òÏ«:íͨ8ñÏ­5ðÑ­2ïʪ0î̪-óÍ®)òЮ&ð̨#ïǧ íÑ­ëÌ£ñÕª€€€æÌ³ ëÌ­íʧïϯ ñͪ$òѪ'íʬ+îͬ.ïЬ1ðά4ñ̬7òÏ«:îÍ«=ïË«@ðͪBí˪EíÍ©GîΫIî̪KîÍ©MïέNï̬PïͪQïÍ«RðάSðέTðÌ«UðÏ«UíÍ©VíͬVíͬVíÍ©VðÌ«UðέTí˪TðË©SìÍ«RïϬPïË«OîͬMñÏ­KñΫIñͬGðϪEðΫCïÏ«@ïΩ>îË©;ñÍ­8ñÏ­5ðÌ­2ïΨ/î˨,ò̬(êȬ%ðѪ!öÓ°ëΧñÕªÿÿÿßß¿ëΧî̪ðѪ!ñϬ%ìͨ)óÑ®,ïʪ0ðͪ3ì̬7íÊ«:îÍ«=ïË«@ìΫCðÏ®EíͪHñϬJîͬMïÏ«OïͪQðάSíÌ«UðͬVîË«XîˬYî̪ZîÍ«[ñÏ«[îͬ\îͬ\ñͬ\ñͬ\îͬ\îÍ©\îÍ«[î̪ZñάYîΫXíͪWðÌ«UðάSìÍ«RïÌ©PòͬMî̪KîË«IðÌ«FðΫCëÌ©AïΩ>îË©;ñ̬7ðά4ïˬ1î̪-íΪ*òЮ&ðÒ­"ïέìÆªáÃ¥ÿ¿¿õÌ­î̪ðÒ­"òЮ&íΪ*îͬ.ïЬ1ñϨ5ñÍ­8î̪<ïΪ?ðͪBðϪEñͪHî̪KïΪNïϬPðάSðÌ«UðͪWñάYîÍ«[ï˪]ïΫ^ïϬ_ïÍ­`ïÍ«aïάbïάbð˪cðΪcð˪cí˪cïάbïÍ«aïÍ«aïͪ`ïΫ^ïΪ]ñÍ«[î̪ZîË«XíÍ©VðάSïͪQòέNîÍ«LîΫIðÌ«FðΫCïË«@îÍ«=òΪ9ì˪6ðÌ­2ïΨ/íЬ+ò˪'ð̯#ïέöЪêÕª éȦïέð̨#ë˪'íʬ+ïΨ/ëͪ3ñЪ6íÏ«:ïÊ©>ïÌ­AðέDíͪHî̪KïΪNïͪQí˪TðͬVîË©YîÍ«[ïέ]ïϬ_ïÍ«að˪cðÏ«dîͪfîÍ«gî̬hðάhî̪iðάiðάiðάiðάiî̪iîάhðÍ«gðͪfíͬeðέcíË©bïͪ`ïË«^îÍ©\ñάYíͪWðΪTìÍ«RïË«OîÍ«LñÍ®HðϪEðͪBóέ>îË­;ñ̬7ëɬ4ïʪ0î˨,ì̬(ñͪ$ïϧ íÈ­ÿÕÕïέð̨#òѪ'óЬ+ïή/ðͪ3ñ̬7îÏ­;ïΪ?ìÊ«CðÌ«FîË©JîͬMï̬PðάSðͬVñάYuh\›¼¤ŒsïÍ«aðέcðϬeðÍ«gð̪iîͬkîͪlïΫmïάnï̪oïÍ«pïÍ«pïÍ«pïÍ«pïÍ«pï̬oñάnïÌ©nñͬlÙºrŒ„zº³œ†ƒðͪfðÌ«díË©bïϬ_ï˪]î̪ZðͪWðΪTïͪQïΪNñϬJñͬGìË©DïË«@î̪<ñÍ­8ðά4ïϯ0óÑ®,ò̬(ñͪ$ïϧ ëħð̨#òѪ'óЬ+ïʪ0ðά4íͨ8î̪<ïË«@ìË©DñͬGî̪KïË«OïÍ«RðÏ«UîË©Yîͬ\ï̬_„{sºba^çÀ©zðάiñͬkñΫmï̬oïͬqïάríÌ«tîͪuîË«vðÍ«vðÍ«vîÌ«wîÌ©wðÍ«vîÍ«vðͪuçǦv‘„x²©¦¤èüüüÿž—‘ÌîͪlîÌ«jîÌ©hðͬeïάbïͪ`ïΪ]î̪ZðͬVðάSïÌ©PîÍ«LñÍ®Hí˪EïÌ­AîÍ«=íΪ9ñÏ­5ïˬ1î̪-ò̬(ñͪ$ïǧ ë˪'óЬ+ïʪ0ðά4ñÍ­8ò̪<ïÏ«@ðέDñÍ®HîÍ«Lï̬Pí˪TðÍ­WîÍ«[ïΫ^ïÍ«aðÏ«dž•‹¶£¢¡ù´±­áÀ©‚ïͬqíÌ«tîË«vðΫwîÌ«yîÍ«zîͬ{ïΫ|ïÌ«}ïΫ}ïΫ}ïΫ}ïÌ«}íÌ©}›‹}®«§£äøøøÿÿÿÿÿÿÿÿÿÜÛÚù¯š…’ïÍ«pñΫmîͬkðάhðͬeïάbï̬_îÍ©\ñΫXíÌ«UïͪQîͬMñΫIíÌ«FìͪBòÍ«=òΪ9ñÏ­5ïˬ1î̪-ò̬(êͪ$íʬ+ïή/ëά4ñÍ­8òЪ<ïÌ©Aí˪EîΫIîͬMïͪQíÌ«UîË©Yîͬ\ïͪ`ðέcîË«gîÌ«jŸ•¹ÌÌÌýÚÙÙýµ°­ãÅ«‘‰îÍ«zïÌ«|ï̪~ïÍ«ïÍ«€íÌ«‚ïέ‚ïÌ«ƒîͪ„îͪ„æÆ¦†™‹{¶¨¢žßðððþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡›•ÔîÍ«vïΫsïÍ©qï̬nîͬkîÌ©hðÏ«dïÍ«aïέ]î̪ZðͬVïÍ«RïΪNîϬJðÌ«FðͪBïΩ>òΪ9ñϨ5ïϯ0îË®,òѪ'ôͬ.ðͪ3íͨ8î̪<ïÏ«@í˪EîΫIîͬMïÍ­QíÍ©VñάYñέ]ïÍ«aðͬeðάhîͪlï̬o¡–Œ»ÿÿÿÿ«ªªüÿÿÿÿ¶³°çÇ®”‘ïÌ«‚îͪ„ðÍ«…î̪‡ðÌ«ˆîÍ«‰îͪŠâ㥖ˆ»­§¤æöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿæååû©–„ îÌ«yðÍ«vïΫsïÍ«pïΫmðάiðͪfïάbïÌ©_îÍ«[íͪWíË©SïË«OñϬJðÌ«FðͪBîÍ«=íΪ9ðά4ïʪ0íЬ+ðÌ­2ì̬7òÏ­;ïË«@ðέDîΫIîͬMìÍ«RíͬVî̪ZïΫ^ïάbðͪfîÌ«jñΫmïͬqðÏ«t¡–¾ÿÿÿÿ··¶þ÷÷÷ÿÿÿÿÿ¶²¯éŬ“šîͪŠïÌ«ŒïάëË©¨•€¯¤›’Ó¹¶´ñüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ šÛïÍ«ïΫ|îÌ«yðͬuïΪrï̪oîͬkðÍ«gðέcïϬ_îÍ«[ðͪWðάSïË«OîϬJíÌ«FïÌ­AîÍ«=ñÍ­8ðͪ3ïΨ/ñÏ­5òÏ«:ïΪ?ìË©DñͪHîÍ©MïͪQíÍ©Vî̪ZïΫ^ïάbîË«gîÍ©kï̪oïάrðÍ«vîÍ«z¢—ŽÀÿÿÿÿúúúÿ¼¼¼þôôôÿîîîÿŸ›˜î€rà“ˆÉ¨¡™Üµ³¯ðíííþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêêêý§”ƒ«ïάï̬~îͪ{ðΫwïΫsïÍ«pîͪlî̬híÌ«dïͪ`ñÍ«[íͪWíË©SïΪNîË©Jð˪EïÏ«@î̪<ì̬7ðÌ­2íΪ9ïÊ©>ðͪBñͬGîÍ«LïϬPðÌ«Uî̪ZïΫ^ïάbîÍ«gîͬkï̪oïΫsðΫwîͪ{ïÍ«¤˜ÂÿÿÿÿÿÿÿÿµµµÿŒŒŒÿÌÌÌÿÛÛÛÿüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©¤Ÿáî̪‡ïÌ«ƒïÍ«€ïΫ|ðάxðÏ«tïÍ«pîͬlîάhíÌ«dïϬ_îÍ«[ðͬVïÍ«RîͬMîË«IðΩDïΪ?òÏ«:ñÏ­5î̪<ïÌ©AíÌ«FñϬJïÏ«Oð˪TîË©Yïέ]ïάbðÍ­fîͬkï̬oïΫsî̪xïÌ«|ïÍ«€¨–ƒª˜”’옗•õÿÿÿÿÿÿÿÿÙÙÙÿÄÄÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóóþ§–‡¶ðΫˆîÍ«…ïΪïÌ«}îÌ«yîͪuïÍ«pîͬlî̬hðέcï̬_î̪ZðÏ«UïͪQîÍ«LñͬGðͪBòÍ«=ñÍ­8ïʪ?ðË©DîË«Iï˪NïÍ«RðÍ­Wîͬ\ïÍ«aðϬeîÌ«jï̪oïΫsî̪xïΫ|âÁ¢„›’ˆËÜÛÚúÿÿÿÿåååüƒ€~õûûûÿÿÿÿÿáááÿ¼¼¼ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­§¢æëË©ŽðÍ«‰ðÍ­…ïάïΫ}îÌ«yîͪuïÍ«pî˪lðÍ«gïάbïË«^îˬYðΪTïÏ«OñϬJðÏ®EïÏ«@òÏ­;ìͪBíÍ©GîÍ«LïͪQíÍ©VñÏ­ZïϬ_ðÏ«dî̪iï̬nïάrîΫwðͬ{©—„¤®ª§çþþþÿÿÿÿÿÿÿÿÿÿÿÿÿöõõÿ‡…‚ôêêêþÿÿÿÿèèèÿ©©©ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷ÿ£“„¿ïÍ«ŽîͪŠîÌ«†ïάïÌ«}ðάxðÌ«tï̬oîÍ©kîͪfïÍ«aîͬ\ðͪWïÍ«RîͬMñͪHðΫCïέ>ðέDñΫIïέNðάSñΫXñέ]ïάbðÍ«gîͬlïͬqîÍ«vϳ–†¥”ÊßÞÝùÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿ£¡ŸöÈÈÇüÿÿÿÿóóóÿ¨¨¨ÿûûûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯ª§ëåŤ•ïÍ«ŽîͪŠðÍ«…ïΪïΫ|ðΫwíÌ«sï̬nî̪iðÌ«dï̬_î̪ZðÌ«Uï̬Pî̪KíÌ«FïÌ©AðЫFîÍ«LïͪQðͬVîÍ«[ïÍ­`ðͬeñÌ«jï̬oÖ·š|—ƒÀ¿½ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¸·´ø¬«©úÿÿÿÿùùùÿ§§§ÿöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÿ ’„ÇïΫ’ïÍ«ŽîÍ«‰ðͬ„ïÍ«€îͪ{îÍ«vïͬqîͪlðÍ«gïάbïΪ]îΫXíË©SòͬMñͪHðΫCîË«IïΪNðάSñΫXïË«^ð˪cîάh¬˜Š›”‰Åº¹¶îþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÑÐÏû”’ùÿÿÿÿþþþÿ²²²ÿðððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶³¯ð࢚ïΫ‘ðΫŒîÌ«ˆïÌ«ƒï̪~îÌ«yðÌ«tï̪oîÌ«jðÏ«dïϬ_î̪ZðÌ«UïÌ©PñϬJðϪEĦ‹V¦‹\º¡…d€p‰ƒy¥•ŽÀ¬¨¥ßÜÜÛúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿççæýƒ~ùúúúÿÿÿÿÿ´´´ÿäääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýÿ£•‰ËîÌ«•ï̪îÌ«‹îÌ«†ï̪ïÌ«|ðÍ«vïͬqîͪlîÍ«gíË©bñͬ\ðͪWïÍ«RòÍ«LñͬGg^V¦vtqãËËÊùòòòÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøÿŒˆ…ùäããÿÿÿÿÿÀÀÀÿÝÝÝÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾»·òÙºœŸîͪ“ñάðΫˆïÌ«ƒï̪~îÌ«yïΫsïάnî̪iíÌ«dïΫ^îάYí˪TïΪNîΫIïΪNáÄ£V“‡~ ¨¦£Ý÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¦£ úÂÂÁýÿÿÿÿÄÄÄÿÐÐÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢–‹ÐðÍ«•ïͪîÌ«‹ðÍ«…ïÍ«€îͪ{ðͬuïÍ«pîͬkðϬeïͪ`îÍ«[ðÏ«Uï̬PñϬJïÏ«OíÌ«Uî̪Zêʧ`™Ž‚¥¢Ÿ›áöööÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÁ¾¼ü§¦£ýÿÿÿÿÓÓÓÿÊÊÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÃÁ¾õг—¢ïÌ«’ï̪ðά‡ïÌ«‚ïÌ«}ðΫwï̪rñͬlîÍ«gïÍ«aîͬ\íͪWïͪQîÍ«Lï̬PíÍ©VîÍ«[ïÍ«aðͪfêǦm™Œ~¨¤ŸšßõõõþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÛÙØý”üÿÿÿÿÚÚÚÿÃÃÃÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ –ŒÔîÍ«”ïÍ«ŽîÍ«‰ïΫƒï̪~îÌ«yïΫsï̬nðάhí˪cïΪ]îË«XïÍ«RîÍ©MïͪQðЬVîͬ\íË©bðÍ«gïÌ«mïΪrêȦy¦—†«¤žšãðððÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿììëÿ„~ýöööÿáááÿ²²²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐÍÌ÷É­’¤ï̪îͬŠîÍ«…ïÍ«îÍ«zðÌ«tï̪oî̪iíÌ«dïΫ^îË©YðάSï˪NìÍ«RðͪWï˪]ïάbî̬hïΫmïÌ«sðάxï̪~ì˨„¤–…´¦ œâðïïþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿûûûÿ’Ž‹þÛÚÚÿíííÿ©©©ÿþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¢™ÖïͬîÍ«‹ðÍ«…ïÍ«€ðÍ«zðͪuï̬oîÌ«jðÏ«dï̬_ñάYí˪TïΪNïÍ«RðÍ­WïΪ]ïάbîάhïÌ©nïΫsîÌ«yï̬~îͪ„ðÍ«‰íÍ«©—…º©£åïïîþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°¬©þ½¼»þôôôÿ§§§ÿúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÔÓøÁ©¤ðÍ«‹îΫ†ïÍ«€îͪ{ðͬuïÍ«pîÌ«jíÍ©eï̬_î̪ZðΪTòέNïÍ«RðÍ­WïΪ]í˪cðάhï̬nïΫsîÌ«yïά~ðͪ„ðÍ«‰ïÍ«ïͬ”îÍ«š­›ˆÁ£–éîííþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÆÄý£ Ÿýûûûÿ¯¯¯ÿõõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ£›’ØïÌ«ŒðΫ†ïÍ«€îͪ{ðͬuïÍ«pñÌ«jíͬeïϬ_î̪ZðΪTïË«OïÍ«RðͪWïΪ]ïάbî̬hñΫmïÌ«sðάxï̬~îͪ„îÍ«‰ïÍ«ïÍ«”îÍ«šïͬŸî̪¥°›‡Å¤–éíììþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÛÚþˆ†ƒýþþþÿ­­­ÿëëëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚÙÙû´ˆ§îΫ†ïÍ«€îͪ{ðͬuïÍ«pîÌ«jíÍ©eï̬_ñάYð˪TïέNïͪQíͪWñͬ\ïάbðÍ«gïΫmïάrî̪xñΫ}ïÌ«ƒðέˆïÍ«Žïά“îͬ™ðÍ«žïÍ«¤ðͬ©ïͪ¯¹¤ŽÉ¦Ÿ—ìçææþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿñññÿ‰‡ûôôôÿºººÿäääÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤œ–ÚðÍ«…ïÍ«€îÍ«zîͪuï̬oîÌ«jðÌ«dïÌ©_îάYðάSïΪNïͪQðͬVîÍ©\ïÍ«aîË«gîͪlí̪rðΫwïÌ«}ïΫ‚ðά‡ï̬ïΫ’îÍ«˜ïÍ«îÍ«£ðͬ¨ðÍ«­ïÍ«³ðͪ¸¹¤ŽÐ¨Ÿ—íæåäýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÿš—“ú×ÖÖþ½½½ÿ×××ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿåååû®š†¦ïÍ«ðÏ«yðÌ«tïάnî̪iðέcïË«^ñΫXðάSîͬMïÌ©PðÌ«UîÍ«[ïͪ`îͪfîͬkïÍ«pîÍ«vðͬ{ï̪ðΫ†ïÌ«ŒïÌ«‘ðά–ï̪œïÌ«¡ðΫ¦ðΫ«ïͪ±îÍ«¶ïͪ»ïÍ«ÀµŸŠ×© ˜ïåäãýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª§¥ú¶´²üÌÌÌÿÑÑÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¥ž™Ûï̪~ðάxïÌ«sïΫmî̬hïάbïΪ]ðÍ­WïÍ«RòÍ«LòέNð˪TñάYï̬_ðÏ«dîÌ«jï̪oðÏ«tîÍ«zïÍ«ðͬ„îͪŠïÍ«ïÍ«”îÌ«šïͪŸïÍ«¤îÍ«©ïÍ«®ïÍ«³ðͪ¸ïÍ«½îÍ«ÂðͫƸ¡‹Ù¨ž•ðäãâýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÊÈÇûžšúÔÔÔÿÉÉÉÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêêêý¥”ƒ¥îÌ«wïͬqîͪlðÍ­fïÍ«aîÍ©\ðͬVïͪQñÏ­KîͬMïÍ«RîΫXïέ]í˪cîάhïΫmíÌ«sî̪xïΫ}ïΫ‚îÌ«ˆï̪ïÌ«’ðΫ—ïάœïΫ¡ðΫ¦ïΫ«ïÌ«°î̪µðÍ«¹ï̪¾ïÍ«ÂðÍ«Æïͪʪ’Ù¨ž•ðÝÜÜýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãâáüˆ…‚øÙÙÙÿºººÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤Ÿ›ÝîË©vïÍ«pñÌ«jðͬeïͪ`ñ̪ZíÌ«UïÏ«OîˬJñÏ­KïͪQðͬVñÏ«[ïÍ«aðͪfñͬkïË©qîÍ«vîͪ{ïÍ«€ðÍ«…ðͬŠïÍ«ïͬ”ðͬ™ïÍ«žïÍ«£îͬ¨ðά¬ïÍ«±ðάµðÍ«¹ïÍ«½ïͪÁîÍ«ÅîÌ«ÈðάÊê‘اž”îÜÛÚüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóòÿ…ƒ€÷ØØØÿ®®®ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðððþŸ‚§ïÌ©nðάhðΪcïË«^ñΫXðάSïΪNñÍ®HîË©JïË«OðΪTñάYïÌ©_ðÌ«dî̪iïάnïΫsðάxï̪~íÌ«ƒîÌ«ˆðΫŒïΫ‘ðά–ïΫ›ïÌ« ïÍ«¤ðͬ¨ïÍ«­ïÍ«±î̪µðͬ¸ïÍ«¼ïΫ¿ïÍ«ÂïάÄðÍ«ÆîÍ«Èê‘Õ±¦›ëÛÚØüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿŸœ™õÅÄÄüªªªÿýýýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©¦¡ßìɨlðÍ­fïÍ«aîͬ\ðЬVïͪQîÍ«LíÍ©GíͪHîÍ©MïÍ«RðͪWñͬ\ïÍ«aîË«gîͪlïͬqîÍ«vîͪ{ïÍ«€ðͬ„ðÍ«‰ïÍ«Žîͪ“ðΫ—ï̪œïΫ ïÍ«¤ðͬ¨ïͪ¬ïÌ«°ïÍ«³îͪ·ðÍ«¹ïÍ«¼ïͬ¾ïÍ«ÀïάÁïÍ«ÂîÌ«ÃÀ¨Ð§“êÚÙ×üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´²°õ¬ª¨ú¯¯¯ÿúúúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷ÿš¦íÌ«dïÌ©_ñάYðέTïÏ«OîˬJí˪EðϪEñϬJïÌ©PíÌ«Uî̪Zï̬_ðÌ«dî̪iï̬nïÌ«sî̪xñΫ|ïάîΫ†ðͬŠïÍ«ïͬ“îÍ«˜ï̪œïÌ« îÍ«¤ðÍ«§ïÌ««ïÍ«®ïÍ«±îÌ«´ðÍ«¶ðͪ¸ïÌ«ºïͪ»ïÍ«¼ïÍ«¼ïÍ«¼ðά»Á§ŽÈ¤šå×ÖÔûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÈÇù“‘õ©©©ÿñññÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª§¥âáÀŸeîͬ\ðͪWïÍ«RîÍ©MíͪHðÍ®BðΫCíͪHîͬMïÍ«RðͪWîͬ\ïÍ«aîͪfîͬkïϬoðÌ«tîÌ«yñΫ}ïΫ‚ðΫ†îÍ«‹ïÍ«ïͬ“ðΫ—ïΫ›ïͪŸïͬ¢ðά¥îÌ«©ðΫ«ïÍ«®ïΫ°ïͪ²ïÍ«³î̪µðάµîÍ«¶ðάµð̪µïÍ«´îÍ«³É­”¾£™áÏÎÍúÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäääü~|ô³³³ÿèèèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÿ”‰§ñάYðέTïÏ«OñϬJðϪEïË«@ïÏ«@ðϪEîϬJïÏ«OðΪTîˬYïË«^í˪cðÍ«gîͪlïͬqðͬuîÍ«zï̬~ïΫ‚î̪‡îÌ«‹ïÍ«ïΫ’ðά–îÌ«šïÍ«ïΫ ïÍ«£îÌ«¦îͬ¨ïΫªïͪ¬ïÍ«­ïÍ«®ï̪¯ïͪ¯ïͪ¯ïÍ«®ïͪ®ðά¬ï̪«îÍ«©Ç­”µ¡—ÛÎÌËøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿöööÿŒŠ‡ñ¬¬¬þÜÜÜþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ³°¯åÙºœ]ïÍ­QòÍ«LñͬGðÍ®BòÍ«=îÍ«=ðͪBñͬGîÍ«LïͪQíÍ©VñÏ­Zï̬_íÌ«dðάhïÌ«mïͬqîÍ«vîÍ«zï̬~ïΫ‚ðΫ†îͪŠñάïΫ‘ïÍ«”ðά—ðͬšïÍ«ïÌ« ïͪ¢îÍ«¤ðά¥îÍ«§îͪ¨ðͬ¨ðͬ¨ðͬ¨îͬ¨ðÍ«§ðÌ«¦ïÍ«¤ïÍ«£ïÌ«¡ïÍ«žÅª‘¬Ÿ•Œ×ÎÌË÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþÿŸž›ð¤¤£ýÓÓÒþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüÿ‡€¨ïΪNñΫIí˪EïË«@îË©;òÏ«:ïΪ?ðέDîË«IòͬMïÍ«RíͪWñÍ«[ïͪ`ðÏ«dî̪iïΫmïͬqðͬuîÍ©zñΫ}ïάðÍ«…ðΫˆïÌ«ŒïÍ«ïÌ«’îÍ«•ðΫ—îÌ«šï̪œðάïͬŸïΫ ïÌ«¡îͪ¢ïͬ¢ïͪ¢ïΫ¡ïÌ«¡ïÌ« ïÍ«žïÍ«ïÌ«›ðΫ˜ðά–ïͬ“Â©Ž š’ˆÐÍÌÊõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²±¯óøÊÊÉýÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿº¸¶èǯ‘VðÌ«FïЭAîÍ«=íͨ8ñ̬7î̪<ïÌ©AðϪEîˬJïË«OðάSîË«Xîͬ\ïÍ­`íÍ©eî̪iïΫmïͬqðͪuîÌ«yïΫ|ïÍ«€ïÌ«ƒðΫ†ðÍ«‰ïΫŒïÍ«ïΫ‘îÍ«”ðÍ«•ðΫ—îͪ™îÍ«šïÌ«›ïΫ›ðΫ›ðΫ›ïÌ«›îÍ«šðͬ™îÍ«˜ðά–îÌ«•ïΫ’ïͬïÍ«ŽîÍ«‹îÌ«ˆÉ­““š‡ÊÃÂÀôÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÒÑ÷‚€ô¸¸¸üÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘‰ƒ©ðΫCïέ>òΪ9ìʨ5ëά4ñÍ­8îÍ«=ðͪBðÌ«Fî̪KïÏ«Oí˪TîΫXîͬ\ïÍ­`ðÏ«dðάhîͬlïÍ«píÌ«tðΫwîͪ{ï̪~ïΪðͪ„î̪‡îÍ«‰ðÍ«‹ñάïÍ«ïÌ«‘ïΫ’ïͬ“ïÍ«”îÌ«•îÍ«•îÍ«•ïÍ«”îÍ«”ïͪ“îÌ«’ïͬïÍ«ŽðΫŒðͬŠîÌ«ˆðÍ«…ïΫ‚ïÍ«ïΫ|È®“‡–…ÂÁÀ¾ðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéééûwwvð³³³ûÿÿÿÿÿÿÿÿÿÿÿÿÀ¿¿ê²šSîË©;ñ˪6ïЬ1ïϪ0ìʨ5òΪ9ïέ>ðÍ®BíÍ©Gî̪KïÏ«Oí˪TîΫXîͬ\ïͪ`íÌ«dðÍ«gîͬkï̪oïΪrðͬuðάxðͬ{ï̬~ï̪ïÌ«ƒðÍ«…ðά‡îÍ«‰îÌ«‹ïÌ«Œï̪ïÍ«ŽïÍ«ŽïÍ«ŽïÍ«ŽïÍ«ŽïάðΫŒîÍ«‹îͪŠðÌ«ˆðΫ†ðͬ„ïÌ«‚ïÍ«ïÌ«}îÍ«zîΫwíÌ«tïÍ«pÅ«’|Ÿ–¹¼º¸îÿÿÿÿÿÿÿÿÿÿÿÿøøøÿ||zð———úÿÿÿÿÿÿÿÿÿÿÿÿ‹…«ñ̬7ðÑ­2îͬ.î̪-ïˬ1ì˪6íÏ«:ïέ>ðΫCñͬGî̪KïÏ«OðάSðÍ­WîÍ«[ï̬_ïάbðͪfðάiïÌ«mïÍ«pïÌ«sîÍ«vðάxîͪ{ïΫ}ïÍ«ïάïÌ«ƒðͬ„ðÍ«…ðΫ†ðά‡ðά‡îÌ«ˆîÌ«ˆðά‡î̪‡îΫ†îÍ«…ïΫƒïÌ«‚ïÍ«€ï̬~ïΫ|îÍ«zðΫwðÌ«tïͬqïάnîͬkî̬hðÏ«dÆ«’p𑉵½»ºìÿÿÿÿÿÿÿÿÿÿÿÿžžœí’’‘ùýýýÿÿÿÿÿÍÍÌ{OïΨ/óΪ*ìͨ)î̪-ę̈2ñ˪6òÏ«:óέ>ìΫCíÍ©Gî̪KïË«OíË©SðͬVî̪Zñέ]ïÍ«aðÏ«dðÍ«gñÌ«jïΫmïÍ«pïάrðͪuðΫwîÌ«yîͪ{ñΫ|ï̪~ïÍ«ïÍ«€ïÍ«€ïΪïάïάï̪ïÍ«€ïÍ«ïά~ïΫ}ïÌ«|îÍ«zðάxðÍ«víÌ«tïͬqï̪oîͪlî̪iîͪfí˪cï̬_îÍ©\ñΫXÁ§b’‰‚«¾»ºêþþþÿÿÿÿÿ¸·¶î{{z÷÷÷÷ÿÿÿÿÿŒˆ­íЬ+òЮ&êϬ%óÍ®)ôÒ°-ð̨2ñ˪6íÏ«:ïέ>ðͪBðÌ«FîˬJï˪NïÍ­QðÌ«UñΫXîÍ©\ï̬_ïάbíͬeîÌ©hîÌ«jïÌ«mï̪oïͬqïÌ«sîͪuðÍ«vðΫwðάxðÏ«yîÍ«zðÍ«zîͪ{ðÍ«zðÍ«zîÍ«zîÌ«yî̪xîÌ«wðͬuíÌ«tïΪrïÍ«pï̬nñͬkî̪iðÍ­fðέcïÍ­`ïΪ]î̪ZíͪWðάSïÌ©PîÍ«Lʱ’RŽˆ€¥´³²èþþþÿÏÏÏõqqpöðððþÕÕÔñ‹{mMę́#ðɪ!ñϬ%óÍ®)ôÒª-ę̈2ì˪6íÊ«:ïÊ©>ïЭAðϪEîË«IîÍ«LïÌ©PðάSðͬVñάYîͬ\ï̬_ïάbðÏ«dîË«gî̪iîͬkïÌ«mïάnïÍ«pïͬqïΪrïÌ«sïΫsðÌ«tðÌ«tðÌ«tíÌ«tïΫsïάrí̪rïÍ«pï̪oïÌ©nîͪlîÌ«jî̬hðϬeðΪcïÏ­`ïË«^îÍ«[îΫXíÌ«UïÍ­QïΪNî̪KíͬGðΫCïή?æŽH„~yœ²±°âëëëülkköäããû‘ްïέíʧðɪ!ñϬ%ìÍ®)î̪-ïˬ1ñϨ5íΪ9òЮ<ïÏ«@ìË©DñͬGñϬJï˪NïͪQí˪TíͪWñάYîͬ\ïΫ^ïÍ«að˪cíÍ©eðÍ­fîάhðάiîÍ©kî˪lñͬlïΫmïΫmñΫmñΫmïΫmïÌ«mîͪlîͬkîÌ«jî̪iðÍ«gîͪfíÌ«dïάbïͪ`ïΪ]îÍ«[îΫXðÏ«UïÍ«RïÏ«OîÍ«LîΫIðÏ®EðͪBïέ>îË©;ì̬7ðͪ3½£ˆ:‰„‘ª©¨áwvvô±±°óib[IÿÛ¶öÑ­ïϯ êÈ¥%òÒ¬(óÑ®,ïϪ0ðά4ñѬ7îË­;óέ>ðͪBðϪEñͪHñ̪KïΪNïͪQí˪TðͬVñΫXîÍ«[ï˪]ñΫ^ïͪ`ïË©bðΪcðÌ«dðͬeîͪfðÍ­fîÍ«gîÍ«gîÍ«gîË«gðͪfðϬeíÍ©eíÌ«dïάbïÍ«aïϬ_ïË«^îÍ©\î̪ZðÍ­WðÌ«UïÍ«RïÌ©PîÍ©MîË©JíÍ©GìË©DïÏ«@îÍ«=òΪ9ì˪6ðÌ­2îͬ.óΪ*ë˪'µŸ‚-€}yWVVíSSSÒÿÿòÉ®íÈ­ïϧ ñͪ$ì̬(óЬ+ïΨ/ðÑ­2ñ˪6òΪ9îÍ«=ïË«@ðΫCíÌ«FñÍ®Hî̪Kï˪Nï̬PïÍ«RðέTðͬVñΫXî̪ZñÍ«[ï˪]ïË«^ïÌ©_ïϬ_ïͪ`ïͪ`ïÍ­`ïÍ­`ïͪ`ïͪ`ï̬_ïΫ^ïΪ]îͬ\îÍ«[îάYðÍ­WíÍ©VðάSïÍ­QïË«OòÍ«LîˬJñͬGðέDïÌ­Aïέ>îË­;íͨ8ðά4ïˬ1î̪-íȪ*ëɨ&ðË­"î̪ëΧiZK222¼ÿÿÿóΪìЪïέę́#òЮ&íΪ*î̪-ïˬ1ðά4ñ̬7òÏ«:îÍ«=ïË«@ðΫCðϪEíͪHîϬJòÍ«LïέNï̬PïÍ«Rí˪TðÌ«UðͬVðͪWñΫXîˬYñάYî̪Zî̪Zî̪ZñάYîάYñΫXîË«XíͪWíÍ©VðέTðάSïͪQïÏ«OòͬMñϪKîΫIíÍ©GðέDïЭAïʪ?î̪<íΪ9ì˪6ðÑ­2ïή/î˨,ò̬(êȬ%ðɪ!íʰõÌ­ãÆª ÿÿªÿÙ³ëΧî̪ðѪ!êϬ%ò̬(óЬ+ïɨ/ð̨2ìʨ5íͨ8òÏ«:îÍ«=ïή?ðͪBðέDðÌ«FñͪHîˬJîÍ«LîͬMïË«OïÌ©PïͪQìÍ«RïÍ«RðΩSðάSðάSðάSðάSíË©SïÍ«RïͪQïϬPïÏ«OïΪNîÍ©Mî̪KñΫIñͬGðϪEðΫCïÌ©Aïέ>î̪<íΪ9ñЪ6ðͪ3ïϪ0î̪-íΪ*ë˪'ð̯#ïǧ íÑ­ôÕªæÌ³ ÿ¿¿ò̦ëÌ­íÑ­ïǧ ð̨#òШ&óÍ®)îË®,ïή/ð̨2ìʨ5ñ̬7íÊ«:î̪<ïέ>ïÏ«@ðͪBðË©DðÏ®EíͬGñͪHñΫIñϬJî̪KîÍ«LîÍ«LîÍ©MîÍ©MîÍ©MòÍ«LîÍ«LñÏ­Kî̪KîˬJîΫIíͪHðÌ«Fí˪EðΫCïÌ­AïΪ?îÍ«=îË©;ñÍ­8ñ˪6ðͪ3ïˬ1îͬ.íʬ+ì̬(êȬ%ðѪ!î̪ìÆªôÓ¦èѹ ÿÿªñÕªéȦõαöÓ°ðɪ!êͪ$ë˪'óÍ®)îË®,ïΨ/ïЬ1ëɬ4ì˪6íÍ­8íÏ«:î̪<ïÊ©>ïΪ?ïÏ«@ðͪBðΫCðË©Dí˪EðϪEíÌ«FðÌ«FðÌ«FðÌ«FíÌ«FðÏ®Eð˪EðέDðΫCðÍ®BïÌ­AïË«@ïέ>îÍ«=îË­;íΪ9ñ̬7ñʨ5ëͪ3ïϪ0îͬ.íʬ+ò̬(ñϬ%ðÒ­"ïέíÑ­ëÌ­óΪÿ̳ ÿÿÿ￯óΪôʪìЪî̪ðɪ!êͪ$òЮ&ìͨ)óЬ+îͬ.ïʪ0ð̨2ðά4ì˪6ñ̬7íΪ9íÏ«:òÏ­;òЪ<îÍ«=ïέ>ïʪ?ïΪ?ïή?ïË«@óή?ïΪ?ïΪ?óέ>ïΩ>îÍ«=î̪<îË©;íÊ«:ñÍ­8ì̬7ìʨ5ðͪ3ïˬ1ïΨ/î̪-óΪ*ì̬(ñϬ%ðÒ­"ïǧ íʧëΧéȦò×®ÿÛ¶ÿÿÿÿ¿ª äÉ¡èÅ¢ôÕªöЪî̪èɪ!ð̨#ñϬ%ì̬(íΪ*î˨,îͬ.ïή/ïˬ1ðÑ­2ëά4ñϨ5ñ˪6ì̬7íͨ8ñÍ­8íɪ9íΪ9íΪ9íΪ9íΪ9ñÍ­8íͨ8ñ̬7ñЯ6ñÏ­5ðά4ðͪ3ð̨2ïϪ0ïɨ/î̪-íʬ+ìͨ)ë˪'ñͪ$ðË­"ïέíʧëΧôÓ±ò̳ïϯÌ̙۶¶ïϯòÉ®èÅ¢ôʪìÆªíʧïέéË¥"êͪ$ëɨ&òѪ'ìÍ®)íʬ+îË®,î̪-ôͬ.ïή/ïϪ0ïˬ1ę̈2ðÌ­2ðÌ­2ðÑ­2ðÑ­2ðÌ­2ð̨2ïЬ1ïˬ1ïϪ0ïή/îͬ.î̪-óЬ+íΪ*ò̬(ë˪'êϬ%ð̨#ðɪ!î̪íÑ­ëΧôȦò̳ãÆªêÕª ÿ€€ÿÿþÿü?øðàÀ€€Ààðø?üÿÿpaperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_64.png000066400000000000000000000172271456262201400257470ustar00rootroot00000000000000‰PNG  IHDR@@ªiqÞsBIT|dˆ pHYsÜæ1tEXtSoftwarewww.inkscape.org›î<IDATxœ­{}Ø]Uuçï·Ö>÷}“¼ùäÛùDP  b("B´€ µ­u:cµµLû´O[;v:¶cíÌ<ÓN;í´N­íX«EA+Šj‡|$"È›ä}ïÙkýæ}oÔý<çÙçÞsϹç·öÚë{Ï3®¾zýÄì~{ÎÑÐ}ºn÷ÉnÊPg< mPÌfbèѲÒlr‚¥-ƒf$+Aã€Æ¾W°²²C×>šÐ=€R$ô@¨JI)ÈJ—™CYv™š•eAZ áÞ)‡‘©áœ˜_2v ŸJ,œÞ½f¯íü óGáãs]Ä5_À¼s7L°Ÿ\4eèÍQg1ôôI+NCôžFË ƒÉ ¤¢·Ê­bD²CAÔÊàGÃUÔ£¢¨È ”‚4"@ 2Wæ°Í–Ê:šaƒðTÂÚ‰’1·›6›Q=êcqï¶÷w\ÿ¢ É.ÿ–ýÂÒ¡Ò1˜qTs„9ÊЋOÚ0†^|¢ hiՌӪ‘ ¡cdTɨ PD€îEµíÜ$I™$ó’R¯šHó2"FèÂr6á]ÐÃmJxJ††“ çÔÉ2úM‡röàbÉq÷Ó ëÖ™nÞ`ÊÕчۇeèHz±ICö>tz1f«§ÑÜhi0MIcIPI#Á ¢8AÀwû×€»«VÀJ@¾˜#S’%2\iY²c˜°–J„Ö\AW *àè3Â&뜜ÚvöqÜþ# pà *Ìߺh³:óáv+ìè(惠#{‡Ó‡IGV/Ö™²ºÆ LISºf†% ÉFŒŒ Ùþ3wûoCPa折 y#å)…èž–Ê0$¥ÌDóˆDÂÔˆ`ŠFjFÎTôfÔù“uœž>ý˜}·=+.–|Î:,žÞöý§tæ–˜tz­Þ€Ãén!«;iUt',&Ò,Ãd0¢q@Ž@´•O’»¯?DÌLd m‰BÒ<)dšÚœÊbˆ·² üÎ9£cWgzÅ`nÖ(uÎŽ§Ÿ>û¸—l$Ùš¯Oï›xzésXeŽ×ì ’nâ<]c"$NaÈp3š²˜1L aÊ4ÒÛê$IFîÈŒ]`. ¸Ñ6> BOJ)iH¦™RzÀ1Ĉ ¼Je(†¡(,u&’ƒ:`Ô°ÉÃ'¶\ðšýw4¹#ñ˜Û¶.aô“Õ½ƒ¬s¨“•RWŠ• ëdV€èê`ÖÙ9¼dfYG±€*$ ÀZTH+JuJBÅ =¥Òt#=¡"°˜äp:HwÀ9)3˜…Ò4“šŒa!2 p3M ‘4‘½ÒH£ L&•d2H+ VFç3[§Ëü.¯*W߃ù;&ËË(9ÛwÝÜI7M”šµ°tG ó€´ÕGñÊt€¥ƒn -®¤ÑI–™íû{æòbK+µ›,‰èÑy_;Uë„èv†v‘svvæ¥3°Cæd;R0Rš84áàΔHN 5:r†qt9ÀÎû1ÚsÍØlspÐþWD ìv5r`ˆ.Á®s–×}{ñׯøë_]±`ÛE¿þž_~ß—n¼q¯ /¼pâÞ{¿÷ùsýÃw ‹åœbKkg–ZLV$–¬(¦, £m‘ˆâI‡ÑôHºA†&àm|¤d„Qlì!‘I’„ p@ (H2ZJ!Ñ@BH$Š-Ì,FÿH3x Àð‘‡ÖÍ{âÛ7÷Ê£;õ7?øö¹ãŽ;¶ÿɇ?<ü“?ùÐäÃ6lýÞãÃ-Ía)5­˜ú’Ãg1 Jb¶F ,BÁ]ÈâðF§#áPq³tN¤‘vP6BT¦ „(@Ȧ"BÆ‘ L d˜Rˆ$3D€hûž6Nn\Ç­Þ±úÄW¾ìä7üîoîE×|öÚ'oºéKsþôÞœœœÄGþþ¯;ùü_¾ÏÐy1Y15ã•O°£ºBE¡³P,E^Y¬ÛԆK* !(Ì€lò€4©C#)€ H€ L65hÊLКî™0‘J`Š AÀ`0HÒää£÷|{ñŽwžöŠ#—ŸpÚÛ/Üc¬b?öÿøÄ¶éé©ÿüÇ<03|íöÛ·lµ…ÿTÓŠ*pzí£X¸) Å’h3E5;8 €Ò8" änȒɃ›è08DGj¤` G&ÉRjDhâ¿M’`F Íøe“öhD )"©­>rÿÝ‹ûÍë^wÔ!û¯<ý­ï^<>;;‹?þЇžÚéÒùÿþ wº^×^ãu¯8å—7Ñåª½Š©÷§j X¡Pˆ]àŒ¾36_­,DÀ=‘9"ÂNµi…у5}-€¸Ëeó~Q‘)*›‚DJÀšªS{Ö¦×-zúþÛ_ûêWõòSÞú®…»[•=öXý³?ÿóm¯;é¤yguVÿ…/|qs]¸ü¢P]ÖQ9ð@4@gͶÆÛb¾"; Œ…M‚·yh‚QpP&¥FLM&"aÜe‰g#‰ÛÞG¦@€l[¢íûM¬Ÿ7ýÐ'¼ú•Gyò9¿:ï,j|ó[wÎ\vÙeñúSN™:ýôÓŸaqßtÛ7yÚ/m1ÈÌ: 5A&z=kXq <…V<‘måcÌ ÅŽæN4n€Á‘* ž)$dF’ i$¥¶” €! ¡—Ôö? ’Ri„ÒšJlïg@S4¡í‚‘DBŠ ÷Þ½ ß¼î¨“O8æÀã.x÷ä³—„ýŸ?59èæ¿þÔSyôË^ö /7"pÛ×ïþ‘§ÿÒ @>D˜dizÄhÿÒ=è™Y„,4÷TÛøP¡Xdh6>šý/¤,R¢mÈ ÍKl6I€¹› ¨fý23!Rùèßš}lÝa«V½ÿqç¿kâÙ€ÀŽ;ð—ý7Ozð Ž=öX,_¾ü‡bW^uÍÆe¯Z½ÖÕlN³’àV úÈŒ#aÖö4Ûp½Ì]É ªÍ# !¨ˆ,6ºWÊÒ|\ínQ’™¤$ijv@ <öÀúyý÷×-_µòeû½òÜwv?f÷±aÆøÈß}læ„•¯\°råJì³Ï>?ô›¾ïñï>pãѧ­ª€Œ,+¬‘E„‹E¤FÎÍΣ±°;¹¡íùì¯N‰B *‚ä}ÚÙ;u7%5ƒh¤üî7çÛÖ‡öÃI¯Úû¨#~¡ü0ÜgŽ[n½mxË­·Õ£Z1oÕªUX°`Á³þnÍ¥—?tà g_…,)d ’Pºydx€n¤ nMS¥!s7NP›•eLµÀm­(Qh( a%¡Âös5—Øvm˜5ž'$>|Ï7ç—m¼dõI¯Z²â°U?'yÖqÅ•k·ÏÌÌt¾tÙÜ3Ï<]÷ìŒ233ƒ{6n¹éÈC§ZLÉØŒ(ÂXaáEÉÚÛ™n ‹²Fa¦”cdÂ̸Á@ŒÁ³êF\Q 暥(4Û@4)mã½wÍŸ[ŸØ{õqG.>üГ_pIøè?||ûQ+›Ø¸qƒ¿ùÍçÀÌžó÷_ö™ï~Ò¹_6º2(\n¡h–¤+¥8#ÓL0šé ˜ÁÛ¶0yBNÒ7&É9–#G¨€l„àØPP¨¦@³÷~kO?¼÷ê×­\pè!'½ à°uzþÿsæíçŸ7÷î»ïÆùçŸÿ#ÿÔSOéǶßrøaÞ¢S !°Óôp|üŸ¬?wÁ['xàœsÎ9Ï{Ϛˮºÿð×¾åë6 Ôei£¸ÂèÆŒ°Bf¤™•i,NE6Öw'3 ‚´¤ŒcižéIŽ8!ÇúÞó S¬|ïÎ[ö˜[öùÙÓNš¿ÿ²×½(àpË­_­ßºëNû–³&¶lÙ‚ÓN;íyïÙ¼ysnÚÆ[¯d˜Áv;wfʬ8KÍhžšÂD™fMC™FS2ŒÙ8FKÁ(¬Ùúm[h綸ÿ›_Ùk§÷}ûNZ°léK^4pøÔEkúùó§ì•Ǽ¼DŽ?þøtßeW}î¾ÃO|Ówi¤RÖæ4Ú(B¯a’,Q)F^ L¡4šÐ~€Í`ÏfÙBF%L0{øÛ·î5§rÿw¼qÕ¢¥/ÙïÇøÛþCêɯ+<²‘óæÍÊ+^н7n¬×9_]B°™Z$!fcQ2ÄôfŒA•AG˜”H±1C’æ@&i`r7B4_vt.{øÛ·í=§|ùÛO?eÉ~ûíûœ9ÇçO?ý4þæ#_/|ß{º/ùË8òÈ#±téÒ|ÿ×Üpÿ¡¯:ë~@D&E9²>³aðQH!IZ ²™iIÑ¡Lšɤšé:öçFU‰÷|ý‹ËÚô!ï|Ëê½öØcÉ Ößs¯>½æ}àý¿[.»ì2¬Zµ {î¹ç ¾ݺõõi.úÚ^LB„Ð|±}H]À‘!º7c4¿3’æfRÖ"64s²FA,àžÛ¯?xm_ñ+çž¹×’%‹"àpóWnËõëÖáý¿óÛvÅWàŒ3ÎÀܹÏêô=ç¸öÆ[ï]þг6`ç[î>ŽÚDvᆌæÇïæ&Œ‚m;7ob—hÎëwo»î°}§pÔ¯¼õû-^´è'_z…–,šÏóßz/¹äœwÞyÏiÝ=׸ó®»gcÁKÿ¤F/ý¿]ߘ»J»P 8€l^< ™2…ÌĽ_½ú¨}æÚËííoZ¶hÑŸ ðZ+þâ¯þVo9k5÷Øc Ö®]‹·½ímÍ_|‘㺛¿vßþÇý}!™·šhÉVŒRp!˜¹2*Â…"¸Ì!@ŠÑE¤ ƒúáßûúuGï9‘'¾ïg-[¸páó½Ç ßüqüÕÿúH¾ÿw~Ë6oÞŒ›o¾\pÁõ¬¯Ý~ÇŒïyøíÙÔ‘Ô8@@‚jD F@fÊhéø ¡˜ÐRÒ ÆÙÙÚ÷øÎÍ—¿ly'üÆ;Ï9`îܹ?•ï®»'×^s­þè?àëׯǣ>гÏ>ûÇ~Þnýƽœðæ-hÁµUJˆ€`’%„\hM’$“вh±øÈ^ëoºìäýÏ9éý¿ö‹/3gÎO ôx|þ†ã‘Mù[¿ñ>¿óÎ;±cÇœtÒI?öón¸ñ¦íóö?övˆÙRë–j*KŸ’,4KJJ“šI š™æú/}懰×ë~çWßyðää³Fž~âññþ—þ –ù/üÜÛíæ›oÆÔÔV®\ù=ókwÝ¿þÀÞ¼UPRJ‰ "Õbo£ÐzŸ)Í“!Á=;¶ü§m}óÝç½ùôOzÍ«÷œ7?ñ˜Åû³¿žóæ3Gý2~ñ‹_ÄÒ¥KqÄGüDÏýìu7lí—qýÄܹ³F¯ +¤†J"R(ƒÆJ"rV £¬<ã/òêÏÝýää§Ö~ìÐ9Îe{-™¿tŸ=püqÇ.=dùò§~`<²iS~äïþ¾þÁïÿÞ ë:¬]»Ç{싲îžmd&¾¹nÃw>áØíCŠ“@‚”2¡lF-Òeí³)!OBÉ5_}bµFÙ^";óìîºíúƒ'듯=úÐŽ8ã´7,~±êéw|³~ñÆ/åo\ø¾$\uÕUXµj~Úäò«®yjëÂ#/ž3µpÀ™`/ 'ÔÖ jçnCB}†zÂú„zw&Ôûïûýƒ™A` èã^/Y¾uɲ#¾óè6»ýš+/õ:»cÑAð‚ÄÚÏ^;»iÓ&þÛóKƒápˆK.¹ozÓ›055õƒïû—_wË7ö=ä˜! JZ *‰J¢Ší{B‘@ˆÌ ·R³åƒ—Þ¾å v†ì4â:!;‰‘ÀNP·yã‹ò±»ß°ú”×sðAžíå$áãŸøäŽ‡:8ñ„|zzk×®Åyç‡Rž7Öù‚ÆEk.ÿ~,=þâ‰É¹³‚*a½¨J oÜu¼Ò„õ„žå\}Âz ÕLÕLitÔl”DÀÆA²îµô€§ö=öÌ+þåÚÛÖ\´æ²MÒ3íííÛwàCú_·¹úôÉO8Á}ôQ\}õÕxÛÛÞöS?33ƒ{¾s'x¡’ªLT‚‰ ¬#Ž¶Û¹Ì£‚ßöäÉâ. ¡4y0þÌ¢ØuM©ŽÆ²cëÖÉw\{ú¹«O9æÐC–w7nŒÿýјýxÿÜR |ðA¬_¿§žzêOøx|â¢ÿûÈÄ!«.2ëzCcs©*¢앪4ëIõ TB}zûLXoPPoð¾À ™;…dÔQÄÔG9<…$’ÍÖLaμù3Ë_ûÖµŸþܵ÷/¼öº×»cÎý§?˜ ëÖ­ÃæÍ›êà§§§µáÉá7ñneY™¨À.ðÄn2 ¢*Ü*R)D‚ðS ¢WdË»[Q5ZThw*SU‰Jcc/¨_qÂéwõeêî_{ï{æÀÕW_+¯¼“““¸çž{Ïë…K®¸ú¡åÇŸ~R=Àž@Oc·~ DÔÞ™ RaPE"b¼ ZŒ8ZX°#¥`D5ZÇÌVÒ*¨•(Œ2z 5G+‰æ6˜€• 4é<11¡÷¾÷½‡¸øÒ+ž\÷ÉÏܵ÷{ /˜Ücï%ó÷\õš,Yòâ'›7o··ämG‡HDBAXÕØXHª¢U¤U¡Ö̺Ռ&Œª 1  DA(ˆÞÌL 1û(ô#ˆ$c"8AQDJð$R2K©9\×}þó:åg~†“““øÜõ7>Ö/>ìŠ_yÄŠF‡Qí¯.úÜKõƒ—îõÒ3Þxê÷–¸üêÏÝ·âÕoºSÀ˜uk¢q¯Q°Jk\ŠTT^U޹ª™ §×€Õ¤¢ˆ¥&ÀÌžF29ÚQÎ%& .¶@›ZÂH™,í¥€é­Ó999éW\uͦ uñÅû¸â)µÊ1f¦;uâ× Xÿäöiÿï÷é—/[¶½Ü¼X¶J„¤¦Ç5Å0ªÖ1UeTÁ*‹õŠ&#9ÚΪ¨Š2Èêü»ßÞÓ ƒ†Ù*•‰‘s݆ DªÉ@Fj\ÙñôÃß9|`qÐK_z¿xÓ­.úçýZñø¨È!I$É2Í, †uñ²C7hj¿;.½tÍô÷ÞÓ|àþ '''h{|âÓ—}û€•«¯ƒ±&6R})T+¥jlìo´ °ÂXÍU¬E`©I«UMªQºZ’Yaä´"x d¢Zs\PâˆõHFO(îºûÛujáâMÎN}|ÿCŽ|RJ‡`t#F%r$9*“çØ¬î&çàØS.øJ"¿òg]óŠÃ–-:þüsÎ^:1ÑJÖßsïp‹\¿78,‘qTT^‰‰Æê€WE ±VbШNU«Y{*lTDíç½ç‹à„¹#û$ÔåI¡ cQ"G¹Íqp¡qúÎW¯?öÎo}}Á¼WþÍþ‡»°„Yh‡1 ¥Èd¢@û.… ­’ˆ½zÙC˜ÿ’Û>ýÉšytËŽ:rÅÔ§.ùÌ7XyÆç)ÔT« U›ÛVÝi=‰šb5ª:¼fÖpZYŨN«ªY“ª†Ò'Uchµt¦Ú÷ tXV\Š%$¹T{µ,xK#î–P+ˆzôñ§8öÔw\»ôcž `2– ÒR-%iç´³L®_Õ„«QÞMâ¸ÕïúO=¾é ø_þ〈}¿°!€„"ኬHPÑä#GúÝÝ*Ñg­j´CP5dÕ TôªIÕ°¬ˆ:ä§nytŸ‰Á`²OS_LVj±bª>pª–ì­k`CѪJÆ•`™næ-­Þš¦F½ØÙ:£LkIfÈqÎa·‘™­¤J£¦ „HÏ£HN¶f §G3×=¨šÈÖ3àðZG6Ó+¢o¶M #YjRµ0k²«aY³YWÌ_òXÙoÇÞ?Q¶ïe˜•Otbš,{\@fEQçÈP”¶)<ᣒy…ÃÍA™Ó\Ùjw 4 F!h=t¹kõ͈Œ–Jmú#`nãRAhMËXÉã× *K‡E®@Z„)X[ÓDÀ*á°Úw%ŠeEßUGV2+8QcþôSGÅ!à†ûïŸÜôäÔ’]­2,5û2(;[eLµhÔ%ÒºEÂÅj†›C†ËZ¿‘¦ #}çêÛf`îìÛ-fo£63—;{†hH©*å;9€jA"³ÏqËŒÓë¸w © Sëª,+ª"f¢ö±mûÏ¿î€'ݲWþëÆ¹Ct ‡ie²3ïÓ ÝfûÖ.3þm32ŽÀ·2˜BR çÉ]ù98Ü0¹ÌZ„Zp™UÑ”rXŠQ4Œ>û@ö•á`ôÞ½ºÞýÖÙmÕ'3w¯ù[ÆàŸÁãñOwlš7…yófc¦ šOvæºJ›ŸÑ3˜ô4f[ëœúÙíê4ŒÚç: •±[Ó”›·†IjËä$ZIµ²Ò¤”fÈPIËaÖDvV‚¦¨;ÛæºQÛ\뜰‰ºm8söÌÞqࢧ?Èg¶Ò>«SrõzMÄS[çïÈF žÙ5Šú0Í‹ÁÒhÈêãÖYŽºF 3«Y3Éhr  ⇃‹î*ÞÀ{ë“qÔ9jY’ŽŒµÏ&r0©¨;”ðð¢@™ô t˜UL ‡³«OX²u÷•ÿ‘€‹ïºk,›Â¬9&èèwµÏv›Þ‹O´–Y‡e¥¥õæA“õFhg£š±5ò ëµ²”‚ˆº‹¼µ"KúõIô®q€#5”Æ-³ãþᢆEá¡Ä°µÍ²› Ì(æMnŸ9ý˜}¶·TÙé–^|ñÅ>|é©óæ²ë¦ëöQõŒ|®í¨³>¨´0ZqZÖÆ ½LëÍ6ðdŒÎ ÖÊݳ¿}ߣ”"HA^vµÍŽ»È­ sV7M·rå„¢%ÊdxÝ–ì&g"&¦íx®žáD€Ä‹¿òðd7gjâéá6ŸÓ-4Ô­}ÞÍ¢§uÞÚçÃhY‡f6A›³öÖZæ¹üxncW¢"•nÔ—de9YQ¦fd1‘Þ)‡5sn™ŒÙªœé§sªÌ "úÁ¢Š»Öì¸à‚ ž7óÿvNXÖ*ÙIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_72.png000066400000000000000000000221651456262201400257430ustar00rootroot00000000000000‰PNG  IHDRHHUí³GsBIT|dˆ pHYsyy ,ÖtEXtSoftwarewww.inkscape.org›î< IDATxœµ|y¼¥UuåZ{Ÿ{ß{5UC¡X(S  F@¨Hm´íNÒ݉v§;I[¢1±;‰&11¢Dà‘´R¢ ƒ™Z ( £ÅTë÷î={¯þã|÷½Ç( 9¿ªúî½uïw¿oݵ÷Ù{Ÿ}ñ,Æνµ¿÷î+'0pŸèÓ6×m>VÌ¢ÐúZ³pZa¥ÌÆÇ™u`Æ1f ¬’4‚F°’´ ¢ŒŽµ’½9ß7ìþ-¥C T †@)’•^¦ ÌR’e?3§e¥ŸžJ+Êa(½§D¦W%ÊD”¡’ýˆŸÆ¶Áo°rIý¬{ç3ý§$^p&ØllÓÀu›•†:åQh=§¥ÓbH+NË KZÍÆúÌ:4#˜QÍØkÕJ#ˆ^V‡z¨¬OºŽ8À)ÈKO’”‚\˜yl®LAV”ý¬Ei©ô¢&ÒC9¨™óÊxL×­3@Mj8ìß³ÝÖ“Of'€$Ùù7>ºh¨ÒÃ8#`¦cèÅÇ ÙÀ)FË7šbhdiÕ44’”$ €àì5d4&™’ŠÜ¥Z$AtO©vK¦†²,i®d"£§&²o½¨©ÆTŽ{?àŠAÍDÉÐ e"6.þÉæÿ´ÇÓÏ  \ªòây›÷æYáp[¦gΠã À én4Ì–K£)êÌsë˜3ÌjD! &ƒ0ƒpíŸ9#àrUTŠäêL Jt@™RCˆ®4+I!sRÎIëEÍ©„õE2ƒÍ“©’1fãuÅÒ›|1§ž sÏ•×Ý7/-V|ótAßAW Å<­3f˜ôb0euMF³€ÉkD˜2f€Q†‘`tIÒáȢ̹Ú1Ù!`&©Å ­±ÈÌ3Q•éÉDÒ•™Èb‘HËAÂJÐ a}ïk\ÁaƶŽM%›N>d×mO йçžë»³t‹M÷QÍÇ{8¥QàˆêJú0«뙼º¢gÈp·Ž=„YÒÄ0%PIc Ù"ÉŒ »#3øxÌ\ÀEÌl¤bHI¢yÖ¢))O3dÉTÂ<,kFªH1V(` x«"¸¨¢l 2,]ñÈq{púq}ಗ¾y»ù‹½?Ó=sTºiXt8}öØ@’Ñ`t7XMº%ÌÙ|‘’f@"ŒdÇïÀI2ÀìüÏ,H³ÃÌ;`\„Ð,ejg^€hH¦'M™B3³TÒk‚9D‚Šb0LÁPÀK bä“¢gªðŒñu+|øä}öhÄÞûµ÷-Á¼‰±š^\æÃ©aA¡™£Ð«jiVA̽Ðð zfH—»Õš.ÁŒ°ˆ4¬À©H³RX3Œ$m6s2Ad gÁ"³½”)dÎ6±'B Òd©…1™Í÷È<¬Df2AZÏ‘°D ã°˜ †A5˜,³G“14Å^ö¸i+8ob·¥k×®-“““_+çÞúÓ.˜ðœ.Ãdé÷Ì-­ é,ô‹©ï*=pzŠÀ-Ònº! NW˜y1),(£“™i63s‘ @fÒÌ„œ @ºÂ #dD* ˘&L ‰ ÒkZš› ¸a(“…¹œ($BLV–^!ªq˜†ë¾þ…lëÞ½|ùò·DÄ]Å7ûô§Ý’Å4,5ÇÝÄ‚BŸDéy¯2Œ7G…ÃÂGŒÒ t¤›»Í€d4©39•i€QI48A 5¯œ#*%$+BD{LË$†hžÒ¼3+0Í#SLˆfˆÜ€0z ¤(3ƒÊÔ/´-+¾séÿÝ¡¿éžwÀÞ{sé¥ß_ôŽw¾3ÎúÂÙï+è›[² 5,&+ÐЫ¬ôD·’…Fa: ÒS,Ý &Ðt$\¤ iA¸%-(3¡Íi™F8‘i#'Ý|`"ÓCÎΙMÈAÑ µ?21I¤ !•‘™^,RLé %šY™i€ ’!`Î6±Öaðæï^²#¾ó”#^¹ÿ«÷Ýç¨%§Ÿ~z~øÃ.Ÿü뿽øô©”aÇ“ø˜Sµ˜jÉ! >¬QŠÓ%zÖ(0:A‡Ñ%8"ÖÀ¢à‘éš 3´)_)“dôlѳd(@J"1ËœÆ&©) 1! d´!¤RDBL#2Rî´B`F/‘ªf2ÂÙLÚÁÌäµ—^´³?öÓ9è•¿ôúßúK.¿üŠ-úЇòŸøDÿöÛïxô-õÓûNz)¦a;4tª– Åï¹)Š”%TœˆB§#á‰,£@€«Ð ¸‰.ΚƒÓ˜nÍÄ@ÒH€¢ˆi„ò‰A«s5&I Dz*S¤¥LibHÒ¤T ¶aK`C$Qa°°[®¼dçúð†_wø¡‡yÄ[À?üÃ?[UKA¢Å9…Þ=Ôw¨z<œ…Ê’Bq ÏÊâ‚,0z ·ÎÿޤétÁ ™.Âh4Fƒ)ÓH§”–j#Ì%  Í΀ $³6­+Ec"!²ù²}EG5³H=@‘×_ù.õ¡õ¯9æÈ_Üÿ ƒNZ0ú6oÞ¬?øŸïßôò5û.ø÷ïz×LÉeW}ëà_þíÊÓ¨Òó6[YÉÆ±HYXYÒ)z–¤;ƒ%3 Í„+Yв)ännPz‚ÎvËÆÎÜ·DZËìÛAJ¶€GsB#”)hf¥ÍRB6ׄYæ4oo- K»å_ÖíÆ-÷ÿâ1G¶æÀW0®ñ®_çàãgœ1ý꣚ÒI'Í€sáE_ÿéÂÝ^õ98]µ1·Ä ›‰”‹è¡â@¸«“˜žÖù(ÑCYœp©óG¢ r€N¤£cRRFÑ@Ñ™™Úä€í±Í¹…„2-(dBÀl€©ùžŽ9è¡L»õšo¬*[¼ö¸ÃÙëU¯ø“ñ7¼á?ø ƒæþ"ø§óÿùö}íÙH8œB"Aª˜õ-Ñáð¬Í »ÓSî@Î2IY”K›8Udt „frRä43IÞe¡F´D¶eO-ßï’Yˆê’‡‘y¡³<5€H‘HŠ)CJHAiÝqý•+}òý~ùÕ‡½xï½Oè?0µVüù_~òÑE æ/>þøã±çž{>nƇ¸ú†[/;ðGO‹rÔ¨T©Y[T¬î—Ÿ1—6CAtî‚§¹CéÖ̪*¦ÒYHtQ¶füa–)'aLB-ÓÙMõèPH¡ó?m:OHm~cl¸ñÊ|ËûœøšÃWí½× ½§zè!ýñ‡ÿdË¡k^ràjÕªUOª}îy÷íq؛·Â[¹Ð‚+©‚¤[¡IEVhê‚¿ÆxB…ÒŒ¹±±¤H,Æl`)K. XÊs,›a’Ѥ£€¤RA %)f" J´idþàšKwœ_Úã¯9|ç—½ôø'VÙ7~pÛíõóŸ?kz¿5û.<âˆ#°|ùò'355…[î¼ïÛ¯Úë¸PÂÍ<òÊ*šgqƒe†›SMéF7)=§ÑòÑÍ›è2:¤9LÊà‚ eÒ Lše’#Í$Z9„€˜ LšÈÔ‚C©1èöë.Ý~¢>òâS^{ØŽ{¬^ýŒÀÀºK¾µí–[nÆÞ{½lþI'„‰‰‰§|ßþñÜ}ùkNû:”nÅR $öÌàVÒhR±Ìp-NÑin€:§ÛLN¢ÓàœË¤ÆO©0rÖ®ö×ИÕò"k5D Éœ „Dt×MW®èZõ«Ç½lÕª]&0ðÅsÎï•Þ’E {§žz*J)Où¾Í›7ký}_þªýæƒ0“àFdpËÕ fØC£ÓÑdFSŽŽ˜õM#Ó&oÌÁ,XÍÿ4¿”š‰“ÍÎjlùZvJˆDËéA@?¼åªe½-?ÝåÔ7¼fé®»ìbOy‡OƒÁ§èO&_ûê£Æï»ï>ûµ_ûµV`yšñù/žóÃý^ó¶+DZf:e™„›!™­Ö^D2L³ì1¢Eéd üÈöEÏì˜5:Î2 @X2Õœv@§É!aÊZêÑîC7ÜpŲÞàÁÞzⱋwÞy§g lܸQÿß¾ím§þʼ;ï¼§žzêÏzÞ÷ÐÔU;ö{$Õ*Ÿ€ÕLƒ›0EX! »šN[¢±."LÒ»4¡™ á”Û\”jå3cTb4õc&N¢É2£cJöۮܮ·í'Û¿ýMÇ-ÜiåÊg\Ð|â¸ñ¦ï×óÎûr=å-ož÷ãÿ'žxâÏüÌYÿø¥ û¿îÔkXÖtÂNkÔ*ì9‹28­°D!MÁ† a†.vi¿¶·E ÙùÒÔMë$]ÍôX Ì€'Ìhr…ìŽ.Y1¯>²ìío<~þÊw|NÀÀE¯Þ{Ͻ:áøcÇ'''qôÑGÿÌÏÜÿñȰÕ*8S0§Rµº¹PM0C°™X[£rJÑ|P)³À`n­0ëÀ0£˜&ŒÌN³nšoìiqŠˆÎa£€æŠð;o¼lÅBlYþž7?o»í¶{ÎÀÀg>ûùé]v^Yvñn>þ|¬Y³æY}îìúê/?ü”[E™!-ÓŒh«/ðlÕ4ˆXH²FZ1ï*|­4ÚÕqˆhU@F ’¦¨Þ*Í~[ù&´€P©æ{Ø1‰(Ê,nøöórÓò÷¼å ó–.]ú¼€™žžÆG>úñÁ¿ûÕÓú7ß|3÷Úk/¬^½úY}öŽ;ÖËÿ‚'2£‹­²&*a@Xa´7ÕL+î­>#c"i C+†6DÕ1Š4Ј„ 4³ ÙhÙIkaá™òõ×\²r±oÛþ='½aþ’%Kž.€ûî@ûøõOþøƒý‹.ºk×®ÅN;íô¬?þEß¼ó凲£Ù³‘¡õ$H­ÛaÄ ˆnM$ÄÌsDÊÐ&áV l9¶‰iF#$ÒÔj&Ðò¨C¿ýê‹wY66Üá7OyÓ‚Å‹?o`àúnÌ‹×}#ÏøØŸöÎ>ûlüñx.ç¼ù–[¦;|£ûÈ´–ñ4@²[Ød[?@ °$ƒ´Ñ‚5R‘5Í‚ÒE)”›’S²ö¢µ´S°Nû׬Ûmio°Óï¼ã¤‹-ú¹€€/ŸÿcÓcâ?ÿöo–Ï~ö³xÛÛÞ†ññ'U3žq\ð+6ìyØ©÷3ÁÆm³ùšD¶2‚ #£•' àhËÁA´9l’nÞBÚêT*G'œq0½Í7\÷Í—ì°»¼÷oZ4oÞ¼ŸIøÌ™gÅž/]mGþK<ÿüóñÎw¾fÏ:D\síuSý{\­q™d[‚àp´5ÉL’-ª',ŽVáloJ¨-á@ œ3;¶´£Ð¼ ÍºÏ Ãéi[õ×÷ÜyIÕûÞõæ%O—÷<×±uëV|ðCÉßúïvwÃ…^ˆ·¾õ­Ïë\ë.ÿÞ/;â´‰Ñý”I™ˆÎJHuÉÌ…2b­ÌIƒ†ÄãûÓlæÔêŠíÛ¦&Ë]׬Ûg§%ý=~ïݧ,~®”¦qÏ=÷âSó·ù¡þ‘mذ6lxÞà|óÒË'ç¯Úï{s^¢äÓ’p–6 .åãß2g ïIcËcõî¼æë¯Ü}Ç%{üÞ8mñØØSðž÷¸ê»WëÊ+¿ƒ|èƒvã7â‘GÁqÇ÷¼Ï÷ëoٰב§=6ç¥nÕäé>3ÿYïÖ[QÕ3Ðà´éá‡zÿzÝŽl·öùÀ{ß½äé²äŸgœ÷Oÿ¬Áô~ï}¿Ã+®¸8òÈ#Ÿ÷ù.¸ðë[·{é!×¶g³¨Ð V`‘ .BªÑ!0§fP€u@È –»Ijå=öàû÷Ýô­ÃVï²Ý¾ïÿÝw/ý·FþâSŸÖ«Øk>ˆëÖ­ÃÎ;ïŒ}öÙçyŸ33qãí÷ܱçao¡ Y¤åÅhe玃Y»ï” p¥ul¹„”RDû˜¹ýé}c÷ÞtéQ{½h‡_øÃßýíÜŸU9æ9-[¶àãŸøóüïùu[±b.¸àì½÷ÞØ}÷Ý®ó~ùŸ/ش㾇_ëºÒÐŽ™hUºŽAh%OPÂÕZÜ Š"ïZÛº+\?ú×Ûæßë·_»ÿ^»¿âýï}ϲ+`àÎ ô©¿þt~ì#v3Ã9眃£Ž: +V¬ø¹Î;qˆÖ¯9ê°)%DJ"[×,•¡®I@‰¶´v›¶ÞÔ0)£ž?ºçöï/ܸþ»'ì÷²Ýü­ÿù¾¥Ï5Öx®ãŠ+¿“×ÝpƒÎøØŸú`0À™gž‰“O> .ü¹Ï}Îyç?ºûAÇÝ ¨+ú[B)B¤%Û $5PHOËÚ@k@iÃÍ×/zìžkÞøÊ—ï}èïüáÝp/Ô8ë‹g×±~ÏþËoÿ¦oݺ_ùÊWðö·¿½ÞÓ.P<ë155… ?~ìŽ}ö\<€”0´UØlëjp˶0I‘JÂrdjèD ,kTù½·_÷ÉÉŸ®?õU¯ø…]¶_±lb¬ßï¿©ÁÓZ+þôcg ñЃËÑGi=ô.ºè"œrÊ)O[;~®ãóÿxÞÆ~á˜K‹{QÀ0„RI0hЈ„…P` Gyïÿþò'T³'dï÷þpÑW?sþîlzÉÊe‹Wm¿lÉ®‡zðÊÕ«_ò‚\ùÃ<¢üéŸ ÿ¿ÿ×þ’%Kp÷Ýw㪫®Âi§öBœ°yóÜûÐÔmû”~ÒÌ(DBJ£ „”ÑuËêüR{L÷TVñŸ®{ì˜Dôö!ÛccQdï†o_°ç=ºöå{íñÒ×ûºÅÏ×ü~pÛíñÅsΫ|ÿŒ‘Äm·Ý†»îº Ç{ì üõß}î'K^þú¯/Cš %UÐDUªÒ8T¢Òm¨T%l¨ŒJ·!¡aöZ¢ŠbÚ¨H’TBÈŽ8þxï½w/þßñš_<`Íšcyísª[¬ûÆ·†·ßq‡Nÿ£?€k®¹ƒÁàçÁ7êG[ñÿ–ïØ£€B‰¤1@¥$èÚ†CH"R¦lí&ž´a’H?ù×ow:[¹‘  Öü a­¡/X´¤®Üã€õ÷lÜrë×Î?oÁŠí/Ý~û?Óô>óÙÏMõ˯¾í´\~ùåÃAô‚‚÷¹/þhCßx9À ¨’ ¤@€ ¥Â BÒª 0Z…)Œ^‘:™abÌ#¥D±H¡5_·3@E*è~ *v\õÒG÷}Ý;¾ôåoß|Î'ÿæïïž~Ê=  ø_§ÿñä!kêŸpüë.¾øb,_¾pÀ Î}÷ߟaÞM+À !RÙ®[í¯+²ÝÇè~@D*´†ƒydÖ„y„5íæfÒ ftš#elµ0jul#Hû¬~¤¿üÅ7Ÿÿ¥³¹pÂWì´råÌü¼qãCúèŸ±í¿½ï½óvÚi'ÀW¿úU¬Y³æY׎ŸëøÌYçÞ³zí‰WvÌ©ƒ@QIVˆ@pެ±VA†"‚Æj™áî•©ÔB";¥·¤¦ö ‘ìgûuúcƒ}:å[߸þÞóþò¯ÿîÁ`€›¾óðcöñ©Óÿ×Í›?>"gžy&Ö®]‹]wÝõßœ ?¼«n±%×J¨‚*¡ ¢"©œ&5òMŠÆ¦ö×Ùzgðèöwðœk>”Þš5¥è­ƒŒÆ’h SBí%Pœî‹bÁ©,ËÖ͛ƮÿÚßþò>{¼èÅ¿ñëïÚêù瞋7¿ùÍx!ª‹O7þì/>½þE‡¾å+ 2mÓg¬© «ˆJ°Žf2£UUT{U%ª¹ “ª UëùЊi–-3ˆ*B£×¢UƒU("Ñ~U@UD8œ·`Ñ”Í[¶þ]ï|Ç8lܸ¿ÿû¿R .»ì2¬[·wß}wK£_Àqó-·N×ù»ü Ѧgš ‰vÓJÔ¹à¤rff‹Œö8GÏ1k1ÙŽuz˜Vꚬ- ‰®±„‰¡ ³€m§¬íö’”°¤Ôõ¶òH«èÀe—]¦~ô£%ºÿçSó㋯»û{®©¥KŒ/Y¾xÞò½V¿xÙ!kîÿ<9ß…—\~çK?õî”rÆ Ac…]âUÕ¶U=E5†›ÆáU8¨ÍÄ B(¤Ë ¬´¶åTÂd€*Zßf¶·µi´>Bš eBf­SkÈÝ õ·gÞ?¶ÛÁ_9dåªmÛ*&Áî^¿à‚?ùË}vY±h—#=på¾ûìýœ±«¿wÍ”-[}E$*¨0³€0Ev`™Y¥‘ 9«Ñjd £‡Áª¨jô*ªV(œ F Y³ª2´¶Þ̶^‘d¨Ò­ [w-R΂Ì ™™R)¤k‹‘­p{ñºuqä‘GüÕßy/vXsÞòw›d0rÔq¿ãn«Ýi·—^%$Ïÿ—+wüÊE—®9`ÍËv?öµG/|6û7.¿úÿíuÔ[ï“”€E˹™Hs«H…: Š—Ñ|Ž‡ŠªŠUKÔÈa<@ÅŠbƒÆ ÎeD;<Ù6äÑY1ÉÚvcÑMTH ±mÜiÑ72‘5Hâ~¤c9†Ÿüôgî±÷ÿŠ_2©ÖÈI¥F­ÀìZê ö|Åa÷@yïÝÜ=ñþüÅ!¯\³úe'wÌâ§3¿Ë¾}Å–ù;ï÷MÄҡ,‘BÙùTSc F… j@(T3àTQÕéÕ¨š´ZÆJÍ¡ªŸòî?ØÎ‘ˆ^[«ª,#Pغ߭ dOb+Å(Q]».%Œ® ·|w·­\±÷ ðÕ‹ÖÝc;íÿ÷+V­Þ0aLB‘4fÛ‡lKp 2æ/Z2½ãêýÖÿd núç/}¡ ¦¶.Úã%/yÒªÀgÏ>ÿÚ=|íµ$ÃŒ5¡ Ya•T¥¡›î­sÆ¢U EÍOgÃ01$EU s ?ù¿³tXÀž÷hmdsA*Éffmw\h\Eëºàa¡»nþÞª-üxïŸl|ä>í°æÓ;¬Úc“²•3¡àid¦$I³€”ðîØ€ 9Á’©•«÷¿ýžÛn¼äÂó{–ÃíV­Úµ_»hÝ£S‹w?kþ’“ÖM逯J h¨”U)»Ù9à +ÅÊD g-hc.8…^“ª…½J³š¦ê'ýö,v8†1˜R´-`™m·]Ï‚ÌÛff"Ešl+tmøþw^ôoc×½ŽúÕ3vØmõ&›S¥ƒ!ÉV˜2²m!P&Ì¢96V‡éj1Æ€ –n7¹âEkn½éwÝrÙ%_›X4bÙ%W~ﻫ_ñêëͬ AC¨ „Ѫ"‚´J²ÒYGÓ9 ¬‚ w¯#«‰1gP§Âe¡Ìàù7Oî:ÈA±dÓmº–ªî±jQ·¡7¥õ$v|»­ÖšÃÝ»öò¯íºý®»oÝe÷=·Z«ˆ[‡b›¹4ÛI‘èÚÃÍÀL>n*»•)ƒ(©5©ABèúo|ée/Úwí]KwÚir´™—B¦ÐmªkyUë•eÈ.ÍH QCáô S$UŠÂ^MËÚvBg@™äç®Þ´lñ¼á¼Á¤—¡e¬Œ{U-}§+é¡Zfv=ÛœFóìúªY o]ô颛‘&…‰4m ﲸ䶇+[ÛG&Äd‚TèÙd; ª•g’mc¯³¥J´¶Ë9;€ =B-ùmw–ZMíy(ʘê fëUÖ©öêü‰þ`ë­>èûïòáéí÷œƤMô‹{. 0€ÅD™b´%0óæw¨”³…žmOœÉ5¿Óv(Ó=…T« ·›=‚6ã¤##SÒLÝ@´=@ CÙ™U…õS ÙÈ9#2fV ºÕˆ¢W'*¥Jz…!" …•ªZÃjFö½*-¢ŽÏ[òð/¶ïð7ת·K>¸ljlAätïj·=|†AI‡×å$:‰Šp±˜,2Ü:!eÛÐÛ·-á˜9kf-Îvd&G+š&S[Ìk»ò$h´^ªm‹žmBJ¾•æIDAT#Zþœ}ó E²˜"ÈÖŽÚ"ã^(†¦@ôZÄ ØTô¬W§†}¯ zó6½n?næ,¿ÿù…ëÇv\¾ré §ËÄH’¢°S]hº³@UO벺­&ZÛðŒêB“¤˜hf6ê ”Œ&MxRThpµ¢ Ëº…?©IT̈œ˜2åICªV•^ËÄ-•‘H˜s˜ìÀ©Ù XjS_èY¿Â30Ì( –o9qOn]Çã.ì³—j|»å[cHŸÎé‚0G4P¼Lô Q}ÐivÌj®n‡²Z«"•Ɯބ²Ëó ÀhÔù¤ýª]T~GmGµÎóN·#DÍêwD·ÉÎÔ„M˜JZ‰šÃìY‰&QÑåY#ö†(Ùd)Ò';xÙ¦¹×ñ¤ ;÷;š(ó·,ÔpÊÑk’8³lΜ£€J£aºÔë5Pr®ÈID·Ëp®nè¥-®Ì|¹;³zG殨sHò¶ú+IŠN"çñ 0Ù‰›X§×1Riº@Þkr-[›žJƘ×ñm ¦Ž;›ñUª§Lx.\¯±xlóÂ3Ǯޔo«M"§Ìˆ*ÍÕš«›«4#l2G7ˆ3Z÷VDcÓ“Ä_*àÞštFr8îMuJs`†UôYí ÂX KdÍX½¨1cÞ ¸bÊkšÐÒ‚m'ïí5ý,€€æ¸w›Ø´pòÑm¥.Y`#‘¥žÓ¦ÔãÕ§ÒšâÔ¬ÐìµǨVJADm‚K3²8œÃ$uÀ ^ ”ϨPIPÏK6& gT¨j§Be©´‚¬Ñé…rÌ{1 $òî˽÷!D @ @ ï³1x·à}´`ÁW¥R™ØÑÑ!&N€þ¬X±bëìÙ³=úÇØ±c»oݺ5ïF½>rvvf³ÙìÒ‚‚¹««+vïÞ½ …†wÃÞiÆÆÆÓÝÜÜ~ ¯‘H$púôéöM›6a‰‚‚‚ÊBãðnã;ÉÜÜÜŠF£<}út†a€aŠwíÚÕƒaÔ××÷,[¶Œ‰w;ß9–––«===3¸\®P¥RÀ³gϰM›6IcbbºáŸB„1öj‰““í‡~(¨¨¨A?yyyR777YNNNOïkùùùâ/¿üÒ ïF¿ Æ­_¿>Íf—ðù|¬ð*• ¢¢¢ž3™Ìžªª*EïëJ¥<<<Òñnø[D"M£R©‘‡ª‰Dð*‰D¢b0¢ýû÷+…B¡ªÿ{IIIM¦¦¦fx÷á­4sæÌÙ^^^I¿þúk“\.-x€²²2™››[[hh¨ª§§ç¥÷:::`ýúõ¿àÝ·Ž#“ÉLÏÌÌ|Þ;°ª“œœ,ؽ{·4!!Aí‡DFFBggçõ÷÷/EïÛÝ¥Íb&“™~îܹV…B1xJP©T'Љ‰i¯¨¨€øøxP*•C>¾ªªªÓÞÞ~3Þyè ™L^Ïb±.·8õÚÚÚà»ï¾•••aW®\K—. » Ÿ«xg¢†NNNÛY,Öï555ÃXÕ¹{÷n×–-[DR©ÒÓÓáîÝ»Ã.ƒËå>·´´\€w8º4qÆ ƒƒƒ«š››G4°ªÃápÄh“Ëå<oØe`›7oNÆ; 022úôÛo¿Ž‹‹«Î`8˜®®.صk— 77W. <<ÚÚFv%‹m ‘HÆxg¥UVVV‹h4ÚY‡Ó¬ÉÀªNmmm·»»»P @UUÄÄÄ k°íO$Áš5kBðÎKkÖ±X¬Ë¹¹¹¬ê\¼xQüý÷ßK ##C£òöíÛ÷½[L V¬XAó÷÷/¬®®ÚÌØ0aAAA‚´´4ÀÅ‹¡¸¸X£2>|('“ÉÞx‡§ ’““Ó€€€{Ož<Ñîu¦ŸÆÆF…‡‡‡Çã†a uuu—Ë`0òðpDŒŒŒ>Ù¼ysL\\ܤR©"Ø7Ú¼½½ÅJ¥„B!„‡‡ƒX,ָܼ¼<‘#ÞY‹¹¹¹5NOäp8M6袓FT*„…… Ž?.xøð!DGGƒ6ê}±Å$ ï<‡ÌÎÎnͶmÛ²322„÷~ŠF£ +**”………pöìY­•êÔ©F333S¼sŒÁòåË·TUUéd`UçÎ;îîîâîî¿vž;wnܸ¡µò;::`Æ Ñx‡û&{±k¬´±±Qg«:ñññ¢6€¿æò¡¦¦F«uW"„&àòkŒ§S©ÔøàààZm rÃÑÑѾ¾¾Â¢¢"@{{;„‡‡Ckk«VëáóùØÊ•+wáõK>ûì3ËÛ±_ݦÕÕÕ]nnnb‰D  ½— mÚ±cÇh´ìl¶µµ]öbq[0œÅmmúí·ß$l6»ïsII $''뤮[·nµÛÙÙ­Å;wGGG¯;wþQRR2ò%' ÉårØ»w¯ ++«o::;;®_¿®“úT*xyy]Â3øqk×® zm;¶¾ñx¼ÑÓ§OûÂ9yò$|¸BÝvl}ËÌÌlß±c‡¤÷o©T ÐÒÒ¢³:e2P©Ôx½ß;öPwé’B¡€ƒ>?sæLße¯©© "##A“Å÷¡ «EMÒKðsçÎ]:”íØúÔÚÚªðññ644ô5¨¼¼N:ºncKK‹rõêÕût»Áüùó= FÎ`Û±õ­  @Êd2Åýd²³³Ëåê¥~ÿÛ¡tþ o333×éÓ§·#„Є  ¦NjD"‘Œ§NjD&“?µ´´Ôi#^(**JD"‘ ýüü&ö¾–’’‚¬¬¬Ð‚º_û.//—mß¾}[YYÙWöc-,,V}ýõ׿ìÛ·/÷Ì™3Mº¾æŠÅbN–——÷ýÛ÷.˜óù|ÖÝN¿Œgð™B¡P°Ùìßuq¹*++ë¤ÓéÂþÏa577{wš¦.]ºô|Μ9óñû¬­­—ÐéôóW¯^}®N'$$ˆBCC%ý_«¬¬„'NŒxÁ|$º»»á›o¾IÂ;ß!³´´´ÙºuëùÂÂÂÍÀuvvÂÎ;…/ýÀËËËÓÛ`Û_LLLýĉðÎuج­­É¾¾¾×êêê†üᦦ¦‡F£‰z'Òz¥¤¤h¼`>"‘HµnݺCxg©GGGzhhhÕ@ÏÓöJMM•°Ùì—~^wwwÃÑ£GáÑ£GºÌy@{ö칋w†Ú0aãÆÇrss_›Ç0 ~úé'aFFÆKgH @XX¼úmЗššš.2™ì…wpZµpáÂ¥¾¾¾Å­­­J>Ÿ¯ ÑhÂ'Ož¼Ôùºº:8~ü8h{Üpx{{ÿ ï¼tåC …r8((è ‹Å½:}ŸŸ©©©8Åþ—ëׯ‹æÎ»ï tŠF£¥½Úñ .@QQ™÷Q(°eË–T¼rÑÛ£4†††/=¬|ìØ1044#‰ÇC …a|>_4mÚ4ɬY³Œ&Mš¤Û‰È¤¤¤Çùùù{uZÉàò,Sgg'?~¼ŠÁ`ôÍ1ñxY¼xñ?÷ìÙ““••%ÐÆ€ààà?BãõÑÜ1ŒT€žžˆˆˆè»---m£P(‡‡SÖ”)SL¨Tjô‘#Gþäóù#ºujhhè!“É;tÕßQ§÷p8œ®úúz@^^ž`åÊ•û½½=ÅbåkrÐÏÏïw4Z¶˜èƒÁHU©T°ÿþN€¬¬¬fgggm•ÿÅ_8øøøœÏÌÌ|6ØJYQQQ›Ý*mÕýV`0©™™™7oÞìJLLü¯½½ý]Ô3cÆ sOOÏ”ŒŒŒu'B¥R»»;®[LpÁd2ÓüýýÛ£££ÿmkk»X×õ™šššmݺ5éüùóÍýO‡Ãi211ù\×õ:K–,¹nkkÛdccc©Ïz{O‡Ãy*•JJ¥Æé³þQÃÄÄ$ÈÄÄäSëÿü«¯¾:ƒ"áÕ@ @ @ áýó?ÎÅAB‘²0IEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/paperwork_halo.svg000066400000000000000000000100101456262201400264330ustar00rootroot00000000000000 image/svg+xml paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/data/work.openpaper.Paperwork.appdata.xml000066400000000000000000000143331456262201400317670ustar00rootroot00000000000000 work.openpaper.Paperwork.desktop CC0-1.0 Paperwork Personal document manager Gestionnaire de documents personnels

Sorting documents is a machine's job. Paperwork is an easy-to-use application which allows you to find in all your documents when you need them. Type a few keywords in the search bar and the list of papers will shrink to only the relevant content.

Trier les documents est un travail de machine. Paperwork est une application qui vous permet de trouver tout vos documents, quand vous en avez besoin. Tapez quelques mots-clés et la liste des papiers se réduira au contenu pertinent.

This is where the magic happens: Paperwork uses automatically optical character recognition (OCR) to convert your papers into searchable documents.

Là où la magie se produit : Paperwork utilise automatiquement la reconnaissance optique de caractères (ROC) pour convertir vos papiers en documents cherchables.

Main features are:

Les principales fonctionnalités sont :

  • Scanner support
  • Support des scanners
  • PDF support
  • Support des PDFs
  • Automatic detection of page orientation
  • Détection automatique de l'orientation des pages
  • OCR
  • ROC
  • Document labels
  • Labels pour trier les documents
  • Automatic guessing of the labels to apply on new documents
  • Labelisation semi-automatique des documents
  • Search
  • Recherche
  • Keyword suggestions
  • Suggestions de mots-clés
  • Quick edit of scans
  • Édition rapides des pages
Office Scanning OCR Archiving GNOME https://www.openpaper.work/ https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues https://gitlab.gnome.org/World/OpenPaperwork/paperwork/#readme https://www.patreon.com/openpaper work.openpaper.Paperwork.desktop paperwork paperwork application/pdf image/jpeg image/png image/x-ms-bmp GPL-3.0+ Openpaper.work Paperwork search suggestion https://gitlab.gnome.org/World/OpenPaperwork/paperwork-screenshots/-/raw/master/2.1/paperwork_search_suggestion.png Paperwork document view https://gitlab.gnome.org/World/OpenPaperwork/paperwork-screenshots/-/raw/master/2.1/paperwork_doc_grid.png Paperwork new document https://gitlab.gnome.org/World/OpenPaperwork/paperwork-screenshots/-/raw/master/2.1/paperwork_doc_new.png Paperwork doc properties https://gitlab.gnome.org/World/OpenPaperwork/paperwork-screenshots/-/raw/master/2.1/paperwork_doc_properties.png Paperwork settings https://gitlab.gnome.org/World/OpenPaperwork/paperwork-screenshots/-/raw/master/2.1/paperwork_settings.png Paperwork dark https://gitlab.gnome.org/World/OpenPaperwork/paperwork-screenshots/-/raw/master/2.1/paperwork_dark.png paperwork paperwork_backend paperwork_gtk openpaperwork_core openpaperwork_gtk paperwork_shell jflesch@openpaper.work
paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/doc_selection.py000066400000000000000000000020141456262201400251550ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): # so we can report an accurate document count PRIORITY = 1000 def __init__(self): super().__init__() self.selection = set() def get_interfaces(self): return ['doc_selection'] def doc_selection_reset(self): self.selection = set() def doc_selection_add(self, doc_id, doc_url): self.selection.add((doc_id, doc_url)) def doc_selection_remove(self, doc_id, doc_url): try: self.selection.remove((doc_id, doc_url)) except KeyError: pass def doc_selection_get(self, out: set): out.update(self.selection) def doc_selection_len(self): nb_docs = len(self.selection) if nb_docs <= 0: return None return nb_docs def doc_selection_in(self, doc_id, doc_url): if (doc_id, doc_url) in self.selection: return True return None paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/docimport.py000066400000000000000000000213761456262201400243570ustar00rootroot00000000000000import gettext import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps import paperwork_backend.docimport from . import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc_id = None self.windows = [] def get_interfaces(self): return [ 'chkdeps', 'doc_open', 'gtk_doc_import', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_dialog_single_entry', 'defaults': ['openpaperwork_gtk.dialogs.single_entry'], }, { 'interface': 'import', 'defaults': [ 'paperwork_backend.docimport.img', 'paperwork_backend.docimport.pdf', ], }, { 'interface': 'notifications', 'defaults': ['paperwork_gtk.notifications.dialog'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def doc_open(self, doc_id, doc_url): if self.core.call_success("is_doc", doc_url) is None: # New document --> no need to track this doc id. # Importer will create a new document in time self.active_doc_id = None return self.active_doc_id = doc_id def doc_close(self): self.active_doc_id = None def _show_no_importer(self, file_uris): msg = ( _("Don't know how to import '%s'. Sorry.") % (file_uris) ) flags = ( Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT ) dialog = Gtk.MessageDialog( transient_for=self.windows[-1], flags=flags, message_type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK, text=msg ) dialog.connect("response", lambda dialog, response: dialog.destroy()) dialog.show_all() def _request_password(self, importer, file_import): self.core.call_success( "gtk_show_dialog_single_entry", self, _("PDF password"), "", importer=importer, file_import=file_import ) def on_dialog_single_entry_reply( self, origin, reply, password, *args, **kwargs): if origin != self: # Not ours return if not reply: # User cancelled return importer = kwargs['importer'] file_import = kwargs['file_import'] self._do_import(importer, file_import, data={'password': password}) return True def _show_result_no_doc(self): msg = _("No new document to import found") flags = ( Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT ) dialog = Gtk.MessageDialog( transient_for=self.windows[-1], flags=flags, message_type=Gtk.MessageType.WARNING, buttons=Gtk.ButtonsType.OK, text=msg ) dialog.connect( "response", lambda dialog, response: dialog.destroy() ) dialog.show_all() def _show_result_doc(self, doc_id): doc_url = self.core.call_success("doc_id_to_url", doc_id) assert doc_url is not None if self.active_doc_id != doc_id: self.core.call_all("doc_open", doc_id, doc_url) nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages <= 0: # empty PDF ? LOGGER.warning("Document import %s, but no page in it ?!", doc_id) return self.core.call_success( "mainloop_schedule", self.core.call_all, "doc_goto_page", nb_pages - 1 ) def _delete_files(self, file_uris): LOGGER.info("Moving imported file(s) to trash ...") for file_uri in file_uris: LOGGER.info("Moving %s to trash ...", file_uri) self.core.call_success("fs_unlink", file_uri) notification = self.core.call_success( "get_notification_builder", gettext.npgettext( "import dialog", "Imported file deleted", "Imported files deleted", len(file_uris) ), ) if notification is None: return notification.set_icon("edit-delete").show() def _show_result_notification(self, file_import): msg = _("Imported:\n") for (k, v) in file_import.stats.items(): msg += ("- {}: {}\n".format(k, v)) msg = msg.strip() notification = self.core.call_success( "get_notification_builder", _("Import successful"), need_actions=True ) if notification is not None: notification.set_message( msg ).set_icon( "document-new" ).add_action( "delete", _("Delete imported files"), self._delete_files, file_import.imported_files ).show() def _show_result(self, file_import): doc_id = None if len(file_import.upd_doc_ids) > 0: doc_id = list(file_import.upd_doc_ids)[0] if len(file_import.new_doc_ids) > 0: doc_id = list(file_import.new_doc_ids)[0] if doc_id is None: self._show_result_no_doc() return self._show_result_doc(doc_id) self._show_result_notification(file_import) def _reload_docs(self, file_import): for doc_id in file_import.upd_doc_ids: doc_url = self.core.call_success("doc_id_to_url", doc_id) self.core.call_all("doc_reload", doc_id, doc_url) def _add_to_recent(self, file_uris): for file_uri in file_uris: if self.core.call_success("fs_isdir", file_uri) is None: # If the user imported a file, assume they won't import it # twice but they may import again other files from the same # directory file_uri = self.core.call_success("fs_dirname", file_uri) LOGGER.info("Adding %s to recently used files", file_uri) Gtk.RecentManager().add_item(file_uri) def _log_result(self, file_import): LOGGER.info("Import result:") LOGGER.info("- Imported files: %s", file_import.imported_files) LOGGER.info("- Non-imported files: %s", file_import.ignored_files) LOGGER.info("- New documents: %s", file_import.new_doc_ids) LOGGER.info("- Updated documents: %s", file_import.upd_doc_ids) for (k, v) in file_import.stats.items(): LOGGER.info("- %s: %s", k, v) def _do_import(self, importer, file_import, data=None): promise = importer.get_import_promise(data) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self._log_result, file_import) promise = promise.then(self._show_result, file_import) promise = promise.then(self._reload_docs, file_import) self.core.call_success("transaction_schedule", promise) def gtk_doc_import(self, file_urls): LOGGER.info("Importing: %s", file_urls) file_import = paperwork_backend.docimport.FileImport( file_urls, self.active_doc_id ) importers = [] self.core.call_all("get_importer", importers, file_import) if len(importers) <= 0: self._show_no_importer(file_urls) return # TODO(Jflesch): Should ask the user what must be done if many # importers are possible. importer = importers[0] self._add_to_recent(file_urls) required = set() for (k, v) in importer.get_required_data().items(): required.update(v) LOGGER.info( "Required data to import %s: %s", file_urls, required ) if "password" in required: self._request_password(importer, file_import) else: self._do_import(importer, file_import) return True paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/drawer/000077500000000000000000000000001456262201400232605ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/drawer/__init__.py000066400000000000000000000000001456262201400253570ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/drawer/calibration.py000066400000000000000000000101541456262201400261220ustar00rootroot00000000000000""" Ensure calibration is displayed when a scan is running. """ import logging import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Drawer(object): def __init__(self, core, drawing_area, read_only=False): self.core = core self.drawing_area = drawing_area self.content_full_size = None self.scan_id = None self.active = False self.drawer = None self.read_only = read_only def _get_frame(self): return self.core.call_success("config_get", "scanner_calibration") def _set_frame(self, frame): self.core.call_all("config_put", "scanner_calibration", frame) def set_content_full_size(self, size): self.content_full_size = size def start(self): if self.active: self.stop() self.core.call_all( "config_add_observer", "scanner_calibration", self.request_redraw ) self.drawer = self.core.call_success( "draw_frame_start", self.drawing_area, self.content_full_size, self._get_frame, self._set_frame if not self.read_only else None ) self.active = True def request_redraw(self, *args, **kwargs): if self.drawer is None: return self.drawer.request_redraw() def stop(self): if not self.active: return self.core.call_all("draw_frame_stop", self.drawing_area) self.core.call_all( "config_remove_observer", "scanner_calibration", self.request_redraw ) self.active = False class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.drawers = {} # drawing_area --> drawer self.scan_id_to_drawers = {} # int --> drawer def get_interfaces(self): return [ 'gtk_drawer_calibration', 'gtk_drawer_scan', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_drawer_frame', 'defaults': ['paperwork_gtk.drawer.frame'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, { 'interface': 'scanner_calibration', 'defaults': [ 'paperwork_backend.guesswork.cropping.calibration' ] }, ] def draw_calibration_start( self, drawing_area, content_full_size, read_only=False): drawer = Drawer(self.core, drawing_area, read_only) drawer.set_content_full_size(content_full_size) drawer.start() self.drawers[drawing_area] = drawer def draw_calibration_stop(self, drawing_area): if drawing_area not in self.drawers: return self.drawers.pop(drawing_area).stop() def draw_scan_start(self, drawing_area, scan_id=None): if drawing_area in self.drawers: drawer = self.drawers[drawing_area] elif scan_id is not None and scan_id in self.scan_id_to_drawers: drawer = self.scan_id_to_drawers[scan_id] self.drawers.pop(drawer.drawing_area, None) drawer.stop() drawer.drawing_area = drawing_area drawer.start() else: drawer = Drawer(self.core, drawing_area, read_only=True) drawer.scan_id = scan_id self.scan_id_to_drawers[scan_id] = drawer self.drawers[drawing_area] = drawer def draw_scan_stop(self, drawing_area): if drawing_area in self.drawers: self.drawers.pop(drawing_area).stop() def on_scan_page_start(self, scan_id, page_nb, scan_params): for drawer in self.drawers.values(): if drawer.scan_id is None or scan_id == drawer.scan_id: drawer.set_content_full_size( (scan_params.get_width(), scan_params.get_height()) ) drawer.start() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/drawer/frame.py000066400000000000000000000243241456262201400247310ustar00rootroot00000000000000""" Draws a frame on a GtkDrawingArea. This frame may or may not be resizable. This is usually used for the scanner calibration dialog or the page image cropping. """ import logging import math try: import gi gi.require_version('Gdk', '3.0') from gi.repository import Gdk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Drawer(object): HANDLE_RADIUS = 10 HANDLE_DEFAULT_COLOR = (0.0, 0.25, 1.0, 0.5) HANDLE_HOVER_COLOR = (0.1, 0.75, 0.1, 1.0) HANDLE_SELECTED_COLOR = (0.75, 0.1, 0.1, 1.0) HANDLE_MIN_DIST = 50 RECTANGLE_COLOR = (0.0, 0.25, 1.0, 1.0) OUTTER_COLOR = (0.0, 0.25, 1.0, 0.25) FRAME_CORNERS = [ (0, 1), (0, 3), (2, 1), (2, 3), ] def __init__( self, core, drawing_area, content_full_size, get_frame_cb, set_frame_cb=None): """ Arguments: - drawing_area: the drawing area on which the frame must be represented - content_full_size: the drawing area has its own size, smaller than the actual scan or image. We need to know the actual size of the content, so we can figure out at which scale the content and the frame are to represented. - get_frame_cb : callback returning the frame to display relative to content_full_size. A callback is provided so we can always have an up-to-date value (for instance coming from the configuration). """ self.core = core if drawing_area.get_window() is None: drawing_area.connect("realize", self.on_realize) else: self.on_realize(drawing_area) self.drawing_area = drawing_area self.get_frame_cb = get_frame_cb self.set_frame_cb = set_frame_cb self.content_full_size = content_full_size self.active_handle = None self.selected_handle = None self.draw_connect_id = drawing_area.connect("draw", self.on_draw) self.motion_connect_id = None self.press_connect_id = None self.release_connect_id = None if self.set_frame_cb: self.motion_connect_id = drawing_area.connect( "motion-notify-event", self.on_motion ) self.press_connect_id = drawing_area.connect( "button-press-event", self.on_pressed ) self.release_connect_id = drawing_area.connect( "button-release-event", self.on_released ) def stop(self): if self.draw_connect_id is not None: self.drawing_area.disconnect(self.draw_connect_id) if self.motion_connect_id is not None: self.drawing_area.disconnect(self.motion_connect_id) if self.press_connect_id is not None: self.drawing_area.disconnect(self.press_connect_id) if self.release_connect_id is not None: self.drawing_area.disconnect(self.release_connect_id) self.draw_connect_id = None self.motion_connect_id = None self.press_connect_id = None self.release_connect_id = None def request_redraw(self): self.drawing_area.queue_draw() def _get_factor(self): widget_height = self.drawing_area.get_allocated_height() widget_width = self.drawing_area.get_allocated_width() factor_w = self.content_full_size[0] / widget_width factor_h = self.content_full_size[1] / widget_height factor = max(factor_w, factor_h) return factor def _get_frame(self): factor = self._get_factor() frame = self.get_frame_cb() if frame is None: frame = ( 0, 0, self.content_full_size[0], self.content_full_size[1] ) return ( frame[0] / factor, frame[1] / factor, frame[2] / factor, frame[3] / factor, ) def _get_closest_handle(self, x, y): frame = self._get_frame() handle_dists = [ ( math.hypot(frame[corner_x] - x, frame[corner_y] - y), (corner_x, corner_y) ) for (corner_x, corner_y) in self.FRAME_CORNERS ] handle = min(handle_dists) if handle[0] > self.HANDLE_MIN_DIST: return None return handle[1] def on_realize(self, drawing_area, *args, **kwargs): mask = ( Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK ) drawing_area.add_events(mask) drawing_area.get_window().set_events( drawing_area.get_window().get_events() | mask ) def on_motion(self, drawing_area, event): if self.selected_handle is None: active_handle = self._get_closest_handle(event.x, event.y) if active_handle != self.active_handle: self.request_redraw() self.active_handle = active_handle else: assert self.set_frame_cb is not None factor = self._get_factor() frame = self.get_frame_cb() if frame is not None: frame = list(frame) else: frame = [ 0, 0, self.content_full_size[0], self.content_full_size[1] ] x = event.x * factor y = event.y * factor frame[self.selected_handle[0]] = x frame[self.selected_handle[1]] = y frame = ( max(0, min(frame[0], frame[2])), max(0, min(frame[1], frame[3])), min(self.content_full_size[0], max(frame[0], frame[2])), min(self.content_full_size[1], max(frame[1], frame[3])), ) self.set_frame_cb(frame) self.request_redraw() def on_pressed(self, drawing_area, event): self.selected_handle = self._get_closest_handle(event.x, event.y) self.request_redraw() def on_released(self, drawing_area, event): self.selected_handle = None self.request_redraw() def on_draw(self, drawing_area, cairo_ctx): frame = self._get_frame() widget_height = self.drawing_area.get_allocated_height() widget_width = self.drawing_area.get_allocated_width() # outter cairo_ctx.save() try: color = self.OUTTER_COLOR cairo_ctx.set_source_rgba(color[0], color[1], color[2], color[3]) outters = [ (0, 0, widget_width, frame[1]), (0, frame[3], widget_width, widget_height - frame[3]), (0, frame[1], frame[0], frame[3] - frame[1]), ( frame[2], frame[1], widget_width - frame[2], frame[3] - frame[1] ), ] for (x, y, w, h) in outters: cairo_ctx.rectangle(x, y, w, h) cairo_ctx.fill() finally: cairo_ctx.restore() (x, y, w, h) = ( frame[0], frame[1], frame[2] - frame[0], frame[3] - frame[1] ) # rectangle cairo_ctx.save() try: color = self.RECTANGLE_COLOR cairo_ctx.set_source_rgba(color[0], color[1], color[2], color[3]) cairo_ctx.set_line_width(1.0) cairo_ctx.rectangle(x, y, w, h) cairo_ctx.stroke() finally: cairo_ctx.restore() if self.set_frame_cb is None: return # handles cairo_ctx.save() try: for corner in self.FRAME_CORNERS: if self.selected_handle == corner: color = self.HANDLE_SELECTED_COLOR elif self.active_handle == corner: color = self.HANDLE_HOVER_COLOR else: color = self.HANDLE_DEFAULT_COLOR cairo_ctx.set_source_rgba( color[0], color[1], color[2], color[3] ) cairo_ctx.arc( frame[corner[0]], frame[corner[1]], self.HANDLE_RADIUS, 0., 2 * math.pi ) cairo_ctx.fill() finally: cairo_ctx.restore() class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() # drawing area --> Drawer self.active_drawers = {} def get_interfaces(self): return [ 'chkdeps', 'gtk_drawer_frame', ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def draw_frame_start( self, drawing_area, content_full_size, get_frame_cb, set_frame_cb=None): drawer = Drawer( self.core, drawing_area, content_full_size, get_frame_cb, set_frame_cb ) self.active_drawers[drawing_area] = drawer return drawer def draw_frame_stop(self, drawing_area): if drawing_area not in self.active_drawers: return drawer = self.active_drawers.pop(drawing_area) drawer.stop() return drawer if __name__ == "__main__": import sys import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk core = openpaperwork_core.Core() core._load_module("test", sys.modules[__name__]) core.init() window = Gtk.Window() window.set_size_request(600, 600) box = Gtk.Box.new(Gtk.Orientation.HORIZONTAL, 20) window.add(box) drawing_area_a = Gtk.DrawingArea() box.pack_start(drawing_area_a, expand=True, fill=True, padding=0) drawing_area_b = Gtk.DrawingArea() box.pack_start(drawing_area_b, expand=True, fill=True, padding=0) frame = (30, 50, 100, 110) def get_frame(): return frame def set_frame(f): global frame frame = f drawing_area_a.queue_draw() drawing_area_b.queue_draw() core.call_success( "draw_frame_start", drawing_area_a, (200, 300), get_frame ) core.call_success( "draw_frame_start", drawing_area_b, (200, 300), get_frame, set_frame ) window.show_all() Gtk.main() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/flatpak.py000066400000000000000000000017451456262201400237770ustar00rootroot00000000000000import logging import os import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def get_deps(self): return [ { 'interface': 'flatpak', 'defaults': ['openpaperwork_core.flatpak'], }, ] def gtk_init(self, *args, **kwargs): # Flatpak workaround: make sure the fonts will be rendered correctly in # PDF files. Otherwise, sometime we get a weird error in the console: # "some font thing has failed" and no text is rendered when rendering # PDF pages. if self.core.call_success("is_in_flatpak"): LOGGER.info("Running `fc-cache -f` ...") r = os.system("fc-cache -f") r = os.waitstatus_to_exitcode(r) if r == 0: LOGGER.info("`fc-cache -f` has succeded") else: LOGGER.warning("`fc-cache -f` has failed: r=%d", r) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/gesture/000077500000000000000000000000001456262201400234525ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/gesture/__init__.py000066400000000000000000000000001456262201400255510ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/gesture/drag_and_drop.py000066400000000000000000000123361456262201400266140ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') from gi.repository import Gdk from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = (None, None) self.updated = set() self.promise = None def get_interfaces(self): return [ 'doc_open', 'gtk_drag_and_drop' ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) self.promise = openpaperwork_core.promise.Promise(self.core) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def _parse_paperwork_uri(self, uri): infos = uri.split("#", 1)[1] infos = infos.split("&") infos = (i.split("=", 1) for i in infos) infos = {k: v for (k, v) in infos} return (infos['doc_id'], int(infos['page'])) def doc_close(self): self.active_doc = (None, None) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def drag_and_drop_page_enable(self, widget): """ Arguments: widget - GTK widget on which page drag'n'drop must be enabled. When a drop is received, it will call the method 'drag_and_drop_get_destination(widget, x, y)'. The plugin to whom the widget belongs should reply with (doc_id, page_idx). """ widget.drag_dest_set(Gtk.DestDefaults.ALL, [], Gdk.DragAction.MOVE) targets = Gtk.TargetList.new([]) targets.add_uri_targets(0) widget.drag_dest_set_target_list(targets) widget.connect("drag-data-received", self._on_drag_data_received) def _on_drag_data_received( self, widget, drag_context, x, y, selection_data, info, time): uris = selection_data.get_uris() LOGGER.info( "drag_data_received(%s, %d, %d, %s, %s)", widget, x, y, uris, info ) dst = self.core.call_success( "drag_and_drop_get_destination", widget, x, y ) if dst is None: LOGGER.error("Nobody accepted a drop on %s (%d, %d)", widget, x, y) return (dst_doc_id, dst_doc_url, dst_page_idx) = dst for uri in reversed(uris): LOGGER.info("Drop: URI: %s", uri) self.core.call_all( "drag_and_drop_page_add", uri, dst_doc_id, dst_doc_url, dst_page_idx ) self.core.call_all("drag_and_drop_apply") def drag_and_drop_page_add( self, src_uri, dst_doc_id, dst_doc_url, dst_page_idx): LOGGER.info("Drop: %s --> %s p%d", src_uri, dst_doc_id, dst_page_idx) if "doc_id=" not in src_uri or "page=" not in src_uri: LOGGER.info("Drop: Import of %s", src_uri) # TODO(Jflesch): Should import to the target document (drop) # instead of the currently-opened document self.core.call_all("gtk_doc_import", [src_uri]) return else: # moving page inside the current document (src_doc_id, src_page_idx) = self._parse_paperwork_uri(src_uri) src_doc_url = self.core.call_success("doc_id_to_url", src_doc_id) assert src_doc_url is not None if src_doc_id == dst_doc_id and src_page_idx < dst_page_idx: dst_page_idx -= 1 dst_page_idx = max(dst_page_idx, 0) LOGGER.info( "Drop: %s p%d --> %s p%d", src_doc_id, src_page_idx, dst_doc_id, dst_page_idx ) if src_doc_id == dst_doc_id and src_page_idx == dst_page_idx: return self.promise = self.promise.then( self.core.call_all, "page_move_by_url", src_doc_url, src_page_idx, dst_doc_url, dst_page_idx ) self.promise = self.promise.then(lambda *args, **kwargs: None) for doc in ((src_doc_id, src_doc_url), (dst_doc_id, dst_doc_url)): self.promise = self.promise.then( self.core.call_all, "doc_reload", *doc ) self.promise = self.promise.then(lambda *args, **kwargs: None) self.updated.add(src_doc_id) self.updated.add(dst_doc_id) def drag_and_drop_apply(self): if len(self.updated) <= 0: return self.promise = self.promise.then(self.core.call_success( "transaction_simple_promise", [('upd', doc_id) for doc_id in self.updated] )) self.core.call_success("transaction_schedule", self.promise) self.updated = set() self.promise = openpaperwork_core.promise.Promise(self.core) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/gesture/zoom.py000066400000000000000000000046051456262201400250150ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Zoomer(object): def __init__(self, zoomable, adjustment): self.adjustment = adjustment self.gesture = Gtk.GestureZoom.new(zoomable) self.ref_adj_value = 1.0 self.ref_gesture_value = 1.0 self.gesture.set_propagation_phase(Gtk.PropagationPhase.CAPTURE) self.gesture.connect("update", self._on_gesture, adjustment) self.gesture.connect("end", self._update_refs) self.adjustment.connect("value-changed", self._update_refs) def _on_gesture(self, gesture, sequence, adjustment): scale = gesture.get_scale_delta() adj_scale = (self.ref_adj_value * scale / self.ref_gesture_value) LOGGER.debug("Zoom gesture: %f --> %f", scale, adj_scale) adjustment.set_value(adj_scale) def _update_refs(self, *args, **kwargs): self.ref_adj_value = self.adjustment.get_value() self.ref_gesture_value = self.gesture.get_scale_delta() LOGGER.debug("Ref: %f, %f", self.ref_adj_value, self.ref_gesture_value) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() # XXX(Jflesch): Looks like a GObject Introspection bug: if the # GtkGesture objects get garbage-collected, the gesture isn't detected # anymore. --> We need to keep a reference to those objects as long # as we need them. self.refs = {} def get_interfaces(self): return [ 'chkdeps', 'gtk_zoomable', ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_zoomable_widget_new(self, zoomable, adjustment): """ zoomable is the widget on which user can zoom. zoom gestures are not applied directly on the widget. They are applied on a GtkAdjustment. """ zoomer = Zoomer(zoomable, adjustment) self.core.call_all("on_objref_track", zoomer) self.refs[zoomable] = zoomer def on_zoomable_widget_destroy(self, zoomable, adjustment): if zoomable in self.refs: self.refs.pop(zoomable) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/000077500000000000000000000000001456262201400227245ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/Makefile000066400000000000000000000004601456262201400243640ustar00rootroot00000000000000all: data out/paperwork_%.png: data/paperwork.svg convert -background None $(CURDIR)/$< -resize $*x$* $(CURDIR)/$@ data: \ out/paperwork_16.png \ out/paperwork_32.png \ out/paperwork_48.png \ out/paperwork_64.png \ out/paperwork_128.png clean: rm -f $(CURDIR)/out/*.png .PHONY: all data clean paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/__init__.py000066400000000000000000000010361456262201400250350ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['icon'] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def icon_get_pixbuf(self, icon_name, size_px): file_name = "{}_{}.png".format(icon_name, size_px) return self.core.call_success( "gtk_load_pixbuf", "paperwork_gtk.icon.out", file_name ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/data/000077500000000000000000000000001456262201400236355ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/data/paperwork.svg000066400000000000000000000056651456262201400264040ustar00rootroot00000000000000 image/svg+xml paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/data/paperwork_halo.svg000066400000000000000000000100101456262201400273630ustar00rootroot00000000000000 image/svg+xml paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/out/000077500000000000000000000000001456262201400235335ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/icon/out/__init__.py000066400000000000000000000000001456262201400256320ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/keyboard_shortcut/000077500000000000000000000000001456262201400255275ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/keyboard_shortcut/__init__.py000066400000000000000000000000001456262201400276260ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/keyboard_shortcut/zoom.py000066400000000000000000000051151456262201400270670ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gdk', '3.0') from gi.repository import Gdk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Zoomer(object): ZOOM_INCREMENT = 0.02 def __init__(self, zoomable, adjustment): self.adjustment = adjustment if zoomable.get_window() is not None: self._enable_events(zoomable) else: zoomable.connect("realize", self._enable_events) zoomable.connect("scroll-event", self._on_scroll) def _enable_events(self, zoomable): zoomable.add_events(Gdk.EventMask.SCROLL_MASK) zoomable.get_window().set_events( zoomable.get_window().get_events() | Gdk.EventMask.SCROLL_MASK ) def _on_scroll(self, widget, event): if (event.state & Gdk.ModifierType.CONTROL_MASK): original = self.adjustment.get_value() delta = event.get_scroll_deltas()[2] if delta < 0: zoom = original + self.ZOOM_INCREMENT elif delta > 0: zoom = original - self.ZOOM_INCREMENT else: return False LOGGER.debug("Ctrl + Scrolling: zoom %f --> %f", original, zoom) self.adjustment.set_value(zoom) return True # don't know what to do, don't care. Let someone else take care of it return False class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() # XXX(Jflesch): Looks like a GObject Introspection bug: if the # Zoomer objects get garbage-collected, the signal isn't handled # anymore. --> We need to keep a reference to those objects as long # as we need them. self.refs = {} def get_interfaces(self): return [ 'chkdeps', 'gtk_zoomable', ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_zoomable_widget_new(self, zoomable, adjustment): """ zoomable is the widget on which user can zoom. zoom gestures are not applied directly on the widget. They are applied on a GtkAdjustment. """ zoomer = Zoomer(zoomable, adjustment) self.core.call_all("on_objref_track", zoomer) self.refs[zoomable] = zoomer def on_zoomable_widget_destroy(self, zoomable, adjustment): if zoomable in self.refs: self.refs.pop(zoomable) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/l10n/000077500000000000000000000000001456262201400225465ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/l10n/__init__.py000066400000000000000000000007251456262201400246630ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['l10n_init'] def get_deps(self): return [ { 'interface': 'l10n', 'defaults': ['openpaperwork_core.l10n.python'], }, ] def init(self, core): super().init(core) self.core.call_all( "l10n_load", "paperwork_gtk.l10n", "paperwork_gtk" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/main.py000066400000000000000000000226451456262201400233030ustar00rootroot00000000000000import argparse import logging import sys import openpaperwork_core # noqa: E402 import openpaperwork_gtk # noqa: E402 import paperwork_backend # noqa: E402 # this import must be non-relative due to cx_freeze running this .py # as an independant Python script from paperwork_gtk import _ # noqa: E402 LOGGER = logging.getLogger(__name__) REQUIRED_PLUGINS = ( 'openpaperwork_core.logs.print', # plugin 'uncaught_exceptions' requires a mainloop plugin 'openpaperwork_gtk.mainloop.glib', ) DEFAULT_GUI_PLUGINS = ( paperwork_backend.DEFAULT_PLUGINS + openpaperwork_gtk.GUI_PLUGINS + [ 'openpaperwork_core.display.print', 'openpaperwork_core.logs.print', 'openpaperwork_core.spatial.rtree', 'openpaperwork_gtk.drawer.pillow', 'openpaperwork_gtk.drawer.scan', 'openpaperwork_gtk.gesture.autoscrolling', 'openpaperwork_gtk.gtk_init', 'paperwork_backend.docscan.autoselect_scanner', 'paperwork_backend.guesswork.cropping.calibration', 'paperwork_gtk.about', 'paperwork_gtk.actions.app.find', 'paperwork_gtk.actions.app.help', 'paperwork_gtk.actions.app.open_about', 'paperwork_gtk.actions.app.open_bug_report', 'paperwork_gtk.actions.app.open_settings', 'paperwork_gtk.actions.app.open_shortcuts', 'paperwork_gtk.actions.doc.add_to_selection', 'paperwork_gtk.actions.doc.delete', 'paperwork_gtk.actions.doc.export', 'paperwork_gtk.actions.doc.new', 'paperwork_gtk.actions.doc.open_external', 'paperwork_gtk.actions.doc.prev_next', 'paperwork_gtk.actions.doc.print', 'paperwork_gtk.actions.doc.properties', 'paperwork_gtk.actions.doc.redo_ocr', 'paperwork_gtk.actions.docs.delete', 'paperwork_gtk.actions.docs.export', 'paperwork_gtk.actions.docs.properties', 'paperwork_gtk.actions.docs.redo_ocr', 'paperwork_gtk.actions.docs.select_all', 'paperwork_gtk.actions.page.copy_text', 'paperwork_gtk.actions.page.delete', 'paperwork_gtk.actions.page.edit', 'paperwork_gtk.actions.page.export', 'paperwork_gtk.actions.page.move_inside_doc', 'paperwork_gtk.actions.page.move_to_doc', 'paperwork_gtk.actions.page.print', 'paperwork_gtk.actions.page.redo_ocr', 'paperwork_gtk.actions.page.reset', 'paperwork_gtk.cmd.import', 'paperwork_gtk.cmd.install', 'paperwork_gtk.doc_selection', 'paperwork_gtk.docimport', 'paperwork_gtk.drawer.calibration', 'paperwork_gtk.drawer.frame', 'paperwork_gtk.flatpak', 'paperwork_gtk.gesture.drag_and_drop', 'paperwork_gtk.gesture.zoom', 'paperwork_gtk.icon', 'paperwork_gtk.keyboard_shortcut.zoom', 'paperwork_gtk.l10n', 'paperwork_gtk.mainwindow.doclist', 'paperwork_gtk.mainwindow.doclist.labeler', 'paperwork_gtk.mainwindow.doclist.name', 'paperwork_gtk.mainwindow.doclist.thumbnailer', 'paperwork_gtk.mainwindow.docproperties', 'paperwork_gtk.mainwindow.docproperties.extra_text', 'paperwork_gtk.mainwindow.docproperties.labels', 'paperwork_gtk.mainwindow.docproperties.name', 'paperwork_gtk.mainwindow.docview', 'paperwork_gtk.mainwindow.docview.controllers.autoscrolling', 'paperwork_gtk.mainwindow.docview.controllers.click', 'paperwork_gtk.mainwindow.docview.controllers.drop', 'paperwork_gtk.mainwindow.docview.controllers.empty_doc', 'paperwork_gtk.mainwindow.docview.controllers.layout', 'paperwork_gtk.mainwindow.docview.controllers.page_number', 'paperwork_gtk.mainwindow.docview.controllers.scroll', 'paperwork_gtk.mainwindow.docview.controllers.title', 'paperwork_gtk.mainwindow.docview.controllers.zoom', 'paperwork_gtk.mainwindow.docview.drag', 'paperwork_gtk.mainwindow.docview.pageadd.buttons', 'paperwork_gtk.mainwindow.docview.pageadd.import', 'paperwork_gtk.mainwindow.docview.pageadd.scan', 'paperwork_gtk.mainwindow.docview.pageadd.source_popover', 'paperwork_gtk.mainwindow.docview.pageinfo', 'paperwork_gtk.mainwindow.docview.pageinfo.actions', 'paperwork_gtk.mainwindow.docview.pageinfo.layout_settings', 'paperwork_gtk.mainwindow.docview.pageprocessing', 'paperwork_gtk.mainwindow.docview.pageview', 'paperwork_gtk.mainwindow.docview.pageview.boxes', 'paperwork_gtk.mainwindow.docview.pageview.boxes.all', 'paperwork_gtk.mainwindow.docview.pageview.boxes.hover', 'paperwork_gtk.mainwindow.docview.pageview.boxes.search', 'paperwork_gtk.mainwindow.docview.pageview.boxes.selection', 'paperwork_gtk.mainwindow.docview.progress', 'paperwork_gtk.mainwindow.docview.scanview', 'paperwork_gtk.mainwindow.exporter', 'paperwork_gtk.mainwindow.home', 'paperwork_gtk.mainwindow.pageeditor', 'paperwork_gtk.mainwindow.search.advanced', 'paperwork_gtk.mainwindow.search.field', 'paperwork_gtk.mainwindow.search.suggestions', 'paperwork_gtk.mainwindow.window', 'paperwork_gtk.menus.app.help', 'paperwork_gtk.menus.app.open_about', 'paperwork_gtk.menus.app.open_bug_report', 'paperwork_gtk.menus.app.open_settings', 'paperwork_gtk.menus.app.open_shortcuts', 'paperwork_gtk.menus.doc.add_to_selection', 'paperwork_gtk.menus.doc.delete', 'paperwork_gtk.menus.doc.export', 'paperwork_gtk.menus.doc.open_external', 'paperwork_gtk.menus.doc.print', 'paperwork_gtk.menus.doc.properties', 'paperwork_gtk.menus.doc.redo_ocr', 'paperwork_gtk.menus.docs.delete', 'paperwork_gtk.menus.docs.export', 'paperwork_gtk.menus.docs.properties', 'paperwork_gtk.menus.docs.redo_ocr', 'paperwork_gtk.menus.docs.select_all', 'paperwork_gtk.menus.page.copy_text', 'paperwork_gtk.menus.page.delete', 'paperwork_gtk.menus.page.export', 'paperwork_gtk.menus.page.move_inside_doc', 'paperwork_gtk.menus.page.move_to_doc', 'paperwork_gtk.menus.page.print', 'paperwork_gtk.menus.page.redo_ocr', 'paperwork_gtk.menus.page.reset', 'paperwork_gtk.model.help', 'paperwork_gtk.model.help.intro', 'paperwork_gtk.new_doc', 'paperwork_gtk.notifications.dialog', 'paperwork_gtk.notifications.notify', 'paperwork_gtk.print', 'paperwork_gtk.settings', 'paperwork_gtk.settings.ocr.selector_popover', 'paperwork_gtk.settings.ocr.settings', 'paperwork_gtk.settings.scanner.calibration', 'paperwork_gtk.settings.scanner.dev_id_popover', 'paperwork_gtk.settings.scanner.flatpak', 'paperwork_gtk.settings.scanner.mode_popover', 'paperwork_gtk.settings.scanner.resolution_popover', 'paperwork_gtk.settings.scanner.settings', 'paperwork_gtk.settings.stats', 'paperwork_gtk.settings.storage', 'paperwork_gtk.settings.update', 'paperwork_gtk.shortcuts.app.find', 'paperwork_gtk.shortcuts.doc.new', 'paperwork_gtk.shortcuts.doc.prev_next', 'paperwork_gtk.shortcuts.doc.print', 'paperwork_gtk.shortcuts.doc.properties', 'paperwork_gtk.shortcuts.page.copy_text', 'paperwork_gtk.shortcuts.page.edit', 'paperwork_gtk.shortcutswin', 'paperwork_gtk.sync_on_start', 'paperwork_gtk.update_notification', 'paperwork_gtk.widget.flowlayout', 'paperwork_gtk.widget.label', ] ) class DefaultConsole: def print(self, text): print(text) def input(self, prompt=""): return input(prompt) def gtk_main(app, options, core): app = core.call_success("gtk_get_app") if app.get_is_remote(): LOGGER.info("passing control to main paperwork instance") # if paperwork is already running, focus it, otherwise remain in this # process app.activate() return 0 def main_main(in_args): # To load the plugins, we need first to load the configuration plugin # to get the list of plugins to load. # The configuration plugin may write traces using logging, so we better # enable and configure the plugin logs.print first. core = openpaperwork_core.Core() for module_name in REQUIRED_PLUGINS: core.load(module_name) for module_name in paperwork_backend.DEFAULT_CONFIG_PLUGINS: core.load(module_name) core.init() core.call_all( "init_logs", "paperwork-gtk", "info" if len(in_args) <= 0 else "warning" ) core.call_all("config_load") core.call_all("config_load_plugins", "paperwork-gtk", DEFAULT_GUI_PLUGINS) if len(in_args) <= 0: core.call_all("gtk_init", gtk_main, core) else: # we remain in this process and call the plugin requested by the # command line parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help=_('command'), dest='command', required=True ) core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args(in_args) console = DefaultConsole() core.call_all("cmd_set_console", console) core.call_all("cmd_run", console, args) return 0 def main(): main_main(sys.argv[1:]) if __name__ == "__main__": # Do not remove. Cx_freeze goes through here main() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/000077500000000000000000000000001456262201400241505ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/__init__.py000066400000000000000000000000001456262201400262470ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/000077500000000000000000000000001456262201400256115ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/__init__.py000066400000000000000000000525641456262201400277360ustar00rootroot00000000000000import datetime import logging import time try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False try: from . import doc_box GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps from ... import _ LOGGER = logging.getLogger(__name__) # GtkListBox doesn't scale well with too many elements # --> by default we only display 50 documents, and only extend the list # as needed NB_DOCS_PER_PAGE = 50 class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def __init__(self): super().__init__() self.widget_tree = None self.doclist = None self.scrollbar = None self._scrollbar_last_value = -1 self.docs = [] self.row_visibles = [] self.doc_loaded = 0 self.row_to_doc = {} self.docid_to_row = {} self.min_doc_box_height = 1 self.last_date = datetime.datetime(year=1, month=1, day=1) self.active_doc = (None, None) self.previous_doc = (None, None) self.main_actions = [] self.doc_actions = None self.selection_multiple = False # the following boolean is a dirty hack to ignore the signal 'toggle' # when we toggle the checkbox ourselves (if another plugin # calls doc_selection_add() for instance) self._toggling = False def get_interfaces(self): return [ 'chkdeps', 'doc_actions', 'doc_open', 'doc_selection', 'docs_actions', 'drag_and_drop_destination', 'gtk_app_menu', 'gtk_doclist', 'screenshot_provider', 'search_listener', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_drag_and_drop', 'defaults': ['paperwork_gtk.gesture.drag_and_drop'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_widget_flowlayout', 'defaults': ['paprwork_gtk.widget.flowlayout'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def init(self, core): super().init(core) self.core.call_success( "gtk_load_css", "paperwork_gtk.mainwindow.doclist", "doclist.css" ) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.doclist", "doclist.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.doc_actions = Gio.Menu.new() self.doclist = self.widget_tree.get_object("doclist_listbox") self.core.call_all( "mainwindow_add", side="left", name="doclist", prio=10000, header=self.widget_tree.get_object("doclist_header"), body=self.widget_tree.get_object("doclist_body"), ) self.core.call_all( "mainwindow_add", side="left", name="doclist_selection_multiple", prio=-100000, header=self.widget_tree.get_object( "doclist_header_selection_multiple" ), body=None ) self.vadj = self.widget_tree.get_object( "doclist_scroll" ).get_vadjustment() self.vadj.connect("value-changed", self._on_scrollbar_value_changed) self.doclist.connect("row-activated", self._on_row_activated) self.doclist.connect("drag-motion", self._on_drag_motion) self.doclist.connect("drag-leave", self._on_drag_leave) self.doclist.connect("size-allocate", self._notify_box_visibility) self.widget_tree.get_object("doclist_new_doc").connect( "clicked", self._on_new_doc ) self.widget_tree.get_object( "doclist_back_to_selection_single" ).connect("clicked", lambda button: self.core.call_all( "gtk_switch_to_doc_selection_single" )) self.menu_model = self.widget_tree.get_object("doclist_menu_model") self.selection_multiple_menu_model = self.widget_tree.get_object( "doclist_selection_multiple_menu_model" ) self.core.call_all("drag_and_drop_page_enable", self.doclist) self.core.call_one( "mainloop_schedule", self.core.call_all, "on_doclist_initialized" ) self.on_mainwindow_fold_change() def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_initialized(self): self.core.call_all( "mainwindow_show", side="left", name="doclist" ) def doclist_add(self, widget, vposition): body = self.widget_tree.get_object("doclist_body") body.add(widget) body.reorder_child(widget, vposition) def _on_new_doc(self, button): self.doc_open_new() def doc_open_new(self): new_doc = self.core.call_success("get_new_doc") self.core.call_all("doc_open", *new_doc) self.doclist_show(self.docs, show_new=True) def doclist_clear(self): self.min_doc_box_height = 1 self.core.call_all("on_doc_list_clear") start = time.time() for child in self.doclist.get_children(): self.doclist.remove(child) stop = time.time() LOGGER.info( "%d documents cleared in %dms", self.doc_loaded, (stop - start) * 1000 ) self.last_date = datetime.datetime(year=1, month=1, day=1) self.doc_loaded = 0 self.row_to_doc = {} self.docid_to_row = {} self.row_visibles = [] def _add_date_box(self, name, txt): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.doclist", name ) widget_tree.get_object("date_label").set_text(txt) row = widget_tree.get_object("date_box") self.doclist.insert(row, -1) def _toggle_doc(self, button, doc_id, doc_url): if button.get_active(): self.core.call_all("doc_selection_add", doc_id, doc_url) else: self.core.call_all("doc_selection_remove", doc_id, doc_url) def _add_doc_box(self, doc_id, doc_url, box="doc_box.glade", new=False): row = doc_box.DocBox() flowlayout = self.core.call_success( "gtk_widget_flowlayout_new", spacing=(3, 3) ) flowlayout.set_visible(True) row.layout_bin.add(flowlayout) self.core.call_all( "on_doc_box_creation", doc_id, row, flowlayout ) doc_actions = row.main_actions if new: doc_actions.set_visible(False) else: row.action_menu.set_menu_model(self.doc_actions) for action in self.main_actions: action = doc_box.DocMainAction( action['txt'], action['icon_name'], action['callback'] ) row.main_actions.pack_start( action, expand=True, fill=True, padding=0 ) row.selector.set_visible( self.selection_multiple ) row.selector.set_active( self.core.call_success("doc_selection_in", doc_id, doc_url) is not None ) row.selector.connect( "toggled", self._toggle_doc, doc_id, doc_url ) row.connect("size-allocate", self._on_doc_box_size_allocate) self.row_to_doc[row] = (doc_id, doc_url) self.docid_to_row[doc_id] = row self.doclist.insert(row, -1) def doclist_extend(self, nb_docs): start = time.time() # FIXME: show month only when there are too many documents. How many? show_month = True docs = self.docs[ self.doc_loaded:self.doc_loaded + nb_docs ] LOGGER.info( "Adding %d documents to the document list (%d-%d)", len(docs), self.doc_loaded, self.doc_loaded + nb_docs ) for (doc_id, doc_url) in docs: doc_date = self.core.call_success("doc_get_date_by_id", doc_id) if doc_date is not None: if not show_month: if doc_date.year != self.last_date.year: doc_year = self.core.call_success( "i18n_date_long_year", doc_date ) self._add_date_box("year_box.glade", doc_year) else: if (doc_date.year != self.last_date.year or doc_date.month != self.last_date.month): doc_year = self.core.call_success( "i18n_date_long_year", doc_date ) + " / " + self.core.call_success( "i18n_date_long_month", doc_date ) self._add_date_box("year_box.glade", doc_year) self.last_date = doc_date self._add_doc_box(doc_id, doc_url) self.doc_loaded = min(len(self.docs), self.doc_loaded + nb_docs) stop = time.time() LOGGER.info( "%d documents shown in %dms (%d displayable)", len(docs), (stop - start) * 1000, len(self.docs) ) return len(docs) def doclist_show(self, docs, show_new=True): self.doclist_clear() scroll = (self.docs != docs) self.docs = docs if show_new: new_doc = self.core.call_success("get_new_doc") self._add_doc_box(*new_doc, new=True) self.doclist_extend(NB_DOCS_PER_PAGE) self._reselect_current_doc(scroll=scroll) def on_search_results(self, query, docs): self.doclist_show(docs, show_new=(query == "")) def doc_close(self): self.active_doc = (None, None) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) self._reselect_current_doc(scroll=False) def _show_doc_id(self, doc_id): row = self.docid_to_row.get(doc_id) while row is None: if self.doclist_extend(NB_DOCS_PER_PAGE) <= 0: break row = self.docid_to_row.get(doc_id) return row def _reselect_current_doc(self, scroll=True): (doc_id, doc_url) = self.active_doc if doc_id not in {doc[0] for doc in self.docs}: LOGGER.warning( "Document %s not found in the document list", doc_id ) self.vadj.set_value(self.vadj.get_lower()) return row = self._show_doc_id(doc_id) assert row is not None self.doclist.select_row(row) if (self.previous_doc[0] is not None and self.previous_doc[0] in self.docid_to_row): row = self.docid_to_row[self.previous_doc[0]] row.main_actions.set_visible(False) if ((not self.selection_multiple) and self.core.call_success("is_doc", doc_url) is not None and doc_id in self.docid_to_row): row = self.docid_to_row[doc_id] row.main_actions.set_visible(True) self.previous_doc = self.active_doc if not scroll: return handler_id = None def scroll_to_row(row, allocation): adj = allocation.y adj -= self.vadj.get_page_size() / 2 adj += allocation.height / 2 min_val = self.vadj.get_lower() if adj < min_val: adj = min_val self.vadj.set_value(adj) row.disconnect(handler_id) handler_id = row.connect("size-allocate", scroll_to_row) def _on_doc_box_size_allocate(self, box, allocation): h = allocation.height if h <= 0: return if self.min_doc_box_height <= 1: self.min_doc_box_height = h else: self.min_doc_box_height = min(self.min_doc_box_height, h) self._notify_box_visibility() def _notify_box_visibility(self, *args, **kwargs): lower = int(self.vadj.get_value()) upper = int(lower + self.vadj.get_page_size()) row_visibles = [] prow = None for y in range(lower, upper, self.min_doc_box_height): row = self.doclist.get_row_at_y(y) if row is None or prow is row: continue prow = row row_visibles.append(row) if self.row_visibles == row_visibles: return self.row_visibles = row_visibles self.core.call_all("on_doc_list_visibility_changed") for row in row_visibles: doc = self.row_to_doc.get(row) if doc is None: continue (doc_id, doc_url) = doc layout = row.layout_bin.get_child() self.core.call_all("on_doc_box_visible", doc_id, row, layout) def _on_scrollbar_value_changed(self, vadj): lower = vadj.get_lower() upper = vadj.get_upper() - lower value = ( vadj.get_value() + vadj.get_page_size() - lower ) / upper if value < 0.95: self._notify_box_visibility() return if self._scrollbar_last_value == vadj.get_value(): # Previous extend call hasn't been taken into account yet self._notify_box_visibility() return self.doclist_extend(NB_DOCS_PER_PAGE) self._scrollbar_last_value = vadj.get_value() self._notify_box_visibility() def _doc_open(self, doc_id, doc_url): if self.active_doc[0] == doc_id: return LOGGER.info("Opening document %s (%s)", doc_id, doc_url) self.core.call_all("doc_open", doc_id, doc_url) def _on_row_activated(self, list_box, row): (doc_id, doc_url) = self.row_to_doc[row] self._doc_open(doc_id, doc_url) def menu_app_append_item(self, item): # they are actually the same menu self.doclist_menu_append_item(item) def menu_app_append_submenu(self, label, menu): # they are actually the same menu self.doclist_menu_append_submenu(label, menu) def doclist_menu_append_item(self, item): self.menu_model.append_item(item) def doclist_menu_append_submenu(self, label, menu): self.menu_model.append_submenu(label, menu) def docs_menu_append_item(self, item): self.selection_multiple_menu_model.append_item(item) def docs_menu_append_submenu(self, label, menu): self.selection_multiple_menu_model.append_submenu(label, menu) def add_doc_action(self, action_label, action_name): self.doc_actions.append(action_label, action_name) def add_doc_main_action(self, icon_name, txt, callback): self.main_actions.append({ "icon_name": icon_name, "txt": txt, "callback": callback, }) def _on_drag_motion(self, widget, drag_context, x, y, time): widget.drag_unhighlight_row() row = widget.get_row_at_y(y) if row is not None: widget.drag_highlight_row(row) def _on_drag_leave(self, widget, drag_context, time): widget.drag_unhighlight_row() def drag_and_drop_get_destination(self, widget, x, y): if self.doclist != widget: return None row = self.doclist.get_row_at_y(y) if row is None: LOGGER.warning("No row at %d. Can't get drop destination", y) return None (doc_id, doc_url) = self.row_to_doc[row] nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None: nb_pages = 0 return (doc_id, doc_url, nb_pages) def gtk_open_app_menu(self): self.widget_tree.get_object("doclist_menu").clicked() def screenshot_snap_app_menu(self, out_file): widget = self.widget_tree.get_object("doclist_menu") if widget.get_popover() is not None: popover = widget.get_popover() if popover.get_visible() and popover.is_drawable(): widget = popover self.core.call_success( "screenshot_snap_widget", widget, out_file, margins=(50, 30, 50, 30) ) def screenshot_snap_all_doc_widgets(self, out_dir): self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("doclist_new_doc"), self.core.call_success("fs_join", out_dir, "doc_new_button.png"), margins=(30, 30, 30, 30) ) self.screenshot_snap_app_menu( self.core.call_success("fs_join", out_dir, "app_menu.png") ) if self.active_doc[0] is None: return row = self.docid_to_row[self.active_doc[0]] self.core.call_success( "screenshot_snap_widget", row.main_actions, self.core.call_success( "fs_join", out_dir, "doc_properties_button.png" ), margins=(50, 50, 50, 50) ) def _set_all_selector_visibility(self, visible): for row in self.docid_to_row.values(): checkbox = row.selector checkbox.set_visible(visible) def gtk_switch_to_doc_selection_single(self): self.core.call_all( "mainwindow_show", side="left", name="doclist" ) self._set_all_selector_visibility(False) self.selection_multiple = False self._reselect_current_doc(scroll=False) def gtk_switch_to_doc_selection_multiple(self): self.core.call_all( "mainwindow_show", side="left", name="doclist_selection_multiple" ) if not self.selection_multiple: self.core.call_all("doc_selection_reset") self.selection_multiple = True self._set_all_selector_visibility(True) self._reselect_current_doc(scroll=False) def doc_selection_reset(self): self._update_count() self._toggling = True try: for row in self.docid_to_row.values(): checkbox = row.selector checkbox.set_active(False) finally: self._toggling = False def doc_selection_add(self, doc_id, doc_url): self._update_count() if self._toggling: return self._toggling = True try: row = self.docid_to_row.get(doc_id, None) if row is None: return checkbox = row.selector if not checkbox.get_active(): checkbox.set_active(True) finally: self._toggling = False def doc_selection_remove(self, doc_id, doc_url): self._update_count() if self._toggling: return self._toggling = True try: row = self.docid_to_row.get(doc_id, None) if row is None: return checkbox = row.selector if checkbox.get_active(): checkbox.set_active(False) finally: self._toggling = False def _update_count(self): count = self.core.call_success("doc_selection_len") if count is None: count = 0 self.widget_tree.get_object( "doclist_selection_multiple_nb_docs" ).set_text(_("%d documents") % count) def open_next_doc(self, offset=1): try: idx = self.docs.index(self.active_doc) idx += offset except ValueError: idx = 0 idx = max(idx, 0) idx = min(idx, len(self.docs)) if idx >= len(self.docs): # may happen with an empty doc list return (doc_id, doc_url) = self.docs[idx] self.core.call_all("doc_open", doc_id, doc_url) self._reselect_current_doc(scroll=True) def doc_menu_open(self): if self.active_doc[0] is None: return doc_id = self.active_doc[0] row = self.docid_to_row[doc_id] button = row.action_menu button.clicked() def screenshot_snap_doc_action_menu(self, out_file): if self.active_doc[0] is None: return doc_id = self.active_doc[0] row = self.docid_to_row[doc_id] button = row.main_actions self.core.call_success( "screenshot_snap_widget", button, out_file, margins=(100, 50, 100, 200) ) def on_mainwindow_fold_change(self): folded = self.core.call_success("mainwindow_get_folded") self.widget_tree.get_object("doclist_header").set_show_close_button( folded ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doc_box.py000066400000000000000000000135171456262201400276070ustar00rootroot00000000000000import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk # noqa E402 DOC_BOX_XML = """ """ @Gtk.Template(string=DOC_BOX_XML) class DocBox(Gtk.ListBoxRow): __gtype_name__ = "DocBox" box = Gtk.Template.Child("internal_doc_box") selector = Gtk.Template.Child("doc_box_selector") thumbnail = Gtk.Template.Child("doc_thumbnail") main_actions = Gtk.Template.Child("doc_actions") action_menu = Gtk.Template.Child("doc_actions_menu") layout_bin = Gtk.Template.Child("layout_bin") DOC_MAIN_ACTION_XML = """ """ @Gtk.Template(string=DOC_MAIN_ACTION_XML) class DocMainAction(Gtk.Button): __gtype_name__ = "DocMainAction" img = Gtk.Template.Child("doc_main_action_image") def __init__(self, text, icon_name, callback, *args, **kwargs): self.callback = callback super().__init__(*args, **kwargs) self.set_tooltip_text(text) self.img.set_from_icon_name(icon_name, Gtk.IconSize.MENU) @Gtk.Template.Callback("on_clicked") def on_clicked(self, button): self.callback() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.css000066400000000000000000000036601456262201400277710ustar00rootroot00000000000000#doclist_body spinner { background-color: rgba(0, 0, 0, 0.25); } #doclist_scroll button image { border: 0px; } .search_field { padding: 12px 12px 10px 12px; } .search-left, .search-right { border: 1px solid shade(@theme_bg_color, 0.88); background-color: shade(@theme_bg_color, 0.88); } .suggestions_box { padding: 0px 12px 4px 12px; } .suggestions_label { margin: 5px; } .suggestions_list { border: 1px solid shade(@theme_bg_color, 0.88); background-color: shade(@theme_bg_color, 0.88); } .date_label { color: mix(@theme_bg_color, @theme_fg_color, 0.70); font-size: 11pt; font-weight: 800; padding-bottom: 2px; margin: 12px 6px -2px 6px; } .border-bottom-light { padding-bottom: 5px; border-bottom: 1px solid shade(@theme_bg_color, 0.88); } .doclist { padding: 2px 6px 0px 6px; background-color: @theme_bg_color; } .doclist_item { padding: 4px 6px 0px 6px; border: 1px solid @theme_bg_color; border-radius: 6px; color: @theme_fg_color; } .doclist_item:hover { margin-top: -2px; padding: 6px 6px 0px 6px; border: 1px solid shade(@theme_bg_color, 0.88); background-color: shade(@theme_bg_color, 0.88); color: @theme_fg_color; } .doclist_item:selected { margin-top: -2px; padding: 6px 6px 0px 6px; border: 1px solid shade(@theme_bg_color, 0.75); background-color: mix(@theme_bg_color, @theme_base_color, 0.6); color: @theme_fg_color; } .doclist_item:selected image { color: mix(@theme_base_color, @theme_fg_color, 0.85); } .doclist_item:hover .border-bottom-light, .doclist_item:selected .border-bottom-light { border-bottom: 1px solid transparent; } .doclist_thumbnail { border: 1px solid shade(@theme_bg_color, 0.75); background-color: mix(@theme_bg_color, @theme_base_color, 0.9); color: mix(@theme_base_color, @theme_fg_color, 0.85); } .doclist_item label { margin-left: 2px; color: mix(@theme_base_color, @theme_fg_color, 0.85); font-size: 11pt; font-weight: normal; } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/doclist.glade000066400000000000000000000174141456262201400302570ustar00rootroot00000000000000
doclist_body True False False True vertical True False doclist_scroll True False in False True True False -1 True True 0 True False False Documents False True False False True True False list-add-symbolic 1 True True True doclist_menu_model True False open-menu-symbolic end 1 True False False False True False False True none True False go-previous-symbolic 1 True True True none doclist_selection_multiple_menu_model True False True False vertical True False Selection False True 0 True False 3 documents False True 1 False True 0 True False go-down-symbolic False True 1
paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/labeler.py000066400000000000000000000124161456262201400275750ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class LabelingTask(object): def __init__(self, plugin, doc_id, doc_url, flowlayout): self.plugin = plugin self.core = plugin.core self.doc_id = doc_id self.doc_url = doc_url self.flowlayout = flowlayout def show_labels(self, labels): for widget in list(self.flowlayout.get_children()): if hasattr(widget, 'txt'): self.flowlayout.remove(widget) labels = [ ( self.core.call_success("i18n_strip_accents", label[0].lower()), label[0], label[1] ) for label in labels ] labels.sort() for label in labels: try: color = self.core.call_success("label_color_to_rgb", label[2]) except Exception as exc: LOGGER.warning( "Invalid label %s on document %s", label, self.doc_id, exc_info=exc ) continue widget = self.core.call_success( "gtk_widget_label_new", label[1], color ) widget.set_visible(True) self.flowlayout.add_child(widget, Gtk.Align.END) def get_promise(self): promise = openpaperwork_core.promise.Promise( self.core, LOGGER.info, args=("Loading labels of document %s", self.doc_id,) ) promise = promise.then(lambda *args: None) # drop logger return value promises = [] self.core.call_all( "doc_get_labels_by_url_promise", promises, self.doc_url ) for p in promises: promise = promise.then(p) return promise.then(self.show_labels) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def __init__(self): super().__init__() self.default_thumbnail = None self.running = False self.tasks = {} self.processing_docs = set() self.processed_docs = set() def get_interfaces(self): return [ 'gtk_doclist_listener', ] def get_deps(self): return [ { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.maindow.doclist'], }, { 'interface': 'gtk_widget_label', 'defaults': ['paperwork_gtk.widget.label'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def init(self, core): super().init(core) self.core.call_all("work_queue_create", "labeler", stop_on_quit=True) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def doclist_show(self, docs): self.core.call_all("work_queue_cancel_all", "labeler") self.task = {} def on_doc_list_clear(self): self.processed_docs = set() self.on_doc_list_visibility_changed() def on_doc_list_visibility_changed(self): self.core.call_all("work_queue_cancel_all", "labeler") self.processing_docs = set() self.nb_to_load = 0 def on_doc_box_visible(self, doc_id, gtk_row, gtk_custom_flowlayout): if doc_id in self.processing_docs: return if doc_id in self.processed_docs: return self.processing_docs.add(doc_id) doc_url = self.core.call_success("doc_id_to_url", doc_id) if doc_url is None: return task = LabelingTask(self, doc_id, doc_url, gtk_custom_flowlayout) self.tasks[doc_url] = task def _when_loaded(): if doc_id in self.processing_docs: self.processing_docs.remove(doc_id) self.processed_docs.add(doc_id) promise = task.get_promise() promise = promise.then(_when_loaded) self.core.call_success("work_queue_add_promise", "labeler", promise) def _refresh_doc(self, doc_url): if doc_url not in self.tasks: LOGGER.debug( "Labels on '%s' have changed, but it is not displayed at" " the moment", doc_url ) return LOGGER.info("Reloading labels of '%s'", doc_url) self.core.call_success( "work_queue_add_promise", "labeler", self.tasks[doc_url].get_promise() ) def doc_add_label_by_url(self, doc_url, label, color=None): self._refresh_doc(doc_url) def doc_remove_label_by_url(self, doc_url, label): self._refresh_doc(doc_url) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/main_action.glade000066400000000000000000000013361456262201400310730ustar00rootroot00000000000000 False True False False none True True False paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/month_box.glade000066400000000000000000000013461456262201400306100ustar00rootroot00000000000000 True False False True False December 0 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/name.py000066400000000000000000000034721456262201400271110ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def __init__(self): super().__init__() def get_interfaces(self): return [ 'chkdeps', 'gtk_doclist_listener', 'gtk_doclist_name', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.maindow.doclist'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_doc_box_creation(self, doc_id, gtk_row, custom_flowlayout): doc_url = self.core.call_success("doc_id_to_url", doc_id) is_new = doc_url is None or self.core.call_success( "is_doc", doc_url ) is None if is_new: doc_txt = _("New document") else: doc_date = self.core.call_success("doc_get_date_by_id", doc_id) if doc_date is not None: doc_txt = self.core.call_success("i18n_date_short", doc_date) else: doc_txt = doc_id label = Gtk.Label.new(doc_txt) label.set_visible(True) custom_flowlayout.add_child(label, Gtk.Align.START) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/thumbnailer.py000066400000000000000000000127731456262201400305070ustar00rootroot00000000000000import logging import PIL import openpaperwork_core from paperwork_backend.model.thumbnail import ( THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH ) from ... import _ LOGGER = logging.getLogger(__name__) DELAY = 0.01 # placeholders size must include borders PLACEHOLDER_HEIGHT = THUMBNAIL_HEIGHT + 2 PLACEHOLDER_WIDTH = THUMBNAIL_WIDTH + 2 class ThumbnailTask(object): def __init__(self, plugin, doc_id, gtk_image): self.plugin = plugin self.core = plugin.core self.doc_id = doc_id self.gtk_image = gtk_image def set_thumbnail(self, img=None): if img is None: LOGGER.warning( "Failed to get thumbnail for document %s", self.doc_id ) return pixbuf = self.core.call_success("pillow_to_pixbuf", img) self.gtk_image.set_from_pixbuf(pixbuf) def get_promise(self): doc_url = self.core.call_success("doc_id_to_url", self.doc_id) if doc_url is None: return openpaperwork_core.promise.Promise(self.core) def on_error(exc): # catch any error, otherwise if a document is corrupted, # the user will get far too many error messages during # thumbnailing LOGGER.error( "Failed to generate thumbnail of document %s", self.doc_id, exc_info=exc ) promise = openpaperwork_core.promise.Promise( self.core, LOGGER.info, args=("Thumbnailing of document %s", self.doc_id,) ) promise = promise.then(lambda *args: None) # drop logger return value promise = promise.then( self.core.call_success("thumbnail_get_doc_promise", doc_url) ) promise = promise.then(self.set_thumbnail) promise = promise.catch(on_error) return promise class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def __init__(self): super().__init__() self.default_thumbnail = None self.running = False self.nb_loaded = 0 self.nb_to_load = 0 self._progress_str = None self.processing_docs = set() self.processed_docs = set() def get_interfaces(self): return [ 'gtk_doclist_listener', 'gtk_thumbnailer', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.maindow.doclist'], }, { 'interface': 'pillow_util', 'defaults': ['openpaperwork_core.pillow.util'], }, { 'interface': 'pixbuf_pillow', 'defaults': ['openpaperwork_gtk.pixbuf.pillow'], }, { 'interface': 'thumbnail', 'defaults': ['paperwork_backend.model.thumbnail'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def init(self, core): super().init(core) img = PIL.Image.new( "RGB", (THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT), color="#EEEEEE" ) self.default_thumbnail = self.core.call_success( "pillow_to_pixbuf", img ) self.core.call_all( "work_queue_create", "thumbnailer", stop_on_quit=True ) self._progress_str = _("Loading document thumbnails") def doclist_show(self, docs): self.core.call_all("work_queue_cancel_all", "thumbnailer") def on_doc_list_clear(self): self.processed_docs = set() self.on_doc_list_visibility_changed() def on_doc_list_visibility_changed(self): self.core.call_all("work_queue_cancel_all", "thumbnailer") self.processing_docs = set() self.nb_to_load = 0 def on_doc_box_creation(self, doc_id, gtk_row, gtk_custom_flowlayout): gtk_img = gtk_row.thumbnail gtk_img.set_size_request(PLACEHOLDER_WIDTH, PLACEHOLDER_HEIGHT) gtk_img.set_visible(True) def on_doc_box_visible(self, doc_id, gtk_row, gtk_custom_flowlayout): if doc_id in self.processing_docs: return if doc_id in self.processed_docs: return self.nb_to_load += 1 self.processing_docs.add(doc_id) task = ThumbnailTask(self, doc_id, gtk_row.thumbnail) # Gives back a bit of CPU time to GTK so the GUI remains # usable promise = openpaperwork_core.promise.DelayPromise( self.core, DELAY ) promise = promise.then(task.get_promise()) def _when_loaded(): self.nb_loaded += 1 if doc_id in self.processing_docs: self.processing_docs.remove(doc_id) self.processed_docs.add(doc_id) self._update_progress() promise = promise.then(_when_loaded) self.core.call_success( "work_queue_add_promise", "thumbnailer", promise ) def _update_progress(self): if self.nb_loaded > self.nb_to_load: self.nb_loaded = 0 self.nb_to_load = 0 self.core.call_all("on_progress", "thumbnailing", 1.0) return self.core.call_all( "on_progress", "thumbnailing", self.nb_loaded / self.nb_to_load, self._progress_str ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/doclist/year_box.glade000066400000000000000000000013721456262201400304220ustar00rootroot00000000000000 True False False True False 1985 0 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/000077500000000000000000000000001456262201400270325ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/__init__.py000066400000000000000000000157161456262201400311550ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class DocPropertiesUpdate(object): def __init__(self, doc_id, multiple_docs=False): self.doc_id = doc_id self.multiple_docs = multiple_docs self.new_docs = set() self.upd_docs = set() self.del_docs = set() class DocPropertiesEditor(object): def __init__(self, name, plugin, multiple_docs=False): self.name = name self.core = plugin.core self.plugin = plugin self.multiple_docs = multiple_docs self.active_docs = set() self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docproperties", "docproperties.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.widget_tree.get_object("docproperties_back").connect( "clicked", self._apply ) self.widget_tree.get_object("docproperties_cancel").connect( "clicked", self._cancel ) self.core.call_all( "mainwindow_add", side="left", name="docproperties_" + self.name, prio=0, header=self.widget_tree.get_object("docproperties_header"), body=self.widget_tree.get_object("docproperties_body"), ) self.core.call_one( "mainloop_schedule", self._build_doc_properties, multiple_docs ) def show(self): self.core.call_all( "mainwindow_show", side="left", name="docproperties_" + self.name ) def hide(self): self.core.call_all("mainwindow_back", side="left") def _build_doc_properties(self, multiple_docs): components = [] self.core.call_all( "doc_properties_components_get", components, multiple_docs=multiple_docs ) for component in components: self.widget_tree.get_object("docproperties_box").pack_start( component, expand=False, fill=True, padding=0 ) def doc_open(self, doc_id, doc_url): self.active_docs = {(doc_id, doc_url)} self.core.call_all( "doc_properties_components_set_active_doc", doc_id, doc_url ) def docs_open(self, docs): self.active_docs = docs self.core.call_all( "doc_properties_components_set_active_docs", docs ) def _open_doc(self, upd): active_docs = {doc[0] for doc in self.active_docs} if upd.doc_id is not None and upd.doc_id not in active_docs: doc_url = self.core.call_success("doc_id_to_url", upd.doc_id) if doc_url is None: return self.core.call_all("doc_open", upd.doc_id, doc_url) def _apply(self, *args, **kwargs): LOGGER.info( "Changes validated by the user (multiple_docs=%s)", self.multiple_docs ) upd = DocPropertiesUpdate( list(self.active_docs)[0][0], self.multiple_docs ) promise = openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_all, args=("doc_properties_components_apply_changes", upd) ) # drop call_all return value promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self._open_doc, upd) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "search_update_document_list" ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self._upd_index, upd) promise.schedule() self.core.call_all("close_doc_properties") def _cancel(self, *args, **kwargs): LOGGER.info("Changes cancelled by the user") self.core.call_all("doc_properties_components_cancel_changes") self.core.call_all("close_doc_properties") def _upd_index(self, upd): total = len(upd.new_docs) + len(upd.upd_docs) + len(upd.del_docs) if total <= 0: LOGGER.info("Document %s not modified. Nothing to do", upd.doc_id) return LOGGER.info( "Document %s modified. %d documents impacted", upd.doc_id, total ) changes = [] for doc_id in upd.new_docs: changes.append(('add', doc_id)) for doc_id in upd.upd_docs: changes.append(('upd', doc_id)) for doc_id in upd.del_docs: changes.append(('del', doc_id)) self.core.call_success("transaction_simple", changes) def docproperties_scroll_to_last(self): scroll = self.widget_tree.get_object("docproperties_body") vadj = scroll.get_vadjustment() vadj.set_value(vadj.get_upper()) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.editors = {} def get_interfaces(self): return ['gtk_doc_properties'] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) self.editors = { 'single_doc': DocPropertiesEditor( "single", self, multiple_docs=False ), 'multiple_docs': DocPropertiesEditor( "multiple", self, multiple_docs=True ), } self.active_editor = None def doc_open(self, doc_id, doc_url): if self.active_editor is None: return e = self.active_editor e.doc_open(doc_id, doc_url) def open_doc_properties(self, doc_id, doc_url): assert self.active_editor is None e = self.editors['single_doc'] self.active_editor = e e.doc_open(doc_id, doc_url) e.show() def open_docs_properties(self, docs): assert self.active_editor is None e = self.editors['multiple_docs'] self.active_editor = e e.docs_open(docs) e.show() def close_doc_properties(self): assert self.active_editor is not None self.active_editor.hide() self.active_editor = None def docproperties_scroll_to_last(self): for e in self.editors.values(): e.docproperties_scroll_to_last() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/docproperties.glade000066400000000000000000000035451456262201400327210ustar00rootroot00000000000000 True Properties False True False True True gtk-cancel start True False False True True gtk-apply end True False True False vertical docproperties_body paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.glade000066400000000000000000000040211456262201400322140ustar00rootroot00000000000000 True False vertical 10 True False Additional keywords start False True 0 True True automatic automatic 100 True True True False True GTK_WRAP_WORD False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/extra_text.py000066400000000000000000000063021456262201400315740ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 750 def __init__(self): super().__init__() self.widget_tree = None self.active_doc = None def get_interfaces(self): return [ 'gtk_doc_property', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'extra_text', 'defaults': ['paperwork_backend.model.extra_text'], }, { 'interface': 'gtk_doc_properties', 'defaults': ['paperwork_gtk.docproperties'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def _get_widget_text(self): text_buffer = self.widget_tree.get_object("doctext_text").get_buffer() start = text_buffer.get_iter_at_offset(0) end = text_buffer.get_iter_at_offset(-1) return text_buffer.get_text(start, end, False) def doc_properties_components_get(self, out: list, multiple_docs=False): if multiple_docs: return self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docproperties", "extra_text.glade" ) out.append(self.widget_tree.get_object("doctext")) def doc_properties_components_set_active_doc(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) txt = [] self.core.call_all("doc_get_extra_text_by_url", txt, doc_url) txt = "\n".join(txt) self.widget_tree.get_object("doctext_text").get_buffer().set_text(txt) def doc_properties_components_apply_changes(self, out): if out.multiple_docs: return # The document may have been renamed: use out.doc_id instead of # self.active_doc doc_id = out.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) self.active_doc = (doc_id, doc_url) orig_txt = [] self.core.call_all( "doc_get_extra_text_by_url", orig_txt, doc_url ) orig_txt = "\n".join(orig_txt).strip() new_txt = self._get_widget_text() if new_txt == orig_txt: return LOGGER.info("Extra keywords have been changed in document %s", doc_id) self.core.call_all( "doc_set_extra_text_by_url", doc_url, new_txt ) out.upd_docs.add(doc_id) def doc_properties_components_cancel_changes(self): self.doc_properties_components_set_active_doc(*self.active_doc) def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("doctext_text"), self.core.call_success( "fs_join", out_dir, "doc_extra_text.png" ), margins=(50, 50, 50, 50) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/label.glade000066400000000000000000000070261456262201400311140ustar00rootroot00000000000000 30 True False True False True False False half True False False True 0 True False False True Change the label color none False True 1 True False False none False False 2 True False False True Delete the label from all documents none True False edit-delete-symbolic 1 False True end 3 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.glade000066400000000000000000000076761456262201400313120ustar00rootroot00000000000000 True False vertical 10 True False Labels start False True 0 True True automatic never True True False True 1 True False 30 True False horizontal True False none False True 0 docproperties_new_label_entry True True True True â— True True 1 True False True False 1 list-add-symbolic False True 2 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/labels.py000066400000000000000000000547111456262201400306560ustar00rootroot00000000000000import enum import logging import re try: import gi gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') from gi.repository import Gdk from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps import paperwork_backend.sync from ... import _ LOGGER = logging.getLogger(__name__) # forbid: # - empty strings # - strings that contain a comma RE_FORBIDDEN_LABELS = re.compile("(^$|.*,.*)") class LabelChange(enum.Enum): UNCHANGED = 0 ADDED = 1 REMOVED = 2 class LabelAction(object): def __init__(self, current_state): # current_state == None for multiple document selection self.current_state = current_state self.change = LabelChange.UNCHANGED def on_change(self): if self.current_state is None: # multi-docs mode : rotate over the 3 possible change values if self.change == LabelChange.UNCHANGED: self.change = LabelChange.ADDED elif self.change == LabelChange.ADDED: self.change = LabelChange.REMOVED elif self.change == LabelChange.REMOVED: self.change = LabelChange.UNCHANGED else: # single-doc mode if not self.current_state: if self.change == LabelChange.UNCHANGED: self.change = LabelChange.ADDED else: self.change = LabelChange.UNCHANGED else: if self.change == LabelChange.UNCHANGED: self.change = LabelChange.REMOVED else: self.change = LabelChange.UNCHANGED def get_image(self): if self.change == LabelChange.ADDED: return "list-add-symbolic" elif self.change == LabelChange.REMOVED: return "list-remove-symbolic" else: if self.current_state: return "object-select-symbolic" return None def __str__(self): return str((self.change, self.current_state)) class LabelEditor(object): def __init__(self, plugin): super().__init__() self.core = plugin.core self.plugin = plugin self.active_docs = [] # self.changed_labels contains the label that have been modified # (color or text) self.changed_labels = {} # self.toggled_labels indicates the labels that have been selected or # unselected (value = LabelAction, depending on whether they are # now selected or not) self.toggled_labels = {} # self.new_labels contains the labels that user has just created # (but are not yet applied on any document) self.new_labels = set() # self.deleted_labels contains the labels that the user wants to # remove from *all* the documents. self.deleted_labels = set() self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docproperties", "labels.glade" ) color_widget = self.widget_tree.get_object("new_label_color") color_widget.set_rgba(self.core.call_success( "gtk_theme_get_color", "theme_bg_color" )) self.widget_tree.get_object("new_label_button").connect( "clicked", self._on_new_label ) new_label_entry = self.widget_tree.get_object("new_label_entry") new_label_entry.connect("activate", self._on_new_label) new_label_entry.connect("changed", self._on_label_txt_changed) def _update_button_img(self, toggle, label_action): img = label_action.get_image() if img is not None: image = Gtk.Image.new_from_icon_name(img, Gtk.IconSize.MENU) else: image = Gtk.Image() toggle.set_image(image) def _refresh_list(self): listbox = self.widget_tree.get_object("listbox_labels") for widget in list(listbox.get_children()): listbox.remove(widget) doc_labels = None if len(self.active_docs) == 1: doc_labels = set() active_doc = list(self.active_docs)[0] self.core.call_all( "doc_get_labels_by_url", doc_labels, active_doc[1] ) labels = set() self.core.call_all("labels_get_all", labels) if doc_labels is not None: labels.update(doc_labels) labels = [ ( self.core.call_success("i18n_strip_accents", label[0].lower()), label[0], label[1] ) for label in labels ] labels.sort() labels = [(label[1], label[2]) for label in labels] if doc_labels is not None: doc_labels = {doc_label[0] for doc_label in doc_labels} for old_label in labels: if old_label in self.changed_labels: new_label = self.changed_labels[old_label] else: new_label = old_label if old_label in self.deleted_labels: continue if old_label in self.toggled_labels: label_action = self.toggled_labels[old_label] else: if doc_labels is None: active = None else: active = old_label[0] in doc_labels label_action = LabelAction(active) widget_tree_label = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docproperties", "label.glade" ) button = widget_tree_label.get_object("label_label") button.set_label(new_label[0]) button.connect("clicked", self._on_label_button_clicked, old_label) toggle = widget_tree_label.get_object("toggle_button") toggle.set_sensitive(True) self._update_button_img(toggle, label_action) toggle.connect("clicked", self._on_toggle, old_label, label_action) color = self.core.call_success("label_color_to_rgb", new_label[1]) color_button = widget_tree_label.get_object("color_button") color_button.set_sensitive(old_label not in self.new_labels) color_button.set_rgba(Gdk.RGBA(color[0], color[1], color[2], 1.0)) color_button.connect( "color-set", self._on_color_changed, old_label ) delete = widget_tree_label.get_object("delete_button") delete.connect("clicked", self._on_delete, old_label) listbox.add(widget_tree_label.get_object("label_row")) new_labels = list(self.new_labels) new_labels.sort() for label in new_labels: widget_tree_label = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docproperties", "label.glade" ) button = widget_tree_label.get_object("label_label") button.set_label(label[0]) button.set_sensitive(False) toggle = widget_tree_label.get_object("toggle_button") toggle.set_sensitive(False) image = Gtk.Image.new_from_icon_name( "list-add-symbolic", Gtk.IconSize.MENU ) toggle.set_image(image) color = self.core.call_success("label_color_to_rgb", label[1]) color_button = widget_tree_label.get_object("color_button") color_button.set_sensitive(True) color_button.set_rgba(Gdk.RGBA(color[0], color[1], color[2], 1.0)) color_button.connect( "color-set", self._on_new_color_changed, label ) delete = widget_tree_label.get_object("delete_button") delete.connect("clicked", self._on_new_delete, label) listbox.add(widget_tree_label.get_object("label_row")) listbox.add(self.widget_tree.get_object("row_add_label")) def _on_label_button_clicked(self, label_button, label): original_label = label if label in self.changed_labels: label = self.changed_labels[label] self.core.call_success( "gtk_show_dialog_single_entry", self.plugin, _("Renaming label"), label[0], self, label_button, original_label, label ) def on_label_rename_response( self, new_label_txt, label_button, original_label, label): new_label_txt = new_label_txt.strip() if not self._check_label_name(new_label_txt): return LOGGER.info("Renaming label %s --> %s", label, new_label_txt) self.changed_labels[original_label] = (new_label_txt, label[1]) label_button.set_label(new_label_txt) def _on_toggle(self, button, label, label_action): label_action.on_change() self._update_button_img(button, label_action) self.toggled_labels[label] = label_action def _on_color_changed(self, button, original_label): color = button.get_rgba() color = (color.red, color.green, color.blue) color = self.core.call_success("label_color_from_rgb", color) label = original_label if original_label in self.changed_labels: label = self.changed_labels[original_label] new_label = (label[0], color) self.changed_labels[original_label] = new_label def _on_new_color_changed(self, button, original_label): self.new_labels.remove(original_label) color = button.get_rgba() color = (color.red, color.green, color.blue) color = self.core.call_success("label_color_from_rgb", color) new_label = (original_label[0], color) self.new_labels.add(new_label) self._refresh_list() def _on_delete(self, button, original_label): self.core.call_all( "gtk_show_dialog_yes_no", self, _( "Are you sure you want to delete label '%s'" " from ALL documents ?" ) % (original_label,), original_label, ) def on_dialog_yes_no_reply(self, origin, response, *args, **kwargs): if origin is not self: return if not response: LOGGER.info("Label delete canceled") return (original_label,) = args LOGGER.info("Will delete label %s on all documents", original_label) self.deleted_labels.add(original_label) self._refresh_list() def _on_new_delete(self, button, label): self.new_labels.remove(label) self._refresh_list() def _check_label_name(self, label_name): all_labels = set() self.core.call_all("labels_get_all", all_labels) for label in set(all_labels): if label in self.changed_labels: all_labels.add(self.changed_labels[label]) all_labels.update(self.new_labels) all_labels = {label[0] for label in all_labels} if label_name in all_labels: return False if RE_FORBIDDEN_LABELS.match(label_name): return False return True def _on_label_txt_changed(self, *args, **kwargs): entry = self.widget_tree.get_object("new_label_entry") button = self.widget_tree.get_object("new_label_button") txt = entry.get_text().strip() valid = self._check_label_name(txt) button.set_sensitive(valid) if valid or txt == "": self.core.call_all("gtk_entry_reset_colors", entry) else: self.core.call_all("gtk_entry_set_colors", entry) def _on_new_label(self, *args, **kwargs): text = self.widget_tree.get_object("new_label_entry").get_text() text = text.strip() if text == "": LOGGER.info("New label requested, but no text provided") return color_widget = self.widget_tree.get_object("new_label_color") color = color_widget.get_rgba() color = (color.red, color.green, color.blue) color = self.core.call_success("label_color_from_rgb", color) self.new_labels.add((text, color)) self._refresh_list() # reset fields self.widget_tree.get_object("new_label_entry").set_text("") color_widget.set_rgba(self.core.call_success( "gtk_theme_get_color", "theme_bg_color" )) def _make_new_labels(self, out, doc_id, doc_url): if len(self.new_labels) <= 0: return for label in self.new_labels: self.core.call_success( "doc_add_label_by_url", doc_url, label[0], label[1] ) out.upd_docs.add(doc_id) def _make_label_updates(self, out): if len(self.changed_labels) <= 0: return all_docs = [] self.core.call_all("storage_get_all_docs", all_docs) all_docs = set(all_docs) current = 0 total = len(self.changed_labels) * len(all_docs) for (doc_id, doc_url) in all_docs: for (old_label, new_label) in self.changed_labels.items(): LOGGER.info( "Changing label %s into %s on document %s", old_label, new_label, doc_id ) self.core.call_all( "on_progress", "label_upd", current / total, _( "Changing label {old_label} into {new_label}" " on document {doc_id}" ).format( old_label=old_label, new_label=new_label, doc_id=doc_id ) ) current += 1 doc_labels = set() self.core.call_all( "doc_get_labels_by_url", doc_labels, doc_url ) if old_label not in doc_labels: continue out.upd_docs.add(doc_id) self.core.call_all( "doc_remove_label_by_url", doc_url, old_label[0] ) self.core.call_success( "doc_add_label_by_url", doc_url, new_label[0], new_label[1] ) self.core.call_all("on_progress", "label_upd", 1.0) def _make_label_toggling(self, out, doc_id, doc_url): if len(self.toggled_labels) <= 0: return for (label, action) in self.toggled_labels.items(): doc_labels = set() self.core.call_all("doc_get_labels_by_url", doc_labels, doc_url) if action.change == LabelChange.ADDED: if label in doc_labels: continue self.core.call_success( "doc_add_label_by_url", doc_url, label[0], label[1] ) out.upd_docs.add(doc_id) elif action.change == LabelChange.REMOVED: if label not in doc_labels: continue self.core.call_all( "doc_remove_label_by_url", doc_url, label[0] ) out.upd_docs.add(doc_id) def _make_label_deletions(self, out): if len(self.deleted_labels) <= 0: return all_docs = [] self.core.call_all("storage_get_all_docs", all_docs) all_docs = set(all_docs) current = 0 total = len(self.deleted_labels) * len(all_docs) for (doc_id, doc_url) in all_docs: for old_label in self.deleted_labels: LOGGER.info( "Deleting label %s from document %s", old_label, doc_id ) self.core.call_all( "on_progress", "label_del", current / total, _( "Deleting label {old_label} from document {doc_id}" ).format(old_label=old_label, doc_id=doc_id) ) current += 1 doc_labels = set() self.core.call_all( "doc_get_labels_by_url", doc_labels, doc_url ) if old_label not in doc_labels: continue out.upd_docs.add(doc_id) self.core.call_all( "doc_remove_label_by_url", doc_url, old_label[0] ) self.core.call_all("on_progress", "label_del", 1.0) def doc_properties_components_set_active_doc(self, doc_id, doc_url): self.doc_properties_components_set_active_docs({(doc_id, doc_url)}) def doc_properties_components_set_active_docs(self, docs: set): self.active_docs = docs self.changed_labels = {} self.toggled_labels = {} self.new_labels = set() self.deleted_labels = set() new_label_entry = self.widget_tree.get_object("new_label_entry") new_label_entry.set_text("") self._refresh_list() def doc_properties_components_apply_changes(self, out): LOGGER.info("Selected/Unselected labels: %s", self.toggled_labels) LOGGER.info("Modified labels: %s", self.changed_labels) LOGGER.info("New labels: %s", self.new_labels) LOGGER.info("Deleted labels: %s", self.deleted_labels) if len(self.active_docs) == 1: # The document may have been renamed: use out.doc_id instead of # self.active_docs doc_id = out.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) self.active_docs = {(doc_id, doc_url)} for (doc_id, doc_url) in self.active_docs: LOGGER.info("Updating document %s", doc_id) self._make_label_toggling(out, doc_id, doc_url) self._make_new_labels(out, doc_id, doc_url) if len(self.changed_labels) <= 0 and len(self.deleted_labels) <= 0: return self._make_label_deletions(out) self._make_label_updates(out) def doc_properties_components_cancel_changes(self): self.doc_properties_components_set_active_docs(self.active_docs) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def __init__(self): super().__init__() self.windows = [] self.editors = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_doc_property', 'gtk_window_listener', 'screenshot_provider', 'syncable', ] def get_deps(self): return [ { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_colors', 'defaults': ['openpaperwork_gtk.colors'], }, { 'interface': 'gtk_dialog_yes_no', 'defaults': ['openpaperwork_gtk.dialogs.yes_no'], }, { 'interface': 'gtk_doc_properties', 'defaults': ['paperwork_gtk.docproperties'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def init(self, core): super().init(core) if not GTK_AVAILABLE: # chkdeps() must still be callable return def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def doc_properties_components_get(self, out: list, multiple_docs=False): editor = LabelEditor(self) self.editors.append(editor) out.append(editor.widget_tree.get_object("listbox_global")) def on_dialog_yes_no_reply(self, origin, response, *args, **kwargs): for editor in self.editors: editor.on_dialog_yes_no_reply(origin, response, *args, **kwargs) def doc_properties_components_set_active_doc(self, doc_id, doc_url): for editor in self.editors: editor.doc_properties_components_set_active_doc(doc_id, doc_url) def doc_properties_components_set_active_docs(self, docs: set): for editor in self.editors: editor.doc_properties_components_set_active_docs(docs) def doc_properties_components_apply_changes(self, out): for editor in self.editors: editor.doc_properties_components_apply_changes(out) def doc_properties_components_cancel_changes(self): for editor in self.editors: editor.doc_properties_components_cancel_changes() def on_dialog_single_entry_reply( self, parent, r, new_value, *args, **kwargs): if parent is not self: return if not r: return editor = args[0] args = args[1:] editor.on_label_rename_response(new_value, *args, **kwargs) def doc_transaction_start(self, out: list, total_expected=-1): class RefreshTransaction(paperwork_backend.sync.BaseTransaction): priority = -100000 def commit(s): for editor in self.editors: self.core.call_one( "mainloop_schedule", editor._refresh_list ) out.append(RefreshTransaction(self.core, total_expected)) def sync(self, promises: list): pass def on_label_loading_end(self): for editor in self.editors: editor._refresh_list() def screenshot_snap_all_doc_widgets(self, out_dir): for editor in self.editors: self.core.call_success( "screenshot_snap_widget", editor.widget_tree.get_object("listbox_global"), self.core.call_success( "fs_join", out_dir, "doc_labels.png" ), margins=(10, 10, 10, -400) ) self.core.call_success( "screenshot_snap_widget", editor.widget_tree.get_object("new_label_button"), self.core.call_success( "fs_join", out_dir, "doc_new_label.png" ), margins=(400, 50, 50, 50) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.glade000066400000000000000000000031641456262201400307540ustar00rootroot00000000000000 True False vertical 10 True False Date start False True 0 True True True True â— x-office-calendar-symbolic True False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docproperties/name.py000066400000000000000000000117261456262201400303330ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def __init__(self): super().__init__() self.widget_tree = None self.active_doc = None def get_interfaces(self): return [ 'gtk_doc_property', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_calendar_popover', 'defaults': ['openpaperwork_gtk.widgets.calendar'], }, { 'interface': 'gtk_doc_properties', 'defaults': ['paperwork_gtk.docproperties'], }, { 'interface': 'gtk_colors', 'defaults': ['openpaperwork_gtk.colors'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def doc_properties_components_get(self, out: list, multiple_docs=False): if multiple_docs: return self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docproperties", "name.glade" ) self.core.call_all( "gtk_calendar_add_popover", self.widget_tree.get_object("docname_entry") ) self.widget_tree.get_object("docname_entry").connect( "changed", self._on_doc_date_changed ) out.append(self.widget_tree.get_object("docname")) def doc_properties_components_set_active_doc(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) doc_date = self.core.call_success("doc_get_date_by_id", doc_id) if doc_date is not None: doc_txt = self.core.call_success("i18n_date_short", doc_date) else: doc_txt = doc_id self.widget_tree.get_object("docname_entry").set_text(doc_txt) def _check_doc_id(self, doc_id): if doc_id == "": return False for forbidden in ["/", "\\", "?", "*"]: if forbidden in doc_id: return False return True def _on_doc_date_changed(self, gtk_entry): txt = gtk_entry.get_text() txt = txt.strip() r = self.core.call_success("i18n_parse_date_short", txt) if r is not None: self.core.call_all("gtk_entry_reset_colors", gtk_entry) elif not self._check_doc_id(txt): self.core.call_all("gtk_entry_set_colors", gtk_entry, bg="#ff0000") else: self.core.call_all("gtk_entry_set_colors", gtk_entry, bg="#ee9000") def doc_properties_components_apply_changes(self, out): if out.multiple_docs: return doc_id = self.widget_tree.get_object("docname_entry").get_text() doc_id = doc_id.strip() doc_date = self.core.call_success("i18n_parse_date_short", doc_id) if doc_date is not None: doc_id = self.core.call_success("doc_get_id_by_date", doc_date) elif not self._check_doc_id(doc_id): LOGGER.error( "Invalid document id specified. Won't rename the document" ) return else: LOGGER.warning( "Failed to parse document date: %s. Using as is", doc_id ) orig_id = out.doc_id orig_date = self.core.call_success("doc_get_date_by_id", orig_id) if orig_date is not None: orig_date = orig_date.date() else: orig_date = orig_id dest_id = doc_id dest_date = self.core.call_success("doc_get_date_by_id", dest_id) if dest_date is not None: dest_date = dest_date.date() else: dest_date = dest_id if orig_date == dest_date: return LOGGER.info("Previous document id: %s (%s)", orig_id, orig_date) LOGGER.info("New document id: %s (%s)", dest_id, dest_date) orig_url = self.core.call_success("doc_id_to_url", orig_id) dest_url = self.core.call_success( "doc_id_to_url", dest_id, existing=False ) LOGGER.info("Renaming document %s into %s", orig_id, dest_id) dest_url = self.core.call_success( "doc_rename_by_url", orig_url, dest_url ) if not dest_url: LOGGER.warning("Renaming %s into %s failed", orig_id, dest_id) return dest_id = self.core.call_success("doc_url_to_id", dest_url) out.del_docs.add(out.doc_id) out.new_docs.add(dest_id) out.doc_id = dest_id def doc_properties_components_cancel_changes(self): self.doc_properties_components_set_active_doc(*self.active_doc) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/000077500000000000000000000000001456262201400256105ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/__init__.py000066400000000000000000000260711456262201400277270ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): LAYOUTS = { # name: pages per line (columns) 'paged': 1, 'grid': 3, } MAX_PAGES = max(LAYOUTS.values()) def __init__(self): super().__init__() self.controllers = {} self.widget_tree = None self.scroll = None self.page_layout = None self.pages = [] self.nb_visible_pages = 0 self.widget_to_page = {} self.page_to_widget = {} self.nb_columns = self.MAX_PAGES self.zoom = 0.0 self.layout_name = None self.requested_page_idx = 0 self.active_page_idx = 0 self.active_doc = (None, None) self.active_doc_mtime = None def get_interfaces(self): return [ 'chkdeps', 'doc_open', 'drag_and_drop_destination', 'gtk_docview', ] def get_deps(self): return [ { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_zoomable', 'defaults': [ 'paperwork_gtk.gesture.zoom', 'paperwork_gtk.keyboard_shortcut.zoom', ], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, ] def init(self, core): super().init(core) self.core.call_success( "gtk_load_css", "paperwork_gtk.mainwindow.docview", "docview.css" ) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview", "docview.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.scroll = self.widget_tree.get_object("docview_scroll") self.scroll.get_vadjustment().connect( "value-changed", self._on_vscroll_value_changed ) self.scroll.get_vadjustment().connect( "changed", self._on_vscroll_changed ) self.overlay = self.widget_tree.get_object("docview_drawingarea") self.overlay.connect("draw", self._on_overlay_draw) self.page_layout = self.widget_tree.get_object("docview_page_layout") self.page_layout.connect( "size-allocate", self._on_layout_size_allocate ) self.page_layout.connect("child-activated", self._on_child_activated) self.page_layout.connect("drag-motion", self._on_drag_motion) self.page_layout.connect("drag-leave", self._on_drag_leave) self.page_layout.connect("draw", self._on_draw) self.core.call_all( "gtk_fix_headerbar_buttons", self.widget_tree.get_object("docview_header") ) self.on_mainwindow_fold_change() self.widget_tree.get_object("docview_back").connect( "clicked", lambda *args, **kwargs: ( self.core.call_all("mainwindow_show", "left") ) ) self.core.call_all( "mainwindow_add", side="right", name="docview", prio=10000, header=self.widget_tree.get_object("docview_header"), body=self.widget_tree.get_object("docview_body"), ) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_gtk_docview_init", self ) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def _on_child_activated(self, page_layout, child): page = self.widget_to_page[child] for controller in self.controllers.values(): controller.on_page_activated(page) def docview_set_bottom_margin(self, height): self.widget_tree.get_object("docview_padding").set_size_request( 1, height + 10 ) def docview_get_headerbar(self): return self.widget_tree.get_object("docview_header") def docview_get_body(self): return self.widget_tree.get_object("docview_overlay") def docview_get_scrollwindow(self): return self.widget_tree.get_object("docview_scroll") def docview_switch_controller(self, name, new_controller_ctor): self.controllers[name].exit() new_controller = new_controller_ctor(self) LOGGER.info( "%s: %s --> %s", name, str(self.controllers[name]), str(new_controller) ) self.controllers[name] = new_controller new_controller.enter() def _on_layout_size_allocate(self, layout, allocation): for controller in self.controllers.values(): controller.on_layout_size_allocate(layout) def _on_vscroll_value_changed(self, vadj): for controller in self.controllers.values(): controller.on_vscroll_value_changed(vadj) def _on_vscroll_changed(self, vadj): for controller in self.controllers.values(): controller.on_vscroll_changed(vadj) def _on_drag_motion(self, layout, drag_context, x, y, time): for controller in self.controllers.values(): controller.on_drag_motion(drag_context, x, y, time) def _on_drag_leave(self, layout, drag_context, time): for controller in self.controllers.values(): controller.on_drag_leave(drag_context, time) def drag_and_drop_get_destination(self, widget, x, y): if widget != self.page_layout: return None for controller in self.controllers.values(): r = controller.drag_and_drop_get_destination(x, y) if r is not None: return r return None def _on_draw(self, layout, cairo_context): for controller in self.controllers.values(): controller.on_draw(cairo_context) def _on_overlay_draw(self, widget, cairo_context): for controller in self.controllers.values(): controller.on_overlay_draw(widget, cairo_context) def doc_close(self): for page in self.pages: page.set_visible(False) for controller in self.controllers.values(): controller.on_close() def _build_flow_box_child(self, child): widget = Gtk.FlowBoxChild.new() widget.set_visible(True) widget.set_property('name', 'docview_page') widget.set_property('halign', Gtk.Align.CENTER) widget.add(child) return widget def doc_open(self, doc_id, doc_url): self.doc_close() self.core.call_success( "mainwindow_show", side="right", name="docview" ) self.zoom = 0.0 self.layout_name = 'grid' self.active_doc = (doc_id, doc_url) self.active_doc_mtime = self.core.call_success( "doc_get_mtime_by_url", doc_url ) self.active_page_idx = 0 self.pages = [] self.widget_to_page = {} self.page_to_widget = {} self.nb_visible_pages = 0 self.controllers = {} self.core.call_all( "gtk_docview_get_controllers", self.controllers, self ) for controller in self.controllers.values(): controller.enter() def doc_reload(self, doc_id, doc_url): if self.active_doc != (doc_id, doc_url): LOGGER.info( "Reload requested for document %s, but active doc is %s", (doc_id, doc_url), self.active_doc ) return mtime = self.core.call_success("doc_get_mtime_by_url", doc_url) if mtime == self.active_doc_mtime: LOGGER.info( "Reload for document %s requested, but mtime hasn't changed" " (%s)", doc_url, mtime ) return self.active_doc_mtime = mtime LOGGER.info("Reloading document %s", self.active_doc) for controller in self.controllers.values(): controller.doc_reload() def on_page_size_obtained(self, page): # page may been wrapped page = self.pages[page.page_idx] for controller in self.controllers.values(): controller.on_page_size_obtained(page) def on_page_shown(self, page_idx): self.active_page_idx = page_idx page = self.pages[page_idx] widget = self.page_to_widget[page] self.page_layout.select_child(widget) def doc_goto_previous_page(self): self.doc_goto_page(self.active_page_idx - 1) def doc_goto_next_page(self): self.doc_goto_page(self.active_page_idx + 1) def doc_goto_page(self, page_idx): LOGGER.info( "Going to page %d (nb pages=%d)", page_idx, self.nb_visible_pages ) if page_idx < 0: page_idx = 0 if page_idx >= self.nb_visible_pages: page_idx = self.nb_visible_pages - 1 self.requested_page_idx = page_idx for controller in self.controllers.values(): controller.doc_goto_page(page_idx) self.core.call_all("on_page_shown", page_idx) def docview_set_layout(self, name): self.layout_name = name for controller in self.controllers.values(): controller.docview_set_layout(name) def docview_set_zoom(self, zoom): self.zoom = zoom for controller in self.controllers.values(): controller.docview_set_zoom(zoom) def docview_add_page_viewer(self, page, visible=True): widget = self._build_flow_box_child(page.widget) self.widget_to_page[widget] = page self.page_to_widget[page] = widget self.pages.append(page) if visible: self.nb_visible_pages += 1 self.page_layout.add(widget) def docview_hide_page_viewer(self, page): # Jflesch> Hiding is not enough. We have to remove the widget # otherwise it's still taken into account when computing # the layout (keep in mind that homogenous is set to True) self.page_layout.remove(self.page_to_widget[page]) self.nb_visible_pages -= 1 def docview_show_page_viewer(self, page): # XXX(Jflesch): We mess up the order of the widgets here. But since # only the scan viewer uses this method at the moment, it's fine. self.page_layout.add(self.page_to_widget[page]) self.nb_visible_pages += 1 def on_mainwindow_fold_change(self): folded = self.core.call_success("mainwindow_get_folded") self.widget_tree.get_object("docview_header").set_show_close_button( not folded ) self.widget_tree.get_object("docview_back").set_visible(folded) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/000077500000000000000000000000001456262201400301565ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/__init__.py000066400000000000000000000037551456262201400323010ustar00rootroot00000000000000import logging LOGGER = logging.getLogger(__name__) class BaseDocViewController(object): def __init__(self, plugin): self.plugin = plugin def __str__(self): return str(type(self)) def enter(self): LOGGER.debug("%s", self.enter) def exit(self): LOGGER.debug("%s", self.exit) def on_layout_size_allocate(self, layout): LOGGER.debug("%s(%s)", self.on_layout_size_allocate, layout) def on_page_size_obtained(self, page): LOGGER.debug("%s(%d)", self.on_page_size_obtained, page.page_idx) def on_vscroll(self, vadj): LOGGER.debug( "%s(%d, %d)", self.on_vscroll, vadj.get_value(), vadj.get_upper() ) def on_vscroll_changed(self, vadj): self.on_vscroll(vadj) def on_vscroll_value_changed(self, vadj): self.on_vscroll(vadj) def doc_goto_page(self, page_idx): LOGGER.debug("%s(%d)", self.doc_goto_page, page_idx) def docview_set_layout(self, name): LOGGER.debug("%s(%s)", self.docview_set_layout, name) def docview_set_zoom(self, zoom): LOGGER.debug("%s(%f)", self.docview_set_zoom, zoom) def doc_reload(self): LOGGER.debug("%s()", self.doc_reload) def on_page_activated(self, page): LOGGER.debug("%s(%d)", self.on_page_activated, page.page_idx) def on_drag_motion(self, drag_context, x, y, time): LOGGER.debug("%s()", self.on_drag_motion) def on_drag_leave(self, drag_context, time): LOGGER.debug("%s()", self.on_drag_leave) def drag_and_drop_get_destination(self, x, y): LOGGER.debug("%s(%d, %d)", self.drag_and_drop_get_destination, x, y) def on_draw(self, cairo_context): # no LOGGER.debug() here for performance reasons pass def on_overlay_draw(self, overlay_drawing_area, cairo_context): # no LOGGER.debug() here for performance reasons pass def on_close(self): LOGGER.debug("%s()", self.on_close) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/autoscrolling.py000066400000000000000000000023651456262201400334230ustar00rootroot00000000000000import logging import openpaperwork_core from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class AutoScrollingController(BaseDocViewController): def __init__(self, plugin): super().__init__(plugin) self.handler = None self.enter() def enter(self): if self.handler is not None: return self.handler = self.plugin.core.call_success( "gesture_enable_autoscrolling", self.plugin.scroll ) def exit(self): if self.handler is None: return self.handler.disable() self.handler = None def on_close(self): self.exit() class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'gtk_gesture_autoscrolling', 'defaults': ['openpaperwork_gtk.gesturee.autoscrolling'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): out['autoscrolling'] = AutoScrollingController(docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/click.py000066400000000000000000000023141456262201400316150ustar00rootroot00000000000000import logging import openpaperwork_core from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class ClickController(BaseDocViewController): def on_page_activated(self, page): super().on_page_activated(page) LOGGER.info("User activated page %d", page.page_idx) self.plugin.core.call_all("docview_set_layout", "paged") self.plugin.core.call_all("doc_goto_page", page.page_idx) def docview_set_layout(self, name): if name == 'grid': return self.plugin.docview_switch_controller('click', NoClickController) class NoClickController(BaseDocViewController): def docview_set_layout(self, name): if name != 'grid': return self.plugin.docview_switch_controller('click', ClickController) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): out['click'] = ClickController(docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/drop.py000066400000000000000000000111451456262201400314760ustar00rootroot00000000000000""" When drag'n'dropping, enables the dropping-in-a-document part. """ import logging import openpaperwork_core import openpaperwork_core.promise from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class DropController(BaseDocViewController): LINE_BORDERS = 10 LINE_WIDTH = 3 LINE_COLOR = (0.0, 0.8, 1.0, 1.0) def __init__(self, core, plugin): super().__init__(plugin) self.core = core self.closest = None self.beforeafter = -1 # 0 for before the widget, 1 for after @staticmethod def _compute_squared_distance(rect, x, y): pts = ( (rect.x, rect.y), (rect.x + rect.width, rect.y), (rect.x, rect.y + rect.height), (rect.x + rect.width, rect.y + rect.height), ) dists = { ((abs(pt[0] - x) ** 2) + (abs(pt[1] - y) ** 2)) for pt in pts } return min(dists) def _compute_closest(self, x, y): dists = { ( self._compute_squared_distance(widget.get_allocation(), x, y), widget ) for widget in self.plugin.page_layout.get_children() } try: return min(dists)[1] except ValueError: # empty list of widgets return None @staticmethod def _compute_beforeafter(rect, x, y): center = rect.x + (rect.width / 2) return 0 if x < center else 1 def on_drag_motion(self, drag_context, x, y, time): super().on_drag_motion(drag_context, x, y, time) self.closest = self._compute_closest(x, y) if self.closest is None: self.beforeafter = -1 return self.beforeafter = self._compute_beforeafter( self.closest.get_allocation(), x, y ) self.plugin.page_layout.queue_draw() def on_drag_leave(self, drag_context, time): super().on_drag_leave(drag_context, time) self.closest = None self.plugin.page_layout.queue_draw() def on_draw(self, cairo_ctx): super().on_draw(cairo_ctx) if self.closest is None: return allocation = self.closest.get_allocation() height = allocation.height x = allocation.x x -= 2 * self.LINE_BORDERS x += (self.beforeafter * (allocation.width + 2 * self.LINE_BORDERS)) x = max(0, x) y = allocation.y cairo_ctx.save() try: cairo_ctx.set_source_rgba(*self.LINE_COLOR) cairo_ctx.set_line_width(self.LINE_WIDTH) cairo_ctx.move_to(x + self.LINE_BORDERS, y) cairo_ctx.line_to(x + self.LINE_BORDERS, y + height) cairo_ctx.stroke() cairo_ctx.move_to(x, y + self.LINE_BORDERS) cairo_ctx.line_to( x + (2 * self.LINE_BORDERS), y + self.LINE_BORDERS ) cairo_ctx.stroke() cairo_ctx.move_to(x, y + height - self.LINE_BORDERS) cairo_ctx.line_to( x + (2 * self.LINE_BORDERS), y + height - self.LINE_BORDERS ) cairo_ctx.stroke() finally: cairo_ctx.restore() def drag_and_drop_get_destination(self, x, y): super().drag_and_drop_get_destination(x, y) closest = self._compute_closest(x, y) if closest is None: dst_page_idx = 0 else: page = self.plugin.widget_to_page[closest] beforeafter = self._compute_beforeafter( closest.get_allocation(), x, y ) dst_page_idx = page.page_idx + beforeafter return (*self.plugin.active_doc, dst_page_idx) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return [ 'chkdeps', 'gtk_docview_controller', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'gtk_drag_and_drop', 'defaults': ['paperwork_gtk.gesture.drag_and_drop'], }, ] def on_gtk_docview_init(self, docview): self.core.call_all("drag_and_drop_page_enable", docview.page_layout) def gtk_docview_get_controllers(self, out: dict, docview): out['drop'] = DropController(self.core, docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/000077500000000000000000000000001456262201400321415ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc/__init__.py000066400000000000000000000133071456262201400342560ustar00rootroot00000000000000import logging try: import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): CAIRO_AVAILABLE = False try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False try: import gi gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango from gi.repository import PangoCairo PANGO_AVAILABLE = True except (ImportError, ValueError): PANGO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps from .. import BaseDocViewController from ..... import _ LOGGER = logging.getLogger(__name__) class BaseDisplayNewDocController(BaseDocViewController): def __init__(self, docview, empty_doc_plugin): super().__init__(docview) self.empty_doc_plugin = empty_doc_plugin self.core = empty_doc_plugin.core def _switch_controller(self): nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", self.plugin.active_doc[1] ) if nb_pages is None: nb_pages = 0 if nb_pages > 0 or self.empty_doc_plugin.scanning: self.plugin.docview_switch_controller( "new_doc", lambda docview: NoDisplayController( docview, self.empty_doc_plugin ) ) else: self.plugin.docview_switch_controller( "new_doc", lambda docview: DisplayNewDocController( docview, self.empty_doc_plugin ) ) def doc_reload(self): self._switch_controller() class DisplayNewDocController(BaseDisplayNewDocController): def __init__(self, docview, plugin): super().__init__(docview, plugin) self.core = docview.core def enter(self): self.plugin.overlay.set_visible(True) def on_overlay_draw(self, overlay_drawing_area, cairo_ctx): if self.empty_doc_plugin.scanning: self._switch_controller() return img = self.empty_doc_plugin.img alloc = overlay_drawing_area.get_allocation() style = overlay_drawing_area.get_style_context() color = style.get_color(Gtk.StateFlags.ACTIVE) layout = PangoCairo.create_layout(cairo_ctx) layout.set_text(_("Empty"), -1) # text must be short txt_size = layout.get_size() if 0 in txt_size: return zoom = img.get_height() / txt_size[1] scaled_txt_width = txt_size[0] * zoom cairo_ctx.save() try: cairo_ctx.set_source_rgba(color.red, color.green, color.blue, 0.33) cairo_ctx.mask_surface( self.empty_doc_plugin.img, ((alloc.width - img.get_width() - scaled_txt_width) / 2), ((alloc.height - img.get_height()) / 2), ) cairo_ctx.fill() finally: cairo_ctx.restore() cairo_ctx.save() try: cairo_ctx.set_source_rgba(color.red, color.green, color.blue, 0.33) cairo_ctx.translate( ((alloc.width - img.get_width() - scaled_txt_width) / 2) + img.get_width(), ((alloc.height - img.get_height()) / 2), ) cairo_ctx.scale(zoom * Pango.SCALE, zoom * Pango.SCALE) PangoCairo.update_layout(cairo_ctx, layout) PangoCairo.show_layout(cairo_ctx, layout) finally: cairo_ctx.restore() class NoDisplayController(BaseDisplayNewDocController): def enter(self): self.plugin.overlay.set_visible(False) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.scanning = False def get_interfaces(self): return [ 'chkdeps', 'gtk_docview_controller', ] def get_deps(self): return [ { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, ] def init(self, core): super().init(core) if not CAIRO_AVAILABLE: # chkdeps() must still be callable return file_path = self.core.call_success( "resources_get_file", "paperwork_gtk.mainwindow.docview.controllers.empty_doc", "empty_doc.png" ) file_path = self.core.call_success("fs_unsafe", file_path) self.img = cairo.ImageSurface.create_from_png(file_path) def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'].update(openpaperwork_core.deps.CAIRO) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) if not PANGO_AVAILABLE: out['pango'].update(openpaperwork_core.deps.PANGO) def on_scan2doc_start(self, *args, **kwargs): self.scanning = True def on_scan2doc_end(self, *args, **kwargs): self.scanning = False def gtk_docview_get_controllers(self, out: dict, docview): nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", docview.active_doc[1] ) if nb_pages is None: nb_pages = 0 out['new_doc'] = ( DisplayNewDocController(docview, self) if nb_pages <= 0 else NoDisplayController(docview, self) ) empty_doc.png000066400000000000000000000025151456262201400345560ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/empty_doc‰PNG  IHDR\`WŽàzTXtRaw profile type exifxÚí—Mrä …÷œbŽ€$„Äq0˜ª¹Á˜t§“žTÍÏbmÊ6B‚÷„óÇ÷¾á¢"1$5Ï%çˆ+•T¸¢âñº®7Å´žëÒ¶ÛèÑò¶G†Ið–ë3ŸÛ¿Â®÷–¶ýx´ÛØw ÝðPffFeûù$|Ùi‡²ûÕôn:ûW³WÓÇïd£+â >…$âé3‹\wÅð$q8‘êiÙ“ØsíÂÐçâÝj´‹uÛåQŠßÔÎ4ÚvÒçÚ-…Þˆî™Ln)>k7ºq^³«)C©ö¤Þ¦²jp„œIV·Œb¸u[¥ 8¦Ø@¬ƒæÒb¨=(Q§JƒÎõnÔ0ÄÄ'ÞÌeÙ\Œ 7™Ò,4ؤHâàÔ@M`æÛXhå-+_#GæNðdB0BO%<3þI¹c.]¢è['€y®i c’›Ox­©.}W ïÖM|V@P—ÌŽ Öx\!¥ûÚ’ÅYà§1…xm ²¾@"äV †b&QÊÙˆ £ƒOÅÈY @ªÜ) °É€ƒÝ€Üèc´|Yù2ãh•Œ­â T+%Åú±äXCUESPÕ¬¦®Ek–œ²æœ-Ï3ªšX2µlfnŪ‹'WÏnî^¼.‚#LK.Š—RjEҊн+ʨ7j´·í5ú@îkj´©MbiùÙÌfo!h':™'q›° y2‹N)ñ$7™ÅÂØÊ F:átšÄ@0Ä:èÆîNîKnAÓoqã_‘ Ý¿ &ºMî3·'Ôz]¿(²Í]852p°ÁáôÊ^çoÒ¿Ãßxzzzzzzú üñ€ÿÃOlØ’¹çÔzbKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEä(/³A.îIDATxÚíÝANÂ@†ác`å *&ÞÀû¸v‡œ ®"¸ª+V’xéšqQؘ ÌLÿæ}“îÒ>i†ÚΈDD4HIsIkI¤àdë$­$Íçà¢FÒ—#äS[+éÑÕ]öqÛJz² >/Ûúgà¦Ñw…‚I?’ž­‡Â7sètÀ‹F ^4zÝ6¸…¦’¾½¢{wîÜ-ºgp—èÞÁÝ¡—î ½p7è%ëðHváÑîð¼è­½#-<ú ð¼è€çý"ÝžðÌè€ß8¦'=ßÑ…à±?ÓrIÏ÷N”5ÀœœœpppGuWìû øímí ø‰Wì»Lq5½b“úÉ=­.›4Çþ¯ÌMeå¯gp"¢3ýõT“¯‰Ò¦IEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/layout.py000066400000000000000000000100021456262201400320360ustar00rootroot00000000000000import logging import openpaperwork_core from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class BaseLayoutController(BaseDocViewController): def __init__(self, plugin): super().__init__(plugin) self.core = plugin.core self.real_nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", self.plugin.active_doc[1] ) if self.real_nb_pages is None: self.real_nb_pages = 0 def on_close(self): for page in self.plugin.page_layout.get_children(): # weird but has to be done. Otherwise it seems the children # are destroyed with 'page' for c in page.get_children(): page.remove(c) self.plugin.page_layout.remove(page) self.plugin.pages = [] self.plugin.widget_to_page = {} self.plugin.page_to_widget = {} def _update_visibility(self): vadj = self.plugin.scroll.get_vadjustment() lower = vadj.get_lower() p_min = vadj.get_value() - lower p_max = vadj.get_value() + vadj.get_page_size() - lower for widget in self.plugin.page_layout.get_children(): alloc = widget.get_allocation() p_lower = alloc.y p_upper = alloc.y + alloc.height visible = (p_min <= p_upper and p_lower <= p_max) page = self.plugin.widget_to_page[widget] page.set_visible(visible) def on_vscroll_value_changed(self, vadj): super().on_vscroll_value_changed(vadj) self._update_visibility() def on_vscroll_changed(self, vadj): super().on_vscroll_changed(vadj) self._update_visibility() def on_page_size_obtained(self, page): super().on_page_size_obtained(page) self._update_visibility() def on_layout_size_allocate(self, layout): super().on_layout_size_allocate(layout) self._update_visibility() def _add_pages(self): pages = [] self.core.call_all( "doc_open_components", pages, *self.plugin.active_doc ) for (visible, page) in pages: self.plugin.docview_add_page_viewer(page, visible) def doc_reload(self): super().doc_reload() LOGGER.info("Reloading document %s", self.plugin.active_doc) self.on_close() self._add_pages() for page in self.plugin.pages: page.load() class LayoutControllerLoading(BaseLayoutController): def __init__(self, plugin): super().__init__(plugin) self.nb_loaded = 0 # page instantiation must be done before the calls to enter() # because other controllers may need the pages. So we cheat a little # bit and make it in the constructor. self._add_pages() def enter(self): super().enter() if len(self.plugin.pages) <= 0: self.plugin.docview_switch_controller( 'layout', LayoutControllerLoaded ) return self.nb_loaded = 0 for page in self.plugin.pages: page.load() def on_page_size_obtained(self, page): super().on_page_size_obtained(page) self.nb_loaded += 1 if self.nb_loaded >= len(self.plugin.pages): self.plugin.docview_switch_controller( 'layout', LayoutControllerLoaded ) def exit(self): LOGGER.info( "Size of all pages of doc %s loaded", self.plugin.active_doc[0] ) class LayoutControllerLoaded(BaseLayoutController): def enter(self): super().enter() self._update_visibility() class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): out['layout'] = LayoutControllerLoading(docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/page_number.py000066400000000000000000000055741456262201400330270ustar00rootroot00000000000000import logging import openpaperwork_core from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class PageNumberController(BaseDocViewController): def _get_closest_widget(self): vadj = self.plugin.scroll.get_vadjustment() view_width = self.plugin.scroll.get_allocated_width() view_height = self.plugin.scroll.get_allocated_height() center = ( view_width / 2, vadj.get_value() + (view_height / 2) ) # look if the center is precisely on in a widget for widget in self.plugin.page_layout.get_children(): if not widget.get_visible(): continue alloc = widget.get_allocation() if alloc.width < 10 or alloc.height < 10: continue if (alloc.x <= center[0] and alloc.y <= center[1] and alloc.x + alloc.width >= center[0] and alloc.y + alloc.height >= center[1]): return widget # else look for the closest widget min_dist = (99999999999999999, None) for widget in self.plugin.page_layout.get_children(): if not widget.get_visible(): continue alloc = widget.get_allocation() if alloc.width < 10 or alloc.height < 10: continue widget_center = ( (alloc.x + (alloc.width / 2)), (alloc.y + (alloc.height / 2)), ) dist_w = (center[0] - widget_center[0]) dist_h = (center[1] - widget_center[1]) dist = (dist_w * dist_w) + (dist_h * dist_h) if dist < min_dist[0]: min_dist = (dist, widget) return min_dist[1] def _update_current_page(self): widget = self._get_closest_widget() if widget is None: return page = self.plugin.widget_to_page[widget] self.plugin.core.call_all("on_page_shown", page.page_idx) def on_layout_size_allocate(self, layout): super().on_layout_size_allocate(layout) self._update_current_page() def on_page_size_obtained(self, layout): super().on_page_size_obtained(layout) self._update_current_page() def on_vscroll_changed(self, vadj): super().on_vscroll_changed(vadj) self._update_current_page() def on_vscroll_value_changed(self, vadj): super().on_vscroll_value_changed(vadj) self._update_current_page() class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): out['page_number'] = PageNumberController(docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/scroll.py000066400000000000000000000105641456262201400320340ustar00rootroot00000000000000import logging import openpaperwork_core from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class Scroller(object): def __init__(self, controller, widget): self.controller = controller self.widget = widget self.allocate_handler_id = None def goto(self): alloc = self.widget.get_allocation() if alloc.y < 0: self.allocate_handler_id = self.widget.connect( "size-allocate", self._goto_on_allocate ) else: self._goto_on_allocate() def _goto_on_allocate(self, *args, **kwargs): alloc = self.widget.get_allocation() assert alloc.y >= 0 self.controller.last_value = alloc.y self.controller.plugin.scroll.get_vadjustment().set_value(alloc.y) if self.allocate_handler_id is not None: self.widget.disconnect(self.allocate_handler_id) self.allocate_handler_id = None class ScrollPageLockedController(BaseDocViewController): def __init__(self, plugin): super().__init__(plugin) self.last_upper = -1 self.last_value = -1 def enter(self): self.last_value = self.plugin.scroll.get_vadjustment().get_value() self.last_upper = self.plugin.scroll.get_vadjustment().get_upper() self.doc_goto_page(self.plugin.requested_page_idx) def doc_goto_page(self, page_idx): super().doc_goto_page(page_idx) for widget in self.plugin.page_layout.get_children(): page = self.plugin.widget_to_page[widget] if page.page_idx != page_idx: continue Scroller(self, widget).goto() def on_page_size_obtained(self, page): super().on_page_size_obtained(page) self.doc_goto_page(self.plugin.requested_page_idx) def on_layout_size_allocate(self, layout): super().on_layout_size_allocate(layout) self.doc_goto_page(self.plugin.requested_page_idx) def docview_set_layout(self, name): super().docview_set_layout(name) self.doc_goto_page(self.plugin.requested_page_idx) def docview_set_zoom(self, zoom): super().docview_set_zoom(zoom) self.doc_goto_page(self.plugin.requested_page_idx) def docview_reload_page(self, page_idx): super().docview_reload_page(page_idx) self.doc_goto_page(self.plugin.requested_page_idx) def on_vscroll_changed(self, adj): super().on_vscroll_changed(adj) if adj.get_upper() == self.last_upper: return self.last_upper = adj.get_upper() self.doc_goto_page(self.plugin.requested_page_idx) def on_vscroll_value_changed(self, adj): super().on_vscroll_value_changed(adj) if adj.get_value() == self.last_value: return self.last_value = adj.get_value() self.plugin.docview_switch_controller('scroll', ScrollFreeController) class ScrollFreeController(BaseDocViewController): def __init__(self, plugin): super().__init__(plugin) self.scroll_proportion = None def _upd_proportion(self): vadj = self.plugin.scroll.get_vadjustment() self.scroll_proportion = vadj.get_value() / vadj.get_upper() def enter(self): self._upd_proportion() def doc_goto_page(self, page_idx): self.plugin.docview_switch_controller( 'scroll', ScrollPageLockedController ) def _on_vscroll(self, adj): if self.scroll_proportion is None: return pos = self.scroll_proportion * adj.get_upper() self.scroll_proportion = None adj.set_value(pos) def docview_set_zoom(self, zoom): self._upd_proportion() def docview_set_layout(self, name): self._upd_proportion() def on_vscroll_changed(self, adj): super().on_vscroll_changed(adj) self._on_vscroll(adj) def on_vscroll_value_changed(self, adj): super().on_vscroll_value_changed(adj) self._on_vscroll(adj) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): out['scroll'] = ScrollPageLockedController(docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/title.py000066400000000000000000000041171456262201400316540ustar00rootroot00000000000000import openpaperwork_core from .... import _ from . import BaseDocViewController class TitleController(BaseDocViewController): def enter(self): folded = self.plugin.core.call_success("mainwindow_get_folded") if folded: self.plugin.widget_tree.get_object( "docview_header" ).set_title("") return (doc_id, doc_url) = self.plugin.active_doc if self.plugin.core.call_success("is_doc", doc_url) is not None: doc_date = self.plugin.core.call_success( "doc_get_date_by_id", doc_id ) if doc_date is not None: doc_date = self.plugin.core.call_success( "i18n_date_short", doc_date ) else: doc_date = doc_id self.plugin.widget_tree.get_object( "docview_header" ).set_title(doc_date) else: self.plugin.widget_tree.get_object( "docview_header" ).set_title(_("New document")) def on_close(self): self.plugin.widget_tree.get_object("docview_header").set_title("") class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.controller = None def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): self.controller = TitleController(docview) out['title'] = self.controller def on_mainwindow_fold_change(self): if self.controller is None: return # update the title bar self.controller.enter() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/controllers/zoom.py000066400000000000000000000055551456262201400315260ustar00rootroot00000000000000import logging import openpaperwork_core from . import BaseDocViewController LOGGER = logging.getLogger(__name__) class ZoomLayoutController(BaseDocViewController): def __init__(self, plugin): super().__init__(plugin) self.last_zoom = -1 def _recompute_zoom(self): layout_name = self.plugin.layout_name spacing = self.plugin.page_layout.get_column_spacing() nb_columns = self.plugin.LAYOUTS[layout_name] max_columns = 0 view_width = self.plugin.scroll.get_allocated_width() zoom = 1.0 for page_idx in range(0, len(self.plugin.pages), nb_columns): pages = self.plugin.pages[page_idx:page_idx + nb_columns] pages_width = sum([p.get_full_size()[0] for p in pages]) pages_width += (len(pages) * 30 * spacing) + 1 zoom = min(zoom, view_width / pages_width) max_columns = max(max_columns, len(pages)) if zoom == self.last_zoom: return self.last_zoom = zoom self.plugin.core.call_all("docview_set_zoom", zoom) for page in self.plugin.pages: page.set_zoom(zoom) if nb_columns > 1: layout = 'grid' else: layout = 'paged' self.plugin.core.call_all("on_layout_change", layout) def enter(self): super().enter() self._recompute_zoom() def docview_set_zoom(self, zoom): super().docview_set_zoom(zoom) if zoom == self.last_zoom: return self.plugin.docview_switch_controller('zoom', ZoomCustomController) def docview_set_layout(self, name): super().docview_set_layout(name) self._recompute_zoom() def on_page_size_obtained(self, page): super().on_page_size_obtained(page) self._recompute_zoom() def on_layout_size_allocate(self, layout): self._recompute_zoom() def doc_reload(self): self._recompute_zoom() class ZoomCustomController(BaseDocViewController): def _reapply_zoom(self): zoom = self.plugin.zoom for page in self.plugin.pages: page.set_zoom(zoom) def enter(self): super().enter() self._reapply_zoom() def docview_set_zoom(self, zoom): super().docview_set_zoom(zoom) self._reapply_zoom() def docview_set_layout(self, name): super().docview_set_layout(name) self.plugin.docview_switch_controller('zoom', ZoomLayoutController) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['gtk_docview_controller'] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, ] def gtk_docview_get_controllers(self, out: dict, docview): out['zoom'] = ZoomLayoutController(docview) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/docview.css000066400000000000000000000003001456262201400277530ustar00rootroot00000000000000#docview_scroll { background-color: shade(@theme_bg_color, 0.95); } #docview_box { margin-top: 10px; } #docview_page_layout flowboxchild:selected { padding: 7px; border-radius: 7px; } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/docview.glade000066400000000000000000000106301456262201400302460ustar00rootroot00000000000000 True False False False True True False docview_scroll True True in True False True False vertical docview_box docview_page_layout True True 10 10 1 5 horizontal center True False True 0 True False True True 1 -1 True False True True :minimize,maximize,close False True False False True none True False go-previous-symbolic 2 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/drag.py000066400000000000000000000070741456262201400271070ustar00rootroot00000000000000""" When drag'n'dropping, enables the dragging-from-pages part. """ import logging try: import gi gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') from gi.repository import Gdk from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) TARGET_ENTRY_URI = 0 class Plugin(openpaperwork_core.PluginBase): PRIORITY = -10000 def __init__(self): super().__init__() self.pages = [] self.active_doc = None self.enabled = False def get_interfaces(self): return [ 'chkdeps', 'gtk_pageview', ] def get_deps(self): return [ { 'interface': 'page_img', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def _enable_drag(self, widget, doc_id, doc_url, page_idx): widget.drag_source_set( Gdk.ModifierType.BUTTON1_MASK, [], Gdk.DragAction.MOVE ) targets = Gtk.TargetList.new([]) targets.add_uri_targets(TARGET_ENTRY_URI) widget.drag_source_set_target_list(targets) widget.drag_source_set_icon_name("document-send-symbolic") widget.connect( "drag-data-get", self._on_drag_data_get, doc_id, doc_url, page_idx ) def _disable_drag(self, widget): widget.drag_source_unset() def _on_drag_data_get( self, widget, drag_context, data, info, time, doc_id, doc_url, page_idx): LOGGER.info("drag_data_get(%s, p%d, type=%d)", doc_id, page_idx, info) if info == TARGET_ENTRY_URI: # drag'n'drop API allows us to provide many URIs. But if we # do, applications like Firefox will try to display them all, # even if they don't understand the URI scheme. # --> we cheat and use the URI target for the extra info we may # need in Paperwork img_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) if img_url is None: return img_url = img_url.split("#", 1)[0] img_url += "#doc_id={}&page={}".format(doc_id, page_idx) LOGGER.info("Img URL: {}".format(img_url)) data.set_uris([img_url]) return assert False def doc_open_components(self, out: list, doc_id, doc_url): self.active_doc = (doc_id, doc_url) self.pages = [p[1] for p in out] if self.enabled: for (visible, page) in out: if visible: self._enable_drag( page.widget, doc_id, doc_url, page.page_idx ) def on_layout_change(self, layout_name): enabled = (layout_name == 'grid') if enabled == self.enabled: return if enabled: LOGGER.info("Layout %s --> Enabling drag(-and-drop)", layout_name) for page in self.pages: self._enable_drag(page.widget, *self.active_doc, page.page_idx) else: LOGGER.info("Layout %s --> Disabling drag(-and-drop)", layout_name) for page in self.pages: self._disable_drag(page.widget) self.enabled = enabled paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/000077500000000000000000000000001456262201400271755ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/__init__.py000066400000000000000000000000001456262201400312740ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.glade000066400000000000000000000023121456262201400316670ustar00rootroot00000000000000 True False False True False False Add page 0 False True False 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/buttons.py000066400000000000000000000067011456262201400312510ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None self.default_action = None self.default_action_args = None self.active_doc_id = None self.active_doc_url = None self.busy = 0 def get_interfaces(self): return [ 'doc_open', 'gtk_scan_buttons', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'new_doc', 'defaults': ['paperwork_gtk.new_doc'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def init(self, core): super().init(core) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageadd", "buttons.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.widget_tree.get_object("pageadd_button").connect( "clicked", self._on_clicked ) headerbar = self.core.call_success("docview_get_headerbar") headerbar.pack_start(self.widget_tree.get_object("pageadd_buttons")) def pageadd_buttons_set_source_popover(self, selector): self.widget_tree.get_object("pageadd_switch").set_popover(selector) def _update_sensitivity(self): sensitive = ( self.default_action is not None and self.busy <= 0 ) button = self.widget_tree.get_object("pageadd_button") button.set_sensitive(sensitive) self.core.call_all("on_widget_busyness_changed", button, sensitive) def pageadd_set_default_action(self, txt, callback, *args): self.default_action = callback self.default_action_args = args self.widget_tree.get_object("pageadd_button").set_label(txt) self._update_sensitivity() def pageadd_busy_add(self): self.busy += 1 self._update_sensitivity() def pageadd_busy_remove(self): self.busy -= 1 self._update_sensitivity() def _on_clicked(self, widget): self.default_action( self.active_doc_id, self.active_doc_url, *self.default_action_args ) def doc_open(self, doc_id, doc_url): self.active_doc_id = doc_id self.active_doc_url = doc_url self._update_sensitivity() def doc_close(self): self.active_doc_id = None self.active_doc_url = None self._update_sensitivity() def on_scan_feed_start(self, scan_id): self.pageadd_busy_add() def on_scan_feed_end(self, scan_id): self.pageadd_busy_remove() def screenshot_snap_all_doc_widgets(self, out_dir): self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("pageadd_buttons"), self.core.call_success("fs_join", out_dir, "page_add.png") ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/import.py000066400000000000000000000123031456262201400310600ustar00rootroot00000000000000import logging import random try: import gi GI_AVAILABLE = True except (ImportError, ValueError): GI_AVAILABLE = False try: GTK_AVAILABLE = False if GI_AVAILABLE: gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): pass import openpaperwork_core import openpaperwork_core.promise import openpaperwork_gtk.deps from .... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None self.windows = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_scan_buttons_popover_sources', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'gtk_doc_import', 'defaults': ['paperwork_gtk.docimport'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_scan_buttons_popover', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageadd.source_popover' ], }, ] def init(self, core): super().init(core) if not GTK_AVAILABLE: return opt = self.core.call_success( "config_build_simple", "GUI", "last_import_uri", lambda: None ) self.core.call_all("config_register", "last_import_uri", opt) self.core.call_all( "mainloop_schedule", self.core.call_all, "pageadd_sources_refresh" ) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def pageadd_get_sources(self, out: list): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageadd", "source_box.glade" ) source_long_txt = _("Import document or image file(s)") source_short_txt = _("Import file(s)") img = "insert-image-symbolic" widget_tree.get_object("source_image").set_from_icon_name( img, Gtk.IconSize.SMALL_TOOLBAR ) widget_tree.get_object("source_name").set_text(source_long_txt) out.append( ( widget_tree.get_object("source_selector"), source_short_txt, "import", self._on_import ) ) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _on_import(self, doc_id, doc_url, source_id): LOGGER.info("Opening file chooser dialog") mimes = set() self.core.call_all("get_import_mime_types", mimes) mimes = list(mimes) mimes.sort() dialog = Gtk.FileChooserDialog( _("Select a file or a directory to import"), self.windows[-1], Gtk.FileChooserAction.OPEN, ( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, # WORKAROUND(Jflesch): Use response ID 0 so the user # can select a folder. Gtk.STOCK_OPEN, 0 ) ) dialog.set_select_multiple(True) dialog.set_local_only(False) filter_all = Gtk.FileFilter() filter_all.set_name(_("All supported file formats")) for (txt, mime) in mimes: filter_all.add_mime_type(mime) dialog.add_filter(filter_all) file_filter = Gtk.FileFilter() file_filter.set_name(_("Any files")) file_filter.add_pattern("*.*") dialog.add_filter(file_filter) for (txt, mime) in mimes: file_filter = Gtk.FileFilter() file_filter.add_mime_type(mime) file_filter.set_name(txt) dialog.add_filter(file_filter) dialog.set_filter(filter_all) last_import_uri = self.core.call_success( "config_get", "last_import_uri" ) if last_import_uri is not None: # this filename does not exist, but the parent directory # will be selected. A hack inspired by what firefox does. dialog.set_uri(last_import_uri + str(random.randint(0, 10000))) dialog.connect("response", self._on_dialog_response) self.core.call_all("pageadd_busy_add") dialog.show_all() def _on_dialog_response(self, dialog, response_id): self.core.call_all("pageadd_busy_remove") if (response_id != 0 and response_id != Gtk.ResponseType.ACCEPT and response_id != Gtk.ResponseType.OK and response_id != Gtk.ResponseType.YES and response_id != Gtk.ResponseType.APPLY): LOGGER.info("User canceled (response_id=%d)", response_id) dialog.destroy() return selected = dialog.get_uris() dialog.destroy() self.core.call_all("config_put", "last_import_uri", selected[0]) self.core.call_all("gtk_doc_import", selected) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/scan.py000066400000000000000000000122501456262201400304730ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise import openpaperwork_gtk.deps from .... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None self.busy = False def get_interfaces(self): return [ 'chkdeps', 'gtk_scan_buttons_popover_sources', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_scan_buttons_popover', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageadd.source_popover' ], }, { 'interface': 'i18n_scanner', 'defaults': ['paperwork_backend.i18n.scanner'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, { 'interface': 'scan2doc', 'defaults': ['paperwork_backend.docscan.scan2doc'], }, ] def init(self, core): super().init(core) opt = self.core.call_success( "config_build_simple", "pageadd", "scanner_sources", lambda: [] ) self.core.call_all("config_register", "pageadd_sources", opt) self.core.call_all( "config_add_observer", "scanner_dev_id", self._update_sources ) self.core.call_all( "mainloop_schedule", self.core.call_all, "pageadd_sources_refresh" ) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def _update_sources(self): def get_sources(dev=None): if dev is None: source_names = [] else: sources = dev.dev.get_children() source_names = [] for src in sources: source_names.append(src.get_name()) sources = None LOGGER.info("Scanner sources: %s", source_names) return source_names def store_sources(sources): self.core.call_all("config_put", "pageadd_sources", list(sources)) promise = self.core.call_success("scan_get_scanner_promise") promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, get_sources )) promise = promise.then(store_sources) promise = promise.then(self.core.call_all, "pageadd_sources_refresh") self.core.call_success("scan_schedule", promise) def pageadd_get_sources(self, out: list): sources = self.core.call_success("config_get", "pageadd_sources") for source in list(sources): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageadd", "source_box.glade" ) source_txt = self.core.call_success( "i18n_scanner_source", source ) source_txt = _("Scan from %s") % source_txt img = "view-paged-symbolic" if "flatbed" in source: img = "document-new-symbolic" widget_tree.get_object("source_image").set_from_icon_name( img, Gtk.IconSize.SMALL_TOOLBAR ) widget_tree.get_object("source_name").set_text(source_txt) out.append( ( widget_tree.get_object("source_selector"), source_txt, source, self._on_scan ) ) def _on_scan(self, doc_id, doc_url, source_id): LOGGER.info("Scanning from %s", source_id) if doc_id is None or doc_url is None: (doc_id, doc_url) = self.core.call_success("get_new_doc") self.core.call_all("doc_open", doc_id, doc_url) self.core.call_all("on_busy") self.core.call_all("pageadd_busy_add") self.busy = True promise = self.core.call_success( "scan2doc_promise", doc_id=doc_id, doc_url=doc_url, source_id=source_id ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_all, "pageadd_busy_remove" ) self.core.call_success("scan_schedule", promise) def on_scan2doc_page_scanned(self, scan_id, doc_id, doc_url, nb_pages): LOGGER.info( "Page scanned: %s p%d (scan id = %d)", doc_id, nb_pages, scan_id ) self.core.call_all("doc_reload", doc_id, doc_url) def on_scan_started(self, scan_id): if not self.busy: return self.core.call_all("on_idle") self.busy = False paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/source_box.glade000066400000000000000000000034751456262201400323540ustar00rootroot00000000000000 True True False True True True False 12 12 12 12 12 True False gtk-missing-image False True 0 True False put a source name here False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/source_popover.glade000066400000000000000000000011021456262201400332370ustar00rootroot00000000000000 False True False vertical 20 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageadd/source_popover.py000066400000000000000000000067541456262201400326350ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None def get_interfaces(self): return [ 'gtk_scan_buttons_popover', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_scan_buttons', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageadd.buttons' ], }, ] def init(self, core): super().init(core) opt = self.core.call_success( "config_build_simple", "pageadd", "active_source", lambda: None ) self.core.call_all("config_register", "pageadd_active_source", opt) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageadd", "source_popover.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return def pageadd_sources_refresh(self): active = self.core.call_success("config_get", "pageadd_active_source") parent = self.widget_tree.get_object("page_sources_box") for child in parent.get_children(): parent.remove(child) selectors = [] self.core.call_all("pageadd_get_sources", selectors) for (selector, source_name, source_id, callback) in selectors[1:]: selector.join_group(selectors[0][0]) for (selector, source_name, source_id, callback) in selectors: selector.connect( "toggled", self._on_toggle, source_name, source_id, callback ) parent.pack_start(selector, expand=False, fill=True, padding=0) for (selector, source_name, source_id, callback) in selectors: if active == source_id: break else: active = None if active is None: if len(selectors) > 0: (selector, source_name, source_id, callback) = selectors[0] selector.set_active(True) self._on_toggle(selector, source_name, source_id, callback) else: for (selector, source_name, source_id, callback) in selectors: if active == source_id: selector.set_active(True) self._on_toggle(selector, source_name, source_id, callback) break # if there is a single choice, there is no point in letting # the user choose. This is just confusing. self.core.call_all( "pageadd_buttons_set_source_popover", self.widget_tree.get_object("page_sources_popover") if len(selectors) > 1 else None ) def _on_toggle(self, widget, source_name, source_id, callback): if not widget.get_active(): return self.core.call_all( "pageadd_set_default_action", source_name, callback, source_id ) self.core.call_all( "config_put", "pageadd_active_source", source_id ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/000077500000000000000000000000001456262201400274005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/__init__.py000066400000000000000000000116041456262201400315130ustar00rootroot00000000000000import logging import openpaperwork_core import paperwork_backend.sync LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None self.page_info = None self.active_doc = (None, None) self.nb_pages = None self.current_page = None self.nb_pages = None def get_interfaces(self): return [ 'doc_open', 'gtk_docview_pageinfo', 'syncable', ] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def init(self, core): super().init(core) self.core.call_success( "gtk_load_css", "paperwork_gtk.mainwindow.docview.pageinfo", "pageinfo.css" ) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageinfo", "pageinfo.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.page_info = self.widget_tree.get_object("page_info") self.current_page = self.widget_tree.get_object( "page_current_nb" ) self.current_page.connect("activate", self._change_page) self.nb_pages = self.widget_tree.get_object("page_total") button = self.widget_tree.get_object("page_prev") button.connect( "clicked", lambda *args, **kwargs: self.core.call_all( "doc_goto_previous_page" ) ) button = self.widget_tree.get_object("page_next") button.connect( "clicked", lambda *args, **kwargs: self.core.call_all("doc_goto_next_page") ) self.core.call_success("docview_get_body").add_overlay(self.page_info) def _set_docview_margin(page_info, size_allocation): self.core.call_all( "docview_set_bottom_margin", page_info.get_allocated_height() ) self.page_info.connect("size-allocate", _set_docview_margin) def _change_page(self, *args, **kwargs): txt = self.current_page.get_text() if txt == "": return self.core.call_all("doc_goto_page", int(txt) - 1) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None: nb_pages = 0 self.current_page.set_text("") self.nb_pages.set_text(f"/ {nb_pages}") self.page_info.set_visible(True) self.page_info.set_sensitive(nb_pages > 0) def doc_reload(self, doc_id, doc_url): if (doc_id, doc_url) != self.active_doc: return self.doc_open(*self.active_doc) def on_page_shown(self, page_idx): txt = str(page_idx + 1) if txt != self.current_page.get_text(): self.current_page.set_text(txt) def page_info_add_left(self, widget): self.widget_tree.get_object("page_prevnext").pack_end( widget, expand=False, fill=True, padding=0 ) return True def page_info_add_right(self, widget): self.widget_tree.get_object("page_info").pack_end( widget, expand=False, fill=True, padding=0 ) return True def doc_transaction_start(self, out: list, total_expected=-1): class RefreshTransaction(paperwork_backend.sync.BaseTransaction): priority = -100000 def __init__(s, core, total_expected=-1): super().__init__(core, total_expected) s.active_doc = False def _refresh(s): self.core.call_success( "mainloop_schedule", self.doc_open, *self.active_doc ) s.active_doc = True def add_doc(s, doc_id): if self.active_doc[0] == doc_id: s._refresh() def upd_doc(s, doc_id): if self.active_doc[0] == doc_id: s._refresh() def del_doc(s, doc_id): if self.active_doc[0] == doc_id: s._refresh() def cancel(s): if s.active_doc: s._refresh() def commit(s): if s.active_doc: s._refresh() out.append(RefreshTransaction(self.core, total_expected)) def sync(self, promises: list): # sync don't change document content --> no need to refresh pass paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.glade000066400000000000000000000037671456262201400320530ustar00rootroot00000000000000
True False 6 Edit False True False False True none False True 0 False True False False True page_menu_model none True False view-more-symbolic 2 False True 1
paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/actions.py000066400000000000000000000070251456262201400314160ustar00rootroot00000000000000import logging try: from gi.repository import Gio GIO_AVAILABLE = True except (ImportError, ValueError): GIO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page = None self.button_edit = None def get_interfaces(self): return [ 'chkdeps', 'doc_open', 'page_actions', ] def get_deps(self): return [ { 'interface': 'gtk_docview_pageinfo', 'defaults': ['paperwork_gtk.mainwindow.docview.pageinfo'], }, { 'interface': 'gtk_page_editor', 'defaults': ['paperwork_gtk.mainwindow.pageeditor'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def init(self, core): super().init(core) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageinfo", "actions.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.menu_model = self.widget_tree.get_object("page_menu_model") self.submenus = {} self.button_edit = self.widget_tree.get_object("page_action_edit") self.button_edit.connect( "clicked", self._on_edit ) self.core.call_success( "page_info_add_right", self.widget_tree.get_object("page_actions") ) self.core.call_success( "mainloop_schedule", self.core.call_all, "on_page_menu_ready" ) def chkdeps(self, out: dict): if not GIO_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def on_page_shown(self, page_idx): self.active_page = page_idx def _on_edit(self, button): self.core.call_all( "gtk_open_page_editor", *self.active_doc, self.active_page ) def page_menu_open(self): self.widget_tree.get_object("page_actions_other").clicked() def page_menu_append_item(self, item, submenu_name=None): menu = self.menu_model if submenu_name is not None: menu = self.submenus.get(submenu_name, None) if menu is None: menu = Gio.Menu() self.submenus[submenu_name] = menu self.menu_model.append_submenu(submenu_name, menu) menu.append_item(item) def screenshot_snap_all_doc_widgets(self, out_dir): self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("page_actions"), self.core.call_success("fs_join", out_dir, "page_actions.png"), margins=(50, 50, 50, 50) ) def screenshot_snap_page_action_menu(self, out_file): self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("page_actions"), out_file, margins=(50, 200, 50, 50) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.css000066400000000000000000000004231456262201400333460ustar00rootroot00000000000000#layout_settings { background-color: rgba(16, 16, 16, 0.90); color: white; } #layout_settings button { color: white; background-image: none; background-color: #373737; border: 1px solid #202121; box-shadow: none; } #layout_settings button:disabled { color: gray; } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.glade000066400000000000000000000152131456262201400336350ustar00rootroot00000000000000 False True False False True none True False 2 0.05 1.0 0.5 0.05 0.05 layout_settings 10 True vertical 7 True 30 True True view-paged-symbolic 1 True True 0 True True view-grid-symbolic 1 True True 1 False True 1 True True edit-find-symbolic 1 False True 1 True True horizontal adjustment_zoom 200 3 False True True True 2 False True 2 True horizontal 400 False True 3 True True Highlight words True True 0 True False False 1 False True 4 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/layout_settings.py000066400000000000000000000141671456262201400332200ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_gtk.deps try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): LAYOUTS = { 'paged': { 'icon': 'view-paged-symbolic', }, 'grid': { 'icon': 'view-grid-symbolic', }, } def __init__(self): super().__init__() self.widget_tree = None self.layout_icon = None self.layout_button = None self.notify = True def get_interfaces(self): return [ 'chkdeps', 'gtk_layout_settings', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, { 'interface': 'gtk_docview_pageinfo', 'defaults': ['paperwork_gtk.mainwindow.docview.pageinfo'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def init(self, core): super().init(core) self.core.call_success( "gtk_load_css", "paperwork_gtk.mainwindow.docview.pageinfo", "layout_settings.css" ) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageinfo", "layout_settings.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.layout_icon = self.widget_tree.get_object("page_layout_icon") self.layout_button = self.widget_tree.get_object("page_layout") self.layout_button.connect("clicked", self.gtk_open_layout_settings) self.zoom = self.widget_tree.get_object("adjustment_zoom") self.zoom.connect("value-changed", self._on_zoom_changed) self.all_boxes = self.widget_tree.get_object("show_all_boxes") self.all_boxes.connect("notify::active", self._notify_all_boxes) self.layout_buttons = { self.widget_tree.get_object("layout_grid"): { "handler": None, "layout": "grid", }, self.widget_tree.get_object("layout_paged"): { "handler": None, "layout": "paged", }, } for button in self.layout_buttons.keys(): self.layout_buttons[button]['handler'] = button.connect( "clicked", self._on_layout_change ) self.core.call_success("page_info_add_left", self.layout_button) scroll = self.core.call_success("docview_get_scrollwindow") self.core.call_all("on_zoomable_widget_new", scroll, self.zoom) def on_layout_change(self, layout_name): if self.layout_icon is None: return icon = self.LAYOUTS[layout_name]['icon'] # smallest icon size available self.layout_icon.set_from_icon_name(icon, Gtk.IconSize.SMALL_TOOLBAR) def _on_layout_change(self, widget): assert widget in self.layout_buttons layout = self.layout_buttons[widget]['layout'] self.core.call_all("docview_set_layout", layout) def gtk_open_layout_settings(self, *args, **kwargs): menu = self.widget_tree.get_object("layout_settings") menu.set_relative_to(self.layout_button) menu.set_visible(True) def gtk_close_layout_settings(self, *args, **kwargs): menu = self.widget_tree.get_object("layout_settings") menu.set_visible(False) def _on_zoom_changed(self, _=None): new_value = self.zoom.get_value() if self.notify: self.core.call_all("docview_set_zoom", new_value) def _notify_all_boxes(self, *args, **kwargs): active = self.all_boxes.get_active() self.core.call_all("set_all_boxes_visible", active) def docview_set_zoom(self, zoom): current = self.zoom.get_value() if current != zoom: self.notify = False try: self.zoom.set_value(zoom) finally: self.notify = True def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("layout_settings"), self.core.call_success("fs_join", out_dir, "docview_layout.png"), ) self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("layout_paged"), self.core.call_success( "fs_join", out_dir, "docview_layout_paged.png" ), margins=(50, 50, 50, 50) ) self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("layout_grid"), self.core.call_success( "fs_join", out_dir, "docview_layout_grid.png" ), margins=(50, 50, 50, 50) ) self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("scale_zoom"), self.core.call_success( "fs_join", out_dir, "docview_layout_scale.png" ), margins=(50, 50, 50, 50) ) self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("show_all_boxes"), self.core.call_success( "fs_join", out_dir, "docview_layout_show_all_boxes.png" ), margins=(275, 50, 50, 50) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/pageinfo.css000066400000000000000000000006541456262201400317070ustar00rootroot00000000000000#page_info { background-color: rgba(16, 16, 16, 0.70); color: white; padding: 5px; padding-left: 10px; padding-right: 10px; } #page_info .button-left { border-right-width: 0px; } #page_info > box > label { color: #919693; } #page_info { color: gray; } #page_info button { color: white; background-image: none; background-color: #373737; border: 1px solid #202121; } #page_info button:disabled { color: gray; } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageinfo/pageinfo.glade000066400000000000000000000123161456262201400321710ustar00rootroot00000000000000 page_info False False end True False False True False False True none True False go-previous-symbolic 2 False True 0 False True False False 6 True none True False go-next-symbolic 2 False True start 1 False True 0 True False True True 1 True False True True False 0 3 1 True True False True 0 True False False / 42 False True 1 False True 2 True False True True 3 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageprocessing/000077500000000000000000000000001456262201400306215ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageprocessing/__init__.py000066400000000000000000000122061456262201400327330ustar00rootroot00000000000000""" Wraps a pageview in a GtkOverlay + GtkSpinner. Displays the spinner on top of the pageview when another plugin is working on the page. """ import logging import openpaperwork_core try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False # workaround so chkdeps can still be called class GObject(object): TYPE_BOOLEAN = 0 class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass LOGGER = logging.getLogger(__name__) class PageWrapper(GObject.GObject): __gsignals__ = { 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'visibility_changed': (GObject.SignalFlags.RUN_LAST, None, ( GObject.TYPE_BOOLEAN, )), } def __init__(self, plugin, page): super().__init__() self.plugin = plugin self.page = page self.page_idx = page.page_idx self.busy = False self.widget_tree = self.plugin.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageprocessing", "pageprocessing.glade", ) self.widget = self.widget_tree.get_object("pageprocessing_overlay") self.widget.add(page.widget) page.connect("getting_size", lambda p: self.emit('getting_size')) page.connect("size_obtained", lambda p: self.emit("size_obtained")) page.connect("img_obtained", lambda p: self.emit("img_obtained")) page.connect( "visibility_changed", lambda p, v: self.emit("visibility_changed", v) ) page.widget.connect("draw", self._on_draw) def load(self): self.page.load() def close(self): self.page.close() def get_zoom(self): return self.page.get_zoom() def set_zoom(self, zoom): return self.page.set_zoom(zoom) def get_full_size(self): return self.page.get_full_size() def get_size(self): return self.page.get_size() def resize(self): return self.page.resize() def refresh(self, reload=False): return self.page.refresh(reload=reload) def set_visible(self, visible): return self.page.set_visible(visible) def get_visible(self): return self.page.get_visible() def _on_draw(self, overlay, cairo_ctx): if not self.busy: return w = overlay.get_allocated_width() h = overlay.get_allocated_height() cairo_ctx.set_source_rgba(0.5, 0.5, 0.5, 0.5) cairo_ctx.rectangle(0, 0, w, h) cairo_ctx.fill() def on_page_modification_start(self): self.busy = True spinner = self.widget_tree.get_object("pageprocessing_spinner") spinner.set_visible(True) spinner.start() def on_page_modification_end(self): self.busy = False spinner = self.widget_tree.get_object("pageprocessing_spinner") spinner.set_visible(False) spinner.stop() self.page.refresh(reload=True) if GLIB_AVAILABLE: GObject.type_register(PageWrapper) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -1000 def __init__(self): super().__init__() self.wrappers = [] self.active_doc_id = None self.active_pages = set() def get_interfaces(self): return [ 'chkdeps', 'gtk_pageview', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def doc_close(self): self.wrappers = [] def doc_open_components(self, out: list, doc_id, doc_url): if doc_id != self.active_doc_id: self.active_doc_id = doc_id self.active_pages = set() self.doc_close() # instantiate PageWrapper objects, and replace the pages in the # list 'out' by those wrappers. self.wrappers = [ PageWrapper(self, page) for (visible, page) in out ] for page_idx in range(0, len(out)): out[page_idx] = (out[page_idx][0], self.wrappers[page_idx]) if page_idx in self.active_pages: out[page_idx][1].on_page_modification_start() def on_page_modification_start(self, doc_id, page_idx): if doc_id != self.active_doc_id: return self.active_pages.add(page_idx) if page_idx >= len(self.wrappers): return self.wrappers[page_idx].on_page_modification_start() def on_page_modification_end(self, doc_id, page_idx): if doc_id != self.active_doc_id: return if page_idx in self.active_pages: self.active_pages.remove(page_idx) if page_idx >= len(self.wrappers): return self.wrappers[page_idx].on_page_modification_end() pageprocessing.glade000066400000000000000000000011261456262201400345510ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageprocessing True False False False True paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/000077500000000000000000000000001456262201400274175ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/__init__.py000066400000000000000000000231341456262201400315330ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False # workaround so chkdeps can still be called class GObject(object): TYPE_BOOLEAN = 0 class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass from .... import _ LOGGER = logging.getLogger(__name__) class Page(GObject.GObject): __gsignals__ = { 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'visibility_changed': (GObject.SignalFlags.RUN_LAST, None, ( GObject.TYPE_BOOLEAN, )), } def __init__(self, core, doc_id, doc_url, page_idx, nb_pages): super().__init__() self.core = core self.doc_id = doc_id self.doc_url = doc_url self.page_idx = page_idx self.nb_pages = nb_pages self.visible = False self.mtime = 0 self.zoom = 1.0 self.widget_tree = None self.widget = None self.renderer = None self._load_renderer() self.rebuild_widget() def _load_renderer(self): page_img_url = self.core.call_success( "page_get_img_url", self.doc_url, self.page_idx ) LOGGER.info( "URL for %s p%d: %s", self.doc_url, self.page_idx, page_img_url ) assert page_img_url is not None self.renderer = self.core.call_success( "cairo_renderer_by_url", "page_loader", page_img_url ) self.renderer.connect("getting_size", self._on_renderer_getting_size) self.renderer.connect("size_obtained", self._on_renderer_size) self.renderer.connect("img_obtained", self._on_renderer_img) def rebuild_widget(self): self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.pageview", "pageview.glade" ) self.widget = self.widget_tree.get_object("pageview_area") self.widget.set_visible(False) # visible in the GTK sense self.widget.connect("draw", self._on_draw) self.resize() def __str__(self): return "{} p{}".format(self.doc_id, self.page_idx) def _on_renderer_getting_size(self, renderer): self.core.call_all( "on_progress", "loading_page_sizes", self.page_idx / self.nb_pages, _("Loading page {}/{} ...").format(self.page_idx, self.nb_pages) ) self.emit('getting_size') def _on_renderer_size(self, renderer): LOGGER.info( "Page %d: size %d x %d", self.page_idx, self.renderer.size[0], self.renderer.size[1] ) self.widget.set_visible(True) self.resize() self.core.call_all("on_page_size_obtained", self) self.emit('size_obtained') def _on_renderer_img(self, renderer): assert self.visible self.refresh() self.core.call_all("on_page_img_obtained", self) self.emit('img_obtained') def load(self): if not self.refresh(reload=True): # renderer has already loaded the page --> reemit the page size if self.renderer.size[0] != 0: self.core.call_success( "mainloop_schedule", self._on_renderer_size, self.renderer ) def close(self): self.renderer.close() def get_zoom(self): return self.zoom def set_zoom(self, zoom): self.zoom = zoom self.resize() def get_full_size(self): return self.renderer.size def get_size(self): return ( int(self.renderer.size[0] * self.zoom), int(self.renderer.size[1] * self.zoom) ) def resize(self): if self.renderer.size[0] == 0: return self.renderer.zoom = self.zoom size = self.get_size() self.widget.set_size_request(size[0], size[1]) def refresh(self, reload=False): if reload: # only if the mtime has changed. Otherwise there is no point. mtime = self.core.call_success( "page_get_mtime_by_url", self.doc_url, self.page_idx ) if self.mtime == mtime: reload = False else: self.mtime = mtime if reload: self.set_visible(False) self.close() self._load_renderer() self.renderer.start() return True elif self.widget is not None: self.widget.queue_draw() return False def hide(self): self.visible = False self.renderer.hide() self.core.call_all("on_page_visibility_changed", self, False) self.emit('visibility_changed', False) def show(self): self.visible = True self.renderer.render() self.core.call_all("on_page_visibility_changed", self, True) self.emit('visibility_changed', True) def set_visible(self, visible): if self.visible == visible: return if visible: self.show() else: self.hide() def get_visible(self): return self.visible def _on_draw(self, widget, cairo_ctx): self.renderer.draw(cairo_ctx) self.core.call_all("on_page_draw", cairo_ctx, self) def blur(self): self.renderer.blur() self.widget.queue_draw() def unblur(self): self.renderer.unblur() self.widget.queue_draw() def detach_from_parent(self): parent = self.widget.get_parent() if parent is None: return parent.remove(self.widget) if GLIB_AVAILABLE: GObject.type_register(Page) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def __init__(self): super().__init__() self.pages = [] self.nb_to_load = 0 self.active_doc = (None, None) def get_interfaces(self): return [ 'chkdeps', 'gtk_pageview', ] def get_deps(self): return [ { 'interface': 'cairo_url', 'defaults': [ 'paperwork_backend.cairo.pillow', 'paperwork_backend.cairo.poppler', ], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'page_img', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) self.core.call_all( "work_queue_create", "page_loader", stop_on_quit=True ) def doc_close(self): self.core.call_success("work_queue_cancel_all", "page_loader") for page in self.pages: page.close() self.pages = [] def doc_open_components(self, out: list, doc_id, doc_url): active_doc = (doc_id, doc_url) if self.active_doc != active_doc: self.doc_close() self.active_doc = active_doc nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) LOGGER.info("Number of pages displayed: %s", nb_pages) if nb_pages is None: LOGGER.warning("Failed to get the number of pages in %s", doc_id) nb_pages = 0 self.core.call_all("on_objref_graph") self.core.call_all( "on_perfcheck_start", "pageview->doc_open_components({})".format(doc_id) ) # drop the extra pages we have if any for page in self.pages[nb_pages:]: page.close() self.pages = self.pages[:nb_pages] # reuse the pages we already have to avoid useless refreshes for page in self.pages: page.detach_from_parent() # add any new page for page_idx in range(len(self.pages), nb_pages): self.pages.append(Page( self.core, doc_id, doc_url, page_idx, nb_pages )) LOGGER.info( "%d pages in the documents (%d components)", nb_pages, len(self.pages) ) self.nb_to_load = len(self.pages) for page in self.pages: page.connect("size_obtained", self._on_page_img_size_obtained) out.append((True, page)) self.core.call_all( "on_perfcheck_stop", "pageview->doc_open_components({})".format(doc_id), nb_pages=nb_pages ) def _on_page_img_size_obtained(self, page): self.nb_to_load -= 1 if self.nb_to_load > 0: return self.nb_to_load = 0 self.core.call_all("on_progress", "loading_page_sizes", 1.0) def pageview_refresh_all(self): for page in self.pages: page.refresh() def on_screenshot_before(self): LOGGER.info("Blurring pages") for page in self.pages: page.blur() def on_screenshot_after(self): LOGGER.info("Unblurring pages") for page in self.pages: page.unblur() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/000077500000000000000000000000001456262201400305375ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/__init__.py000066400000000000000000000217361456262201400326610ustar00rootroot00000000000000import logging try: import gi gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango from gi.repository import PangoCairo PANGO_AVAILABLE = True except (ImportError, ValueError): PANGO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_core.promise from ..... import _ LOGGER = logging.getLogger(__name__) DELAY = 0.1 class NBox(object): """ Chained boxes. Useful for some plugins like boxes.selection. """ def __init__(self, box, index): self.box = box self.next = None self.index = index def __lt__(self, other): if self.index < other.index: return True return (self.box.position < other.box.position) class Plugin(openpaperwork_core.PluginBase): """ Load the boxes on the pages and notify them to other plugins. Do nothing else. See other plugins in paperwork_gtk.mainwindow.docview.pageview.boxes to have something actually happening. """ def __init__(self): super().__init__() self.cache = {} self.running_promises = {} self.nb_to_load = 0 self.nb_loaded = 0 def get_interfaces(self): return [ 'chkdeps', 'gtk_pageview_boxes', ] def get_deps(self): return [ { "interface": "gtk_pageview", "defaults": ["paperwork_gtk.mainwindow.docview.pageview"], }, { 'interface': 'spatial_index', 'defaults': ['openpaperwork_core.spatial.rtree'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def chkdeps(self, out: dict): if not PANGO_AVAILABLE: out['pango'].update(openpaperwork_core.deps.PANGO) def _upd_progress(self): if self.nb_to_load <= self.nb_loaded or self.nb_to_load == 0: self.core.call_all("on_progress", "boxes", 1.0) self.nb_to_load = 0 self.nb_loaded = 0 return self.core.call_all( "on_progress", "boxes", self.nb_loaded / self.nb_to_load, _("Loading text ...") ) def doc_close(self): self.cache = {} self.nb_to_load = 0 self.nb_loaded = 0 self._upd_progress() def doc_open(self, *args, **kwargs): self.doc_close() def _index_boxes(self, boxes): # Tesseract seems (seemed ?) to have a bug: boxes taking the whole # page. --> we remove them. # Also we strip empty boxes. boxes = [ line_box for line_box in boxes if line_box.position[0][0] > 0 or line_box.position[0][1] > 0 ] for line_box in boxes: line_box.word_boxes = [ word_box for word_box in line_box.word_boxes if ((word_box.position[0][0] > 0 or word_box.position[0][1] > 0) and word_box.content.strip() != "") ] # chain the boxes chained_boxes = [] pbox = None index = 0 for line in boxes: for word in line.word_boxes: new_box = NBox(word, index) index += 1 if pbox is not None: pbox.next = new_box chained_boxes.append(pbox) pbox = new_box if pbox is not None: chained_boxes.append(pbox) # and then index them spatial_index = self.core.call_success( "spatial_indexer_get", [ (b.box.position, b) for b in chained_boxes ] ) return (boxes, spatial_index) def _set_boxes(self, boxes, page): (boxes, spatial_index) = boxes ref = (page.doc_id, page.page_idx) self.cache[ref] = (boxes, spatial_index) return (boxes, spatial_index) def pageview_get_boxes_by_id(self, doc_id, page_idx): ref = (doc_id, page_idx) if ref not in self.cache: return None return self.cache[ref][0] def pageview_get_indexed_boxes_by_id(self, doc_id, page_idx): ref = (doc_id, page_idx) if ref not in self.cache: return None return self.cache[ref][1] def on_page_visibility_changed(self, page, visible): ref = (page.doc_id, page.page_idx) if not visible: promise = self.running_promises.pop(ref, None) if promise is not None: self.core.call_all("work_queue_cancel", "page_loader", promise) self.nb_to_load -= 1 self._upd_progress() if ref in self.cache: self.cache.pop(ref) return if ref in self.cache: return # even they are not yet loaded, they will soon be --> we can mark them # as loaded self.cache[ref] = (None, None) # Gives back a bit of CPU time to GTK so the GUI remains # usable promise = openpaperwork_core.promise.DelayPromise(self.core, DELAY) promise = promise.then( LOGGER.debug, "Loading boxes of %s p%d", page.doc_id, page.page_idx ) # drop the returned value promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self.core.call_success, args=("page_get_boxes_by_url", page.doc_url, page.page_idx,) )) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, lambda boxes=[]: self._index_boxes(boxes) )) promise = promise.then(lambda boxes: self._set_boxes(boxes, page)) promise = promise.then(lambda boxes: self.core.call_all( # boxes => (boxes, spatial_index) "on_page_boxes_loaded", page, boxes[0], boxes[1] )) def stop_promise_tracking(*args, **kwargs): if ref in self.running_promises: self.nb_loaded += 1 self._upd_progress() self.running_promises.pop(ref) promise = promise.then(stop_promise_tracking) self.nb_to_load += 1 self._upd_progress() self.running_promises[ref] = promise # piggy back page loader work queue, but with a low priority self.core.call_success( "work_queue_add_promise", "page_loader", promise, priority=-10 ) def on_page_boxes_loaded(self, page, boxes, spatial_index): LOGGER.info( "Page %s %d: %d line boxes loaded", page.doc_id, page.page_idx, len(boxes) ) def _paint_txt(self, cairo_ctx, txt, x, y, w, h): cairo_ctx.set_source_rgb(1.0, 1.0, 1.0) cairo_ctx.rectangle(x, y, w, h) cairo_ctx.fill() layout = PangoCairo.create_layout(cairo_ctx) layout.set_text(txt, -1) txt_size = layout.get_size() if 0 in txt_size: return cairo_ctx.save() try: txt_factor = min( float(w) * Pango.SCALE / txt_size[0], float(h) * Pango.SCALE / txt_size[1], ) cairo_ctx.set_source_rgb(0, 0, 0) cairo_ctx.translate(x, y) # make the text use the whole box space cairo_ctx.scale(txt_factor, txt_factor) PangoCairo.update_layout(cairo_ctx, layout) PangoCairo.show_layout(cairo_ctx, layout) finally: cairo_ctx.restore() def _page_draw_box( self, cairo_ctx, page, box_position, border_color, border_width=2, box_content=None): zoom = page.zoom ((tl_x, tl_y), (br_x, br_y)) = box_position tl_x *= zoom tl_y *= zoom br_x *= zoom br_y *= zoom w = br_x - tl_x h = br_y - tl_y if box_content is not None: self._paint_txt(cairo_ctx, box_content, tl_x, tl_y, w, h) cairo_ctx.save() try: cairo_ctx.set_source_rgb( border_color[0], border_color[1], border_color[2] ) cairo_ctx.set_line_width(border_width) cairo_ctx.rectangle( tl_x - (border_width / 2), tl_y - (border_width / 2), w + border_width, h + border_width ) cairo_ctx.stroke() finally: cairo_ctx.restore() def page_draw_box(self, *args, **kwargs): # WORKAROUND(Jflesch): with some malformed PDF file, we get unexpected # exceptions. See: # https://gitlab.gnome.org/World/OpenPaperwork/paperwork/-/issues/913 # https://gitlab.freedesktop.org/poppler/poppler/-/issues/1020 try: self._page_draw_box(*args, **kwargs) except Exception as exc: LOGGER.error("page_draw_box() failed", exc_info=exc) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/all.py000066400000000000000000000027621456262201400316700ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def __init__(self): super().__init__() self.visible = False def get_interfaces(self): return [ 'gtk_pageview_boxes_all', 'gtk_pageview_boxes_listener', ] def get_deps(self): return [ { 'interface': 'gtk_pageview', 'defaults': ['paperwork_gtk.mainwindow.docview.pageview'], }, { 'interface': 'gtk_pageview_boxes', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageview.boxes' ], }, ] def set_all_boxes_visible(self, visible): self.visible = visible self.core.call_all("pageview_refresh_all") def on_page_boxes_loaded(self, page, boxes, spatial_index): page.refresh() def on_page_draw(self, cairo_ctx, page): if not self.visible: return boxes = self.core.call_success( "pageview_get_boxes_by_id", page.doc_id, page.page_idx ) if boxes is None: return for line_box in boxes: for word_box in line_box.word_boxes: self.core.call_all( "page_draw_box", cairo_ctx, page, word_box.position, (0.0, 0.0, 1.0), border_width=1 ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/hover.py000066400000000000000000000102601456262201400322330ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gdk', '3.0') from gi.repository import Gdk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class PageHoverHandler(object): def __init__(self, core, page): self.core = core self.page = page self.boxes = None self.actives = [] self.realize_handler_id = None self.motion_handler_id = None def set_boxes(self, boxes, spatial_index): self.boxes = spatial_index def connect(self): assert self.realize_handler_id is None assert self.motion_handler_id is None self.realize_handler_id = self.page.widget.connect( "realize", self.on_realize ) self.motion_handler_id = self.page.widget.connect( "motion-notify-event", self.on_motion ) self.on_realize() def disconnect(self): assert self.realize_handler_id is not None assert self.motion_handler_id is not None self.page.widget.disconnect(self.realize_handler_id) self.page.widget.disconnect(self.motion_handler_id) self.realize_handler_id = None self.motion_handler_id = None def on_realize(self, widget=None): mask = Gdk.EventMask.POINTER_MOTION_MASK self.page.widget.add_events(mask) if self.page.widget.get_window() is not None: self.page.widget.get_window().set_events( self.page.widget.get_window().get_events() | mask ) def on_motion(self, widget, event): if self.boxes is None: self.actives = [] return zoom = self.page.get_zoom() x = int(event.x / zoom) y = int(event.y / zoom) actives = [(a[0], a[1].box) for a in self.boxes.get_boxes(x, y)] if len(actives) > 1: # will sort smaller areas last actives = [ (abs((p[1][0] - p[0][0]) * (p[1][1] - p[0][1])), b) for (p, b) in actives ] actives.sort(reverse=True) actives = [ a[1] for a in actives ] if actives != self.actives: self.page.widget.queue_draw() self.actives = actives def draw(self, cairo_ctx): for box in self.actives: self.core.call_all( "page_draw_box", cairo_ctx, self.page, box.position, (0.0, 0.0, 1.0), border_width=2, box_content=box.content ) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10 def __init__(self): super().__init__() self.handlers = {} def get_interfaces(self): return [ 'chkdeps', 'gtk_pageview_boxes_listener', ] def get_deps(self): return [ { 'interface': 'gtk_pageview', 'defaults': ['paperwork_gtk.mainwindow.docview.pageview'], }, { 'interface': 'gtk_pageview_boxes', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageview.boxes' ], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_docview_closed_page(self, page): self.handlers.pop(page.widget).disconnect() def on_page_boxes_loaded(self, page, boxes, spatial_index): h = PageHoverHandler(self.core, page) self.handlers[page.widget] = h assert page.widget in self.handlers h = self.handlers[page.widget] h.set_boxes(boxes, spatial_index) if page.get_visible(): h.connect() def on_page_visibility_changed(self, page, visible): if page.widget not in self.handlers: return h = self.handlers[page.widget] if visible: h.connect() else: h.disconnect() def on_page_draw(self, cairo_ctx, page): if page.widget not in self.handlers: return self.handlers[page.widget].draw(cairo_ctx) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/search.py000066400000000000000000000046631456262201400323670ustar00rootroot00000000000000import logging import re import openpaperwork_core LOGGER = logging.getLogger(__name__) MIN_WORD_LENGTH = 3 SPLIT = r"\W+" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 # those are keywords used in python-whoosh query syntax. There is no # point in highlighting them IGNORE_LIST = {"and", "or"} def __init__(self): super().__init__() self.re_split = re.compile(SPLIT) self.keywords = set() def get_interfaces(self): return [ 'gtk_pageview_boxes_listener', 'search_listener', ] def get_deps(self): return [ { 'interface': 'gtk_pageview', 'defaults': ['paperwork_gtk.mainwindow.docview.pageview'], }, { 'interface': 'gtk_pageview_boxes', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageview.boxes' ], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def on_search_start(self, query): query = self.re_split.split( self.core.call_success("i18n_strip_accents", query) ) self.keywords = { keyword.lower() for keyword in query if len(keyword) >= MIN_WORD_LENGTH } self.core.call_all("pageview_refresh_all") def on_search_results(self, query, docs): pass def on_page_draw(self, cairo_ctx, page): if len(self.keywords) <= 0: return boxes = self.core.call_success( "pageview_get_boxes_by_id", page.doc_id, page.page_idx ) if boxes is None: return for line_box in boxes: for word_box in line_box.word_boxes: word = self.core.call_success( "i18n_strip_accents", word_box.content ) word = word.strip() if word.lower() in self.IGNORE_LIST: continue for w in self.re_split.split(word): w = w.lower() if w not in self.keywords: continue self.core.call_all( "page_draw_box", cairo_ctx, page, word_box.position, (0.0, 1.0, 0.0), border_width=2 ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/boxes/selection.py000066400000000000000000000130251456262201400330770ustar00rootroot00000000000000import itertools import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) IDX_GENERATOR = itertools.count() class PageSelectionHandler(object): def __init__(self, core, plugin, page): self.core = core self.plugin = plugin self.page = page self.actives = [] self.boxes = None self.orig = (-1, -1) self.first = None self.last = None self.gesture = Gtk.GestureDrag.new(page.widget) self.gesture.set_propagation_phase(Gtk.PropagationPhase.CAPTURE) self.signal_handlers = [] def set_boxes(self, line_boxes, spatial_index): self.boxes = spatial_index def connect(self): self.disconnect() handlers = ( ('drag-begin', self.on_drag_begin), ('drag-update', self.on_drag_update), ('drag-end', self.on_drag_end), ) for (signal, cb) in handlers: self.signal_handlers.append( (signal, self.gesture.connect(signal, cb)) ) def disconnect(self): for (signal, handler_id) in self.signal_handlers: self.gesture.disconnect(handler_id) self.signal_handlers = [] def _find_box(self, x, y): if self.boxes is None: return None zoom = self.page.get_zoom() x /= zoom y /= zoom nboxes = self.boxes.get_boxes(x, y) # take the box with the smallest area try: nbox = min({ ( abs( (n[1].box.position[1][0] - n[1].box.position[0][0]) * (n[1].box.position[1][1] - n[1].box.position[0][1]) ), n[1] ) for n in nboxes })[1] except ValueError: return None return nbox def _get_selected(self): if self.first is None: return [] if self.first.index <= self.last.index: first = self.first last = self.last else: first = self.last last = self.first current = first while current is not None and current != last: yield current.box current = current.next yield last.box def on_drag_begin(self, gesture, x, y): if not self.plugin.enabled: self.first = None self.last = None return self.actives = [] self.orig = (x, y) self.first = self._find_box(x, y) self.last = self.first def on_drag_update(self, gesture, x, y): if self.first is None: return (x, y) = (self.orig[0] + x, self.orig[1] + y) last = self._find_box(x, y) if last is None or last == self.last: return self.last = last self.page.widget.queue_draw() LOGGER.info( "Text selection: first: %d ; last: %d", self.first.index, self.last.index ) def on_drag_end(self, gesture, x, y): if self.first is None: return self.on_drag_update(gesture, x, y) self.core.call_all( "on_page_boxes_selected", self.page.doc_id, self.page.doc_url, self.page.page_idx, list(self._get_selected()) ) def draw(self, cairo_ctx): if not self.plugin.enabled: return for box in self._get_selected(): self.core.call_all( "page_draw_box", cairo_ctx, self.page, box.position, (0.0, 1.0, 0.0), border_width=2 ) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10 def __init__(self): super().__init__() self.handlers = {} self.enabled = False def get_interfaces(self): return [ 'chkdeps', 'gtk_pageview_boxes_listener', ] def get_deps(self): return [ { 'interface': 'gtk_pageview', 'defaults': ['paperwork_gtk.mainwindow.docview.pageview'], }, { 'interface': 'gtk_pageview_boxes', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageview.boxes' ], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_docview_closed_page(self, page): self.handlers.pop(page.widget).disconnect() def on_page_boxes_loaded(self, page, boxes, spatial_index): h = PageSelectionHandler(self.core, self, page) self.handlers[page.widget] = h assert page.widget in self.handlers h = self.handlers[page.widget] h.set_boxes(boxes, spatial_index) if page.get_visible(): h.connect() def on_page_visibility_changed(self, page, visible): if page.widget not in self.handlers: return h = self.handlers[page.widget] if visible: h.connect() else: h.disconnect() def on_page_draw(self, cairo_ctx, page): if page.widget not in self.handlers: return self.handlers[page.widget].draw(cairo_ctx) def on_layout_change(self, layout_name): self.enabled = (layout_name == 'paged') paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/pageview/pageview.glade000066400000000000000000000005021456262201400322210ustar00rootroot00000000000000 True False paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/progress.py000066400000000000000000000014011456262201400300220ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [] def get_deps(self): return [ { 'interface': 'gtk_progress_widget', 'defaults': ['openpaperwork_gtk.widgets.progress'], }, { 'interface': 'gtk_docview', 'defaults': ['paperwork_gtk.mainwindow.docview'], }, ] def init(self, core): super().init(core) widget = self.core.call_success("gtk_progress_make_widget") if widget is None: # GTK is not available return header_bar = self.core.call_success("docview_get_headerbar") header_bar.pack_end(widget) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/scanview/000077500000000000000000000000001456262201400274275ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/scanview/__init__.py000066400000000000000000000166551456262201400315550ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False # workaround so chkdeps can still be called class GObject(object): # type: ignore[no-redef] TYPE_BOOLEAN = 0 class SignalFlags(object): RUN_LAST = 0 class GObject(object): pass LOGGER = logging.getLogger(__name__) class Scan(GObject.GObject): """ Implements the same interface than the mainwindow.docview.pageview.Page objects, but display any scan relative to the current document. """ __gsignals__ = { # never emitted 'getting_size': (GObject.SignalFlags.RUN_LAST, None, ()), # emitted immediately and when a scan is started 'size_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), # never emitted 'img_obtained': (GObject.SignalFlags.RUN_LAST, None, ()), 'visibility_changed': (GObject.SignalFlags.RUN_LAST, None, ( # TODO(Jflesch): not implemented here (never emitted), but not # used anywhere anyway. GObject.TYPE_BOOLEAN, )), } def __init__(self, core, plugin, doc_id, page_idx, scan_id=None): super().__init__() self.core = core self.plugin = plugin self.doc_id = doc_id self.zoom = 1.0 self.page_idx = page_idx self.scan_id = scan_id if scan_id is not None: scan_id = self.core.call_success( "draw_scan_get_max_size", self.scan_id ) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.docview.scanview", "scanview.glade" ) self.widget = self.widget_tree.get_object("scanview_area") self.visible = False def __str__(self): return "Scan renderer ({})".format(self.doc_id) def set_visible(self, visible): if visible == self.visible: return LOGGER.info("Scan renderer: Visible: {}".format(visible)) self.visible = visible def start(self): LOGGER.info("Scan renderer: start") size = self.get_size() self.widget.set_size_request(size[0], size[1]) self.widget.queue_resize() self.core.call_all("draw_scan_start", self.widget, self.scan_id) self.widget.set_visible(True) def stop(self): LOGGER.info("Scan renderer: stop") self.core.call_all("draw_scan_stop", self.widget) self.widget.set_visible(False) def get_visible(self): return self.visible def load(self): # the docview rely on this signal to know when pagss have been loaded # (in other words, when their size have been defined). # It remains in state 'loading' as long as not all the pages have # reported having be loaded --> we report immediately ourselves # as loaded self.core.call_all("on_page_size_obtained", self) self.emit("size_obtained") def close(self): pass def get_zoom(self): return self.zoom def set_zoom(self, zoom): self.zoom = zoom self.resize() def get_full_size(self): if self.scan_id is None: return (0, 0) return self.plugin.scan_sizes.get(self.scan_id, (1, 1)) def get_size(self): size = self.get_full_size() return ( int(size[0] * self.zoom), int(size[1] * self.zoom) ) def resize(self): if self.scan_id is None: return size = self.get_size() self.widget.set_size_request(size[0], size[1]) self.core.call_all("on_page_size_obtained", self) self.emit("size_obtained") self.widget.queue_resize() def refresh(self, reload=False): self.widget.queue_draw() def hide(self): pass def show(self): pass if GLIB_AVAILABLE: GObject.type_register(Scan) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -10000 def __init__(self): super().__init__() self.scan = None self.doc_id = None self.doc_url = None self.scan_sizes = {} def get_interfaces(self): return [ 'gtk_pageview', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_drawer_scan', 'defaults': [ 'openpaperwork_gtk.drawer.scan', 'paperwork_gtk.drawer.calibration', ], }, ] def doc_open_components(self, out: list, doc_id, doc_url): self.doc_id = doc_id self.doc_url = doc_url nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None: nb_pages = 0 scan_id = self.core.call_success("scan2doc_doc_id_to_scan_id", doc_id) self.scan = Scan(self.core, self, doc_id, nb_pages, scan_id) if scan_id is None: out.append((False, self.scan)) else: out.append((True, self.scan)) self.scan.start() def on_scan2doc_start(self, scan_id, doc_id, doc_url): if self.scan is None: return if doc_id != self.doc_id: return self.scan.scan_id = scan_id def on_scan_feed_start(self, scan_id): if self.scan is None: return if scan_id != self.scan.scan_id: return self.scan.start() self.core.call_all("docview_show_page_viewer", self.scan) def on_scan_page_start(self, scan_id, page_nb, scan_params): self.scan_sizes[scan_id] = ( scan_params.get_width(), scan_params.get_height() ) if self.scan is None: return if scan_id != self.scan.scan_id: return LOGGER.info("Scan size: %dx%d", *(self.scan_sizes[scan_id])) self.scan.resize() nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", self.doc_url ) if nb_pages is None: nb_pages = 0 handle_id = None def goto_page(*args, **kwargs): self.scan.widget.disconnect(handle_id) self.core.call_all("doc_goto_page", nb_pages) self.core.call_all("doc_goto_page", nb_pages) handle_id = self.scan.widget.connect("size-allocate", goto_page) def on_scan2doc_page_scanned(self, scan_id, doc_id, doc_url, page_idx): if self.scan is None: return if scan_id != self.scan.scan_id: return nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", self.doc_url ) assert nb_pages is not None LOGGER.info("Displaying new page %d", nb_pages - 1) self.core.call_all("doc_goto_page", nb_pages - 1) def on_scan_feed_end(self, scan_id): self.scan_sizes.pop(scan_id, None) if self.scan is None: return if scan_id != self.scan.scan_id: return self.core.call_all("docview_hide_page_viewer", self.scan) self.scan.stop() def on_scan2doc_end(self, scan_id, doc_id, doc_url): if self.scan is None: return if doc_id != self.doc_id: return self.scan.scan_id = None paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/docview/scanview/scanview.glade000066400000000000000000000004361456262201400322470ustar00rootroot00000000000000 False False paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/000077500000000000000000000000001456262201400260205ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/__init__.py000066400000000000000000000633701456262201400301420ustar00rootroot00000000000000import logging import random try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise import openpaperwork_gtk.deps import paperwork_backend.docexport from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.ui = None self.active_doc = None self.active_page_idx = None self.windows = [] self.button_validate = None self.button_send_email = None self.preciew = None self.zoom = None self.quality = None self.combobox_page_format = None self.model_page_format = None # The reference ('ref_') is what is displayed as example to the user. # It's always only one page. The exported document size is estimated # by multiplying this reference page after post-processing by the # number of pages in the document. # Inputs (export_input_*) refer to export pipe inputs # (see paperwork_backend.docexport) self.ref_input_page = None self.ref_input_doc = None self.export_input_type = None self.export_input = None self.export_input_doc_urls = None self.need_zoom_auto = True self.pipeline = [] self.renderer = None self.tmp_file_url = None def get_interfaces(self): return [ 'chkdeps', 'doc_open', 'gtk_exporter', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'cairo_url', 'defaults': [ 'paperwork_backend.cairo.pillow', 'paperwork_backend.cairo.poppler', ], }, { 'interface': 'export_pipes', 'defaults': [ 'paperwork_backend.docexport.img', 'paperwork_backend.docexport.pdf', 'paperwork_backend.docexport.pillowfight', ], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_zoomable', 'defaults': ['paperwork_gtk.gesture.zoom'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'notifications', 'defaults': [ 'paperwork_gtk.notifications.dialog', 'paperwork_gtk.notifications.notify', ], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, { 'interface': 'external_apps', 'defaults': [ 'openpaperwork_core.external_apps.dbus', 'openpaperwork_core.external_apps.windows', 'openpaperwork_core.external_apps.xdg', ], }, ] def init(self, core): super().init(core) opt = self.core.call_success( "config_build_simple", "GUI", "last_export_uri", lambda: None ) self.core.call_all("config_register", "last_export_uri", opt) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.exporter", "exporter.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.widget_tree.get_object("exporter_cancel").connect( "clicked", self._on_cancel ) self.button_validate = self.widget_tree.get_object("exporter_validate") self.button_validate.connect( "clicked", self._on_apply ) self.button_send_email = self.widget_tree.get_object( "exporter_send_email" ) self.button_send_email.connect( "clicked", self._on_send_email ) can_send_as_attachment = core.call_success( "external_app_can_send_as_attachment" ) if not can_send_as_attachment: self.button_send_email.set_visible(False) self.zoom = self.widget_tree.get_object("exporter_zoom_adjustment") self.zoom.connect("value-changed", self._on_zoom_changed) self.quality = self.widget_tree.get_object( "exporter_quality_adjustment" ) self.quality.connect("value-changed", self._on_quality_changed) self.preview = self.widget_tree.get_object("exporter_img") self.preview.connect("draw", self._on_draw) self.core.call_all( "on_zoomable_widget_new", self.widget_tree.get_object("exporter_scroll"), self.zoom ) self.core.call_all( "mainwindow_add", "right", "exporter", prio=0, header=self.widget_tree.get_object("exporter_header"), body=self.widget_tree.get_object("exporter_body") ) self.core.call_success("work_queue_create", "exporter") self.combobox_page_format = self.widget_tree.get_object( "exporter_page_format" ) self.model_page_format = self.widget_tree.get_object( "exporter_page_format_model" ) self._add_page_formats() self.combobox_page_format.connect( "changed", self._on_page_format_changed ) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def on_page_shown(self, page_idx): self.active_page_idx = page_idx def _add_page_formats(self): default_idx = -1 for (idx, paper_size) in enumerate( Gtk.PaperSize.get_paper_sizes(True)): store_data = ( paper_size.get_display_name(), paper_size.get_width(Gtk.Unit.POINTS), paper_size.get_height(Gtk.Unit.POINTS) ) self.model_page_format.append(store_data) if paper_size.get_name() == paper_size.get_default(): default_idx = idx if default_idx >= 0: self.combobox_page_format.set_active(default_idx) def _get_possible_pipes(self, input_type, active_pipe=""): pipes = [] if input_type == paperwork_backend.docexport.ExportDataType.DOCUMENT: self.core.call_all( "export_get_pipes_by_doc_urls", pipes, self.export_input_doc_urls ) else: self.core.call_all("export_get_pipes_by_input", pipes, input_type) pipeline = {p.name for p in self.pipeline} if active_pipe in pipeline: pipeline.remove(active_pipe) pipes = [p for p in pipes if p.name not in pipeline] return pipes def _expand_pipeline(self): """ When there is only once choice possible, this isn't really a choice. --> we expand automatically the pipeline to include the only choice possible. """ while True: if len(self.pipeline) > 0: last_output_type = self.pipeline[-1].output_type else: last_output_type = self.export_input_type if last_output_type == 'file_url': # pipeline is complete return pipes = self._get_possible_pipes(last_output_type) if len(pipes) != 1: # there is a choice (or none at all), nothing to do return pipe = pipes[0] assert pipe.name not in (p.name for p in self.pipeline) self.pipeline.append(pipe) LOGGER.info("Pipeline expanded: %s", [ p.name for p in self.pipeline ]) def _add_combobox(self, steps, previous_input_type, active_pipe): possible_alternative_pipes = self._get_possible_pipes( previous_input_type, active_pipe ) if len(possible_alternative_pipes) <= 1: # no really a choice return possible_alternative_pipes.sort(key=lambda p: str(p)) widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.exporter", "pipe.glade" ) combobox = widget_tree.get_object("exporter_pipe") choices = widget_tree.get_object("exporter_pipe_model") choices.clear() choices.append(("", "")) active_idx = 0 for (alternative_idx, alternative_pipe) in enumerate( possible_alternative_pipes): choices.append( (str(alternative_pipe), alternative_pipe.name) ) if alternative_pipe.name == active_pipe: active_idx = alternative_idx + 1 combobox.set_active(active_idx) combobox.connect('changed', self._on_pipeline_changed) steps.add(combobox) def _refresh_pipeline_ui(self): LOGGER.info("Displaying pipeline: %s", [p.name for p in self.pipeline]) steps = self.widget_tree.get_object("exporter_steps") for widget in steps: steps.remove(widget) for (pipe_idx, pipe) in enumerate(self.pipeline): if pipe_idx <= 0: previous_input_type = self.export_input_type else: previous_input_type = self.pipeline[pipe_idx - 1].output_type self._add_combobox(steps, previous_input_type, pipe.name) if len(self.pipeline) > 0: last_output_type = self.pipeline[-1].output_type LOGGER.info( "Last pipe: %s ; Last output type: %s", self.pipeline[-1], last_output_type ) else: last_output_type = self.export_input_type LOGGER.info("Input type: %s", last_output_type) t = paperwork_backend.docexport.ExportDataType.OUTPUT_URL_FILE if last_output_type == t: self.button_validate.set_sensitive(True) self.button_send_email.set_sensitive(True) else: self._add_combobox(steps, last_output_type, "") self.button_validate.set_sensitive(False) self.button_send_email.set_sensitive(False) def _rebuild_pipeline_from_ui(self): LOGGER.info("Rebuilding pipeline from UI") self.pipeline = [] steps = self.widget_tree.get_object("exporter_steps") for combobox in steps: self._expand_pipeline() pipe = combobox.get_active() pipe = combobox.get_model()[pipe][1] if pipe == "": return pipe = self.core.call_success("export_get_pipe_by_name", pipe) self.pipeline.append(pipe) LOGGER.info("Pipeline from UI: %s", [p.name for p in self.pipeline]) def _hide_preview(self): if self.tmp_file_url is not None: self.core.call_success("fs_unlink", self.tmp_file_url, trash=False) self.tmp_file_url = None if self.renderer is not None: self.renderer.close() self.renderer = None label = self.widget_tree.get_object("exporter_estimated_size") label.set_text("") label.set_visible(False) def _resize_preview(self): self.preview.set_size_request( int(self.renderer.size[0] * self.renderer.zoom), int(self.renderer.size[1] * self.renderer.zoom) ) def _on_size_obtained(self, *args, **kwargs): if self.need_zoom_auto: allocation = self.widget_tree.get_object( "exporter_scroll" ).get_allocation() allocation = (allocation.width - 20, allocation.height - 20) zoom = min( allocation[0] / self.renderer.size[0], allocation[1] / self.renderer.size[1], ) self.zoom.set_value(zoom) self.renderer.zoom = zoom self.need_zoom_auto = False self._resize_preview() def _redraw_preview(self, renderer): self.preview.queue_draw() def _show_preview(self, tmp_file_urls): tmp_file_url = list(tmp_file_urls)[0] LOGGER.info("Preview: %s", tmp_file_url) self.tmp_file_url = tmp_file_url self.renderer = self.core.call_success( "cairo_renderer_by_url", "exporter", tmp_file_url ) self.renderer.zoom = self.zoom.get_value() self.renderer.connect("size_obtained", self._on_size_obtained) self.renderer.connect("img_obtained", self._redraw_preview) self.renderer.start() self.renderer.render() return tmp_file_url def _show_estimated_size(self, tmp_file_url): preview_size = self.core.call_success("fs_getsize", tmp_file_url) factors = ( p.get_estimated_size_factor(self.export_input) for p in self.pipeline ) final_size = preview_size for f in factors: final_size *= f LOGGER.info( "Preview size: %d ; Estimated final size: %d", preview_size, final_size ) final_size = self.core.call_success("i18n_file_size", final_size) label_txt = _("Estimated file size: %s") % (final_size) label = self.widget_tree.get_object("exporter_estimated_size") label.set_text(label_txt) label.set_visible(True) return tmp_file_url def _get_pipe_plug(self): if self.pipeline[-1].output_type == 'pages': return self.core.call_success( "export_get_pipe_by_name", "png" ) return None def _set_quality(self): can_change_quality = False for pipe in self.pipeline: if not pipe.can_change_quality: continue can_change_quality = True pipe.set_quality(self.quality.get_value() / 100) self.widget_tree.get_object("exporter_quality").set_sensitive( can_change_quality ) self.widget_tree.get_object("exporter_quality_label").set_sensitive( can_change_quality ) def _set_page_format(self): page_format = self.combobox_page_format.get_active() page_format = self.model_page_format[page_format] can_change_page_format = False for pipe in self.pipeline: if not pipe.can_change_page_format: continue can_change_page_format = True pipe.set_page_format((page_format[1], page_format[2])) self.widget_tree.get_object("exporter_page_format").set_sensitive( can_change_page_format ) self.widget_tree.get_object( "exporter_page_format_label" ).set_sensitive( can_change_page_format ) def _reload_preview(self): self.core.call_all("work_queue_cancel_all", "exporter") promise = openpaperwork_core.promise.Promise( self.core, self._hide_preview ) if len(self.pipeline) <= 0: self.core.call_success( "work_queue_add_promise", "exporter", promise ) return # some pipeline only accepts ExportDataType.DOCUMENT as input, # other accept ExportDataType.PAGE, but not immediately. # For the preview, we prefer ExportDataType.PAGE, # if not available we fall back to ExportDataType.DOCUMENT for (idx, pipe) in enumerate(self.pipeline): if (pipe.input_type == paperwork_backend.docexport.ExportDataType.PAGE): pipeline = self.pipeline[idx:] ref_input = self.ref_input_page break else: for (idx, pipe) in enumerate(self.pipeline): if (pipe.input_type == paperwork_backend.docexport.ExportDataType.DOCUMENT): pipeline = self.pipeline[idx:] ref_input = self.ref_input_doc break else: LOGGER.warning( "Can't display export preview:" " No matching input pipe found in %s", [str(p) for p in self.pipeline] ) return ref_input = ref_input.clone() pipe_plug = self._get_pipe_plug() if pipe_plug is not None: if pipe_plug.can_change_quality: pipe_plug.set_quality(self.quality.get_value() / 100) if pipe_plug.can_change_page_format: page_format = self.combobox_page_format.get_active() page_format = self.model_page_format[page_format] pipe_plug.set_page_format((page_format[1], page_format[2])) t = paperwork_backend.docexport.ExportDataType.OUTPUT_URL_FILE if pipe_plug is None and pipeline[-1].output_type != t: LOGGER.warning( "Can't display export preview: unexpected pipe end: %s", pipeline[-1].output_type ) self.core.call_success( "work_queue_add_promise", "exporter", promise ) return promise = promise.then(self.core.call_all, "on_busy") promise = promise.then(lambda *args, **kwargs: ref_input) for pipe in pipeline: promise = promise.then(pipe.get_promise(result='preview')) if pipe_plug is not None: promise = promise.then(pipe_plug.get_promise(result='preview')) promise = promise.then(self._show_preview) if pipe_plug is None: promise = promise.then(self._show_estimated_size) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_all, "on_idle") self.core.call_success("work_queue_add_promise", "exporter", promise) def _gtk_open_exporter(self): self.pipeline = [] self.need_zoom_auto = True self._expand_pipeline() self._refresh_pipeline_ui() self._set_quality() self._set_page_format() self._reload_preview() self.core.call_all("mainwindow_show", "right", "exporter") def gtk_open_exporter(self, doc_id, doc_url, page_idx=None): ref_page_idx = 0 if page_idx is not None: ref_page_idx = page_idx elif doc_url == self.active_doc[1]: ref_page_idx = self.active_page_idx self.ref_input_page = ( paperwork_backend.docexport.ExportData.build_page( doc_id, doc_url, ref_page_idx ) ) self.ref_input_doc = ( paperwork_backend.docexport.ExportData.build_doc(doc_id, doc_url) ) self.export_input_type = ( paperwork_backend.docexport.ExportDataType.DOCUMENT if page_idx is None else paperwork_backend.docexport.ExportDataType.PAGE ) self.export_input = ( paperwork_backend.docexport.ExportData.build_doc(doc_id, doc_url) if page_idx is None else paperwork_backend.docexport.ExportData.build_page( doc_id, doc_url, page_idx ) ) self.export_input_doc_urls = [doc_url] self._gtk_open_exporter() def gtk_open_exporter_multiple_docs( self, docs, ref_doc_id, ref_doc_url, ref_page_idx): self.ref_input_page = ( paperwork_backend.docexport.ExportData.build_page( ref_doc_id, ref_doc_url, ref_page_idx ) ) self.ref_input_doc = ( paperwork_backend.docexport.ExportData.build_doc( ref_doc_id, ref_doc_url ) ) self.export_input_type = ( paperwork_backend.docexport.ExportDataType.DOCUMENT_SET ) self.export_input = ( paperwork_backend.docexport.ExportData.build_doc_set(docs) ) self.export_input_doc_urls = [doc[1] for doc in docs] self._gtk_open_exporter() def _on_draw(self, drawing_area, cairo_context): if self.renderer is None: return self.renderer.draw(cairo_context) def _on_zoom_changed(self, adj): if self.renderer is None: return self.renderer.zoom = adj.get_value() self._resize_preview() self.preview.queue_draw() def _on_quality_changed(self, adj): self._set_quality() self._reload_preview() def _on_page_format_changed(self, combobox): self._set_page_format() self._reload_preview() def _on_pipeline_changed(self, *args, **kwargs): self._rebuild_pipeline_from_ui() self._expand_pipeline() # WORKAROUND(JFlesch): call this method using mainloop_schedule. # Otherwise, in Flatpak, with Gnome 40, it crashes. self.core.call_one("mainloop_schedule", self._refresh_pipeline_ui) self._set_quality() self._set_page_format() self._reload_preview() def _on_cancel(self, button): LOGGER.info("Export canceled") self.core.call_all("mainwindow_back", side="right") def _on_apply(self, button): LOGGER.info("Export settings defined. Opening file chooser dialog") dialog = Gtk.FileChooserNative.new( _("Select a file to which export the document"), self.windows[-1], Gtk.FileChooserAction.SAVE, None, None ) dialog.set_modal(True) dialog.set_local_only(False) file_filter = Gtk.FileFilter() file_filter.set_name(_("Any files")) file_filter.add_pattern("*.*") dialog.add_filter(file_filter) (mime, file_extensions) = self.pipeline[-1].get_output_mime() file_filter = Gtk.FileFilter() file_filter.add_mime_type(mime) file_filter.set_name(file_extensions[0]) # TODO(Jflesch): better name dialog.add_filter(file_filter) dialog.set_filter(file_filter) last_export_uri = self.core.call_success( "config_get", "last_export_uri" ) if last_export_uri is not None: # this filename does not exist, but the parent directory # will be selected. A hack inspired by what firefox does. dialog.set_uri(last_export_uri + str(random.randint(0, 10000))) dialog.connect("response", self._on_dialog_response) dialog.run() dialog.hide() dialog.destroy() def _on_dialog_response(self, dialog, response_id): if (response_id != Gtk.ResponseType.ACCEPT and response_id != Gtk.ResponseType.OK and response_id != Gtk.ResponseType.YES and response_id != Gtk.ResponseType.APPLY): LOGGER.info("User canceled (response_id=%d)", response_id) return selected = dialog.get_uris()[0] self.core.call_all("mainwindow_back", side="right") # make sure the file extension is set (mime, file_extensions) = self.pipeline[-1].get_output_mime() for file_extension in file_extensions: if selected.lower().endswith(file_extension): break else: selected += "." + file_extensions[0] self.core.call_all("config_put", "last_export_uri", selected) promise = openpaperwork_core.promise.Promise( self.core, lambda: self.export_input ) for pipe in self.pipeline: promise = promise.then(pipe.get_promise( result='final', target_file_url=selected )) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(Gtk.RecentManager().add_item, selected) promise = promise.then(lambda *args, **kwargs: None) promise = promise.catch(self._on_error) # do not use the work queue ; must never be canceled promise.schedule() def _on_send_email(self, button): (_, file_extensions) = self.pipeline[-1].get_output_mime() (target_file_url, fd) = self.core.call_success( "fs_mktemp", suffix="." + file_extensions[0], on_disk=True ) fd.close() # we only need the name self.core.call_all("mainwindow_back", side="right") promise = openpaperwork_core.promise.Promise( self.core, lambda: self.export_input ) for pipe in self.pipeline: promise = promise.then(pipe.get_promise( result='final', target_file_url=target_file_url )) promise = promise.then(lambda *args, **kwargs: self.core.call_success( "external_app_send_as_attachment", target_file_url )) promise = promise.then(lambda *args, **kwargs: None) promise = promise.catch(self._on_error) # do not use the work queue ; must never be canceled promise.schedule() def _on_error(self, exc): LOGGER.error("Export failed", exc_info=exc) notif = self.core.call_success( "get_notification_builder", _("Export has failed"), ) notif.set_message(f"Export has failed: {type(exc)} {exc}") notif.set_icon("dialog-error") notif.show() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/exporter.glade000066400000000000000000000447631456262201400307040ustar00rootroot00000000000000 True False mail-message-new True False True :close 100 75 1 10 0.01 1.5 0.01 0.01 0.10 True False True False 10 10 10 10 vertical 20 True False 0 none True False 12 True False vertical True False 10 10 Export Steps False True 0 True False 0 none True False 12 True False 10 True True True True exporter_quality_adjustment False 100 0 0 left 1 0 True False Quality 0 0 True False Paper format 0 1 True False True exporter_page_format_model 0 1 1 True False 0 2 2 True False Export Settings False True 1 True False 10 True False True True 0 gtk-cancel True True True True False True 1 Send by email True False True True exporter_email_icon False True 2 gtk-save-as True False True True True False True 3 False True 2 True False 20 0 none True False 12 True False 10 5 True False vertical True False edit-find-symbolic 3 False True 0 True True vertical exporter_zoom_adjustment True False True True 1 False True 0 True True always always in True False True False True False False False 1 True True 1 True False Preview True True 3 -1 True False True paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/exporter/pipe.glade000066400000000000000000000014631456262201400277570ustar00rootroot00000000000000 True False exporter_pipe_model 0 1 0 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/global.css000066400000000000000000000011371456262201400261240ustar00rootroot00000000000000.button-left { border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-right-width: 0px; margin-right: 0px; } .button-center { border-radius: 0px; border-right-width: 0px; margin-left: 0px; margin-right: 0px; } .button-right { margin-left: 0px; border-top-left-radius: 0px; border-bottom-left-radius: 0px; } .borderless { border: 0px; } .txt-hint { color: mix (@theme_fg_color, @theme_bg_color, 0.3); } .headerbar-selection-multiple, .headerbar-selextion-multiple > * { background-color: #38a1d6; background-image: none; } .button-tight { padding: 0px; } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/home/000077500000000000000000000000001456262201400251005ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/home/__init__.py000066400000000000000000000027611456262201400272170ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['home'] def get_deps(self): return [ { 'interface': 'app', 'defaults': ['paperwork_backend.app'], }, { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'icon', 'defaults': ['paperwork_gtk.icon'], }, ] def init(self, core): super().init(core) widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.home", "home.glade" ) if widget_tree is None: return logo_pixbuf = self.core.call_success( "icon_get_pixbuf", "paperwork", 128 ) logo_widget = widget_tree.get_object("paperwork_logo") logo_widget.set_from_pixbuf(logo_pixbuf) logo_text = widget_tree.get_object("main_label") logo_text.set_text("Paperwork {}".format( self.core.call_success("app_get_version") )) self.core.call_all( "mainwindow_add", side="right", name="home", prio=100000, header=None, body=widget_tree.get_object("home") ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/home/home.glade000066400000000000000000000025001456262201400270230ustar00rootroot00000000000000 True False center center vertical False True 0 True False Paperwork kick-ass edition False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/pageeditor/000077500000000000000000000000001456262201400262735ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/pageeditor/__init__.py000066400000000000000000000315101456262201400304040ustar00rootroot00000000000000import collections import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps import paperwork_backend.pageedit LOGGER = logging.getLogger(__name__) MODIFIER_ICONS = collections.defaultdict( lambda: "document-properties", { "color_equalization": ( "paperwork_gtk.mainwindow.pageeditor", "magic_colors.png" ), "crop": "edit-cut-symbolic", "rotate_clockwise": "object-rotate-left-symbolic", "rotate_counterclockwise": "object-rotate-right-symbolic", } ) class GtkPageEditorUI(paperwork_backend.pageedit.AbstractPageEditorUI): CAPABILITIES = ( paperwork_backend.pageedit.AbstractPageEditorUI.CAPABILITY_SHOW_FRAME ) def __init__(self, plugin): super().__init__() self.plugin = plugin self.core = plugin.core self.editor = None self.modifiers_to_toggles = {} self.buttons_to_modifiers = {} self.pil_img = None self.surface_img = None self.size_allocated = None self.allocate_handler_id = None self.draw_handler_id = self.plugin.widget_tree.get_object( "pageeditor_img" ).connect("draw", self.draw) self.zoom = self.plugin.widget_tree.get_object( "pageeditor_zoom_adjustment" ) self.zoom.connect("value-changed", self._on_zoom_changed) def add_modifier_toggles(self): assert self.editor is not None toolbox = self.plugin.widget_tree.get_object("pageeditor_tools") zoom_box = self.plugin.widget_tree.get_object("pageeditor_zoom_box") for widget in list(toolbox.get_children()): if widget == zoom_box: continue toolbox.remove(widget) for modifier in self.editor.get_modifiers(): glade = ( "modifier_toggle.glade" if modifier['togglable'] else "modifier.glade" ) modifier_widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.pageeditor", glade ) button = modifier_widget_tree.get_object("pageeditor_modifier") button.set_tooltip_text(modifier['name']) if modifier['togglable']: button.set_active(modifier['enabled']) button.connect("toggled", self._on_modifier_changed) self.modifiers_to_toggles[modifier['id']] = button else: button.connect("clicked", self._on_modifier_changed) img = modifier_widget_tree.get_object("pageeditor_modifier_img") icon = MODIFIER_ICONS[modifier['id']] if isinstance(icon, tuple): icon = self.core.call_success("gtk_load_pixbuf", *icon) img.set_from_pixbuf(icon) else: img.set_from_icon_name(icon, Gtk.IconSize.LARGE_TOOLBAR) toolbox.pack_start(button, expand=False, fill=True, padding=0) self.buttons_to_modifiers[button] = modifier['id'] if self.size_allocated is None: self.allocate_handler_id = self.plugin.widget_tree.get_object( "pageeditor_scroll" ).connect("size-allocate", self._on_size_allocate) else: self.set_default_zoom() self.plugin.widget_tree.get_object( "pageeditor_img" ).connect("realize", self.refresh) def _on_modifier_changed(self, button): modifier = self.buttons_to_modifiers[button] promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_busy",) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.editor.on_modifier_selected(modifier)) promise.then(self.refresh) promise.then(self.core.call_all, "on_idle") promise.schedule() def _on_size_allocate(self, *args, **kwargs): self.plugin.widget_tree.get_object( "pageeditor_scroll" ).disconnect(self.allocate_handler_id) self.allocate_handler_id = None self.set_default_zoom() def set_default_zoom(self, *args, **kwargs): allocation = self.plugin.widget_tree.get_object( "pageeditor_scroll" ).get_allocation() img_size = self.pil_img.size zoom = min( (allocation.width - 20) / img_size[0], (allocation.height - 20) / img_size[1] ) LOGGER.info( "Allocation: %dx%d ; Image: %dx%d ==> Setting zoom at %f", allocation.width, allocation.height, img_size[0], img_size[1], zoom ) self.zoom.set_value(zoom) self.refresh() def _get_scaled_image_size(self): img_size = self.pil_img.size zoom = self.zoom.get_value() return (img_size[0] * zoom, img_size[1] * zoom) def refresh(self, *args, **kwargs): widget_size = self._get_scaled_image_size() img = self.plugin.widget_tree.get_object("pageeditor_img") img.set_size_request(widget_size[0], widget_size[1]) # WORKAROUND(JFlesch): I shouldn't have to use 'mainloop_schedule' # here. But somehow, I do have to use it :/ self.core.call_all("mainloop_schedule", img.queue_resize) def _on_zoom_changed(self, adj=None): self.refresh() def set_modifier_state(self, modifier_id, enabled): super().set_modifier_state(modifier_id, enabled) LOGGER.info("Modifier %s: %s", modifier_id, enabled) def show_preview(self, img): super().show_preview(img) need_rezoom = (self.pil_img is None) self.pil_img = img self.surface_img = self.core.call_success( "pillow_to_surface", self.pil_img ) if need_rezoom: self.set_default_zoom() self.refresh() LOGGER.info("Preview refreshed (%s)", img.size) def show_frame_selector(self): super().show_frame_selector() if self.pil_img is None: return img = self.plugin.widget_tree.get_object("pageeditor_img") self.core.call_all("draw_frame_stop", img) LOGGER.info( "show_frame_selector() (img size: %s ; frame: %s)", self.pil_img.size, self.editor.frame.get() ) self.core.call_all( "draw_frame_start", img, self.pil_img.size, self.editor.frame.get, self.editor.frame.set ) def hide_frame_selector(self): super().hide_frame_selector() LOGGER.info("hide_frame_selector()") img = self.plugin.widget_tree.get_object("pageeditor_img") self.core.call_all("draw_frame_stop", img) def on_edit_end(self, doc_url, page_idx): super().on_edit_end(doc_url, page_idx) self.plugin._on_edit_end(doc_url, page_idx) self._disconnect_draw() self.surface_img = None def _disconnect_draw(self): if self.draw_handler_id is None: return self.plugin.widget_tree.get_object( "pageeditor_img" ).disconnect(self.draw_handler_id) self.draw_handler_id = None def cancel(self): self.editor.on_cancel() self._disconnect_draw() def save(self): self.core.call_all("on_busy") self.plugin.widget_tree.get_object("pageeditor_back").set_sensitive( False ) promise = openpaperwork_core.promise.Promise(self.core) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.editor.on_save()) promise = promise.then(self.core.call_all, "on_idle") promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_success( "transaction_simple_promise", [("upd", self.plugin.active_doc[0])] )) self.core.call_success("transaction_schedule", promise) def draw(self, widget, cairo_ctx): if self.surface_img is None: return cairo_ctx.save() try: zoom = self.zoom.get_value() cairo_ctx.scale(zoom, zoom) cairo_ctx.set_source_surface(self.surface_img.surface) cairo_ctx.paint() finally: cairo_ctx.restore() class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.ui = None self.active_doc = None def get_interfaces(self): return [ 'chkdeps', 'gtk_page_editor', ] def get_deps(self): return [ { 'interface': 'gtk_drawer_frame', 'defaults': ['paperwork_gtk.drawer.frame'], }, { 'interface': 'gtk_mainwindow', 'defaults': ['paperwork_gtk.mainwindow.window'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_zoomable', 'defaults': ['paperwork_gtk.gesture.zoom'], }, { 'interface': 'page_editor', 'defaults': ['paperwork_backend.pageedit.pageeditor'], }, { 'interface': 'pillow_to_surface', 'defaults': ['paperwork_backend.cairo.pillow'], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.pageeditor", "pageeditor.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.widget_tree.get_object("pageeditor_cancel").connect( "clicked", self._on_cancel ) self.widget_tree.get_object("pageeditor_back").connect( "clicked", self._on_apply ) self.core.call_all( "on_zoomable_widget_new", self.widget_tree.get_object("pageeditor_scroll"), self.widget_tree.get_object("pageeditor_zoom_adjustment"), ) self.core.call_all( "mainwindow_add", "right", "pageeditor", prio=0, header=self.widget_tree.get_object("pageeditor_header"), body=self.widget_tree.get_object("pageeditor_body") ) def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def gtk_open_page_editor(self, doc_id, doc_url, page_idx): LOGGER.info("Opening page editor on %s %d", doc_id, page_idx) self.active_doc = (doc_id, doc_url) page_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) if page_url is None: LOGGER.error( "Can't open page editor: Failed to get page url (%s, p%d)", doc_id, page_idx ) return self.ui = GtkPageEditorUI(self) self.widget_tree.get_object("pageeditor_back").set_sensitive(True) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_busy",) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then( self.core.call_success, "page_editor_get", doc_url, page_idx, self.ui ) promise = promise.then( self._show_page_editor, self.ui, doc_id, doc_url, page_idx ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_all, "on_idle") promise.schedule() def _on_cancel(self, button): if self.ui is None: return self.ui.cancel() self.ui = None def _on_apply(self, button): if self.ui is None: return self.ui.save() def _on_edit_end(self, doc_url, page_idx): self.core.call_all("mainwindow_back", side="right") self.core.call_all("doc_reload", *self.active_doc) self.core.call_success( "mainloop_schedule", self.core.call_all, "doc_goto_page", page_idx ) self.ui = None def _show_page_editor(self, page_editor, ui, doc_id, doc_url, page_idx): self.ui.editor = page_editor self.ui.add_modifier_toggles() self.core.call_all("mainwindow_show", "right", "pageeditor") paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/pageeditor/magic_colors.png000066400000000000000000000017421456262201400314460ustar00rootroot00000000000000‰PNG  IHDRÔòÅœsBIT|dˆ pHYscc¾Î–stEXtSoftwarewww.inkscape.org›î<_IDATH‰µ–KhœUÇmZ+I444HèÂ&"BÔªèB1Õ€(µší†Q¤+ݹêBP%V«Å(†ÆØJÑ–VŠ‹„¶¶'’6’4ÚÌÏÅ÷MsçË7cÒ&çraî¹gÎïÜÿ}ÌÀ•Û& 6¯îº€•K¿¨Uttt wwwŸîŠ}W‡€,°aÙÈõõõ=™LFÕ–––,Ѫ6O,hîííUµ¯¯Ï²²²¢UߺœP€ŠöööŒêØØ˜?õÀ×ÀQà‘8n#ðüRÃ?hkksjjÊ®®®q`]ìÿ ˜ªãñ6à,K¨F3lhhx&˜Û4•oÉÀ×'ãþUJ̲]¯ðßD÷û%à^` °h]h²ÅT¹ØŒ_&bøÃÀuÀ 0½ˆœ ²¤Ü½Á\-ÑãNX-Ô Â5Kï À#@M8)” o §ã~Q¼ðCħ;î[àáhMöœðú倫€Søóx…°¯8ìO/¾;gˆUo] XáaÅBÁ`§’ÂîEÀn_¸ ø3ïI Ækp¤ sk AÿRé ¶xœN³Ü“÷oMË“´Oð0 ¹‘uÈ®/§¸¨¨8)ÎàáÎû=È ÓäòSŠž`ÆW9°\•»dS(÷–¸E|#Ì.¾ë?³zðÇ·¢3hu$J˜ú¬¥PîOà&d£¶^³ÿur›9/Ù¯ßÂ{ wåÛ4øgø s?yø/yp¾uŠ9ñÈ蔡M«Ù»#ðzýüó÷d˜º5!÷£ ðIp¾mm2ã|Ûׯýh]úáÿ.”ûtþxž&òr18‡^³\Ý®¾£~¡¾­¶9_êæeó'ï= .þ< ¼’²%Õ)¾Èfod’èE*°\yѯU+‰þe>8wçR‚GЦ©L÷Ÿ)ÅŽf0'wOÑP¹¹¨ì*e$—¼]Ò]òÁ{¢d/Ñž¯-Y«|_´€þBð˜rCQðpc>íjà–’à¾I…ÏTÈïc8§t”\õÎÿe)à6d(µ€ñZÙ*ÇsE¡çÁ. True True False True True False 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/pageeditor/modifier_toggle.glade000066400000000000000000000012711456262201400324310ustar00rootroot00000000000000 True True False True True False 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/pageeditor/pageeditor.glade000066400000000000000000000141211456262201400314130ustar00rootroot00000000000000 0.01 1.5 0.01 0.01 0.1 True False True False True True False True False always always False True False True True False False 0 start True True True False vertical True False vertical 10 10 True edit-find-symbolic 1 False True start True True vertical pageeditor_zoom_adjustment True False True True start True True end end False True -1 True False True :close True False True True gtk-cancel start True False False True True gtk-apply end paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/000077500000000000000000000000001456262201400254155ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/__init__.py000066400000000000000000000000001456262201400275140ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.glade000066400000000000000000000175121456262201400301660ustar00rootroot00000000000000 False True False False Search 800 300 system-search dialog False vertical 2 False end gtk-cancel True True True True True True 0 gtk-apply True True True True True True 1 False False 0 True True in True False True False vertical True False False True 0 True False True False True True 0 gtk-add True True True True False True 1 False True 1 True False 0.02 True True 2 True True 1 button_cancel button_apply paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/advanced.py000066400000000000000000000456111456262201400275430ustar00rootroot00000000000000import datetime import logging import re try: from gi.repository import GLib from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps from ... import _ LOGGER = logging.getLogger(__name__) def strip_quotes(txt): if txt[0] == u'"' and txt[-1] == u'"': return txt[1:-1] if txt[0] == u'\'' and txt[-1] == u'\'': return txt[1:-1] return txt class SearchElement(object): def __init__(self, dialog, widget): self.dialog = dialog self.widget = widget widget.set_hexpand(True) widget.show_all() def get_widget(self): return self.widget def get_search_string(self): assert False @staticmethod def get_from_search(dialog, text): assert False @staticmethod def get_name(): assert False def on_model_updated(self): pass class SearchElementText(SearchElement): """This is the keyword search term text field""" def __init__(self, dialog): super(SearchElementText, self).__init__(dialog, Gtk.Entry()) def get_search_string(self): txt = self.widget.get_text() txt = txt.replace('"', '\\"') return '"%s"' % txt @staticmethod def get_from_search(dialog, text): text = strip_quotes(text) element = SearchElementText(dialog) element.widget.set_text(text) return element @staticmethod def get_name(): return _("Keyword(s)") def __str__(self): return ("Text: [%s]" % self.widget.get_text()) class SearchElementLabel(SearchElement): def __init__(self, dialog): super().__init__(dialog, Gtk.ComboBoxText()) self.on_model_updated() self.widget.set_active(0) def on_model_updated(self): labels = set() self.dialog.core.call_all("labels_get_all", labels) labels = [label[0] for label in labels] labels = self.dialog.core.call_success("i18n_sort", labels) store = Gtk.ListStore.new([GObject.TYPE_STRING]) if len(labels) <= 0: # happens temporarily when Paperwork starts store.append([_("No labels")]) self.widget.set_sensitive(False) else: for label in labels: store.append([label]) self.widget.set_sensitive(True) self.widget.set_model(store) def get_search_string(self): active_idx = self.get_widget().get_active() if active_idx < 0: return "" model = self.get_widget().get_model() txt = model[active_idx][0] txt = txt.replace('"', '\\"') return 'label:"%s"' % txt @staticmethod def get_from_search(dialog, text): if not text.startswith(u"label:"): return None text = text[len(u"label:"):] text = strip_quotes(text) element = SearchElementLabel(dialog) active_idx = -1 idx = 0 for line in element.get_widget().get_model(): value = line[0] if value == text: active_idx = idx idx += 1 element.get_widget().set_active(active_idx) return element @staticmethod def get_name(): return _("Label") def __str__(self): return ("Label: [%d]" % self.get_widget().get_active()) class SearchElementDate(SearchElement): """Search entry using a time span""" def __init__(self, dialog): box = Gtk.Box() box.set_spacing(10) label = Gtk.Label.new(_("From:")) box.add(label) self.start_date = self._make_date_widget() box.add(self.start_date) label = Gtk.Label.new(_("to:")) box.add(label) self.end_date = self._make_date_widget() box.add(self.end_date) super(SearchElementDate, self).__init__(dialog, box) self.calendar_popover = dialog.widget_tree.get_object( "calendar_popover" ) self.calendar = dialog.widget_tree.get_object("calendar_calendar") self.current_entry = None self.calendar.connect( "day-selected-double-click", lambda _: GLib.idle_add(self._close_calendar) ) def _make_date_widget(self): entry = Gtk.Entry() entry.set_text("") entry.set_property("secondary_icon_sensitive", True) entry.set_property("secondary_icon_name", "x-office-calendar-symbolic") entry.connect( "icon-release", lambda entry, icon, event: GLib.idle_add(self._open_calendar, entry) ) return entry @staticmethod def _parse_date(txt): txt = txt.strip() if txt == u"": dt = datetime.datetime.today() else: try: dt = datetime.datetime.strptime(txt, "%Y%m%d") except ValueError: LOGGER.warning( "Failed to parse [%s]. Will use today date", txt ) dt = datetime.datetime.today() return (dt.year, dt.month, dt.day) @staticmethod def _format_date(date): return "%04d%02d%02d" % (date[0], date[1], date[2]) def _open_calendar(self, entry): self.calendar_popover.set_relative_to(entry) date = self._parse_date(entry.get_text()) self.calendar.select_month(date[1] - 1, date[0]) self.calendar.select_day(date[2]) self.calendar_popover.show_all() self.current_entry = entry def _close_calendar(self): date = self.calendar.get_date() date = datetime.datetime(year=date[0], month=date[1] + 1, day=date[2]) date = self._format_date((date.year, date.month, date.day)) self.current_entry.set_text(date) self.calendar_popover.set_visible(False) def get_search_string(self): start_date = self._parse_date(self.start_date.get_text()) end_date = self._parse_date(self.end_date.get_text()) if end_date < start_date: tmp_date = start_date start_date = end_date end_date = tmp_date if start_date == end_date: return ( "date:%04d%02d%02d" % (start_date[0], start_date[1], start_date[2]) ) return ( 'date:[%04d%02d%02d to %04d%02d%02d]' % ( start_date[0], start_date[1], start_date[2], end_date[0], end_date[1], end_date[2] ) ) @staticmethod def get_from_search(dialog, txt): if not txt.startswith(u"date:"): return None txt = txt[len(u"date:"):] txt = strip_quotes(txt) if txt[0] == "[" and txt[-1] == "]": txt = txt[1:-1] if " to " in txt: txt = txt.split(" to ", 1) else: txt = [txt, txt] dates = [ SearchElementDate._parse_date(date) for date in txt ] se = SearchElementDate(dialog) se.start_date.set_text(se._format_date(dates[0])) se.end_date.set_text(se._format_date(dates[1])) return se @staticmethod def get_name(): return _("Date") def __str__(self): return ( "Date: [%s] - [%s]" % (self.start_date.get_text(), self.end_date.get_text()) ) class SearchLine(object): SELECT_ORDER = [ SearchElementText, SearchElementLabel, SearchElementDate, ] TXT_EVAL_ORDER = [ SearchElementDate, SearchElementLabel, SearchElementText, ] def __init__(self, dialog, has_operator, has_remove_button): LOGGER.info("Search line instantiated") self.dialog = dialog self.line = [] if has_operator: model = Gtk.ListStore.new([ GObject.TYPE_STRING, GObject.TYPE_STRING, ]) model.append([_("and"), "AND"]) model.append([_("or"), "OR"]) self.combobox_operator = Gtk.ComboBoxText.new() self.combobox_operator.set_model(model) self.combobox_operator.set_size_request(75, -1) self.combobox_operator.set_active(0) self.line.append(self.combobox_operator) else: self.combobox_operator = None placeholder = Gtk.Label.new("") placeholder.set_size_request(75, -1) self.line.append(placeholder) model = Gtk.ListStore.new([ GObject.TYPE_STRING, GObject.TYPE_STRING, ]) model.append(["", ""]) model.append([_("not"), "NOT"]) self.combobox_not = Gtk.ComboBoxText.new() self.combobox_not.set_model(model) self.combobox_not.set_size_request(75, -1) self.combobox_not.set_active(0) self.line.append(self.combobox_not) model = Gtk.ListStore.new([ GObject.TYPE_STRING, GObject.TYPE_PYOBJECT, ]) for element in self.SELECT_ORDER: model.append([ element.get_name(), element ]) self.combobox_type = Gtk.ComboBoxText.new() self.combobox_type.set_model(model) self.placeholder = Gtk.Label.new("") self.placeholder.set_hexpand(True) self.element = None self.remove_button = Gtk.Button.new_with_label(_("Remove")) self.line.append(self.combobox_type) self.line.append(self.placeholder) if has_remove_button: self.line.append(self.remove_button) else: self.line.append(Gtk.Label.new("")) self.combobox_type.set_active(0) self.change_element() def connect_signals(self): self.combobox_type.connect( "changed", lambda w: GLib.idle_add(self.change_element) ) self.remove_button.connect( "clicked", lambda x: GLib.idle_add( self.dialog.remove_element, self ) ) @staticmethod def _select_value(combobox, value): if not combobox: return active_idx = 0 model = combobox.get_model() for line in model: if line[1] == value: LOGGER.info("Element %d selected", active_idx) combobox.set_active(active_idx) return active_idx += 1 assert False def select_operator(self, operator): self._select_value(self.combobox_operator, operator.upper()) def select_not(self, not_value): self._select_value(self.combobox_not, not_value) def select_element_type(self, et): self._select_value(self.combobox_type, et) def change_element(self): LOGGER.info("Element changed") active_idx = self.combobox_type.get_active() if (active_idx < 0): return element_class = self.combobox_type.get_model()[active_idx][1] element = element_class(self.dialog) self.set_element(element) def set_element(self, element): LOGGER.info("Set element: %s", str(element)) if self.placeholder: self.line.remove(self.placeholder) self.placeholder = None if self.element: self.line.remove(self.element.get_widget()) self.element = None self.line.insert(3, element.get_widget()) self.element = element self.dialog.rebuild() def get_widgets(self): return self.line @staticmethod def _get_combobox_value(combobox): active_idx = combobox.get_active() if (active_idx < 0): return "" value = combobox.get_model()[active_idx][1] return value def get_operator(self): if not self.combobox_operator: return u"" return self._get_combobox_value(self.combobox_operator) def get_not(self): return self._get_combobox_value(self.combobox_not) def get_search_string(self): if self.element is None: return "" return self.element.get_search_string() @staticmethod def get_from_search(dialog, next_operator, not_value, search_txt): for se_class in SearchLine.TXT_EVAL_ORDER: se = se_class.get_from_search(dialog, search_txt) if not se: continue sl = SearchLine( dialog, next_operator is not None, next_operator is not None ) if next_operator: sl.select_operator(next_operator) sl.select_element_type(se_class) sl.select_not(not_value) sl.set_element(se) sl.connect_signals() LOGGER.info( "Loaded from search: %s --> %s", search_txt, str(se) ) return sl assert False def on_model_updated(self): if self.element: self.element.on_model_updated() class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None self.windows = [] self.search_element_box = None self.search_elements = [] self.dialog = None def get_interfaces(self): return [ 'chkdeps', 'gtk_advanced_search_dialog', 'gtk_window_listener', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def gtk_open_advanced_search_dialog(self): if self.dialog is not None: LOGGER.warning("Advanced search dialog already opened") return self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.search", "advanced.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.dialog = self.widget_tree.get_object("search_dialog") self.dialog.set_transient_for(self.windows[-1]) keywords = self.core.call_success("search_get") keywords = keywords.strip() keywords = re.findall( r'(?:\[.*\]|(?:[^\s"]|"(?:\\.|[^"])*"))+', keywords ) self.search_element_box = self.widget_tree.get_object( "box_search_elements" ) self.search_elements = [] add_button = self.widget_tree.get_object("button_add") add_button.connect( "clicked", lambda w: GLib.idle_add(self.add_element) ) if keywords == []: LOGGER.info("Starting from an empty search") self.add_element() else: LOGGER.info("Current search: %s", keywords) next_operator = None not_value = u"" for keyword in keywords: if keyword.upper() == u"AND": next_operator = u"AND" continue elif keyword.upper() == u"OR": next_operator = u"OR" continue elif keyword.upper() == u"NOT": not_value = u"NOT" continue LOGGER.info("Instantiating line for [%s]", keyword) sl = SearchLine.get_from_search( self, next_operator, not_value, keyword ) self.add_element(sl) next_operator = u"AND" not_value = u"" self.dialog.connect("response", self._on_response) self.dialog.show_all() def _on_response(self, dialog, response_id): if (response_id == Gtk.ResponseType.ACCEPT or response_id == Gtk.ResponseType.OK or response_id == Gtk.ResponseType.YES or response_id == Gtk.ResponseType.APPLY): search = self._get_search_string() self.core.call_all("search_set", search) self.gtk_close_advanced_search_dialog() def gtk_close_advanced_search_dialog(self): self.dialog.destroy() self.widget_tree = None self.dialog = None def add_element(self, sl=None): if sl is None: sl = SearchLine( self, len(self.search_elements) > 0, len(self.search_elements) > 0 ) sl.connect_signals() self.search_elements.append(sl) self.rebuild() def rebuild(self): # purge for child in self.search_element_box.get_children(): self.search_element_box.remove(child) # rebuild for (line, sl) in enumerate(self.search_elements): for (pos, widget) in enumerate(sl.get_widgets()): self.search_element_box.attach( widget, pos, line, 1, 1 ) self.search_element_box.show_all() def remove_element(self, sl): self.search_elements.remove(sl) self.rebuild() def _get_search_string(self): """concat all our search terms into a single string""" out = "" for element in self.search_elements: # Add AND/OR oper = element.get_operator() out += " %s " % oper not_value = element.get_not() if not_value: out += "%s " % not_value out += element.get_search_string() out = out.strip() LOGGER.info("Search: [%s]", out) return out def screenshot_snap_all_doc_widgets(self, out_dir): if self.dialog is None: return self.core.call_success( "screenshot_snap_widget", self.dialog, self.core.call_success( "fs_join", out_dir, "advanced_search.png" ), ) def on_label_loading_end(self): for element in self.search_elements: element.on_model_updated() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.glade000066400000000000000000000053411456262201400275010ustar00rootroot00000000000000 True False vertical True False True True • Search GTK_INPUT_HINT_SPELLCHECK | GTK_INPUT_HINT_WORD_COMPLETION | GTK_INPUT_HINT_NO_EMOJI | GTK_INPUT_HINT_NONE True True 0 True False False True Advanced search none True False text-editor-symbolic 1 False True 1 False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/field.py000066400000000000000000000136471456262201400270650ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise import paperwork_backend.sync LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -1000000 def __init__(self): super().__init__() self.search_entry = None self.widget_tree = None def get_interfaces(self): return [ 'gtk_search_field', 'screenshot_provider', 'syncable', ] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'index', 'defaults': ['paperwork_backend.index.whoosh'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_gtk.mainloop.glib'], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, { 'interface': 'thread', 'defaults': ['openpaperwork_core.thread.simple'], }, ] def init(self, core): super().init(core) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.search", "field.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return self.search_entry = self.widget_tree.get_object("search_entry") search_field = self.widget_tree.get_object("search_field") self.core.call_all("doclist_add", search_field, vposition=0) self.search_entry.connect( "search-changed", self.search_update_document_list ) self.search_entry.connect("stop-search", lambda w: self.search_stop()) self.widget_tree.get_object("search_dialog_button").connect( "clicked", lambda button: self.core.call_all( "gtk_open_advanced_search_dialog" ) ) self.core.call_all("work_queue_create", "doc_search") self.core.call_one( "mainloop_schedule", self.search_update_document_list ) def search_update_document_list(self, _=None): query = self.search_entry.get_text() LOGGER.info("Looking for [%s]", query) self.core.call_all("search_by_keywords", query) def search_get(self): return self.search_entry.get_text() def search_set(self, text): self.search_entry.set_text(text) def search_by_keywords(self, query): self.core.call_all("work_queue_cancel_all", "doc_search") self.core.call_all("on_search_start", query) if query == "": out = [] promise = openpaperwork_core.promise.ThreadedPromise( self.core, lambda: self.core.call_all( "storage_get_all_docs", out ) ) else: out = [] promise = openpaperwork_core.promise.ThreadedPromise( self.core, lambda: self.core.call_all( "index_search", out, query ) ) promise = promise.then(lambda *args, **kwargs: out) promise = promise.then(lambda docs: sorted(docs, reverse=True)) def show_if_query_still_valid(docs): # While we were looking for the documents, the query may have # changed (user tying). No point in displaying obsolete results. if query != self.search_entry.get_text(): return self.core.call_all("on_search_results", query, docs) promise = promise.then(show_if_query_still_valid) self.core.call_all("work_queue_add_promise", "doc_search", promise) def search_stop(self): self.core.call_all("work_queue_cancel_all", "doc_search") def doc_transaction_start(self, out: list, total_expected=-1): class RefreshTransaction(paperwork_backend.sync.BaseTransaction): priority = -100000 def commit(s): self.core.call_one( "mainloop_schedule", self.search_update_document_list ) out.append(RefreshTransaction(self.core, total_expected)) def sync(self, promises: list): # If someone requested a sync, assume something has changed # --> try to keep the view as up-to-date as possible. self.search_update_document_list() promises.append(openpaperwork_core.promise.Promise( self.core, self.search_update_document_list )) def screenshot_snap_all_doc_widgets(self, out_dir): self.core.call_success( "screenshot_snap_widget", self.search_entry, self.core.call_success("fs_join", out_dir, "search.png"), margins=(50, 50, 50, 140) ) self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("search_dialog_button"), self.core.call_success( "fs_join", out_dir, "advanced_search_button.png" ), margins=(200, 30, 30, 30) ) def search_focus(self): LOGGER.info("Focusing on search field") self.widget_tree.get_object("search_entry").grab_focus() def search_field_add(self, widget): search_field = self.widget_tree.get_object("search_field") search_field.add(widget) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.glade000066400000000000000000000111361456262201400307670ustar00rootroot00000000000000 True False gtk-close 2 test1 test2 True False 75 True False vertical True False True False Did you mean ? 0 True True 0 True True True end image_close none True False False 1 False True 0 True True in True True liststore_suggestions False 0 True 0 True True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/search/suggestions.py000066400000000000000000000065201456262201400303440ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -2000000 def __init__(self): super().__init__() self.widget_tree = None def get_interfaces(self): return [ 'doc_open', 'gtk_search_field_completion', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_search_field', 'defaults': ['paperwork_gtk.mainwindow.search.field'], }, { 'interface': 'suggestions', 'defaults': ['paperwork_backend.index.whoosh'], }, ] def init(self, core): super().init(core) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.search", "suggestions.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return suggestion_revealer = self.widget_tree.get_object( "suggestions_revealer" ) self.core.call_all("search_field_add", suggestion_revealer) self.widget_tree.get_object("button_close").connect( "clicked", self._close ) self.widget_tree.get_object("treeview_suggestions").connect( "row-activated", self._on_row_activated ) def _get_suggestions(self, query): out = set() self.core.call_all("suggestion_get", out, query) out = list(out) out.sort() return out def _show_suggestions(self, suggestions, query): if query != self.core.call_success("search_get"): # Text has changed while we were looking for suggestions # No point in displaying them now. return LOGGER.info("%d suggestions found", len(suggestions)) model = self.widget_tree.get_object("liststore_suggestions") model.clear() for suggestion in suggestions: model.append((suggestion,)) self.widget_tree.get_object( "suggestions_revealer" ).set_reveal_child(len(suggestions) > 0) def search_by_keywords(self, query): self.widget_tree.get_object("liststore_suggestions").clear() self.widget_tree.get_object( "suggestions_revealer" ).set_reveal_child(False) if query == "": return promise = openpaperwork_core.promise.ThreadedPromise( self.core, self._get_suggestions, args=(query,) ) promise = promise.then(self._show_suggestions, query) self.core.call_success( "work_queue_add_promise", "doc_search", promise ) def _close(self, *args, **kwargs): self.widget_tree.get_object( "suggestions_revealer" ).set_reveal_child(False) def doc_open(self, *args, **kwargs): self._close() def _on_row_activated(self, treeview, path, column): model = treeview.get_model() suggestion = model[path][0] self.core.call_all("search_set", suggestion) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/window/000077500000000000000000000000001456262201400254575ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/window/__init__.py000066400000000000000000000310701456262201400275710ustar00rootroot00000000000000from typing import Optional import collections import logging try: from gi.repository import GLib # noqa: F401 GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import PIL import PIL.Image import PIL.ImageDraw import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.widget_tree = None self.core = None self.stacks = None self.components = collections.defaultdict(dict) self.navigation_stacks = {'left': [], 'right': []} self.defaults = collections.defaultdict(list) # keep track of the prio self.mainwindow = None self._mainwindow_size = None def get_interfaces(self): return [ 'app_actions', 'app_shortcuts', 'chkdeps', 'gtk_mainwindow', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'] }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_init', 'defaults': ['openpaperwork_gtk.gtk_init'], }, { 'interface': 'icon', 'defaults': ['paperwork_gtk.icon'], }, { 'interface': 'l10n_init', 'defaults': ['paperwork_gtk.l10n'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def init(self, core): super().init(core) self.core = core if not GTK_AVAILABLE: LOGGER.warning("not initializing main window without Gtk") return None self.core.call_success( "gtk_load_css", "paperwork_gtk.mainwindow", "global.css" ) self.core.call_success( "gtk_load_css", "paperwork_gtk.mainwindow.window", "mainwindow.css" ) self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.mainwindow.window", "mainwindow.glade" ) if self.widget_tree is None: # init must still work so 'chkdeps' is still available LOGGER.error("Failed to load widget tree") return opt = self.core.call_success( "config_build_simple", "GUI", "main_window_size", lambda: (1024, 600) ) self.core.call_all("config_register", "main_window_size", opt) main_win_size = self.core.call_success( "config_get", "main_window_size" ) self.mainwindow = self.widget_tree.get_object("mainwindow") self.mainwindow.set_default_size(main_win_size[0], main_win_size[1]) self.mainwindow.connect("destroy", self._on_mainwindow_destroy) self.mainwindow.connect( "size-allocate", self._on_mainwindow_size_allocate ) try: self.mainwindow.set_icon_list([ self.core.call_success("icon_get_pixbuf", "paperwork", 16), self.core.call_success("icon_get_pixbuf", "paperwork", 32), self.core.call_success("icon_get_pixbuf", "paperwork", 48), self.core.call_success("icon_get_pixbuf", "paperwork", 64), self.core.call_success("icon_get_pixbuf", "paperwork", 128), ]) except KeyError as exc: # Will fail when generating data for the first time. LOGGER.warning("Failed to load main window icon", exc_info=exc) self.stacks = { "left": { "header": self.widget_tree.get_object( "mainwindow_stack_header_left" ), "body": self.widget_tree.get_object( "mainwindow_stack_body_left" ), }, "right": { "header": self.widget_tree.get_object( "mainwindow_stack_header_right" ), "body": self.widget_tree.get_object( "mainwindow_stack_body_right" ), }, } self.widget_tree.get_object("mainwindow_box_titlebar").connect( "notify::folded", self._on_titlebar_fold_change ) self._on_titlebar_fold_change() def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_initialized(self): app = self.core.call_success("gtk_get_app") # when remote, this segfaults... if not app.get_is_remote(): self.mainwindow.set_application(app) for side in self.defaults.keys(): self.mainwindow_show_default(side) self.mainwindow.set_visible(True) self.core.call_all("on_gtk_window_opened", self.mainwindow) def on_quit(self): # needed to save window size # TODO(JFlesch): not really config --> should not be stored in config ? if self.mainwindow is not None: self.core.call_all("config_save") self.mainwindow.set_visible(False) def _on_titlebar_fold_change(self, *args, **kwargs): LOGGER.info("Main window fold has changed") self.core.call_all("on_mainwindow_fold_change") def mainwindow_get_folded(self): return self.widget_tree.get_object( "mainwindow_box_titlebar" ).get_folded() def _on_mainwindow_destroy(self, main_window): LOGGER.info("Main window destroy. Quitting") self.core.call_all("on_gtk_window_closed", self.mainwindow) self.core.call_all("mainloop_quit_graceful") def _on_mainwindow_size_allocate(self, main_win, rectangle): (w, h) = main_win.get_size() if self._mainwindow_size == (w, h): return self._mainwindow_size = (w, h) self.core.call_all("config_put", "main_window_size", (w, h)) def mainwindow_get_main_container(self): return self.widget_tree.get_object("main_box") def mainwindow_add(self, side: str, name: str, prio: int, header, body): self.components[side][name] = { "header": header, "body": body, } components = self.components[side][name] stacks = self.stacks[side] for (position, widget) in components.items(): if widget is None: continue stacks[position].add_named(widget, name) self.defaults[side].append((prio, name)) self.defaults[side].sort(reverse=True) return True def mainwindow_show(self, side: str, name: Optional[str] = None): self.widget_tree.get_object( "mainwindow_box_titlebar" ).set_visible_child( self.stacks[side]['header'] ) self.widget_tree.get_object( "mainwindow_box_body" ).set_visible_child( self.stacks[side]['body'] ) if name is None: return False if name in self.navigation_stacks[side]: self.navigation_stacks[side].remove(name) self.navigation_stacks[side].append(name) return self._mainwindow_show(side) def _mainwindow_show(self, side: str): stacks = self.stacks[side] LOGGER.info("Navigation: %s", self.navigation_stacks[side]) # some plugin give us None as component, which means to use # the previous component in the navigation stack (see doclist # in multiple selection mode) component_names = {h: None for h in stacks.keys()} for name in reversed(self.navigation_stacks[side]): LOGGER.info("Showing %s on %s", name, side) for (k, v) in self.components[side][name].items(): if component_names[k] is None and v is not None: component_names[k] = name if None not in component_names.values(): break has_changed = False for (h, stack) in stacks.items(): if h not in component_names or component_names[h] is None: continue if stack.get_visible_child_name() == component_names[h]: continue has_changed = True stack.set_visible_child_name(component_names[h]) return has_changed def mainwindow_show_default(self, side: str): # the default component may be incomplete (for instance, it may # provide a header, but not a body). So we update the navigation # stack to make it the behaviour consistent: # We ensure it contains at least one element with all components # We respect priorities for (prio, name) in self.defaults[side]: self.navigation_stacks[side].append(name) if None not in self.components[side][name].values(): break first = self.navigation_stacks[side].pop(0) self.navigation_stacks[side].reverse() self.core.call_all("mainwindow_show", side, first) def mainwindow_back(self, side: str): navigation_stack = self.navigation_stacks[side][:-1] self.navigation_stacks[side] = navigation_stack self._mainwindow_show(side) def app_actions_add(self, action): if self.mainwindow is not None: self.mainwindow.add_action(action) def mainwindow_focus(self): self.mainwindow.grab_focus() def mainwindow_present(self): if self.mainwindow is not None: self.mainwindow.present() else: LOGGER.warn("Activated a second time but mainwindow is None") def _draw_overlay(self, img, area, color): overlay = PIL.Image.new('RGBA', img.size, color + (0,)) draw = PIL.ImageDraw.Draw(overlay) draw.rectangle(area, fill=color + (0x5F,)) return PIL.Image.alpha_composite(img, overlay) def screenshot_snap_all_doc_widgets(self, out_dir): out = self.core.call_success("fs_join", out_dir, "main_window.png") self.core.call_success( "screenshot_snap_widget", self.mainwindow, out ) left = self.stacks['left']['body'] left_alloc = left.get_allocation() left_width = left_alloc.width (left_x, left_y) = left.translate_coordinates(self.mainwindow, 0, 0) left = left_x + left_width with self.core.call_success("fs_open", out, 'rb') as fd: img = PIL.Image.open(fd) img.load() img = img.convert("RGBA") img = self._draw_overlay( img, (0, 0, left, img.size[1]), (0, 0xFF, 0) ) img = self._draw_overlay( img, (left, 0, img.size[0], img.size[1]), (0, 0, 0xFF) ) # drop some black border in the scn img = img.crop( (left_x, left_x, img.size[0] - left_x, img.size[1] - left_x) ) # keep only the top 150px img = img.crop((0, 0, img.size[0], min(300, img.size[1]))) out = self.core.call_success( "fs_join", out_dir, "main_window_split.png" ) with self.core.call_success("fs_open", out, 'wb') as fd: img.save(fd, format="PNG") def app_shortcut_add( self, shortcut_group, shortcut_desc, shortcut_keys, action_name): """ Arguments: - shortcut_group: Group name in which this shortcut belongs (human readable, translated ; actually used in the shortcut window if enabled) - shortcut_desc: Describe the shortcut (human readable, translated ; actually used in the shortcut window if enabled) - shortcut_keys: see gtk_accelerator_parse() - action_name: GAction that must be triggered """ if self.mainwindow is None or not GTK_AVAILABLE: return LOGGER.info("Keyboard shortcut: %s --> %s", shortcut_keys, action_name) Gtk.Application.get_default().set_accels_for_action( action_name, (shortcut_keys, None) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/window/mainwindow.css000066400000000000000000000006251456262201400303500ustar00rootroot00000000000000#mainwindow_stack_header_left headerbar { border-right-width: 1px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; } #mainwindow_stack_header_right headerbar { border-left-width: 0px; border-top-left-radius: 0px; border-bottom-left-radius: 0px; } #mainwindow_stack_body_left { border-right: 1px solid @borders; } #mainwindow_stack_bodyr_right { border-left-width: 0px; } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/mainwindow/window/mainwindow.glade000066400000000000000000000074251456262201400306410ustar00rootroot00000000000000 mainwindow False Paperwork False True vertical True False True mainwindow_stack_header_left 300 slide-right 333 True mainwindow_stack_header_right slide-left 333 True False True horizontal mainwindow_stack_body_left True slide-right 333 mainwindow_stack_body_right True slide-left 333 horizontal vertical paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/000077500000000000000000000000001456262201400231235ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/__init__.py000066400000000000000000000000001456262201400252220ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/000077500000000000000000000000001456262201400237035ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/__init__.py000066400000000000000000000000001456262201400260020ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/help.py000066400000000000000000000032121456262201400252030ustar00rootroot00000000000000import logging try: from gi.repository import Gio GIO_AVAILABLE = True except (ImportError, ValueError): GIO_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -1000 def __init__(self): super().__init__() self.menu = None def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_app', 'menu_app_help', ] def get_deps(self): return [ { 'interface': 'action_app_help', 'defaults': ['paperwork_gtk.actions.app.help'], }, { 'interface': 'help_documents', 'defaults': ['paperwork_gtk.model.help'], }, { 'interface': 'gtk_app_menu', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GIO_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def init(self, core): super().init(core) if not GIO_AVAILABLE: return self.menu = Gio.Menu() def on_doclist_initialized(self): for (title, file_name) in self.core.call_success("help_get_files"): item = Gio.MenuItem.new(title, "win.open_help." + file_name) self.menu.append_item(item) self.core.call_all("menu_app_append_submenu", _("Help"), self.menu) def help_add_menu_item(self, menu_item): self.menu.append_item(menu_item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/open_about.py000066400000000000000000000021011456262201400264020ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -10000 def get_interfaces(self): return [ 'menu', 'menu_app', 'menu_app_about', ] def get_deps(self): return [ { 'interface': 'action_app_open_about', 'defaults': ['paperwork_gtk.actions.app.open_about'], }, { 'interface': 'gtk_app_menu', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("About"), "win.open_about") self.core.call_all("menu_app_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/open_bug_report.py000066400000000000000000000023501456262201400274460ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -300 def get_interfaces(self): return [ 'menu', 'menu_app', 'menu_app_open_bug_report', ] def get_deps(self): return [ { 'interface': 'action_app_open_bug_report', 'defaults': ['paperwork_gtk.actions.app.open_bug_report'], }, { 'interface': 'gtk_app_menu', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Report bug"), "win.open_bug_report") self.core.call_all("menu_app_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/open_settings.py000066400000000000000000000020711456262201400271360ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'menu', 'menu_app', 'menu_app_settings', ] def get_deps(self): return [ { 'interface': 'action_app_open_settings', 'defaults': ['paperwork_gtk.actions.app.open_settings'], }, { 'interface': 'gtk_app_menu', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Settings"), "win.open_settings") self.core.call_all("menu_app_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/app/open_shortcuts.py000066400000000000000000000021221456262201400273310ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -1500 def get_interfaces(self): return [ 'menu', 'menu_app', 'menu_app_shortcuts', ] def get_deps(self): return [ { 'interface': 'action_app_open_shortcuts', 'defaults': ['paperwork_gtk.actions.app.open_shortcuts'], }, { 'interface': 'gtk_app_menu', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Shortcuts"), "win.open_shortcuts") self.core.call_all("help_add_menu_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/000077500000000000000000000000001456262201400236705ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/__init__.py000066400000000000000000000000001456262201400257670ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/add_to_selection.py000066400000000000000000000020011456262201400275320ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_add_to_selection" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_add_to_selection', ] def get_deps(self): return [ { 'interface': 'action_doc_add_to_selection', 'defaults': ['paperwork_gtk.actions.doc.add_to_selection'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def on_doclist_initialized(self): self.core.call_all( "add_doc_action", _("Add to selection"), "win." + ACTION_NAME ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/delete.py000066400000000000000000000016701456262201400255100ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_delete" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_delete', ] def get_deps(self): return [ { 'interface': 'action_doc_delete', 'defaults': ['paperwork_gtk.actions.doc.delete'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def on_doclist_initialized(self): self.core.call_all( "add_doc_action", _("Delete document"), "win." + ACTION_NAME ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/export.py000066400000000000000000000016441456262201400255700ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_export" class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_export', ] def get_deps(self): return [ { 'interface': 'actions_doc_export', 'defaults': ['paperwork_gtk.actions.doc.export'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def on_doclist_initialized(self): self.core.call_all( "add_doc_action", _("Export document"), "win." + ACTION_NAME ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/open_external.py000066400000000000000000000014601456262201400271060ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_open_external" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -50 def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_open_external', ] def get_deps(self): return [ { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def on_doclist_initialized(self): self.core.call_all( "add_doc_action", _("Open folder"), "win." + ACTION_NAME ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/print.py000066400000000000000000000016271456262201400254040ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_print" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -10 def __init__(self): super().__init__() self.active_doc = None self.active_windows = [] def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_print', ] def get_deps(self): return [ { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def on_doclist_initialized(self): self.core.call_all( "add_doc_action", _("Print document"), "win." + ACTION_NAME ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/properties.py000066400000000000000000000025531456262201400264430ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_properties" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 100 def __init__(self): super().__init__() self.active_doc = None def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_properties', ] def get_deps(self): return [ { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def init(self, core): super().init(core) self.core.call_all( "add_doc_main_action", "document-properties-symbolic", _("Document properties"), self._open_properties ) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def doc_close(self): self.active_doc = None def _open_properties(self, *args, **kwargs): assert self.active_doc is not None active = self.active_doc LOGGER.info("Opening properties of document %s", active[0]) self.core.call_all("open_doc_properties", *active) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/doc/redo_ocr.py000066400000000000000000000017041456262201400260400ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_redo_ocr" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -90 def get_interfaces(self): return [ 'menu', 'menu_doc', 'menu_doc_redo_ocr', ] def get_deps(self): return [ { 'interface': 'action_doc_redo_ocr', 'defaults': ['paperwork_gtk.actions.doc.redo_ocr'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def on_doclist_initialized(self): self.core.call_all( "add_doc_action", _("Redo OCR on document"), "win." + ACTION_NAME ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/000077500000000000000000000000001456262201400240535ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/__init__.py000066400000000000000000000000001456262201400261520ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/delete.py000066400000000000000000000024061456262201400256710ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_delete_many" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_docs', 'menu_docs_delete', ] def get_deps(self): return [ { 'interface': 'action_docs_delete', 'defaults': ['paperwork_gtk.actions.docs.delete'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Delete"), "win." + ACTION_NAME) self.core.call_all("docs_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/export.py000066400000000000000000000024051456262201400257470ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_export_many" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -50 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_docs', 'menu_docs_export', ] def get_deps(self): return [ { 'interface': 'action_docs_export', 'defaults': ['paperwork_gtk.actions.docs.export'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Export"), "win." + ACTION_NAME) self.core.call_all("docs_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/properties.py000066400000000000000000000026651456262201400266320ustar00rootroot00000000000000import itertools import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_change_labels" class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.menu_add = None self.menu_remove = None self.idx_generator = itertools.count() def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_docs', 'menu_docs_properties', ] def get_deps(self): return [ { 'interface': 'action_docs_properties', 'defaults': ['paperwork_gtk.actions.docs.properties'], }, { 'interface': 'docs_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Change labels"), "win." + ACTION_NAME) self.core.call_all("docs_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/redo_ocr.py000066400000000000000000000024171456262201400262250ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_redo_ocr_many" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -50 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_docs', 'menu_docs_redo_ocr', ] def get_deps(self): return [ { 'interface': 'action_docs_redo_ocr', 'defaults': ['paperwork_gtk.actions.docs.redo_ocr'], }, { 'interface': 'doc_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Redo OCR"), "win." + ACTION_NAME) self.core.call_all("docs_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/docs/select_all.py000066400000000000000000000024211456262201400265330ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "doc_select_all" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_docs', 'menu_docs_select_all', ] def get_deps(self): return [ { 'interface': 'action_docs_select_all', 'defaults': ['paperwork_gtk.menus.docs.select_all'], }, { 'interface': 'docs_actions', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_doclist', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_doclist_initialized(self): item = Gio.MenuItem.new(_("Select all"), "win." + ACTION_NAME) self.core.call_all("docs_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/000077500000000000000000000000001456262201400240375ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/__init__.py000066400000000000000000000000001456262201400261360ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/copy_text.py000066400000000000000000000023261456262201400264320ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_copy_text" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_copy_text', ] def get_deps(self): return [ { 'interface': 'action_page_copy_text', 'defaults': ['paperwork_gtk.actions.page.copy_text'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new( _("Copy selected text"), "win." + ACTION_NAME ) self.core.call_all("page_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/delete.py000066400000000000000000000022451456262201400256560ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_delete" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_delete', ] def get_deps(self): return [ { 'interface': 'action_page_delete', 'defaults': ['paperwork_gtk.page.delete'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new(_("Delete page"), "win." + ACTION_NAME) self.core.call_all("page_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/export.py000066400000000000000000000022521456262201400257330ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_export" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 0 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_export', ] def get_deps(self): return [ { 'interface': 'action_page_export', 'defaults': ['paperwork_gtk.actions.page.export'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new(_("Export page"), "win." + ACTION_NAME) self.core.call_all("page_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/move_inside_doc.py000066400000000000000000000024421456262201400275410ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_move_inside_doc" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 910 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_move_inside_text', ] def get_deps(self): return [ { 'interface': 'action_page_move_inside_doc', 'defaults': ['paperwork_gtk.actions.page.move_inside_doc'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new( _("Another position"), "win." + ACTION_NAME ) self.core.call_all( "page_menu_append_item", item, submenu_name=_("Move page to") ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/move_to_doc.py000066400000000000000000000024221456262201400267060ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_move_to_doc" class Plugin(openpaperwork_core.PluginBase): PRIORITY = 900 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_move_to_text', ] def get_deps(self): return [ { 'interface': 'action_page_move_to_doc', 'defaults': ['paperwork_gtk.actions.page.move_to_doc'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new( _("Another document"), "win." + ACTION_NAME ) self.core.call_all( "page_menu_append_item", item, submenu_name=_("Move page to") ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/print.py000066400000000000000000000022471456262201400255520ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_print" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -10 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_print', ] def get_deps(self): return [ { 'interface': 'action_page_print', 'defaults': ['paperwork_gtk.actions.page.print'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new(_("Print page"), "win." + ACTION_NAME) self.core.call_all("page_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/redo_ocr.py000066400000000000000000000023171456262201400262100ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_redo_ocr" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -70 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_redo_ocr', ] def get_deps(self): return [ { 'interface': 'action_page_redo_ocr', 'defaults': ['paperwork_gtk.actions.page.redo_ocr'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new( _("Redo OCR on page"), "win." + ACTION_NAME ) self.core.call_all("page_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/menus/page/reset.py000066400000000000000000000022471456262201400255400ustar00rootroot00000000000000import logging try: from gi.repository import Gio GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) ACTION_NAME = "page_reset" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -80 def get_interfaces(self): return [ 'chkdeps', 'menu', 'menu_page', 'menu_page_reset', ] def get_deps(self): return [ { 'interface': 'action_page_reset', 'defaults': ['paperwork_gtk.actions.page.reset'], }, { 'interface': 'page_actions', 'defaults': [ 'paperwork_gtk.mainwindow.docview.pageinfo.actions' ], }, ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) def on_page_menu_ready(self): item = Gio.MenuItem.new(_("Reset page"), "win." + ACTION_NAME) self.core.call_all("page_menu_append_item", item) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/000077500000000000000000000000001456262201400230745ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/__init__.py000066400000000000000000000000001456262201400251730ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/000077500000000000000000000000001456262201400240245ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/Makefile000066400000000000000000000021161456262201400254640ustar00rootroot00000000000000all: data out/paperwork_going_up.png: data/paperwork_going_up.svg convert $< $@ out/main_window.png: # screnshots [ -f $(CURDIR)/${OUT_INTRO_PDF} ] || LANG=C WAYLAND_DISPLAY= xvfb-run sh ./screenshot.sh l10n_extract: # will generate out/translated_*_$lang.tex files cd $(CURDIR) && po4a -M UTF-8 -k 0 po4a.conf l10n_compile: l10n_extract out/%.tex: rm -f out/*.tex cp data/intro.tex out/intro.tex cp data/usage.tex out/usage.tex $(MAKE) l10n_compile out/%.pdf: out/%.tex out/main_window.png out/paperwork_going_up.png # run pdflatex twice because of the TOC pdflatex --output-directory=out ../$< pdflatex --output-directory=out ../$< clean: rm -f $(CURDIR)/out/*.png rm -f $(CURDIR)/out/*.pdf rm -f $(CURDIR)/out/*.toc rm -f $(CURDIR)/data/*.aux rm -f $(CURDIR)/data/*.log data: rm -f $(CURDIR)/out/*.pdf rm -f $(CURDIR)/out/*.toc $(MAKE) out/intro.pdf $(MAKE) out/translated_intro_de.pdf $(MAKE) out/translated_intro_fr.pdf $(MAKE) out/usage.pdf $(MAKE) out/translated_usage_de.pdf $(MAKE) out/translated_usage_fr.pdf .PHONY: all clean data l10n_extract l10n_compile paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/__init__.py000066400000000000000000000216571456262201400261500ustar00rootroot00000000000000import datetime import locale import logging import openpaperwork_core import openpaperwork_core.promise import paperwork_backend.model.pdf from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def __init__(self): super().__init__() self.doc_urls_to_names_to_urls = {} self.doc_urls_to_names = {} # in case document is edited by user self.new_docs = [] self.doc_urls_to_new_docs = {} self.thumbnails = {} # At this point, translations are not yet available self.help_files = () self.label = () def get_interfaces(self): return [ 'doc_labels', 'document_storage', 'help_documents', 'thumbnail', ] def get_deps(self): return [ # Dependency not declared to avoid dependency loop # { # 'interface': 'new_doc', # 'defaults': ['paperwork_gtk.new_doc'], # }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'page_img', 'defaults': ['paperwork_backend.model.pdf'], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, { 'interface': 'thumbnailer', 'defaults': ['paperwork_backend.model.thumbnail'], }, ] def init(self, core): super().init(core) self.help_files = ( (_("Introduction"), "intro"), (_("User manual"), "usage"), ) self.label = (_("Documentation"), "#ffffffffffff") def help_get_files(self): return self.help_files def help_get_file(self, name): lang = "en" try: lang = locale.getdefaultlocale()[0] if lang is None: lang = "en" LOGGER.warning("Failed to get default locale !") else: lang = lang[:2] LOGGER.info("User language: %s", lang) except Exception as exc: LOGGER.error( "get_documentation(): Failed to figure out locale." " Will default to English", exc_info=exc ) if lang == "en": docs = [name + '.pdf'] else: docs = ['translated_{}_{}.pdf'.format(name, lang), name + ".pdf"] for doc in docs: url = self.core.call_success( "resources_get_file", "paperwork_gtk.model.help.out", doc ) if url is None: LOGGER.warning("No documentation '%s' found", doc) else: LOGGER.info("Documentation '%s': %s", doc, url) self.doc_urls_to_names_to_urls[name] = url self.doc_urls_to_names[url] = name return url LOGGER.error("Failed to find documentation '%s'", name) return None def doc_id_to_url(self, doc_id, existing=True): if not doc_id.startswith("help_"): return None name = doc_id[len("help_"):] return self.help_get_file(name) def doc_get_date_by_id(self, doc_id): if not doc_id.startswith("help_"): return None return datetime.datetime.now() def thumbnail_get_doc_promise(self, doc_url): if doc_url not in self.doc_urls_to_names: return None return openpaperwork_core.promise.ThreadedPromise( self.core, self.thumbnail_get_doc, args=(doc_url,) ) def thumbnail_get_doc(self, doc_url): return self.thumbnail_get_page(doc_url, page_idx=0) def thumbnail_get_page(self, doc_url, page_idx): if doc_url not in self.doc_urls_to_names: return None if page_idx != 0: return None if doc_url in self.thumbnails: url = self.thumbnais[doc_url] return self.core.call_success("url_to_pillow", url) page_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) assert page_url is not None img = self.core.call_success("url_to_pillow", page_url) img = self.core.call_success("thumbnail_from_img", img) (self.thumbnail_url, fd) = self.core.call_success( "fs_mktemp", prefix="thumbnail_help_intro", suffix=".jpeg", mode="wb" ) fd.close() self.core.call_success( "pillow_to_url", img, self.thumbnail_url, format='JPEG', quality=0.85 ) return img def _get_doc_url(self, doc_url, write=False): # HACK(Jflesch): # This document is read-only, but Paperwork doesn't really # support read-only documents. # --> discretely copy the document and switch to the new document. new_doc_url = self.doc_urls_to_new_docs.get(doc_url, None) if new_doc_url is not None: return new_doc_url if not write: return doc_url (new_doc_id, new_doc_url) = self.core.call_success("get_new_doc") assert new_doc_url not in self.doc_urls_to_names self.doc_urls_to_new_docs[doc_url] = new_doc_url self.new_docs.append(new_doc_id) self.core.call_success("fs_mkdir_p", new_doc_url) self.core.call_success( "fs_copy", doc_url, # reminder: doc_url points directly to a PDF here self.core.call_success( "fs_join", new_doc_url, paperwork_backend.model.pdf.PDF_FILENAME ) ) self.core.call_success( "doc_add_label_by_url", new_doc_url, *self.label ) self.core.call_success( "mainloop_schedule", self.core.call_all, "doc_open", new_doc_id, new_doc_url ) return new_doc_url def page_get_img_url(self, doc_url, page_idx, write=False, **kwargs): if doc_url not in self.doc_urls_to_names: return None doc_url = self._get_doc_url(doc_url, write) if doc_url in self.doc_urls_to_names: return None return self.core.call_success( "page_get_img_url", doc_url, page_idx, write=write, **kwargs ) def page_set_boxes_by_url(self, doc_url, page_idx, *args, **kwargs): if doc_url not in self.doc_urls_to_names: return None doc_url = self._get_doc_url(doc_url, write=True) return self.core.call_success( "page_set_boxes_by_url", doc_url, page_idx, *args, **kwargs ) def transaction_simple_promise(self, changes: list): for new_doc_id in self.new_docs: changes.append(('add', new_doc_id)) self.new_docs = [] def doc_get_mtime_by_url(self, doc_url): if doc_url not in self.doc_urls_to_names: return return datetime.datetime(year=1971, month=1, day=1).timestamp() def doc_has_labels_by_url(self, doc_url): if doc_url not in self.doc_urls_to_names: return None return True def doc_get_labels_by_url(self, out: set, doc_url): if doc_url not in self.doc_urls_to_names: return out.add(self.label) def doc_get_labels_by_url_promise(self, out: list, doc_url): if doc_url not in self.doc_urls_to_names: return def get_labels(labels=None): if labels is None: labels = set() labels.add(self.label) return labels promise = openpaperwork_core.promise.Promise( self.core, get_labels ) out.append(promise) def doc_remove_label_by_url(self, doc_url, *args, **kwargs): if doc_url not in self.doc_urls_to_names: return None doc_url = self._get_doc_url(doc_url, write=True) return self.core.call_success( "doc_remove_label_by_url", doc_url, *args, **kwargs ) def doc_add_label_by_url(self, doc_url, *args, **kwargs): if doc_url not in self.doc_urls_to_names: return None doc_url = self._get_doc_url(doc_url, write=True) return self.core.call_success( "doc_add_label_by_url", doc_url, *args, **kwargs ) def doc_set_extra_text_by_url(self, doc_url, *args, **kwargs): if doc_url not in self.doc_urls_to_names: return None doc_url = self._get_doc_url(doc_url, write=True) return self.core.call_success( "doc_set_extra_text_by_url", doc_url, *args, **kwargs ) def help_labels_get_all(self, out: set): out.add(self.label) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/000077500000000000000000000000001456262201400247355ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.png000066400000000000000000006671331456262201400266160ustar00rootroot00000000000000‰PNG  IHDRH”ÖÙÒxsBIT|dˆ pHYs‡‡åñetEXtSoftwarewww.inkscape.org›î< IDATxœìÝy\–u¢ÿÿ»€ Êâ.¸ã‚û‚û†ûV3f'§Å³Æ²úžLË,Çœ35:Ùè©s&5rÉD3qÜQQ„d_ïû÷?îÉㆠ\¤ïç_ ÷u}®÷å >|óY¬Ìf³‘ TXXHDD{÷îåÔ©Sœ9s†k×®qãÆ 233qppÀÉÉ WWW4h@Æ iÑ¢;w¦}ûö8::ý """"""""òˆ²RA*¡¸¸˜mÛ¶±|ùr¶nÝJVVÖcggG÷îÝ;v,£GÆËË«œ“ŠˆˆˆˆˆˆˆÈãL©”«üü|¾þúkæÏŸÏåË—-_wuu%((ˆ€€üýýñöö¦V­Z–Ù¡éé餥¥qñâE.^¼ÈÑ£G9pàiii–1¬­­éܹ3“&Mâé§Ÿ¦F•þ~""""""""R~vìØÁ_ÿúW† ÂÔ©S É ‚TÊ͆ xíµ×¸téPRŠ>ùä“Lš4‰Î;cccs_ã™ÍfNŸ>ÍúõëY³f Gµ|V£F &MšÄË/¿L«V­Êõ=DDDDDDDD¤bíÞ½›÷ߟŸþ€Þ½{³k×.C²¨ •‡–ššÊ /¼Àš5kpwwgæÌ™¼ôÒK899•Ûs.^¼ÈêÕ«Y¶l.\°|=88˜?üvíÚ•Û³DDDDDDDD¤üíß¿Ÿ÷ߟíÛ·[¾feeEXX}ûö5$“ Ry(GŽaܸqÄÅÅacc믾Êܹs+tù»ÉdbÛ¶m,Y²„-[¶`2™°²²bôèÑÌ;—-ZTسEDDDDDDDäþ9r„Ù³g³yóæ[>›2e _}õ•©J¨ •¶yóf&L˜@NN¾¾¾|÷ÝwtîܹR3œ8q‚9sæ°víZÌf3vvv̘1ƒY³f•ëìU¹ÇŽcöìÙüðØÍf¬­­7n999lÚ´ OOON:…«««aUÊY¹r%Ï<ó ………ôíÛ—Õ«WS»vmÃòDEEñÎ;ï @£FX²d 4,“ˆˆˆˆˆˆˆÈãêÔ©S|ðÁ|ÿý÷–Õ¿#GŽäƒ>ÀÉɉ–-[RPPÀÊ•+yòÉ' ͪ‚TîÛæÍ›5jEEEŒ5Š•+WR­Z5£c°qãF^~ùe°²²bÚ´i,\¸;;;££‰ˆˆˆˆˆˆˆ<òâââøä“Oøê«¯(.. ÿþ|òÉ'tìØ€‘#G²aúuëÆÞ½{±²²22² R¹?¤OŸ>äää0a¾ýöÛû>¾¢Ý¸qƒ3fXö®èÞ½;«V­ÂÛÛÛàd""""""""¦Ë—/3oÞ<¾þúkŠŠŠ€’NfÞ¼yôîÝÛrÝÎ;éׯÖÖÖ8pÀRšI©”Yrr2:t !!~ýú±eËìííŽuGÿþ÷¿™:u*YYYÔ­[—­[·Ò¶m[£c‰ˆˆˆˆˆˆˆ<2âããY¸p!ÿûßÉÏÏJŠÑ?üð¶§ÒwêÔ‰C‡~0Ó¯© •21™L 8;vиqc:dèæ¹eèQ£8sæ µjÕbýúõKDDDDDDDä7-11‘O>ù„¥K—ZŠÑnݺñá‡Ò¯_¿ÛÞÊàÁƒ±··çüùóøøøTfä;²6:€ü6,^¼˜;vàèèÈš5k~å(€ŸŸ{÷î¥K—.ܸqƒÁƒ³uëV£c‰ˆˆˆˆˆˆˆü&%''3cÆ 7nÌ¢E‹ÈÏÏ'00-[¶~Çr`Ñ¢ELž<¹Ê”£ ¤R±±±´mÛ–ììlþçþ‡7ÞxÃèH÷-;;›ñãdzuëVœœœ £k×®FÇùM¸~ý: .dÑ¢Edggжm[>üðC†~σ–®\¹Býúõ)..æèÑ£´k×®2b—‰fÊ=ýñ$;;›îÝ»3}út£ã<gggÖ­[Gß¾}ÉÉÉ!88˜“'OKDDDDDDD¤ÊÛ¾};5bþüùdggÓ²eKBBBˆŒŒdĈe:…~ݺuP¥ÊQPA*÷°cÇ6lØ€ _|ñÖÖ¿ÝoÖ¯_OÇŽIMMeذa¤¦¦KDDDDDDD¤J{ÿý÷ÉÈÈ Y³füûßÿæØ±cŒ7®LÅh©Ò-GŽYQ1Øo·í’ g6›™9s&Ï?ÿ}:={ö$77—©S§j©½ˆˆˆˆˆˆˆÈ¯|ýõטÍfú÷ïOëÖ­ïzmQQñññ{×k3339}ú4ׯ_§gÏž9r„ââbËç¥ÅhFFF•œ ¦‚Tn‘ššÊ÷ßÀ´iÓ NS±š7on™"þþûïSTTdp"ãmÙ²…¤¤$\\\5jÔ¯;}ú4ûöí£V­Z¸¸¸pôèQZµj…åšÒÉwyyyüòË/žý~© •[¬^½š‚‚š7oN·nÝŒŽSáÞzë-ÜÜÜ8þ<Ë—/7:ŽˆˆˆˆˆˆˆˆáBBB˜0aŽŽŽ·|n6›9xð ´jÕŠŒŒ Ο?OÏž=oYìêꊷ·7þ>© •[”NŸž4i’ÁI*G­Zµ,û¬Î;W³HEDDDDDDä±f2™ `äÈ‘·|~íÚ5öîÝ‹££#>>>ìÛ·jժѿìíío;fß¾},ãV%V檸ð_ “’’‚§§'&“‰ .аaC£#UŠììl|||HKKcݺuw:."""""""ò(;pà]ºtÁÑÑ‘ëׯß4ƒ422;;;lmmÉÊÊ"))‰®]»òÄOÜuÌuëÖ1fÌjÕªEBBÕ«W¯è×(3Í •›üøã˜L&üýý›rJ6 ~æ™gX²d‰ÁiDDDDDDDDŒ³sçN‚‚‚,åhNNШQ#.]ºD^^ƒ¾g9 0|øp|}}¹qãÿû¿ÿ[¡ùï— R¹É?þÀ Aƒ NRù^|ñE¬¬¬Ø¾};±±±FÇ1DTT:u²|-??777\\\8|ø0ôèÑ[[Û2ikkË믿À‡~Hrrrù@*HÅÂl6[ ÒÁƒœ¦òùûûÓ½{wÌf3ßÿ½ÑqDDDDDDDD  @Û¶m-_suuåêÕ«$&&ÒµkWÜÜÜî{ÜW_}•æÍ›“––Æo¼Qny– R±ˆŠŠ"))‰jժѫW/£ãbìØ±¬]»Öà$""""""""•¯¸¸˜óçÏвeË›>kÕªAAAØÙÙ•y¼üü|²³³°³³ãoûÖÖÖ|ûí·Uf›C¤b@¯^½prr281ÆŒƒ••‡"!!Áè8""""""""•*==ââbÜÝÝoú¬N:÷5Vll,Û·o'++Ëòµ>}úðÞ{ïðÆo°gÏž‡LüðTŠÅÑ£GèÖ­›ÁIŒãëëKÛ¶m1›Í– ‰EDDDDDDD©©©@Éž¡µjÕz 1233 '++‹ÀÀ@jÖ¬yÓç³gÏfРAäççÌ¡C‡:÷ÃPA*¥ðœÄX¥Û ìÝ»×à$""""""""•Ëd2`mm••Õ}Ý›““Cdd$—.]ÂÇLJêÕ«eYb_ÊÚÚš:wîLFFƒæÈ‘#åö÷K©››Ë¹sç¤=zô¨S¼EDDDDDDD*Sé¬Ñ‚‚òòòÊ|_\\ÑÑÑ899Q¯^="##±³³£GÔ®]û–ëkÔ¨Ahh(:t 55•Þ½{³iÓ¦r{ûae6›Í†[é«yU ñññ4jÔÈà$Uƒ¿¿?€fŠˆˆˆˆˆˆÈcgøðá¬\¹’‚‚‚[>/((ÀÃÃÄÄD®\¹B÷îÝ騱#vvv÷õœ¬¬,FÍ—_~‰••³gÏféÒ¥åò÷C©%ûnÔ«WÏà$Uƒ‰‰‰'©\ÇÇÍÍëׯ³bÅŠ[>www'==¦M›Ò²eË2/§ÿµ«W¯Ò«W/6mÚ„½½=Ë—/gΜ9†lý¨‚T€’oJPAZÊÃÀäädƒ“ˆˆˆˆˆˆˆˆT.¦OŸÀ¬Y³ÈÌ̼åš^½záííý@ã;vŒ.]º‰««+Û¶mãé§Ÿ~¨ÌC©`2™¸ví ‚´TiAZúë""""""""ò8yóÍ7ñöö&11‘?üá˜Íær÷ǤgÏžÄÇÇÓ AÂÃÃéÓ§O¹Œý T ÉÉÉaeeEݺuŽS%¸ººpãÆ ƒ“ˆˆˆˆˆˆˆˆT>'''þùÏbccCHH³gÏ~è1¿úê+‚ƒƒÉÈÈ 00ýû÷[Ê6’ R±ì³éêêJµjÕ NS5ØÛÛÜv#b‘ÇA¿~ýøøã˜;w.ï¾ûîÍ$5›Íü÷ÿ7Ï=÷………Œ9’]»vYVðM©XfI–Κ”’½6òóó N"""""""²ŒŒ £#ˆÜÕÌ™3-³GçÏŸOpp0ׯ_/óýùùùüþ÷¿·­Ó§OgÍš5899UHÞ¡‚T,%`i)(`kk @aa¡ÁIDDDDDDäQõöÛoãââBçÎùÓŸþĹs猎$r[sæÌaÑ¢EØÙÙ±eËZ¶lÉ·ß~{ÏûRSS0`+W®ÄÆÆ†Ï?ÿœÏ>û ›JH]v*HEémäååhË©Pf³™ƒòÎ;ïЬY3Z·nÍìÙ³‰ŽŽ6:šÈM^}õUvíÚE£F¸ví¿ÿýïéÖ­?ýôÓm¯¥[·nìÙ³'''Ö¬YÃk¯½VÉ©ËF©¨ ½œœ€*5Ý[DDDDDD-3fÌ zõêÔ¬YkkkNœ8Á‡~H@@7æ­·Þ"""“ÉdpZèÖ­Ççí·ßÆÞÞžˆˆúöíKÇŽùꫯ,}ÊþýûéÚµ+111xxx°k×.FŽipú;SA**HoC©ˆˆˆˆˆˆT4wwwþøÇ?%ç‚\¾|™åË—Œ½½=.\`áÂ…tëÖ OOO&OžÌƵœÊÉɉùóçÃý×akkË‘#Gxî¹çðòòâÙgŸ¥oß¾¤¤¤Ð¢E öïßO`` Ñ±ïJ©X ÒÒ“ÛÒÒÒ¨U«–ÁIDDDDDDäQöÖ[oáîîÎ¥K— ±” III,_¾œñãÇãììLJJ +V¬`Ĉxxx0yòdBBBÈÎÎ6úä1Õ AþñÇìÙ³©W¯éééüóŸÿ$77—>}úNƒ ŒŽzO*H…¢¢"à? $%%àééipy”U¯^wÞy€O?ýÔ2;ÔÕÕ•É“'óÝwß‘””ÄêÕ«™8q"5jÔ --+V0aÂêÖ­Ë“O>Éwß}GVV–‘¯")///æÌ™C\\!!! :”iÓ¦±mÛ6\\\ŒŽW&*HGGGrss NRu$&&P¯^=ƒ“ˆˆˆˆˆˆÈ£nêÔ©¸¹¹qõêU6lØpËçÕ«Wg„ ¬ZµŠ””¶oßÎk¯½†‡‡™™™–ò´N: 0€Ï?ÿœk×®ð&ò8³³³cܸqlÞ¼™¿þõ¯¿©•Ê*HŲ!´~ÒôW¯^ÀÃÃÃà$""""""ò¨sttäé§ŸàË/¿¼ëµôïߟÏ?ÿœ+W®°gÏ^{í5¼¼¼ÈËË#,,Œ×_///zôèa¹NDîL©àìì  }K~åìÙ³4iÒÄà$""""""ò8˜:u*VVVìØ±ÃòoÒ{±±±±”  œ8q‚Ù³gãççGqq1ááá¼þúëøúúÒ±cGæÌ™CLLL¿‰Èo•Ùl6BŒN=ðññáòåËFÇ1œÙl¦fÍšdeeM›6mŒŽ$"""""">}ú°k×.f̘ÁÂ… j¬èèhÖ®]ËÚµk9qâÄMŸµk׎1cÆ0zôhZ¶lùPÏy¨ ¢££ ÀÕÕ•ÔÔT£ã.!!¬­­ÉÌÌÄÉÉÉèH""""""òø×¿þÅÓO?M£Fˆ-·qÏ;g)K:į« ???ÆŒØ1cèСVVVåö\‘ß ¤Bll,Mš4ÁÎÎŽ‚‚£ãnëÖ­ :´ÜÿB¹›ÔÔTÜÝÝ)..æÌ™3øùù•û3âããÙºu+7n$44”ÂÂBËg>>> 2„àà`† ‚­­m¹?_¤*Ò¤‚««+………ܸqÃà4Æ;tè:t08‰ˆˆˆˆˆˆ_ÄH*H___€ÇþûS§NqíÚ5ìíí5ƒTDDDDDD*]Û¶mqpp //³gÏÞöšøøxŠŠŠ ãĉ—kGGGFm)K·mÛÆ /¼€‡‡999¬]»–#FpéÒ¥r}®ˆQT P² héŽ;èÒ¥ ÎÎΧ‘Çþþþ?~ü¶×8;;“‘‘­­-™™™üõ¯%,,Œˆˆ€r]oooÏ AƒøûßÿΕ+Wؽ{7Íš5£¸¸˜M›6•ÛsDŒ¤‚T¤¥J Ò~ýúœDDDDDDDW­ZµàäÉ“·ýüÇ$66–f͚ѵkW†N:uÈËË#!!Ÿþ™£GÙl.·\666ôìÙ“§žz €7–ÛØ"FRA*À ÒÇy‰}~~>?ýôýû÷78ˆˆˆˆˆˆ<®J Ò;Í õôôÄÍÍ+W®Bzz:õêÕ£OŸ>8;;S\\Lbb"»víâÔ©Slذ‹/%ÿö}XÇ`×®]dee=ôx"F³5:€T Íš5îü‡ïã ,,ŒÌÌLÜÝÝéܹ³ÑqDDDDDDä1Õ¸qcàÎ1‘ŸŸOJJ ¤§§sùòezõêETT:u¢nݺ\»vk×®Q­Z5ÒÓÓ‰‰‰áÌ™34jÔËd©ûÕ¾}{êÕ«ÇÕ«WÙ¾};£G~àw© T P² ´µµ5ׯ_çÊ•+xyy©ÒýðÃ@ÉOÂlll N#""""""+WWWÒÒÒîxƒƒÞÞÞx{{c2™ÈÎÎ&55•ºuërôèQ prr¢eË–øùùaccCbb"ŽŽŽœ9s³ÙLRRVVVtìØ‘¬¬,ªW¯^¦|VVV 6ŒeË–±iÓ&¤ò›§‚T¨Q£5âüùóDGG?viqq±e#GœFDDDDDDg...ÀÝ Ò_³¶¶¦FÔ¨Q€ºuë’À¹s爊ŠÂd2ááᇇ 33“´´4’““©W¯{÷îÅd2‘ŸŸOïÞ½±µµÅÚúî»2³lÙ2¶lÙòp/+R¨ ‹¶mÛrþüy¢¢¢:t¨Ñq*ÕŽ;HJJ¢fÍšÚTDDDDDD U:ƒôƘL¦{–•ÿ—››nnn´iÓ†ŒŒ ®]»ÆÅ‹ §uëÖäääàççG`` éééxxx““ÃÙ³g9räõêÕ£M›6Ô®]›ââbìííozFPPÖÖÖ$%%qáÂ5jT>//R’““9}ú4………xzzâçç‡Ý¯WA*¬Y³†èèh££Tº+V0~üx N#""""""³Ò™ &“‰œœœ2/}¿š5kR³fMš6mJPP‰‰‰œ8q‚³gÏ’››Ë¹sçhÙ²%®®®4mÚ”ÄÄDZ´hA­ZµØ¸q#^^^ØØØ0pàÀ[ÆmÞ¼9'OžäÀ*HÅp¹¹¹,]º”¯¾úê–3vžxâ žzê)¦NJË–-o¹W§Ø‹E@@QQQ'©\ÙÙÙ¬_¿€§Ÿ~Úà4""""""ò¸+((°ü·ƒƒC¹kooOýúõ6l#FŒ ^½zøøøpþüy®]»Æ¡C‡ˆŽŽÆßߟ:uê0iÒ$üýýiÒ¤ÉmÇ+=àøÀå–Qä~™L&–,YB£Fxýõ×-娧§' 6ÄÁÁëׯ³xñbÚ´iÃäÉ“INN¾i ¤bQZž?ž7nœ¦ò¬^½š¬¬,êׯOÏž=Ž#""""""¹ÜÜ\lllîº,øayxxеkWFŽI›6mpvvæêÕ«üüóÏüðä§§Ó°aÃ;ÎUA*F;{ö,AAA¼üòË$%%Q·n].\È•+WHLLäÂ… ddd°f͈ÉdbÅŠaG©Xx{{S¿~}L&{÷î5:N¥ùâ‹/xî¹çî{_‘òVZVæp666øùù1yòdúõëGïÞ½ïùoä.]ºI~~~eÄ ))‰W^y…V­Z±gϪU«ÆÇLll,3fÌ ^½z–kííí3f ¡¡¡ìÚµ‹Æ“˜˜È!C,«¨ÕÉMz÷î ÀO?ýdp’ÊÁ‘#G°³³cÊ”)FÇ1¤ …’’ÔÖÖGGG6lˆ»»û]¯oÙ²%ÎÎÎäççsòäÉJJ)³ŒŒ fÍšE“&Møâ‹/(,,¤gÏž=z”wß}÷ž¿gz÷îÍ‘#Gèܹ37nÜ`òäɪ •›OAZ:{t̘17ýtADDDDDDÄ(W®\°œ._UÙØØXö'58<Êòóóùì³Ïhܸ1}ôÙÙÙ´jÕŠ 6°{÷nš7o^æ±jÕªÅúõëqqqáøñã„„„¨ •›•¤ÑÑÑüòË/Ɔ©`—/_fõêÕ¼úê«§)qñâE6lhp’{+ÍXšY¤<™L&¾ùæüüüxã7øå—_ðõõåŸÿü'QQQ >Ürmff&{÷î%//ïžãzzzò /%gÓ¨ •›4lØfÍšQ\\Lhh¨Ñq*ÔÂ… ),,¤K—.ôèÑÃè8"""""""Ào« -=ÀI©”·Í›7À3Ï<Ã¥K—xâ‰'øóŸÿLLL Ï<ó 666@ÉìÒøøx~þùg|}}©V­Z™Æ0`GUA*·:t([·n58IŹ~ý:_ý5ï½÷žÁiDDDDDDDþã·T–f¼pá‚ÁIäQqàÀúôéCpp0ÇÇÉɉ·ß~›óçÏóÇ?þÑR€qîÜ9Ο?OQQ-[¶äܹse>0ÌËË (éˆTÊ-J ÒmÛ¶Q\\lpšŠ±`Á²³³iÓ¦å}EDDDDDDª‚S§NXö÷¬Ê´Ä^ÊË©S§=z4]ºta×®]ØÙÙ1uêTΟ?Ïüùóqqq±\›››ËÖ­[ÉÈÈ fÍš\½z•ÂÂBºv튃jê“õ IDATƒC™ž— ”œr¯‚TnÑ«W/jÔ¨Áõë×Ù½{·ÑqÊÝÕ«WY¼x1³fÍÂÊÊÊàD"""""""%’’’ˆ‹‹ 00ÐØ0eàíí ”äy ¼øâ‹´mÛ–õë×ceeÅøñã9yò$K–,¡nݺ“ššÊÁƒ9sæ ]»v寤¦¦Ò¼ysš5k†““ÓmÇ¿³gÏЬY3¤r+FŒ`9ÄèQòᇒ““C‡;v¬ÑqDDDDDDD,8”ÌÌ,ë)ö›6m"<<“ÉT‘Ñn«zõê@Él<³Ù\éÏ—ß®ÔÔTfΜI³fÍXºt)EEEôë׃òÝwßÑ´iS˵EEEœ={–¨¨(<<<°±±áøñã4kÖŒ¶mÛâæævËø‰‰‰lܸñŽÛ?œ>}PA*w1qâDÖ®]KQQ‘ÁiÊϹsç,{~üñÇš=*""""""UJiAÚ¥K—2ß“——Gƒ X·n!!!„‡‡WZYéìì ”œ6^–ÓÃErrr˜?>7æÓO?%77—öíÛJXX;v´\k2™¸téÛ·o§zõê4jÔˆãÇS«V-z÷îm™Áük)))\½z•Ÿþ™V­Zѵk×ÛæøñÇèÔ©“ R¹½AƒáââBJJ aaaFÇ)73fÌ °°>}ú0pà@£ãˆˆˆˆˆˆˆÜ$<<()mÊÊÊÊ ///ÆŽËøñã©[·.ß}÷«W¯æØ±cøOA ••U¡Ï’ß¶¢¢"–-[F³fÍx÷ÝwIOOÀÇLJgžy??¿[î±¶¶&##ƒ&Mš‰ƒƒC† ¡~ýúX[ßZk¦¦¦Í70`&“‰ÈÈÈ[®KLLäСC« •Û³··güøñ,]ºÔà4åcëÖ­lܸþò—¿GDDDDDDä&©©©ìÛ· Ì“z ±³³»ék5bâĉLœ8;;;V¯^ÍêÕ«-{.–'gggËêÌÒCoD~Íl6³fÍZ·nÍ /¼À•+Wnú<>>žéÓ§Ó¨Q#†zË÷©‡‡YYYôéÓ‡ºuëbccsË3Ù²e 111´k׎ºuëröìYbbb,{˜þÚºuë0›Í´jÕŠFaeÖrQQQ´k×bcc©_¿¾Ñ‘XAAmÚ´!&&†W^yÅrH“ˆˆˆˆˆˆHUñí·ßòûßÿž† ÞqßÄÿ+::ggç2xELL 666ôìÙ³Ì{œÞKµjÕÈÏÏçÔ©S4oÞ¼\Æ”GÃÕ«Wyæ™g,«“k֬ɴiÓðõõ%++‹üü|._¾Ìþýû‰ŠŠJ¾ŸV®\ɨQ£î9¾Ùl&%%…ÐÐPÚ¶mK“&M8tèiiiâää„««ë-÷µoßžÈÈHæÎË{gmù¾¶0:ÒûÓŸþDLL nnnÌ™3Çè8"""""""·Ø°a€åàä²8sæŒå‘{  “ÉÄؽ{7vvvôïßßrØÒý2™L%ÅÖã"99™-[¶0~üø›¶ÿX·nÏ?ÿ<ׯ_ÇÞÞž—^z‰÷Þ{ÚµkßöúíÛ·óôÓOsíÚ5žzê)ÂÃÃiß¾ýÇOLL$** ///‚ƒƒ¹rå ;wî¤I“&P«V­ÛÞwøða"##±µµeÊ”)Zb/w÷ÒK/ðå—_þf§ÊŸ>}šyóæ°`Á‚;þF1JAA¡¡¡ 6¬Ì÷ÝnƲÜÓµkWÆÏàÁƒÙ¿?!!!„††Þ÷A͹¹¹–¡œœœî;ËoÑO?ýD@@Ï>û,_~ù¥Ñqª¤ùóç3vìX®_¿N‹-8pàŸ}öÙ];™ðÍ7ß%Íœ9ó¶×±wï^"""ðõõ¥AƒÄÅÅMƒ ð÷÷¿c9 ÿÙJrذaÔ«W@Kìåî hÖ¬—.]âÓO?åÍ7ß4:Ò}1™LôîÝ›½{÷ÄÎ;ur½ˆˆˆˆˆˆT9k×®eìØ±¸¹¹‘˜˜ˆ½½ý=ïINNæÌ™3ôêÕ«\2”îš››K½zõèÞ½û=ïIIIÁÝÝ€ÌÌÌž‰ú[P\\ÌG}Äܹs)..`ÕªUežÁû¸xûí·Y°`Ï=÷ýë_qtt¼ë=ÅÅÅüíocÖ¬YdddX¾wÓ–GåúõëÔ«WÚµksáÂÒÒÒpqq¡S§NØÚÞ}±|ff&^^^dff²yóf† h©Üƒ½½=o¿ý6Ÿ~úéoné¢E‹Ø»w/NNNüïÿþ¯ÊQ©’JgÎ=õÔSe*G¡äÄû®]»–[777‚ƒƒ?~<µk×¶,ù¿›ÒžÀÊÊêž%ØoYJJ Æ cΜ9–r [·n¦ªz¾øâ K9:{öl–-[vÏï‹íÛ·ÈôéÓÉÈÈ €¦M›°k×.~ùå¶lÙBzz:;v¤víÚœ8q‚ÄÄDéÖ­Û=ËQ€•+W’™™‰¯¯/ƒ ²|]©ÜÓ”)Sðõõ%99™Ï?ÿÜè8evüøqÞyç>úè#7nlp"‘[¥¤¤°eË&Ož\æûŠŠŠn9Á¾¼Ô¯_¿LcgffàèèxÛÓÅ;wî¤M›6„††âààÀèÑ£ðòòÂÇÇÇàtUÇ‘#Gxã7xÿý÷ïyLDD}úôaàÀDFFR½zu.\È¡C‡èÔ©—.]Jöõöö¦E‹>|˜ôôtüüü3f uêÔ¹g¶ÜÜ\fÏžÍôéÓøÃþpÓ÷« R¹'fÍšÀ¼y󈋋36Päååñûßÿž¼¼<ú÷ïoù """"""RÕ¬\¹’ÂÂBüýý-Åн8p€Ž;VX¦².—JÊÂGÙlæOú$))‰úõëóóÏ?Ó²eK@³Gÿ¯™3gRPPÀàÁƒ™={ö¯;vì#FŒ [·nìÚµ [[[ž{î9NŸ>ÍŒ3°µµÅÅÅ€7nТE .^¼È©S§prr¢Aƒx{{—)צM›hÕª~ø!yyyôèуW_}õ¦kTJ™L™2….]º““ôiÓŒŽsO3gÎäøñã<ñÄüóŸÿ| M«EDDDDDD*šÙl¶ôó_ÿõ_e¾ïâÅ‹4lذ‚R•½ -á÷ë}"IIIôïߟwÞy‡ââb&L˜À±cÇèܹ3 K—.§¬:"""عs'¶¶¶|þùç·íaNŸ>ÍSO=E»víØ¸q#ÖÖÖLœ8‘“'O²lÙ²› ÏÜÜ\Ëò|¼¼¼hժݻwÇÁÁáž™âââ9r$ÇçÂ… Ô©S‡¯¿þšÝ»wãæævÓµj¤L¬­­ùòË/±µµeÓ¦M|ÿý÷FGº£U«V±hÑ"–-[öHþKDDDDDD ¡¡¡œ>}GGGþð‡?”éž_~ù¥LËŠÆ… ÊTÀ–®2mРA…æ©L»ví¢}ûöìܹ>ûì3V¯^MÍš5ˆŽŽ }ûöFƬR¾ûî;FŒA³fÍnúìÔ©Süîw¿£U«V¬Zµ “ÉİaÃ8rä«V­ºåz(YRÜô}Þ±cGË`w“ŸŸÏG}D‹-ذaÖÖÖL:•˜˜ž}öÙÛžO£‚TʬmÛ¶¼þúë<ÿüó\¸pÁàD·:uêÏ?ÿ<o¼ñ†e_‘ª¨ô¬I“&Q»ví2ÝFPPP¦‚ôôtË2ç»y”fšÍf>þøcúõëGbb"M›6%""â¦mû’’’¸vímÚ´1*j•³cÇFeùÚÉ“'yòÉ'iݺ5+W®Äd2Ñ¿ÂÃÃÙ´iw/66à¾gIÿøã´nÝšY³f‘››K`` `É’%¸ººÞñ>¤r_æÎK‡HOOgܸqäååÉâÆŒ;–¬¬,zôèÁŸþô'£#‰ˆˆˆˆˆˆÜQLL ¡¡¡XYYñÚk¯•é³ÙŒ]…ˆt»Yv·söìY5jT‘q*\vv6'Nä¿ÿû¿1™LLœ8‘ÇÓ®]»›®;vì>>>·,Ó~\åççsúôi:uêÄ™3g˜8q"mÚ´aõêÕ˜L&ÈÞ½{Ù¾}û=÷nMOOçüùó@ÙKèøøxÆÏ Aƒ8wînnn|ùå—ìß¿¿L{õª •ûR­Z5¾ÿþ{ÜÜ܈ŒŒäå—_Æl6‹¢¢"&L˜À™3gðôôdõêÕv’ŸˆˆˆˆˆˆHyøôÓO1›ÍôíÛ—V­Z•éžÜÜ\òóó !22²Â²™L¦{^“ŸŸÏ‰'î:°ª»páݺu#$$>ýôSV­ZeYRÿk¥ËëÛ¶m[Ù1«¬‹/RTT„••Ÿ|ò ­[·æ»ï¾Ãd21hÐ öíÛGhh(Ý»w/ÓxÄd2áééyÏ­ Y°`Í›7çûï¿ÇÊÊŠ)S¦Ë/¾Xæ3ilËt•ȯ4hЀ+V0|øpþñP«V-þò—¿šiúôéüøãT«Vµk×R¯^=C󈈈ˆˆˆˆÜÍåË—Y±bï¼óN™ïsrrâw¿ûPRL­ZµŠ‚‚<<< *Óá5÷[¦¡QQQR½zuüýýú¹F ãÉ'Ÿäúõ븹¹±råJxÇëcbb€’SÕ¥Dérx³ÙÌòåËèÛ·/óæÍ{ ƒ¬öïßÜû¬Ÿ~ú‰W_}•S§NЮ];þö·¿Ñµk×û~¦ Ry C‡åóÏ?gÚ´i|öÙgT¯^>ø€øøx.\¸@ll, $%%‘””Drr2)))dgg“——Gzzºeæ©­­-5jÔÀÁÁwww¼¼¼pww§yóæжm[<==ï˜åþçøâ‹/°²²bùòåôADDDDDD¤2}òÉ'Ð¥Kú÷ïÿ@c4lØÐ²Gcjj*Û¶m#//777z÷î½½ý{øða&L˜P¦ë:tèPæ™zUÉW_}ÅK/½Daa!þþþ¬_¿??¿»ÞSºô»qãÆ•ñ7¡tZ(™Y»páÂþžسgÀûÄÄDÞ|óM¾ýö[jÕªÅܹsyùå—xë ¤òÀ‚‚‚èܹ3à£>â“O>¡¸¸ø¾Ç)**"-- (Ùì¸t?_kÔ¨ÁÁÁ >œ^½zYþ_¾|9o¾ù&P²?jYþ1RBBÿøÇ?˜5kV¹ŒéææÆÈ‘#’²tóæÍP»vmz÷î­mÙ* ââb¬­­Ë´é‘#G€ßÞiî&“‰wß}— 0zôh¾ùæªW¯~Ï{K¬VAú}ûö%((ˆ#F0mÚ´2¯ÝNnn.{÷ûkEEE,^¼˜Ù³g“‘‘••“&MbÁ‚wXWV檰¤üf\½z•¥K—²zõjΜ9sËçÖÖÖøøøÐ¸qc|}}©[·.¸»»S§N\\\pppÀÙÙK¡š››KFFÉÉÉ\½z•ÄÄDŽ?NTTqqq7=ÃÓÓ“W^y…úõë3eÊŠŠŠx饗øâ‹/*ã—@DDDDDD䡼òÊ+|ñÅtìØ‘C‡Uè³RRRøùçŸ)..Æ××—.]ºÜµüܼy3Ý»w/Ó ö 6$..ŽÆWž±+L^^“'O&$$€3f°`Á‚2Í€ÍËËÃÙÙ“ÉÄÅ‹ï¹?¦Ü¿ÐÐPÌOSDDDDDD¤"œ;wŽeË–0gΜ ^:u,åååË— Ál6ãïïËACdee•©‰‰!..úõëW!ÙË[JJ £Fbß¾}ØØØ°hÑ"^zé¥2ßõêUL&“er˜”¿íÛ·0`À¬­­IMMåƒ>`ñâŘL&œyóÍ7ùÿïÿ•kÿ¤‚Tî*%%…9sæ°téRŠŠŠ äÅ_dÔ¨Q<ñÄžÁÍ͉'2qâDòóóY¹r%sæÌ±ìqqåÊðõõ­ð,"""""""ãÝwߥ°°^½z1lذJ}¶¯¯¯åßÎqqqlذœœÚ·oO³fÍøþûï3fL™ÆÚ¶m:uÂÕÕµÂ2——Ë—/3pà@bbbpvvfåÊ• >ü¾Æ¸víµk×~à½.åîJ Ò~ýúñÍ7ß0cÆ ~ù傃ƒùÛßþV!ý–ØË­ZµŠiÓ¦Y¾Èûï¿O÷îÝ NVbîܹ̟?Ÿœœ\]]Y¶lcÇŽ5:–ˆˆˆˆˆˆÈmœ˜˜ @||Þ’’’¨W¯f³âããð÷÷gñâÅ:Sù·wĘT¸7n0~üxžzê)~ùåüýýÙºu+¡¡¡U¦…’¬9B@@iiiŒ7Ž_|‘œœ££‰ˆˆˆˆˆˆÜâ­·ÞÂl63vìØ;–£PRž={–ýû÷Yá¹:tèÀĉË\Žfdd°k×.\ÉÞÑ£GéÙ³'ñññ4lØ={ö++ €5j”WDù•ððpË=šS§NñÎ;ï”ûY7·£‚T,¶oßN=8wî^^^üôÓO|òÉ'T«VÍèhwåààÀgŸ}ÆÆ©S§Ç§sçÎìÙ³Çèh"""""""äææ2sæL¦M›F³fÍîxíáÇqwwçäɓԩS‡Þ½{3`ÀŠŠŠˆ‹‹£¨¨ˆŸ~ú‰´´´ÊŠ‹o¿ý€§žz +++ÃrÜÍŽ;4h7nÜ 00={öàííýPc–ZíààPåÿ˜8q"ÁÁÁlÙ²…µk×VêY3*H€•+WLVV={öäèÑ£ôèÑÃèX÷eذa:tˆ6mÚ’’Bÿþýùú믎%""""""¹ ‡»»;³fͺëµ~~~899a6›9}ú4ëׯ'99™ÀÀ@z÷îÍ•+WHJJbß¾}ìÛ·ÄÄDL&S%½ $''³sçN ¤ ­ŠöìÙÃÈ‘#ÉÍÍ%((ˆ;v”Ë!Óùùù€ ÒŠÒ§O6nÜÈ!C*ýÙ*H…Å‹3iÒ$ 1b¡¡¡¸»»ëÔ¯_ŸððpFEAAøÃxñÅ)**2:šˆˆˆˆˆˆ<†âããùôÓO˜7oµjÕºëõO<ñ 6døðá´hÑwww 8~ü8 Ó·o_ÈÏÏgëÖ­lß¾ 6TJQú¯ý‹¢¢"Z¶lI›6m*üy÷+""‚aÆ‘MÏž=Ù´iS¹-‰/ýõ­ª³fåÁ© }Lååå±nÝ:ÆŽË´iÓ0™L<ÿüó¬]»GGG£ã=”êÕ«³fÍÞ~ûm–.]ʸqãÈËË38™ˆˆˆˆˆˆ¬­­™?>Ë—/ÇÁÁ~øáÇ“mt4yLlݺ•uëÖammÍâÅ‹±¶~ð¦zõêøùùÑ»wo<<<8tèGŽ!,, [[[úôé”ü{¸°°ýë_œ8q‚ÔÔÔòzÂÂÂ8{ö,ŽŽŽU® =vìýúõ#--ÀÀ@¶mÛv×™£f³™ððp’’’ÊüŒêÕ«”{ñ,Ƴ5:€TŽãÇóñÇBqq1žžžŒ7ŽI“&ѹsgƒVŒÉ“'[Êà°°0 ÄæÍ›ï¹¤ADDDDDDäaäääðÊ+¯ðÒK/ѵk×r·F@\\YYY8p€Ë—/ãëëKÿþýÉÉÉ¡eË–?~œ-[¶0hÐ hذ!¼rtÉ’%@Éa:nnnåò>å!>>ž!C†ššJ@@¡¡¡wýw¿Ùlfß¾}Ô¬Y“:uê`6›Ë´l¾tÌò,¥j°2›Íf£CHŹví³fÍâ믿¶£AAAÌœ9“>23Fïe÷îÝ >œŒŒ :tè@hhh¹lÐ,""""""r;o¾ù&þóŸ©[·.§OŸ®Ð‰:999ÄÄÄðã?Òºukòòòhժ͚5#//“ÉÄÎ;IKK£cÇŽ¸ººâááq_{iÆÅÅÑ´iSŠŠŠØ¿•™huãÆ zôèÁ‰'hܸ1Ô©SçŽ×çååAãÆ©V­GŽ¡k×®¸¸¸ÜóYáááôèу:uꜜ\ž¯!SAúˆ*,,ä³Ï>ã£>"##€àà`Þ{ï½*ó‡Xe;xð å'J­ZµbçÎwýCSDDDDDDäADGGÓ±cGŠŠŠX½z5&L¨´gÇÇÇsâÄ ®]»ÆàÁƒÙ½{7AAAÔ¬Y“„„¼½½Ù´iÔ«W€€€2•ƒ¯½ö‹-¢K—.DDDT›Ü[AAC‡eÇŽÔ®]›}ûöÑ´iÓ;^_TTÄÁƒqttä‰'ž >>ž&MšàááQ¦ç]¹rooo d™ý½ö7•ߤ ãÇ3eÊ> @óæÍY¸p!C‡58™ñN:Å€¸zõ*mÛ¶e×®]eú‹@DDDDDD¤,L&=zô ""‚Aƒ±mÛ6ò\¹r…óçÏ“––†••#FŒ ==üü|ŠŠŠHNN&22lmméÛ·ïmǹ~ý:õë×';;›õë×3räÈJ~“[™ÍfžyæV¬X££#aaatëÖíŽ×²oß>|}})**"11‘–-[Þ×êR“É„‹‹ ™™™ìÛ·¯Ü¶Mãé¦GHAAsæÌ¡C‡>|˜Zµj±dÉŽ?®rôÿ×¢E BCCquu%::šqãÆ‘ŸŸot,yD|ùå—DDDàèèÈ_|ah///z÷îMûöí騱£åP§ÔÔTÒÓÓ `È!xyyѰaÃ;ŽóÙgŸ‘¿¿?ǯÄ7¸³¹sç²bÅ ¬­­Y±bÅ]ËÑÜÜ\öïߣ£#ÖÖÖœ={–Ö­[ß÷Ö{ÖÖÖtêÔ  ÊÌ¢•ò¡‚ô÷ÿ±wßQUÞY߇?‡*ň E‘fEýÅ,11öhŒe4cy±$Mb,јIvcoØÅ b¬€`C@©ÒË9ï,˜qÆr•}­5+ ÷½÷ÆgùåW< }ûöÌ;—œœºwïÎ7øê«¯*Ì9£EÕ¨Q#|}}100àäÉ“ 8°ð|V!„B!„âm=yò„Y³fðí·ßbkk[Îå«U«–––4iÒ„:uêð÷ßÏîÝ»±°° aƯ H“’’øý÷ßðööFC£ü£¤#GŽ0wî\/^Lÿþý_ùlvv6'OžÄÎÎ}}}BCCiÛ¶-FFFoÕ»`Õ¨ŸŸß[½/ÞMåÿ»Z”˜7æâÅ‹T­Z•õë×ãë답µuyöÎjÑ¢Û·oG[[›½{÷2a„òI!„B!Ä{nÅŠ$%%ùúìÙ³‡ìììržêß´´´hÖ¬ƒ ÂÕÕ• ¼ñ_~ù…¤¤$lmmùüóÏË`Ê׋ŒŒdÈ!(•J¼¼¼˜|ÈŸþÉ_|Q¢zâÝ +HßSF¿" IDATwïÞ¥U«V…çm̘1ƒ³gÏJ8ZLC† aÁ‚@þV'N”óDB!„B!ÞW-Z´àöíÛ\¼x‘qãÆallL||<¿ýönnn4jԈŋSޣɒ%KHNNÆÑÑ‘Áƒ—÷8Lš4©ðΕ]»véù‚­ôíÚµ+q8  P(1b¿½_©T–¸¦(²‚ô=tøðaLbb"Õ«WgË–-tíÚµ¼Çzo©T* ĶmÛ011!00ðµ‡S !„B!„E‘••ÅذaGŽ!77MMMºvíʰaÃèÓ§zzzå<éÿЉ‰ÁÑÑ‘´´46mÚTîÛë÷ìÙÃ'Ÿ|‚B¡`÷îÝôíÛWmµŸ={FJJJ‘ÏŒMHH víÚ¤¦¦Ê*Ò„¬ }ÏÌŸ?qqq!((HÂÑR(¬Y³gggâããéׯiiiå=–B!„Bˆ÷œ®®.Ÿ~ú) 66–•+WâêêJ^^GŽÁËË‹š5k2tèPNœ8Á»´†íÛo¿%-- ggg¼¼¼Ê{€ü3@ÕŽÆÆÆ@ddd‘Wƒ3mÚ4¦M›Ftt´ÚæåCÒ÷DNN#GŽdÖ¬Y(•J† ƹsç¨]»vyöAÐ××gÏž=˜˜˜píÚ5F]Þ# !„B!„ø€óå—_ÄÍ›7ñööÆÌÌŒääd6nÜH×®]±±±aúôéÜ»w¯\g ÁÇÇÈßFþ.Ü\_ (Ûê‹";;›¨¨(._¾Œ½½=ÎÎÎÅÚ.?}út5jDbb"½{÷&55U-s‰òñîü¯”””D÷îÝY·n,Y²„õë×S©R¥òíƒR§N¶mÛ†¦¦&[·neÆ å=’B!„BˆPÆ Y°`ÑÑÑ?~œ!C† ¯¯Odd$ .ÄÁÁ6mÚ°jÕ*ž?^æóM™2…ÜÜ\zôèñÎìZU(j[eûäÉ‚ƒƒiÖ¬vvvܸqƒààà"¿¯££ÃöíÛ©V­ÁÁÁôìÙ“„„µÌ&Êž¤ï¸û÷ïãîîΩS§¨T©[¶laòäÉå=Ö«K—.LŸ>€ &QÎ !„B!„øPijjÒ¥K|||ˆŽŽfåÊ•¸»»£R©8wîcÆŒ¡F 0€——Wê3ùùùáë닆†?þøc©÷+®’¤¹¹¹óèÑ#Z·n¶¶6ׯ_'**ЦM›«Vƒ ؽ{7œ={––-[rþüùÍ'ʇ\Òô»|ù2½{÷&66sssöïß››[yõÁËÍÍ¥M›6\ºt wwwüýýÑÔÔ,ﱄB!„BT¡¡¡lÛ¶ 6ðàÁƒÂ[ZZ2xð`¾øâ ÔÞW¥RáææÆ•+W9r$kÖ¬Q{·µdɦNJ¿~ýؽ{÷[×Ù·o¹¹¹´nÝšôôt"""055¥Q£Fèèè¼UÍ   <<þôéS&L˜À_ý€††mÛ¶ÅËË‹Î;coo_ì™ÿ[VVQQQ|È£G Y¤³P­­­‰ŒŒ,ñ< HßA?ÿü3ÞÞÞ(•JºtéÂÎ;©ZµjyUáüñÇŒ;mmm®\¹‚““Sy$„B!„¢‚JIIaïÞ½lܸ‘“'On5×ÕÕ¥k×® :”~ýú¡¥¥õVõ333©W¯>dÖ¬YüðÃê¿Ä¶oßÎÀqssãòåËÅz7++‹Ë—/“žžNÇŽ‰‰‰!00›bïÔÝ¿?-Z´ÀÌÌ쥟÷óócÞ¼yœ>}ú…רQ'''êÔ©CõêÕ©^½:ÆÆÆ––Fvv6*•Šøøxâããyöìñññ<}ú”¨¨(?~\¤utt°°°ÀÊÊ 333LLLؾ};ÉÉÉèèèpøða:wî\¬¯ûC'é;D¥R1uêT–.] ÀÈ‘#ùã?ÐÖÖ.çÉ*&•JE¯^½ðõõÅÝݳgÏ -„B!„B”—G±eËV¯^ÍÝ»w ?^³fM<==>|x±ÏÓ\´hÞÞÞ˜ššñÒU’åÉ××—ž={R·n]BCC‹ü^ZZÇŽ£R¥J´jÕŠ[·n‘’’‚]±¶À«T*Nž<‰±±1...o|>44”M›6qäÈ®^½ŠR©,r¯×ÑÐÐÀÜܬ­­ ÿW»vm¬­­±°°ÀÜÜü…w&OžÌ/¿ü‚††[·neÀ€j™åC"é;"77—Ñ£G³~ýzæÍ›WªçA\¸pàà`ÆŽ‹††ÜÕõ*÷ïß§Q£F¤§§³zõjFUÞ# !„B!„…®\¹ÂªU«Øºuë 7Þ7hЀ¡C‡2bÄjÔ¨ñÚ‰‰‰ØÛÛ“Àï¿ÿÎøñãK{ìb»té-[¶ÄØØ˜øøø"½…¿¿?:uB¡PFRRnnnXXX«ÿùóçÑÑÑ¡jÕªÄÅÅѺuë"¿›””ÄÕ«W¹uëQQQ<{öŒ„„âãã M000(<ÕÈÈSSSLLL¨^½:&&&ÔªU kkk,--‹µnáÂ……—Q¿«ÿnß¾²²²>>lÛ¶¤¤¤Â;991lØ0Ø»w/­[·& à¾{ÃÎÎŽ{÷îáëëûÆüD¥RqöìY”J%ôèÑ£Øý®_¿NíÚµINNæÎ;´o߾ثk/\¸€­­í+/uz“¸¸8nÞ¼Y˜IŹsçèÖ­éééôë׿þú MMÍ·ê_QÈá“åäÑ£G´mÛ–   ŒŒŒ8~üx™„£‘‘‘˜ššJ8ZDíÛ·ç³Ï>C¥Ráíí]Þã!„B!„EÒªU+V¬XÁãÇÙ¾};={öDSS“7n0uêTöîÝ‹B¡`ñâÅït8 P¯^=nܸñÆg ŽŽŽ¿U8z÷î]"##144ÄÏχb‡£ÿý7*• “b÷‡ü…u!!!4nܸÈïܺu‹Þ½{“žžNûöíÙ²e‹„£E i9 £M›6„††R³fMüýý‹u¸oI>}@ÂÑbúñÇÑÑÑÁßߟC‡•÷8B!„B!D‘UªT‰pèÐ!¢¢¢øùçŸiÔ¨Ÿ}öY™æo«iÓ¦…牾‰¹¹y±ÂÅׯ_çÚµk¸¹¹qúôi¼¼¼¨]»v±jÜ¿Ÿ””,,,¸|ùr±gHII!$$„ºuëLjjêß‰ŠŠ¢gÏž$$$àääÄž={¨T©R±{WD–±:uêDdd$666øûûãääTfýoܸÁ?üPfý>$¶¶¶|õÕWL›6­ðÀk!„B!„â}bnnΔ)S¸qã÷îÝÃÇǧ¼G*ggg®^½Zj=’’’044ÄÅÅ…+W®`ll\ì•£AAAhkkcaaADDDa°[œ.\¸€‹‹ §OŸÆÍÍíµ—RAþjÓ®]»‰­­-GÅÈȨX}+2 HËPpp0íÚµ#&&† pþüyʬxx8}ôéééôìÙ³Ìz—•JÅ‚ زe‹Zê}óÍ7T©R…6mÚ¤–šB!„B!Dy©S§Î;ykýËÜJll¬Úë'''sáÂŒ‰‹‹ÃÄÄ—bÕxþü9iiihjj¢¥¥EݺuÑÓÓ+òûiiiÄÅÅѰaCnܸÁÀ©V­ÚkßIMM¥W¯^„††R£F Ž=JÍš5‹5wE'i¹xñ";wæÙ³g4iÒ??¿2ýÍI×®]yüøqáw*ÂíõQQQ̘1ƒQ£F‘™™Yâz¦¦¦L›6 €¹sç’““SâšB!„B!„x³ZµjáèèˆJ¥âäÉ“j­ýüùs._¾LÓ¦M '''§X4+•Jîß¿ÏíÛ·±´´äúõ똚šbmm]äééé…mxxx‘Õåää0`À._¾LåÊ•ñõõÅÞÞ¾È=E> HËÀ™3gèÖ­III4oÞœS§NajjZfýïß¿O»víxøð!ŽŽŽÔªU  ðŸ2+++ŒÉÈÈàÊ•+j©ùõ×_cbbƒغu«Zj !„B!„âͺví €¯¯¯Új&$$ˆ ·nÝ"##ƒ–-[«FDD<ÀÂÂ---\\\000(VÇS§NΟ?››Û/wR*•Œ1___tuuÙ³gO±W¼Š|–2???zõêÅóçÏiÓ¦ Ç/Ó3 """hß¾=>¤N:œ8q‚èèh€b0ü>R(…¨?^-5 ™0a?ýôJ¥R-u…B!„Bñz½{÷`ïÞ½¤¥¥•¸^nn.iiièèèžžNZZíÚµCC£è‘™J¥"$$„:uêpóæMôôôе0.++‹K—.ñÑG^¤3G¦L™ÂæÍ›ÑÐÐ`ãÆtîܹÈ=Å‹$ -E‡¦G¤¦¦Ò¾}{>L•*Uʬÿ;wèС=ÂÆÆ†“'ORµjU’““Š…7ñ©+ ˜8q"•+W&44”½{÷ª­®B!„B!^­K—.XYY‘ššÊîÝ»K\Ï×וJ…±±1ééé…lQ=zôˆ3gÎðÑGŒ››fffE~?''‡+W®`mmÍÍ›7©W¯æææo|ï§Ÿ~bÙ²e,]ºOOÏbÍ-^$i)Ù¹s'ýúõ#33“ž={räÈ*W®\fýCCC騱#ÑÑÑ8::@:uxðà¿ ÒØØ¸Ìæ)OíÚµòWóªëæyccc¾üòK ÿ%!„B!„B”> >ÿüsþõ¯½u¥RÉ¡C‡¨S§©©©T®\¹Ø·Í'$$†³³3gΜ¡uëÖT¯^½Èïçääpþüy,,, ÁÚÚ›7¾·víZfÍšÀìÙ³™4iR±æÿKÒR°e˼¼¼ÈÎÎæ“O>aÏž=TªT©ÌúÒ®];bbb¨_¿>~~~XZZù—5AÅY= ЪU+ªV­JRR/^T[ÝÉ“'£««KPP§OŸV[]!„B!„B¼Ú„  ÿ>~øðá·ªQp™’¡¡!‘‘‘˜››+»yøð!W®\ÁÞÞ\\\Š´òó?EGGcllLLL 5jÔÀÊÊê¢ÔZ[!„B!„/÷Í7ßP¥J®]»Æ’%KŠõn:u°´´äÙ³gÔ«W¯X*%''sîÜ9ÌÍÍÉÌ̤yóæÅÎX‚ƒƒ©\¹2 ¨T*¬­­ßøÎÍ›7éÝ»7tèÐM›6¡©©Y¬¾âÕ$ U“?þøƒ¯¾ú ¥RɨQ£Ø¸qc™†£¿üò ƒ&;;›~ýúqúôiLLLþ繂¤- ÕÓÓ &&¦0$V‡¦M›Ò¢E rssY¹r¥Úê !„B!„âÕ,--™?>ß}÷]±Ô³±±¡sçÎ/ÍN^%99™€€Z·nŸŸ666T«V­X}?~LNNYYY¨T*lmmßøÎÇéÞ½;‰‰‰4iÒ„½{÷–éQޤj°dÉÆŽ‹R©d̘1¬\¹ ²ù¥ÍÍÍeúôéLž<•JÅðáÃÙ±cÇ+ÿC©ˆ[ì–ÊïܹS­µÇÀÊ•+ÉÊÊRkm!„B!„B¼ÜرcéÚµ+YYY|òÉ'Å^¥««[äg‰ˆˆÀÁÁ   êÕ«Wìp fÍš˜˜˜ T*iÞ¼ùŸöì}ôÑÑÑØÙÙáëëKÕªU‹ÝW¼ž¤%4þ|¦N ä_Ú³bÅŠ2 GèÞ½; .D¡PðÝwß±nݺ׮\­¨[ìÓÒÒ ü×_©µö€055%..޽{÷ªµ¶B!„B!^NCCƒíÛ·ãààÀãÇiÛ¶-¥ÒËÈÈsssBCCiÔ¨öööo]ËÞÞžfÍš¡P(^û\zz:½{÷&,, SSS>\ì‹ DÑH@ZsæÌaÖ¬YLŸ>%K–¼ñ7·º„‡‡ãîîÎÉ“'©T©>>>Ì™3çµïdggóäɠ⤩©©…?¾téRáJZuÐÕÕeøðá@þ%]B!„B!„(FFF>|˜Úµk‰»»»Z/hþO–––´iÓ ‹R©ÿŸ ŽP¼páUªTáèÑ£8::–zߊJÒ· R©˜:u*óæÍÀÛÛ›Ÿ~ú©Ìú:t777BCC±²²" €Áƒ¿ñ½G¡T*ÑÖÖ~áfûŠ `©¥¥%*•Š;v¨µþ°aÃ8vì˜\Ö$„B!„B”!{{{Μ9Cýúõyúô)=zô`ìØ±<{öLí½ŒÕ^ó¿)•J†αcÇÐÕÕeÏž=4mÚ´ÔûVdew‹ÐB©T2~üxþøã,X€··w™ôÎÉÉáÇäûï¿G©TÒ´iSöíÛW¤ÛÎàßçZYYU¸›Î Vº¸¸ÍÚµk™6mšÚê7lØWWW®\¹ÂÖ­[ÕZ[!„B!„¯W«V-._¾Ì¸qãØ¸q#üñÛ¶m㫯¾büøñXYY•ùL©©©DGGÇÓ§Oyüø1OŸ>%++‹ÄÄD²³³IKK#//MMMŒŒŒÐÕÕ%**Š={ö ©©É¦M›èÔ©S™Ï^ÑH@Z yyyŒ5Šõë×£P(Xºt)_ýu™ô ÃËË‹«W¯0zôhþõ¯ëÖ²Gï‚&ø÷ Ò6mÚpâÄ BCC9wîîîîjë1tèP®\¹Âúõë% B!„B!ʘ¡¡!>>>|öÙgL™2…°°0,XÀâÅ‹qww§oß¾´mÛ–&Mš¼öþ–¢HOOçáÇDGGMdd$QQQDEEñðáC=zDJJJ‰züöÛo|úé§%ª!ŠFÒ"ÊÎÎfРAìÚµ MMMV¯^͈#ʤ·ãÇ'55•ªU«²bÅ ¼¼¼Š]'::Èßf^Ѭ 555¥oß¾lݺ•5kÖ¨5 4hS§NåöíÛ\¹rWWWµÕB!„B!DÑôêÕ‹nݺ±cÇ~ýõW9sæ gΜ@OOGGGììì¨^½:ÕªU£jÕªT©RÒÒÒÈÎÎ.\á™””Dll,qqq<{öŒ'Ožœœ\¤Y455155¥FXXXP£F ôôô¨V­ºººèë룩©I^^‰‰‰dee‘žžNëÖ­ ó¥OÒ"ÈÈÈ ÿþøúú¢­­ÍÆùì³ÏJ½ï½{÷˜8q"‡òW?nÚ´é­/Xzüø1@™&ü®)XAj``À_|ÁÖ­[Ù±cË–-£J•*jéQ½zuºwïÎرc‡¤B!„B!D9ÑÖÖæóÏ?çóÏ?'44”Ý»wsìØ1IOOçÚµk\»v­Ä=jÖ¬‰µµ5VVVXYYammM­Zµ nff†††\ô®“€ô RSSñððÀÏÏJ•*±cÇ<<$ B!„B!„x×I@úiFFFáõ·±zõj´µµQ©T,X°€_ý•öíÛ«íöô7‰‰‰*îöúJ•*••õÂÇ2dß|óÚúõèÑ€3gΞž®¶ºB!„B!„B½$ }ccãÂÕ‡o{)€cÇŽ`êÔ©äää¨e¾¢zúô)fffeÚ÷]QfddüÏçæÌ™ƒ®®.çÎÃ××W-ýœ±°° 33S­+S…B!„B!„zI@úZZZ…«H£££KTköìÙÊš5kÔ1^‘={ö SSÓ2íû®ÐÓÓ^Ö®]›Ñ£G0kÖ¬ÿÙ†ÿ6 Eá6{u…®B!„B!„Bý$ -{{{îܹS¢:&&&Ìš5 €ï¾ûŽçÏŸ—x¶¢*H«W¯^f=ß%¯ H!?544äêÕ«¬\¹R-= ÒÇ«¥žB!„B!„P? H‹ÀÑÑ(y@ ðü;;;bccY´hQ‰ëU||<ÒVD•+W %%奟777göìÙ̘ÃÛ±j IDAT1£ðR«’èÖ­ZZZÜ»wˆˆˆ×B!„B!„ê'i888^âZ:::|ÿý÷,Y²„G•¸fQTô€´à˜„×#ûÏþggg’““™>}z‰{Ѽys@n³B!„B!„xWI@Zê\A 0pà@ÜÜÜÈÈÈà»ï¾SKÍ7©è[쌌€×¤ZZZüþûï( 6nÜÈ©S§JÜ·{÷B!„B!„ï* H‹ nݺ€úR…BÁÏ?ÿ Àúõë¹zõªZê¾NE_AZ&$$¼ö¹6mÚ0|øpT*ãÆ#--­D} ÒÓ§O“••U¢ZB!„B!„Bý$ -{{{ )))j9› ]»vxxx T*™9s¦Zj¾ŠJ¥*\9YQW|Ý+i_gÑ¢E˜™™ÆÄ‰KÔ×ÕÕcccÒÓÓ ,Q-!„B!„B¡~¡¡!uêÔPkȵpáB´´´8rä'OžT[Ýÿ–˜˜Hnn.PqWZXXõÆg«W¯Ž¬]»–-[¶¼u_ ÜÝÝ8sæÌ[×B!„BˆŠ >>ž+VðÓO?qäÈbccË{$!D i„\çÎS[Íúõë3bÄ~üñGµÕýoÛëutt os¯h¬­­¢¤ý”)S3fL‰.èjÛ¶-o]C!„B!>Tyyyøúú2`À,--7n3gΤG˜››cee…‡‡sæÌÁ××—”””òYñQ¨T*Uyñ>XµjcÆŒ¡uëÖj IïÝ»GݺuÉÍÍåüùó´jÕJmµ \¾|™-Z`nn®¶#Þ7qqqÔ¨Q€”””"Å999¸»»H‹-8þ<ÅÿžÂÅ‹iÕªUªT!!!MMÍb×B!„BˆMDDëÖ­cÆ DGG~¼nݺ888ð÷ß¿t‘‹¦¦&NNN´mÛ–6mÚбcGLMMËrt!ÄFÒ"º}û6 6DGG‡ÄÄDôõõÕVÛËË‹mÛ¶ñÉ'Ÿ°k×.µÕ-pòäIºté‚££#aaaj¯ÿ>P©Tèëë“™™É­[·hРÁß ÁÓÓ“[·n¡££Cll,ÕªU+vŒŒŒHKKãÊ•+¸¸¸¼Í— „B!„ï½´´4vîÜÉÚµk9{ö,‘DåÊ•ñôôdäÈ‘…;8!±ËÕ«W &((ˆsçÎñäÉ“jjhhàêêJ÷îÝéÞ½;-Z´…)Bˆb‘-öET¿~}LMMÉÎÎVûe;ÞÞÞ( öîÝË;wÔZ 55µ×~_( lmmŠ´]ÞÇÇ777nݺEõêÕÙ·oß[…£ÚÚÚ´lÙsH…B!„Ó¹sç5j5kÖdøðá…7jÛ¶-ëÖ­#&&†5kÖ¼Ž˜ššÒ­[7¦OŸÎÎ;yüø1wîÜaݺuŒ9{{{”J%|ÿý÷¸»»cffÆèÑ£9qâyyyåñå !Þ3‘B¡ uëÖ€úÏ’lÒ¤ ;wF©T²f͵ֆüïÐAþeSYݺu^B§¥¥1räH† FZZmÚ´áêÕ«tïÞ½D½ÛµkÀÙ³gKTG!„B!Þ?fáÂ…Ô«W6mÚ°fÍž?Ž¥¥%3fÌ ,,Œ3gÎ0|øðbý}ÕÁÁádzfÍÂÃà ç·ß~£W¯^èëëÏŸþI×®]±°°`üøñ—âW*„xßI@Z !×áÇÕ^û‹/¾`Æ …7Ϋ‹¬ ÍW¾ê˜ÀÀ@\\\X·n …‚‰'rêÔ)¬¬¬JܻࢦÿÜB"„B!„šììlöìÙƒ‡‡µjÕbúôé„……¡££Ã§Ÿ~Ê¡C‡xøð!óçÏÇÁÁA-=ííí™0a$>>ž}ûö1hÐ yúô)Ë—/ÇÕÕ777Ö¬YS¸ˆH! H@Z Ÿ|ò …‚ .©ÖÚ}ûöÅÈÈˆØØXŽ=ªÖÚæ+HCCC_øx^^?üðîîîܹssss>̯¿þж¶¶Zz·lÙâââ*ì9°B!„Bˆ×Í›7™}¸~ýz‰·Ôÿ7===\]]9‡T!„BñaHJJbÅŠ4oÞ'''~ùåâââ022büøññ÷ß3iÒ$ªW¯^æóéééÑ¿öïßÏýû÷ùúë¯133#11‘yóæaccƒ··7ñññe>›âÝ"i1yzzð×_©½öðáÃ8xð Z—üÔªè+H7nŒŽŽ©©©„……±jÕ*š4i¹sçÐÓÓcÙ²eìÝ»SSSµ÷NOO/ eƒ‚‚Ô^_!„B!Ê‚R©$ €1cÆ`eeŸqã DCCwwwV®\ITT¿ÿþ{á"‘ò–MTTÆ ãþýûlذzõêñüùs-Z„ƒƒ .$;;»¼GB” H‹éÓO?E¡PpñâE¢¢¢ÔZ»Y³fXXX••…ŸŸŸÚêl±¯è+Hutthذ!Œ3†ÔÔTÜÝݹví“&M*•¾ téÒ…K—.¡««KÿþýK¥B!„B”–0wî\ìììhÛ¶-«V­"-- [[[æÍ›Çýû÷ àË/¿D__¿¼Ç@¥Rñøñc®_¿Ž¹¹9ÏŸ?G¥R1tèPn޼ɖ-[ppp 11‘éÓ§ãêêÊ… Ê{l!D9€´˜êÔ©C³fÍP*•lß¾]­µ }ô€ZÏ!•¤ù222 |÷î] ùí·ß8sæŒÚÿoQQQ´mÛ– .P¥J|}} ÿ !„B!Äû`æÌ™ØÙÙñÝwßñàÁƒÂרQƒŽ;’››Ë‘#Gð÷÷g¶«ÇÆÆrúôi²²²ÐÓÓ#;;—ÂðVSS///n޼ɢE‹¨R¥ 7oÞ¤]»vÌ™3Gí—' !Þm¾…!C†°|ùròòòÔZ» <;räˆÚjlÐÑÑQ[Í÷Íhذ!W¯^ÀÅÅ…›7o2aÂ44Jç?ƒÜÝݹ}û6ffføùùѱcÇRé%„B!„¥åæÍ›…G†ý§§OŸ²fÍæÍ›Ç˜1cèСÕ«W§fÍštïÞü‘€€€2ݺžMLL wïÞ¥zõê$''cbbBݺu_ºhHGG‡iÓ¦FŸ>}ÈÍÍeÞ¼y´mÛ–˜˜˜2›[ˆ¢ÊÉÉ¡[·ntïÞ•JUÞã|0*ùÕ,¶çÏŸcmmMrr2»wï¦_¿~j«˜˜ˆ©©)yyyDDD`ggW⚟þ9[¶lá§Ÿ~búôéj˜òýÂĉ9qâ5kÖdÑ¢E <¸TûÒ«W/âââ°±±áرc¥¶JU!„B!JSff&!!!¤§§“‘‘Aff&ÏŸ?çéÓ§DGGóäÉ"##¹uëÏž=ûŸ÷õôôèÚµ+žžžxxxPµjUµÏ˜——Gtt4÷ïßÇÁÁP¹reêׯ––V‘ë¬^½šÉ“'“ššŠµµ5ÀÙÙYíó ñ¶~ýõW¾þúk HLLD[[»¼Gú ýO Q¨råÊ|ñÅ,]º”_ýU­©‘‘®®®\¾|™³gϪ% U(ê; 111üøã¬^½šœœ´µµ™4i³gϦråÊ¥ÚûСC|öÙg¤¥¥áììÌ‘#G077/ÕžB!„BQZ*UªDÓ¦M‹ôl\\7oÞäòåËœ9s†€€RRRØ¿?û÷ïGWW&L˜@ûöíÕ2_jj*±±±$''£¯¯Ïƒ¨_¿>FFFÅ®5zôhZ·nÍÇ̃hÛ¶-‡¢mÛ¶j™Uˆ’HHHàûï¿òïV‘pT}d‹ý[š8q"ZZZøûû«ýVò‚›þ®]»¦ÖºA||<Ó§OÇÁÁåË—“““C§N¸zõ*‹/.õptÕªUôíÛ—´´4Ú·o¿¿¿„£B!„Bˆ ÃÔÔ”Ž;âííÍ¡C‡HHHàüùóL™2²²²Ø¹s':tÀÙÙ™7¾tû~Q(•JBBB¸uëÆÆÆ¤¥¥abbBëÖ­ß*-аaC.^¼H‹-xþü9ü±ÚÿÞ/ÄÛøöÛo Ïù8p`9Oóa‘€ô-Õ®]›>}ú°téRµÖ.X¾¯®€´"¬ }öìsæÌÁÖÖ–… ’žžN³fÍ8rä'Ož,¼½¾´äææ2~üxÆŒCnn.Ÿþ9GŽ)•­#B!„Bñ¾ÐÔÔ¤U«VüüóÏÜ»wóçÏ3xð`tuu¹~ý:C‡¥I“&8p ØµãââÈÍÍECCƒ¨¨(Ú´iƒ­­­Zæ633ãøñã4oÞœ””ºwïÎÝ»wÕR[ˆ·ªU«¨R¥Š\­f–À´iÓP(lß¾]­ßM*Hÿþûï:ÔT‡{÷î1iÒ$j׮ͼyóHII¡~ýúìØ±ƒË—/—ɱ±±tíÚ•åË—£P(˜;w.7n¤R¥J¥Þ[!„B!Þ …‚V­Z±qãF>|ȬY³044äÆôîÝ›?þ˜¨¨¨"×333#>>œœœ ©KåÊ•ñõõÅÉɉøøx @VV–Z{QTÓ§O'77€O>ùD25“€´Z´h§§'J¥’©S§ª­n:uP($&&òé§ŸÒ¢E Œ©W¯cÇŽeß¾}äää¹Þ‡¶‚T¥RáïïO¿~ýpppà_ÿúééé899±iÓ&nÞ¼‰§§§ÚÿÏñeÎ;‡‹‹ ~~~èëë³uëVfÏž]&½…B!„â}effÆ?ü@DDãÇGKK‹C‡ѨQ#Ö­[Wä::tÀÔÔ´Ôæ466fÏž=T­Z•àà`¦M›Vj½„x•àààVYËözõ“[ìKèÞ½{4hЀ¬¬,öîÝ[¸í¾¸bbbX¿~=¾¾¾\ºt騙™ãÇgÚ´ioü®Á°aÃðññáûï¿ç›o¾y«ùÞÑÑÑlÚ´‰?ÿü“ˆˆˆÂ»»»ãííÍÇ\fÁd^^K–,á›o¾!''víÚ…““S™ôB!„BˆÉ•+W9r$ׯ_ò/Kúí·ßÐÕÕ-çÉòíÚµ‹O?ý ‚‚‚Š|i•êЧOöïßäŸóƒ––Ü»®N²‚´„lmm™0aÿïÿý¿b­ì¸xñ"žžžÔ®]›Y³f@NNÕªUÃÐÐüãlÞ¼™‹/²cÇÆŒƒ‰‰ ±±±Ìž=gggÂÂÂ^Û£ 4|Ûƒ¯ËÓ³gÏðññ¡[·nÔªU‹éÓ§¾¾>Æ ãï¿ÿ& 2 GïÞ½Kûöíñöö&''‡¾}û(á¨B!„B¼%WWW‚‚‚ðööF¡P°zõj:vìXx!MYxôèQa@ûßú÷ïOïÞ½Q*•Lš4©ÌfâêÕ«/¬õôô”p´È R5HLLÄÁÁøøxfÏžÍܹsßøÎ“'O˜>}:>>>…[ß›7oÎàÁƒéÚµ+õêÕ{å»YYYlÛ¶éÓ§óäÉlmm¹pá5jÔxéóãÇgùòåx{{³`Á‚·û"Ëн{÷8pàÄßßÿ…ÐÙÕÕ•!C†0dÈŒËt.¥RÉü··7©©©°hÑ"ÆŽ+[ê…B!„BMvíÚÅðáÃIMM¥qãÆ?~ü•ßU‡§OŸrëÖ-,,,¨U«zzz/}.""‚† ’ŸŸíÛ·/µ™„(зo_öíÛWøsù½W:$ U“ 60|øp´´´ E‹¯|öرcxyy‘€B¡ÀËˋɓ'ãêêZ¬žqqq¸»»θqãø¿ÿû¿—>7}út.\øÚgÊËÍ›79xð ·oßæÞ½{’ýÂ3õêÕ£_¿~ :ôµÁqiºrå &LàâÅ‹@þù³6l nݺå2B!„B|È®\¹ÂG}D||< 4àÌ™3˜˜˜¨µÇ“'OHII!33“jÕªEݺu_ÛgÈ!lÚ´‰þýû³sçNµÎ#Ä»uëNNN… ë,--‰ŒŒDCC6„«›üŠªÉ°aÃèÛ·/¹¹¹ >œŒŒŒ—>·téRzöìIBBNNNœ9s†Í›7;…üs'–,YÀáÇ_ù\åÊ•HII)vÒðøñcf̘½½=NNN̘1ƒ7rîܹÂp´C‡üüóÏܹs‡æÏŸ_.áhLL £F¢yóæ\¼xCCC/^̹sç$B!„BˆRâêêÊ©S§¨Q£·oߦÿþÿ³˜æm©T*üüüxüø1ddd P(hݺõCØ‚#ööíÛW¦ÛÿEÅ´páÂ.Üþì³Ï$-%ò«ªF+W®¤F„††âííý?Ÿ_´hS¦L!//ÁƒséÒ%Ú´iS¢žööö@þY¯bddäPž>|ȸqã°µµeÁ‚ܽ{ºvíʼyóøá‡€ü@÷ôéÓL™2‡r™õÉ“'üóŸÿÄÞÞž5kÖ T*8p ¡¡¡L:MMÍr™K!„B!*ŠÆsðàAôõõñ÷÷gܸq%ª—‘‘APPÔ®]›ÈÈH*UªD³fͰ¶¶.R-Z`ggGnn.G-Ñ÷øñã÷{¹¹¹,Z´ˆúõë³bÅ 233qsscóæÍ<}ú”cÇŽñí·ßÒ¥K ËeNÈq§L™‚Ë–-###ƒfÍšqêÔ)¶nÝŠ¥¥e¹Í&„B!„››>>>( Ö¬YÃŽ;Š]#%%…û÷¾>ñññ$%%Ñ«W/¬¬¬Š½¦W¯^øúú{!ŠjñâÅ/ÜÉbkkK³fÍÊq¢›¤jÖ§O&L˜€J¥bäÈ‘ráÂÆÀäÉ“™?¾ÚúùøøÐ½{÷W>SêEGG«­oQ]»væÍ›ãííMFF­[·æèÑ£\¾|™AƒQµjÕÂgãââÊüò%•JÅñãÇéÛ·/vvv,]º”ôôt\\\Ø¿?—/_¦cÇŽe:“B!„Bˆ|ýû÷/¼9~ìØ±Eþ»mff&·nÝâúõëT®\233qvv¦iÓ¦o}x»ví€üÛÅ…( Ïž=cíÚµ/|làÀrAt)’€´üòË/téÒ…ŒŒ <<<èÛ·/YYYôêÕ‹Å‹«­ODDà‹/¾xås@~ùŸß}(m›6m¢uëÖ\½z•*Uª°lÙ2Ξ=K·nÝ^úüǨ]»v™Ì÷èÑ#ÆŒƒ‘‘ݺucß¾}äååѦMöîÝKPPòB!„B”³ иqc˜6mZ‘Þyôè …pqqÁÅťĻ96lÀ;wÔv.ªÿé·ß~#-- ccãÂ3G½¼¼Êyª›¤¥@KK‹;vàèèHll,OŸ>ÅÑё͛7«õ0ݱcÇ’““C‡hÒ¤É+Ÿ³°°@OO¥RIxx¸Úú¿JVV_}õC† !==.]ºpûöm&MšôÚ¯?** €Zµj•Úl ¬ZµŠöíÛcccêU«HNNFWW—Ñ£GsõêUΞ=KŸ>}$B!„Bˆw„®®.Ë—/G¡P°mÛ6.\¸ðÆw´´´ÈÉÉ¡^½z8::R©R¥"õR*•¯½çÃÞÞ rrrÊe§¦ø°¥¥¥±|ùrlllP*•Ô¯_ŸF•ód6 HK‰‘‘¿ÿþ{áÏwìØñÂvò’úúë¯9qâÚÚÚ|÷Ýw¯}VSS³ðÆõ[·n©m†—III¡{÷î¬\¹…BÁŒ38räH‘Îî¼}û6uêÔQëLiiilß¾>}úP³fMÆŒÙ3gP*•…s}öÙg¬ZµêµA³B!„Bˆòãî§'*•Š3f¼ñù:uêàììL•*UŠÜãÞ½{\¸pŒŒŒW>£¥¥UX3))©Èµ…(Š•+WòìÙ³ÎÇ4hP9Oõá“€´ݹs€æÍ›ãì쬖šÁÁÁ´oßž_ý p©££#£GfóæÍ/ýVÁwnܸ¡–9^&66–:àçç‡{öìaþüùE:ðZ©T@ëÖ­K>> 0333ÈþýûÉÎΦ^½zÌ™3‡°°0–,YÀõë×KÜS!„B!Déúá‡ÐÔÔÄßߟÀÀ@µÕ}úô)çÏŸ'//êÕ«¿ñòà‚€499Ym3‘““S˜÷xzzä/ê¥ëíN$EröìY€Wž¹YÏŸ?ÇÛÛ›•+W¢T*ÑÖÖ¦AƒdffFxx8áááüùçŸ@þ’ÿöíÛÓ¡C:t耛››6mÂß߿ij¼Ldd$;w&"":D‹-Šüþ7HHH@__ŸæÍ›»jj*~~~œ>ž¤¤$âââ066&11###ÜÝÝ‹ô~zz:úúúÅî-ÄËdggóÓO?0yòdvïÞ ÈåLeEÒRTp¨óÛ^:”œœÌäÉ“Y»v-–––¬X±ž333ÃÓÓOOOž6??ŸÐÐP455177§´´]]]œœœÎ­¨¨ // Q{¯¶;wòàÁŒŒŒððð`éÒ¥())ñÖ[o½è¥½”¤G÷! ÊÆÆ†ÄÄDüýýqsskбgΜaÚ´i$&&¢¤¤ÄäÉ“ùöÛoŸêÎXZZ—.]âðáÃ’’òÄ;;»Ç¦-Z´¨wÞ¬¬,úôéCXXVVV\ºt {{û¯¯sçÎܾ}»AǨ««Ó©S'\]]quu¥G8::6øÜ3fÌ`çÎÌŸ?ŸuëÖ=Õ‚ ‚ ‚ ÂóóùçŸóõ×_3|øp¼½½ëŸŸŸÏÝ»w±²²"//””,,,hݺ5 :wll,vvv(++STTÔàãáïJJJhݺ5III¬Y³†’’–-[†››þþþ/zy¯‘AÚ„:uêDbb"§NR8@š——ÇÂ… ùá‡$ ¶oßΨQ£—Íýû÷ÑÕÕÅÐÐssóZç433cìØ±Œ;¨*>}ýúu®\¹Â¹sç "&&†˜˜öîÝ €……½{÷–gdÚÙÙ=6gQQ#GŽ$,, sssΟ?ÿTÁÑŸ~úImÞ¼9ªªªTVVÊ c›ššbllŒ¹¹9NNN899Ѷm[ììì­^hu9€ê¦Z‚ ‚ ‚ ÂËmøðá|ýõ×øûû×ÛO"22’ÜÜ\ÌÌÌÈÏÏGEE…Þ½{£©©ùT玪>7‹à¨Ð¾ûî;’’’033cÖ¬YòÞ,¢9Óó#2H›ÐÉ“'â¦/Ç IDATñôôDSS???úôéSïø9sæÈkNž<™ 6<–²ŸššŠ’’¤¤¤PVVFpp0ýúõ#!!+++lmmk¬·Y›ôôtüýý¹xñ"/^$,,Œ¿ÿZ´lÙ’¾}ûÒ¿z÷îÍÂ… ùí·ßÐÕÕåâÅ‹tîܹ¯L•¨¨(ºvíJ^^‹/–×Úø;™LFhh(YYY“œœÌåË—‘$‰¬¬,:vìÈ”)Sž*@ pêÔ)F…³³3!!!O5‡ ‚ ‚ ‚ðü”——chhHAAW®\áõ×_¯ulTT¨««Ó¾}û§ŒV[¿~=óçÏgРAœ={ö™æ„´´4œœœÈÍÍeÓ¦Môë׎;¢¢¢"š MOH›Ø¨Q£8uê:::|ûí·L›6í‰àåµk×X¼x±¼Ã¼••;wîÄÃÃã‰ùnܸA^^ÙÙÙakk‹™™ÅÅŤ¦¦’šš*ï¼gii‰–––(+++¼æŒŒŒÇ¦ï_M]]3gÎпÿ¾*PZZÊ믿NPP®®®\¾|¹Æ;~•••Œ?ž#GŽÔ9Ÿ––›6mbÚ´i ^Khh(:t Y³fäçç7(¸,‚ ‚ ‚ ¼ƒ âܹslܸ‘¹sçÖ:®  eeåFk¨4aÂ:ÄçŸΪU«eNáÕ5yòd~üñGÚ¶mË;wX¶l_ý5ƒÆÏÏïE/ï•!¶Ø7±Ã‡3bÄΟ?ÏŒ3X¹r%+W®ÄØØ˜;wîpèÐ!yÖ¢ššÓ§OgåÊ•µÖ­N³ÎÏÏçáÇèëësþüy$IbÈ!hhh`nnŽL&£¤¤„¸¸8BBBhÞ¼9úúú˜™™É;ÚׯÄÄ„1cÆ0fÌ ªÙ”¿¿?ÀÇLJòòr¦OŸþTÁQ€… „¾¾>¿üòK­Û!f͚ő#GPVVÆÆÆFVVVfÒ¤ItíÚ•ƒÀôéÓ),,dÞ¼y ZK«V­PRR¢°°ôôtqwFAAဳ³3çÎãîÝ»uŽÓÑÑiÔóн{÷FWxõ²ÿ~6lØ€ššš|8JJJ8p€’’¦NŠ’’?ýô&Lª²L,XÀÆQRRâøñãOÔl­¹¹9iii\½z•×^{­Á×$‚ ‚ ‚ <_»wïfêÔ©ôêÕ‹Ë—/?—sFDDÈ;Þ§§§chhø\Î+üóÈd2zöìÉÍ›73f GåÆôèÑuuuRSS100xÑË|eˆ Ò&ÎðáÃ)--ÅÕÕ•×_k×®‘ŸŸ C‡eüøñ˜šš>qlVVFFFõž£:Àigg‡­­-]»v%66###())AWW—æÍ›Ó¦MŒiÖ¬W®\‘WQVV~¢S`` “&M",, ¨Ê.ÍÈÈ wïÞO½ÿ>'ND’$fÍšUkpT’$.\À´iÓxûí·å5F—,Y"ލ¨¨°~ýz²³³Ù·oÓ¦M£gÏž5¾¦µiÕªiiiÄÆÆŠ© ‚ ‚ Âÿ€–-[””ôÜÎY]s´k×®"8*<“Õ«WsóæM´´´X·n‡`èС"8úœ‰iJJJbèСdffÒ¾}{NŸ>­ðhii)×®]“wuwuuEWW·Þ ¤ªjÕ´:˜8hÐ d2YYY$$$ššŠ––ÙÙÙ´nÝSSSŠŠŠ¸{÷.šššòiEE«W¯æ«¯¾¢¼¼###¶mÛÆ/¿ü±cÇêm8U“ÌÌLFŒAvv6]»v•¿Ôäܹs„……¡­­ÍªU« 11}}}–.]úÄx%%%¶nÝJ@@,^¼˜={ö(¼¶V­ZqíÚ5âââ|]‚ ‚ ‚ ÂóW]---í¹³zûó°aÞÛ9…ž›7o²|ùrÖ®]KË–-‘Édò߯ڒɄ¦#¤MäÞ½{Œ9’¸¸8Z´hŸŸŸBÁÑèèhâââ°²²¢K—.èêêOqq17nÜ }ûö”••agg‡ŠŠJ½s*++cbb‚‰‰ eeeTTTÅÇ‰ŽŽ¦¬¬L~>€ØØXÞ{ï=þüóOÌž={°²²bõêÕ´iÓ¦A¯GAA£F"** Nž£ÔÔTBCC¹{÷®ü+88˜‚‚ôõõ9{ö,VVV ÍgllŒ–– $''“™™‰«««¼ë{rr2&&&øùùqãÆ ´µµ±±±ÁÒÒKKËzçWWWG]]—ÇOLL`ÿþýÌš5‹‚‚´´´øúë¯ùøãåÝ«ÇY[[+ü1räHÐÓÓÃÛÛ»Þµ^¹rwwwyfgÛ¶më|€#F4zc1¡~"@ÚpõêU¹s絎WUUeß¾}½qPZZŠ‘‘2™ eeåÇŽÑÓÓCOOï±b`` èêê’””Dvv6NNN´hÑ‚‡RVVFhh(/^ÄÐÐ;;;,--ôJEENŸ> Tejîß¿‡ÇÆåååU_EdggãééÉŸþ‰¶¶6'Ož|"8[“èèhÚµkü7pYȬË矎ŸŸGeݺu Ž›7oü÷úAAA„—[u‰9¨*×Ô~þùg&NœØäçþ™¾ùæ~þùg”••Ù·o&&&@Õïï±cDZ½þEÒ:Èd2®_¿Ž··7ÞÞÞ×8ÎÊÊ [[[¢¢¢äSOOO~øáù/{ee%***¤¦¦OAAjjj¸¹¹!“ÉÐÕÕ­u]»v•ß½{w’““INN&,,ŒîÝ»#“ɰ··§sçΔ——“@FF¦¦¦¢¡¡AëÖ­»»ö(///fΜIff&ªªªÌŸ?Ÿ+VÔ8ÞÄÄ„„„233ë}ý"""ðôô$<<œæÍ›sòäI…j—J’DNNŽü|€üŽŠ$Iõß§O:tè@HHûöícÉ’%õSíïkAAAáå$“ÉäßWfl*ׯ_'<<uuuÞyç&=—ðÏtôèQ/^ À²eË4hü¹?þøƒôôttuuE}ÛDHk‘‘Áž={عs'111=×¢E ^ýuzôè‹‹ íÛ·gïÞ½üûßÿ¦¬¬ }}}Ö¬YÃôéÓåÇÈd2¼½½QWWÇÁÁ'''´´´(--åþýûdddP\\L=(**¢ÖÚ)úúúèëëãè航ª*YYYÄÆÆRYYÉ­[·ÐÐРmÛ¶˜˜˜PYY‰L ‘tuu0`€¼ÑSnn.sæÌáÀ@Õöõ<ý;kkk¸uënnnµŽ;~ü8ï¿ÿ>¹¹¹˜››ãëëKçÎzý+++åßW,«ÈŠnŸ2e Ÿ|ò ^^^ H«ï6>zRAAAxyåççË¿oÌ-ÉO|6üᇀªæLÕ=,AQ~~~¼ûî»Èd2ÆÇ_|ñØóÕÝëßxã:ûµMGDƒ‘••Å—_~ÉÎ;)--@KK‹2räH<<<«½y÷î]<<< `È!ìÚµë‰úœÊÊÊ <˜üü|âââ ÃÕÕ•ˆˆLLLèÙ³'êêêÄÅÅC`` FFFcllŒ¹¹ùoÎÕÿmdd$sîÑ£aaa˜™™qæÌttt000Ï¡¦¦&Žž?žÉ“'’’sæÌaõêÕµ6@ª6vìXزe ï½÷Þ[Þ‹‹‹Y¼x1[¶lA’$ºté‚——-[¶Tøç ªªŠ¾¾>999¤§§ckk+ïNX]µ>o¼ñŸ~ú)AAAÄÇÇckk[çøê­õM]Ô[AAAhÕR 444žzI’(--åÁƒdgg£©©ùX‚OJJ ?ýô~øá³-Zxåøúú2fÌJKKñððx¬î(@ii)ÇÙÉ/ØOLÕÝ¡õë×ãààÀ–-[(--¥]»vlÞ¼™””N:ÅôéÓåO™LƦM›èÚµ+èêê²cÇNŸ>]kó"---LMMéÞ½;£FBCC 444ˆåĉѺuk À믿TÕâôññÁÇLJ˜˜Š‹‹ë¼–víÚѼysÞ~ûmÜÜÜ022B’$ ±³³£¤¤„O?ý”Aƒ gÏžeÓ¦MõG&Mš„¹¹9QQQôîÝ›ß~ûÂÂB ªVjçÎÙ¼y3³gÏæêÕ« ŽV³±± !!@^ 5**J¡ã[´hA§N$‰S§NÕ;¾zÞÖ­[7x­‚ ‚ ‚ Â󗜜 O¨iˆòòrŠ‹‹IMMå÷ß'%%…ÊÊJlmmŸØý¸iÓ&JKKqqqaðàÁ²váÕ°wï^FMII îîîxyyÉתùúú’››‹±±±¼Qµðü½ò¤©©©Œ7ŽK—.àääÄÚµk5jTãcbb˜|ˆ$I˜™™±gÏ<<<ôš<ÊÚÚšy€´}ûö„……QRR¢PÊùˆ#¸uë¾¾¾Ìš5«Öq•••ܸq¨úù ‚ ‚ ‚ /¿U 2ŠÊÊÊ¢  €ˆˆÔÔÔpqqÁÁÁeeeÒÓÓyøð!:::òÝ’ùùùìØ±€Ï>û¬Ék ÿ ååå,^¼˜õë×ðæ›oòÓO?Õ˨î^?f̘Z{ÇMï•Î ½té;wæÒ¥Khii±iÓ&BBBj ŽJ’ÄÎ;qqqÁßß---V¯^¿¿£dѪU+FŒµµ5;vDMM¤¤$¸zõ*NNNèëëÓ»woôõõÉÈÈàæÍ›\¼x±Î¹+++ùöÛoéÙ³'wïÞÅÐÐÇóóÏ?×MIIá‹/¾`åÊ•5Î×¹sg"""øøã177§¼¼œ¬¬,$I¢[·n?Spþ›ÉTeÆêééQVVFPPBsT¯áÂ… ufÞΛ7ÄÄDš5kÆÀŸiÝ‚ ‚ ‚ Âó Ô ÍÏÏ'((ˆK—.––­ZµB]]øøxÐÕÕ¥G¸¹¹=VJnÇŽäääТE ÆŽÛ¤×#ü3ÄÅÅÑ·o_ypô“O>áÈ‘#5îÚ-,,ÄÛÛÝë_´W6ƒôСC¼ÿþû”••áààÀ‘#GèØ±ccãââ˜2e çÏŸ gÏžüøãMšmhnn޹¹9ŽŽŽH’Dff&“™™I·nÝ044¤¨¨ˆ6mÚÔ:OTT“&M" ¨ª“ºgÏ,--Ÿ›——Ç7ß|ƒ¿¿? ,`èСµÎkbb¦M›Ø´i‘‘‘ôë×äädV®\‰©©é3_Ïž=Ù²e W¯^ªê¸vïÞsçÎqíÚ5y ‚º¸ººbjjJzz:.\x"h[YYÉüùóùî»ï€ªÒ ’$=óÚAAA„¦ üwÇaµòòrrss‰‰‰¡  ;;;´µµÑÒÒ"77—;wî §§‡¥¥%¶¶¶òæÀWVVƦM›€ª —hê+ÔE&“±k×.,X@~~>ZZZlÙ²…>ø ÖcNœ8Aaa!u6šÞ+™AºiÓ&Þ}÷]ÊÊÊðððàæÍ›µG÷ïßO‡8þ‡‡¦¦¦¤¦¦*TûåСCL˜0–-[Ê·_;vŒ¹sç’˜˜ˆ––;wîäÁƒ|ñÅtêÔ‰[·n5ÊúAAA„¦‘’’"OþIMM}¢QÓ©S§Ð××GOO{{ûZ{wÔ&//Ö­[“‘‘Áºuë˜?~£­]øç¸rå +V¬ÀÏÏ¨Š }ùå—Ì›7¯ÞŒãœœÌÍÍ)--% @ž&¼¯L~xee%3fÌ`÷îÝ,\¸5kÖPTT„ŸŸ—/_&22’„„>|HLLŒ|»µšš¡¡¡ 4H¡s)))¡¯¯‰‰ fffXYYannŽ¥¥%-Z´ÀÑÑGGG´µµý:½¼¼˜9s&™™™¨©©±téR>ÿüó'þaJ’ÄøþûïY½z5ýúõ{êsVVVÊÅÍ›7–å?fÀ€üüóÏœ={–áÇӧO444HOOçöíÛOt¬ÉСCQUUåÁƒ¬Y³ooo._¾ €½½=^^^tìØ‘ôôtV®\ÉíÛ·¹|ù2½{÷n´ëAAAWu ¼6mÚÔØÅ¾_¿~Ïôùtݺuddd`eeÅG}ôÔóÿ<ÅÅÅ=z”Í›7ó×_U;X'NœÈW_}…­­­BóüöÛo”––ÒªU+zôèÑ”KðJH‹‹‹?~<'Nœ@II‰Õ«WÓ¡CÞ~ûm¼½½)--­óøòòòZŸkÖ¬’$É„P|ÌÎÎ&;;›ˆˆˆZµ±±ÁÁÁgggºtéB—.]hÛ¶íSÕ5ÉÍÍåã?fÿþý@Õ‰Э[·'ÆFGG3{öl:vìÈ¥K—ÐÐÐPèyyy|ûí·ò Üjò`rcH‡ ÂÏ?ÿ,¿Ó¬Y3^ýu.\¸€ŸŸŸBRLLLHIIañâÅhjj2oÞ<–,Y"Ϙ555eìØ±8p€-[¶ˆ© ‚ ‚ ÂKìÂ… ôïß¿ÆçŸå³ijj*6l`ÕªU/|—è?…L&c„ (++ãâ₳³3:t¨·ÉÖË ¸¸˜óçÏóË/¿pâÄ òóóPUUe̘1,]º´Á»iùåÞyç…vÈ Më¿Å>''‡Q£FñçŸЫW/ÒÓÓ‰ŒŒ”133cðàÁ´oßž-Z°uëV._¾Ìˆ#˜?>†††b``PgZ~NNÅÅÅ‘““CZZiii$&&’žžNbb"111DFFÖÚU]KK‹:гgOúôéCïÞ½k¼ö¨‹/òþû’³gÏfÍš5O¼‰K’Ä÷ß——ß}÷íÚµSôe$**Љ'òùçŸ3räÈÇžKLLÄÆÆ¨*b­híÒú¤¥¥aaa$IÄÄÄЪU+Ö¬YÃâÅ‹éß¿¿üŽa}:wîÌíÛ·QSSã“O>aÖ¬Y5Þѹqã=zô@UU•¨¨¨ÿ‰7iAAA„WL&ÃÚÚš””¼¼¼xóÍ7uþ>úˆmÛ¶Ñ¡Cnݺ%jC6’-[¶ðñÇ?ñ¸žžÎÎδoßZ·n-ÿ_Eº[aa!·nÝâêÕ«üþûï\¾|™’’ùóæææ¼ÿþûÌš5 kkëÏŸžžŽ••ܾ}»Ö¾8Âóó&''3tèPBBBžxNGG‡qãÆ1eÊzöìùX´~É’%¬^½š©S§òÃ?4úº$I"!!ˆˆ"""¸}û6AAA„„„PVVöÄx'''ÜÜÜpwwÇÝÝ###JJJø×¿þÅÆå öìÙSc)€ŒŒ ¦OŸŽ““+V¬hPÓÏÏeË–ñã?Ò¦M›'ž¿wïíÚµCUU•ƒÒ®];¬­­ÑÓÓkÀ«R³®]»ĶmÛ˜9s¦|k½ºº: ÕL]·n .DII‰¬¬, jwõêUúôéCee%Æ {¢±“ ‚ ‚ ‚ðâ]½z•^½z¡¥¥EFFFƒë‹Ö%""gggÊËËåý0„g³³3ùùùŒ=šÊÊJBBBxðàA­Ç(++cccCË–-±±±ÁÒÒ+++¬­­±°°ÀØØXžÌVW³­Úäçç“™™)Of‹‰‰!**Š;wî.oF]ÍÈȈQ£F1~üx ðLóï¿ÿžY³fѶm[žz¡ñüc·ØÇÄÄ0dÈ¢¢¢{ÜÄÄ„>úˆ?þCCí~üáÇM²6%%%lmm±µµÅÝÝ]þxyy9¡¡¡rùòe._¾Ltt4÷ïßçþýûìÚµ ºuëF·nÝðóó“_ßøñãÙºukÁ¿ßÿÿû߬]»777…×)“ÉX»v-7nÜà÷߯u‹Bu&gEEcÇŽ•?®¡¡©©)vvvtìØ‘víÚaoo¶¶¶õ–ÈÊÊÂÆÆ†   |||˜9s&;vÄÊÊŠ¤¤$Î;§Ð™3g²hÑ"$IbÇŽò­öZ·nŸ}ö2™ €ðððzçAAAž¿£GUeÙ38 0wî\ÊËËéׯŸŽ6¢™3g’ŸŸO×®]9räˆ<——ÇÝ»w !<<œÈÈH"##‰¥¬¬Œ¸¸8âââê___444俚ššhiiQXX(OFËÏϧ  €ÌÌÌÔþ>g÷îÝéß¿?ƒ ¢K—.õb°´´¬7xZ½½~ܸqõ^›ð|ü#3Hoß¾ÍàÁƒÉÈÈ?æèèȧŸ~Ê{g¦¦fÇïÞ½›©S§Ò¯_?y]“%99™?ÿü“‹/âçç'ïÄ^ÍÀÀ€ï¿ÿ¾ÆT%%%,_¾œ°mÛ¶Z3'k’˜˜È´iÓèׯ .¬óM ((ˆ®]»*~Q€ŠŠ FFFXZZbiiùصôôtRRRˆŽŽ–ß±ÑÔÔ$//555¦M›Æ®]»˜2eмéV}Z¶lI\\...ܹsGþ¸$I¼ýöÛxyyUAÝÊÊJ*** ip AAA¡é”••ammMFF‡jÔÓ‰'=z4ªªªâââÒhs¿Ê~úé'&Nœˆªª*7oÞ¤S§NõSYYI\\QQQÄÅÅ‘””Dbb")))ÄÇÇ“––FVV–<ÉéY˜ššÊ“¹ìììhß¾=]»vÅÞÞ¾ÁµA½¼¼4hP»]iÑ¢2™Œððpœœœžõ„FðÌ ]½z5())1pà@æÍ›Ç°aÃN¹®)ƒ4--ÊÊJ,--ŸjMò»!)))äç磩©‰™™mÚ´ÁÅÅ¥ÆõYZZòÎ;ïðÎ;ïUéþ§OŸfÞ¼yøøøðÚk¯=q\xx8S§NeöìÙ¬^½ºAkõòòbýúõlÞ¼Y¡À§£££üûû÷ŸÏµk׸yó&¡¡¡DDDÈ W«¬¬$==]Þ‘¾6NNNÄÆÆRRRB`` ={ödøðáìÚµ oood2™B?WOOO6oÞÌÝ»wåǤ¥¥Ñ­[7°µµåæÍ›Lš4 ???~ýõW AAAx‰?~œŒŒ ŒŒŒ=zt£Í[ZZÊÂ… øðÃEp´‘dddðÉ'Ÿ°páB…‚£P•TU°¬KNNÙÙÙ<|øììlJKKåM´KJJ(nÂë IDAT..FGGG^fPGGŒŒŒä_OÓ(»&©©©˜˜˜Ô›”wøðad2;wÁÑ—È?2@ºdÉZ·n͸qãž*ÀUS€444”;v””„¾¾>:t×¾077G]]]>¶¢¢‚ØØXÂÃùÿ>ÉÉÉ())ѦMÚ¶m‹‰‰ -Z´ ¨¨ˆÌÌLvîÜÉ­[·èÞ½;óæÍ«ó ÀÑÑGGG–,YBqqqÛÞO:źuëØ·oööö _wff&Ÿ~ú)ÚÚÚüþûïhkk+t\õLAA………tíÚõ‰ÀjJJ ¡¡¡„„„B`` ‘‘‘9~”ššŽŽŽtéÒ…ÊÊJ¢¢¢8wî={ödРAhjj’žžNPPݺu«w ,`óæÍTVVâåå…¡¡!#FŒŸذax{{£¬¬ÌرcñóóãðáÃ|õÕW ½‚ ‚ ‚ BÓûþûï˜8qb½¨†X»v-‘‘‘˜˜˜ðå—_6Ú¼¯º¹sç’™™‰££#_|ñE£Ï¯¯¯¾¾>­Zµjô¹*88˜6mÚpùòeÚ´iSk‚]õöúñãÇ?Ïå õøGn±V!!!¸¸¸ ­­MaaáÏçääp÷î]’’’HNN&11‘üü|tuuQQQ‘×urrÂÉÉ +++…Î{éÒ%V­ZEÇŽùâ‹/êLÉ666&++‹7nн{wùã»wïæìÙ³ìÝ»Wá'À‘#GX¿~=Ë—/gÈ! WÍÑÑ‘ÈÈH|||ðððPè™LFll,!!!òàiuÆiEEÅã[´h!/àJMMƒ*ÜM-**йsçÒºukÎ;÷Ô®-,,ˆŒŒ$99Yác”••±··ÇÞÞþ±­eeeÜ»wÐÐPBCCñõõ%88˜„„*++QQQaøðáœ={…¤ àèÑ£$%%ЬY3yVê£ôõõqwwÇ××—_ýUHAAá@ff&þþþ 6LþyIøgY³f o¼ñF£G>þøc éÞ½;“'On´y_eùùù̘1€3fü£ƒ£PUæp̘1„‡‡×¹eÿàÁƒH’D¯^½Dpô%#2HkPRR"ÿƒš””Ô º£™™™òÚšfA6kÖ sssÌÌÌ”ÙY'''"""ðõõeذa >>77—•+W̆ h×®Ý3­gܸqò-é6Ÿ––†¹¹9Põf2~üxbbb°··GYY™¤¤$ùóuùóÏ?éÓ§PÕ´éÖ­[èëë×8öÇdòäÉ888Ñx#‚ ‚ B“˜2e {÷îÅÖÖ–U«V1aÂ…ûP/¿[·nÑ­[7d2ׯ_ÇÕÕµQæ=vìcÆŒAEE…€€€Çvh OoöìÙlݺ+++îÞ½‹žžÞ‹^R“),,$ €:PVV†™™Ùce«Éd2œœœˆŠŠbóæÍÌ™3ç¬V¨økQMMMy€ôÑ:¤5‰eÑ¢E <˜Þ½{3uêT¶lÙÂÅ‹ ”yyy±|ùrÞ|óMÜÜÜpwwgæÌ™ìܹ“   ÊËË´Æê kqqqƒŽ“Édìß¿www:tèÀ™3g-,,dòäÉÕ­"7$ƒTQfffUK;;;Ú´iƒL&ãôéÓ Íãææ&/Ìܯ_¿Zƒ££GF]]ÈÈHnݺõl ‚ ‚ B“«ÞEÏĉquuåÂ… /xUBcY¼x12™ OOÏF ŽæææòñÇ0gÎm$×®]cÛ¶m|÷ÝwÿsÁѸ¸¸ÅZ$Iz,&RSpàÌ™3DEE¡­­Íÿýßÿ5ÊZ…Æ#¶Ø×ÂÐФ¤¤z¤ÚÚÚxzz²lÙ²mO/++#""‚ÀÀ@öìÙCpp0šššôîÝ›¾}ûÒ£G: N׶ž.ååå 0OOO®\¹Rë?ÚºdggóÖ[oñÑGÉ×—ŸŸÏÕ«Wؾ};>>>´k׎víÚÉSµk×##£Ÿ¯Úk¯½†¯¯/ׯ_—?6|øpÂÃÃñññQxD—.]¸~ý:¿ÿþ{ãôõõùä @ll,æææ¬_¿^¾ÞÐÐÉ“'ãîî.¿†ÌÌL.]ºÄŽ;øä“O2d-Z´@SS“öíÛ3vìX–/_Α#G |l uM¨JÑèÝ»7úúúäååqùòe…®cÚ´i())!I;vì¨s¬§§'ÄÆÆrûöí¿f‚ ‚ ‚ I’˜0aÂSõõžÌÚµkX¿~=fff [PPÀ?þÈ… ÈÌÌlÔu†L&«wlvv6ñññVïø¬¬,ÌÍÍñóó«sþM›6!“ÉèÓ§... Z¿ð|ˆ-öµP4ƒÀÕÕ•K—.Uw"""ˆˆˆà×_åþýûäææÊ‹ƒannމ‰ æææLž< ç­k‹ýÓÖ }{÷îåàÁƒœœ£GâííÍ·ß~«Ðu 2„]»v\ïXOOOy€tùòå Í/‚ ‚ Âógmm TmÓMKK“7Mpww'00Ý»w³|ùrRSSY¼x1Û¶mã‹/¾à½÷ÞCUU|<~™”””ðÞ{ïQVVÆ Aƒî;QŸ¾ùæ *ËÑÄĤQæ}Õmܸ‘›7o¢­­-oФ¨’’RRRä[Õ¥p££ÔÔTTUUŠ¿Üºu‹Ž;Ôº£·ZII C‡%<<œ:Ô:nÆ Ó®];FŽ©Ðš…@j´hÑ" fΜù¢—R£>úH¤ùóç7úÜÒ®]»¤×^{MúóÏ?%I’¤©K—. Ò°aäÄÄÄZç– $@=z´$“É´†ÒÒR)44T:r䈴bÅ iܸq’‹‹‹üü!!!’$IRZZ𤬬,RDD„Bs‡……Éç¹xñbc“’’$%%% bbbt ‚ ‚ ‚ <_††† ]»v­Ö1………Òš5k$###ùçiûöíRaaás\­P—©S§J€ddd$%%%5Êœ’«««Hƒn”9IŠ•ttt$@Ú¸qcƒ÷óó“Nœ8!………I’$IW®\‘|}}¥òòòÇß¼ySºÿ¾Âóïß¿_¡˜D~~¾ôðáC)++KÚ¿¿”››[çø3gÎHYYYÒ‘#G¤²²²ÇäääHzzz ŒŠŠ Çgýúõ Z‹ºº:íÛ·ç­·ÞbéÒ¥:tˆ;wîлwoNŸ> €©©)ݺuÀ××W¡¹Û¶m+oªµuëÖ:ÇZZZÊç÷öönÐ5‚ ‚ ‚ð|=Z‡´6ÚÚÚ,Z´ˆ˜˜–/_Žžž‘‘‘Ìœ9kkk-ZăžÓŠ…šìÚµ‹]»v¡¤¤Ä®]»Ë~[¶láÆ4kÖŒíÛ·7Êœ¯:I’˜:u*ôèуٳg7xŽ’’¬¬¬ppp—ä300—*ü»û÷ïãèè¨ÐÜ)))X[[+”=êççGZZ………Ë·ïפ¨¨%%%ŠŠŠ°··GMM­Æqëׯ'77{{ûÇvß / ­ECj¾M±Å~Ù²eTTTpæÌ–.]ʃèÕ«K—.¥¬¬ www‚ƒƒyÿý÷šoРA¬\¹€Å‹ãïïÿÌk:t(gΜ‘?VÝ;º €"ºwïÀÅ‹ëëéé À‰'ž_AA„ç¯z»´"M^tuuY¶l111¬X±KKK²³³ùæ›ohݺ5o¾ù&'Nœ ´´´©—-<" @d[´h£Gn”y”~ª¤™AºaÃ>üðCtttذa]ºt‘ß]Ûºu+gÏžÅÖÖ¶As~öÙg¼ñÆTTT0iÒ$òòòžiÕÝ/_¾L~~>ðßé¥K—äÕ§º`tFFéééuŽ­úûû7¸&­ ‚ ‚ Ïžž¹¹¹ chh(O9xð ={ö¤²²’ß~ûÑ£GcnnΤI“8tèP£w×wÿþ}FEii)ƒ bÕªUÏ@&“ñý÷ß×Ù€ÉÙÙ"##9}ú4&Lxêõ ‚ ‚ ‚Ðtôõõ†H«©©©1~üxÆÏÍ›7ùá‡8vìYYY8p€ ¬¬Œ³³3Ý»w§{÷î´oßžÖ­[cnn®ðyòòòˆŠŠ"**ŠøøxzõêÅk¯½ÖàõþÓ$%%1tèP233éС¿þúk½wÅÅÅÄÇÇ“””Dbb" $%%‘@bb"IIIdddÈÇ«ªªòÃ?ˆL¾F2{öl²³³iÓ¦ ‹/nбÑÑÑ\¼x;;;:wîŒŠŠ 7oÞ$''§Ör~÷îÝ£mÛ¶ ŸãܹsLš4I¡±wîÜ¡U«Vœ8qsssÔÕÕk›——GQQyyyµÆJbccÙµk_ýµøû ¤µ¨)@êêꊫ«kƒæ©¨¨h’nˆÕÒÆÚb/I;wîdÁ‚ ©©ÉŠ+øôÓOk­û¡(}}}vî܉‡‡{÷îÅÓÓSž•ÙPJJJ <˜}ûöqæÌ<==QRRbذaìÞ½…¤ªªª´jÕŠèèh¼¼¼êíP?bÄ6lØÀ‰'D€TAA^RÕ¤999Ï4OutëÖ­œ;woooüüüˆŽŽ&88˜àà`vïÞ-¯­­……úúú ªªJEE…üùÜÜ\233ÉÊÊzbWƒƒÏ´ÞÿuIII 0€`ccÃéÓ§QSSãÞ½{$%%‘””D\\œüûê ¨¢%ñTTT°°°`þüùtêÔ©‰¯æÕðÛo¿áåå…²²2{öìASS³AÇWVVbii‰µµ5¥¥¥Èd2ÆŽKAAA­7‚‚‚î\ß 2 ááḸ¸Ð²eKtttê›™™É!Cøõ×_yûí·kóé§ŸRVV†››#FŒPx‹#¤µ¨æççS^^^kÁÝú4Epw‹}jj*Ó§OçÔ©S¸¸¸°ÿþÕõ¨ÏСC™1cÛ·oçÃ?¤_¿~òÿóò4sí۷ﱚ£Ã‡g÷îÝøúú"I’B)ô#GŽdãÆ„‡‡×;ÖÓÓ“ 6àëëKii)OµvAAAšNcï´SSScذaòR_ÑÑÑ\»v7nHDD­ð¼:::XZZABBB£¬õUrr2ýû÷'22¨JrvvV8È­ªªŠ……¶¶¶XYYaeeõÄ÷æææMöÙüU”““#¯;{öì§Ê€NHHàþýû¸¹¹QYYÉþýûiÛ¶-=zô¨q|tt4ööö ÏáÂyi½úDDD`bbBQQ–––u6KHH ¸¸˜ÔÔTÜÝÝkÌ =}ú4ÇGYY™o¿ýVá5 /–x‡¨…±±1JJJH’Ĉ#ضmvvv/zYrõ‡ÿÈ‘#Ìœ9“‡¢ªªÊüùóùꫯêL'Zk×®ÅÛÛ›ÄÄD¾üòËw¶¯6dÈTTTHHH§Ø4 RRR¸uë]ºt©wžO>ù„7RQQÁ‰'êÌjíÝ»7FFFdeeqñâE† òTkAA¡éTŽiªþöööØÛÛ?–Å–››KLL äääÈû<š´¡««‹‘‘ÆÆÆXXX`nnNff&&&&”””““#/ðªÙ¸q£<8 7ØRWW—gÚØØ`eeõØ÷666˜››?ó®G¡a.\Hrr2¶¶¶òÆÌ ÁÀéÛ·/•••DFFb``PçÙ€€Þ}÷]…æ‹‹ÃÁÁA¡±’$‘€™™QQQ¤§§× ½qã½{÷毿þª±”bii)óæÍ`Ú´iòÑÂËOHk¡­­Íš5kø×¿þÅÙ³giÓ¦ S¦LaÑ¢E/E ôY¤ééé|øá‡;v €öíÛ³oß>ºví TÝÅKLLÄÅÅ…°°0:uêôÌtš7oΆ xûí·Ù¼y3'N¤sçÎ žÇÀÀWWW8sæ mÛ¶EGG777Î;‡BR[[[ôôôÈÍÍeçÎuHUTT>|8û÷ïÇÇÇGHAAá%T½óïy6ÐÕÓÓ{ªÏ5FFF¨««SVVFZZÚ+ ûì3åÁQKKKJJJHJJBUU•ÀÀ@JKKŸyÝo½õÆ £²²’Ù³g#IÒSÍ3tèP *u½Zu7ûG·Þ×çõ×_àêÕ« ŸóÌ™3 Ï/‚ ‚ ÂóSAZWê—…’’’¼ûujjê ^͋Ӷm[¶oßΚ5k˜3gžžžtïÞ }É3}út$IbâĉòÏÈ 9þüùó888Ȱºv튱±qÐß~ûMáÚ±QQQ´nÝZá5™››Ó®];233ÑÐШµþ©$I`eeÅÝ»wklÂþó ª1“‘‘‘Âë^<%éi#T¯___þóŸÿpåÊùcÍš5ÃÃÃ!C†0hÐ lmmŸÛznÞ¼‰««+†††dee)tLvv6³gÏæàÁƒ@U1ð}ûöÕY/äÌ™3ØØØ““ƒ³³óS× }Ttt4íÛ·§´´”Ç3vìØÏQ}ýdff¢££Ctt4­[·FYY™äädÌÌÌêçøñãò¦Nqqquþ >|ˆ©©)•••DEE5¨þ‰ ‚ ‚ MoÓ¦MÌ›7‘#GròäɽœzuëÖÀÀÀ§þ\$ÏÓ¢E‹øæ›o066&,,LàWÔ­[·äŸÕ»uëÆýû÷IHHÀÍÍ­Î>RXXˆ²²2’$!I2™ 555ÔÕÕ)))A’$JJJnäpýúuœœœHHH ¬¬ì±Ä±GI’DHHùùù”””àææöXiÂŠŠ ^{í5þúë/ú÷ïÏü!üÿcD©‚<<<¸|ù2wîÜaΜ9˜™™QXXÈ‘#G˜:u*-Z´ M›6Ì™3‡'N(´|Z Ýbïç燋‹ DII‰éÓ§To1å~ýú¡££C«V­ %%åÿٻ﨨®îáãßah"½)"¢€(Ø# Æ‚{ï-M‰AÓML3&Q)jŒÆ–" KcCA±Wº¢€ ("½Ü÷Þ™H¤Ì FŸÇóY˵’;çœ{—Àì»ÏÞ©½w'''Þzë-.\X¯ÌÔÎ;ceeEII ¡¡¡ªu©¨¨P;ËsäÈ‘ªbÝ«V­ªu¬™™]ºtD© ‚ ‚ <‹”GëëÛd÷ߦLêHKK{Ê;„ÚEDD°råJV¯^­qp &&†ŒŒ <<<§¸¸˜3gÎÔ°´´Ä××—1cÆ0jÔ(F͘1c7n#GŽdðàÁªkšG322¸{÷.†††äææbeeUãX™L†‡‡žžžØÛÛ?Ò·åË/¿äâÅ‹²qãFý/$¤òððàûï¿çÎ;;vŒwß}d2qqqüðÃŒ9KKKÚ¶mËìÙ³ùé§Ÿ¸råJƒîC -))¡¢¢¢ÆqyyyÌœ9“Aƒ‘’’‚ƒƒÁÁÁ¬_¿##£:¯¾¾>qqq8;;Õ û_´hæææÜ¼y“Õ«Wk<_KK‹Uƒ•õ9fïââ@```cÅ1{AAAxv© ­í3Ô¿IYwTÝŽí‚ð4( ^zé%ÊÊÊ:t('NÔxõë×àè舮®. \¿~aÆallÜÐ[VKyy97æÖ­[”””`oo_ç¹\޳³s•kçÏŸWÕxÿì¼ IDATýæ›oÄiÓÿR"@ZOr¹œ>}úðÍ7ßÁÝ»wÙ²e Ó§OÇÎÎI’ˆeÆ ¼öÚktêÔ‰-ZàççÇþýû)((x¬û+‹K’TcÒ<<<Ø´i’$1uêT"##«í´Veú{bb"]»veÏž=½>ùä¾úê+rrr4^C¬ü믿T×”ÒC‡©]˜}ôèÑ@åÑÿòòrµîÒ 5YAAAh8êH/_¾Lddd½>‡4$e`(//ï©îCjóõ×_ޱ±1k×®­×ØØØàîîÎÝ»wUÇåÝÜÜ4Z§!°ÅÇÇãââBlll½ƒšÙÙÙLœ8‘²²2|}}™={vƒíOøw‰i(,,äüùóœ>>,_¾œ+W®hܬH™A 6j*,,dÞ¼yøøø””„©©)¿ýöS¦LA¡Phþ©ì@ߨQ#®]»F›6m®×:›3gŽŽŽdeeñý÷ßk<àÀhiiqóæM®_¿À‹/¾H“&MÈÍÍåäÉ“j­3oÞ< ò)²²>kMºv특¹9„……i¼gAAAžes¦Ú¤)))Èd2LMMINNæÊ•+ÄÄÄ<•e‡§¨„š\¿~%K–°lÙ2µ²,ÿéÊ•+˜™™Ñ¯_?ÌÌÌÈÍÍE[[[[ÛGŽª×e×®]äææj¼‡*(( !!]]]JKKÕêaRW_}•›7obmmÍ/¿ü"ŽÖÿÒzÊÍÍeóæÍŒ1KKKFŒÁúõë‰G&“Ñ®];Þxã ~ýõWbbbT¦S§NÅÚÚšÒÒRŽ;ÆÂ… éÔ©¶¶¶L›6­[·ªUæáéÃuHÏž=KÇŽùþûï‘$‰I“&†­­-;w&$$¤Þ=<<(,,¤¼¼Ξ=[¯u”tttøàƒX¹r¥Æßä,,,© ª££ƒ þ1{sss,,,øå—_j+—Ëéß¿•{ ‚ ‚ ‚ðlP~¦¨­¹¬¥¥%vvv$''£¥¥…¶¶6ÚÚÚDFF¡jÄòohܸq•} ³D’$fΜIQQÞÞÞõÊŽLNN&""‚ŒŒ  wîÜáþýûÓ£GÖŠˆˆÀÑÑ‘ÒÒÒÇ:ÕZQQÁ… prrâÁƒèèè ¯¯¯ñ:+V¬`÷îÝÈår°±±©÷ž„§OH5 P(Ø·o&LÀÆÆ†—^z‰}ûöQXXˆ¥¥%/¿ü2Û¶m#55•¨¨(Ö¬YÃŒ3pssÃÖÖ–©S§²eËRSS¹|ù2K—.¥OŸ>èêê’––ÆÖ­[™6m¶¶¶têÔ‰>ø Æ€¦¶¶¶ê©haa!%%%|ðÁx{{sýúu,,,عs'Û¶m£mÛ¶ØÛÛSTT„——W¯^­w&©ººº4jÔˆòòr®]»öX_Ó3fàààÀƒøá‡4ž¯<ò~àÀÕµúÔ!íÝ»7.\Pûž"@*‚ ‚ Ïe&fmR===lmmñöö¦M›6˜šš’ššJYYèëëÎÍ›7¹zõªÆ§ý4¡ìå—_櫯¾âöíÛ¬Y³†… ª=WY433“'Nàëë‹••:uââÅ‹8p€·Þz«Îuzö쩪=²zõjU‡½êØØØÐ±cG._¾ÌÁƒ™5k–ÚûAAáÉQvƒ¯-ƒ´&tìØ¨L ILLäÁƒèêêVI9}ú4iii( ´µµ‘ÉdªÏ‹ºººèëëcbb‚L&ãîÝ»dggsëÖ-Þxã*÷TMë{ÂOž”9s懇ÿùÏ4ž_RRBJJ ±±± 4ˆÒÒRöíÛ‡•••*ö¡®´´4bbbxá…())©Wãaqqq´jÕ ;;;kß¿ŸáÇ“MÇŽñ÷÷ÁÑÿ"@úìÙ³‡¯¿þšsçΩ®wëÖÙ³g3a„*õ?Gqqqµu.™={6³gÏF¡PpöìYUvéÅ‹¹yóf•žB¡`À€üôÓO4kÖ¬ÆûÉårììì¦sçÎDFFbll\뜚4nÜ777rssqww'##£Þu;ôôôX°`sçÎå»ï¾ã­·ÞÂÐÐP­¹Êš ¿ÿþ;P2d/^dÿþýjHÜÝݹté’ZGçÈåË— RAAAxFÜ»w Þ W”5jDÛ¶m)++£°°…B¹¹9©©©Œ3Fã5wíÚõÈ5¹\ðXÇ…¡¡°oß>är9›6mªµéYMHHH mÛ¶X[[süøq:w‡‡ÆëÒ¥K’““144¬WÜA©´´”ŒŒ ^xá8€———Úsóóó2dׯ_ÇÆÆ†?ÿüSíØ…ðìaîÿO’$vïÞM‡;v,çÎC[[›I“&qéÒ%Ξ=ËË/¿Ü`ÁѤ¤$Ž?ν{÷çâŋՎÓÖÖÆÛÛ›%K–pîÜ9ÒÓÓùý÷ßyå•W000@&“±dÉ<¨V SWW—îÝ»súôiºuëÆÙ³g¹ÿ~½ÞCóæÍiܸ1 sêÔ©z?ù|õÕWiÚ´)¬]»V£¹ƒ ªÖUÖ! U»Àúĉ¸}û6EEEµŽíÛ·/ÇŽ«ò´XAA„§GYMyDþqéèèФIUp´¡ikWæ,‰ RáYñàÁæÍ›ÀüùóéÚµ«FóËËË)**"88˜¼¼<ºwïNJJ qqqܾ}[ã‡7oÞ$>>ž&Mš™™I›6m4šÿOwïÞEGG‡ììlJJJÔÎ6/++cܸqœ?cccöïßÿX¥…gRÙ̧S§NŒ3†¨¨( ˜?>ñññlÛ¶N:UùòeΜ9C~~>œ={Vu”C]-Z´ÀÕÕ• .вeKJJJ «Ò‘¾:æææL˜0Ÿ~ú‰‚‚ ùè£4:êojjJÇŽÉÍÍÅ××—+W®Ôyßš888`ddDyy9fffDGG×kÌÌLÕ7ÞE‹iT¤|РAhiiqýúuèܹ3666”””pìØ1µÖ™3g2™ I’øé§Ÿjëíí­ª{Zß÷,‚ ‚ BÃÉÏÏW}ް³³{Ê»©ª¨¨¨Úde© ÏŠwÞy‡´´4Z¶lÉ矮ñüŠŠ ’’’pss£uëÖdggsýúuLMM8p FkI’DTT...œ:uJUãq(ë‡&$$¨}šV¡P0eÊ<ˆ¾¾>{÷î}$N$ü÷{®¤áááôëסC‡N£F˜?>‰‰‰¬X±‡j繺º’œœÌÙ³g‘Ëåäææªê˜¨.\\\Ø¿?nnnäååi¨¬ojy‹-(//çÒ¥K´hÑ‚°°°zÿPvww';;---233IOOWkÞƒظq#}úô¡yóæìÝ»¨|2“””¤öý---éСðw©–––*³TÝnö†††ª'Í¿ýö[­cõõõUM®Ô À ‚ ‚ ‚ð䤦¦•AG++«§¼›ªnÞ¼I‹-¹.j ϒdzyófd26l¨× ÚôôtŠ‹‹éÛ·/>>>ÄÅÅQTTD·nÝhÚ´©FkÅÆÆbbbBAA2™¬Aþ]çææ"Iùùùje€–––2aÂvî܉\.ç·ß~£OŸ>½áÙó\Hsss騱#:uâèÑ£hkk3gÎâããY±bE)ߌ3†¼¼<®]»Æ‹/¾HëÖ­Ù¿•.÷êpvv¦_¿~dddзo_bbb¸víÚã¼="""¸rå 111DDDYí8š5kFvv6-Z´àÊ•+õºŸL&£GèëëãããSë7­‚‚¶oßÎðáñµµeÖ¬Y„††RQQ‡‡‡jœ………F{¨í˜}PP’$©µNÿþýÊày]”ßCBB4Ú« ‚ ‚  ïÖ­[@åñzeffC+--­W’Jrrrµ 8ÊÚ£Oj¿‚ ®ÂÂBæÌ™T6RöññÑx I’ $77WUØØØ##£jÔ¦´´”œœzöìÉ;wûh=TÆJìííIHHÀÔÔ›:÷0aÂvïÞ\.ç×_eôèѽáÙô\Húé'ÂÃÑ$‰:ÁÚµk5:†¡££ƒ··7ñññ9rÑÓÓÓ¸À¶‰‰ ·nÝâÔ©S´oßž .póæMMßñññØÚÚÒ±cGÚ¶mKûöíqvvæÒ¥KÕŽoÙ²%EEEdgg#IYYYõº¯\.ÇÅÅ¥Ú×JKK bÊ”)X[[3yòd)--ÅÉɉ>úˆ˜˜ÂÂÂTsôôô4º¿2@Bqq1PìÔÕÕ%55•ˆˆµÖ™?>PÙ@ëÌ™3µŽUÖ!=~ü¸(ª.‚ ‚ OÙ7hݺõ»GRRR' kSXXXm6ž²ƒ¶¦Ÿ¡¡}øá‡$&&bccÃ7ß|S¯5²²²055ÅÊÊ ;;;.^¼HZZžžžwzÇØØ˜«W¯bddÔ u…Û·oO»ví¯3)+??Ÿ#F°wï^ttt`êÔ©½áÙõ\H•G£¢¢¢jlTKKK|||>€V­Z=±{©*‚È ž¶ÒÒR^{í5ÊËË5jcÇŽ­×:;vì`ðàÁ¸¹¹!—ËILLT­×¤„Dii)‘‘‘˜™™‘••…ƒƒC½{¯ÔDWW“j_‹ŒŒ¤{÷îDDD`ffÆáÇ1bDƒÞ_x6=—RKKKÕ?I’˜;w®ê‰‰¦zö쉓“fffH’„§§'ææædffj´Ž––­Zµ¢¢¢‚[·náëëKpp°ªv‡:š7oNbbbµ¯UTTÔ8ÏÌÌŒ6mÚ‹‹ áááäåå©uϤ¤$–/_Ž««+íÚµcñâÅܼy}}}†ÊæÍ›¹sçþþþ 6 mmíj×Q6¨ÒÖÖ®qLm”Çì8 º6tèPΟ?¯vó(eÚü½{÷ÈÎήu¬ò˜½¨C*‚ ‚ O×õë×'›AÚÐJKK‘A*<=K—.%::š&Mš°zõêz­‘ššŠ¹¹9ׯ_§E‹ܺu‹7n””Tc ²&EEE˜ššbmmMZZZƒfÖ% €=zpëÖ-š6mJHH={öü×î/<]Ïe€´qãÆªú/‹-â•W^A’$üüüXµjU½Ö´··§I“&ìÞ½¨¬íHhh¨F똛›Ó®]; ÚÚÚôë×ÈÈÈ:uóððàÌ™3U¢ µ¦ØØØàääD~~>4nܸƱwîÜaÕªUx{{Ó²eK.\H\\r¹///Ö¯_OZZLŸ>]­îwÊ@p]M²j2hÐ d2W¯^U‰iݺ5:tH­u^yåU}”º2‹•Ò“'OVÉ€AAáßSXX¨:bß®]»jÇH’DYYY½ï!I’Æuë’ŸŸ€¡¡aƒ®+êˆeéÒ¥|ýõ×w™W*))AKK gggrss‰ÇÊÊŠI“&i¼Ö™3g°³³£¤¤„.]º “Éêµ'M( Þ{ï=&NœHAA=zôàÂ… UI ÿûžË)üÝ%ýþýûlÚ´‰7ß|I’xûí·Y±bE½Ö´³³£S§NDDD••…««+yyyu6ûù'333z÷îÍéÓ§)))ÁÞÞž°°0U†e] èÖ­ÑÑÑDFFI£FhÙ²es-,,èÖ­[µæ²²²TY ÌŸ?ŸS§N!I;wfåʕܹs‡“'O2kÖ,Œ5zßÊuu’«‰êØáÇU× ¨Ì^GG‡æÍ›•ÇjÓ±cGÌÌÌ(,,äìÙ³õÙ¶ ‚ ‚ )22’òòrŒk¬zÿþ}bbb8sæ )))7¨½víZikSPPPcòɃêLf„†VQQÁ¬Y³())¡W¯^¼öÚkõZçìÙ³\»vÔÔT,--‰ŒŒD¡P`kk‹™™™FkÅÅÅa``@vv6ùùùϯ¤¤$úôé÷ß~ À¬Y³ i¦P—ç6@ªld”‘‘L&cõêÕøùù!Iï¼ó_|ñE½Ö577§uëÖœ8q‚fÍšáææFzzz½šøtïÞk×®¡««‹••T»[º––ª?vvvjÍÓÑÑ©ò„¦¨¨ˆÀÀ@Æ 3fÌ ((ˆòòrÜÜÜøôÓO‰çâŋ̛7¯ÞÙŸðwéã|#R³¯®éÁƒÕ~b¬œ[ë8---^|ñENœ8¡ñ~AAAx|W®\*»T×”q–••Evv6èééÏ©S§ˆŽŽ&!!¡ÎS{W¯^ÅÕÕUã½Ý¼y‡j_SHÿ@ <ì‡~àÔ©S4jÔˆM›6Õ;SÓÓÓ___FŽIDDàææ¦ñZ‰‰‰899ñHóé'ÁßßNž<‰¡¡!¿üò ëׯ%/žSÏm€T0LNN*›$­\¹’ùóçðñdzxñb×mÒ¤ mÛ¶EOOèèhœœœxá…ÈÊÊRÕÄQ—™™]ºt!22KKKìíí¹|ùòc QGyy9ÁÁÁLŸ>+++†ÎÎ;)--ÅÁÁ???._¾¬jÈÔP]ïܹÔ?ƒÀ××€àà`Õ‘÷^½z©ºÍŸ>}Z­uÞ~ûmÊÊÊê<šïíí  qc.AAAFxx8@­õ ñòò¢Y³f””” P($ ccc ¹yó¦*ùãöíÛäææ"I’j~}Ø'''‹©ðÌQÖmÞ¼9:::½žC‡eîܹ4iÒDãff÷îÝ£eË–\¹rìíí{O5INNfذa̘1ƒ¼¼<ºtéÂ¥K—x饗žØ=…gßs U>ù»víšêšL&cÅŠ,Z´€Ï>ûŒ… j¼¶\.gĈx{{súôituu±··çúõë56Pª‰‰‰ /¼ðÑÑÑtèÐîÞ½[åuC¨¨¨àäɓ̛7[[[ú÷ïÏ–-[ÈÏÏÇÎÎ???ÂÂÂ8sæ Ó§O"…’#""j|Ò”ššJnnn­kxyyѤI TK]]]úõë¨ÌÞÉÉIu æÇ¬u¬2@zæÌµ3|AAAh8.\jBå‰9sssš5kF÷îÝU5KKKÑÒÒ"55+++JJJHHH¨òùMÓ&¼JÅÅÅ5váVó755­×Ú‚P_‹-B__Ÿ¸¸8Ú·o¿¿ƒ¬Û¨Q#ÜÝÝ5žgccƒ‹‹ ;w~bÇÛ +V¬ ]»v!—ËY¸p!§OŸ®Wù áËs mÓ¦ PyL⟾øâ >ùä–/_ÎþóŸzÝÃÐÐû÷±1VVVDDD¨²VÕeccÃСC9|ø0Íš5#22’sçÎ5HT™ÚªU+zöìÉ÷ßOFF&&&L›6}ûö‘œœÌŠ+ˆŒŒdìØ± œURH«û¥æþýû´jÕŠîݻ׺†¶¶6>>>@õÇìÕ tëÖ €°°°ZÇuêÔ rss‰ŠŠR{}AAA_^^‘‘‘ôèÑC£¹úúúØÛÛÓ¹sgÚ·o§§'r¹œ¢¢",,,ªœ–=z4Û·oçܹs ¶we™±ã8± <쥗^âòåËtìØ‘œœf̘AïÞ½ë,3÷¤ÙÚÚÒ¤I“_788˜Î;óÎ;Oûöí9}ú4K—.m Z῟V X¼x1Ë–-*»¹½÷Þ{ßC&“1|øp,,,ˆŠŠÂÆÆkkkÂÃÃ5êJ/—ËÑÒÒÂÍÍгgOòóóëýƒ9))‰åË—ãêêJ»víX¼x17oÞD__Ÿ¡C‡²cÇÒÒÒT ™¢¢¢ðññ!''‡ÐÐPºtéR¯ûÖæÎ;¤¥¥!“ÉèСÃ#¯ëêêR\\Llllfå1û¨® <™LFll, jíIY¤úÁƒܽ{·Æq:::tíÚ¨ìf/‚ ‚ ¿Gy’ËÒÒ’Ö­[?ÖZ:::4mÚww÷GŽøZXX0iÒ$ŒŒŒØ¾};ÇŽ£¢¢â±îwûömU“XAø7µiÓ†3gΰpáBttt8~ü8:uâ£>ªóôæ‹óçÏÓ¯_?ú÷ï¯J^ûî»ï¸té/¼ðÂÓÞžð yn¤Ê#ö9995¿,XÀòåËøöÛo™3gN½²'ÝÝÝ‘Éd$''caaA“&M¸víšFARGGGœ‰ŠŠÂÕÕUÕ…Q)))¬Zµ oooY¸p!qqqÈårúõëÇæÍ›IOO'00qãÆ¡««Kff&o¼ñŸþ9?ÿü3|ðA½ž¬( Nœ8AZZZcBCChݺ5&&&¼nllL»víê¬#:hÐ d2ÑÑÑܺu ¨| ¥ÌL}8³´6ãÆC.—×g©‰¨C*‚ ‚ O‡òwpooïz7šÑDÛ¶m™4iíÚµã?þ  ÆÄ›Údgg“——ðDë- BmôôôXºt)ÑÑÑôë×’’¾üòKY¾|9EEEO{‹õrêÔ)† †§§'GE[[›Y³fÇÛo¿­ú¬/JÏm€´I“&ªº×!ý§ÿüç?|óÍ7¬[·Ž×_½^O {÷îMVVwîÜáÅ_ÄÈȈ¼¼Ž/‚ ‚ BÃRH5=^ÿ¸¬¬¬?~<&L ¼¼œ?þøƒ?þøƒ]»v±k×.‚ƒƒ ®q~JJ PY³ÑÜÜüßÚ¶ TËÙٙÇãï<`áÂ…899±téÒz×àý7•––²}ûv¼¼¼ðöö&((™LƘ1cˆŒŒdýúõÕZø'=Ç|||$@Z¹rec×®]+Éd2 ^{í5©¼¼\ãûåææJ©©©Rll¬T\\,ýùçŸÒ™3g¤ââbÖ)**’233«}­°°PÚ±c‡4tèPIWWWTÜÜܤO?ýTJHH¨vnII‰´iÓ&ÉÓÓSZ¾|¹TRR¢Ñ¾bbb¤¥K—J}ûö• $}ÿý÷Rbbb­s***¤°°0ÉÂÂB¤ýû÷×8vóæÍ uêԩν¼ÿþû =ZuíìÙ³ éééIyyyj½§ H€$—Ëký;ÏÉÉ‘är¹HIIIj­-‚ ‚ Âã)((ôõõ%@ºpáÂÓÞNYYYÒƒ¤ŠŠŠj_ß¿¿H­[·þ—w&µ+))‘V­Z%Y[[«â Ò믿.?þioïÑÑÑÒ|Pe¿r¹\š2eŠý´·'ü—x®¤ .”i„ ¼¶dÉiñâÅRFF†êÚºuë$--- &Ož,•••i|ÏœœiÓ¦MRTT””››+I7n|¬÷Q\\,íÛ·Oš6mšdddT%(êàà -X°@ºzõjóóóó¥+VHݺu“¾ýö[µƒ‡åååÒÉ“'¥÷ß_òôô”f̘!íÚµK­ù‘‘‘ÒÂ… %Õ^ŒŒ¤‚‚‚çÄÇÇ«¾ÑeeeÕºþÑ£G%@266–JKKUûU~ÃÜ·oŸZïñÞ½{ªýÔ:ÖÃÃC¤­[·ªµ¶ ‚ ‚ 篿þ’É¢^I,OÓwß}'Ò AƒžöV¡ZÒÚµk%ggç*q†6mÚH_~ù¥ûÔö)}õÕW’»»{•½™››Kï¿ÿ~‰a‚P“ç:@(RÓ¦MyM¡PHR=¤eË–©²<7nܨ ’Nœ8±^ARI’¤mÛ¶IÑÑÑRzzºtîÜ9éèÑ£5>Y¬Nyy¹&ùùùI–––U¾!4mÚTòóó“ÂÂÂj\S¡PH!!!ÒË/¿,yyyI6lP+“µ¤¤D ’fΜ)yzzJóçÏ—BBB$…BQçÜ[·nIü±*ÓRùG___;v¬tâĉ:×ptt”iÏž=uî³qãÆ …††ª®Ï˜1C¤Ù³g×y/%333 ú÷ï_ë¸7ÞxC¤9s樽¶ ‚ ‚ õ7oÞ< ¦L™ò´·¢±Y³fI€ôöÛo?í­B­ÊËË¥}ûöIÆ “tttª|žwrr’üüü¤½{÷JiiiOlñññÒ–-[¤×^{MjÖ¬Y•=ÈårÉÇÇGúõ×_¥¢¢¢'¶á›L’êÑuèă°´´¤¢¢‚ÄÄÄjël–——³aönÝÊš5kèСÛ¶mcúôé”——3nÜ8~ûí7›eddpìØ1\\\ÐÕÕ%##ƒ¬¬,FŽY뼘˜¶lÙ–-[ª4—211aذaŒ7ŽAƒ¡­­]ãüeË–··7S¦L©¶kü?]¾|™Í›7sþüy|}}9r$íÛ·¯s^vv6»víbëÖ­œ8q¢JÒþýû3yòdFE“&Mê\ `æÌ™lÚ´‰7ß|“~ø¡Ö±#GŽäÏ?ÿdáÂ…,]º€;w2~üxš5kÆ­[·Ô*â®\ÇØØ˜œœœÇmÛ¶)S¦àîîNdd¤ZïGAA„úsuu%..¦M›ö´·£‘^½zqâÄ Ö¯_ϬY³žövA-üþûïìØ±ƒ3gÎP^^^åõV­Zѹsg\]]iÓ¦ ­[·ÆÖÖKKËãJ………ܽ{—ÔÔTâââ¸ví111\¾|™ôôô*cµµµñòòbÔ¨QŒ?^ÕcFêë¹Be‡ùèèè: &''3sæLÆŽˬY³øý÷ß™6m …‚¡C‡òÇ §§§Ñ½322ÈÍÍ%>>KKKÜÝÝ« ´^½z•€€¶oßÎõë×U×õõõéׯÓ§OgĈèêêÖyÏÔÔTrssqqq©slII Û¶mãçŸÆÕÕ•3fàååUgP±´´”°uëV‚‚‚(..V½Ö¦M®^½Zg°±&Lœ8—Z›kAeS­9sæÐ¾}{ÂÃÃÈÍÍÅ‚²²2ÂÃÃÕ ò}???>þøcäry­s®]»Æï¿ÿÎo¿ýF||¼êºòÈÿôéÓñññQež;wNõžêÃÂÂOOONŸ>ÍÞ½{yûí·kkoo¯ÊX=tè/¿ü2C† !$$„ýû÷« uss#""‚¿þú«Öq]ºtaÿþý\¸pAHAAá ÚµkcÆŒ©u\yyyŸkþm—.] yóæ"8*üϰµµeôèÑŒ=ºÊõ‚‚îÝ»Gzz:H’Dvv6:::¡§§‡±±1VVVXYY=sÿ^…çÃs íÝ»72™Œ˜˜’’’hÑ¢EsÞ{ï=Ö­[Ç´iÓð÷÷gÏž=Œ;–ƒ2bÄöîÝK£FÔºQQAAAøûûsèÐ!ÊÊÊT¯¹¹¹1nÜ8f̘¡Ê”¼yó&+V¬àÈ‘#Ñ·o_f̘AçÎëõþrrrTk¾ûî»|õÕWµ£ÏÌÌd×®]øûûWÉnÕÓÓ£ÿþµùWÖ ­o€`Ô¨Qœ>}š={öÔ ðõõåêÕ«8p J€ô½÷ÞãܹsÜ¿ ‹:ï9nÜ8"""HJJ¢´´´Ær]»vUHAAAx2îܹ£J¾øg0æŸbcc044ÄÂÂâ™ÈBSH»téò”w"Ož¡¡!NNN899=í­Bê¥úÑ´iS:uêÀ¾}ûT׋‹‹Ù¹sgó^ýu^|ñE^yåÌîÝ»Ñ××çðáÃøúúÖZ;£¤¤„ÀÀ@¦OŸŽ••ãÇ'((ˆ²²2Z´hÁ‚ Tň?ûì3lmmÙ¾};ƒ â½÷ÞÃÖÖ–-[¶ÂÇL×®]ëp”$‰Í›73pà@\\\ côèÑÕG‹ŠŠØ¹s'Æ ÃÖÖ–Ù³gsêÔ)´´´ðòòbåÊ•¤¤¤ȸqãj 6D€Tù„øÔ©SÜ»w¯Ö±ÊÚ¡GŽA¡P•…Ü[µjEyy9‡RëžsçÎþþšÕä…^àüùój­+‚ ‚ ‚ævïÞ$ItèСΠK~~> …™LFtt4‡"11‘7n——÷/í¸*e€ôq]A„†óÜHFŒÀŸþ©º¦§§Ç¹sçøê«¯jœ÷úë¯Óºuk>þøc ¤Ê=q⃠ªòö¢¢‚“'O2oÞ<š5kÆðáÃÙ²e ùùù4mÚ???ÂÂÂHLLdÙ²e¸¸¸üyóèÛ·/·oßæ—_~a×®]Lœ8ssóÇzÏáááøøøpùòe‚ƒƒ™4iÒ#AËòòr‚ƒƒ« 亹¹ñé§ŸrãÆ ÕûR'³!¤ŽŽŽ¸»»SQQA```­c_|ñEŒŒŒÈÎÎV=a†¿§û÷ïWëžMš4ÁÚÚÿÇuëÖ ™LFrr2iiij­-‚ ‚ ‚f€º³G¡2)¦¤¤„K—.QQQ——ååå”––E`` 7nÜ !!…BQåTß“¢ùä“*ÁÑîÝ»“ššÊ¾}û?~¼FÁѲ²2üýýéÕ«yyy„„„T Ž*ß<~€`äÈ‘ìÚµ«ÖqŽŽŽ8;;#IGŽQ]2d ~R¨ ÌUÖù'åßý¹sç Ú‚ ‚ ‚ÐpNœ8Abb"5R%¤4”FáääDË–-;v,ݺu£°°ÔÔT"##±µµeàÀ D€TáY"¤À‚ HMMÀÀÀ®\¹Â«¯¾Š££#+V¬ °°{{{‚‚‚øí·ßX¼x±*²:ÿЬ.H¦P(øðÃùñÇ |äX¿ÒåË—ñóóÃÛÛ›ýû÷3uêTNŸ>Íúõë6lØ#Çôÿ©¬¬Œ#GŽðÆo`ooO÷îÝù¿ÿû?nܸ\.§wïÞ¬Zµ ???\\\4nUQQÁÎ;yñÅILLäðáÃ,X° ÚàªòkVS=WM(!Ú¿?ÙÙÙµŽõõõàÀªkC† Qu²T÷¸ÿäÉ“¸{÷î#%”:uê„\.çÁƒܼyS­uAAA¨ÛÆÊd‰†® úOzzz4kÖŒ^½z1xð`š5köØkFGG“’’‚¶¶6}úôi€] ‚  á¹±råJÕÿÛØØ””ÄÇŒµµ5÷îÝãwÞÁÉÉIÕ¨iÇŽ˜˜˜0hР*MŒVW€túôéØÛÛ³sçÎGº¿²aÃzöìÉÚµk™0agΜaéÒ¥tíÚµÎ'–………ìÞ½›éÓ§cmmÍ€øñǹ{÷.úúú 6ŒŸ~ú‰{÷ŸŸª†§&’$H¯^½¸téä³Ï>{¤¾éÃêˆ=€§§'ÎÎÎ×™EªìZèÐ!U«íÛ·¨³Ñ“ÒÌ™3‘ÉdH’ĺuëªchh¨ª®Öº‚ ‚ ‚ Ô.##ƒ?þø€×_ý)ï¦~” =zôxâ^AA}Ïu€ôÖ­[¼ôÒKH’¤ê6®P(°³³ãóÏ?'99™õë×Ó´iSU ÔÙÙ™-[¶àççÇ_|Áرc9yòä#k×Äô÷÷gΜ9U®Ý»w… âããCii)ýõ›6mÂËË«Î÷’••ÅÎ;UAÑ1cưe˲²²000`èСlÞ¼™´´4öíÛÇ+¯¼R%0«é1‘àà`z÷îÍ©S§Ø·oË–-Së|CHáïŒÎ­[·Ö:®wïÞ••U¥6¨òï]Ýcöúúúª'Ç5ŽS^#""ÔZWAA„Úmذ’’ÜÜÜÔê!ð,:xð ð÷ 7AáÙðÜHËÊʘ8q"™™™¸»»3þ| 2@ª¤§§Ç¬Y³¸qã+W®ÄÚÚš””f̘AïÞ½ÑÕÕeÏž=,]º”åË—W9rÿðòÒÒÒGýw¬;wî0oÞ<&OžŒ··7§Nbîܹµfbdff²qãFú÷ï••ãÇgË–-äççcmmͬY³8pàYYY2}útŒk]³® Re`400;v°lÙ2LMMkó°ÚÊÔÇÔ©S‘Éd?~¼Öcòúúúª?ÿú€7nh4·&NNNxzz"I¿ÿþ{­c•Çì•Om¡²¡’••EEE„„„¨uÏwß}¨ |×4GHAA¡áqëÖ-7nÌ•+Wxë­·X²dÉÓÞ–FöîÝKii)ŽŽŽªæ¯‚ ³Ṡ²zõj~üñG\]]UÁê¤J†††|öÙgDFF2pà@ Ë—/ÇÓÓ___~üñGÕñmmmm¬¬¬€Ê†>+//gÍš5øúúâééɱcÇ0`@÷---e÷îÝŒ=sssÆOPP¥¥¥´nÝš>úˆððp’’’Xµjýúõ«1ÐY“²²2€Gš>effâëë˶mÛøé§ŸX¿~=¶¶¶­}ìØ1ú÷ïO·nÝˆŠŠ*¿ÎêflÖEÙàÊßß¿Öqʧ´/^$==¨<ê¯ÌU÷˜½«««* þã?V;F MNN®³” ‚ ‚ µ[±b `Û¶m@íŸÝžEÊ]ãÇ׸ę ‚ðd=wÒäädUÝÑ9s樂kêH•œ9xð ;vìÀÔÔ”ˆˆºuëÆ±cÇ=z´jœPy„þa©©©( Nœ8Á˜1cj¼OLL .ÄÞÞž1cưgÏŠ‹‹±··ÇÏϰ°0âââX²d‰* W_5H›4iÂÏ?ÿÌÚµk5êÚ(Iûöí£{÷îøøøŒ––NNNª×Oœ8ñX{Vš8q"ººº\½z•+W®Ô8ÎÙÙ'''***8räˆêºò˜}PPÚMªºví @hhhµ¯ÛØØ`mm$Iª ° ‚ ‚ š»páÇGKK‹øøxUÙ.ƒ§¼3õÝ¿Ÿ£G•Ÿ_A„gËs -))a̘1333Uvh]Íš”ã>fïë닎Ž·oß&::Z­{¾ôÒK@e'Í´´´jÇxxx☽ ‚ ‚ <ŽåË—бcÇ*¿[ëëë?­-il÷îÝ”••áää$Ž× ‚ <ƒž«é»ï¾Ë¥K—TuG5j¤z­>R€æÍ›säÈ>ýôS´´´Ø´i$''µ‚nqqqÌ›7fÍšáççGTTZZZôë×Í›7“’’ÂêÕ«éÑ£Ç9ŽQS€T]Ò¹sg&NœHTTºººL›6˜˜6oÞL›6mÈÏÏWÍ9|øpƒìþ>f¿}ûvÊËËk÷p€Tùä¹I“&ôèÑPÿ˜ýÔ©SUµb×®][íeVomÍœAAA¨Ybb"{÷îUý7üýÙ­>Ò;wî““£öɱ†¢<^?iÒ¤õ¾‚ ‚zž›éÎ;Y³f ëׯW/•ê …ÊŽõŸ}öüñœ8q‚>}úвeK._¾\ãÜÐÐP €««+ßÿ=ùùù8::²lÙ2îܹÑ#G˜>}z•`î“ üAÓà«$IìÞ½www†Nxx8†††¼÷Þ{$''ãïïOëÖ­Uã®;óH}Öú6l&&&¤¦¦ªŽ®T§OŸ>èëësÿþ}.]º¤º®·oßæäÉ“;vŒØØXU²È“’‘‘¡*/6a„'z/A¡~ž‹i||<3gÎàÍ7ßdòäÉŒQvœ¯¨¨PejjÔ¨Q9rSSS®\¹¢*$«:v¯tèÐ!¼¼¼èÓ§GŽAKK‹AƒH||< ,ÀÆÆ¦^û¨e6¤&ïýܹsôîÝ›1cÆ‹¡¡!~~~ܸqƒ¯¿þºÚý`nnŽ$I7ÈþõõõUõ\k;fohhHÏž=8pà€êº2@zæÌ233Õºç°aøvíZµO •Ò¨¨¨Z³ZAAAxTJJŠªë½{÷ÉdlذAõz}¤åååܾ}###¬­­iܸ1©©©:tˆK—.‘““ÓàÍŸvìØB¡ M›6´k×®A×AÆÿ|€´¤¤„ñãÇ“““CçΫÔ}ØÃ]ßçb=8~ü8ܸq¹\ŽB¡P5ŠŠŠbàÀøúúrúôÿcïÎâ*ÛŽ‡}SÄD@EAÅ}ß·rÁSTÒ2Í´Ì·´õ-Ó,­jx¿Æ IDATlÑ4×\PQ1sAÅ=ETT@TAY•†a™óûƒßœ×‰E@,­çs]s]pΙç÷sßèééáééIxx8GŽaĈr°ò¯¤ WæÚïܹØ1cèÖ­çÎÃÀÀ€yóæq÷î]~úé§ »Ük¤šìËšªC ÿ[f¿oß>­¥üVVRggg)..æØ±c•:ßüùó’Y,µ¿eË– T*åå@‚ ‚ ‚ TÎ×_M~~¾ü]íí·ßfÈ!deeP»ví*Ù¡C†еµ5æææ¨T*bbbhÖ¬fffÄÅÅáïïOBB!!!¤§§?õuüú므X^/‚ð<ûÇH?øà®\¹‚¹¹9»wïÆÐаÌãj*@ ЦM>Œ©©©œ9xòäIæÎKûöí9~ü8ººº¼ñÆܺu‹­[·Ò²e˧:gyT*U¥Ž333þÀ,KAAË—/§M›6ìß¿…B»»;üøãÔ«Wï‰çÑ4¬ÒÔ :qâDÕÿéÛ·/M›6%77—”{ÜСC¸té’V¶¨&pZÙeö¶¶¶˜››hÝÉÖÐ××ÇÑÑ(É2AA¡râããÙ´i€œ}¹lÙ2 ¤±- ¯lllhÖ¬™ÜàÁƒ$%%accƒ$I˜ššÁùóçyøð!©©©¥V>Ipp0—/_FWW—W_}µÚóAž­t€ôèÑ£¬\¹(i¤£ V•¥¼iXXƒ bïÞ½Uz3ìÒ¥ ÞÞÞrMÏ¥K—²zõjŠ‹‹yùå— cýúõØÛÛWõ²Ê•‘‘ÁñãÇYºt)£F¢GåfÌþ™……@¹wHýüüpvvæÃ?$??Ÿ=zpéÒ%öìÙSáëúgš†Eþþþ$''³páB¢££+=Fy 'N*^fߪU+(..ÖÊ`Õ,³÷óó«t¼gÏž”¹_øRAAA¨¼¥K—ÊÉúúúxyyÉKêŸ&ƒ´,šÄ†0xð`ÌÌ̈%<<}}}5j$g𦤤pæÌ™J¾ß°aPò]£I“&52_A¡æýc¤ÉÉÉLŸ>I’xýõ×ˬ;ú¸ò¤®®®ìܹ“¨¨(† ‚››‹/ÆÏÏ»wïV4uss“ëbªT*5jÄþýû9zô(...Õ¾6•JÅÕ«Wñööæ“O>aìØ±ôêÕ‹)S¦@»víØ¸q#|üñÇ•ÓÒÒ()Zþ¸¬¬,fÍšÅСC‰ŽŽÆÂ‚ü:uêTå¹k^/}}}yÛwß}G³fÍpvvæƒ>àüùóÕ®Ùééé ”d¦&%%•{Ü!Cíeö ÀÌÌŒ´´4.^¼X©óijÛfddSj¿&@U¹ AA„¹¸¸89{`ñâÅtìØQþ] }š ÒŠ4lØž={2~üx:vìHAAqqqÔ¯_ŸôôtZ¶l‰®®.þþþ6dÍÉÉa×®]Àÿ¾7‚ Ï'…TS뛟#jµš!C†pêÔ)š7oNhh(µjÕªð9ÙÙÙòÈ””¬­­Ë<.==K—.qéÒ%îܹCBB*•J^&ndd$gcÖªU I’Ø»w/¦¦¦Lœ8###êÔ©”,Y/**ÂÞÞSSSLLLä.ïjµšÔÔTRRRHNN&99™ŒŒ Š‹‹122¢E‹´nÝZ.ô]·nݧzÍNœ8Á!C°³³#66€óçÏ3uêTbccQ(̘1ƒeË–ÉÁÔê°°° ##ƒéÓ§óÖ[oáííÍÅ‹ ÔjeiiÉÀ1b£FªÒ‡Ÿ:påʾùæ,XPæ1`ôèÑ4hЀ„„9ÓwäÈ‘:tˆ>úˆ¯¾úê‰ç’$ ŠŠŠ˜?>ßÿ½Öþ­[·2mÚ4zöìÉùóç+} ‚ ‚ ‚ðo5gÎÖ¬YÀ¸qãðññ‘?¯?þùûöíÛ4kÖì/[xx8J¥I’èܹs…Ç®_¿žY³fakkKLLŒÜ÷AAxþü#¤K—.åÓO?ÅÐÐÀÀ@Ú·oÿÄç(•JLLLHHH¨°ÑPEòóóQ*•deeÉYH’„Z­–ëåñðáC222000   @®ÿibb‚¡¡!æææ4lØkkkêÕ«‡••UµæT111888 ££Cff&_}õß|ó ÅÅÅ4jԈ͛7ËY—OÃÌÌŒÜÜ\Þyç~úé'y{jj*GÅ××???²³³å}ºººtëÖ 777F““S…çX³f sæÌÁÎÎŽèèè2?ˆäææbee…J¥"44”:°nÝ:Þ|óMÚ¶m[áÝàǵnÝšððpš5kÆíÛ·µö]¼x‘nݺaii©UïTAA„Ò222puu%..'''._¾,Oƒ’¬LMòKrrr¥ú ü]:uêDhh(‹-âóÏ?ÿ»§#‚ Tà ¤OŸ>±råJÞ~ûíJ=¯°° dI‡­­í³œæs§¸¸KKK²²²èÔ©!!!Œ;–uëÖ=u†ª†‘‘*•Šÿþ÷¿,^¼¸Ìcòóó9þ<‡bß¾}rc' FŒ››ýúõÓ*%š7nLVV;vì(·¼ÂÀ9}ú4K—.•KÜ¿Ÿ&Mš I±±±ØÙÙ=ñš>ÿüs/^ŒŽŽùùùZå²²²¨S§’$U˜™,‚ ‚ ÿv*•ŠáÇsêÔ)êׯϥK—JÕíŒÅÞÞ…BAAAA©ïÏ‹ÐÐP:uê„®®.111ÿºï—‚ /šT ÒÜÜ\^}õUŠŠŠ6lsçέôsk²‹ýóH©Trùòe¶lÙÂþóÆŒ£uººº´k×€ŒŒŒØ¸q#¿ýö[•ƒ£—/_.·i‘&«¶¢‚êFFF 4ˆŸ~ú‰øøxnܸÁ²eËèÙ³' …‚»wï²råJLÆ ñôôÄÇÇG®EdffÆ;ï¼À'Ÿ|‚R©,ó<š®õG•·ÙØØÐ¶mÛRÛ+¢9—Z­ÆÛÛ[k_íÚµåläÈÈÈJ'‚ ‚ ÿ6………L˜0S§NaddÄÞ½{Ëlj”’’””äz^ƒ£?ÿü3Æ ÁQA„ÀóûŽR ï½÷·o߯Úښ͛7Ëuj*C¡P ««Kqqñ  MIIáÚµkdggSTTDNNyyydddÈäädÒÓÓÑÑÑÁØØ˜æÍ›Ó¶m[&MšDëÖ­µ>P;vŒàà`Œ9}ú4ݺu«ô|$IÂÇLJիWãììLûöíéÑ£G©ã4uF5uX+ÃÅÅ>øàRRRðóóÃ××—£GòðáC¼¼¼ðòòÂÈȈ^½z1bÄ<<<ذa±±±¼ÿþû¬^½ºÔ¸C‡eáÂ…’––&×V>|8aaa>|˜7ß|ó‰ó³²²¢nݺ<|øÍ›7Ë¢4Z¶lIBB7oÞ¤OŸ>•¾nAAAø7P«ÕL›6ƒ¢¯¯Ïž={èÕ«W™Ç&''<×KëSRRäæLóæÍû›g#‚ TÆ?&@zâÄ Ö¯_ÀÚµk«õ†©§§÷ÂH ›BY[[Ó¼ys,,,¨S§ÖÖÖ• D>|˜qãÆ¡R©hРÛ·o¯Rp4""‚ùóçÓ©S'öïß/ϧ,šé©S§h×®;v¬R »^½zxzzâééInn.ÇÇ××___RRR8yò$'OžÀÑÑ‘äädÖ¬YÃàÁƒ=z´ÖX­[·¦I“&ÄÅÅqúôiÆ”H¿úê+N:E^^žVÍ£òôïß9Èü¸–-[rúôinÞ¼YéëAA„I’x뭷عs':::lݺ77·r×d>ÏÒ_~ù…üü|\\\0`Àß=A¡þÒôôt¦OŸŽ$ILŸ>±cÇVk}}}T*ÎÎÎò6###ŒKkhhXf଼혚š–¹ÝÄÄ„ÌÌL‰‹‹£}ûötíÚUt–õhÕª•¼$þiüþûï¼òÊ+2räH¼½½+„’3+V¬àøñã¬Zµê‰Í“ åŸwíÚÅ®]»hܸ1#GŽdÔ¨Qôë×CCÃJÏÝÔÔ”1cÆ0fÌÔj5—.]âСC:tˆëׯ-;nÜ8<<q.sæÌÁÇLJÜÜ\®_¿N›6mä}š%ûçΫôµ ‚ ‚ Â?]qq1³fÍbÓ¦M( 6lØÀ¤I“*|ÎãKìŸG¬[·(É­J2ˆ ‚ð÷ùG4išIll,¾¾¾ìß¿ŸÓ§Oóøæ&&& 8777ttt˜1c 6äÁƒò˜)S¦°cÇæÌ™#×zCCC xã7älf€¤¤$lll(..æöíÛ4kÖ¬Ú×%‚ ‚ ÿJ¥’I“&qàÀ «V­bΜ9O|ž¦Ñª‰‰ K–,aÖ¬Ye&¢ü]¶oßÎÔ©S±²²">>¾ÌdAáùóÂH÷îÝ‹»»; …‚“'O>Õ†ÂÂBâããµ¶©T*òòòJ[Þö‚‚rssµ¶eddÎ7ˆŽŽ&..N^j®¡§§G£F044¤[·n˜˜˜žž®USTó(((¨ö5–eôèÑìÞ½ƒJƬY³øþûïˬ3ZM'G€ëׯcgg‡ŸŸ>>>øøøh«§§GŸ>}ä€iÓ¦M+}ž?»sç7n$!!A®[ª¡ ˆJ’ÄÅ‹éÒ¥ ÞÞÞxxxФIîÝ»W©ótêÔ‰ÐÐPlmm‰‹‹ÓÚ×§Oüýýùúë¯ùðë}-‚ ‚ ‚ð¢ËÈÈ`Ô¨Qœ;w===Ö­[Çk¯½V©ç|8¾¾¾@IÙ†zõêQTTÄ7pqqyâØß~û- .D¡P““£Uª`ÕªU¼óÎ;tèÐA®+‚ ‚ ÿ6ñññŒ1‚k×®abb‚Æ «ôó{ôèA`` œ={–ÈûÚµk‡»»;C‡ÅÕÕµR«ÜžFZZaaa„……qõêU®^½JXXúúúܽ{·Êß—A„¿Ï  ={6k×®ÅÞÞž7nTºvfM*(( $$„€€üýý ÐÊPÔpppƒ¡={öÄÙÙùo«G“••…§§'àóÏ?gÑ¢E•zÞï¿ÿÎúõëÙ»woµ–±h²2&Nœˆ···¼ïСCŒ9’ZµjñàÁîÞ½ËÁƒ9xð ¡¡¡ZfÜÜÜ5jýû÷¯tp·,ÑÑÑL˜0Ë—/cnnNFF†¼O“õ¹|ùr.\øÄ±rss©U«’$±råJÞ~ûmyßãËìoݺEóæÍ«=gAAAx?www’’’°°°àСCôìÙ³JcØØØðàÁNŸ>M¯^½Ø¿?¿üò gÏžÕJ±¶¶¦{÷¸ÐºukœiÕªU•z‘’’BBB<àÖ­[ܺu‹¨¨(¢¢¢äz¨6cÆ 6lØP¥ëAþ^/l€ôâÅ‹ôèѵZ¯¯/ÇÿKÎGpp0Û·o'$$„G¡T*µŽÑÓÓÃÕÕU+ Ú¨Q£ŸKQQzzÕë³¥ þmÚ´©RËYΟ?Ï’%KØ¿µëè¬^½š¹sç%]'“’’ä ±Z­¦Y³fÄÄİvíZfÍš%?/%%E^ŠâÄ ­º¥&&& 0777F]­n–š2 P’ýkooÀòåËùðÃéÓ§gÏž­ÔX7&!!®]»¤µ¯oß¾œ;wޝ¾úŠ>ú¨ÊóAA„ÕªU«xï½÷(,,ÄÉɉýû÷WyI|QQFFFe&Ü¿Ÿß~ûýû÷PfY2===,,,077ÇÜÜ\þY­V“ ”,ÿ/,,$99™”””R¥ÑþÌÚÚWWWÚ·o««+®®®8;;?óìUA¡f½Òââb:wîÌ•+W3f ûöí{&ç)(( 00?þøƒ‚ƒƒINN.uœ™™ݺu“¢ÝºuÃÌ̬ÆçSTTDXX'NœàôéÓèêêrøðáj½ùÚÛÛËñãÇÅÅÅÌŸ?Ÿï¿ÿ€7nЦMtuuINN–LUdÚ´ilݺCCCòóóµöýüóϼýöÛ´oߞ˗/Wjn‚ ‚ ‚ð"S*•Ìž=›­[·àææÆöíÛ«ÕX7>>ž&Mš P(ÈÍÍ-7q#77— .påÊÂÃà '22²TbKe™››Ó¨Q#iÙ²%-Z´ E‹´lÙ’úõëWkLAáùòBHúé'Þ}÷]ÌÌ̈ˆˆÀÖÖ¶FÆ•$‰7npâÄ Nž<ɹsçJ5\R(4oÞœ{÷î¡R©Øºu+ÕÎä,ONN޼t#<<œàà`òóóquueàÀ 0 Z*4 (,,$22ò‰wn“““Y¾|¹8¬®… òí·ßÊ¿ÿüóÏZ*>|ˆ­­-ùùùøûûÓ«W¯ ÇÓÔõõõå÷ßçÖ­[ZûqsscĈôìٳ’ÎÎÎDFFâèèÈ;wäíš@²··7'N|â5^½z•öíÛpá­&V/³¯Ìë.‚ ‚ /²+W®0yòd"##Q(|öÙg|öÙgÕή¼pá½zõÂÚÚºÜåíåQ«ÕÄÄÄðèÑ#222ÈÌÌ$==ÌÌLtuu133C¡PP§Ntuu©_¿> 4 Q£F¢½ ¿À  MHH U«Vdee±bÅ þóŸÿ<Õx’$ˆ{÷îåþýûZûk×®Mß¾}éÖ­;w¦sçÎÔ©SCCC JeAÄÆÆrçÎôõõåLR¹ngnn®V¥ÌÌL222HJJâöíÛ(•JLLLhÙ²¥üèÔ©Se¥ªT*¹!TBB 6¬‘qŸdÖ¬Y¬_¿^þ}ܸqìÝ»W똩S§²}ûv&MšÄÎ;«4~xx8¾¾¾:tˆ€€­º¥õêÕ㥗^ÂÝÝ!C†”ª=ôé§Ÿ²téRtttÈÏÏG__€9sæ°fͦL™‚——W¥æabb‚R©ÄÃÃ;vhíëß¿?üñ_~ù%Ÿ|òI•®OAA^jµšo¿ý–Ï>ûŒ‚‚¬¬¬Ø¼y3nnnO5®——žžžtîÜ™K—.ÕÐlAá Θ1ƒM›6Ѷm[BCC«¹ÂÎ;Ù»w/ñññòv}}}ºvíÊ AƒKKKRRRÐÕÕ}â¹{÷îÍùóç©_¿>IIIZûÖ¬YÜ9spuuåêÕ«Õº6AAAx^Ý»wW_}U®á?xð`¶lÙR#=>ûì3–,YRf"‚ ‚ <*@AÛ¶m)..æÄ‰ 4¨JÏW*•x{{óË/¿"o722’³ ÝÜÜž¸týñã£G°´´¬úÅüå(J¥RÎ&}Z………ìÝ»ooo²³³ñððà7Þ÷»¹¹áëëK½zõÈÈÈ   €«W¯âêêª5N§N ­±,ˬ¬,üüü8pàGŽÑêT¯¯¯OŸ>}9r$Ÿ~ú)ÙÙÙôíÛ—?þø(y}êÖ­K^^tïÞý‰ç[¿~½ÜdêÏÿ}$''Ó¸qc±Ì^AAøGQ«Õlܸ‘÷ߟììlŒŒŒX´h ,¨±†E'Nd÷îÝ,Z´ˆÏ?ÿ¼FÆA€ªµÞ§Ÿ~Jqq1C† ©Rp4&&†÷Þ{Æóú믂®®.nnnxyy‘œœÌþýû™\©óMŸ>]þøË/¿hí«_¿>}úô(U^@AA^D¡¡¡tîÜ™Y³f‘M‡ áƒ>¨Ñnîš^w¯A„šðÂHoܸÁþýûQ(|ýõוzÎÝ»wyýõ×qrrâûï¿'== ðé§ŸÃÁƒ™2eJ•›i¤zzz5`|‘íÝ»—~ýúaff†¿¿?}ô‘¼TýÏ4Y### ÀéÓ§K7yòd,--‰Ç××·F端¯Ï²eËh×®jµš‰'òÅ_бcG¹‰S^^žVÑ÷áÇ•êëëËe|||Jíwww/wŸ ‚ ‚ ¼(233™?>]»våòå˘™™ñý÷ßsñâE\\\jü|·oßD€TA¨y/L€ô›o¾A’$^~ùe:tèPá±ÑÑѼöÚk899ñ믿RXXH÷îÝÙµk÷îÝcÉ’%ØÚV¿ó½&²¦š&ýÕ45N%IÒªÍYIIIŒ;–ÀÀ@Ž;ƬY³äº¬åÑ4ƒ²µµ•³2Ï;Gqq±Öq&&&xzz¥30k‚ŽŽ_~ù%ûöícêÔ©„„„‹¹¹9AAAòñ#FŒ@¡PpõêUâââ*uMP5<<œ?W±?~¾ ‚ðïöBHصk~øa¹ÇeffòŸÿü‡V­Z±yófŠŠŠèÕ«Ç' €W^yå‰A¼ÊÐd¾èRø_VgUÉðáÃéÝ»7|ÿý÷4iÒ„Q£Fàçç'kkkKëÖ­Km¯È¼yó€’~޵µµXf/‚ ‚ ¼|}}iÓ¦ sæÌ!55•¦M›²wï^:TªymMŠˆˆ AƒrRƒ ‚ Ô”"@ºyóf éСƒXzœ$IlÙ²'''~øá éÝ»7'OžÄßߟÁƒ×è|¯¥ù4222¸ÿ>7oÞ$44T~DEEq÷î]亘5ÉÄÄDþ¹*RI’X¾|9»víâäÉ“ôèÑ£JçÕ,aW«ÕÉ ÊªCÚ¬Y3ˆ$I¬[·®J穬>ø€_ý•ÔÔT^~ùeŽ=ªulU—Ù7oÞœZµj”9±Ì^AAx‘0`ÀÜÜܸyó&æææ,[¶ŒÈÈHÆ÷ÌÏýúuÚ¶mûÌÏ%‚ üûÔüÚ‡&I¿þú+3fÌ(µÿêÕ«¼ùæ›\¼x(É\±bãÇfsªl€´°°k×®ÌíÛ·¹wï)))( tuu133ÃÔÔ”Úµkcll\*X™žžNvv6ÙÙÙèéé!I … 5jDýúõ±³³ÃÖÖš4iR©ŽôPPP@ff¦ÜѾ"iiixzzÒ»wovìØ!;«BÓ=^“Û¿Μ9Ù3gäÆI{ë­·8yò$›7ofÉ’%5Þkذa¸ººÆêÕ«Y´h/½ôºººÄÆÆróæM¹ËüðáÃY¶l§NÜgò IDAT"??¿R¯s·nÝ8qâþþþ¥ö;–¹sçrýúu­ó‚ ‚ ÂóäâÅ‹|ùå—ro===^{í5/^Lýúõÿ²y\»v RAáÙx/_æîÝ»âáá!o/**bÙ²e,^¼˜ÂÂBŒŒŒX¸p!|ðV†ä³ ÉêÔdþÙwß}ÇáÇ‘$‰6mÚÐ¥K^yåìììjäCDJJ ©©©$$$pÿþ}üýý‰‹‹ãþýû¨T*Š‹‹±²²ÂÉɉåË——9Fƒ ˆ‹‹#))‰V­ZUx¾«W¯2{öl¾þúkúõëW­9oݺ•Í›7ÿ[£©CêïïOaa!úúúZÏ9r$vvvÜ»w]»vñúë¯WëÜåQ(ÌŸ?ŸiÓ¦±fÍ>ùä,--éܹ3AAA=zT\vïÞ+++=zÄü!gšVäõ×_çĉ¤¥¥ñàÁ7n,ï«W¯ýúõãÔ©SìÙ³‡Ï>û¬F¯M„çßŋٽ{74oÞ\ëñ¬ßÇAáI.]ºÄ_|Á‘#G€’:þ&LàóÏ?ÿ[nîk2H5¥¯A¡FIϹŋK€4xð`y[DD„Ô¹sg ÷ݽ{÷/›ÓÊ•+%@6lX™ûïÝ»'åççÿeó)Ë£G¤¨¨¨r÷wéÒE¤;vT8Îþýû¥¾}ûJñññÕšGff¦4yòdùß ^yåI’$I¥RI¦¦¦ ”ùü%K–H€Ô®]»jÿIT*•dee%’¯¯¯$I’ôÅ_”úoN’$ÉÃÃC¤¹sçVjìââbIWWW¤>ø Ôþµk×J€Ôºuë§¿A^wïÞ•/^,999iý]üóÃÆÆFêß¿¿4sæLéÛo¿•öïß/EFFJ*•êï¾AáÎßß_1b„üž¤P(¤#FH—/_.󸬬,)>>^*((xfs***’LLL$ Üy‚ ÂÓxîkjêS:€•+WÒ¡C‚ƒƒ155eÍš5;v {{û¿lNñññ¥25š4i‚¡¡á_6Ÿ²XZZVØÝ±Aƒ@I7ÈòüôÓOxyyqäÈlllª<‡:vì(/ÉïÒ¥ ð¿¨ôìÙ€Ó§O—9ƬY³044äêÕ«ZåkŠ\ŽÁÛÛø_Ò“'O#[Õ:¤:::4kÖ €ýû÷—Ú?nÜ8ôôô¸q㆜U+Â?Ozz:ëÖ­£wïÞ8::òÙgŸ…¾¾>nnn,\¸±cÇÒ¦M¹|Çýû÷9sæ ëׯgÁ‚Œ=šV­Zabb‚££#/½ôsçÎeåÊ•øùùMQQÑß|¥‚ ‹ª¨¨ˆ;vЮ];z÷/:::Œ;–«W¯rèÐ!Ú·o_æsqõ› ‚ TÇs¿ÄþÆ8991qâDvïÞ ”,yÞ²eK…AÀgaÇŽ¬\¹ø_ ôy“••ÅÝ»w‰ŽŽ&::šáÇãââ¢uŒ¦îhY×P\\ÌüùóQ(ìÙ³ªÅÑ%IbåÊ•,\¸‚‚êÕ«ÇæÍ›¹xñ"—.]B­VËÇöïߟãÇsæÌ>ùä“RcY[[3fÌvíÚÅš5kèÖ­[•æR“&Mbݺuìß¿Ÿœœôôô´®ã‡~J§zzzÄÄÄY©g£Gfùòåܾ}›¢¢"yl€ºuëÒ¿Nœ8Áž={X´hQ_› ‚‚Ž;†¿ýöyyyò>ggg<==™>}:õêÕ+õÜôôtÂÃɈˆàîÝ»ò#""¥R)ÿ~üøq­çéëëckk‹ƒƒƒüpvvÆÅÅ;;;tuuŸùu ‚ /–G±iÓ&V¯^M\\†††L:•÷Þ{¯RKéííí ÄØØ˜'N`kkKݺuktž—/_J¾V¦€ ‚ TÕs ÍÈÈ»‹Ï˜1ƒÄÄDtuuY´hüq•wO#;;›9sæàåå%osuu-óØœœ:DÓ¦Mqpp¨Ñâå………¤¦¦’ššJRRIIIr ôþýû¨Õjj×®ƒƒŽŽŽ´lÙ[[ÛRã4oÞ€[·n•ßÝÝ!C†ðÖ[oUy~)))L›6Mî?pà@¼¼¼hذ!—.]Jš:¤.\(·ùÑ[o½Å®]»Ø³gß}÷]™…§Ñ»wolmm‰ÇÏÏO«©ÒáÇ婥¥%]»våÂ… >|¸RÒwß}—åË—£V«ùí·ßxå•W´ö»»»sâÄ vïÞ-¤‚ðʶmÛðöö–ß¿lmmñððàµ×^£E‹¨Õj"""077G¡P``` kaaA¯^½èÕ«W©ñJNÃÃÃ‰ŠŠ¢°°PÞögØØØhM5AT{{ûj5ÞA^\QQQ¬Y³†M›6É hkÕªÅôéÓY°`A•V©T*ŒŒŒÈÈÈ aÆÏdEƒ¦!o×®]k|lAA€ç<@ªR©äŸ±¶¶fçÎ 4è/GHHܾ}…B³³3áááò2õ?S(¤§§såÊbbbHNNFWWµZ……–––XXX ¯¯‰‰‰Örü‚‚rss)..&++‹´´4ùK¶$IèèèаaC¬­­±¶¶¦qãÆ 0€3f`ccSé ±ænðÍ›7KíûïÿKÇŽ«ú2qòäI<==ILLDOOO>ù„Ï>ûLž“æ øãÒŽ;R»vm²²²¸té}úô)5nïÞ½iÛ¶-×®]cóæÍ|ðÁUž[Ettt6lëÖ­ãÌ™3øøøÈû¢££)..–3¯†.Hßÿý'ŽÝ A,--IKKcãÆ¥¤cÇŽeΜ9ܼy“7nˆ¢ó‚ðÒ4’Û´i·oß–·×©S777<==8p ü7P­Vˆ™™ááá ««Knn.˜ššbffFƒ J5°kÔ¨‘¼àq………ÄÇÇkM5ÔØØX ä}'OžÔz®¡¡!ŽŽŽZAÓÇ‚ Â?C~~>ûöícÆ üñÇòö-Z0gΦM›FíÚµ«<®©©)yyy––Fff&íÚµ«ÑdM¢…¦d— ‚ Ô´ç:@úxFK÷îÝÙ³gOµjaVWyK޼¼ÇÔÔ´Ì癚š–›}™––&?²²²JO¡P`llŒ‘‘r ´¦—Fj¤±±±(•JŒ’%šU Žñå—_²dÉÔj5M›6eçÎtïÞ]ë8͇¤Ç—ØëééÑ»wo>ÌéÓ§Ë Ìž=›Ù³g³fÍÞÿý=zöìɺuë8zô(©©©XXXžžŽZ­fß¾}¸»»%Ò?þ˜óçÏ“‘‘A:už8v¯^½8xð |çûqVVVr™ „Dzz:>>>lÛ¶€€ùÆ¡¡!ƒÆÝÝwwwùoëãâââ055%55SSSÔj5¦¦¦èééajjЉ‰ 999dffrìØ1êÖ­‹­­-ÔªU«Ì×úúúå4 ¸ÿ~™ËöcbbP©TDDD”Y Ù¢TÀÔÙÙ™6mÚ`nn^¯¤ ‚𬅇‡ãååŦM›äú ::: 0€™3g2vìØ§þlݧOêÖ­KãÆqrrªÑàhaa!W®\D© ‚ðì(¤ÇÓùžCš Ä?þXk â³–’’«¯¾ŠŸŸƒ bÛ¶m4lØ‘#GrèÐ!~øáÞ}÷Ý¿lN5I­Vcff†R©$,,Œ¶mÛVkœØØX<<< J–Œ¯_¿¾ÌÀá—_~Éÿû_<<<رc‡¼}ÅŠ¼ÿþûôéÓ‡³gÏ–yžœœlllÈÌÌäСCŒ1¢Zó-OLL ( $Iâí·ßfÛ¶mdffòòË/Ë%š6mʽ{÷ؽ{7&LxâØ~~~r“±ÈÈÈRµœ6nÜÈo¼““S™½‚ <òóó9tè^^^øùùQXX”ÜÌëÙ³'S¦La„ XXXTiÜŒŒ òóóQ©TäääЪU+BBBP©TXZZbjjJVV’$¡V«)**"//sssZ´hArr2¦¦¦Õ*?’™™ÉíÛ·åÇ­[·äŸÓÓÓ+|nýúõiѢ͛7§yóæ8::ʵ•A„¿Wzz:;wîdÓ¦MrpJþvO:•™3gÊ%·žVVVAAAòMºÌÌÌj­F+Ohh(:uÂØØ˜ÌÌÌrå ‚ ÂÓx®3H/^ü—Ÿóøñã¼úê«$%%¡¯¯ÏǬµT<''33³¿|n5EGG‡æÍ›síÚ5nÞ¼Y­©3gÎ$##ƒZµjñÝwß1sæÌ Ï Ú¤ð¿:¤AAAäååÉ]îgffÆÔ©SùùçŸY³fMHíííiРIIILŸ>cÇŽ‘™™©µ `èС¬]»–ÇW*@úÒK/¡¯¯Oaa!«V­bõêÕZûÇÇœ9sˆŠŠâÚµkÕV ‚PóÔj5þþþxyy±wï^233å}NNNLž<™)S¦`oo_ís”uC©sçÎäåå‘’’Bbb"&&&ܼy“¦M›bllL£F000 99™ÌÌL’““‰ŒŒ$##ƒ¦M›bnnNݺuŸø>ennN§NèÔ©S©}>,4Õwî}ûö­ÑqAáq"@JI¦P—.]ä&I7æÑ£G,X°;;;ìììhÒ¤‰¼ ûŸ â±’$ñÃ?ðÑGÉ «¶lÙ"×Ö¬Œò–ØCÉ2{M€´"³gÏæÌ™3lܸ‘E‹•¹¿:‚‚‚ˆŒŒÄÀÀ>ÿüs äß877—ÈRcccúöíËÑ£G9|øp¥¤sçÎåÓO?E’$¶nÝʬY³´ö;–Ù³gsëÖ-ÂÂÂpuu­‘ë¡bšº¢Û¶mãØ±cò²@ºw»;S¦LÁÊÊ (¹‘røðaš5k†Z­ÆÒÒ333~ÿýw$I¢N:XYYaiiÉÎ;éÚµ+Íš5{æ×ahh(gÕwèÐAÞ®R©044äæÍ›¨T*tuu133£U«V#IzzeÈÈÈààÁƒøøøàççGQQ ýúxxx`mm-g'5lØðY^ª ¿VNNû÷ïgçΜ8qBþ›¬P(èÞ½;žžžLš4é‰MôNŸ>µµ5………ZïOC3Þ­[·ˆŒŒ”W^=­;wÎ3]¹!‚ "@ ÔªUKnÎ#I÷ïßçþýûek``@qq1P²ÔZÓ­ÑÑÑÚ·oO³fͰ³³«rS)M€ö¯¢ÉŠŒŒ¤   Üù¦¤¤0mÚ4¹QÑ Aƒðòò¢AƒU:_y¤ 88˜¬¬,j×®]æcÆŒ¡qãÆ|8GÅ××·RurÍÍÍ©_¿>ÉÉÉxyy• Ö©S‡AƒqäÈ|||D€Tž¡Çk´y{{Ëå4 $S}„ xzzÒ¨Q#011‘ÿÿ·°°`äÈ‘äç瓟ŸOFF¿ÿþ;˜™™Ñ½{w>|ˆ‘‘ 6Äßߟ¤¤$ å&JµkצN:ÔªUë™_«¦ã}·nÝäm’$‘’’‚™™Y™]‹•J%¾¾¾ìܹ“£GÊU€öíÛãááÁĉ±±±ÑSÓ¹:Í¢A„²sæÌ¶mÛÆï¿ÿ.—ú‚ÿ½gMž<¹J¥§,--¹zõªüwõu ‚ -<<¶nÝJll¬¼ÝÊÊŠqãÆ1uêT9;%??Ÿàà`š4iBXXyyyRPP€­­-†††XZZÁo¼‰‰ J¥R.Ÿqÿþ}ŠŠŠHOOG’$j×®¾¾>FFF¨Õjîß¿……AAAXXXдiS$I¢iÓ¦ÏüuP(Ô¯__kÛãAã]»vi½4iÒ„Ñ£G3mÚ´2ß' äìÛ½>· Âó 66–åË—ããããGäí666Lœ8‘É“'Ó®]»j]«V-êÖ­‹““ð¿F©5ªVF©žžžü]¤C‡øùùUk^eËëA„¿Šþ¿ °víZîÞ½Kݺu=zt©cT*< ::š7npóæMnݺ%Osrr´‚yyyäåå•@U(òì† âàà@=hÓ¦ ]ºtA¡Ppÿþ}bbb¸~ý:iiiäææ’——Gvv6ÙÙÙò²š?ÓÜ]ÕÑÑÁÜܾùæ›RÙJººº´nÝšK—.qõêU­/¾EEE|ùå—,Y²µZ;vì gÏžÕ~+Zb¯P(èÛ·/{öìáÌ™3.ÝŸ5k_}õ—.]"88˜Î;W{Nûöí###ƒúõëóÒK/1~üx<<!!!¥ºF=šY³fÍ•+WÊ D‚Py øøøàããSª®¨››S§Nåå—_.Õ÷öíÛXXXpóæMôõõ±²²’ƒ›&&&qöìY5jÄÑ£G±··ÇÜÜ\¾)¦ÉÊéÝ»7W¯^ÅÌÌŒÂÂB233ÉÈÈ V­Z¤§§Ó½{wîܹƒB¡ 55•¨¨(ÌÍÍiÑ¢=ÂÜÜœ´´4ìííålКŽ——Û¶mÓª»liiÉøñã™:u*={ö|âê†ÇoVuõ„ ‚PÚk¯½&—ž²°°`ܸqLž<™>}ú $$$”Ê*T(É_¸mmmå&EݺuÃÁÁ¡Ì¥‘UÕ¾}{.]ºDXX˜¼íÞ½{xxxÈ#Çdž žzYKE¤PR‡T ­HÆ 5j{÷îå—_~yê©fy½§§'YYYò]oOOO ¤ùÉÙ³gñ÷÷×zÞðáà çðáÕ vïÞCCCT*?ÿü3[¶lÑÚ_§NÌáÇñññRA¨&ÍñmÛ¶•Y7SS£­¢%îmÚ´ uëÖré}}}rrrHMMÅÞÞžÄÄDêׯOëÖ­144$55¥RItt4EEES¯^=”J%úúúØØØÈµ«U*ééé¨T*Œ¹xñ"={ö¤víÚ$&&¢T*Q«Õ$%%¡££ƒB¡ 88˜ììl,--155­öû@ll,»wïæ×_åÖ­[òvcccFŒQnи""@*‚Psâââ8{ö,Û·ogüøñ5z“ÌÆÆ†Û·o“ŸŸµµ5gÏž%99›j7uuu177G__Ÿ¢¢"¹_ÃÓÈÏÏgâĉܿ###úôéóÔc ‚ BERyѪ!M¥B¡ ::{{û_’$¹}û6aaa\¿~»wï’@rr2YYYrõI4T 6lˆ ŽŽŽ¸ººÒµkWš7o^©»Ë¿üò o½õ}úôáìÙ³x{{óæ›o’••…©©)«V­búôéU¾V¥RIBBŽŽŽò¶Ÿ~ú‰wß}777I÷îÝ ¢aÆevøÜ²e Ó§O§U«VDDDTëšáßèñ%â;wîÔªÑæì쌻»;Ó¦M«±%ìáááXZZbddăÈÉÉA©T’™™‰££#FFF˜™™QPPÀíÛ·±´´¤¨¨ˆ¼¼<Š‹‹±³³ÃÈÈkkk­/½¹¹¹(•JRSSÉÌÌÄÉɉÈÈHŠŠŠäeøjµy^^Þæ=xð€Ý»w³cÇŽRè_~ùe<<<9r$ÆÆÆÕz=RRRäÌ£ììl±Ì^á),[¶Œ>úˆN:\ãã'&&’““Cƒ ¨U«ÇŽÃÌÌŒN:U;»gÏhРAAAŒ7®Ú½rrr5j§OŸF__ŸmÛ¶1qâÄj%‚ •%2HÓ®];zôèA@@[·neÑ¢E5:¾B¡ Q£F4jÔ¨Üe"J¥’{÷îÌåË—‰ŒŒäÞ½{¤¥¥‘R©J‚­J¥RD–U×ÒÐÐ:uê`mm­­--[¶ÄÅÅ…N:Ѷm[ …\»èêÕ«Ì›7•+W%5AwíÚEëÖ­«t/^dóæÍ\¿~ùóçkHŸ”Aêää$7`ò÷÷gäȑ垧ÿþ´nÝš7n°eËÞ{ï½*ÍScË–-¨Õjºv튳³³œ5úxmÓiÓ¦ñæ›o¢V«Y»v-ü1={öÄÊÊŠGqîÜ9† òÄóyxxDbb"™™™¥ºŒº¹¹¡§§Gdd$·nÝ¢E‹Õº.Aø·Ð,ߺu+IIIòöF1~üx^}õÕëÐû¸´´4\\\JÝÌÉÈÈ ''‡äädîܹƒ¡¡!‰‰‰H’D½zõhÙ²%J¥•J…Z­æÀÔ¯_Ÿ¼¼<úõë‡R©¤yóærêÎ;“••Å£GP«ÕrI'•<ÉÌÌäÀ•ê@ÿ´ 222D€Tá)ìØ±€)S¦”¹_“PQUYYYáèèHvv6ØØØ IÒSe©vêÔ‰ÄÄDŠ‹‹ÉÎήvóÙôôt†N`` †††x{{3f̘jÏKA*M´lذA$;;;©¸¸øïžNYmH IDAT)¹¹¹Rpp°´fÍiöìÙÒàÁƒ¥–-[JVVV’¾¾¾Tê¡P($ccc©^½z¥¶Ï›7OÊÏϯôœ ¥Í›7K=zôfÍš%•yÜÊ•+%@>|x¹cMžqâD ÞyçJS©TJ …B¤o¿ý¶Ìcz÷î]á~Aø·‹—~üñG©]»vZ¿Œ%wwwéàÁƒRaa¡¤V«¥˜˜)""BJII©Ñ¿éþþþ•:îôéÓ’$•ü½ÉÌÌ”bbb$I’¤S§NI»ví’Ο?/]¾|YÊÏÏ—bcc¥””éøñãR`` ôÇHAAAÒÅ‹¥›7oJÑÑÑO<ŸR©”<(M:U211Ñz}œ¥Ï?ÿ¼RãT‡™™™HaaaÏd|A„ƒÐÐP ôôô¤ÄÄÄ2 ’vìØ!:uªÊ㧦¦JçÏŸ—~úé')))I*,,”¥Ÿþù©æ}íÚ5éðáÃÒ­[·¤­[·JyyyU#11QjÛ¶­HfffÒ‰ÿÇÞy‡EumÿK‘ÞEPÁ†¨±›`Çб X‚±¡#[BEM æ½1&Á`Ô`DÁˆ€ˆˆ,TEЍHï]zõþÁoÎu¤ÍÀ£wžç<9gŸµ×ž{ÙsfµÖ7°K>1 ƒ! ,ƒô5–-[†/¿üééé¸uëfÍšõ¶]@AAcÇŽm!ðç¾¾‰‰‰ˆŒŒD\\ž={†ÌÌL ¼¼œëG¯d ò‘——‡‡‡LMM…ò…Çã᯿þ‚½½=fÏž ¨¨¨´9¾=‘&>FFF¸páB‡}H`íÚµøî»ïðâŠܼysæÌÊo>·o߯‹/ ''‡O?ývvvcccôéÓG`¬‰‰ Μ9ƒ„„óóçχ»»;®]»†ßÿ½Ã9åää ««‹ÌÌL¸»»ãÛo¿m1fáÂ… …O«×ŒÿE^͆ô÷÷Èž122‚……–,Y"¹˜‘‘Á Ú¥¥¥!;;ºººHKKƒ²²2´µµ¡¤¤ÄejŠ‚0Y1èÕ«7^EE…Û#üw/–””Dbb"ˆêêꀲ²2†Ž¢¢"444 wïÞ­ÎÓÔÔ„àà`¸¹¹ÁËËK@^OO+W®ÄŠ+0lØ0‘×) Ý»wGee¥€Ú2ƒÁ`0DãüùóšŸ={öìÙê999ÈÈÈp}­…þ.ÓÔÔDJJ –,Y555„‡‡#11±Å³¯¨ÔÖÖB[[0`€Èß­ééé011áD¯_¿Ž‰'vÉ'ƒÁ`0DH_CEEK—.…««+œ¤‘‘ššÚ[ô°}ddd0fÌ®tþuˆ ˆˆˆà¨QQQ(((@=„2FDDà믿ÆìÙ³qãÆv£|:*±š¤ðøñcASS³Í±ÊÊÊX¹r%þüóO?~\ä)_œiÉ’%PQQ››ÀÂÂ¢ÅØmÛ¶áÌ™3¨¯¯Ghh(¦N ˜7o¤¤¤’’‚§OŸbÈ!Î;gΜ:u ?nµühÑ¢EرcîÝ»‡ÂÂB±”¿2ï"MMM Á¹sçpåÊÑ~KŒµk×¶ù²o߾ܿÐÔÔ„¬¬,ÈÈÈ ªª Ïž=ƒ‚‚TUUQPPUUU¨¨¨@QQ‘ûÑÙíícüùž¢uuu(**‚¬¬l›‚ááá¸xñ".]º$Ð^@KK Ÿ~ú)V¬X‰'vºœ¨ôë×éééxòä ·—3 CxšššàîîXµjU›ã"""   €>}ú ¾¾7oÞDee%ŒŒŒ„R¢ÏÌÌ„‚‚tuu1bÄ(((tù÷MEEŠ‹‹¡¥¥…¸¸8Œ3Fh±¿èèh,\¸999ÐÑÑÁÍ›7ßøK=ƒÁ`0^‡H[aõêÕpuu…ŸŸŸÀÙØØXüöÛo¨©©ÁäÉ“1~üxŒ3Fl¢ÿ1b„@oÑ—/_¢ÿþÈÈÈ€»»{›ýŽ€æ·ÃûöíC||<.^¼(ÒÛæŽ @s¶Sÿþý‘––†;wî`éÒ¥íŽßºu+áçç‡ÔÔT¡…µ*++áåå°´´Dpp0233¡¨¨ˆ%K–´?zôhÈËË£¦¦þù' ÕÐÐÀøñãqÿþ}\»vM¨©µµ5N:…††NlêUôõõ1tèP}ú gÏž(,,DYY„ ŽÖÕÕ¡¤¤÷ïßLj#P^^Žüü|”””tI vâĉÈËËƒŽŽ–,Y"ô÷§§'Ö­[‡êêjèëë#00ðúmÅ`0Œ÷ m…3f@II eeeç„0LLL`bb‚ÚÚZÜ¿‘‘‘ðôôDzz:¤¤¤Ð³gOôïß:::èÞ½;wHJJ¢[·n\é§´´4”••4ÿ~Um¹²² Ð××o!àó¦PUUÅ–-[pàÀüúë¯mHŸ>} KKKlÚ´‰+G~i}G åg̘ggg„„„t >|8¦L™‚ÐÐPœL™™™oÛM"jÞ§÷ìÙCZZZœ’’’´`Áº{÷îÛvÁ`0Þ9\]] õêÕ«ÍçÑììlºrå ?ž²²²(??ŸéñãÇT__ßátùòeòöö¦óçÏÑÝ»wÉÝÝ¢££»äÿ“'OèÞ½{DDäããCÏŸ?os ãÆ#$%%Evvv]š—Á`0 qѵZŠ÷¾XFLL JJJÄb³¡¡nnnعs§Xì‰~ö¤›››@¿Ð‘#GÂÛÛ»ÝÌH"¹sç°hÑ"¬]»gÏžm‘)*liŸ>}¸>meX¾J·nÝðÙgŸŽ?Þáx'''¦M›†âܹsš×ß^ù¿¼¼<'Ão Ï‡/åçç×áü°råJîs8vìX‹ë’’’œ¸ËÍ›7…²É`¼« 4@s‹‹U«VAOO@s¹ú¥K—`mmI“&AUU“'OÆ×_ dff¾M·ÅBSSaii mmm˜››ÃËË uuuÐÓÓÃwß}‡„„<|øß~û-WÆ.JJJ’’"ôx"Bpp0–,Y‚à§Ÿ~BAA455±sçN¼xñ>>>˜îÝ»Ç%¤0 ƒñ¯àm¦¯þÛ™5k ±Ù,++# úøãÅfóuÊËËéÂ… dffFrrr´xñb¡ï6m _ýµÃ±´cÇš7o^›e4¯rðàA@Ë–-ëp¬›› }}}¡ü&"Z¼x1  6´9æúõ뀔””¨¢¢‚öïßOhüøñBÍqïÞ=®œôÕR¤ÊÊJ’““#.”-kkk®¼¨µRªÂÂB’””$”’’"”Mã]ÄÈȈÐéÓ§ÛÓØØHñññäââBVVV4lØ0îïãÕCZZš† FVVVäââBñññÄãñþÁÕ´Mjj*ÙÙÙÑàÁƒ|–——'sssòññªDRx<…‡‡Ó·ß~KÓ§O§mÛ¶Q@@€Pí ’’’ÈÆÆ†ÔÔÔ8_eeeÉÜÜœÅê'ƒÁ`ü/ÃoC5lذvÇ%&&’³³3QNN=zôH¤çÄëׯӣG(77—ˆˆ®^½J”ŸŸßùQZZEDDÐË—/©¬¬Œ;Ÿ™™IS§Nå¾G–,Y"TÛ.ƒÁ`0þiXi;Œ9¸7¬â@UU;wîD@@BCCÅfhn`ee…Þ½{cÕªUˆŒŒÄ† °ÿ~¡mð³?ùo±ÛÂ××&&&1büüü¸’øöHKK œÂ1_­:99ééé;Žf±& ¹D©­¶ÎÎ΀eË–AII‰koaa!Ô“&MâÈ¿Zί¨¨ˆ3f¾ÌÞÚÚ@sf­O‹ëšššøè£BÙd0ÞW¤¤¤0|øp¬Y³ŽŽŽHHH@ii©@–©††‘˜˜ˆ“'ObíÚµ1bÔÕÕabb‚}ûöÁ××eeeÿ˜ß999øý÷ß1eÊèééa×®]xö줤¤0kÖ,¸¸¸   X°`P%’ÂðèÑ#|ûí·022‚§§'ÌÍÍÌž=²²²­ÞÇãñ¸ý}èС8tèÊÊÊлwoØÚÚ"33mV 0 Ct„yÍÏÏÇóçÏ!))‰^½z‘””$”@(UUUMÆÆÆóKJJÒôéÓÉÑÑ‘Š‹‹Å:'QQQ988±±1mÙ²…ÂÃÅΞ‹‹£;wrû’ Ù³g“··w»v ƒñ>ðøñcÚ²e Í™3‡ÒÓÓÿ±y¹ïˆŽæ½~ý:ݸqƒ***(..Žþúë/úý÷ß©¡¡AèùBCCéêÕ«”@töìYúã?ºº ***hË–-œ¸é°aÃ(..N¬s0 ƒ!nX€´ÂÂÂõìÙSì¶ùÁ4ÿNÛðòò¢Ñ£GêׯÙÛÛSIII—ü*))iU]½¸¸˜¾üòKš;w.=~üXh{ dcc#œ¦ÄžˆhóæÍ€Ö­['ô|ööö\iþëþg>hÐ âñxœ}QZ¤¦¦r{JJJå°)))\P!;;[({óæÍ#¤ªªÚêõ¿ÿþ›ŠŠŠØKoŒ â ¶FYYݸqƒöíÛGsæÌ!uuõSÔ½{wš?>ýç?ÿ¡   ‘^u¬@ÿóÏ?SFF†Ø××ÔÔD´víZZ¸p!¹¸¸PUU•P÷666’—— ø«¨¨H_}õ•ØÇ ƒño£¶¶–Ο?O†††ûà| ÒËó®°gÏ@FFFíŽ‹ŠŠ"'''¸¸˜œœœèúõë"ÍLÁÁÁTPP@µµµDwïÞí´ÿ¯Jƒ â>K ª¬¬›}ƒÁ`0Þ,@Úñññ€Än»¶¶–úõëG"÷Ç{øð!͘1ƒ ö={V¬Á³^½z æÎíÝ»—|}}E²SXXÈ>ø™•híÚµBÝïééI¨oß¾BÏYZZJŠŠŠ E¼>úˆÐ¨®®Ž455 ]¹rEhûûöíãú† ;wî\çg½ž9sF({W¯^å>Ÿ/^´¸ÞÐÐÀe™†…… í'ƒñ.ñ&¤¯Ããñ(11‘œœœÈÊÊŠFŽÉý=¿zHIIÑÈ‘#iÆ töìYJLLl±W766ÒÍ›7iݺuÜß)ÿ0`}÷Ýw”ðFÖñôéS²µµ¥©S§’HýçJJJèðáÃ4`ÀlQníâì½Í`0ÿ6’““içÎܳ ?ƒsΜ9¤­­Í½Üêj_ÎŽàñxÔ¯_?¡¾+++)""‚KTˆ‹‹£;wî<¯w?¨zæÌJJJ¢ÜÜ\:räݸq£Kë jÖ@Ø´i—HгgO‘ž± ƒÁxÛ°i;¤§§sMo"{_Âùòe¡ÆWUUÑW_}E’’’Ô½{w:zôèñkæÌ™€Ž;Öi>¤þýû’““#gggÚ»w/ KKK¡lqå©­ÛâóÏ?o‘Ç=üfddÐåË— ihh%V‡/®2jÔ(@»wï¸þí·ßŠTßÔÔĵøê«¯Z³hÑ"@{÷îÚOã]⟠¶Fyy9ÓþýûÉÔÔTà󫇚šÍ™3‡¶nÝJ+V¬ ž={ \×ÒÒ¢­[·Ò½{÷Þˆ0TSSy{{“©©)­[·Žþþûo‘æIHH 7r/‘ø™ð[¶l¡¤¤$ª©©¡O?ý”»öå—_²Òzƒñ^DóæÍhÒ£GÚ¹s'÷¬ÃU|ðÁo4›žßÚJNN®Cá¢ÈÈHJHHàZ´Ü¾}›Nœ8A=iΜœŠ%¢æ„ÜÜ\‘Jô[# € ô ssó,—Á`0 qÁ¤íPZZÊ}Ñ·×/.++‹èèÑ£´ÿ~²±±¡7ÒªU«hÆ ´sçN:xð 8q‚®\¹B T__O 4dÈ6lX‡?BïܹC$ Ú´iS—KéÛ­­m§îwss#@ºººADÿ-!Z¿~½Ð¶ø-D œüðCîEÆë‡²²2YXX¿¿—`¶ÅË—/ÉÑÑ‘f̘A¶¶¶"ýèäUgÍšÅeõð÷{{{¥a¢æl¦Ý»wsãÌÌÌXi$ƒÁx§©¯¯'?~¼Àþm``@ŽŽŽT]]Ýâž„„®'³²²2¹»»¿ß6lØ tû©_ý•\]]©¸¸˜x<¹¹¹ÑÅ‹EzQVSSCÇçªâããéôéÓ-*¢„%''‡,,,XÖ(ƒÁ`0Þ ¤ÁhHHH€ˆP^^ ëW¯^ÅáÇѻwoŒ=úúúøàƒ ¬¬ %%%ÈËË£¡¡¥¥¥(++Cii)ÒÒÒpãÆ $''£®®ªªªˆˆˆ€››[«Ê•DìØ±ººº ÄÌ™3ßèº{ôè(,,龦¦&|÷Ýw8tè`Ê”)¸|ù2´µµõõõЦzrk!66!!!X¿~½P÷Œ=“&MÂýû÷qúôiüðøpáÀÒÒÅÅÅð÷÷ ¼z=8;;hVÓ^´hvìØØØXäää wïޚ׬¦¦†²²2„†† ¥ô¼téR$$$ 55uuu->###@tt4*** ¬¬,´Ï ƻ̵k×Я_?Œ9òŸ{РA4h·GTUU!** ¡¡¡Ø»w/àÏ?ÿ„……ÞˆÉÉÉ8}ú4¢¢¢°fÍܼySh•û—/_âÌ™38vìRRR011Á¶mÛ0þ|HJJ¶¸OBB?ýôˆ/¾øÞÞÞ˜1c|||8ÕdƒÁx(--ÅÉ“'qôèQdggddd°råJX[[cÔ¨QmÞ;lØ0Ü»wË–-CDD–/_ް°0û瑩®Ž{Ëœ™™Ùâº8²…òóóiĈ¤§§×¢\þåË—œˆ¦¦&‘¹¹9­]»–¶nÝJ¶¶¶ôûï¿ÓùóçÉßߟbcc[} .*IL‰¨¹§‘‰‰ ÷yYYYµXÏöíÛ¹²Mañöö&Ô«W/¡ï!"ruuåʦ.]ºÄ•ÇVWW“ƒƒ Áƒ m¯¦¦†ÔÔÔ¸õýý÷ßôÁ:{ö¬ÀØeË–µ[2ÿ:œ]''§VÇð³nÞ¼)´Ï Æ»B[¤·oߦmÛ¶‘‘‘­[·ŽÜÜܨ  à-yÙL^^÷÷*¬’(ðx<òóó£… ÒÚµk)**J¤ûŸ={FÛ·o'%%%ÎO999²°°YA8((ˆÛ÷tttèáÇ"ÝÏ`0oƒœœ²¶¶Ø544h÷îÝ”““#’­ºº:Úºu+g§W¯^äääDMMM]ö“ßk_CCƒêêêÚO—.]"???ª¨¨ Gúéû¿ IDATÑ¥K—(11Q¤9“““ÉÅÅ…ûnyðà=z”üüü„¶qçÎ9r$÷™ 2„=Ÿ2 ã½ eúƒ£ªªŠûwko‹¥¥»ž€«¥¥…ƒ"%%gΜáÎgggcêÔ© „ƒƒ qíÚ5œ8q?üð6lØ€éÓ§CGG•••ˆ‰‰££#ÌÌÌ0mÚ4|üñÇØ¾};NŸ>'Ož€ˆ„öIEEPYY)Ôø¸¸8Œ7••ÅéÓ§áèèØ"Ó©¡¡@óÛ{a™>}:¤¤¤››‹§OŸ }ß²eË ¥¥…ÂÂB.£uÕªU——ǹsçëÖ­ÚÞÕ«WQVVÆewcîܹ€7nŒ?>À××W(Û=zô€¦¦&€ÿf©¾Î”)S¡¡¡BûÌ`¼ëLŸ>¸uëöíÛ‡ªª*lݺsæÌÁ¡C‡DÚÄEEE€æLryyy±Ùmhh€««+Œ‰“'OÂÙÙÞËãñ„ `È!ppp@ee% ;;;dggãܹs1b„H>Íœ9aaaèׯ÷týúõÎ.‘Á`0Þ(غu+ôôô`ooÊÊJèëëã?þ@FF~úé'‘3áeddpôèQ\¾|ºººÈÍÍ…¥¥%Ƈ˗/£©©©Óþò«›–/_Þá³quu5””” ­­ %%%”——ãùóçB?«ó‘””D}}=êêêPZZ L›6«„jôôt¬X±3fÌ@\\TTT`ooøøx˜˜˜ˆäƒÁ`0ÿJÞv„öß̳gÏIKK¿q¡ŠI“&‘ŽŽUWWÓ“'O¨OŸ>¤¬¬ÜiUÉÊÊJŠŽŽ¦³gÏÒºuëhâĉ´bÅ ºxñb‡Màÿøã@sçÎípRQQ!Ô»woºÿ~›cׯ_OhÏž="­eìØ±€Nœ8!Ò}»víâÔ™PTT%&& ˆ5 Ëܹs —é6yòd  ¤®®.M\PPÀ5ÿ¶±ÿ'Ÿ|BHAA¡ÕëG%4}út¡}f0ÞDíAZ[[Kþþþ´qãF222"ŠŒŒl÷ž¢¢"º~ý:ÕÔÔtÉ×èèh@ªªª]²Ã§¶¶–\\\hêÔ©dgg'R¿Ï—/_Ò‘#GH___@~æÌ™tõêU±d85gcñ÷ánݺý«zÅ2 Frr2­_¿žddd¸½p̘1äéé)¶}¨Y,õ‡~àúì ===:räH»Z­Q\\L²²²€îÝ»×îØ’’ºpá999Ñõë׉ÇãÑåË—)**Jäj¶‡RDDQFFyzzRtt4'ÚÔ•••dkkKrrrܺMMMEzŽf0 ã]€HÛ!((ˆPß¾}ßø\ÁÁÁ€¶mÛF½{÷&---Љ‰ëÏŸ?§_ý•ÌÍÍÛ ø;vL@Ш5x<ÙÙÙqÀI“&uX¶ÔYñ§;vˆ\òOD”ššÊùÇ/§·±±!4sæL¡íäååq-^^^\Мˆˆ³áííMóçÏ'ôý÷ß ÜóŸÿüGä@,?óáóÏ?oqÇãQ÷îݹþ§ Æû„»»;ijjr{Ф¤$ÒÞ½{©¢¢Bh; äëëKË—/§ Ðùóç[}¡P\\LdaaA†††dccC¡¡¡Bí/üÌq}}}‘ÖÈ'??ŸlmmÉÈȈ\\\„®Nhjj¢ëׯӜ9sÔèû÷ïO?ÿü3•””tÊaÈËË£#GŽ€4S·g0oƒœœÚ¼y3uëÖÛ¦L™Ò骫WyðàEFF µ§–••ÑáÇiРA{c÷îÝiË–-íVU 4ðäÉrpp ""*,,¤ÄÄDÊÏÏz]¢âããCÆ ãÖÔ·o_ºpá <3 ƒñ¶aÒvؼy3 Í›7ÿ#óEGGÓØ±c[Í ü'±³³#´téÒמ={Æ=0IKK“Ðv—,YBèçŸÉŸŠŠ î!X”Àqxx8çgnn.ݼy“¢¢¢HA—Q£Fúå—_ˆˆÈÒÒ’Ëöå—¾ÜÕ£–•• 5?øÐVf?{KÔ3ƒñ.P[[KçÏŸ§)S¦üД””$###úã?(--Mh{%%%tâÄ 222"[[Û6H666Rhh(ÙØØÐôéÓÉ‚<<<Ú þݹs§K¤ÖÖÖ"ôøòòrrpp Áƒ |.FFFtåÊ•7Öþ¥ººšÜÜÜhÞ¼yÙY¯¯ ñ1 Æ›¤¤¤„víÚ%Pâ>yòd‘öÔ¶(--¥ÈÈHruuíTéø½{÷è‹/¾ }rèСôË/¿|¥¦¦r/º„iÅE7nÜ ÔÔT""ºxñ"=zôè¼ §3fpþ+**’­­­XD` ƒÁø·Óu•¡÷˜˜˜À˜1c„¾‡ˆ››‹ÂÂBsGII ÊËËñòåKðx<Í"Põõõš?TTTðÑGáâÅ‹¸xñ"”••¡©©‰=z {÷îÜ¡¥¥)))ñ/øÿ(--tïÞ]༿¿?V®\‰²²2hjjâÒ¥K066ÚngDš€f¬±cÇâþýû¸uë–ÐB#NNNSSSôìÙ;wî,]º´UÑ­Öxøð!?~ iii¬\¹0kÖ,899!00ÖÖÖØ¶mbbbŸŸmmmÍÿŸÑÑÑAvv6‚ƒƒ±dÉ’çZ¾|9¢££‘ŠŠ (++ \Ÿ:u*|||˜Pã½DVV«V­ÂªU«CCC”——ƒÇã!$$!!!غu+FSSS,X°ãLJ¤dëZƒêêêØ´i6mÚ„°°0lÞ¼ŠŠŠØ±c‡À"%%…)S¦pBhOž<¯¯/>ùä(++ÃÍÍM@OAA@³`Fgøí·ß„÷üùsüñÇpvvFyy9@^^«V­Â¶mÛ0jÔ¨NÍß<·o߆««+®\¹ÂÍ Ã† ÃêÕ«1~üxÌš5 RRR-„ø ãMPSSƒ#GŽàðáÃÜ3ê¨Q£pàÀ˜ššvÉvSSž ¼½½AD˜8q"ܡ휜TWWs‚LuuuˆŠŠÂ!Cº´öWyöìöìÙƒ+W®€ˆÐ­[7XYYá‡~€–––Øæa0 ãß ¶AEE¢££üWAüu¢¢¢Œ´´4¤¦¦¢ºº’’’èÝ»7zôè hhh {÷îèß¿?444 %%EEE.H(''yyy¼MMM¨®®FUUŠ‹‹‘••…ØØX£¨¨ùùùhjj‚´´4tuuѯ_?ôë׃ưaÃ8EôÎR\\ à¿R"ÂÏ?ÿŒ={ö€Çãa̘1ðòòBÿþýE²Ë‹ ###Ü¿!!!ؾ}{‡ãkkkqéÒ%€¥¥%ªªªàååX³fÐóòïgÏžÍ)ŸÎš5 HJJ‚´´4 „çÏŸãæÍ›°°°HHH`îܹ8}ú4üüü„ nܸ;wîÁÉÉ©Å:§M› Ccc£@ІÁxŸ1b>øàDDD@FF†Û;àñãÇxüø1~úé'tïÞÆÆÆ055…™™TUU[µÇ€ÆÇÇãÈ‘#(**‚½½= ÐbìСC1tèPìܹ555-þκ 툰°0888àÊ•+œ:r¯^½`ee…­[·vyoøøx¸ººÂÍÍ YYYÜymmm¬X±«W¯† ..@s@›Á`0Þ$D„‹/b×®]ÈÌÌèëëãÇÄòåËÛ|A&¬í§OŸ¢OŸ> " oß¾HLLÄ‹/`ll,tpôUdee±dÉ,Y²………puuÅ™3g˜˜777\¼x‘ûY½zµP6srr0xð` 2ÉÉÉ——‡¼¼<äääDöïuŠŠŠðË/¿ÀÞÞžû®555Åo¿ý†AƒuÙ>ƒÁ`0ïo/yõß··7§ÌÞ÷ïß'___Чªªªлf(55•îܹCÎÎδ{÷nZ¼x1’±±1YYY‘ƒƒ…††ŠTR¾xñb®¾¢¢‚SX@Ë—/j­999-J? :uJäµRSSª¤ÔÍÍ––Õ×ד““ ¡KR¨gÏž€ÜÝÝ®=š““m߾Њ+Æð´´´„VQíÝ»7׿5ø¢Pâðb0þmÌ;—Û‡lllHJJŠŠŠ Mš4‰û[àÒÒÒdhhHvvv”””Ԯ킂*//ï”_)))œZ¼¸Ô‘+**ÈÑÑ‘†.°&rqqY¥XrrrèÈ‘#\<þ!''GæææäããÓj }DD ±ûÄ`0|îÝ»G&Làö¦ž={Ò‰'ÄÒÚƒÇãQHH¹»»Sll,•——Sqq1yzzR@@Ày¦ÿûï¿iþüù\i½„„vx_YY]¿~._¾LDͽAoݺEAAA]ò§¢¢‚lmm¾Kg̘Aááá]²Ë`0 Æ» ¶_q}ýúõoÛ•NQWWG téÒ%Ú¹s'Íž=› É‚ìíí©¸¸¸Í{ÇŒCÈÁÁFŽIHJJJè~£gΜ¡©S§Rii©Àù±cÇ:}ú´È멪ª"YYY¡ƒƒ&&&€¾ùæ"úopv÷îÝBÏéããCHUUµEï¥o¾ù†ÐªU«8) àkee%ÉÉÉŠŒŒjεk×rj¨­5Ÿ:u* “'O ½ã]„¿ó,îÝ»'ЇsÉ’%tùòeÚ¾};éèè´è©§§GÛ·o§ÀÀ@±‹‹‹¹9ŠŠŠºdëÅ‹dcc#гNVV–,,,ÞH/êêêjòðð SSS¾¢|Q,GGÇÇ¡¡¡¾¡æŒŠŠâX[S«ÿúë¯Ûô‰ÁxŸøê«¯mݺ•;WYYI[·nå~8÷ìÙ“¼½½‰ˆ(>>žìììÈÐÐP@åÿ§(lnnN...B‹¦µ‡ªª* ˆˆˆNÝJæææÜ¾€zõêE¶¶¶Be‰Bcc#……E‹¬Û‘#GÒÏ?ÿLYYYBÛã‹Ý 0@¬~2ŒÿmjjjèÇ$yyy.ÃòÓO?儉ºJNN…„„еk×(>>žˆš_„;99Qll¬Ø*ˆ¨ÍJ¥{÷îq/¥;e»²²’233;%šäìì̽¸ç¿èrrrëÚ ƒÁx—aM [ÁÝÝèÕ«—H"Do“êêjÔÕÕhn8ÿª¸FEE4 %©««#>>ñññ¢QuuuÈËËãî---ÅÈ‘#áåå…¶;pp0lll°ÿ~Ì™3§Õ1ü~zZ£‘‘îܹƒ|óÍ7mŽsvvFSSÆÇ5ñçÿ·°O¥¥¥ðõõÐzÏÒiÓ¦AVVùùùxñâ¦M›†7nÀßß&LàÆÍŸ?7oÞ„ŸŸlmm;œ×ÀÀòòò¨©©ÁñãÇ1uêÔ׿þ· Æû ¿rQQwNQQGÅòåËaii‰çÏŸÃÌÌ æææ8qâlll`ccƒ‚‚ܸq×®]ƒ¿¿?Š‹‹áéé OOOHKKc„ X°`-ZÔ)‘ }}}DGG#99ãÆêžÚÚZxxxàðáÈçÎ`ûöíX±b…XEàéé ¤¥¥qç{õêsss˜››·Ù_»=^ïQÍ`0]% Û¶mÃóçÏãLJ½½=&OžÜeÛUUUxúô)222 ªªŠaÆAVV>>>øðÃѧOŸ.Ïñ* HJJÂÔ©S[ˆýç?ÿ˜››cèС²¯¨¨EEE‘î Ç·ß~‹°°0ó¹¹¹8zô(222°`Á|øá‡ò‰Á`0Œ÷ m…£GtuuñË/¿TUU¹fð HJJ‚¾¾¾€xHMM jkk4«¿|ù’»öªb}cc#***¸k|a& YȨªªŠ»VVV"Ðü»¦¦@ssù²²2ñ.ü5–.] ggçvßëêê`kk‹””´û£™/ÎôìÙ3ÔÕÕ‰,ò1cÆ ÀßÿݦHÁÅÅ@³8œ?€hâLîî«Ã€Z}@WPPÀ¤I“pûömbΜ9\€tß¾}Ü8SSS|ùå—ˆŽŽF^^zöìÙáÜ í[·Z\;v,€f¡”ššÈËË ½&ã]BMM ^öð144DLL vìØGGGxzzâîÝ»8uêæÍ›---¬Y³kÖ¬AMM îÞ½ ___\¹rYYY¸{÷.îÞ½‹]»vAOO¦¦¦X°`f̘!”øÙ AƒÍý˜oÔÔT8::âÔ©S())мš™™á믿ÆÄ‰EüdÚ&;;.\Àùóç91%PRRÂâÅ‹±zõjÌœ9RRRžƒ°~bQ ㋬¬,X[[ãòåËš÷;;;|öÙgè²ýúúzÔÔÔ@BBýû÷‡®®.bbbPTT„ &ˆ=8úüùsÄÄÄ`ܸq-‚£QQQð÷÷‡„„¾ûî;±ÎÛ)))سg<<<@D‘‘ÁªU«Ð£Gܼy=BLL bbb`kk‹~ýúaÁ‚033ÃôéÓÅúÒŽÁ`0Œw‚·›Àúï#++«E/»wýPRR"uuuRWW'---ÒÓÓãŽ?ü ÈÀÀ€&OžLãÆ#$##ÓjÌWIHH iÓ¦‘£££PŸ­¦¦&瓯¯¯ÈÿÛÔÕÕµYÊ·/æ$''G%%%ôàÁ@ݺu©tuâĉ€~üñÇ6Çìß¿ŸÐìÙ³ééÓ§\ÙT~~¾À¸!C†:{ö¬Ps;::rŸSAAÀ5Gjjjí~ ÆûÀï¿ÿNhÁ‚íŽ ¤¾}ûr3æææíöXG)þ÷ßÏõ n ~ý«½>{öìI666”Ýñ $ÂôE¤¯#öîÝKhÍš5b³É`0þ·hll¤_ý•kû!))IŸþy—û:¿ÊßÿMÞÞÞ\ù|zz:yyyÑ7Ä"ôô*BW¯^¥üü|ÊÊÊ¢»wïRII 7fáÂ…€/^,Ö¹[#&&†V¯^MݺuãÚ˜››Srr²À¸´´4rpp Y³fqcù‡ªª*-_¾œ.^¼(–Ö4 ƒÁ`¼ ° Ò×ÐÑÑÁ¡C‡ðüùs ÐWKÑSRR’’yyyLž<™{Ë-//999€¤¤$TUU¹û¹ Jiii(++s×”••¹¬%Ò555ξœœ—1(!!ÁeXÍüŒL)))¨¨¨tjý 1b$%%Û|{OD8uêÜÝÝqæÌèëë e»ººšû÷Ù³gajj*’o222˜4i‚ƒƒ"PÊ%%%X¹r%`ذaPWWǹsç4—º ›ñôüùs„‡‡CBB«W¯nq½¾¾^^^¸rå ((ýúõÃÀñâÅ q~ÍY¤OŸ>…ŸŸ—ÕÚk×®Å_|GGG|ÿý÷Ü5  88QQQ->ã}ŸUßQ¶ã¬Y³‡;vàÔ©SðôôDXX±`Á‚㇎áÇwXŠ/%%…‰'¶ZŠÏou*`»®®—.]Â/¿ü"Á)î2z‡[·náܹsðòòBee%wmذa\öl¯^½º<×ëzôè!vÛ ãý'..ëׯGdd$`̘18~ü8&Mš$û………ÈÌÌDqq1&Mš £¢¢&L€ŽŽŽXæáÓÐЀ²²2¤¦¦ÂÜÜÕÕÕ¸sçÆŽËýxôè|}}!!!½{÷Šu~>DüöÛoæÎâðáí~¾ýúõömÛ°mÛ6”••ÁßßÞÞÞ¸qã^¾| www¸»»£[·n˜>}:ÌḬ̀páBôíÛ÷¬Á`0Œ· ¶ÂÎ;Û½~êÔ)XYYaòäÉ Ú.¡¤¤„;***PYY‰úúz”••¡¾¾¥¥¥÷ð{‹¾ZâÿjÐôÕ«««sÁQUUU(**BIII Û šËù›ššZ' `ee…>øBÿØojj¾X###.@ºk×.î|vv6LLL¸ïŸ}öêëëááá@´òzggg¦OŸ===î|ZZNž<‰³gÏ"??Ÿ;ÏãñðàÁ|üñÇ8~ü8üýý¤óçÏǯ¿þŠÀÀ@Ô××sò¶••Eß¾}‘––OOO)Ð\fŒèèh¡×Ä`¼k 8::béÒ¥øüóÏ‘™™‰… ÂÂÂÇŽksìl)¾¡¡!¤¤¤‘‘gÏžAII 'OžÄüÁõèä—ÑõÕWbé£4¿Àruu…‹‹ òòò¸ó:::Xºt)Ö®]‹>úH,sµ¿ÄžH †(Ô××ãÀ8xð  ¨¨ˆýû÷cëÖ­Bµ6iÆÆF466"::EEEÐÔÔ„±±1ž={†øøxŒ7ÇÓJþK~~>®^½ ###XZZ"22III:t(ÌÛ¿?ˆ¦¦¦bï󙜜Œ‹/âÂ… xúô)€æ$ SSS|ýõט>}ºPvÔÔÔ°bÅ ¬X±õõõ¸sç¼½½áë닌Œ !((Û¶mÇ~È}¿½š Â`0 Æ»ŽÑÿ5¸dÍÙ³g±~ýz̘1!!!Üù²²2ܾ}™™™ÈÎÎæ"â îPSSC·nÝ ¦¦YYY(((@II©Ý #?€J¯ô }µßiee%ªªªPYY‰²²2TVV¢²²ÒÒÒhhh¡[·n8~üx« â  ­­  YÜéÕþ£7nÜÀ?þˆÃ‡‹,îñòåKŒWÈËËãæ–û÷ïcòäÉPPP@II deeñèÑ#˜™™!##@ó÷ÜÜ\x{{céÒ¥ÐÐÐ@NNŽP=O‰Ý»wGii)¬­­allŒÇ# aaa\q=`ii‰GáæÍ›Ø´iæÏŸ @SSùùù\@»¡¡ZZZ(++Cpp°PÂ_[¶lÁñãÇ!--ÚÚZ ÑåË—annŽ#Fd©1]»°lÙ2\ºt @s?Okkkœ8q¢ÍìÈ—/_bçÎ8yò$€æ ™3gÎ`æÌ™BÏMDˆ‰‰¯¯/®]»†˜˜¼úUÉÏF/**ÂèÑ£Ït{õê…M›6aãÆ"ïo­‘••…¿þú ÎÎÎxôèw^^^¦¦¦°°°Àܹs»`– -- Ä”)S0xð` >ãÆCïÞ½ÿ Æ»Exx8Ö¯_„„Í™ÿ'OžÄ€Äb?77MMMÈÊÊ‚¼¼<ÔÕÕñäÉäååaÙ²eo¤_{CC"##ÑØØˆ¡C‡¢¨¨ªªª÷daL IDAT€¶¶6÷ ˜€Q£FÇã!<<ãÇïòÜYYY¸rå ÜÜÜΗ——ÇÚµkamm- í*>„Î;‡””îüþýûÿ±~ª ƒÁ`ü#¼…²þw'''@Ó¦M8ŸœœLöööäááAwïÞ¥ŒŒ ±÷9zÓTTTpý‡òòòˆˆ¨©©‰¬¬¬è³Ï>ët/»ÌÌLÎ.¿ïßÁƒE¶ÓÐÐ@ÊÊÊ€BCCÉÝÝäåå¹¾£è»ï¾#""333@[¶lÚ¾¯¯o»ý\§M›F.\ ÚÚZ*(( AƒRPP ’’’••%)`÷“O>!ôõ×_ å¿§)ºvíšÀµÔÔT@RRRTYY)ôÚŒw‰Ÿ~ú‰Ðòå˹s©©©$//O¦¦¦ÞïëëK½zõâöœÍ›7wzÿÊÊÊ"GGG255åö›× &Ð… ¨®®®Ss¼JYY9s†¦OŸN’’’ÜÒÒÒ4oÞúè£Nù8gÎ@sçÎå‚}ôçwRRqráááBÛ^³f  ¾}ûÒˆ#èƒ> %K–ÐáÇhÀ€ß_~ù…fÍšEèÿý¿ÿ'`—T2dˆÐ¾ðÁ¯‹Ô<{öŒ›óÌ™3BÛc0Þ%vïÞMhýúõç:Ľ éˆââbZµj÷ƒNOOnß¾Ý%¿ª««ÉÇLJ–-[F²²²4~üx‘ö˜¶¨¯¯ç쾄;v,9r¤…\G¼|ù’ÉÖÖ–.\H&&&´}ûvòððI´ŽOJJ '¨âèèH»w殮K—’žž^«ÓþýûÓöíÛ™ ƒñ?ÈãÇiÔ¨QÜ~`ff&VºØØXruu¥ˆˆª¬¬¤èèhrww§´´4±ÍÑ÷îÝ#zþü9EFF’··w«c“’’¸àp{ÏѯR[[K‘‘‘ôçŸÒ† è£>j! €FE ÔÔTq-­ééé´iÓ¦Ñëׯ¿±9 ƒÁx›°i'¸pá ‰'¾mWÞüçñññ޽|ù2Mž<™bccÛÇÏÌ2dYZZ’‘‘éÔÛ};;;‡ÄÏ>ûŒlllM:•ˆˆ >žlllH[[[`_ÓÕÕ¥íÛ·ÓÇ…¶•M´}ûv255¥… ’…††Rmmm—}=þ< #F´¸VTTD7nÜ ½{÷Ò„ ¸ ÿ4híß¿¿SYƒñîÐÔÔD‡æ*jTUUÉÕÕU,¶ˆˆèÖ­[äååEÙÙÙTPP@×®]£óçÏ ¨Æ‹›¬¬,º|ù2]¹r…JJJ())‰ÜÜÜÚ}¦ã¿t766æÎÕÖÖRZZݽ{—®\¹B¿ÿþ;mÙ²…fÏžM h±wò---Z¹r%999‰5ÐÜ­FÇO~~~ot^ƒÁ`0Þ6,@Ú .^¼È=,t•¢¢"zñâÅÆÆRTTwDGGSFF†X~ÔŠJ÷îÝ;̼¬®®¦íÛ·Óš5kZ-)z£Gr%F‘‘‘ÜW[oÔi÷îÝÿŸ½3«9}ÿÿë¤B«%Ù²ï…A•5[ƒ,CŒ-cŒÌ3”cb1Ö¤ÊR%Ii±µJ«Òª}?Óõû£ßy;ΩN)dîçãñ~¨÷}ß×}ÝoûÜïë¾îë’ð<ª¬¬¤Ù³gsíwíÚEB¡ºuëFèÔ©SDD4räHP¯#¤€ºtéB@jãÇs;ùzzz”––F€† Âû¨ÓèÑ£ ÙÙÙɤÏÅ‹¹q&&&ÒåË—¹…³œœgp•Å“ŽÁhnŠ}¦«³hÑ"êÔ©S½6XrssÉ‚ûLõêÕ‹|||QcÙyõêÙÚÚÒ€Ä^€ÕÕÕÉÜÜœ¼½½ëŸÏ§²³³£Å‹ÓĉÉ‚dÚܪNDD¿ùæ@k×®­Sæ›7oÈÉɉfÏž-ö’ݺukZ»v-EEEÕKGƒññ­¿Ð¤I“())©ÑäçååѳgÏ(44”ž?N~~~tÿþ}zöìg­±~ll,ÉËËêÛ·/éèèpëëº.%%%7nYZZrszS… ¨NRR3F,´ 3Œ2 ã¿ËbßD sDI9ꢠ ÁÁÁ CTTâââPVVyyy¨««£]»vhÕª•X&H>ŸÌÌLdddˆ%ééÒ¥   2½zõâ²Ø7JJJÈÎÎË:_ˆˆ¬[·7nÄ¢E‹d’™”” *aÊÈ‘#ѪU+”••áØ±cÐ××—¨¿}ûvã·ß~CïÞ½±xñb,^¼ööö¸víäää°oß>|ÿý÷ðòòBrr2”••±`ÁDEE!$$rrrX¶l™Ìãvtt˜››KdÎ …øñDZwï^À‚ ààà%%%ÀÆaaahii!%%·oß{>³fÍBPP<<<°iÓ¦:õ™7oZ´h¡Pˆ¥K—âáÇ\’­[·náÔ©S8sæ ¶oߎû÷ïËzõê--­Fëãm€áÇc„  ARRÆŒƒ>}úÔØîêÕ«ª2Í¿¦¦&:vì---ôîÝýû÷Gÿþýѯ_?ôìÙSbÚ”¼zõ {öì½½=ø|> oß¾8pàŒß› ƒÁ`|p>´…¶9réÒ%@Ç—Z^PP@W®\¡uëÖ‘¾¾>͘1ƒvîÜI...Ñà$B¡’’’èÆ´wï^277'CCC?~©¬L˜0Ð_ýEDDzzzœ·¦4üýýÉÔÔTÌó¨úuøða®î¢E‹}ùå—DD´mÛ6@S¦L‘Y¿””Î;óùóçbe………dbbÂϵ²²"¡PÈ•RÛ¶m 2„Ö¬Y#¦ˆ.´@AALz½ía¦¬¬Ìy^ÅÆÆrÞ¬wïÞ•y¬ ÆÇŽ@ àþ¶¥%ûÅÂ<~üxƒägddÐüùó¹ÏUŸ>}èÞ½{襁€¼½½ÉÜÜœ”””Ä>ËÚÚÚdkk[ãœGdaaAFFF´páB²³³#??¿z'ÿ+**"777Z·nM™2…,,,èüùó\">Yeˆ¼¡êýYYYI7nÜ I“&‰Íi¿þúk“{1Œ¦çmI555úúë¯%ÖUÍ…ôôtºrå ÅÆÆRII ݸqƒîÝ»'SÜÏ´´4úî»ïhçÎtøðaruu¥€€JNNn”d~Abb¢Dò%eee@K—.ýÐê1 ƒñÞaÒpõêU.@úÛ,X°€ŒŒŒè·ß~£'OžˆÒšŠŠŠ ¤ßÿfÏžMãÆ# ºpáåææÖ[Þˆ#¹¸¸ˆÝ_ºt)íܹ³Æãç5‘››ËÅ¢züø1ýù矜Á±¶#ú999tâÄ 3f ·xûöÛo¹ò¼¼<.«ô½{÷ÄŽÛŸ>}ZfýõWª’¡T'99™† F¨eË–äàà V~ïÞ=RSS# *QTVVíܹ“;"UýHTee%ñêÕ«2éUýHp‡$Œ)Ó¦M“ˆoÅ`4wbbb¸PÒ²µ RTT¤­[·J”Ò½{÷èÔ©Sufzwrrâ^è[´hAVVVïÖ¤²²’üýýiýúõÔ®];1cAïÞ½içÎFߢ¢"òóó#[[[š;w.rÇåšp$::šþúë/211!Ú¿ÿ;e–¿{÷. öíÛ‹ÍkÙÙÙäêêZïìÉÞÞÞ4|øpîÙ :”û~`0Ícccªbô‹rŠ.:{öì ÕÂÂÂÈÕÕ•"""(++‹ìíí)((¨AëêÄÄD²°°H¾äááAžžž€Ú´iSïÍ8ƒÁ`0š;Ì@ÚÜÜÜjLTñ1xÁ…BzöìýñÇ4uêTš:u*ýþûï-S{©Ɔx§ …BθÉãñè›o¾¡ãÇÓíÛ·¹EÙßÿ]§QÜѱcÇŠ½œ>|˜‹'XYYIÞÞÞܸ¬^šDD$tðàAî^@@—8¥}ûöf7nÜàŒ³”œœLkÖ¬á2ÌW7‹Xµj 5kÖȤ׋/8YàîgeeѼyó¸²9sæÈ],¦¥††mÞ¼™BCC?´ºR),,$OOO:~ü8¥§§Srr2"¯Ä#G޼S¿¯_¿æ2±×v©ªª’……ÙÙÙÑíÛ·)--MLN||<ñx<âñxEÉ~ùå""277'dnn.³ž€(33“ˆª$‰ŒŸ:::OÉÉÉäàà@………tùòen9uêTrww§îÝ»scêܹ3’I¢._¾Ì•Ëp¿k×®€† FDDžžžœ'ªÈëíc9®Å`4¢d@«W¯®±Ž‘‘ééé‘««+ijj0`mß¾®]»ÆÏÈÈ [·nÕéùîèèÈ…Ê——§ü±ÎÏÕ›7oèðáÃ4vìX±9MQQ‘æÎKW®\‘0fggÓš5kèäÉ“ùΉ7ÂÃÃÉÚÚš ÈÜÜœÜÝÝ›d£N´I%šk‰ª¾ ïß¿Oeee5n eddÐ… j=Î/vì~ÅŠTZZÚèc`0M‹h}üvø¤ØØXÚºu+uèÐAl®4híÞ½[¦#ëïƒüü| §´´4zóæ ݺu‹‚ƒƒ%†67hÍš5\è‘—ïÍ›7¥Ö755%´cÇŽ÷¬)ƒÁ`0f m7oÞ$Ô¿ÿ­J½äïïO?üð™™9::ŠíŠÏ;—ÐüÑà~¼¼¼¨S§Nœç(P•á}ݺud``@mÚ´©Õhª¨¨H#FŒ "¢£G5j”XááᜧXRRqžHÞÞÞ2ëº~ýz@sçÎ¥ÊÊJ²µµåtž6mååå‘·°ïر#‹ÏÄÄ„¶lÙÂyGtêÔ‰\]]iïÞ½€ Åú*,,ä Èê=aiiÉCEñMP¿~ý( @æq2ÍQì]GGÇë,X°€Z·nMrrr¤««K>”Z///~ùåš4imܸ±ÖcÜ)))ÜÑšŽ}—••Ñ¥K—hΜ9b^8<ôõõéèÑ£”ݰˈÈ(:eʲ´´$??¿&õlJHH @·oß&¢*oU'''âóùtïÞ=rqq‘8ŽYXXHîîîäïï_gB¡~øánîíÛ·o“Œ…Á`4ùùùܼ(m}RVVFNNN4sæLnU}þóçϧÌÌL²µµ¥3fp^íÚµ“HhEDÜ‘û·ËöïßO@UÜ'YU]]]æ.ƒÑ)))›G  MĶmÛHAAbbbêÝGjj*mÙ²…LMMéåË—Rë¼zõŠ 7òöÕ¾}{Ú°aC^«Å‹/èǤñãÇÓ¶mÛdŠ©ú.TTTÐõë×iÑ¢EÔªU+±13†œ)%%…\\\(11‘Š‹‹éàÁƒ)!+44”\\\¨´´”nß¾MwïÞ­õEÛßߟ˞,òÞe0Íwww@***2{ƒ¾|ù’lll$b8ËËËÓ¤I“hÿþý×$úFDDеk×(11‘rrrÈÛÛ›®\¹Ò,ãÆÅÅѪU«Ä £ãÆ#//¯zÉ©¨¨àÂL½ÚŠÁ`0ŒOõÂÇÇ“'OF=˜˜ÈÝõêbbbPVV†ÒÒRî_ÑÏ%%%(//Gqq1ø|>ŠŠŠPQQÂÂBBUUµÆ ¢¢EEE(++£eË–PRR‚žž>ÿüóFß·ß~‹ÀÒÒ©££#¾þúkC]]GÅ’%KP\\ 555TVV"11=zôÚ>11S¦LA||<äääPYY ã÷ßÇÖ­[1räHÜÜÜ0wî\¨««#55¹¹¹èÑ£„B!ÂÂÂ0xð`™ô655ŵk׸笮®Ž‹/bðàÁ˜?>=z‡­[·bÏž=(,,ÄêÕ«qùòeÀ”)SpúôihiiIÈ^»v-Nœ8Õ«WãĉÜý¸¸8ôíÛrrrHMMEÇŽëÔóÇÄž={0eÊܾ}[¦±1Í@€#GŽÀÚÚyyyüõ×_èׯ ++ /_¾Ä¸qãÜOll,6oÞŒQ£FaÛ¶mPPP+'"ìÛ·Û¶mÌ›7+V¬ÀŒ3 ¨¨Øà~k#??nnn¸téZ·nµk×bÊ”)àñxMÒDDDàÌ™3ppp@zz:w_KK K—.ŪU«Ð¿ðù|$&&";;ݺuCjj*FŽ 999®Myy9‚ƒƒ¡««‹¢¢"DGG£°°“'OF«V­¤ö###BSS™™™4h"##›lÌ £i¨¬¬„ŽŽ¢££ñÓO?á—_~©Wû   œ?nnnHHH+ŸOîîî”™™IñññHwïÞ•›œœLôâÅ tóæM ®QçÏŸsaNôôôÈÙÙ™€æã›Á`Táàà@HII‰âãã,çÙ³g´{÷n5j”ØZÿ?æûªU«èìÙ³ï'Ôßߟ®\¹BÁÁÁÍÊs466–V®\)ÏU__ŸnÝºÕ yOž<áÂk­[·ŽÐÆSeƒÁ`0>j˜´øùù ™¥óSá—_~!´dÉ’Zëݽ{—´´´¸céVVVI:ìíík=NÁe|ïÙ³'w¼áÂ…DD%–õÔÐÐÒÒÒ8æÈ82pà@@ÿý·Ìã´³³ãb–~ýõ×”™™IGåŒ1]»v¥°°0""ºvíw¤^KK‹Ÿ¼¼¼¸—ôøøxò÷÷¯Q·ŒŒ Îë¿[·n”˜˜È•=xð€óf0͛͛7s'®j[+¾+)))äàà@+V¬ nݺILy<õïߟ–-[F¤ÀÀÀ&Ÿƒ“—/_ÒŠ+$ £"¯þú’œœL–––4kÖ, •Z§  €ëKôýÊ`0 Ƨ36€àà`ª²—Š8::rÇuªãììÌ [·nMvvvµÊ)--å²`V÷$ruuå<2uuu¹£POŸ>åâlÖ´p]¸p!·`KKK£òòrÒÐÐ tùòe™Ç(òl5jwÄSUU•®\¹"¦ÿâÅ‹9ïÔ†Äz}òä U1KóòòÄÊæÍ›GhË–-2ÉÊËËãŽì?þ¼Þº0Ÿ±±±dffÆÍ***dmmÍÍ4wî\Ú²e‹Äg¯>¼‹4//Ž?NFFFdeeE±±± ÖCRSSÉÎÎNlK4_›™™‘»»;UTTpõKJJèÎ;”ššJwîÜ!@ &/##ƒâãã)##ƒRSSéäÉ“”œœ,V§  €|||èòåË”ššJ>>>µ† ÉÍÍ¥aÆPs:::Z¬\´Ù¡C‡Fx" ãCRXXÈyý›šš¾·Íݘ˜:vì-\¸[ã½})**ÒèÑ£é›o¾!GGGŠˆˆùDÏû"&&†–/_.f?~|ƒ £™™™deeE&&&Tg}Ñ©ƒ§OŸ6¨?ƒÁ`0šÌ@Ú?~L@U2‹OQr¡aÆQÕ °……·81b½xñBjÛØØXÎkëÎ;€Ú´iýx=z”;š?qâDÊÏÏçÚž±2Ñx(³¼ &pa FÕ<3xð`±°ׯ_çÊ===iâĉtîܹÉoˆ4$$„,,,ÈÐÐŽ?Þ¤±íJKK¹¸¢Õ“ÎÉÉÉ‘¾¾~ ŸÞ¼yC^^^TXXH±G={–âââ(//|}}¥z¥¥¥ÑñãÇ©¤¤„ÈÉÉ©Fƒt~~>5Š;.Q'44”ûÞ`0ÍŸÀÀ@nn0`YXXÐéÓ§)&&æ½éðúõkrww'kkk211¡¶mÛJ5š*((PïÞ½ÉÄÄ„¬­­ÉÙÙ™ÂÃÃ%6ššøøx‰£úúú Ž1šMÖÖÖ4cÆ ©Éõj¢oß¾€<==Ô/ƒÁ`0Í y0ꜜ ²²²Ñdæåå!>>ñññxõê„B!ÔÕÕ¡¦¦eee¨¨¨@MM êêêPQQᮦ@YYP\\Œ   |ñň‹‹ÇÃæÍ›±gÏ(**J´KNNƲeËpáÂÀÝ»w“&M‚œœlll°k×.À¼yópîÜ9´jÕŠkÐÑÑ‘ªŸÏ‡³³3`ÇŽ€3gΖ,Y‚–-[Ê4>www¼~ý 0{ölœ9sêêêbõÜÜÜŸŸîÝ»cåÊ•2ÉQ\\ KKKœ>}šû;yöì™XÈÉÉ!::±±±èÛ·orqïÞ=ܸqÛ¶m«—N ƧÈäÉ“%%%TVV"==&&&;v,Ξ=‹éÓ§cÊ”)ؽ{7–,Y‚£G¢M›6®G~~>.^¼''' 0–––5ÎeïJee%>|ˆ3gÎàÂ… (((àÊ´µµaff†•+W¢GRÛóù|äää`À€ „±±±Dàà`´oß½{÷†··7`Ĉbu’’’—— ¤¦¦"44K—.•˜K ¤¤³gÏFpp0ÔÕÕáéé)õùÈËW-Kì„Á`|´èééa×®]ؾ};ð×_¡¸¸‡BJJ `È!000€Øº°±èÒ¥ ºté‚Ù³g„B!"##„G!((‘‘‘¨¨¨àÖâׯ_çÚ·nÝÚÚÚÐÑÑAÿþýÑ«W/ôêÕ ={öDçÎMϘ˜ìÞ½NNN …€ &ÀÆÆ'N¬·¼¢¢">|wïÞÅ7ß|›zµïܹ3bcc‘––Vï¾ ƒÁhŽ0ihÑ¢p‹Yxõê·ðJHHà~ŽGNNNƒtiÛ¶­˜ÁTdTUQQ²²²T£jMmDãRRRdddÀÀÀèÔ©0mÚ4©z¼yó .ÄÑ£G¹—rOOOÀĉ±nÝ:üûï¿KKKìß¿Ÿ34‹HLLôêÕKjW¯^Evv6Ú·occcdggãæÍ›sss™ŸÙÿþ÷?îçÎ;ÃÈÈHê˸€*c®è¥]²²²0lØ0¤¦¦ÆŒƒÀÀ@xyy‰ÕÓÔÔĈ#‚›7obãÆuÊž5k¬¬¬ððáCäää ]»v2ëÅ`|ªqòòò@¿~ý°lÙ2:t666ðõõÅœ9spèÐ! 2¤Qú®¬¬Äš5k™™ sssܺuKêRc .àÌ™3ˆçîwîÜfff033ƒA­2 €#FàÕ«WÐÓÓ“¨Œââb 0nnnPRR„ ÄêÂ××FFFÈÍÍ…ŸŸf̘!ÕøÌçó1oÞ<Ü¿JJJ¸~ý:tuu¥ê'š‹ë3ç2Œ+++øúúâÖ­[øî»ï333Uó÷Ó§Oáïï#GŽ °°ÚÚÚ000À„  ©©Ùèú´hÑC† Á!C°zõj@EEbbbððpî߸¸8”––"44¡¡¡²Z·nÍL«N»víŠÎ;CSS³N£ï‹/°{÷nœ?ž{·˜8q"lll$æ^Y(..Ɖ'àææ†õë×cëÖ­àñxõ–Ó©S'@zzz½Û2 ƒÑao  &ÒÜÜ\1£gõëÕ«WuzÄ(++s‹+ ??EEEÜ•››+ÑçÛ÷JëÖ­¡¢¢༒Œaoo_ã"5!!Ë–-Ãþýû1lØ0@\\BCCÁãñàêê ðx<ìܹ³Æì„„@Ïž=¥–ÛÛÛ–/_EEE899¡¼¼ýû÷ÇèÑ£ecAAç±Àãñ––†M›6áÿûLLLðå—_bÆŒPPP@\\`èС2É€¨¨(˜˜˜ 55rrrغu+"""T‘#""ļ¦fÍš…xxxÈd ÕÑÑAÏž=‘˜˜ooo,Z´HfÝŒO•¬¬,€‚‚`ii‰«W¯¢²²ŽŽŽ¸téöíÛ‡¯¿þ®®®())i´¾åää°{÷ntéÒ¥ÑdV'77...ptt„¿¿?w¿U«V˜={6ÌÍ͹9K|||0|øpŸÓ§OãÂ… øòË/áííÍ9?4‘w,32 ã¿36ÑbƒÏçÃÌÌŒ3‚æååÕÚŽÇã¡k×®èÝ»·Ô«cÇŽ2õ_Ý`šŸŸ‚‚¡¸¸¸F£jMmÊÊÊ8¹¥¥¥(--ëËÎΖ––5î<bóæÍ8yò$ ÄÝ?wî€*£¯aoo/¾ø¢Æq‰«íÛ·G×®]qùòe„††bùò刌ŒDII ¾ùæìÝ»NNNuzYÖ—Æ6Ž–——ãÖ­[8sæ \]]QQQ ÊÈ0vìX,_¾K–,3nÊBhh(&OžÌmÔ¼}4TRDCCqqq())¾¾¾X¡Pˆ E‹:t(îß¿öíÛs›cÕ!"¬[·ÎÎÎhÑ¢Ξ=‹™3gÖ9v€HŒO MMMØØØ`ãÆ8pà¾ûî;©†Î-Zp†J @ZZBBBàââ‚;v@NN#GŽ„®®.Æ/5¬GcѪU+ >Ç—(+((@bb"g0­~¥¥¥qßM(((À‹/jìgÒ¤I°±±Áøñãë­cEEΟ?{{{,Y²·nÝj/|555U' ƒÁøO𡃠6Güüü¤wÇÿϤŸÏ§ððp & “¨SQQAîîîôôéSJKK£ÇK}ÑŽ§ŒŒ zóæ yyyу$Œ¨"¶nÝÊG;&³¾µ» FógþüùR7ªß•¸¸8rpp 222"SSS²µµ%??¿&ßÜj(€”••)??¿Þí7lØ@vvvTZZúNz„„„Ð’%KhñâÅôìÙ3î¾  åË—¿“|ƒÁ`0š Ì@Ú6oÞLÈÜÜüC«Ò$H3feeѦM›hìØ±dkkK¹¹¹RÛÚÙÙ‘¼¼< N:QRRÝ¿ŸÆŒC¯_¿®±Ï˜˜Î0еkW±2‘Ç®¢¢"eee‘P(¤nݺ:}ú´Ìã²¶¶&4nÜ8™êÿóÏ?œ‘tæÌ™Þš§NâŸß(}eddPDD…††Ò£G$Ê+++éÎ;ôàÁ*--¥«W¯Rxx¸D½ÄÄDºqãeddŸÏ'zóæÔ>þùgnL{÷î­—¾ŽŽŽõš§ FóâÏ?ÿ$4}úô&í'//¼½½ÉÚÚšæÌ™CFFFdeeEîîî”ݤ}ËŠP(¤^½z:qâÄ{ïßÏÏæÏŸOË—/—ê8 šË—.]úÞuc0 ãCÀ ¤õ¤²²’zöìIÈÑÑñC«Ó$H3fddÐýû÷k4à•••ѪU«¸—âY³fQ^^ݹs‡&L˜ õ~u‚‚‚ļ§¹2‘Ü… ‘··7·ã^PP Ó˜*++©OŸ> ^ÞLÕί_¿ž*++)77—.\Èé:dÈ3f ÷{ûöíéܹsÏÊÜÜœ“Süü|γíÉ“'2éõ÷ß‹…`0þˈ¼»wïN&&&dggG/_¾¬±~xx8éèèˆÍ9ýû÷—jl,iJJ íØ±ƒFE œLG†††ôï¿ÿÖ¸ñÔP’““ÉÇLJ²²²èåË—›-Q¯¸¸˜N:EÏž=£ØØXº}ûv^õvvvÜØvîÜYo:DhÆŒõnË`0>~nܸñAÂh”••‘¿¿?ýþûï4oÞ<222¢óçÏ¿W¤ñÃ?255}/ý …Brww§)S¦¥¥%¥¦¦ÖXw÷îÝ€¾øâ‹÷¢ƒÁ`0f ­'"oÆ–-[R^^Þ‡V‡#77—vîÜIOŸ>}gYÏž=ãb‡ÊBRRg äñxdmmM•••äîîNS§N•éØÐ;wg88wª*àâ"‰ õñà½wïWµ¦#¡5qêÔ)ÎHjffFÝ»w'$''G3gΤHÄ-yÂ~õÕWäááA¥¥¥äääD¨gÏž}Lž<™ÐîÝ»eÒ)>>ž{Þµyæ2ÿV¯^Mè‡~ ââbòöö&KKKš0aYXX»»»Ô#ãÎÎÎÔ¾}{1cå¬Y³Ä欆H£¢¢èßÿ¥åË—sBÕ/yyy4hmݺ•îÝ»GEEEò,Däää%$$ˆÅ”«Nrr2Ý»wÂÃÃéîÝ»äåå%a-))!WWWzñâååå‘››ÅÄÄH•wâÄ n®üî»ï¤·è…|ñâÅ jÏ`0>nD›ðµÅ¹_| Gï>|H¨uëÖT\\Üdý’?žìììdúÎùí·ß-Z´¨Éôb0 ãcB2}$£VöíÛøüóÏ›4kf}QWW‡¾¾>þþûoèëëÃÚÚ>”ÈJ/ ÅÅŪ2Ð×ÅíÛ·1zôhBEE...°±±Áùóçñï¿ÿÂÍÍË‚Yììl˜››s¿‹2+))üýý—.]Baa!ºv튩S§¢¸¸W¯^,_¾\æ19::LMMѶm[™ÛÀÊ•+±wï^€‹‹ ^½z…Î;cêÔ©¸sç^¼xuuu9r‡Æ´iÓвeK¼~ýÇŽìY³ ¡¡sçÎANN‰‰‰™LgÍšðððI§^½zaРA "xzzÖk< Ƨƛ7oPRR‚‘‘8___XYY!>> .„±±18€ääd€™™233ñÓO?AQQDhhh`ûöí "™úÆþýû1oÞJ>¬}¶yD<x<žTOÍòòr©™ß7|>ŸnܸA[¶l¡)S¦¡¡!­Y³†lllèèÑ£äêêJÞÞÞtãÆ rvv¦àà`±ö¢#ì½{÷®±ŠŠ ²¶¶&999ª²,?þœˆˆŽ=Jsçέ1›fzz:Òƒ¸{îîîœ×%úì³Ïˆˆh„ œgÑéÓ§¹z@¦çQZZJmÚ´!týúu™Ú¼ÍáÇ9ϯ=z¶¶6÷ûäÉ“)))I¬~AA¹¸¸ÐòåËÅ<ÔD×ÛÞ¯ÑÑÑœWª¬É¾¶lÙBhþüù ƒñ©``` SLâììlrvv& š2e YYY‘··7ñù|*(( SSS±˜ \(Tó -..¦»wïÒ®]»hêÔ©\,âêW‹-HWW—6mÚD—.]¢ôôtNœœºyó&Y[[ÓŒ3¸ùéí«}ûö4kÖ,úùçŸÉÛÛ»ÞI<"""Þé¤CYYùùùQhh(yzzRpp°T+wwwÎûÉ’%^¨õÁ‚••Uƒe0Œ—ŒŒ nŽ{;i啹sçúùçŸMæ‹/hݺu4{ölºuëVƒd¬_¿žÐ÷ßßhz1 ƒñ1#ߤÖ×OˆÊÊJ|óÍ7 "Ì›7Ÿ}ö™Dyyy”””`áÂ…PQQÁ’%K0}úô÷î £  €™3gbæÌ™¡Pˆ˜˜¤¥¥!-- ñññàóù\ý6mÚˆµ¯Ëƒ411æææÜN÷Š+päÈ())aß¾}xþü9\\\ //ùç•””„E‹áàÁƒ=z4w¿¢¢ ¦¦†×¯_#,, ÏŸ?Çýû÷üŸ·è™3gæææhÑ¢…LÏãêÕ«ÈË˃¦¦&¦M›&S›·ÑÓÓƒªª* ‘””hÕªöìÙƒM›6‰y]€ªª*,X€ @(âáǸvíN:…ììl„††ŠÕ0`úõ뇗/_ÂËËKÌ»¶&ŒñÇÀÛÛ|>ÿ£ð„`0>Õ=Hk£]»v033ƒ™™„B!=züñÇ8vìÜÜ܉  ** oÞ¼ÁªU«¸öÛ¶mC`` BBB¸9KDëÖ­1zôhÂÀÀãÆƒªªªT=Ú¶m‹3f`ÆŒ"Btt4ˆ€€DFF";;œg¹œœ´µµ1fÌŒ;zzz4hÄü#B[[[¶X-[¶„’““ñúõkôîÝ[bž¹{÷..\ˆŠŠ ˜ššÂÁÁ¡F}d!== ©©ùNº3Œ“ÊÊJîgY×qŸ:£F‚««+‚ƒƒßYVhh(:„¼¼<üðÃbkíú"ëw+ƒÁ`0Ÿ ÚBÛ\%žPRR¢„„„:ë'%%ÑÞ½{iæÌ™¤¯¯OtêÔ)zðà%%%QNN•••QQQeffRdd$ݼy“ìííßÉû¦1°··'¤¯¯/QæììLmÛ¶åâGÙÙÙqe¶¶¶´~ýúõŽŽ¦Q£FQXX˜DÙÅ‹ 9’:wîÌ…¯®GJJ µhÑ‚H•QÓ§O'´yóf™ÛH#$$„455 >\jB—º äžÝÛ±¦6mÚT¯XO|>ŸÔÕÕ Ý¹s§Þº0Ÿ €Mfõ¹NÚÕ¶m[211¡½{÷’¿¿£Ç²+(( ;wîÐîÝ»ÉÄÄ„:tè Uuuuš6míܹ“<<<Þkvæ‡rÞ³FFFTZZúÎ2G%‡šÁ`|ZÄÅÅq1ŸkJüù_ÃÓÓ“K4ØD‰—¦OŸN–––§šd¡°°víÚE'Ožäî‰âãÿóÏ? Ò‹Á`0Œæó •çÏŸcÛ¶môìÙ³Î6Ý»wÇÖ­[±uëVTVV"22¸~ý:RRRPXXˆââb´hÑjjjhÛ¶-zôè>}ú€Çã5ñˆjçåË—€>}úp÷ÒÓÓaaak×®†Ž3gÎ@GGD„ï¿ÿŠŠŠ8räˆT™X»v-ÎÎùªn IDATŸ?/&W„ÈKAAcÇŽÅ•+W8¯©•+W  1räH Ÿ;!Wgý´´4úñÇiòäÉäààÐà ÞÞÞ4qâD²µµ•*CKK«^kRƒÁ`0š;̃´¾øâ ÄÆÆ¢S§Nprr‹—tðàA”””`ôèÑ9r¤ÔlíÍ‘©ššf̘///@ïÞ½qúôi.#²@ Àš5k0lØ0|ûí·ReùúúÂÆÆ®®®µzwU÷ Õ××çîÏ›7jjj Btt4°xñb™Çòûï¿@ƒc63g΄““<<.RRRݺuky‡‚œœ>Œ… bÆ 8tèÐ;É<|ø0Z·n-ƒº)QPP@ÇŽ‘ššÊÅ{–ÆãÇñï¿ÿ¢¢¢+W®ÄîÝ»Ô_`` víÚ…Ï>û nnnR¿;ËËË‘––ÐÒÒjP? ƒÁ`47˜´ˆ_}õ<==¡  €‹/¢k×®bu¾øâ À××üñ зo_hkk£W¯^èÙ³'zöì‰:¼7½322Ï]iiiHOOÇ›7o••%–œ©¢¢mÛ¶E§N ©©‰`̘1ˆlݺ|> øöÛoacc%%%U §eË–aæÌ™5. ¯_¿Ž¿ÿþîîîu.€*#GïÞ½Áãñ@DX²d ÀÑÑ@Ub"YŸ§ŸŸ²²²%%%2µy̘1rrrˆGll,w´ ¨:f/2îÛ·¯NY:uˆ#Š›7oâ›o¾iJÕŒÑg\CC£IÓÀÛÛ©©© ÅåË—±cÇ”””`РAÐÕÕ…¡¡!zõêÕd:ÈB÷îÝѽ{w,Z´@ÕÜúâÅ øûûãÁƒ Edd$'''U/èC‡…¾¾>gtÕÑÑ“šš ###¤¤¤ {÷î¸yóf£~¿ÅÇǨJø¾“2Œ÷ëW¯TÍUÅÁƒñÕW_aܸq8|ø0222àââR/oÞ¼Áwß}‡K—.¡¬¬ JJJ8þŸââb´jÕ ?þøc=¥¥¥xòä ž?ŽgÏž!<<aaaÈÏϯ×8“““ñüùs©e|>8rä† ÂÝ/..Æ‚ °zõj±XEÕ9þ<.\¸WWW´nݺN=¢¢¢TÅÏ»|ù2ˆZZZ˜>}:ø|>.^¼ ~qDþùgîçêžS Œ1!!!¸yó&6nÜÈ•ƒÇã!22RfÐY³f!447nÜ`RÆŽììlï/FZ—.]Ð¥KnÞ CCCakk‹øøx())q/Ô†††hÓ¦Í{ÑMòòòÐÑÑŽŽ,,,iii\ÓÀÀ@„„„ ¤¤¡¡¡ åÚvíÚ•‹c:tèPlÚ´ ñññÐÒÒ‚¯¯o£8€ªïOb›F ãÓBäAú¶ÓÁ»¢­­””ôïß—.]ªU«pêÔ)™ÚnܸG…P(DëÖ­±|ùrìß¿íÚµCQQž>}ŠÐÐP\¸piiiPVVưaà««‹Ñ£G£cÇŽï¬]Ò-Zˆ­ëCjj*víÚ…ÌÌLìÛ·ýúõ«³MLL €ª|ÚÁ`0Œö'…ýû÷ÃÖÖ0gΘššÊܶOŸ>µµŠ‹‹QPPÀ]54ååå¹Iee%¢££„   ",,Œóº|›víÚ¡OŸ>èÝ»7´´´Ð±cGtèÐbI4‘ôôtdffâñãÇðóóãžœ8q«V­’ðÊÊÏÏǶmÛj<~ìØ1ܺu ÎÎÎhÙ²eÍëÿséÒ%>|›› {{{ÀÚµk!''¼yóíڵìY³ê”T-îß¿Ïý†äääF;Òõ®Ìœ9!!!ðôô[ðvîÜÇÇãÇáéé‰ 6Ô)ËØØ?ÿü3|||PRRÂyù2ÿDÒwMÐtçÎŒ=š{I••êHÑNaa!ž={†ÐÐP899!##ZZZÐÕÕ…† öAæwîÜsçÎÅܹsTÍ—ÏŸ?G@@=z„ÀÀ@¼|ù¯_¿ÆåË—qùòe®­††¼½½›ÄSVd ­éx)ƒÁhþˆ6Ä›"$ŠŠ bbbгgOØÛÛCWW·ÖuTZZÆŽ‹¤¤$())á×_•¥¢¢p÷ªM]\\––&¶1¦§§WoOS‘3Ayyy½ÚÕFQQ>Œ»wïbÇŽbc¨ ‘´ÿþ¦ƒÁ`0;Ì@ú!!!øþûï¹ß]]]Ѷm[ôïß#GŽÄgŸ}†~ýú¡_¿~èÓ§LÀê(++CYYY"C/!33™™™HKKCrr2~úé'λ§  @B–šš†ŽÁƒcèС2d ôNÞJ¯^ý?öÎ<®¦üÿã¯Û*%!E–ˆQC¶R1[Z”±ŒLŒe2Ì’LcÌŒe a²Í ²„¬E›Jˆ mJ¥R¤E{Ú—[÷¾ô»çëj»í1Ÿçãq8Ÿí}n:÷œ÷çõ~¿“¹Pš%K–Ô²*RPÕÆÎ; WWW‰vœ?Ž+V@ ¨ÞA÷÷÷ÇçŸ~ àáõŸ|ò‰ÄŸ÷±cǸt={öDvv6|}}Û,ŸTC˜™™aÛ¶m@YY™˜ÊÖÂÂaaaðððÈAj``uuudffâæÍ›°´´lMÓŒENN€æ9HËÊÊ`aa±cÇÂÛÛ»ÙÕØ»té½P¯[·¸Ðü .`Ó¦M …\hþ‡~ˆ4kÍæ ##===èééq÷œœœ.i@@§Â?þŸèèhÀèÑ£[e %%%C[[ëÖ­ÃìÙ³kU«ÆÇÇCOO%%%066†———ÄJÉÚœ¦ ã6Æþøã:Ÿ•kC$zh‰Í³ÊÊJ?~œ«Loooßè9DRmmífÛÃ`0 ÆÛs¾A÷îÝ1`À ¨¨•••œ‚366§OŸæúJIIA]]ªªªPSSƒºº:””” ¤¤YYY(++CZZeee(//Pý"^ZZŠ‚‚#==™™™ÈÎήS ü/?œ¡¡!ŒŒŒ`hhmmm…B¤¥¥!)) OŸ>E@@²²²—/_‚Ç㡲²Dîß"{ºté.Ì_II‰[³¸¸¸QÅ7vî܉äädœ8qRRR ö?xð ¾üòK…BŒ1‘‘‘\èÕÔ©S¡¥¥…¼¼ŸN:µªãmàÀ8|ø0lll`bbÂ9eEdffbÔ¨Q(++ÃæÍ›±mÛ¶f¯ÙµkWL™2S¦LiÒx‘P 9R"⢲-Z??¿&—ÅÅÅ€Dáø ƒÁ`¼+0éhiiq*}}}„……aïÞ½èÓ§BBB„„<þ|>ééé\•Ç– sçÎPWWGïÞ½1`ÀÀÐÐ={öDrr2âããŽsçΡ¸¸222èÛ·/WjôèÑ\Ñ%555‰ª¿NS¤D„ 6@^^ž •oˆ;wbãÆkkk <‘‘‘\òþÏ>û àââ‚ŠŠ ¼÷Þ{044”hîÜÜ\ÄÆÆ¨vªcÏž=ðõõ…@ h×ÐVÒÒÒ066Æùóçáíí-æ }] –ã¶.f̘“'Oâúõë8xð`kšÎ`t(DEšš[,háÂ…xõêÖ¬Yƒ_~ù?ýôS XW7µ…æ"22÷î݃““òóóѯ_?.4ôèÑm>µ4 qŠ™™™¸víìììtŽ¢¢¢ºººM3”Á`th=z6lX«çµ\¾|9:„ìÝ»ëׯP½9%rŽþüóÏØ²eK«Ú!)ÅÅÅЬ±üŠŠŠðòò’(ÿ]îg5bĈ&ÏÃ`0 ÆÛsÖƒ(T]II VVV°²²âÚ’““ñòåKdgg#33YYY())AII ø|> ¹„ï¢ÍN:AQQ]»v…’’ÔÕÕ9‡f=‘‘˜˜® ýµk×pþüyôë×ZZZÐÒÒ¼yó0bĈ+Ã7999ÈÉÉÏçskõ!`kk |ûí· ö'"|÷Ýwؽ{7`Íš5Ø¿?6mÚ Za«¬¬Œ9sæø_xýÒ¥K%®P½mÛ6x<6n܈Î;£sçÎxõꂃƒ1vìX‰æimÌÌÌpþüyxyyaïÞ½Üy)))˜™™ÁÙÙ9HÍÌÌ ++‹””DEE1ã?CK(HE¬^½ÿþû/¶mۆɓ'còäÉÍž³1(++×ÛLHHÀƒpòäIüôÓO8sæL«Üû뢼¼·nÝP½ÓŽ?ŽÊÊJ‰”û/^¼@aa!x<†ÚS FGät9rd›¬çåå ØÛÛcÅŠPRR¢E‹‘‘9sætç(ddd@½•å¢%”°@uj”ââbtêÔ £Fj‘9 ƒÁx`Òz9Hóóók´IKKcàÀÍ*TqêÔ)øùù!11åååPRR‚¶¶6´µµ1fÌ,Z´¨]Š )))!//¯A)ŸÏǧŸ~Š &ÀÎήÁy‰ëÖ­Ãööö\1¬’’®ß'Ÿ|‚Î;#>>ÁÁÁàñxX´h‘Äö»¸¸¨V(ˆ*[øá‡ðöö†··w‡ròx<ÄÅÅÕ¨XoaaÁ9HEÎÞúèÚµ+Ƈ;wîÀÃÃ9HÿZ"éë899!((666ˆŽŽnv>Òæ2xð` <‹/n—õVï-Bä ­«Ò|sÑÖÖÆÚµkqýúuÂËË ŽŽŽXµj¦M›Ön×Eaöõ9HKKK1wî\XXXHäøì³ÏpàÀðx<ìÞ½›sŽà ÿ…ן8q0eʉÑ\Èí† ¸ó¢v‰æi zõêÅíÌ¿i—©©)dee‘ššŠÇK4ŸHÝåééÙ²†2˜–vvéÒ‡³gϸ͜ÿ2·oßLœ8±QéI|xÓe0–²²2„††@£ª©7—-[¶@EE—.]Âüùóׯ_o—t%u‘™™Ém†«««·Ùº|>EEE5Îß¿0nܸ6³…Á`0ŒŽ@Çy:è€Ô§ m ¡««+qeö¶¢!iqq1æÍ›‡åË—céÒ¥ ÎWQQ+++8;;CZZGÅ×_-ÖG”3TUUFFF …\A,kkk‰m…KÉÉɉ333s!¹sss€···ØyeeeŒ?@õƒ¼$ˆòÞ»wyyy-h%ƒÑqý_©Å[‚éÓ§ÃÜÜ¿ýö[«m½-ܹs0iÒ$î\XXŽ;Vï8têÔ ü±ØùÔÔT¬]»¶FJ–ˆˆÌAÊ`¼«***6lX›®½gÏ…Bdffb„ 022jÓõB^ß­[·6y'HIIÁæÍ›abb‚°°°í"iGûœ ƒÁhm˜ƒ´ºví @r©¯¯/¾ûî»Ö4©M¨ÏAš——‡Y³faýúõ˜;wnƒscÀ€¸rå dddàââ‚Ï?ÿ¼F?Ñglcc‡€€¤¤¤@QQ±Æ v]…Bøúú¦M›&V@GG„@ €¿¿¿Dóµ"ÇíÍ›7QQQ!Ö&rxŠ ¤4„®®.455!àççײ†2¡PÈ9H›[¤éM~þùgäççãøñã-:ïÛ„P(ăT+HEøûûÃÆÆ¿ÿþ{­ãªªªpþüyXXXp@µÚwñâÅ8|ø0z÷î-6F¤Xb/ä Æ»É½{÷|ðA“Õ›¿üò LMM±råJ899!00P¢M¬Ï>û ’’â6ßñcÇÝ“%"33 ¦¦ÖjkÀÝ»wñÉ'ŸÀÖÖFFFÛüªŸóããã°û1ƒÁ`0þ{0i=4VAš’’‚ßÿçÎkM³Zº¤˜={6¶mÛ†éÓ§78O~~>LLL¸qYYYdeeA(Šõ CBBddd¸p}Qq¦¹sçJœîüùó(//P]ÉóMD6w¤0ûqãÆAEE%%% k³´´P­º…7„H‘*©S•Áx›ÉË˃@ Ðr!ö"ÆŒƒ±cÇâàÁƒ ¢ûm!..ÅÅÅ••+ª²aÃXYYÁÞÞÿüóOqwïÞEff&.\È+**‚ àèèˆ!C†ˆõùò%RSSÁãñØ 9ƒñŽr÷î]à¢cšÂæÍ›áããhkk#,, _~ù%¦OŸ333¬[·'OžDtt4÷Ý "<<>„¦¦f£×ýå—_`ooßd»"!!0`À€Ÿ»°°G…±±1®_¿Ž;wÂËË 3gά5¿½¿¿?ˆšššMú¬ ƒÁx›aEšêAä }=?f},]ºÀæÍ›aeeÕ¨|mõ‡€€…B¬^½ºEæ¬EEEâÒ¤¤$,^¼NNNU´ÌÉÉ©©) ¨¨MMMÄÄÄàË/¿„««+þþûoî%Y¤Ð255…††JJJpùòe ¯ßµk€êjÖµb255ÅÑ£Gáãã#Q᣶@FFÆÆÆ¸xñ"¼½½all̵éèè`ðàÁHHH€DEZf̘ÇÃËË B¡°CåØb0ZQº YYÙV©ì¾bÅ ØØØ ,, úúú->¿@ @ff&RRRžžŽ””¼|ùiiiÈÌÌÄ·ß~+vOhkDù‡ &V¬JZZ§OŸFQQV®\ eeeXYYqíþþþ––Æ´iÓT«£¬­­±uëVŒ=ºÆ:AAAª Rµ´£›Á`´?Ü&ð›ŠÅ¦ ¡¡ ±û#ŸÏÇÓ§OŠS§NáéÓ§ÈËËC¿~ý0lØ0 :´É0 ,ÀîÝ»‘žž^Cý^ÉÉÉPPPh0Â!** Z´Àf\\<ˆˆˆ,Z´ׯ_—¨è (å“(‰Á`0ŒÿÌAZݺu ¹‚TZZ?üðæÏŸëׯcÖ¬YMZ7997oÞ䎴´4€A›8HßTÆÆÆbùòå8qâD åOmdffbúôéxüø1TTTàéé 899aÓ¦M ÄÈ‘#ñÓO?ÁÎÎŽSÜŠŠ3]ºt ÅÅÅÐÐÐÀÔ©S%²¹¤¤„«‚üÉ'ŸÔÚÇØØ²²²HKKCttt‡©ônff†‹/ÂËË »wïk377Çàáá!‘ƒÔØØ ÈÎÎFHH [Ël£Ý9H»wïÞ*3g΄´´4ÜÝÝ›å -))Á£G‰ØØXÄÅÅ!>>ÉÉÉ5TN222èÕ«úõë×î=èééÕh“““Ã… `ll kkktïÞsˆ>xð#FŒ€ŠŠ BCC±aÃüùçŸuæ…ñ×¶±Å`0Þ~îÝ»‡’’(++·Ús‰œœ† V#¿éË—/ƒèèh\¸p¯^½‚P(ÄàÁƒ¡¯¯aÆ5X`éҥرcNŸ>]#r]„‡‡cÚ´i˜={vƒ9›EÒææfðôôÄÑ£Gѽ{w¬_¿^"Qƒ"⢬˜ƒ”Á`0ÿE˜ƒ´šR¤iΜ9èÑ£.\¸Ð(iFFÎ;‡Ó§Osªž={bòäɘ:u*¦N*‘s²%9HKJJ†U«VáìÙ³ÐÒÒjplrr2ŒñôéS¨©©ÁÇLJ{8[·n,--ñùçŸãÖ­[ظq#>Œœœôèу )…×[[[K¬Âݾ};„B!x<W¨éM”••1vìXÂÛÛ»Ã8Hg̘‡˜˜¼xñB,¤É€··7ªªªÄòªÖ†‚‚&Mšoooxxx0)ãFä íÑ£G«Ìß³gOŒ3þþþغu«Äã’’’póæMܾ}!!!ˆ‹‹ã¡;wÆ!C```€… BCCýúõƒ††úôéuuõvwŒŠÏ:th­íJJJðööÆäÉ“ñÑGÁ××|ðbcc¡§§‡ùóçCAA®®®uVfNNN梚zË`0:.¯ç‡—••mÓµkS›VVV">>¡¡¡¸pá~ûí7äçç£OŸ>œÚÔÐлoéèè`ìØ±pvv–ÈA())ÕùL*‚ˆ é ÒŒŒ 8;;ÃÇǦ¦¦pvvnRáÂÇ#-- ²²²˜2eJ“la0 ã­†uIHQQ±Qã/^L½zõj°_QQRTT$€ÆŒCDD©©©Ügñøñc‰mÖÐÐ ¤­­]o¿_~ù…±±±Äs·#FŒ täȱóåååÔ¥K@wîÜ‘h®ýû÷‹}¦ Æ»Š““ ##£V[㫯¾"âóùuö©ªª"___Z¹r% 8»¯uëÖŒiË–-tåÊJJJj·ûzSxï½÷¹»»×Û/55• @ªªªCòòò´nÝ:ÊÈȨwŸÏ§qãÆ6l•””´¤ù £ƒ §§GèСCímJ½¤¤¤§§'mß¾>ùäúæ›o¸¶C‡ ®wޏ¸8êÝ»7©««ÓvËÑ; IDAT“'O\óÙ³g€¤¤¤¨¸¸¸Qö†„„вeËÈÜÜœÜÝÝõýOaaabçvîÜIhòäɲƒÁ`0Œw¦ ­‘‚´¤¤|>rrr300À™3g‘‘^½zÕhONNÆþýûñ×_¡°°ššš°··ÇâÅ‹ëTê´%"ihh(ÂÃÃ%Ú…Ž‰‰±±1ÒÓÓ1`ÀøùùaРAµö•’’—_~‰°°08;;§=yò$ÆŒ#ñNz||<^¾| X³fM½}MMM±yóf¢¸¸˜»ÖöÆÌÌ ‘‘‘ðòò‚­­-w^^^S§N…››<<<Ä*I×…¥¥%ìì슗/_BCC£5Mg0Ú…ÄÄDlÛ¶ Àÿ*·cÆŒ££#âââjÜ“‚ƒƒñÏ?ÿàòåËÈÎΆ¢¢"Œ±`ÁÈÉÉA  99>Dpp0x<zõê…ÁƒcèСÐÕÕÅÀ[,_uKRUU…¤¤$À{ï½Woß>}úàÆ˜8q"LLLÀç󡬬\§jTÄ÷ßû÷ïCQQ.\@çÎ[Ê|ƒÑAÈÎÎæÒuHRà³=éÛ·/úöí˼|… bÆ pvvƘ1cjŸ€)S¦ ªª ·nÝ‚ŽŽNƒkŠÂë ÀÕ¨¢¢"œ={gΜÁ¨Q£àààШâNprr‚‚‚6mÚÄwssÃT?+3 ƒñ_„9HëAä €‚‚‚“¬‹èÛ·/€ê—öפ/^¼À÷ß .¨®Ð¾fÍLœ8±C !z@344”È9äää`È!ðóóC¿~ýêì_^^ŽåË—ãìÙ³ªs½Þ¾}ÀÿÂë—,Y"±½"‡¢¬¬,¾øâ‹zûêééAMM YYY¸sçf̘!ñ:­‰¹¹9víÚÿÎx ÎAºcÇŽç8p ttt .·+ƒñ®+++.ľ®Ü–-èÅ3%%ººº¨¬¬Ä¥K—°ÿ~ιgaa+++̘1£^'ŸP(DFFâããñäÉܸqIII¨ªª‚ºº:tuu1lØ0èëë7ªHkÊÊJ@ÿþýìÿÞ{ïÁ×ד&M!''§ÞþîîîØ³gàСCxÿý÷›o4ƒÁèpøùùA(bРAunœ¿ tíÚ}ô\\\°{÷î9K“““1}útðù|ܼySbÁCHHÔZÀîuâããqìØ1„††ÂÊÊ ÞÞÞPPPh >Ÿ777üý÷ßÐÑÑÁž={¸ûzll,¾úê+.÷¨ªªj¹ü ƒÁx×aÒzPRR‚ŒŒ ªªªŸŸ/±ƒTMM •• Ú¹ºuëVDll,ddd0þ|‰lœsÕÀÀ ÁÜVRRR066†‹‹ |||:ŒƒtüøñèÚµ+ „É“'smàñxˆŠŠBRR’DJ3f 66žžžÌAÊx§8|ø0ììì8çP½)ÐZˆ6{RRRpíÚ5¬_¿‰‰‰4hvìØ+VHœëMJJŠË‡÷úï8Pý}…èèh¸ºº"==Ý»w‡‘‘ŒŒŒ §§'ñËpK  :gª¤ÊÎáÇÃÍÍ ¦¦¦HNN®³_JJ –/_"‚ ¬­­[ÄfƒÑñå511igKšÏÒ¥Kqþüy\»v óæÍãΧ¦¦bÊ”)ÈÏχ¯¯o£6íDEꌌŒjmOOOÇ矎޽{cõêÕm”‹ÈÎÎÆ±cÇàåå…9sæàòåËœ"226l€¿¿?€êH®/¾ø?ÿüs“ò—2 ƒñNÐÞ1þ=zzøð¡ÄcÂÃà ]¾|™NŸ>M½zõ")))Z¾|9½xñ‚„B!ݹs‡V­ZEcÇŽ¥¥K—’³³3=~ü˜ªªªšd§P(¤gÏžÑÝ»w›4þuNœ8Ah„ õö»}û6—SOO²³³ëíAýû÷'¤  @HNNŽ·víZ@³fÍ’ØVwww.ßßW_}%Ñggg@C† ‘x¶`öìÙ€¾ûî»m£F"äää$Ñ\þþþ€”••©¢¢¢¥Me0Úœªª*²··ç~ßÍÍÍiîܹ€¶lÙÒjëVVV’´´4w¯>|8¹»»“@ hµ5Eäææ’§§'988ÐÌ™3iúôé´víZºpáåææ¶êÚ~~~€455=öÁƒ5rÛ‰àóùôÁÒÕÕeyGŒwœ>}úºråJ{›ÒlõíÛ—,--¹s¤££CÊÊÊôàÁƒFÍ' ¹÷Œ[·nÕÚ§²²’ 5o||<ÙÙÙ‘‰‰ ¹ººrïB¡<<<ÈØØ˜û.@JJJѨ5 ƒÁxa ÒPQQAnnn£*Ù‹”M7nD||< àîî®Ïĉ¹|’qqq¸}û68€'Ož€ˆ ªª MMMôîÝ;wF§N ++ >Ÿªª*¼zõ ™™™xùò%§TÕÔÔ„A³+K¢ õòòÂÇŒ²²2L˜0ׯ_G×®]ëíÿÉ'Ÿ °°}ûö…®\¹‚>úªªªàóù8wî4JMô믿ròä‰DcLMMÁãñgÏžAKKKâõZsss\½zÞÞÞØ¹s§X›……=z¬^½ºÁ¹&NœÈ)RïݻǪ‘2Þj^½z…ùóçÃÏÏ`gg‡½{÷rJó.]º´ÚÚ2228p Š‹‹±gÏ|öÙgm–3´{÷î077çòáââ―+W¢  zzz066Æøñã[Ta* ‘—4râu ëlûöÛo%%%¸ºº²¼£ Æ;Ì“'O––Ø´i._¾Œ‘#GbÔ¨Q5jzôèÑÎ6))),^¼üñÒÓÓ!--©S§"%%žžžõÞûj#!!¹¹¹––†¾¾~­}ddd ¬¬,Ñ|wïÞ…££#”””°aÃŒ1PVV†Ó§Ocï޽ܳ2ǃ©©)|}}Q\\Üá¢Ù ƒÁh˜ƒ´DyHã åóù€¤¤$ìÚµ _ý5¤¤¤ê쯭­ mmm±s999HNN朳¥¥¥¨¨¨@—.] ##ƒ OŸ>èÕ«ÔÔÔZôÁ¦!éµk×`ee…ŠŠ Lž<îîîõ:(öíÛ‡ 6@(bìØ±8wîF\ø·‡‡rrrн{wXZZJd'ŸÏçr7Õy |TWWǨQ£Ž7n4˜·´­…ûGFF"%%E,«……~ýõW ´´´A§‚¬¬,¦M›†Ë—/ÃÓÓ“9Ho-OŸ>ÅG}„ØØXÈËËãÈ‘#Xºt) °°$~yl*PVVnwgÇƒŽŽttt°jÕ*„……ÁÏÏŽŽŽ€ &ÀÆÆ¦IŽÍ×…Ø7wž×¹víöïß8xð Ë;Ê`¼ã¨¨¨@]]™™™ˆ‰‰ALL N:ŵ÷íÛ#GŽsš4¨ÞgæöfÙ²eعs'ááᤤ$xyyáÃ?lô\> 6¬ÉEC+**pþüyœ8q†††Ø·oúôé ºÂÁƒqèÐ!îž®  €%K–૯¾‚ŽŽLLLàë닳g϶j>oƒÁ`0Þ Ú[ÂÚÑ™6m £GJ<&77—>ûì3 oEËZ»wïêÕ«W6’‘‘!4cÆ *--­sžÊÊJZ½z5Â3þ|*--¥“'OróWVVÑœ9s­^½Zb;ûí7nîÞ½{:þ¼Dc7nÜHhöìÙ¯× 6ŒÐßÿ-v^ šš ëׯK4×?ÿüChèС­a*ƒÑêøøøŠŠ ÷;þï¿ÿе;–‹‹K“æøð!¹ººRDD•——·„ÉíJii)ùúúRZZZ³çÚºu+ Å‹·€eD/^¼ îÝ»Z¹re‹ÌÉ`0:>UUU”˜˜Hîîîäàà@–––¤¥¥%âýú!''GC‡%kkkrtt¤ÀÀ@*..nïËCôÝ£  @~~~Mžgݺu€lll=6##ƒèƒ> GGG±çqQˆ½(RSS#‡é°þúë/@ï½÷^“¯ƒÁ`0Œw¦ m€¦(H»wïŽcÇŽµ–I­N] Ò£GbÕªU …˜?>NŸ>]gQ¤W¯^aÞ¼y¸yó&x<¾ûî;lß¾<ÇPì^FFyyyðôôиðú£G¨.Ðbff†C‡ÁÝÝ]¢O¦¦¦Ø±cüýýQYYÙ`q§¶ÂÌÌ ÑÑÑðöö† w^JJ ¦¦¦8uê<<<`aaÑà\3fÌÇCLL WT†Áx[8zô(Ö¬Yƒªª*Œ9nnnÐÔÔëÓ\i=ðèÑ#œ:u qqq¨¨¨€¼¼<† mmmèèèàý÷߇ªªj³¯§-PPP€±±q‹Ì%T‡w6—ÊÊJ|òÉ'ÈËËÃðáñwïÞfÏÉ`0Þ¤¥¥¡¥¥---Ìœ9“;Ÿ™™‰ˆˆ}ûö%tûöí[¿¼¼œ?~L.\ _~ù…/^L¦¦¦4cÆ úꫯèï¿ÿ¦‡¾óÅ…-]º´Ùs‰ ð)))Ñ“'OšoƒÁx')++£àà`ú믿híÚµ4qâDîY­¶£wïÞdiiI?þø#¹¹¹Qjjj›ÙÚÜï€òòr’——'ôøñãzû òõõ¥yóæÑ’%K(**Jlžþù‡tuu¹Ï…Çã‘™™ݸqC¢çê‰'Ú»wo³®‰Á`0Œ·¦ m€¦(HßvD R"Bii)œœœ°qãFÀÊ•+qðàÁ:óCÝ»wsæÌAvv6TUUqùòe®œ8qB¡ãÆãv©E ¥K—JœKUTĈÇãÁÎÎ<ÊÊÊÈÏÏG`` ¦NÊõussƒ——¼¼¼`ooeË–aõêÕ˜2e ÜÜÜàããƒI“&5òSj&Nœ%%%âßÿûìÌÌÌ ++‹””<~üX¢\Q ƒ§§'Ö¬YÓš¦3Í&77óæÍí[·8åùo¿ýVçý¦5rÊËËCWWºººb竪ª¨¨(¸¹¹aûöí(..†²²2tuu¡¯¯CCC¨««·˜-úRS¹xñ"þüóOÀáÇ¡££Óf1ŒwN:a̘13f „B!nÞ¼‰³gÏÂÍÍ ¹¹¹5ú§§§ãúõë¸~ý:wN]]úúúÐ×ׇžžôõõÅrº·ÍÍIÊÕhHµ¹hÑ"Œ9‡æ [eggãØ±c8pàWKNN ,Àwß}Wã;¬>&NœˆÀÀ@.'*ƒÁ`0ÿYÚÛCÛÑÙ¶m§šü¯PTTÄíBoذûû·ß~[ïNô?ÿüCrrr€tuuéùóçbíB¡Ë;%ÊéÇív?{öLb‡ÎÙ%R¢ÎŸ?ŸXß‚‚úù矩OŸ>b»ëC‡%¤§§'ñºmÁÌ™3 }ÿý÷5Ú&MšDhûöíÍuÿþ}.OÖ»®xc¼ÝDFFÒÀ uêÔ‰NŸ>]o¡PÈ©ÑÛÈÊšRPPíÛ·>ýôSš>}:YYYÑ®]»( € ÛͶæðÓO?²¶¶nò Ôµk×Fç—f0ÿ]¢¢¢ÈÁÁ  ¦íÔ©“££#¥¤¤P~~>’££#Y[[ÓСC¹H§7?~<ÙÙÙ‘³³3EEEI±ÔZìÞ½›±±q£Æ=}ú”ììì¨sçÎÜõõìÙ“ìí훬 uss#¤¥¥Õ¤ñ ƒÁ`¼+0i¼­ Ò’’dgg###999())AAA€jÕ•@ €œœ!//Î;£GèÛ·/úöí )))…BìÙ³`oo;vÔº–P(ÄÆñû│V-ž={¶Feû€€<{ö °²²P­(€É“'càÀ][TT?~ÌýÛÓÓï¿ÿ>>úè#¸ººÂÍÍ ŽŽŽœUYY[¶lÁ¦M›àááýû÷Ãßß111€°°0lܸß|óM‡È5hnnŽk×®ÁÛÛ¿ýö›X›……nß¾ NÕ[†††PSSCVV$Ê]Ê`´5žžžX¸p! ѧO\½zcÆŒ©wLqq1„B!€Ö¯b_]ºtÁ¸qã0nÜ8î\~~>‚ƒƒ„ ¨¨}ûöÅäÉ“1eʉÕL7nÜÀöíÛáåå…N:µÖ%ÔŠèþIMT–••ÁÀÀÐÓÓÃüÑ’æ1Œwˆ²²2¸¸¸ÀÉÉ áááÜyEEEÌ™3VVV066®¡Úœ0a&L˜Àý;//aaa Ehh(˜˜ˆüü|Ü»w÷îÝãúªªªŠ©Lõõõ1`À€V¿V<±ïŽúð÷÷Çž={àååÅÝ—‡Н¾ú ÖÖÖÍúŽ000<{ö ùùùÜ»ƒÁ`0ÿ9ÚÛCÛÑ9uê >ø ½M£¬¬Œ=zD®®®´}ûvúâ‹/ÈÜÜœÞÿ}±]å–8zôèAZZZuŠŠŠ\ßuëÖQUUU­6úé§€>ýôS"ªÎ©Ô¯_?@Ç—øÚ¿þúk.g)š:u*½zõŠdee =zô¨Þ9bccÉÎÎŽddd8ÛåååÉÊÊŠ‚‚‚$¶¥5xþü9§r}³utt4 iiiÊÉÉ‘h>kkk¦àbtH„B!ýöÛoœtܸq”žž.ÑØ×ó—••µ²¥Í'99™NžtèP³Ö …A÷ïß—xÌ®]»Í;·Ik.[¶Œûù4f]ƒñßáùóçôÝwßQ=¸û…´´4™ššÒÉ“'[¤zý«W¯ÈÏÏvíÚE , Áƒש4íÞ½;MŸ>6nÜH®®®­ ©©IèÚµkuö©¨¨ WWW244³süøñäîîÞ¢*XQÅûèè蛓Á`0Œ· Q3Œ½ã\½zsæÌA·nݰ}ûvŒ1ººº5Ô‘­…(ï¨Âgdd$ââ└ĩ§êCUU={öDçÎÑ­[7Õj+iiiTVV¢¸¸˜û3++ éé騪ªj’­_ý5vïÞ]k[aa!z÷îÒÒRøûûcêÔ©ð÷÷ç}¦UUUèß¿?ÒÓÓñ믿bÓ¦M““CNNºté‚iÓ¦áæÍ›øù矱eË–ç+,,Ĺsç°oß>NQ úúú°µµ…µµu­U?[ÄÅÅáøñãX¶l™XÛàÁƒ‘˜˜,\¸°Á¹Î;‡… ¢ÿþxñâE+YÌ`4ŽòòrØØØÀÅŰdÉ=zòòò‹‹ãòYvíÚFFF;v,ŒŒŒ`ddÄåië¨<{ö @FFÞÿ}˜››cÆŒbý ðêÕ+ÄÅÅAZZZâùKJJàææ†+W®àÖ­[ÈÉɆ†—«®!þúë/ØÚÚr÷êÆ +âáÇœB‰Á`0bcc±}ûv¸¸¸pÏœ½zõ‚­­-V®\ V]¿  €SšŠþ|úôi­Šùnݺ‰©Lõôô0hÐ ‰sæ×Fnn.±”žžŽ^½zÕ°ïĉؽ{7RSSTç5k¾ýöÛV¹Ÿ8IIIðóóôiÓZ|~ƒÁ`0Þ ÚÙAÛá9}útfGƒ ¢9sæÐæÍ›ÉÉɉ®^½J÷îÝ£gÏžQiii£×ÉÏϧÔÔTºuëíÛ·lllH__Ÿ:uêT§²³S§N4räHúøãiÆ ´oß>rww§ˆˆJOO¯·Ò|]TUUQJJ 9;;“ƒƒùúú6xhkk:{öló=z”¦¦& ""Z²d‰˜¢T<<<¸*ïÅÅÅ\^ÑË—/Ѿ}ûéëë7꺅B!ùúú’•••˜ªT]]ìííéÅ‹š¯¹|õÕW€,XP£mÍš5€/^,Ñ\yyyÜ5½^ù”Áh/ÒÒÒ8EŒ””íܹ³Á1IIItñâEzùò%U«èÅ~__?† BÖÖÖäääD¡¡¡Mº¶%111téÒ¥ç/^¼HÈÅÅEây–/_Î)ûûôéCK–,¡'NÔP¤×‡««k“r4‡„„pß["•Ö… 5ƒÁx7yüø1-X°€‹@FFFtæÌª¨¨hWÛ èÖ­[ôÇТE‹HGGGÌÎך:u*}óÍ7töìYŠo”šS ¦¦&v>!!ìììÄ"³ºvíJvvv”’’ÒÒ—,ÆØ±c :uªU×a0 £#ä P\\LÒÒÒ€† F***…¥wéÒ…(Š>jÔ(Ò××'}}}ŸO!!!\¡Q¡§Úî£úúú\‘ŽÆ…kOéèèÐÈ‘#ë½÷¼xñ‚æÏŸORRR¤  @Ÿþ9ݺu«Éß7nÜ  qE;rss¹ÏÊ”)dffFè?þh’ ãÝ 55•lmm¹çi¼&Þ‘)**ªQêõkxó¹ÿÍBPuÝEšÌÌ̈ˆ( €fΜ)æÕÖ֦Ç·YÍ3fÚ»wo›¬Ç`0 FG„9H%`äÈ‘€Nž¥¦¦RXXXPôK—.‘««+¹ºº’ݽ{—=zD‰‰‰”““Cåååmp5-ϯ¿þZk8xyy9YYYÑÔ©S9E‘ccc@ööö¯säȪÃôEÎЂ‚’““#ADD?þø# “¸ºjBBBÈÖÖV,å²²2ÙÚÚ¶ZB{Ñnþ–-[j´Íœ9“Ð÷ß/Ñ\€dddèÕ«W-m*ƒQ/B¡vìØÁ©cÆO™™™õŽÉÏÏ'OOOzòä QPP]¹r¥IF•••EGŽáT@µé‘‘¡¡C‡’­­-§j ÅxCTTTP¿~ýh„ bç322ÈÜܜЌ3())©ÅÖ|½XŸÏo°ÿ–-[8¥®hãfëÖ­€-ZÔbv1ŒŽŸÏ§?ÿü“zöìÉÝ_GM¾¾¾ímZ«P\\L÷îsÐÀ— IDATÝ£ýû÷ÓÒ¥Kiøðáu¦QRRâž[E‡œœY[[SXXX»Ø_UUEòòò€"##ÛŃÁ`0:ÌA*ýõ CCÃö6¥QP^^žØ‘””D‰‰‰: ë]çøñã@ì彨¨ˆ,,,èÌ™3\x½H›ššÊí¶7æAlüøñ€~üñG±ó“'O&´}ûv"ªvfŠ^Ô[Ú˜‘‘A;vìàB„EcccruumÑ<‡û÷ï'4f̘m‡&4bĉçULuuum1Œ†(..¦¹sçr¿/ŸþyƒNμ¼<º|ù2ݽ{—ÒÒÒèöíÛÖ,Õvjj*yzzr÷³üü|òõõ%²´´¤îÝ»×ú2ÛµkW266&rww§ÜÜÜ&ÛÐ ѵk×HMM:uêDhqGnii)÷4”»ôúõëœóûàÁƒÜùƒ¶øfƒÁèØ\¾|™Þ{ï=îþÑ¿:yòd‡I ÕV”””PPPýùçŸôÙgŸÑˆ#j(M•••iãÆÊÝ<}ú”´´4•••µ«- ƒÁ`´'¬Š½DFFbäÈ‘••EQQ‘ÄU–›JII ^¾|‰¬¬,dff"==YYY())AQQ PZZŠ’’TVVB(BZZÒÒÒàóù5ª®«¨¨Ô¨¶)ªh/ ³gφ¹¹yí¾¾¾011ÁÀñìÙ3ÀŒ3°nÝ:TUUÁÒÒJJJHOO‡’’¶oߎ~øcÆŒApp°D6$$$`È! "ÄÅÅaÈ!\Û®]»`oo?ü·oßASS)))8wî,XÀõ---Å‘#G`hhˆñãÇKü¼‰@ €§§'öïß®ò©––lmmaccÃU(m*Ïž=àAƒ %%…—/_B]]kKMMEÿþýADHJJ‚¦¦fƒó}ñÅ8rä–.]Š'N4Ë6CÒÒÒ0kÖ,„††BZZ¿þú+ìííë“””„GaòäÉ€ÀÀ@(++cܸq““k’¯^½Âµk×`jjŠÂÂB‘Ø=DijgÏp÷î]„††âÞ½{‡P(¬ÑOKK ãLJ¾¾>&L˜€Ñ£GCJJªI¶IJII  === <‡ÂðáÃqæÌèêê¶ÊšÊÊÊ(**BXXF]kŸ/^@__¹¹¹X´hΜ9õ]¼xVVV=z4ÂÂÂZÅFƒÑ1ˆˆˆÀúõë úÙóûᅦ:uêÔÎÖµ/øí·ß°}ûvTVVBFFFFFðññ¢¢b{›XZZbРAHHHhos ƒÁh?ÚÑ9ûÖÀçó9uÌ’%KZ,/Pee%:tˆ¾ùæš7oMœ8‘&NœHôÙgŸÑ?ü@ŽŽŽtæÌòó󣊥äädÊËË롟DDÑÑÑ€äåå9›Dé>þøcN5&B”çhß¾}¯! ›3Ä”¨º**þç[¤îå¾{3´óäÉ“Üν={V¢ðÑúˆ%;;;./¨è³°²²jvž­Áƒ‹©o_gĈ€:$Ñ\nnn€zöìùŸSr0Úž   êÕ«§’©-æëTTTÐýû÷éÒ¥KôâÅ Š‹‹£«W¯RTTT“m¨ªª¢ÇÓÍ›7©¸¸˜Èßߟ222$ÿz®9++«:óL+))qÅ9\]]LÐTD!ë<Ö¯_ßêJÑýÇËË«Öö²²2ÒÓÓ#4|øðÅDõëׯUíd0íGFF­X±‚SGÊÊÊ’åää4yÎÐÐPJHH /^´hdN{pÿþ}6l÷}ñá‡R\\\{›%Æï¿ÿNÈÒÒ²½Ma0 £]aR 9–DÇ·ß~Û"óVVVÒ¥K—èþýû¿°wDòóó¹Ï&;;›;Ÿ““Ãå4þ‘‘‘øš…B!iii:zôh­}DáãçÏŸ'"".<öõpÞÜÜ\Z¸p¡Xn¨~ýúÑÎ;›Ž_PP@GŽ¡¡C‡ŠýÑ××§#GŽ4É™ñå—_Ö™Ãï‡~hÔmqq1—CõáǶ…Á®0ÒàÁƒ)&&¦Þþ€îܹCOž<¡ììlzðà]¿~^¼xÑdòóóéÖ­[ôàÁª¬¬¤ÀÀ@òõõmö怨”½½=?^,/ñ뇨Ԏ;(00°Eœ™yyyôñÇ“O³ç’QZ“'NÔÚ¾lÙ2@***ôôéÓí=" ºº3ƒÁx·àóùäèèH]»våî{ÆÆÆß«û÷ïSxx8QTT‘‹‹ EDDPllì[^ZZJöööœã¸k×®täÈ‘#nxÏ?ÿœÐ7ß|ÓÞ¦0 ƒÑ®0©ˆr\8€êêË qÅ %íÛ·Ð!C¸µk×úè£$žûÖ­[€:uêT§ó‹/¾ ´lÙ2"ª~pWQQ!äççW£ÿË—/ÉÁÁA,ï`çÎÉÀÀ€BCCsé5 …äëëKVVVbù¦ÔÕÕÉÞÞ¾QN@ªªª5”Ë÷îÝ#¤  PC¹U¢*Ó¹$C"„B!988pÿçMLLÜxÈËË£k×®QPP“¯¯/=yò¤Y/ÁùùùH¡¡¡ôòåKruu¥'Ož4y¾úàóùBŽŽŽ\¨Ú¦²²²¤¯¯Ovvv\¨ŽÎ¬Y³ýñÇ5Ú:Ä©Y/_¾\ëøøøxNÝÏ`0Þüüü¸M0ôþûï“··w‹ÌžžN‰‰‰Íå¢~òä ¥¥¥ÑÓ§O©  €®]»F>¤ŒŒŒ&îkmüüü¸}4{öìvÏ3Z&L¨W„À`0 Ææ m€ÈÈHâñxÄãñèîÝ»\¨ýóçÏÛÛ´…(!¿§§'wnÔ¨QbÅ“ø|>©ªªºxñ¢Äs/_¾œÐ‚ êì#Rùª©©q ± úòË/ëWTTDGŽ!E—ÜÝÝ%¶±.ÉÞÞž»n‘³ÀÒÒ’|}}T”––r/!ÿþû¯X[UU7ïëŸ{}ˆœÖM¾&£6²³³I[[[¬SCéHÊËË)==ÂÂÂ(<<œîÞ½K7nÜhV“ÔÔTrqq¡ôôtzþü9ùùùQttt“ç“„¤¤$±R©©©téÒ%úæ›ohâĉԹsçZ¦4wî\úý÷ßéÎ;ot´¢{ï?ü vþÁƒ\tÀ¦M›êŸ––Æ]«(í ƒÁxûmJ¿¾Á}šÛ…o(Q¿‰‰‰˜“6??Ÿäää…‡‡7¸–(TJJŠ>ýôS±Ü‚êêêäààÐ"!!!dkk+6¿²²2ÙÚÚÖªtÛ»w/ ##£m...œXRD*¿ãÇ7ç2 1Ž9Â¥|xý%±¶CEE…ÆGŸþ9íÙ³‡|||¸”¦PUUE^^^tÿþ}*(( àà`Šˆˆhv¶úEOž<¡””ú÷ß©°°Pâñ999äááA?þø#™˜˜ˆåñ{ýèÑ£͘1ƒ¶nÝJ>>>”ŸŸßj×ô&;vì 4oÞ<"ªþœ¹{NC÷Ãòòrî:êrŒ3Œ·+++@K—.¥rpp }}}N=):TUUÉÊÊŠœ›ëýMJKK)++‹bbbÈÇLJ>|Haaa”˜˜H±±±D7nÜ *++£œœœÏaš™™IÖÖÖb‘W¯^m‘¹]¾|™ŒÉÞÞ¾U Þ¹s‡€êž ƒÁ`ü×aÒzUN×ÕÕåTMŽŽŽ€LMMÛÙºÖ¡ªªŠÒÓÓ)22’|||èÔ©S´gϲ··§„„„:ljò;vŒ***¨gÏž€\]]‰¨º8’ÈÙ|ÿþ}‰í9=¿þúëûЉcÇŽåÎM›6MÌiÚ"%¬““¥§§“ƒƒõèу{ð•——'kkë ÙÍÈÈ ;vpj¬×Ãû]]]9eVll,ç¸ÍÊÊ›#//+8%iNÃõëײ²²jö50"DÎz‘#???ŸBBBÈÙÙ™ìííÉÒÒ’´´´j¼<¿~(++“¾¾>YYY‘ƒƒ¹ººRTTT½ ¤²²2ŠŽŽ¦ÀÀ@zúô)ùùùQHHH«^kii)ùøøPTT………QHHH‹„'&&’³³3ÙÙÙÑøñã¹ ž7---²¶¶&GGG lµ|G%4mÚ4""úþûï¹û $…Þø|>gssà £ãáééIHQQQls(##ƒœÉÊÊŠ”””Äî]ÒÒÒ4~üxÚ±cG«¤>ÉÏϧÄÄDzøð!]¸p^½zE OÙÙÙL×®]£œœœÉ_êêêÊ…§óx<²µµmÔFY]ðù|rvv¦I“&‘ƒƒååå5{κÝç'NœØjk0 ƒñ¶À#"£ÐÔÔDff&þþûoØØØ®\¹‚¹sçBQQÅÅÅíl¥d”——#;;ÈÊÊBVVV¿WVVBJJ  ¦¦uuuôìÙêêêèÕ«zöì }}}ÈËË׺ƈ#ðøñc\¹róæÍC÷îÝñìwTT×÷öŸ¡J+6@° [,ATì5Ê׊¨±› 1ÖDÅ.± 56@PQ,E¤(b¤w˜™ýþÁ;÷'Òf`Ïg­Yâ9÷ì»ï0Ü9÷9ûìýîÝ;(**âÀX´h:t耘˜ðx¼ý~÷îttt îÝ»W{|ll,:uꤦ¦¢y󿨷oœœœÐ«W/„……ÕxÎ 6`ãÆ:t(nݺ ì³pöìYlß¾QQQsss899ÁÆÆF¬ë© @???ìÝ»·nÝ‚èOR__ŽŽŽøá‡пÄÅÅáôéÓ˜¡PˆÛ·ocÏž=¸zõ*'dvïÞ .ÄôéÓ¡¤¤$–ŸUƒƒâرcÈÏÏP&µiÓqqq˜>}:<==˽O¦¦¦ ªñ¥¥¥hÖ¬²³³ñ÷ßcÈ!uò™ÁoooŒ5 ]»vÅóçÏ%Ÿ››‹èèhDFFrÿFEE!11U}M©¨¨ÀÐÐFFFå„S===N8•&éééxñâÚ·oÐÐPôéÓ­[·–úyª#!!>Ä£GððáCŸëSQQ™™lmmakk‹–-[Ö‹Ï>Dvv6ÔÕÕADÐÑÑA£F‘‘‡:T9–ˆpäÈüøãÈÍÍ…œœ,X€-[¶@EE¥Ö>åää`ß¾}ÀìÙ³1yòä/¶xmmm ìÚµ K—.ý"çd0 ãk… ¤U`llŒˆˆüüóÏØ¸q#€2ATUU¥¥¥ –àö)ïß¿GJJ RRR””„÷ïß#''EEEÈÉÉA~~> Áçó!P\\ •r⥪ª*ÔÔÔ¸—¦¦&÷¯¶¶6'„6kÖ¬^‚ªPSSC^^nß¾áǃÏç#,, ½zõâ";y<âââЮ];±lvëÖ /^¼ÀîÝ»áìì,Ö'''ìÛ·S§NÅŸþ èÙ³'ž>}Šýû÷cáÂ…5Úèܹ3bbbpìØ1Ìž=»Òc"""pðàAœþ\l¿«B ¿¿?1‚³_Y~E===@gΜËîÑ£G uéÒ¥Î>2Dÿwßl×®Ý9_~~>…††’§§'­^½šìììÈÀÀ€dddªÌqÚ¨Q#êÙ³'M™2…6oÞL/^¤ØØØj+±•JJJ¢çÏŸÓÝ»w);;û‹\£$…Brttärá-Y²„|8Y[[síZZZ/‘OÜøO¿K Ƈï¿ÿ^¢\ï•Q\\LäììLíÛ·¯p_ÒÑÑ¡ùóçÓÕ«W©  @ŠÞ×Lii)mݺ•+¬Ù¨Q#Ú¼ysŠæääЦM›hèСtéÒ%®ÎÁ—¦  €ûΔôþÎ`0 Æ&V‚­­- 3f”kÿüáÒÓÓ³<üºøðá÷žˆ*¤ïÞ½›ˆÊ>Q¢ãÇ‹msñâÅ€lmm%ò¥°°”•• QXX÷à/NÕGqB§¸£‹ŠŠÈÃútéRî3bbbBÞÞÞR™ü<˜Ð¦M›*ô-X°€Ð´iÓIJõîÝ;NÔNHH¨³o FPP 6mÚ4¨N§N¢5kÖÐèÑ£©C‡$++[¥(¨¨¨H=zô I“&ѯ¿þJýõ½|ù’JKKôZÄåsqôÀU›––F< S§NÑ/¿üB3gÎ$SSSjݺuµ´®^½*±_?~䯋{/e0ÿ.öìÙC¨W¯^R³GnnndccS¡X’’YXX««k½‹ˆˆ ¾}ûrç8p EEEÕÚ^ii):tˆ† B—/_n0aTDtt47?®i¡Á`0Œo&~Fll,·šµ»»»s$@;vìh@OëŸÏ§‡ÒhΜ94bÄ277'2dM˜0œÉÃÃÒÓÓ«µÃU'M´DÕÖEQeÊÊÊbWö,))¡fÍš:þ¼Ä×6räH@?ýô×&I„¥P(äDÝS§NI|þ»wï’M9±¡C‡äêêJùùùÛñûï¿sôϹzõj…ÈÙšèÙ³'¨VLa0Ä%88˜P‹-Ú•J)**¢'OžÐ™3ghݺudooO:u"99¹*EAêÖ­Mœ8‘6nÜHçÏŸ§¨¨¨:EIIÄÑš(,,¤¨¨(òññ¡={öÐÂ… ©mÛ¶äààP+{IIIÜ{ù5½g Cz$&&róúˆBÌËË#ooortt¤–-[V¸OѪU«( @j‹Z%%%´mÛ6NœUVV¦mÛ¶ÕID  333ruuýjßnܸAHOO¯¡]a0 ã«€ ¤Ÿ±hÑ"@ƒ.×.Ìš5kFŠŠŠ€nݺÕ0NJØØXZ±b>}š^¾|YN¼ …ôîÝ; ¡ƒ’©©)EFFViëáÇܶ#dooÏõ988HÙHDtéÒ%nKgQQ‘Ä×¶ÿ~@½{÷æÚ.\HhòäÉbÙprr"4vìX‰Ï/"&&†œœœHII‰›È7kÖŒV­ZE)))Û‹ŒŒä„èÏEë‚‚‚ ‘³5±~ýz±S 05!J‹¡¥¥ÕЮHDII ÅÅÅ‘··7mÛ¶¦OŸN½{÷æîg•½äääH__ŸlllhÕªUäááA¡¡¡_|ë§P(ä¢Çy<í۷¿&DÑI í ƒÁ¨GzõêEhÏž=õz@@¡¡¡äââB½{÷®õÞ¤I?~9::’··w…E«ÀÀÀrÅ¡llljµÓGDhh( :”Ž=Z/Á€Îž=ËÍu;uêD{÷€àÒ¥K -Z´Hê>2 ƒño„ ¤ÿ>ŸOíÚµ#äêêʵ¿}û–Û³téR²°° tøðáôöëB$Ì +Vpí¢÷jåÊ•bÛÚ·o÷@]—IåòåË ?žk›4i’DA‘9uêÔZûQ•å)mß¾}yJEé´µµ+¼?ŸæûKLLËiÓ¦Z¸pa®‡ÁxõêIþ-RáµlÙ’,,,ÈÉɉN«‹ZohqôðáÀæÎ[ã±'Ož$4`À€/àƒÁhHôõõ ø: ˜ …B §M›6Q¿~ý¸¨PÑKCCƒ&L˜@Gޡɓ'síÚÚÚuZ …ôûï¿Óرc)55UŠWô<|øKi`hhHgÏž%@P+[?üð(ê”Á`0Œÿ2L ýÿœ;wŽššZ¹j»£GæVÅ i„ €–,YB¹¹¹ èqÓŸŸO?~¤ÿýïÜäòÙ³gDD”’’Âmµ‰ƒh›Ð¯¿þZ'ßDÅ¡ÔÕÕ¹ˆVQ¤«ŽŽŽXâ«(úICC£V¹PÅ!66–œœœÊ‰(äääDÉÉÉŽÏÉÉáŠìììpåÊ,Z´ÈÈÈ@]]Í›7‡ŽŽTTT   àñxÐÔÔäì+))¡Q£FÜÿ555Áãñ PQQáúÔÕÕ!++ ““ƒšš×W›säææ¢°°yyyÈÉÉAaa!òóó‘ÂÂB ++ EEEÜÏ………(,,Dff&÷sVV PXXˆììì ïaóæÍ‘––ضmÖ¬YƒÞ½{#44T¬ßAtt4ŒŒŒÀãñ‡víÚ‰5®2JJJдiSäææ"((¦¦¦ÈÎÎFóæÍQRR‚ððpôìÙ³Z¥¥¥ÐÖÖFFF®^½ kkëZûSÙÙÙ8qâ~ÿýw¤¤¤(û\Œ5 Ë—/G¿~ý¸cÍÌ̈-[¶`Íš5åì¬Y³Û¶mã>¯5‘™™‰æÍ›ƒÏç#22FFFÒ½0Æ7Cjj*Zµj(((€’’’TìfeeáîÝ»ÈÏÏGNNrrrŸŸÜÜ\üóÏ?ÈÈÈŸÏAVVM›6…žžttt ££]]]èêêBQQQ*þH ¡Pˆ„„DFF"**Š{EGG£   Ú±<û÷ïÇ‚ ¾·@`` ¬¬¬Ð½{wܾ}»ÜwVU¬_¿›7oÆÌ™3áîîþ¼d0 …ìììжm[$%%5´;URRR‚;wîÀÝݧOŸǃ··7llljm3<<K—.Å–-[`bb"EoË ÅĉñæÍÌ™3¿ýöÔÕÕël×ÖÖ¾¾¾Ø³gœœœ¤à)ƒÁ`0ÿnäÚ¯°°0CVV .äÚ×®] >Ÿlj¢sçÎEll,BBB••ŽbccÊý¯†qãÆq?Ÿ:u 0cÆ ±Ç{xx(ë"Že⢹¹9._¾ ˜ššBCC¦¦¦¸yó&¼½½kHåååaccOOO\¼x±^R ,Y²óçÏÇ•+W°sçNý‹Š£OŸ>ÅèÑ£¡¯¯???±ÄQx÷î@[[»>Ýc0_ƒ ‚ŒŒ ’““‘˜˜]]݆v©R`aa{÷î,--ë$Žþõ×_8qâ.\¸€¦M›JËMŽÝ»wcÕªUhݺ5‚ƒƒË-˜×Ñ÷6ŸÏ—šMƒÁ`0þÍ0à"FG®ýÈ‘#€^½z¡M›6€=zàÆ€©S§âôéÓ8p ŸŸ’’e¹ŸFY¢¨¨ˆûVVDÁ»ÅÅÅå"†rrr ”MZrss¹¾êÎ!jjjPRR‚ªªj¹ŸÕÕÕ¡¤¤hhh@II ÊÊÊÐÔÔ„’’”””Êý¬¥¥%%%„……ÁÖÖ5ÂæÍ›!!!xñâäää0qâD±ü …8}ú4ÉDÕê°²²ÂåË—áç燭[·(ûß¼yW®\‹‹K6ìííáéé‰Ë—/ãðáÓ«ß?Œ?ãÇǽ{÷°wï^\¼x÷ïßÇýû÷a``€±cÇ‚ƒƒ‘••U.ŠxÀ€hÒ¤ ÒÓÓKKËÏimm{÷îáêÕ«øñÇëíÚÿmD‘í¸{TUDFF¢K—.õ⇶¶6´µµñÝwßUè+--E||<¢££ñøñc¸¹¹!33***èÖ­Œall\皺 ##}}}èëë—{h'"Œ;—.]â¾¾oÞ¼µµ5ÔÕÕqíÚ54iÒD챉‰‰ðÕ % CzhiiÁÐБ‘‘¸wï^÷iiiHNNFÇŽ¥ ))¾¾¾Ê–kˉ'àïï .H}—‚P(Ä’%K°ÿ~Œ=Ç—ú‚žè{»¦ïlƒÁ`0¾¾yôÝ»wøë¯¿K–,áÚ;Æ “»wï®tlHHÀÙÙãÇ—è¼ïß¿ÇÛ·o‘‘‘ôôtdddp/Q”Ч[í²ÕùêV¹?a,X///,^¼›7o.·U_Zœ?@™(êNž<  LxkÑ¢…Xvnݺ…ääd¨¨¨ÀÞÞ^*¾Y[[ƒÇãáÙ³gHJJ‚ŽŽìììàää„'OžàÍ›7ÐÓÓ«Ö†¥¥%ÔÔÔžžŽ»wïÂÌÌL*¾‰Ã Aƒ0hÐ ÄÆÆÂÕÕžžžˆ‹‹ÃŽ; ##>Ÿ‹/böìÙÜYYY >gΜÁÕ«WÅH×®]‹{÷îU\ qù4‚´ºh"ÂÞ½{¡¤¤„uëÖ¡Y³f_Â=e>vêÔ :u*מŸŸgÏžáéӧضm ++‹N:¡wïÞèß¿?:tèðÅü¬ ‡>}úàÒ¥Kxùòå9gzz:¬¬¬PPP€;wî mÛ¶g)ƒñm1hÐ DFFâþýû˜:ujµÇfffââÅ‹ˆEnn.x<tttбcGî>Ý®]»rß-Ò"-- áááj/nß¾)))8sæ ddd¤éJKK1cÆ xyyaÙ²eøý÷ß¹´\ÒD$KÝ6ƒÁ`0ÿF¾ytÿþý())A¯^½`jjʵoذжm[|ÿý÷Æeddàõë×€V{ŽçÏŸãáÇxøð!^½z ,Ê©M›6hܸ1÷jß¾=7n\å$H”߯*DÑ"D¯Øâèòå˱uëÖrÑ`ŸRPP€Õ«WcõêÕPWWÇÅ‹³fÍP6©óòòP¶ T\DÛëÇŽ+5!·M›6èÖ­ž={†k×®ÁÑÑ:::066Æ“'Oàëë‹E‹Uk£Q£F°²²Â¹sçpáÂ…/*Šèر#<ˆ_ýüñöïß·oß~þùçr)P6Ù?sæ |}}±wïÞí÷èÑ:::HJJÂÍ›7Ë¥J`0ÄåÓ‡Øê¢Qx<ÜÜÜpëÖ-Ìš5 ššš3f ¬¬¬ ¬¬ü%\­€ŠŠ  €pm|>111 ÃîÝ»ñêÕ+¨¨¨ OŸ>0`¾ûî»zYtªŽÎ;ÀH 1jÔ(ÄÇÇÃÏÏÝ»w¯ô¸èèh\¾|666èÖ­×ND\>e&2ß&&&pss㶯eâ[JJJ¹Z@ÙýlË–-åÚ233¹¼Ì÷ïßçÄSYYYèêêÂÈÈ]ºt¾¾>ÚµkWkÑðáÇ "ÎŽ$–.]Š&Mš`ß¾}µ:MÌ›7^^^غu+V¯^]/çÀ1¤¦¦ÖÛ9 ƒÁøWÑ`塾 ¨I“&€<==¹öàà`®²å‘#G*D¨yóæú££#õë×æÌ™CîîîõE+.÷éÓ‡———XÇïÝ»—«ìŽŽ&:sæ =z”P›6mˆÏçÑ¥K—iii‰]ù=77—TUU ݼyS¬1â²zõj@£GæÚ\\\YXXˆeÃËË‹¶¶v½T&•”’’rrr"¤©©Yá3•žžNrrr€¢¢¢Ä²éèèHhæÌ™õá2ãAFF†Ð«W¯Ä“œœL{÷î%kkk²µµ¥M›6ÑßÿMùùùõèiíÈËË£ÀÀ@Úºu+ÙÛÛÓ°aÃhîܹtîܹ/rþÈÈH@ TZZZoçáóùdggG222tþüù ý/^¼ 5kÖ™™Í›7®_¿^ÁŸääd®:tnnn½ùÊ`0¾âââÉÈÈPzz:•ÍI¦M›FcÆŒ¡€€€Z̓ )""‚þúë/Ú²e Íœ9“† F·oß®•Ÿ¢yàĉ%»~ýzúý÷ß+í»{÷.©¨¨ƒƒ=zô¨V¾ýòË/€Ö­[W«ñ’pàÀ‰æÃ ƒÁ`ü×ù¦ÒÇs"ç§b^¯^½©©©U9öäÉ“€úõëW®ÝÓÓ“ú÷ïOË—/§ððð/*ˆ~N‡]»v­ÚãJKKiñâÅ´páÂ*º=<<ÈÔÔ´œðabbBè§Ÿ~âÚìíí ÍŸ?_l??N¨uëÖœÐ*-DB¶ŠŠ ÷;'$//O™™™5ÚÈÍÍ%%%%@ÁÁÁRõ¯¶dgg“¼¼< gÏžUèýn~ûí7±ì]¾|™û[øD`Æ¿@ÑÑѵŸŸŸOÿý7mÚ´‰ìììhذaäììL'Nœ ­[·Ö«(X[jý.)ÅÅÅ$++Kèõë×U—““C!!!µ™—.]JhïÞ½\Û‡h×®]dnnNóçϧ{÷îU{¯àÐ Æ·C«V­ùûû—kûö-­_¿ž† B¿üò ÅÅÅ5‡DÓ§O'ôóÏ?K4î?þ åË—WÙŸ™™IóæÍãý{õêEÇŽ£‚‚±ì_¿~x<M›6í‹\iAAÍ;—ˉȱ±±ÄãñˆÇãqêéé館¨(±8dÈ@k×®{Œ¸ðù|jܸ1 €€®]OOpѰ5aggGèÇ”ºµåûï¿'´}ûö }[¶l!4dȱlåååQ£F…„„HÛUÆ7‚ŠŠJ•¢}môüùsZ¶l ©Øý7Ó¦MP­(ûÓO?qQ\dooO;vì „„„틬-ZDDe;ÉÆÆ†.^¼(ö÷ÛÞ½{Ydƒñ bccChÇŽ•öóù|ºqãú믿RXXØ (°°° äææ&ö___š2eŠX‹Èaaaôý÷ß“šš rtt¤ÈÈÈ*ÇdffRÛ¶m©sçÎb ªB¡ž>}J;wî$;;;š7ožØ×"âÚµkÜŽ9QÄŸ>}hÆ Ú A ƒÁ`4߬@êïïOHQQ‘Þ¿ϵÛÚÚ’““£ÂÂÂ*Ç/X°€³³ó—p·VˆÄŠˆˆˆ }|>ŸŽ;F ¨R@ŠŠ¢Vº}tøðá€̵íß¿ŸP‡ÄžT½yó†Û–[Û¨³š˜0a eË–qm‹-"4iÒ$±lœ8q‚žžÞW3a‰ fffú"""¸Ï±8Q²Dÿ÷;ݰaƒ´]e|#hjj •ª]¡PHÆÆÆdhhøÍG88Љ'ª<&;;›ÎŸ?O6l qãÆ‘¾¾>÷ð;eÊúçŸ*FŠŠŠdnnNÏž=£±cÇ’ƒƒ=}ú´F¿ÎŸ?Oƒ¦·oßѼyó-^¼¸vÊ`0þ•¬ZµŠÐŒ3j<¶¸¸˜nݺEË—/§¡C‡ÒäÉ“iÿþýQ¯÷zѼ»»»XÇ?~ü˜¬­­kL•––FsæÌ¡‰'ÒÓ§OI(ÒíÛ·iܸq$''G222diiIW®\©°cjöìÙ$''Wí"uVV¹»»Ó¤I“ÈÜÜœœÉÇLJrrrĺŽÏ¹~ý: UUU222*'– V­Z‘££#y{{•io ƒÁ6߬@jiiIhΜ9\[QQ—»ñÓœ••1yòd@¿þúk½ø÷Ï?ÿPHH?žvìØA , kkk255%[[[±D:Ñv×—/_rm'Ož¤7RÿþýióæÍU®R‹¶Ô¾J(ÒâÅ‹¹ÉÓÎ;¹¾~ýúUˆÈ­ Q®¥ÏSHwww@;wæÚDÛ?544ÄŠˆÊÌÌäÞÏðððzóU>M••U¡_WW—ÐÙ³gŲçêêJè»ï¾“¶«Œo„-ZÔ[* OOO@>>>R·ýobâĉ€~ù副½yó†Ö¬YC ¤££C)))åúsrr¨C‡Ô²eKrrr¢±cÇŠµ6$$„FŒA«V­âÒ“““I]]ÐÂ… %ò“Á`ü»Ý«ûôé#ñØ´´4ºxñ"-]º”FŒAÆ £éÓ§Ó¶mÛÈÇLJââ⤲H-Š ­j÷Ôç;v¬ÆÅæ3gÎÐ!CèÁƒ•ö¿}û–\\\¸ººº´eËJKK£èèh’••¥¥K—VWTTD/^¤ & ?~¼\`G]øóÏ? õïߟˆÊRƸ¹¹‘ ·#LôjÔ¨YXX««+%%%Iåü ƒÁ`|m|“éË—/¹môŸFW.Y²„‹²ùüáñsD©[¶l©“/?~¤ÀÀ@:xð -X°€ÌÍÍiàÀ4zôhrvv¦={ö··7={öLâbQÞÌO·ô¼yó†®_¿^etlNNM:•œœœ*‡¥¥¥äààÀM–¸âŸn¹ÛÇN::pà€D×& iii\”ª(@II iiiºqã†Xv† Fhýúõõæ«$…Bn¢}éÒ¥ ý¢.q¢8ˆÊWÖä›ñm!Úþ$uÛ%%%¤««Kƒ ’ºí+V¬ 4wîÜZ % êÖ­[¹h(’‘‘!ccc±Šå%%%ѼyóhæÌ™åòÖÝ»wK4iÂòÚ1ß¡¡¡\T¢4xÿþ=ݼy“öîÝKÿûßÿÈÒÒ’,--ÉÆÆ†æÎK6l #Gޝ¯/EDDpÅ¡ªã‡~ ´bÅŠ:û÷áÃ?~<­_¿^¬â¤%%%tîÜ9.ŠUQQ‘ÚµkGªªª”––Æ÷ðáCš={6 6ŒvïÞ-ÕûhII ÒèÑ£ Y[[W8F´ÁÁÁš5kV!ºÔØØ˜Ö¯_O=úæwv0 ã¿Ã7)Š*v6¬\»(©zß¾}k´!Ú¶½uëV±Ï›™™I´yóf5j'„®]»–NŸ>MOž<»ò»8ˆ®GÜ|€/^¼ VZµ¸¸¸˜ÆWnr4{öl®íÚµå¼$"ºÿ>'´VµåSZôîÝ›Ðþýû¹6Q°¸N¢¢^:uª/7%fæÌ™€þ÷¿ÿUèóññ!Ô¬Y3±'¯;v¬qû.ƒQ¢Ü¾âlµa×®]RÍq* ÅÅÅôøñc:|øpƒFψr{Ž1¢Ö6üüüÊqå¡[³fM…òrssÉÅÅ…lllèÉ“'åúÜÜܸHûŽ;r…-,,Ø4ƒñžžÎÍësnW\\L‰‰‰tÿþ}:þ<¹ººÒŠ+ª­ bçÎÏY+ãñãÇdjjZë´2‘‘‘´páBRWW§ 6ŸÏ§¿þú‹,--ÉÉɉbbbêäßçÓ‚ ¨I“&åæó5¥BLk×®¥îÝ»WK[´hA³gϦ .p ƒÁ`üùæÒôôt.7§¯¯/×îææÆ}Ñß»w¯F;ãÇ'´mÛ¶*yóæ yxxЬY³ÈÄÄ„¬­­ÉÅÅ…|}}éÇR¹žêÐÐÐ b+ÃÃÃ\iôg^^—ŸRVV–KCp÷î]"*‹d #ÇÛ?‘P=vìXñ/ª–ˆŠ–Œ9’k;sæ  Ö­[‹µeëýû÷\騨¨útWl¼¼¼µmÛ¶B_AA)++zøð¡Xöœ M˜0AÚ®2¾DûçÕ‹¥…èopݺuõb_Dii)={öŒŽ;Fóçϧ>}úpÂ:tèP½ž¿:Dó½{÷®“KKKÒÒÒ¢wïÞ‘®®.uêÔ©Ú¼Û¥¥¥äææFƒ®—º´´”Ë;(o333éÙ³g\ñ·ºî¶`0ÿDóϯµècTT7§ý4jSŽ=JvvvbE¬ÖDnn.¹¹¹Ñ!CÈÅÅE*6E”––Ò™3g¨W¯^åDM555=z4¹¹¹Iœ_ôÍ›7tàÀ1bw½ÉÒÒ’öíÛ'Va@ƒÁ`0¾&¾9tóæÍ”ú4¢E´5TGGG,;Ó¦M«´ Í½{÷ÈÁÁú÷ïO“&M¢C‡I,¦QZZÅÅÅQDD=zôˆèòåËäååEnnn´{÷nÚºu+­ZµŠœœœÈÑÑ‘&L˜P®*»h…¸º•íììlš½^Q^Q±ììÞ½›PÏž=ëÉSÉUµþý÷ß+ôíß¿_"‹‹‹IMM­FÁ„Á¨ ‘èváÂ…z;Çü!•Ȥ¤¤$Úµk :”‹€‘““£““yzzRttôW·5üÉ“'\ô¤¤¤¤ÐĉÉÉɉrss¹Bn666•ŸœœL³fÍ"GGÇJ·Ê>yò„³Ñ¨Q#òôô¬pŒP(¤Q£Fq‘îÒŒŒb0_'#GŽ$´wïÞ†v¥JNž™:uj…\K"ÑØØX,ÉÉÉÜ„Oœ Ï_‚_~ù…Ëó÷9‰‰‰\dWM…ÇDˆ’ö¯\¹RÚ®2þã|÷Ýw \$»´ùøñ#ÉËË×êóùáÃÚµk 0€û;îÚµ+9;;“Ä…ð‚äädîaSÜ ÒÒRruu%+++zñâ×¾|ùr’‘‘¡§OŸ–;¾  €¶mÛF#GŽ,WÈðSNŸ>ÍEÚ¶mÛ¶ZÁ:##ƒttt¾XJƒÑ°ˆÎ?]|þ¼ðgC#¸(RWWW±ÆÌ™3§Î‹Ç×®]#333Ú¹s§Të…BòòòâR^ V­ZÑ¢E‹èÌ™3”@)))”ššJñññäççG™™™”——WoyCSRRèðáÃdccÃŽ½deeI[[›-Æ3 ã«â›HEïŸ>X*xIRÍRIhkk[®JCCC@>>>‹ŠŠ¢Ö­[jÙ²%WE”ŸÒÒÒ’;ÖÓÓ“›„‰»ž––Æm wk»4 äíÚµãÚRRR¸ß¿¸[gûöí[eÄfCÂmªl’+z8räˆXöDz]»v•¶«Œÿ8&&& B$¡³³3YXXиqãhôèÑdaaQá5räH?~<1¢Ò~{{{²··' ÒÒÒ¢îÝ»‹íWxx89::r‚ž‘‘¹¸¸Ô9Ú¿!(((à0ß¾}[ãñaaadaaA®®®¢a³²²¸\Ò"¼½½iРAäááQinf>Ÿ_.ßè÷ß/V¿   .‡³››[Ç3Œ/Ë—/' |Ìß~ûÌÌÌhéÒ¥tãÆjs)~ýõW@æææõ~®wïÞѤI“hùòå”™™)UÛ>äv‰"58À‰ÒôèÑ#ºqãåææÒÇ)//òóóÉÓÓ“<<<èîÝ»µÎÇ*¡¡¡4uêÔ ¢Ø¢ƒÁ`0¾&¾ôÞ½{ÜÊÄÄD®ÝÆÆ†k—d%÷È‘#€† VîJ…!C†:zô¨ØcBBB¨iÓ¦œøúõk"*‹@jÑ¢ ///îx ‰£ 7mÚD¨I“&â_ŒHOOçÐ_¾|ɵ‹Òˆ»lëÖ­€X_®J„@ à~7•å~\¹r% Ñ£G‹eïíÛ·œhÌì3$AtÏ9vìX½žÇÅÅ…dddjÜ®Âù¤¨¨H666äííMyyyõê_}#Êüé}ìs233ÉÉɉ&Mš$VQÀØØX5j999UI›žžÎ¥%@ŽŽŽ¥Hí¼hÔ¨Q•‘© ãßÏ–-[Mš4©\»P(¤ððpÚ²e Y[[“¥¥%­]»–üüü¾HñÒωˆˆ $///uÑR„P($:t(=~üXª¶?~üHÜœMQQ‘V¬XQm=Q¤éþýû¹ …wïÞÑ›7oèÆäçç'µˆÒÐÐPZ³f uêÔ©œ(úéÖûú*êÈ`0 FmÁ7‚««+`ìØ±ÐÑÑáÚµk;;;(**ŠmÇãø|¾”=•-Z´¤¥¥‰u|`` ÌÍÍññãGáÞ½{000øøø -- °³³¼}ûÿý7`Ú´ibûåîî.ÉeHÆã»ï¾øùùqí¢ë¹råŠXvÆŽ xðàRRR¤ì¥äÈÈÈ`øðáÀ}ž?eäÈ‘€€€×h¯U«VèÑ£Àßß_Šž2þëÈËËJJJêõ>þþþèÛ·o­m}Îùóçaddlll‰;v@CC£Êq<&&&˜5k²²²péÒ%ÄÆÆ";;}úôA«V­púôiܺu çÏŸ‡@ Û'¡Pˆ°°0lذ;vDŸ>}°uëVÄÄÄ@FF&&&puuåæªòòò055­ó{Á`0 †´kh¾‰‰‰¸|ù2ÀÙÙ™k_¹r%ø|>x<öíÛ'‘Í„„@Û¶m˵ …Bdgg#77ùùùÈËËãþÏçó‘••"€ ?«««CFF222ÐÐЀªª*7n ---4nÜ­[·æ&â ‰@êãム& ¨¨}ûö…¿¿?š4iÂõ‹DÍ©S§BII pòäIôîÝݺu˧§OŸ">>@Å÷îK`ee…ÀßßK—.Œ5 6lÀ;w™™ --­jmtèÐݺuÃóçÏqåÊ,\¸ðK¸^-#FŒÀÉ“'+4MLLиqcddd ((ˆS«cäÈ‘xúô)üüü0þüúp™ñDAAê]hìß¿?”••qûömØÛÛ—ëûóÏ?±`ÁcùòåX¿~=ÔÕÕ«´‡°°0xyyáÅ‹011­­-Œëõ:j‹²²2²²²ŸŸ_®=>>ÎÎÎ022µk×j\ôóööÆÎ;±jÕ*X[[Wyœ¯¯/¦NŠœœ´jÕ .\@ÿþý%ö[FFžžž066Fdd$–-[†Ã‡Kl‡Á`|݈î=EEEÕ'//þýû—»Ÿ#22Ïž=ÃñãÇñòåK(**BWWíÚµ+÷ªN ‡>}ú 99/^¼àÌ?EF¦v±$‡‚¯¯/öîÝËHƒ¤¤$,X°W¯^ÀÍÍ æææbÛhÓ¦ €²ÅƬ¬,ddd "":::èÑ£ºwïŽçÏŸcРA••­Ö–@ @PP.\¸€Ë—/ãÝ»w\Ÿ‚‚† {{{Œ=š[¬;räÀØØX¢çƒÁ`0ê›oB Ý·oø|>úôéSnvüøq@ß¾}ѪU+‰lºvíʵ…‡‡cåÊ•PQQŠŠ ÔÔÔ ©©Yîÿ ®®YYYhiiq?‹ÈÉÉP(Dff&‘™™‰ôôt¤¦¦"//DMMMèëëÃÈȈ{}*hÿ'¾ÿ¾Úk9uêfΜ >Ÿ333\¹r¥\QZZ·Ú;kÖ¬rã`úôéb¿ožžžÜÏ’¾çÒÀÚÚ?ÿü3‚‚‚——UUU£]»vHHHÀµk×0yòäíØÛÛãùóç¸xñâW!>²²²HHH@LL :uêÄõÉÊÊbøðáðòòÂÕ«WÅH­­­±yófܺu lË Q4a} ¤ 8p î޽˵•””`Ù²e8pàLMMqìØ1´oß¾F[000À„ ”í ¸sç<<<°lÙ2téÒvvv:thŠ_ àÒÒÒR={öŒ«ÂÙy³*£_¿~UVc=yò$ }}}±lñù|.­ŸŸŸ´]eüG?~< ­[·rm€ÆOÎÎÎtàÀºqã%$$T($)ëÖ­#YYYÊËË£>Ѐ-[¶ŒJKKëz)/^¼ M›6ÑàÁƒé矦ääd©Ù®-=zô tñâEzùò% 2„Nžå¶Òß¼y³Ú¨¦×¯_côèшŒŒ„œœ~ýõW¬ZµJª×°sçNÜ¿OŸ>…­­-îÞ½[czƒñï@ôð%çy222hÙ²¥Äî………Pç2ûöíÃßÿ¿þú M›6­“­O9sæ .\ˆÌÌL(((à§Ÿ~”)S––†äääÀÜÜB¡JJJ …——‡P(Dpp0’’’ ¯¯=z@NN®Ú”3•ñæÍxzzâôéÓˆ‰‰áÚ5j+++Lž<666Ü÷RMDGG#99rrr:t¨D¾0 ƒQßü§R"‹/æ&jAAAœh¸qãF‰lfffbïÞ½''')z+}:tè ,_jqq1—Šˆðã?b×®]ÊÞWW×J‰Çãùó瓓Ô)S”M|½¼¼3fÌÛ€‘‘ž}W®\K µ··ÇöíÛ Vq§ú¦oß¾hÖ¬þùçUˆú9r$'.[¶¬F{#FŒàòšFGGט×Á¨MREEENøüü~’••…W¯^áÕ«W¸wïÜÝÝññãG@³fÍ ¡¡œœ¸ºº~ÑH###:t|>8~ü8¢££!++‹Ž;BWWmÛ¶år»ÉÉÉq˜EEE\ÄRNNJJJ““ƒ‚‚£iÓ¦5.¸ˆ„Øšª+_½z¿ýöV¯^]í}ø¿|£ëÖ­ƒ@ €±±1.]º===1ßÉéСV¯^ 6 ¤¤îîîpwwGûöíáàà‡)æÇ`0êFCDÖ"âòa~žóT2220mÚ4LŸ>]¬üõârãÆ Ìž=oß¾ÇÃܹs±{÷îJ£\E"ô!C ''‡””¼ÿïß¿¡}ûöèÚµ+ QTT„ÌÌÌ*…Íû÷ïãĉ8wîrrr¸öþýûcúôé?~¸té¼¼¼d©L™èºHS½zõЫW/ôêիȾ¤¤$4kÖ ñññ¸wïÆŒƒüü|˜šš¢[·nèÞ½;ºvíZ©ÅàªV­ KKKXZZx~ÝwïÞÅãÇ‹{÷î!''G,éëë‹ÓjÕª¡víÚ¨Q£ŒÑ¦M Y³fež·,ijj*-Z’ðôô,³`Gnn.lmm±gÏÀ¤I“°}ûö—RœmÙ²eˆŒŒÄ¾}û`hh===ܽ{ßÿ=–-[†~ýúá³Ï>Ô)SDq*™×›ììlÐ8íúUqáÂÜ¿Z/²Ý»w_|ñœ‹}G•‡œœ,Z´ëÖ­I´jÕ ;wîÄàÁƒËì+W•²Ç 66V-2ÖÐаˆAJJ vìØ­[·"22R´7iÒ666˜:uªÎæ …gÏždddddd^:¯Nþ´r¹yó&õôô¨§§ÇððpÑ>räHQ\H¡Ph<žJ¥¢……ÐÒÒ²2L®>ùäàâÅ‹9lØ0QXhÇŽ%ö‘î×¾}û€5b^^I299™Z·’ ¨,[¶LŒûî»ïVìâ*À¯¿þJ4hhKOO×VV‰ùóçÇ_Y¦jÅîÝ» €:t(vË–- €Ðh<©xÁàÁƒui¦Ì¿” çÍ›÷ÊlHII¡¿¿?]\\hkkËQ£FÑÊÊŠ¶¶¶tqq¡“’’*|ž°°0¦¥¥éÀbí‘ÞEÅ=Ç?ÎÒÏÏO£±?~Ì÷Þ{O¼œœœ¨R©tlqéddd°cÇŽâýºyófš››«©[·.mllèããóÒí“‘‘ÑŽÅ‹§OŸþªM)•ÁƒÿóŸÿhÕÏÏσæ£GtfËåË—Ås'L˜À””ÿ"œ6mkÔ¨!Îi``À?þ˜žžžÌÏÏ×ù9}||€ÆÆÆ:-¦(#####£+þµÒiÓ¦GŽ)Ú²³³Y¥JàG}¤Õx›7o“‡[·néÚÜJcÙ²eÀ ûKª©R©øÍ7ßpñâÅ$É>ø@T…–ذa°}ûö¤FEE gõÝ»w(ª^¾ªÝ7nGù³gÏD»äDþá‡4çܹsÀš5kê¼ZhyHLL¤¾¾>0**ªÈ~[[[àÔ©S5/$$„X­Z5¦¦¦êÚ\™ß~û-pÖ¬Y¯Ú”"ÄÆÆÒÃÃNNN´±±¡¥¥%­¬¬hggG7772''Gãñj×®Íü±-.™Aƒ·oß.Úž={ÆY³fÑÖÖVãgÑùóçÙ¸qc ‘‘=<<*Ëä2¹ví«W¯N\½z5IòöíÛttt¤©©©š³´sçÎ\¶l£££_™½222%3kÖ, ƒƒƒZûåË—ieeÅÅ‹óäÉ“jó¯—ÍéÓ§Åü&""Bã~ÇŽãèÑ£™žž®; /^,¾OLLLxðàA˜ Krss¹{÷nöéÓGí™Ú±cG®Y³†ÉÉÉ:?gaìíí €Ÿ|òI¥žGFFFFF¦¼ü+Sì“’’ð×_€Z ùÂ… QPP===QhI¢££áàààyº~\\œZex¥R‰ÌÌLµ> …B¤INµ”ÈÊÊB^^žZ[FF†¸—HKKSK§T©THLLD~~>”J%”J%òòòD_i“Ηœœ ###;v ƒ *r˜5kš5k†ü111ðõõ×,!¥×öÙg Ñ»¹¹$ €víÚ!33†††ÈÌÌĆ 0wî\ÆÑ%Ý»wéñ§OŸÆÇ ày5{ooo;vL£^ï¿ÿ>š4i‚øøxœ:u ãǯlÓKÅÄÄï¼ó‚‚‚pòäÉ"÷vÔ¨Qزe ¼¼¼ R©Ê,*Ó£G4oÞ1118}ú4>úè£Ê4_æ Gªb¯P(^±%EiÚ´)š6mª¦sš——‡¨¨(Qê矆R©Å¡ºté333˜™™©=ïrrr™™Yn}½„„\¾|—/_Æ7°dɘ››kÜÿE}¿ãÇÃÙÙ?ýô,,,4cË–-˜;w.”J%:uê„£G¢sçÎÚ_ŒŽxï½÷°råJ,\¸‹-BÿþýÑ·o_899á矆ŸŸ¶lÙ‚cÇŽáÎ;X¾|9V¬X!C†m¼×=WFæ…gÏž@)Ÿ>}úÀÓÓAAA8þ<¶oߎÔÔTÔ¬Y:uB‹-ЪU+´lÙ-Z´@ýúõ+ÍÆ•+W>ýôStìØQ£>À¾}ûàîîCCà Û†Ï?ÿÁÁÁžk¿¯_¿ðó󃞞2220nܸ LLLÄÚµk±uëV$%%x^piÔ¨Q˜3g>øàƒ—RÏËË Àó" 222222¯%¯ÚC[üøãÀ.]ºˆE•JÅZµj{÷î­Ñ8?æ’%KÔÒOÞäíêÕ«Å^gnn.'L˜À-[¶ˆ¶+V{õê%Ú"##E$è½{÷4º‡*•ŠmÚ´!nݺU´ÿòË/"òòîÝ»¥k¤hÊÂ)`111ÔÓÓ#Þ¿_£q¾üòKàäÉ“+ËT­Xºt)pÔ¨QEöeffÒÐÐxåÊÆ›9sæ‘*'óêY¾|9POO=zô ££#}}}µ’3yHLLäéÓ§éââÂ/¾ø‚Æ ãðáÃùÕW_qÓ¦MFÏž=Ë?þ˜U«V}ôõõiddĆ ÓW1Ø IDAT²mÛ¶j[§NسgO¾ýöÛìÚµ+;wîL333víÚ•:ubÛ¶mÙ¢E 6oÞœ¦¦¦¬_¿>k×®-&FÙªU«Æzõê±Y³fìØ±#ûôéáC‡rܸq´±±N@Œ/öz?øà=zTü[¥R±}ûöÀ7Šö%K–P×í, ___ ¡¡¡Z*U~~¾HñÑVî@W9r„hjjª6©îÙ³'píÚµsêÔ)`:u´JÑ­,.^¼H¬Q£³³³‹ì·²²"´(é>ÉȼÈ7صk×"ϩڵksìØ±Ü¸q£Æ‹+¯¼{÷.9"´‡wïÞ]âñ< ““-,,Ä»ÄØØ˜~ø!yþüyfee•Ë–îÝ»‹EÀ€€ûÅÆÆ²o߾‰íèèÈ‚‚‚rÙ K ËÌÌL&$$°I“&¥a†……ÑÑÑ‘&&&j¿offftrrbBBÂKº™Â4kÖŒxæÌ™––ÆðÚµk?ýôSŽ9²Èö×_KÒË;v¬FçÞ²e mllt¢›Î^½z‰ç•¥¥%£££™‘‘ÁK—.ñŸþáÑ£G©R©xëÖ->|ø©©© àµk×xæÌ9r„gΜáÝ»w™žž^D/422’3fÌPûÎ033ãÎ;_Ùwô>|˜|ðÐîÞ½;-ZÄóçÏë¬èEçÎ €GŽѸϥK—Ä{°víÚ%jQW”¼¼<&&&òÉ“'|úô)ãããE!“;wî044”W¯^åºuëxùòe>|˜‡bPP÷îÝKòyIoçÎež377—îîî9r¤è€Õ«Wçˆ#øÇTʵÊÈÈE¡PˆçŸ6 b•±«R©ŠÍ`è5™Ïž>}š³gÏ®ðb’R©¤“““Èâ©Q£œœJ7//ýõÿüóOz{{óúõë|ðàsrr˜””Äàà`=z”^^^tww§R©dhh(mllÔš™™[¶lÉ~ø¡ÒRÛ¶mKôööÖèø={ö©˜öíÛóæÍ›õ“RI£££ùðáC†„„ðîÝ»ôóóãõë×yôèQ^¹r…nnnüðCtìØå'//IIIxòä âââpïÞ=Ü»w>D^^ôõõѼys˜™™¡[·nèÖ­7n¬ÑØ À… ðÛo¿‰"¬•Avv6~úé'üþûï(((@ݺu±|ùrÌ›7¯Üß yyy¢ bzz:~ýõW¸¸¸ˆ¢¬#GŽÄâÅ‹µ*üWÙ?~ÖÖÖ011Á“'O^»ï$Á«öÐê’±cÇmllDÛƒD÷¢E‹Ší'¥}Ì™3‡aaaŒ+Ôׯ_çÀ9`À4ˆ“'OæüùóùË/¿pçÎôôôd`` cbb^ÛB$W¯^é†eEDîØ±ƒØ¬Y3‘Ž“••%"AOž<©ñy--- €ß~û-ƒ‚‚Ø»woIT)Ò§°fìË"<<\D:<}úT´ÛÙÙi¤'‘››+îÑËŠH(øøxñ{_\Š›ƒƒpüøñw÷î]²¸¾Œn)((Ñ¥–––E¤JªT©Âž={ÒÑÑ‘þþþ¯…^&ùÿ¥\>ûì3êëë³Q£Fܾ}ûK³¯ZµjÀ;wî”xÌÓ§O9dÈq/mmm©T*E’¿¿?CCCyýúuž9s†?f^^CBB¨P(Í'OžP©T255•|üø1CCCÉ‹/2..ŽŒŠŠâíÛ·¹gÏzzzÒÝÝ»víâéÓ§¹k×.^¼x‘äsY•Ó§OóÊ•+¼}û6ïݻLjˆ¦¤¤½äÂQí=r!vvvZÝ#///ñ ¬_¿~9ŒLyøé§ŸT¾¾|AA>|H///®ZµŠŸ~ú©ˆ>?>wîÜɰ°°bSË%©¡ZµjñôéÓ•bß‘#Gijx®wªiÖNY(•Jnܸ‘5ã÷êÕ‹çÎÓÉøºfΜ9E¾Ïdddddd^Gþ5Òû÷ï‹4ùÂÕÚ‡Này1£’˜666éâ( ÆÄÄ0((ˆÇçÎ;ù믿rÁ‚œ2e ‡ ÂrРA´°°àĉ9oÞ<þôÓOtuuåÑ£GyñâEFEE1##C——_**•J¤•å„0`pÉ’%¢mÏž=À¦M›j¬a#~¡¡¡Œ‰‰Qs@æ»ï¾#Ž7Nó‹Ò!Ò½Ù·oŸh“$j×®ÍÜÜ\Æ‘ÒÚçÌ™SY¦j…$7Q¸Ð–„ŸŸŸÖ×סC ›››®M•‘!ù\–ÃÃö¶¶lÙ²eù’† r„ tuueLLÌ+³ÓÅÅEØ4uêTµt•MFF†8wIEˆ®_¿ÎÖ­[x®%-ýÍæææ2!!iiiŒŽŽfLL oܸÁ .|®­êëëË .ˆtw777zyyñÈ‘#ùû÷ï/¶ïܹs±aÃØÛÛã?þЉ=HLLéA…ÿ?!!IIIHOOIèééÁÐÐÆÆÆ022Bݺuadd„š5k¢nݺ€êÕ«£V­ZjçRI"55iiiˆGbb"ÒÓÓ¡¯¯gggôéÓ?üðV¬Xwß}AAAÅÚüàÁ´k×$qçÎtêÔ 0lØ0øøøàÛo¿…³³³F×ïää„ï¾û®ÔóIøøø`ذahذ!¡§§§Ñ9t…ôó·±±ÁîÝ»ÙÙÙhÞ¼9>Œ^½z!<<aaaHLLý Q£F deeaÈ!HKKCpp0Z·nš5k¢E‹HMME½zõÉÉÉhР@©T¢Zµj/åšmmm±uëVãúõëÂþâxôèÌÍÍ#ÚæÎ‹uëÖ½ SedþçéÔ©"##qèÐ!Œ?þU›àùœ',, W¯^EÕªU1}útdee¡M›6HJJÂæÍ›ñå—_Vø<˜|xe›ûJ¹ÿ¾(‚âáá¡¶ïÔ©S"ê*==]´k *!‰±3Fã>}ûö%îÙ³Gã>ºD*ÔUX‡6##ƒÀÀÀÀ"}BCCYµjU6jÔˆ+V¬`rr2wíÚ%>^=¨>ú¨Ä‰ibb¢ÐÈ*-z¡0R!4GGG]›*#£R¸µk×ÒÝ݃V‹Ìiܸ1?ýôS®ZµŠŽŽŽœ0a{öì)¢pÊÚ Ù¶m[ZZZÒÖÖ–NNNtwwg`` Î m”ÉѵkW’Ï?¶¥HIƒWR쮲ÈÈÈP‹`Ú¸q£ˆ *ìÌ8þ<4h ´nܸÁÌÌÌ7*’MFæßÀ·ß~Kœ2eÊ«6Ec¤lšò,l{{{³iÓ¦b±îûï¿×8577—ûöí£……E‘w×¢E‹¸|ùr¡¥\½zu®X±¢R¾’’’èèèHkkk•k …BÁ#GŽpýúõ$Ÿ«˜˜˜Oœ8¡Kseddddd*…7ÞAzðàA‘Î’šš*ڥȑ6mÚ”9ÆîÝ» €ýû÷¯LS_ æÎKìܹ³Ú$nÒ¤Iž‘¸víšÖ‘  …B¬Še`` <ÈßÿóæÍ£µµ5»víÊÚµkkä@522b÷îÝ9fÌ<˜³fÍâ¶mÛxäÈúûû3<<œ :¯l¿sçN‘j~ôèQÕݤI^ºtI§çÒ*•Š …BD榧§3))‰¡¡¡ŒŽŽæ;w¸}ûvîß¿ŸGeTT;F___.Z´ˆ>cI‹>Í›7gBBÅBV÷îÝ…L‹$EP£F×b±JFæ^½z(¾8ä는MÓ©S'ûäääpÁ‚±ٺukQØ®<ܾ}›öööjÅå¤í­·Þbppp¹Ç.‹ŒŒ :99qذaôõõ-ל3g‡ ÂÕ«W3>>žäÿW«Ví¥§•‘‘‘‘‘)/o¼ƒôý÷ß'Ο?_´>}ZL,4‰H|1"§¨¥H£ÔÔT‘ºxîÜ9q¬pôèÑèÐ!Ï«uj£Ñ'¥¦¯Y³Fó‹Ñ!÷ïßΔÂÎ`)b©{÷îÅöS(tssS«(*M˜§M›ö²Ì/‘Ç { ;$~úé'àСC5/66¶Ôñdd^‹/.²¨#‘••ÅmÛ¶±gÏžjšï½÷wïÞ]æ³)))‰×®]ãøÛo¿qîܹ´¶¶f—.]„Æœ6[ƒ Ø©S'öïߟ£Gæ´iÓèàà@gggn߾ǎã… xûöm&%%•êÐûã?ÄǼô·Ø§OŸ—ÕªR©˜™™ÉgÏž1,,ŒOŸ>åõë×Έˆ^½z•wîÜáÙ³g¹|ùr:;;óÈ‘#LNNæ¦M›¸gϦ¥¥1??Ÿ®®®\½z5½½½éîîN777ž:uŠ·nÝbpp0×®]Ë{÷îñìÙ³jÕëSRRتU+ᤖîñðáÙ––&Ž“ÞEy¯ËÈÈhNᬔ»wï¾js4æÑ£Gbî–••UæñwîÜa·nÝÄ³ÇÆÆF-@£"äääp÷îÝ¢ê{›6m˜­“±_D¡PÐÕÕ•ƒ¦»»»ÖýSRRøÛo¿qРAtpp(¶NÁæÍ› ”-u&#####óºðF;Hƒ‚‚„S«ðdLJ ¯[·®Fãøúú[¶lYn[FM###†‡‡—{Œ—…ä311arr²p¶iÓF|˜+•J6nܘxàÀÇ–R°gÏž­•M$Μ9³ÔbS•IÇŽ @MX¿°Cðþýû%ö-(( ‡‡ÍÍÍÕ#æææôððx¥LÒDÞÕյȾàà`±º¯é¿GÀM›6éÚT‘ž[–––¥HÙ €5¢££#?~\®s'&&òêÕ«twwçªU«ÄǬô·Ô¤I!gRžMOO&&&ìܹ3ÍÍÍ9vìXNŸ> .TÓ£“b4YŒz±žB¡`zz:CCC™ÍóçÏ3 @D¼îرƒûöíã‰'èååÅþù‡tqqáµk×èååÅíÛ·ÓÏÏ...ô÷÷çöíÛùÏ?ÿpçμv협‘A200P-Ѝ¸ç¢ä€½qã>|È€€ž:uJí˜ .ˆç²]\\ŠDê:;;ÇŽ«ñÏUFF¦üHÙX;v|Õ¦h…J¥¢¡¡!ðÖ­[¥û×_‰ cccþý÷ß•bÓ‚ €sæÌÑùØyyytss£……]]]K,zW‘‘‘´³³ãÀéææVª¤À_|A´³³«¨Ù222222/…ªxƒùã?cÆŒA»ví>Ä­[·óæÍÓh###@zzz¹mÙ°aÞ{ï=|øá‡¸zõªóudáÂ…Ø»w/"##ñÝwß!$$0}útèééŽ?Ž„„Ô­[£FÒhÜäädœ8qðÙgŸ•z¬R©Ä­[·ðöÛoÂÃÃ[·nÅÖ­[ÅqµjÕB“&Mиqc4nÜM›6E£FD›©©)š4i‚F¡zõêÚ݈9r$"##qâÄ aÓ¦MѳgOÂÃÃóçÏ/¶¯¾¾>FÑ£G# sæÌÁ7pñâEŒ3Ý»wÇ7ß|ƒÿüç?¨V­Z…ìÔ–#FàæÍ›8yò$lmmÕö½ýöÛhÖ¬bccqæÌŒ?¾ÌñF…7nÀËË ³fͪ,³edJ¥Y³f€˜˜˜RëÙ³'vïÞ_ý7nÄ–-[˜˜ˆU«VaÍš5˜8q"ìììðÞ{ïi|n˜˜˜ W¯^{{{L:ûöíC~~>¾þúk888 ##IIIxúô)ž>}Šääd$''‹'%%‰Kû”J%H")) III%Ú ¯¯—"ï¹ØØX}Š·ß~~~~:t(Œ‘——‡nݺaïÞ½èÛ·/‹¶mÛ¢eË–¨Q£jÖ¬‰~ýúÁÀÀï¿ÿ> >> 4@TTªT©===DDD G¨]»6"""аaCÂÀÀµk×FHH2331jÔ(„„„ //OŸ>…½½=:„„„4nÜ`nn{{{1°°°€¾¾¾Ú}ˆ4oÞ\㟫ŒŒLù9yò$   ?ÿü3:wî 333´oßþ¥Ï{´AOO­[·Æ;wðàÁ˜™™9&//_ý56lØèÝ»7ÜÝÝѪU«J±éñãÇtûü"‰ƒbíÚµ=z4N:û{{{cÆ hРæÍ›‡wÞy§Ì> ÕûUFFFFFæ•òª=´å%66VDèøùù‰öaƉ(žÂ• K#22RD¢–7ÒO¡PÐÓÓ“úúúoÄJ©T”IJ‡Ò××gtt´Ø/é¼Íš5Kã1×®]+¢J»!!!477çŸþ)Ú$-̆ ÒÔÔTØ¥ÍÖ°aCvéÒ…C† á„ 8`À­Dá¥{bll¬¶".Eܤ››ýýýyàÀ;vŒAAA æ±cÇ„ŒJrr2CCC™Àôôtµ¯P(˜’’°°0* úúúòÊ•+$ŸßËk×®ñäÉ“|úô©H­ß«ŸJ IDAT¶m}}}éëëË#GŽÐÇLJ‹-âßÿM¥RÉÜÜ\:tˆ»wïæ©S§€€†„„088˜?fjj*SRRH’ÙÙÙEªBpÈ!žkj¿hû”)S_ñ^FFF÷ >¼Ø¹YµjÕhffÆ?þ˜K—.å_ýÅæää¼j“ï¾û.ðСCEö¥¤¤pðàÁâzlmm5þ¾(/ÒœXW…K}||hiiI'''d$T*;FKKK.]º” ÷ÍÉÉ™wîÜ)Ù222222/=’¬Ïk%³téRüüóÏèÖ­nܸ===dff¢^½z(((Àĉñ÷ßk4VBBLMM¨]»¶Ø„¨¨(ÄÆÆâñãÇxüø1ž>} ¥R‰Zµj!++ ¨Zµ* Žèèh„„„ [·n•ríºâ“O>Á|ð¼½½)))hÚ´) .^¼ˆþýûk4Þ{g   üòË/øî»ïŠìÏÏÏÇêÕ«áíí WWW´oß^ì›:u*ÜÜÜðÃ?`ùòå(((@bb"‡ÄÄDÄÇÇãÉ“'EÚRSSK´©uëÖxðàFö+ 4lØ™™™ð÷÷ÑP¡¡¡èÑ£ªT©‚„„4hÐ@£ñ$°iÓ&ü÷¿ÿųgϼ­—‘)žŒŒ ©‡&Mšh=†ŸŸÖ­[Z¶l‰¹sçâ‹/¾€±±±ÖcþøãX¾|9૯¾Âúõë‹D7V6iii¨[·.¢££E„SAARRR`bb‚ôôt+++ñ4{ölœOFF¦dRRRàããƒ[·náöíÛGTT”Je±ÇW©RmÚ´™™Þzë-¼õÖ[033CçÎQ§N—jûÛo¿7nàèÑ£;v¬h¿{÷.¬­­5j`ÇŽ˜4iR¥ÛÓ¼ysÄÆÆ;gӆ˗/cåÊ•èÚµ+-Z„zõêiÔO¥RáøñãX¿~=úõë‡ùóçký>¼|ù2úõë###<{ö쥿edddddÊÅ+vЖ‹ììlQ)}×®]¢ÝÖÖVè·I5ÿ·2üb¡ '''®[·ŽÇŽc```™ã>}ú”õêÕã'Ÿ|¢ÝE½>|("5wïÞ-Ú7lØ@lß¾½Æ‘Y·nÝ‘¨/jÝ‘dhh(ßÿ}:99[ÕYÒ[š;w®Öב““Ãèèh^ºt‰?ýô“Z­Æ’ŠE-^¼X­]ÒÜ»w¯ÖöIdddÐÅÅ…-Z´öU¯^666•®];nÜ8 ££c‘}™™™¢ ôµk×4oòäÉÀyóæéÚT‘ªÕW´zûýû÷éèè¨VAØÐÐ666 Óz<'''1Îäɓ˕ª)™™™ô÷÷gBBƒ‚‚È“'OòÒ¥KŒçž={¸dÉîØ±ƒ‰‰‰$Éþù‡ÞÞÞôððà¶mÛxòäI’Ï#ü½½½yõêUž={–qqq¼páoݺŴ´4Túõhƒ———Ð#-ü|–"ÂÊS|DFFF7(•JÞ»wtrr¢­­-ÍÍÍË,vgllLsssÚÚÚÒÅÅ…>>>ZÍëµ¥sçÎÀãÇ‹¶+W®ˆoÆóòåË•vþÂäçç³J•*Ê_ì*,,Œ“'O¦­­-ãââ4î§R©xðàAZXXpÕªULOO/×ùIÒÍÍ 4ÉÈÈÈȼa¼‘RWWWQhCJÑ)((©ÌåyKXW¯^­°}¬ZµªZÊze‘ŸŸÏ›7orÛ¶mœ9s&»wïÎÞ½{kÔ÷èÑ£"õºpÊMß¾} €?ýô“Æv,\¸@ÑjèJ¥’NNN2d£¢¢Jì/¥±O™2¥ÄcîÝ»Ç3gΔX,iË–-"Gú]Ð6=iÓ¦MÀ·ß~[­}þüùÀ &h5^qHùR11ɱlmmÍ‹/Vxüâ*‰vïÞ½Øý’4…¦é¨{÷î%ð¼°—ŒÌ«¢W¯^ &×QÒÓÓ¹víZ¶oß^­`Òˆ#xòäI­Rù7nÜ( Æ§Q!¥ŠpâÄ þùçŸÜ°a7nÜÈ   úúúòĉôôôdJJ ƒ‚‚˜œœL’|òä CBBÊ]¨JWdddðöíÛÅ.œiн½=çUí%‡BË–- €gΜѕ©222:$66–>>>tqqŽS###§NNNôððà½{÷*TS¥R±fÍšÀëׯ“|^ÀRZ0ëÒ¥ ä¬Y³8iÒ$­«þþþ>|8™––¦Ußâæõ“&MªðX222222/‹7ÒAÚ½{wàòåËEÛü!&PZçãã#úž>}ºÂöI‘™Ú85%66–GŽáwß}ÇÁƒ‹jšX¯^=ZYYqýúõ%Uœ/¬3I===êééÑ|+‰‚‚6oÞ¼H$jYQ£yyyœ6mpĈÅŽïããÃàà`†„„ÐÏÏOíƒ:??ŸŽŽŽâ> >\8HCBB4º‰ÂÓ˜˜Ñ.éxÖ®][§ºYþþþ´¶¶Vû077§»»»Ö•EK£¤ë’ôc{õê¥ÑxÉÉÉ"ÂáöíÛ:³SFF&L˜@\¹r¥NÇ-(( ‡‡‡ªö·ùÖ[oqóæÍk¸íÝ»—U«V%ZZZÒßߟáááLHHÐéß·ÄËüˆ…BÁøøx†……ñüùó}ЩS§2õ#%Ѽys(•J\¹r½{÷ðÿµ]-,,Ä=)‹S§Naøðá¨U«žFŒ{{{ :´ÄqÏœ9KKK˜ššâôéÓ°°°@rr2Þyçœ>}õë×G~~>ìííqûöm4jÔ°°°sQ]âî'âwÞAppp©Ç¦¤¤ÀÙÙAAAøþûï1pà@ÏóàÁ,Y²µkׯ?ü€æÍ›WÔt5† YZFFFFæÍâU{hµeĈÔ+nŸ8qB¬þj« ¶ }öìYØéììLÅFë•Fnn.W¯^M<¯~>qâD®^½šþþþZU¡,L\\wïÞÍ÷Þ{hff&ö©T*¡µ¹}ûvÇ”ô(?ÿüs’äï¿ÿÎ7–šò”˜˜È©S§ iƒºuëríÚµjQUIIIôññ¡R©äƒxäÈ>{öLì¿wïÍÌÌDôÀŽ;H’'Ož$¶k×Nãk(Œ$0~üxµv©*ráˆ[‰´´4ePîß¿O;;;‘î…ÿÓ¾Z¶lY…Çÿúë¯ €üq±û;uêDܹs§Fã­\¹’8dÈ Ù%#S^$éˆÁƒWú¹¹råJ6mÚTümV­Z•'N,3JÑ××—ï¾û.›4iÂêÕ«— õ¦olÚ´)»víJ ~øá‡üâ‹/8cÆ öéÓGíúkÕªÅ3fðúõë¼|ù2×­[ÇÏ?ÿœfffBž@Úôõõ9dÈîØ±ƒ©©©ÅÞç={öˆHyI;ðüùó•ñë ##óšpïÞ=ñœX¾|9g̘Á¶mÛª=?¬¬¬JÌŠZ¾|9päÈ‘B^¥G%FS&&&ÒÃÃƒŽŽŽ9r$?ù亸¸000°B©þ«W¯&Ž=ºÄc233éääÄh­³œ‘‘ÁeË–ÑÚÚZH T’®«§§g¥CFFFFFF×¼QÒˆˆñÑTø¥.9ÉêÕ«§õ˜’õvíÚ@oooØ*¥È:tH£ã9kÖ,¡¿dddÄI“&qëÖ­JëÉÈÈàñãǹ`Á5ÍK)íó·ß~ÇJiä5jÔ(ñôEÒÒÒ„3O­7•JE777ññ €ÖÖÖj…T*Ïž=K???FEEÑßߟ111j~.\`£F€ 4 ŸŸŸØ·cÇàÀ5º†ñóó#ð\›U¡Pˆvwww`Ó¦MÕ&ÁlÖ¬ 8}út†††–ë¼…ILLä²eËÔîS:uhggWl,M¤$ŒŒŒ˜——WdYÔ &V«VMãß]âíí-^ …‚{÷îú§ÒÖ»woîÝ»W#­ÑôôtÞ¿ŸW®\¡——÷ìÙC~ÿý÷´··§­­-'NœÈ1cÆÐÒÒ’={ö¤™™Û´iCccc«É«”wÓ××ãµmÛ–mÛ¶åÛo¿Íž={Ò‚–––œ0a§NʹsçÒÑÑQ.ܹs'ÝÝÝyúôi3::š™™™j×™ŸŸÏÇsðàÁjçíС×®][ªÎ]zz:O:E{{{ñ¡]ر:kÖ¬bå=>ûì3 çÎÓþ‡,##óÆ––&ž …Óê¯_¿ÎiÓ¦ )ZµjñÀEú>œØ±cG`“&MŠl-„„º»»söìÙ:t(ÿóŸÿTh(ÍÅfÏž]d_^^]]]9hÐ º»»kåU*•tuu¥……ÅK)^׬Y3 ¿¿¥ŸKFFFFFFW¼QÒY³fP/%&Fßÿ½Vã…„„½MiµYW+999¬^½:-ZT¦ &L žž 9bÄÖ¬Y³ÔbEeFggg4HDërèСtrrâîÝ»…“´puË©S§x^uYS¶mÛFlÞ¼y™šz!!!ìׯŸøyµoß^TN–HNNæ©S§xíÚ5FFFòŸþ)RDdÛ¶m⺺víZÄ,E6Nœ8Qãë(ŒR©dݺu €¾¾¾¢=##ƒ†††ŠV{·°°Pû€·´´äñãÇ+M››K7771q—’666¼yó¦Vc) ±PÜ„õÌ™3ÂZØ1\*•JL€5]‘Ñ%RäP•*U4úÕ5/^ä„ Ä‚ð¼xàwß}÷Òõ@ SRRJÝ222^Š-ÉÉÉ\µj[µj%ž‡N//¯rdºuë/^\dÌÑ£G«9#222Ôž—r‘&™7YYYâクJ÷7nÜ`ïÞ½Å3ã—_~û233…f½_QÝâ„„„ -KÚÚ?ÿü³h+(( »»; DWWW*•J­Æôññá Aƒèââ¢ußò"¹zq¾,#####ó:óÆ8HSRRX«V- ‡‡‡hÿàƒ„Ó¨¸¨¸Ò?~<p̘1|çwtîèy÷ÝwKL?«Ö 4àÊ•+E4ÍÌ™3Y«V-¦§§ktžììl?~œ³gÏfëÖ­ÅD¯[·nüöÛoyêÔ)fgg‹ãgÏž]$}'++KD$½è´,—,YRâ1©©©´³³=5jÔà²eËŠDZݼy“ÞÞÞ|òä £¢¢xêÔ)µú‹1YYY; 3gÐÞÞ^ãëx‘>úˆøí·ßªµK?³¥K—é#\’d$'°‹‹K¹%$¤¢1}úôQsÄš››«ý=”ÅèÑ£ €‹/.²///õêÕÓÊ© ‰ðϘ1Ccddt…R©ÎɈˆˆWfGtt4.\¨ñ­¯¯Okkër;ßDBCC9sæL5‰:uêpîܹ:ûùÐÓÓ“–––âY«¯¯ÏÏ>ûL,¦…††Šß mNeddÞ, …xÞ¼¸ ^øi¾@Q=pà€ÚœjëÖ­/Óôb‘ ÜÜÜH>wn2„NNNZ ç¸qãhggW¦Ó6;;›çÎãÏ?ÿ¬“…%é}xåÊ• %#####ó²xc¤¿þú«HÍ“>6ÓÓÓ…Óí?ÿùVã…‡‡‹tý‹/rÀ€À]»v•Ú/55•W®\á®]»¸råJ:::ŠmÅŠܺu+=<ºÛ¶mKggg«*¿IT$¾¢„„„päÈ‘âœFFFܼy3U*]\\ij÷âÅ‹•fƒŒŒÌ«¥  @<ÊŠÜÿî»ïı›7oæ¤I“Ä¿+’¹¥KZ´h!ªÇÇåË—k0!Ç/¾ø‚Ÿ~ú)>|Xâqááátvvæˆ#hmmÍŸ~ú‰¾¾¾Z;b £R©èåå%‚. K`ÉÈÈÈÈȼî¼R¥R)& ëÖ­íÒj°žž^±i5¥ñé§Ÿ?øà’ÿ?bÐÙٹȱ{÷îåçŸÎ~ýúqĈüæ›o¸uëVz{{óÊ•+ äµk×xâÄ îÞ½›«V­âÌ™3…nš$ Ë·ÞzK8¨¶mÛÆ'NÐÝÝÿý7]\\øõ×_ÓÊÊŠ†††ìÙ³g[`Á%Mˆ‹‹có   ¶}ëÖ­ " 2Dk¾`ú›¦¦¦g ÙØØÀÈÈzzzèÝ»w¥ËTV­Z¥6úÉ'Ÿh” ü'ȇÃápÄPí¤cÇŽa̘1l[`` {(lmmáïï_m2p9‡Ã©,Õ:@úòåK¦+T¼ ­ð€nܸ±Fö^½zÅtÓŠwpŠ´.‰Íš5ÓŠïYYYz¹€ììl̘1C”è|y/‰/ÀÆŽŽŽ¢mþøã/ÇIIIÌnZZš6ܯVL›6­D&nAA+=ôññeG©T²ŒQáåsÖ¬Y¸w¬œ˜˜Ü»w¯Äö«W¯2_š4i‚3gΔiçðáÃ%²aÆ"š5kD]SYY¼:uRÙ~þüyêׯ/*CíÆ, «¼€¹:RxxxT: 22Ó¦McÁíöíÛ«=Nø½LŸ>]”Ýàà`¶h¡-áG,B¦wñ…´wIMMÅ… °eË̘1ööö2dfÏž ™L†°°0­dêkƒ””xyyÁÖÖ¶Ä¢†™™<<<¯µñÔÝsLMMáé驵ÒÌÒP( ÁèÑ£áêêª5yG±Œ|77·ARM«O8NõE³º|ù²Ví&&&bÆ °¶¶ÆâÅ‹Ù}7)) úúúøþûïµ:ž0]±b…Úýr¹\mPöåË—pppÀŽ;*´ÍÍÍ…··7¨6 ¿V­ZpppÀ¶mÛþuM9‡Ã)j ÍÎÎF“&M@DØ¿?Û.4à144Ô(»$--uùÞ·oŸÚc„À_uÒ#ÈÈÈ@dd$Ξ=‹½{÷ÂÃË-‚››Æ'''ØØØ¨ÍÌÊÊb×ȶŸ8qD„† Š.9¤Jû´lÙýúõÃĉñÃ?à?þÀ™3gðäÉ“Rÿ^dY>¦¦¦å®|çååÁØØŸ|ò‰Ú¨¯¾ú D¤•‰krrr ýP@µü¾øwZ …‚•«ž8qBÔØ111¥ê”>þ¼Â×üG_µ4ÝÐcÇŽˆÐªU+Q“í¼¼<Ô¯_D„ÐÐÐJùÆáhŠ a!VòB@¡PàñãÇ8rä–,YØÙÙaæÌ™øã?^©,FmðâÅ lذ5O+^ÞhaauëÖU([HÐ*îÑ£‡Š]œï=Îáp*OÇŽAD8{öl™ÇeddT:ûþáÇP*•(((ÀСCQ£F œ?¾ÜsÜÝÝѽ{wèé鈰cÇŽÇuèÐDTn•Àúõë1eÊ”Jé* Åe³7n 77·Mí  •JÑ«W/v-§Y³f3f ¼¼¼þ+«ñ8‡óßOµ *•JÖP¨ø ¯Pö«§§§QWÛ¬¬,Öã?þ(õ¸‘#G‚ˆ°víÚJù¯Žüü|<þ—.]ÂÞ½{±råJ`0`¬¬¬0uêT,_¾ûöíÃÕ«WËìþæÍB*•ÂÁÁ&&&%tëÞýׇLMMe0±A¶ÜÜ\6Æ´iÓTö"66.\Àž={ •JáêꊢmÛ¶%ÊDßý|ýõ×ìEÙß߿Կ“\.GÛ¶maaaQªŸ[¶laèС¢®«<¤R)ˆC† QÙ.t›e)ߺuë eg M—úõë§òÝUT§tîܹ "Lš4Ií~[[[–/_.ÊÞŽ;@DèÞ½»F~p8•eÁ‚ "Ìž=['ö•J%¢££qàÀ,\¸C† $ >¬Õrw±DFFbõêÕèß¿‰{ýúõ1räHìÚµ‹i4GEEaöìÙ*ú¢M›6ÅÒ¥KKè8kAcyäÈ‘pssÃýû÷5¶¡P(ðäÉœ8qYYY¢Î²ïïÞ½  è95qâD•ïjéÒ¥ûÂápª‚oi çOŸ>Åĉakk‹5kÖTZ«3##¦¦¦øè£Ô.L…‡‡ÃÁÁDErVVVX³fÚ…g…BCCC=zT清……˜;w.¤Ri…æ“r¹{öìAÏž=Uî‡æææ8|ø°h¹™ØØXlÛ¶ C‡EíÚµUléééáë¯¿ÖØ7‡ÃápÞ'Õ2@"Bݺu‘’’ h2 <|  ‘½µkׂˆÐ¶mÛ2ú‚8º:ÝÅ 6ÀÜÜööö˜|(:)>>û÷›ºtéRbÕVøÔªU fff°²²Â„ 0eÊvlñò›mÛ¶¨¨¤]ìäjÍš5lœØØXQçÈårDGG#882™ îîîlµÚÙÙYåXwwwèééáСC%ììß¿DêËÚŸŸÏ‘=zôÐÈÇÒ¸~ý:ûn‹ë‡fff²ßä7ʵ“žžÎ&¿•í•ÿŽ;ÂÃé©©¢lœR mÓ¦ ¾øâ ¬]»xòäI MΟ~ú‰­ G(•›ü§„©cÇŽ•º.à?MŽjÕªU"S6??¨S§N‰ÀãСCÑ®];•àCBBœ±dÉ( „††‚¨HU( Ö@*  „?šd!YYYˆ°jÕ*­øöôéS¸»»£Q£FìwÑ A¸¹¹•Ûa4''‡i¿ª+­}òä ˆÍØd*Ô•Žq8ºâèÑ£Õ"{9!!>>>˜7olmm1nÜ8ìØ±CE¿X×àÂ… X¼x1ÌÌÌTžÖÖÖÐyð6,, S¦LÁСCáïï/*蘘ˆ]»vaòäɰ±±››öïß§OŸŠÏÍÍ Éd,ðûÉ'Ÿ€ˆàëë«r|~~>FŒÁ¾—-Z”¼àp8Õ—nݺH¼Æ{qŠ—ÛÚÚ2©MæðÎÎÎhÞ¼9 ˜˜ˆ¾}ûBOO3gÎÝ\SXŒoܸ±Æ×P™™™X·nÓÂ'*jˆºtéR­T@<þœUáKhÑ¢…¼çp8§ê¨vÒû÷ïCOOzzzˆŒŒdÛ…ySSSì åÖ-Z´(7[F˜œ4hÐ@ç *J#++ þù'ú÷ï_" Ú¹sgÌœ9Õ9R¡P0=£]»v±íÑÑÑì;މ‰å×Ë—/™¾>éÓ§ƒˆ0aµûѶm[´k׎ç²³³Q³fM,\¸çããƒ>}úàâÅ‹lÛãÇAT¤yª®‰SEpuu•h‚%”•wëÖM”uëÖ© XW–ŒŒ xzz²¿·Øttt,3;ÊÞÞD„_~ùEíþN:ˆ°gÏQ~|ÿý÷ " >¼B×ÁáT„7n€¨¨ñNeÑfVerr2> 777X[[cÚ´iØ¿™ò)ÚæÔ©S,KHWzŸ@Q£6 <‰DT`óáÇððð€½½=Æýû÷‹TfffbÛ¶m°²²ÂüùóÕ–ÊZXX€H}ù\Ît“‰Š$TÞ×sŸÃáT¡ÙܱcÇ*m+""prr‚««+|||ÊÍèôóóQ‘¦»™™j×®­Ò`V BsÌO>ù¤2î«““ƒ_ý•5Þ‡Ö®]‹ŒŒŒJÛÏÏχ§§'kÒ©§§DEE±ª]K¸p8‡£Mª]€Tè@^\ïQè¶NDjË®K#??ŸŒÄèŠfee1­LMKÈ+CVVüýý1cÆ •Ò}}}ØÚÚbïÞ½š`„„„€ˆP§N±ôüD„Aƒ‰¶õå—_2Ÿ*#½˜ ]2‹gdÆÅÅaÊ”)J¥Š´›êÖ­‹þýû#//°… ðÂ… 1þüþdee±ïP[YA¡}ûö*ÛãããÙ$0::º\;‘‘‘,x+ÈGhA§ôÝ&.Ÿ}ö¼¼¼JdDlܸD„¾}ûªµ7þ|ÆŒ#j|!{·^½zÈÍÍ­ôõp8bHJJ]šXr¹õêÕÃèÑ£‘žž®E‹xþü9vïÞñãÇÃÞÞ+V¬ÀíÛ·µ>Nqär9“ö¨¬Þž:âãã!•J1`Àxzz–«š˜˜ˆ 6ÀÊÊ 3gÎDPPFM¯ž?ŽE‹ÁÆÆ{÷î-ó>#@7mÚ¤v¿\.Wi¸aÃÑ~p8œêCïÞ½AD8|ø°Ví>þžžžprrÂÈ‘#áåå¥6#T.—ÃÀÀúúú¨[·®Š¬‡X~ûí7iG?_¡PÀÇLJU~ Q­-†„„ sçÎÌ~¯^½Tª‘Úµk"Âßÿ­•ñ8‡Ã© ªU€ôõë׬ä÷ôéÓl» -¤iÙ‰P2ߤIÑ+¥&&& "œþøc•Àè–-[4¾ç–F||<\\\˜ýFÁÓÓ³DÅ– ˆ[·nÕʸ‡ÃáTÕ*@º|ùrVJ.”º we•«£°°iw ‰b2NêÖ­‹Æ—hx¡«O‹-àêê ­”…§¥¥±nÅçÏŸgÛÏ;DzJÅê" z¡DÿJûöË/¿°2ìk×®áóÏ?ÇÁƒK-oʶ¢ò»{`“C??¿Jû+0`ÀÖ­[§²}åÊ• "XZZвS^÷xm#dxÿ-ׯ_nnnxøð![8pà@‰sóóóYp¼øï¨,„(‰DËWÂᔎ |åÊEÙ-[·nÅÍ›75Öƒ¾téZµj…zõêUYöKTTÖ¯_!C†`Ò¤IðõõÕZ¶ðò矮”ÌÌLÈd2ØØØÀÝݽÜJ‹„„,[¶ ƒ † œœ¬ÑxB”.\ˆgÏžitþœ9s@D*²,êÈÉÉ££#Z´hÁËA9œ!ÂüÌËË«JÆËÎΆ¿¿?\\\Я_?H¥R <K–,©°Í &”» SQQQ2d›çÕ«WîîîZ«†(((€§§'«tÊéK“Œ™5kˆóæÍÓÊø‡ÃáTÕ&@*—ËY3%™Lƶ[ZZ²ÌMV?…lÃzõêiôRö믿V(ÀY¯^=Pmݺ5+ÕoÑ¢LLLУGôêÕ æææpvvÆW_}…%K–`Ïž=:éx,hcvìØQŶP*?qâDѶ„ÆBuëÖÕŠF›ð7ݸq#rssËý»* 8::²ïúÚµkåŽ!4O*­´²"¬Zµ DENŠsÿþ}–…)æ·È2›µ¥‘*†ôôtlÚ´‰eI&ÿ.ži\œ/¾øD„E‹‰ÇÛÛDmºÏá”É» yRSSáëë www 2ƒÆ‚ pøðaQ*ñññèÖ­j×®­Õ…1¼|ùžžž°³³ÃðáÃáãã£Qú»‹8#GެÐù?†»»;lmm!“ÉÊÍr½uë&Mš„/¾øAAA?ßär9vïÞAƒaݺuÖÊצOŸ^¡ó9οáþÿ>²sss‰D‚þýûC"‘ 44Tãù²°{÷nÎËÈÈÀÂ… Y5ZÍš5ñÍ7ßàõë×Ù)‹óçϳJ"§Ÿ~ŠË—/—yΆ @DprrÒš‡Ãáèšj õòòbA#AÃ,--'Ož,Ú–R©d“%wwwüP(¸zõ*+— Ó'OX)}rr2+±/++©gÏž "9rD£ñµÅçŸ^b%:''‡e‰²SPPÀ&]bu(Ë"77—u·ÔD{/##ƒu)£'di3‹ñöíÛlòY\ÓøO3£½{÷–k'77—e÷ ÙnUIaa!Ž=ZB§´aÆj»wïáã?e?99¢³}9m`kk "ÂŽ;Ôî/,,DDD¼¼¼ ‘H0lØ08;;C*•Âßß©©©%Îyóæ úôéƒ5jh¥ùGExþü9Ö­[;;» ¿ü D4ir¨P(‚Q£FaìØ±¢îU¡¡¡5j\]]+¤wš——™L†ÂÓÓ³ÒrkÖ¬aìØ±•²Ãápª'wîÜa¥ÜÚ(O¯, …¡¡¡lAÉÍÍ þþþ¢ª„ÅjMªöïßÖ­[³ë·¶¶FDDDe.A…ÄÄD¸¸¸0­ýzõêÁÃÃCTÿ}ûö¨t{‡Ãápª#Õ&@*è8þðÃlÛ”)SX‡&]?"BíÚµß[¹œÐ=÷Ï?ÿÔŠ½œœÄÆÆâúõë8yò$þúë/üúë¯jWˆ=zľ·â:¦Bf_‹-Dw3Þ¾};›x½«½Y.\¸ÀáåeEFFbõêÕìß?F“&M0uêÔrǺÅksåZ©T¢M›6 "?~\eŸÐÌhÔ¨Q¢l ±ÅïïƒëׯcôèÑlòVâ˜W¯^±…ŠÇ‹²+è‰Õeåp*‹ ¹¼|ùrÑçdff"44žžž?~<¬¬¬àââOOO„……A¡P ##}ûöEíÚµqñâE^‰aãå5QJOO‡L&ƒµµ5¤Ri¹YHJ¥¾¾¾°¶¶ÆÒ¥K5zV dffbõêÕ°²²ÂþýûE?ŸÊã÷ßaðàÁZ±Çápª‰‰‰øê«¯ØÜDøT7½ËˆˆH¥RØÛÛÃÕÕ>>>jïÁJ¥µjÕ!22²\»ñññ* æÚ¶m«ÕUB9½TADpttD\\œhAAA/Ìq8‡ó¾©AÕ€‹/ÒÍ›7©fÍš4{öl""*,,¤C‡Ñ€¨yóæ¢í­Y³†ˆˆf̘A­ZµÒ¾Ã"hРeff–zŒR©¤ˆˆzõê½~ýš’““)99™’’’(99™233I©Tª_¿>}ðÁÔ¬Y3jÙ²%}ðÁdffÆÆ)ÎîÝ»‰ˆÈÚÚšLLLØvooo""ruu¥5Äýéûí7""jÕª™™™‰»ø2¸wïõîÝ›ôõõÕ“——G«W¯¦ë×¯ÓæÍ›ÙvSSS £ºuëª_PP@oÞ¼¡–-[²mÆÆÆDDôìÙ³Jû, §§GC† ¡Ý»wSPP9’ísvv¦M›6Qpp0åååQíڵ˴åàà@'Ož¤ÀÀ@Zµj•Ö|Ô”>}úБ#GÈÖ֖Ξ=K§OŸ¦^½z©Ó¼ysúì³Ï(,,Œ‚‚‚è›o¾)×î°aÃèÚµkHóçÏוûCxF¼~ýZô9õë×§ЀhÞ¼yDDôôéSº~ý:y{{ÓŠ+èèÑ£@ ggg ¥nݺéät…±±15hЀ233éáÇԻwïRݹs'Sppp¹Ï‰3gÎÐêÕ«©OŸ>tìØ1jÔ¨‘F~åææÒöíÛ) €æÎKK–,!===l”EÆ ‰ˆ(==]k69Îû#77—6nÜH”••EDDC‡¥¸¸8Šˆˆ š5k¾gUéÚµ+uíÚ•ˆˆ¢££É××—FŽIM›6%rpp ¢¢ç–\.'"¢¶mÛ–iÓËË‹æÏŸOoß¾¥5jЂ è矦zõêiÅç›7oÒ×_M7oÞ$"¢>úˆ¶nÝJvvvÙiÖ¬¥¤¤hÅ/‡Ãápª„÷¡€‘#G–hZ#è=R)Ym¥qúôiVý>»Ñ M1V®\Yê1‰‰‰H$X¾|9d2üüüpùòeDEEUXT½  €i¹îÛ·mgeÏwïÞe+%%…ej+ÓqöìÙeж_¼xýúõƒL&¥ß”’’{{{œ8qBeû­[·X969zô(ˆŠºÁ÷¯°°Íš5áÔ©SåÚyñâËòÕdE^W·æææj÷K¥R2±„ïßÐаÂúŽ&¿ÑÒ´t+˳gÏЪU+têÔ©„ÄÆ¿AvEU !!!°¶¶†»»»èfÅ‘ËåÉd077‡L&Ó™³¿¿?ˆfff:±Ïápª¥R‰ýû÷£}ûöìÝ [·nð‰•â= ª3ñññ*¥ô7oÞdRGe3lØ0vý]»vÅ7´æÓ›7o ‘HXVnݺu!•J5êÿ  T*Ù{œžžžÆ9‡Ãy_¼÷é³gÏXàîúõël»lêÔ©“Fö‘ó÷Ý”aÆŒ ¢Ju´¬ "!;;›m_»v-ˆ={ömK"‘°ÉMY/Áùùùxòä Μ9ƒ?þøK—.ÅĉK”¡ÿiø´mÛ6•í©©©pssÃØ±cE—hFGG£ÿþ¸páB‰}©©©lY‘’ÏÒHOO‡¡¡†? IDAT!ˆwîÜQÙçâ⢑– ©ºsçN­ùWQ"""X£©7oÞ”ØãÆ jÕª…ÌÌÌrí•%GÀáè¡ÁžX™‹ŠpõêUÔ¬YNNNZiXW•LŸ>D„ùóçWØFHHë`¯N³µ< ±{÷nXXX`÷îÝZ+¥/ AÒ¥M›6:‡ÃáèŽË—/£OŸ>lN×¼ysìØ±CeaEÖ­[mÛ¶…‰‰ >ùäôêÕ ƒ bÍQøálܸ{÷îE`` îÝ»W¡EmãëëË‚žê`ïE5jÔÀ?üP©Æ}ÅQ(ðòòböéÿ—Ó‹if¨Žèèh 6 Ë—/gö’’’´â+‡Ãáp8ºæ½—ØÿöÛo¤P(ÈÜÜœúôéCDD¾¾¾¬$cåÊ•¢m]ºt‰BCCÉÀÀ€¾ûî;ø+1%öºà¯¿þ""¢ñãÇ«”¢ïÛ·ˆŠÊëÅràÀ""êÞ½{‰ÒIoooÚ³gåçç“¡¡!µk׎ŒÉØØ˜ìííÉØØ˜Ú´iSÂæÃ‡‰ˆèã?fÛiÅŠ´råJ²±±å[HHýøãäííM}ô‘Ê>´qãFöï””$ÊÂÈȈÌÍÍéüùóHŸ~ú)ÛçììLÞÞÞtâÄ Ú¾}{©Æ £ˆˆ:uê͘1C+þU”®]»R‡(66–Ξ=KcÆŒQÙß«W/jÙ²%%%%ÑÙ³gÉÙÙ¹L{ÅåUä8]P¿~}""Vv© úõëG«W¯¦Å‹Ó–-[H"‘èl,m#H¤÷`M™;w.5iÒ„Ž9B7Öøüàà`Z»v-1‚BBBÈÐаB~ˆ¡  €nß¾MDÄKì9œ#Ïž=£%K–Б#GÕ®]›¾ýö[úþûïÉÈÈHåØN:Ñ™3g(''‡rrr4ËÈȈڷoO;v¤víÚ‘‰‰ uîÜ™:wîLÆÆÆ:/Ýùò%µk×Ne»\.'wwwÚ¼y3 .]º··w™2)špýúuš3g…‡‡Q—.]hëÖ­¢çâÅ)(( 7Òõë×iëÖ­Ô±cGZ½z5åååQJJ µhÑB+>s8‡£SÞgt6##ƒ €ïöþÑG±F>š`oo_¢Tÿ}¡ërOu¤¤¤0‘÷þù‡m c«Î‰‰‰¢l %ÒDooïûóòò4.™IOOg6‹7Ïzúô)rssEÛ‘Éd6l˜Ú2×ÜÜ\Œ7Žóõ×_k=ÓKÈT8p ÊöÌÌLÔ®]»D6ti\ºt‰Éh+ 2¸¹¹ˆðå—_ªÝ?uêTf̘!ÊÞ±cÇÔÊp8º`ïÞ½eÊDh ¥R‰¡C‡¢nݺxòäI¥íåååáܹsغu+æÎ ØÚڲϢE‹4’™) A~¦]»v•¶¥ ‘‘‘øâ‹/ ‘Ht𩇕+WÂÒÒuëÖUiÜ¢§§WnS@‡S=HOOÇwß}Çæ³zzz7nž={Vê9………¸ÿ>ÂÂÂpñâE„„„À××>>>صkÖ¯_ï¾û_~ù%œœœÐ¯_?˜šš²9[YŸš5k¢S§Nptt„»»;öïß{÷îiµlÜÝݽDõÛ£GгgOæÇ´iÓÊm²'–ÔÔTH$VÁ'”ÓWt.zéÒ%XZZÂËËKe»‘‘ˆ·oßÖ†Û‡Ãáèœ÷ ݸq#ˆ:t`¥v<`“eË–‰¶uëÖ-èééAOO÷ïßוˢY¿~=ˆ#Gެ²17mÚ"ÂG}¤JåEÛº¬×ªUKkúp>dº” ˜B"‘ÀÍÍMmifJJ “X000€‡‡‡6Ü.AYåè¢5[ ѤI‘ŠÕûâøñã "´lÙRíßçÈ‘#<333Ù Nxx¸.\æpB@¾G:ëÅ‹022‚¥¥e…îeYYYؽ{7œQ¯^=öÌkРºwïŽ>}úÀÖÖ @Íš5Ù}ý§Ÿ~ƒ*ì³l¨ Õøøx|õÕWpqqÑ™¸B¡@@@Ù‹~ñï²K—.hݺ5t2>‡ÃÑؾ};š7oÎþþùç¸zõªÚãSRR´2nRRnܸ£GbÓ¦M˜7o`jjŠ5j”8544ħŸ~ŠÉ“'ã×_Epp°Êâ¿&Lš4 D©T  h¾U¿~}¦KzðàA­\«R©„——>øà•rú²‚Ïe‘ššŠ™3gÂÕÕUíߣAƒj%©8‡Ã©®¼·©B¡À‡~"ÂúõëÙöAƒ±‰‡&ÂàÎÎÎ "|ñźpWc¶lÙ"ªÒ³O?ýD„µkײmhÑ¢ˆ>>>¢ì( ¶ª®Mÿ=¸¶mÛj|nFFœ±e˵û£££Ñ©S'–‘ùnÓ&mÓ±cG:¤²]&“•©#õ.B¶kiM«ª’ŒŒ ¦¯ªnµ¿¸þªØlV¬X¡mw9‚ƒƒAD055­’ñ„ÿëê2ìKãùóçX¸p!7nÌgÏž€€¼|ùRí9)))Éd°²²bÍ3ºwïŽÕ«WãéÓ§¢ÇV*•¬bãÚµk¢ÏÓ”üü|¬_¿ööö¸yó¦NÆP*•8~ü8ºwï®°èÝ»76n܈°°05~âp8ÚçôéÓèÚµ+û¿Ü¾}{8p Ô¨gÏž!88™™™ ÓY†¸\.ÇÇáë답k×ÂÅÅ=zô`s!uŸfÍšÁÆÆß~û-þúë/ܾ}»Ü÷áÝgçÎøá‡XƒÔ>}ú &&F+׎~ýú1??üðCQMEÕqêÔ)Ìž=æææ8{öl©Ç A^±Ía9‡Ãyß¼·©­V¿~}Vv÷æÍöèââ"ÚÖƒØyºz!Ӕ͛7ƒˆ0lذ ¯P(””„û÷ïãìٳؿ?<==±téRL›6 NNN°´´„¥¥%âããYI|5Ïìœ8q‚­@çääˆûÀlU¼T¿²>|D„^½zit^LL ÌÍÍqæÌµûCBBШQ#Z·n­•rÔò˜={6ˆS¦LQÙž””Ä~‹ÑÑÑåÚÊ‚MLLtä©fXZZ‚ˆ°f͵û­­­ADX¹r¥({6l¡_¿~Út“Ã)Á¹sçXб*P(èÕ«Ú¶m[î½555îîî¨]»6ôõõáèèˆÇLNNfÝß…h333xxx¨Ü÷KC›ìÕqñâEXXXÀÓÓSg‹“'Oª”Ö­[³fÍ­[·t2‡ÃÑ=˜1cØÿçzõêA*•–yO}ñâ®^½Š;wî 88ÁÁÁ8vìBCCqçέ6æ,‚‚ÄÄÄÀßßR©cÆŒ™™»/¿û©Q£ÌÌÌàââøûû«ø)$Œ`º¸¸ˆž·—ÅÛ·oUÊéëÔ©©Tª‘´UqvìØ}}}téÒ¥ÜÀ¯P!qïÞ½ Åáp8NUóÞ¤ "|óÍ7l›««++|ýúµh[ãÇaÈ!ºpµBüöÛo¥–µß¾}þþþؽ{7V®\‰yóæaâĉ°¶¶†…… |Ž=sçÎŲe˰mÛ6øúúâòåËˆŠŠBzzºŠÍ¹sçª ÈŽ=D„™3gŠö]ÈDmÚ´©ès ‘€°°°RË©… ±&Y©/^D¿~ý¥vÿüÁJP»wïŽ/^ˆ¶]üýýADøàƒJ„n«6l(×Nrr2›´–vU‰‡‡ˆj÷kð|ôèˆúúúUòÒÂùßåÌ™3 "—ØwäÈØÛÛÃÞÞãÇÇ?þ///\½zU£gÍ»„„„”¨‚(ŽR©Ä®]»Ð¸qcèëëcêÔ©î ü.OŸ>ÅêÕ«ÙýZ__–––رcG©¥§Ó¦MañâÅZñA 11S¦L««+’““µj[ **ŠI˜U&nnn¢Ã§zñúõkÌž=›•°`ÆŒåêä¿~ýÛ¶mÃ;wàíí¤¤$$''#%%wïÞÅ‘#GˆÀÀ@=z=P”Ù^Yå©©©¸pá¶lÙ‚3f wïÞeêœvìØÎÎÎ*¥ü†††Ø¶m[¥}Êé‹K8::jTyð.ÂÑÖÖå/èAWé3‡ÃápÄð^¤ááá,Z|ò"è4H´­'Ož°‰Å¥K—t䱿” ]¾|96lØ€½{÷"((·oßF|||…ßår9š5k"ÂÑ£GÙöÔÔTö^¾|Y”­ÌÌL–9wî\µÇìØ±³fÍ‚““,,,XPwüøñøöÛo±ÿ~µçýôÓO "L:U”/‡‚Ú†R©d°ˆC‡5YÓYYYlÒûnÖòªU«4ú÷íÛD„7êÀS͸{÷.ËvP§SX‘€§©©)ˆûöíÓ¶»ãï¿ÿfeƒe‘ššŠ°°0øøøÀÃÃnnnptt„££#ÆŒwwwÈd2„„„ &&¦\Q[[[´nݺD&M\\ÌtYb‰Ÿþ™58¬Y³&†^¢¡Çºuë*UÙð.J¥Û¶mƒÎª7ÒÒÒ0þ|¶f``€Y³f•*IÀápª7'ND:uØüÍÖÖVôý±  ÷ïßGJJ Ξ=‹ƒâÂ… 8zô(’’’™™‰¬¬,¼|ùñññ¸|ù2”J%‚‚‚pöìYÄÅÅéøêÔû}ûöañâ۵µUÑ-þiÞ¼9BCC+=æíÛ·Ñ¿fרØþþþ¶WXXÈ*§&Ož,ú}…H9‡óoã½H]\\@D>|8Û¶|ùrö פÛá—_~©qPµ*ðôôÁÉÉIçcùøø°ŒÏâ(·mÛÆ4ùÄ6Yºt) ^—¶’ûöm}‡FTTž?®ÕNôšòòåKœºuëÆ*$ª Ïž=c `™™™²¡P( “É0xð`]ß‹/àèè¨R†zäÈŒÅápªŽóçϳ{:½NSSSLŸ>ûöí«|Fvv6>|8zô(öìÙƒ+W®àéÓ§HNNÆÛ·oqçΜ;wÿý7Ž;†¿ÿþxþü¹¶/·ÊP*•ðööFË–-Ùw9dÈ<~ü¸RvÓÒÒ0hÐ èééi\唚šÊ|)Mö…Ãáp8œêF•H…2ënݺ±Ø‘#GØCT“— ¯¿þDE]«B)Ê‚ t:N||<[¡-žyÍ& b;`>~ü˜ýJë_&Nœ¢Ò;𧤤ÀÎήԮÐwïÞEûöíADhРA…»oj‹¨¨¨RËÍ,X"Â_|Q®âY›Çו»¢þ?¶mÛVmZ(enذ¡¨ì‹¼¼<ÖÉT¬Ô‡£);vì¡M›6U>öªU« §§‡‘#G²ÿ;óæÍÃîÝ»ñÏ?ÿ¨•«x(•J4hÐDT¡fv‘‘‘°³³Ãï¿ÿ.º*A 6oÞÌ|400ÀÂ… ‘­õ±8NÕ̤P^¿~ ¸»»£W¯^j¦&&&pqqL&«ÆüË—/ŽÀÀ@¬[·×®]C@@¢¢¢ T*‘’’‚çÏŸãéÓ§¸pá péÒ%øûûëLOYÛùDeû?þÈ´ïÄ2nÜ8–™Y¼T_[eñêš={ö }ûöÅ•+WÔž###VúàÁ­ûW}Íwƒº/^QQGV1B¿úê«2³6«’ôôt¦÷§N7J.—³ÆÅ‹EÙtrráûï¿×¶»œÿq²³³ñý÷ß³ßlýúõK=6>>QQQZÏdމ‰a/§?ÿü3är9ëpìááØÚÚÂÖÖnnnðôôDHH´ê‡„ |M5·oßeY=þƒ bßc=t¦kÊápÞBƒË®]»–Ø÷êÕ+øøø@"‘”0ussƒ———ÆåèoÞ¼Á£GpìØ1=zçÎC`` JAFFÎ;‡   ìÛ·DPP^¼xñ^ËñÕ‘••©TÊ*éjÖ¬ ‰D¢•J¤¬¬,XXXÀÀÀ‡ªëׯ3ù/‡Ãápþ-Ô *ÄÛÛ›^½zE|ðM˜0ˆˆîÞ½K?&"¢ ˆ¶µ~ýzÊÍÍ¥®]»’£££Nü­ ¯^½""¢-Z°m±±±CqqqKqqqôäɺpá7޼¼¼¨V­Z¢ìGFFÒåË—ÉËË‹ˆˆ¦OŸÎö ýû÷‘«««hŸO:EDD í‡&dggQ½zõT¶¿|ù’æÍ›G ccãçíܹ“¾þúk*,,¤¾}û’ŸŸŸÊ÷ú>qpp Í›7SPPMž<™m777§fÍšQJJ ={–† V®Ý»wÓ©S§ééééÚõR122¢Ï?ÿœ._¾LAAAÔ­[7•ý†††dccC~~~têÔ)²°°(צƒƒP`` ­^½ZW®sþÇðóó£o¿ý–bccÙ¶Ï>û¬ÔãÈËË‹bbbH¡P‘‘uéÒ…ÌĮ̀K—.Ô¥KªS§ŽÆ~˜˜˜Ð‚ ¨{÷î4eʶÍÄÄ„œœœØq………ôâÅ zðàݺu‹Ž9B ”‘‘A:t ®]»’™™uíÚ•Œur011¡°°0zö왨ãÓÒÒhîܹdjjJþþþd`` uŸöîÝK‰„ÒÓÓ©víÚ$•JiÑ¢ET£F•NQ8ŽŽ‘ËåDDjç˜Í›7§1cÆÐ˜1cˆ¨h}éÒ%º|ù2]¹r…ÂÃÃééÓ§´sçNÚ¹s'ÝÏlmmÉÜÜœlll¨M›6¥ŽÝ¤IjÒ¤ uîÜ™ˆˆ=zDJ¥’®^½Jÿü󙚚RBB999Qaa!=zôˆš6mJ‰‰‰HM›6¥ZµjÑçŸNÍ›7×öW£4wî\zñâYZZÒÖ­[©k×®•¶““CŽŽŽtåÊÚ·o7N£óóóóiÅŠìYÚ´iÓJûÄáp8N•Q•ÑØîÝ»ƒˆ •JÙ¶€ˆP«V­]€KãÍ›7,ƒ­¢+›º";;Û¶mc+ºÅ3 —,Y©TŠÝ»wãï¿ÿÆÃ‡‘““èééÁÒÒ²ÜÆG)))˜3gjÔ¨† 2íÊâÞ§Úµk‹n¤tòäI¶BæÌ™Š]|95‹7÷IJJÂüùóÕ– Êåröû ¢R›6½O}Í&Mš”hTâêê "‚››[¹v233™6oxx¸®ÜͪU«@D°¶¶V»ÿ?þÁÌÌL”½/^°lØØXmºÊùäÉ“'pppPiôñù矃ˆ0mÚ4ÑvÒÒÒpýúuüõ×_pwwLj#`oo''',Z´{öìÁ;wª$s(>>!!!ðôô„››`ii‰1cÆ@*•ÂÇÇ•.Utwwý=;wæææ:“Æxûö-“^¡ÿŸU¦I“F‡óïÂÛÛD„~ýúi|nbb"|||àææ33³Ù¥T,ÃÔÇÇG£ù‚‚ܺu §OŸÆ®]»°víZ\¿~W®\a^ñññÈËËCaa!‚‚‚àïïË—/Ã××·RM4!::ƒf×ÛªU+­”Ó dggÃÊÊ *«¿ÿ>¬­­!“É*õ·æp8ç}QeÒº£§¤¤@__D„)S¦ˆ¶%蘚ššê¬{®¦$%%á§Ÿ~B³fÍT&kbK9‚Úµk£k×®¥Ο?6mÚ@__...˜4iˆ£FR9îË/¿‘f]Ã…†N 4}ަôèÑDªÝÑ>¬ö…_.—ÃÄÄ„}S¦Lщæ]eÉÍÍEݺuAD%äŽ;"B‹-D5lllÊÔh­JÊk•ÀžOž<eó“O>A&“iÛ]Îÿ………ððð@íÚµ™Fåܹsñöí[L™2D„ü±ÒãäååáÞ½{Ø¿?-ZØÙÙaúôéØºu+®\¹Rá&Gš’ššŠÐÐPÈd2H$888ÀÚÚZ%p&ZEÐjµ²²*ó¸íÛ·cêÔ©:kÌ´—õôô ‘Ht"íÂápª»víÁÒÒ²Ò¶bccáåå…©S§¢cÇŽ%‚¥úúúøôÓO1oÞ<øùù!55U”]¹\Ž””„„„`ÇŽ€°°0\¹rgΜANNâââðäÉܹsgΜAAA¢££qåÊ4£ÌÊÊÂ’%KTÊé.\¨Õûsvv6¬­­a``Pj/€Ò(((€‡‡†Ž—/_6nÜ"‚“““Ö|äp8G×TY€tذa "L:•m|zzz*e‘žžŽÆƒˆð×_éÈ[ñ\¾|Ó¦Mc/ìBæ&ýýIM¸!!!022BÛ¶mKh?nÚ´ úúúèÒ¥ ÂÃÑ““ƒFˆpòäIv\NNË, 5nNNkôäêê*Ú_M´fOŸ>]æqr¹¼Äd·yóæè¯ „nËïf²²²ØoáÚµkåÚÙ°aCµYmW*•hÕªˆ~~~jùì³Ï@Dغu«(›K–,ÁÙÙY›®rþGˆ‰‰¹¹9»'ôíÛW%ÛZhR1aÂÑA{Myþü9üüü •J1räHØÙÙaܸqðððÀùóç‘••¥“qÕ‘””„³gÏâ÷ßÇœ9s0dÈØÙÙaìØ±XµjU© JB“”:”i_WÁÊœœH$¶ÀÒ¡C\¸pA'cq8œêÅÖ­[ATÔa]ÛÄÇdz ScccµS333–aúæÍѶïß¿€€:tW¯^Å¥K—p÷î]•cΜ9ƒ}ûöÁËË 2™ ¡¡¡ÈÊʪtÖ¿¿¿?:tèÀ®ÃÂÂB­>|eÈÏÏÇàÁƒ+*:d2™Êsgîܹ "H$­úÊáp8Ž.©’itt4ËÊçär9[ Õd%yõêÕ "´k×NtI¾®8pà€Êä«[·nøóÏ?ñûᅢˆ`nn®±ÍÛ·o£U«VhÔ¨Ο?ðõõ…žžFÅ^À÷îÝ˲‹¯VïÛ·Oíö²X·n»†§OŸjäo~~>bccqùòe>|›7o.õźuëÖ "\ºt©T{yyy*ÁÑÉ“'£sçÎ "üßÿý_µ+±ÀþÞŸ}öY‰}€˜æD=b“øW¯^éÂU2òfÍš¥v¿É=tèPQö.]ºÄªãß‘S}‘Éd¨_¿>ˆuêÔ§§g‰—N{{{•ûq÷îÝñóÏ?ë¼d[È4Z±b†;;;Ì›7‡~/M˜Þ¼ySf‡z¡³°A•7¹q㻟ƌ#:«‹Ãáüû‚GŒ¡ó±ŠLÕe˜¨LÅÜ‹òóóˆˆE N~~~øçŸ˜˜ˆÜÜ\¤¤¤àåË—¸zõ*víÚ…={ö 88çÎÓÈuR2^^^:©¦š6mšÆ>J¥2™ ÇW[ù&øîéé©MW9‡ÃÑ)U 3gN‰’¾åË—³‡¾XÍÅììl4oÞD„ßÿ]WîŠfË–-ìÚ·oÏ:j®\¹D„I“&UÈîóçÏññÇ£V­Z8tè>üðCôèÑCåeÖÊÊ D„ï¾ûNå\!H°hÑ"Ñã +íïfeggãáÇ8{ö,¼¼¼°zõjÌ;ÇÇÀ²kÀ^ IDAT1hÐ XYYÁÅÅK–,ÁæÍ›áïï_êj¹ñZÚË»\.WYõ:º?zôˆeꏏˆ¾®ª"66–eBÇÇÇ«ìÛ¹s'ˆÔkuº¹¹aäÈ‘¸qãÛfjj "Òx_:tˆ-F¨ãÚµk,cZLæ\aa!š4i"Bpp°¶Ýåü’””Ä„E’‡–z¬‡‡úöí[¢û±±±1æÏŸK—.é\–E¡P ""2™ “&M‚ $ üýýuV®® r¹œ-Xjº VQ Ù¸5Òªn‡Ãùw $9Œ7®ÊÇŽ‰‰——ÜÜÜо}{µÓ^½zA"‘ÀÇÇG”†ÿÛ·oqäÈœ;w'Ož„¯¯/Ο?ëׯ3½Ò„„ܸqCt&iNN¤R)«@Ò×ׇ›››Z­~m°lÙ2–.]*úœgÏžaèСððð(õº„Å0m¹Êáp8ŽÎÑy€ôíÛ·,ó§x©®(éܹ³h[›6mb«¨U%ˆ^¡F,À¥K—ªø4%++ èׯ{ÑßµkÛÿìÙ3ö¢ɶÇÇdzRùwKJ#!!MW®\ɶÿòË/pppÀôéÓñË/¿`×®]8uêîß¿¯QYRq„ŒauŽwËêßmltâÄ vÍ[¶l©Ðøºäã?áÏ?ÿTÙž””ÄüŽŠŠbÛ  ëééÁÙÙwïÞ…D"QQCª÷Mjj*û=ÿ ( ´hÑB£ ð¸qã@D˜7ož¶Ýåü—qõêU–u^£F üòË/¢³âããã±mÛ6ØÙÙ¡fÍš%ä:¦OŸŽ“'OV™æåýû÷±iÓ&Œ1C† Á¯¿þªr?¨j„ÿ·ºj¾Tœ´´4&Còî§eË–,€,“ÉpùòeÑ9ο©T*ZÎ騱c Ô™/ŦíÚµ+7`*&@ùöí[DFFŠî?ð.þþþ*‰½{÷VYD×6ÇŽƒžž&Ož,*3Uȵ³³+ó¦P(X€Wȶåp8ç߀Τk×®e¢Ï©ééélâ—œœÌ¶ggg³,±âÁQ¥R‰ØØX&[ü§LSDW§¦MgΜÁÈȨ„®ŸPRfaa¡öÜ{÷îa̘1%&㬠×ËD°³³S»ßÇÇD„¶mÛŠ ð$''«Í¨åp€" âéÓ§³ÿC† ѪFeNNüüü0uêT4mÚTåÿ[­Zµ0tèPìܹIIIZ³,”J%®_¿Žï¾û–––J¥xüø±ÎÇd t© ççç###–µûnFÕëׯqîÜ9lݺ³fÍBÏž=Y5‘ª$‡ÃùïàÛo¿aîܹåûêÕ+´iÓ¦¦¦:+// ¥R‰ˆˆlÙ²£FR»¨chhˆà§Ÿ~ÂÙ³g+TÙ–››‹eË–¡N:,;gΜ ?÷ÂÂÂDi_gffâã?Æ| j.íããKKKÑÁêóçσˆÐªU+QÇs8‡S]Ði€TÐ0lР[i½sç›\¬ZµJ”ÂÂB¦Í¸bÅ ]º¬{öìaàÀŠÊ©{ôèÁ®ÏÞÞ^ëcž={DEJŠ—"Þºu‹eé$&&в%4Í!";vLë¾'11‘%…333Y§t"ÂìÙ³­¤ß¼y©©©HMMÅ­[·ðìÙ3@FFÌÌÌX¦luZÀÿcï¼Ã¢8»÷À޽ÅÞ5öò±£¬ŠŠ5*ָꫮƶj4óF]KÌÆ]Ûj,Ø¢kÇ.XÁ¢‚‚i»÷ï®y~,[˜-æ}>×5×¥;3Ïœ¶ÌœçœûFF…³ “šµº544”ÝøfNgåÒ¥KH$Õ ~~~ŸL'ÐW¯^eÉ#SÆñññ¬…Y¬¬ƒPQû믿::\ÎgLBB« vrrœ9srT/4-- 'OžÄäÉ“Ú+áêêŠåË—#,,,ÇbÈŒN§Ã©S§0jÔ(tëÖ 9v¬±cÇ‚ˆ —Ë>¶^¯‡B¡`•ñ_ýµÅðøøxLž<™ÉyËæÍ›‡ÃÉ]Æ"ÂÌ™3EmîÜ9äÏŸÆ ËáȲG¨0õõõ5š`î¿… S­V›­åÉ“'Ñ A¶ÿW_}…Ë—/ÛßÑ£G‘/_>8;;ÃÓÓÓb‡À˜1càì쌓'OZ3::¾¾¾ËåVãªT*‹“ë‡ÃáäUr4A*´çN›6½Ö¡C–pûc+Tj–(Q"O9ÞnÚ´ D777öZ\\êÕ«Ç ͰaÃ@DF7‹S¦LÁÛÛ[ôXžžž,ÙjoOJJ ¢££qïÞ=\ºt Z­Ö ’2,,Œ%>t:Qr4³ÁÅ‹ƈˆ@dd$€¼kÚäããc6é ToÙ²%Ûqþùç4oÞÜ JA*•æŠ#¶N§cÆh4¹ÔZ´h‘¨1³«Jåüïñöí[´nÝDìÙ³ç“_¯×ãÚµk˜;w.›€É¼4kÖ …7nÜø$ñ$%%åèo ÓâèïÏøøxôîÝ›]·#FXLìÙ³UªTaÛ÷ìÙ“U˜;46‡“ûŒ5 D„yóæ‰ÞgÞ¼y "?~<#³žÌ SÁWALÂ422~~~l»Ò¥KC¥RÙXòQìC¥0™Õºrå 6lØ€={öàĉFxx¸M•M‚FgõêÕ ’£¦f°Í9v>}ú¯^½bÿª ('L›¢¢¢XÒ6""Â`ÝÙ³gÙ{ÂZÁz­Vk ÝP¬X1ÈåòOæöü×_(ÃhÍwïÞ%!  ×ë™îì¾}û.ç3">>ž%GK—.K—.åvHF¼zõ þþþðööf¶ÂR¶lYøùù! ÉÉɹªhöíÛgv2Ç>Ìô¬Ë•+g6É––•J…bÅŠ±{©TÊ$xþþûï™\äp8yƒþýûƒˆ°téR«ö;vìˆrV7ȸwÄäLzz:®]»†eË–¡gÏž(^¼¸ÁoÇ—_~is;}jj*Ôj5ºvíší½ïÝ»wQ¡BT®\Ïž=÷ß~‹ àöíÛÛA*•ÂÍÍ jµÚ.c¥þù… ²Jz‰Ãáp8œ¼BŽ$H###Yu¢ £–œœÌ.­1_f!¿ûÕ.„ÄQV7ùØØX£™ãR¥J¡L™2(Uªš4i‚–-[,‰ÄââííÍ4æÏŸop<ÁùRŒ+¨€Ðò]ªT)œ9sáááÇÛ·orm²"$º3›p|ÿý÷&·Å½{÷Œ^üø±ÁL»N§cf#*T00tÊ-„dϺuë ^OOOg"ÿæZÕ-¡Óé ÑhØß(ÃåT¡Pä¸û¶c%A#ø¯¿þ5æèÑ£AD;v¬#Cå|F$''3y†råÊ!$$$·CÊ–ØØXlݺýúõcÕüÂR¼xq 4;wîÌñϤ½6UªT±k½^Ÿ~ú‰}?|õÕWxúô©Émƒ‚‚Øï9Q††tæ®øñÇADðõõµ+.‡“7îÙ2·ŠÅÍÍ •*Urxuyjj*¶oßÎd^¤R©ÃÝãÓÒÒpùòe´jÕ D„6mÚØ4ŽV«…D"Z­]|‚¢E‹â«¯¾‚³³3“=‹‹‹ÃÊ•+áîîŽ3f°*S[yòä |}}1|øpÖ%dk*‡Ãáp8¹EŽ$Hår9{X4Ï,U,fåСC ÊÐ+ô'óB+}ãÆÖõéÓǨÚÈQ‹V«elje3µçÏŸwDD„¨ã899ÁÉÉ ÎÎÎ(P  (¸¸¸ xñâ(S¦ Ê”)ƒ*Uª jÕª¨Y³&6lˆ† ¢U«VhÛ¶-\]]ѽ{w&“ ,ÙéO=yò¡¡¡ìÿqqq&Ï/..Ž% [·nëíWsæÌ¡OŸ>FëFŒawRPH”Ö©S‡]ËråÊA©TæhKªðà`®zcòäÉ "|óÍ7¢ÆÛ³gk­ÕëõŽ •ó ×ë1hÐ VUmJw8¯“””„ýû÷cĈF†… B=°~ýú<×ùwîÜ¡páÂ6‘Àt—‰2t±M}ÅÅÅA&“±$jÑ¢E¡T*M>Ü Õe ,°9.‡“wŒ(ÕjµÕû Îè«V­rH,¯_¿ÆÂ… ™r½zõ°|ùr,[¶ :u‚J¥rø=åÓ§OÙwaÖ¶xK„††ÂÇÇr¹Ü&i¢+V€ˆP±bE<|ø3gÎD×®]±sçN»»RRR R©Ð³gOܾ}Û¶m¡yóævËáp8Nnàð釨Ãbæj²Ò¥KƒˆP¿~}Ñc †NãÆst˜áÔ©S¬mÜ xòä ®]»†õë×£V­Zì²e˖ذa4 Ö¯_µZmvb... ¥µkׂˆP§Nщ&ÁÐ)·…B!*Τ¤$ܾ}wîÜ1{#‹-[¶ pá 2®æýÔœ;wŽ%²ÞtîÝ»—U»Ú[ ´Xe68©Zµ*T*UŽ´ú ^^^&×ÿóÏ? Êh“£ËÏ&>•ñ 'ïðË/¿€(C–aÿþýFëŸ%Mêõzö@˜9é!TM–)SFôXBòdøðᎠѡܿŸUÐXË•+WP¿~}öéëëkÖühÍš5l»ÌA=bmðb+“®_¿ÎÆÚ¼y³èx©TŠ:@*•B£Ñ˜ÕÚ{úô)¤R)ºuë†àà`ÑÇÑëõǰpáB 452Ð.ͺ”-[–iÚòÀïh"b:O™ñööaöìÙ¯¿xñ®×ÄÄD(•JV©M”aªdN•%ÒÓÓYeø‘#GLnÓ§O™6Þ2ÅòåËADhß¾½Ýñq>Y´{÷îÐëõ8zô(ëÈ\uY³fM´iÓ†%ã,-ùòåCݺuÑ»woÌž=þù'‚ƒƒóDÕéýû÷±xñb´nÝš™¸ KíÚµ1mÚ4:\ó.;„ê©ìz½ .dí¡-Z´0ªhJMM…J¥bcçÏŸ2™LÔ¤Upp0ˆ2º$>õµàp8Ÿ†¦M›‚ÈvƒÆ„„¸¸¸à?ÿùUûíܹ“U÷÷ïßß@ÂI,èß¿?†n—^çÏ?ÿ "ÂàÁƒÖéõzh4tìØÑ *ÓÞ¼yƒ‰'bàÀ¢Í’Þ¼ycñoóáÃ( ôèÑÃä5LJJb wïÞµ9v‡Ãápr ‡&H> "B‘"E˜›µPe™µZÈ—/_fÉyÙ¸#s›¢-LIIIËåì³zõê8uê”Ñv‚NµjÕ ^Ÿ?>ˆ:u}Ì^½z(C<=55Õê˜BBB T*áåå…Î;C©T"((111ËåðððÀÙ³g-ŽñîÝ;B­VC&“A"‘0##SKШQ#øúúB¡P À 1,´ÙÛrãëH6oÞ "ÓNÌ6l¡aƯ æ%®®®Ùº’Zâýû÷P*•(Y²$»n5‚F£±[ëó›o¾A&“™\¿~ýz‘èö·{÷î±äVfó-ο—iÓ¦(CíðáÉQgggôìÙ»víb¿oß¾eɶõë×ãèÑ£X½z5¦N ooo4hЀi0›ZœQ¯^= 4J¥ÇÏÕ÷Zdd$Ö¬Y‰Dº„¥B… ;v,>œ#2Y’b¾oÞ¿ÏôA‰2´†³V’Ÿ;w7fÛ´lÙAAA¢ãÙ²e ˆ­Zµ²ú\8Îç £qôèQ›ÇèÓ§ªT©"êžæåË—èÛ·/»ïúçŸl>®ÀÍ›71bÄôíÛ×ÈhN ½’‡‡‡ÁëW¯^E·nÝ P(ìꊰÆå^ ..óçχD"ÁéÓ§Mn€:X”d¦J•*Å'º8‡óYâÐi×®]Adè¦.´€.\X´›¡Pe—×lØÃà«W¯lçøñã¬]ÜÉÉ R©”=|¾|ù’Ue®ÊÕëõ¬kÆ ¢Ž£ÓéXÑœ–¤-¼yóÛ·oǰaÃàååeÔZžššŠh4( x{{£víÚFÕT™—J•*ÁÛÛr¹þþþ Êöý#´™ÛÒzåHbbbÌŠðg^—ÙþçŸ6H˜H$»Úðß¼y…BâÅ‹³1›6m Fcó˜þþþ Ê020ETTû›ŠÕÊ´u·mÛfs\œÏƒ   ÖB]­Z5ö9(P ÆŽ‹ððp£}/^ÌÞsæ¶t:?~Œ`ñâÅðóóCË–-\æ3/5jÔ@ß¾}±dÉæJ‹~ll,¶nÝ £XK”(AƒaçÎ6rˆ¡yóæ¢*¹=zÄLöòåˇeË–‡T*eŸýR¥JA¥RYýp<}útFmõ¹p8œÏƒêÕ«ƒˆ0þ|Œ5 ¾¾¾èÒ¥ ¼¼¼Ð³gOtéÒ¾¾¾6læÌ™ƒuëÖáÈ‘#¸ÿ>ûNÙ´iˆ(Ûî¤íÛ·£téÒ(R¤–/_înšÌ„‡‡C&“1MO±“ÐÂ$ºPÜðüùsŒ1ÇÇË—/íŠI«ÕÂÍÍ *•JÔù “ê;v4;‘þàÁôíÛr¹‰‰‰Ç[²d‰ÃŸ18‡Ãù”8,A„VŽèèhöšØ‡ž›7o²}¬©>É ôz=ký¶§ÝȨ¦ôóó3¨ú ÂèÑ£Ùƒiæ‡xÁͳpá¢Åã3kÁæ”ktTT´Z-T*KTXªð*UªkÙW©T ´YC´Aƒ ">|ØÁge=‚“)·Õ¶mÛ‚ˆŒ J¥,‰$$Jíù¼zõ r¹œ%Ɖ2Œ¬Nœ8aÓXÙ¹¯¶hÑD„ßÿ]Ô˜“&MaÈ!VÇÃù|HKKcÆ™—¾}ûš}/¥¦¦2ƒŸÕ«W[}LN‡°°0üý÷ߘ7ozôèJ•*™ü*X° Úµk‡iÓ¦áï¿ÿ¶kÂË>|ø€}ûöaøðáLÃXX *„=z`Æ ˆ‰‰qØ1…êÝ?ÿüÓì6Ge²eË–ÅñãÇÙ:½^¦iM”aÂd«Ä‰0ÁjÎð‰Ãá|þÙÇŽÃË—/M&ÜÞ¿èèhaïÞ½øõ×_1qâDtíÚ^^^?~<ˆË—/7yŒ””üç?ÿ¡]»v“Ñ9ÁË—/1gÎH$’lˆðÇ€ˆàîîŽ_~ùÞÞÞ¢[àÍAƒaÖ¬Y¢&Õ>|ø•Jwww³‰ÑÄÄD( ôïßßä¦)|||@$ÞŒ•Ãáp8œ¼†Ã¤cÇŽ¡k×®ìµAƒ±6G¡eR ..Îè5ðõõeZŸÂlxæ„Ó·ß~ µZmSK³F£aZùóçgÉŬ:Bâô›o¾=¶¼²ÆTÊqqqíñ:t0¨V̺d×ïÚ´i"ÂöíÛ:®-üðà "ôèÑÃhP×±cG“ûÞ½{~~~,éääooo»ÜÞŸ?™Lf¬îСƒÕíü‚€¹„Õ÷ß"BÏž=EwäÈeè;ººƒ“wôf…¥víÚ8vì˜Å}„ Ò¥K‹zèË‹/pøða,X°^^^rÂâììŒ-Z`úôé8zô¨CŸiii8qâ&MšddD—/_>tìØ¿üò‹èVs ÉuëÖ­ÓëõX¼x1›¬iÖ¬™Á÷õÇ!‘HX\uêÔ±»uµråÊ 26·ãp8ÿ„ ['~ÓÒÒpãÆ T«V ½{÷6Z…6mÚÀÉÉ Í›7ÇŠ+äPÓJsˆí’Zì%‰C4ó5 :wW¯f»mZZV­Z…N:aûöí&+ýTwww³111xþü¹Ñ~‚LVæÉ4‡Ãáp>'’ }ûö-k \’’’XËpVN‡*Uª P¡B˜>ž][kÄíÑòI’_‚k²ØêÅœDp}/R¤ˆ‘VßÝ»wY²ÃR¥Ú™3gŒ’6¾¾¾vUCUª™M¯®$O¼ IDAT$ ®]»&jÿì /^4{Þ¦øøñ#ûîÈmiNÎÇtDóåˇéÓ§‹zoÉx±¦_¶¢Óépûöm¬]»~~~ÌT0k…©››–,Ybw·€5èõz\½zsæÌaˆ™—-ZàÇ´©úH¨ôÉZ…•˜˜ÈŒæˆƒ b â?B¡P°‰– @&“Ù@~ûö-;^tt´]cq8œ¼‹ÐÍb¯¿ÀÈ‘#Q¾|yƒ×îÞ½‹êÕ«£X±bÐh4HHH€V«…B¡@Ÿ>}àéé ¹\Ž€€¼{÷ήãÛÃÚµkADèÖ­›]ãU£r¹\”nõÑ£Gáææ†uëÖ™½'¿uëºuë¥Ri”ðMNNÆîÝ»áããƒ~ýúIܾ}›ý.|ÊIE‡Ãáp‰C¤‚#ã—_~Éf#çÍ›ÇxnÞ¼i´Oæê“Â… cÊ”)¬zÔÓÓÓa}„É… ­{ðàºv튅 Z]MšYc´`Á‚ë„ʪ *ˆž[DÄÒY±¶=¾téÒkwÂßbñâŹƒ€N§Ã_|"Ó-ÿ‚QÁæÍ›ÍŽ¡×ëQ³fM–Éš(5ך,†{÷îÁÏÏUˆ‰­R=þ<ˆ2œ¦Mé6f>ïC‡‰ŠEО;w®MçÂÉÛ¼{÷U«VEË–-EU¸Àõë×Y}Ö*•OAxx8Ö¯_Aƒ´ Kƒ —ËqñâÅOjDqïÞ=,^¼­[·6š¤ª]»6¦OŸŽÀÀ@Q1 6 D„ °×ÂÂÂЬY3–ÌV*•ì·ëÌ™3LÆD¨€w”!ž0T®\9‡ŒÇápò&ÙÉôˆå×_áÅ‹2&¥Ë•+‡ *˜­NMJJÂÙ³g±páBx{{£GX¼x1‚ƒƒí6±´†Õ«W[ÕicŠƒ¢sçÎÙê°Ï"C† L&Ë61|èÐ!£ßÜ   Èd2¸¹¹A©TšÄZ¹r¥ÉŽ7‡Ãáp>'ìN¦¦¦²6Àµk×ÈHìަœ¼´Z-«ʼØc$ó©™9s&ˆcÆŒ1¹^¯×C¥R¡OŸ>ˆ=nJJ K^5Ê`P)9cÆ Ñã Ú{õêÕ3Ù_¬X1³‰Ð‚ ¢Q£FðóóƒR©Ì‘öxG •JAD˜={vn‡àÿ' &Mšd´nÆŒ ÊÐ`´Ä¬Y³@”!]qáÂxxx°¿K •JíjÑ ¯¯/K¶dW¥šžžÎ4͵P Zº&LÃï¿ÿÎ’ÀLž<D¦%*>5:7nÜ€R©DûöíÙ¾°T®\Ó¦MÃõë×?i\ÏŸ?ÇêÕ«áééiP.Lž;GŽ1[Y4nÜ8fÍš Ã,Pøl—.]šµÌGGGÃÏÏ}G”.]Úf s¬ZµÊd· ‡Ãù÷’’¾£ìø:uêˆÿüóN:…"EŠ ^½zVÝ›~üøÇŽÃôéÓáé鉡C‡bëÖ­9^ž`Á† fõ¾©©©P(1bD¶±±±Ëåèß¿?=zdÕq"##¡R©Ð­[7Èd2£ß·Û·ocòäÉ÷°ýû÷ç“݇Ãùì±;Aú矲‡&¡¥bëÖ­ì&hÿþý÷×ëõ00ðpqqL&³ÛÍñS ˆ­»ººZÜN«Õ¢mÛ¶&«iM±páBv=2'À¢¢¢XâTl[¥PE”áŽl.êì쌺uë¢ÿþP(ؽ{7/W®\a•œÙU© •Þß}÷ɱvîÜ ¢ §r1<{öŒU±æFµ 'o‘œœÌt˜÷ìÙ“Ûრ6 W¯^(R¤ˆÁwh£F°páB<}úô“Æ F???#-hx{{Ãßßß zhÚ´i "Lœ8jµš%Y4h€{÷î1&áoáää???« ¬.\¸€‡ZÜF˜Ü’Éd6?‡ÃÉû$$$°ï%{ðÞ¼y"€P´hQ4jÔÈn»ÈÈHlÚ´ ƒF×®]±xñbÜ»wÏ®1M!˜Sš»‡2Ç“'OеkWìØ±ÃâvéééX¹r%ÜÝÝqêÔ)Ñã'%%A£Ñ`À€èÛ·/4A—ÚÇ¡ÑhЯ_?H¥RƒJ]½^Ϻ‡²Óçp8'/cw‚´U«VFU{B[pÙ²eEW™‰ÒÌ­ÄE‹…L&ËÓšdBËqÙ²e³ÝöÙ³gpuuÅÉ“'³Ý¶Zµj "Ô­[×àõ¥K—Z]m'˜e^¾øâ xzzbêԩظq#®]»&J0§HOOGDDNŸ>M›6á‡~À˜1cлwo¸¹¹ÁÕÕ®®®èÞ½»Y—cAêÁ㪜äíÛ·,™U·0==µîX§iÓ¦ "üú믯kµZƒ‰…¢E‹B.—[U©œ1Uª›6m¡aÆ&Çx÷îÓ«ÁÛ¤IÖ¯_os윻wïfíÖbM/r‹ÄÄDüõ×_èÞ½»A§³³3¼½½qôèÑOÚ‚d<ä@*•¢B… ßû… ‚D"J¥Âwß}¢ ƒ%a}¯^½Û·o3}m¡óÀZ󤨨XŒ7£FB\\œÅm…cmذÁžSçp8y˜×¯_³ï”øøx»Ç«R¥ ˆ2佄V{G‘žžŽÀÀ@Èd2tìØ2™ Z­Ö!fO‚Ô¢E‹Dï£ÑhÐ¥K/õêÕcï²eËB©TÚUl®JUHÔ ºÃYY²d ˆ²—ž8{ö,ß–'οƒÌ"Ù†åe®_¿Ž1cưÉ)¢ y“¹sçâõë×¹“ð?{öl³¥ àÈ‘#8tèëþ "tîÜÙêöÒ°°0ôêÕ r¹Ü¤‰›)"""X BB‚-§Æáp>?~Ì>ëÙu—=zô;vìÀ´iÓгgOtëÖ ½zõÂÔ©S±jÕ*üý÷ßÐjµÆëׯM>oÄÇÇãÅ‹¸ÿ>Nœ87B¡P`РAèÒ¥ z÷îyóæáøñãV¹®‡„„@¡PÀÃÃ2™ Vi2 3°¸]dd$ºuë–mKýéӧѹsçl%iâââàïï~ýúaøðáÐjµFqA*•ÂÍÍ jµÚäuyÿþ=–-[fСðÅ_`éҥܽžÃáp8Ÿ=6'H#""؃¬PõÉ*˲«Š‹ø\¿3WÈåFEŽ)|||@d蜯_¿F»vín´Nx¨öôô4x}Ê”) ²Îù²mÛ¶ìšå´Kgll,öî݋ɓ'£S§NðððÀÌ™3±wï^¦Ÿ™“k3>>jµîîîJ¥fý Þ¿•J…Š+$Fíˆçp8'/as‚T0xÈ\­7`ÀÖ®g*)es’ÎT…œ#Z‰Á¢E‹@Dðöö¶j¿ÐÐP¸ººÜXüý÷ßìü.\¸À^OKKc³µ»ví5~bb"Kb>ܪØÄœœŒãÇC.—£S§NèÞ½;–,Y‚k×®9D§ÉZA”á*WÐëõ¨\¹2ˆL–õêÕ D¹\nqœuëÖ1™1Ÿ¡””¨Õjvl¢ Ó$•Jes…fzz:üýý ’= 4;ž°ÝöíÛE/TNO:Õ¦ø8Ÿ?‚QØüùós;‡’žžŽ?ÿüÓ`’ÁÅÅ ,@RRR®Ätÿþ} :”ýFÆgu‡Æ… бcG›í…ßÏÞ½{[½/‡Ãù|º J•*er}ZZZ®êN'''ãàÁƒ1bºté¥RiÒ¨ÒB…~ví홪Lu‚éõz(•JøúúZ|¶ÙµkÜÝÝqåÊ“ëoܸ)S¦ÀÝÝK—.5™¸ªE;uêµZm6É™¥RÉ&±…‰4¥R™k¿_‡Ãáä6%HP²dIƒd݇˜1‹D"1ÚGp{ÿúë¯qøða›*ä2W¼”-[ …"×¥'Nœ`•zÖ> îØ±“&Mbÿڙ˔)c°]@@ˆ%K–}C¢T*Ù5ÊÎEX,oÞ¼ÁÖ­[1`ÀtìØóæÍÙ3gò„™ÊíÛ·Y›v^bÔ¨Q,ùásÑ A‹cÄÆÆ¢P¡BVëô}øð*•Ê ªFP«Õ6'±SSS±víZfJcÎtlâĉ " :TÔ¸þþþ Ê0\àüï‘””Ä*ª/]º$jŸÄÄDôèÑݺuÀðÝwßá×_Åž={pùòe¼xñ"Ç+ç­A§ÓaçάŒˆP½zuìܹó“ÅùñãGL™2Å 1jËÄD\\d2 d—#õ!C@DøþûïmƒÃáä}.\¸À’ky””9r£G†D"ÁªU«ÒµvãÆ 6A–õ;ÿõë×èÓ§T*•Ùýããã1nÜ8L™2Åâd÷Ï?ÿŒàà`£×ß½{µZÎ;C*•Z4ÒŒ‡R©DéÒ¥ ~¯T*•ÍI‡ÃáäulJªT*ªT©ÂZ_æÎË~@oß¾m´ÏáÇY‚‡ˆÐ¶m[»ZiMµ ‰RG¸cZCbb";·›7oZ½ÿ7ß|ƒS§N!11‘iMfNš€¯¯/ˆR©Tô¸5jÔ`74öƒ5kÖ K—.ðòòªU«aט9Á³gÏØ{!§Z²lA£Ñ€ˆPµjU£☘˜lõEúôé"ÂäÉ“­Žáýû÷P*•Ì EHÊúûûÛl4 hϘ1Ãäú#Gްd¿˜dì«W¯ØµpTBŸóùpøða6Ñdé=ùêÕ+=zÔè3ž€=z6lÀ?ü€#F {÷îðòò‚——Æ•+Wâøñ㢌,r N‡?þøÃ`â¢cÇŽxðàAŽ÷Î;L?XÐÚÛ­©,L˜!‡!ijsçN»Çâp8y—S§N9äžôS“’’Fƒž={bàÀ&µ;Å"t‰5iÒÄàu¡¥þúõëf÷½téÜÝÝqêÔ)«„ñãÇ£wïÞð÷÷·Xhñúõk( ƒûÅ5jðÄ(‡Ãápþ'°:AªÓéXëìÒ¥KÙk%J”¡aÆf÷}öìd2™A¢´uëÖÙ ‹[Bh%ÎìÐ[®\¹O®‰#¸R ×ÄÞ½{‡ððpÌž=Dö™+rÞ½{‡"EŠ€ˆpþüyQc†‡‡³ëñßÿþצ˜6n܈îÝ»£{÷îØ¸qcž3ÇÊJ||<;çÜ2B1E||>3gÎd®ñ...X½zuŽT“nÛ¶i—)SkÖ¬a¿+ýõ—¨1ÂÃí6a²Djj*;÷»Çãp8y—£GZÕ%¢ÓéàããƒîÝ»cðàÁ˜0a¾ÿþ{,Y²jµjµýõ4 öîÝ ­VË– . ((ˆ->DXXÂÂÂðäÉ›ïg@•+W¦råÊQ©R¥D/¥K—¦R¥JåHì;w¦³gÏ’R©$¹\n°nÉ’%4{ölruu¥ÀÀ@³c$''SÅŠ)>>žŽ=J^^^6ÇóæÍZ¾|9­\¹’>~üHDD­[·¦yóæQ¯^½DIÕ«W'ôôéSª^½ºÑ6½{÷¦ƒÒœ9shÑ¢EÙŽ¹`ÁúñÇ©k×®tìØ1ëNŠóYS«V-Šˆˆ ;vÐàÁƒEíA “'ORéÒ¥iÀ€äååE }Üäädºzõ*;wŽ®^½J©©©Ô¢E ’J¥T»vm[OÇ*>|H#GޤK—.‘D"¡Í›7SÕªU2þÆI*•’^¯'wwwÚºu+­_¿žþûßÿR“&MèÖ­[äììlvÿôôtZ³f ;vŒ–/_N5rH\!!!Ô´iS*X° ½ÿž ,èq9NÞcÿþýäããCM›6¥Û·o[µo||<ÅÆÆRll,ÅÅÅQRR¥¤¤^¯§øøx""úøñ#%''³}Þ¿Ïž1ˆˆâââ Æöî©P¥J•¨fÍšT³fMªU«Õ®]›ªT©bOJJ íÝ»—¶nÝJÕ«W§ &P‹-²=‰'Òï¿ÿNS§N¥o¿ý–&MšDcÇŽ¥!C†˜ÜþþýûôŸÿü‡LR©TÄ•" ¦?þøƒ¢¢¢ÈÏÏúöíkñ7ñÕ«W´bÅ Zµj%%%QíÚµI.—ÓèÑ£)þü¢ŽËáp8οk3ª;waâĉìµêÕ«³wk*_~þùg 4"B‡pæÌkÃb˜2§\s²:hÖ¬YìxùòåÃàÁƒñþý{Ñû ®ßD„?þøÃ`]ûöíADøñÇE¥×ëQ¼xqV¡+†?ÿümÚ´ÁÌ™3­v!v$qqqÆîÝ»±téRŒ?]»v…««+:wîŒaÆáçŸ6»Ö÷“µ‹=ú¸–ô`ÝÜÜŒÖÝ»wDæfÙ9[9D„aÆ9$®˜˜ÈårVYFDhß¾½Y]ѬZŠëׯ7¹^0—jÖ¬™¨ñ®]»"B¡B…̺²rþ};ž>} ©TÊŒ—„ÉŠ³gÏZÜoæÌ™ "ôë×ÏäúçÏŸ³ë+F·V¯×³Éýû÷Ût.œÏ]»ve+Ñb ¡¡¡P(puu…ŸŸŸÍÉÒÜàÆìû `Á‚ظq£ÍcýóÏ?L×wìØ±,Á¹fÍ*W®lÖ`ïÝ»w˜0aFŽi— “%ír±FnçóeË–- "¸ººæv(VóñãGœ9s …]»vÅ7ß|ƒÝ»wÃ|ùå— "}úXC§Ó¡J•* "lÛ¶Íá1>yòÄäd…)7T8yò$ˆ%J”0kŒÕ¬Y3Ö®]+*†Q£FÈ:C2ÎçÍôéÓAD>|¸ÃÇ aÉR©TŠÀÀ@‡WB:š¸¸8ViD”a„f­.ixx8Ê”)"ÂàÁƒ ö>“‹-2»ÿñãÇEW’ÛŠ01¨T*sô8'÷Q«Õ "xzzæv(v‰•+WÂÃÃÓ¦M3ªò …\.GçΡP(NÇîõíéÔzñâ”J%:vì¹\.Ú4õÉ“'F>Í›7·IƒžÃáp8œ+¢¤111l¶Q«Õ0¬;v¬UÚÆe2™Ñº;wîÀ××—íääooo‹îŽÙ!$J3»W¯^ÝîD©ÐZ_²dIþ[8}ú4›üKTT”J%\]]!—Ë­ú® Å!C :‚\]]qüøq[Âçp8çQ ÒäädÖ¢.%&&¢@ "téÒŪƒúøø€ˆ0pà@QÛ_¾|ÞÞÞì^HÒ}:|||àêê WWWøøø`úôéX³f Ž9‚û÷ï;D’ 'ùá‡@”¡ãšFƒråʱĢ\.7„puuÁßß?ÇâKLLd­M¦ZÖ…Öò1cÆd;V£F@DX½zuN„jÄ¥K— >ƒ €ŸŸ°víZÖªeŠôôtví9"êxîîîÙ¶sþ$''³¸°°°\‰!¯'K…ÄQöf}aaapqqaÕªUëÒÓÓñÅ_€ˆ°gÏžœ 9[.^¼Èº/òÒµæp89ƒÐbŸy©V­†ŠuëÖ!44ô_ý]°qãF–¤´„P-:tèP|óÍ7°J.ëöíÛ8p Á󆻻;N:eï)p8‡ó¯GT‚TøQ/_¾Þ‹/еkWc ¡å&szRRJ–,iUR)**Š7gÎQûìÚµ ;vìÀåË—s̈ãS!´//^œ½???v]êÔ©c²ê믿A£ÑähŒ‰„%½³jvîß¿DîÕÙÝ ÿôÓO "´k×.'Ã5âüùóèܹ3»ž Ä!CØ{822Òä~C‡aâĉ¢Ž#$„:tèàÈð9ydz £¼`a*YšX¼x1ûœYª2*ºÛ´ic¤µ*Ts»¸¸XtZþ¬_¿žÆ9œÿ!ÒÒÒ°cÇŒ752ºž3úöí‹+VàÚµkŸ¹žæÍ›"ËZÛK–,››–.]Š˜˜«Æ¿~ýºAÑ…PÀ’W~Ã8‡Ãù• mÞ¼9ˆóçÏQ…"è6jÔȪŽ?D777«ƒ 40ØÉ\Íf+oß¾…B¡`II¢ GeS®Ž;vì` Ú'NØt·bÐéthܸ1T*UF–!g!“ÉСC‡<‘,ªÌK–,i²ƒB¸–NNN&«ÔgÏž "BïÞ½?E¸™4mÚ”‹¯¯¯Émccc™A@HHˆ¨ñëÔ©"ÂöíÛ6'qðàA4h`Õ~¾¾¾pvvþ$­â:,Y*—Ëír!¶•?˜/e– À&ÍÉ×4iÒD„õë×ÛCrr²Eíp±•èŸJ&„Ãáäm¥R ‰D‚"EŠÝßåÏŸ-[¶„L&ƒF£Allln‡-šÖ­[ƒÈ¼gµ]uY£W®\qÈø‡Ãáü/’m‚´W¯^F-!U«Ve?ÖÌt FOõë×7jý³­V‹V­Z%J£¢¢lóõë×F‰ÒÆ3íÇ&MšØ­ÉÙ¶m[eid&**ŠÉˆ5©ô܈[¶l±+®OMDD¶nÝŠÉ“'ÃÓÓuêÔAñâÅ-&A3/… FåʕѺukxyy1mX"‚ŸŸ,?--ëSh -°ÿ÷ÿg\’¹D„ºuë²íSRRŒ7bòäÉèØ±£Áû²páÂ9³%t:kù/Uª”ÙŠçŽ;‚ˆ°dÉQãNœ8D„¡C‡:2\NC¨.nÓ¦Uû%%%¡}ûö(\¸p¶׎$s²ÔÃà …Â.ã@k‰ˆˆ`“tJ¥’½~îÜ9–@¸ÿ¾Ñ~¯_¿¶ÛéäÉ“pssÃÑ£GmŽ_ |ùò "œ={Öî±8ο´´4A¥RÁ×××À\UXòåˇFA*•ÂßßÏž=Ëí°Í"h±Ûû{uþüy¹1'''x{{ãÚµkŠ”Ãáp8œÿ],&H=zÄGW¯^ðÿˆË–-} ?²*½ 6ص´Z-«®!Ê0ë‘J¥¬…Ù^¿~ ¹\ÎZŸ3ßÔ®]>>>P(øûï¿ñøñcÑ ã>°k;nÜ8ƒuK—.¡E‹¢ã*N ,˜'Í”ÂÃÃñçŸâ»ï¾C÷îÝѰaC”)S†}e·(PeÊ”AóæÍ1lØ0,Y²gΜaɸ¤¤$ÈårvM+T¨­¼@dd$;Ž—u{Œ „JßÓ§OcÀ€¬ÂRXêׯfÍš™½F™IÃÃÃsG{yôè6oÞÌ*AëÖ­‹%Jˆ®-T¨*Uª„¶mÛbøðáX±b.]ºÄªŸ>}j`d%pùòeÔ¯_ŸãëëkÕC÷¥K—@D(]º´Ã®…%ž?n²’+22óæÍ3™-R¤Z·n ©Tеk×âÒ¥KHLLdïóœÖbƒpãþý÷ß›\çΖØcl–Y“õâŋޗ“G°'A dèñ–/_uêÔùìæÄ’žžÎ&ˆ»wï²ï”7n˜ÜgæÌ™VWdëõzøûûÃÓÓS´ž]JJ T*zöìi¶âøñã ÊÐaæp8[ ƒ¿¿?¤R)ëðʺTªT ¾¾¾P©T rh›X®_¿Î&µ¬ÕÍê» ÔÞ½{7‡¢åp8ç‹ RA/ÔÔ’?~¬^½ZÔ½N§Ã—_~ "Âÿû_‡ŸÝ1˜Á¡X±bËåvUúÄÄÄ@.—£P¡BlÜ’%K¢R¥JfNNN¨S§úõë‡ü{÷îe­BÍš53?88˜]_±•¯›6mbÇÊéVSS• %J”0éFj. ZµjU´mÛÖ 4ó kll¬Á¹'%%áüù󈈈0¨$LMM…B¡`•”¥J•Ÿþiõ9mÙ²DÖ·øÚC‹-@Døý÷ßֱʈ"EŠ 44Ôl¥ÐÚîáá‘Ó!g‹PÕöÕW_™Ý¦fÍš "ìܹSÔ˜={öaÞ¼yŽ ““ÇØ½{7ˆŒ+æE?Èž;w… BÇŽód}N Lì8;;C"‘€(ñØ‚^÷š5kDëÖ-H$(•JÑÜû÷ïG§N°cdzÛèõz >D///Qãr8Ž^¼xF™L†–-[š¼//Q¢ûn ´ªØÃV„ß9k<´Z-“âÊœ5%¡Âáp8Ç1˜MÞ¿ŸÝX”(Q… 2™«T©!&&Æì87oÞd õÜ6+gïÁÐ-+&LQ†6¬Ö¬Y¢ ½Vο“3gΘ¬&ܳg<<<0bÄh4¼{÷Îâ8Û·o‡““lu…ÎçŠ`t$,Z­Öì¶‚þ9 >@¡P _¿~¢µJ###áëë‹Ù³g#11Ñìv:ß~û-ûžp”Y ‡Ãá˜">>Z­r¹:t`ÝV™—¢E‹2ó=­V‹¤¤$‡Ç!H õíÛ7ÛmµZ-3t"ʘòóóˇÃápþ×0› 2dˆîîî2Ú…YãÆ´¾üòK³áíÛ·aòäÉ9s"¥uëÖe1—)S …"ÛoK<{ö 2™Ì ¢´]»v`Û„‡‡cÿþýøé§Ÿ0`ÀfNQ¢D ƒù´´4T¬XѪ »˜˜öw±æú†††býúõ?~<\]]QµjU«’ E‹E5àêêŠ1cÆ`ÕªUfu^¾|i¤íùâÅ ±ÿ§§§#::7oÞd×$$$wïÞ5h«OKKƒR©d×»D‰P«ÕfÏ3-- kÖ¬AÛ¶m±ÿ~ƒu>ĺuëàãã"ÂÂ… E_?{¹pá«5¥{úöí[v½³«øªU«ˆÛ¶mË©pE#LDøûû›\èÐ!öÙS•öôéSöž‹ŒŒtt¸œ<@hh(«.7Ett4üýý1xð`tîÜ …Âà»#3‹-aîܹ9ržaÿþýì{Â’fufÍOK)èܹ3>,êøz½jµnnnÙ„¤§§cäÈ‘ìóüÛo¿‰:‡Ãá8ŠÄÄDB©TB"‘ H‘"F÷¸ùóçGË–-!“É Ñh2ù,•JAD˜>}ºÉõ‚<Ø×_Íâ(X° üüüðèÑ#»Ïáp8G&¤<`mËgΜ 8ýhŸ?@Fkwf7m"BÇŽ ~̯\¹¢ ÝÁÇ‚S²Ljj*üýýQ§NsÙ²e¡P(²u;·ÄÓ§O¥:tÀ‰'Œ¶´ã²&ä<È’~bg°g͚Ŏ÷üùsƒuB%¨T*EÛ¶m­N‚šª½uë€ 9¡b3--µ(enUÒétxðàѬ÷íÛ· *“RRRpæÌ6ž^¯ÇÅ‹qëÖ-ƒ$ZXXsB'"¸ººZ|O8qíÚµƒB¡0h»ÕétP©TpssChh(ªV­ "pééé([¶,ˆGŽ1¹àT]ûüäÉ“ADžd+Z´(Zµj…J•*´ý[ZœQ²dIÔ«W]ºtÁÔ©S±mÛ¶l+õÞ¿ëׯ#55IIIFJJ Þ¾}‹û÷ï#55>|@xx¸AK{zz:®\¹b`–•€Ó§O³k®ÓépîÜ9DDD°môz=T*›éwqqÁªU«Ì¶Ñ>|øƒ ÂðáÃŒ¹BBB ‘H°páB¤¥¥TV}jƒ¡J{Ò¤I&×wéÒDÚª– OJ–,ùI´´,qôèQe^™Kšº¢æÌœ²"˜Ëøøø82TNBèH8vì˜Uû………A¥R¡W¯^èÑ£T*?þíÝy\Íù÷ð×Õª²iR¨,™²ŒID+Y+5–Æ 3̈1KóûÚ†¯1†1Ê6bŒ‰˜d'ƒ)…-•²”­MÚ´×ížß÷óuu«[n sžÇ}˜¹Ÿ÷ç}ߟëºuÏ=ïs½=ikkSLLL=­¸é¸}û6íÚµ«Ú²Û¶m¾ÀT†:t(%&&Ö8¶´´Tø=@EE…¶oß®”50Ƙ²‰ÅbŠ¥€€òòòª´[Nz333#///  ØØØç•Ö_?qâýoWÛ»ï¾+Ì©¡¡A3fÌàÝ2Œ1ÆX#ª ‹‹‚¡gÏž%"¢éÓ§ ?ÀCCCåN”’’B#GŽ”ùBMMMÈVŒŠŠªß+©£ÒÒR  öíÛ ën×®­\¹’Š‹‹ë^‡´{·©©©Üã/×!ÍÌ̬rž²²2jݺ5Õ× lÅÅÅB†hU]¯7mÚTã–à—IkTêèèükðüÛ¸¸¸úùçŸëøàág×eŒ½iîß¿O4cÆ ²°°û»¶¡¡!yzz’ŸŸEGGËÔÖ/++vå%&&RHH™›› çjkk“O•µÛcŒ1Öp*H¥[é¥ÝpŸ>}*d‡רUøÊ•+2߈JÏkêJJJ( @¨ €:tè@~~~¯”¹}û6M˜0¡R'ÍWkŒnÞ¼™‰‰‰Â F¤†UÝ´´´ÈÚÚš¦M›FëÖ­£þù§Îµ”***èÑ£GB–å½{÷èÉ“'TQQA±±±”••ED/‚ÑÑÑ2ÙƒÒÆKÒ@…D"¡K—.ÑÝ»w…k½uë9s†ÊÊÊ„ó~ûí7¡„ƒ††ýøãUf%9r„lll(00Pæù+--¥ 6P¿~ýhÏž=•Îûúë¯ M˜0¡NÏËëÈÊÊèñññ•Žçää—òºÝ¿lüøñ€|||êk¹ “~Q²xñb¹Ç=z$dš+²…¬¼¼¼É€YýX´h ¥ÌWQQAëׯ'‘HTe†v]”––RXXÍ›7lmméþýûJ›»>Ik¾NmÖ‹/Ò Aƒ„²;5)**¢aÆ [F÷íÛWçÇfŒ±¦"55•BBBÈÇLJ¬¬¬*ý~¼(•5dÈZ¹r%ýùçŸÂ®­—û èèèÜæ¡Œ1Æk2ÒØØXáý¹sçˆèÛ[(œý!‘Hè÷ß²G¿üòK导žŸŸ×ݱcG 2ë"..ŽìììijjVÚÆ/mdõý÷ß+4_EE…©7`À #???òòò"+++™Z¨ò¾é2dùøøP`` EGGW.**¢ëׯS~~>‰ÅbЉ‰¡‚‚*(( ÄÄDáZ¢££)99YæÜ‡ Y¦D/:$ÇÆÆ ™¤ÅÅÅ#“!™žžNÂz{ôèA×®]“»¶„„rqq!™²EEE@ýúõ#ÿ*³{õêEè·ß~«þ ¯'¶¶¶€V¯^-÷¸´Ö!Cª'((ˆP§Nêa•µãïïOÈÚÚºÊ1={ö$Õ6Øz™4óúMz/aŠ“f ·hÑBæK’×åããC"‘¨Ö[÷_öìÙ3úí·ßh̘1Ô¢E á=ÜÅÅ…222äžS^^N111^òBJú¥Åúõëk}®X,¦… Ò¤I“nhXXXHC† ‚£¬õã2ÆØ› 33“~üx¥ãeeeKäëëKnnn2Ù±¯ÞÔÔÔÈ‚<==iÉ’%täÈa»Oaa¡•™œœLÅÅÅTQQAqqqÂý 2 VÊËË)>>^¦–è“'OèÞ½{Â/…)))ôàÁ™†M!!!Ô¶m[^tõõõ•ûúÉÍÍ¥¹sç’›››P/--¶mÛFóçÏ'òóó«v{mFF†Ä5°ÛP¤]·œœä—f`éêêV;ONNŽéýjy†vçÎ![¢ªÒwß}GÈÝÝ]¡9ÿøã@æææÊ\*k"JKKIGG‡€ÿ•vQ†¢¢"277§.]ºÔj'@ii)íÚµ‹\\\„WFFF4}út:tèT{~II ýòË/äììLóæÍ£„„„×½”×bccC(((¨Vçeee‘»»{­¤eQ444*•MaŒ±·Y~~>}º®ËeŒ1ÆcŒ±"¢˜˜!;ëÒ¥KDDäçç'f-Z¤ð„ååådjjJèǬŸU7¢gϞђ%K„­ÙÒ™!!!ÕfIk]®Y³Fæ~ií=MMM¹„ò¬Y³FxlyÍ}«ÿ9± IDAT”%''§R¶©´îiUu•lmmiÆŒäççGÕÖóòòhÆŒÂù:uªòCuHHõïߟN:%sÿ¦M›H$‘ƒƒƒÐ@JÅÅÅB=AE›ŽÔ—Ï>ûŒÐG}$÷5$ $ÖT‡ôþýûBùå€tc %Ô¶mÛ*¿@øøã Í™3G¡9—,YBhøðáÊ\*k"ÊËË…@Þ¶mÛ”:wBB©¨¨¯¯o¥cÏž=#'''@¤èèèJc’’’ÈÏÏ\]]i̘1´mÛ¶3º«’——GkÖ¬!GGGò÷÷o/¥eK._¾\í8±XLß|ó Í™3§V%u222„Ÿq­ZµªUÖ)cŒ1ÆcŒ5 "¡!Ž››½ÈøÓ××jæ<{öLá …IŠüÞDÒ†KÒmó¨gÏžr¥—/_2/_ÍÈùôÓO…à˜¢¤Û—ŒŒ”r-µQ^^NqqqLÿ÷ÿG®®®B¤¼›ŠŠ uïÞ>üðCZ¾|99r„’““éÔ©SÔ©S'aÜ´iÓdš,I¥¤¤ÐرcÉÇǧR°ÕÏÏD"¹¹¹Õª¾ ÑÎ;…^CfrÉsøðaáy077§õë×Ë<Ò:¤zzz5ÎÕ£Go~T_ …Ò Ue¤¥LMMšSúïHCCC¦|{{HËtíÚµV%L1vìXÒÕÕ•yí$%%‘¹¹9ijjÒÖ­[ÚFŸ••EäááAãÆ£Ô©ÎvYYÑ AƒhùòåõúóRºóáúõëUŽÉÎÎ&úý÷ßk5wzzºð¾£««+|ÉÊcŒ1Æco\»vMȆ”2¶mÛ&l¾øâ …'“H$diiIháÂ…õµæ&Á××—§§'ùúúÊÔñìß¿¿LcŠY³fòð𙣨¨H¨mzìØ1…755UøûZ¼x±R¯éudggÓ™3ghýúõ4}útêׯikkW8•Þ «¼ö­[·’]½zµÒ±ýû÷“H$¢1cÆÔ*8ñèÑ#š0a‚P“oúôéu¾fe)//§Y³f ÑPË–-iΜ9”˜˜H[¶lî¯*ˆ"‹)>>žFEÈÕÕµ¯¢²¡C‡Zºt©ÜãYYYB·WE2¡+**„Fc‡VörY““#¼'îܹS©sGFFð¿Nî©©©dddDmÚ´©²ÞqM²²²( €ÜÜÜÈÛÛ›ÂÂÂj]«T"‘Б#GhèСäãã#ÓìNY¤ï-qqqrß¹s‡\ëÌÏÔÔT²°°JêܸqCËeŒ1ÆcŒ±‡¾}û ™¢Ýºu#sss¡ã¢ŠŠ =zôHáÉöïß/Ô«Ívç7Ѿ}û„Œ?¢7ÒÐЂY  }ûö‘®®. C‡ÉÌ!md`` p£´¶£H$’ –%$$иqãhñâÅ´gϺuëV­¶HÖ‡ŠŠ ºsçíÝ»—/^L|ðLmSkkk¹ÛTóòòhâĉäãã#7øùôéSjݺ5õïß_áÌÑÂÂBZ¹r%999ÑÉ“'…àmxxøk_§²<{öŒV®\)“Y+‰ÈÖÖVøÿM›6Qnn.;wNF÷íÛW&¸*}M5¶_~ùEøwPéµ­^½Z¡9§L™Bè³Ï>SÖ2YóŸÿü‡™™Y áj«_¿~dnnN‰„œœœH[[[iA½[·nÑ·ß~KNNN´téRJNN®õ4vìXòööVj32鉉‰•Žýõ×_4hÐ zøða­æ|øð¡°›ÁÀÀ€nݺ¥¬å2ÆcŒ1ÆXƒÃ˵4åÝ&Nœ¨pƒ&+++@óæÍ«çe7¾‡ ¬ììláþ¤¤$š:uªðTzÓ×ׯ°1b ¯¾úJáÇÕÓÓ#Ô»wïJǤêÈÇLJFŒA$777òõõ¥ÀÀ@ŠŽŽV¨kx}êÚµ+ £GV:véÒ%²±±©6£vîܹ¤¦¦F·oß®ñ±$ …„„Ѐ( €***„ iccc¥oãU±XLû÷ïºÒ¿|{9SùÕ›ªª*õèу&NœH¡¡¡}/|ÑRU™Ž+VrrrRhÎáï®®]ÅYÓ–••%”xY°`RçÞ´i“0/Ú¼y³Rç'zñÅPXX}üñÇ4vìX:yòd­_«QQQ4nÜ8š:u*Ý»wïµÖ#‘H„÷ˆWƒ¶;vì )S¦ÔúgBrr²PkÜÐаÊÌTÆcŒ1Æ{Sˆ–.]J«V­Baa!@$¡U«VÈÍÍ…”––V¯^Ù³g£*'OžÄˆ# ®®Žû÷ïÃØØ¸Ê±o‹öíÛ#-- ÿý7†*sìÞ½{X¶l‚‚‚@D˜4ivîÜ)ÏÈÈ€±±1Äb1nܸ޽{×øx×®]ƒ••`çΘ4i’BëÌÉÉA\\âãã‡;wî //mÚ´¥¥%,,,`ii‰=z@CC£Ï@Ý´hÑ2×MDX·nNœ8???4kÖ šššÐÑÑŽŽÔÔÔåååxçw0|øpìÞ½»Úǹ|ù2þóŸÿ oß¾X°`Z´hpttĹsç°`Á,_¾¼~/ö5ݺu 6lÀü²²2á~]]]¼÷Þ{èÕ«z÷îÞ½{ÃÒÒ²Aþþj£sçÎHJJŸþ‰>ú¨Òñ˜˜ôîݪªªÈÌÌDëÖ­«ïùóçhÛ¶-ÊËËqóæMôêÕ«¾–ÎÑŽ;0yòd¨««cýúõ°··G÷îÝ!‰^kÞ´´4ƒˆ`nnޏ¸84kÖLI«®,==8yò$†ŽéÓ§COOOáóccc‘––VéçKm”•• ï ?–ùÙ\XXmmíZÍ—˜˜ggg¤¤¤ cÇŽ8}ú4:wî\çõ1ÆcŒ1ÆX“@ô"óÐÇLJTTT„ÆCŸ|ò ÙÛÛËd¨STT”ÜH«ƒƒC“©éØP¤õW¬X!÷øãÇ…çôæÍ›2ÇV¯^M¨Gµ~úè#š4i=~üXæØ?ü@"‘ˆD"ݹsGi×Uß222hîܹRë­°iæÌ™€&Ož\åiI={ö(4§´ãø?þ¨¤U²¦F"‘TÊ ÖÕÕ¥‘#GÒÒ¥KéäÉ“”››[§¹¥e~ùå%¯ºjeee"Ô*}õçA}ª¨¨žÃ¤¤¤×š+>>žÚ·oOÈÄÄäµçcŒ1ÆcŒ±¦BDD$ –Þ¸qsæÌAdd$ÀÈÈ^^^صk?~,UpèÐ!èêꢢ¢0`À¨¨¨àöíÛèÚµk½s›šE‹aùòå˜8q"‚‚‚*_¾|9-Z„¾}ûâÊ•+2Çz÷¬Y³óçϯñ±$ ´µµQRR‚‘#G⯿þRÚu¼êՌӻw¨íÚµ²M-,,н{w¨¨¨ÔjniÆ –– qõêU|ñÅX·n¬­­ ¸zõ* ‘ŸŸ²²2¤¤¤àöíÛˆGvv6bcc+½ÎÄb1Ö®]‹ÐÐP¬Zµ ýû÷ŽUTT`Μ9øõ×_sçÎ…ŸŸßk>S¬&‡Æ|€wÞy©©©r3gÍš…Í›7ÃÛÛ5ιzõj|ûí·°³³CDDD},›5OŸ>Å?ü€sçÎ!66b±Xæx³fÍðî»ïbÀ€0`lllн{÷3B×®]‹¯¾ú ‰‰‰ò³êÆظq#ÒÒÒðùçŸcĈ¯[uuu”——#!!æææušãÆ6l233annŽS§NÁÈÈHÉ+eŒ1ÆcŒ±FòjÄTZ³±C‡BÖ‰““}õÕW2`TUUiþüùDD4räH@&Lhàønã’6Yzÿý÷+“H$Ô¥K@7n”9víÚ5á9LKKS豤µÔºÓ°²UúúcŒ1Æc¬±U¹±eË–X³f nܸggg”——cýúõ8}ú´Ì¸œœ\\\гgÏ:æ±¾™¤Û9‹ŠŠðèÑ#™cÛ·oŒ=mÚ´î‹Åx{{+ô8ÅÅŸqãÀÓÓSKo4Ož<tèСұ   |ñÅ ª±Yüõ×_}ºr.„)lĈ€'NÈ=Þ¼ys8::Ž;¦Ðœ...µÏÞ>íÛ·‡§§'üýý‰ììlDDDÀÏÏžžž000$%%açΘ7oúöí‹Ö­[ÃÎÎß}÷Ž=ŠgÏž5êuhhhÀÛÛ§OŸ†••>üðCÌ;)))J{ uuuiô¦ˆˆˆ <ÙÙÙxÿý÷}}}¥­‹1ÆcŒ1ÆšŠÛ÷ZXX <<!!!055î×ÒÒBË–-¡¦¦UUU|ÿý÷õ¹Î&©yóæBPîöíÛÂý………Ø¿?`êÔ©2çœ8qéééhÙ²%ÜÝÝzœ_~ù€… *céFZËöåNÊ¥¥¥˜;w."""&ó:“'##S¦LÁž={pìØ1¹æ[·nÁÞÞ 000ÀÙ³g… kX#GŽ\¼xÙÙÙrǸºº¨}€ôĉ¿ ö殮¥;;;Ì;!!!HOOGJJ Ž9___ØÚÚBCCùùù8þ<~úé'¸»»C__;w†··7üýýqõêUH$’_³fÍ0jÔ(üý÷ßpwwÇÖ­[•6w]¤Ò÷Ìüü|ôíÛaaa2_ö1ÆcŒ1ÆØÛDUÑžžžo|öb}°°°@rr2„@PHHòóóadd„!C†ÈŒß±c`üøñhÞ¼¹B!ý lff&X|½šAúèÑ#x{{còäÉ•‚Éò" «V­‚Ü1§OŸÆèÑ£ñüùs˜™™áĉÿšÆaMQ=бcG2jÔ(|ñŸ~ý:RRRjlþ2xð`hiiáÙ³g¸rå lllêkùì Ö¾}{´oߣFáêÕ«¸xñ".^¼ˆ¨¨(¤§§#))IÈ4^ì èß¿? €þýûÃÆÆzzz ¶nggg8;;+m>MMM/v#(âĉ3f Š‹‹agg‡¿þú -Z´PÚzcŒ1Æc¬©©1ƒ”UÏÌÌ À‹íÜRÒíõ“'O–éòž——‡ÐÐPŠo¯OIIÁǼèö]Ì›7¯R·ç¦äå ÒÐÐPŒ?6l¨18š‘‘±cÇâÂ… ¯28„‘#Gâùóçèׯ.^¼ÈÁÑ&`øðáªÞfß±cGXZZ‚ˆpüøñçkÞ¼9œœœ¼(µÀ˜"´´´`ooo¿ýDZZšÜ,ÓçÏŸ#,, Ë–-ƒ««+Ú´i#“e‰òòòƾ…I¿Œ+))©qì±cÇ0zôhÃÑÑÇçà(cŒ1Æcì­ÇÒ×ôr&$$''#22àåå%3688ÅÅÅ011­­­Bó/^¼ ¢¢‚9sæT;ÖÖÖþþþpwwGiii­®£¡Hëê%%%!88aaaèÑ£GµçìÝ»îîî˜;w. ¥¥%wœ¿¿?&OžŒ²²2 6 áááh×®Ò¯Õž4»úðáÃÈÏÏ—;¦¶Ûì¥ÿ†~ÿýw…3ã{•4ÃtåÊ•ˆŒŒD~~>¢££áçç///˜˜˜­ejoo===aKÿÞ½{‘™™Ù¸R i€´¨¨¨ÚqûöíÃèÑ£QRR‚#FàøñãÐÑÑiˆ%2ÆcŒ1ÆX£Rx‹=“¯cÇŽþ ݶmˆvvvèÞ½»ÌXéöÍÉ“'C$)4ÿÖÖÖÐÐШvì?þˆN:aöìÙøøã±ÿ~…§!dgg£°°0qâľ™™™øüóÏ¡««‹Ó§OC[[[î¸ŠŠ Ì;7nð¢îë–-[ ªÊ/廉OŸ>€¬¬,´jÕ ï¼óìííññÇcðàÁhÙ²%\]]±jÕ*„……¡´´´ÒëýáÇ8tè<ˆëׯãùóç^ÝýýýñÝwß5øu±·šš¬¬¬`ee%Ü—ššŠ«W¯âüù󈌌ÄÕ«WQPP€óçÏãüùóX·nÀÐÐvvv°µµ…••úõë'ÔÿlLÒiu_$ÃËË b±®®®Ø·oŸ°5Ÿ1ÆcŒ1ÆÞvAzMÒ ÒÇC"‘AÐW·Œß»w.\€H$ª”YZ•¨¨(äææ€ÂÁŸ™3g¢¨¨_}õüýý1oÞÄb1ž?ŽŠŠ  ¼¼ÅÅÅ())Aii)ŠŠŠÐºukUÚ"ýrƒ&yNŸ>ÿüç?Xºt©ÐÔ§*)))pqqALL ´µµ±gÏ¡†%kšlmm]]]œ={¸v킃ƒqìØ1ܽ{‰d‚£-[¶„µµ5Æ ÇÊËËÑ¢E äçç#** ööö ~]Œ•³LKKKqõêUDEEáâÅ‹ˆŠŠÂ“'O*e™êèè oß¾8p lll`cc£ô/µªjÒ´yófÌž=D„ & 00ƒ£Œ1ÆcŒ±%þ$ôšTTT §§‡ÌÌL„……¨¼½>""IIIÐÔÔ„§§§BóîØ±Ch´$mÔT–––èׯ8 7@š••…¨¨(\ºt ±±±xøð!>|ˆ¬¬,…æWSSƒŽŽTTTвeK4kÖ ­Zµ´nÝZî9Ož<ð¿²R¥¥¥X²d ’’’pìØ1´iÓ¦ÚÇŽÅÈ‘#ñäÉ´iÓGŽÁÀZ7k}:6oÞŒf͸o#cŒ1Æcì߉¤J ¯¯ÌÌL”––ÂÔÔ2ÇwìØððð¨2xøª_~ù```€^½zÕi]ð÷÷‡X,†ªª*?~Œ;v`÷î݈ð"ÀÛµkW˜˜˜ÀÚÚ;vÄ;ï¼]]]áÖ¢E ¨««C[[[ø³.¤Ò—3Hãââ0{ölLœ8Q¡Ú¡ÿüóF¼¼<˜™™áøñãèÖ­[ÖÖ TUUñìÙ3$&&Vjb¦¥¥8;;ãĉhÛ¶mµÁQ)ggg„††âÔ©SXºti}-Ÿ±×öj–©X,Fbb¢Ì¶üøøøk™:88ÀÀÀ@áÇ•H¥™Ù?ýô“P³wæÌ™Ø´iS“jèÇcŒ1Æc ¤JðòvÈO>ùDæƒfII öïß@ñíõEEEˆð¢Û{^^"##ѳgOtìØQáu™˜˜ ¬¬ aaaX¿~=Nž< "‚½½=V¬X oß¾ÕÖùT¦—·ØÖ­[‡C‡aÛ¶mèÒ¥Kçïß¿“&MBII ¬­­ŠvíÚÕ÷²™’èèè wïÞBS›W¤R8qℵz‡ ¸též?Ž–-[*mÍŒÕ'UUUXZZÂÒÒ3f̤¥¥!::Z&Ë´°°PøïuëÖ¨œejmm]©¬É˼È~ÿý÷ _ý5V¯^ÝWÊcŒ1ÆcMH•àå>W¹¹¹Xµjôôô ©©‰ . 77úúú6l˜Bó­X±‰"‘‹-!..»ví£G ££ƒaÆaôèÑÕfØIëι¸¸ M›6X°`&OžŒÎ;¿Þב4ƒTSS#FŒÀàÁƒ•Ïõ÷÷Çüùó!‘H0tèPìß¿_¦Î+{3ØÙÙ ÒiÓ¦É#ÍÀŽŒŒ²Ÿ«cii CCC¤¥¥áìÙ³Bvco"CCCŒ5ªÖY¦jjjèÕ«—0uttD§N@x={ö,.]ºðõõU(kŸ1ÆcŒ1Æþ ¸‹½àéÓ§ÕŽQUUÅ©S§*m¿—ÇØØ)))x÷Ýw…­ð/{þü9Ž;†ƒ"-- ˜:uj¥ÚÛ¶môiÓàíí ???èêêÖî”L[[EEEX¸p!ÆŽ‹÷Þ{¯Æsˆ¾¾¾B–ÓäÉ“±uëVîVþ†Ú»w/>üðCtîÜ÷îÝ“;¦¬¬ ººº(**ÂåË—amm]ã¼^^^ ‚üýý•½lÆš”ÔÔTDEEáÂ… ˆŠŠÂµk×P\\\iœ©©) €¤¤$DEE ÷sp”1ÆcŒ1Ædq€ô5eggÃÐÐeeePQQš\TTT€ˆd²KE"|}}ñã?V9_rr2ÌÌÌ›6m¬Y³ª}ü’’ìݻ۷o‡±±1fÏž @qq1._¾ GGÇ×½Ì×–••…¶mÛxñœ)¬---Å”)S ÂsǵòÞ\éééBú””´oß^î¸ÁƒãŸþÁÏ?ÿŒ¯¾úªÆy1eÊXXX ..N©kf¬©+//Çõë×%N>|(wìªU«„æLŒ1ÆcŒ1Æ^àékúᇰpáBtíÚ 2]€g̘­[·¢OŸ>HLLDQQÀÂÂÐÓÓ«4ßĉ±{÷n¨ªª¢¤¤D¡íçR7oÞĆ ””Œ5ªV]‰ûí7\¹rÍ›7‡¦¦&Zµj ÀÈÈ066®ÓÖö7n OŸ>ÐÖÖFAAAãsssñÁàìÙ³PQQÁ† 0sæÌZ?.kzºté‚û÷ï#$$žžžrÇHë$zxxàСC5Ιšš ###/jݾÜŒ±£´´4DEEáâÅ‹8~ü8âããñÉ'Ÿ`ëÖ­½4ÆcŒ1Ækr8@ú¤]ëÓÒÒð믿Êðž>}ŠN:¡¤¤Ç‡ ììì„ì6--->|Xh0#Õ²eKäççÃÉÉ §OŸ†»»;444`bbSSSáOSSS¡Æè«ÒÓÓ±nÝ:œ={ÿý·Â]çsssñìÙ3äå塸¸%%%ÈËËÃÓ§O‘žžŽÔÔT¤§zß  ”IDAT§#77"‘èÒ¥ ºvíŠnݺ¡GhݺµÜ¹CCC1jÔ(˜››#!!¡Úu¤¦¦ÂÅÅ7oÞ„––‚ƒƒ¹®ä[dêÔ©øã?0wî\øùùÉsúôi8;;COO™™™ ú-,,pûöm*Ü1ÆcŒ1ÆcŒ›4½†]»v!-- zzzðòò’9æïï’’ôìÙLJH$Bll,¾üòKøùù¡¨¨Æ ÃÌ™3±aÃ4kÖ gΜA~~>`áÂ…‰D8zô(rrr””„¤¤$ÄÆÆâï¿ÿFZZrrrPVV˜™™ÁÌÌ †††hß¾=.\ˆ¥K—ÖªVgëÖ­« pÊ“‘‘;wîàîÝ» ÅŠ+ðüùsèéé¡gÏžpuuÅÀü¯ƒ}‡ª3..#GŽÄãÇ¡§§‡#GŽÀÖÖVá5±¦ÏÖÖüñ"##«3`À¨««#;;qqqèÙ³gó2·oßFxx8HcŒ1ÆcŒ1¦0Ö Í`æÌ™#“¥YXXˆ€€À7ß|#S3síÚµprrÂøñãQZZŠ_ýgϞũS§ðý÷ßx‘Eêìì,œ£«« +++XYYUZ‡D"Ajj*sæ FÜÜ\˜ššâøñã077WþÂY£²³³ð¢ìB~~¾Ü’ Í›7Gß¾}qáœ={Váéúõë"âZµŒ1ÆcŒ1ÆSHëèĉˆ‰‰††F¥Ú˜[¶lAVVŒ1~üøJçzxxàÞ½{°··ÇƒÎ;£´´àîî®ð:òóóall ccc!ðÔØôôôàää$sŸ4@ZUé0qâD””” W¯^øë¯¿„š’ìíbnnŽvíÚáéÓ§ˆŠŠÂСCåŽsppÀ… /¾ø¢Æy 555¤§§#>>–––Ê^:cŒ1ÆcŒ1ÆÞB ­£_~ùàííwÞyG¸_, ™¥_~ù%ÔÕÕåžollŒÄÄDLœ8ûöí8ÀÇ1kÖ,¢C‡ŸíÛ·—éþžŸŸ©S§";;D„ŠŠ hkk£]»vÐ××G‡`bb"Üé__¤[ìåe®]»_ý5$ †Ž}ûöAGG§¡—ȈH$ÂÀqèÐ!œ?¾ÚéÊ•+qîÜ9…æmÑ¢¬­­qᄇ‡s€”1ÆcŒ1Æc áiܸqááá‰DøòË/eŽãáÇhÙ²%>ýôÓjçQWWÇÞ½{±eËÌœ9Ò~Yˆˆˆ{NóæÍe‚¦]»v¡¦¦¦xçwPTT„ŒŒ ºwïKKK¼ûî»èÞ½;´´´”ðÌTM^©D"Á7ß|#›'OžŒ­[·Öªn*{3ÙÚÚâСCÕÖ!µµµ…ŠŠ ÒÓÓqçÎtëÖ­Æy‡ "HçΫÌ%3ÆcŒ1Æcì-Å]ìëÀÛÛ;wî„››Ž=*sìý÷ßÇõë×ñÿ÷X±b…BóåççÃÀÀÅÅÅøì³Ïн{w> ŸÅÅÅhÑ¢z÷î÷ßï¿ÿ>ÌÌÌjýÜTE[[EEEˆ‰‰AÏž=QZZŠ)S¦ 88°`Áü÷¿ÿ庑ÿQQQ0`´µµ‘›› UUùßÕôíÛW¯^ÅÖ­[1mÚ´爈€ƒƒZ´h¬¬,¶3ÆcŒ1Æc¬F ­¥””˜™™¡¬¬ gΜ£££pìäÉ“1b444œœ CCC…æÜºu+f̘ccc©28 ¼lêëë£W¯^UŽÉÉÉARR’Ì-55iiiHHH@aa!233‘™™‰+W®T:_SSfff°´´„ŒŒŒ ‘H••UçÎàÒíõÚÚÚ(..†‹‹ nܸ ìܹžžžµž“½ÙÔÕÕѯ_?œ9s ,ÀÔ©SáììŒvíÚÉŒ³··ÇÚµkqæÌ™JsààÁƒØ½{7ÂÂÂPQQàESggç:ôcŒ1ÆcŒ1ö蘆ŸŸŽ;"77þù'>úè#áØÍ›7ѧO@ll,,,,š3!!ï¾û.D"îÞ½‹Î;×ËÚ5?ÓÒÒœœŒäädÜ»wOæ–]íù:::èÒ¥‹Ü[uç= www˜ššB,ãñãÇhÓ¦ Ž9‚*û2Ùâ§Ÿ~Âwß}'ü¿H$BïÞ½1lØ0 2ööö(**‚¾¾>$ }Š]»va„ õ|u———W)ãôîÝ»¸wï222ª=WUUb±ЧO;v¬V%Ø¿CRR†ӧO#''Gî¸Ö­[c̘1˜4iѬY³^)cŒ1ÆcŒ1ÆÞ& U4Ó³:***رc‡Â΃b̘1ÐÕÕEJJ š7o®Œ¥6¸üüüJÁSé-55U×­[7DGG£E‹¸Zö&¨¨¨@tt4°ÿ~ܼy½zõ¢E‹àêê MMÍÆ^"cŒ1ÆcŒ1ÆÞ UÐÆñÅ_ÈÜ'‰ ‰Ð¬Y3!Czõê…ÐÐPtèСÚ9G…ÐÐPÌž=7n¬—u7¶ÂÂBÄÇÇ#""³gÏæÀcŒ1ÆcŒ1ÆkR8@Z )))øñDZyófTTT@MM ³fͲeËOOOa»y³fÍðé§Ÿ" @nç÷ÔÔTtêÔ b±ÑÑѰ²²jèËaŒ1ÆcŒ1Æcì_‹÷Õ‚‘‘6lØ€+W®ÀÁÁåååX·n:wîŒk×®!%%Ë—/‡ªª*$ ¶nÝ ===9r¤Ò\üñÄb1zõêÅÁQÆcŒ1ÆcŒ1Æ Hë OŸ>8{ö,Ž9SSSdeeaÞ¼y°¶¶†½½=ÒÒÒàèèÈÍÍ…‡‡Þ{ï=™fF;wîL›6­Q®1ÆcŒ1ÆcŒ1Æ[ì_[qq1Ö­[‡~øùùù777¬[·qqqðòòBnn.€MœæÎ www899A]])))hÛ¶mc^cŒ1ÆcŒ1ÆcÿZ U’ÇÃ××ÁÁÁ "4oÞß|ó &Nœ___>|Ò§Z]]eee?~<‚ƒƒyåŒ1ÆcŒ1ÆcŒý{q€TÉΟ?yóæ!::ºÆ±¡¡¡puum€U1ÆcŒ1ÆcŒ1Æäái=H$ Ä¢E‹’’‰Dhݺ5Äb1Š‹‹ÑªU+¤§§CUUµ‘WËcŒ1ÆcŒ1ÆØ¿×ÿ:øËôf†ÂIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex000066400000000000000000000077331456262201400266240ustar00rootroot00000000000000\documentclass[10pt,a4paper]{article} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{lmodern} \usepackage{float} \usepackage{graphicx} \usepackage{wrapfig} \date{} \title{Welcome to Paperwork !} \setlength{\parskip}{\baselineskip}% \begin{document} \maketitle \begin{figure}[h] \includegraphics[width=\linewidth]{data/intro.png} \end{figure} They are going to drive you crazy. Your phone operator, your bank, your daughter's school, your dog's veterinarian, even your ISP; it seems like all of them are trying to drown you under tons of papers. Papers you have to read, classify, and memorize just in case you may need them later. Most of the time you won't, which means you waste your energy for nothing. Paperwork will help you get rid of all those papers by turning them into searchable documents. It's simple: just scan and forget. Looking for a specific paper? Just type in a few keywords and tada \pagebreak \section{Documents and pages} \begin{figure}[h] \includegraphics[width=\linewidth]{out/main_window_split.png} \end{figure} Paperwork's interface is composed of two panels. On the left (green) is the list of all your documents sorted by the date they were imported. On the right (blue) are the pages of the currently selected paper. You can add papers from several sources, depending on the devices connected to your computer: scanner flatbed, scanner feeder, camera, etc. You have no scanner at home? You can still use the scanner you have at work. Paperwork will easily import PDF and image files. \section{Find} \begin{wrapfigure}{r}{0.5\textwidth} \centering \vspace{-20pt} \includegraphics[scale=0.5]{out/search.png} \end{wrapfigure} Find what you need, when you need it. Type a few keywords in the search bar and the list of papers will shrink to only the relevant content. This is where the magic happens: Paperwork uses optical character recognition (OCR) to convert your papers into simple text files, so it's easy to search for text. \section{Export} \begin{figure}[h] \centering \includegraphics[scale=0.5]{out/page_actions.png} \includegraphics[scale=0.5]{out/doc_properties_button.png} \end{figure} Sometimes you may want to export a document to send it to someone else. Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper (requires a printer, sold separately). \section{Labels and additional keywords} \begin{figure}[h] \centering \includegraphics[scale=0.3]{out/doc_labels.png} \includegraphics[scale=0.3]{out/doc_extra_text.png} \end{figure} You answered an important email and you want to keep track of it? The paper you scanned was so unreadable that Paperwork failed to recognize some important keywords? Add keywords to your paper so you won't miss anything! All the keywords you add will be searchable, as if they were directly written on the paper you scanned. You would like to organize your documents a bit more? You can also add labels to your documents. Each label has its own color. With time, Paperwork will learn which labels go on which documents and will automatically apply them on new documents. \section{Your first documents} \begin{figure}[h] \centering \includegraphics[scale=0.5]{out/doc_new_button.png} \includegraphics[scale=0.5]{out/page_add.png} \end{figure} Click the + button, the scan button, and that's all folks! You are now aware of the main features of Paperwork. You can start using it by adding your first own paper. This document will automatically disappear from your document list as soon as you have created or imported your first document. \section{Need more help ?} \begin{figure}[H] \centering \includegraphics[width=\linewidth]{out/app_menu_opened.png} \end{figure} If you need more help, there is a comprehensive manual you can find in the help section of Paperwork. We hope that you'll enjoy this piece of software. If you like it please tell us, and if you don't please tell us why! \begin{figure}[b] \includegraphics[width=\linewidth]{out/paperwork_going_up.png} \end{figure} \end{document} paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/000077500000000000000000000000001456262201400255075ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/ca.po000066400000000000000000002546721456262201400264520ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: 2022-05-08 09:41+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" "\\date{}\n" "\\usepackage[catalan]{babel}" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "Benvinguts al Paperwork!" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" "Ens faran embogir! L'operador de telèfon, el banc, l'escola dels fills, el " "veterinari del gos, inclús el teu proveïdor d'Internet; sembla que tots ells " "vulguin que quedem enterrats sota una pila de paperassa. Paperassa que s'ha " "de llegir, classificar, i memoritzar per si després fes falta. Però la " "majoria de vegades no passa, així que estem gastant temps i energia per res." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" "El Paperwork pot ajudar convertint tota aquesta paperassa en documents " "cercables. És senzill: només caldrà escanejar i oblidar. I si necessiteu un " "document en conret? Aleshores tecleges unes poques paraules claus i zac" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "Documents i pàgines" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" "La interfície de Paperwork està organitzada en dos panells. A l'esquerra " "(verd)hi ha la llista de tots els documents ordenats per la data " "d'importació. A la dreta (blau) hi ha les pàgines del document seleccionat." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" "Es poden afegir documents amb orígens diversos, depenent dels dispositius " "connectats a l'ordinador: escàner pla, escàner amb safata de documents, " "càmera, etc. No tens un escàner? Pots fer servir el de la feina. Paperwork " "pot importar sense cap problema PDFs i fitxers d'imatge." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "Busca" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "{r}{0.5\\textwidth}" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" "Troba el que necessites, quan ho necessites. Tecleja unes poques paraules a " "la barra de cerca i la llista de documents es reduirà al contingut " "relacionat. Aquí és on rau la màgia: El Paperwork va servir el reconeixement " "òptic de caràcters (ORC, Optical Character Recognition) per convertir la " "paperassa en documents de text on és més fàcil fer cerques." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "Exporta" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" "A vegades busquem un document per enviar-lo a algú. S'accepten diferents " "formats: ,pdf, .jpg, .txt. etc. I per suposat, paper (es necessita una " "impressora, no inclosa)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "Etiquetes i paraules clau adicionals" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" "Heu respost a un correu electrònic important i voleu fer-ne seguiment? El " "document que heu escanejat era illegible i el Paperwork no ha reconegut " "paraules clau importants? Afegiu paraules clau als vostres documents i així " "no perdreu res! Totes les paraules clau que afegiu apareixeran a les " "cerques, com si estiguessin escrites al paper que heu escanejat." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" "Voleu organitzar encara més els vostres documents? Podeu afegir-hi " "etiquetes. Cada etiqueta té el seu propi color. Amb el temps, el Paperwork " "aprendrà quines etiquetes van amb quins documents i les aplicarà " "automàticament." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "El teu primer document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" "Cliqueu el botó +, el botó d'escanejar i ja està! Ja coneixeu els elements " "bàsics del Paperwork. Podeu començar a utilitzar-lo afegint el vostre primer " "document." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" "Aquest document s'eliminarà de la llista de documents tan bon punt hagis " "creat o importat un document." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "Necessites més ajuda?" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" "Si necessiteu més ajuda, hi ha un manual més detallat que podeu trobar a la " "secció d'ajuda del Paperwork." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" "Esperem que us agradi aquest programa. Si us agrada, digueu-nos-ho i si no " "us agrada, digueu-nos perquè!" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "Manual del Paperwork" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "Introducció" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" "La majoria de documents personals són ben ordinaris i recurrents: nòmines, " "lloguers, factures de la llum, etc. Per a molta gent poc organitzada, haver-" "los de trobar passat un temps és, com a mínim una molèstia. Per la gent " "organitzada, posar nom i ordenar els documents és tan avorrit com mirar com " "s'asseca la pintura." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" "L'idea darrere del Paperwork és que la gestió de paperassa és una feina " "perfecta per a ordinadors. Els humans hauríem de fer el mínim indispensable " "i deixar que les màquines facin tota la resta. Al capdavall, el que volem és " "«escanejar i oblidar»." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" "Si busqueu un programa que permeti posar nom i etiquetar cada document o " "corregir petits problemes amb l'OCR i generar jerarquies complexes, etc, " "aleshores el Paperwork no és el que busqueu." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "Definicions" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "Carpeta de treball" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" "Paperwork guarda tots els vostres documents en una carpeta: la vostra " "carpeta de treball. En aquesta carpeta, cada document apareix com una " "subcarpeta." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" "Això fa que el Paperwork sigui difícil d'utilitzar amb altres programes, " "però té un avantatge molt important: No us haureu de preocupar mai més pels " "noms dels fitxers ni per l'estructura de les carpetes." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "Document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" "Al Paperwork, un document és un conjunt de pàgines. Al disc dur, pot ser un " "conjunt de fitxers JPEG o PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" "Els documents només queden identificats amb una data. Tant pot ser la data " "en la qual s'han importat (per defecte) com una data que trieu vosaltres." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" "Es mostren al panell esquerre de la finestra principal (la part verda de la " "captura d'imatge de dalt)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "Pàgina" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "" "In Paperwork, a page is just an image and the word positions on this image." msgstr "" "Al Paperwork, una pàgina és senzillament una imatge i la posició de les " "paraules en aquesta imatge." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" "Les imatges poden venir d'un escàner o bé d'un fitxer. En aquests casos, es " "desen com a imatges JPEG i s'extreu el text mitjançant l'ORC (Optical " "Character Recognition, el reconeixement òptic de caràcters). L'ORC pot ser " "un procés bastant llarg: pot trigar fins a alguns minuts per cada pàgina. " "Per això, el text que s'extreu es guarda en fitxers hORC al costat dels " "fitxers JPEG." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" "Les pàgines també poden ser les pàgines d'un PDF. En aquest cas, per " "defecte, el Paperwork només guarda una còpia del document en format PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" "Al Paperwork li és igual si és la part del davant o del darrera d'un " "document. Tampoc li importa la mida d'una pàgina (A4, legal, carta, etc.)." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" "Les pàgines es mostren a la part dreta de la finestra (la part blava a la " "captura de pantalla de dalt)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "Indexació i Paraules clau" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" "Per suposat, necessiteu una manera de trobar els vostres documents. " "Paperwork manté un index amb totes les paraules clau dels vostres documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "" "Només us caldrà teclejar algunes paraules per poder recuperar els vostres " "documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" "Per desgràcia, a vegades els documents no contenen les paraules que " "necessitaríem per recuperar-los. A més, l'OCR no sempre és un procés fiable " "i, a vegades, pot no funcionar." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" "Per solucionar aquests problemes, podeu afegir etiquetes i paraules clau als " "vostres documents. Totes dues s'afegiran a l'índex." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" "Les etiquetes es mostren al costat dels documents. Les paraules clau " "addicionals gairebé mai es mostren." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "Configuració" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "Accedint a la configuració" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" "La carpeta de treball és la carpeta on guardeu tota la paperassa. Pot ser " "una carpeta normal, una carpeta sincronitzada entre diferents dispositius o " "una carpeta compartida en una xarxa." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" "Un vegada tanqueu la finestra de configuració, la carpeta de treball serà " "escanejada i el Paperwork actualitzarà el seu índex amb el que trobi a la " "carpeta." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" "Cada vegada que engegueu el Paerwork, cercarà els canvis en aquesta carpeta " "i els sincronitzarà amb l'índex." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "Escàner" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "Dispositiu" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" "Al posar-se en marxa, el Paperwork busca escàners. Podeu establir quin " "escàner voleu fer servir a la configuració." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" "No es poden utilitzar ni webcams, ni fitxers desats, etc. Només traga-" "paperassa." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "Mode escàner" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" "La majoria d'escàners moderns escaneja en color en un temps raonable. Alguns " "escàners antics, en canvi, van molt més ràpid si escanegen en escala de " "grisos o en blanc i negre. Aquí podeu seleccionar quin mode voleu utilitzar." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "Resolució de l'escàner" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" "La resolució de l'escàner defineix com de detallades han de ser les imatges " "escanejades." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "Alta resolució significa" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "escanejos més llargs" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "OCR més llarg" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "més estona per carregar la visualització del fitxer" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "més espai al disc" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "però també millor OCR." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "Una resolució més baixa significa" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "escanejos més ràpids" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "OCR més curt" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "menys temps per carregar la visualització" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "utilitzar menys espai del disc dur" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "però també pitjor OCR" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "i potser una imatges illegible (inclús per a una persona)." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" "300 dpi es considera un punt mig òptim. Potser el voleu reduir a 200 dpi per " "a ordinadors lents." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "Calibratge de l'escàner" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner calibration. " "Scanner calibration in Paperwork is simply an area that will always be " "cropped out of images coming from the scanner." msgstr "" "Els escàners solen produïr imatges més grosses que les pàgines escanejades. " "Gairebé sempre escanejareu pàgines de la mateixa mida (noralment A4 o " "Carta), per això Paperwork ofereix l'opció de calibratge de l'escàner. Això " "permetrà que determineu quina és l'àrea sobrant que s'ha de retallar cada " "vegada." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "" "OCR (Optical Character Recognition, inicials en anglès de \"Reconeixemnt de " "text\")" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" "Per defecte, el Paperwork fa servir Tesseract per l'OCR. Si no està " "disponible, aleshores fa servir Cuneiform." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" "Al sistemes GNU/Linux, si s'instal·la amb Flatpak, el Paperwork sempre porta " "el Tesseract incorporat. A Windows, el Paperwork sempre es lliura amb " "Tesseract." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" "Per obtenir millors resultats, l'eina d'OCR necessita saber l'idioma " "utilitzat als documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" "Les llengües disponibles a la configuració del Paperwork són les que entén " "l'OCR. Si el vostre idioma no és a la llista, significa que l'OCR no té les " "dades que necessita per llegir els vostres documents i l'heu d'instal·lar." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "Afegir idiomes" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "Flatpak" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, no-wrap msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" "# és una llista de codis de 2 lletres dels idiomes, separats per ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "Debian" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" "# és un codi d'idioma de 3-lletres\n" "# ex: 'fra' per francés\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "Fedora" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" "# és un codi de tres lletres per l'idioma\n" "# ex: 'fra' per francès\n" "$ sudo dnf install tesseract tesseract-langpack-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "Ubuntu" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "Windows" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" "El Tesseract i els fitxers amb les dades es lliuraran am l'instal·lador del " "Paperwork. Podeu tornar a executar l'instal·lador per afegir altres idiomes." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" "Si un idioma no està disponible durant la instal·lació significa que o bé no " "ha estat empaquetat (en aquest cas, podeu demanar que ho facin) o bé que no " "hi ha un fitxer de dades disponible per aquest idioma." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "Desactivar l'OCR" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" "Si escanegeu una pàgina amb el Paperwork, immediatament hi passarà l'OCR per " "sobre. Aquest procés pot trigar una estona per cada pàgina. Si voleu " "escanejar moltes pàgines ràpidament (per exemple, la primera vegada que feu " "servir el Paperwork), podeu desactivar l'OCR temporalemnt. Per fer-ho, només " "heu de de-seleccionar tots els idiomes OCR." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "Actualitzacions" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" "Si activeu aquesta opció, quan el Paperwork s'engegui, es cercaran " "actualitzacions si no s'ha fet durant (més o menys) l'última setmana. Per " "saber si hi ha una nova versió disponible, s'ha d'enviar una consulta HTTP a " "\"openpaper.work\"." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" "Si es troba una actualització, apareixerà una notificació, però no " "s'instal·larà res." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "Nou Document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" "Per defecte, el Paperwork genera un document anomenat «Document nou» a la " "llista de documents. Si l'obriu, sempre estarà buit. De fet, aquest document " "no existeix al disc dur, però es crearà tan bon punt hi afegiu una pàgina. " "Podeu afegir pàgines escanejant o important fitxers o arrossegant les " "pàgines d'un altre document." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" "Tan bon punt hi poseu algun contingut, aquest document obtindrà una data " "(per efecte, la actual). A la llista de documents, el «Document nou» passarà " "a ser el d'aquesta data i s'afegirà un nou «Document nou» a la llista." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" "Si esteu buscant alguna cosa (més al capítol \"Cerques\"), només es " "mostraran els resultats de la vostra cerca i per tant el «Document nou» no " "apareixerà. Podeu tornar enrere clicant al botó \"+\" a la part superior " "esquerre de la finestra principal." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "Escanejant" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan pages." msgstr "" "Si s'ha configurat un escàner, podeu fer-lo servir per escanejar les pàgines " "d'un document." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" "A la capçalera hi ha un botó per afegir pàgines. El triangle petit de la " "dreta us permet seleccionar l'origen de la pàgina. El vostre escàner en pot " "permetre més d'un origen de la pàgina (la safata de documents o l'escàner " "pla)." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" "Una vegada hagueu seleccionat quin escàner i quin origen de la pàgina voleu " "fer servir, només haureu de clicar al botó «Escaneja des de...»." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "Això començarà una sessió d'escanejat:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" "Les pàgines escanejades apareixeran al final del document actual. Si feu " "servir la safata de l'escàner, el Paperwork anirà escanejant fins que la " "safata estigui buida." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" "Aleshores el Paperwork retallarà les pàgines seguint el calibratge de " "l'escàner." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "Hi passarà l'OCR per sobre" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "Indexarà el document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" "Si la sessió d'escanejat genera un nou document, el Paperwork intentarà " "afegir-hi etiquetes automàticament." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "Importa" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "Imatges" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" "El Paperwork pot treballar amb tota mena de formats. Admet JPEG, PNG, GIF, " "BMP, TIFF, etc." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "Cada imatge es considera una pàgina." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" "Les imatges sempre s'afegeixen al document que està obert en aquell moment. " "Només cal que seleccioneu un document buit («Document nou») per crear un nou " "document mentre importeu." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" "Sempre es passarà l'OCR a les imatges importades. Si la imatge és la primera " "pàgina d'un nou document, el Paperwork hi afegirà etiquetes automàticament." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" "Tingueu en compte que el Paperwork és un gestor de documents. Encara que " "pugui, no està pensat per treballar amb imatges amb molt poc text o fotos. " "L'etiquetatge automàtic no funcionarà bé en aquests casos." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" "L'OCR (Tesseract) funciona especialment bé en textos negres sobre fons " "blanc. L'endevinador d'etiquetes utilitza el reconeixement de text i " "necessita com més paraules clau millor a la primera pàgina." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "PDF" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" "Cada PDF sempre es considerarà com a un document complet. Mai s'afegirà a un " "document existent. Es copiarà i es posarà un nou nom a la carpeta de " "treball, però mai es modificarà el seu contingut. El Paperwork sempre " "mantindrà el PDF original, encara que n'editeu algunes de les pàgines: la " "pàgines editades es guardaran separades del PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" "El Paperwork buscarà pàgines sense text enganxat. En aquestes pàgines, hi " "passarà automàticament l'OCR. Una vegada s'hagi passat per totes les " "pàgines, aplicarà automàticament les etiquetes. Tingueu en compte que aquest " "procés pot durar alguns minuts per a PDFs grans." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" "Si el PDF ja forma part d'algun dels vostres documents, el Paperwork " "senzillament l'ignorarà." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "Molts PDFs a la vegada" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply ignored. " "Folder is browsed recursively (all the folders inside the folder are also " "examined)." msgstr "" "Si seleccionau una carpeta a importar, el Paperwork buscarà aquí PDFs per " "importar. Els PDFs que ja hagin estat importats s'ignoraran. La carpetà serà " "examinada recursivament (també buscarà a les carpetes dins de la carpeta)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "Etiquetes" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" "Només hi ha una restricció: Cada etiqueta ha d'estar aplicada com a mínim a " "un document. Les etiquetes que no s'apliquin a cap document desapareixeran " "quan reinicieu el Paperwork." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "Crear noves etiquetes" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" "Per triar un color per a l'etiqueta, cliqueu al rectangle gris o negre de " "l'esquerra. Per afegir el nom de l'etiqueta, teniu un espai per fer-ho entre " "el rectangle pel color i el botó «+»." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "Si cliqueu al botó «+», l'etiqueta s'afegirà al document actual." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" "L'etiqueta s'afegirà quan tanqueu les propietats del document. El Paperwork " "aleshores actualitzarà l'índex." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "Configurar les etiquetes dels documents" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" "Quan obriu les propietats del document, apareixerà la llista d'etiquetes. A " "l'esquerre del color de cada etiqueta hi ha un botó, que us permet afegir o " "eliminar etiquetes del document." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" "Els canvis s'escriuen al disc dur quan tanqueu les propietats del document. " "Aleshores el Paperwork actualitzarà els índexs." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "Canviar el color de les etqieutes" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "Canviar el nom de les etiquetes" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "Eliminant l'etiqueta" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" "Atenció: Una vegada hagueu tancat el document, no es podrà tornar a posar " "l'etiqueta eliminada." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "Endevinador automàtic d'etiquetes" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "Cercant" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "Cerca senzilla" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" "Només heu d'escriure les paraules clau al camp de cerca. En uns segons, " "apareixeran els documents que tinguin aquestes paraules clau." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh query language} to make more complex queries. If you want " "examples, you can use the advanced search dialog described below." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "Cerca avançada" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "Mostrant" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "Nivell de zoom" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "" "You can change the scale at which pages are displayed using this control." msgstr "" "Podeu canviar l'escala en la que es mostren els documents amb aquest panell." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "Mostra les pàgines com a graella" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "Mostra les pàgines com a llista" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "Moure les pàgines" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "Dins d'un document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your mouse." msgstr "" "Podeu agafar una pàgina (premeu el botó esquerre del ratolí), arrossegar-la " "i deixar-la anar on vulgueu dins del document. Mentre arrossegueu, una marca " "blava us mostrarà on aterrarà la pàgina si la deixeu anar." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "Des d'un document a un altre" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "Copiant el text" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "" "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "Editar una pàgina" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" "El Paperwork inclou un editor d'imatge molt senzill. Permet realitzar 4 " "accions:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "Retallant" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "Girar la pàgina 90º (es pot girar vàries vegades)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "Girar la pàgina -90º (es pot girar vàries vegades)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "Eliminar" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "Podeu exportar tan documents com pàgines individuals." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "Imprimir" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "Sincronització entre ordinadors" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "" "Beware: You should backup your USB key from time to time on another one." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "Aplicacions de sincronització de fitxers" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" "Atenció: Si trieu allotjar els vostres documents en el servidor d'algú altre " "(DropBox, OneDrive, etc.), aquest podrà accedir als vostres documents, " "perquè el Paperwork no els encripta." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other self-" "hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" "El Paperwork és verificat diàriament amb Nextcloud. Tot i que no és el més " "senzill d'instal·lar, Nextcloud us permet auto-allotjar els vostres fitxers. " "També hi ha altres alternatives d'auto-allotjament: SparkleShare, Syncthing, " "etc." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing not-so-" "confidential documents with others (associations, etc)." msgstr "" "Utilitzat DropBox o OneDrive pot tenir sentit si compartiu documents no " "massa confidencials amb altres (associacions, etc.)." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "Carpeta compartida" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "Encriptació" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "GNU/Linux" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "" "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" "Les distribucions GNU/LInux inclouen moltes eines per encriptar carpetes." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" "Amb el Paperwork hi ha dues carpetes que s'haurien d'encriptar per protegir " "la vostra privadesa:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" "La vostra carpeta de treball (per defecte: \\textasciitilde /papers, però es " "pot canviar a la configuració)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing " "so ;-)." msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Documents: \\textasciitilde /papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc." "pdf) so Paperwork can parse and display it more quickly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 msgid "" "There is also an IRC channel for live discussions: \\href{https://web.libera." "chat/}{Liberachat}, channel \\#paperwork" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on \\href{https://gitlab." "gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: " "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "Fitxer ZIP" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "Desinstal·lació" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "sudo apt remove --purge paperwork-\\*" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "flatpak --user uninstall work.openpaper.Paperwork" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "Windows 10" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/de.po000066400000000000000000003227411456262201400264500ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: 2021-12-21 19:24+0000\n" "Last-Translator: Tom F \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" "\\date{}\n" "\\usepackage[german]{babel}" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "Willkommen bei Paperwork!" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" "Sie treiben dich in den Wahnsinn: dein Handyanbieter, deine Bank, die Schule " "deiner Tochter, der Tierarzt deines Hundes, selbst dein Internetanbieter. Es " "scheint, als wollten sie dich in einer Flut aus Papier ertränken. Dokumente, " "die du lesen, sortieren und deren Inhalt du dir merken sollst. Nur für den " "Fall, dass du sie später noch mal brauchst – die meisten brauchst du " "allerdings so bald nicht wieder und du verschenkst deine Energie völlig " "umsonst." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" "Paperwork wird dir helfen, dieser Papierflut Herr zu werden, indem es lose " "Zettel in durchsuchbare Dateien verwandelt. Ganz einfach: Dokument scannen " "und vergessen. Du suchst ein bestimmtes Schreiben? Einfach ein paar " "Schlüsselworte eintippen und tada" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "Dokumente und Seiten" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" "Die Oberfläche von Paperwork teilt sich in zwei Bereiche auf: Auf der linken " "(grün hervorgehobenen) Seite befindet sich eine Liste aller Dokumente, " "sortiert nach Datum. Auf der rechten (blauen) Seite wird das gerade " "ausgewählte Dokument angezeigt." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" "Du kannst Dokumente aus verschiedenen Quellen importieren, abhängig vom " "angeschlossenen Gerät: Flachbettscanner, Dokumentenscanner mit Einzug, " "Digitalkamera usw. Du hast keinen Scanner zu Hause? du kannst auch den " "Scanner bei der Arbeit verwenden – Paperwork importiert ohne Weiteres auch " "bereits existierende PDF- und Bilddateien." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "Suchen" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "{r}{0.5\\textwidth}" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" "Finde ganz einfach, wonach du suchst: Tippe ein paar Schlüsselworte ins " "Suchfeld und die Dokumentenliste zeigt dir nur noch die relevanten Dateien " "an. Hier passiert die Magie: Paperwork verwendet optische Zeichenerkennung " "(engl.: optical character recognition, OCR), um deine Dokumente in einfache, " "durchsuchbare Textdateien umzuwandeln." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "Exportieren" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" "Manchmal wirst du ein Dokument aus Paperwork exportieren wollen, um es " "jemandem zu senden. Verschiedene Formate werden unterstützt: .pdf, .jpg, ." "txt usw. Oder natürlich Papier (setzt einen Drucker voraus, nicht im " "Lieferumfang enthalten)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "Labels und zusätzliche Schlüsselworte" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" "Du hast eine wichtige E-Mail beantwortet und willst sie im Blick behalten? " "Das eingescannte Dokument war so unlesbar, dass Paperwork einige der " "enthaltenen Schlüsselworte gar nicht erkennen konnte? Füge eigene " "Schlüsselworte hinzu, damit dir nichts entgeht! Alle Wörter die Du dazugibst " "werden suchbar, als ob sie auf dem gescannten Dokument geschrieben waren." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" "Du willst deine Dokumente noch gründlicher organisieren? Dann nutze Labels. " "Jedes Label hat seine eigene Farbe. Mit der Zeit wird Paperwork lernen, " "welche Labels an welches Dokument gehören und sie beim Erfassen neuer " "Dokumente selbstständig ergänzen." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "Deine ersten Dokumente" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" "Klick auf den \"{}+\"{}-Knopf, dann auf den \"{}Scan\"{}-Button und das " "war’s. Damit kennst du bereits die Hauptfunktionen von Paperwork. Du kannst " "mit der Benutzung direkt starten, indem du das erste Dokument hinzufügst." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" "Dieses Dokument wird automatisch aus Deiner Dokumentenliste verschwinden, " "sobald Du dein erstes Dokument erstellt oder importiert hast." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "Mehr Hilfe benötigt?" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" "Wenn du mehr Hilfe benötigst, schau ins ausführliche Handbuch. Du findest es " "im Menü \"{}Hilfe\"{} von Paperwork." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" "Wir hoffen, dass dir dieses Stück Software Freude bereiten wird. Wenn du " "Paperwork magst, sag es uns – und wenn nicht, verrat uns, warum nicht!" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "Paperwork Handbuch" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "Einleitung" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" "Die meisten privaten Dokumente sind ziemlich wiederholend: " "Gehaltsabrechnungen, Mietabrechnungen, Stromrechnungen usw. Für die meisten " "unorganisierten Menschen ist es bestenfalls beunruhigend, diese später " "wiederfinden zu müssen. Für die meisten organisierten Menschen ist das " "Benennen und Sortieren so mühsam, wie Farbe beim Trocknen zuzusehen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" "Die Grundidee hinter Paperwork ist es, dass die Verwaltung von Dokumenten " "ein Computerjob ist. Menschen sollten so wenig wie möglich tun, während " "Maschinen den Großteil der Arbeit erledigen. Das Ziel ist hier \"{}scannen " "\\& vergessen\"{}." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" "Wenn Sie eine Software suchen, mit der Sie jedes Dokument einzeln benennen, " "in einer komplexen Hierarchie organisieren, jedes Mal manuell markieren, " "kleinere OCR-Probleme beheben usw. können, dann ist Paperwork nichts für Sie." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "Definitionen" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "Arbeitsverzeichnis" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" "Paperwork speichert alle Ihre Dokumente in einem einzigen Verzeichnis: dem " "Arbeitsverzeichnis. In diesem Verzeichnis hat jedes Dokument sein eigenes " "Unterverzeichnis." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" "Dies erschwert zwar die Verwendung von Paperwork mit anderen Programmen, hat " "aber einen großen Vorteil: Sie müssen sich nicht mehr um Dateinamen und " "Verzeichnisstrukturen kümmern." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "Dokument" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" "In Paperwork ist ein Dokument eine Ansammlung von Seiten. Auf der Festplatte " "kann dies entweder eine Ansammlung von JPEG-Dateien oder eine PDF-Datei sein." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" "Dokumente werden nur durch ein Datum identifiziert. Es kann entweder das " "Datum sein, an dem Sie sie importiert haben (voreingestellter Standard), " "oder ein von Ihnen gewähltes Datum." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" "Sie werden auf der linken Seite des Hauptfensters angezeigt (grüner Teil auf " "dem Screenshot oben)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "Seite" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "" "In Paperwork, a page is just an image and the word positions on this image." msgstr "" "In Paperwork ist eine Seite nur ein Bild und Wortpositionen auf diesem Bild." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" "Bilder können von einem Scanner kommen oder importiert werden. In diesen " "Fällen wird es als JPEG-Datei gespeichert und der Text wird mit OCR (Optical " "Character Recognition, englisch für Zeichnerkennung) extrahiert. OCR ist ein " "ziemlich langwieriger Prozess. Er kann bis zu ein paar Minuten pro Seite " "dauern. Daher wird der aus den Bildern extrahierte Text in hOCR-Dateien " "neben den JPEG-Dateien gespeichert." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" "Seiten können auch die Seiten aus einer PDF-Datei sein. In diesem Fall " "speichert Paperwork standardmäßig nur eine Kopie der PDF-Datei." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" "Paperwork kümmert es nicht, ob eine Seite Vorder- oder Rückseite ist. " "Paperwork berücksichtigt auch nicht das Papierformat einer Seite (A4, " "Letter, usw.)." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" "Die Seiten werden auf der rechten Seite des Hauptfensters angezeigt (blauer " "Teil auf dem Screenshot oben)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "Indexierung und Schlüsselwörter" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" "Natürlich brauchen Sie eine Möglichkeit, Ihre Dokumente wiederzufinden. " "Paperwork verwaltet einen Index mit allen Schlagwörtern, die in Ihren " "Dokumenten gefunden wurden." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "" "Geben Sie einfach ein paar Schlüsselwörter ein, und Sie erhalten Ihre " "Dokumente zurück." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" "Leider enthalten Dokumente manchmal nicht die erforderlichen " "Schlüsselwörter, um sie wiederzufinden. Außerdem ist OCR kein perfekt " "zuverlässiger Prozess und funktioniert möglicherweise nicht." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" "Um diese Probleme abzumildern, können Sie Ihre Dokumente mit Etiketten (oder " "Tags) versehen und zusätzliche Schlüsselwörter angeben. Beides wird in den " "Index aufgenommen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" "Etiketten werden neben den Dokumenten angezeigt. Zusätzliche Stichwörter " "werden fast nie angezeigt." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "Einstellungen" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "Zugriff auf die Einstellungen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" "Das Arbeitsverzeichnis ist das Verzeichnis, in dem Sie alle Ihre Dokumente " "speichern möchten. Das kann ein normaler Ordner, ein über mehrere Computer " "synchronisierter Ordner oder eine Netzwerkfreigabe sein." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" "Nachdem Sie den Einstellungsdialog geschlossen haben, wird das " "Arbeitsverzeichnis gescannt und der Paperwork-Index wird entsprechend seinem " "Index aktualisiert." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" "Jedes Mal, wenn Paperwork startet, sucht es nach Änderungen in diesem Ordner " "und synchronisiert seinen Index entsprechend." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "Scanner" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "Gerät" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" "Beim Start sucht Paperwork nach Scannern. Der zu verwendende Scanner kann in " "den Einstellungen ausgewählt werden." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" "Webcams, Dateispeicher usw. können nicht verwendet werden. Nur Papierfresser." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "Scanmodus" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" "Die meisten modernen Scanner scannen in Farbe in einer vertretbaren Zeit. " "Einige ältere Scanner scannen jedoch viel schneller in Graustufen oder sogar " "in Schwarz-Weiß. Hier können Sie den zu verwendenden Modus auswählen." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "Scan-Auflösung" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" "Die Scan-Auflösung legt fest, wie detailliert die von Ihrem Scanner " "kommenden Bilder sein müssen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "Höhere Auflösungen bedeuten" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "längere Scans," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "längere OCR," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "mehr Zeit für die Anzeige," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "mehr Speicherplatz auf der Festplatte verwendet," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "aber auch eine bessere OCR." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "Niedrigere Auflösungen bedeuten" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "kürzere Scans," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "kürzere OCR," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "weniger Zeit für die Anzeige," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "weniger Speicherplatz auf der Festplatte," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "aber auch eine minderwertige OCR," #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "und ein möglicherweise unlesbares (auch von einem Menschen) Bild." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" "300 dpi wird als guter Kompromiss angesehen. Auf langsamen Computern sollten " "Sie eventuell auf 200 dpi reduzieren." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "Scanner-Kalibrierung" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner calibration. " "Scanner calibration in Paperwork is simply an area that will always be " "cropped out of images coming from the scanner." msgstr "" "Scanner neigen dazu, Bilder zu liefern, die größer sind als die gescannten " "Seiten. Da Sie in den meisten Fällen immer Seiten mit der gleichen Größe " "(normalerweise A4 oder Letter) scannen werden, bietet Paperwork eine Option " "namens Scannerkalibrierung. Die Scannerkalibrierung in Paperwork ist einfach " "ein Bereich, der aus den die vom Scanner kommenden Bildern jedesmal " "ausgeschnitten wird." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "OCR (optical character recognition, englisch für Texterkennung)" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" "Paperwork verwendet standardmäßig Tesseract für die OCR. Wenn das nicht " "verfügbar ist, greift es auf Cuneiform zurück." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" "Unter Linux wird Paperwork, wenn es mit Flatpak installiert wurde, immer mit " "Tesseract ausgeliefert. Unter Windows wird Paperwork immer mit Tesseract " "installiert." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" "Um bessere Ergebnisse zu erzielen, muss das OCR-Programm die in den " "Dokumenten verwendete Sprache kennen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" "Die im Einstellungsdialog von Paperwork verfügbaren Sprachen sind " "diejenigen, die vom OCR-Programm beherrscht werden. Wenn Ihre Sprache nicht " "in der Liste enthalten ist, bedeutet dies, dass das OCR-Programm nicht über " "die erforderlichen Sprachdaten verfügt und, dass Sie diese installieren " "müssen." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "Sprachen hinzufügen" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "Flatpak" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, no-wrap msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" "# ist eine Liste von zweibuchstabigen Ländercodes getrennt durch ';'\n" "# Beispiel: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "Debian" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" "# ist ein dreibuchstabiger Sprach-Code\n" "# Beispiel: 'fra' für Französisch\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "Fedora" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" "# ist ein dreibuchstabiger Sprach-Code\n" "# Beispiel: 'fra' für Französisch\n" "$ sudo dnf install tesseract tesseract-langpack-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "Ubuntu" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "Windows" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" "Tesseract und alle seine Datendateien werden vom Installationsprogramm von " "Paperwork bereitgestellt. Sie können das Installationsprogramm erneut " "ausführen, um andere Sprachen zu installieren." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" "Wenn eine Sprache im Installationsprogramm nicht verfügbar ist, bedeutet " "dies entweder, dass sie nicht mit eingepackt wurde (in diesem Fall können " "Sie sie anfordern), oder es ist noch keine Datendatei für diese Sprache " "verfügbar." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "OCR deaktivieren" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" "Wenn Sie eine Seite mit Paperwork scannen, führt Paperwork sofort die OCR " "auf der Seite durch. Dieser Vorgang kann für jede Seite eine Weile dauern. " "Für den Fall, dass Sie viele Seiten schnell scannen möchten (z. B. bei der " "ersten Verwendung von Paperwork), kann die OCR vorübergehend deaktiviert " "werden. Um OCR zu deaktivieren, können Sie einfach alle OCR-Sprachen " "abwählen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "Updates" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" "Wenn Sie diese Option aktivieren, sucht Paperwork beim Start nach Updates, " "falls es dies eine Woche oder länger nicht getan hat. Um zu prüfen, ob eine " "neue Version verfügbar ist, wird eine HTTPS-Anfrage an 'openpaper.work' " "gesendet." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" "Sie werden benachrichtigt, wenn ein Update gefunden wurde, aber es wird " "nicht installiert." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "Neues Dokument" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" "Standardmäßig enthält Paperwork in der Dokumentenliste ein Dokument namens " "\"{}Neues Dokument\"{}. Wenn Sie es öffnen, erscheint es immer leer. Dieses " "Dokument existiert tatsächlich noch nicht auf der Festplatte, aber es wird " "existieren, sobald Sie eine Seite hineinlegen. Sie können ihm Seiten " "hinzufügen, indem Sie scannen, Dateien importieren oder eine Seite aus einer " "anderen Datei darin ablegen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" "Sobald Sie einen Inhalt hineinlegen, bekommt dieses Dokument ein eigenes " "Datum (standardmäßig das aktuelle). In der Dokumentenliste wird \"{}Neues " "Dokument\"{} durch dieses Datum ersetzt, und ein neues \"{}Neues " "Dokument\"{} wird der Dokumentenliste hinzugefügt." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" "Wenn Sie gerade etwas suchen (siehe Kapitel \"{}Suchen\"{}), werden nur die " "Suchergebnisse angezeigt und daher wird dieses \"{}Neue Dokument\"{} nicht " "angezeigt. Sie können es zurückholen, indem Sie auf die Schaltfläche \"{}+" "\"{} in der linken oberen Ecke des Hauptfensters klicken." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "Scannen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan pages." msgstr "" "Wenn ein Scanner in den Einstellungen ausgewählt wurde, können Sie diesen " "zum Scannen von Seiten verwenden." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" "In der Kopfleiste befindet sich eine Schaltfläche zum Hinzufügen von Seiten. " "Der kleine Pfeil auf der rechten Seite ermöglicht den Zugriff auf mögliche " "Seitenquellen. Zu diesen Seitenquellen gehören Ihre Scannerquellen " "(Flachbett, Einzug)." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" "Nachdem Sie die gewünschte Scannerquelle ausgewählt haben, können Sie auf " "die Schaltfläche \"{}Scannen von ...\"{} klicken." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "Dadurch wird eine Scan-Sitzung gestartet:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" "Gescannte Seiten werden an das Ende des aktuellen Dokuments angehängt. Falls " "Sie einen automatischen Papiereinzug verwenden, scannt Paperwork Seiten, bis " "der Einzug leer ist." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" "Die Papiere werden dann entsprechend der Scannerkalibrierung beschnitten." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "Paperwork lässt die OCR laufen" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "Paperwork wird sie indizieren" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" "Wenn in dieser Scan-Sitzung ein neues Dokument erstellt wird, versucht " "Paperwork, automatisch Schlagwörter im Dokument zu setzen." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "Import" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "Bilder" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" "Paperwork unterstützt eine Vielzahl von Dateiformaten. Es unterstützt JPEG, " "PNG, GIF, BMP, TIFF, usw." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "Jede Bilddatei wird als eine Seite behandelt." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" "Bilder werden immer an das aktuell geöffnete Dokument angehängt. Wählen Sie " "einfach ein leeres Dokument (\"{}Neues Dokument\"{}), um beim Importieren " "ein neues Dokument zu erstellen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" "Auf importierten Bildern wird immer eine OCR ausgeführt. Falls das " "importierte Bild die erste Seite eines neuen Dokuments ist, erzeugt " "Paperwork automatisch Schlagwörter." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" "Beachten Sie, dass Paperwork ein Dokumentenmanager ist. Es kann zwar Bilder " "mit nur sehr wenig Text oder Fotos verarbeiten, ist aber nicht dafür " "ausgelegt. Die automatische Verschlagwortung wird bei solchen Dokumenten " "nicht korrekt funktionieren." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" "Die OCR (Tesseract) arbeitet sehr gut mit schwarzem Text auf weißem " "Hintergrund. Die automatische Verschlagwortung verwendet den erkannten Text " "und benötigt viele Schlüsselwörter auf der ersten Seite." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "PDF" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" "PDF-Dateien werden immer als ein ganzes Dokument betrachtet. Sie werden nie " "an ein bestehendes Dokument angehängt. Sie werden in das Arbeitsverzeichnis " "kopiert und umbenannt, aber ihr Inhalt wird nicht verändert. Paperwork " "behält die ursprüngliche PDF-Datei immer so bei, wie sie war, auch wenn Sie " "einige ihrer Seiten bearbeiten: Die bearbeiteten Seiten werden neben der PDF-" "Datei gespeichert." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" "Paperwork sucht nach den Seiten, die keinen Text beigefügt haben. Auf diesen " "Seiten wird automatisch eine OCR durchgeführt. Nachdem alle Seiten " "untersucht wurden, wird automatisch verschlagwortet. Beachten Sie, dass " "dieser Vorgang bei großen PDF-Dateien einige Minuten dauern kann." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" "Wenn eine PDF-Datei bereits Teil Ihrer Dokumente ist, wird sie von Paperwork " "einfach ignoriert." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "Viele PDFs auf einen Schlag" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply ignored. " "Folder is browsed recursively (all the folders inside the folder are also " "examined)." msgstr "" "Wenn Sie beim Importieren einen Ordner auswählen, durchsucht Paperwork " "diesen Ordner und sucht nach zu importierenden PDF-Dateien. Bereits " "importierte PDF-Dateien werden einfach ignoriert. Der Ordner wird rekursiv " "durchsucht (alle Ordner innerhalb des Ordners werden ebenfalls abgearbeitet)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "Schlagwörter" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" "Derzeit gibt es eine Einschränkung in Paperwork: Jedes Schlagwort muss sich " "in mindestens einem Dokument finden. Andernfalls werden beim Neustart von " "Paperwork Schlagwörter ohne Dokumentenbezug verschwinden." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "Neue Schlagwörter einrichten" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" "Sie können auf das graue Rechteck auf der linken Seite klicken, um die " "Schlagwortfarbe auszuwählen. Sie können den Schlagwortnamen in das Textfeld " "zwischen dem grauen Rechteck und der Schaltfläche \"{}+\"{} eingeben." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "" "Sobald Sie auf die Schaltfläche \"{}+\"{} klicken, wird das Schlagwort zum " "aktuellen Dokument hinzugefügt." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" "Das Schlagwort wird endgültig hinzugefügt, sobald Sie die " "Dokumenteigenschaften schließen. Paperwork wird dann seinen Index " "entsprechend aktualisieren." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "Schlagwörter für Dokumente setzen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" "Wenn Sie die Dokumenteigenschaften öffnen, wird die Schlagwortliste " "angezeigt. Auf der linken Seite jeder Schlagwortfarbe finden Sie eine " "Schaltfläche. Mit dieser Schaltfläche können Sie Schlagwörter zum aktuellen " "Dokument hinzufügen oder davon entfernen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" "Die Änderungen werden endgültig auf die Festplatte geschrieben, wenn Sie die " "Dokumenteigenschaften schließen. Paperwork wird dann seinen Index " "entsprechend aktualisieren." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "Ändern der Schlagwortfarbe" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" "Wenn Sie die Dokumenteigenschaften öffnen, können Sie auf eine " "Schlagwortfarbe klicken, um sie zu ändern. In einem Dialogfeld können Sie " "die neue Farbe auswählen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" "Die Schlagwortfarbe wird endgültig auf der Festplatte geändert, wenn Sie die " "Dokumenteigenschaften schließen. Paperwork aktualisiert dann das Schlagwort " "für alle Dokumente, die dieses verwenden." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "Ändern eines Schlagwortnamens" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" "Wenn Sie die Dokumenteigenschaften öffnen, können Sie auf einen " "Schlagwortnamen klicken, um diesen zu ändern. In einem Dialogfeld können Sie " "den neuen Namen eingeben." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" "Der Schlagwortname wird endgültig auf der Festplatte geändert, wenn Sie die " "Dokumenteigenschaften schließen. Paperwork aktualisiert dann das Schlagwort " "für allen Dokumente, die dieses verwenden, und indiziert sie dann alle neu." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "Löschen eines Schlagwortes" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" "Rechts von jedem Schlagwort befindet sich eine weiß-schwarze Kreuztaste. " "Wenn Sie darauf klicken, können Sie das Schlagwort löschen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" "Nachdem Sie die Dokumenteigenschaften geschlossen haben, wird das Schlagwort " "für alle Dokumente entfernt, die es enthalten hatten. Paperwork wird dann " "seinen Index entsprechend aktualisieren." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" "Achtung! Wenn Sie die Dokumenteigenschaften geschlossen haben, gibt es keine " "Möglichkeit, das gelöschte Schlagwort wieder einzufügen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "Automatische Verschlagwortung" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" "Paperwork nutzt künstliche Intelligenz. Es verwendet sogar eine ziemlich " "einfache Methode: \\href{https://en.wikipedia.org/wiki/" "Naive_Bayes_classifier}{Naive Bayes classifiers}. Dies ist die gleiche " "Technologie, die von E-Mail-Clients verwendet wird, um Mails als Spam/Nicht-" "Spam zu klassifizieren." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" "Basierend auf allen Schlüsselwörtern in all Ihren Dokumenten, die ein " "Schlagwort haben (oder nicht), kann es eine Wahrscheinlichkeit abschätzen, " "dass ein Dokument, das dieselben Schlüsselwörter enthält, dasselbe " "Schlagwort haben oder nicht haben müsste. Wenn die Wahrscheinlichkeit hoch " "genug ist, wird das Dokument beim Importieren oder Scannen automagisch mit " "dem Schlagwort versehen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" "Natürlich bedeutet dieser Ansatz, dass Paperwork genügend Muster benötigt, " "um zuverlässig zu arbeiten. Sie können davon ausgehen, dass dies ab etwa 100 " "Dokumenten funktioniert (und nur für Schlagwörter, die für mehr als 10 " "Dokumente oder mehr gesetzt sind)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "Suchen" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "Einfache Suche" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" "Geben Sie einfach Stichwörter in das Suchfeld ein. In wenigen Sekunden " "erhalten Sie alle Dokumente, die diese Stichwörter enthalten." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" "Paperwork führt eine \"{}unscharfe\"{} Suche durch: Es werden auch Dokumente " "mit Stichwörtern zurückgegeben, die dem von Ihnen angegebenen ähnlich sind, " "aber nicht identisch sind (z. B. \"{}flech\"{} statt \"{}flesch\"{})." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh query language} to make more complex queries. If you want " "examples, you can use the advanced search dialog described below." msgstr "" "Sie können auch die \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh-Abfragesprache} verwenden, um komplexere Abfragen zu erstellen. " "Wenn Sie Beispiele brauchen, können Sie den unten beschriebenen Dialog für " "die erweiterte Suche verwenden." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "Erweiterte Suche" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" "Der erweiterte Suchdialog hilft bei der Erstellung komplexer Suchanfragen. " "Sie können verschiedene Kriterien angeben und sobald Sie auf die " "Schaltfläche \"{}Anwenden\"{} klicken, wird eine Suchanfrage für Sie " "generiert und sofort in das Suchfeld eingefügt. Die Suchergebnisse werden " "ebenfalls sofort aktualisiert." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "Anzeigen" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "Zoomstufe" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "" "You can change the scale at which pages are displayed using this control." msgstr "" "Mit diesem Steuerelement können Sie die Vergrößerung ändern, mit der die " "Seiten angezeigt werden." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "Seiten im Raster anordnen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" "Wenn Sie auf diese Schaltfläche klicken, versucht Paperwork, die Seiten in 3 " "Spalten anzuzeigen. In diesem Modus können Sie Seiten per Drag'n'Drop " "innerhalb des Dokuments oder in ein anderes Dokument verschieben." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "Seiten in Listenform anordnen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" "Wenn Sie auf diese Schaltfläche klicken, werden die Seiten so skaliert, dass " "ihre Breite der maximal zulässigen Breite des Hauptfensters entspricht. In " "diesem Modus können Sie Text auf der Seite auswählen (und dann kopieren)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "Alle Wörter hervorheben" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" "Mit dieser Option können Sie schnell alle von der OCR erkannten Wörter " "sehen. Manchmal (selten) verpasst OCR ganze Abschnitte auf einer Seite. Mit " "dieser Option können Sie solche Abschnitte schnell erkennen." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "Verschieben von Seiten" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "Innerhalb eines Dokuments" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" "Sie müssen die Dokumentseiten als Raster anordnen (siehe~\\ref{layout:grid})." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your mouse." msgstr "" "Sie können dann eine Seite greifen (halten Sie die linke Maustaste " "gedrückt), ziehen und an einer beliebigen Stelle im Dokument ablegen. " "Während des Ziehens zeigt Ihnen eine blaue Markierung an, wo die Seite " "landen würde, wenn Sie die linke Maustaste loslassen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "Zwischen Dokumenten" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" "Sie können dann eine Seite greifen (halten Sie die linke Maustaste " "gedrückt), ziehen und in der Dokumentenliste auf dem Dokument ablegen, in " "dem die Seite erscheinen soll." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "Kopieren von Text" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "" "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" "Sie müssen die Dokumentseiten als Liste anordnen (siehe~\\ref{layout:paged})." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" "Sie können dann Text auf einer Seite auswählen. Halten Sie die linke " "Maustaste gedrückt, um die Auswahl zu starten, bewegen Sie den Mauszeiger, " "um weitere Wörter auszuwählen, und lassen Sie dann die Taste los." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" "Sie können dann den ausgewählten Text kopieren, entweder durch Drücken von " "Strg-C oder über das Seitenmenü unten rechts im Hauptfenster. Nach dem " "Kopieren können Sie den ausgewählten Text in jeder anderen Anwendung " "einfügen (Strg-V)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "Bearbeiten einer Seite" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" "Paperwork enthält einen sehr einfachen Bildeditor. Er bietet 4 Funktionen:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "Schneiden" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "Drehen der Seite um 90\\degree (es darf mehrfach gedreht werden)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "Drehen der Seite um -90\\degree (es darf mehrfach gedreht werden)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" "Automatische Farbabgleich: Ein Algorithmus passt die Bildhelligkeit, den " "Kontrast und die Farben an, um das Bild so gut wie möglich lesbar zu machen." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "Zurücksetzen einer Seite" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" "Das Zurücksetzen einer Seite setzt diese in den Ausgangszustand zurück, in " "dem sie gescannt oder importiert wurde, bevor irgendeine Vorverarbeitung " "stattfand." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" "Dies kann hilfreich sein, wenn Sie eine falsche Änderung an der Seite " "vorgenommen haben (z. B. einen falschen Bereich beschnitten haben), wenn die " "Kalibrierungseinstellungen nicht passed gewählt waren oder falls " "Vorverarbeitungsalgorithmen die Seite verkorkst haben." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "Löschen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" "Wenn Sie ein Dokument oder eine Seite löschen, werden diese in den " "Papierkorb Ihres Computers verschoben." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" "\\textbf{Wichtiger Hinweis zu Flatpak:} Ein Fehler kann Paperwork daran " "hindern, Dateien in den Papierkorb zu verschieben (wir arbeiten daran). In " "diesem Fall wird Paperwork die Datei direkt löschen (dann ist keine " "Wiederherstellung möglich)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "Export" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "Sie können sowohl Dokumente als auch einzelne Seiten exportieren." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" "In beiden Fällen können vor dem eigentlichen Exportieren verschiedene " "Transformationen vorgenommen werden. Zum Beispiel können Sie Farbseiten in " "Graustufen umwandeln, bevor Sie sie in eine neue PDF-Datei einfügen (wodurch " "die resultierende PDF-Datei kleiner wird)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "Drucken" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "Sie können Dokumente und auch einzelne Seiten drucken." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" "Beachten Sie, dass die Seiten immer als Bilder an Ihren Drucker gesendet " "werden. Bei sehr großen Dokumenten können also einige Minuten vergehen, " "bevor der eigentliche Druckvorgang beginnt." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "Backup" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "Synchronisation zwischen mehreren Computern" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" "Paperwork ist zwar ein persönlicher Dokumentenmanager, aber keine Anwendung " "zur Dateisynchronisation. Es gibt Anwendungen, die sich der " "Dateisynchronisation widmen und das bereits sehr gut tun. Daher ist " "Paperwork für die Verwendung mit solchen Anwendungen (Nextcloud, Dropbox, " "OneDrive, SparkleShare, etc.) konzipiert." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" "Nach dem Start prüft Paperwork als erstes den Inhalt des " "Arbeitsverzeichnisses. Es sucht nach Änderungen und aktualisiert seine " "Dokumentenliste und auch den Index automatisch. Wenn also eine andere " "Instanz von Paperwork auf einem anderen Computer etwas im Arbeitsverzeichnis " "geändert hat und diese Änderung auf einem anderen Computer synchronisiert " "wurde, wird das andere Paperwork diese Änderung beim Start automatisch " "übernehmen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "USB-Stick / USB-Platte" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" "Dies ist der einfachste Weg, um Dokumente gemeinsam zu nutzen. Kopieren Sie " "einfach Ihr Arbeitsverzeichnis auf einen USB-Stick, weisen Sie Paperwork an, " "es zu verwenden, und schon sind Sie fertig." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "" "Beware: You should backup your USB key from time to time on another one." msgstr "" "Achtung: Sie sollten Ihren USB-Stick von Zeit zu Zeit auf einem anderen " "sichern." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "Anwendungen zur Dateisynchronisation" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" "Solche Anwendungen synchronisieren ein lokales Verzeichnis mit einem Remote-" "Server (oder einer Cloud). Alle Änderungen, die Sie in Ihrem Ordner " "vornehmen, werden auch auf dem Server vorgenommen. Alle Änderungen, die auf " "dem Server angewandt wurden, werden auch auf allen verbundenen Computern " "angewendet. Der Server kann Ihnen oder einer anderen Person (normalerweise " "einer Firma) gehören." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" "Achtung: Wenn Sie sich dafür entscheiden, Ihre Dokumente auf einem fremden " "Server zu hosten (DropBox, OneDrive, usw.), kann dieser auf alle Ihre " "Dokumente zugreifen. Paperwork verschlüsselt diese nicht selber." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other self-" "hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" "Der Paperwork wird täglich mit Nextcloud getestet. Das ist zwar nicht die " "einfachste Variante, aber mit Nextcloud können Sie Ihre Dateien selbst " "hosten. Es gibt noch andere selbst gehostete Alternativen, die existieren: " "SparkleShare, Syncthing, usw." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing not-so-" "confidential documents with others (associations, etc)." msgstr "" "Die Verwendung von DropBox oder OneDrive könnte dann sinnvoll sein, wenn Sie " "nicht ganz so vertrauliche Dokumente mit anderen teilen (Vereine usw.)." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "Gemeinsamer Ordner" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" "Wenn sich alle Ihre Computer im selben Netzwerk befinden, können Sie Ihr " "Arbeitsverzeichnis gemeinsam nutzen. Seien Sie jedoch sehr vorsichtig, was " "die Zugriffsrechte angeht. Wenn Sie zu freizügig sind, könnte ein böser " "Angreifer Zugriff auf alle Ihre persönlichen Dokumente erhalten! Und diese " "richtig einzustellen ist knifflig." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" "Achtung! Die Verwendung eines gemeinsamen Ordners bedeutet, dass Sie nur " "eine einzige Kopie Ihres Arbeitsverzeichnisses haben. Sie sollten regelmäßig " "Backups Ihres Arbeitsverzeichnisses erstellen." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "Verschlüsselung" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "GNU/Linux" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "" "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" "GNU/Linux-Distributionen enthalten viele Programme zum Verschlüsseln ganzer " "Verzeichnisse." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" "Für Paperwork sollten 2 Verzeichnisse zum Schutz Ihrer Privatsphäre " "verschlüsselt werden:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" "Ihr Arbeitsverzeichnis (standardmäßig ist das \\textasciitilde /papers, dies " "kann aber in den Einstellungen geändert werden)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" "Das Cache-Verzeichnis (\\textasciitilde /.local/share/paperwork2, dies kann " "nicht geändert werden) enthält Indexdateien, aus denen der Inhalt Ihrer " "Dokumente teilweise wiederhergestellt werden kann" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" "Beachten Sie: Wenn Sie sicher sein wollen, dass Ihre Daten immer " "verschlüsselt sind, empfiehlt es sich, wenn möglich Ihr gesamtes Home-" "Verzeichnis oder sogar Ihr gesamtes System zu verschlüsseln." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "cryptsetup" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" "Die meisten GNU/Linux-Distributionen bieten mittlerweile eine Option an, um " "Ihr gesamtes System oder Ihr gesamtes /home mit cryptsetup zu verschlüsseln. " "Dies ist die empfohlene Methode, um Ihre Dokumente zu schützen." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "Encfs" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" "Zur einfachen Erstellung verschlüsselter Verzeichnisse kann auch Encfs " "verwendet werden." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing " "so ;-)." msgstr "" "Beachten Sie, dass Encfs einige Sicherheitslücken zu haben scheint. Während " "es also wahrscheinlich ausreicht, um eine Laptop-Diebin daran zu hindern, " "auf Ihre Dokumente zuzugreifen, wird es wahrscheinlich nicht ausreichen, um " "die NSA oder die Polizei daran zu hindern ;-)." #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" "Unter Windows wird zum Schutz Ihrer Dokumente dringend empfohlen, BitLocker " "zu aktivieren. Falls nicht verfügbar, gibt es andere Anwendungen (Veracrypt, " "usw.)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "Tastenkürzel" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" "Die Tastenkürzel können Sie anzeigen, indem Sie das Anwendungsmenü öffnen, " "\"{}Hilfe\"{} und dann \"{}Tastenkürzel\"{} wählen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "Dateispeicherorte bei Paperwork" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "Voreingestellt:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "Einstellung: \\textasciitilde /.config/paperwork2.conf" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "Index: \\textasciitilde /.local/share/paperwork2" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Documents: \\textasciitilde /papers" msgstr "Dokumente: \\textasciitilde /papers" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" "(unter Windows werden dieselben Pfade verwendet; \\textasciitilde{} = C:" "\\textbackslash Users{[}login{]} ; Ordner sind ausgeblendet)" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" "Der Index wird auf der Grundlage der Dokumente im Arbeitsverzeichnis ständig " "aktualisiert. Beim Start von Paperwork wird die Änderungszeit jeder Datei " "genutzt, um Änderungen an den Dokumenten zu erkennen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "Innere Struktur des Arbeitsverzeichnisses" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "workdir$|$rootdir = \\textasciitilde /papers (by default)" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "Globale Struktur" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "Im Arbeitsverzeichnis gibt es pro Dokument einen separaten Ordner." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" "Die Ordnernamen sind (normalerweise) das Scan-/Importdatum des Dokuments: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. Das Suffix 'idx' ist optional und ist " "einfach eine Zahl, die im Falle einer Namenskollision hinzugefügt wird." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "In jedem Ordner haben wir:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "Für Bilddokumente:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "paper.$<$X$>$.jpg: Die Originalseite im JPG-Format (X beginnt bei 1)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" "paper.$<$X$>$.edited.jpg (optional): Die vom Benutzer bearbeite Seite (X " "beginnt bei 1)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" "paper.$<$X$>$.words (optional): Eine hOCR-Datei, die alle per OCR auf der " "Seite gefunden Wörter enthält (optional, aber für die Indizierung " "erforderlich; kann mit der Option \"{}Wiederhole OCR\"{} neu erzeugt werden)." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" "paper.1.thumb.jpg (optional, wird automatisch generiert): Eine " "Miniaturversion der Seite (lädt schneller)" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this document" msgstr "" "labels (optional): eine Textdatei, die alle für dieses Dokument vergebenen " "Schlagwörter enthält" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" "extra.txt (optional): vom Benutzer hinzugefügte zusätzliche Schlüsselwörter" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "Für PDF-Dokumente:" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "doc.pdf: das Dokument" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" "paper.$<$X$>$.words (optional): Eine hOCR-Datei, die alle durch die OCR auf " "der Seite gefunden Wörter enthält. Einige PDFs enthalten Mist anstelle des " "echten Textes, so dass es manchmal nützlich sein kann, die OCR über sie " "laufen zu lassen." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" "passwd.txt (optional): PDF Passwort, falls das PDF passwortgeschützt ist." #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc." "pdf) so Paperwork can parse and display it more quickly." msgstr "" "doc.docx / doc.odt / ... (optional): Originaldatei. Konvertiert nach PDF " "(doc.pdf) damit Paperwork sie schneller verarbeiten und anzeigen kann." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "Im folgenden ein Beispiel für eine Arbeitsverzeichnisorganisation:" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "hOCR Dateien" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "Mit Tesseract kann die hOCR-Datei mit folgendem Befehl erzeugt werden:" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" msgstr "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "Beispiel:" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "Schlagwort-Dateien" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "Beispiel für den Inhalt einer Schlagwort-Datei:" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "Rechnung,#0000b1588c61 Wohnung,#f6b6ffff0000" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" "Es ist immer $[$label$]$,$[$color$]$. Bei gleichem Schlagwort sollte die " "Farbe immer gleich sein." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "Unterstützung bekommen" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." msgstr "" "Es gibt ein Forum für Paperwork: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 #, fuzzy #| msgid "" #| "There is also an IRC channel for live discussions: \\href{https://webchat." #| "freenode.net/}{Freenode}, channel \\#openpaperwork" msgid "" "There is also an IRC channel for live discussions: \\href{https://web.libera." "chat/}{Liberachat}, channel \\#paperwork" msgstr "" "Ebenso gibt es einen IRC-Kanal für Live-Diskussionen: \\href{https://webchat." "freenode.net/}{Freenode}, channel \\#openpaperwork" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" "Das sind die Anlaufstellen, wenn Sie Fragen zum Paperwork haben oder einfach " "nur plaudern wollen." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "Probleme melden" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" "Wenn Ihnen ein Fehler in Paperwork aufgefallen ist (und Sie sicher sind, " "dass es ein Fehler ist), können Sie einen Fehlerbericht erstellen." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "Fehlerverfolgung" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on \\href{https://gitlab." "gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: " "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" "Eine Möglichkeit, Fehlerberichte zu erstellen, ist das Erstellen von Tickets " "auf \\href{https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}" "{Paperwork bug tracker: https://gitlab.gnome.org/World/OpenPaperwork/" "paperwork/issues}." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" "Dies ist der empfohlene Weg, um einen Fehlerbericht einzureichen, falls Sie " "ihn mit den Entwicklern von Paperwork besprechen möchten." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" "Um sicherzustellen, dass Sie alle erforderlichen Informationen angeben, " "können Sie das in Paperwork integrierte Werkzeug verwenden (siehe unten)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "Automatischer Fehlerbericht" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" "Paperwork enthält ein Werkzeug zur Erleichterung beim Melden von Fehlern. Es " "ermöglicht Ihnen, auf einfache Weise alle erforderlichen Informationen " "zusammenzustellen, um einen perfekten Fehlerbericht zu erstellen." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" "Um Ihre Privatsphäre zu schützen, werden alle Anhänge automatisch " "anonymisiert: Dokumentinhalte werden in Screenshots unscharf dargestellt und " "Protokolldateien werden durch Entfernen Ihres Benutzernamens anonymisiert." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" "Falls der zu meldende Fehler mit Scannern zusammenhängt, fügen Sie bitte \"{}" "Scanner info.\"{} in den Fehlerbericht ein." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" "Wenn der zu meldende Fehler mit einem Darstellungsproblem zusammenhängt, " "fügen Sie den Fehlerberichtsdateien bitte \"{}App. screenshots\"{} bei." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "ZIP Datei" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" "Sie erhalten dann eine ZIP-Datei mit allen Daten. Bitte stellen Sie sicher, " "dass der Inhalt der ZIP-Datei keine privaten Informationen enthält (sollte " "er eigentlich nicht, aber sicher ist sicher). Dann können Sie diese ZIP-" "Datei einem Ticket auf Gitlab beifügen." #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "Automatische Übertragung" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" "Sie können auch zulassen, dass das Programm den Fehlerbericht automatisch an " "openpaper.work sendet. In diesem Fall können Sie den Fehler nicht mit den " "Entwicklern besprechen (oder Sie müssen im Fehlerbericht eine Möglichkeit " "zur Kontaktaufnahme mit Ihnen hinterlassen)." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" "Wenn Sie die automatische Übertragung verwenden, gibt Ihnen das Programm " "eine URL, um den übermittelten Fehlerbericht zu sehen. Diese URL ist privat " "und sollte nicht weitergegeben werden, bis Sie sichergestellt haben, dass " "der Fehlerbericht keine privaten Informationen enthält. Wenn es private " "Informationen gibt, können Sie die Löschung des Fehlerberichts beantragen, " "indem Sie eine E-Mail an jflesch@openpaper.work senden (bitte geben Sie die " "private URI in Ihrer E-Mail an, damit wir sicher sein können, dass Sie " "derjenige sind, der den Fehlerbericht eingereicht hat)." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "Deinstallation" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" "Paperwork kann deinstalliert werden. Bei der Deinstallation von Paperwork " "werden Ihr Arbeitsverzeichnis oder Ihre Dokumente niemals entfernt." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" "Wenn Sie Paperwork mit dem Paketmanager Ihrer Distribution installiert haben " "(der empfohlene Weg), hängt die Deinstallationsmethode vom Paketmanager ab." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" "Beispielweise kümmert sich unter Unter GNU/Linux Debian oder GNU/Linux " "Ubuntu folgende Befehl darum:" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "sudo apt remove --purge paperwork-\\*" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" "Wenn Sie es mit Flatpak installiert haben, können Sie den folgenden Befehl " "verwenden:" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "flatpak --user uninstall work.openpaper.Paperwork" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "Windows 10" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" "Paperwork kann wie jede Windows-Anwendung deinstalliert werden, indem Sie in " "der Windows-Systemsteuerung auf \"{}Anwendungen\"{} klicken, Paperwork in " "der Liste suchen und dann auf \"{}deinstallieren\"{} klicken." paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/fr.po000066400000000000000000002277061456262201400264740ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: 2023-05-13 18:21+0000\n" "Last-Translator: Frédéric S \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.17\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" "\\date{}\n" "\\usepackage[french]{babel}" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "Bienvenue sur Paperwork !" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" "Ils vont vous rendre fou. Votre opérateur téléphonique, votre banque, " "l'école de votre fille, votre vétérinaire, votre FAI, etc. Ils semblent tous " "essayer de vous noyer sous des tonnes de papiers. Papiers que vous devez " "lire, classer et mémoriser, juste au cas où vous en auriez besoin plus tard. " "La plupart du temps, ce ne sera pas le cas, ce qui signifie que vous avez " "gâché votre énergie pour rien." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" "Paperwork va vous aider à vous débarrasser de tout ces papiers en les " "transformant en documents cherchables. C'est simple : scannez et oubliez. " "Vous cherchez un papier spécifique ? Tapez juste quelques mots-clés, et " "tada !" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "Les documents et les pages" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" "L'interface de Paperwork est composé de 2 panneaux. Sur la gauche (en vert), " "la liste de tout vos documents, triés par date d'import. Sur la droite (en " "bleu), les pages du document actuellement sélectionné." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" "Vous pouvez ajouter des papiers depuis plusieurs sources, en fonction des " "périphériques connectés à votre ordinateur : scanner simple, scanner à bac " "d'alimentation, caméra, ... Vous n'avez pas de scanner à la maison ? Vous " "pouvez utiliser celui de votre travail. Paperwork peut importer des PDFs et " "des fichiers images sans problème." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "Trouver" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "{r}{0.5\\textwidth}" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" "Trouvez ce dont vous avez besoin, quand vous en avez besoin. Tapez quelques " "mots-clés et la liste des documents se réduira à ce que vous cherchez. C'est " "là que la magie s'opère : Paperwork utilise la reconnaissance optique de " "caractères (ROC) pour convertir vos papiers en simples fichiers textes pour " "qu'il soit facile d'y chercher des mots." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "Exporter" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" "Parfois, vous allez vouloir exporter un document pour l'envoyer à quelqu'un " "d'autre. Plusieurs formats sont supportés : .pdf, .jpeg, .txt, ... et bien " "entendu, le format papier (nécessite une imprimante, vendue séparément)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "Étiquettes et mot-clés additionnels" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" "Vous avez répondu à un e-mail important et vous souhaitez en garder une " "trace ? Le papier que vous avez scanné était si illisible que Paperwork n'a " "pas pu le relire ? Ajoutez vous-même des mots-clés à vos papiers pour que " "vous puissiez les retrouver ! Tous les mots que vous ajouterez pourrons être " "retrouvés, comme si ils avaient été écrits dans les pages que vous avez " "scannées." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" "Vous souhaitez trier un peu vos documents ? Vous pouvez aussi leur ajouter " "des étiquettes. Pour plus de lisibilité, chaque étiquette a sa propre " "couleur. Avec le temps, Paperwork va apprendre quelles étiquettes vont sur " "quels documents, et il les placera automatiquement pour vous sur chaque " "nouveau document." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "Vos premiers documents" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" "Cliquez sur le bouton +, cliquez sur le bouton \frquote{scanner}, et c'est " "tout ! Vous connaissez désormais les principales fonctionnalités de " "Paperwork. Vous pouvez maintenant commencer à l'utiliser en ajoutant vos " "premier documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" "Ce document disparaîtra automatiquement de votre liste de documents aussitôt " "que vous aurez créé ou importé votre premier document." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "Besoin d'aide ?" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" "Si vous avez besoin de plus d'aide, il y a un manuel plus complet intégré " "dans Paperwork." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" "Nous espérons que vous apprécierez ce logiciel. Si tel est le cas, dites-le " "nous, et sinon, dites-nous comment l'améliorer !" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "Manuel de Paperwork" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "Introduction" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" "La plupart des documents personnels sont plutôt récurrents : fiches de " "paies, quittances de loyer, facture d'électricité, etc. Pour la plupart des " "gens mal-organisés, devoir les retrouver plus tard est, au mieux, " "inquiétant. Pour la plupart des gens organisés, les nommer et les trier est " "aussi ennuyeux que regarder la pluie tomber." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" "L'idée principale derrière Paperwork est que gérer les documents est un " "travail d'ordinateurs. Les humains devraient faire aussi peu que possible " "pendant que les machines font le gros du travail. L'objectif final ici est " "\"scanner \\& oublier\"." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" "Si vous cherchez un logiciel qui vous laissera nommer les documents " "individuellement, les organiser dans des hiérarchies complexes, les marquer " "manuellement à chaque fois, corriger les ratés mineurs de l'OCR, etc, alors " "Paperwork n'est pas pour vous." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "Définitions" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "Répertoire de travail" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" "Paperwork enregistre tous vos documents dans un seul répertoire : Le " "répertoire de travail. Dans ce répertoire, chaque document a son propre sous-" "répertoire." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" "Bien que cela rende Paperwork difficile à utiliser avec d'autres outils, ça " "a un avantage majeur : Vous n'avez pas à vous inquiéter des noms des " "fichiers et de la structure des répertoires." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "Document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" "Dans Paperwork, un document est ensemble de pages. Sur le disque, ça peut " "être un jeu de fichiers JPEG ou un fichier PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" "Chaque document est identifié uniquement par une date. Il peut s'agir de la " "date à laquelle vous l'avez importé (par défaut) ou une date de votre choix." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" "Ils sont affichés sur le coté gauche de la fenêtre principale (partie en " "vert sur la capture d'écran ci-dessous)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "Page" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "" "In Paperwork, a page is just an image and the word positions on this image." msgstr "" "Dans Paperwork, une page est juste une image et les positions des mots sur " "cette image." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" "Les images peuvent venir d'un scanner ou être importées. Dans ces cas, elles " "sont enregistrées sous forme de fichiers JPEG et leur texte est extrait " "grâce à la ROC (Reconnaissance Optique de Caractères). ROC est un processus " "assez long. Il peut prendre jusqu'à plusieurs minutes pour chaque page. Par " "conséquent, le texte extrait est enregistré dans des fichiers hOCR à coté " "des fichiers JPEG." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" "Les pages peuvent aussi être les pages d'un fichier PDF. Dans ce cas, par " "défaut, Paperwork enregistre simplement une copie du fichier PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" "Paperwork ne mémorise pas si une page est le recto ou le verso. Paperwork ne " "mémorise pas la taille du papier (A4, Letter, etc) correspondant à la page." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" "Les pages sont affichées sur le coté droit de la fenêtre principale (la " "partie en bleu sur la capture d'écran ci-dessus)." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "Indexation et mots-clés" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" "Bien sûr, vous avez besoin de pouvoir retrouver vos documents. Paperwork " "gère un index avec tout les mots-clés trouvés dans vos documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "Tapez juste quelques mots-clés, et vous retrouverez vos documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 #, fuzzy msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" "Malheureusement, parfois, certains documents ne contiennent pas les mots-" "clés nécessaires pour les retrouver. OCR n'est pas parfait et peut ne pas " "fonctionner correctement." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "Réglages" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "Accéder aux réglages" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "Scanner" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "Périphérique" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "Mode du scanner" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 #, fuzzy msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" "La plupart des scanners récents scannent en couleur dans un temps " "raisonnable. Cependant certains ancien scanners peuvent scanner plus " "rapidement en échelle de gris ou même en noir et blanc. Ici vous pouvez " "choisir la méthode à utiliser" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "Résolution du scan" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner calibration. " "Scanner calibration in Paperwork is simply an area that will always be " "cropped out of images coming from the scanner." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "Flatpak" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, no-wrap msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "Mises à jour" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "Nouveau document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "Images" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "PDF" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply ignored. " "Folder is browsed recursively (all the folders inside the folder are also " "examined)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh query language} to make more complex queries. If you want " "examples, you can use the advanced search dialog described below." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "Recherche avancée" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "" "You can change the scale at which pages are displayed using this control." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your mouse." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "" "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "Recadrage" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "Effacer" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "" "Beware: You should backup your USB key from time to time on another one." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other self-" "hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing not-so-" "confidential documents with others (associations, etc)." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "" "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing " "so ;-)." msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 #, fuzzy #| msgid "Documents and pages" msgid "Documents: \\textasciitilde /papers" msgstr "Les documents et les pages" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc." "pdf) so Paperwork can parse and display it more quickly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "Obtenir de l'aide" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 msgid "" "There is also an IRC channel for live discussions: \\href{https://web.libera." "chat/}{Liberachat}, channel \\#paperwork" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on \\href{https://gitlab." "gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: " "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "Fichier ZIP" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/messages.pot000066400000000000000000002117501456262201400300500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "In Paperwork, a page is just an image and the word positions on this image." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner " "calibration. Scanner calibration in Paperwork is simply an area that will " "always be cropped out of images coming from the scanner." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, no-wrap msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan " "pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply " "ignored. Folder is browsed recursively (all the folders inside the folder " "are also examined)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use " "\\href{https://whoosh.readthedocs.io/en/latest/querylang.html}{Whoosh query " "language} to make more complex queries. If you want examples, you can use " "the advanced search dialog described below." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "You can change the scale at which pages are displayed using this control." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your " "mouse." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "Beware: You should backup your USB key from time to time on another one." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other " "self-hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing " "not-so-confidential documents with others (associations, etc)." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing so " ";-)." msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Documents: \\textasciitilde /papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this " "document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF " "(doc.pdf) so Paperwork can parse and display it more quickly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "" "tesseract paper..jpg paper. -l hocr && mv paper..html " "paper..words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: " "\\href{https://forum.openpaper.work}{https://forum.openpaper.work}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 msgid "" "There is also an IRC channel for live discussions: " "\\href{https://web.libera.chat/}{Liberachat}, channel \\#paperwork" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on " "\\href{https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork " "bug tracker: https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/oc.po000066400000000000000000002205061456262201400264550ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: 2021-10-09 10:57+0000\n" "Last-Translator: Quentin PAGÈS \n" "Language-Team: Occitan \n" "Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.4\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "Vos desiram la benvenguda sus Paperwork !" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" "Vos faràn venir craba. Vòstre operator de telefòn, vòstra banca, l'escòla de " "la petita, vòstre veterinari, vòstre provesidor Internet, etc. Sembla " "qu'ensajan totes de nos encombrar de tonas de papièrs. Papiers que vos cal " "legir, triar e memorizar, se per cas vos fa mestièr mai tard. La màger part " "del temps, non, e aquò vòl dire qu'avètz perdut vòstra energia per de prunas." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "Los documents e las paginas" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "Trobar" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "{r}{0.5\\textwidth}" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "Exportar" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "Etiquetas e mots claus addicionals" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "Vòstres primièrs documents" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" "Aqueste document dispareirà automaticament de vòstra lista de documents tre " "qu’auretz creat o importat vòstre primièr document." #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "Besonh d'ajuda ?" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" "Se vos fa mestièr un pauc mai d’ajuda, i a un manual mai complèt integrat a " "Paperwork." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" "Esperam que vos agradarà aqueste logicial. S’es lo cas, digatz-nos-lo, " "autrament, digatz-nos cossí lo melhorar !" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "Manual de Paperwork" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "Introduccion" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "Definicions" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "Repertòri de trabalh" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "Document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" "Dins Paperwork, un document es un ensem de paginas. Sul disc, pòt èsser un " "jòc de fichièrs JPEG o un fichièr PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "Pagina" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "" "In Paperwork, a page is just an image and the word positions on this image." msgstr "" "Dins Paperwork, una pagina es just un imatge e las posicions dels mots sus " "aqueste imatge." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" "Las paginas pòdon tanben èsser de paginas d’un fichièr PDF. Dins aqueste " "cas, per defaut, Paperwork enregistra simplament una còpia del fichièr PDF." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "Indexacion e mots clau" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "Picatz sonque d’unes mots claus e traparetz vòstres documents." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "Paramètres" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "Accès als paramètres" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "Numerizador" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "Periferic" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "Mòde del numerizador" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "Resolucion del numerizador" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "Calibratge del numerizador" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner calibration. " "Scanner calibration in Paperwork is simply an area that will always be " "cropped out of images coming from the scanner." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "ROC" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "Apondon de lengas" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "Flatpak" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, fuzzy, no-wrap #| msgid "" #| "# is a list of 2-letters language codes separated ';'\n" #| "# ex: en;fr;de\n" #| "flatpak config --user --set languages \"\"\n" #| "flatpak update" msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" " es una lista de lenga amb un còdi de doas letras separadas per « ; »\n" "# ex : en;fr;oc\n" "flatpak config --user --set languages \"\"\n" "flatpak update" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "Debian" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" "# es una lista de lenga amb un còdi de tres letras\n" "# ex : « fra » pel francés\n" "# ex : « oci » per l'occitan\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "Fedora" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" "# es una lista de lenga amb un còdi de tres letras\n" "# ex : « oci » per l'occitan\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "Ubuntu" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "Windows" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "Desactivacion de la ROC" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "Mesas a jorn" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "Document novèl" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "Numerizacion" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "Imatges" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "PDF" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply ignored. " "Folder is browsed recursively (all the folders inside the folder are also " "examined)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "Etiquetas" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "Deduccion automatica de las etiquetas" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "Recèrca" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "Recèrca simpla" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" "Picatz pas que qualques mots dins la camp de recèrca. En unas segondas, " "trapatz totes los documents que contenon aqueles mots." #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh query language} to make more complex queries. If you want " "examples, you can use the advanced search dialog described below." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "Recèrca avançada" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "Nivèl de zoom" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "" "You can change the scale at which pages are displayed using this control." msgstr "" "Podètz cambiar l’escala de las paginas afichadas en utilizant aqueste boton." #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "Veire las paginas coma gresilha" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "Veire las paginas coma lista" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "Suslinhar totes los mots" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "Desplaçar las paginas" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "A l’interior d’une document" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your mouse." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "D’un document cap a un autre" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "Copiar de tèxt" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "" "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "Modificar una pagina" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "Retalhatge" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "Reparametrar una pagina" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "Supression" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "Export" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "Imprimir" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "Salvagardar" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "Clau USB / Disc USB" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "" "Beware: You should backup your USB key from time to time on another one." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other self-" "hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing not-so-" "confidential documents with others (associations, etc)." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "Dossièr partejat" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "" "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing " "so ;-)." msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 #, fuzzy #| msgid "Documents and pages" msgid "Documents: \\textasciitilde /papers" msgstr "Los documents e las paginas" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc." "pdf) so Paperwork can parse and display it more quickly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 msgid "" "There is also an IRC channel for live discussions: \\href{https://web.libera." "chat/}{Liberachat}, channel \\#paperwork" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on \\href{https://gitlab." "gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: " "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "Fichièr ZIP" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/sv.po000066400000000000000000002124271456262201400265070ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: 2021-01-05 17:31+0000\n" "Last-Translator: Ã…ke Engelbrektson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "Sök" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "Exportera" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "Introduktion" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "Arbetsmapp" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "Dokument" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "Sida" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "" "In Paperwork, a page is just an image and the word positions on this image." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "Inställningar" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "Skanner" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "Enhet" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner calibration. " "Scanner calibration in Paperwork is simply an area that will always be " "cropped out of images coming from the scanner." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "Flatpak" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, no-wrap msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "Uppdateringar" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "Nytt dokument" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "Bilder" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "PDF" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply ignored. " "Folder is browsed recursively (all the folders inside the folder are also " "examined)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh query language} to make more complex queries. If you want " "examples, you can use the advanced search dialog described below." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "Avancerat sök" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "" "You can change the scale at which pages are displayed using this control." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your mouse." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "" "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "Beskär" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "" "Beware: You should backup your USB key from time to time on another one." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other self-" "hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing not-so-" "confidential documents with others (associations, etc)." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "" "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing " "so ;-)." msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Documents: \\textasciitilde /papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc." "pdf) so Paperwork can parse and display it more quickly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 msgid "" "There is also an IRC channel for live discussions: \\href{https://web.libera." "chat/}{Liberachat}, channel \\#paperwork" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on \\href{https://gitlab." "gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: " "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "ZIP-fil" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/l10n/zh_Hans.po000066400000000000000000002141201456262201400274410ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE # Copyright (C) YEAR Free Software Foundation, Inc. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "POT-Creation-Date: 2023-02-10 18:54+0100\n" "PO-Revision-Date: 2021-03-24 23:17+0000\n" "Last-Translator: 玉堂白鹤 \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.4\n" #. type: Plain text #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "\\date{}" msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:11 msgid "Welcome to Paperwork !" msgstr "欢迎使用 Paperwork !" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:20 msgid "" "They are going to drive you crazy. Your phone operator, your bank, your " "daughter's school, your dog's veterinarian, even your ISP; it seems like all " "of them are trying to drown you under tons of papers. Papers you have to " "read, classify, and memorize just in case you may need them later. Most of " "the time you won't, which means you waste your energy for nothing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:24 msgid "" "Paperwork will help you get rid of all those papers by turning them into " "searchable documents. It's simple: just scan and forget. Looking for a " "specific paper? Just type in a few keywords and tada" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:28 msgid "Documents and pages" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:36 msgid "" "Paperwork's interface is composed of two panels. On the left (green) is the " "list of all your documents sorted by the date they were imported. On the " "right (blue) are the pages of the currently selected paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:41 msgid "" "You can add papers from several sources, depending on the devices connected " "to your computer: scanner flatbed, scanner feeder, camera, etc. You have no " "scanner at home? You can still use the scanner you have at work. Paperwork " "will easily import PDF and image files." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:44 msgid "Find" msgstr "查找" #. type: wrapfigure #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:50 msgid "{r}{0.5\\textwidth}" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:56 msgid "" "Find what you need, when you need it. Type a few keywords in the search bar " "and the list of papers will shrink to only the relevant content. This is " "where the magic happens: Paperwork uses optical character recognition (OCR) " "to convert your papers into simple text files, so it's easy to search for " "text." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:59 msgid "Export" msgstr "导出" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:69 msgid "" "Sometimes you may want to export a document to send it to someone else. " "Multiple formats are supported: .pdf, .jpg, .txt, etc. And of course, paper " "(requires a printer, sold separately)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:72 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:113 msgid "Labels and additional keywords" msgstr "标签和其他关键字" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:84 msgid "" "You answered an important email and you want to keep track of it? The paper " "you scanned was so unreadable that Paperwork failed to recognize some " "important keywords? Add keywords to your paper so you won't miss anything! " "All the keywords you add will be searchable, as if they were directly " "written on the paper you scanned." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:89 msgid "" "You would like to organize your documents a bit more? You can also add " "labels to your documents. Each label has its own color. With time, Paperwork " "will learn which labels go on which documents and will automatically apply " "them on new documents." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:92 msgid "Your first documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:102 msgid "" "Click the + button, the scan button, and that's all folks! You are now aware " "of the main features of Paperwork. You can start using it by adding your " "first own paper." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:105 msgid "" "This document will automatically disappear from your document list as soon " "as you have created or imported your first document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:108 msgid "Need more help ?" msgstr "éœ€è¦æ›´å¤šå¸®åŠ© ?" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:116 msgid "" "If you need more help, there is a comprehensive manual you can find in the " "help section of Paperwork." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/intro.tex:119 msgid "" "We hope that you'll enjoy this piece of software. If you like it please tell " "us, and if you don't please tell us why!" msgstr "" #. type: hypersetup{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "" "colorlinks, citecolor=black, filecolor=black, linkcolor=black, " "urlcolor=black, linktoc=all," msgstr "" #. type: title{#1} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:20 msgid "Paperwork manual" msgstr "Paperwork 手册" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:32 msgid "Introduction" msgstr "介ç»" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:41 msgid "" "Most personal documents are fairly recurrent: earning statements, rent " "bills, electricity bills, etc. For most unorganized people, having to find " "them back later is worrisome, at best. For most organized people, naming and " "sorting them is as tedious as watching paint dry." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:45 msgid "" "The main idea behind Paperwork is that managing documents is a computer " "job. Humans should do as little as possible while machines do most of the " "work. The end goal here is \"scan \\& forget\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:49 msgid "" "If you're looking for a software that will let you name each document " "individually, organize them in complex hierachy, tag them manually each " "time, fix OCR minor glitches, etc, then Paperwork is not for you." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:52 msgid "Definitions" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:54 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:158 msgid "Work directory" msgstr "工作目录" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:57 msgid "" "Paperwork stores all your documents in a single directory: the work " "directory. In this directory, each document has its own sub-directory." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:61 msgid "" "While this makes Paperwork hard to use with other tools, it has one major " "advantage: You don't have to worry about file names and directory structures " "anymore." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:63 msgid "Document" msgstr "文档" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:71 msgid "" "In Paperwork, a document is a set of pages. On disk, it can either be a set " "of JPEG files or a PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:74 msgid "" "Documents are identified only by a date. It can either be the date you " "imported them (default) or some date of your choosing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:77 msgid "" "They are displayed on the left side of the main window (green part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:80 msgid "Page" msgstr "页é¢" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:82 msgid "" "In Paperwork, a page is just an image and the word positions on this image." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:88 msgid "" "Images can come from a scanner or be imported. In those cases, it is stored " "as a JPEG files and text is extracted using OCR (Optical Character " "Recognition). OCR is a fairly long process. It can take up to a few minutes " "for each page. So the text extracted from images is stored in hOCR files " "beside the JPEG files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:91 msgid "" "Pages can also be the pages from a PDF file. In that case, by default, " "Paperwork just stores a copy of the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:95 msgid "" "Paperwork does not track whether a page is recto or verso. Paperwork does " "not track the paper size corresponding to a page (A4, Letter, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:98 msgid "" "Pages are displayed on the right side of the main window (blue part on the " "screenshot above)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:101 msgid "Indexation and Keywords" msgstr "索引和关键字" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:108 msgid "" "Of course, you need a way to find back your documents. Paperwork manages an " "index with all the keywords found in your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:110 msgid "Just type in a few keywords, and you will get your documents back." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:128 msgid "" "Unfortunately, sometimes, documents don't contain the keywords needed to " "find them back. Also OCR is not a perfectly realiable process and may not " "work." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:131 msgid "" "To mitigate those issues, you can add labels (or tags) on your documents and " "provide additional keywords. Both are added to the index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:134 msgid "" "Labels are displayed beside documents. Additional keywords are almost never " "displayed." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:137 msgid "Settings" msgstr "设置" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:139 msgid "Accessing the settings" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:166 msgid "" "The work directory is the directory where you want all your documents " "stored. It can be a standard folder, a folder synchronized across multiple " "computers or on a network share." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:169 msgid "" "Once you close the settings dialog, the work directory will be scanned and " "Paperwork index will be updated according to its index." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:172 msgid "" "Each time Paperwork starts, it will look for changes in this folder and " "synchronize its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:175 msgid "Scanner" msgstr "扫æä»ª" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:182 msgid "Device" msgstr "设备" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:189 msgid "" "When starting, Paperwork looks for scanners. The scanner to use can be " "selected in the settings." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:191 msgid "Webcams, file storage, etc, cannot be used. Only paper-eaters." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:194 msgid "Scan Mode" msgstr "æ‰«ææ¨¡å¼" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:202 msgid "" "Most modern scanners scan in color in a reasonable time. However some older " "scanners scan much faster in grayscale or even in black\\&white. Here you " "can select the mode to use." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:205 msgid "Scan Resolution" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:212 msgid "" "Scanner resolution defines how detailed the images coming from your scanner " "must be." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "Higher resolutions mean" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "longer OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "more space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:221 msgid "but also better OCR." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "Lower resolutions mean" msgstr "较低的分辨率æ„味ç€" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter scans," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "shorter OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less time to display," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "less space used on disk," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "but also inferior OCR," msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:231 msgid "and possibly unreadable image (even by a human)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:234 msgid "" "300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi " "on slow computers." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:237 msgid "Scanner calibration" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:247 msgid "" "Scanners tend to provide images actually bigger than the scanned pages. " "Since most of the time, you will always scan pages having the same size (A4 " "or Letter usually), Paperwork provides an option called scanner calibration. " "Scanner calibration in Paperwork is simply an area that will always be " "cropped out of images coming from the scanner." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:250 msgid "OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:257 msgid "" "By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls " "back on Cuneiform." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:260 msgid "" "On Linux, if installed with Flatpak, Paperwork is always provided with " "Tesseract. On Windows, Paperwork is always provided with Tesseract." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:263 msgid "" "To get better results, OCR tool need to know the language used in the " "document(s)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:268 msgid "" "The language available in the settings dialog of Paperwork are those " "understood by the OCR tool. If your language is not in the list, it means " "the OCR tool doesn't have the data required to read your language and you " "must install them." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:271 msgid "Adding languages" msgstr "添加语言" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:273 msgid "Flatpak" msgstr "Flatpak" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:279 #, fuzzy, no-wrap #| msgid "" #| "# is a list of 2-letters language codes separated ';'\n" #| "# ex: en;fr;de\n" #| "flatpak config --user --set languages \"\"\n" #| "flatpak update" msgid "" "# is a list of 2-letters language codes separated ';'\n" "# ex: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update --user" msgstr "" "# 是使用 ';'分开的åŒå­—æ¯è¯­è¨€ä»£ç åˆ—表\n" "# 例如: en;fr;de\n" "flatpak config --user --set languages \"\"\n" "flatpak update" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:283 msgid "Debian" msgstr "Debian" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:288 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:304 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" msgstr "" "# 是一个三字语言ç \n" "# 例如: 'fra' 表示 French\n" "$ sudo apt-get install tesseract-ocr tesseract-ocr-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:291 msgid "Fedora" msgstr "Fedora" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:296 #, no-wrap msgid "" "# is a 3-letter language code\n" "# ex: 'fra' for French\n" "$ sudo dnf install tesseract tesseract-langpack-" msgstr "" "# 是一个三字语言ç \n" "# 例如: 'fra' 表示 French\n" "$ sudo dnf install tesseract tesseract-langpack-" #. type: paragraph{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:299 msgid "Ubuntu" msgstr "Ubuntu" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:307 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:815 msgid "Windows" msgstr "Windows" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:310 msgid "" "Tesseract and all its data files are provided by Paperwork's installer. You " "can rerun the installer to install other languages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:314 msgid "" "If a language is not available in the installer, it either means it hasn't " "been packaged (in which case you can request it), or there is no data file " "available yet for this language." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:317 msgid "Disabling OCR" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:323 msgid "" "When you scan a page using Paperwork, Paperwork will immediately run the OCR " "on it. This process may take a while for each page. In case you want to scan " "a lot of pages quickly (for instance, the first time you use Paperwork), OCR " "can be temporarily disabled. To disable OCR, you simply have to unselect all " "OCR languages." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:326 msgid "Updates" msgstr "æ›´æ–°" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:334 msgid "" "If you enable this option, when Paperwork starts, Paperwork will look for " "updates if it hasn't done so for a week or more. To know if a new version is " "available, it has to send an HTTPS query to 'openpaper.work'." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:336 msgid "If an update is found, it will notify you but it won't install it." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:339 msgid "New document" msgstr "新建文档" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:345 msgid "" "By default, in the document list, Paperwork includes a document called \"New " "document\". If you open it, it always appears empty. This document actually " "doesn't exist yet on disk, but will exist as soon as you put a page in it. " "You can add pages in it by scanning, importing file(s) or dropping a page " "from another in it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:350 msgid "" "As soon as you put any content in it, this document will get its own date " "(the current one by default). In the document list, \"New document\" will be " "replaced by this date, and a new \"New document\" will be added to the " "document list." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:359 msgid "" "If you are currently searching something (see the chapter \"Searching\"), " "only search results are displayed and therefore this \"New document\" isn't " "displayed. You can get it back by clicking the button \"+\" in the top left " "corner of the main window." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:362 msgid "Scanning" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:368 msgid "" "If a scanner has been selected in the settings, you can use it to scan pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:372 msgid "" "In the header bar, there is a button to add pages. The small arrow on the " "right gives access to possible page sources. Those page sources include your " "scanner sources (Flatbed, Feeder)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:375 msgid "" "Once you've selected the scanner source you want to use, you can click on " "the button \"Scan from ...\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:377 msgid "This will start a scan session:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "" "Scanned pages are appended at the end of the current document. If you use a " "feeder, Paperwork will scan pages until the feeder is empty." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will then crop them according to scanner calibration." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will run OCR on them" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:386 msgid "Paperwork will index them" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:389 msgid "" "If this scan session creates a new document, Paperwork will try to set " "labels automatically on the document." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:392 msgid "Importing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:399 msgid "Images" msgstr "图åƒ" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:402 msgid "" "Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, " "TIFF, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:404 msgid "Each image file is considered as a page." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:408 msgid "" "Images are always appended to the document currently opened. Simply select " "an empty document (\"New document\") to create a new document while " "importing." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:412 msgid "" "OCR is always run on imported images. If the imported image is the first " "page of a new document, Paperwork will automatically apply documents labels." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:416 msgid "" "Note that Paperwork is a document manager. While it can, it is not designed " "to handle images with only very little text or photos. Automatic labeling " "will not work correctly on such documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:420 msgid "" "The OCR (Tesseract) works very well with black text on white background. " "Automatic labeling uses recognized text and requires as many keywords on the " "first page as possible." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:423 msgid "PDF" msgstr "PDF" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:429 msgid "" "Each PDF is always considered as a whole document. They are never appended " "to existing document. They are copied and renamed in the work directory, but " "their content is not modified. Paperwork always keeps the original PDF file " "as is, even if you edit some of its pages: the edited pages are stored " "beside the PDF file." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:434 msgid "" "Paperwork will look for pages with no text attached. On those pages, it will " "automatically run OCR. Once all the pages have been examined, it will " "automatically apply document labels. Note that this process may take a few " "minutes for big PDFs files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:437 msgid "" "If the PDF is already part of your documents, Paperwork will simply ignore " "it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:440 msgid "Many PDFs in one shot" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:445 msgid "" "When importing, if you select a folder, Paperwork will browse this folder " "and look for PDFs to import. Already-imported PDFs are simply ignored. " "Folder is browsed recursively (all the folders inside the folder are also " "examined)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:448 msgid "Labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:464 msgid "" "There is currently one constraint in Paperwork: Each label must be on at " "least one document. Otherwise, when you will restart Paperwork, labels " "without documents will disappear." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:467 msgid "Creating new labels" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:475 msgid "" "You can click on the gray rectangle on the left side to pick the label " "color. You can enter the label name in text field between the gray " "rectangle and the button \"+\"." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:478 msgid "" "Once you click on the button \"+\", the label will be added to the current " "document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:481 msgid "" "The label is actually added once you close document properties. Paperwork " "will then update its index accordingly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:484 msgid "Setting labels on documents" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:488 msgid "" "When you open document properties, the label list appears. On the left side " "of each label color, you have a button. This button allows you to add or " "remove labels on the current document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:491 msgid "" "The changes are actually written on disk once you close the document " "properties. Paperwork will update its index accordinly." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:494 msgid "Modifying a label color" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:497 msgid "" "When you open document properties, you can click on a label color to change " "it. A dialog will let you pick the new color." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:501 msgid "" "Label color will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:504 msgid "Modifying a label name" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:507 msgid "" "When you open document properties, you can click on a label string to change " "it. A dialog will let you type in the new name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:511 msgid "" "Label name will actually be changed on disk when you close the document " "properties. Paperwork will then update the label on all the documents that " "use it and then reindex them all." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:514 msgid "Deleting a label" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:517 msgid "" "To the right of each label is white-on-black cross button. Clicking on it " "will allow you to delete a label." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:520 msgid "" "Once you will close the document properties, the label will be removed from " "all the documents having it. Paperwork will then update its index " "accordingly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:523 msgid "" "Beware: Once you have closed document properties, there is no way to put " "back the deleted label." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:526 msgid "Automatic label guessing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:531 msgid "" "Paperwork does use artificial intelligence. It uses a fairly simple method " "actually: \\href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive " "Bayes classifiers}. It's the same technology used by email clients to " "classify mails as spam/non-spam." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:537 msgid "" "Based on all the keywords in all your documents that have (or haven't) a " "label, it can estimate a probability that a document containing the same " "keywords should have or shouldn't have this same label. If the probability " "is high enough, it puts the label on the document automatically when you " "import it or scan it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:541 msgid "" "Of course, this approach means that Paperwork needs enough samples to work " "reliably. You can expect it to start working once you have about 100 " "documents or more (and only for labels that are on more than 10 documents or " "more)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:544 msgid "Searching" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:546 msgid "Simple search" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:553 msgid "" "You simply enter keywords in the search field. In a few seconds, you will " "get all the documents containing those keywords." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:557 msgid "" "Paperwork does a \"fuzzy\" search: documents with keywords close to the one " "you gave but not identical are also returned (for instance, 'flech' instead " "of 'flesch')." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:562 msgid "" "You can also use \\href{https://whoosh.readthedocs.io/en/latest/querylang." "html}{Whoosh query language} to make more complex queries. If you want " "examples, you can use the advanced search dialog described below." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:565 msgid "Advanced search" msgstr "高级æœç´¢" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:582 msgid "" "The advanced search dialog helps creating complex search queries. You can " "specify various criterias and once you click on the apply button, it will " "generate a search query for you and put it immediately in the search field. " "Search results will immediately be refreshed as well." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:585 msgid "Viewing" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:591 msgid "Zoom level" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:597 msgid "" "You can change the scale at which pages are displayed using this control." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:600 msgid "View pages as grid" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:608 msgid "" "When clicking this button, Paperwork will try to display pages on 3 " "columns. In this mode, you can drag'n'drop pages to move them inside the " "document or to another document." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:611 msgid "View pages as list" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:619 msgid "" "When clicking this button, pages will be scaled so their width is the " "maximum width allowed by the main window. In this mode, you can select text " "in the page (and then copy it)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:621 msgid "Highlight all words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:629 msgid "" "This option allows to see quickly all the words identified by OCR. Sometimes " "(rarely) OCR misses entire chunk in a page. This option allow to see such " "chunk quickly." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:631 msgid "Moving pages" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:633 msgid "Inside a document" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:635 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:644 msgid "You must display the document pages as a grid (See \\ref{layout:grid})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:640 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "wherever you want in a document. While dragging, a blue marker will show you " "where the page would drop if you release the left click button of your mouse." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:642 msgid "From a document to another" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:647 msgid "" "You can then grab a page (hold the left click button), drag it and drop it " "in the document list, on the document in which you want the page to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:649 msgid "Copying text" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:655 msgid "" "You must display the document pages as a list (See \\ref{layout:paged})." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:658 msgid "" "You can then select text in a page. Hold the left click button to start " "selecting, mouse the mouse cursor to select more words, then release it." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:662 msgid "" "You can then copy the selected text, either by pressing Ctrl-C or by using " "the page menu at the bottom right of the main window. Once copied, you can " "paste the selected text in any other application (Ctrl-V)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:664 msgid "Editing a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:670 msgid "Paperwork includes a very simple image editor. It provides 4 functions:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Cropping" msgstr "è£å‰ª" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by 90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "Rotating the page by -90\\degree (can be rotated multiple times)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:679 msgid "" "Automatic Color Equalization: An algorithm that adjust the image brightness, " "contrast and colors to make it as readable as possible." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:681 msgid "Reseting a page" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:684 msgid "" "Reseting a page returns it to its state when it was scanned or imported, " "before any pre-processing did occur." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:688 msgid "" "This can be helpful if you made a bad modification on the page (cropped a " "wrong area for instance), if the calibration settings weren't appropriate or " "if pre-processing algorithms messed up the page." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:691 msgid "Deleting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:694 msgid "" "When deleting either documents or pages, they are actually moved in the " "trash bin of your computer." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:698 msgid "" "\\textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from " "moving files to the trash (we are working on it). In that case, Paperwork " "will delete the file directly (no recovery possible)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:701 msgid "Exporting" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:703 msgid "You can export both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:707 msgid "" "In both cases, various transformations can be applied before actually " "exporting them. For instance, you can turn color pages into grayscale pages " "before putting them in a brand new PDF (making the resulting PDF smaller)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:710 msgid "Printing" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:712 msgid "You can print both documents or single pages." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:715 msgid "" "Beware that pages are always sent as images to your printer. So for very big " "documents, a few minutes may go by before the actual printing start." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:718 msgid "Backup" msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:720 msgid "Synchronisation between multiple computers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:726 msgid "" "While Paperwork is a personal document manager, it is not a file " "synchronization application. They are applications dedicated to file " "synchronization that already do that very well. Therefore Paperwork is " "designed to be used with such applications (Nextcloud, Dropbox, OneDrive, " "SparkleShare, etc)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:733 msgid "" "When you start Paperwork, one of the first things it does is check the " "content of the work directory. It looks for any changes and updates its " "document list and index accordingly, automatically. So if another instance " "of Paperwork on another computer modified something in the work directory " "and if this change has been synchronized on another computer, the other " "Paperwork will automatically pick up this change when starting." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:736 msgid "USB key / USB drive" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:739 msgid "" "This is the simplest way to share documents. Simply copy your work directory " "to an USB key, tell Paperwork to use it, and you're done." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:741 msgid "" "Beware: You should backup your USB key from time to time on another one." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:744 msgid "File Synchronization applications" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:750 msgid "" "Those applications synchronize a local directory with a remote server (or " "cloud). All the changes you do in your folder are applied on the server. All " "the changes applied on the servers are applied to the computers that connect " "to it. The server can belong to you or to someone else (usually a company)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:754 msgid "" "Beware: If you choose to host your documents on someone else server " "(DropBox, OneDrive, etc), they can access all your documents. Paperwork does " "not encrypt them." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:758 msgid "" "Paperwork is tested daily with Nextcloud. While this is not the easiest one " "to install, Nextcloud let you host your files yourself. There are other self-" "hosted alternatives that exist: SparkleShare, Syncthing, etc." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:761 msgid "" "Using DropBox or OneDrive can make sense if you're sharing not-so-" "confidential documents with others (associations, etc)." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:764 msgid "Shared folder" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:769 msgid "" "If all your computers are on the same network, you can share your work " "directory. However, be really careful regarding permissions. Being too " "permissive could let a pirate access all your personal documents ! And " "setting them correctly is tricky." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:772 msgid "" "Beware: Using a shared folder means having a single copy of your work " "directory. You should do regular backups of your work directory." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:775 msgid "Encryption" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:777 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1024 msgid "GNU/Linux" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:779 msgid "" "GNU/Linux distributions include many tools to encrypt whole directories." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "With Paperwork, there are 2 directories that should be encrypted to protect " "your privacy:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "Your work directory (by default \\textasciitilde /papers, can be changed in " "the settings)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:789 msgid "" "The cache directory (\\textasciitilde /.local/share/paperwork2, cannot be " "changed) (it contains index files from which the content of your documents " "could be partially recovered)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:793 msgid "" "Note that if you want to be sure that your data are always encrypted, it's " "recommended to encrypt your whole home directory or even your whole system " "if possible." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:795 msgid "cryptsetup" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:799 msgid "" "Most GNU/Linux distribution installer now provide an optio4n to encrypt your " "whole system or your whole /home with cryptsetup . This is the recommended " "method to protect your documents." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:801 msgid "Encfs" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:803 msgid "Encfs can also be used to create encrypted directories easily." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:807 msgid "" "Beware that Encfs seems to have some security weaknesses. So, while it's " "probably enough to prevent a laptop thief from accessing your documents, " "it's likely to be not enough to prevent the NSA or the police from doing " "so ;-)." msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:811 #, no-wrap msgid "" "$ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2\n" "$ encfs ~/.papers ~/papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:818 msgid "" "On Windows, you're strongly advised to enable BitLocker to protect your " "documents. If unavailable, there are other applications (Veracrypt, etc)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:821 msgid "Keyboard shortcuts" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:832 msgid "" "Keyboard shortcuts can be seen by opening the application menu, selecting " "\"Help\" and then \"Shortcuts\"." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:835 msgid "Paperwork's files locations" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "By default:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Configuration: \\textasciitilde /.config/paperwork2.conf" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Index: \\textasciitilde /.local/share/paperwork2" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "Documents: \\textasciitilde /papers" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:844 msgid "" "(same paths are used on Windows; \\textasciitilde{} = C:\\textbackslash " "Users{[}login{]} ; folders are hidden)" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:848 msgid "" "The index is always updated according based on the documents in the work " "directory. When Paperwork starts, the modification time of each file is used " "to detect changes on the documents." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:850 msgid "Work directory layout" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:852 msgid "workdir$|$rootdir = \\textasciitilde /papers (by default)" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:854 msgid "Global organisation" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:856 msgid "In the work directory, you have folders, one per document." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:860 msgid "" "The folder names are (usually) the scan/import date of the document: " "YYYYMMDD\\_hhmm\\_ss{[}\\_{]}. The suffix 'idx' is optional and is just " "a number added in case of name collision." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "In every folder you have:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "For image documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X " "starts at 1)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR (optional, but required for indexing ; can be " "regenerated with the options \"Redo OCR\")." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 msgid "" "paper.1.thumb.jpg (optional, generated automatically): A thumbnail version " "of the page (faster to load)" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "labels (optional): a text file containing the labels applied on this document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:875 #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "extra.txt (optional): extra keywords added by the user" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "For PDF documents:" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "doc.pdf: the document" msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "paper.$<$X$>$.words (optional): A hOCR file, containing all the words found " "on the page using the OCR. Some PDF contains crap instead of the real text, " "so running the OCR on them can sometimes be useful." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "passwd.txt (optional): PDF password, if the PDF is password-protected." msgstr "" #. type: itemize #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:892 msgid "" "doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc." "pdf) so Paperwork can parse and display it more quickly." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:894 msgid "Here is an example a work directory organisation:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:926 #, no-wrap msgid "" "$ find ~/papers\n" "/home/jflesch/papers\n" "/home/jflesch/papers/20130505_1518_00\n" "/home/jflesch/papers/20130505_1518_00/paper.1.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.1.words\n" "/home/jflesch/papers/20130505_1518_00/paper.2.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.2.words\n" "/home/jflesch/papers/20130505_1518_00/paper.3.jpg\n" "/home/jflesch/papers/20130505_1518_00/paper.3.words\n" "/home/jflesch/papers/20130505_1518_00/labels\n" "/home/jflesch/papers/20110726_0000_01f\n" "/home/jflesch/papers/20110726_0000_01/paper.1.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.1.words\n" "/home/jflesch/papers/20110726_0000_01/paper.2.jpg\n" "/home/jflesch/papers/20110726_0000_01/paper.2.words\n" "/home/jflesch/papers/20110726_0000_01/extra.txt\n" "/home/jflesch/papers/20130106_1309_44\n" "/home/jflesch/papers/20130106_1309_44/doc.pdf\n" "/home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg\n" "/home/jflesch/papers/20130106_1309_44/paper.2.words\n" "/home/jflesch/papers/20130106_1309_44/labels\n" "/home/jflesch/papers/20130106_1309_44/extra.txt\n" "/home/jflesch/papers/20130106_1309_44/passwd.txt\n" "/home/jflesch/papers/20130520_1309_44\n" "/home/jflesch/papers/20130520_1309_44/doc.pdf\n" "/home/jflesch/papers/20130520_1309_44/doc.docx\n" "/home/jflesch/papers/20130520_1309_44/labels" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:929 msgid "hOCR files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:931 msgid "With Tesseract, the hOCR file can be obtained with following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:933 #, no-wrap msgid "tesseract paper..jpg paper. -l hocr && mv paper..html paper..words" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:935 msgid "For example:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:937 #, no-wrap msgid "tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words" msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:940 msgid "Label files" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:942 msgid "Here is an example of content of a label file:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:944 #, no-wrap msgid "facture,#0000b1588c61 logement,#f6b6ffff0000" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:947 msgid "" "It's always $[$label$]$,$[$color$]$. For a same label, the color should " "always be the same." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:950 msgid "Getting support" msgstr "获得支æŒ" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:953 msgid "" "A forum dedicated to Paperwork exists: \\href{https://forum.openpaper.work}" "{https://forum.openpaper.work}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:956 msgid "" "There is also an IRC channel for live discussions: \\href{https://web.libera." "chat/}{Liberachat}, channel \\#paperwork" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:959 msgid "" "If you have questions regarding Paperwork or simply want to chat, those are " "the places to go." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:961 msgid "Reporting issues" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:964 msgid "" "If you noticed a bug in Paperwork (and you are sure it's a bug), you can " "make a bug report." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:966 msgid "Bug Tracker" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:969 msgid "" "One way to create bug reports is to create tickets on \\href{https://gitlab." "gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: " "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:972 msgid "" "This is the recommended way to submit a bug report if you would like to " "discuss it with Paperwork developpers." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:975 msgid "" "To make sure you include all the required informations, you can use the tool " "integrated in Paperwork (see below)." msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:978 msgid "Automatic bug report" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:985 msgid "" "Paperwork includes a tool to make reporting bugs easier. It allows you to " "get easily all the required information to make a perfect bug report." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:989 msgid "" "All attachments are automatically censored to protect your privacy: Document " "contents are blurred in screenshots and logs are censored to remove your " "user name." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:992 msgid "" "If the bug you want to report is related to scanners, please include " "\"Scanner info.\" in the bug report files." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:995 msgid "" "If te bug you want to report is related to a display problem, please include " "\"App. screenshots\" in the bug report files." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:998 msgid "ZIP file" msgstr "ZIP 文件" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1002 msgid "" "You can then obtain a ZIP file with all the data. Please make sure the " "content of the ZIP file does not contain private information (it shouldn't, " "but better safe than sorry). Then you can add this ZIP file to a ticket on " "Gitlab." msgstr "" #. type: subsubsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1005 msgid "Automatic submission" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1009 msgid "" "You can also let the tool submit the bug report to openpaper.work " "automatically. In that case, you won't be able to discuss the bug with " "developers (or you have to leave a way to contact you in the bug report)." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1016 msgid "" "If you use the automatic submission , the tool will give you an URL to see " "the submitted bug report. This URL is private and shouldn't be shared until " "you made sure there is no private information in the bug report. If there is " "private information, you can request deletion of the bug report by sending " "an email to jflesch@openpaper.work (please specify the private URI in your " "mail so we can be sure that you are the one who submitted the bug report)." msgstr "" #. type: section{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1019 msgid "Uninstalling" msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1022 msgid "" "Paperwork can be uninstalled. Uninstalling Paperwork \\emph{will never} " "remove your work directory or your documents." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1028 msgid "" "If you installed Paperwork using the package manager from your distribution " "(the recommended way), the uninstallation method depends on the package " "manager." msgstr "" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1031 msgid "" "For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command " "will take care of it:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1034 #, no-wrap msgid "sudo apt remove --purge paperwork-\\*" msgstr "sudo apt remove --purge paperwork-\\*" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1037 msgid "If you installed it using Flatpak, you can use the following command:" msgstr "" #. type: verbatim #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1040 #, no-wrap msgid "flatpak --user uninstall work.openpaper.Paperwork" msgstr "" #. type: subsection{#2} #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1043 msgid "Windows 10" msgstr "Windows 10" #. type: document #: /home/jflesch/git/paperwork/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex:1047 msgid "" "Paperwork can be uninstalled as any Windows applications, by going in " "Windows Control Panel, clicking on \"Applications\", finding Paperwork in " "the list, and then clicking on \"uninstall\"." msgstr "" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/paperwork_going_up.svg000066400000000000000000000300621456262201400313600ustar00rootroot00000000000000 image/svg+xml paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/usage.tex000066400000000000000000001014311456262201400265630ustar00rootroot00000000000000\documentclass[10pt,a4paper]{article} \usepackage[utf8]{inputenc} \usepackage{amsfonts} \usepackage{amssymb} \usepackage{float} \usepackage{gensymb} \usepackage{graphicx} \usepackage{hyperref} \usepackage{wrapfig} \hypersetup{ colorlinks, citecolor=black, filecolor=black, linkcolor=black, urlcolor=black, linktoc=all, } \date{} \title{Paperwork manual} \begin{document} \maketitle \pagebreak \tableofcontents \pagebreak \section{Introduction} \begin{figure}[H] \includegraphics{data/user_manual_intro.png} \end{figure} Most personal documents are fairly recurrent: earning statements, rent bills, electricity bills, etc. For most unorganized people, having to find them back later is worrisome, at best. For most organized people, naming and sorting them is as tedious as watching paint dry. The main idea behind Paperwork is that managing documents is a computer job. Humans should do as little as possible while machines do most of the work. The end goal here is "scan \& forget". If you're looking for a software that will let you name each document individually, organize them in complex hierachy, tag them manually each time, fix OCR minor glitches, etc, then Paperwork is not for you. \section{Definitions} \subsection{Work directory} Paperwork stores all your documents in a single directory: the work directory. In this directory, each document has its own sub-directory. While this makes Paperwork hard to use with other tools, it has one major advantage: You don't have to worry about file names and directory structures anymore. \subsection{Document} \begin{figure}[H] \includegraphics[scale=0.33]{out/main_window_split.png} \end{figure} In Paperwork, a document is a set of pages. On disk, it can either be a set of JPEG files or a PDF file. Documents are identified only by a date. It can either be the date you imported them (default) or some date of your choosing. They are displayed on the left side of the main window (green part on the screenshot above). \subsection{Page} In Paperwork, a page is just an image and the word positions on this image. Images can come from a scanner or be imported. In those cases, it is stored as a JPEG files and text is extracted using OCR (Optical Character Recognition). OCR is a fairly long process. It can take up to a few minutes for each page. So the text extracted from images is stored in hOCR files beside the JPEG files. Pages can also be the pages from a PDF file. In that case, by default, Paperwork just stores a copy of the PDF file. Paperwork does not track whether a page is recto or verso. Paperwork does not track the paper size corresponding to a page (A4, Letter, etc). Pages are displayed on the right side of the main window (blue part on the screenshot above). \subsection{Indexation and Keywords} \begin{figure}[H] \includegraphics[scale=0.33]{out/search.png} \end{figure} Of course, you need a way to find back your documents. Paperwork manages an index with all the keywords found in your documents. Just type in a few keywords, and you will get your documents back. \subsection{Labels and additional keywords} \begin{figure}[H] \centering \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/doc_labels.png} \end{minipage}% \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/doc_extra_text.png} \end{minipage} \end{figure} Unfortunately, sometimes, documents don't contain the keywords needed to find them back. Also OCR is not a perfectly realiable process and may not work. To mitigate those issues, you can add labels (or tags) on your documents and provide additional keywords. Both are added to the index. Labels are displayed beside documents. Additional keywords are almost never displayed. \section{Settings} \subsection{Accessing the settings} \begin{figure}[H] \centering \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/app_menu.png} \end{minipage}% \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.5]{out/app_menu_opened.png} \end{minipage} \end{figure} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings.png} \end{figure} \subsection{Work directory} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_storage.png} \end{figure} The work directory is the directory where you want all your documents stored. It can be a standard folder, a folder synchronized across multiple computers or on a network share. Once you close the settings dialog, the work directory will be scanned and Paperwork index will be updated according to its index. Each time Paperwork starts, it will look for changes in this folder and synchronize its index accordingly. \subsection{Scanner} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_scanner.png} \end{figure} \subsubsection{Device} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_scanner_device.png} \end{figure} When starting, Paperwork looks for scanners. The scanner to use can be selected in the settings. Webcams, file storage, etc, cannot be used. Only paper-eaters. \subsubsection{Scan Mode} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_scanner_mode.png} \end{figure} Most modern scanners scan in color in a reasonable time. However some older scanners scan much faster in grayscale or even in black\&white. Here you can select the mode to use. \subsubsection{Scan Resolution} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_scanner_resolution.png} \end{figure} Scanner resolution defines how detailed the images coming from your scanner must be. Higher resolutions mean \begin{itemize} \item longer scans, \item longer OCR, \item more time to display, \item more space used on disk, \item but also better OCR. \end{itemize} Lower resolutions mean \begin{itemize} \item shorter scans, \item shorter OCR, \item less time to display, \item less space used on disk, \item but also inferior OCR, \item and possibly unreadable image (even by a human). \end{itemize} 300 dpi is considered a good trade-off. You may want to reduce it to 200 dpi on slow computers. \subsubsection{Scanner calibration} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_calibration_dialog.png} \end{figure} Scanners tend to provide images actually bigger than the scanned pages. Since most of the time, you will always scan pages having the same size (A4 or Letter usually), Paperwork provides an option called scanner calibration. Scanner calibration in Paperwork is simply an area that will always be cropped out of images coming from the scanner. \subsection{OCR} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_optical_character_recognition.png} \end{figure} By default, Paperwork uses Tesseract for the OCR. If unavailable, it falls back on Cuneiform. On Linux, if installed with Flatpak, Paperwork is always provided with Tesseract. On Windows, Paperwork is always provided with Tesseract. To get better results, OCR tool need to know the language used in the document(s). The language available in the settings dialog of Paperwork are those understood by the OCR tool. If your language is not in the list, it means the OCR tool doesn't have the data required to read your language and you must install them. \subsubsection{Adding languages} \paragraph{Flatpak} \begin{verbatim} # is a list of 2-letters language codes separated ';' # ex: en;fr;de flatpak config --user --set languages "" flatpak update --user \end{verbatim} \paragraph{Debian} \begin{verbatim} # is a 3-letter language code # ex: 'fra' for French $ sudo apt-get install tesseract-ocr tesseract-ocr- \end{verbatim} \paragraph{Fedora} \begin{verbatim} # is a 3-letter language code # ex: 'fra' for French $ sudo dnf install tesseract tesseract-langpack- \end{verbatim} \paragraph{Ubuntu} \begin{verbatim} # is a 3-letter language code # ex: 'fra' for French $ sudo apt-get install tesseract-ocr tesseract-ocr- \end{verbatim} \paragraph{Windows} Tesseract and all its data files are provided by Paperwork's installer. You can rerun the installer to install other languages. If a language is not available in the installer, it either means it hasn't been packaged (in which case you can request it), or there is no data file available yet for this language. \subsubsection{Disabling OCR} When you scan a page using Paperwork, Paperwork will immediately run the OCR on it. This process may take a while for each page. In case you want to scan a lot of pages quickly (for instance, the first time you use Paperwork), OCR can be temporarily disabled. To disable OCR, you simply have to unselect all OCR languages. \subsection{Updates} \begin{figure}[H] \includegraphics[scale=0.33]{out/settings_updates.png} \end{figure} If you enable this option, when Paperwork starts, Paperwork will look for updates if it hasn't done so for a week or more. To know if a new version is available, it has to send an HTTPS query to 'openpaper.work'. If an update is found, it will notify you but it won't install it. \section{New document} By default, in the document list, Paperwork includes a document called "New document". If you open it, it always appears empty. This document actually doesn't exist yet on disk, but will exist as soon as you put a page in it. You can add pages in it by scanning, importing file(s) or dropping a page from another in it. As soon as you put any content in it, this document will get its own date (the current one by default). In the document list, "New document" will be replaced by this date, and a new "New document" will be added to the document list. \begin{figure}[H] \includegraphics[scale=0.33]{out/doc_new_button.png} \end{figure} If you are currently searching something (see the chapter "Searching"), only search results are displayed and therefore this "New document" isn't displayed. You can get it back by clicking the button "+" in the top left corner of the main window. \section{Scanning} \begin{figure}[H] \includegraphics[scale=0.33]{out/page_add.png} \end{figure} If a scanner has been selected in the settings, you can use it to scan pages. In the header bar, there is a button to add pages. The small arrow on the right gives access to possible page sources. Those page sources include your scanner sources (Flatbed, Feeder). Once you've selected the scanner source you want to use, you can click on the button "Scan from ...". This will start a scan session: \begin{itemize} \item Scanned pages are appended at the end of the current document. If you use a feeder, Paperwork will scan pages until the feeder is empty. \item Paperwork will then crop them according to scanner calibration. \item Paperwork will run OCR on them \item Paperwork will index them \end{itemize} If this scan session creates a new document, Paperwork will try to set labels automatically on the document. \section{Importing} \begin{figure}[H] \includegraphics[scale=0.33]{out/page_add.png} \end{figure} \subsection{Images} Paperwork supports a lot of file formats. It supports JPEG, PNG, GIF, BMP, TIFF, etc. Each image file is considered as a page. Images are always appended to the document currently opened. Simply select an empty document ("New document") to create a new document while importing. OCR is always run on imported images. If the imported image is the first page of a new document, Paperwork will automatically apply documents labels. Note that Paperwork is a document manager. While it can, it is not designed to handle images with only very little text or photos. Automatic labeling will not work correctly on such documents. The OCR (Tesseract) works very well with black text on white background. Automatic labeling uses recognized text and requires as many keywords on the first page as possible. \subsection{PDF} Each PDF is always considered as a whole document. They are never appended to existing document. They are copied and renamed in the work directory, but their content is not modified. Paperwork always keeps the original PDF file as is, even if you edit some of its pages: the edited pages are stored beside the PDF file. Paperwork will look for pages with no text attached. On those pages, it will automatically run OCR. Once all the pages have been examined, it will automatically apply document labels. Note that this process may take a few minutes for big PDFs files. If the PDF is already part of your documents, Paperwork will simply ignore it. \subsection{Many PDFs in one shot} When importing, if you select a folder, Paperwork will browse this folder and look for PDFs to import. Already-imported PDFs are simply ignored. Folder is browsed recursively (all the folders inside the folder are also examined). \section{Labels} \begin{figure}[H] \centering \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/doc_properties_button.png} \end{minipage}% \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/doc_labels.png} \end{minipage} \end{figure} There is currently one constraint in Paperwork: Each label must be on at least one document. Otherwise, when you will restart Paperwork, labels without documents will disappear. \subsection{Creating new labels} \begin{figure}[H] \includegraphics[scale=0.33]{out/doc_new_label.png} \end{figure} You can click on the gray rectangle on the left side to pick the label color. You can enter the label name in text field between the gray rectangle and the button "+". Once you click on the button "+", the label will be added to the current document. The label is actually added once you close document properties. Paperwork will then update its index accordingly. \subsection{Setting labels on documents} When you open document properties, the label list appears. On the left side of each label color, you have a button. This button allows you to add or remove labels on the current document. The changes are actually written on disk once you close the document properties. Paperwork will update its index accordinly. \subsection{Modifying a label color} When you open document properties, you can click on a label color to change it. A dialog will let you pick the new color. Label color will actually be changed on disk when you close the document properties. Paperwork will then update the label on all the documents that use it. \subsection{Modifying a label name} When you open document properties, you can click on a label string to change it. A dialog will let you type in the new name. Label name will actually be changed on disk when you close the document properties. Paperwork will then update the label on all the documents that use it and then reindex them all. \subsection{Deleting a label} To the right of each label is white-on-black cross button. Clicking on it will allow you to delete a label. Once you will close the document properties, the label will be removed from all the documents having it. Paperwork will then update its index accordingly. Beware: Once you have closed document properties, there is no way to put back the deleted label. \subsection{Automatic label guessing} Paperwork does use artificial intelligence. It uses a fairly simple method actually: \href{https://en.wikipedia.org/wiki/Naive_Bayes_classifier}{Naive Bayes classifiers}. It's the same technology used by email clients to classify mails as spam/non-spam. Based on all the keywords in all your documents that have (or haven't) a label, it can estimate a probability that a document containing the same keywords should have or shouldn't have this same label. If the probability is high enough, it puts the label on the document automatically when you import it or scan it. Of course, this approach means that Paperwork needs enough samples to work reliably. You can expect it to start working once you have about 100 documents or more (and only for labels that are on more than 10 documents or more). \section{Searching} \subsection{Simple search} \begin{figure}[H] \includegraphics[scale=0.33]{out/search.png} \end{figure} You simply enter keywords in the search field. In a few seconds, you will get all the documents containing those keywords. Paperwork does a "fuzzy" search: documents with keywords close to the one you gave but not identical are also returned (for instance, 'flech' instead of 'flesch'). You can also use \href{https://whoosh.readthedocs.io/en/latest/querylang.html}{Whoosh query language} to make more complex queries. If you want examples, you can use the advanced search dialog described below. \subsection{Advanced search} \begin{figure}[H] \centering \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/advanced_search_button.png} \end{minipage}% \begin{minipage}{.5\textwidth} \centering \includegraphics[scale=0.33]{out/advanced_search.png} \end{minipage} \end{figure} The advanced search dialog helps creating complex search queries. You can specify various criterias and once you click on the apply button, it will generate a search query for you and put it immediately in the search field. Search results will immediately be refreshed as well. \section{Viewing} \begin{figure}[H] \includegraphics[scale=0.33]{out/docview_layout.png} \end{figure} \subsection{Zoom level} \begin{figure}[H] \includegraphics[scale=0.33]{out/docview_layout_scale.png} \end{figure} You can change the scale at which pages are displayed using this control. \subsection{View pages as grid} \label{layout:grid} \begin{figure}[H] \includegraphics[scale=0.33]{out/docview_layout_grid.png} \end{figure} When clicking this button, Paperwork will try to display pages on 3 columns. In this mode, you can drag'n'drop pages to move them inside the document or to another document. \subsection{View pages as list} \label{layout:paged} \begin{figure}[H] \includegraphics[scale=0.33]{out/docview_layout_paged.png} \end{figure} When clicking this button, pages will be scaled so their width is the maximum width allowed by the main window. In this mode, you can select text in the page (and then copy it). \subsection{Highlight all words} \begin{figure}[H] \includegraphics[scale=0.33]{out/docview_layout_show_all_boxes.png} \end{figure} This option allows to see quickly all the words identified by OCR. Sometimes (rarely) OCR misses entire chunk in a page. This option allow to see such chunk quickly. \section{Moving pages} \subsection{Inside a document} You must display the document pages as a grid (See \ref{layout:grid}). You can then grab a page (hold the left click button), drag it and drop it wherever you want in a document. While dragging, a blue marker will show you where the page would drop if you release the left click button of your mouse. \subsection{From a document to another} You must display the document pages as a grid (See \ref{layout:grid}). You can then grab a page (hold the left click button), drag it and drop it in the document list, on the document in which you want the page to go. \section{Copying text} \begin{figure}[H] \includegraphics[scale=0.33]{out/page_menu_opened.png} \end{figure} You must display the document pages as a list (See \ref{layout:paged}). You can then select text in a page. Hold the left click button to start selecting, mouse the mouse cursor to select more words, then release it. You can then copy the selected text, either by pressing Ctrl-C or by using the page menu at the bottom right of the main window. Once copied, you can paste the selected text in any other application (Ctrl-V). \section{Editing a page} \begin{figure}[H] \includegraphics[scale=0.33]{out/page_actions.png} \end{figure} Paperwork includes a very simple image editor. It provides 4 functions: \begin{itemize} \item Cropping \item Rotating the page by 90\degree (can be rotated multiple times) \item Rotating the page by -90\degree (can be rotated multiple times) \item Automatic Color Equalization: An algorithm that adjust the image brightness, contrast and colors to make it as readable as possible. \end{itemize} \section{Reseting a page} Reseting a page returns it to its state when it was scanned or imported, before any pre-processing did occur. This can be helpful if you made a bad modification on the page (cropped a wrong area for instance), if the calibration settings weren't appropriate or if pre-processing algorithms messed up the page. \section{Deleting} When deleting either documents or pages, they are actually moved in the trash bin of your computer. \textbf{Important note regarding Flatpak:} A bug may prevent Paperwork from moving files to the trash (we are working on it). In that case, Paperwork will delete the file directly (no recovery possible). \section{Exporting} You can export both documents or single pages. In both cases, various transformations can be applied before actually exporting them. For instance, you can turn color pages into grayscale pages before putting them in a brand new PDF (making the resulting PDF smaller). \section{Printing} You can print both documents or single pages. Beware that pages are always sent as images to your printer. So for very big documents, a few minutes may go by before the actual printing start. \section{Backup} \section{Synchronisation between multiple computers} While Paperwork is a personal document manager, it is not a file synchronization application. They are applications dedicated to file synchronization that already do that very well. Therefore Paperwork is designed to be used with such applications (Nextcloud, Dropbox, OneDrive, SparkleShare, etc). When you start Paperwork, one of the first things it does is check the content of the work directory. It looks for any changes and updates its document list and index accordingly, automatically. So if another instance of Paperwork on another computer modified something in the work directory and if this change has been synchronized on another computer, the other Paperwork will automatically pick up this change when starting. \subsection{USB key / USB drive} This is the simplest way to share documents. Simply copy your work directory to an USB key, tell Paperwork to use it, and you're done. Beware: You should backup your USB key from time to time on another one. \subsection{File Synchronization applications} Those applications synchronize a local directory with a remote server (or cloud). All the changes you do in your folder are applied on the server. All the changes applied on the servers are applied to the computers that connect to it. The server can belong to you or to someone else (usually a company). Beware: If you choose to host your documents on someone else server (DropBox, OneDrive, etc), they can access all your documents. Paperwork does not encrypt them. Paperwork is tested daily with Nextcloud. While this is not the easiest one to install, Nextcloud let you host your files yourself. There are other self-hosted alternatives that exist: SparkleShare, Syncthing, etc. Using DropBox or OneDrive can make sense if you're sharing not-so-confidential documents with others (associations, etc). \subsubsection{Shared folder} If all your computers are on the same network, you can share your work directory. However, be really careful regarding permissions. Being too permissive could let a pirate access all your personal documents ! And setting them correctly is tricky. Beware: Using a shared folder means having a single copy of your work directory. You should do regular backups of your work directory. \section{Encryption} \subsection{GNU/Linux} GNU/Linux distributions include many tools to encrypt whole directories. With Paperwork, there are 2 directories that should be encrypted to protect your privacy: \begin{itemize} \item Your work directory (by default \textasciitilde /papers, can be changed in the settings) \item The cache directory (\textasciitilde /.local/share/paperwork2, cannot be changed) (it contains index files from which the content of your documents could be partially recovered) \end{itemize} Note that if you want to be sure that your data are always encrypted, it's recommended to encrypt your whole home directory or even your whole system if possible. \subsubsection{cryptsetup} Most GNU/Linux distribution installer now provide an optio4n to encrypt your whole system or your whole /home with cryptsetup . This is the recommended method to protect your documents. \subsubsection{Encfs} Encfs can also be used to create encrypted directories easily. Beware that Encfs seems to have some security weaknesses. So, while it's probably enough to prevent a laptop thief from accessing your documents, it's likely to be not enough to prevent the NSA or the police from doing so ;-). \begin{verbatim} $ encfs ~/.local/share/.paperwork2 ~/.local/share/paperwork2 $ encfs ~/.papers ~/papers \end{verbatim} \subsection{Windows} On Windows, you're strongly advised to enable BitLocker to protect your documents. If unavailable, there are other applications (Veracrypt, etc). \section{Keyboard shortcuts} \begin{figure}[H] \includegraphics[scale=0.33]{out/app_menu_opened.png} \end{figure} \begin{figure}[H] \includegraphics[scale=0.33]{out/shortcuts.png} \end{figure} Keyboard shortcuts can be seen by opening the application menu, selecting "Help" and then "Shortcuts". \subsection{Paperwork's files locations} By default: \begin{itemize} \item Configuration: \textasciitilde /.config/paperwork2.conf \item Index: \textasciitilde /.local/share/paperwork2 \item Documents: \textasciitilde /papers \end{itemize} (same paths are used on Windows; \textasciitilde{} = C:\textbackslash Users{[}login{]} ; folders are hidden) The index is always updated according based on the documents in the work directory. When Paperwork starts, the modification time of each file is used to detect changes on the documents. \subsection{Work directory layout} workdir$|$rootdir = \textasciitilde /papers (by default) \subsubsection{Global organisation} In the work directory, you have folders, one per document. The folder names are (usually) the scan/import date of the document: YYYYMMDD\_hhmm\_ss{[}\_{]}. The suffix 'idx' is optional and is just a number added in case of name collision. In every folder you have: \begin{itemize} \item For image documents: \begin{itemize} \item paper.$<$X$>$.jpg: The original page in JPG format (X starts at 1) \item paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X starts at 1) \item paper.$<$X$>$.words (optional): A hOCR file, containing all the words found on the page using the OCR (optional, but required for indexing ; can be regenerated with the options "Redo OCR"). \item paper.1.thumb.jpg (optional, generated automatically): A thumbnail version of the page (faster to load) \item labels (optional): a text file containing the labels applied on this document \item extra.txt (optional): extra keywords added by the user \end{itemize} \item For PDF documents: \begin{itemize} \item doc.pdf: the document \item labels (optional): a text file containing the labels applied on this document \item paper.$<$X$>$.edited.jpg (optional): The page as edited by the user (X starts at 1) \item extra.txt (optional): extra keywords added by the user \item paper.$<$X$>$.words (optional): A hOCR file, containing all the words found on the page using the OCR. Some PDF contains crap instead of the real text, so running the OCR on them can sometimes be useful. \item passwd.txt (optional): PDF password, if the PDF is password-protected. \item doc.docx / doc.odt / ... (optional): Original file. Converted into PDF (doc.pdf) so Paperwork can parse and display it more quickly. \end{itemize} \end{itemize} Here is an example a work directory organisation: \begin{verbatim} $ find ~/papers /home/jflesch/papers /home/jflesch/papers/20130505_1518_00 /home/jflesch/papers/20130505_1518_00/paper.1.jpg /home/jflesch/papers/20130505_1518_00/paper.1.thumb.jpg /home/jflesch/papers/20130505_1518_00/paper.1.words /home/jflesch/papers/20130505_1518_00/paper.2.jpg /home/jflesch/papers/20130505_1518_00/paper.2.edited.jpg /home/jflesch/papers/20130505_1518_00/paper.2.words /home/jflesch/papers/20130505_1518_00/paper.3.jpg /home/jflesch/papers/20130505_1518_00/paper.3.words /home/jflesch/papers/20130505_1518_00/labels /home/jflesch/papers/20110726_0000_01f /home/jflesch/papers/20110726_0000_01/paper.1.jpg /home/jflesch/papers/20110726_0000_01/paper.1.thumb.jpg /home/jflesch/papers/20110726_0000_01/paper.1.words /home/jflesch/papers/20110726_0000_01/paper.2.jpg /home/jflesch/papers/20110726_0000_01/paper.2.words /home/jflesch/papers/20110726_0000_01/extra.txt /home/jflesch/papers/20130106_1309_44 /home/jflesch/papers/20130106_1309_44/doc.pdf /home/jflesch/papers/20130106_1309_44/paper.1.thumb.jpg /home/jflesch/papers/20130106_1309_44/paper.2.edited.jpg /home/jflesch/papers/20130106_1309_44/paper.2.words /home/jflesch/papers/20130106_1309_44/labels /home/jflesch/papers/20130106_1309_44/extra.txt /home/jflesch/papers/20130106_1309_44/passwd.txt /home/jflesch/papers/20130520_1309_44 /home/jflesch/papers/20130520_1309_44/doc.pdf /home/jflesch/papers/20130520_1309_44/doc.docx /home/jflesch/papers/20130520_1309_44/labels \end{verbatim} \subsubsection{hOCR files} With Tesseract, the hOCR file can be obtained with following command: \begin{verbatim} tesseract paper..jpg paper. -l hocr && mv paper..html paper..words \end{verbatim} For example: \begin{verbatim} tesseract paper.1.jpg paper.1 -l fra hocr && mv paper.1.html paper.1.words \end{verbatim} \subsubsection{Label files} Here is an example of content of a label file: \begin{verbatim} facture,#0000b1588c61 logement,#f6b6ffff0000 \end{verbatim} It's always $[$label$]$,$[$color$]$. For a same label, the color should always be the same. \section{Getting support} A forum dedicated to Paperwork exists: \href{https://forum.openpaper.work}{https://forum.openpaper.work}. There is also an IRC channel for live discussions: \href{https://web.libera.chat/}{Liberachat}, channel \#paperwork If you have questions regarding Paperwork or simply want to chat, those are the places to go. \section{Reporting issues} If you noticed a bug in Paperwork (and you are sure it's a bug), you can make a bug report. \subsection{Bug Tracker} One way to create bug reports is to create tickets on \href{https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}{Paperwork bug tracker: https://gitlab.gnome.org/World/OpenPaperwork/paperwork/issues}. This is the recommended way to submit a bug report if you would like to discuss it with Paperwork developpers. To make sure you include all the required informations, you can use the tool integrated in Paperwork (see below). \subsection{Automatic bug report} \begin{figure}[H] \includegraphics[scale=0.33]{out/bug_report.png} \end{figure} Paperwork includes a tool to make reporting bugs easier. It allows you to get easily all the required information to make a perfect bug report. All attachments are automatically censored to protect your privacy: Document contents are blurred in screenshots and logs are censored to remove your user name. If the bug you want to report is related to scanners, please include "Scanner info." in the bug report files. If te bug you want to report is related to a display problem, please include "App. screenshots" in the bug report files. \subsubsection{ZIP file} You can then obtain a ZIP file with all the data. Please make sure the content of the ZIP file does not contain private information (it shouldn't, but better safe than sorry). Then you can add this ZIP file to a ticket on Gitlab. \subsubsection{Automatic submission} You can also let the tool submit the bug report to openpaper.work automatically. In that case, you won't be able to discuss the bug with developers (or you have to leave a way to contact you in the bug report). If you use the automatic submission , the tool will give you an URL to see the submitted bug report. This URL is private and shouldn't be shared until you made sure there is no private information in the bug report. If there is private information, you can request deletion of the bug report by sending an email to jflesch@openpaper.work (please specify the private URI in your mail so we can be sure that you are the one who submitted the bug report). \section{Uninstalling} Paperwork can be uninstalled. Uninstalling Paperwork \emph{will never} remove your work directory or your documents. \subsection{GNU/Linux} If you installed Paperwork using the package manager from your distribution (the recommended way), the uninstallation method depends on the package manager. For instance, on GNU/Linux Debian or GNU/Linux Ubuntu, the following command will take care of it: \begin{verbatim} sudo apt remove --purge paperwork-\* \end{verbatim} If you installed it using Flatpak, you can use the following command: \begin{verbatim} flatpak --user uninstall work.openpaper.Paperwork \end{verbatim} \subsection{Windows 10} Paperwork can be uninstalled as any Windows applications, by going in Windows Control Panel, clicking on "Applications", finding Paperwork in the list, and then clicking on "uninstall". \end{document} paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/data/user_manual_intro.png000066400000000000000000011256751456262201400312120ustar00rootroot00000000000000‰PNG  IHDR'Ábî¹&ÑzTXtRaw profile type exifxÚ­œi–\7Ž…ÿs½Î$–ÃñœÞA-¿¿ËHɲ,»ÊíR–•©Èˆ7À@¼rç_ÿ{Ýÿð§[¯.—Ö«Õêù“-[üÐýçÏç{ðùýýþÄöþ¥ÿîuç«OŸwð’~úüË×óù¯—ß>Ðò×ëó÷¯»¶¾ÎÔ¿ôõ‹oL:s䇯÷õ¯¥øy=|ýÛÙ×çFþáv¾þ»+¾_—ùùÕÏÿÎÅØ…ã¥èâI!yþî:Kúü7ø¯ñwL…7…”ø9ñ¯‘r ¿^;÷ýÇŸoޝ+üiíüøzGúýRh±¿V÷§5úz=”_¯Ý[¡¯(|û1þþ>ÇèüóãÚÝÝï=Ÿ»¹²RÕ}Ý”ÿ:Äû‰7²œ9½U¾ÿ~nïËøêÜâ"b›hN¾– "«}C;ŒpÃyßWX\bŽ'6¾Ç¸bz¯õԢŕ‚¬¯pcK–¶Kh,¢–x9~¿–ðÎkï|+tμ>ñ‡/÷«ÿ?_ßt¯R7-æü„˜ëz Îe(rú›wp¿Ö´¼õ}_î{”~û£À&"XÞ2wnpøù9Ä,á·ÜJ/Ή÷ŸÝ·Znûë,ç.\LHDÀ×J¨Á·[¬c'>ƒ+)ÇIB)qw‰MJ•àô¨só™Þ{c‰Ÿ—QR¥l:+çBþ´ÜÉ¡QRÉ®”RK+½X5Õ\K­µUaÔh©åVZm­õfmôÔs/½öÖ;`6,ZŠUkκ™ÁI‡|zðŽ1fœiæYfmöis,ÒgåUV]mõekì¸Ó¦üwÝÍí¾m©tò)§žvú±3.¹vÓÍ·ÜzÛí×îøµ¯¨þ>já§ÈýuÔÂWÔ±üÞ×~‹/·öíApR3"s âM ¡£bæ{È9*rŠ™·HQ”HÔBQpvPĈ`>!–¾Çî·ÈýeÜ\É+nñÏ"çºÿFäœB÷¹?ÆíQÛã1JzRjM}ºo8}Ä>ÄIú}C›í¶ºÅ}Ö8µôusí'ÖJ‰X'.e•É#SAÓzdŸò³ØjãHžÕe-m¤Ãrëìì/!#ZÉ¥´ZˆU€‘ac»5å L„]Æ&:q´'ïÉ-ÖÇ™°>i4X ¦m1äÂÿœ¸R?üÓïv ÛGF]”l5¥Þrõk´`€FöàJ_¥¶Døê­gäY»»`6VœÄºyÕ\êæ–ì„»ý²½Õ¼såÕ‡õµrM,ùUâËÒÞ:/à?¹wn¼E¾±ÂJ˽Ko›âX¤÷œÖ-ý–e1°Âuݽç&‘B¿qf˱ƒÝF§µF*Ø¥¤¼ `çc“4îè¦Ã'KKur)aÌ`§ŠvWç:Å9SÛ+‡sÚµRÇî§'ò¼,Ï-íw/s¤J’Ö9L:&Aþž’×n³ðÛ–]ª~Üg­ÒÓ\·šo–gËK©jSNÚ¡šqÕkïxn©äãm“µŒ¹B—`öjqÆz.µ‘Y‘3:î:Á—ÍÁf. ¬ÜÛÉý6På..&‚Cóä²20r¼ñëÀJÄÑX­Cå¶]çôý\è»Õ=ʾa[Î{Rø©ÝÁA9ëþªÒË.ð±]m7 vŸ8Æ¥5ó3Æ Ÿ93Ù£L.ÀKxÏ2P@@—©æXäÙŠ›kÄ\W³¸„8}ŠÔæY³n¸Åkñÿ¬êçÞ@ŠÙX›•¸ÓºÃ>À×µ©`ë`YàC•èzKZ'í¥jJÆ5æ î´L©: Y4'JVì>zKîð›}û.6Ie’ýêN 3l$÷GmGÑ=‡p_ŠäôÂûlpêrgr{’ë©­YãÊc„t÷é¤k"`ktaW ª—Ø÷Îm›!­E9¢ˆ(€°ºÎ:¯q³¤TAF%À˜ˆÂà`wGƒФJ‡u¼“å)-±h«ä\a©¸‘A£Í “â­}_ˆùŽ]W³&(¸4ë•%åNÒd |\H®{à5°¯Q‰ÿ”Uˆ0åð;rl;R‚»… %àÐ7ð!“#° ‘9]ï‚Ø¸Û“Ž)ÊÎMªõZéœb¶ßÜ­>Ÿç€oüƒ…ö¹•å"?:yUj0ÏèÀáê[Fª’¨ |t)=ÒcôÛUdµÌÕ§Vë’ö”øå¸1Rb0‹[RVî Öü smh¸å)JÜ¡•C&tu+¤Nªü}w³6v *ß{1:NvÒº æ¥ ËJrÿ']öÌKvx0/7_76ŒìØô“úȬð ŽhS°‹Ð*e>C…B³ê€‚ÜÌ"Ø™–ó2`Æz@NÁ&¬çn6”BÑ¡¬_ëµìaH•Ú-p|QV¬ItØòá[l`©»e/ÀIà% ŽßëŒíK¢®È£$ 𣳬[*H€ Ïr¸j.ö@¥àQ¦Ìm¢Š‰ À8€eÂÆgI­97Š7Bú]ˆ*”e“wô”_“©ÔÒÎå¢PJ¨íØö¿ »APGbh±aƒ ×Åé÷%1A¸¼W…Ü»~s7 n„¿/R·š–äŽPrëÅ ðÔý†’³pIï³’Sh$F"Y<Õ€Rw™¥¤„¹ç©O‹ŸY /ZUdÁÂM£UX `¼Ýéð¥ÃV×ëìõÔH”O% bšZoØ¡0rª av5YŠÈ‚Ø ç`…¬PpQÛ¤E[Hpr»,"ÕÊÍ‘èQ*gž·C‘C³¾ð 7¡˜Ü™!ߨ[Ú µu„Ô†›Ú^²q8CECRƒè¤/]Œ€õ%‹3«¯/nY…® c3o„|2JU ˜æ‹%¬3bKÙ8,iÔÐ$„ßðgr(3N'((ˆ!¥˜(_ ¢d¡Š$ìÙÖ{W!gíµv+Už']D+WŽœ .¨rGé Ž>Ÿk‘ž€@}>Y¸f£rF\b2¨ä³kù\C¨P`߆G ´G b\hïf‚ÖÌp‘¶Í#§—í…T OK%g".!zQ× ÄtÀ |Fàò§œË èk¸x8éòÄNµæB”ñ,y'V3®n]Rú(ÒŠäê–`§‘Nuó‹‹  Lqƒ,œÙ b^_ 5z¦ ´óÕ7B”,7²h‘ ÈAphŸé…»r$‘Õ :ÔAßøYË£¢÷÷¾c¶*¬é2j€êJ½PEÊÀN)“ØE‘9 ŽÔéW¨x‚ûGtœÕ œ.ªu•,È,þ¿† }Ë !|XKîÉ_ʰ+„¤#_H °k™¥r,ÊR¸Ó ÚƒÈ Ž*ÀnÛ€æV¹duÖà40pÖ<’ž”OZp Y"ΣÞQ$;ÝØ¨|´ÖqrU¨ñ"~%Ã+I ù1ˆ¡=dW=ÜwD!hP¯áî-9dŒ‹Ó§¥‚½–¨È¥ ³ã$串H ï2ÒÄUõr¬ËJíq¹`r„%MÉ÷j™ì×:ý9݃ñ·uF¿p êœk3¸¿„‰¬ƒ6À/¤l%{‰À`çÁã5Ñ'Øbۨ%ì(dï‰( àd€Ð‹0K z°t`ЇÖYàÝððð„¾ô?È]GçˆJ:8Y£p@çëàd`@(‘—1&¸)‡*Ts>d;²dP2pžÛ sè YdP8›&™¨ÔÒ!ÐIׇŸ’Aî!kÉýà¾:œÊËHa”m<·P†~!g83JPçÄ}„ÔF*¤Ø<`p#fÀõá¸búÆØ‰ÖZ¡À뚤 â$Ë‘ CŽ Yž¼’˜Äµ Ø‘¾ð,Õ¿ú¸1Cñ‡$?À x.û]µFPp¤ !í AÈs±¬ÕøœªF!Z‹S$ Ý”}Á*åD•Ôå'¤7—ÅjƒX,ªÊ$*² 25"‡CÚEÔƒQ¯B!Z(%Ö+V΋$ÄAˆ7Oà祶²Èà : ‹l¢ŒpE€ðpsEÙ`:tqÑ)­ˆ~‡Y ¦²i(¼Iqé¯;ÿæ»z·ä´ žCéÖY@¨ÃŸåI_4Áwb€õnÛ~¯<lsAê2œ÷¾EˆÁ#*qV®ÙÖOn¼mI8#špdJ²ú"…}“—Öý&xV„)º¡‘Ô.bÄx/Bârßäw! áyêo ©/ŽÀ¢*4ýŽ3ÐÄÀdÉp{D‰ªap°d>‚M©]XSä#É÷üACd9{4I:PBXmÏoQª( (vnn†pV({úѾyÜ^#90_K‰4Be]ì½W·"uðDîÉR\óMd•GǦã¸ñÄAw,ÙÜÂÆØ¶à·Y¥T‹  ×·jÛꟋú±æ^ FÜ€æÇqÌZ=r\çK÷»KÜhê<ñ†RâìCf¥€ qP$j 8e\ñ¡{ÁkKk‚„¯ ø'¡?ni⤠TØ#Õ[1“]ÜîásÐ-â¾øvžÂ¤ú‘s™¢µæ/\†«¿ŒôÀÎ aA *‰¦ÊkÁLFÈéîw@wo]Ò‰ì§pT%tÒØ^̇˜’¸oÉ[Áür24@»ÚÀ)§pÅÄâ@JÈlVÕù2/QtxÄ¢­,~©tC 1–Qî|Kˆ7¬l(|¼!•5ƒÜ%˸Ð}Xtd©·Ž •J²WH\@Ô°´ "* Æ®îÙv÷)a³Â’ð,ñŽHUDM¡ 8Šà¨>N\Ü þzjŸJ6ˆ%õH/ ãàÓQ#èôTP„U—ÐzN#Ó =«Ò°%ÒY[Hß Äñ¼ˆ²%w:4íYƒöÖQŽ™©Ò.Ÿøn¨U©T|e}TÜTê 4ÅìÌÚµ©à§\§„“W†àíÚ.˜"uM®Pfœˆµ"£‘ËÀ('±'0 m ˜ ¢¶°˜§KxXxùk+>)…•éM&¡Ì‘l¤W‰e‚¥:þ°´ƒ9æLKð‘cØf ’ µáOP¸9»‹9c±:ÐâÕÂ>–4LÕó,e+ÈÄÅÒpy¡ ÿZµ}¥f]Æ{§6nºän˜°6R­üWÆ™P§¸o4¹Þ%eÔùxYÈX—MººAÞÂ驨pSe¦±ø Ì ÉYñ©6'Wo22ð7úkynÃè°Î༠Ekm´  *TBŒ©têRS´ªƒ¬F¡YrPSôÚä WVIrÀ…²Àš:è¬[ýAÜ2„yqç™$óLKÂ#øìâ5´ä’&HˆáùH¸½ˆ]N J‘™¢rïÏôã®3w´Å…M,Wy·ÓE†TàSûÞ­^Òh£l/rÈßÅ“keð[RaµuT²’ðC±Í¼ƒÑôÜGWÙb‹§Vm‹ˆÝgo¬T­9º^iÞ@G èpTÀv ­¤ž+‡å¥A *J;M›ˆùמFCÛÆ[MÚa°š[…@ˆH÷S\ƒJn¦¯©«QdÎQS5ɺò_Ö Õ¹I`uÜ x,Ë5yuóDj ñ‚æ,aZ”ßXô|×íb${.ÈtÔÛ†ÄPM¼E­G²¯@PÕT·“¿ŠÉ=jq«g†a=÷ ËæÙ¯¡XI~bt†—z8”;ž}FÂ2]/XU æK ¾ž"¡.0õʸdÒc“S»ŽûµÝ}KT”š¾Y™Ò´ãǧY rÙ¸vØ>ú‚ùG“uùÕÙ$®c$ؘ W|œ‡b7Õdé°5Š?é «G/¼–ÎCfÂX5ñ–Ï ¥B y¸¡KDR¶ÔdW_>›kj†qMfü½ªxç™ÆÐ#ƪÚk^(Õ ¨f!»E ÙWÓaÐïŽ{! HlÄg‚,Õ»øÈeÒ áx»P9XÔ1ø ¥ú*éhÜé|Úà;ö%fNŽºA~x–d.I(ðç†#ÛÔÖn—g07~‰0~Ü<CÙ±¸ÈxbvKRQÆÊª@ãL êÔa¸°ïµÜ†; !ù®¤5d«ª›¼QÈ €ºÜðú…¶Èñ~mL5ñ¤£ùI*ákóó©¬IÒ,н^-zzøLhË {Îû±Ž¾ÿ;u|º6( BwHA0‚:  Ü á—;À-ün&½´VˆÍ¹s5غòZIˆò}ë€ð£vÏN, Òû¨Û>"ÙH®½õD#²~ í Å¡®P‚£Z’sæ6ê¤AæP’&”A$Œr ˆdÁž6yJÕÎáàªËSœ!Óçâ¶wèÎ¤í› a"S i È@% ‘vÐTN»j¯nT³hzSàßåj)I›ÃªHNÅk[lûG}ü#j󋺓n_ÚÅö„Î =8´Ó ¯póóÅq{s$ЀƒI‚àÒf™¶òÈØBò»œG”2ëh¡ÜѺêVã]ðTðäFØk§¦¡¿zjÔW‡XÛ†Õy­gòEs&™î\MóP„o(Y‹=Èdð«äºhj˜L I}UËMaÕ è!;@NJiCO>ÄŸÍkä;Še6dsr„Ë”eðI¤=Jäkn85Ù ªº*æ·ë0¬l=?QH¬ïÈ=§íÐ E˜“ÀÂ{åH>?G«VT^×N‘†r&´Ú¨WE² À 9¨Ø úBm?æE9 K^¿x±tãæ‡– TÝ£>º:ô/€d©ÿÈ­q3ˆ0r‡@'µ¿ú%ªFu(ss„­ñ,p©:à˜5`©†%¯ÕõNqMu}¥Bà8бkx¬Ç¾‹Z7’`GÎT*­©o½üëó5t¢ Q6è–E7òê¡ñ+÷%‹]_ïì»b¥*²&9}[ˆý V´MyÒ8‡0!D"ö„ÒÖ"Kä|^ ÄÔ^%ë“Õ[C"ÉÎbq–ú-©º¡¤Ï"'„ÅŒ8? uï@ÑAƒG§j{Á˜ñ³©ª,ÔèB<­/ŒOO‚ˆâ1ˆ$1BQë•T©–®a dõڂƒh9Ä´ZܼwÁžCÎÀ!hÉ‚æG¡……dº¡èÁyÊš<—Åí濘Hô6ÄCxùL=èLÉÕ®ÛÀQÐÆ‹sla ŠZ;ê(µ³‹ß‚ZDŒâœûx.4ˆß@-B×»vj"ðe&CÅ«ÓtA&×Þ3¾RmnÙ]Ê}h¹.ì¬!‹=ç{›qNˆÝ@7‰/À ÐI8tÔ¨&)LýŽ %)ÜÄE°ó÷Û|k³—÷¿^Q¹;m¶êÁÞ¾ù åëkãa£¶¨°Fd€äU“D?ò¨úÒF2õµoŠŽˆÀOÝ)ÓÎ>¦›ñ·‰ôÄàD¯ý̈Χ¼L<¬˜×fù“5ÙC¸œüÍÜ*@<`˜>CðÈe½Hô´À"lI©ñ! @\?ujjD¨]!2Ì.©—©\c²ú§T¦¦U[pb+iqm’VY+ÐDEš¥î/·q‘gÖÞÆrˆ°¡ë*L£64÷ˆöUÌmK³®”S_?k·š[\å.ŽB઱]“'ØD´G6õ™ªz¦(ϦqÄPQlG› [’/&¼Ih\‹î:.Éêf¡Vxþvv©hÅ]Â_ûÙ(îº\E£ãAJä`$jTmLí)¾V·Àú’Æ‹‹Bô’ç úXê[ƒU{„:l©Y8XÞ“³zpRK± 6 • Ð’?ð=iüH{ÔYSF`µKhj<•Æ]à¢34*q¢ÚQ†¹7îeò°£¶§Sãu‘`v‚ä(Õ‘-KжS¿¨¡žA,Ó„ƒ6<½ÆX-ÐÒd¢&µ);„]Ïé $¥)Ï4ÜÑtÔÅ0p˜Q´Û…x̤,žXW²-'«©MvKd¨Juuñ£f†P€ðš¶ ©Æ `,M"N`9<¤[¯7øgÿŸà@œ#½g”_œ‚bT-†ô&Ïg×>Ú†zTÇ¡LuŸñwð Qà‚½Œ5Bújý4Xelm[VäŸcY鵩³jUŠºÓ¾>gS#IùD>£ q>ÔO¶´£3kÔ€Ìlnü\diøS;êâïHÎÌ…ãxr„ég©yWâN½:\áMëñc¸u0ECtÇHzVÀù é¸!gŒÅQàYøF¨¶ßÎÙRhêÀÕ:i„ƒ)Ød©Él\+«… ×°@:’MÚÑè)t4¿ÕL@qSy‹×´C<¡º¼¯J "Ër-m²BhÑoECoä EÂÕ ›æ¤ðj׺vš6·&…‡úŽŒ^pÃyŠt %nÐtâáKlTÞÔÅmÚ£D™áÅ`Àž5âLW£¨?ò5Êb˜͉ÓêT©,ðX²lrU²’Ú;FV'Ð*´« Ag#åNýpjä‘å²`¦( ðŒ†õ&5¹å©byi$ªÖغæp OÀÔî^Î ûßÕ)ÎRÚmi÷Yí£ˆÁ¡@‰8ŠGM&%¸úr`ùËvå€ðÒð)k¬ ÑŠm¹gniPÊ+œ­JŒ"Ñf=/Ä©>èP/’¢Òn»üÝ[6²64¾WüH ã…­¨Úx#¼ÙeÆÚ–„Ç÷Œ Ø ëîÈ”¨¸¬%éÉsϬÓm°Ôia#QÓX3|„?™ã="Yu¹:ù2Ä·ÆòÜÖ6 GUMCÜ'5ŠhEØÂ¢ekŽIˆNöàŽvÅ+R0q ¦†Qäv!E1V!Éþk±iLVâů|Eñ“š‰ƒ®—•áZ¯dæ=÷ ü¹S´{‹QC”·i÷ˆ“7î×|Š6Ÿˆ |Õ>lšõžg-ÿs‚ÌÝev£ÜÐ7ÍE ¸‡ð¼Á9R£líü”€øÚ°E@Nˆ/Ô⊀>t #7AbŸ¿ÚäáÓSsŒÆƒÅ ø«ê¶aQ¬ša'{Ê›2œÚ¡šÚ ò$‹Æ€ã„l5‘§Ýkuú79ƒà—ƒì& FÆÊgü9Lz§†ÞRDÖ zTƒ©¥84—@ñf xk„HMfͨ©¹äïºX[¦ÖtÙ›ñ–p¡y$;…Ü$t8*’_vç&fjDÒTúWL9ù!uéTp½¿>ÏShCŠ´Yê…©»ä¶7xÑJOI›<çžæ°…Ø<„`Ü“jôÕªMi.¡ˆö4í¼cÄŽˆÓgéá¢Vã%ȉPý¼Á…7ûÛ<ØešƒL÷ꇽ[odîš ¹ð%® ìRÏ7O”*èÃËuª©zÍÉLþhŒè“e°ÂBG%kÔ·¤!+D¤€×6F1àÕ©ù, àíМ q£ž6ºÝkÈ B<©54öܵ=óFŠ"DŒp6dÙµüÆÝpápâ-p=Ÿ†Éм9˸—×óMMkÈyÔt塵Ñ۴ϲ5ÉXf˜Ÿ „ ðýÜ+e®=sT‚¼Aª?¦2¦‹ú›ó?®I³áˆ~,5î\3=éà8z’ oê$`°¸  ¥Êh4Ê0²Ä@;aÙÕFµ†3Xw`1¾¹U,ÄBhQ´3©m‰zäÞÒKÍŠìRB-¡$ˆ.ŒG.@ÍNÜ2Y—vz¾ÈaϺLW%†$rUgœ?`ƒž –øí]­aΰœ¨9¨ —¶8 ʈ_I¬I}ñx}´ÁÛ °!P! B¡D7ŸÕèE+ë<ÕT—àF4ôáb’ŽÆ›PsÒßø-2©ôꀣi?Cûž'±€¤Ò–W¦²(<[£ž»èMÿâ ‰)jMËÔê%ÍK훸Yv°ŽÃkÞøhÿš’Q÷ßÁP‡“HûuðDè€yžœRÈF2ŠøÉj\Ö‰ºnh™ Ù²æ*LËBtÔ¯Ò†¼ÀX@@Z2sª  _%—&÷QX$‘ÜHý0tt Y‰Ë«¨¿²8BߔʛRñDœ:2m f==fËwТF;\Ô8ÎâÍžé§ùO 9¢AÈ®Lñ"BV¯B!]ïšÚ>ãh£3Jf:íU³[„vð»ˆ:Ô ÉD α6åy}ÓfIs~‹Š™š™ýôŒ½8NÛÅD_AÕG$ìV–YDž; ,±){u§¾ ¼¿JØp“ÚÄó{9Mçf”ZºªÚ2^téA¤¬ù×5Èk¤Œº0‡4C¢.~M²pŽòt¶²|×ÔDf¦De2¥lWÓÀùÈ=Èh#;öÝõ>H`¼©¯‹`Gï;œÃ¯¹ „w»6›8™žóCǼ€÷ž€ÔvÕv&P;´ß×\Ö&—ÓŽt¸¦ŠÕ{9^.h¼1BÓ8\9¦zûí{“”dÚ#x'‘Å(9®îu=¢EcbÚÒ ®ÆÀžCÐ/HÌ󚱓¢–Hu¤ŽYW›ëPýdˆ† {z›ïC ¬T%Rqú©á3=£wáûhñ•‚6&Ì!!=ŽG[EzÄ%žš¸‰H-“§¨ LhË}kT‰kò¸3aµV(û¡5êoV:ÉøKÈ4ƒªqþ }úÒ^‹&VOÓf ¯i÷™ÊÆ¡á%¹W£¦˜jÃÉ,Ío±€(Ah€[ÒÖj$1à2+ˆã4·aÑFÛTÿ|Ž.e]»ƒ£·žRâ,eÄru¹H¤% JÁ‰¹pJ25ª7ÉAiF%¨Ð¡>‡ÌBwBàH!ÔO†‰å"Ɇ¥>sUKV0©¡NЄºö.ANÄ,E-É®æC^艄#ÖÔgÑ€"¼g€JÔ*J:ïÔ¥]¦˜+5= !ûý”¾PÍìÐÉz§O›S›ZKvè *4$Æ9Qg~›õaÞ8¶AöšÔ„-TáÞfïÒãLJo¿…¸µi¬¡ =Á2ÔRk”°Eä±sAô]d5”VYmíÀ:²1b½5©Þz7ßÔ$+\…Úø´Ãxõ÷éw_‘ë”rGXɺ˷`W×=¶|T^X„%‰´M jMj|¡Ú¤)€;C"KÑ~S7êÁ wJÃiÊw¶®õX|ЫŅö¥ç•¸cõæ²Ìe<<9‹äãÂ4ÕƒÊYœÇ£üï” ¬6„¯)Ynõo.ÞP³Ð<+©á’ó&!ÍûT¥Ê5â hÀí:\4ù ¼Hß]š¶îjå$Wµd=ÿ™ƒÇ¶º–{à”tþ‚Sl5g.®›lY¼Áª µÇ½ßÄÀ«ô\)¯Ñ/—;.Lœ ¢ozòmPéË’€†½îS‹jʼ‰´o“i?~w?¼ ô¢º™Cr¡5SÕàJ@å‡y4û€‰‚«àrü3æ°ƒž"öÝéYÆ€°6‚ZË5cË|ÐPø›F&Í"nKOîhÿ{ÂjêOÍR’vzê±8¼¸®[ƒ’è'®J“ˆsDéÅürc2ÔeÒ–¾ÝÔÆ€Õ±3¥ Å©nhŸj¼a[å¸ÚÜ嬕ðÓnCOã™$äŽå ƒ8<ØMôt‚È/=œµ/šŸÅ)à¤øìèÕ«ðì'6õ‘éò!¡ôŒ¬tÍãò&‡|§¤¨Ñ ÃIº©iª{.‚ìZåm%éÑ•ƒ€×{5Ûc’蛘²Êîm‚A—ºnÍöÕ˜„3´µÁñ›ÔI³ÿú?/@H¦ònÉ¿±p.Ô^ÚòyÉ´è©›9ÐMeÂ]Ñ4õϪÉQIuru[7-Ð)‚?à¹ÈW=‹ìõ šf¼®Šžë}³¸ð EЬA'kºê)C¯ÓgnÁsÅ8ЈzToêñ'b«tâED“ž¥Úl{¥²T¢©Ã³JÛä528ÑGk%¹‚·õ‘·bxÔæšæ¦Ž#ÖÖÑŒIaÇ3™~®Çü¯œzüISpWòYÿwo }Pg]û:=¥>¤iÒl²fÔ 99Þ€6‹s÷Õæ•ïS®›Baáµó|õÜB”«Å‹h^a©Yéx¬,ö?'ä2* ‚˜*Ã5¥‘Ã)3¹CkÁ³9¹â1ø÷€ Å|fM-…t[‡ÎÔZl•˜˜žÔÅFÕKí¨7= Šσ„ÈÁ2ÀÖn“_'ÌQÌ}ËêÓP/è"ík‘”‚ pz©´ôP’0Ü=,æ!ƒ´9 g[BÌQÙÖÓÚ S‚LôülÁ®¤ÏÀ!Šþ‚PYÕ“ÖCÿKrêí jQ¢J…Z¾š;§êrÓÔáUS6Ã}áìxN€?°)„BKsH£šë¼Kû{U{²ïÈì®ÿ/‹i÷‰·•ýÇ­8÷ŸçÞE”n¼FTOik^ƒWÚÆAB7¹µ’Æ{r¦i¢N¹"PQOWéÑdßÑÈ‚-ŠZôå5W¡}æ у‹ÛkèNª}£qÒÅû’,¿Ütÿá£<÷Þmîÿåî6/™¦bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEä *œZ5¤ IDATxÚìwœ\eÙþ¿Û³é i$„z¤¥ Št)Š,ŒØPlè+¶W},ØTÔ# ˆ t¤÷N¤w’R7ÉfËïë>¿9,›dwgfëõý|æ3›ÍîÌ™çœóìs_Ï}_7cŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ÆcŒ1ª<Æ3討ç6…1ÆcŒ1ÆczŠ*`,°pp3°¶‡ÅcŒ1ÆcŒ1夨8¸xX 4-À•À8“1ÆcŒ1ÆcJE%0Øø&p'0X†D‰€¿§wÇ÷o&{èŒ1ÆcŒ1ÆÓ]j€IÀ‡ßO F`>ððC`w`- ^C€Ëãçî¦x(1ÆcŒ1ÆÓ*€¡ÀfÀ‰À¿×€¥ñx¸ø°)0 eTtÄh Š[±…1ÆcŒ1ÆcVA%2³ÜøðÊŠhDYO燠Ú.¼ö(ào¨Äã?(£ÂcŒ1ÆcŒ1†`*ppò‹X‚‰9¨ã›ÀH`(¦5ôhTâ± ebŒõðcŒ1ÆcŒ1ƒ `8°-ðUdT9‰K€WP†Ã±¨G=«.×ècQ9È2àâ8cŒ1Æczl1lŒ1¦w¨Cf–ï@eSPYÆ `p3 þ ,@m@;$Ÿ$@5ÐÜ˵uãx&¡–£;_Cb…1ÆcŒ1e¥ÚC`Œ1=F ꘱°°7°ÊRhCâÃÝÀuÈ ò•ZV÷¢ù$©6> ì | µí*³ã€+€¯Å‘PbŒ1ÆcLÙpæ„1Æ”`$° ð~``KäñP‰J6^Aþ7ó€•yñ%¦§G"ï‰ à9`Ÿ†\n^7{ $P¬„Žß±šŒ cŒ1ÆcŠÅâ„1Æ”n>­Æ…`ð~à}(Kb 2¬lÞ®G]7f¡ìˆÖξQF”øp@f¢RŒ-ã{gÿ×˵tó³ìüeu|¸¬+ÇhŒ1ÆcLWpY‡1ÆtJ`(òix°gôëG@_‰Äˆ9Àµ¨MçýÈGb)k(Õèˆ|’Ô ±ãs(Sb$ð*p&ðw”u±F>\ <ÕÏÖ<ˆÊD.~…JúF”Áð0*ÕxxuÛè´‘O’Z ­!—[ÿ삇½‘(28uÖ˜Û˵ÆÏV'g£¶ Ç7ärMÝüÌ•ÀÇß‹ãë»±@aŒ1ÆcJŒÅ cŒYu`>Mî†ü"¶& /‰V`!ðBìwO£ì…åt#3"Ä…jà;ÀdàâýÏAÙÀóÀùÀåÀ[©(Ñî5F¡V¤5ärw15Àg€!ÃÎ÷bÂcŒ1Æ”‹ÆS˜‡¢²ˆ]€;#@oááIà.$H<‡ЦRëá'ñ ü•e|µýA–t$J´{#€ [€£r¹åEV5ò·ø>ðò´xe‹cŒ1ÆS4öœ0Æ fªPkÏm‘WÃzÀ”ù0¸e!Ü ¼„ÊV–ë€r¹–|’œü+Žþµ}³‹åׯgÚ>Ž¿»4#Á¤øð7à0$ÔcŒ1ÆS4Μ0Æ 6ê€ €=€C€í€±1.žnE‚Ä󨔡©§2Ÿ$ïþ…²9>ügMÙ¼Æa@µ)ýXêaQäØ| xø*k1ÆcŒ1¦(œ9aŒèÔ ñakTª±7'êQļ_ƒ:TÌVÐû% ÓS?!ãËéz盀gã3o ÿN³#– ìˆP{ÏgQ©FŸ3x s̯ßEbÅá ¹Üœ.¾Æ©ÀO©æ·ºš}± †Åë5÷dz}ùcŒ1ƘbòÆ3P²¦"ψ´Ûÿ:ê0qp?0•jôXvD>IjÙæ2äÑÖÉߊ2'ŽB^§4ärËÖð>cP¦Ä€£.#wû7ärÍ%úH£â¸Ce0Ç£¬cŒ1ÆcºŒË:Œ1‰)˜¯ŒùmÊ<¸eG´ôô哤uÿø<ð>”±ñ):écÑË5æ“ä4Ôôhà‘|’üezÔ¡ò”‰HŒØ)Þk`42ü\†:}œUâÏ¿8eQìü!>×|_†ÆcŒ1¦«8sÂ38µßü]æŸB­/sÀôPéF>I*Hò¡à·A.ž¾ÜÜ sËm€kQ'‘+P–ÈzÀÚ(‹¡.~t0 x¸¸eŽ,ïl¶F\ì ü8™ˆcŒ1ÆÓiœ9aŒ(TD€ÜAùmÀkÀw€‹AdÙŠ|’T!³ÍÇ¢ò’&äËð+Ô–tI7E‚'PÈyñú-ÀràmàäIqð8ÊYÚËõD¦ÈÜÛ¿¢î'Ë€S€¥¾$1ÆcLWóÆ3в#Ö¶GÂDuÎgE («aêr>ðxC.·¼ïUl޲梬E([be™2#:Ëdà2ÔšõÀÿĘcŒ1ƳF,Nc ÓPÁÓÈ2 Œ«‘(ñsÔ©£¸ƒdP䓤µøüò„x¸¸x½‡²ú ÿŒ±ø j;ºÒ—¦1ÆcŒY.ë0Æ v@æ·óN³Éæ ª€Ÿ (î¦x¢ 8˜€Œ.ÿ€º‚,.QËÎþÆË1¶W§¡ì•„>ئÕcŒ1Æô-,NcÈ|²•Ž}%š‘Qæà äp,Å ͨ|áûÀ¼†\®©¯P”ŸTô€hò4*o¹•ÓÌF cŒ1Ƴڽ1ÆôwF 3ÈQÀލ[EGÔ'!bp=ØÅ£§ Šq¨Åè‡P·ór¹r—ZT‡DƘG÷cÂcŒ1ƬgNcëS"~k5?·µmEEø p5ê2ÑïÉ'Iê²'p(ð^ÔÖ´µúü}F+ð/d’y&*í8u1ÆcŒ1æ]Xœ0Æ 6@™`WóN¿‰,U™Ç…@-*ÇHPÅ]1'ÖÆ£uŠºqŒFG ¿2}|øòVè•NaÊ9Ø eGÇVĘ׫€+xÓS¥'-HY ø:‚Ž^ðåjŒ1ÆcÚã²cL_šªãQÿ®‰çª ÒïeE„z`ð~äw06£"pü&êCtHw,…¶Ÿ©€‘¾U¼_EseUGSˆÓƒ™Q®1µL=Ø#Æ •Q<\\_/éÅ®!©ÏÇIq~Ž^òånŒ1Æc,Nc:C%ʘæSÀŠÕü|U»à¾&ó¨×H…‚µâ1_†e~6ýÝô5«2¢AeFÀh/ TPÈbhC;ø­ñÜ_7Çceæ¹)Ë"À_ ,FíG‹âëý€CâëÆxŸ÷óË(FT#QvÄâ6ñj‹÷~eŽÜ¼,oÈåÚúȵ4uJùð$ðQ ÆcŒ1&‹Ë:Œ1Y1b$*‘ØØ Ø:„fà`!Ê8HËê#@Î>Rq!ÍNH3ª3¢B–Öv‚Asˆ-ÀòŒ€Š+âûËâë¥!,‰ã[Ï 2ÿ·"~we<Ò÷kɼÃÆôßÙï­…ºO Ì>œƒ 'K*ôFg:$ í‚J5v&Æ8.^ !âZà¿À‚0ºì.¨´£ •Ð\ <ïÛÎcŒ1Æ€3'ŒìÔ r€Ý"Þ5þ]AüÛ¨,`sT‘Îmí‚÷lfB*¬ˆ º1D‚T0˜ÌEÆ•óâß‹ãgš2ÂD*´´ È|Ý–Ê9O®:OìBÀ'ÑÎÿÈ|r`N‘‚DU [ûû"¨5Æê”qO$Ëz 5h)œ äB˜øðŒoCcŒ1ÆãÌ c(³aZÀ‡ð0"üyÀíÀM¿âÂñ;©ø°œBÊÌ×+Ç×2eòä–Q£FµNš8±môèÑmUUU“×^»µºººrêÔ©éÜ“–¤>UqiG¶,$õœÈf`d31²¯5¸«!—+…ñc%ÊX¸X/„SQ«ÒÚøÜ•ÅÌ¥ù$Y uÕ8•‡Œ×L½#nnžÞîÃÙa)ðU$^}øÊ x·5fUsv]ÌoË|ŸcŒ±8aŒéϤå›#óĆÐ0$…—€›#~ e7´€ŽÇšíà ÀᱠΊÕ¡¡†wûG¤邼½Döyu¼‰Ì1g9n5ÀÇŸ ì…s€¡,PFGS|†º"Þç8àñõìدˆÏ²¢ŸeG¬‰eÀ7âÚû||Þ:ð2æ¢Ä0`#àÇH½ ¤ L­•&cŒ1'Œ1}*Tž±Ú•ßX;¾¿$Á7"ï‚% «OÅF±¸Î–|´R(÷H (›3ßKivFêÑ”ùù ÙR’ôõ›Q¶Á›E~ŽÀé<7"ÁåâvÁ@ê‰Ñ‘FW¸ •¼<‰²#z³³FO ÿã÷à2àxàÞWc©ˆ¼ê³oÌß“‘܄ʠŽAò#¨=ð-¨]p“‡ÐcLÇžÆ jca»'Ê\ØM¡›Ãƒ±˜½íº•¼õe9C]>²&“mA¡½_E[»G–Öî8‘úKüy>¼œˆv,; š¯DÆ¡;‡°0àˆs:uU™ÛË--áË×_¾šO·â 38Ö_Cb¾Ùuáy/2½­ùfj¿{+p 2'>$榩(»k1ðxÌí×£²6gTcŒ±8aŒéñûw(2Mü òØ"Äfà5´«öo”)±À‹ÖÕR‹LA†v+oNbUÉeÈ»c7”ù0‰aq=}$Æeð-à‚ F5H: fŸAe-(Ì@£l‹Jìö q¢.Ĉù¨eóÀ]„ÏLÌÛé=Wóþæ1ç•éÕ!O—G€¿ÿAÞ8ÎD2ÆÓopY‡1ýoq;*‚ƃC”Ø€‚9ã Ø] Û%^œ®‘м¿ 4Äx üíæ¯Ž¦øýª"HÔǵuxOë‡x°•\ÜS†·^ œÊg~ ü •Óü‰lÆôç¹¥.æ—]P‰Ý®¨ýp%Êzx•×݆:Ø,bõ"rKüÞÀCÈg#àÀ¸owAe| »¿†Ø1 ~ÆcúÁNcLß$F£úã#€½y§Äã(;âFàUJàèžO’‘œÖ£iÐÆx4Sð©HÅîì¦WPðk¨Èü»2óïÀ¢2•wÔ¡Ç"‘çyàË(tFÔù3pdœ“‡ú¡ Q‰Jp6ÀéÃ1© ñ0piŒÇ¬u@YUÀÑÀ/‘pþ-Ô¾ÕÙ>¦?Q…:îl‰Ê/>lŒ2‘ZQIÝ1g§¦·+)¾reÌ×›G!ñzjÏÔé☧SÞöËÆcL·pæ„1}“ŠŒ qT,r׎ÿ{ eGü ¥þ¾|)ÙøJ†w[fM)³–v"Cö³¤Ïmí¾—":úTžrd/¥ ¶C¦Œ{ÅñŸ\ñgwáu–ÇñÖö#A¢Õ®o‚Ä^À”Œ qO·ô€ ‘¥%Þwðà,´ãücÊàbL I½#öFß{(´^†:"Ýóöq—:£­•u<„²1~sÜÇ€ý‘æG‘'Ũ$íÙ2üí0Æc,N3HÝÚ· Ab?ä}PÌEiî—÷‡@QΔ÷Çb!»q²ãâ1 í´CY5ñ¨ç+ÚïÊuôïì#<Úw÷hŽt©‚Óš^¾‚ŒåêQèwQÙBWwé›)I}UŒ¨Šs·q{ÇŒŠYÓôL†ÄšŠâúÿ3p徂²„Œé T Ž>[Ç<ò”qTsÈl • nËé¹²ŠäUq ò΋L7Cþ8_E¥Sÿ’Mæâ²cŒ1}à¬1¦÷‰­# Ûuܨ â.”Šû`,{Å?"üÚ—[Tež³™m«%V÷u[¢Ev¡½²È²Ž!È ÿó1ÆCQ ÇY(½zq7_÷2d™Ÿî ‹û#F›ïC- 7¥ =¯Çµu 2ЛÛË­ìc÷Å&Èb#$”=çÉ”é Òrí·Ã¾H<®DÂÙSÀu!ÔþN”!ᶉÅ-°G£6}9`Ï(–D€~.* (uºò7"xxØ9ó tÍT³+bÄn2#ÆgĈ¹È'äf$p½,éƒbD-Ê‚Ø8>˨u鏸¿–‚^Œûãvd xj™øMà_TŽ´ 2³Ü ™[ÖÆ½õ"Ê8ºuFZHŠcù$©C?á ¸uµ™]â.Fµ1Ï…„Öõc8eS\s‹³ùŒ1ÆXœ0¦ÝWc"@>!–#bQù_T²q=Jî± ‰h9 Õ/Š@} rkoŠ÷J ¹Lm;Ë!HŒá¢ãÿfÄ8_Œº|”kœ¿AÃ)¨á`à”±ñf‘çkR|®43b\;1â¿À­(ëæ`qó¨@%Ðîó^H<šbKe\oóB€¸+‰çQfKzMV î‹àñO1¦HÒî{¡–ÉÛ!q³"æÆ'«Q–ÕKô¬™åªæƒ¨ ð›(³hFÌ=ÿjÈåË0·v>…ºEŒ±¹•šŒ1ÆXœ0¦ÏR×ñh×i ÚazµH¼íÂ-ï¥ÅíHàF´ëžvÂh qb92JL‹E™ÇÂÇ×ñ³±8]ÏMñs Ê(nT"‰#XÝ3‰ŠroþŠ2zb‡óËÀ™±€¿íhîÇñ‰î !$}8=>Ã\´k{Kˆ/…Ñ—²mj"€Y•f¼B‰ÆÐ8GÈŒó‘£GЮìRV- Õ¡ì¢õ#ˆ|ÝSéu¨¬îP”‰³*áhB¥Xw!SȇQæSŸ+­‹ya2ò^9>>Óm1O<ÙË•c¾«÷ühÌiëÅü=2~gýcŒ±8aLŸa(2[<%‚åáÈGâFà/Ê z{ç­eì‡v³Ç¢Ý‘ñÒÖ Õ!´¤Ý8*;x¹¶Ìçɶÿœ|¤!—[X†Àb‹$‹€·•ÃÜ üy+Ì£gSŽOEåŸEN÷ã‘/BV ˜ÝsUAÀŽÈÀóeT¦ÑW‚€JÔNv"ÊŠØ•µlˆ²YªãšXÇ~ŒÇcqΖwá<­ãä±áN¦³ë›!!B„Jë6‰¹¤u׸6æéçâ{ý¢\!æòíÅ}·4æ_o–IN3Õyoã)þŽÚÙØ ÆcŒÅ czíÞ‹ÞÏ¡´û ”’~2·|£¯.vÃÇ m ZÚXÌ×Dà9$„–ñ•ù÷°4†ÆÏÕÇkÜœ]¢¶w•ÈAþ´K¸M¼×Û2$î÷VÐ~ rÑ? Q ÑçqÜ÷!Šþ¾ÛŸzElBÄ.H,ç„Tæ¢Ô{㳿€2XV¸ì„¼4þ×ëÝÍê¨GY6¢6¿›Ç5º‰c—!‰™q]öH [̹Å}òz)ü`òI2eé}e7Ì ¡à ¹\¹D¼ôoß¡ÀבáðË(‹ì&ߟÆc,NÓsT¢´õ†”¦¢ôßûPîh·xÀ»šÇî~ef.©ZŠ\t§µÎïEÆ–@NòMX\ˆÒ‰gÓ7R‰O~œ ü9óý1Ày(}üàXàµ~ôw¡y\lêòwGY©WD3ê*ób|¾ûC”x“Òï@Ÿ€ M¿ƒ„ c:$6Bž/‡ mÊÐyeV]‡ügVôÆæ“d,*Á˜Aü¹ÀÃŶRµÓâïÒP”­÷À ¹\¹Ê+㳜|‰?~³›Œ1ÆXœ0¦¬Ô[¡ôýC"ø\\œ àå¦nÏCCPšðh·s}TVòòê¸xí:ö%>‹ñSP˽,£_#»÷a¢&Ĉ-çûã| ÿO½"FµùSðŠXIyŸŸ"ñçpäëa <$‹Ç4 %O£vŸ×!³Ø^Ÿ7¢£™è®¾‡ß!ãÍ…Å”c䓤&þF}7îaB ùðPÍr«Q–Ø/Q¦Û5À)sKecŒ1'ŒŒŒ@Æ~§ Ö‡u¤åQùÆ«tc?v»jãŸÙt÷6úO·Œbçžú(ŒàbÓ)!ÓÇ‹PùÆúnªðÉÀÏV!N€2 ~Å}!PÌêÇ‹n‚œø÷ abTü_cu÷"Îé(+bEŸ‹ àò¶vG" ¼T!¿™ƒâ^Ú2æä%(³êŠôg"±¸OÍ£1ïBa'#߈*Ôyã"TªVTÉG>I† ï£o£ ´åñõùe2ÌLç“iH¨ßx ùã2cŒ1'Œ)z¡5.æ#hn‹ÀèwÈDm>E˜å“äƒ(M½>o©¡d3…ÎËygô±uÎXÏñýôçWf^#}ÍV ©—EÊÖ7Eé×Ä‚¶6>ãc¨«ÉuHêmêRq"ë9ÑžQ¨Äã0äpòÉè±_/‚‡ï¡ÐžtyŒù=(;a:*YFïšÜÕ¢Ö¡ NÞœë”" ÿ02‰‰„²Ç3sÆLú`‡5ˆï¹c$„/@™+¦$#ü(>Œ: ]ü¾ŒâDÊXÔÞ4‡£ÿA†™M¾Œ1ÆXœ0¦kT¡ºúPWˆIœÝÒóˆW)¦G?FõÁ©1eú¨ÌœD¬ ×°hOPÀ?Q9È’2_Ë£#¨ßùFlç¢ VsÐÎæ(CâU$tõ%Çý¨~¾2¹…ž¦£‡âZNÛê^÷ÛSôórº(÷X‰–Ç O£•qÝÿùSÌ¾@µÈ ¨§l÷ÃKd^JnÚÁ¢¹2ó¹²mB«âÑ ,)EûºUP‡J4ö1Ý*Ä”¦X\ߌҕÿ‹JbV먣V¢«cà_(CçûÀ9]‹J$þŒA»­Û†±%ªÅ?Ó„2#¦#è^”™²˜þ•b½Ú5ÿ/*EYé©kÐ1 e´"CɃiîz1Ç½Ž„ä¿Ï”ëúÎ'ÉÞÀQ¨¥í@c¹ÊäòIRÊ®NŒë~LÜ»7£L„ûr¹¾.ÔU ‘ú7¨$gfw` cŒ1'ŒÔ7Cf]A»rhî¼âàÝÎÌC‘ÄAÈÔr“)VχqðÊÜh€ãvÂÛ~¯ IDATëøêQ«Ú±°¿÷Åö¨b¿ø¿åHÈJK!J:ç“ä³ÀYqÏ=/®Þ*c6E5F­«7Œyô T6q]øHËä=ñ…ø[{Tü½õßXcŒ1'Ì ¥¥Ó•nÔ#† ïèßå=5_Ô¡ÒÃã±aÑKcÁ~52 }™Þ7Sì >üH¾„J5:C%ò€¸8†¦ªPÆÉNÈ_aK´ó8ŠBg—&TŠ1 •ÝBÄË(µ}ÅóPæÇräO27‚Î9¨Ôã T®2í,·7…M=XLÿ¥¸5æmy§)jò:ymI¡ûÅ…ÀßPûÞ¢¯0°|_Ùp*¹¸x±\%Qò1yöœ„<|mÈå–õƒsXƒÚD!D•ÛèƒÝTŒ1ÆXœ0¦œ×ö´«? yìŠjxŸ‹@òÊv¼¬>†²"ˆ `3TZ°8Èÿˆàᵞӂóà\àËh'µ³T¡ÝÐß"açȸ^ÿã݊ĹÀ‹¨s+£ØÊ¸Ö²nÒ.7KQ6ÉÂ3ÞŠ±œƒvÞÅÿ¥¦±Í™±¬Š€¸6æ‘Ù¨VÞóDïÍA×E@¾*½ëh¾âÅgQ)Ä($Z]…¼ƒ§™7ù$©6G%‡ ¬%qž‡Ã¥e,ù¬ŸeF?i;]‰2ÅvŽó3e.ÎöåmŒ1Æâ„ ×õȨpÛöZPïõß¡V‰oFðç›U/&w@~{GXcö$2v¼6‰Áìp<º¾ü²‹¿[ÎQ§Œc‘˜övR/Ç×iðܯ®ÕðB©ƇðòbC.·¢÷ò'‘ˆs6ò‚áx`2Ú9ŸˆJ]FQ0„­C;¶©Álû¿ymq£­Ý{¦ê;>€JLïpò³Ù#îÕQÁ{CÜSëÄ=t/ò?¸3Ä„¶"¯ïª¸þŽD"å†ñšÏ¢l¼+7úAÙE9ÿ×#!ç($äLï­D%jÏûÒ6Æcq tªPªí‡#¨Hs‹Q*ø\Ï¢.¾ ®ËbAÛÏ-ñ­¼³Íg]¼~}M£‘ãú˜xŒŠï×S蜑þnö>l[Eà”Ý nŒçeñXž \›(¤²§éìÙ´ötg¹%è¶dèi –vƒ 'E€üHˆ·D ½l ^8pL5är‹;ñ+G^ßDÞ]¥í¶~4WÓO³H=¯GBÖ¶¨te§[Cr¹ºñÒ‡¢Œ’3QJx{²ív«3bDÚ±fJ‰ÆZñõˆÌ½[¿“Î+)´a­@å;ñÔÚkü9D€½P·ŸÎþ‹2¾NF%È4óO!̦È죸îG RÏ¢N9CQ¶ÎÕ(kã‰nsýYØ$þþ_× L¥G€Ýâïî®”·²1Ƙ~Hµ‡À @ZQ=þÀbA´9Ú©Ù4‚Ï)ÈX°¦Q€ŒÑš â[3"BÚ #Û£rÇÒšùݶÞku =Ú‰!Ù]ÝîÒÖ‰÷¬Šç{QvÀl¸aG?ÎÉ'ɯ;±ë™¦ú×tómW ¿‰¡r™«úÉX¥YcõQ–ÍÈ3cíø¿¶>^®§û»¤é.÷ðÕÜïé¹Èfñ,èdÛ‘Øq@ÄK(da˜ÞcYÌMCºð;-Ht¾¸<‚áSBDøÊvú7êÎôÝ\cŽX\O’‘yí'BL9>îíòIr.w÷“RŒÎ’–þm w§Å¹Z‚Ê\.n¤ ZÞÁ¸1ÆXœ0¦£àûZä°ð+ä‰î¬ÖF 3 ¥†G;ªcÑkúFa÷µ&•vW›cµ8§oÇc~<R0ékŠG6…¼­Ý׉ՙ÷Nëàë3_×Å£*ósé.puæûiÆFMæ9Û‚´%ÜMF~WßE]tùKì~îÒ¾ÛÉdg>óÊø¹bæÒq]l˜¹¾úšQ2Öcû"¦ ]㪋1v÷ ügP–ÒŠ"ÒÛ›Ö NCG>Û¢2P{ÊOá,ÃÞ¦)ÎAm7)ï@¢ô§ùIÔñã1djy-ʤ떿HC.×3ß·D°vay¥Y?üEÆÿ7÷‘Þ•2'Ò’’RR‰ÚN~x!ÒÔLsDœã¥žz]”(ÖxM´Ä=q]ß“På£QYÆç“Pw2Ó|uåèO™5©™íDä±WˆPðiB¾I÷Åã®&æSÈdê*ï÷¾ƒþYiŒ1Æâ„1E1¥¢O‹…æ I§®ÐnØÂú!óI²r_µ=«[ý5¡Øñ¬¡t!‰£€ƒB|˜âà ¦§i Ú´mîKqí?—WÄB´kÜ\„YeO‰åÌœØ ø*¯ù,J;Ofq¢Ï\Pœ·KWhFeÅ<11‚ë#B¨hˆÇÛ¨ÄéÚ,fÐÍò2ÏéÃQ‰Æ{BŒØ•h¤&³ñy¯ÏñhÜK)ðRƒJC–ÓùV°Æc,N3 XŽLº¶Dõô'ÖL]ÉË =èóI²p1*q88³a"í¸RL9F*U#ÃÉÕ1ø**ËHEÀë!:¼œæÅ9Lˆþ꣒v’IËOJÉ:È[b(ðàvÿ?ŠBKTÓ{¤BéÈ^xï&”QôWà2`L÷‡`±ʰHî.à”•ô&=ï_”šW®ƒJ4öG¾:i‹ßÖ¸ž_F^·#enÌå*׊9kÚ40Æc,N˜AGªÿ°/2ïr:éšÅ‰1hǽ±„*ä¿IœÃçÃX®Ø×€Ì/·òÀ·‹|ÝÖ]§óc>щ íÈ)„8ñÿÛÔö³¥9¼!çíÑž¡(kfcd„ù·É‘qŽí9±fªÐnü| e1¥"õjÛËŸ±)‡kP–Á0”™·oˆ[¡nGÇǽúxüìmÀ‹1§–ã­E¢òÖÀB,Ù DŠ–8'‡q*áš‹J4zbÎØùÛÜŠ³Œ1ÆXœ0ƒ˜ÇÐ.Ñ®x/ëD[všö‰…Û²XT¦Æ…+"`jÊ<Òï­ŒÅ`ûö¢­™@4}Nw+3ª¸/«P*lu,2 œÙÉûâTT_Ü>èÌŠ =Z3ÂĪíšíŠŠvÏd‚²ÕgÙן‡2žéâxC;Ô3èÝvªMÀ—PÖÄQ±àÿ.pðH>Iþ ÜÌïL¶@>Iê€3£ÃSr¹E%8ÎR‰oŹí[ö]¬ q¢¶DâD¿ŽÚžBÇæ¯U(»¢…Õ·HŒÔ„P°j¿¹gÌ•¨äáRà£1÷–joEÞ•íÜ”+{¹ti*Y¸¸ [롬ŠQVŧ€O†¨ñÊ$¸ x.3Ô <°«c^˜‚Dó=ây 1sòŒøWˆ¢ ¦> T"ÃÍ&Ô†ØcŒ±8a-+ÐÎè–(åµ3âD3ðmT_<íR Í<†ÄrH<êÑ®núý4ã!Í„È í†TÌH 4ûb…ŒŒlfFkæ‘]ü¥‹Øô½_¡{½ä§Æï¿Ø›âDoç‡1íFÑîÈg!ŸO’xuU¦Žù$©FNû'Dð©†\®TmRÓÈš"_g~<õ-û.Zã¨)Ñ߬õÐ.wðedÊ*ĉ!I*㺇Ê1Þ‹2BÎmÈå^ëÆKóóv'ÿþcŒ±8aÌ€¥-oŸF;NׯiññÌ5-¤b·.ÛÞ®}«»ÊvÏk:ÎlƼ3Ë¢mM‹íXT¦ÇÑÖÍÅù†ñüB_9ÑÞóÅ|’ü ¸í@žbÅÿ'Ï'Éo€W²Ÿ;ÆäPà;(›$×˽ZÂÃk‰óTÁlwƒØtç~ŒoÙw‘Šu£(>Cex뢄«W3TÆyMÃÁFUÔ[E@½wËCb<^ 1âê¤S!myòñ8šwv@éi׈µVqŸCe%Gǽ~c>Iþǵ¤x±4!1õuäAQבGÄö¨ô!mù»6ðÁøœËPæÈ£!FÜóó<Š,Óˆ¿aC‘(ºq&;… 2)þ¯ùg\²3ºÊø8?…¨bŒ1ÆXœ0ƒšÇ"¸Ù9®ù’¤hÇ‚·Ï–h§pýøL¯öµ“㽸/Ÿ$?D¾' ÓÓä“ä\ Žð;E0ºµ‰|¼Ä‡•úÔù:K2Á³y'­œN(rœ«‘˜µ/J§?{ ¢CÊÖhepÔÉ× Ï‚ Q™Æ~(ãlLŒÅ"´C-ƒeK¯¤·-Ê øh‘sJ#òÀ»Š9ü®8ÞãÃãýŽ@`—„_ÍË ¹\_™Zâ~:¡òŒ PKÛ}€ïÅøÎ Aà­UŒuW„ˆôüŽGþÛÅc”‘R„Ÿ•q®_D]<îEe"Ïwó­7‹×~ }ÆcÌj_Æ tF"§òj´C5ßC²J®ˆÅñnÀ“}ý`#3bRA'Gû:ò—xí쮃¼*.(CMúÖÈÿj´SÜÝ×?¥Åÿ íüö¥1NXWöÒtÊxÚù¼ÔÍ¿u‡FåNtâu†FP6,‚¸·Ð}^ã$`Sd¨¸Sªc2Àq}_‹üæÐ±qhG ~‰J± Áàõnïˆ8CÿÌ‚ÕÌcå H‚Ƀ@ÂÊü^.ûèˆa!Œv¤{Y éýZBÎT$0½•V¬‹JqjãÇ›Cˆx‰ø„ 1e9¬(Á8}ù»üÃb1ƬibÌ@g)ÚõÙ-‚W‹“šÜ­@i¼}žX8¿‘O’Ÿ#ÍÊ–X ñ_I™ÌòRú"_§©7æäðãH½† Ò‰ñÔlˆvX×±<µ»S‘´ ãjºŸY²)jÚ‚üG:ãƒPþž9QÁý„‡‘г1\PfÂà~dÒxWŒÓÒn~þ%q?V£r‹<»#P¤sÒèÌñ®j>x ¸<Ÿ$WE0~8ÊªÚ x.—ä“äBúN6¨%éºHHŸÓ{¹‰n'Å}»VÌK•ºN½ÜÄ£(sã"šÊ ØTÅõ¶"ÞËcŒ±8a=-(ϸž̃‘zet°­C»ŽiËÔ~C¯å“ä!RüíÿøQwZv’´æ{ª¿îeO¤ 8U¨öt»  †B)Bú¨Cõ ŽŒßçzt|Ú¹­§àŸ‘ú 4!q¯7ÿ^ÌŽcêŽaèZÀBtùp +ǪŒÏ¼’þaˆYç{4ʈØ2Dˆ÷ iL&°oB"í#ñ¸?æÈÙqÿ—*ý~1µjB$ø ÚAŸÝÅ×iF ›ÐI*¼j^È'ÉOß!£É™çWQ™×­ù$ù=poC.רËçoŸ¸÷®¡{¥‡U(;hg$(=‚Àt”1#ĉ&z. jX%o£cŒ1Æâ„1±8«ˆ굃|,ö o†3"Em,üõ7q"4£V£‡¡â9e:Ò]× PÉÀ±¨ýiWþ5™ qMl€ZŽo˜vô¼*!$íÓïÙˆvkçFó ª9•AÌ뢧©ŒkrIFhè uH¨Ú•,ý¶ BC*ø,£yËdÆ%›º¿]|Æ­P‹É‘ÌC—Çù{0„ˆ‡QÉÖl F“åü| Q¶Jm oˆ·ºðiGjºh›ñª¹'Ÿ$÷“Q{âO rªOå“äàJ`^/”|T¡¬‡&TvÒšQùÄ™q¯.Zz¹½ê8 f˜K¼ 1ÆcqÂñ\%[S\W…ÀF¨{ÉÁÀÉù$¹9°õhgu&ýܸ,‰Wzà­šã1+‚žó"{¶‹¯34ž—vâgçÄûlF!e»5s,M™Ç2”RÝÁÊbT¯¿4K"8]V ¹—ëñk‘AßÎ1–»E@ú]ó›¨B\މ`ü´‡®ü~uŒ_oGš 1<ÆdXß‹Ê2&ĵSÇØ×â](m:2Vœ×B¹…ˆU1•\€Œ+ÿâ@W|<^ë}BóB 03Ÿ$¿þˆ²éNB2ÎN.’gCìì &Äߦ׻;o…ó6}Ëe£¸~§38;ÞcŒ±8aL‡¼‹ó"øY6ˆÇâ¯蜆Zý}7Ÿ$lÈåêÑNñ‚4Ë'I]C‡¢·ô¶|}4(¸øp>êЕá´DcA'‚E‘ª^ÑÁq´õÃóSvú7G4öáeD|¦ùÀPw–ΖdUFüÝøýÏÐõ´òÚøYT—„.PƒÒà'¡2Œ­QIƦ¨µäpÞmdøJ/Eøj|Þô=v.ð)àÂ87ŒóÒY ×â¼N.ö@âY\•O’‘Yä ¨,â H¼½;Ÿ$ç!¡gq™ï«m‘ßË¿Xï‰ûûQú^ö‘1Æ‹Æô #Xœ„²­8ÑË5æ“ä,à)dùc`ãI“&ýmöìÙU‹Ï<㌵¦®³ÎûP‹Î(ì ߯àÎ:éH˜h‹ñùu؇ oƒÓè|gƒt7x~'Ïa6h¬ˆ{p2ÊŽøp7D€ QÃïQvKg„¼Yq¦”x>\<šO’Çb.<ø$°7Ë^.Ì'ÉeÀëeȦ¨±†¸ÞJÛÚ TnÔ<á?Æc,NS`ʞإˆ¿=˜£!—kÊ'É•hçõÀ1›l¼ñ#³gÏ®\½õ&N™2å¶”ZÐŽì{¹~¹/ÒSJ©ÿ2íûªí¿¨“ãÄx9tœj‘GÆôíƒJ†Å¾bÄ5Àx/ïfÐ=•Lήêæë ‹¿‘ ‹ ÓnSQÒî¨,c*ÊI;‚,q¸?‚¹éÈÐpVCwÇ£¼e½ œ–O’Šèr1yNäQÙNšA1o ¿7'Æi2Ê h-ñœØ‚:ÿœâÉÎ!œì üo ͇JèeSìD¨‡Ð=_‡²~–ÒuTcŒ1'ŒЬDõêéíKƒ}@b÷ý‘|’lúøO ˜IÎlÈåÞêæëÍFmEàCÈLöÓ!~¬Šôú˜Xq"3/¶!o–›òIrêŒsL<>‚2£¦ç“ä×(Ó¡Ø’IÈäö¥¾|ÿG—§:ïI3">Û› òÍcŒ1][D3X8Õ ¸ÄÃñ.ö®>|ø…çýö·ÿ‡:]4{XVËx”fÿ&2n\í§Ÿ¡ïƒYýÎa jo¹ÚQŸÙÏþ† A]#ÖCå »…(1™¬bÄëÀ!HÜcVJ³ÉZàû¨Œã>àè"ƒ½#PæË™(cuç/›²G£"ˆnBÏ ²ˆûPkÖ·è›Þ« NkP™ÃO‘Ðô$ðeàž"2ª&¢Ì‰ Œ™Üjî•uQiË“¨ ¢©?{%«ö fǸϟ‰ñ¸º!—ë®WÄÁÀß‘Éí×èC¢Tœóq¨<ãÔžö,à†N2[Åõ~p$6Ä4ÆÓ œ9a/ÇóúŠiX²dÉò†\î G§H3'²Bo ð—Ô‹àö$Ví?Q‡J–ѵn=M%ÊLÁé¶!¦lBÄðØšQÂS!FÜ2ÞŒÏØZ¦c;µ¬|…Ε ¬‰õã¼Îìà½F"1ißxlŽvŠ+PæÃ(#äv”‘úCôÛ­!—[æ‘D"ÐGQ†ÐoòIòó†\na7^öMäïð{”A‘G%Í?ËBH¯³žüì­ÈæŸù$¹ùð|)ÎýÀCù$ùpwC.×UÑä}ñ|Go ‘1‰k{Źޚ‚aï< m×ÄÔXc>G?ïþdŒ1¦çpæ„Lì\ à“8Æc¥Ÿ¿DgÖ̸¼ç£v„Yqaò;Øí0ÿ‰ŽwÉG¡Tòè\;Ñž"†R(OØ%Ä–MQ–ÀÐø™æºß@%,÷¡Ýí1&=Ѻ²™j&! |$D‘bß÷—¨»Ä‡ãõÖvE> ; ]ÿªxÏ™ñÙoB fÓs]>z#ˆ­C;þ?ADkü¡nšµŽA™Ç86t PŒŽ{­e.,íå1¨EßF¾­À¿/urjP'š­ãÞ±>GM\Ë;Ƶ¾k‘ úêXruÜÛov2SæDàq]œï?Æc,NóN6‰ ã.Ô2λ9ïdGT^pI,,ûKºym,ò{¡æTÖ±ù™´˜vBí‰À«#ÿ‰)Ü=ÊšzakQiÆ´¸vEiÙQiFE ‹P»ÊÔKã±ÌS!¢§¯™Š8ÞËC0ùTˆÅ •ÀWÑ.þb<6Ž÷hA>×÷Ä”++¤¯Þw•¨ÔâGqm7?ÎmÈåuó^úòt¸8–w–xŒŒû¤ e‹»x¼Uh'e)»Ý䓤eP|•ö¼…º~ü¹¦™kEÀ¿,®ãÅ=pÞ*âžÞ•Ó÷úÈø‘ù¨»Íõ¨}ô `i7JwÎDÙ%G‡°aŒ1ÆXœ0&CºÃ÷*Úé²Éã;y2è»6ƒ>)Nd×› TðƒâXé…r”1\¬ˆ€©½8‘õŸx&‚¸Yí~fs´[|ò9(·hVR·§¢ß]ãyÝP*c<¢‰éq|£ò„ÅqŒ}áúØe§¬ |í¾w÷¸ÒäÝQvÄîÌ—"Ï‘ âóÈä¯_œù$†ü^nŽö™¥zí!È,ò{(«æäûñt7D€4ƒâ¸r:ØŒˆù» •uUœøH×­H€}¡ˆŽ#½þ$ê~1ŽõÀO×0›Æ½u|æ¦2ÿ*$>nï³7*[ª‹¹ëU$L_‡Çy%›‹Ð&À^ ¬.$ÆcʼH5f°ÐAÆh_û’îü¦µó}-ÀªÅü!äo~[Ãl IDAT„Ìca½¼«%Õ«³öþ?±"+b¤Æ‰s)ýÎ{e‘GÂ.h‡v#´k›vH +oB»Ö l€Å”Ö´²”LD¥ë£ì„01*²´G2òÜ/®«÷„@“¶7½íúÞD¥¾:kbÚÅž\šO’ï³K‘iÔË-Ï'É…1Fg£Ýø3òI’t±åæÛ¨änHœ“ß#/‘·ãþªŠsÐãnFÙ;¡²µòIòçAÞ*6›¢!—{;Ÿ$gÇõòy G«c*ÊZz†ú‘„€;$^ ¥HkÅ8.F™Oׯ=ÿÊ<+Õµ]…ÊÚV¢.+ÆcL§pæ„L ôÄBæ„ ÑTli."àHÝðŸö§wÊ Ú®¡í‰iP.A;ùW ìWr¹Þ'†Ç"¿e¬j!>•ìˆê°@Á óÔ¶õ—À7‹<žš@6v©­­Ý»¾¾~÷Ë—oni©lkkk«ªªj©­­]2bĈY'Lxn½u×}jÚ´i/O™95Žg¶—Æc,Nóîàä&d>¶E´lŒÅ~=«w.o£°ËÚÖÁÿ­êž¬Œc­Š×¯A»kõ¬ˆEèÄXüMAýäß¾ÔËÍéæÇšâÄÈA¾ÇË^B†L$AmÆ,àäò$fõ’ ‘e(JÉ‹ð·V󳡄uxg ±ÀP›ÛŸvñýkÑåfÀûã‘¶±¬®¨¨h=jTíĉ+6Ü`ƒÖiÓ¦µM:µmÔ¨QuµµmÕÕÕ]éu›>·"—þÐoK|/ÍRhÍ<7ÑV²³Ô‡À“CeHDzf¡± ’ÿ‰sµ<‚Ý¥À³°] ²‘åx$€~ µI}³T~-˜oƒ²„vŽùäë¨ÝfW‚áµãøvC]AÎD%EµÍÌÝÛÆ8|0ÄåÀƒ!\Ý ,è›§‹k°«Ÿcdˆ,ûĘl÷~šñl|–Q[ãÅ=p£ˆqÞe¾cŒ1'ŒiÇ?‘yÙn±Èíî|s”R>q5ÂD[^ö¹­Q¢2‚¦ì£2ó\?[‘yŸ´Ãý ðÑ"|Æ šîF”ú¼¤‡¦ÊXPo ÁÂÔ$!ÃÉËb‘ýzwûºCÚœÁïœ5Ì·;¡þ¡h×ôJàÔõàdT²ºß¯kn+´3ºKˆÃ)´±œçñ®ššš‡?ôÐe»î²K娱c««ªªêCüáq,ÃQÇ&™k¬2s­µÄ¹HM/›3•ñhŠëpYüì"”I2?D¥ÛJpîêBØù:jUú:'2VF xz|=øaˆEoĸµ † 0vØ÷ ñ`#ÔêñkÀ­%΢…:5œó×…À÷r¹®´xü5DŽ;bÞþ72*m)Á1V!Qö »¶Šc \в7^,c@ÊâØ•S­îXÓû½‡ýQ©Æ„¸g›wÄ]H„{‰v+zÁ(xtÌAËã—bŒ1ÆXœ0æ]ü™·í‹v¼»»¨†œå§¬&Ê 탽öCºûœîJ§_ì- ±`QVs#žÏ ÐîÔ’"¢ÙÝ®m)c­pf×o»0?€2 ªP*ýC!HÜ‚ÄÊ>z=Õ¢ÝÜã³¼Þ‰ ù€!šÑŽéÞl·ß=­ˆ1Z7D=ã¼LA’fÆy»•BæK—vÿ£ãÉ·Q¶J…Œ‰THK¯Ýl6OU;Ѭª€–ÒÞÞßËÍ,b¬«BÐ9 ¥‰NçÆŠ·ëã\µF0xïnY9ŠŠ¹¾cÐ×ä9%Ì¢¨Fž¿Œq ‰pÓ»Pæ19„]ãø¿–J=&Ãâþ$*÷óîí¨æ=”¾#Ðßc>Ø•©u$žŒC™(R(Õ¨‹ùcþ®G%‹3€e=”±:ÆÇqÍAåDcŒ1'Œy?¾Šv—ŠYÜ×ÅbyM÷WeAVöÞËfQ´´ûšX„þÿLŒ2Öý§uÂSb‘þf‰ÑÈiÿȈ֎ñy;‚ÅÄ1Ìéc« ˜ÿƒ²&¶Gžk¢ÕåÿeÜãqPˆ 뢌ˆ}Ñ®ãø87i—‘°vG{s(AË$kÛ]—]ÏÙÒ£¬0‘.†  Q(+cpç´2„“?Åg=:‚Ŷ.ž«›"л'Æ÷>´ ÿÚ`œ ãœ0Ÿ PÀ×P–Ks ßgmÔrôȸ†OþÑÑq<òÙ‰R7”qLRoŠ ²iqÝ är¹Y%|»ëPVÈN¨Lö¼ˆÌs·E6@¥OÇu|kœ¯…¥ #<ï¢íÌU¡ÒŽî.PkP*ò.È´óÙ†ÊQþ‰J6æõÁ]¿®Òt]~g%Ju¯ˆ€p#´s½•hÜ‚Äs¨”g0/î7Aï öžÝfVĹZ œãz4òþøJEoLƒAîù$9ypœÁøÞù$ù p{)Ê¢åèùÈ+ä<à‹ÀÆù$ùB'²ÖŽûã%VïëRÊqiEY×ä“äÆ˜KéÓγ-\s ‘ÑkÊ>XÚJ5V5ß§^[Ç1•{}Ø ùRÇ¡²¤o#a³Ø`¼5Ÿ$C™ßªòIò‹Îf#Ä5¾^|†W#l ´‹}z>I.ëN–Fç!?•óP·”ÍóIòàåbÅ¿†\ne>I. ñ¡‰w A[¢Œ“XÞ©8±>Pö^ ã½PéÓN(k¥)‰Åã% q ç=m‰]cÂcŒÅ cVMš9án³8ج. XŠ:ô b§oTÝ€º_Çx}™ß>-7¨÷åS4SPgŽ1¨íïÍ”vWyV¼ÞÔš:zí¹Èâa´›ÿ«Ô¾ÊBŠ(ÚòIò òZ¸øV?í¤@QÁ)À÷óIrî*:Þ,A~(g¢²•÷ä“ä‡lÝù.Q¸/Ÿ$¡.3  ‡Oå“äbÅ¿(ÿzcÿ½}ñàÇ}ù@3Y;Ÿö…öRààÀ­ ¹Ü’2Êñ±ˆÿŸdM÷ üØ;ŠÓ(xÄ”Š-æ-ÀQ¬~Ǻ*æ‹óP‰Ç“ã¹¥×oeÞ£N7?~ÔË-ëÄïnâÀHÔöóòŽü]B´Û-®ÏõãsŸØË½^ÄqAåd”iu2pM™üej€kã<ìAr9æ’Þè ²ÊDø-*aêÉysê€s2?^‰u³‘˜û·¸Î»[¦7 ù•¼Ž:²¬ðôfŒ1Æâ„1«NŽ´8ñ.Aõðg¡î}Q”¨ŠÅôá¨~“˜Ë^.‰ÇK=Ø áh”>ÿ¿1n] †G¶íž¶Äss_)•é!ê#8ÿÊ–8Žòt/X;‚¦(}}Y'çǨÜc1òŠÈ—B8‰ x›§¢ ‡ÿmÈå;ñ{û£î­( ÿÖUiÈoQgçPæÅ£Ý½ÆòIR‡:Ôü0¾õMàOe0÷E!cb{`Aæ“ê­‘ÂC¨Ýq¹ï¿OÆ9éQ3Ÿ$õ¨Dæ(ä­²nóQW¿÷QšVÏcâ>kv¤eÙcŒ±8aL_b½Xìþ¹7yHÞÁÈìì(½/‰CmQÆËc܈Ħó»€E½ÔwKÐÉ'É„¦¡üð.‹ÏÕ˜ùz)JÓ_ò’øþŠxnŠ×híàñÿÌ¿[2ßOëâҞvدFYßžA^!¯•àz©Š€qC.—–cŒDåß:ýôã6ßl³í¿6ärkBêB8ù>”þ |#޳µÈã¬@¢é%À†ÀÀékÊø‰Ïwl¶‹QÖÓ}«ºþóI2:®ÏO‡ðs*pÕ*JB:+¬‚ʈ(Î-ñý·Aœ¯é17­(üRóÇQñ­9ÀíÀå™`½sÊ÷QÆÄÇâz¢LŸm㘣ŽDånµqþï‹yëN`nw¯ƒU0 y„ ‹9»Ï·I5Æcq˜Þ`ÚÑ™ƒÒ—yHÞÁ~¨èoQ{¿Þ$*QŠðAh§q ”nÿ:p)*x±³$V%è\þÿØ»îð¨ªí»f&=¡wPDÅ.`A,ر÷’ç(ö‚ û³÷‚]Ÿ¹:Ög}ö‚]A¬`A¤w %=™ßkß\†ÉôIB8ûûæ›”)÷ž²ÏÞk¯½7€ä Å{oíôžåüæ‚,Š,=|ÒÑáH {vÿ=á5î‡.>pn:ÚD& ÆÁ~,®z€_Ó°nrœ£5ü €å`æi]›ß{Ï=véÜy{ˆSì÷—Åq­Û Ø ìTs%m¯Nñz= è%0…äe—ûý¥1Þ—¥û¼Œ€Ÿ `B€"LºŒšßà±xRI¢ìÏ]¤/¦™æ½¸§Æ7¦Ôg@Çx@Ðjwµ'XwÁ£5ùµ€£ i*^p(˜Æ4%÷ãÐ]zéD­Ù<àüQß;ÀÒ êÍ<<½Áô‘E°bÅŠ+V,8aÅÊzÒ ¤íæÈh*µC²Žì à]0Ï~t‚9È‘:\ÎB€IP- ¥ÊsOTðØfñÊ¢l„*Úg¹À‰ø9-òõ( {äëÿ9.@#Ëõy^}¦ÏõÙÙ®×™gJ=’j~Câ넼 äÁ×N;0Ýà°€åɾ#Ä‚ZûŸyúéwï9lØy çg)ôU÷ß^{ã\Ý`|RgQô‘#¾=Xà¼X¬Ž€ãd²"ÊÀt‹Ï¢>­ÙÿèÖ÷¸.p&@ÑF¿–¦™ys*”êàžT×FœŽ}{°ÆÅÑÒ‡]´n–€Þó~‰•zC²l ]sR¼n/X³e0%jwÍI5€ßµæß0·‘€\X»bîo–=Z­X±bÅŠ'¬XY_²åØn)pb¾’ud•O¸¨‘ Sƒa°Ánr¼—Êà¯b¿¿²™Y³b›¸œ•h:Þá¨kd°gÎÞŒþ¿†jÀèž7µÝü)Gý—0Gýf—ù|¾9cÇþ&§þ}÷ë6fLjgé;ÆÈÁ\ Ö¥x¡Ž7ÉÞG9À»øÀÅ~ÿò8гÁî"UÚ?o64Ÿ®ZÏJ~²f6³½u1˜.õþ½ŽFên! ¢­œëãÀNÁú0ÓÁ:3o „D¯§É @fCi’ט¥÷û ÖG ìxd|üØ­?3!/!}þ³=Z­X±bÅŠ'¬X‰¼æ_3’V:m ‘Ý䨌p2©tÁ—ç€ôöz0â÷4ñ[ÖLX‘ä@' ¥uläÒUÎÓ@uðRH#¹?˜Ò Ø.l +ÅÑrþǸA©ÃåØo Rùïàûý±€†öÎYYS\Ö?©Iá~º‚Œ†½@züiÅ~ÿâ8ÕÀ4/Xc\4&HÀqzxÀ0Ÿ8!EF@º¥‡æâ9ôKäôŽ£ñµqZ_tfŒy`ÛÙçÜÇZq‹I/\`W$™^pœ>Ù?+4‡Ïé\[ÛÄ:óaÕÚV¬X±bÅŠ'¬X‰ 7‚î“ÀÈ—•ì*÷yd(ÇÛeX{å|œRð»ËHÿŒ’þ€¦)И¨¶ƒ¼ŒÊ[‰.ù èt¤Æí¤Ðù"à8­A–Ï¥:Óîp_gq €o|à("§È>Ö ˜*ÿûÅ}` Ò-9‚`ûËÛ@€­.Éûê¦0í/gü¢XΦœèƒ8éˆVGDi0ÿ–óY±ßßÜ:+dƒ€åé`QÇN` ÓÁÔ”ш…fm ¦œ©ë; ØïŸ–ÀÇlà{0MíP$ d§£Æe6b5'÷Z¬=À›VíY±bÅŠ NX±YN”±#€»ìp¬#»œÈdº,°+Á9`‡ö`5÷7åTýÞÄ.“YOÏ€Ý&îµK(ªx\‚8SåÜ-Oryl ¨Ü,ºw!€Ob¬ŸŽrhWv>q;÷ý@ÅþrŸë,‰”åƒÔÿëÁTµþ ²Bf&R§½îi&€ãq<5.»ƒì§.`ºÑÍÑ@íI€êf út?'‚ùÍJ|‚™_h.åú5ÎAFE¢Eyé…ÿ»§¤’Îäi¦sv"ØåýV¨û¬E¨CP=Ö/ô[­GV¬X±bÅ‚V¬l2Dø7\wÝ9[ôíkº#äèa æƒÔÝ|„ŠzÑp…:°âô4·e‹×Pn+§òã’(rgÒ:ž©êõi¼Æl°Á…`k»V Mû99Rs›qêF49À}¯±v{E&†ƒ(VƒùèÓ’\K&ã!}ó%Èxø'Žüÿ<5Ñ t8NѾYÈl|z'Žn&mÁ£ÁV¦e CäQ}N}{‰Ô5Ð{¶SØ6Y%Om,¤x×QÍÿ`ñP/€¹`½‘—@À«¾ßÃÁ`•–š –v!º ¬Ï±½Ó¸¡.AÆ5upþÐØ¼¶I¶bÅŠ+‘dÙ!°²ÊB^¯w@¯ž=Ÿ3Ÿ‡PçÓåÀç2œÜÏѤÀ}ǹ7Ó¹ÛªÕÐF€Âñ†‚¹ÌY`¾ä%"æžkÒeÜ+*»1ß{悬•—Àˆtý¼žº‚Q¾-Dp·45CÜ?»»|xŠ‚ç£,Ìh~®–£þ¸Þ;LyHf=µ–Ó3Jß}€{‹ýþUq~DŠõSÖ“b¿¿2à8¯ƒé—ƒŸðaÀq®0#Êš-ÓVÞÓ•ÎÕã¼zL€H\@A2{Cïù9à8‡k¬æ åHPëêHm‚ž[‚õ)F̯gÁ‚ÇÍð쨵»´Í‹iaz B-LóÁv¢ŸêlÊwéÓAÈ#Ýaºé Ò9ÑôêaÅŠ+V,8aÅJ ––ƒÁ«W¯^œ›› 0’[R±WëQÒ„+ä¬Ç+èzÔ»œŒ6`·«ô 8Îèb¿?íÆ§¢¢ÝÁ\ÞSåô,®öHþJÆ{¢’ëYÒ%}ÀHX{ì·¬ÜÀA ãÈw‘¾8½ëúLc¨ç¸„wÖ0¯7ïq?|. ;ì»Ì{Í÷š¶¢yrÒÛÈ!hÖ\(Òÿr±.hÎr;ÛuÚ#UúŒNšÿwƒ`s½ Àn'Øþ4èrX½1ü…ǹŒâÞ²=vpKÀqž‰ò½õr<ïÙ #œ) à$9Ñ/©%“b¿fÀq.ÜÀY>9·ƒÀbÆÃ¤³´¶þÓ„`¼ÀY`ªØ`ô¾¶ÝO'=/iú¯ðûA€¼kN^‹/pé_˜N2{²Ü Öþ­ù³µ¬X±be#›Öaec]÷¯Þ¹S§ýï3f:BQßzàPŸˆA/ç©XÄng° ãþN‡®Ïïæðž æ:¯B¨€åd¥)¦FŒó ïiìéSÚË1›`<€ÕÍ”«cs°0â/>HàÚ|2¤xõ€ "=Zé¹µëç„Ò…r]ŽŽ PðFZÇá¬OzÝ ´ªuªJœ[ëú¹dBÔ¸}s½ÄÈ »?/Ýn%ç~rót¸Öe'­ùKÌJb-yAo'z>;Îkh‚—kœ†ûý³øÎ`êÏiZ S\ ÖL¨µjy½½ÕŒº‹|n«¿¬Qó€wA v¶Ö¥À& cåyØ-â ÓR©µ¸¡ŸE 3â8ÍMwé‚y ðü*DW 6éѹù0•§  î.@bs°¾‰Oã¿,Ú9Àw`ŠÕå Ú-”°Œ9‡…QÃç&Lµ¹SÎÒ$0ã·4¦/ùÀt®=ì)‡«¹8öýA&σ5M&6S‡Ì«}Ò¡:ƒÁÔ³Núä|¯YJ“ÀâŸÓNTdøÞÚøð …•µ±½L-:ŒÐŸ¢µ×Y×<LŸý^¨Ï/Ó•š¢ÖH6˜J±—‰Á C¢ d¾ °3ÒÇÉùqï9p:™}À}Å~i{+ÿ¶ðz$ÐÏ%@%Õ/kfcÔ^Žói`šÇ ç¾ìŽX·NÄ@%aêDÔÈÑþLϘè"Ö ÔÝ¥±¤§®ãO0R_+ÇøyíåC@Ð-:‚'ÎÒ½ù@èQ0}«4M×ßÅÊ@ ª±Rx²AÆÈ^ŽÓJZk\f ÝëºçŠ ¬9/L>²G.™µ1Þs;˜nx3€»`ÙjV¬X±Ò¢Å¦uXÙ˜eªŒÍAšÆ gEé8ÎÑ2ŽPpœ³Šýþå&ö0‘F÷ž/öû«yLÚÈø+߈ÖA–ÖÀe`®µŒòÞ ÒÎר­’1k*?Âÿ:ƒl?ÁjýßÄJaҞ邌Gêó¿Aô”¤-ÁbŒÿ‹g^*z±õm‰îÿGiòÍ~¯2“žÑMNú0›4ü,9”e`”}Š€ˆ_Á¶ÕúS;‘]ÀT’Yºž~¼`âé®×Öiã@FÝÎ ƒl_1uXÿç“4èÆ]×l¤ž" ÑM÷q,âµÒýÎ;3½¡±X“Á9óéû¬Q:sc12êÁ”?ØõêY$Ð]ÇŠ+Vš™˜óu'° ¶[-8aÅÊ:2 ¤“nP»ºŒJ±ß?'à8ǃTÖƒ8Ç9À¦2¼ ä$;il¯xNÔnDàD°cºÿåš›gµ>jì6I›˜qQ„ÿÍS¬–ÇbK0èàl0M¤½@뻸à>2>E|TõŠŽó.€ï ,¬̵`”ù ÿÛ5¦Óñ€ìÖ £ds°þÂŽrä»êÿA0’¾@ãöìÎ’C[ÕL ¬^šëÚçO Ø­`1Ô†®¹\FãDÃå pö‚æà d kŠL‹ãûŽÖ>õ‚>î0µ Óš5z €ûµOóïë“øœ|°ðï&ú‚3h ;»f“žQ*GvÈšv²¨Ü€öÁe`*Àù2O”S|K¥ÈkÏܬs¢¬Ç0F~¢ºz<¯èZÒ1žÙ SdǃQ9wÊÆ{º÷?‘x;ÖT$_û}4Èh:Sú4Ñï¶“§¹´)vV¬XÙdG}wÎ:0ùÈÔ«°C´î¡kÅÊÆ*käÜl*ýÑÀ‰b¿YÀqN£ôKQÝà‰&&Œ>h%ÅYÙ‚ç½€+e(ûÀz#wépèFð‡»œØU2Œ/°Èn›¤Å°qZ%JdË)¹Ay¥öÎÝæÇÙZ·Þ–#þÂzï”ò«µ.öð^ÀqîðG[úB:áyir+¹?,¦ÂxAp1] ± È ë©¿çkŸB¬ÕxLÓ2~•ýLÛhì:é”Þºöä°ÿ,'9ѵ¾p(X§âJÍÃ÷kÌ⬊4_+R&< Óm7­Ñ¡`Ê’IÙ‡C"“) I+éU¿öÛ© %™ëøS:x(úتS+V¬l@ò0Xcè°ŽÎ_`û-Üàb;DënV¬lÌëßtì*üQ%à8@šë"Ï¥±]b2ÒZN ä–µ°ù6]Séë³Á6u…1^Ñî'ÃúL0GüVùnV‘c¥9dËé4ÝHrõ·|ÝK¾þ6À¬F¬¡à–Àèíƒ ó!ž{óQÓkÀb†^_h~JÈë à9÷#@WÀqZé=W€ÖÔ`A ÆFª’æèßÖE8^Ï[€Ì‡~ú¹'È‚h¥¹öɬÖ^^$ƒhºs@6DB‘œ–D/½Ày ¹JÀBª:Þ#à(“}@Pó镟âXW¦îÐ-2JùîV`ºM/0Õä 0…#2ÝÞµ™º.£r¤r¥ ò¤r\zëgA=j¼Té3ËõlÖLÖÙj„RU:‚õ=ÓZóƒì›`Šúãu°˜n1g¬X±bÅJSH=mÀÚ9¯èï'ƒivkÁ ‚­§cÁ +V„Ú;k*çvpâU ?ËÀÜ-«îDØáZ0rùØ•c^ƒ¹'ؽdoý¾Ìýÿ$Ý…œð"9Æ‘0…ó µÑ£mõh-§¥P¯Ï s:Œã9OÇèh‘) àCñpQ4GE{b3š¬Æâ79tŸ& âí-Çf,Ø¢4˜Ä>m v¹Tëc˜ª2¬—‘©=œ-`äjUÕT¨—£VvËXÖY˜FÍç€Qú5Z·KzÒÙÐQá[H{À«=x„ÖR_9ëß ¤øNg¤õ0Lk ÖOˆwþ7Ó—¹@„zX]¥ïêÚ¼a{ßçz×eû%b]Ïõ.ðÂü^¢û™®ý1l{ªÖ`ªÒNãÚŒ@γæ‹+V6¹ìúö†ì#y`w¤N¶S<¬À¦uX±²@Z—¦º€fJ¸eŽ Ý„£RÇÉ“á¸<Ãt÷DÄRÜï#§¥`Äó4œºâQìq`=Šô¸M`ÅшL­OEÐ5¶“^Î s(<.GÂ|oË1­Ñ³qT*䌮ÑïæñE‚NåºöÖãhk¤³ò-äØŒðF<­E£ÈÃß“™;íÓ•Çy ìöq–7 ´º3à8oûý™È‡¯‹ž¦õ¼Œ¾ÿ! bžˆ2×ZØX«€›=Ÿ¤ÿ€õB|i“z÷X­ÓCAÜ^`݇`›ÌWuÆÜlHÅ@:Ødì¢÷šš8¥å)À!ˆU­µP©Ç—^X«ýX¶^ê]ÀƒÇe'ÆE¡ë‘‡C«ÀöÒ‘ÕúÛ‡ ð¿$Mc^&°é°ûȳÖ|±bÅÊ §IÏŽ û{%Èv; dòZ±à„+€ L˜½±K¾ŒÊU‰8oÇ) {^.czH+njñÉYxŒ:þ Ãö·(NŠiéj*ûS Öêón—Óq¸tIµÆ½RNÃZ9«e”—É)£ãl0NF•ËѨq9ÿÿÜ @0ÓÕ¡(Ž×V€,‡¥`ËÁiHEé§±ø;•Ñu, 8έ £á°³Æ¹ǹÀø4§hù´v»ƒuVj]–Zµµžx¬·á™.ûkÌ–ÔÙÅZ[ËÁˆ¹Ëy¯Fœ5  I‘*ØN`:Ŧ@LAã}ÿV Øx€“Àz ¦&EÛ(à„WgÑNZSûJÕËx}B÷ö·ö“¼4té·`àþÿd$œyáAí½u ð2€KÒ¼>ëF_ÔX±bÅJs– éÈ=e׸¥HzüI°¶ NX±Ââh[l±Å7\{íÑÑTMôÉD¥+ʹ5y·•ú_u3b ¤"R’¥ñ¯*R8,R¸›Æê->M-me’1ý˜ß]Cž,§"¬Îÿ0BÑÉ'å„\$€â8¤¯£Ég¾qáÐúC Y[np"1èäÅ~ÿª€ã\ ˜&PŤ‰Ô!MEM5/3ŽsÖÆµ`!Õ—|pœ;LHSûÑ͵Þ€”ùe°ÝcÒÕ…³dv`‘aý¹u~]˜3ïN‹ð…9熹T ‰3´¾¦ÝUz€EÏ^YK@V‡1Xó@&QOéÒá`½ŸNzÍ2œ{ì,Õ˜6¢áR2%J!3ÀÙo`™¤‹gmdk;¡ö¶ÝÁº_‚@u½ÝúV¬4KùLÛˆTÇm¼ÎöJ;LëlV¬lÌr¸×ë}õˆÃ«?êÈ#‘êÁúÌwªVp¹Œ‚ræ€Ñ­¹`d®DkEvàHDv•}l¿Wß(ᕳôo£Y`öÛäŒ5e4Ë ,|X÷³Ìíþ ªóéฌþUØxUsí£¡ ùa°-á× ‰ÝFqIO°mî¯`Ku#~w¶Öö@°(êÜtÒšv×¾¤ýó9ØQdr …LQ8[ÈÍÝQ}Ž„ê¢,GìV¯éSK¨ìì ‚¯­@fB0•¯Bõ[Úèÿz½×åxða¥ôú ôóJ†¹”Î8ÀuÒ—ó@ðö$}÷W&ºé9KÀÈR¨|Mzµd¢< ¸û8Ø*õ„ ܰîÌhQc7;½˜.T  Ó³BkðGùw²CÊ-XaÅJ³‘SAÀö °N‘ÛF¾ ˆ]#[ÁŠ'¬XÁ)žÜq‡>¸ôâ‹¿G¨`˜¡924 \l”&÷6!ŠmÐeЖÉAþŒ¦ý"ãa)€µÍ,*¾/Hþ™‰äpt•“t– ú¿À.ïûýM]@3_ ÁÍr8> *ÎŽb¨åƒù~·ê~ÈÀþVAžîõ°ªòšÿ§Áô•õþ»•bJ0ú;S†vF"*.Ú @™«þCŽœÁÍN,ÈÔM§Œ€_æá׀̘;LMbÏ€)ImÁèú‚æ2¡®N1m¥úõZ¶‹DvÖõ¿àìb¿¿¦‘.í(0åæ>±@/Ö/éw*D"óçÑŒó \ ‡aâ-ë |#½3½7DfL!˜C½#ܾ4Õæ 8N.ß)§6°¾¾þבh\³1%OûÈÖKê¢51À$,ë«×´×>¬Ù|_‚ôñ)`ðÄV¬4€†v”½ø¾ëë|ü ÚX±à„•X¼`5wÓgøz9¨ÑŒp·kZ´å”árˆzƒyÈ›Éë, ÃDâ‚2 J@zê`qÅ?ÁH\€ÚtDuÍ>uq~Þ! [àEàþ¬¶`Äïb0¾L•‡Æˆ6¤Ç6•ów˜;~'X7bm”ùïFX#M¿ „05):ë3×8–ƒµ5¦j¾`áë`ËÂÕv[E•Î`·E`%ÿŠ 'j/ßà1ՈȖÁ¾9ØFva#8î­dl\26Ø«ØïO´Ë@W­¹Å 3£¢±'Nº$WÎg'í·íÀ4‰þºFýÈ8Z ‚°3ÀZ ã±…mu0lgÙÔl–΄­ô{™@‰åÕºh)i:{€…+g äÊ4¬¿N c­zÜsÏþtüøÏÀúFƒ¾Ôºæb“·Ñ¸ ¦øä‚é=€¬Æ_µfêµ®Ú€ à0O[`aPëk‚Îõoõ»M³b¥ñ¥#È|¼ë²mOÙfÓÀ`†ØšV6NÉ jÝu£ ŠœïH‡új³"8I9ú®6*úË ßVŽñ`9i0ºZFù 8Λi0ä‹Ü }Àq>Óæ€i&‘À„<=W¹î£¤&_#0g5ȬxÀüFt6¢ÍåÑ`JI0Rt±@Ÿ†®-[÷4F@Ë0ºœÓ­ãi¿Èؾde F£F‚Ž£Ù×£åFñÒ!¦@BÑãtÇjmVk ]ÎòJ­—Vq³bm¼pœ@&EO$—‡Ÿ¥5»:“ŽEÀq²êÈ` >ö£³}uý4~¹Ò[µ h·lù‹Œ¬&ÊT5Cl±öèæº§¦Þ—µ“Á>Ÿv³9Fºñ¤Àž8Nk}0€÷>¼ìÓñã?|»JoèâkHœFV7Õ^ÿEã÷"×™©Õ:Ÿ ÇýÚ£;)—{‚€ý¡zÝ— ¨>Aú$+V¬4†,—m.«Àà×óvˆ,8aeã•.`Îê‰`´jHkôEƸ)žY*Pà; Ú8ýeHlÛBÅÿ:Ó+çb7*åQ> 8Îûr"Vº†9U*v¹+Ø&q°Ë×AFŸ͠††¹·[dxU€ùz"z¤®-Hó>C†ÞÝ õ»Ì5‡ëoíÀˆÓ2äö»ŒÐX,)·ï€Ì‰ïô³5øBŽE6Ș¨<ëœsêÊ+*j´þ=iþ¯æíaÍëY¾wpA°íæÞZ76Ö¤x+à8ž$F¦€c]ªkKNžÖvg9ïýÁÈkoéÇ6uîq§©•ËÁù ¡µßA`n€Êf”¦¶Z:w;åTfwc£1c&Œ’®\™äzÍöƒÁÈÿUW^sM5˜²p&2¿ — 27ÏÓAk÷Mm4‰µ~®Ö~\à=íåí@Ðv?0 æH0óª¢Ù°l +V’•þ °øY’ï7çú4;”œ°²ñ‰¤=Þ/c`:Øuá Þ‹ã"äœT뱬Ùð?E-óÀ¨äj„ZÙ¥"«À*Àýe˜ì¯Ÿ/‹‰-ðmÀqÞ0qägdU×Ô`“=:‚é#4n_4ùÉiê<ª´(`Z—NkKüÅÈò‚ôÿ€yÿ€(öç®±î$àâTÍϵ`c^'£øz0µLŸs!˜t>o£OïS1X Í>Üb‹-FÿüË/µé'LR#=`Dõ½¬žÉzF"URH}ªs­aOœcâÀÐV†Ó­ÿ`T¶BÝyÌwTií΋7ÎÔúþGÎŽIA¨[Ó6ç<ö:éø!ºßìبò;ؽã(#$öu¶ôú)2ÜO/öû—ëßÓ@Ài°Öñ†¦ssì"ðfoíÕÅî;AÍF¨õl*{ DgÒ—Ò»€µ@öp¥ôó» ¨?= ßieÃÖ‚I²’¼ÜvcJV†‚H¯J NXÙ¸¤=Xì\ãcAzþ*0½ÂD›LÄDX“΃BÎÐ*“ŽóÈè„“b0Zs4€Õ'üò_~9{èСHQN™ Ÿ6ƒb—Æ Û¬‡±­ŒÓÁÚÑ"s9`‘ËÛl¼)PjˆXgiLîóug¸ú* ì˜Rˆ‹AæÅÝúÿW kb9( ™®Ù˱è`¤ë1st™@€,ç›K–.­”írŠÓLì¦àdÉØ»Çù7ß;ë6CÜ´¶Ì‰2y`‹Ê~ ø¶½~î"ç-Kk½Zke®À‡ér$gƒ©«>´„öÈ?Km…ä£ZV’“9¼‡€ ð;H€½"†Ï)Ò#‹œZì÷»S/WH¯l£5¾¡€­¥¯GŒI x,š©Áõ*Þ‹8÷SHNÕóᚣ»A†™- Ù²å*0àôƒì@+ÉÉæ`ÐóÁ>c°ÎæNv8-8ae㟗{ä4ΣïËï¤Ç2´pôX@E…œ’¹Çy !ÊçÃ‹ŠŠúz=_Muu5Èx±Øï/m—Ÿ-‡ë0âã)«7ÉŠfÌuSQŽ ô]F¦ ØÒNð9rþ^™ po©ÄçxŒÈVx¡”‰h¼ÔŽ> ý·HŽå_ÇùŒZþv„Éøµˆù3Dëf7ýy2˜f1ÀêÅ‹çk }é'ÄØ^óY¨y|9ŠS½@R_]5)~¿©+S•aaZ¡:Âu\!‡§Ð宑Îû LÁøU€„a@Ôn -Ž“•ßµÞ¶Õz³ÔõÆ•Ÿä¦8ñèEê.éé‘ ˆ~ü Ã~Ø «¹Šd-®=º¥Öâ$°¨ôxMÔ‚)O÷€Àþá`!èãt¶@ ~¡)Z¬ì£uÙ_{hÒrÝ… Ø<d5µŒÑÙòeŠömlÍ NXÙ(¤£ѳ´Î_‘Ó9ßuàöÓ(&Ž:ÿ|ïÁƒÏ—²^ ×-’,AóË©N¬0…´> 8Îò¿úúëÓkëêîþtüø§<âˆÇ“u¸\u5jStÚrÀ(÷%`´)Lá¸d+TƦ†xŒ ÿ,Ãpª Ã,°óÁ°øåB0šðÖíA.sÁ(×µ çB}ÞzŸ‰Ê7VúË_`µçÃl+cãr'€ãü*^*G¢‡@‰cuï“Àb³ß†1n‚2ŒMËÝT¥¯ éªÆÅØŸk´§7“³* yXHõå€ã¼Pì÷¯Ê08‘ߨÔ\+'mŠœ¹ÅcjZŠÞJPæKGl¹1‚­²¤‡›âÞk¤†ƒÀá{` ÖÙ1\½.‰jLÔÿƒ© Í­Ödm¦Qö‘ò!iý¡¡3LãÐdZÌɈhØã@ÖÆI:ÏÎÙ”x¶^KK“|0Õ­Dëë.íØœekJ\ßL€ c¼¢>@>‡Ô§+-I²@¶ÄÝ [bq?‚!p*Xƒà–€ã<à#•õ¹oS¾TÆî$ûý1kTÈÀ(BˆBnhíµMÜz³!Ù,Äù¨œÛd@‰ ÷ ×ûý“¸Ž\0ú~)˜—#gë^¡±œÊ¶zïùZÏi<Æ0î¤û;Cÿ#pM: i¯µö§ ÉŸ´N† á¦™rD¼`d½‡®é(0­¢H Ô;`ýŒi骢T‚c t£ò7ƒõÊ0оÓ¶kž$ûÝÝ4oÛÊп¹Øï¯Œã­Ž ï}åܤrÿ€)bm~]à« ¤Õ‚0ZƒmPW40ÿ¾f¬[šBÚ ¨ ‚ aéÆrãZÇ) (7Wçá\Ã+¥§ÊÍù”µ“ à!°FÐM`´¾>Êu÷ð–ôØÕâ˜÷Sè&ƒŒµæÒ)É 'Œ¼Þç÷¤«¦ÅºVKcÀÂݯÉ\a†–WgÛ¹`P§ ȶº¬[aëQ4_„Pjg,ÉSø¦è®ë¥*¥s‡ŒÔ`P0ÙÖ×ù²%ÏÖ^ÿLÏm.õƒžY]GKg%#Êæž²ƒ-@árä¬XiI²¿œ–,9KïˉÜŒŽ—I‰Wƒ]1êeà”8Œnt—ÕK†Å&:´wiä_#¾š]¥œ{ëûÊõÝ%ÇY$q6B,•úU›[¥ñh/C%îk8N‘Æï*0o dµüKÀ|\X'à>¼*ÆgútH‘¢_¦ñ6„L½FSçÊ6i>ñÊr°µÝ8®ðµÊF5ªh½¬‘qògÀqžÓZ>I?˜[<)à8ø\]$’q|<`[É;ÁN)UŽk^44Gõ`ôz½ÂŽ*~‡x{µ|\{ñE·Æ LLo0Eb'¦8ìŸÊ¸¸V`Üë^ 8έæ¥ÑÑ«ÑÚê$஡ù·†Íº²V:`K;¥ÙýçkÍ´A¨¾Ùw¦ª9“VXpœý¼¬ãP&½²VNF¥ÞW¥uiº¸,oà̪‘¾= ‹_EXÛm×¾î Fñ{JŸ<ƒ1°œûIï–4P¢-€ã õÖØ>/Ýøg~½@‰ýä àî€ã¼˜A†V=‘¾ÀK `ˆæìmý}–Õ3ÍR׺ë‡ÝÕÞåøï(Çz€Ç+eû—²r Þ‘ ]å–ÃÀÂyZoSeÇÌj&ã}„ì©z¤Öz æëm»¯ÖW¦V¬´$9¤„ÖKIº+àÖ¹@‚r0:S ¢Çóp¼ Òœ'¥^àïb¿?&pœ 5r)í<=²±nÇÃÐX ¢ÍsA$õ„Zõ•¨È0=w€€š/A4¸6Ž{ÌÓ#nxn¹ IDATS)'í3ãY¼2 ÒÜõÓxL(ñ%â+vÖ¤¤ž«1~dÌÌÖÿ; ˆ8Ußù_°˜æ$GîÁ¬×Á¾À7¤¶G úrc‰"¨d<œ ói]=à­b¿MŸç€ôˆÀ»Áô–âX›9¾Ó1¶Xh>ó2ñq ئ®ïÏ(rÈÂ8©ØïOÄ)9PëóQWÁ4Œq® ©Ûä/!ÿZš ÉzÁèÊP­µ?7t%-½‘+§²ƒÒ&ƒ):©Fj= kê­ÙÉÓA¨:0­AзtS/ÒÝ[:¬“þoZÇúÐpW˜ ëaÀ° tÝÑÅ~ÿoQÖïµ ˆû >×F¸ÞAr”Þpy{Ç "ö£µ?71tˆÎ˜-u–¿.Pâ/$Ñ}KöG'kg ª_tn}™ ›¬˜âÆ·io®Ð™1I¶†µ’9 ºœ©= ¸Rë´Hš¨=wtœßw5ÈLÍÕ™njH-ÙÇ·xl ®Ò?#As…ù°lÁ:°»ÌËq^[!8zG6^¦ä|µ~—$ñy[ AvÈKv)[pÂJ˘ƒ~´œÚ[ä´v—!ÖKН£Œµn ÍukD¯_¬qèqn£µ€c,ö‘ÁØK†z‘^ë‘r®£õs@Á“‰8” È& B=d•TǸ·Þ åó(©ò9XúÇ8 ŸîûTºÚU€Ñç:˜&Å9'y`téf‹ÀˆÏ·9ŽwØB‡ÁU:D«R+¯@°“õødÔô@Š) tV u^2‰r.\ à›XyÍzÿù2n| {ážb¿?ÞN79`ׄ~츔Ët•`ÑÑ'Â@½î$³Rì÷ÏIp câ°H_M÷zG°®É¹1?@öG@ű`MáØ@Š—iL \çfÿ~Ò]¥ óêDR«5rb<pr#X,´X:Á þôélÊÓ<êìiã5ZéoEú¡^›¯÷åHçþ»ØïŸå+;ƒÀdg0ÚúC„k2g&êý[‘ 80é”léÔ›@¾ëv½¨MÓ\ »T ?¤³ö·F¨'ÒNÎÓ(ýü¹ÎìUv'5 y h 2(¾‰ñúÙšv’ú£ì™c8Ù9Ò¿ 4«—:U{ð;ÄŸÂá•Ýý­>£!f¥±}×ÈŽ? ñ³ ruoçƒ)œ™Ž²÷¶ƒ%ù9}¥ƒ`Ç”v)[pÂJË”<9ýÁtŠG¤ˆË*‚è“¢;D>ï—bm²Íqc‰ &\©{É•sv3H¯ÉÀ؇·Ò^ 2Qîj„®Z&˜`Îü7ôhÑ]Î6™©5q¥tè‰Q^»€O@€ÿ:íËße_öAÃl‡Á¥ ˆ¼ (LJ„»S€Wée¿/ÛnÀ–ÏX-™c@¶Ü_º×LèßÓd«–Á‚“üœ+e~ 2_¬XpÂJ ^Ïû pèƒP®v™ ¾•tHwÿ²¹Þ+ÂU„P-ˆ’©Þ-Ãr6ÿÓSjÃÀo@¦Éz¶œÚ=¤P·“ãõt%1ŒÓ"9ØUó0GNñË â‰eÉ鹌"eƒ…nÔ¼V ð8AÊ¿»Ï«t¸¦³hZ{}wîé2ÊPmîŽFž®õv0ªý£ †iÆIךÙLó4Œ’œà÷$ùÁ ×ZF#©MgëºZƒ¢me ?‘dİŸ>/ÀvÇY À£+˜ã=À¬TS àª5ØMGø%ÉëÅ»@ר”ú¨dxõ‘žØ„ E7KF¡Ñ¿‹À."¿k/Ζ\f@€ F÷s¢Ÿ£iÁ°ûÙ]º0ßõ¿`ð`"zA0aÀ‰Z×Ïõ. £Z÷V2ŒÆÛB¥(Ò^ÛQŽÇ‡iøÌí@PøÁ–i©+qºÎ²Ž`¾[µŽÊãÜG¦x´ ×ëhè½­å€^†PË—a}™ߣÀ‚ÒGéLµÒ´{êo­¿#õ·áQ^Xå`„xŽì¥` (’|!û­Zçrk0òŸ¨€©ÃtN<¦_Ôjÿ´Ó5ôpéÙD¤Xpö5ñŠtõ?È~™ˆPÛôdæmª®÷XmeÅ‚VZ°x]ÀÃaR mB|«eÌ Õúß9ŠBnQ¢dS9½B Ì£&ŠFëð&ÈDØM‡ÉßANá~·A*k,'µµæâB #×€)*¥ˆ²ç“S;Ì!Ï“£s— Þµú›‰,m¢ûOB…3´ÖÞ{Éñ à°&B]#Ì©¡f×& XydÜ.cs¹À‡ñrÆvÕ=õÔ½Ž.öû—$y¹QÁ ×5µ™ÿ’{¥@‰ ´>ÏL²–CoQ5Xs³sÀq¦ƒ´Lãh¬)Ó‚éI•)ÌWkâNí›Õç§“¸þãÁ¶~7ëó ˆ(’ÔOºrGÍ_'í7“z¶dÔÌ»Öü FôK×T7Q;KSGçkïµ@¤A¦šIc0© y`DÜ;“%òåÔ]¦–ȹzB?'0ä øÞ à¿Å~U‚º¥+ÈΚO÷°$[ã|¤)“*{XÀÔJÓI9Ë›êl9A6oCí_ŸÓvwÙDçÊ»W6^$ÙE:q+Ù}éDíªKÁzdu`‹bÙä‡ TÈ~±î+™³·ŸÀ‰É²]â]߯!”žõTŒ×¯ÔÙ°ÈÐHvÞ~—ÞÚÜÝÍ‚V¬4­˜zư Ê8R£×ÊÉžFSg4ãr—ciŠbšHÚ†Pt£.§ËÀ JI>àízêeÁ`ð|ŸÏwŒ3vìqÎÐa–äºìöPE¯t”!sŽËj9 ‡xR¯ù% e¯©ºW‡Y™æw0˜ž³›îé#°Åô†@9æ­u½eIFž.Ó÷œ¦"|¯ë|t}×P ­û¯D¨ú½»Õ¬[7Ç'[ãŸ+#¡ÀåHå‘û’m*ÅÃ*Í[ƹLº3Åqºž\0ü&}?ÀœÌá1rÛ’ÍAú÷@ÍKw°ÓÈx9á]Œ™"5rjïëqT¤°ç @JûM`Ôõ#isˆ˜î«õõ„º`šõB¶öBw9ô; ÜŒfåé¥52ÎæHLÖ[¨¿W'’ePzÊy]¨=YÇXDJ]ßá¿{]ÏnРv°±Æ'%Wëxw ý$ÅÏ몳{¡ôkE®9Ëå¸ ÕxìF0 I€ÐZc'J¿€Ìžë,î›Iñè"Çé_:_‹d3ý"Çïz9šVšNv•“?LéX£y‹¤o Á:H¥ ƒÂÈpÙÁ#AVE¬uñ>koÙ[›ëâ餱 Þ«ýdÒ‚z€Aa²µßFü:ݲôÁx„ê³Ä’6 °ž#_à4Üï)“AV^2J0 ¶µìÇGí2¶à„+£°ŸÉ¯–Y'E³LJöO=*¤ÈŸ#‚&ÙP}k±µ’£\$åz®˜|Kþûúë¾óî»ûì;|ø¯§·“"­ÑèÁ:eQ®ž`= ¿r9΃ÑÔx£C>zçËil-gö9™+dèî RL÷Ò{~)Žß4ô]2 »´ûb½>%É(ù~:˜×uŒ‘c¦[÷w^æyæFpzbéb·3j€2C'¯Ò¡ya"Ñ·ÔÁ´(ã\U€)1dÀ‰ÁŠÞÑ®Ç'gàq0z€wL'ñ€žõ½[7hí ›£6šÓQ`º@êòÅ~ÿÒÆÖ¤¬<$ƒrÈØø4Î’@Æ×;rêRØû¹ »¬‡Àš¥{ <1­pMZÂ?Ò}“d.Y ͽ¦BÍóÙÒC›JoXiZ9ŒTš®P©&n¯µ¹JàS:A Ή+´çòä˜Ý ç$%}(}3d_ôÓÙu6€¿š¨•¸Gúoîw/0ÈP ¦¼2×ú‚Tü@0ÛJÓÉÙ{iÌÒÞº<ÂkwS#¯Ò™jd€l³—e»Å²w>’ Ôš©pK I+}÷P]ã`¬ÏX6)…Ú[í‘8³jø]'pæÓXÝŽPšÞ`M‰p9 âÕêÜœŸäœ H´D{m©]Æœ°bÅ8Ñ›É (“ó2Hú&: M‡ ó¼F*„"ÞåRÌkÂõ/“^&C•þWÕ@ E¨·™GÌš=»ëmwÜ‘³õV[Õ]xÁó}>ßx9t“”7àŒä‚(ð™`µèv Bþº ¯¿0ä²düŒ#kmu<¦Cx™œÜÝÀòP½ç°BúG h2{é:ÿRÓK@šü’¤]oFØ? £í¢kxWÀG­ëûóØ Äè1ÏY®µf¢°f}Ôº@±j­½j¬Ë¼(KGw9Ñ'é€/ÐòEš(é¹'úÅN¸œéŽÓæ$h´{åÔ?Ò’ÇÊhÙ_»MHßkÀ»‹¥Ž)öûOÃø¶£%ȸ{À˜8Šen&‡hª Òê¾³Për°—~rº µîꥳ–iSô=É€*džUÜ1ŒøÞ«{õè¶Fñf#ÇÙQk¤Ö/ÀiЉVÈ7gM¹ëoån½ g7æWà`ÖeŠ„3LŒÔL†ÒÖL!˜ÃÞG{lz ÃÕŒ”VdK8‘ FPoÒ™1W?¿ÔSQÂÇ·»Öêa ¥ý°FIcÙy²Ž×=÷Òß‚õWäø–k î®3nœÎé½–JSÊ…`½­­´v^AØ!^{­ìž-Ãþ> ŒäWhOF+rz&˜*kì’‡Àô½ŸAFlC2LÁ­Õú™ÒÀëú ÄØTºëXÙVñÊ>Z³?鼋%…:òtß­µ®Ïˆp¦L™%›B6O¶g Â÷X±à„+눉·–3´ Hß:GJë7„Zªå¹œI“{l µðˆ8*–V-ã©DÉ,)ö92– ¼¨Ðk« ÀSÚeþ‚GÞrÛm7×ÔÔT8è =>ꨙ 8¦>98êÀÛN ÁB)ÝqRÂñ:µY ‚‘Œ´"Æÿ¸@‰å*#ÞÛiŒ–#ýQC‡ªî­æò‘_RiŸ0;ç{Ç€Ôû"ý¾F‡ãWÍ\µIºk®H£‘±•h÷óP°ØWWd7€4òí*’xA´=&ð®Ø=¢.ã{yìFÏ×:lèZºh]-’qW™À÷ F‚rª±d†MÖúG{¬¢™¥e$*íÁÈàZ/‚Q®­@úŸ `ÿ§µ‘¯sh8ÍÄÁŽsw ©”™tÁÄ€ãôA¨hl$0"üûëÁûÙQØV— ¼YNK}œ×’ èbæÄjéÛTÁ ¯£ÛtþWƒ æ½:Ÿë34ç`êâeÚ£7ƒE«2´ÌLÚÆ Ëq;­·• Cëy°à_i„3|'K¯ÊY­‡•¦’c@¦ãÚë;댻dº†;Å߀Á‡`˜ã=E Ô¦šó†ä‚ì™ïã´í–h¯Þ¤k‹&¦ÃR®a ŒÇEÚ«o ؈%W‚¬‰Çlôƒjáï¡û]£ëû(Éù:,"¿Lv•(‹ÆŠ+¡èÔr=æJqÕÊÐ}¡bL˜Z¹õ}/p=É¡î"g¯‡ ¼N`$w¨Ëø4•ÞMýz]Ç<s]Æ ˆQáz}5’¤{ËñZ(%½ €£Þ|ûí¾o¾ýö_a_'9G'ôô¶úÞ_ÀÔ—÷u}ñ,Ù`Dób…`5ÿ[Á(À*0½ãBÄ=t¿ß‚¨ý×h¸åi6B…GÈÉ\$Ãs€…ip¼ {¡µærµœîÍ568!çtn†¿&“À¸Oóý¸ÖÓWZÓŽ@Š÷´>·#‹£ŒER£G߀ã¼/@ëA„¢=§çûœH!o­=“H Ò÷f–ƒlˆ2@«[P‘FȦºW`Ä®û±æ};éã AÞÓò±.ðmŠlš³'Ïuöé¹Ðõœ§5ó}Ь—Rí™~®³ÊÝÁÄüÔõÕ‚4ïhkë0%àp11™IîðiÀqþ#ÝmƤ©Gð åx\(~” 0‰·JLT'”çé„ä0ípœkÒ\ìÒ´òö |é¨óû7ï댬a+]à™'šNLqgsÌÐ3ìu§H‡<ÞÀ>éªÏ¨‹±?ºÉ±¾®šZ1dé§ l»Xò"ÈB=X`™'½íÓk7cmvÕZ÷cA°>ü»¶¹zM²ÀD6€óä|b—®'¬XIFv—Có½Iªùö>—aY¦ŽtÕ!²ˆXw—Âì+'¤'aÖmcW£g“bRFŒVƒT¸2”æy•ëkô³yO… 1õ3^+sŸ æÛ{Àº'hLÚëzæÊ yYFU"Ôá|Ú? ÌcÌ£š#ÔÚïHiÞFÿ/Õw=!0¤²#ÖÈ ¢îy KåKÒè”™º#9: +(m­qšo·R£‚Ù`KÁ1úŽË4ç;ƒŒ›}´.²®}(ðj¡»ŠË ˜pœäDŸ­õþC×Q£ýÚ^ëyuß5_@^K“ªu˜æ€®ë´ƒ  ë[76{Û -z#à8ÞTØb¿¿$à8W&è$ÔÇDæÌ-uîÍŒq=¥û·Æº­¿ {±2Á‚Øw‚ƒÕ`„÷ D"›k3ì•`* P±ß_pœ7Aõq·ÝŽsli_±tmåx–€ºl9±Oê ŸžÀù]¥uk±&—]±n2G‚i®¦žÁ~ c÷·ΖÁàO´syíÕñÊþZos¤›ã±©fºÖm"{* }<-Ðì4Qû–À‰‹} ”ƒÁ¸#e¯W€l¡d¥«ìù€´bÁ +V’\v 99éÈc5À‚Ií0m÷ÜF¶©qÑG‡ÉöR˜½¤³ªEP&åé•"m‡P›;w¤Í-†î[ï9LmŒ >WFK-ØÍà9ö[ëó‚Q¯—A:øšœ:¯®s8˜b±“®÷/°bñ×2œžÒZ†Ð4MÿŸ¾¿. (±‡•]etN‹h¾ æ@§;ÊŒp /Ñw·±[)â>ðdœÈ#7ÉY9̯ÓI¾é¯gÉ0©r'÷ [ÕȎ蚀ãÜ‚ÑÚêÖÊiêf‚ÿ×%]5—§Ëˆ2DÞźÀåR—îÙ¨$]ú. ›*íÇíA¦ËÌ(ÎW9õü¤ë¾r¥k“9£ós‘ÖQ˜®pµœ¸xÇ®Èìû"à8߀©Qu)Ì×ÏÇ9 dptŠpŽÇ+Ù²N»²?¦‚i^ËQJôZMý“l«†š\"ÕGƒàßÙj[˜…† ÷×~ˆv¶”i¯• 1æÞ!ÎŒ—…X©5¶‰¢tVîÇkO×~xÌuÆVèœ8L6®éJåøm suÆw âcXpŠ+ëÈŽ EøG¬¥É¤jl­œñiµ,™{€tõmꢱX ó3TzO˜ÆÐ L/höÜVJ¸ž»ƒÑeŸËèóè{ºȘFY>ÕáOA ®akªw¨¾«Öe$-Ñz-H³¯“£ñزí/D)B¦|Ý¡`zˆ¾sŠÎñÖ†G´\mD y¹ØïŸ‘ļµ8‰ kkú¬ï`×fœÈÕü_)ãi¤ ·á]#°êR0ºâÕžº¤˜ `k —EQ‹ØýÒk^dƒ¬¢f-ªó’¦Ž¤³`ž¤ Ÿ*ã²3˜®r;^Á5Uá;Û-Øl$2LGŒ†ÖQg0o΂ËÂÚ²šâÂeH,½ dÞRÀ—€µJ^Aâ/Û 8W@Øø€ã\Wì÷/KA', 8ÎåÚC‰¦•è,?¬ƒÔJº# =2 ©µ\5)49)'VR—l„¯nY ´cäŸ/gÿå(ŸõžŒ†£ú]±n W¼ò™ŠIˆÝ´#˜æ['û0˜àÚ\ ¦MwCÃwƒiŸƒ…¿€¬é§e¯šv¤0Õ8»ÀØÑ¶;‡'¬XIX|`$ÅR¡Ë›ðZ‚Æ\)°Ä´Uܤá óv”ö+HQRÄ+”»;wÙ€y@Úëê­ƒj79j9 Ëa;=¯–󞀊¿]ãÔ!6ÁÖº¶½åPÔý]c_Býô¿¥2D_Bˆ•Q߀Ñj@}5_;ê_“t(Yì÷—Gx_H%>N€H/çï$©Mdèþ­ƒ7OcW(µ 6R1mO}.,’/'ã<#§hÔE¹37ÿÕ¿Œ.½'ãìQÄAéndY©qk6µT×¥Œ@÷ On Fâª5'é(B™­Ï<]z¯ƒ@‡@3ZñÝåÒIílvΖ2©5•§sçI05ï#°Ur8³©•öÄÊ8Á‰,0ry#Èà«óÉïÐJ†iò;X«â­ÿ>¶ 8ÎþH–½"Ð2ÞT¯Ö÷¡`¬­5.³Aþ%0U( «qP-s¢iÅ#;5Âÿ.•ý÷¼l²›c|Öoú¼yQ^ó—^Óñ×ñ€ES!û1– AÈlÑøEgd•tGCk½dI®YRn¹M N°sM€‰‘H½¶Ê;:·ªìÒµà„+‰J?-3åà771ùÈÿ+wÒ¡ë Fƒ«À¿ÏAý"Wçz@¯[#~NØ¡’#ã((#p À†ýAÚÜ®`n÷l°bºG×á‘z“ÖP ¢çKçŒ+黿‹Ö}©ë¨‹â ™*㇃©!}õúïJ|J¸ZáíF\Meò2ͳ3&< ²îÓµ×y™[ƒú¹v;­'UZéJMhA<dÛœˆøòM݆öß4ŽÈño°×åˆ?ÚÓRªµÖª @¯Æv x¹ º¶±­‚ÚÿƘMÅøn‚›#A Ö°”î£[ ãp¸JuMííökVbòÉKÂþ>\óí“~ýÀ™Å~I„Ïh/}²,ʞϙu0‚û/=S@¶Þ·©ìñb¿¿.à8Ÿ@ù %|{€¿4à8︺‹dàé¸<ŒW‚E<×¹» é-ZiÒ:lzYÓÛ‚¹ˆœ"°\vÈÃ:ŸñYfoEcԬОL$å©3Xdr€Îîh¸æÎ²i»êúAâEn—éÜÙIö]$¹C N$Àæ ÅzÿMÚCéûô°bÁ +V6†O‘ÕgÐü"§áR ÒQ? 2T†Ë¹æÒž¡ÃgŠ ¦¯A„¼<Šòb]„·LFÜ)ìÞ2Æ“£ÒW¯Ë×{ê»>Ñç ¢ÔtÝ3\Ël4€&‹!‘ëGŽé¸u¾ F¹(öû+ÃÞ›+ůñè¤}˜ãÿ.ر#Yô ȾX# ËWÌàaòõemÁ‰v¹ŽÁt2b§G4$å`„ä[„Ú¾#=`Ú›xìJ¤£Z7Q ½ÚW{hÈ\èªÿeÉ@­Ñ:Œ ÿ :œ+3Ñn5éßm4,‡«,º;¬#²ñGsfYÛ] yÈ&u¥rËBé÷!r²GûýËøŒNzŽÖÑ¢ ~›®&óÁŽW‘¦nJ¶—ç° ¦˜= àÉ€ãÜYì÷¯H£R¨ñ9À^º¯åú¾gtÆeêü1…³sìnRé-›cÓ(gÚéq~V­«¼ûÕ½ç’<°¾E£7É&í²‹NA¨fE°ÊÞZÇ…`}1'…óv2€=2†ÜÒ Lwú¥p¢ r9Ò v™YpŠ•¦– Z[RË‚е×K™þ¢Ç£2ð @Ø]Äu”˜ Pã'„îl0jº‚¸»y¬™ÓÁèLW„Ú¥Ž“ƒx–œËäÔxA*ý“ mîב§žZ½ÏÞ{ûd4v’Õ,ܵ©¦ýjg9£^2ÉQ™¡êönǪ3ÈÎ)@ÃôÙ~ ¤ðNP™†\øýt¨¿¶g4i,s@JbÐn©ˆS¬Â[ñç›h —ãGêL•z1å×<Þ‚PÚÛÀ‚¬MÙÖD‚Ú¦ˆðÉ ì¢µ<Œ:õÓ>2íkåäÏÑþ™"=3WàD%€Ú$)ì^.¥«ÒÞ7tý5 ˆy9˜R–è¾2éam7$p"à8¦e54Yµ±v·5i¦µu¶Ë¶3]žj]:Ü´«^ëÒí• p[£yÌ´îòÑËur°è4Ê IDAT¥¿Ö:œ à”­4{ëyA”×l¦<˜û\¦,zôs´®Rf7¨æò€ãܧ=ò°tÈ®Çà犔zuÆ ôÝB÷ð·ÎÝ×Òdº^Ža^ÚšM+s´ŸÓ‘6÷žÀ´îQ^S$±¯ÖÞ,„GÀÚ]£µ.zƒ,†cegž/`àP0°X6_w„jÎT‚Å'ïGjéÔ†Ù¢´pWˆÑtÜ2»¼,8aÅJs‘aR–/#z$ÆRíA„v‘œšÒ Ò7“þ1_NUk9ûʩޤ·ž¢ƒ`¡ µïdTõ—sæ•q¿RFä"‚sô±™¡Ë8"Ô~é[0¢óÙÞ{íUzúi§í vÐ覤>SyÝfU 0úBNÿ·–¹+¢+O¹¿‰£ô¹U`Þå3`z˲4Vo«Ã¼Z¨GkHÝ+±Û)¢¬EìM,Ù¤Zv™9gij_*ú_ƒÖb[gƒ·?CÓÔ¢1àDZ˜Ú3—hü:"”–Q£ïú]Äd°Ì|9qUiè‘‚ŽC@vÄPýî“óø…ôð\)± Ö¯Ÿ“Èš«–>ò¦iìŠjEW®k+w;øÒ]A„:(¹…·òµ'ÜÏù.Ð!_ï1àƒÏõð`ý"³îŸƒ~vƒÕµ¤^`eÀq–»ôý2=Ï03Mg\Xïg Öí `:M}àâb¿^ Ò¤õE{Ýúܯõú^:+NÖ\•pûLën†Æ!•¶ µJõØŒÄàwçÉHõ¢Hîá }^;­·Ï¤—¾AúS7¢I­Æ-é­d%1ÙZgA:ó±nºo$ùI Bo0ÈÔI:ûw0Å·Þe/þ¢³e‚Þ;L}ÝLy2:È2íþ Ê.HýLÖó1²ýLÝ[Á`Æw kÖŠ'¬Xiö’-c¥ÌϋljÝŒÞg) Ǥ>L—QWÙQ¨XR'pá{0‡þ0*:d7 •Ñv ˜·jZŒÚf¡€„m]†¶9\²e¬,B(¥£• ¾§AZÝL9|8ý´ÓrÁºh¬+uxÌÒÁ7WÀ‡?–Ê!Zƒ°mJù(¨t ËÓ¸?%@äðt4ˆ¤-n2l~£½€EKÿ Kæ(ƒ;ÙŒvÕš;™)]㧬H—ŽÌB¨cˆ›&é ²7¸=ƒc`ÀB…ðÌõ´c­Á¨bk×k °n>»;çݧƒò0M"“]F’IëèÒ˜wð ÈàÙSóÕØÄJ}ç|0|?°ûÞ2>f‚Ô×7µ¶Ò¹ª¥£šS ?ŸöÖÎ @9Ló•¥uôÈÎú¡BeÛ¸BcÖQúfÈBy nK´Íÿs‘|”Ö¤µ³6Oò’F` ‚ĵH-Ed€ôØ4Ü ´£t`¼Ý+jAàñ­Û|„R‘p0HNÜÒGŸjýÖÄ1†F_™”ÄíÁ”ƒt­ÕrüŸ%È|Ëdç0˜o¥ñd–ÖÆnHO …[0Ù®#@Ðr3°S\SúÙ{ê «wc^×ÿëìr¶à„+á’+ðÀòIÕˆ3Æð=¾siØ}däl¥Ÿ»‚mœE¯Ëˆqç%ëç%×!D .—Xpœerš€‘ÇÅ.ÐÃoKÄ0̃Œ(Ñ]Îÿ)%–‚53ž0/Bê†WFëCšÓ B¨ÁêÝÎ Ý| œö ÀžR½f›F}K]q°ïÐóUz]"÷—¯û+’‘]$P¡îµB]JÚ x0@C^ØZñ„­³>‚®5bhåÕZ#K]ÀWµÆ§6Ã{­Öª8 ì(2H×°JÉë*F*rt榊õÕ~^ íã@Š|e3ž?sÞÔ[p¢I¥«K¦CÆ·°ñY îlâ“^èál2v… NX±²ŽtÁ¼ë÷\O‹ûýµ2¾WƒÑÕO”br}ód´™¨w[=éï…zMë¹0ìÿ`”¨#Bíä|.£Þé¦årßç¦b¿U·eê3¬A#Ø*tÙ¤¸ž'}ÈL`Qõ$ò@¦ÄM{¾H1Y†pPcs4ÈØ¡6‰†bçu=ÜR…ŠÙ2V¿×šÙ¤ù¿’Èx9̯Ïq}§»ê¾\0u/*ä–é¹DóXªßKõ?ø©D(ç¾ÚP§/èºîú4?Œ&• €Bí Ö¥û3é)ÕM +Là j¬?–3¾©œŽcå¼ï­ùùP ËpLÂY‚î¿1Á ¯îwK°èëA ¬Pkh¹ûŸîo•æn°@»ÝAÚºi úXdt’öT4§Ñ°ËrS´Wju¶€_ÓKo­‡IH>×:Oëj ˜óÞôѼÿ•â”c>¬ýp$ÈÚÀ^ºŸ):ƃ wîw?%±£ÎÎ5:£Ò±öBFEhò¬ˆÁ’ñ¸ÎM+M'†1»*MŸWj‡4#2BçW"³ÿþ iÅ‚V¬¬#›ÈО֘lÃzX/0"ÇÖãr<EÐ ]?ßTt•#Ý[÷j˜½ÀœÚû“<à ôÝ)µ] »·||ÿéx¥`uçÇJÔ7à”6müLzO Bl Ó­¤Rßi¢÷õ`þò†D ¬D|© Ajó^rüÏqOf ø"Íùzï`T²LŽsº¢KÕˆò#| ˜Ûz§œ—mÁ4¤ô|¢œ$Œ².NÐaªÒëó3iP­õ‘ häÛ^çm›£¥@ôÒZ”¡û1{}’Ξ;ÁtÍãt懯½þ‚ìŒ 41`pœ°ß•ºæJ^ç^²Ò´bÒ¢&Ø¡hÖòÈ’‚¤›É.ù Úzœ°b%¢l¦çZòMŠªièüUH½Ê¶aN$íô‰² Hÿ>AÈWn0µØï¯‰òÝû‚-¢Êù¹NÆU  tdƒ¹ï÷EŸVLˆ@:îNr´.—#ûg©NÆÛr9“ÿs§©ÌÇÆv0™ûÍmÀÁî 9<¤<Äú‘QÓ £ BQˆ+ŒÖÜ.;{ôXѬYâ õ:uZïÝåÅóúer¢ÞÙÿ;TŒÓþ½ës²Ì¾'Ét† Š"ŠbźX×ÞËZ㺖u-¸vݵ­ºêª«koã‡Q×Þ×î.bA¥J•"¦gòûãœ÷÷}ÄÌL’If2™÷>Oži™/_y˽çž{îx°ÛÌ—ÍÌ%ÓZ²-ï´•'€e''ûéܺèï ÝtœœßJ”Ûì°ÐGçaDK@AÕ¨-…+ÚÒû] ·ÃL2æÓÿZp¢í­¨7±dÜ$c=@Ò:Í©H@H͛֠¬G´6}–þMsë_šCW!f¦@ƒÃA†Ñä’`0¥Ú:Jì–Ž”?ð6˜˜C\º1€ÈΧ¶ßKÿ‚ÆArk™a+À$Ùö` ÚŽšw/X`‚Ö¬5e}µÉ.··"apÉ|¢“A¦CoC7x· ‡Ìˆ—^'+ ²nSxÈ”Ø^ïÿl½ø6exb™€ŠA`)ÀéFš3ë”%g&``÷Kq0qv#sr½ŽÑ®ŽÀ¡ ’O3˜Õ (5F Å?ÀÌÅhYéV½œ$œÂZ9'׃,£A̓õšfWßA°HŒÿo€ËIŒè –^R냥_>0“û³@”Ïø ×ûN×½ÎÕ|[f'(èš*0¢* Ζ-pÂýžs·Î`ÛÚÎ kí}$^ gì0Ð~Q GSc¾\¥Ö´"+@v_"@ôfZºø!ä8fÿ*oIÇ%†€þ‘šãA߉M$b>¹Ha9§µ¤í3{ ÚM÷ø¤?ÚÛaÁ kÖš³nr&âÒ]Ð&˜á_ÀúëÙ ¤ÊT&°Ñ·g+V`“¨™27‡€™¥a îÕÊW5RÞP PâJ0Ëéå·T¹Ótô™ÿp¿¨ 1@•@:ë®úÝ<03l×ÄôZØ8x­7XÊq(X>PŠÆÁ =4êÁò hæ-5`g—@1Ê (¨ú] Îß`ú‘¼öƒBŸV€µ¨Õ°ŸÆìµ`Våi°<"ìùì†fƨ_s¥+Èîfmvb]<`ÄB!ÿÓ¨û3\}‰zXŸÊž ÷®Ñà˃’x‹@ð¹Ô!ªof.Ãm»í݃ HW–_­MSYÝŽS{KÀR¶+ì ¶ <rœç›Ø#Ûo} ð{Ö™n ŽnðqI0X•à5™ÔU° ½5kÖ,8aÍZZÌJñÖDû@þßÁmqgJ%ÖXrœ™`vqŠ‚€U-²i3ï©à$QÊì óAaÀÛÌŽ¡+áSu ‚ÎÝåè}§ sH×-çkX¶ñ0ˆRG·gÊÀñW¸mF¿³ê¹ ÞD®iµ:¸Ùc}ˆ¨ ø4Íb2ÝGzÂmiw?(ÚxH™üT÷8!3dÇlÑBp ˆhA°ì:6€Yäÿ‚¬†sÁÞìcôýk`ÉÇ,¸ÂŽ9ºî"û-ÀÒ•ÁÒŒ­Àì«‘lÙM¦«Æ' Û!,k:[ÀNW5˜QýH€Ä|2mØWÃûm 8Q Ûa -­Ps¼,{HÆvK‘¾Fóm¿óõªˆñÜ @Áî`›íçBŽó€ŸS˜Xðé|@‹r}þ‡!ÇùLàÆÅuîð'…'$"Ò 0Q &Q®Öú·øŸ- “-ë,ð€–9aÍš5 NX³– {œ‰xœ‡pÈqn³›[+0æ ~v”ÓcjêVÁO!ÇùPœ–!´g–E/9'‰¶_ýìÀñ5€¯bÔ¸úÁÌí© œéM;‹Ì(ñ(H™].€¡L@P}Œãm'gô+ÀÖ¤_êùì©kéÔ‹ ZsÍÛÓcAÖÀ‡þ º)Û¨ ¾«‚ß)¨? n;ÏE`–ÈŽù.×°nV6UV#å2°öûtA°õí‹ µÛt’Ùõ†+è3e&µºÞ¥š'ßiÞÌÕ¼Ølz•Ö.´/Á¹wÀåh›V­Ý#曌™ u-,s¢-m+Pf ’kÙ³ÿ i!LÀí\µ<Æs¯pXòu8X&x €/BŽS‚r-*£ÐœÜnÉTBV V˜rœsÀ¬ µÆÝ¦uò®ã¼R nh”ø­æùNºWÏ€‚‹Z$)™XE À‡žÅ<;·¬Y³–*óÙ[`Í…é)ž ›h¢mÚ¦Ä0PÇ`ýÜMA™‘[ f%P@0]û:5-tŒZÃ'‚"yß%x¿|1®/WNØy Èz*ýdC,ÅKŒ,KÊ»-£ìÜp¡ŽÙd³ü Ì {u-¶µ ¾WðVk§EZl;P0n¼lÔ5ø~^Ç1 žW5Õæ×ø?Ìœn!ààwú»Ñ¤(×Ú1OÁÕdIdDD7%Çêk/­StOþ#PhÒ£‘ {lÅz*&j[j}š¦€ÍÎí¶±sAqÈ[Ô&:‡hÝX ‚™k›y­çÓ5vjcìC9`kéSä ÒÜ[ ²ú^0³$¬Iâz{jÜU) ¯hÉÍ“±µ•S@PrÈŠ˜ W$øH­Ã5Ÿ?Ñýž\ &Ãò ýñÚK‡ø©‡[Öù€@Ý:;Ô­Y³fÁ kÖ³nrHêÁŒÂE`-æ ¸bXk±€šô)ò@Šu{€ì­ÁÌ¿¸«SаÌzNÕkŽ~·@u†€>°nxoF?»ÇÊÕ}¹¤å ˆxÔ ¨3È¿µ V ”xJï‹õŒŠÁvs×êY/»u„qj{ÈÁ«ÖóYo§IZl[@ß*X8düñ·´õƒYþƒÁ²„©¼/däj̤Jïb°èyŸé4¿Æü^ZFk® Ózâ™&Ÿ €ø lÇ{°ñ! èeƒÞ÷%¨Ì?As¢™O;O÷ú$'·ƒ®ûS­ 6ÃÛú–à%¿Ys‰XP{Ḃ²Íeÿi­ùÀqh”Ò>]¬µ?¨ùÓ]óc2ÈîúÀ²XÛ鳿Û>µÅ&ͦ5Ïøñ¤îÇI W«¹r7€o’WÌÚ3î Ïú\Ÿ7õý=ÈŠ©”ÿt'–Zö¡5kÖ,8aÍZÖ¤p–hó­—ãÔd,¬P€Z©¸JAM¥¾šW\zy…‚Ùõúyƒç%Â&G( Àb3l#@–Å`ênêÅ#:ÆFh1]Ù 0Ÿ;,iÄù1º·ÊѬ{ËßÓÄÿƒ¡À¬Ü.ha–ËZ£ÖOb¾ÿd¬Lð8Hp¨ÙКv¦Æàµ ’ZÓüzuY#§ìÞúý ¨PëØ°½ç»úÛºvœß¶/=Ab¢ödÏØ ©õ­È"¨Áìµ Œ÷ ÑzD| «íA°îqk@lŠ> ¼ÏÒç€ó#àþÀ†f‡€­NŸËÍR ªåèI)úêøk5ÖðC’ „OëIP D?ù6¯ƒ Æ™ Å¯g{‚æè ÃCÚÇ×ÀêRX³f͂֬5j…`«¼m õ‚+*7\pÈt´x#sÇl¾†iQ§ Ø€¿€5§ ôZ¦ ¼*µœ¢)ø?4â˜æ‚™÷¿!a2û¸ `ÒfyŠÎK¨J4Vµ³å€·@p4˜¾ ñµg>ø’sÍ¥#áv§ùdY|jnT·óñlÊhNY‰Z©‚¥¿hìÅüA^Óé£V_ë[Öy ™#uÚW*ôÚ ßÕÀm5ëíîö<{ï{¾zßgDWëSÌÐ3¥[o*àçþùõeÚû5/°± Èx]c œÄ½/ÈQ¢yoÚŽÏË>^Åœcçkm£½+còNÞ,I²|Ô’•€lÒ~Ú{_ÐùÏkàñéÏAãÍä‹\'pÈ–RY³fÍ‚֬ŰÍÁšó`6mÜÖ{»%K´æékœÓ½Šr ((³˜=´9wØÑM+ô€&1àE9\ẙ~x±Fh €hÑÌèl'‡i˜@‹>ú[\1GöX–3<—âN!]ÁLXÌàÆÛ³¾dIÜ$àa)HÛ~^Îöž ëá% q.} å÷"0ÓÓMàÌÍ`©ª‘€n¨§£tÏÜ-g¶ŸèpUþë<àSÜÒŸ†8A+@Tëe‚ ï±Ãž Ãü>â .ÂM¬ã~˜=†ó<_ópåÂíYï÷ŒQŸç˜>OðbŸþ?Çsâ½w°¬äz°„ʧãÜ‚ЖEaÍšµfÍvë°Ö8¿6×*m}=± ÞVë÷;ék_9#]Hx.s¬`¶bSǽV ëø]ìn¥×6 ¨{ƒ¬ƒ½<Á`­ç¸sL+ §êû¥`Ft*€—%•+¤§œ‚íôÚ¬íÅÖl IDAT ·6=•–'§qyœŽ‹OÁÿ ½¤»Þ­ëê#Pâ4Ýç@ºêÄÎÖøõ?¿õ zƒ •¿ƒ´ÛXtRŸÁ1`ö®É»UÀÕýº‡™4Ò³<${?#Q_½ÁB$ ˆ@TÀÑõ~﹘qî÷|ïýb€=§H ®+ÒÄß³À‹[0þixXÕŠkÊF=‹.rÆ z¶Ë“FzžzcŸ ¸›”àqÍó®Cö±~LV:™6¿=&­Ô\Oôs¿Ðøê ²Åzx€¹€ç¾GÏ©jç„ç–2J‚Á†ã<¦µ°7€wÕø+Öyzö(snÏžå'~Ïßó´Îyß¿ lï› p"Ô–©€ÖœuKý.ÑX¾dMÔÆ9úȺXŸ=4ÉyºÉ3Ùo„ç]í©Ç€"‘ѬJ3êþ-Í`ߨf^$ߤÔrz@>G¢÷, ²Jþ(Pâ.‰±/ä~Ûηµm°žó×öVXkO›5kÙl#A–ÄRÚ™·æ5åÌåxœ o@ØúðërŸ'h4B›ëåÐ,Y3áŠ[Vè„ kj‡‚B™½áêN@Ǭ’ƒ¶TüxýnQ;Ñ€Í5€z5)¾¯ý@æÄ9žM?_Э &‚tü‰ºoÇ™±þynkäË’u•Ã3Fç±ÌŽ>†Ø]; G~4€+t¿—€™­Á,ÑA eüq9Qùz&¦ÃŠ—iÐXÙ¢Æˆó² ¢Ù8æ÷¹ž——Ýë 6¢Áó™†ÁaX†¡a´S*=c¥Îó>¯ðëþºÿЉ h¼`vƒç8Þ—ù]¿ÎÞšß­Ôñ[DBs]AúöªV\SvEáÞþqà;ƒÙÜ}üWcnˆ€š£@&E5X†pâf5öלƒì}¼nú™ÿ÷t[Ï*`Jè¾6Œ4Óš2_ãÏûêõµ Àë%ÁàòtÞŸ70µöÄò÷b­O9žïרHQiÇm µ7$öÒó:F?¯ÁÌé`™Ò·Úsʱ);ÈdìÏ0±™æQ°üë¤^óÁ§1‰Ñ;À8ß S3Éï﮹a˜À•tSÅ¼ê ²(ÎÖý¿drZÁéÖ³Ï@`ób{+¬Y³f­í-Oæm¾åúþ39;“à—Âx-HÛ ‚Nk¥Ÿ—cfêÇ+ÀЉ`ÂÝ ¢ý s¢—Ž•.r€‚Ìÿé>7f}Á¬—éBr•JSŽáÈQY-€b³&Î9l÷ú \Ð{æšbOÖ³®xq‡@ TÀ¹¤Ö·&£ÌËnx‚/Há}™àÈ”Ey1@œçr…îÑYí`nû5ÏÖi޶¦m+pó$ÆÊñ»ï(pòZ±«¹z¯ Ì‹ÇöÔ{¿Îâ¶wûƒÚóü¿N‘Ö€´µ¶±“4žïmblúA€m‚ö¸u ë7 lô™*誀·d¹= ž•AîU©à¸µ­LF,оž) DOÝ—éº7+ÞlŸÆ}/O>Î}æ; «Ä&GÓoCtÏ´·Âš5kÖÚ>p *|—Ë¡yÌ ïf 6ÏÈ¥b³4æ<áýb RU9` = ÅF;sÀlìír趇›¹ÈÛd |j+,×5nŒ:ÖBÆç€ ƒÁ I§/ýNŒW°ëì¶a«³^{ÀÕ8Âã } Ò>sšxžƒÁr Sçý¼žecw¡>cœ‚¶µúÿÆþg€çzò:è¼9D÷êvâ8Þ ±uz+îV ˜ö_$^j0FÁ×ã ¨VW‹ÃŒõ `Z¥g¸4Jsÿ,—gë^\”´Ô)°Ûb›ÄilÖÈ{òAVã½ï­ÇÍÍÁÒÇ?‚âŒÓ4ÿ¾YH«µÌulúëGkÜ\–ìɇ'7ä8ybI$b½¢ü¨=·­ŸAo%á%“‘Û çà“:ïêóg€,¿"iµ È{ÌÞ kíɬ愵l³<°Fõb039Ô.øP›bºÍ”u¤·¯)ÛS@¦„¡ wõ†)ˆßE›÷ž 4|  XÃù­‰`Ë®Z¸-P{Áíî1D¯ rvÛ¨5xœ’épû¯ÏSP^‹Äh¯5zuŽ<åƒÚ3Heþ Rï»ì‰ õÞAŠÕ|N1¨+q˜õùQAéxÄ.û(s¹îkDÅí ˤ±ºe#h×Kϧ#ª‹ÏÕuï(‡5-÷ ä8ù«õ Ò}²å“4®w™O­¥µ`Jb 4ö¡@¿RÌÏTð¼XãîgÓz&¨‰øêåóõþY8.Í8L`è¤} Ì¢WÃZ[XÈ@,µ’¢Ö¾nÙmµ7< ·ôôä^‚úÏ(¨½»ƒ ý#`'Užu P_+“\§6ðZÈqÞ°,ÎN-†Ñ¶m§±àÓ~6À ësÒ߯ûÖZçÖ _ãtH‚e$7êyר©’–øÎˆ’Ž··Ãš'¬Yk;Ò8r†Þ““0Ìž› ´Öd´¦‚tØãp­Û\¾¬óí$gmˆ®ÝÀr»Ø[€‹qÔ¾ÙAêè,PDÒÌë|ý@Úën ý} ˜Á:JÃ0ÃcÀÉpi´M9aUr¼z0`° å<¸Y«¸À²—‘ Æ.×9Ç îºwêýårdžÐ÷ÑNn/Pý\>a]ÏÝúÚ\pb4BzÊ¡ÞÐçÎÍ‘þrìSN„'Wcñ(P§a¦±–ŒÍÔsÛEc¾µ¥z8‘hæï'Pv4HuÞBç¾ È–ò~ÆO þJ<à‡)áÊÆ <AÌC´æÿWA­µ¶±­µž| ‚àð<Ë#m‚÷—i?‹µïäj?¸ïúŸ{Áò üœ,Œ?ÉÚ,×x?ä8e&•ƒMÍ5£UÞà„aJœ)P¢Ÿî£ý÷§6LÖË?øÔ‘¹K÷÷z4ž °–œk‰®Ö¬YpšµÛF9#äoïêõ·jŸë­KÀºÕ¥Ê=`F:æŒ``¹^3À,é$²9˜Í Ò[)°9A×T!€â{P }Š®e)˜™ýd/ä‚¥&ý í£¯[é>­Rà÷…ûYpÙÆ ö PcÈÖxXÁ\0;ò¥Ö™ßƒú]AÀ«PDq¬Æ€µæ`©Ë :§†(‡u|ªîSµêºã Öjt ýÐö4ܶ²Jÿ¡™Öµð¶ß; ,Ýé¬gò=¨Ò6ÓJÕA:nk9·f-ÉCâå/ š7·È9ï¤ãl©ùmº™,3ëxjœÏl' «+^»HëGƒî±eM´åè9ú´Nÿè0ß…Ø¢¶~׃L£<­w xj DhÜ$Å&* Ã!ǹ, *³Ðg8Àê ò.€µ1„C‹õù«šY# h[ `e HM÷3Á¨~Zßо<™Ñ)£À¿µŸ?!¿c˜|õ=Zf=ÁÄLŽ|°2{K¬Ypšµ¶³• ¦kÓ+)äÛ(ˆî­¹̶…«Rn SšQ¥à`¨ñ#H%Ÿ«@¨ éc]Dà²;Ö+ y]z7 #ð E0G€õÙµ`|–À…oÀRŽr–V€ ‰gä8öÖ=ÚGàÇ0÷ 9æó?0gê8ŸƒYàýuËtßÿ'çh‹;-åj½/VPšà· `å`Ñq£€ïûóA6ÉÅB:ë|•Þg"qµñæ{jcŸßçN½®{gP˜4)…ùã,™3@¦DÝß ýúesRÐA¦¬??XÁ}k‚áµd‚«E ˜¬åyŽ›mŽ`š³=´>˜Ò5kmc¹ ˆ^²r´^ß гAöܸF‚Ñ"Ô¼^{õ,í ï">fÛw {²PAûÚD÷kuá˜rœtÞ‡€ ùî`ÿ"cCŽó,€Åžµnò)V!*±!ж Ú^ ñú.€ó‘\— Ÿ>ïdÝOÓô °ëO2-AÓm z>Ç€:9GƒI…JùÓíôiñÞØ]ãý Å{[¬Ypšµ¶±ZÞõA¿£ß›Ž¹pÛ€™Ë. H7³ ýToá0F`Sí†er–¦´˜'Gd˜©KG¹ˆ,Vè5À£ºŽ^ è÷Òkˆ¾ŽÒÿULŠé ÅvŠѵ:–Q@Ï•S¸¥üQAvCv™®q¡‚MºF÷ñ  U MÝ´ÖÚO‰á(™ìØÍ ph¤ þ ›¶œì¤ó¹,sÉht€Wt}-Ù€‚Ù®Í:è܉hL˜¶|“$r5gŽõF†h,­õ ž•3ZщXî uu7ÍûÖr¬ÃH¬JºÍ—Åà„aNÄ#T›« /f‹«ì–ØfÖ)jÏü¨9àAäÛ´"Æ~0 d½Œ³ÿ·€àóšöÕ/@ÍÁ’ŒG´­L¤ë³_ 9Î[Ú/Pp}=(ÖùšØ³J‚ÁºŽ•ž52O{ôÉò%j¾N™ÉuW Š `Òá~í™ÜRØì3Þý¶›@ N$o=äãå‚ÌÙgì-±fÁ kÖÚÞ¦(`ÞÌʧ½n†¦)ª§Èðvݦ@}„~6Ú †iaZ ­Ò¦°XÁÞÏz­Ë6ªRè4„u-FTÏd¨ŠáêMì' a+°Î÷XÝ‹Z93«NÌ3M? x]Î]®Í=@±ÉÝáŠmC¹Š§µ9þSàD-Hßÿ~­aœ‘R0ãc/¯Yõrd»ê>_¬ëHí}¤ W¤úYŸ·•œÉžºæer°+J‚Áº,Ÿ;óu¶Œ0»ýõ ÷–³¼ÌZð €qŠÈ%c4–M›ÖrÆ#H]‡kͯqxhκ °ŸAÀx Çz´ÆPGõ+ µtAÎw@ðò'íŸ`Ó2Á\í¯¦CÕõÚGƃl»©IÌí°Àˆa hzXîó,~ÿœÌz!­‰I!ǹßKÁ•ß |ùpðàÁ¿Ìž=ŠŠÖ?öÈ#;€ ôj/| ó¿°1Á’ŽBÅq ‘ö°,4“Ë"| ¶Ö• 3Æ”ý¼ Š#^…íTJÊö–KŸ¬Y³à„5k`Fü¼ïTÿ ˆ/³è2ŒðãB°vïÍ›nr|‡*Hª€®7˜®÷ù°i™ÈPb–œˆÙ1Vˉ®FrÔN¯ÕÃÕ¯˜&§%OŽâ–:·:çþ`æb9;>9Õ:×Er(§éÞ¯û˜²36x¤Øß«Íqª@‡ 1®©HàÎõrHËÁìØc ›Ã¾ÇéÛêã||…Ôw&øYÏ}>ÿP0Ûæ×9Í 9Î7úlS&SÙÂ:áL³Åºý=c7”0À3œ¨÷† >²Xæ‰n›+pjg9¹­Ñ‘Ç0' ËZzÍŒ£ü8Þ»UKä˜×*p«ð¬‰+5wWƒÀìý}=\ ·VëMÜ2èvTpÃW©"{*Ðì—qس{j~¤yùT{™ yš»c@TþV¡½áI´Lœø°Äð>Qs È28Ô’xÄ.1+ ëÌ9ÎM`ùĉ ›â¸í‡ ÌŸ??7xÖY×À(О:üß°PÇHÄ À’ËëÀÄ0؉ì6Pd2Ó»LuÑܼBãfȘ|Kã¥n·( N$nÝAæªNÿ«½%Ö,8aÍZfØr<³ðW*Èþ Dè'›À2 GÓ8ªËõš,§- ùT²z¨ØJÿ¶ú¾/HAßKH$ 1%³ìÍ“ƒµVç[“Ä97È1ªÖñ¿Õ9çÀmkÚ ®0æp¯ÎÜ˨¶Å 0Ëþ#\Å `/u€ÞX-B‹ä¬^©ûPà5·Â¥¡vÙW(®u'îéj;¶T糞ÍG ²øAº/{€úˆžÅRSBŽóÜ®)åid ´†­Öxé£{ aÀ¢ÁN,#ÁìÝ_e`ÙÆ†–mÄcåš/5†¶Òç6X`¢Õ̰Œ6PSã« Ì×kÝÚAëqX¶—«µÚ«1?Wì´^ÀDÖ¼j»Òd¬Ó«B¯JÏ«Fï¯Ñ±ÂžëhÐgûá–<çå-òG[ç¼¢ß5.}žcÏ|†÷srt_̽1àC7¸mªû€`|o@]åzî¥ÙËju?Œ0õ—Ú‡¿ƒ›ÑÏWp=FkJÎ= ýûOh¼sG¢V&þ ç£A`õT _‚€÷HðÖz·<ä8xÀ«V¯þg جk×®tÝÿ‘ï1@U€v>ȺZ_}:ïÛAð?ÓE_;Ɉ봗V¨zP¾„™ÓËnuCì’kM›2Y#òÍØ[b­=š¥¤ZËVËW`û&XP-§ÊW3b†À…‰ Œ {!Á¥q; ¸ `˜©ïf:ëÜ ë",çªBç÷‹°…`–{¹ÇI6EjôJö:üžsí)§Ôt>ªs7-7MéK6ÄÅ .ÅÇp³8FEüH°6wG¸z·ƒ%µ:Þrd·×3ûHU†äÅÂ|¿)ë–-Q¥ÀÏ×hà vDbü.zmjêgÄP Àa”z@½Žû<@ˆ/8á‹z_ôË Æ™ÒÅWh­\¤×/ÚVk/ÚB÷ø;OÐ_ –Àé×^ÜC÷øáåiO~ÍÝ#@VÅNúýoq©`N ðj¸¡á°ÝvÝõ¸Ë.¹d| Xd…Ù®ÔžäËdþ Og:(‘ê†\‚ûu øçí {45Þÿ-?á$ ydíÿí¸mâÕø¶f͂֬e+ÐêRô·VejòºÈÙ4‚‘kôO•£2MN×j¤Îëó€†*ÛK`Ŷ`ÉÄ6 ‹¡›Þ“tDZVÀ‹¡./35³(/3~Év1l‹|g_PÜëOºÇ |0å/£<õÓ9ŽW û•œ«\=“›=Ì%¥ªút€„ýôœo@óY„N/]@ÆHÌ6p ÖsÔ 3€¿è²™žOƒ£Ÿ0ªç°&ÃÁŠ-ØÍSQ+uù«@ÆÄ`ôwH¼N:]ö×êkk€Ì6:NÚœ¸Ns+›l'°3ÐÛ`z¸‰¹ßda¤µånr¿1ŽuÃç ÜP6 „Yû ³ HkEg­´çꕯ÷ä{À 4`SFEçgH‡£j#â\¨ãë3 õ7sî `ö‡pԱͫÖóªñì!†²nËÞ5ú]%\ýÃØhîÞö…/çí±¿€å5`«é§[9à.ÖÞs¹¾æ‚Àëýoñ¶òõZ,%ÝMÀZ2Ÿ Aü ¸L‰ÉÏ͵PÍËÕõ_' Á§}ÿ6ønlO¿,ï¼¶ýe¢v£îwžîñ~Èü2kÖ,8a­ÃY¡‚©¾`†s9\¡ËnúýŽr F€z ÝäLJ{…¨i ’ÿƒ‚ܵ'-æ÷8Çm¦sßÌö÷é¶½àfÿŠ<«Oޤ)ǘ–GL#Ëå„%*·³@„HϼOÇé*‡ê÷`Ö¤X÷ë]PSbªP¿À‹À2ްôæ6°ô¤6{ÔGŸy8˜iê§çh²…×€”ÞæŽó†‚òý@Zd\rœ€®Ó€"F8´Ÿа@£)Þ³^ÉR|Ói=5.Ö tÙ¨ë3ÁXyuÒݳ|“U–¶à>ì –à¼Œø2ë©ZW6׺‘ àD‰@£l'†@æ§ f@¸‘gr¼›~š»—ji+qÀhB,†E,‹4ð{D(Ï{"|†—¹Ž1¼Ö€Ôñ0 p&P÷ñ¥ÖÙ£À¤Á"P«a<ÚNg @ÁôP7)Oëó£ cg%âï„“§kÙ /—&pEÚ{®€[ú9I{×ÇH½ÎRª-–R]¥ç›§ó¿M{{sÝs³ÿcPØö—ñÙ žÓ:X!d޽-ÖÚ«YÍ kÙl Ú s•2ì¨q:\µèyr4^™a9ЛË!=_€ÐL0ãù>âkÿçÓóÚ Ì¦ªgÑõL ëÁ–¤â¼×“@vͰDÀ •5˜òš©!Ç ÉÑܤ/ÿVÎæoäüVë¢ÖtßX—@E@·NÞý¡$4µô-$zöG( Þ,‘8ÉgLëܶÓ\·Âºö_™`~OЙmftv àÑAñ¬}; ”8Hcè>½Ú4Ч”,™ãezÀ–¯uù|­ËÝ@púYq‚~h¯9db¥tì–••ùA¿@yiiiSÏ¢'j<]¦5ênP«Âœû¢8î®ö¦ÄßʶHûÎåºwY|w èÈtP"dz^êxiO¿S`C¼ç?WïÝEãȶŽoíWLö¤·,Êš5 NX³Ö«“cb(±Íkôš¶: hƒì·ËÅ. ‚¶Ô†0\›± ô×êÿ'€™‚™r’“-¥ˆÇž¯5ÚÜWi£ÿÆãÄçä>[vÖõl£kà4ϵx»‹Ìx1dެs/˜ad.tÒïß‘37›vIéW1}€À–ë`ÄS»_(å$Ý÷z¾¿xTýž¡cÕ `jXOà:Y_wÑ5%õÌ$’¶A€ÕO!ÇyA«)-:\cç°\b)€ÿ†çe9êk[YXÒ;g*t¿ ¶´0@ÒHg+ˆì¡±:Täo iæ]_9Åéf3á¿2GÓïY˲ÍLù@6yÜ ÌtŸWäZ`¬‡µÖ4#˜{„Ö´ò/‚âÈÏ "´Ÿi¨ ò `¦À*à~g»À_ÊÊÊÞ+--mnm¨Õø)Õ>s>˜”¸ ,{ ,š×Ä^b4Šªã‡µ\W‹é+8ãÑ:݇Zb—ê>ƒe,÷­AËÜCW‚I­´Yp"¾g0Fs°d±VØÛb­½o(Ö¬e³½ Òô÷PŠ Àˆ@vK,¶U ¹³‚þÍjD,³ð@Tûg÷é,âÿ¹:×n Å~;]ËýÜKGž6A/pQ®ë0å0s@µò—xÁ"=p=˜-¯Ô{ï…˨@ÎÞÖ Mô$ý6àÏlŒ×ùDgG0#ö(’×8a(ä_€4ñ´èC¨çftNKzêÏËAýŽ@FEE+2*ü éH½æ´àæÈ) 2þÖ:þbÖý¢€¤ê^_ÈÞÙ,¥™—æ{” ‚—Ãb-΀uî\—¥SÙdFe.lõR\ª@w!(øÈ”²Özæ™…%‚ à\§ÿQÍ“rl š½2*®Šé@ q¢öÿÁí ”°•••å‚å|c”¼ÖåÏ/--Ä èúÎÕ~:Ç—AÖ`,b3­Û˵¾Ç °‹AÁá˵nÕÃm“=¡å¹ò.Ö>ÙE~ÍC ¨åj$”ú@­‰“Ú|n§X³v æ™O{ÀUÈ|¡TkÖ,8a­CÛs ×(9 éÞ° áj\Œ€#„¶ÌÌ’#6 Ì6¬Dã%­½.1¸b¸úF Ó0GŒÎ…Ô—xd xÍŒ7_aP§âo‹êš8·ËONÈP¤Mwª÷÷b€ Ѷ˜•' ¹{ÛCP¥‚ó´g Ä÷(§Lë­±2_A×+fµ@õ={Àq Ùw ^‹íFiLì£1d€¤2°æ<•Ì\ô $l ÒÇ"ði ï¦×‚ Xçþf[ÿˆì’ë†KA1Às.W\†Ä4¬µÜ ãî<¹ÒSAû; ƒíÇ&lGkñ(ÍÛ. à|<ȼ }£\úKZ¿W$º7  Øl/»#È(ü§ÆÌÚfJ=¢¯·7p_ s\§s{Î̹m©usÈ{×ìBÝ×êškXÞ£}'ÓƒÊ<½LS!>,PbU æa©Žw3:ZkÜöð:Ȇ]^ßÛÛb͂֬e¶=&‡â0E­íÀåÂÕ±ØY`Åp•P,'¬AN‰é2 Ì(ÏцcZ³5õ¶f[öHXS:Z›â§ž÷ùuWêïy 0nÛ:4V9@Λ$LíîO ÒßRÀOfÉ/Gê9¹Ç y&Dž Á <µæÍPÑE­à¾³ÆÇ Øö>€%ilßy7(Fv,(ÂÏyâ”ço IDATç*X9dI и6lšW,N¸âÓ}9MÏw)ÈÈy,÷H‡½¥àj¤Æf[Û¥räÏÕ½È&ëf¼W¼FÁåã 8™:™ J Qpz,D.×\+ÓþÕÓáA ‡‚ 5ïz]¬ ýD°¥ä–ú̵zïó Knm"ApYYYw°Dãbm3[ëÜ¥¥¥‰t¾ðk} vé²u^Óuý–NÁØãu?òA½¡¿h_©Ó¾t§‚ÉLo7mº‡ŒÑ×<ÝÃG@IBÏ£®{7AcÌvœˆmÁ®2¥ò GÁ2M¬Ypšµva÷Ê)9ZAg&8w9pË(vô¦<"nK8Ó[~=˜•X®àk ܾò+Á,S…‚öj¸"ré¶Ký Ô˜€ÖPq|s 7ƒYµÊF6ÙõÉîî Ægƒôÿ·ÁÌT¼e0†Š[¢cn –~\g ó¤ÝâœçV5ü[€å,£å´ç»/„~†ÔëS\ª«7膧¤•ž—%Q.Çûi°[Bk”¥œRŠ?©â]A=‹[A–Cª3’/jÌ&ÔÕ%v%ü­sË+RprÈÚZ2cD|„ÖRg¹`ùÁí¥E"žYlKxƒ+œø~ @gÍeCñï'Ÿu9Xzö¬æ^\º eee†íq­@ƒ|…w'€JKKôƒìÑ {d€Îã?ÚçžÌßkoÿ ÈDókºM·ÔÌë¢}ð2= èžÿ d.®KƒŸÑE÷¦ÔŒZe§_£ Î÷òwÖ€:/‹ím±– f1­e»UÉ¡)Ìó1½æM·I œs@1ÉrtL Ŷ1zʱÚ^ïõ‹ 1L§…µ.怙œ¹`=¨·ûFª Ã,¨ó:@ÎçNTî)š+šøÌßÁm8Ô yCàDUN¯icvØZ«»œ§'å Æ›aýQNç¶'J‚Á:=·‡CŽS¦ñpŠ®íp=d+LMáG¯Ð×>q¼÷80{–£ç5Ì".Õù·–-Òøš*Gú:))á·‚T뺮+þ ÚCÍydC–±PëÈ r¸kAÊø]c–)‘~ ¢§ÖÒý´·l· Ã<§¯ƒ¬¾DŸÇ:¸šYƒÞ7d<Þ²àÎK%Î[”NAзЌÎAiiiÀì²²²óÀr k@½‹±¾/++»À‡q‚ `iæ}`™ÊÉ Ûìd­‰ùzσºoùp[jŽCf—o˜gs<˜|¬1ð9˜©ÿ\~DºlXâr”>Û‚±íAù< ò VØ[b͂֬µ«mcÝÛ.t­ÎÿaÓŠ9†Ýàj@˜W¡ÐKyÂe`ÔjÓ_­@n€) îÃ9‚ɰ-Lmÿ6r\JtÞo™ÜYÍ8¯>Çßäôü €%‘¬h!¨×p ¨×Pfòî’㸉‰ªMÕ瀫Ò¦V V˜rœ©º®ÝÁZoÓ>3•¶Rã wïÖpf»6¶Q;Ôe¶Ñü9GÕ t÷5Qþ¡çÛÒ·Zc· CÖ€g-i¯æAÎ46(û;ÈÀiÏÊýÈ ÀíòâýÙçy™çö¼ôòyöŒç†ÛrÔÛz4¢¿ÕÇ#>0[½=Øæø`˜íª½Çüï|ÍuÓ…!Ù±fº2uóýa틟j<ôÒ9¦Ý ¢L¯eÍ€õ¾)++; d-^–\„L+++{dëÅ£IÑ àù1±tŽQp](@íNtßáó¯›À”KÁÄHȹ­§‰Ñ g}XBò•ucµ–ª{$œ [þb͂֬µ3™ÒÜvxîsZ-‡ð—Fã¬æ Äè.Àb;°«À`0ûÕK_’3R'‡i‰6¸¼¦Å:mzá&Í:°ƒ os#ÓGï³`i¼¯©ý=lñ¶“®ç'°ýu9É¡ uÍCµFf̦/‰õ> 9Î8ëTŸŸÉ†n83À-©$<LÖ–ƒüwÓòô· T˸&‚ Š«ÁN/G‚Tò XIöÞUÂív“IàDí×ü  çaº·U`ÙÛã ]Ù”°­ÑZ¸^Ï¡nÛÆ:OPl ðš.Ky•ò<æyþî÷¦¬®.+­Z?W{öŸh0íš{€ìƒÍô}W¨Ï5Ÿé]»£Ùp± ŸÌxþÇ DDƒužs6÷«B¯ß^ ÐÐûknÿF÷ûžÑÚIÁú/ø ¨XjO¼¦5ú|²×ƒ¬¹2-÷K3 E-€/ÊÊÊNµc.ÁíG@æÕseeeÏX(ÖEs{õZÝ£ è«Ü¡ß­Êà¹i@‰À²A#/iœŠÖoÍ;AcvO6ðvíï©—ñ ­Yk·f5'¬e»]fðÏ•CÓÍïqЋå0T@¿³¼>rž½ZäT-VÐ?Ì-•úQÄ Õ÷}MD„p˜]f¸›ËŽæ p)U°¹¹ìoŽ“ÓÝG°'XP fÖ6t°ñ2X÷óK¤±ª ŸÆä(P·d'ÂýT‚:ÝA‰ H¦ $§ñÑnVs°œÝ¯ÁŒç8$.èvÈÔ9Ô´hk»QÌ) C¤½ú#Û‚Ôýap5y:iNçxÀ†èÀ0`Æ×È×HœçÖÜgùbœ—YKÃðĵžŸ<„? ì0:E~Ñà9n.‹Âõ½ù_„D37LËëe ßÕ¼_"Àâ ­ÏG"Nm‡8lP›á Ã- Ú ®Ðy s¯—Œ'Aí‡åñÌí²²²<°”åBÐ삞€z6SJKKkâ8ŸN`kè9 k/œÁó­³Ö°1Z Sâ>­§m tË` =xueÿ߯‚%MÐ>·—|1kÖ²Æ,sÂZ¶›ÑœÈïÀ÷ÀëÌVÙÇirDsäwdž€BKÃ`ô™ê>š”rÜzÙÀåÚ(k<·å4¶hòsNÔþr÷Ù!«À,ÙSºžšÝ/Óêu ‚Ú !Çé – ¬’¿À† QfŠ™Œj/¤ À9Ž_Ç?Ì|ÕØúd;$°ÔÀÍNŽ59^…9뀌šÃ„ì –~,©êÿËâGup3æ™dí™9ÁÏ›pͯ@à3OAKW}í¤u¡HkP6-•ð–20 FÏΰ Œx°à &}€ /êsrµ§ø=k«Ñý©™kz­‡+T\§—""Që´ù\/€âx_Æ¢Ù¾( #š9Ò®>з î½Aà—š‹»i®|’Âõ¥A{Ž?Á»)9¹d=œ Ã^à,Pûy=‡FMLŠÉeee5ŠÎÐÿŸ¢uêë²²²ßL‡ˆ³ËQZ±®éÏZ{«ÁvÕ÷¢m˜ѶA{úþž,8Aë¬= ÃsgX kœ°f­Ý™)-(°·"¦§ºÌ–}ãqÊsA:².†Âé ßis¼ ÉeYjAÑÉ`ýðÏQÎv0{‘>; ÒŸu-–¦as®‘³; nÿð~`Ö½«Îy)€ïUZñµÞ_‘Æöž­iU]€¥,{¦V©[™Ÿ3Án$U>³“’(é0`ÁjšþP$ïF°6÷@¸ ¸xQcg°$èP0sxXê1Ì–6U»^—a{h¶íå9šoa=Ïiqþ_t€+ˆ·F›–ñ…4îÓ:kïJØ{,•ú ©aOTk^uFjÁϰ¶AÀúR ÷j­ù+¨S× HQ`AYYÙßv¦û²^3ÊÊÊѲ&]ŠL1ò –°l¯½îM°lçGdNùD=ŽýV¾Á÷vºbG°CJ?ýü¦]׬Ypšµö NDᙉZÄZT솙`æÌ[_] ·}a×l”Ÿ‚ŒˆQ`±_Aëé [aKÇÀN’IãõOÛn­Ï›R›W°;TNÞqºO«Ì9ÎxPØs.€Õ%Á`{¬•5`U¤HSAmQwp˜ù^#áq3[x¯ê&ì f·?s{¤‚ÜýÀúùy CâeˆûZ€ÆÑ `v™9«|j¡LįK{<Áp¦ÌYd‰³š£9¿=XNömÿkÛ‹&fKÁv §h».{è%öÒº—Š’¡J­1Ó4 “â °´ã&/¯‚ Š[µVDš)@æË¿ËÊÊÞ†«K±¯ö¡ë„ÊÊÊÆ">]ж%ºk?»dGÖ‚åwƒB—õxÞßi>=©ŽˆåìÌq¿]ï¬e«YÍ kÙn§€tî[@Õwk©µ3\Þ*’'c[ÁÕ¸Ài Ðe°täm0ë=­—Ù9̠ߦ—7Ðγ-˜I¥À»‚…AZ÷\0Sÿ™ÀŽUjÚ¨›E"–¯s¨`=i±­ãäË©¿LÁMX3Vÿ’²Mî…+Žç¥UƒuË‚º&Å õúK#ã4Ί@Щ,)è+‡x.(÷"Èì©S`rƒÆ—3à™Ý à*Ûöª9Q CÐÜ f§ÏÊÐà)›lk0»5ؽâQ¸Œ´ƒÀr¨ 8[ÞÂÏê§ÀsŽÖ„t¯éub ¸¸ dk%¤§#]Šá ÈzŒöuºw˜YZZZ—!ÏÔ2ÿN5·‚Éš´VNFf Mn¯5úZ×:òpœö*ã™9jÍš'¬Yk‡vŒ‚Š;åÀ[K­í¢àî9AÉ8E`vΔmø¿ v~8&{€ŒŽ7€64€ç‚õïýˆïÖiofñ#`õ\Ý«O@&ÆÊ -ñëw™ “%Š\¦{âõVÀ¹: z³¢‰ßæ‚@ØÉ 6HçµPàÃszF™¿…W÷³¼ëå(?fO¯Î pâ/LNÕým/fºîKÃôûY`†×Ì?[W~ÛUc§@ãèS¸¬Ã±zF¦NKžG/¦¿Zs«²®Í§qv ÈÆ(†{G2`KYYY,m<]kDÝ÷ €«KKKËÛð9´¶ý^Ïqsí?oƒ/¦#"Ç)´ ˆ5 È:rÇŽ[A ŸöŸóìre͂֬µ_; ÌúÜ/ÇÊZj­·Í5H^5Ú§ ö"°îõ9ñ«Ñv´Å-ÁrŽ„#é*‚Y«]¤ï-g«H×T.€âc¼s¬Ë Íw€ï Rë%ŽéÏÃu­ßjþýÔåHsäL×-ðš ˆ; 4 ‚uÍÝÀÒOÀŒÔ0˘«±p €Ñ`fÙÀ4éGÑö”ã伞®€>Ó-dFÁn}Ü}¡û¹HkÀ =«FŸ~óëY<–{ ˜â+…K“µ® :à ˆ[ъט ²(î™_+Л“Ì.++3ºH'hÿê àÈÒÒÒ)mðüòÁdÁEò{:ƒâ×/ìÆùí”0ÖÔEY£}¨ªƒÎÉ#õ 5g.Y:Ö¬Ypšµvj*ÐzB°µÔZ‚ëArŒ·Ài4â‹™!é*p""z}²RgŠB0ƒµ»ǽA¦E.\ÍŠ)+¾3ømÙ äßrŠ~£óŠ”0Bk;È 'PbBI0ØÙÑ£äÄÝ 2 â±áò;P;e €‡å¾I>Pƒc{Oýn%(øoíÓVÏëz™ Nø5~+PbW­+@ùI èoƒå€L˜W_­V»z™¶¡æk¤™{N‚™• –@^ fÚƒ Hç×ܾd ýɳÙ: è¢=cuŒÃþ(ŽRÐ~:Ø¥"©1&¢ Øqj:´–u5uÆh_ÉK$ŸÔ³J‡ht¢ã8W{j?µÀ—ÍŒOb5hœt´–ÞÐ~ó¡žqXûÛhXý kœ°f­]ÛÞ`åórr­€Pê×'Aúè ÆB6X®@—í(-J¡£f2÷å| ¶ë­Ï­X1Ìä!g³¢õ*µKn»–B-Wƒe µ:ç{|×Ê‚ £&¥þDî• .FmFGêY,³Ž/è™4€Úe`–y£Þ·Z Àã`¶¿µ3”7‚”õS@06“ևΠÀW¢±ÞS÷g¨ô¶Šž V ŠàÕ*ÐZ ²–$ØçÁÑÄúݲÓçæç@Ôßr¢~xþß|ŽDˆõj l—ƒa~Oƒefa½êt=±ŽeŽQêÆü= `°XÞ±+X"õ¢ŽÛd?m©çøm’c"Oç¶5Z¨i“‚ þ/ Óà ü±ø>­C 4ÚE¿ÿ,»ùÔ&hõkQ,hGÈÝYÏ»«æÍDG5Ó™©“öÀ\°cÇzt,ËË©NÖÚòƒÖQ«¿c-ëÍvë°–íV¥ ºŒK‡E´ižÒ´³œ¨W`º˜ K8!6D…áCŽó´œ¹A`ì °$âPk¦ÅÄã| –,°1Ì ÓW¾KßH5`¦ôóä6êRRéUw7¥6oɱßI Åá`]úÅ`¹ÁX-1̺^ gšÎ2£&=¬¹Î®2Ñ{y™AÛöi½&ÇúX´>0‹û8ؾršÎy'õqÐÕ€Ó‡à²,öGl‘¦¬l¹+ÜîCµžÀÐ!· ‘_¯Ï÷Þßû<ßGƒÑmLá Ì×°@0_ èðÿ¯ã˜s.ÖØÎÓ«Èó™ÑçàýüZ$×m§\@×; #çcskA&ÔC héd$—‘¯Óú—ƒ¶mñ½õªA½š—PLAæf¦ ƒëh°¤l8ܶ›÷èk«1 ´tÙgÛ ˆ©½¬»ÆknׯIÚ¿ÞFóe>ϼéˆv¶Ö΀žñ LX³à„5kÙauÚÜ -8‘6›¡{< ÙÓò+ÖU@†Ã¤t}PI0X'Çÿ[߆ça9 ÁLþÁ`ê80[_fú&†çS°%æ"U)+¼¥ í—è¼þ vÂ™ØÆ­SkôÜZ DVëžž–\¨ å°>ý>9äÐ}À¿$]¨@z°Dá PÉÒ›Å4Ah[Ò·>lj “j°~·NÀÕX°ÍnXÞq6¨²ƒÞ·\÷ë°uq5È܉ yÍ ¿à< àb^VCƒý°ççpŒŸ#žµÏ˦ð‚Þ—_×]à@1ÀIZ6zÞh xÖ¯ H>Ûü ØÖù ' Pаø‹Æz/=³dÖÖµº…m¼Î×€àcÀ•`yÖ)`‰G&íc~$? d€n£1ù!XÆ6Qó¥Õ,ä8½üÓû‚e™>Ç*°¬o¢^³ô»jíwñ1tL¶ëÞ`›W3?nÒÏÖ¬Ypšµ,°Z¸âuÖÒc‹AD¸(6Ø,}Üšª•^߆ç_ Õz¨¡2 nVúwr°ø:ä8Ïø"]@ŒH]càD=˜í¾Àì’`0ÄÊL&:©"ë$_.ðáb!q‚¾—aiÏ€jý{TñQ2®ÕïŸÑ˜J»!×L·¦ù@ªö¾` À~`¦¨+ðk,'jÀ‘¢F‚ŸP7RxK-°i¹œ|QŸë‹!¼FÀjø@ pm+· ®ËN™+Ž‚ÎÕšÎõs’m[[®kìœëFÖ±€æú (fdÀ¹åjÿ9[kýf ‹æ Pôw ÚN£iK¸™ý4ß'€Œ¨å XÞ’s èú«Ðñºõ57"Ÿ9èØÝJ¬Yp𵬲:OÀâ··#-¶NŽëØ´¾»½Û|9ECå(µ‰ƒ¤LÓJ½>9NžÀŠa òÔ9žÖæþVÏ$àDçFÎ)¢û“If²×4wŽ—'À ë)Ú?oÑó‘œè }?Ô+9düQòç Óâs¤¶ä#×T¶†iÌ 2zúë÷óÀìó+~Öº»dv刀] žÒ{g#vÖw8( ÷Ô%:oŒc_c—è¤lºôazsµ—¾§àé }ŸLf{-\—L°jA‘–sýd)ÌiƒsñÃüþ~EZÿY,³3`ŸýL®Á¦ºh¦Œi-:ViG_°ÔÍ€§¥Ö¬Ypšµ,'°̉tÚe=àf:²Á–ÊñÚ¶-Á‰AW-˜‰^rœÏÀ¬_O0ÃVÔÔp£k;z^Ñ”út€S0äÌ•­@vÀk¾MÇ™©`-ûÝ`úž°½¼ j›´”M‘¯ëOgv-l‡{„ Óç–ƒ™Ü2ÂY>·€™Õz&«Z„@¶Ds‚}»(Pûm ¥!áÚÿg¤¤€ÔÞ¬Þ4œ«ßOÓ¿+’Ïè®CÓecmaUnÖÜ>_óúT´›§ys*hn¥±7 d]½¦=)#Ê´-Lóz™"Ikáxa„úѺ˜Ö,8aÍZö‚Vs"=V#gs ÝçlQÕ.×uõk?3ŽV©LU­œÖ¥)<´Qø/nGÏË—fp´•ëëÕr&÷µ%ÆúßÂÕ)X dŽãÎ/xñ¥þ6N|2YÂNi'r@}ˆœŠÝuA»)žð>˜ÕÝÔ Šãàâ=½ï+ooØ‹Úh<ê+ä¨ 9Nü-‡uz•ƒ `¹æÍ­‰F|3Œ_kTxÅ2kÛX«¥)3å4»)8ŽèY¯QðÜ)É1g˜0Ý3ìz+A–O‘ÆòXéê(Ðþr(X*³³ÆÛ:ð{JÏ`#:ž0d¾ŠŠtíø‡¾_ ²Çê`Íš'¬YË*3aRO÷¶F3‚ŽÑög©vT—‚ôõîhy©D{² ¢:ƒÙëö Jfα¤ÅÖÃÕ¨ú݆Ñü´°aÄóª‚["¯÷ ¶z<Ô–8HÀÃ8P¨îkò hMÉǰ4ä4ýÏ!kŠ<Q¼àD©a-4ì§Àlo°Œ¨Ì"?àuò^¶Ã êýFGb2€gu½K‘\æsµ¾ÒÚJ°®ÞÌXš¾¨ñç[M hz_‡çª Ñm‰¶ùZ߇êšÍ[ŠávÑÚŸ¨•' N„'_ã½ò N¤ÕV#sÔ×Se&{u'¾ê@ϳFs'í-xCŽ“+@ázP`í°ÔaE‚‡2Yé Úd·ý1‚Ã@Œ@ÑÛöÑM³ã=°#ŲÀgºÞžú?Ó áV9¬ãA=‡ñz$Æ>n˜‰P€Íuý@ Èè®õr±Àˆ×ÀšgŸ‰ÛA z_ýn¥«çuëSèPÏð%ë~Ô§`¼å€Yÿº—u:n­ç{/ËÁti€«¯³Âsá+¨qñ|oŽQMiú5Iq­¹TÃeÀ<åèäqÍ8éÄ™Ysõ?W8*ä8Wø< š kÁ¬PÜ ` c'å‚å/'€Ý6¶ÓïÖ‚àÛX]U›%Nø@P2ÛÁ#lö±×‘^=kÖ,8aÍZƒ žàÃZúÀ ?2¯†¸¥6CŽÑž`#Ñ`¨3Xƒ?­ß0Y«Ò¼é”.pB‚ƒÛ ”8ZNû·n„KéOœ Üø~Í"ðÇΣÿî\œÖ¡/ÖÒl•×€Ø 6‚ú)ðÿ3ÈyNãéI&ËNA ÒÀKº¯5VÎÓØÏÑ÷5Ö<‰þÿQg•ƒ•í`0MôÞiÀ™IwƒœHt}ùVsâ&ýo…翤x}]2™ÞK0–‚]S  _×u€þwO­£•"žÓ8^ŽŽ]¶Ñœ™±±¦\«afE@†ÞvlX³à„5kÙk8a-}¶JŽD·,»®…ž -¤Ã°¯‚¾e 9οÛHaÄ‹R N”è¶ì;ÌÊÎp€J‚Ád»˜@ª±@=Ñ: €à:0ÓY fï ?ÒLR à£#\–Mܧ€ÿClÊ8ˆxîý,/T± IDATA€¬’߃%×*Pÿ, ™èQ'|`r¨‚¹£AJyd><§óø^Aco°Ö>jwäëúÿ–š|Ä„-[b?ƒ­[Ç ´–—‹¬Y-Ãá–läê:óôÕ æo†]ͬ‰Ö™hˆ.üØ”™Xí%ð0Ì#3·¼à´>$sÌÝ‹^H°’t&æ‡ç<°„èvÍÃÜrœ—R ü,0ñ64.ÔxŒ>簃͙ ~@_½g68¾ªÿ­†µxÌtŠ*ÏòëÜN{„aWFÛ´°µf͂֬µ¢5xEké'€äi¾™j+åˆT’LP1¬™?Tâ¾ÀÝ!Çy£$¬ÈÐëëZSN„Ç”`o²n* [ê„Ö#u5ü~¿Õóª01É|4D[¨Gñ•‚³Á›§Ãíð¾ÿñë²O”o!°ä,?G PxRQƒç|üº×»€5úèÿs<Ç|ÔæX­ßWw”æq­Ž?V@ʲ6ª@-~]ZÐØ8+P Ú_çë}…ávÒ˜¤@±Îó2 œ·Ä£¿.óˆ`SM¯5ÖÒÖüÜžÚ’æjÌWGæûDÙˆùpK$ŠÀ'Åh, kBŽó6ÈÞ¹\c÷!g†篾) SÕé`&¨ð¢ÎýgÍÀí¶q6€š‹ôs4‡Ú}· Ê}£õlfºöãþpÁ½ªªª–Ae«Ù4FÃè̲f­C›­Á·–íÖIÁa‘õµö–¤Åë$ëä³¥F´HAe/ŸÉDuîCÁÌÛ±r`'ƒÔäÏ2°•`w°Uäz0ëŸt&R DW°æz Xƒ]v¹xÀ²k=uΫÀ-Éžî–78Gì²ú€ôî~ (`¢m eyûêç°\ãUP»b~]6â×½<džì 7Ã_2ºÄØGç -0Q×ñ? uºg‡8×s¬ešËcAaζì"‘ à «´¾443Þ¶…,{¢ñR¬HŒï½ìFÀ¢F÷Á´ ]·hÜ£UzUëUë>¼ÚÞro \o'Ïïžïsô³,M3k0¨ß2A€˜Y§.p7€?* jÎü À{«Ö¿z]Ër»- fèݲ“ê4î° E]=üšWi¹Psì\µZ\|—!Kt$Ô!åÓúw €‡R=ö¤?4À%γÏ÷ɧŸvihh8A÷3Û,_kÿ‡šßïÝ›ÖÚµn–9a­#˜W”ÌZzÌ´ „äË2ѪÁZü­ä€&N”ƒõ¦ŠŠü¨apà÷CŽs3€ij—Œ™À,-`…§XAÍU ¨h%˜M¼À¼gM÷Œ–jËl PvË/ÞÔ¹Õß6ê¾Ô'|„ÁÌê›;z+ :¬O¿ì0IÎGpEá@€õ59³# ž.Pâ ¸4üå`¦÷Ua+=Ït((‚y’‚:;e:nk•m4gý@&Ç<éÏüX¨k¨kÍÑËŒeS¾a^ú]([ ¯…Që†_‹ªú›Ñ_cýÎ N ¨ˆ6¯¸æ»` A:Í-tÍó£ÖtC¹§«Hã󯠾ɰDç “×RpBëÈw!Çù¨£rH?À½!Çyª$liÐ× ¹4,õzÔ¡Ùj˜< (gbKØd×o({‡@¥÷ƒL·H ?',!£gVTWWW‰DæñÝ–v"Ȩ4å^¿X`šµ_o†Ö¬e£u³>Ýäȯ±·$-Ö¤¯.³5Ytm÷‚¢ˆÇ+PL…3VRío’S¶N Å#%Áàê ¸æb0Ó^Š'®KðúŠÀÎתÁv›÷˜.°&ÕÖ]AøFí‘LÀcÄ÷Öóø‹Àƒ×AQÓ ¸™ñ0뛪5%OÁàq æ†)0\¦ ¨ Ô¢ˆ z ÈÈ3·38M–³†[æqHß]ç¿ZÉÓúßLißÙ>û‚]¢­›ÖÍË@–ÅZã~ÐXóTý=@ qNî{d9ܬ7¬1'XJÖ’Ì?Ý Ð·Yd!Çé ³¥ºo¸§$\›¢ãçkM`ÜÍAÈ·¬+ ï°l':ƒ€VÌ¡µÝš5kœ°Ö¬À— øÞÚl-õ– àS°^tWîš-v0˜‰~JÎvªëlM=öÍ ;£ÌLþ3"‘-™7Ÿƒ™üš›7ÊVö³Û§â )¾. [ƒIÓdÈ6$8~o”³<Ôn¨³Å'Êa¾JNr%˜á«U`’ÎlW@€Â‰ ãaöí… ›ã%_iÎí'@¨˜Ñ œÈÕ3ü4Ã’Èdm˜"¡^›–Úe¶U­X÷¿»ÖôåQ{jͳeQóhØyÇì·È=Oþ Šcî«ñ˜®@»@Ÿó7©±d¬½Ñ‚u)Oëã–ºY16µm‚‚»‚b´cŒK°rœN ‹æ2” €€Õ½ ˆ½ÞÝêyW|4lG͇úy:تܚ5k2«9a­#˜¡5Ûné³z9h#Ld8rœœ·ß}·ç+¯¾ÉÉÉ~Þ¹çvÙsäÈõ©¬·U6t^ÈqÎU|‡áƒBŽs)È8hháuød 0;ŽV{ß~9âM»Ô.¸IÅøG—‚*ü¥ óçFß‚_U ÐÌç¥{íZàA {ƒÙÄýA†Í…rÜsôÞA&ÎA`öº›jW,o…sN•õÁ±°BÆma›åzÓ±);¨³žÍJààWà½æŒÏnÔzkÎVè}…鼈’`°:ä8o€Þ`W§œrœLKb}­Â!ÚïÚ=8!ÖÛñ z€º6Wø¥%û§ÌæHPHu­¥ßé³>m¤}´3,šS~P€Ø€«´wZ³fÍ‚Ö:`àì˲M.Ó,fYr ~Ÿ-ú¨ýö»óƒ?ìTܩӨ;í4^ªØ/P‘ ºµZ㽬ãÞ%gî?n9ÎÓ%Á` ʄm!‡ü,¬§ y i=¨«Ð¨èŸŽ½ H“>LAû½ 5wEªC\ àóã”5PÁÁD9º77ƒeAPüï`½½+–ƒu×¹ •»Z—uQ€øÈPê –{œ¦ïÊýËz^‹f¼¶A¬n‡sok¡ò²W/“mg¸, /Ã` ¥ôžKO0Ãý'}ÿ(~ùšÖÚ¨¹šŸî Ñú¼4ä8×€ú-·¥*{x"ä8÷X™ÀšKQŽÙ?¶ç- «A€¶l~¼%à²Öí Xz¦¾¯ÁÔøª™ã›=5›Þ£Áäƒé¸ó¥ÖgkÖ¬YpÂZ2#(–Šº_kMÛtÝãíA%ùl°Uᆆ+ÀcëÖ¯/®®©Ù¬  àdP— NAëw!Çy¬«^\ &Ê9^rœ œº›äÌrœ?˜­lU_³{kAÝ„xiNÄdN¨fø4õ›â™Wø.•8ÄÊ(3²]A¬¹ù/K*àTA• #a2Xc›À€sÀÌ/@š{.Ú^´Ìdm…,·—Ã_+ࢠ̯EûaIIJþzŽó¹Žãl£`¹Pp¥¾!ÓÝCÓ‘Æ´ö4_#ŒÔyÛzÀÛtþ0‚˜ôÕˆ`æFÃç§f¬6¶Gy[ÖëœWèÙÏMS+QXžK™¼÷„|Ç@–Äõ`7›Õ`דú¾¹óªn-p³¾Öø2ä8Çjýº,[8À™!Ç™’ÀýüI_¥p½ ˆ´¦¶HÈq6Xp,ÈÒº,ã¨OòxFwê´î¶Ž~,™çiâ“l h]Ê5¾…î‘5kÖ,8a­ƒ™i/h[‰¦ßfÊyÞEq»w*J‚ÁZ¯ù|¾s#‘È^Ï¿ðÂɼà‚X'ýPá(9v•æ„ç}PPq&€É%Á`UÈqžE)ï““·#€ËCŽó^Sõ¿!Çé¡ úO ÖÊ wƒÔþŸLYG®ç؆‰q§‚øJ$¦RÃÃÊø˜á\§@âéfοAçÛ\Àãp X×\'§q¼žëƒ:Î`vØ<¿®Ú3WeÐÚV —-ò‘€œê,YOLÖ=QÚÿHPŒ± u?ž9êKâùD9~$‰Ï‡çzjÁÎ-sÓtïóáv¼™õùè뉚£µ <ÿ²Žâ˜{>¸­IsÛ`]¯9ÎS`ÛÜ+´ ÛœÆksõ܆êšZZz—' dHÈqÞ5-V¦ ¨€=HûÂnZëί†$ŽÕMûÔ… ë&QÔøXçÞã™iýà–fƒmj,:VGÇšµ”l¶Ö¬µ7Ëð!( · Hw¶–ë Ö·/…ù6fѵ= ·sÂÿäå(` Ö‘"·“ÞùÞk¯g¨J¨9N9­—Êq»ÀÝÑ”X‰7“¹Ì®> Ö 'êä¾öœßÀTeõË6¶YcLJ1["d¦Ü*påKP_aj3ŸÓðë¯g1¾ ç÷cå@Ÿ ž׳ê¡ë‹M¶£Á2‰Á¬ë$ß²4•¶¯Ö¸gHE²dÎí¤gøþÕÆ9~ 5» Ø0L†Ýù ˆ6I\D,0ÃÛÒÓ´õô¶÷lÐ|¯Å¦, ÃШñ¼Ï¼¢™MÞóÉѫԎIW—ˆ~ ÖÊ Íÿš7{h¬uÖï>Ó<¤kmÎ:ƒ ßæº_—efmÆ´Ó:Þ,ÏKج€þk­»u-<urœÆâ*k ÿ¶%Œ¼Ÿå—?ô,(Æü*€ËK‚Á•I«‡‰³ÀÒ:POâŸXçÞcÊ÷‚  qoÍÕ)´í3é1ìp3Hs»,»³fÍZ ³Ì kÙnƉ´Ì‰ôÛ?[ËÙË&pbŽœó-Í/D{] à‹ã|–_ôE OÕÎÿ àb°wû+!Çy,͈ۑ- ׇç6Þÿkƒ· 9Îe%Áàj#AÃÞrúÇ‚l‰ù- íÚd6»ƒLƒÍPÜ] ®NÕ –Ã<@÷ñx7x¤$\×Ì¿÷Ð9m!ÇxVÀÄ~`éCž‚£7l%G½7XÒñ\ '¸¯îÇ2}mÈ  HçS‘EÀ@po±@Š^`˽xæK²Gó¦­l€„÷á2qºkŽtKžF+øŒ'h6L¨Ár‘oAf€ JÛÌ´Ž'ÓÅkö¸-´F¶´›E‚ü'ApöP°ìì$SBŽóžÇú Tþ{×ÞV•|ä";.qz'!Hè„@è½-u!0+z‡¥eC[zg¥úÑ;,ЗÐK)„Þ;îMúýqÎÝ÷¢Ÿ‹$KŽœÜù>}r}ºï¾{çΜ93c@æG´¯îpC"5$GèLªÛ.? q®ŽCí ËÜWj­m&å0ÅñSýü[­Á޶–¡{ä±I§YcÅŠ'¬lØàDØc YIÔÉ1`(Ö¯v¢¿ë}ãf ܰŒô9æ„çi9³û‚QöíÀÊõã|r¬°2–¨Rq0ØrœÀ’'ÁÈR7U›?ì“nÚÛ] ²’a,û<çD9€‚Ñ«oÍInÆ`€Ã[4o?tëïcWzÊ Þ_Fë‰`Ä·)iG7ù`G”ôÿÈ6yÌ¿n*JßOïËt­†4rô^µžé“ °pë‰ bÉz¾¤³ì¨5þ¥ÎÐ,;ißÔƒl‰wc|ö0ÑWzï<=W ã *@vZ‘ê6í?å>SÁå.` Í™zO€ ÷]!Çy3À¶)=› `,€;õLÿ ‚¿mae|²~°(ÆsÁ/=˜Þ°¹~>ì¤ò:›B¿Ç 9Rï @V¢)ø›Îºo$È*ÉÐó=nËk+V¬4!6’leCäîˆÔåèZ¡œ`ØSþæõè¾Fʨ~ìî3AtÝ à87™rrß–c<µ8¬ñz½Á¨×~2ÊrÁ(óõÞNbûÎûu¯€Å>r_2 ðyØ7ËP­ÕçÞ[ –Äp‰`:Ãh0ÝædµMuÛÝ,ºƒÕè»<#'à0ÂÕ\ÁËÇÁHæÑˆ‚,ŒÚ8o;Ãø4 í4å¿éùß²žØ%ÛÈí`”žÉL½—ƒöV뵌b—Êa¬Â:Ï+Lj T2Å*}žç“ ÒÊsÁènžÖK!˜Î•¯¿‰.– Ï瘢›&Å£n‡ù] Ü4jפ‘Dô7 M¼Lš‰¹oêI[çÿeìÛOŸ¡ô—Œì_£¹nMrô¿ÿÐuÿ vô)ÓÏ®¯7£ÌóhLQá϶HÈÖl˜—ŠÑù±-ØÎøÍéTí÷â87r@ßUZsxUu•ÚK êd­§nZóÿáÿ‚Œˆ¦ög¡²¿ ‹"í•ÉÒÍï‚LÆtcSÜ·õ»`ábX±bÅ‚V6hyOîŽp#àVR#[‚Ѷ¯ÀAýzr_¦ÆÂTìqt2´;iŽNë9ôÔý"£ÿ}«ZcS(Ï÷^0…äiýË“lÀßFísË“mtç ¬ù'€Þ`nñ%¾‹!úæ:OQ·ÿXXÑÌ9·•®>`Ô÷n=‹Ç@6ÊGz&«[øÌ·@Jú`=ŽYöŽq-d @Ù_z¨Ðãx®;¨|¦}ïž9^Æùº¯Ž,~9z/Qö:¸ÌJ£bŠ*ú°v7‹°ÇaoÃïuþëàvêhô¬SDÕ€9pkT˜:>ÄÞõ)Þ–¶füޚѯp Ñà_Ì}š{­`³Æó¾ÆÞ˜ÿiô¬Ï€—Lí‘îÒwÛ„™-0áÃ×hO° í_A öB9gfo_¶-ðZ3:b¨Æò)€’Yt7Iò†tð(¤¸%¤X[ è9Pkñ#íûY-ª[t#€SAVÙ©`GŽö¨ßà±?Xps;­§%`­‹g@à1Ö35¬Yr°tŸYŸKõ<žÖ³¨Mƒõ1RgSOíá± ÛÊ+œ°²ËÀ¢q;ÊÀ²’:)󉓱z=º¯_eØDëi(ï·‡ ¶Se`eÉÀzQÖï­tåÈ£¹¥)22o#mGÔÝdÙ`ûË[AÆB%È–¸?F¶„Œœ=&#Õ‘ÓTÚ0ñ"X(óv½2õ™Ç‚7—Õ’Aü¡®uÈxùEÀM,Fõ_A¶E¦ÇI6Žv¡Þkäè|甞à;vp`b=Ï. ³å%9Í `M›L¸. ÁZ#]äü˜¯‹Àº¦g®œSÓ€ ÑÀ@8 Ô¨#üÆÁ_õnœ|„£¿ØDžß™1š6¤^@ÄËàx®ã}eyþÖËàð8Í(Ñ Šé¢á8S-àìa£¥h=•òÃ×ð#rþ†µ£ÚãÀš2'é97¥+¶(ØlU}#€÷be ´ƒ< 2öÁ딋ºzì2'¶ÓZ¼À“MÍ‹˜v÷ƒ ì µ0¹Ú•æ€5#NÐÒ[ –a:¼²žÚrvå‚àôip™µzOJg¯ÀºaSÀB¯ûèûoÀÀF¬X±bÁ +¼¼)ãaš/”g%9’Òã÷Ñëûõä¾rÁz]$$­¤Ãe4F,+ÁháÃúÜÊu@k¾^ï$©š¾çƒ,‡<—ø%F€%LºUNÙ ãºgwk°®D?0Š{+ÜŽ''ʈ`Q †ö'`¡À£ä¨}£çÕZ9 #y[Ýë'r(¦¥üGNu£¸äÅZÓã°µëYè¸àýrž&ÈI¿VàD8c¥m h"QÎ_T;îîr—öZsÀ†aü\, ª%ý‘ ¦E] j@ÖÂí`ÆuUâ^ù–’Ô·ÏŒ­4[ƒ­GOÙ#å”’ tQq0¸2…먟tXP:Ít¥xRNú2´OÐ<ì?´z ç ˜Ý¬›]¥Ã6–Þßž­X±ãabÅÊú.õp£LVR/_ÊØl}Y·ÜS˜r‘ F¹“N( ¸0ä8÷‘Ç]ÀÖr£eX]à­ã<`Z;23F\ Æóp…±æñ°]ç‚?X±ý>ÍÅï`´õ;4M×õƒ‘»Ç Ü¢ùóëëSAÕXÄ^ÄÎÔ%0ºÄ²5bqŠ*Ajûþ2ÔÐÜfË ß LE(ÓLŠB¬R qtÄnYz·hnÏ–#Õ+í!Íí¿ÆVöc&Ö.. ˜^¥çx‘œ³–"Õ¦ðaa º±ìbñ=XËè*§ƒTþ{BŽãÆ@;‹VsÖÅÃÓ™ñsÈq޾ÛG:æM°hi¾À¢›âãÝ¿› 9Zz«I'HïŪ'“%•`êÈ#Ëñ`ýšK4/SÚa §Áíì5¬¯aÅŠ NX±²8aŒ*+©—¹ 5x„Œ•¥ëÉ}-Ôêžbƒ3,GõÝã| `HU=JïǃíH«Å—§(rhñ쉞`T¿¤˜ÿF>¿Ž£Íi–;Á¼ó÷ÁÂz š1x3e$ߣq_!#Õ²6N Y‹ø:÷˜Ô€:É'#8–y¯0¬y±7ÈâòyœÀZ½úëzâ«;aÀ‰Ê¶ŸLQ×£´Þ/ÙI™18ÈVâ*˜Ô–€œjSïÂÔð(².h:ÄÔÎX¦+M)ìׂuANS—Z{~•žõ«n¬ 9Îs`!ÈóôY789ä8·‚ÝŠÚ3§¿\óZ°.lq0¸4ä8AûÌ«r…ôT jtÀz" é$ü_ °>í_ Û¤vü,´¼µÖl9È>ÜT€É©ú>U€É¦`ª Ì<¦ë!Y±bÅ‚V6`©•3°SÑ.Ræã£*ë 8±D†è Å?Vç´-Fg€i!Ç/Ãïä;ÌŠYÎ 9Î÷)(j<A¼À„_Fài P5ÀËÅÁ`yœÎëUºNX ï>4_P,Ìc¿B Âù`½‰l¹q¶‰ã4oñ¾}vŽôI9b/´6K Ä0-aX+ÀzUg˜'+&_ã¨î`¶Ç=`*ŠVn£½Up[†–ƒ(MëЕr€WÃ-TY¥ÿ¯ï €†©…‘‰µ‹Wfx~f^YpëH˜šÞÚ¦¾DŽÖAžLÈÓÏLÑá²¢>×+¦Þ†·î†ù¾»ôÑg éG1ñkŒûÂ0'º`í®+­éÄ0€e!ǹLí¸ ¬ýò€ŸBŽs €Ï’ØR¹%1|»¬ëEU ® 9ÎiÒ‘ÝÁ.Hß$¹.G˜šö»iÍþÖFzCú¬±÷RQwÜ£µ ^kN”K¿ŒSLŽÓzMö™™ ²4rtíÑ`ád+V¬XpŠ•µ¤.-ÛJê% FÎŽ»1|Žö¥u¦JæÉ» Ì‘¤¯ÎBŠóXAà‰ã¼ €ä,0zµRSxÔD¾aND@zþŸ`m†eq€'~°›Çý2„ÿ£ê_ ù:]À|â± v†œ¦0²zš€‰1H¬åŸ‰™’Gn IDATWëš~9WñÌG)RS4/Wׯé@{im/8Ö}€Q{ã0{»NDϧ)^Y¥¹-ëy”ê95Àí¢á}™v¢æeº§˜—i×éífáuÎM¡LowŽL¸ë XP¤W¡^ôÊÁÚ7¼=3¢€ ãŒEÉljn$D·Y­‘ön’•š?3‡¥ú›jý}­æËÜlÏ»€GÆÃÞ ÃíìÑUÏ/‡Nl0#ä8g€5®/øoÈqn0)–V"²Jcî‘›ª8\rœø’œö.ï%~ „ø€ÚdH'°ÖÆ)ÑOÏaÈ<{Q€YgM£3|œ€ŠCRpn?²ò|jþ°æ +œ°b¥)©BèéV’Ÿtðï*Ã{}¨;ñ˜G½ؾl3Ö:Às`„f RLgUDð‹ã|-Ç'U<ê'4žYˆŸ¡àp0£;ØÉâ0¥&Ò 1ŒÜó‰O ßæl“áÖ˜˜‘à\ç±J†1d§ƒ<ÎzG?H=ÏÕs»ÂãŒçÞ0òõ*k^=åöÔ÷Ýà2Rü-8î@l…À½ DsQ}oI_3ïÞ¿‹xÀ’8b–è.!æwµp Îóó½ªõª„Ûq£Úó2[çtê<ŸÑ–n$WË<L¹ŠG jwx|V×úqDßå„rœ1:o®Ôû[> 9ÎM¦¤¨³ÇrÍYoÄÁþHñùÌó',Ö{‘Î=?ȸL)lÏš,Áš#cje ÔzUgó ØÖPR­¿9©©ÒdÇùµ>G|¶+V,8aeQ̱SÑn²Œl*碤ß‹_Ægì8ÑGŽé½` r¦¯£õO€òòT«ÅÁ`ñL•Ç¥½G…r,ÎÒg_ àA4Í‹LÞ§gò–Œè%rV£jSL´%ŠeÚ.V‚­òF†gŽÇáí2dU‚ÝT¢¥1îIoêƒa]¶B–¨ð{þǰLJ„rà¦8˜š þ(°Á\Ë€(™X»>Fƒ¨Ôþ7€Á}_åù›ZÑåP…=ßGwÒˆ }£Ô-É÷z^ÛiþâI¥ø ìrq&Ⱦ¸Jû÷{ì²ÅÂ1êÃZCŽ3Izá20:¾€CŽsX„7™:¹LÏ®—ÖÅúÐaƃ ´Zÿ?뜛ˆöf35·û€iÛkW‚©£!gyŒs?L{ýG$?ˆpÜBƳÁÔ+V¬X±b¥I¹JFÓv*ÚM2ÀÜÎR[vÐ{È£3·ƒ¾ªáF-ÇÁònvŸø Œ$•ƒlŠ«e uÔt¢#µo®lcxS°¸^ÈzØ-w× È‘1ô«d´,,ù¡ž×'`ÚK[e }Îk2:«Àhq:ì³OAJþÀ²®Šå ß ÛA©£K>ÈFúL[ID²l"0á'È©’Îu¤ ãårœÂãœrœé!Ç©9μã\rœ¢$ÞÿFÒAŸ¢c33}pY€éU øýÊç·ãX:8©LMž2 ãu®&2ß7ëZMò˜O…ŒhÔ­X±Ò£ÐŠ•õ]Lä5ÏNE»I#ØÎ+ nK­Ž"Ù`M‡ÇÁTŽóáæ6€‘ú{õuµîóŸ2ìŽéͦSÅåÐ FU|ì"ÅàJ{,ðù!MýÍS»‹4ÿ7hoŸ à6=‹-AÅn`šÍX99ɧ§ŒI‡Ö kDÇI*£áû‚5ilº]Ç•˜æT…Ä#Ñu`=˜ÛÀýÁµr"ß”¾À`Ähƒknì ‚ÇYzÿ ä8û†'z­J¯îè˜L䘢8L­ù@ú4 v9ÚL³û©OáÈSô®Y¯‚…N×0ÙWëãv0M/^}—­s¡É/RÙßÞT€éˆV¬X±bÅJ³r–¤SìT´«Ëp»´j{ƒŒÕr|§‚Ì´†Bh½mœd. ¬™Wéw!b|°æàÆ]?Os[²®anêYTí6·†Kµ?lc[ ÓìœÄ±n©çøXÇ¢R Êº–N2´"Å-n“üÜ#e®ƒM1í¨bE!¹ S†ÖóarR—kÏ/ëRì ·öK«rœŒãlrœçBŽSrœÒãÜrœ¶vðÊ0 dtë ÏÌÔn0-_Kt¶­AâãÁTŠö ^vèð‚ÆP vxzdOtNÂXü`'• û"™ªKàÞ¬Sœ¬X±bÅŠ•å$xçÙ©hWÙMNùÃHo–VX ï#¸¹á“À×MÁ®Õ`4$Ð/g{wÏ€]$ªôþ$Xý<ÛÛî/'üæ$_×4oi>þ£sÙ­ü϶`ýˆjÒÇóü.†Ûfr’__Æ€/‚Q¼ °è^:8úÓåué@º!ÖùSç@XéˆrŽö£)jš Éã˜z߀Qþn±~vÈq!Ç98ä8߆ç“ã´ÀÌë ¥{Z•I•8ÀK`]ÓåæéÏ¡h?“dŽÀŸ ¦ë DrËA:w«ÁÎOÉ´G&Á­ó,’ Š[±bÅŠ•õTÆê ¾ÄNE»Êf2~ÞFzÖ]8xßJ|2 À¢`˜xŒ&µÅˆÝXFüoÃð}‡Ê I·”}äÜ‘Äkfé~gk>ó‡[23ÀÂv ôŒî‚K¡í =`úÆ‘HMÞËœxLãØ! žQærN4Š} ¥ÀÑV]vHyM{aÇvpf‡I/;!¬–™%½ºQ¬NgÈq BŽÓ5ä8¾$¬aGs02 ŸO°_ Ö©Ðk::oœ¾vÏæ`z9Ê|,Ý –Äÿ“¢Î7kƒ”€R“õ;)&ÝËV%X±Òv±TJ+‚Ô{F+í'kÀ¼áH/æD¦ Éñ =Øàk_ÉÈè à)2Ÿ€)AËÚ¸ç‚ýÕ'€tÕsŒ#ð¿ëó^)­éP?Ù5'ºË‰8E÷w»€†–º^dƒã¯Ó÷W€ùèõ }öa°šü¯`Õÿiˆ£ ageXã!]Zwš”–z¤O‡X%FmÏ•sûZ¼‡´”ãDwÉÁØ\¸­Y;ëUœ4)Bo«P,R¦õW d«Rp;ÀÃ5:K> öS6kþœ ‚‡¤k›ÕÅÁ`y×ðlÍÁ@°ÓȺŸžó(éÎ}ôŒM à sM;í7ÃÚØMãÙY€H XðòQéïš$ïŸÖõápøä'ŸzêýO?ÿü/ZGê¬h‹ôëR Õ÷K´6­X±bÁ +VÚÝɲ›ÔèU ]S»ŽÇ“vÖ¦qdË(º n€mCŸhð‘ áICXü³^—¡v–@[À”„·eôL^ÇsföM[ëcdè>ïðH#žØŠƒŸ/0â|Öç‚E.3ä¬Ü&£÷9°vŲÎ…iAY ä4ùÅëZŒZ"P&ÕÀJ_}mÚÖZ`…{‚©IXÈÐ÷¹rÖ;ÉñÊ÷ õ³½Ìßæ ˜0­S½mR}Qºi:XŒ¶4ÆáÞ¥½}ºœµ’èdúåøÝ‚Èå`]š ß"à½<‹ÁÔÍ¿© ÷ 0Iµ>Kï›§Á~ê!°æ4ǦNý LI[„öU kã8°Pô@=‹™ Ûä 9ô IÞ?~?¬†øýþÚâN¸ñ³/¾˜‰DþàiÁ·¸ å€5W õxŽÕ^V¬XpŠ•X¥A‡ô6rŽætu¥K­ÔjžóeW®C=·¥ÿƒ4–é2zßÃÚ=ÛûÈpÙU¿;©‰B`ÈD0çv0€ €ce\£˜,V¬ƒõÑ«-¬—®`ñ92VŸ•ƒ±¨g´—Ÿ#Á(è) »%W@ĹrÈ/'5)ž‹l9r5úÚ2'Ú.½´6Êj[1n‡é^·•!{ª€^šŸ¿È: LÃig GŽa•À‰0Òƒ9aœ%Gá °‹Ê|0Ý%_k¬VΦi[Y·(¤÷U¡ßW{@‰:ÏÚh0 Fq0ؘD±Pgì´=}Ï'§ò°h%X/ÁtwiNÂÒ1wƒàò `Ô܀ς|æ¥`Ÿ,Óœo¢ýØ^àD6Ø­è0M0,ÌùÕŸÖN:ÊãÝìô±—Îü·Ï‚,‰”°6BŽ“Ö~8SŸ¯yxTs1#*MéøÚJcw=Àvâcõ}Èh´ªËŠ NX±«ü F£v ©GɈ[ F©'‚¹˜¿Ëqm°S×&i#&› ùÝZ3–L+ÏeLÌ”£üºŒÜè¨MW0Ê´'X¤òL^£9.%Ú7ŸÛ7eÈß„so¢†‚ŸF“ŠdÔõéí}AZnWý®Vh_0xØšôI0Ý$ÕlŠ,=×'áV°È¡ŒÜMc°‰®×èq–Ì«¤"¿ k¼,`iXmýi°VÈ$9¢ý¢ífýÖj^ÂibŒšuU×õƒé¶2%z.U3a½LZƒ/êåÚs¾fÖ£÷ï£S"MüÌõÞFžŸ0¹8LõšûUN<{"ÅÁ`:P>=ŸH¬ûQQnƒõžgȹ¼Wû}2€¿ƒŒ©X÷Z£€’{Àt¯Aó9¤OxPŽr²æ²TgE_©sAà÷bá—²G“Î\ںɧ3lk9éÃ-½¬ô¼’ªdŸSª'aRXNƒ~¸µ›^°¸™ýÒYkmU‚ã:d7úJ+fÅŠ NX±³Ô…Š>—ƒÚY‡êé`Äa#0j~ e*ÿ¯Ajä,‰¯¥Ç#a9ÐÙhŸNÆ`9KàBý¬ lUùg3ÆHLñ8H†]¹¾Ïágr¼sõÊÁÚ9Üþ(ÇÇN ê÷þ(gËüm£Ö_-Ü^ïezÍ£C;È0]vºÉ™)OÁÚ4Db¥ygkoÙ>ÝÏn2¢ õÜÜ«˜Ë}Wósé¬#\ÏM¼É««<º$3G,ÅbÖQGŒÚ-Ôn¦9mˆZKãA@¹)С=æ>âùì9 SRýÙ?ê;Ðs €Ñê´’ tÚ¤ÓrœÕÎ×¾¾Hká!°@q¢Ìµ0jÞ FîOÖyÿw°6ÅS`d}açjxÖ:(IÑÙ–2?/°½~6L2LÀTƒW&uâH0qS=¯•ÒÍσl·Õ©‹ÖÏ& ³ð8yU-ÛîAIWÞ€èƒR™`¡ëxǘ¡3΢5÷V¬X±à„+ ð9!.’Q\Šz ,¾µ‡œ¡‘rªÆÔÒE õøW0¢3Or%\ꬕÿ/‹t÷Lñç‚ù¶ã@zñ 9ÉÇ ¤h)çvXp­Ìo>Êã€D<Îtƒç½^FÑÏóoô8ßÞè«7¼Nk¦L†÷JÑKô})iªñ\Ó\7¬™#U'‚Ö¹ möeiÉŠÜõÐ{k@€øn#Y2T“1—'ÃÚô À-ög˜(]>L”»Ló¸“öf?¢ûO´LïN•dë½n”ØJÛä­÷ãµþô<ÛdÜTóÝàÙ¿Ñ VkCØã°F¾¨ï#QïL¬ð{š2Ö¥øÁ®9ƒAÀ´¼§Ò/={¹trÈ€2ó<Lû*ÕsÉa5jmÝ ²&NYW—ÊÁu¤WÚR4‚Àê®rÜg%y~‹ÀT¶óAfY£æîn0xRÑϸ‹ì¡ÓÂäës¿Ô~¡s"% iÈq²ÁôÀóà¶ú^²E0³8ŒåÜ(}³dHÆ+û‚ì[ŸÎÙ×ÑþéªV¬XpŠ•õÄ€*p„ø¡:XÞp§Œä°ðàCr¦ú9ï»ÉøÚDìAU/'²TæR½–è{Sl¬n.p¥Œî:l8õ-ÂÍ#N…ÀhÒÕ2^ªdlÞ­çp¨‡–tÝP0âu˜. `…jXàÍãnlÂajÎñ‰v®â]U`TêGY°‡ŠQ2¶Ï—‘ü €·äà·e ‚›SÞÒü%`¢ÉûÈ:ªÚƒ^¦Htnú- Û¥PûÑF¨‘!z+Èzª^Çg¥)®I“=Ü‘A’E`!Ãëô>DÎG"Ÿsõ²’¾²Ø#GgieŽeW!HýŸ%}ý¾§öÅb­åBÁšP ’R„¥Çnkœœ²).ÑØž”®Y’ྞ"½0d´µU|:·Æ€iËvøLYù¾taL=ûjnf×Áú()Kc 9N'oÉËw€éK⨟’«s¦›ÖÁ’8‡S$`£Hßÿ éV¬X±à„+qð½Á¨Ìé j^#Pâ_`¥ñhÃÇä¯#¿/èî  ?¹¡÷þ`Äw °x¡—ªï­žÖnÀŒÅ`näT9“sÁ(@Ýzø LEëdƒ™šó«Á<å0H¯¼,ÙRPká¦g´d¸fÈx™ÔæÔäU¿ 2&úƒl Säën°¸æë`Tkj¤Œ††e€6õûþ2òŽÔ¾ºLÅ(ifŽ[’J÷ùz¶ÅpSk. dÖ¦‰NI7‰¤é¸bqŸ£õŠœ çAöŒ•Ž![ƒÀî+ (–Sé£íG©›€l±[À"¿+¢¨÷¹Úÿe a/é„Òë‚DÚÚå¡Q Åõ`Äý4M1N:ç!ÝÇò8?Çœ9[£m;|²)Ž(±‘æáE°ã¤–¥™fþ¢1Œ °J ÔS` *¤ 9N@ë`¼À‰ c÷Œ‡Õq²˜2@ÿ0雡.€[ ¦Zר¶*ÀŠ NX±‹øDœFEzƒtÓçu¸MEìÅ.Ã:€ªAfÄp©¾Ù`-‚<Ýd¨™WW½›"‡ÁÈÑÆ`áECù/£ß‚4É_AT?¥@;‚aÝ·/ ÷ã#úÿ«°@&Á µÔ ð4Ȱ˂KËoJJ5Æ.Ic²ŒÄ,½L„Iè¬WÏšë¡uô\Ðìt­ÿŸáÑŒ•Mar‹k°vZ‡Oã8HÀD­×‹eô%ZDÖÔµèFɮԞ;d¬ëâ´õžçb%yzz 9Ñ_knG Nt(™£½‘ ¬ôþ`êÆÉ:‡«Áâ”w€©1M8äûhÌÈÈ8{À€«-Z´O}}ý~`ä~0d1XSà隥H°4LŠ@€ìéÊëÁâõ*b-:¼H÷9Ts‘ˆÓÚìPr‰to.ß²êS¸ ÁZF'i Eº‡ŸÀºF  mªPêHéÿÝ´6¾ÛJZ &ÚŽß®?ï¼S@Ð}=ßr0âÿo°c] çöv*>è yÇsÌCáp¸¶´´t„G:ý·ßFF"‘ƒ@¦ÜñzUê<ÿ,†ø«œçJÄ.7‚̰+A&Å`*ÅrFŸÒ«µî%Ò¯}¥ã':Ì·Ë¥G«¤£ïÙ"©f½t,ôÔÜÍÓ\¼¤Ï¯i‡µ”!;h¼æ"KvÏ­¾l(¸áÚk}N˜0sùòåû:tüÈí·?执žŠÕô,‰®úþ 4·ÝܬX±+ÍJH§<À J¾DF…#Ã"]«Ùû5þž2Lv0Z`…q–kÁˆ÷¯+¾sqK‘þUúËÈø Œ¶'uS.†[ìò~=ßÖÚ= ¦õì£ykJ†éw_É ìî {Á´ õyÀ¦è÷,¸óôu'ÏË0 Øà½&ðÿ‹oÖÉ0¬°nÍR}]¢Ÿ—ÊÁ¯a\©u“«uu"€C™¨á[rfè¼Fý@cÓÁ"` Z—èzaÍÜ»½Æ° dqÌãiR—Êá‘­ƒÛNôNݨ¿ýX{"]À¸Á"Ÿ÷€Ý6kÒ,\Çãê 2cæÈ1L÷Ô°,ó5±BÈjý÷ÈIkO'»¬M3À´¨ö–íñù9`¤|?N?ÀížhkN¥W ‘óï‹ÖŒþ1Ày¦G×eyôYÜE9žWv$ <ûüó›|dzÈ!{;fÌMš‡€ˆ'æÍ›÷òÍ·ÝÖPYY¹…æiw-ùºFµtÎdéñIÒ#eqž‘zçÊi/’¾ ŽÍè$?’ï&=9=ƽ°3Xäw'ó}íéH SÂÞ{)-£õŒËÀOé,,oÝ+0n3°Éá:§i>h (¡µ_Ð<ÕªU#®¿é¦ÜÊÊÊJŸÏ·Kuuõ”8ælÜÑãµ?­X±’"±Ì +XË—1p÷l°–ÃÃr$–#ý™a0Rò§^ïÊhé&€bw½¶Ð!{˜Œ–U`Tãö8C†~%Ò«sˆ)ÚE÷ÏØò6])g°,ZvíjŒa4ÊàìÖÂßÕê9ôkŒäG]ç»%‰îðáe4„=`à =¿p ©.•¼nÍÓR´ÁóBœÆv•ÖÇO ey0·W훳ÌëW¼©5X'£.[À^ÈV/‡ÁˆS­¿ë#ƒ~S½Êi"@Ä<‡FÏ=UÀ6.Ó³ö?O•cI³uÑÚ¨ö8$é ?ÂQ W:ŠIÇº¬Q­¹ë¥§_ÔÏ~\cÛTëÙàãÜVÿOÙÙ¡Hq?éóãø´÷æj&cýgi3‡âÿw™ñÅ ÇšÒkÿ«¥äóù‡rHxê´iUß|ûmviiégžqÆõ]ŠŠJâ˜?Ãöêöö;ïT;fÌé ‹ðléxÁ„| À£¿NžüÏ;î¼Óú[ÉÁÞIúÆœ‘Ò±S|&Àb6ZôeC\ à^½u"˜jö70=åA?á¨}8Á‡´Nd€Á”ËÀtÓ¹äF穳@¶ÛXéÿAóLHo€i3íÂ(±%Xä`éÿ9Ú‡¯ƒem¸¶_gÒ%ƒÔuíÚõÓ>½{Ï:mÚi:ËN‰q®MÇ/è\žjÍo+VRïàY±Ò‘ÄFÒá2TÓ0šþ.ˆ¬G{4KNà`0Ò²»ŒÙžp =Ö˱]  âW¸Å6Kª1| Ðcgøßdc äð>§¿K¦¾0.OÒ¾ë­1L€ò™ôD{Ô’0Ïj¤‰}àv™²N¾,˼~Ž@ޱ:«úƒñLoXÚÄÞ ÖõøLÿiéœÙC×)ƒ*—jY±bÅ‚V¬ ŒZn¦Ã­TÆÏ,9NSàÜK¦c½>€Y 袧 ŒÞôô822Xj5‡³ä€}-m%oÙæ£C{€QµžßeÊx'ã%CŽÖm í´*Î{*#l¤Æ½\Fâ÷ Õö+4]yÜ€³dønè`W†ÖŒ)ÆZ×{ª·öò\‚žnÏ È®Y¥ñõ£ê•Ó³ LzZN{1?Š´gªAZ|eöi&Èd(ë0l ·b¬×è&Çí|0z;[Žþ{Íè>š×ù`VM:<ìãdƒ)&·éÙ¿àââ`pa ÿk¢¹'‚l£r ß–S6-Ý;q$ {Ë9ÿ¬£ïýí 2 žÙqäÈó.8ï¼lõÍÓ”sº…ÖÚáZk5º¨mr Å8Mפ~)öÖþÙH@KD`Ål9õŸÊñ])ÝäÙgËùî*›d™öË`ÚéQrn !¹µ°üp™§ê=Gã|SŽúom8¿ † 9 ”@sóŠtäÌ:·´tí ½r æ|+K«e/<®s¼¢ƃoN@Ô’<ª9õi·°&¥+œ°bÅH.ˆ¶÷×!ÑdäÀíP ·æÂt½¦ÀmmXô£Š·§dËX¸EüW`qºÈ®ØVÎÈ@;¦¥_©œ­O@ÄošÏxœÕ'À(ä^=²ôyãJdéYÝæôÇMñË ~@Nî[`”£ŸîwGýÝ7îSªš'6dæÄº–nrlLÎzºQÜ @f‡d­‘3¿ ?F÷P ‚zj¥:RY¨=´^Ó%KÆ|gíñ~Úï›è5@Žxg.Y`!À{bGžôËxÂ^2–&ÐiÎY05iü`TsIº,“~ dAÌ¡¾‡¬ØdVŒò€­õe:7& ˆ8@@I‘tÄ¿@&GI’ìõ"'§ÊîºËñþÞ#)ÞevS(w–¯‘}õ˜Êµ$‘Ö¼b.m²<” Íñü¦7“ÂÓÔõ¶ùxâÄóŸ…Ž ‡Ã ÔiêEd;Ýlí+V,8aÅJ48ñ€‡íÁhE8jgéïLÍ…a2–7—AÑ.Ó¢nKÇ™rŠ~–qµé׎³-ŽË! {`é¹H†”×iÈ’¡sXˆ2,Çý:nÝ[÷!2{i+ÁhâG ­r:šnÕv Iündk†€„wÛàˆö”ñ¤žå`¥¾™54À%2¤²À×ÿc2‚Á†Í°YW’§õ‘²jJÒl|YZ'#@æÄüfÎÓ|93gÈQ+Y[_hýW \¢ÎC¦ö)(ÚEún€ôܰCJ/¬ Ô–i¯ÌxR"çrw¸ì¹oÀS`T8ºegÉQ!'òcéš__±½¾`t4¡<>Ý97A7i-\ Fõ4ïWȡɒ|=ñߪú›”§2‰€Ì­¹³³³·yâÑG«À©çIdi;"°ovs©b¼ DéšKÑr· ¿Œ„\¸L‹-á¦0l¤k›vœµ:´˜.ç{ñ/Óa•î5-ü2`nóq@šù¿°vÄ×ôF|2å Þ 'ª¶ #©P€Ï!`Ät0ÖfUüF@¿’óS-Ãìb9ýSAæÆ[mpÒü9×ø©õ¿¡uLŽþçt0ºÖUŽÐ ­« `K5R} 9Nä1Qî|Íc®~f"× p[ý5Déî Ï»÷åóèvóûU`kÄt5²:Á­¢¾-HéN·³òM9ñ£¤Z‚lŠbâ9F/IýÑf"ÀyZ›ýà¦]l,G¾›ö¡w­øµ^ÀÈi‰œ¹ßäM—³F7̉ß_G¥öü#z ÷ät7jl=À:gƒu)êäŒß!Ý‘(¨Ð,~›-§$ÝÀ)ã<í+]ÚF—¬¬ÞÒ×x·ƒwÞH¸›(ÞHÏbIŽñI lj§ÄêÄÈi; L1*Sñ³À€erô7—ej?äË2ÀC£Ög•œ·ýïíð‡ôÓ éÇZ­±°g½›v~›ëº µ‡^Si€ £l2\Š|ŒÜö‘ŽøP†üÏh;Ó!_Ÿ—)p"©i=¢¡gxö~&\ð:KïšÖÚÊYÛ^Îl?ýx ˜vð€‰´D\ä*é´Ë¥›ãƒ½AÀúu9©Qóž©uwµß\Ï­Tz#$0­¬…z øë+ áH9ÿ]´~§Ê}WÎp¼:?Ãs&î2 Fk/åIG@ øi s¢J¿€®#á¶ÝÌ™ O ÔLiPÍuWéᣤïújl+5ßÏlÖÒ ¿>ã@/Û`m6ãs‹j⸦)ÈûW0ÕsSÍí×`ªç×ÅÁ`…¾> °|u™` ¬‹ì=“ÞjÅŠ NX±²–ô—«Q€×'2˜~’ÁÒ&æLÈqžÑü?¨ù¨Ò«Z¯:­Ÿ BÓ*Ö|m€óò®!ïÏ¡±î²fî)/KÓ=ž­y F¦áÿ¥µ|8È(ˆu_äË RŒ#…¹ž}ïe>TjÏšŽD3¥ûjýUHßÕëù¶´2üÏ#‰&òü=Èø\Ÿí`ô”‘^ªu¿Ÿöw Hy~DãJVúÅ9;¦nAK7À1ÅÁ`i Ÿç—ãvXËè&Sד– ‰Ê9­3AvIeû¾?©>ÀßÀÔ€–Ð\9íÇ‚ÅGè™/ÒÚ ©u1¬›^¯I#Èfx]`À´D:KD@ÆÕX”†UÑ`¦ßïâ°CýpΜ9§Lz¸ÀÀnÚ¦ èçHQq]ÏœÐæ0ÙW]5¯%ÇK€–'ºÖ5çÁ3Ç à«“}÷¨Ï’xíÇþºfP_Wƒ–ûÀô*£O2AÜ.º×©QÀÐtÙ|Ù0Ÿ!Åé2V¬X±à„•Ž)CÀBO“ä4ʈè&gf7Ct fëÿ `ñ»¿Ÿe<­€›¢ á1h»É‘Ò7Ó¡ÞY¿Ïò8FLôÒ8Æ!©‡ 5ÑÐr9årBÊô^ ·­cØãŒ†åH\¨1e€¹ßW”îF¸E1Ï£RÁ(ë¿eÌ­Fr£ö&Rß]ãY¬1$ ¾øAJû½`g‘îå“L»Qº‘rè uóµæìkQqi!ÇyD†Ù>ÅÁà·©ÞR{rí¿jjŽtʲ֜]µÀÜLçã-jdw<©ë”$ˆ²#zƒì«óu¦ùD¶ßn»ª3f*«ªµ¿^ÈÒÚ>MôL0õ#† ÙWài'í%`Áë×À`Ïʶ¬sͯIÏ9Hzeµöíã¦Ä[§BE3‡ƒŒ´#tN—iÌÌhXê ²Þ*AÐÞ9Jú-Sky_»­­XY7’i§ÀJN:ØË<ÆfµŒí…rR³@…éà1RNÎ&`~ÿ2êu0­dr²×lR4¼Žt#ܨv)íþ.-8[Î@g=ôÞ]ÆRW¸íùòà³3Ñ»¸>o”¼9ð0ÒÄ>6”È¿ƒýâ«õÿ]eü]Òb—€•ôCr‚R‘¯‘á¿Øó³D™l0’s» ‹Ïu/¿#5)4&­ãZÚ]kéH݇É2å·åØü‡Y©g“ÓNûÇ|NMïqÖù¾ ù éÓbréš­@`´¯Œî€þÆ€«=Ädé›`D²Æ2&C ål\(G1 ‚²@¶G¬m€ (R£ýöºGÿ&S2À: »Ê|8Ï(«ú÷ÒÚi„›cÀ`JDo‹†x¢ÁJÝHÛýäiïhÒ 2áFòMJcžÔÎ:'ºhÝ>Rà#qêÍ—Á”—ƒÀˆt¤0ãJ°àå\¡LgR¬Ï Qzø£ã|ªóí#ÁÂÇ«|rœ—4¬hª{„ã_BŽs Xâ/`M–¥÷—x'ä8!“‹ƒÁª‹aâݲöÈÌ̼Úï÷ïXQQ‘;pàÀo~Ÿ3纺º‰š‡Æ¬‰^º§ÃÁ€N¸Å­“ŽødT´… $/dœ/;, L÷¼L%[Ïgx@•½ÁÔŒ‘ZÓ‹5§O˜×Â5 P< k³{¶Sz2¥l*‡+œ°b¥UçÊ/Ç 9ƒ§^†J©ŒÿWuæÊh "÷[Ê©èF8÷ñ8¦šýb9¿ÓáÖ•X)#Ø[3,'¼Nck®žßãtù<û΀9ž±vò€ùú¾@ßg{ŒLïûQeþ& &¬ÿû XE~¨îën0•` :FQϾ`Çc4ǷȰ‹;ÝS­*c¨^sõX¢Hëç0ª²»Œ¤ŸÊ°›"ã²¾p"O¥Úç©¥<Ÿ·‰lp.Ö_Üvœ[‘¶Å`T¾,£L*Æ,¬]„Ò¤bT'„ðŠOŽå‘rö†jí}¢ý2 dÄ •IŸ¾œÂµ“-£dCÅ[;Æ&Î eG0 \àY#M½ÌÞ3û¯^gß$Äþ~¬3t•W×01^ÚŠÿÎ剬5Eõ„gȘÖ¦8. ¼À!Çù(/PíÕ½:–x4ä8ÏißÁT¬S|Ì9΋ìæ%Ò*Sûñ½ûþýïV—–nÛP_ÿÆÂE‹NšþÛoI¼t¾ôYTGì¢Î:ÿW‚àúÛp™€umd‡˜³¶—Ó@·Qçâ`ºÅê8S7²¥×Ž“=Ð_ל*PâÝÑÚ5—J’î1l¿h^¦õ\bUˆ+œ°b¥5Öè±hpPF=ß‚Ë2È£âƒA:çæ`m‰¾pS6Ž…[³JçB91[¯Åúy9Ü<ðhc%Ü„Óë•¶Ë#…`ÊJé¹Ìo­—‘z«ŒÎŽ'Cêj!ÓÀn_#4U|?]†åyI¥0ÝH>s«óe,æò“su¶ ›(Àb6ÖÎ^ªç2¬cp5RÛ ÏФ³¬ z¼¡ç‚ÌœMµ÷·Ò×½à2· ƒjÈ€˜.ãx¦ôB™G´GQDÓzo,˜¯?Pã{"AÛ(áp»¿¤JŠ‚Ìãåü€‹þ]`ÅÓɪät—€ø nKÑýå¸Áês¤£? 9ÎË`úÇÿº~è:˼rœ×@&Õ:Svt¥~9Î+`êáâÙÉÐÍž4ž}5¯[ë~k@pü½fƒéIYJÝ(ÓfÏй×IÏw˜*13Ž6 ~0h´;È|¥ë×K‡À´ÕÅ­ÕÀ9N >²8†ççåå >_~õ•OÏqXçÆÔ•zßV¬XpŠ•Xq µQoІiSúŒ;“>QFùúéÐÛTïýt ÉÐ6)­Õ0yÝÞ‚™õC•ÀŒ5p#\&¥ÄôX7¹Ã›Ê±L ™VÿñÓ¹×ÕóÝ,8xŒæïK°XÚOHŒ-á#FÊPûìX03Éc`š§×kz&ÁœÞÀˆ¡WÝxóÍø|¾‰>ŸïÏ¢¢¢çKJJR16ÔîŠ4_!1)S9º9ÆCAvÔ0‰ÓMcêTÊ 2!&k,ƒ †Ó`~2ªœ!¤»œ¢ `­†9Iº¼i6¾ÞÏúúتøÉ(Âë`ÿ~,Ç}«(p"[àÃrôÇ‚µP ¸7ÕF?òˆ)]–ŒûÀ°FÂOîYQ£å¸î¬1o©¾Ät¯c­¯g†çÜ,pù•±¯ÎëÉ!Çy[s0L'l È45l 8ãLÛÒ½ÁîOÛé:õ`zÙë ‹ê0}%™í°³dw2LèùÿÖ,y,DÚõ À1JàÔžÒÑaÙaÏ€ìψJÃiâ:4®Cõ"›È€4ïÍŸ?¿s$9S¶Ú©T2L­X±bÁ +Vâr>Ú[L{¿p+ÀôˆÏ=¶éæ‘+§Çˇ[7"W?+ÐA\¨W¾~—ëùÿ\ý®‡®ëÇÚu+¢ÛEæéë%`šÀèQH“+ª ×n2ª®i¾ +2œY]ÁÂ[㋃Áåíd ¯£ìS@êig9Çû ¬Ø4‰ü=‰\PRRRÒš?SFþÐ}'3"ßY†^ºU%p‹f`m0Ò¦pl¾öH/°{Î& P8d±ieyöqžÍT=›Ÿõ¾@?¯MS9 dp«uÝYÞÝ“ߘ"ݤ†É’)Çf´îï.9Sí1×aÏæ%µ²À‚ˆÿÔùyȰðê8Óf«n ÖÊp¯ŠY–%«.œôPÖõ»‚l½ã@À9:—~ 9ÎC]Ö˜1è`úÈ`0`  À]õ9ó|-öÆ/`ZŸ)6iR1·Ó[:×2¤×6Ù&Фlü!0âÖùÏUs^ï ¦nì¤Ï.ÁÅÇÁ`BekŸ«àAgÝ÷1º—Þúõ/êll±0gÈq q¤ôã&Z;UÒ'¯ƒš?Ôþ9oÞ5ž5{‡î)w¾·[ÙŠ• ÓÙ³b%^Ù]ÎêcrbÛ²Þýp[Ë­ë½ç‹ŒÑîm]šƒµ»{˜t“Cœ£C<"C)Ò#ÊÛš@ºåu`d»Àý2pV&ú|BŽS҆ϓÁv#€GŠƒÁtÈg7Œ—>`”èx}õóZ°ëÇ'`Nð05¨­Êž£™»ƒ“Ót=øÁBzÇÑÈ.2°´':É6€^'¸…dýpAÄ:0r¹R Ã,½~‡[œ²©+N™LýP`9J»è~çk<Ô¶Ík³€ÌŸdÖDÉ;€\®çõ9y~ÌýŽÀJG“ Ó°‡ò½@d ˜¸¬AqœÀpkâ+ 4úÆë®;Që>Ozàvïƒ)-êrœL°VÂN–óìpòˆÎÚ-Dïýº—M@0ú ÁW¨=]+€f&˜*¶L½\©9z®8¬Õµ²F Ô9±·ÀŸžš×*éµ÷ÀT‡™ÂIž“\\?^çH_=¿Y «áU°ÞFki~@Ûé:ûèZºÿÏÀY?€3[$²5/‡ Ü&›¢B€Æk`ç‘`‘O/Ðú†¨g²d+l‰ä3+­X±bÁ +ë©ì(‡í9°à`"¹¬p‘”oAúöù7u:š‚јúéNÝÏ!qƒŒ·0Ù¸I`BΖ¢:Ð^2‡ IDATܧë.#ÍŸ&«àWŠæ"LiÙÇcȦÃ2ÿ•1õ¾¯O`nÞ£]£ŠƒÁt3¾r‚`Àžš“.¸,!“òT©=¼n:Í\=s“Šaºc4v0g×vßÙT㟦n¼-  ÕÀJ'0Í¥X›ce’®ÛÀͺ·e`5ÿ*9¯‚ÑêFXéhr(X¤p2Xgà ­Ñ3@ª|©œÛIͬÝ~ “i.€=CŽS/‡ø20%. kßà£â`0å眜òm’  d1˜FÓ­œIYl†ƒLŠÀTƒ®ú].hÝ ðcŽÍä€wQ¯}øX¿è+p­I ‘2ÒÓ66ÓWƒ,„§"TµÄ’ˆÐWÐýw—ï± d‹¼ ¦q®j àðÔÕ8P€Ä6z&†!ñ"X3b‘xš, ÝBÿ›©gðÎ`[”׊ NX±“l©ƒø=°HR"ÆkW9z}á¶+4Õ÷WËP^F®çÈáñFZÓ•ò]F êÀóé Nød¤ ÁË—1z•žKÂÀ"2»íè…@Ïðç:È»n‹dË9ß ¤¨î¬ï}`Í‘ŸT|ªµZÃÜøäøm `ûâ`ðÏ4Y  5ù\TËSÞ£^Ë´ßüp Äšâ±µZï|hNrdlŸ)G¨‹öòZ×ߢåVÊÉ–\9 ý-OÂ3(€e-'ƒì Ñ`ZÓ³ øN“5jXl†c˜:ÙoLÛgÓú¹n;è\ý]Ü*pÓ½3L­#³Î<Àš÷Ý€s X»h²ù½·ŽQ$ê=Œµ[`ó‡’!È9¼L§óõî“ó8Vz¾¹g;`¿’î«÷8¤Ûƒl¸½ôL~Ó?N5“BcÈÔøÎ’S\²–&ÈI_Ë9ã+òÀÚ7[€é;€€}‘ÖŒOk¤JzpŠöâw S¢¼5–B‰^ ¸?VzÙ8ÿ“A–Ä–6ø+õ¤³˜}´.6×iÔý| p_Ñ aÀÚ½AÖͺVÈÜxdÎ-kbÜ×wêÜ1]à–‚)I«¬©mÅŠ'¬X‰Uƒ(ýw ý7‘ƒy#0â0lÝ8\‡ï0Ù/„›6¸4ñJx1_ Åbh+Á(‡éÄQ…öm%ØQÀ‰N28¯’ƒ²Œ€…Ðö*å9`ôõ¸±8,ëàk>SFÞ6`ôj_´&—v6%ú@kº¬)Ã_†õ+r0w*×e%rR½‡hý ¦l}(qC‰œšóþr|¶Ös_F¡Ÿó¤ëÖÁز‚ •ž\ØÆûÜUÎÜ@=çó<×2¢@†l½Lm "ÒÝóÞ]àP‘“BdÀ†L¸u€¢ÓòàÑý‘ì._+Ñg†á¸‘¨W4ñ€vÞ‚Ëô¨“ó[)½±JçÛb9Ý‹ÁÔƒ5 ¥5ðxW0µà{l›Éq€¬¨ZÙ×ýu>Ïæê(=#?de‚ÅïÑç–&³¾B Žò hÇk,àö ȤˆÄyMÚÈÓ¾¨¹>QzqX;¢1…÷Ôd6ŒÕ{g¸E5_ÙZsšrþ5þN²¯v°±®™©õ3WÏÿ°XwY+)fL{jL#ávì˜+0â5U <÷3<(P}–±eÅŠ'¬X‰CúÉp™«+‘~à^€ãPt~¡=@”~½6Ö¡ÛMƃ‰‚ù¢Œ@ «Q·Œl/ˆ±L½HE+Çt'²À”œë@@ ˜šs‡æ¦­µz‚”á1Æx-Ö¶eëZdØEb0®L ÌÁ`êÃÁÕ:iý-—SðH“]¨¹Ž(Z·5›˜Šˆ[ŒçLXÕþí­j°ÈܽÚÛ6Kºå08@û÷'9ð# µF’ðÌ>NÙd”%"¹`ªÆµºï‡Àb‡^ðð!'(–Ó‰‡ Ð`êïä{À…nr;ëUä ´Lýž¬¨kú£Àoç$ÃV¨ö¼L÷¤5žwÓÚÔÕpÙ †Í ·¨kŽçeÎ ó{  ÙÁ\øIQ¿x¾öη[”÷½ M¦çåYà9ÓªÀt Ã*ŒNŸZ—Uð$H¹_éÛÙ m¿5Ç/Gì°ÆÔ”ftfŒž_¬¹ hLäH/M5[NÎóÆ ;o¬žÏb7 E8ëîAÿHÕ}xj?줳sOr‡ÞÖ3›íü{:b ë&í'ýÐGÏ¢A6ÐO:LêIu )0ÝŽ/ £‹Æ4OÀÆk ãª-u5rºŽÒ÷σ@¹eMX±bÁ +Vâ’n:ì*åì&â€Úèç RÞš“f ¶,Æ5ŽÞ`jHè=tˆã¸.ÃQ ÑÑd£óéNøÁ¨øå`õòLÒ{ X$­M²§Mè# ³`2 ™ÒÒ8dˆ •ÓöXq08+N#£AVÅöZ‹rŠ€ÔÙüدoß·ÝrK}ª#‹ÍŒµ‹”,‡çmS°á´ôi¯î àtáyrnߣ¯SÒ ¤ydìì,§ ^é#ðð¯rrÇ,žè(ü“rò~‘c6RëÆ¤N˜NFæûhC´-c&íǤMÐÀ´h.•#µ\ÎÉ Bkôªðü¯·~Iƒ@iLîìºGk®ÓJ<÷êkâkïZˈš?Ön‹u¶uÕÙ6Àó2]oò=ˆ/ _"°b‰þg=ƒqžbÜgë>ð–æVµ ¶”^9Hc\®õ嘙jÚä8GuˆxÀÓh¡pf3×»ìTuzq0øl ÆÚMNùÑ€zê׋ˆ¾¨=¸Æ{Ž*Ý£§Î™ƒ¤»è ëùO Z~2.*ŠƒÁúÎÁ<0åð0¤§öÖBéÅWÀzåI:Ûóu¿¦uë+`ªŽ+V,8aÅJ\’'`¡¬VH›Ì­ä°µ¥nES†¤é¸‘©Ã:OF€aa p!ùÚ‰±>b'ê±î búeœ^RyMÄïF´¡5h”A“ ¦Ü%ƒúU°MèÒŽ²˜C޳¹Œ¢~Ž.?nÃåL{¹ÍÀß}|ê÷käX~ FŒfèg)^½dŸ-¾ ¤_ßÒ±ë7Ý•¥û?N¯úùl°|EMC’טONüFÚ'¿ƒñAzù¾`Ô>ž59ì¾3Dúé½7å`l§¹È’“³·~î ÈàMGX)@a™ÞKõó ½Lº]=þTÃfH‡ÎMÞµ²¯öÈ ÍÅ¥hcMžuJ†çL3À|_Ë0 @_—‘bþÿŒ®ãs{iå€uIfǰγ@&ÖÒ7Ýõ¬ÓJ>°<•E‘›aR"„ØkRœ¦6[ >™¤qõ qŒ@…îZïË$¼2JKÍIw˜Ž#û ØJöWDçÇL5¿³ÀTºÇeŠm ²¥6Ñ™±\çÔó`0ª<ÏÍ0EæÏŸàç_~yü~x ÜÎ)·"ù©dV¬X±à„• ÄÀÿRÀv:øãÓñã °ßúr²µz¥Ê@5¹´3uÐ×&ùú¦[G#XWàD¡@ŸKe´.•ú´œ†6ÏoÈq ÁêíçÊX¿À£ 8]ë˜*@e0ȸ.ÆB^±êó€ ЭÁHÔîrˆsàRnÑ^˜ÒõK“Vdè³NÖZè-çð-°0ÞTlL ¡ÛdIì&Ã~æý ¸.ÃI\[æs7—Cq€ªN`4z\œi=—KWžà…ÿ'¤I_ FÛŸ–ñ¿²•ù*‚›6×Oë±Ö*˜Z ^ƒ·®BGo ä0È–¸Éë’’ìõmùl9²E:co×~¿ñƒÑ>ÍÁ5.ˆ”ñ8⇃Àøæß*0µàe0À±¼µˆ~@ŠóÀAÀC`ý˜­t¶£û¾¡8¼%Á1dÉæØñ·ÁÉ0ÈlùDsñ <í:=é›kѽ´çæ ÌxWˆ™§ë€ å©Ÿ ¤¿Õ}`e2ú¼BÙDÇØÿû~è{ïý÷"‘<:åZ·YÛŠ NX±’È:}OÆÏH°›F¼²Ø.*nnœè¹`Dy†á•`qµÇNÔ¹F&~•³lªi ˜âÐÞàDHU¿ÑóùO‚QÓÅÉpùØD×Ü Ì‹=À먆B¢÷±‰€‰!`TíÊ$Í9 wÛƒ¬ž,þ%`ø¯VÌ€Qã³3FíŽ2:÷“Q¸dLÀº+êØÞb*ËÖPØD?ÿCÎÉË`ÊM}×”ÉßLñÙ[ÎI–€¡ÙŒ²ì^ Έãòsèc)Té»Ü%}°_GòÙõIürï—öÀßÁrGòLD|1OOê)'Øiœç~0úh8·CWÈÚúŒøÏ–ƒžT°B Å`ÇIÎàô,š©Irœ]Á:/¯8%Ö€‡å0Xº÷píÃ|­Ÿ… Ãáu°ÀæïuUÃc(X”öH­ÅlÙ?S4} ‚ØUñÒOýÁÚ'FéĤç%#ÇóìG:HŸí/---¹ã®»0oÞ¼þpëXô€ó±UCV¬XpŠ•DäyÍ߬1¯dê÷°© ö>`Ä'n>mXŽT•Œ™Õpó’—êÝä(—ʨØQ·%œ16‹N’ólƒÓ´äôËAYÓNÏÃ/ƒèr91~V׃iI¡Ñ*ã`wëy}à"°MhJØ.Êg`Iq0¸2I× Rh7;S\Q V®ç¹Pè.Ú [Ê!àª)¿ÓXü(#¾$ `ÈèñWÊ“CòŒýp’Ö’$v–ѿȖñK_ý$gä3é¬SÁè àü8½m@ÆÚ@úusÏ2W`ÌUÒ§ŸjÎÁúÁjHå~ÜÀr¢&Ê¡õ£=n"Ð:ºt‡í·¿ç .ø€‹ƒÁêö‰ik¹-X{/'­å2Œý ¬E5ŒÜ×%iŸfÈ?,;ƒì…gA¾w/†§—l…L»ƒs[p CÊHÞT÷U ‚ÍïE$ë?„£ÆÕGÿW¬3 õ“ƒO,Nt.zlvn9Xz¡BúäQ-IbI@ÀÿH,›hWëÙ¾<å”k·’¾6©ƒÁ`ןVY±bÁ +V‘û@ºø!2$Újš¶r… ý|c0‚0D†b/¹X»}œ·S‡·Ç¼4L¡µU`ô8Dñß—’lg-dfäL´G Í"®~œ¢™`{ÖÄ‚~2:.kvŒÊþ;•½íCŽ“ àJ°xéMîi«rœo‚ÕÑŸéõéŠbº€ô–!9¬„?HÏ8Sk¼Œè~ 2?úkMÖú«©¹jo–mN©©%q”æbˆôÃB÷Ï€Œ¬d9:†½À ý¤£LþøÞs³–ƒrœîr ºØ«8œãÇöOÓ%)zoû¥3ï“]vâxJkÆJ󒲿®Ð>»Wó¸!ÏÛ`¥3Àð3O?}Ån»îZ$‡ù>/剀ÒrÈs¥»vÖzÝ^º/Gúj Ä~)ç|˜ŠQ߯½›©{: dRtÓg}àq?ƒ•ÿ þŸšZJWééÃÁúB¤‡*@0ù-]ó5Q]6ü²uFÉŽÚ]:¾ ö<¯ÿ]Ø@¤Rì ¦^î ñ-»t=’Á’ÈÐtÐn¡çX.ø‚žáòâ`pKÍM?éˇÎì+½ö“UGV¬XpŠ•Däj9ª'€QÁT‰? ¼ÈƒÛš®»^=AÚiw …z€´BSIÞÛvôrº›ìˆXžÃÎ`’v0 Œú=*0&©÷&¶Áç2¾.[a¦¬0œ@„ÛÀœåyŽ‰Ã‘kéºE2Bg¸)p%ä8Ý´æþLe1·&Ö¾iѸ‘á]z ÒZƒ ùZ0âô2ÈIš#žÆâמßCkd”æªdG<©õš¬ Û,öwÈøòƒl®‰`…ýŸàÉoÆi8d½àÌÿcï¼Ã£,³6~ÏLz½E”¢`G+öŠ»{ÇŠº~ºö¾v\uÕU_Wì½·E¬`WD‘"Ez‡Ò¿?ÎïÙyM™IfÐ÷\×\ !yËSÎsÎ}îsN’B‘ øÌÑÿŸ¹€$×âl},éBœ¤?:[¦©Ò âPôæù8O•Òñ±¾ç|Y#iÍÙgžyþvC†œ(u³ÐŸ÷Ê@¸&Õ&ÀÙ/ÀaÝ GukÀ‹|Xñ½Œð®¤©ÅÑhYîéRŽFôf¯LÆqIÆbxûákiœðm±;BìÅ/ø›±’~«]‚ßPä0ôºdìœqâ'7†™’ð^ N•1ªdé¦÷*-IÈïêÑ쎶âLZ-KAy†¹úͧß:ÊjlÀœ~,c‹ÄY­¬(fM – $' $U9UÒrÿ\Kž)âûê ×»¾ Æ}€ÁÏÊLîu¾ŒºØ pba†ßùdY”ï=œ‘)ÊP”Ãj YÔ~~&Û„Æ<¯=†Ô:Åm5u8{d‘ë) v¾¼àòd(õ1Ïë-£þ¶—´Kq4º ×x>{ïï¬ï*eø6œâUúc³$ÜÜm†S1œy¯bí?-c“ÌL×þ¦¨]’cdùó98$ŸÊŠL~"iq²ÀÙXY´ußâhôó$þ,›}¾1ŽÀ,Æ£;ýÁ8·ÈÚúl‰†Á­20ws+å4¥1 n“a2`¯=:e[˜{{akKo7…9²¥Ç%ÍJSGǬè"‹ø»º=e@\)óô,@Ò¬Æå8ómeì…Sd g{ÉÙ3izðU²­ÆËXåuœ7mdìŠSyŸ|ôÇûŒÝ%ÔŸhØr`K7Y:Û»€H_4•!Èüw’ÂÇÈÒ0ZË€ð_н/Kš^Ç9ÜC–^– Ø4¶‘ PžÉµÝH 8H )Ë2”ÿfYø@Lrd9Þ©ñLR‘A2 ùYšÊ$­ã¿˜çuÃ8Þçïøâhtf=@ÃÆ¬Å>{d¤#vÞ裚­k‚Ddu$®–´ÿþHÆúNüV 9²hÛA¬ó~8‹duO<©R¥¯èkGµbY´¸ˆëÇz{]Ò¼&Ю’Õ;y_Ò‘IFKŸ@÷î,‹"“1§úà\ŸÃ×€-Q¿¸Èwà„?%c.øI˜1¹Ÿ½u›¬>JºxJ‚“ÚO– s°¤v2†Òk2`ìûtf?ʘJû*^h2Üu˜+ «y× õP€ª^ŠwªY)KÑøRÆø²>@gî%QUœ™ñ#@Î+²:•i›î²6ÑQsj‰Œ¹ðgae®‘¥Ûì cHlÏ|WÊz/Kz^ð)m`ìOc}Õ ?æ:Ù€<;ɘŸ**@p"@R•euí´žkÖ¬¹QÆjº'PY€’ªtœX,c”Cò_ùÆÑ>ÁÍ¡7.ÅQ¹\VüjKYºÍ^h31 þ-Ë«^+ r€‰$:c”\S_ᮘçmÁ¸Ê"ÆG$¦[Ä<¯F÷%2:êxYD뫆 ¬˜ç!£$?)éÒf&BpgK:£þ[ætœþ`6ó¼ ÀÂ;gËhäŽý€,¯{¢,£ª×dˆuem½žáû Æ ˜-iXq4Z_jÆn€5±žP¸aÉ“QƯbÝ/+ ºôO>.¹²t«Øc'ÈŠº½¶‰,ul ûuQŠë:Gñ”¿ÈŠ5VÊZ‚ºNÓ•Ðf3M{*GûX«3àËXùO꫉ó¼ýd,Û‹£ÑËëù½v2¦ÈY²5³tž‘uĨIû¸‚Ãe©}ýe샗d5¿¦¤Â” =÷;â@X— 7™3õ5¾O[ìdôi®¤ª¶mÚÜpÏÝw—1nw–Ô±²²ráigž9½¬¬l+tÜ—Ú $œ$T¥H¹ËÅ^ Éå:öpY´¨9¤Ÿ¬cÀ¯2Zf‰,bÑ_Fý<€9[ £©?‚aØbtfŒ®á€)­$Ý(éÎŒÆ>Ì]1ž¶¯Ë™#2ÓGdŒ¯{$®Ï„2»¡¤3á«CïwÀ€)£éΑå:ÿ[¿o¹.žiù2vÄ®Ì÷æ€Õ8>ßËÒþå}çËŠ®­nÁµé(Æ/JЦ‹Ž]ǽ²cŽDog–¬`Øi&dtÐ÷/еJÍH Ç!;ÇAÊÖ祋aµL– <9‰{ÈŠ¦]¨ñ½Œ‚ûiºs S”°,¢w”,‚Ù‹yñd54æ­£ÎgDé(«¬¿'`Ož,Ò?CV(ï5œ„åü¼5†²p`Z ”‰y^YÅø—^vYlÖìÙ›KR~~¾öÜcò#;l† `}Ûcyq4z¤¬fÆ=²´Ž@ŸÈZ$YÁ²ŽH%†ô@YT$'â²#¯u3Þ³B–†à ~é3Â+eQ©‹e”Ó£”E²§Êh¨Ïc®ÉäƒB+½€`¥ŒûJ†ÝŽ2ªq¹¤c’&$©8]ó¼Çd…ﮕåì¾$éÞ˜çÝ^ÃÈ< IDAT#˜IP¢s0Y‰‘|ÿºJ¸¢tëaôï+«Ñ bNá²HåT‹%ñËzr½–dŒ,<9Uö=–áûMÂù8Ç-VÞÍðù]³’¯ËøºŠŸ•àˆT0ÖUýUü¬‚1¯dÏ—ûþ¯ýá>ÎYp:¥F¿ïò­÷5Ä'ì³o"ü;ìû?÷}Ä÷É’Ev³dÀkŸ>ù| г­ḛ¥¶Š·šüNÑnÍyU»ú?U¼Ûº ôD§o<Ç;"K…»‰=: ý3‘wË(õÈ¢ìÏJúk(º~ñâÅGõÕW¿Ûe—¶2ÔžŒÙRI?Æ<ï]ôëY{Íê:t±cKLŽyÞ}²˜;ò<Ûp~íÁ\,釘ç½'«©ä®²n„ °RÒ«<ëf²š#ûÊê4Ëÿ=@Ò?Å™•0x©¬>LD^^#é³dÁ‚zÎDTïh´÷øùH© fÌóŠbΔ¥ääÉÀî{Ñ-“ÒÜêÕ?ý±+ö“´Q(*r¿Ów£¾:â°ÃΓÕ)KœÇŸÐU›³Žƒtµ@Y‹$`N².ɽ2Úç¾jžÚ ëŠ-+üu¹¬zsI/cb¾¬øÛŠzœÉÖ‚'c¼ÉhôßÊ¢Hoc¥•þL±´ÛdѺß0Ä>M¢D[ži ¬¶Æ]¬Hž sƒŒjúµ,’ömº;1Ô"Y2¦Ñé8¡í0îÇ`€NÕºÑÔf[_EÜUVÙ½;Žc¥¬Ýç26ϧ¬É5 8~aŒmeQÛi-ù’Ô‚x=u@:ùzî÷ެ+Éîu´­íƒ³]x“ƒ1ïœÏPŠvDïkˆ¨©¨ë“HÔõQÂ×Pºªïÿêz~ÿ³W3&y>0§Ê÷;Uü¬ÝVPV hQŠ\Ã÷e>Çÿ÷U Àø©öp&0&¦ÀÄøþß7¹| ×åȘ g8盟'KåÈ–ȼ“±8GÒÍÙÙÙ?òÐCOpÎlËù1XV3&—÷›Ëµ_±1'£§qþ eõ¶—´;zžÇßÊFãÐ+«·¹çú¼÷_xrôÖ<ÛîDœéQ²ÔÈ|þ}£¤wšÚZfÃÆœƒ‡(ÞiäKµwe©.ÕI\Ë¥ (ѵø#×zUÒÂts*­˜§²úV½XK«¦N›öëU×\³UMMM8 …B§WUUýXÇå е§‚š€Ò(¹J?JÖ>3“#e5®TóöëÎÆ"‹FýÄßäÈ"ÞÉ󳕗cd±é*bž·=Ï8ƒìç$ ¯!²”Ž’ö(ŽFg5Ѩê…yNÞ)’ÞÈ@‘͸ºÚ­d5%•EÄfkífJDxæ>8%»ÉR¹:³VªY&á8|€ƒ½¢ïõFú°–6P¡W¿'‹î\þáûeËØKÃ$V¾Uùµ,Òx8g.ŽÿÓÊç¼:Ö|ßûÞ<ß'Çx¸ßó³B ήû™ ¨ò9éþŸUúœüJßÏkp úЧ¾œï×ø>«V&THú§,{, ÞYÆNêÎ÷mŸV>‡?Û÷ΡZ€–dí´P@Pcí¿DÀ¨& ©Ôï™/¾cÜÉÒnR¼NT+Ywš³Ñûç.T²^0ØÇÝ­W§Ö“¥8ì‹^èÀ¯,DxRÆòY–¬~e/´ÎÑ/$½0é§ŸÆ_ããØkå²b¯6pù¨¬õ³€BëPH 8H k™œ/Ë]=UuÓÿŒR,‹TüUFÓoN¹€99_V +Ý“'‹¶†ÓÞƒv©ŒÂú4ÆæüÆ:Ó1Ïk#£þU.HáïÚbTo/‹Ì$kÖhƒ çóYªÇjIûG£ß§”Ø‚9Ù ÷Wæå)»`mËw‘ÕŠG1wµzíÈ;UÉ ÀMÄþ°i9ŽPSŒà›dEAGÈò¡[œñ,7ñ¹.Ó욘çí @1VÒˆZ ÞõÕå˜ ˆ‘.ús¤[¤.vC}¶Ju-δêùYmNxcǹ‡5Gyi³ûSÐ’£ß§ŒäêSJüì†Pp#ß5åûy–üqlŽˆoìüà‚¼ñ33ü©'Žá˜¼)÷þëøÁŸ*ôÜ©è"W“¨+gÔpœû“ œ~"KÅúIÑ.iPh+cQ ˆÙ•÷È“41ÙB޾k;`e}𾺵ã¼FÆÄû@ÆÖú"0$áLØ^VprKÆqcô’’d1Ôqíû÷ñ ˜›d5>Rb6ø@‰“8ǺÊápò'55Ý$an{£—”1 ñ)€ÂG’æG£…R{ó~(¹Âà¯}²¥êf~H 8H uÊ2ŠþHYC &®?üHŒŽæ”!2*èË2ºjc@„0Fþ Ytv_Y€Æþx€‚±2úk³T¾y^Y*Ѿ8g§Éò}«›pÍ"{aIWG£×¥áQsdtçQ8y÷ÿÀp\¶Ù²(^/Œý¡†=q"ÌïBÀˆ±T¿òéÎ ‰cp–,‚Ø¢ó¼ 0¾JÚ¡)Ó$ï×JÆÖè'i×âhô›„_é&+f7]y r³/®¨j NòÊ`Hþ+÷ÉÒéö’Í}eE·8I–*QãÓ O¢oOæûTñ¶èÁ£ė¬×¯eàýÛ²bšÕØ'Yè­¾²´²Ýe)®ÎÓ|ÎÁV­JȆ©÷àÄi’žj(‘'còœ¦xËUФ¯˜ €¦dì‚Ód©/K˜Ÿ$MKSaN×ÂtàÇv26Ë*ÀŸ3Fó@g: {_»¥!iÃ\…p"@Ö. b².I¹Ï $.­0ðZ¢Ö òÌKcZaVsO1Z¯–啊a»‡,*²c⌔¹™*Š£Ñù1Ï;A–.sŠŒ{kÌóîoŒÓó¼n€H{Ér¯_mâ#æbÀ]ˆã˜-‹ŠÝ%«¥°L-[lÏQ¥»³>†â˜ôÁ0ÌâùJdQÈ·eѰ ¾u•iªíl¾®·–ìå™ì©ý0ƒÀ„£—ÏÄ8ß Â/þ¨{ µë®J †£ÖµFß#‹¶‘¥g.LøýMpú'*Å–Ø8Ç‹%½EÊ.èÙYÛ¢cþó«Ø_«/ºé oºt W"±NGâ^N,lé>Õ>@ÆÕåH,Þé®÷OÛGp<#²šHwðŒ‰r:v”Œõ•޵ž/K;EÆVkÇX½†>þ®©…gÑïÐÅ'ÈÒ4\ÁçÏyÿÿ¨Öé_²ŽvH¶3”¯ëÆ¡2¶I?æáÞï-5"5„çÙKÌ÷g­ÁùŸÑT˜Ò0êT@ž\ôÐ;2†ÍW’Jê9#ódƒ½ðe>ä\”¤mq Ø¿Œ5°²–HÀœd]’*ŸñH\\û¬Ò¸w¹,òº†_:Á‰jÅsLÇcL ”UßgiwYÄé]œ¹ J3ƒ¤8-‹yÞ“7Ê µ½*鉘çÝ*_¿ú:€bY·Ž|YÚÍ•ÅÑè’FAÃdQÇÁd_ÉŠ¦½§æaθü÷6RcXn%iCQƒC´HV#b)Q}/Œup«, bu†Æ9§´=Fä@YªÁ@þÝFq:íûágY~ð—²ÖŸC˜ŽêíÙ²èâ2öÈÎ$dѽ]‹£Ñ))\²#ÎÂYÄ3Õ±l…Q|‚¬€[+œ¯YŒ]/þ’Elï—åH¯¨çÃìéc$]¾ÜÄ1Ë’±FÉR7 Ø÷‰B© àZ˜ýäê­d᤬Jp²kêp¦Ý÷¡‡7âsêks¬›’BRSÇß&SP³®ëÔÖöTú}N\Hñ-õý¿{o·’¸+e,Ä[ˆ¿’±.S¼ðd¥ïšÙ>0Æuií‘òùY¡ïÿ[ù \ñ9î*U{ÑK`8p)keë÷mIÝ5HyÎÿoªŸÝv4çû=’.Q˜pì­v²4“3déƒY2fÐc8ª³ÓÄ (D_F¹_GÆqº,Uá9Y÷¨51Ïëˆ;UÒ.µ¾®;ÊX;0¯‹d"”4%Õ⟾qÙq(óú9¶Öç¹fÂsñܧðµký æüëâh4UÝ{*ú4$¿‡¤hK>*«™qžÖ¾BÑ€²ŽÈYõíëùbò¸,º‹Œ‚ÝÜrŸc1¸šSœ±¹#Éö>®5é“¢ˆ–Ò”2€!×ãèãyË*ÅÀÁÜJÆ8K–’Ê3äË¢nIÚÚJÜ"ke·:cX ‹ü÷|$+þÖ]F¿ÍWœV^Š#5EÆÜøPb¾âíkÒ4Ö¹Œõ š¡Ñ®f…cgLÂà‚hi*àÂxÞ?±ÛBCÒ GjOÞû}ûYœŒ¿3~×ãH¸¶{ÊŠήç½w—Q–ß ¨hä:í'£.Â;NL|QÒâZ?~—É:”âTΗ±˜ü-0ýÔÿˆÏ÷3ª}ή‹ªûÓ Jø~•ïk™~Ÿ~àÄïø†àûS*|Àˆckà(ú[—Ê÷|®KE™ïãïXáï`áO…¨Â‰{o°êg¹„î›zdB"¾{»9ÉJŽB ó•ÈŒ©ëºþy÷·ƒuȵœI;ÊÒÎ’’&„ÃáÒƒ†ß÷Ð#¦¦;¥)a0g§±‡‹Øÿoáè¢.©ë>YAÉ]eA„m¸W9zëYJÈpÆì&·/ÙÃmQ—¸ìƼLáÌyFŒW5RGô’¥x‹®Ÿ"cú½ÒöEÂ{÷8†³¥Æ÷ÜÏKú­‘sãš!ôÒIï7ð<ٌݧžy¦×+¯¾z s}¤‚6¢€ÒHÙŸƒø6I †ã¿ò¬¬€Þ2zds‹ë¢rŽš¿[ˆ_\û±Ãùlˆ±¼ ÐæE ˜ÙJC,Œ¯Þ¼ÿÑ8(‹eì•í1*Ÿ“tiq4:'…K·–QúÏ—U]¯Æ¾)M „ë˜ÑCyœÿnŠö«Â1[*cü$Ëcž¤xçŒ5J#‚ñtíe»Ê"Ž»c´¯‡sÂÃ|~(‹îÍ–UǯhäX¼ ³•,E)éƒqí"žÐø™BÆr•âôÿ;eQÔX3Së‹Ö¼[[IÛG£³SÇ0ŽÞy8C­e‘áÛeÝ[–×JDïd,‹Õ²Hò]2šyu‚ͪǮ+Å *ÁÙÍ´cÞRÈÞ,Â\Gÿ•§dÌ›dER²³³¯©©9òôSO]¼Ý!ÊÚtŽ•4§)Ñû$œÖõpÎV<Õà;ØüšRh¹ÙÀ½rØ›{ão.~sêÎã~5²Zœô`-’íž,M®¤‘ÝG"œ§´€¼‡k/nLŠ‹Ý±­ €ÆÞXÉ<>€^+iÂxv•±ózpÞnàQ›l-³wØ(©håÊ•Ï:çœVÕÕÕmdŒ‹YÁv $œ$ÆÈn+÷ʢɘ¼,‹*‘4¹î_ŒÑñ8_--®5é¦2Šê>œY8]?É ¾Ë÷+Ô„È †^OY.sT-_!é:I%IW a (éló¢Ç÷6c"UP"$‹`bÐ ` Æ`k‹s^‰S5 §ÿ[íßøybž~ºœ‚ÏÖ0bFíz²è«0jåýÇâ0Ì“TÚ@ÄÍ0]¹^6ïô‹þ—Aó8NÀ®½ IYõûmeÅî.WòŒ‹"óå8ÖÞÕ’'‘€ß™ÅÑè#IŒgH–{~²,Ü`ánž·6‡#ÄÚ½'%‹5p ë *P¯õŠk%*À­ a\žçÌÞŽµÞ ì[VVöÒ6[o½ú¬3ÏŒ„B¡NûO²zoqÆ­ld1á†ôQЪŒ­–+cÃ¼Šžø®éuÝ/Or^pL¡E¾ó@èàOe5k>(©jä= x¯ÓyÏ"ôéÃ|æ5ìÈãL9\Vúy{€±Á2æ]D¦ÏôVeeeì„“OŽÖÔÔœ¥–a|H 8ÈD¶Ç©| .È4yÃçtNkû.‹¶\-+œ•Œ1ÓíIŸ¤ƒ>[PÑ Ç|? –¾1²ÈË·2Fŧ²HöòÆ8eDj:)ÿ) #Òå÷…SÙ #ê}€ž/ùw}:ÜQ©[cˆ­ÏûÀ`ìî"ÄõÈ¢™ãd‘ß©åÊL®·J:òLÛÊR46Á¡Î•E WÊr²ÇÊR$&b¬—5`4;ô«Œ0B%su1B89OɨÓþ­WÊrÜ“1RÛñ;Cei$§ðÌ©H!ÀÃÉ8=Ū…Éó¼meu >“4¼.Þ±m'£9Ÿ ذXFM°‡£0íb záh¦ä ËýÙ¥=úc9:¸$’ÿÊ+2Ð|[%š÷–ôE$ùù®;îø¿¶mÚì%clˆŽ«1§Æ±ÿ¾hŠ³Þ€³½ gÔAèÕ ¸ùûvZ#êÕ¶wïC÷\.«Ÿ³;÷úGüsÞ±¢‘÷Èa\”1CúqîL“1Ÿ’´ ="èÛ½Ña޲ýý0Ͼ"¬äYúfDRM(zøñG½„qÛµÒ‡µRÉÙñ5 Ö‡2†ÄjžçÞÿJY ^ ²–HЭ#uIÖàÀ(ÖüÒÒÝKœ–“Âßô•¥Cœ+鋘çÝ!éýâh4Ý'ª1–\·ˆ›d‘ô*¶–E÷öX,K]øø œr5¾€Á3°¨!ÉÁ :ã·Ïù¤ŒZû£âUíòt‡">y‡~|zc$¶á÷²§Ñ—òNßt|ɵ]}ˆ´çÚÒäËjq¬/«å0XÆdéXáý–â`|Ìxÿ,‹T–§m…q‚¬P¦+JéÒ?~â=Æ°Ý PáGÖ‡sœ6Jâ^ÇL¼.ËÓ^Ùˆ!*‘±Œ†ÊØÝdÆDùõ·5s<¹–±nÍ{]„Q¾gçnI³êpÚrYóW1'Æá ûgI R“W\²DX^›ŽsmT“•"IÙUUU Ï>çœcž7N–jÔCƬڟýp Ÿ¥²ŽÏÉÀÌùuâtùI_Å<ï«hOöþ`YרK%ýó¼—p|§ãô¦ÊæˆÈRêV˘&³eàe ×k,CÂ¥ªì) l†^,8xg}y*À¯¸åvŒÇ0ºrôé7s3†Sˆ®‹HªÚy§î<õä“;€8vD ç÷»²@Öϼcmç\O¾. ¶j ¬]8x¬K²‰,šðn@96y£ikŒ¤æ–d´Í[px’1rrpÌFÉ"ŽYò6Ioe¤¨Ë0lã·†Öæ®ÒüJ bFÝ·²t‡ÕpFBÜo7í~ÎÍ|Æïß2 o ˾|6”±Ú+žŸìŠëUÊ@»\g:NìÏ26Ä<®é*ÿ§› í:t—15¶”¥hô‘±$XÅXΖծøD¥ŸÃ³W4’¦ÝAV±}?Æa2ûáEÞßÀt‘µ‚=ÀæJÀ -e …§‹êš×<”Þ²:?6qø<ÃcÅSÇw”Œéq7Eó_Ä~?MñŸ/±~®Ã©ÉÂI¹‚5flr¯³`"eÙpíkØY Éu뻀_©Ôr9W _¡Z¢Ù8ÝÐ1±Ž»s¿ÌÅ32æÙ¼t ºn}á0ö]Žùtîù† T\œÌ½a¼!«ý³MІAƒ|ôîÞ²âšqèËÑ‹ÏÉjÎÌH•ñ“¤?ºs„Œá'Ηѣ“$­Iwº ÷ŸrúéO•––*)”——WsÉE•÷Ýh#ÇŽøLÆÔùHÆ lˆi—¹±ŒÝóC°e $' ¤±†à—8Šû+¨°ìäMuvÕQ`/Ãâ •þ‡/£#Ÿg¿PÖ2[VWÀ+›ñ="8Ú½0~wôé©xAÆ2Yÿ·8ª_(^ ²®H‘+ÔyŒŒVÛ“kÍ–1*ėn²ô‹<ÅS0\ÛÁêù2ʽ!¦cŒ­À9¯R@;_±Êö<ÿfŒk+êO)—ÑÜgÉÒ2¾dNgÊ"åi¢a·’±“–ç3&eõ 2ÆÎ%|ÿ$×xÐdŸzæqSæüKѦFï ©³oÌózcx·V<½'¬xWŒ5€1—åÃ׿…YÉ@Ý|À«®\÷ «ZXe±¾:2·®gžŒý2[k;a @Û;²‡Í˜çâ(wc?Z­Vœ%Õ’çcŽ Ìí#ÿ’)\À8n"ì¾K±/â÷–”½ÐC˱£bNº€ Ð[ƸŽnh…¾^&.ÇÊǾ«'-ëIÎЋ£ÑoRx×d3ôÖn&c$.KcÚFâ8IÚ¶´´ôø³Ï=÷˜²²²P(Ò^{î¹ø˜£Žz*‰¼ —¥x¦ì(ô `S™ $µF‚´Ž@Ö%q=× p$p">.aý¾U]sJÈçH§$Ôšó¼ÏWFÉJšó¼[%½ÙL E†×rY$åߊ×IØDÆ®ØA–Jq±+&9‡à3 ÓåŽÈ"Mád¹6}Õ2vD/þíúé€Sp´ûaŸ*ýo׃L…ù8ŠBlËtQ<-£gh!`Í7ŒÁd“Õj8‚Õ”³ëBÆöK€ŸyIüÝjY-qÊÿ•/‹Àf×:tÁðŸ”FÝjàž%«¯õ­Ÿ2ÃaÀÄõ€]cNd>§³·N˜¸`cM ë°^²n"ÛF|z%,c†Œ•ô/ØòµD÷¶U¼‹BM3Ü/ Çê|YÄ7·½¿GuJ ŽK{ª2…½²5Nþx%Q£gt™¤O8?®“EÂGÈ¿]dEWJú6æyÏË¢å3›R+fÀjôü1Ï»]?DÆZعûu•¤_cž÷…,²ÿ-ûº„kÍ`¼z£Cë#Úp–ìÊb Š÷ü@â=ÎŽ”˜ èþBžÿ8À—蜉²¢ ¯)ͬ”„gÈæ”txeeåúx^nyyyH’6Úh£”——߉D¦5äÞ™1*& dí“€9Ⱥ$]eôç¹h¥ÁH²èÐîE?¶ÀýÆ‘¿±)†IFê…_Ù¼Óm²<ÿ•™ ¦ /]ˆ qØwEO»bŒ‡0H#8²~à¦LÆ~˜‰áèR/~õ%ŠWmϸ+ÀquQÎm1ò»ùÅJÅÓ2~T¼«ÇT¢,SÆjN÷q2æÁ Ÿqõdmx·âšËeÔåuü~§Y8†Ma´–Et×c¼§5à0DÖRM=†¹+yœ¤‘€. d]Ž–åËŸ“q3kzcž£#ÛÓ¬Ëæ`*´–1¯vêºsT2žß7ñ–'I͸ߠ ^L àD 4RÚá•ʢ쫂!‘dE¨†Ø|×÷? §ç I·¦ÉXÉ•E´/Â`ÉÁ)¾]ÒëÅÑèòµdì#80†]ºŽUÐá‰EŠ×AhÖš)¾Öeì-1 ûóüŽ‘TÁÞšÅzúœ}çZ‹–'ÆÀ°v pžÚ*NÝoÏÏŠp&òø}á8?QG!³e´â,z\ŒË dµ6å{ËR<êr ž“E-,k,¸r!Îì ²"”érZÉ"Ç—ðn+púF+ž1RV{#Ìtà‡cå8Züû²ö…ãøw¦@Á3Ñï3Ë|óÙFVQ_PDZ¯ó>--gËjíœ%k+›IÙGqµ¤ód¬™U¾yé)KQ cÌd±ONk±r-Vkp&H6fýHµ’Ý*œéëò³#ûjgtñ*YšÜ#2†ÙÒ ±ß\0bSY·á¬ÛJ€·Ø«¯½6þ©gž¹¿¦¦fKÞWÖIS¥¯,¥Ã­· p àD 4J eÑ|×eÁH²ByGãÖ÷b_,ë4‘NãÅ£x¿Y.íh»¥-Ȥ¨Mrd, áØm  r£š‘:Oñ¶Ö2öC„­eÑÿ̈X‘û=û뜙e²B•Uµ\?‹wÍç>]qŽz+ž®Ò ã·ˆû¹BžÿÃÀuóX%‹jž@ÕüD0è_€—ÈØMu(ú` ç`”諸©¾{P|'ËOÕ‰ c aìwc=7U x¶KYs¥ìÛ¸¾ŒrqîGà ¬äý¿áûýØÓ=˜§8ÂU\ëq¥ÎÅ ‹2_‹’ã{~í ¦GOÓ!˜!‹|gJ0æŠéŽ©eÝ»±Êáý›¬ÈÔh.iÇz*a­5tïË%]Æž¾G™kg\€ŽÚ1ÙXqFÅÖöû²Ö™z†lÅ 1aÝ•1$`¸Fq–ůèÃ7-êê>‘ì3ä³ßŽbÝvg¼§ËÒž¨ÉHê€MWYêÍñ²šÙ/¯3ßÝ}Ï=¥ã'L¸EÒüé\àZ–¦ý4FFšá½H àD `É“Q»É¢¾óƒ!‘d9ô§È Wkûg œHp¶7ÇPÙ §xº¤bP-ÌTt§‘â å¹"‹¥—#ÜÃm{cœË6Šªtµ ¦ÉR2\[Q×1£²8­âš¹| p4:8l€QÝÇÖÙh¨”±Vãð.“Q™òu±ŒE²Œÿwl’JžsFx"ð´ ÎÖo8©éè.Âш“ÒOuðË•Qœ÷ »"Ic9$‹”ž!cÑäÉ¢ß6ÑË–¥c\!‹¬WË¢ª7ðN %!ßœùÞ§òxs©HñÚg(},¬Ã9²îê:ž³GòÅ™óZx‡X û+ó¬µ-qš§±î“‰ô¶ÅÙÛDÆ4ü¥Ǧ#ºo‘¬ídCÀì]’Nn]TtÔ½÷Üó1{?cÌ2ä\Ňñ}ºçuI1æ´$“8Œ¶Ö2Àí!tö›2–Ì'2ิ)Ï‹m}ôÖQ¬‰<ôð{²â–_ÈÒ&3ʸŸ( €«eñ5zðmÎq7ïûp¶·°9BMH÷©EöEŸ¼È3Ýß d-‘  f ë’TÉ"v9>‡+¸ã[ØB÷w†r»LÝ€(΄˜ç‡~¶¬ÊöM8yÅ<ïI³Ö"‚SՃ쳦8¡>À ×ìËu·äûŽ6.òæ U~-£-£ÅÏÃQpëÚáŒ÷´AÌóë¡δK·pÝ!j¸~÷XÊugà8M8XĺXÍútE<«šhèg?Ľӽ‡\qÒº¤ €lk0Â\RÇü†p¼ÛççB ïÆ®‰0Æ_q޳eé7×ÊØÉ&Õõü| ÎÂX ƒ@óÓ8î™Ï> %‹5¸ŽmO§+{`4ëkm°Ÿz0Ö™fñEy÷{•| W¿¦ZÍŸSï:­$}ÿZR¸oß¾çÕÔÔÜ …>yÞ£26CÚë qF”Jú>æy?ÈZõ’¥7ì'åŠeõO^ŠyÞ‹²"¥x–*IKcž÷®â­}ûJz±8m4ø ÑE.-cÏñÞß¾¼)«S‘‘ú-N¯úÈR½0q:`MSÇbKtɳÅÑèxÎÈ¡œskKªh àD0¬CâŠòEÒl ¯ëRÂ×¼º¿«TßYñHl¦@Š I_Ç<ï4Y—Óeí/–Õzx!æy÷aðT´àœü,‹/kåv Î^2†”Ë“îˆa·†åýž Q£xZÆ$Y‡‘odó™ì•l ¯²Èú@Àˆõd‘«BÅÓ-\1Ï Œ€ s¹Þ¯8‘sg=”òû•É‚B¾(Z/Y B¹¬#K2i/ýÑҸκãè‹÷kÈÑœ‰±ÿ¤¬^Âþ²Š÷pêsフ÷þ½ZÆ8ø;÷iŒÃÆY?穵vƒ,Ú›nê¾c¿ìX0•õœ.Y€þÚAÆ‚š+cH fWùÖø·²HçcZ;ŠaæÉR—V+óE';ûöfcV_¤·ˆõ±…¬®ÂÜf¿>If¿/iùÄì»rÕªÕ­‹ŠFÈŠYΔôrÌóžc¯Ê8P# z|ó¼ ’®–¥ÃDY‡³ß¦Iz3æy¯£kW¤wõyœsÞC)2Ã|íEwâÌÙŽ}T!ëÞò¼Œ)05I}Û ËŠüE–NXÈå\+iI=ãwƒO'/—ÕªHñ\g“a2¦ÆÆ€®Öȧ2 ½NÈÚ%AZG ëšÄdó]età@Ìpºç<Ö÷ßTVœë- ¢fs0ÆzÊ"^QÍRYzË?$}R–´Ð¼´ÇèÞ”g97Ñ¡æù p>úbÈm Ñ(¬xÛÎE8ˆßðùI…ª–E–{ó·ƒ!ºË"÷®å` óS"£ôþè0G`–,š´\ñÈk¹¬;Duæ¨-϶¬æÂ–²ˆ|ެ¾Å.ÅÑh2ÔC2Zò®é8ÿOÆ8¨‘åu¤†)¾!ž+'Z+žR<µ§}GF]Ÿ˜Š‘p¿N2öÂi|?[VSâ)•tƒ‚aÖâ}8 ¿È:)|ŸÆ{EØ·W±_\AÖYï`, ¨ÔÚSY¿«,â?à/“Ý£†ËrñòtÆiè‚€W¤ kcsKg%ûå?Í<6Ý›i²š åI¬ƒ$ݶM›Ëî¾óÎiápøX@«¶¬‰™²ú$¯T-Ê$M*awÅël¡xaʹ²Ó—ÐC šú,1Ïëɘ-•19.ŽFW'ñwaæ}çï0°]…nMV¯d¢2Àüð=C{ÀceiN혷ɲ:/ÈÚ¸–'±v¾à|¨‘º'5pÿ€Ü†Ü{O¨ßµUÎXŒ•«G£a섞ì—y $@p"@!£%(‹ä †C’t2ÆÌ…8Í-ëËR¾‘åq–7÷`uEÛN•EI„aô $/C/Ír`Ñ—²(æLž5#nOœ¿0&QŽC;[¡ûJ–û<'´LÆT¨ñ]ïv SÇ(ª–±–@L–Õ—˜ä J¸WUº"€‰98Hý1·0i+crTò\“eõ#^“ôm’Ôâ»Xïûò·ép0Ç1þb¼÷TòÅKµGæ²#cúÀÑ4KbQ#A;—r¸¬(lO@¥d…AçeÈYË@à{p|žˆ™“¡{uÅ™nËØMDZ^›[üõÅ1ý@+“L­œäSpºÚ(Þ (ìû=•p>Þ‚ÃÛÜãØûΑɤm&sçJÚ)æy«eø=d5!¶ä½…þ˜(c ½'lK3U ¢›Œ‘p° du:czãMÀ´ijDŠ˜çm&ùß–tT}ú=ÛJ|=Ôõ0G(ˆS’án›HìÇ>®æìzU0N”uIf<Ö—ùû³–—ÇSjyÿ\î·çÁÅï2ÅÓßfÎ`¸±Ä™"»W+@Y+$Hëd]“¥ÀEÁPüW ½M Ý¿ü}‚¡Ül‚Á±0æya”í KùØãæ+YN~sŠëÍ~—&|ñcÞå¬éïwÆcèΠ¨L¢0\5FXWYtèGÚµþ,U i…\ÚÈVï[ad¶âý]ËwdÑÆOp>]7TŒøù¬±^i:ÿFñìH:@ñH[²R‰Ñ;CV1¬ÿ-0ÙX)ä™.è)‘1Gîä~™*àÖVVOãÞc”ŒŠ]–¡ûUãPÍѺ%®]g&ç¯c_Áél%‹J·’‘Šƒ’«u\µTúKû •ó`Îâ>’G£É€ÔGbž÷„ŒI¶NðN²B°;)ÞÑâ˜ç½‚þKkûK¢ý3$͈yÞôÄæ<Ë®²ôeR~“46æyorî,H²óE[tÏœº€ À€þ2&Ç!26ZD–þñ2ÎüxIË2UP””‰n26Ïq²@@¶ €} =ø…RO{É“ ûñï×e¬*ÿYÓN–*··,mdCô¤«“ó!çÌ8@¢UuŒC–¤óÙ7*µNZîÌ (—Ë€è9œµ5 $@p"?¥#Þ6ŠÿŠëußR€M/€ ÍXÓR£»R–ü,Ûƒµ¹e.c’-ÄùË–±æ1‡è°ñ(€GU£‡þ”~²HÕ6ií™ûjÞe¦,ª<Ðå7Y¯©³+,zˆ,*×X–NX=ÇæœŒBÅ[ ¦*5irRspºþ†ÓS!Ë¿#8Súˆ,:}‡Œ2_Ö&ó-•ìk“õYGÓÔ<Ì„|â¹Üsmw‚j/ œ,H•ÇZ+­˜-ivÌó^cŸö‘¥0 —EÁÏ’u’Y(és~ïcôëštéE€ƒù’Þ¦ˆ¥kO:LñßLVk(ÊYôsÌóƼü¨ºÓQÜÏ cžvg̸î€6żk®Œ±ñ¾ Œ ’©Â–Ž©±¤dl–6ÌÓ¸û>ÏÐX]±séj•|xÙ¥—æm<`@7Yá©N¬«cæ};b" T2c°‘ŒãÚ§V'©{3‡³ÿ³Xç¥ìÉ·d©>“x¾¨$FHÖȺ&'ÉR;FÉ*—b´Ù7d4ïs›ù@ c8|(ÑWÍ_|mm•ƒ0ï–uUXg €ˆ"£¿âµ0úÊ¢†.R[.K3øYƈø”ïK*Ë[£•,:Ö[aû¬ kö¾?‚çþ,·y ­á0ŽÇßdírC€;×ãTdð¾}dL£ãq_—t)Æ{õZ¾\³ql$‹T7r¥ŒÕR¬ô¶8¬m~úËê í*KSûk F¹²Ú*K’¸w'(¹@É×ãèÃ>œÏþ\™¤®Ê•±X¶—¥"mçs`Wã4~às`gªVéX{s6¯¾¬‘EÙF×¼ït%sOY à£{N÷³jAT ÒIÒe2zù÷œ%쵦èAÇë c u“¥LRuÙœûÈ ÝÑÊ |Îáìqu–º3VG2ß…ØB¯Êj÷ü µ£ËP àD 4°þ\Ã`B>Æy[œ‡®²´Þ|íƒóò¨ŒŽ×OG ¢Žüm+ מ+ cûiY1¹ù b †MsvËÈÇ)8Gñb…²¨ó¢ Lg+žÏû †Úä(r™ŠäÈŠ¤ U¼“J‹®9"a­p¸ø€ˆOͬ¾À" ïd9Ä®3H‰R¯‘ø9ìÓõdyäC1Æ{ò|Y¬©×$E‹£Q½ƒ"Y$´ÿWIêšÎÌÙÜãzY· ç˜<)£eï8ÐÒ÷Bàßd ësj¸¥iS¥«,G}G¦û%=Á÷k;[""‹®ßüÇÁä;S–{‘EÕKOÿ{9&ÀrΠŒ-eé`û²ÆòY¥²4 ÙÇ¢çŽ,Oóû e-l…ûw}¾9[æ˜ýsö}YºÂƤZµG…;ÈŠ1.‘1ÒÓ8à e ˆ_Óäd»¢‰ƒq2·cŽ8°  åcY1ÊTÖ¤8ÉœØàd0ÿÎaMe3®eè‚7±s¾“´2S…-}gÆ8×G¢›%£Ÿæ3=]@`t¿wß{ï’gž{îÈ’’’¬P(¤=vß}UôØcß—¥GŒcÖ4æÝ9gº0ïŽUÓERÖçãÇ—þã¾û ª««Ÿ“1Æí¦\ôȬ•ûdÅ:ç7 s»#Ø;ë³þŸ“±Ÿf*H÷$z%¨9Hs‹ëª0DFt”½|>y>0!¬x¹*Rîcøø¶jÅ[%Vò7¾wÆÈ:S¡yFki4;E)ãÝ Õ<€cI·ÊŠrÍ¥Ú\,£wÏ8!Ë©Ý[UºH–¾2‘Bi¯ÈŠˆ­mÔÉrž{˜¬ýã“Íù£vm˜“þ®Å`» b‰Œ¥ð…, < #}u€ˆ,Å‹fÂéÚšçhA^Å^œ«x‡’o0ÊiË«dQëûŠeQ¬ºž1OV_ârŒÆE2¶Àãú=ëÂ9©ùÍ\í"+Öº)ït§,–©~É–E¨w”šça4W¯ú® ów€B© ”n#‹Tvd¹AñHÿ²p8üHMMÍÔššš2 ö_øú%k³ƒâE&k/´8…5s4z¯ w73ÍûºúôDÖÉk¬Ý)ì“ϸ™,}`2öƌǻi8×Â8ª·ÈRŒVrv>Œî¸‚3ü%Y§ Äb©®(l8‰3),c¼ôE¥g¥cÑYnyÞ ŒÛz€»ùtâÖÔjYm‹/cž÷¡¬Ðð,YaÅÊ&>Óq?ËêP<É|õ€:˜µZÂyñ¦¬°e&‰ë~ÖÛìˆeœ«ÊØ:+ÓÄ’pyö–t\IIÉ–ŸO˜PTRR–¤¼¼¼¹¥¥¥GHú¼1 ïS¨¸— l(´«eé†ïHz½¦¦æÛêêê1¼{Û»%WÖbúÎÆ3™dlŒröêM²@ØŠ³âöÄnýLH0'i.¬“ µ>\ñêÄÏWù‡Rþ½TFߟ#CÍgã´,À™8‘ÃgÔb–¥|Vs½J~¿Š{ÝŠAZÉA5^ùÊd>wsˆë>IIÎTj˜ƒþ º/d”ã)®—È¢jÏdÈò÷?šgÈÇáü™Œö¹6D&²1ÞwÀyRiŒ˜‰ËØl/‹¼oˆ“2#¼ÆZ–ÏáZœ}ÍÚŸ„Cœ ‡]p ‡â8f†‹–rÏ/eõ –H*Oh*’E‘÷—¥`\(‹êV$¬×¾8áûóîÿÆ™šU‹¡y§,2¾¿ŒV©=´¤«0ZC²t’k™‡æØ\«ÇåçóÖ=fmæ,YÂ:X#ëTðçÅùì·#‹î-àÿ‡Ëè§wø¤êà:¦LE2ó¼|ñ#$À ”,Šù´¬åÔL>KRò1f»á¤ÿš¢Á•Ã5œ£ÓIFí­xšSWöQsä˜Få8(ó18¿åó s¶Zièì¸=ϳ,¿kÒE ?@p¼¨Z/+fÖØˆd{œ|×nî#tÉ<ÆjWY»¹Ö—£øZ×ýnÀxˆÎ‰ÈM/½ùÖ[ÿyâÉ'¬©©éÌš¾P ÙsÇA}ÙÉþÀò{µ´ŽùyRÖdGÞ]2ËìÙƒ±­jÒ¤ÿ?fÜ·UÃu[ $' ¤‰âèÐàôï'‹F´Áàùƒü Yñµ=ppÏPãÚö¥ò\‡Jú'‡ÖAäy2”ý ‘•²(Õ=nëRᢶ¬%8ˆéÏö²4˜S—e¹—þ"gdÕ³?WòQùf2&L'2iGÍWÌqˆ¬ÅÙ®8,%8Áÿˆ\œIzl=€Ë»P/ÊX; \;.€ ëÉèÍݯŸâÚ[F|:»Š1^…³0[)ý‰¯3øy‰’c"¤2Ö]˜³íYo½OϨP¼hæxÖÃD ÒR5‘™Q‡Óº‡Œ¹3È\ Gb6{ÿ5\ÃáŒÃeQ¶tê ÍeEþvÄI½SFa_ÜB:£Œ5S8ñ½âUé[a8¯-‘½Î’®“EyK(Œy^)ó_ž¸·q4û1÷Û°/Δ4¾8ÕȳΠÙvÛ~Ì÷S’Þ©c]º1¹–s¤\ݾMƲ)F¿|„3³3ºp€C;ör;öržï¬ ûÀ†•Œû¯8öo£þÂÚÉæšÓ%¾æúe\#‡½×“gX(cµ âo&+-_G)ÂßTóÉf‡gÆs–3†œÌe^ÞGw—±ß{r}Çyqa-c›‡C•¤H$r’÷ðÃ2VÌk¬Ï¥- ·ýë(‡=âêDìÂ×îèä*ÞíSÆåIóY°ñFY°æÐâhô4<»c±õÅ?XÆ`smHÇ㜿'iaÀw¿~Ør¿lÖ÷g ã8ÏÜr챓e–úæ¢'€ó!€­ïâñ©|]<êÕuvŒå·ä¬ÈfLö•´UúV!YÐd ÌÛH 8Hú%£ksýaŠÓ[+pÞæÐþçÀ‰dy¦™6η“U¸v%ÞVœžçœÃc$Ä9\…at/ÿº@½k…ÁšÅ®‚iaí»ù:qú°ð¦,[)£o®h”è0uàG†ÝéY1Ž\?øƒ™ëþ¼Ã|æt ÀTsuû˘&g3f{'€y’ãçÙŠG^ðࢭ‹0Úf²§f*NÏ^ÎïUHªN—!OˆBYT¸Ÿ,Ò3C®®KϘ‹s;N–êó+Ï•6 `Ä¥§ÔV%¾PV»aNàbMw¢ŒºŸÌ¸¸ÖGÉ¢¿éöÎbßÊ¢ÌU†R8V¶€­ IDATpÊCI8Gaó«p$?býíŠãüNrK2Âè’{eÑüÙKbžW„󰳤“‹£Ñ_ÖÊž¨ÝpXÎ/ŽFçøÆh;n\ó±ZÖjúéJôÊ÷ŒÉÇ’*vÜa‡¶999­çÎ;gÒO?UúžÙ±*ÑuîãŠ3‡Ydé'‡ðÿÏÈX}sÎ(J:¡¦–9ß}÷ž¯Hp.zÅéÇÆjÀ˜‹ÓØ•59Tñ™¿ñw‡á~Àø¯Nx¶Þ€”SØo›ätç…”gÈØîo‹p÷sz/ ýpó 7|ѽ{÷Ã}zû]YÐ`‚2\!=”“<`o[Þ5„®ùçS¥bó¼bVOÒ¹iÊZhÃ~.KYØ€y/a ?%cJÌIGRq¿C8/r¹ß׬뷹Ÿënq1ºÇ&=HÖÕ¢¶ñîÆ{-«±Òе9SVâUÞkEŠ PošY2vÏj€œO8_‡)½ÅgÛ²&úƬu;8@p"µf½rØíÂÁ¼9ÆNGj"Æ;²ˆké–…‘~=??€Ãåw2zôè"á¡‹$9rä‚F—ESÈh³Uiz×ŧ{q(ŸqžFG£™hõéÀ‰#qh›"Y8m4™/cf<¥†;4˜ëÏz_,éö$"‡…ìï“ÐÖ_+öª‹&¶„äË"êWñs^•„–±+îÀ)ZˆÎ{VRs¹9ûþ{þf>ùŸ•ß=\ÆÊ IÚ©8žäÉØáÐ~‚Óø­¯«Ï’úÞ‡ñìÁûÎg¶â­¯—.–ËXqò§·Ë˜xâ<™%©KVVÖ{7\wÝÃÝ»u;ˆ±ïÄÿ/Àé³n~S T¦ÄmÍYs0k«ÿ=ÇüII¿4”bó¼ÎØÝ%‘,{‚¹êXr,µ³+ûy Ñ󜩳’Ð Éèg—V¹ï=€sb÷{ä·Zî× ;±ˆ¿ð°Òwý"ìdžlË~ø›î%±’FV!@É›ÑWb§žÎÚ¼OºÀ°0zéVÞcçìÜÀ­$œ$õõ‘ÇA·5`ÄPÅ[_U \?æÀ˜ xÞnM‚ãz0†ÉJºþU(FY߉Qœã[Ÿ $ 9rä´ž½“¬öÀ jèi‹1u¦Œ’EŒîÁaY¦µ¯ T!ã™-cN4œÈfÌnfqpQýêoãp?Lp’'K)£K`Œþgm¡,:r9†vƒåZœßF8Þ]ŽÃév‘—‰¬‘W1ÚÒÅ€ÿ™ŒâZV‡¡j®ˆ ãÑŠýÑ}½ Žm'Å;xT0÷So%ú#û½DReYŒèS¶3zf}ŒÔ@Õ” ‹£ÑLt„qi‡Iz½ :³+ßñ8¬/¡f)Íl‰˜ç°_Ï–Æù€„I²Í®‹â»r«Ñse8‹Z@ŸuCÿŒÀ©½BÒ1Ï«à º›ßyWFƒŸQVÇ<¯,嬘µr®¤WœËÚ?TVP3}óÏyò®;…}ò‰ŒUð¤*œÑýp2zÊ §˺=G–Föj={#_ÆÔ»Šqÿ€hJÌó„cz%kð€½p˜Â’v,ŽFgò>íøÝí®ô¯$ôX6s{3û1ß?ó¼Õ37°(ŽFgñÞei¥¾ñÜ%`dF½Z1–(^b gkzæYæâLöÌ(:Ytä9C'tæšKÑI¯àÌÏmé6Íì‡Ák»ú¬Az¬ÙZS(bž×QÔÄø_U×;Hôà‡0í°MÊ/b›ÍK Q$+r¼6Ò†ì£R3ö9ôæì°/Qß<ÌY,öUTÒ÷¼“kÁyŒ,8f~_⬞,c>6õ¼lã‚v’1Ù"Ø#{ÉRG&¤qy ¬É’cAO=¸€4l¨:*÷–|CdHwNâr¢·9h•¡åUõ¬±!\¹Jo%þþèÑ£âÐvňq’ËÉ}MÒˆ‘#G&M/”±$Æ:I©3\¿õ‘²]ïúŽúüµ¤h#£OVN¬jäÜ÷–EŽ`Ü_Çhœ–¤Su4Æù²ñ68LgÈhÔÙ\ë> % ÀCFèõ€+0dîQý­"“5°œ<dkr†H gaašXÝdé6å¼×Ìf4”ü[öÔ&¬Íe‘g×J4Äó-ˆp+ÓÖÁ£C×UÉß CpÅsákoé÷5Fä—²tŸ,rúw¤1 S•ŒöëÙK3dñ7”æ‚—1Ïkƒ}6º: w¿,º¼¤s–€|˜,Ê}š·@p;°ì;tÇ·€0çãäÖàßQ®b=mÀ³D;EÒwnãøœ„ÓW%+<ø´o-å¡®ÄéšÃï>­xD· úð8®q?뉜!Y¡ågjû0çèÍ2Öà*ôäÃ’VRà÷@Ƽ'ûïΞó8 ¯æžU2VÓ?9[§0NŸ5 ·pv1a¶Œåx¹¤_bž×Šõt. Â˼OàÚ¡¼çËìßóáÄz¹£Ž4\YDÿz¾ïÈûÌ<~bßå¢Öøœ~—>:BVÓªϵÐï#û/e¬ŠMÇd½uÅ)¨Îì{[Ö5è Y‹ÎþæltЛ’N+ŽF$\3¹'ã°vJ%cð>€Í×€H•M|‡sµ%ó7Ì7î+eàþ ¼Ï Yqã†tÎ(öp7Öq±íeLšY{+Ðûÿ’û+ÒÜ*|?«åeös…Œó9gÐÖif;ÀmÃ^ûq{`s]ªoH 8HÆ%[†ôo ‹P¸JûÝ ®Ài‡áð½,r‘,ß_†à÷à`úW-ÀD6Žá>'5ŠçÚ®”´ËÈ‘#¿mà~Y²ˆû98œŽrÛXÉ•E’ÎĨ,ÂIz@VdoÑZR´—ÕÇXÎ<®NQtÁ08•kMÁ~] ³%ü²ëäYD±˜µU!s ÓòƬ­¬Ü…¬Å¹8,h¤£’x.NúŒî ¯\þ¾ŒŠû…šV-ÌZ<_–o}/ÎHºÒ\uùB «î¼SÀˆ>²h££éû[‰þ*‹ZMP¼`åJ¥¿`¥Ÿ­±>`Ä0¾öðžNÏ|ÊÚùQƘZ“f£´>ù'ënOž#•yîËžÙC7†Ã6Oi¢³n;œÎš­Ä ¾[Æ*YÕ„õzˆ,rXÎÞûW3έб±7…cž×MÒ]èß9èö·‹£ÑJÖÖÎÌ]OôËy.ÍÃçÔ/c@¬BϽɺŠÈ¢š×â—ã8ÞŒž¯†5°ƒŒÕ7@F-¿€¹½ƒssçÛ«µ€gÙ2ºÿí_ð<_Ç<¯†}z£ŒRÎÙò4ï¿'ŽçYì‹ÅÙ#]yßóýï[Ï9¶€Ëúìÿ+$½ó¼rYôø&tø@’12vÕhÔŸ9OK‹ýƒs$½UhØ ·gÍ|ÖÕ#€‰ó0ýÕÒÍWÄsí%+†»±â)%à®ËÈw€Í-VøR 7E·ìǼUV¿Œ“†ï÷–S™ç´3"€Ÿöì—!8vY§nm¬DÏ|äÓ3‹TKç…f”§˜ÿÏõO—E6'8§9æymqdNS¼’ÿM8‘W3ÿï6üZËÚmÇûœÂv¯,ým)lbîÙQ–ªðWœ–Ñ€cÑÓ¹ÿY¬¯°,Ê~—«§QíÍÀ¼z’nÙv›mæŸsöÙ]dµ„ŠÑ¯ÈXsùÙ58È/ò{]p¶\ÊÚin>jdvaÜñîï@ͨ ½™ßÙI 5zêÐ59ŒÝf9;ñ¾…èðè¿wØ/?ÉÇVhf "ÂzÙ^­ß±­\ˆ0VÏ`smèéì³R~ïe@‰ijbŠƒìéƒC>œ½Öšµ2 çEÖç¢&0×nc¿eçææ®uÁ+60 ˆ÷úuõIÖdåH@‰kÅí8GªéA„Nì÷ýeì£ÐAaö÷ ¬ƒg÷$@pâÏ"®“FEmYѦÜ!‡yâce”È©8~MtþºÊ"PÛ἟W—s:zôè-pœÂu¬OR\7räÈ¿Õc„íŠ#Y!‹.~šÀ ‚ñ3’æ5ÈßeT½–(œÙÃa:Æšö|;–s1€W0Gwê$kdé÷Ý1`,.•Q¬—Eèí¤í:lXöÂ… ·øyòä³+**öùI–óý NnºŒGWsdˆ,ʵ àB5õ+²¨ß”ŒÛB “^àȵ'¯•èZö[S¦"N< Û~²(ÓüìˆâäÌæ÷ga †Ùê;¼•‘'/ŠYÛ†ÎÜãu?öø£2ü·é£¬uK gq1ŽòxI³2äPEyvKX‡ú ®wgœæ3X³kḋU8Χâ4d‘ü¿9vHuUUäí(äÖ©²NÍñÎtuUÕ’úëí·7Mž2es‹`äåxî9²—:s¡¬FEÏ÷/€Ïòl>lø Î÷s_cSؘKm‰1®CÆ…<ß[–ÈØO•‡Ã ÜïÝÜï§ÌëÓVÎzgóZä´î®®ªZ%c\-cÔ!ÿoAfïÉsÄ=ž‹¾»Y¼VÆ©ŽÃÖé"c.ž¨û9Ÿ{9Á½”Ë÷ÏÄ1LE~×òù™ÕUUOVôC®hæµTÒdÞ÷š¬pd&õv{Ì)‡óØ/öÞh£I#vØ¡¿~ý¶î×·ïñݺuëZXXx@Ø;¢©2»§Œ…±6ÙŸ]ØŒÎ{Gy" w];ö÷Ë–-;±±±ñˆÆÆÆ¼@  ¾}ûÖ] …þ¥ŠƒvÀØŽŸÓ}¿«ç<쉾~ PîöJ"óÌp½‘uÿg(6µøCdÎ.¼o®²#;²ãû‘eNl¸£PýÞCbŒØ<ŒÌzâg2Ád ¹e 8±íÝ0øö•¡ý'#Ø[•••7cŒåÅìI—Îá‡WTT<Ñ‚ø´,u%Š¡£r¥sdQ?£Ôše©,W(9B{Æ&(ÓdÑÆÆ8Ž×(YŽå–pOË"–ÓRB²èøh »¡<—9ïcÔ´·*¸sÌαºÉ¨”ôÏòp8Äzÿ÷”ƒw½Œ6¼&Ý‹K´©Å|Yá¹DŸë/1úî܈¶ñ]ÅÜÀƒk%Ú¬ µùþm©ŒÞ?gfkŒÚžÈgØÖÊ"ÏŸ!c¦àÌ,WŽáÒ…ýµ$ŽcÑGVkà8Þÿ¡,Ê–SâL(±@^ŽþüDö];;Àôà¾"8¸‹Ò¼ÎYdýoòŠÄž-‹f7³ÿ/c Vð·ç¨/áZ|Þ¬Ÿ(ét×½¢ïì%cœ"¯õò%²Ô×Í£½uòÍ4} a ç÷NYúÈò8{d¸Œ±;{èO’£®Ã`dî(y­5ï—1oîæž¦ÈÀõϸæf²HîVÈ·3ÊÃá9­8¿=dÁ€“p”^–tÉðaþ¸äâ‹»ÊëDR̾½½QÄúüYï —íÁ¹>SÒ[1çº@Vaó]&£­ÿ':–±WèÉ€ï`s(Ϩ7²¬†}‹¤—Z9;®Îk—ZÈý!3;ñêŒ,é‚ëì{•ð™|®ä*++{rÇv8íÅ êS®¶Ïœ¯íÇ 9uØ…Ÿ°¯ßÆ.\‘†š®%ûö²‚Ó{JêµxñâÐcÇD"‘@ h¶Ùfƒ?ÿâ‹Ù?¢¬/•ç6p,¹N2vÊlÖÞü~1¿FÆ.^„Þköí‰2Cê,ÎB#rà6ÅgÓ‘#aäÊ#Y—&;²c]Ç*;6¬Ä½AAâ-ÅКŒ‘ý%Jh­:®âzwY~ð¾²<ûSÛ&k0Dfb¸|FeP^;ÏWâ|¶+ŽßæòXYý¸ `àHîûrY¤} Π̢>ÇA¤hÌ^ÙŒ9ÀßžÃèü$Áu*ÆØ8 ¥ëX¹·×q"ÚeHbØ Àø=ŽïYÈ\ÇKš‡ÁÁ€?ìbŒ°‡0²o”åŒÖ¦kq‰¦ÍѺ´ÌDG”—KɈ¶ñ]kdÇŒ"Ôƒ7ÉRI†bÌvÇàv4ãFYö[æ÷Œ1¤v"Zߊ— 1ŽmWöÿY8¹³ÇSÒŠ6–1%NÄÀ_ˆ“<^ÑmNð d®ŸWWU=’Â3É•W6Ý@_PVWâNöØ»Ù2ÖBOä÷!'Kšû!ˆ »“½yŸ¤?•‡Ãm¥Ðt’¥ø]è7‡üŸÎiàÚƒ”B_Ž—± úÊòí·bïŸ+ibG.¹ué«€3üŽB–õÄ1ú=Àð«øÎËÊÃá¥|fî³,Enl+÷[ĺ]Ƙ Xði$®æ «i¬,=h-öÄ_e)& ˜÷qâïF.¿ P4Ë: ørYz@3NÖµ8|Éî½ø9Iõ‘ãó%=]]Uõk>\ÆV9 ¹¹yÇúúúßß~çŸtçù÷“Wß§§¼?…>€!ä|_ñ½š-u¬û"~Öóû¾ÑhtØŠ+¦¿8aBcç=„£=½²7Ï£'À‰«íó%:óuóf¾Œ‘.–Ww¾ÿŸèŒ%3¿ûîåëo¸ah$Ù\Rs4òù_¬Ì€.s…<7“ôIy8<¿•·ÿŠóþ ¤«du‡.C¶¿*c1Ž”eçy-dͳ†|èÉóÿy3©Ë#9Ø‹O(M5в#;²àDvtô(FX^Š œ‚1÷ Šn ÂðÇÈáÞguo„úÉ2Ä9‘ñ$†yOœ Ê<Š“ù‚¬f¬aVбúKKãâœÒ N÷βè2é þáØ“pb~'‹š…eE3QâÔÀTŒþXp¢3àÐùüû#»ãµ”`çy0ŽÎpžÉž±[§vS`c(ìÇãÎÃX~Ç,Þš5È"‡óì\Û½‡qœoÆùYý#ŸÙï8—{cä~·É“]Ù—¥òºâ4²fsp§!_¾â¹¬‘1""?1ÙZ€³±€½åj³%‹(„»‡­Ý]8%ºsÆÎøXJ$Ê”èÁy?ƒyWËMÉȲ€_¼ÈoždËåo.ýÅéœDä@¾¬xâeØ7Éö_+ÐûpP'³&ß–‡ÃQ@´Sd©äê]mÍ—EûÇÉ¢ÇkeÅCoeGX»nÈž³¸çÑ#ïóÿǾxTÆ¢˜Ã^ à¸^“» ðã^I«i?úÀÔ:À‹;XÏËy^uÈéËÃá:ê]‚Þ(âÚ×—‡Ãµ-ØpÛqÝ=p–î’tÓèC]0ú°Ã6‘± Ä6H29ÿžEoçs9ûåòZÞ&éšòp¸Æ§úbÍúLf­ßn‡“5”ýúMÏy®¤¢òp¸ g¶_ X• }š““SÛØÔ´ISSÓ;>`Ö_«I^ºS- ì*^Ë‘Ëe¬˜eü\!ce¬æ¬ÔòùF`áÎ×~ì³M‡Õ Ñ ÇzW3akÎ~×t)oÈ‚T3ø]Ú s^»â\ýÕûYð÷ägŸþÑ5×]ws4ÎGß•¥–¤ a§ŒBNÿ‚çvIuUÕ-Üor¨ ÃD±Αդ¸P®›Œqzë>€{Åçš±ížCŸ¾Â3W+@â <ç•€€=”MíÈŽìÈ‚àsÚF‘Ø%wÆËÊõ`~ýdÔÓ]dQë“”\è©2ôø,”Åݲ(Uð’ŠŠŠ¦8@Í­Wï pR)DÀ©=@áÖunŠÎÇRŒÁe¹·GËršÏ’Q™]ÁNç¦Hòwh±GnÀpY‚ý@ë㺹l-‹Þ„ÁQ ðw@§v³$| Ä&8ÇÊ£°_É^šŸ`d§Àe2 Å…@Õ8Ö•²ÊæË$Ðn®ŒÑsË!J®Õk&Ç7¬S!NÙ +`9slØÀÙÉ‚¹ò%œÛ pVó oVúêJ¸ú/Ê"ŸËqïJb﫺ªªDÕ»£y Nï½)äÏjKqÊ^eM\j].Ϊ‹Ê®À º\­í†î:†ûx,â=eŸ¼Ï9ŸJAÏ‘8ö›ÊØFç «z¡c1N©t 9 ¹I^}‡†8râ(žË;Ü÷:œËç»N_,ëTÒT]UÕU^Wóã6öÀ5²àÂ*tØã|¿ÓÖù_#‹ü¶—iÓÌwä¥Á^r[oôÌpžÃ&¬'ÞŠF£jljjnljr:y1ºhç}r|{¾N^º E|?S“ùî‘<³Åì‡þO¿’±{p9ï9«“é«Ò]Û‡sZv ŽyOþ¼ý8ûlç3Ÿ÷x¶cÒ8]ÐFòœ¨õûµµ´œ.<Ãxé`sdÁ°£˜ûcØ ¯øäa)÷Þ‡ÿÏåµRm³Q E‡Ê‚‹c/ï0•Ù‘Ê֜؞O/ Œ“pÖ_ǨøX—®ÑÚØ ƒn+s «qãÆ%EÇ—SXYY™#Iq€ˆØáçY‡#e4ÖTG×:GMYŒ3~/Š7U§6G :W†ÄwâÚE²ÈÕ=?‹0ÚW¡4›äEUš0x¶ÆIxYFÙ<¥ù¬,Rùu+×aÀýFÆ\Øœy/ÕÎxÃ:]m]KÖ œª2¾ë>%‘W߆òÓ·†îw\û‘v€Ní0Dê—¯/¦ºmL¨ IDATªjY*Ì)åáðWúšï•#/_Û9»Å¾—ËáΓÇrŸÍ—Wø·×~„óÙ÷¾Y^´Ó<«óýÎ…E²|óoq¶äïÿ4øBiHƒðKY4}@ |ÌL”ÈÃ0ÿ3C-×¹AF½Ou÷Íš¸sa=\T¸‡|cÀåõÃú.]â#â3œÞOdiA€à0Ü%éòòpØ¥[äâ0Ÿˆ #+@iÁéè|*ÄT£àæî¢­.aOîïqì¹¥Á9|`âË8Ï¥}q>ûîï²´‰e*çûþö óX„“|?ûë œ|?Cä2¥2/Æ|·côœ„ í|»J–ÂÑØ~5ûk{ëÞòp¸†5ßÐö8tç0—Þ²ÀÀ/*O“¥Õ4ËKq`ÚÞ{·ÒÇ<ëœÅDì£"yEz‡£ ‡#s»"OxßÄÙ_‰žüV–ò0ûa¡,âíRa›;ØÆ ¢ÏÏÏÿí?î¹§'ûc3uÿ]ÿŽŒhÊ€np5,¶ÆYßÏ'ws®‘1WÄìӾȦ“yNß WW¦8—\À¥cuûùÀ„g9ÃÓ$­iCö8«î:/ÄyÏ®ü~Š,HS—¦%-A¶üŽõÍz>+K19^›’œÙ‘'²#éárHÿ,/Wö/òòDìá"^Ê¢Õ.+&ºahu—EW¾á5WÕ±aܸqÉ5…à'¡ŒŽRzh AŒ³ß¡P»aÀ<€c;§†ŠsÈÏ’åevçû\áÒfŸá´Gc-ÿoð9Rky-ÁÐ ÈáhܳxßÊ"hÿmA±º–¿`GÉ‹&¼ô2ß“.*hÆÅy²¨A ów-G¥9J_`v&ŽS' õ'¦)sU‚>‡Nœ“×åõO_o Zn-éýòpxm ˜ÃÏ<€|Ο{¹"pE>p¡T^a¸R~Wâ{¿¿œ«oôýŒWo&Њ®ªc è´¨hôG:#\ç1Y4.WÖRÑÕfIWúÒ`äùÁÌó%Sè“D ®ãº…ìϯ' >I““ÔºEO¾ur`ig|'÷s.g9ê»Æ>2¶ØFàç#¯œ<8ð!çýo~vÑÿøûùåáð7-Ȳ2Óå÷8-ó”B×8*úF²T„0÷÷.ë8™®}eÝeòd©÷: $fm6Á¹‰C{¤çª«ªšdùç·É"¡ d̆§¹þ dr_äõÅþVœÕUU=dÑÙôЇ12±DÖ àb@ïå?wUœuÖ’vܱ¿,¥äpæù, ÌW>VF9k]&‹2ÿrØ9I›²/Ï.‡gs^÷ãº[¡<˜™fç}+ääG2–@ï"O6fŽÛòþMhŠU® g¼öÊÓgò¼VË+h¸¾1ÃFKªÎÏÏ¿ÿïwÝ5" ”Õ&ysþE¦Àß9)DÆÎÙîÇÚ.Äú—ŒM¹¼}û4‡3ïZ»';—N²Z(§Ë‚…ؘelw%­LŒý,õäÎYì=äs¶f¾ÝÎeu©_·q½é²ú4Ó°»¦°¾;*ñTèìÈŽŸôȦu¬#$C˜ÿ"‹€Ôc€Ü(_®ìz0ÇÝQݺ‰MJqzûûöYÃk5ŠnÁ¸qãfÊ¢b³q®?—´²¶E±,²2†÷£ôå§F0Ò®E¶NG\$‹ =Çs˜ªä;R4aTœÏüw–WÙ¼àc©¼. e!ŸƒŒyùçÝÀO—EÉžSü"œy²¨×á2¶É`®5'àŸ\#]‘©̽æþfb4?&iI[†ÅØkÿK²Z‡Ò?•{Ë¢¢'ñó §7etät¥|tű]ƒ#±Ê÷,gÊ£Ïoá;cÇ.È‘Ç*(ÀQ)åg™ŒÚêÀBžuÈçP6Ècä8g>P;€à€à^~ Â1B­ÎùÆÈ©fßßc?ôýŒ!¢>இc9gek»Ö2øóÁÝýæâDhXìsvü`‰+l»ñ=¥©•fuUUÏóØÓpŠ_m£nB¬¡Þ›s湄¼šØÖu56ÆÙxEÒôV:¿¸v°mß3-Ž1îOçC²´¶›Ü59ϧ1÷ÄÇâ8\µÈú¦ê-8g},Ïw•¬žÃmò1¤hßyÀP?ôÌU²Vþ‚¦‹yNsœCG~† ïÅ>9OÒ×€-Gñ·î8’HúÚ'ß:±‡/ˆ‰ 2,¸­qi-¾û܇ûÜš5{DÒµ;Žñõ9gŸ]ƾ8—ïž.«ËñR̾؛çPG a¼¯=«Kpõ%jqÇɘYt÷*toºÝ2ñ]@¤ýØï›ì„(õ¬ç7èש²Ô™0 ê5\¸&ß{8‘ã{9@%è0bÁÇVpUëhFÚR^ y³1—ðžZÀ’èʨÑWË‹âËYóƒ%n^JPyOäÖ–8Ÿ·JºÏ1Oà:ej¢#fË"û•‡Ã+œÇÁ8ÎNÇü#EgÇ¥OŒãð Ûê·<·®ÌížÛy€¥ > à"÷ÈÀ I°¦Sâ7²´†Í¹ö³Üßþ3 8z)ßW¼»ç&šÄwn z4çáY­‰¾g´ŒqÖÀýß˺`.Å2êysßÙðålY$»IÆ,¸š5o¤ çã²´™å耻}£1ß¿9àËC’¦úçÀÜʦ~üñšnº©7{ídÓd‚“Ò`‡8ÙÑglÏ0¶KPÈw‘£‹d…y§ÊÒ9¿AN¬QfÛ£wäÈ•ÕHÙN–^±ÎM¾ÖŸûr–w`í×°¿þ‰³0‰ú5¥œA׆s•,Hõ^óÉ—±a~ǾïÂùrvчq˜L©îÁkPþÀ™‰•qäµ_}]–ê:=ÕØÊõKeì©óxŽÜÃõúaZ硜ÉñÌé§Vl:;²# Nl Ã`+/²óírõz4Ï<Œ›+æ"T2XÆÀApNXFªÜ]V·âõ˜tBÖãL‰Ã3 LÄã]eêÓdtÒ ÂC¼æ(µH’kÃu8Ô ®óàÃ×8ÎOaèG[8ÃÎsŽeûhoœ†mYë\úYé½0xúÈRX\÷Ù€Yÿ”´4PÂU÷WÑŸ&£‰¾ÚÎôg8ìšïŽÃ°\Q¾_½K¤X©s”öbž#ä1š1¬ P,/•§Ñ·_¢¾—c5¸¿»Âk.Íg Æ^ ?Wãà­”W¾V^M…X !Oë¢ XO É^ª8o.íÂ}>Ààj™_<†ƒ«Xïþ½L^5ûÕ’êúõë×´õ–[6o²É&¹ uíÒ%?//¯uíÁKdl”é):Ôù8o'ËØ;Ó‹2’ç;ã8ÛäÚåZ7’žˆ±~àܬë?8K gófYÍŠdduÙ÷çpë´ ¬®ªÚCÆÊº[^†TåS7dç©èÅYÑß›äÕ®qßÛƒï\Èý}ÃzúLóKKC………ÁE‹9'ؽ§9R* Œüž³÷ NÜ“JO[Ù<@¥]Ð{£‘KŽý·JÆx˜1ƒ9Ìá÷«}@éOyü3û(Ýò©@èxžG/ÖÕÙOIšbQÍBå.<Ï« ÛHöc¿o+¯Èäò”Ïï2Ʋ5²ëdlCœsx@öûÈÑžü~ŸûŸ,°3ß»N*ûÈ‚)ЕSÐoµ°wûx¬DvÖ(;²# NdÇ8reèê2ÔzµŒFv‹ÒЪ.Í£ðä”Îi²èoÚ¢í-ÐÌǨ?CåH”èµÛqïûã@Õà8݃KÅáq¨ÂÜH1éÇýÏÇè¿O^º†+èÖ¿§, 5Š×Pœ‰FY Šçd¨ÿ8’i¥ˆâõÄ!ùÆíBYT¢JÒâÛ"Ê«¢?£ôIUåápº Iæ/¯ÈV„õzX–v23ÎÉØ.Gà` æ=áxíÀñ´0¢Á÷³>Æ÷3© Ôq…â~!‹ÞÔ ÅE}`ˆ<–ˆ-á,fï90Ä¥T4¸×Áƒ#[mµUh«-· äôë×/W^ú„KUêéEº³O:Ë«]Q$/%Å1D\7kÛY,u3œÊï¥jÓ- Ø¿Gɨû.úv‰¤WÊÃáú¯b¯\&‹º5Ë(õWÐ4'p þyæÓÝo¥`èîü‘ùÔá4<€œªÃÁy޽ö¬,b8?μFD"‘ð¼yóþ~keå7 ,ðïW«¤DëÖ&q̱ßÒÔ#kŸ’Q½WûÎŒÿ\E%E»tîÌÍÍ,Z¼¸5g+s¾ÜÏá8lù²:×Ë+’ü}Ûnœ¬@ÏÆ…nûS·r¹ÿ›Ïjeçÿâ ‡X—ïÓ‘@Q(*mnn.ŒF£Z·°l¯Αc9ùë½dQàe’=8ãß30Ò`‡8ìJôwgl ²ðKœÑå<Ë&ßóû9Žm£Þ®&Ô±²Új ™*«]ó‚¤elYÝâtA<Ù¼%Ætdú0YZ×Hô.r§F^‡˜|öûJ‹õnYJKkà^¶Ù^ØnS²®QvdÁ‰ìø1†+ªu‚9(‹Ú^Ž‚Xß"dÔä“d(ñ ™ÎåÌǰÿ=Jäpeæ˜ÄÈ‘±=Ž–¥| `-žÇ€®IqOüG~ŽŒ6ÝIíý-Ü,Öâ Ô»åµÛ0ˆÓ8ƒ÷=‹ñ—κ ± DÖÁu;Y r·¤ ‚®Ðß•(èFœ‚kԾ}/×Ö«”çø&ÀÓ$žñ6¼ç >³F½½c§ÖuT®sè'k¸Îí`öD®¼â««p®¾Æèúº´¤dþàÁƒW 0 nÓM7 uëÖ-· ?uAAA°   / ÈK5ñ׺pÎd™¼Z)®¦hð§¤øSPüi#uò˜KCæñš)éòpxI;Ïì­œ§Ëq2#i<AÀ´ëd4éZöDey8¼4 b˜Œ!tÏíYõíD"™œÇ^²T†rîñ^€¥)Èýƒ6çÙM’19>ôé©2³à(žÕ8™ÎÁtVŠ$•NÑh´„ë»Ú&~g9ØÂ|\  ßyMeŠ´ðû¨ZNwŠ÷7÷ûö´ëRÒ ¯¦‰c)5øÆˆ<ö{u„;K…ò ÌæiÝÔ-Dzª÷]+ž½ïý…K›}ÿ÷¿\m7àÈ|dصȆtȯN×­´Ÿs¯ÃoÂ1[ö3#bG)ÀD7ý9íIÐå<‡.<ûÒ_’Òñ¬/“²ÀÄùº¨Qkf ¼º›±TIú¸…ú2éËÒK”1rãé‚cJŽ\øÑ<£A8¾ÿÄ`„×1.Îe ‹dÑÂK$½›©ªä­Œ<€§ÃeQA<‡iR®PØ<À“pô;pŽæÙGÆäÙSF•îc—'û%ûáCkc±s¨ª«ª¢È +¹_WFòØ5þ¬-9G~‡È1?ØàjI,ÁX[Ä–ð·ò:Ô4ù®Ms÷–_/“ø›ÆsP$cÐüyùެ®Â‡ ž—r>òµ{¥¬•äš瑃,ºãy†Œ>1T·§¢2FË~²T¥Íy. ø²~ÈÛgª—~Ø=EqÀ—TH¹Ô×Îѱ‡œ“ÝK–Jøµ,ÕÀZ·…l¼-9q@Ú“ûçÞsåÎÿÚþÅmu‰ñw‡ñƒr.%ÊWˆ²ùâ¾·Þ÷^Šø_þîNu¾ë7ë‡V"¾ùÇëY1Ì?§Q–•Èk©”¥Ì]%cÞç(gÉÒRËé‹ÔàLçÉŠ¹6¥ ßo‘:޼Iô{]Úâ62–ÊþÈ–( Ç“èèiNDíÅùí'©ÆÇØ8»f[tÔ@ÌË Ó,ï[¹ìµ±_^lå½'Ê:ÝLĹ–Ó™îÌ¥²‡ 7¾B†×*;²# NdG9=£08‡cŒÝ&Ë!^¾žÎ¹«,êvcXí$7®“,Ê’—_ë3ŽœqÉi7n\sÀÄ¥²ˆÝ\YDîc­ßhr>ëJÊD'YAÆ]Ù×뇈û`€Y”+ Cèó}—¡@ë3}£ÕUUŲ‚UÉ"`µP7cô4'x—Ã~‰,¢2Wyþgš _µÇxé‚ã¬,ÊÒ™ýûNÚK8RÍ(?z3§}Ø+ýq΢²Hõw2 é뜗>§ßÌE«»"và:ù>kŸ_ÉYv)®Î…ÿç^µòèõ®æE£ïÜG3Ì~ikì-K³‘Œ6|‰ÚYs‚õ&£Äd½n”ô÷˜.­9ÝÏ–± fîý3™4¦êªªî²´»S‘ ÈXG Ú i»œïs8‹óÐOÝx–ÿ“E·?TËõi‚8µce@ûò ¤*Œˆu´|},"ž?…=~ˆÏ‰ŽbÿH›Ù–ÚÕþNÆ$¸@–êåÀ ÷ÊóÉ~'ÂDµnú–”hòrî½¹€Ô[BÏꀳq(÷vŒUÔÞáŠ!Wœ.${–{/CFõ—é¿DΖ¥“< (³^ê{ðà¯Õù<ˆW?ì§§$]—@±—,•ëiYÀ£©ù¸£‡Ê˜[þöŸ¯ÉR’¦ÈÚn¦[gu•1 v’¤@ Põàý÷•1øŽE×tfÏ)+àúY-‰úáGFÍeŽ­1]û²n˸•šSž¬=êf²@Ãô¬Ë”?ç‘m%Ú1£'ÆÛq/ÿ’E¾ÕúÛæª»¼üù×dtèØ–K;Êè­ŠhÝ™ß(«‘t͸qãþÓJ»ÐËeEÏfË*†OÕúMIUÉæaÐï&KÃøkC$0ÔIFý[%>¿œ=u)Fà¿2µ§FÉhç[3Ïÿ¦|šh¡9¢)#d‘–]pXîÆ±›÷#8±Ž3czoœƒÎÈÈzœ„âðuDÁª\ÎàœÁ‘8gÅœ…U0¯aèŠ!º[*m?ýÙgý8³Í2æÂ›€.orÍ%òÚDj=Ò1ÞÕ¹‡s†âWiOæ,œÈÑ™µ»sHS‰Œ 6VÆRbísSÑ Eèñ_¢3·Eÿ…äk–ÇØ˜£eLˆ'%2¦Çþ¬ý;CŸ—Õ‡ÈkKœÙ‘'²#­£PF±½úé¼õ|Þ%²¨Ç²¨GKÀ„Æ·’ûrmBýSÀg»¼\·ßVÇ´ NØí(Ži(åŸ2zÄ1¸Çó ÅσÊhß=etïy>CýSÀ¯y²hÓ=²ˆÓ1²Hn:Œ¹ð«·d]Þ-‡ë’¸N1óºãï[cä¹$rê•Ãd9ñ…’nN€þîÀˆ~¬×¾8g½0ú1î^ŒxcM†Áˆy]NÆáZÛhìˆ|®ôD4éÍdÑÃ|díæÈ’“e醩Œ<~f’¦½‚5{+…séœúØõhiÜß>œÉý¬ÿgPëÖ¸p) .ßË·¯7ãÌú;ç¸t×=§»¼:KHüµ)Öòþa2fÔXצÖ¦=ÀR{¹I–Ç¿HM¶•k.E¯\+åÏ–ÕY9ûãLY‚q2ðþzdØšvÈštè^ȱ^<4³‡×Ê+Ê;›ç?“/”—Òæäqsšåi$ >‰DŽíÑ£ÇùÍÍÍG†B¡½9¿®XêW8ßÏ Ç–gºnumº ?÷Ýw]³fMWI*++k:ôCž)..¾»<Œ;ô¡,}f6ÀN²4Å|ôÄ|ìÖ—‘Ï3c.Ó ÝøNKvmœñ@Ó€fk2´¼3°;¶ÅÞ›£ìÈŽ,8‘i.:|ƒ ]Žãù˜: @•k&·LÄ*üÏ’=d»}§¶ÅOt ”Õó(”E?ßV|¿7NÃ2À¿ññÛð³Œ*;^Fõœ–†yö‘|Còõd iaÌü@cgûMQ 1èpÆË"j¿Å¡ÏÃPŒW³%„ñÙãe$sèÍç"¬ç;1¯a¬Ræ"¿ é+£êî ˆÐ‹95b°O”Eö_—ÕX a-:soÛË¢÷¿ðhMòÚý€#7GR}‹}þ®CAŒë>8iýe‘âž8i¥òò÷³Ð„ƒP”¦)5ãèå#w5Š{ûdc- Ã=åápMŸÝHÖeçDîc*FîÄd>®× â,®õ<Éwm8²Ú)—#{fñï_ÉèÊWµ˜p×wa‚Üóvü{µ¼ú~öƒ¿.ƒ¿øªß¹wÿvÖSÜ÷©8ü8®óGžÖtc€ƒXæÓÙQý°>…>¶p¦Ýgrb®ïjRĶ pß®sÎw<‹€oßᯘp5cüëäæº)`ôö8Ó¿dOÏOòÙåúÎF*6äÞ2ÖÞY å³dµZ»^°átdúídÍò ¹ÞÁµŽ“±+ŽæÜMVj,W›¡AÆB[„l™Ãkð žÍ÷YŒ´¶=GŽüâÃ>Š655íUSSS×¥K—¹²4Ê/eÌ“/%­ÍäÜ_Ø´» Cv’ÔcúôéÁgŸ>?*''gå/÷ØcçM‡‘N=CŠMOdÉþ²ôWk©Ýÿ6 åDÀˆU­Ì!•¹Í¤!K­œš¡å^# œŽ­ôxÖÊŽ,8‘ér@vÁ`ŒCw¦,Z·¾çlçË¢Ú'1ßÔ1,¾~;¡\NNÁ¸ÚÐFwœê²HÎÃ-(Í Žq?ê IDATHOúXf…k;;B^¼e´Úñ8RíEß?Å XQ'Lmöµ4tQÚMõY^~"] ŠPÒgbx—b4¾)«:þ kâR…†òþÝq¸ºã¬4ap¾Ç{U¤3(sÔIåé#‹nïÇsê-¯ÞÃKãY”ç+æÔ@2 C½hq÷ö2¯’j:Œ,qàCgžy$Ç|è 0Q¬u#•®H`-÷=GíµYÈ‚%J­NKÏeß»0Á}¼+2ݦçIš’[¢Çj,çr¶,¥é±¶@Öù—2¦Õ–8Qr­µmè¤á°ß¿¯ï"Khbïµg¸Â¬Ýåµí¦ø­<ãµÀT (ðÍ_> ^ØzGñZ‚¶ôýþŸÞ¯˜÷ù ¥fŸCÛÀË’]"cBÍä50È6ÉœÕòätÓ|ï12FУ)Ø-©8nÐ5gpÛð-äꊂßÌ9Å'›Ù“¥\Ãþàõ:Ó"0y•ŒY’¯³ÂúZOçWûï¿|Ùòåß|úé§›?ò裷ŸqÚi×)Íl„V^È™}Y÷ÈïfI /^üäwß=°¡¡a7Ijjjšñô3ÏÌxú™gšÛùÝŽ 8]·¿ŒÙUê{†ÓЙ¯aŸ$“–¸’k @g%r5Šî˜û±2“Z•@=UÒaœëõµ&]vdGœØ@F¡¬ÐÚ%8ú÷È¢cË6}P!£TÎF×ß;PVtm5ñ,Œ¸Ÿò(¹ÜY¹ºyˆŒE2ç(VQÍ–Ñ ·`ÿ­Æ1è'kIxÏ2ån0ÐÍ“© ¿$£¬dž—Kz*€£ºªªGê\öFCµZ–':ÇgŒäË(¿GÊ"©¹¬çRþW}Žÿ ¥Þê+Q§¡s>£n€ŒX)‹ú½*cF|ÉóK& XÌý¹"–¯Ë«‘6fΰËs/dßvÅÚX^a¸¾²]x_žÏ¹tÎÚY4x*ŽÙ·ò(ÒKØ·®ÓGs†AÍ®SbKeuúáÔ_Q/KÀ¸)£¤oϽ݂ó¶ çp¤¬®Å±Ìý1®Ý[¢‹, WÁÙxŸë¼ËžËÅp4ڳ¦w°GɘaKåïõïÇ‹ Ï8oòí›&ö„sø×²–®3ÔjŸ³±F^ŒH °‰2"j½+Hìg£m8îÕó3â»FDé PÈR þÈ»2ðœšddŠ[ÿ¦$Þ¿-ßû Îñ2¦V2`AT––pº¬ûÓö26[¬c8UÖêø îû0ôÃsÌá“Dî–ÞÓ¢±wïÞ«§OŸ~VSSÓ³“Þzk›Io½µFirù˜½1Gâ„áÜ8g3dÀ÷ ’>»`ìØ3#‘ȱ\æ5û¥9Å9ä¢Svdì"c^åò¼¾cŸü``‘ROK\ ¸±³ sóHÅO]+£¹¿8q>@̯‘­·Jú€ì'1Ðuïa@ÏÔNƒ\wœvã ÷åyºµž û?ŸÃ\ìÞBÒiòè—•DJ€H)÷³/²c3~áZ/Ë ¿Î\jÓ¤7ïF²w>JpßÎäY삎Ÿ”¡Ç¾B^g©íe)žÙ‘Yp";’!Ê|§,‡zŠ,ú¿!¤q8ƒñPœßµ²Â‹(óÕÐú€‰eQ—Õ?ñ½”Q¼ÏÃi;E­Óʇɢß²FñöS={n;ym‚û,Ú0šgûûL®1À‰˜Ýe‰ÿ“ôv[Åþˆœl/k-º+Fòe©,¶‘—ï䥭Ãeö”EÇàmÀIs§,f}š“xŽ¥2ªé¯0¬†`´7ȨÛÏÈ"LïÉkïùý™}Øa²hüÞ>'ßÑÂ[£¹'úòçÊ;`"óŠG“÷G€]z­< º¿*ýÀˆ¥8¶ŽžYÏÛŽº‚h_&Ø•‡ÃÕUUO¶¥ÃØî!K?:MÆF˜HñJ²Œ΃릱@Ê KZ™‹«ñ'`÷oæ13Ž ¼_KœpŽÅžÜ¯ëöñzð öDìwuØžàyÄÖyðŸÇÜð×¥ˆžÄ¾B-œ¯ÖΚÿókeÅO“•ÃYÊڽ싩~;£FÆ:ø­Œ¹µ˜Ÿ%2êûl~·:Ž~w÷iCî 1FÉØxçBµ·“É3è‹=±§^ná}Qt[•Œþ~0s89ü6ru¢Òß]åǵ2ÆÖ2Ôi ‚Hî¸Ú:›ËR~vf/u‘×¥gµ L~0àCÀ­–*›Kè„û˜KvcG솬ÊPúF¼;0deº»w!W»?ùŸÿÌ{âÉ'ë¢Ñè(€›H±AhÙ]왢Ì£€'GbÏLP˜ÍŽ,8‘IŒBŒ³‹e‘È¿aL.Û@æ”å­þ xŠ)Ó‚p NóÏ ˜ Ô®ÇØ8Y­çx‡d¬ŠbYšÐÒVÙk,{àлç7_Æ‚y”ŸŠL1(~%‹€­•EŠï.‡W´a,1P.’×Zt’,jJ‚y¤Î.Æ¡~“k\-‹o*‹"ïp1’}áY,•Eý¦á°~ÍÚ-“W-‡yn/‹ˆï&c¦„øîÏeãeÑíÕmœ£¨Œ%T'9áwhüïóƒ~ªx4Îï£>ýš¸‡z¾ÏÙ[…C³œ5XÁœjøéº8J½ËÏnÞ€Ïàž²üõ2=8¡{i˜(ÄØ'¨±Ÿ«ÛÚÿ­œ‡‹òpÔ.UÛuZ qLÿ,‹‚Î@v¼¤–£ÉØÛ“pxÜÜG~ f¯M4ù{'ÒÊýù‹EbÀÿ+ªu™Ù,kKؚ㲫¬pbwt³ëšá,B1€D æì©°"öïñjaÄc†ÔK:½ºªêÑ$(é9€­w sž”Õa˜üyUq½™g›ëû[=Å1€ñìÀ¦Vôѯdì„‘±çî¦C¬•Õ”xDÆÈx» pÁE׫dµöa>»¡g¿ÈyZë²w:tøRãŠØ[KS”ŸO¡»|¿ùQÄ>Ù›`yõ"È‚…\ãmYŠ×׬gCÀòÎ~súw`ïÞ»¢÷“1 ã±#ž•1fËcf¤kýsdLÀáj{JÚlÇv(|æÙgÕÐÐPçÌ·6&òîÇùš‘¡­ó.öÇ(tÕreGvdÁ‰ìH`¸4ŽCd‘Ñ •|žç Lì†Ï•Eží%Þ`b+Yý€Ÿ0!YªÃ½>@ëí6Öz({ë[Yä³µ÷~й+†?§v–ŒþEÏziîñSYâ?’¾H X`±,:p çi& ÄÓÉÞÄ ^#‹åûw×Vl> [.†ÑÆ2–ÉÎp0¸v•×ÊÏ9ô«d´Ïî€i…>Ãê%Œß7E7 %È8*‡ë««ª.ÄñwˆçÐÄvÀ‰—Gï+â½/çs‘Žh%ê3ÐóøY‚Þ™äsN8qŽ»0T»)9ú{ì}m%KaÚ“ç?^Æp˜b ÇQòR8¾å<ü§ æPŽ,B~ó¨Å‰¼E)oí÷`]·²fÅœ“qP»à8>/«iÓª#Y]U•'«pNS r(_^WxÌ…xN”Ï8By¾óì¯cáŠ!ºßGb^Ñ8g¯Që²›ü`£ôÿ>4\"iRç®yý䃫/ÑÒzOg7—¥“9VÃ6²ŽN[ÉÒ!Nj¹Ó–ë&uï»AÆh«Ióù|E¹ß™}ü|ŸqLŠÇyÿ®²z{°ÿ/–1yîxnÈ€| È«ÝÒKÆFÚŒ×@~×;çpôd²c…,°qà㑱€cuUÕpŒ]å]Žò½3 'ÊKÑX›LûbFW#°3מ€ÎwëP„·'²bdlP^Kë‰<«i€5i~…Ø[»!w¶C%Õ544̾ão+khhèƒÓŸŒœ^‰w•Œ™úÊLÁÊ%²‹«ÃòrÖåÊŽ,8‘m9õ;ÈÐâ¡2ôù m8iÎÙNÆZ(ÅèxD™¯ <ÀL<ô3&º²_úhý«µÊR>JdÑÿ¶Póy²ÈÅÊ[ðk&ÆLµ,Å£‹Œ<7Í÷9CÒ5mÞD3¶GÁï °àŠ.L!rÒÈõà kɈu©K1ÜEþc@ ` 7Ũܘg×Çà3Y„çe «%jGÛQ à zÿÇDKXGW,³¿¼b™Ý0Þ]ˆ¤ ««ªîï€ÄÊŒ“ȧa¸nì}ËòìÏ`ÿ¼+K¥˜’¬±Ínƒ‘ïÎÃÍ26ÂâVÎC'üë¨HV‹äYj^¢õ¢úaq·\žáo‘C9+seÌ“‡8ïmÜ[OÎùÑèú`Àuµð§6µTs"È~ê"c@µñt|‚q€‚f­[¨2‘ÑZñÌØkDÓ°§ò:9í‹3y®Œ×Úsu­ç°'\+éÀÐ[2–Al¡½œ@ÓØ‹‡0‡ ;,A˜Z{âIœ¾×”\ÑÁµœå×ưOX›Œ~}m§ìËg]d?öAÆÅ²UÖÊ¢à*uV­£úŸ"c (cSø÷ÞÜo­Œ6 }õàc:X ûs’ÔP\\üç»ï¼³ 6ÝA2V¢+Ý(c­< ñ.¶JºjGø™"c—ï%cЏ¶ÚnO²oßwÅ…³fÏ~Ùðn’v¯+àz® H¾5v”˜Ó#²´¥#t²];²# NdGÜárêÇñïûø÷†VMwsYD¥ó¿·=NV+Æ•£ÐpT”EŸcbÕÏ`Ï0ì"£ý߀a· iа-E^+ËGó&Î×$sáËdOˆ5|›÷ûù²ô³]d‘ä%qûÖ-dí®·D¿œ–‚¾p5òåu„iíó“xýGóÙÖ¯=r!úö œú]d)s9'°¥Z@³;`JOîkħ¼¾EÞ¸®2Ííd ¬–±ªž•ÕfzCë2žÆËØ|‹‘Ki®ýà çÆí¶ÝvÂYgœq)²° ï©}‡zº¤ÕéL„‰ÕGàØ_ƴ鋞ŠÈØ ï±¯ÈRVümµÏ@OÝ ˆ$»F °Ë*°©nQf““ØSû±×*;²# NdGŒPî#£Õ‚#3V†lÖo`÷2`¢O87µ,8ªmŽÏÀÈÃ`-Á@.“WÙ¿³ïå*üÊ£ÒçËè—ýL€‰Y G¹,‚un‚÷=ZF·þ«£œGe¹ÆÇÈè”[0òçÉÚ’Þñ4çkÊ0ë‡bX¿‘¥1 ”µ»B ¶máše2ŠòYÇ +X°pa0vOÃtýQÜ“0|îKЈu´ÒÁ8gƒdLŒ-9œã¾RVìQ %Ê|Ú–Ö1ÈÙ,cß E7cþa|iÝ"‚ŽÎ¾cxº,bû†ù< *×ê±Nõ=ò#Ö®pU>”YNv| €ø…èBgÍseìkÙsoã<äã´]¹RÝ{Q çxŸ âøÇóÖ="‹|~›(V]UÕ‰syŽöý’./‡¦¸?ó§sfŽ.‡¿ú‰Ú=aÊ‘7"¯íbÕ‰g¹B?Œ´ærýú8z(ê›C;çVôúÃèìdS Ñ7'ÊØgMq/¶b7Õ³Ÿwã;_k‡­à™`ól<ßÏ~$ –¼„¬Jß,‹Úÿ“yLHÁ ØPFïRÏST„ÅPk$= Ä©|SpþFòŒZ2þ–³gá@<Š£s2PÝÃbSœ°}0 îâ<-H%²CTvFûö’æ-Yºô¿Ñhôpét —«îÎA¼‘+¯-Û–òŠ •ÉiÂÐx›½PŒó¿%÷q*¯÷2)S|Ø2ÛaSw œÔîÌÍ+t¬‡ÕœÓùÈ ÷ràƒ+Úð#ƒ‰Ž‰“E©B°$^Nñô‘k<’ï@ ×F Ç0Y¾ù¯x6ÉXY_)9ʯë¶ñ+m¸€3Y,‹|>‰Áý¾Ú.ì{oÛÉÒF°_.’ôL²ÝJ|×̘øòóØòpø‹Ÿ ¾È•uî¹A–Zö5ôkJŽÕèjˆ,ˆ³·Ë ¶N44øæÑƒy±ßîPòì‚<ç3ùì*dóßd9.nÅ¡{GÆ Øñd;×Ö¥-½ î-cSœ é2†Ð2Y¤úYêËâ¶ÎL¿:hä`› ‘1b–Ö=ªÔÖÖÎq'À€Q’öyù•WvX´xq‘$•””Dþõ¯ßÄq~]°&Íì—†´£¬ènè,W€ÚuöxY/•1EÚ’ç!tu½ÚǬú–ï?}ÿLžyD–>w,{õI­çLËìÈŽ,8Ñ1ÎeyŇše‘ìëµþwãṗ"”LO “qˆ‚²œÅc€—ïÛäš0.–c¨®’Eqüþ—òÿ^þ*ÿœà>w Œ^9’ϼ‡Ð}ãó§Ð£<€R­dÏ!û‰Œ]q'È"Ñ‰Ž¹8‹C›æ·òÞµ85ŸË"sWñ<þ€ÒM§ƒ\$kƒ6‚g}±RÈË÷-pVÎÁ©zRÒÅŸN›¶«¬ØXÿ4ν‰=ê i:¹°ÆÒ(Æþ8ö9œŸµ€—Ïb¼Îçù¬bm»bîåHÔ1ºÒå öfŽÛrö7a®…ÜW4€ø–}ñÒÎx­“ ëy›ÐD ËïdŒ˜buPÝrÔÃiëÇ_$ib+‘Æ€Œqó;@ÅÎ8——"3“1VsÐiG`ì•W@v¥¬ÐâÃ2öKC’÷V†#z>gþ9îmfªûvÉYÜëb«ãSý´F@Æ*¼'D2zþ•- mMø93Î÷ìÌüo=[ë“×+˜Îãw©Èê]d¬¼™²èò æv;ÿ/ŹŽwöêd`ön¬Ë«J_dºIÖân£g ‹ð`äïAØwoþ½-c$u$àÂnë&c¯ýBÖNx8²[è–CØ'Çê‡u¦’ÕùìÃ]dEwÄnÌ‘´ö³Ï>‹F£QIŠÖÕÕM}ûw½ëž{Ö¤Y>æ"÷@NŽÍ"<ƒçxMÂÖ©O¡Ò̽v•²×†%kw6ÊR=-cPü/CÀÁ‡œ9?_f]³ìÈ‚?ßQ€£3cîs·7´þDùý…èºà„ „ŠÃärÁóäõ³~ åÜ“Ï>Žà_‰¡PëPæ òhîMúaKöÆM(Ñe”äa¬ïò¢#«et¼çdˆüWíQ¸?ò‚Y¾y1ÁµÊÅ`ÆS2{m­Œòy$ë;¿÷7`|} ˆ²¿,êy¿O×Ú7ÈjšÜ+ë:E—HÊŽ€)Ûa¸Ÿ+é :ôgÈë¸ÑÞ•W£ 'gé$µ´¯Àxƒö3^ 0xZ2žVX(p¾ŒF}l2Î2Q®dÀ&€;`toŒãWâ0| €2ÿ»ô @DõÓAÀ™†Žç<£¡€€ûó½·Hº¥<^܆Ú0c(úXY4my÷ZÊž Ö™ý÷*Në%–¥rnª«ªúÉZ:îì›ã£íéÄâ&®`^ÇIz¿L«\]>‡¶ Z'KѸ<Žƒ½x%ò.Èž½\Æê:+ ùV„,îÎýÍ‹ùûPY¤¹TÆœÑÂu†q?MèÃo:@6e ô6#ûâxæ¢?Å&™€3º6‰çåÒêúbŒä§‘s9Ûuè”ïÛïÉ€ä¹Nvs½½xf3˜çŠ6ô¨KÕØ 0`sƒ È}|Í}½€½¸¼<ÞÙÓ 9qŒÚnmÞÚyÌÃFÚ›p7Y`-‡ûþšïV\¦ÞN€;ÓÐÛ#8“keÌè[´ÙȨÿ½=C6ê@YªQ `ÊreGvü F–9a£;Ú™8roÉ „}¨ôw²p†D¡¼´‹~2Öà ­Ûư‡=äûl3¼kQõ Š{?g¦ÔÈ+Bk,þUFI»XF]|7CÀÄ_eTÉ·KKKï¾úê«£B¹ÕÈ¢ïá @i"‹ŒÅ)‘ò÷ºLë'z\ÂýþBÆ>¸& `"(£»Ë覩0 &³/ö`9šá²‚ŽŽ?þ&I3ÆŒãWø5/£œD_%+Ö.Ú{ªQxœï_c f\*c`Ä:”ËÙë½iéÚKYË¡œ“;eçtîÁUÿ/"ƒkÅ`÷W±Žæ§œ¥©Î+%ÕýTA î"ägoI_”‡Ã‰¤Ü Döx/sËÁè½dŽûøòpxe+2`cdÞ ÜÛ à·ÐC¹h‡ÈcPå³^D®¼ÁÿÓiðO@f¸4¾!ÕUUdqì¶Ë«kT*¯¨r™¼bÊ]9ïKdL¢·Ûá äâ¬÷–×FÔuqÌÇlòéʈ¼4ÇÖê€8'%ŠülÚB¯]‚3ÀIºB8h¯QÌþY. ª4Ë¢Òy ·ãt6¶ ƒ¢¬¿cžÝÇ><\FaOôœò —*>Àþ•ŒisÎVK²n:òöØ)gdÈóë7‘³RÂþù,²¿=sxðÏðckh­o¿¸zD›ÈX#‘7½åµS^#»ß¸œ*ð^˳jIN’±ž~Ãy¿·•½Ú ½²3óª—ׯÉkó9W?l7–—Ò¸P)’‚ŒXægGDÙ##^gMë2ÌÜ›.i^ è¿çÈ‘£ß~為ºº¿`7]‰N½G^:Q´PòqƒóhÎH&€îÙì±Ã™ÛYw-;~ãçΜȑµ­º'n>NÙ¿”ž\d×Ý¢7FñÖçA8RPæ®3†«õ° a1 IDATVóa>Bû;€‡õ5̱ù¤“NjÞn»íòåѸUTT4¶á Á2'p^šÖ4ˆqY‰Bþ`³Í6;ùì³Ï>–{ªf~ÑVÖ¬/‚x´ŒnÙ¥¸LÖªêE”óL·?ò>ÊÉ>à%ǶÙ$„‘J錌Î$ $iüøñýe…³¶aýD™RˆÏž*£óvÂh‹ãÛ!µˆžnŽÑ¾çá!Àž–:#”±/¢ÜûÊ4MçYtêß²¼ÿµºm©‡cq¡Ún×àyåpêõ Z»×€˜²ˆì.>c?$‹`Ý€a[&c4ÄY=0]FeL»Ü1È…qHg´dàø‰€T½0H¯K@ùì(Ã`'äÀZGp(æ)C),ÕUUEÌs7ÅgÄ2âùŸîk@Ï'ir{ö4Ï£„½ãX…ßÏH óIÅ9Š´0ל³ß˺;àÌ^ ‘®ºM³>‘1›ù®ßÑšŽÜZFwÿ/û¨‰Ï×Ö™ ¢—¶8ÅóËcÿ¸b–/pÝ¥íl±š¨,JêÜØØ¸õ-·ÝvËç_|±õïN9eñ.;ï|Py8ü%ºw?ìô2óIìÕÏ[Ÿùœm7>ÉÐô÷Woã0ý4j³eGvdÁ‰F/¯1£Çqˆæ¤ (òdqw„Û8ÕÃd´ÀRyy¯®ßw ä,Zþ cÎÕŸÒj®¬¬téÅ(Œþ²ˆî¦|O?J£¤#+**ÚbCäËRN’µ•<¹€L5=Aî&‹ªQYYér]·ä~o”ôXEEE[N¤k¶#Ɖ«Úœƒ»Co"‚ûkÖµ#´ kw{ç`%—£Ô¸VF»›âüƒ²š#›&N0Êe(oÖí.YtlQ Hä9] ¸´JFuü[þ–Œ‡Þ8%aöùû°o·BƒFøœm”¾žàÛpÝdQÜLFîú.­’EÝWÿܲ¯˜g)2n, c{dÜÆì‹r®c÷5€‰9Iyo"K¶MÇ~ésFî&Èò?Kzº<nÉí„Ów Ë YôoÌ)Ò‚¼(B¿€Öƒ½ùµ,BúëR×Ï,Çe?yQw÷jD‡ÕáÀ­ò½j|?×øþÞÀϺ ¼öIˆ=[!ÙKx&7àôÔ¤ùûvGN=$c$£C6AÖ¾‹Cé±R‹­eÑù¸VŽ,GЯ»Ê™Øè¬Ötã¡2@ý=ôÚú ó9sÛ #wc Kå±\8ÃSÑ!®FAZgD$«óo–¥Aý@³¹…sš#)š “.€Ôu¿z^Æ€mI„°÷v’Eø÷Àn b3|„ù*×­Í4Ž.)Ä&ØUÆÚ!©ûÔ?λ­²2w‹-¶øúw§œ2òŒ³ÎšÇ^+AŒAžuEv½+cF¼ÂýøŸÝYœéëñ2q_…|÷0Àž²®kvdÁ‰ŸÞpíA¯–E4¾ÅzNmÓ2ó1Ž]o8ŽÜ0Y´¿ïq,ˆ58‚ßÈPõ©òªà×È‹h|¯0*++]ʇ+”´)`ǦÚòêLåUÜ_#£N‘tyEEE"Ñ÷®²¨ðŽ8Æã”\t8—yn…ñkI½‚Á`ÍÀÿÓ»wïË&Mš´°²²2˜ò®£åIÏWTT$ò!”ÇP G“t\!§©²h›>c SFneñ0Çá²èB2ß×…¹ö”±x>oÇ|Žp¸=ý½¢¤öÄF²¶¦§ñ½sxï?%-3fŒÞŲ(Ú%ì¹NÞQ˜*ÕUU›âT ”1GnôHy8\“ {NMЗŽÑCà+Yd*“­¼ e왞8ž‹b Ë=p¦{j†Sý†”ºÑèd\÷;:LƺÚCßÉÒFäÛYtê]žË,Yä±1IG6àt8k=§÷ãÚ|þƒ¶AF£¿^ÒÂŒðRœÀ ‘ë«eàøÍè£æä_Ýcø\èyÎðGè”H?Ó Ï)‹ÆüNÑO’ÕÓ‚NÜJ8„%c>*c=fb-Ná;Æò3Y`ôôåÈ9·/6Â4öw")‡W ëO’±wbÇ52 üpönk£€u…#ø€Ö¯6îAäT'tצœÁiÈ×é(Scì—Ò9' ×XÕ 0a„b\‰èÜ£hºrîË‚EO «·Ò‘(rÈ$ÛpöFb§ SJšüæ¤IÜý÷¿_ÞŒD"‡ÆÑ뮕é¯ÙÃÃùÝ,øû86ÁZt×;Ø,¿Tj)¹‰Œ°,ÍéAÎA¶0fvdÁ‰ŸÐ½ÁéÅáþ·,*¼Ìç 8EÓù/®¯,²Û'9—kº"FK^ŸÉ¢ùÓì+ùû: ª²²2Ã¥×ߣfSY„° B5ä \‰92J {9Únž¤ï***’©¦{J; ™€Sß°?}Æb/Ÿ“S"Kí¹^ÒÓcÆŒYcx Æñúµ¼î7¥ ô©®ªÚœux]VØsA’Íxkd/yâÛ;:³"²èýª ʧnr9²èÍ ßÚt•E†2—zÚåœý9òR¿æaº(t²ÁŸKïœÇ¦öF§1,tu\NȆì¹þȺ>ü®Ì'ãÄ×údé4äÃgˆh¯a–'‹fœ˜Ÿâ½—ÊÒ}.`¯L̛܂1^,‹àEÞתÝ(ÙÇñé$‹üŒPƽ#ËÝOw ”ìHm Ï“µíÌCÿ ç:¥n(IŒJ©ßÈÀùdeχØ*;Åè|ø~€Œ‘ñ`rߨ|XÖª9Æñ{ }¾‡k³½:|9çüìv[GF\ɾ»–·gŸ G6ºŽT· ßÙyt´Œ­Óï›'‹îÿtYG€æèŸÞì¥Ñìßnüy•,63ñ…¤šòpøYºÆ]€h‘Vì³"lÝ“ei¦]œ¾Bv¿,« ´3gä­ Ýjwìó"¾kvvëgGœøiŒ‡¡#aŽ,çoß3G^Ñ¥zæØÇü0V¡¤ã***^Mrl H3‚û_#/µ¤ÑLóþ(ÙrôÓæE•••}d“mùÛió|ë‘Çw•E¤C2fÉ­2êèJW“‚µ»B‰Š¢žÆÀ™.©–÷æâhÀðÙð ׯG¾‡²šÂs«MÑÉî01 ƒàf%YïŒsáŠ~†=>€k'µ’^2~üøYEÿ±²T”|ÖäÄ1cÆÌŒy{>Fï 3dEÊ&(ñ¢Ÿm.m©!Å(ëÕhG`4¤cä– à¼ÎË |áÿYjTSŒ¶ge˜¼š59y>yårë›äÑêëåÿs…ÝßcÞßè“aQ áÀ×ñ õ)äUàûéþ–ë“«þ¹Õ~Η1fàœƒŒ[áæ™!jž,ÚØO^kÚTöë²Ôå¬÷·Pð²yôÔ&œ­ë[cåF. ï‘¼²vß"WÿÍ¿ë•?ö(â\þ^Æ@ ±—+e ÿ e>ÒŸ+«-² sø:ÉÏ—N95qÀ—8'#[=eõ\Bì{jÇÆ€°µØ‰¤ æpVÎÄY¾4 Æ­3(D°oÛã¸)«!•ôq( WÝwßlöÕQìõžü}ûâ1‰šŽ`H‘JÖð(Ym“2äêÖâY`aaŒÉE†î'KÃ{%‰3¶±,Hs¤ \.F_®f>/²GÓÙrÖo§_Žù³,8’ÝúÙ‘'6ü’E¦OкQ>iÝ+xõBÿ aïjA¬•Wáû†3Ît±¼>Ò; áwy¼µ£v&ŽùdzùþzI ßµ€ÜKV\k„r£~‚¤q ¦tÄX{ËZ‹nŽÓ^ /ªéÚºˆæÌùO²hè8ÙQß\7–½…â:QÒt!ÌÊÊÊ| ” 1zr1ºï—E›æVTT4WVV–ÉhzÇ£ˆJäNsÅ•>‘´¸¢¢¢Á瀔áÈíÍšm.¯"y€Ï$>ÿ½"KTxˆkV᤬Máì(c <Å¿ÓA}¼‚õ<¹µ:ÆŸ‹Q{1`Ò˜1cƼÞÂ|ûÈX/ÇòÿGQ”óõã·zu¹Ÿ§Ë¨¿é’í P˜‰Q†a3 ãç6œb?;¡³Œ…Ð[Fñíÿ»sÝ"Pà^]¡BÁB)~áÂ@ÌóuÀ…/¸á¯/°y±Ù9›ó¶ùö}7¡!-¥P…êÁž_œ‚ÀPÅ~û:Î}Ë¢iÈòö›dõ1®EÞøÏ{ uwôÔN<»dÜý2¶ÄêDRŠUvóW®{FЧÿÜ~ÈÕº­5Ý{ü{Á¥ F}:°!Ür@~Ô§##1¯æ8ûH>+öþÜ{šÛ¨=Ó‘vS' æ\‘ËE¯ê™X]Uxð¡‡ú¼òê«ïD"‘¦ü¼¼m×ÖÖ®hÇyX'¥Ìg;Ý%Kóû#÷ØÚ ʺqüI@¸²TÆî8ðæâ$@†¾œbôîçÊÿz_@v½Œé˜ŠLÝMÆZÜBRÝŽ#FÜpÎÙg÷Dÿ¹ú‹Øß"Ãj:ˆ!ðÉÇrôqgdÌLÀ¹§ÐÑ«Z™ÓPYm¾Œm±2…³ïжï!Kgá[Ÿ%Ø»Ë+Fœ.™5˜sºˆïζÍŽ,8ñâ~ƒ+¶E§3Œ6–EÖ–!âa¢HeJ}åŽÀîòªe7`¨-‹NOÆÁ_$c'4ùAˆ8`ÇFÂÇ K1ç ŸÁ9_QQQÑ”ÄZôÄ:Ç]ÌíL„·kcêzŸ”!Ï÷Ëèä(&²\YYÙEQ<š¹ž,é­Ø{­¬¬,ÀA>›ë£4^ÁÁžÌÿsq¾ö—±E¶ÁHŒbÄO—1…oiEEE³¬è `´7빿sŸÿXuŸ€Â‹Çª(’u99†÷¯VzŒ·2º3×dÑ¥Ó´ÇweO<ˆá0~üø<eqÙ˜1cZhò’®gÏÏÆ}Zé+Àç©€ÏarNUžÏ9w¯b€º±²ÂU÷(…hx ãFùžw&dÒ92æÇÓ€T)¯#F\0fÍüŽhŽOîÅ:¨y>ùòÍ/Ö9u`®ŸáwTsÚ,ëbÐNZPVÛ ‘ïêÉy[p¼¦kˆ-Ì—Eæ.üp ÄÈÿó-1×Êe ¦ÐAÓeÔã'‘MIÎ-×'{s} SP?ì¨Ñš=ˆ âýÛ2ľü „b@‹xÀEÄx5kÝN~6KYªãßõ>=Õ¤uÛƒ6ð³ÞjO*‡“ež¸â‡J áz“dý·•¹Ž>ñö^'IÏ™3gìW]µeYYÙwýúöÝ|ò”)ÉvÉ•6SË5X†¡¯Vã ¶%_‹Ð' K|àØ·èðÙIÊɳäu±9U™o-º!þìà CRµ'† \øíÌ™“š››·“¤GŒ¨9çì³.XÊþx[lE%2ÖâqÈÔÈYØjT­N€µáؘݪö³òdìç3d,æž2&K6ëDldgöçûB2 üPìÎl[ÑìÈ‚?³q¼,Rp,êÁ‰vÑø¾Ì=P棌±üŒÂø ÎþZI­´Ñôƒ]vÇñ=]QÆß"”Ÿ–¥{¬ñ9à‰Œ"Yï¡'Nø$œîIJ¼"vð)2ÔúdÅ´F«¬¬,ÂH?Ÿ¿]"éÁŠŠŠú8÷'£Ð‡QÝ—?Í€yET+¯“ǔ֮2š¶+~´ äÄßwº¢|=X‹_É¢1®åU­Œbþ?YîÏ/B2Jé2F+5ª¿£„_.¯ºzº ­n( ûÒ ‘î¬Ã©¬Ùc8Ù«c”©H(`ÿ• ug¾=Øß9_ż¯G/çå^!ŸÓíg8güï]é =ž!KÙ9yî±3h곬ømÑPu‰»ÈkÏ<˜Ÿ’tUy8<#Ëí&cK9ÆRº m× ø2äQÙs „“?9范%6g_/•uG¨Fw¤\‡T °Œö,ý0¥§)XjŽyE|S,h˜#/½'_3ÇÓ­ËÔÉñýÛfýÿŽeòøˆó;ÿÏD€ÿ¿—KÚ‹‚‰ÚI‘÷”¨•±n“EJë:ðtõ$ƒ?š:5rë_ÿZØ©´´zÈ!'Ož2%•ýì ï¨ø…Cìã3diŒ×$ _ d@öoÑå+d Šj¾#ٽ݅óÔY™íZ°îÙ¼»â:%ÀžðµýÜîՉϫ~øáëë냽zõŠžx K¶ÚrË—‚&©ƒjH0¯|Y€ïpöÎ@îo!gî_Øvɦ‘ ö’g¦Ù— ±ç7eÞ‡aS î)À”/ðR‘í»ËOoËRm³©}Ù‘'~&#W–÷½»¤ý+++'˨»‡Ë"\ýd‹<„ BnŠŒ.6M–sÖ*#"Žcî"!ÛÉrÚöÃÊPp‡ Iâ—bPý k÷¹{½O–R’Š ëP²=ÀCe¬Rt8¥Y"C|/•4;P[¤ÆÒ ²1¤¿À~ZVü³ž÷²^;É¢2;Ê¢¹<‹eí_4?ÐqŸĺÿ‡¡Ã}>Ê`±¬ðå<×)î±Á2VHŽŒÁ1#û7(+ù[YºÍÓèxåúœ‘€…1XË0:]$¡‹l(ѺéÎI‰ÊFâ8IÎrŽUŽKX RÏ3éÅ3J¤p["cÀƒÛÙ¢i|N[ahõ‘Õ˸_?³\jœh—vÏ>)–×É£çe(†^wy‰C>z¹¤òòpøõ¾ölYT÷YÁÂtèÑ~2šºc*¼-cüÍ^uÅ-wÙ“óQ‹“õ€Œ™³0]{€µ *~ïGªNÎM Î¾Žµ/1¿‚¾ŸÁ8`D,ñÿì]gx\åÑ=»ÒªK¶\$÷FǦcSB15´ @ ,I‚!/@NB 5€CH€.YÀ5ôbz1`š±{·eK¶ÕË–ïǜᾺ^­¶«Ýyžû¬,¯vï}˼3gÎÌä:@O_PÄLa1ÏçWc´x5¥Œgÿ¯¸›yöÜγ>˜¥}¢¬rýŽç½¼tÕÕWo^¾bÅ ½—ŒŠŽJá7èP .N†„Á£é NE<Œ†\ƒa ¿ÆïIõšAs‹h<¼„m‹‚z!õ"fòy×BXOŸ>}kŒ1Êå½ aTìÉïi‚0´bò7£0ÁŠMõX]Ûæڽ ‰†eÎô ¬ ñ}Þwÿ~çêÝ$¬.ä¾xRGç}¤žƒìJú¥zù “mtn¡Ã”M¦Ä@Z—ðj„°¸î°°Êïoç^ü€ïÝ Iw¥\E€íGüŽÎd×n.$¼¤æè|såî?wÙ2‘õÓŠk¬à÷×\³×²åËŸƒ€Æ_CêzÌÎÐz.¤íµ?uãdž‡9\Û_CÛ¬Š“Ù”¨ú€ã¸Çßë†ùñÑÛŽã0R€tÇÇC» žþÆgàȞʹã>àóì·µ®+.8Ñ/d:„ò{!„Ÿ’y‘ÏC}2Ü xip¿‰t¿ zúôé]$Ôœ‡ÐaÚ‘©Æ~-ý›Tl‹è¨gÒ°Ê…Ôž¸÷ð¯-ʘäP!ÿš‡T$òù,$5`>$u%cL ì©Ô}ŽK.Ÿs+Š8_Љ·°`¶X ñÒq™Éuï÷­$kñþ3ÑS #Â,F¨9ÚùØ–¾l:%tËyi4Zk7”ð½ú9Î4Š á6lØHgp ¼ju4Ô1lw ÝiærL§ó/‚Ð~Ó%¥4 òiüoIò‡ARª¦s=-£Óñzš³ØÞ¿²†Ò¬¤þѵR »¾‡3í&Úñm÷tìÖ¡,™&W[©w¶pm¢nÒßéºjÝîT;>DÒL)Ö:3Å(ô]°™W»Ñùk'€9¿ €q"õÛ±ü÷kt’ÖSŸ»š|uÇ#Ôokàòë)¶YÃaÈýBÅqoþB½ÎZú@À²Ê¨+.…0þš ùê·Xà`…´Ç^ t$ëÐ]iOx1€ûº·+¸ÞÿELÃ3Ñ>ÚÀÃU~,e$®û­Þ]Îì–ßsŽî‡¤ Ʋ'ÿJ[×õ¯Jã¤vïÞ6ãþ´Ù ¹¿6B€ÿçh«®«òû3Í «‚0tív7ë@ëTTð Ú‹ãµ Ç®˜ïiáÙñ!¤îÆá–ò/ é wé»â‚}[ÎðO%JtÓŽsÞ#x€Ž§s©m?߃ô«À¦N˜^:Ãé| IÑKÇÔKcd ¨wèŒ/£cm#ØGãþ:GAŠh-£óqŒU„ýp$}b좟¯P /àxµÄ+”-0R§â ŽW%BЀ¹Àíq¤ß(äï4\ÿ ©Æž,Ë¡ÆÂ¥‡ÿÐQÓ”‰A°#Ð…'1ZáGçÞ5Eu`3j¸FtXc8‰°;±ô°!QÙ’FÔFæÜ»é\Ó¯Ò!ݽˆÄÐ 4•s=N¦Ø—A=Õ[ Ì€´uÀ² i˜»žƒ¹^LÖ‚²a´~GqiªÍf¾Öójr€ Í8Ñnß2$²Ñ±Ãÿî§a4øváümÇß)Äì6²… Ô%ˆ^ä6‡NÑ%<#Š!‘ô[9&§pž+ùÌ+ yñÿ!8ÜØ‹ö”ë7hÛZeÕÃ.Z«E1•)ÓÙÚj¢NÒVÜ-èØQÃdT…â8w=ضÀ¦Þ³¦© Ľ§ì1-À[›ý3žÉ×ÓÈZº A‰!Tí8vÿã›ß µý(øLVŸL£Ãv ÏìXRéCü¹):ÇtãŒ`[¶êéõÔ÷¯ yB²`¢Ö·Ø•cñÚ ¿¥ë0@nðSVºSþ I‘š7ïÞ©O‡0`æðrK€i4ÿ}„=J`sòMäYs¤nDï¡Âèy“¶ß×<Ú³V«ì©Ó2v£-¼ÇZêî•<VPÇoàÿÕÃföu×|ú8Ö“èIŸ#vZót°mËjW\qÁ‰^.ùËPê¥BØ@6 =ØL¾–ãó ¯å´ÃUdÓ×==’Ö|,$(2˜Ï?†€ä®¸â‚}HöDdAåëiÔtNSòÀü†P¬õÓÈÑeüÀ/ÒyW§&ž6C=M´=à(PGCòy‡S‰*«â9F ù»ÇU ö ¡As0Åx är\¶ò°ø„Îà×4V껨ßÑ™\LcéH~b¢2½?Ÿ‡¿IÚèn­´ÉPiÜZÎý[n*éŒrœBc ¤ŽÉl%ü­¡°˜{_ 7¶ÀèuvîäÒ1ÕÚ)C©'Æ×êÈ:ºz^µÓ)®å>_BÇl!‰MÿvƒçBZ·Ó˜‹§puÎPêêŸÓ,£ŽšË5ñ2 ðöÏ©·×ø]:¦N˜ÿBá,âóà¥ufôg톢ìae´ÂŽìF࣊æØkñIa‡ÓÈÀב4Ë`§ hÔ*lèÅÍÔ‰Ë`G­VÀŽZµz.–¾ý¤ÍÞ­®Žñ~ïõêç6:xjŒ¯#@Uåû5Õ¤v‘Qg7³Fƒ™&a¦J8/k̬ ­©¦xmàUm\[`× iAÇý]ö…°c>§cŸvJ4ô±<Nç¹÷)„ÑófÅO…´¿:0l|WõV%ìšM8Õ ÖHÝšax%Ò29’Zñî©Û¢í+‚1§ó9GpÝà¡*¿s Cº+$e`=$hQë.ãmôÞíƒþ)ô^Èsóÿ8ÿ&pk®ÑáT#a×îR_™¯/CcË4f1P“‘ "`¢ìÚ\®Á&‚_4ù˜gÇ–8õ¨Zˆ|×îoG+£6xn²÷šh»k¥v4« þ*k¶Õa³ësúŒï/6@”2HpdGHšÇþÍ7¼·7©šÜ-àŠ Nôͱ ¡öÿ€Šä—tZƒ)~îPæûÁ.Þ-êÕYÔ†‰b°š E³¡«Ñ1B¶vëÇzÃÐ gi|óy¨iñ¹oËkt確´Q_b(•õš;QRÑ›<> Ÿ»hÑ¢ê;ï¼S‹Žjí€!-?o‚Ðùãq>‹!QœË8—O@"ckáFtÒ-h… Qƒ¥œ·Ïx ï‹ô ÔŠøó ìŸ6w »sÌŽÑްS.†Áî¢zMõUz¦‘úg=„¼’ÆîJs[aP ¥¸`z†[0Š>¡¨_JCt $útI³£YËÀÉPG¹LÐXë+h½祩ضÆL=¯Ž¦~V»€êX¹ Yü’OÇ|7›an:?<`Yè$þŠûe$òÿT•ߟL· €G!Œ…xž¥ªS?†0?ODü`úüî0$Eei”g/&О é̪Cë#0s¤KÓîY»Œ‡Jo‡¤¿”B¦EÔ!{ѩչʅ°Pª¨GjéàÏær—¾+½YrÝ!èT"ÃyÜü7À®?ñd’†_. ŸiÈÿ RJi½ŠŽš´ÝÆï‹`ýRpãw•Ó×bÚJ!6+÷«Ñ¬ŽÂVk u.æC(ÓZ,.ÀE„‡FCÿAè¥ó°/$ry™ T¼ËûkÕ.K¼Èî4'@öýaWíß„Y»iÓ¦ó Ñ…ñèÁ\¡mÇC ÞÀ°©“—@è±nA¢Ìè¬+¸G®Ýǽ•ÎÛ@Î}:Á -2:„ßß_À ³jxA5¾ÆS¯  ^Ê5@@ÕhPæÃrÎר@LÆW& uÊÍÔ‡ŸF1V‹ y»¿ƒDžê!¬©;ø7gp_ŸB} @²Y$°ë4hñÍvtìD¡‚Ò‚ÃC5š‘êJv¤RäÎóçéX,ü8ä˜Dëÿ°1…Z0Ã!¬Á•¼×TE×j Z-á˜] ¸ü, °ÑûCV¥1ÊÞaBOÐçiÚ ®Ø²®¹„s°ìú_Z¯Ë”Ý J,…tÔÈ&óS[N°˜öã¿ `§gh ¶÷h?Ö"»i”!ØlæÞðÓöÔ¦W¦Ã@^Úú]ÿ]J½Ð°Ñ#†]®çh3ß mÚ0$-ê&‚2wó\ž Ò¸âJ¯—9¿‘~<„B¾B%Û’à8àá=ÿ^Iç{N‚÷â2o&ªj².œ­Õ”6‚°êU »¥‚¦Á­ÈôHôx!^G£ éM[È£#8¨86µP+@¿ÅÃ`>„.×Ë 7”‹©ÜrË-ï®X±âNبûF>ë«hb¨>:5DŠß¢°.U:S²çf=çp£1ÚòóÎÁ—ÛR]›%hL®­}lL}1ŠÄnË±Ô j<{¢•FÓFÀ y-†BÐl8áÝÕ-&R¸ï0‚#‡yñ=/Á¦Ïs·`Ÿ•qtÊ6@¢ÌõÉ~óõÇRÌ_ÿRlyqôŸB·C"¦©)Ãr,ãI€ aLày=;]°¬RH›ñ&OG·\HËï3!íHïrÏÞmdùصk>¤Õ®ë÷— a¾N"q(ü.â™±…vÞk´ù´mf_H•ÍéĖІ/áÙu$`ç°ºnƒ]¤ù)ž×-»OÜ%ïJo—9Ÿ„ uÞ„äáí I ˆG x¸^KÃ_Ös!µ'ÂÜ_²à”ÒÃÀÐÂ@ã 9»ñpÁû=ÞøÎVëa\;'|3lêq"މZzšÎÂëá8Žÿö‹œ¬… ÅP1¯æ}}Ëôp0,–Ìœ9óé¹sçæ˜Óˆ|>#¯Á¿ˆs$‚Tïn—ŒI$_¶10£dA®¹|Îe ˜E¶Í[t87 Á¶w\ëM°)š½U´Ê·‚»Ðéž)6˜c«E¿Ú8†Ë!4”MUÇýDÏmUâ>}xŽá½O¤3s,Ÿ÷]HMŠ9Ǭ R¬w~.8Ñwe ôý l¸¤"Ë*#xp)÷Ô|¯Wùý­i¸O¤ V$Í4œ¦}¤þL”V I|ˆ¯'`ÛÖ•‰Ža$ˆp+çc6÷¡³ÅkŠ:’vûçÑ[VÐæ<v¤Wº˜ðð 0Çsh ϨzÃN~Âà¨Eï, ϾsþÛÇsê4HzÍxîñ!°7¸¿F@Ò¤vå¸|±rÅœèG„:††jWà„— Ƶ<õ:¯·AjXh.]wŠæ«^Oçm‰ñ|Jí.ƒ°ÆÓ©Ù‰ Åpþ¼'lXóªëè@®¡ƒ³„NÎZ6u°‹|Fb(ïZ:ïs<‡AR3…°+ÆBRANçûµ¾Æ2:§‹ùýx? ìâQ ¡É­ S‘§i…0:VAjM¼ŽÔj‘¸ÒµLæ^šI­ ;Öòz>×r ¡†îa´4pMhßõÏ Åi…Ýe¡§‹ÖsÑ”® •Ûwƒ{Ca3!´-êVî•…ÆÉ<Ž•viGïŒHFhỒЕÏ0ÖNæ̃t x{ ’òq €{á·í«ÒNø`K&!p‚E(£þ™HÝòG÷Tùýé,Ö8Îk‘Øt=»‚ž$öØ+Ô«S!Œÿ$ëHܹR¿©˜Ÿýktž&¹R˜óW(®„ËžpÎÏ c^WAêdS´ é®\ÇÒ–,„Œz‘ûïcØA„þ’Þ¦5‚¤ßÂñj€0®î†°ºœF`b2ížÑœ×Vw¹»â‚ýO¾¢1¿ ìÊ¼Ñ”Ì H­Š‹!Qÿ9èÝ'è}èovq¶u4Øž„ÝNÛ8 ãa³# q.FÓ9Òz΂xµüܕƵ†à‚ö£o5œ£feË uò8Þã ´·ý8?Þ ;Z`æÃ×ñó7ÓáØÇXø šÛ é!¯Ð Z7G<ÓRaMäаª‹òž\c+ ¥c9šFÏv¼v‡ÔÙ¡H>GÃz%¢§iaÙܦ3=\“%Ü£éíI#p÷¦ÏxeBÌç^þŠÿÞ»^B_3ìÇ Êpçw$*ûx'kÉ”Å4÷àxnr·c÷ ; äÎV´â¤Ñì €¶.êGmqW\qÁ‰~$T,ÎöùÖïh¨´xB^EÁx ƒ /Š:-T°ë£`¹x1Jw¯1|ÕB•ü·Ïaxšâ¬tïl­Ú»Š~ì6S-°Ùõ°ûÁ·¯AMÒx½RÃÀMãÈŽäC¨º^HT­>8®]|øAŠs!Ñò'éìï@ â:û¸ÊWBÞâÚÑö™é0N|Üܺ*©gFr?Œ"ø mÉòa§O)Q ‰<-à=alа¬ ìH³î­ÊŸc\& hîË ^Cy ⥄|?NŒÓ™Ë„c«ŠJxÏ#!@èØÇŸx¢é©gži°ENBâí}Ãf͉4¡Ý-™–yË㺚 éb5,5Ö¸Ùn/ŒŽ­÷¼šÝNÌÖÛ…è:e¡Žûh ×P<ë96ç¡dS8Ȉt጗ðÞ6CÔtJú(Yp¢R èXØ«ªãxî ‚;S ¬Ék”Óɉ!Ø0ØX·X¡ílµ˜¦”l…ÝŠsÑÈ#ªO8þøq£Fò•——‡ ¼>Ÿ/×ëõN‚t4)0Ö½ÙnØg|—Ï s?{ѱ¿zÄûÚê5p7аÊH¤’N[¾> …DÔÇCXXã8¾C¨´Å§'‰„‡ ¶Ìãñ„"‘Hï5™hóÇœü nN{*s9Ò)à4Ö‹ùßÚêl‹`§÷iÊ‘¦èþÐ×°q¶t¦›ŒîÊÁ~lØ€VWò¤¨_kœQ~s<|dN¢®¹'`Yÿ‹Á@Mý1饿kÚc¶í ˆ,€¥ôCÒ,þÇ~ÓVÄB‰kGJ=„ÝøÏéwᲜ®¤Î qÍxx>ìˆäS_|<¿ö€€ú‡A‚GÜ£«¸žâwlAÿ ääðl: ’º± ǯÀ¿hS~‰.ºÍQGÞIÛämHÁÝM´- êƒtüO?€\qÁ‰~'ªÔƒ"TGø?H4=‡ÆëŸ!¶xô°;¬1 ¥ Ç2‘h¬iXya·VUBiÁ>Ãi+4®bÈ(ƒä°îÉ?¾Y.†Ç¨ðeOëthmuu¬‚YîGž ) øçp bW¯ãž„Ž5a6qïD‘žäá>v´µ™ÎÿrHį˜‡ýw ‘¸iD‚]kEë­Tàƒ^Êv(âzó{¾s×;Ui$ª´ ’Ÿ[IGXO£»‘óºñ†Ά0<ò=qü¬€BÈñ4^µ‹ 8Ôó¾ôžªùªEl`³Š¸‰$éP¨ÃZ»'¼™C;Þt”Þo²GTW´ðÞ–@ºõ,°¸­­mÅ?ï¿ÿ‘H¤˜†r²:wŸ{gÎgs‚{XÁV¯ñs¾" ª¦ðè«þ¬À«£×UùýÕ½asŽw†DÔç\¶A˜h³! ¥y\smU~w:3s¸®¦x¬«5ÃuŸèzHäÇÔ-¥\¿vñç{pݼ—æ³HuEªíåCt¢~©ë3+€`%®–4œ_ïÑ1>Àù´Éú+¸;$’Hðç4ÎË~t”¿ŒSúxîíDí0þ<v«Ï¹tH³~Dµo=´ ö§Ýq÷w3$íøŽÓÆ8Ǩ’Šx$òSÈ®ÿ— x Á•á †+®¸àD?|W!ºoö¾ÑmŒó³Ìh¤+é•ãçd¤FÁxOC÷Téχ´Òžêdj-u*›Ô,«Îáðn†¤;Ô®Ûa:»íÝìt%{CXI_AXIˆœÅÈÞ‰æÝLÃõFÅsØ6ªâg}Áë>H*ϵ<øo‚€“ƒ ð!ÇÚèÈVC7Ëè„-¥±v Q›„!]h.¢÷AŒ5§ÐB¾§ÝXAi7~—®£ˆñ»ˆ¹‡ÒQÈÏH¹PfÓ  š¾5ŽÀÎPÎ[‘áÄ›`N$R¼ŒŽ¹Å]£ >«qïp-%,ROc²‚ÏÑå9Gs­¥ó­ì˜°Y_ ‚æÁ® L3íÆé8:Sª ˜öhp—Ë!Q½"‚G÷CÒ«hJØÊ,¢N݉·ÕŒ5Ú"°Šc1†ó¹”ýc–Æ`Mxd„!ì’žj?,‚ÀgAºhŬ=Á¹OWí&­u4¼}ÂæèoRNÀ¯€cuäóš'Ajtl޲Æò¨Ãv!q$82€ú©•º°œÎòY<çÚú¹Mëƒ&~H aœ¾ý<.Ab+s!AПpŸEý©RLÛc çâ—`Ê?]WÀœèRFGµ‚<l€MIŽ»[³ çÊp:£AHõñ-Ýtm\æy4ŽŽFT é ‡MÕ7)ù¦Ó‚]{c+€š€e­§“³×2[ b´¡c”¼Ýá0…„2P•>s.š® Øfbe|vçýl!ȰRlí~ŽííˆÍÈh‡ÔØÀ÷íË¹Ø aQ­¤ƒ±„óF~W#lVKAÇ è4—r=?I4@CM>¶é”huœ’• ¤¾Ï)öÄc°ëeCt]OGüô¿Â‹`ˆøz€¿_a*‰ì¿Ìõ8Röch<ï¡þYK°ã5®×ãi=C=Ý_A /p?‚º €­'t?€÷aNýì³ Àî:H=•åQl$£§¸ßN…¤‹¸©®¸àD?:ˆ¥Þå/ ù6^.s¢g‹ÀUtfî‚PE»Eh°¾ à]F!=àA#¯ù<¨45E jñB/Ì¢†Zal[_†c4^ÍH|›ùsÀ²Ú Lÿ/åÚ ¡û~ÓEw‡)âOó •©ãq ƒ4b·C˜wAŠØF6V•ë!ÙjÞK®á,‡êp¾FÝáPj›Æ<Ø5+ʸV†Cêr ‡ëÔõd¦[Dc=´pÎWóZa\ëé ÖÃNQ ¥9’®ÏBòTã A§–äml6 ÔîÞÇs–u,„¶^‰Ôݰ¬;«üþºî¸/¦/\阠loc Ro;ë—s G] Ž€P¯Ï!0Ó̽|'€«üþ¦ïk÷ý‚Xú‰à\:_uvè©…¤ÖD2NÂx{ À÷! †‡‘Ý(û›ÜÓœ¹ûº½t%$ÊI7¼/ÊYRǽ9À;19œ:ðYd¨ïIâ£8”ÇßÏ'ð4b·MTÊ!-CGrÍ>cÝF>ÅÓÔŽ@ZŠº©ã®¸à„+q‹VØ7ú1 R<¬‚ŽC#ƒê3fl¢£Pc¼n…M'Vš½:yÿ¶Ê>ì"kÀ¶}âm{Æ«#ùiï@I.¤CÂNêãkè§©74Z»k>‹ éHµõx‹¥)8Q€ø(Êmt¼·# u $º9Æ[SŸÙIéh§C‰âœÁõY›Í’g8ž(`ƒÙ¤™úa1Ÿ[†õ|­5‡fc<tÈØ^0:v(«c$B7’ÿ< B=VÐAÛ…z£ŽÉ)QÎÎÏç‹ð «¬Ü>??ÿuž»Z‹èá4ƒù´‡«!€_”H­†`§¬yu˜nÇ-v×tËbH‘é‹!šÈnÁåvH]”£yOdH—g[†óÜðq<ŸNpLž…¤1œ@Ð!ÖÜËsõiôž —‡gÖ.´·O€Ô7Ê…¤i¼ÌýüÏü`7Üß ¦Ô7àX"c«õßÌÎ[-çBjX<7µÃœpÅÛɲýhpü’ ¸‚Je~Ÿcj@äó(„ÝRo¯!Hæ`þ<Èøÿ‘°SGLEfvðh]x®žõµ°[jT+û7Ãfg(ÈÒ†žÝºËÃëpHÄúÁ f»C(ûùŽy4ÅìŽâ,FDGÖL3Âú€emæªì™Z^[9/pãÛ\}=تüþ£ˆÎ¶’íYv6vå½ÀßRX75Ü#ã|ÿ&~×pÎù½›éxµ@˜B"oËÒ¼§qùT:>Ø5j éd©žAPd4uCA:³ ¥¦c4@˜#K b èlÐÖƒÁ²0 ¿ù¼Ÿöup‚EkÀ²â\ýÂÚ%`Y瘗¬sÍηs,oðt/,~äy¼œ:µÖ8ãj¿ž?ÿ,—0 Âãñ,'Àó€š4>kmƒ« iGZà:Þ×[HoÐÐm^îÑt‹7ŠþK§„ )0Ó Ì…û©K²)K!Ôùßø ¤h`;z¯ø8¦ã¸v.FâÀëKþHìvtÎ-à{Ú¥›T´ëŠ! ÿ‰¼ï ¯­³BŠmoìf}>ÂŒj‡¤Ç%š>6À S¾àù¼?×G_,^êŠ N¸’ b)þt6Ò7\C…‘èaŽâ07 èÊðÑ:ù¼Š çd($:ZI§¤‚¿@ƒh-˜éíÄ©¡c»B7š`§Ÿ¨³¬¬­èÈÔhåû•t8Òaã{‚ŽWóŠD1ˆb[à Ѫ+uX@(¥etúJ(—MÆ\òÿŠŒK©õƼ(sƹfôÙƒ8ÑÊgý–°¬°a˜j‘ÔÍ\¿_eiÏ(­±˜ó±.…Ϫ†·lå:«àX:×K=¤J~B‘’£ºëzDK!ì•ňq‚]½±“»¶O*ÎH1_›ÎzžBc~|0äCÇ¢Ä ÁnùXÄ9y Às©´Ÿ$Øè­òûµnÇgË:Â;Ò©áâ€e=›h«O¦sœ é ò.€›ÒÔ*3ÛÀM˜NÊ›Ñþÿ¨#<'Gj7o~RsfcA /„õx'¿Ám°7—šv}œ¡’œH§ãY@ݺ6ð| Ï—éHS¤:`Y>ëÀªN€õÁ‰ÓxýRð°·J!¤Å¥—gúß“øŒã]éÀÏ‹a+Mä¹°´Ž…—çÝî#Ž‚°»|´3?àÙý*×b{™¿[è/܈äê!E p´!Œ?Ò¹n5W\p¢ßJ$5ãrÄÏ!û•MBM1u|¢E[K`§”8Ùéiw}ÿ ~FŽ(Ã12êˆã爜1ŠvÃùn7@°a`éÿ·Âf(xÒ ).6BSü,CFp @­iü›JÍ"¦JéÕ¹Q CçblÆŒvp)5þ;ט§“2æ3[r¤Šúb©Ž¼*ÇxÓqÖ”“\ØÑÂ|Øle˜@‡F Mf@¾ñ÷y°£Ñ¢‘Z—CgÚ„³õ©3=&Ï0¸‹Zt«8¤"ÔÀáAÇš$æXæ:©µAÙô~Ïû»©±Wò!Eú€øÛÕ)˧ŒßÙhpÇóG<øOw ÉÈw½â0ž>£>©4ÖmȘŸh`›2•´n½ñ¾ ±Çý¬>@¼ëÞcèŒ<êߢŋ×ýáOZ@g)•(9¢·€þŒF{!lV’ÉVÒKÛ;6óÒÄ«™s}¤•nSÀ²þ–³!`Yƒ uÎà=ÝêÐ-ÍËš aDÝ ©±31`Y—Tùýkãøü"HzC¤hã|ôQ …B#DÂápºŠà–Bj×\ aDl€¤z²Àü‹úí„dÁ²%¦rÏl Ü׏!ô2C?÷Bocƒ]ÂstÀ›Â3<Ï¿?ÂliŽâ'œÈÏ®íÙHf"¤vÈ‘R!ïmÇâ9H­ è¹)x;A‚˜ tŽdí­ N8ƒ+k9?ƒ0…îBßk¡ëŠ N¸Ò‰ø ôÄßPI~E%ðÎô]:•ÔHE<躵© 8(-'Ê«8ñ9€RHÔdwIdÑÏ6ÀÑÓ š ‰x¼àõëñó>EüÉ €aÇb­ƒFHŠG$J7‹Ž`²L. €L=Áhí-½dÉé~ ¥[×9er $P0‚ó6vjZ9ÿ_Ï`mmí•\c^$õóðsCQÀ‰ õRToéDø¬ Ñò?ذ¬Ç»J£áßMp/€|i\E7„–õ:$Òø:‡ãY‡â³ÎØ2<Ï 3ø€@+ÈëÔ%ÛÓQOµ«D>Çì÷TF:зÐau⸌‡¤Í˜LŸå\{ûp4¦ñ™•ILÃCÐe?êôsa³6#"Œ¯PWÿõ'¨J Mç|Ý àú*¿}Þ aZà H …Žh}Ž…tbÈç|]—â9¿ ÂàÙRÈÉô,ã\V#»€¤—¶Úv¢GARñÿy߯ðü\aöt½T©3Q¢¿HÑ zÚu˜:þLtîŠ+.8ÑGdM° ‚à_}®ƒÐÉ–ChÛß@ŠÔl€DKZÐûûLÙ@u=:Ý$WDq6\ÉŽ”@"‰j`%ë8zJÀIkDlŽóoÛ!) ã_‡zH¤#ððO&] À¾Ô=±`•v³^Ó4¯BŽÅt—pδ²4 ¬œàÂHÔu(¿§œ¯šjTh€^Cw8ëÞÔó>¼÷þûu¼÷µ ¬‹hgå@~G“Ãá¤CWùý‘€e}Dg.¡ú®XÖ{ …䛦ã÷ËXL‹–u*÷L€g\°¬';I'M‡®À•U~}ÖKyÔÍè<2Pbž/sjñÁ¯›¡p×ÛSŽ÷UÓ›Ä}Òeg)c¯i*Ÿ¦Z6TùýÍQôh*i^:Ò.zÒ‚µÖñ¾f:eû`xq¶¡5€¸¿rݯ¡¾1Á4¨…Ü_3 )Y?F`NÆ)Zã&Ì}Ÿjza ÷ÿ5ŒœgÑ$Hºè3ÈlÇc<ÛþÜSx.ø¸Ös]=›‘©3™\¦AžïA€ÊTî]÷kg)=ßx 9‰usqÅœèÅRÄÃþ H ‚ÈO RÝ ’òq ßäaP£Æ3•…Âs›yx·»C›™@±‘ޱ LtŸOcöEHô9ÙÃ~¦Bwý$¿ÒÉEüu6ê ¹œ^HA‹€W¢…<÷ Ñ7 ™)ÆšˆA8€ À8:ÛC"t•$Jèp9AlöÉåÔœû!ì±uêè,K©ÁÇ@ØC <”ÀNç2 uš…pÛ`ƒ½+¨c×Ñ1YCµ††s#좯íBŸ|úépêU5d“×G[&˜*¿?°¬W©›n‡D„O@”"t,Äy.,$s¼ÀA•ß_°¬_BºyÌàwí°¬?›µ$–•¡âWBÒ:¾èãz©„ÏZľTPâr‚ê£ë l®®Ö_¤þN Œ¹”vHÏ)Ôy‹¢8îc t÷1ÜgÊ&Ò.<…Ü¿³–õá÷¤8f^Þ÷ÝÔ#÷€èl-.àz½–WUœû*ü9˜N×%–'QG£Ê'ñ:Ž`POwr+!Ì@eÝôÔÌx:ç÷ c:ÄQÔÍÿCúƒi9\/“ø=‡£cªF-÷Í+|]F›­·õFCXTÔé²?=1웿sÿŒ¶V+\qÅ'ú¼ÔP‘¥!óW94Êh Œ'P± ÿJHä@ ˜ˆZ,‡Ps?†(ZÇÏv{§$ý…óq=€¹ît›”B*¶·ÑHMæÀôØRÿaA§‡“0\6ÂÎgW¶B(Åù¨Ä}jÿÆŒùùó³Y2¶r ˆ!4÷„PÍw¢#SL'×›‰ÐLj¹ ¬%(P »˜f= Ë?BЇþRó`"Î÷$~¶ÖÉÐŽk`Ã&Ø}´.CìB¸‰Ôͨãý•óùZ“»d8&@ñ€ ‚ݰ¬ÓªüþZÃJ à‡£‹<‘hÍ*¿¿%`Yw󜹠Ú+`YXF§o*¤Ðó|ëÃé*éŸ>IˆòAR‡®äxyy¾Ü ©oAìJÎûRH°Â)ïÑV8’þv¬ÑK!©^8Ô6Ô-°;f-pü­Ù(QɃa½–ÿ{®¥–.Àû)˜ùXà@ˆï{À#)2x¶r¾žâ½€ÔÓx2)ã u Šh'NFúÚZ/„°z'Aº´-3À #éL˜¦3hŸ aL¤nÖTo¸g^¡^ê+¶¯{£R([ ïÇ´¥)GÃWz¸xÜ!HY†@ŠÕÐ`èÊQje$j:ÒÆi„ÑTÔù|;Ñ56OŸA"]+iØ÷f9“ëZi¬f«Í‹x8¼ ‰xou‡ªÛægÓç!Q³Ö$>cÔâjÉ‚¿ãu6€ÇüÛÁ¦ÀQ|–Ÿ"¾¼Î2-u ÌtÅ^ê˜JH.ñdH ÉÔY°sÌ4,~¶v‡uÈÍÖ¾}ç:Ô~:ó‹ÜQ^^þÔm7ß<Àçó ÝFX‡ €P†œÞJHQ¾¿8š‚ä:' ¦³¹*g¼ûRÀ²J õpއ´Á»ßžhØn4pàóTº«0=d4\?‚çÍÅæ@¢ª;˜Vå÷¿ØôÓIâš¹*Žó|w:¹ßå¹ó9¤5à«I¬“ãé|ß »C)c š|[Œ9ô@“¹¿6q½ªs×½tì·JÞ÷JHÀ$^=ZaÝh“éêx¼{y?êÍtT׏V#i*ê›Ë¹ºçѥ蹬ÕK vyæ<›æÏÿ¤èóE&¢®· –MEâ©—Z7b¤Xü‘Ü/C8ö­œó÷©gæÀî¬Ñ׊7)P¹Œö¦4|f÷íîÛæNl¥« EO…äZκ⊠Nô2)† îì•‚ÂÑ6‘4v€P7÷‚DR†Â¦d†©¼kiL,$p±€ÿ6 ’ÞTŒ3Ǹrñж™Ú¶t°ñs1ì°;‚h Í~ÖfŽãÇ"ÎWW2"eBiÛA¢fÉDdväA?Ž ÄŸ‘<Ý^+¶_ IÍJÆþ7ƒ'!ugº¾öƒD†f(K%2ä¡nL½1™Ÿ¿3ïMˆ6®ÿe€óHJÙZþ¾é) š ZÿÂ)àwþ“Ž×:dPõÑ€?œÏ~„^ŸÌw'8‘¨ó–*@1œ€ÙžšF«è –A"翳`¼ß§…/æ¯Þ§Óø8€ŸVùýý½w5uÁ uv^ƒP³OãŸGG÷%$O×¾Â^9 ¼:¥RtlLW7‘Áºª!„šâÐ9#!)GA€ÍŸÐ‘ '¨+n&Àv;¨l[* )"£!L¤—zàš¡äïHÛî»H“Á”ÉÔÞ‚0¥‚\ÛÏÅßÄ_+ IDATxhƒâç}£>r}Êïú„7¢oÙŠ9{BjT¥ XJpbìNÑdOHJØ»ðÕea»Ò£ÅMëH]Ú¨lGÐ!NœPªs ……–HÚ’s0ÅÞ•€ÅÎ<ö‚ä¸jjH £:+h8,… «J—n¦Dzj³ð–vÅ0Á…bŽÏ^å½V×w¶-0.m“d² TÌBšZ/;Ò«Q‰|Ö‹Ñ3‹ö'9’Þô?$—Z3R0p¤w*À Q» ¨dd$¥ã!üaHôiKŒ½r÷Ê“  ClÇý?v‘<­£í`¿¤Ãð!„–¿††`:ªòw&A:jçs~.ät_Ggn6$ç#ê£Lu”‰PF ùå·¦`kÎ&d1¢Wå÷¯ XÖOhÌ^Æ_o%€ð@•ßß’æï«XÖuæHg-€kû 0¡Eƒˆ`{¸÷~Îk0Ï×› ŒTØx>¨Ø‚Î)ß-tÏã¾_•ƽä:ï*h•CÀêN:ͳ!̃åIì Á‰ n<ˆ4u„X–¦Ôw‘îTM0êa‚KŸQ§÷$9•ÀDÒ5çà |‡·ö…€Úë ÁƒÁ›H'û¡˜gÏÞ x?Ú¦E¼ßoŒxT×£ÿ0~=6Â{CZؾšÆÏV&c^ï[³ÚÜàŠ+.8ѧEÛMæA˜‰Ïo§‘½‚†‰—sWD4½] ËQDu,¤“:ô!Øyäõtž6ÒAØÈ×Óo¥ƒ2~8”QÉ æ= âó—ñ¾ò ƒ^‹èi»#Lߣ9²š«QÝØù雸»:Ð ò~5·V©èåtd‡Ð‰}¡+§ŒÅû~›z·–Wµ1N:FãþCý ;U)ƒÐS[é,&êð ‚Ðo'ÑýR/P¨ŸŸÂg¬…´2}RTÌ àˆÞ¢Îz¶-zç4j ¸ÇÆA˜T“ ´ Q¨Lª:}ŸB¢QŸÓqiD†TËa|‰æ68¨Öm¼Ÿs $E#û{tF6ÃŽ ½ÇûOg+8ís8$ª” ¨à£SÖˆìÓ¿¡ãö/êÁ‹|š)]Så÷·,ëy:+¿àí/yÊùöQC¾B§ÿ=×óFH‡ƒû9/©î±~nM ç!uÆ}ôtšöKŸ“Û8QavLç~ø+„í‘J‹ÂuÖÄÚù/bjEÀ²Š¹OÎægv•Žô2Á‰s êè9m¸‹ùÚ oeè{ l¾ó9B_[ `³S éÈS ©{ÂnÅ!@÷¤Hük›úsÍ´A\OÍÔ™æ4~¶ÚËÚ…'ÖܾO»v’ N¸â‚ýCÖP1 ÍÒ÷…©è•¦½‚H›-ú”¥PɃd<¯Qã@B;I,£¤³vE¨ ¹­[hÈ×óÚÌßék-ì‚wõTØÍ°‹ÞéçEŒ×p‚ŽA1žIzîq»Óè*àwšBxÒ »3@+€Ö€eµð¹›øœßTùýn} ‘c!ìŸç!ªD¤€Æ!46/Gr¹ÿØmó`€w©£k!”͇ ´X$ÅÃɦ˽¨tL½§|ÿciðÀµ;Šk9‡k¯áúÂ>ø µ¬CvÛª ¹az=°¬'¬q8Îíüÿk8û@èÂS!íÍŽâ{¶@:¼‰´- ˜J ÅB«!n1’¯‘ÇuÒ’mp‚-Fߥ3ÐVå÷7eá;Ã,ë2¤/¿¿7È@žëa³ r¸fÿIyh!Pt3 ¥q? „°Vb90_ðü<€F:Î=Û¢±ÕV<ÂÔ[—C=©:¨{õæ†3œ 01‚Ÿq÷~<ì’vH1ß© ðy:Ö=a=΃€Ñ´M3ô]HqП|ºœóþ ϤS õhvãÉåšÙÊ3èÚ¡ ¢´£ïÕHT¼ô°ñ`Ê—iþ|íþWØ…?¡Ít„ ÷zWÊ·+.8áJŽN+•Ѐn¾3¡‘ÖBãÿÍ‘…¼4BS-Šù{M§È3Ö‰Öºh2€…:ã2z0… %ÊòÚþ5„fÿî±&kâ":ŠWC"»ÃhŒâk%ìÖle'e‡ä¯Z;c#$?¼¿K)„šÞŽÄ‹Wú »Ói]ˆŽmþ˜Ó¹Ð¶y!‘‹áœ»\@ŠhÖÁŽ8¤c}®0(„¤n”B˜«÷ ¦Qñ„ ±'„J; v§€\ØÅ*Wñ™?‚]´n º¿¿ûr;—A˜ 7@èÑo,ë«› Ç6'_¥qTJ£í;)&A¨¯@Òê9_s`³AÖð÷ñFVwà¾Ý€Ô6&Û+ëÂ1ÜÒ ßÛß ØJØ…\Û¹v.çžÎ‡0|ô\Hw$xÏÛåj![ Œ‡_ A°˜…2w#p´+$R|-WcÈzÎu€÷q º?Â|×B6L:ƒZ4y $€µ;uòFžQ <;÷1œÙ ÿÿ ÊxÛì‚Qe$žZ®©t[ ÒÖ€®S;æpN€­Mîô¸â‚}wüŽ‚Mq¬ïá÷2°(kûà¼ä@rü~I§ðgˆ¿Åã8HM„åþUå÷ׯÇ<ø`Ó½Í×|ú7Bh‘ëÜ­8šFã+HŒ5áåœ\A0áeHÎõPÊZ«D ¡šuK|c{%¸v«¦.Ϲ ¸‡Ïü‚)¥! ‘y„"îá¾làZy•@Ä'&6Án¡Ùc¤ÊïˆøRÿâGÜwÇq¾ª¼°¬‡éLÕ;€Š-š#s!I‹éí ÉiŸBðb$šÙNõ ÁŠ÷`Gé:«qïÿ!µˆc ÁJ®§ »ûì™ÞDÇö”€ :`×xÉ»ìJvå÷ŸÕ[a³7Q7¬¤³ý÷Bmš“5Q‰–Ï H³ŒÀÌsH=•Î)aêÉéöÄH€=Á Âñ8Ê!©6W™íwãh^„0ßΡwqž5ñsN>¤ŽL„ÐT\-¶¾;„³=ÏQ­UTÇq(áߘgçB$ïq]¶»ê¢K;ô—Ô7!}m_û¦vºu,YKݱ3$Pã¶uÅ'ú  ¤áûs:£oÀ-´ØSdw}¼ DNy9‡‡øÍNÃŽ• ð4Çø¬¡<ø×Bò/3*¼÷Ø54ÆÙË>ØMu1Šiè‡8¶‰°&&Bhº9tðmýª‹ªú>:§Ã8Îñ~ÆA49°(«!ìœ9÷Hs[ ÎÕùtÐ,ݺ?épM›òÿÎ1~öb[&™v[ÒôªrH]…ÁhbÖ–ÐEàÁ§q¼Æcïxb¬±õÓS"Ê‹²0×>cj"¸•°ëGr|C"žûAXùQôt3íŒÍԕʶПk¹? ý¯u•þF‡öžƒ¹®àk6Ö{9¤àã‚›Ÿv¡“FpO~úèB/§á¼)6ê…°GÞCöRr `ê•\ï@ê˜-Õ5]q(õ¡^C¸Ÿ´sZàu)„‘ò9×õzžCAž‰Ó^=†¿ŸÃµ9Òué<~Ö¯!u¼\öDtÉðžË ,ÊLó×èTÚ]­ëW!Á’ÓÜùsÅ'ú†xy`þƒ‡Â3<¸‹!Q»ÙjôÁiÓ¦ †ääM€ÝâSs¼Z!ÑôøºÅ­§±œ5k–›»—¸¸B-ÿ7 d2Š{>¦{ü*Ù|k~ÖLgTùýÏdÁqÜ‘ß9v$Ѭ1âlÅêìžâÀß`j•ß¿4ÁÛ+€D°÷áaýFûõ4ÄŸ…D’’¥æ—C œmÇ=úŠñ#y¨o 3ÝЉ®,"Ø8‘Îö~Üß §FYÚÂóc:òµ½ ˆèd„ª¬0—9Ô{Ÿ@ÒYš`)ו\×A"7ÅÜ›J9n‚DêîâkCE5R>ˆÑ>œ“Ý R–ÀNÁ¨#`ñïy.ðZÄ_;`(ï­ ˆ{sî¿mC]·Þ( ]ØØGu<§• ¡öåzžkm€LÃøœ£ L·—¸ç?äšÚƒkä,£¦Âr¹=?¹;d*Á­o¸>3¹‡î€Ôµ:±»kìC®¿)è›iÝ®ôqÓ:;¬Nƒä4æBhá3y¸+õ®À84¶Ð9=ˆþX;ð}ã¨LBp¡Ñà•Ó¦M[¡}¯€D<´û…..€±­!~$W÷SHD6Zg)Á‰f÷¥hà”@Ún¡sš YiϘkã^Ã1ÈuL&%ºˆ¯ê”ø ÇÏküߺ$³C © ïC˜ñ©‡Aê…¬€PvSXAZí>BÐДjØ“i6ð¹K¸o÷ƒÝ2m8 Lp­¬çs½G§w…D$½c¼J:õ¬íÌçxiT–@:_Ô¤¸yÞO7šºílîµU> XÖ‹t6Tùýí¼ÿ5n³8¦'ÑÞ‘Ÿ[‰ÜA§ß XÖ¬ŽqÏÚµh=¯ çÑ žÀu7B±O`©ŠÆ|=–¹ü[eXtVpsõÿŸ!;/Df"Of1]³Ð«:(†“SÈù-1œ› )ÊLHgÕÉHpùŒ '?‚ŽÝ’ò`3°ÌF†Ã«]‹¨Ívеüy+¯ÃéSG+‚ì3S>¡ So·EÙ"bÁ•ñZ‡žk7€OàrŽ¡«Ky)CEŒJØ]AĨä^Îç: DœÝ sð_žÅGQï¾ãýsyÞß^å÷oNã}„yVl"`=›ã«ëÝÜ'ˆNx !Z Ús›ĵ­u-õª‚všª¸™¯5ŽýÔ›EïÜù µD&@3¯û½‰ëÃÇÏ|€véß!-Áw&çÖÕêhÿÍà\ÿ1 à^=×Vqœï}àd(®¸ÒãÄeNÄLœ;÷p:PuÆð€ü’vƒuÚ´i¦S8 BA<•Î’*h„Ñ‘.«ÆZ3–:ØTöfÃ@ÔÃÏlí©ŸÒ7õoZ§F°Ï8LÍ\]5õo›ŒÏÒô€vøÔÃ;ˆèµ¾r¥`9À¼—ã`˦€eé°ð<€uA/ïê³öáð6€“Sù¬> ÖÃþ\ó/ÅùwvÃ8Hîï HžV»3ËV»Ñ Sí ‰$|F‡ö(Hª†fÚ2m ï·!Q©Üi1â (\à·4$æñÞß$U/À°¬Hôq²ïC¨êïXŸÈºdJǽ4"Û ‰Ê­à|§C䡞š)ž÷ €%fxÀ²ÆHÈÏÇŸUøht?‰Þ~Qå÷'ÛR4‡ë°œß£ ‹ItØŠyÏA:Ñ‹! ‰7©Gj >B;N]ÿ):]õDÌz ¥†#:vºC9:w5»&å¡cÄ?7ŠÓãtt0håy±™kµÆpjÔ™i‚]§@S¤‚Æ\˜z};êÙ'¹Fõÿœ¬3²ìÔÿ=UFq>—\Öº(ƒŒ3û Vº˜hw‰× 13UpÕ Xë-äsÎâZܳ›Σ!¬ˆ¯!í§·t¢—reb}ùVÝÄñ™Ã}œoìA8>`Û–ã­Æþj0.eék#„)r!çä HpËdeb/K f€ïèU½ù Ͻ䪎›@½| ÏÁŸPß÷÷ö”Ú+÷ÀfRgº ê6ÝgCRS»’#i<Í¿qSÌ]éqâ2'Ⓣš¡Ródž6ÑîmñY³f©ñÖ¡yÝ:mÚ´™t|´Ñˆ†"Ô5hãV~î ØÕ–G#vÌü§6šAKá:ÿ?å2©µf½ƒvãùM£·eÚ´i[ù¬ëèˆÌM°ÅùɃDÈ¿NÐ!Ô‚Z!w¤L8Žóøt?&Àõ½ »·ÐK—C¢êÐ@J˜È‡tÄ(£3µÂXÓZ¿`e@r ¸Nk ù¾³!̈E4$Û2h„EèD£ð› H£ñ£€e½‰ô¯ÐÃ0o‚äŸICùÁ…­>XÖs›åüœXc"8›ÃñMzwHû¾fó!ÑÜB¾g_Îÿ K–õuç×|ÎRGù†Q' XÖ?nÕÆ‘òá¼÷F^«9§9¼ÏrHžýdh»Òߟ:a3$:û×a5„9ñw:†°IFk7ßr°mŠ•S›Ì„CWj}˜:td#¨3So88u°S!´@¢ÉÑj°$ ôDèœlE÷v2H· ãšX|ÊI'…N9ùäíÀÔ<‚QÍ €«‰Êp®“Uv†îr¦¬läœD÷·„|‹Àê÷ ,Ž»£éÜ Ör aœÍ}s=mŒp‚º €tåtfó¸ÇO@æS&* ¾€gîú(zÓ ›É¡Ï±Â$¾óóm¯çû¹³;R®šȆ~T¦UIœïÿ„ööÁô96ÀW\p¢×I)$§«Rìò™(ÊWs£‚ÑdÖ¬Ym4DfM›6í1~þ.tD§c¶?¯‚Z¿LÃz!N“õ‰2·¹è˜ï˜O‡"ë˜àIØø,5¨ó`SˆÍœI¥k¾¤¶qÔ~˵†ƒ¨÷iÖ>ÐW-Ü´3ÁDúB:ÛÑax*‰Ãq*$Rô.º.(ÔÐQD°© žèÏ’¡¿{ ùËñöÕžÌu°’ë› ÀóHÂW¨àh:ýGñÿÆŒˆÐ0ÿBk}“@b=2@Ýç:)åç·(À@§ûÓ€eÁ½4–÷y ×è÷!ůZ )6,ëUÞ÷Z5ø™ï,ë#:»C"Gˆ9”Ÿ³À›Ëz’ÚPSå÷‡5M‡}>$²û.÷Ü8HÚÍx_%#öåx­à^là÷î i«võÞ‹ªø[ ÄüÖÐZ\Qø"RßDýŸ XÖ=>OÁ9Ñ™ ¼Ÿ7`ܬ€Íž9úáHî÷sÝMP'—€V:2ÝZ9·Í0RÏçÝl¼n1€…FØl4M›p²Ñ’e$äÄUð"YÑ{Éñê3à„Ç㙉DrÇ×|ÊÉ'ÿ ½/å9ö$úu†¢ô\÷ÕÝ8TðÄkǤ ÿ¼ÆCg H »Cé4¿aieZr¨gn§ÎZ a²½Ì¶Îãþ,ç÷¼øÛŸ'+>HúëöîëÄ^i‚]È)µ›ü Öþ5³¾/‰RP{{ŽÅÜ,}oC‚àÄÚ8gó|{Òuó\鉛ɕØãó ²ü!ަtCèà[ Qâ¤3S@òù™»Ò‘8„ηÒk!‘è‡iT×dºþÄ´iÓÌHód:&ûò@-6 ¥3n6u¶mó¦ ‡Vr/æ!·"gÉTB¾†ãq âìûNãh4Ÿg& ‘Ó •¾“Ë€eí ¡æ~àø$;[ô™ ¡~¡ŽÆ³/J i ûò ɳ idž»Ø×X~‡¦,Áÿ³wÞaRV×ÿîÎöBィˆ¢ Øņ1j¬€Y{4Š%–ˆíg_M¢1¢‰£WÅkŒ½co€J•Þ; ÛËïó¹yß·ÌìÎ,³8÷yæYØyç}ï=÷Üóýžf‘o#k‘ߘí'r×o–Õ>Øðÿà¿HÒæPÐÍgÚ!§‡0·ƒø]’¼•Ÿ±ç¶BbÎ÷Ë ¯åì@÷²È°6¼e{é%îé4¦RÖñyHÒÅyÁ`EaAAšÌû6†ý¾›j·e¬dO~ϳõæûÚ¢+–°ÞýÐsíyž*Ÿí/âêR?Ÿ–´<^Ôsµ3ºÿîo,Šd „…#|Ý}…F(¸ 5jÙ‡$Öõ0Y±À!2¢ýöfÜC*ÄÝŽ2ò|iK*ä×‘í®Ø§#Ìá—­ÚÅÝÿ]ºL†¼Ô¤ÿ¥Ç<þä“ýß|ë­þçœ}v騑#k Ÿ…ŒZãŽK—ÉŠ .ÁÖx¢p%{¹²¦7ïá¸,ë—Šn?žyýºó6iyµ,íà|EÖ‚:Ò‘##P/a.ž”¨-Q4p¼,­4U¡·S è†_±‹!âêJãù'vÑAªßqàZ÷B²=+‹ØÛ–DÛ¶=eÎÃtHµ¹-ô½'";7Ë"YÂsÆ¿ÊÿK¶S#AN´ºÑ]ž§p v]£­Œ%-¸o‰")àŒ±Îƒc1â]jÇ чöÕQþî¶Ž£ Jú3®XÒRY˜ö @ÖRW‘¤S§NeîìA“-Üß÷I vb¬–p˜,ã°þ‰gY`Ý,/Dº¼.COó]²0úßçƒþ‚÷Nš,?û`Y…ïpÙùñ€¾·ùwIº, <ã`?™#yÝ*«7ñ‘,D@³9í%› °Nëpò§sýtÑ›üÞZä,s0dÅ2µÆÒ]áÌàýyO9¿{0‚ïËðz—ç¤ÚÊd‘#÷²®šC06`€÷”¥õÊÜ/PN¦Î’nì"iœ¬Hp?ˆ’yWתyáâ#+ –æî‘ä¹g]/d°+sŸ+¯&Gh÷ J£¿p¡¿¨g(ITóà”)YŸ~öYúE^øÙ°¡CïDmŠQ¤D踂b³¼ÂÚ¥èƒù²È¯ïÐËy_I”‰ÔTY´Ó0„QÖy®½÷1¬Õù’žl`¯&q>¿"‹Nš K¨‰Á~$ë>1Šç¾ ðVÖkߎ}Ô=¸·¬ÞD,GoteWôD}©“÷J:}þq#s8XV—hdõ<žã—P‡"bà"YËóÕré-GBýÝ®Ì}ŠÝK‰®‰‘ 'Z•²¹Ræ•¿GÆÞ×§lr '’QÌ1«Î;~üxçÍÛ]Æx‰±¶AIq¯¤ÅM%) $Ú£°NôtãÙŠ0ŽÞ“yU ¦NÚÒy†}e¡ž=eŘ"J甈ý0HÒåu®Myq…@]ŒÕ¼Ö1÷%ËWòþ½ó‚Á•¿àý3 Cr•¬ðá= /=âÈ`#d“«NÝ cú`ŒºÞ¬¡ #ÊÒÞP¯T´ôÄXO—yw{C "‹–rµgª O¾(} iV«Í¦¬è$‹J8Læ™ì+¯Pc ò;½ò×ú_”ÅåÚ@%¯+G:ò¿¢®;óžÆ5E?¼.C‡Œ‘Õe!¯ÃIhUúЊöb/}É}f3/CäEwTûÀhj§'nÁÐþóµ5ÊD…‹¸ºXù’-‹4¹F-µ-k̤pÎpte>ÞôwYû…èËgšñ=×ËòªOUxØš²7.ãÌM÷‘ •>‚«D^í —S$‹^t¿si;®ð§+íÒeÜyQUQQ‘tþ…>RVV¶G—Î÷[µzõ÷-¼v Ox¾Ñ²(Ìì¥4yiC%<ŸëܰЗ;ÖË«Iâ/€íê˜8ýÚŠÕuH$ó˜—±ÏÜþ¯nâZö´Æž-éVI¯ø‹ä†ì±îÈ×YòR^ÉK¯ŠÖH—‘à·ÈRTß–EN,lÁ3"yO–ôû3–¤H¦,íàhÎåkÐ[·³vǪvûíúF>s2{ñAVº– IDATrY´Ýöî™ß›¸˜³¼%Áþ¡i÷#Gážc•‘×gÈöÄHŒ9Ñ F{Y¼ö²üì ¼×¨YZâ!*ºq蟰¥óðÔ©S7‡yd“:BâP Û$ŒŸi²ðüO0 Ê·qÓLYÛQ²"UW7êzBî,ÄPidz;]ÞÓYÈ•ìêh„$]ã0àx7à€Äz\á…&»0íª]à5㱟̫·?]wy·È¼ŒÓdQÓÙÛœŒSS {LŽ`Ovö´bYdÏ'„®¸ÕçáE®ÓчÉRö@?9@_˜ù ƒü#YäÐÖ¼`°P‘ Ø= `» ¿«ÀøZÍšôä÷¥èÉ×dÞÎïGÝda¿AîÃOTø«Ð—Ë«ãîs“,Âé?èÙ#¸F;y]ä“•±cÿQIs¢œb•täI2~sÓ’ò–‚œü^FVç ÷O2ç±÷F±6ŸÈ¼×M@'¡oÔE{$!ÿXÿ%¬å ÎVת´LµÛ:V7#Ê!CæîŽ|µt‘¸gåÕÁ™éÓy®Êt»Cvá,òwŽðŸCþ.YnŸ9r§\µ;x¹B«Å>’ǵ€íÅþ?ò-’5lð¹ˆû]!K+zLÒÆ:HÞó\d¬#ë?•½Ÿ'«ùriÀn2g{> ½X^¡Û–¬—0 ¶“,Rsl®X˜“d‘!ŸÊ"ø64BD^%ë"òBöÙØ²HÈ›[Ê.Þ#¹™€-zO ëÿÐëÊÈçpÇ~2‡Â{2gÆ/½x{b$ȉV1~%¯eZcE31ø:ʼ¸ëZòF!ºÈ¼ ¿Ç(ø\Öòô‡º¢(¨!Ñ£öD £n>Bâ=™wí3Ië·AdD}# «’/ó®§0ëL4ÑPvFŸ •wEEÛ±Þ®^†óÖ/—ô~^0Xô ß?ƒ³o`üFÒs=ÐÛƒ|„,µ¨·¼´… ×9€Šd5#Z$M£°  ½Ì;T _.im40dE. øNtKJˆÞ®DÌ•…ìΜ,‘EETs¶¾³Ó®å§‹ *ƒÈcþÚËÒ#ʇ²ç†É¼ Õ–ßðáàêI¼…ýÀÓ}:kšéS޼r ©ïïå²4Šÿ`På@˜ ¯Ý««UáH5R&‹šy@á±6Š¡ú™€·d^î%¨/)öÞÂTÀÜy2ok äЈ‰!Frk¼ hVß‘^îÓ³Ã!ÿ^´VÅ`%IJj¡” !kßð,{*†ÑõKoB<ø[6ÖªSØÙò S·‡Äì¨ÚEªs|ç“+já#ý)1¡QLÉ>}sDW8kçŠB_ÍžØ$K;ý‡¤u¬iúd"äcäÐ °o^—ײ9`7 òãtÇײʯÔò&–¢W×B|c{ÿײTØ$ìÚ§Ò—ËØ3™w=Yæ@¸}ó™,g¶¶¿4=±s–Ê"Öµð÷;’á ìÿªtÞGì­}äu2KŒÄHq:’eLèoeᱯ„a ¾' £¦è†FBR0nçß +LôìÔ©S+ø{'ŒËe9Ã.Bbã³-kãˆð}0ü+ß%Ä5®õKMÀ* Cº·,_u„Fo~ŸÁ^tõM–C|_0ovÞuaAAFÆYºCQCé…{Éj9äÈëü0Ÿ=ô>÷¹:ZdwæfOH‚¡ìçЂþ2‹ÿ`x/ç^»΀øpdÏ,ˆ¿è5 /î·UáŠ`ŽÂ Þ“¿™dž˜}XGWûâMŒáo!zÉZ›æÉòÑÓBˆŠ÷e^ä3¹n‰¼Ú?Êjí¼ÍuŽCt !%jäET0'OȼL ¢Ý”„÷@\ŠÌ;|} Õ$æb”ÌÃ<ð¹Q17…W×óÙÓ'©~OxäÕá2/õβ(‰Y²t¿0Æp†l;ºp–,T•´àwgz`?D+j#à[OG°»ß;²ÝßÑ+C^QÑ}¦Ž<†5oHGeÊÒ@¯ÁÆ(“…ôÿIV˜7t¯e Ç#ÇièއЫ|rœqó/lœ¯ùÜ7€±d€òŸdé!%²4Ø¿±gZzœÃžu­—¿ñ÷ ÄöàÿE²6Ûª?Šê\YQé‹Y—HuUžñ(˜ËÑÛ‹—>]æÄ;”õ|R-߆w_ÎVW4¶*‚õ¹™së"ÎŽÄHŒ9Ç#í-†wcdC*Fò`™ÅõÎó^Kà?~üø, úë18¹0ñŽ(еE.Bbm XFcth Dê—ÝS;ÞuK:¯\@toYnæ`Y]ƒ^²È×ÚÖÕö؈üƒmDÄzE… øÌÎæ»ßa_|SQAÍ’=e)_#x¦Þš5s0ÿ ° «þDÉhæeFúFIžú.í¢þ‰ÜO{Yáÿ® €òg²H†ÏØÿƒdQ ®vM „@¶,r%¢` d̳².ýÃu©’/T›ªüåÕ®-óìVË›ïNg>7lc½= R¡=zkH‡oêÑW©²z?×@LÖÈ"tn•ôM^0XQÍt…¼Âß±o^S픾Ð{ë%K:F–Šr;{Ks|º,¥¡úïJÖ{[ؽ8Û: sû+¶Ý-reÄðA²¶Þ YŸ\Y„ðÕèÐyÏ“Eª\ IÑTùþ×H“EÑܬF¼¶àø•ÏN«mSÙ‘‘FN}óŽ,-ýhmG­¡#ANlc ›õ[”OyóøšÌÛ°'Æh(a,c¡/„ìøŠï˜ øØ¤(Öràû„˜è#¯ Ør™w÷yŒÎõq!Q—1ógæðiŒç„"mÈIRó[Ó0:Ú`ÄvAÎ\eý^ü®£¼ö}.D¸ÊGB,Áž áŠ.ËkÉó!p¢¬8š«iPÍý¼è@y] –B’€¾ƒ!¢³x‹äÏîKê#*|DI;ß\­ã_£7fB\lõ¥n´—ESŒ“¥iug¾·$ý¤E×üÒaž,Íâ·€‘$™óSÖÒÍI¿wsÒh-槃¼:£‘‹rY„É£ÜÃj‡Ý¹c‘!×¹ Ë~c~ïëŽ,=- #^ˆÌ–y…ö–×êsš,ä7üj Ë{%½ž 67œ?  ›ÏÙ±P–¯=½ …‹’ØGF6á²þ ϳµ™û$•{>ƒ9í `úË>O‘EâÍ\ïaE-›ºãÙ¿ƒ¸ç‘ŠmäF ÄÀUÑS±á²6ê»s¶L’éþu;^溕Wsì…Ñ|ß@q{gakMóÈ‘9†`;¼¹îc?ÑþsÉ|f¡Óû Ëç'LäÄHñ;Æ`|?„qÎfšw™§·.²àxY‹¡>c¹BæÅ[&Ëw m| šBZðý1l7˼s%m®à3.²b³¤Šm\üÒÉéo1K˜çe 1mÐÈPtxì€1Ôù¼NáþrøìŒš]…måuÃ\tUå×°n?d~‚$['¯‚~T " j"íÔ€°3ãös[îóG™÷éIËB=‚€ð›1ŠÙà e©»pr¸p_VQr@ek׃Ïg²&eœ30ΧqÝMü½ ß9ƒ4 âôHË.¾5sëåHÓŬÃYû%–Uì½=e·2ˆ’‡!SÖ56ßÌQgtìi€ž dá@ÃÈCG¾ïw2onß÷'Y]ךYÙy{0²”½ÐKæQÊc^^ãý#Y«}˜‹û$]FªG ëÐŽuÙä¢:±ÿ¶ðÿåFß…)ç.‚á8Y¨ðNü~±,ï{*rÕ\ï~:„Ô…€ÐÖáEÀJùYɺüy;\•w)äÐ ÛÎÜÒªP]Ó ½Óójˆ¤Ûó‚ÁÆr¹»@­h”lƒçOBžfÝÅë]äyô¸ÿYÇÊêPä²go—ôŸ¼`0œsåVÀðfYôÒ]¡×cì,«Ås r{5÷_æ“ï $F[tÆœAÛŸ‡®ó{„b½á:°<‹-yxíÈ:œ‰|YÖ¡n>s4–ÏÞ‰ÍÐÜ{éÁµŽæ~®EŸµ6GS2ç×}§lÃg8R韲º-‘®ÉµìËd]#1äDœŽ3P:Wø‘ÆÆ(¨# uçmî†Á¹§ÌÓ¹ƒÌ[•)/O´#e†¤S§NÚäžã¿T8$ÃøñãwÀ8ÍÅ(%óÖ~͵fdÌpCý®Z>¯/žˆ‡4d%›9q) £z#cíI„Va¸½' q­¯hgÆèá2ÏØN9òj@”„ñ°@³»óàû¿Ö}TŪ›IaAA€ö I5µ¨DEwæá{óöÆÀ4ž³ƒ¼Êú§É¼Dý˜ËˆƒÌåy$Ëd5mž‘ôu^0¸¥0ïôFˆ€áò*ñ;^Žþ•,õé#I‹ê‰ôp<Øï hw2\QÉM¬[{ ý5’/C|œ   È¢8ž‘yoæÖÊzi€ßÄýmаJ‡¹L^®ÿB™'{„ÍHöøÓ€Î yuKö—¥>üKbãv WE®Ý¹ß]±#kw¤ÙIÇäƒÕEêÉù:ùlé¶‹Éè—2u·¬ K¤I™¼z<þgAõ,DkQdðìß èžù€âWY§ë¯”×Åë:düÖb Ïóˆ¶]TŠÇʺúdÉ¢öVl»ƒôÄvêQóRúÃ¥£ý }¾^–b3EF¿È¾¸2J÷”%Kw»†õ{‚dy+²ëºÊœdQŠßlÃ{qÎÔHZ‰úÇPlB)^¦ÄHŒ9—cÜ©ºáŒ|YQ™ã1JÃ%\Aª¡€g¯‘tnsȉ‰ŒN £0°²1š«e _ËB—ù@Lïpq!äŽlÙÒÄzÙ²Üô1·ªù) ñJ:¸š$®²zÖ ‡,ì®ÿî*óeË«×ä¬ed«Y¯Y²ÜôŸ‘«1ˆê3öã°ëÀÿ]ëȯHßpÝ ÒåòZÖÕg¼'¸Nàž—Jº1/Œz?ð‚‚n²t…™çùM8š‚kfO‚ ëÏõ–bPÁ,‚¬™.‹RÚMV!½ ëä:‰¤²ï“ù ©ôÀ²èŒ2ß=$Adž*óh퀨ö]7û*áû_äþæ×åÑ„üèý-`µƒl×èçü‹$÷óýAîÇÕ¬ø”¿½`A6:2OÈ"|Ê>…¾:ó”—Ûþ$Ä‹ÜoGÀÊy<ÇO²h–]˜yaAARÈ=²23sË+*ÚWVVö‘ÕÙ ܇ë¤ûˆ¹rYöræxûa÷ÔY鉜 ‡´º :©<óŲȖ6²÷çs¢XÝü]Á,K«¹—Ÿp~¥ÊB}oB×WðLß@¾ì úDñ‰ÛN>†}Ù‚LŽàì?½½RçYdTc$læÙƒ–,èº*´î–)ÅùÂù@…Dt°oS$U6¾ˆ¹ž©sм®%×+²pÿ€,Êì~ÈßC8B?\ÀÜnëôÕ4æy$ÉØQuÙå)ò:©¸§†üßéã€ï÷® K&6ÂDææïìû†ôH;ȵKÐy³Ðó×ÈRÈ.²Ü@wEO_&‹^Šw]@F¯”9%/߯÷|$gÅݲˆ¦Eï`OìÇy“‰‘ 'âpü‰íY¸r8õ\:[æh.Ið@e-©a’ÁaÕ²d_Œì^(³dy=Ó·†K1(ðr‡h¹,´rj„ÏàÀºCødm›ªÚÑ8ˆÓäµ~k/‹lèÅüöÆì,¯5i¦Ïèð× (¸¹t‰å€a½°ãxï+Ð(Kí*‹€ØÀ—ÌÜ»‚ŠïË"kÂbÙñ’8ª¹@Pf¡HGÆllÈpŸÅ>®Äzšßͬ¯ðƒ€¿k¿WÌwTÔ¤s0øÎLä"÷%òÚXúÓ¶²T»mg²ïo®ø[Gy]%Ä^š#óz½%‹ Z› Vpé²4›ƒõÃ0(“¸‡Jyí4]m‡ŠÚuÍ9ä1vΠo–õmÅ3w’×¶³y˜,‹Rù•,"gWžqÆøS-Õ¬¯«±p˜,¥áQIïÔQŒ4@u™,`«¤ÑyÁàßú÷ìO”QQQñê_~yÝßï¿«¼T§A.m¦½ì«òí³¥sÙ•ò¢•ú°;B*¸Ú* YïÕ³Ïùȉd>{¤@¦,ú蟜!+£¨ÒØwW3oI€µ;!Ñ&È"NÚóŒ7Ë¢oüdV.kœÆ9°ÚŠ\lQë§ËÒ ®€¬iLe./EÌÝCèÇÕD†¹Ö¬/É¢®ªZð\ú5Ïyv¼ðôþÒ_)úEBχ¹@mµ¤Û¬[Øû÷(2oz/tÂ(öõœek}{±¦Ò#´mj ÿOõÙ0)>2ÙOBˆ×%Bè~cùÎÙœCŽPvÝR²9ƒråµ€Mç^üßbÃ'ù¾ËýÎÝó:tùŠ0eb „Äq\#ó3â¬ÕYÌÅ£c«ãXW Ì—A’/ÙÆ÷º ÄΞ$‹šù¥F&'F‚œˆëq,ïpÕ“¢QÇʘû?òùíj@–dp˜ì( qß #¿ iª„Uú^›eÞ¨ÿDHNŒÆÐ+øÄká5G>dP:ZpÐ÷‡|p¡ÿþhaŒV`–Xׄ–rø-•—.±…÷UÈ+­Ã¤ Æh €ÆI;Q–²Ô›{wÝ(Þ‚À›%¯­g}Às˜¬­Ød¥˜çú ó­¼Z+%!äAªÌ{s°,÷ý¥¼`°²ð"Ëk½“¹_,¯8çz Ç$M'u`'€c/×€…—%-¯‡¨$ówðÉ‹€˜Ísôad‡èÝPÝ[Ž!^Ág î}› Þ”¯v © .òjÏ|Ï‘Ž|TÈóü¯–…?$Kû¨ªgþ2Y÷t` àu¸¬hè¯ù.¥á9™7i¹Ìv®,š¤ óý¢ÌËôc˜))’ªiçš±ÐQÒçDF¤bØwJKKÔ³gÏC;wê4nóæÍ—-_¾±¨¨¨ƒ?´8ëFŒ÷²h°2y©4=eÑJ.÷ÿJYs·_çÉÂÔÌ=$‹DpS7öc? æ½÷ÊRc6(:9ñ®ÎÈ•ì›d™'üÏìñ_Æû¡Wî•¥ ­¯CŸdÈ"b:!g0Ðwå;¶ò#îæé·œ9 ¤GB¬cž¾† {ËíÉ¿û$H¼ÛeŽ–©ù>pò¨j{€³æos“&…Y¢p¯ïOç`']$¯Eet˕컕¼ç±zd²®±“O'»û­©ç§êøuý>¶v†ï¼÷=5¾W5÷ÛÎÉPÎÿKå¥IVûÞ[î³!J h†°Ç_ˆP§¤¡Ÿò!KdÁwÊ‹ ŠÖH“Eý›i.2ð¶â¯åh::òx€üdmû‚žgÈ"c.Wøiè¡cg”«)”(6Ÿ r"Ç} GHú8ÌÏ-óþ#}»þt„€œ¨òçjY'’HŒ›î2ÏG_Y4ʳÛèpQ ΫÑ2¦›¼î}|äC޼¨‘$ŸáàH‡Õ8WŸa f§Ôzª¶Á3w‚$X/ó@ù€w.`ä(°þÌIïŸxþp¶9ôþ”;±_Ž\ºN.ú`-`g&€|àéV€AFÒÝ¡5B¾+™õ¹V–N’ÈwÏRƽþ é¯|·+(™&¯ì™—ùþþ*ï=ˆßFÒ}·PÍZ_‡…˜éì{_¨·K<ß ÿ,>3 œl¬’E-¸ú+|Q9ÌëXÖj'yÑNÎß þ³¤y‘*ßw …(:ûÚ¡s÷Ý]VO"²¤T–nãÀúú¦¤Øøöe6òÚ 5 ƒÜýßZ¤¤¤TÕÔÔl®ªªZ °”=—Ê^B º:-•òÒ¤ÖBfËÍ ›SËà Y½…Ódù÷áìÁ,΢UM¨Ý“¹ý~$lèu†ñŒ/+ˆÈè.|Ç’ÎÌ gúÞr&zâR™SÇOôw“i=ƒ}<=õ‚ꯓäF¶,EdWß9좒U;ݴƧ§+}?+|ç¶û…ïÿ•¾óÙ¥ÓUølùþ]Í}\Î~ÛÀy°Àoù¾Ç ¥>BÂ¥ÌV©vêlMúÂOt¸¾-ÍÐ+mÐ[—BVW°?îE6Š¢¤³Üº_A˜Äùtº:^:z†-:("y¯sœiê™ñ®,špYÛÄHŒ9gã.YÞòQ²B1áŒQ2f¹)í|ãçŠò!™·æAŒ·X Köàm&=eì}?H‡nòB¶3}ßp‹M€ÆÅ€sWq w‹¼ú ñšW銳­æ€úÅH(« ìY0CùPŒóòjTC<¬Ð'cxÍ„ é%¯­h6ä‚ó?Ìs&c¼ÅkòRƒ<¼,ó¬þijÄÐÙ]æ‘OQíÐ\…Q ñk0˜Ï`îˆß`̽!i%D…óÖõÂàøµÌ Ö5| (šÎ³¬ —4°u”œ)RÆüýƒ{Oƒˆ:O^ÍÕ¼ç™ ëWWȵb.ÅÌÉIoæÎ…[W…[?@’¬G^ú1ß;³¯³} ¥œ=º’½û#ó½ßmâÚ•€®7™×S!Ò÷¿‘…ݾ'‹@r^©nìTÖgQ3÷n×¹Tæõ °¦wÉÒöÄÁs¼ØþA{(#x-E‚<p¼A­7Ø‘#eésõseÞþke)šëaLeM~ .Œ=— 8Ü[ÒyÁàâeäžc¥Ì óI=ò»7:î YFU˜:!x dÖ’NÈ úÞvš,’ª¾4š€,Bórȯ4dùfy!õá¬kr„ëÑðoêèÁ ÔÔÔ»™2¥ÂæI_5ƒ mÉý‘ ¿X^ç¤ùœKÏq¾G#Ê!UFøßÁY·5UÛ¾˜i;tæ`tßkq²>.Ò{,gjSÇåì¯ë83&1äDœÙ¨ã0<ûÉ<˜oÊ<0•‰il²Lž-óÊM—yØ×FøùtyÑ®¥f{€hW@A^]W¹¼ßåsºè2@É&™§u•,ÚÁ¥[,çþ6qx–éçÞÓÖ4úA6´“Wÿàßñó™ñÓl>{àyóíjެ¿ [ÙPbü§È¼òdQ3»òÚQžgÛåáø|÷;ðï¢RÖL]×J®syÖ«Œ×@Z¸è—b®ßÖgèú»2¸´‰2oʋ̓ká;–× ®QÃ3ÏEW|€,u„Ü<àÜVµs˜±¼A–÷ÿ"sØÐ¤ÌóŸ†~, Ñþ@¾‚”¤J´…D9ýÖM^ýˆj®}F^0è«Ùq$ó;„?-Á û{ewY$Åá¾ïÞZ]]½dݺuwüñê«?*//ï*‹öØëì ÚÅyYµŽëÏfN—ó·.ÌÇ`Ö¡{Û[xï,Hï !Öó·Ê0öïYözä}AïÍa†0?Ó|$ß ´ù‘„ÉìÑ_AŠï¦Ú5%>a/^)¯Þˇü_DHú>Áu ó6Yû0ÚZ«¼g —Ⱥ-o@Îìû’(€Ê,YäÑåèšã óÚg²Z:ç°¿OÊ 7‡ù}m‘‰SØ/¿UÃ…'GCL? ( ‡¨ì'‹pû5`µ€û]B<žÂu¯’E®5Vw‡ :”ß½É~ù¡œ³¿aßdì0pà»7\}*{4•ç¾>V]«b4² ñÎGäpþ~†>ü@^zb’Ï–Št¯t’‘ÝçóÉ¢½fl#М̹v›ŒP?Sñ“úð$úwl榎ÁÌóÚÊßSùžyÌÍË€ß2®1@»Ÿ¼ެX`}ìà=„÷fñ}.„6ï1ø*÷~¬,Ťó›6mz¢¸¸xT×®]+þpñÅU={ö,eþ %=Ÿ FýÞ!ŠÛøÎé ÕgjâHãÜ<‰×yQ|³8[\úâœqÕMØ·»!pVþ9^ßÂ˹6Q@V¿gv‰Ú ØX#Õ¼tŒ4lº=±U¾LÀ‘ÄHñ5&ÈXýëe5$Â]8t\‚…úyÄh\»ìÊkÿèuwƒ¿Zµ]þ"RÅÌýzyÅ%WóZÁï6RêËÿ%ŽÝ/þ<ãLYû€ß!òjM¬–yQß–yQÔA2¸"…;`dŒ‘yïYQ¦Ú‘ŸË¢66b¬dl>‡s Ÿ}ë:ª+ßÕ²ëø¼`p3¤G[@Üi\£Cˆn,ây: sË»ý˜“¾·YËb¾* Þ‘EœÌ@ÞRÐ{`äìƒa—íû¾¹2Oû»>㮽Ì{9_ñÈŸtYÎöUÜG6×>‚#—¹¼^ÒsÎ{Ihx€x€,ЍJµ¼¢žocüüf] EÓ!--­WÛ¶m‡§§¥íµvÝºŽ¥¥¥1XV—%))©¢¦¦¦˜9ÚÀ|¦óÜ®¥ÿ3þî5îsË™Ÿ92¯êbäÓ•‹¶Ç­-dÞÚ7 ¯mØÝ ¨æúæëöUž(ÆèÓ{®Ï©ÌçfŒÊû!WG«vÁÆÏ1ð§©vŽHÇ¥2Ïáïd¤}’¬VÃ8ˆ±·ãL—ù;ëü"ézñ/±=û<ò¾ÈÊ(tÞYºÆ:‰.X 11#Ûd úà3ä&œ§ð¹ëø^ÕC÷ÇN: ]y·¤ûó‚Á†ˆ¶_Ë<í‘ÖèÊ•E|\Åsý ò~¼ØX…ik×­ÛÿÃ?üÓó/¼0"èÖ›o^Ö³Gg dfçƒ%QþÎ ÈJ×doæg¬“ÑÒî±ll‚ñ²w=ù}¹ŒTÞˆí°²‰ß‘ŵ¯ã,oé5O“—f|#2Ov⋲(–}Õü¢ñ§qŽ<ÌòK·‡c”ÄÔ9VaÔõ ¿õêö²Ú¶2/铪]~%dÅ<ÀÛRy©Åòr™ËõËná³³¬†ÀwòÒܼ”1WÅ@î猵õ¼\z…ëfá‡V퀗ÌãÌÆ(ë,¯íèW’>hBeøpâdd×ÍW‰¼VŠSøþ10÷ÀðpaÝ«1¸?–y#°Ö’>—y>\dÅ€ô1ªŽa½72?áZ³}@³F’‡YXPp2„Ç gÃdéX“!#œ®ËA&Šø|5ßóß‚‚·x®£0Þw“yëÚÊKmYÉÑ ù›†¬ä}=¹÷…|GOY‘ªÓùìw€£÷!-^a;ò}c˜ÁÞ+›O`È/Î k ~àÙºC*Ì‘TMdD‘¤ >]ð=©”g/’ô‚‚È9\k˜,bc/YŽ}0ÊQme²jׂ؅÷»š!íÊËË3׬YãO…qéQ+YËÍ\§]MM‹zêYâÈFG<ÌP-à§+$ëFÿ~o©°ßMp¯É¢(>Týž«"ýM€ùÛ䥎= Ùt®, £®¨»TöËy²üþcOn•yºÿÎ^ªdßÜÉÏâ(<¯KwèÁÏdxûö]mÛ<åd†ÞÈí²ˆŽvìÏAõM©MÐÔûÁzïÀZ_¤ÒH|À1LEè“™a~gOYŠ×þ蜳^KI¥zÚ:R”sz·ºý2Iß…‘ªPŒüdF8‡E²È·×!5Ž—ÕUEé»)°£,¥Ë¥:§Á:Iÿ$z"–2ÝIFì!RÆyý ,"Èuøjê(F†ß”ÕD8NÑó$k¾"Æk~úùtm¼öÕݬ)ãuöû1òŠ='Fb´øHDNÔ=và{]ÆØÖ§Œr8&q0¬HHæùï²võ R|Êĺ‹|$†óÌ.Å_ƒ_$¯ÔöÊfž"¯æÃ!sä‚ÿÕ*†EšÜõÐõ‘W £¤W‡Kiq`ï I¢P-tŒ”n|LÂ]ݹÙY-Ë ÞU^Ç*äú' ×9àWªv½‰4æa€Œý-óĸ°ÐymG¿–…?%óŒÿï:…íÒs­RÓß%}ÖPgõÉlOy„{©všÁ&€p;h[À³»: ®£ÆtÞ;ˆuMe߯dNÞy3]ûÊtÞw FØÞ¬ÿ_$Ý)…ǵ»»Ÿpòä‘Ï,I=*++÷Ú´iSåwß=mñâÅ¡m„²FYò KºÂ°.Ej1ºË>íϵáY“|$Äz>3‚k®¼b”ñZË%y»ãyBDÀ­µh®V@6r:rêßg²´²¿²·GÙ£5ijåuDyWæ½þRÑÍ‹>@=RÆø_@íÇZµäHD‡Œ%¯o5 m9$êEœ/uã_ð™á ?µ&’ÀàŸŒÞ¸¢js{q4@̵ÿ|5L=ÐWÖ6x¸,²æüê_!Ì\ÿ¾R/çC Þ)éÔ¿Ø—s¦k4å|…óÌ¥ï]†žJÆLŒ9'£7Ju®Ì«[2g®rñ8(*dÕîo“×"* Ú º`œ÷“×z² ʯ-Ê>Í@“BHŒ”ÿZyÉ+Êè ÿ•´bã8Œ©[yµVòÁåÌ–WܱÆâ@d ·¼".ZÁW®e™‹ÙÐ]*/çKIKcPé{YxvSºÎ¤±7ɰ?ÆZ7y2]1Cñ9FÕ:y‘C.5ÀyòGÉ" ú3Ÿ.dt$Å›\kñÄ .(Ûgï½Û@*L„¨‘…;>,KQXŽq’öq‡;yE¾Êc逯 ö K(â¹Ke^¬§R®KGžµ”=ü)ϲkÍaÎÔ¾ƒHG2¥ûȲ¬á.ýýálIã"P–cÏDq×£+sð‘ëxF÷¹YÈöæ´¢‘IôÇdÑ&e¡ÛÕõ’ËŠüž(¯Ú{í@ÿÃÌõI²Š!ÈÜ—DHº$É¢µ‡0›r_鲊þ}e‘ßD0TiôŠ,ª«9öJGÖøBþ½XÖÁà)tMÔu gCGöèùèËrI¿ðÒK¯=ûÜs÷ðLýÔHdL¶DºøDY´böÝFYJå‹2Â~±¤Ò‚éY5NÉ•‚ú$ºm‘¼º.ƒdÄû'sÑÔI]±¿Ï–W+á¹­çOæšW#Kç*þjÉõ‘‘Ù.Šé™(\söÊ™“d³#1äD\Œ¥€"Çø¶AÉ^Šâ­äP¸ TÁ¼»žÛ0pÅ]¸v _×¥ ̺®¡¹×®åry] –ËËýsi$TññÆø ì+Z)1±›,ÜtÖÌE=¸Î ®§ W_8ŸÇa°R^zŠ['—/_ÕmÇöä`zƒ¯9Fcü«,Ua$¤ÅŽrþnKdÞò Kxþjy­KÛË«[q€¼( ð—@Ú¼|uÂñÇo8jìØÉÉÉçApd²ž•åùÏ·à#žÂìÿ³Þ®gÏP,/Ò%Ãøi¾{gîñ1™W{+ÆÝA²”‰A€#ž™"Ë«þ«ÓÓÍ0:“xvWL´;Æt_H³îe®¶CºO·”ól«äµØœNtQ3CxGD¸®›X“ïXWbS+$!ê=0Ê×CÆ•@h××½ã0²ÿÈ¢,œ!ßžÿ¿Ž}<$…«q?`{3ßù*óŸŒáü „O,IéìÍÏIîރܟ+œMp…\í"‹ É}äò÷ι÷ U¿ƒü¬ð/`dĹ^©ú¾ÂèÖÑD[â/²keÉ7F7¯Â‚‚Ü{Y”ÅÝatÑIB—<…®|LÖ©%R€‘ÊœîÄœ,­4gHªibôÞN×dN‰æzøè³?0×9ÈÅß!¤ÖEC.yîìÕ øÎ­“']sMÑ’¥K?C>ÿ(óB7å{ÒóãxíÄšl’ÕOC®Ž´³Rä $ÕÉ2gAÏü)çè»Ø–¡ó{ˆ,•p 6s´I“™ãàOÈèZlñBE'Jcôq1ºcaž?í‘óH£—¢´æOÊÒ…&°†‰‘ r"F¦ŒííŒ2ÞŒQy=€¨L’x¢:[ס@a8o| 6çïÇ¿]Õz?áqµÄpí1·<6sèm@Áû G®çà)â3±4~×þI™Ç°Õ…“Œ“y”ä#Š–8~¬¹‚œÅÑ•Mž“&Mú_»®üüüh½]ý·e^¡ª(ë›T@UoY¸ú(™­'lò¹ãõ5ÀÐ ÕöZ¤ÉË#?Ch°°•2¥¥½5~ܸMŒ5633óXYÄR FÞý²ÚE¬± i½P–çŸÁZ:²ÂÕKÉE†?–åD_Ì^ýFÒÑyÁàzŒÝTŒŒeÞà£0Lï–tS²á<Ë®~ÄÎòR0¨vôƒ¿¨¤«ç²‘y^ ‹fpDB„ÒnÌqæ9븈‘%2ëgü\„‘X¦í344 ëpš,¬½ ø Ä^] ¡ û«DÝ¢0^Ã|¿Àÿ¯EBø½ì»"»ï˼¶+Õ2‘r½÷s ’ݹ×5_Á~nJ ºTä¶r;L–ŽàÚȺŽ5.½ë yÅs—ËKû í¸ç®·©ž}ãŒæV¼÷_sY„ÄÞ²H±³YËp¢¶º!G#dmx¯ ƒHb>Éš<( yoÊzä`Ûd°Ñ.Ú=8-€Ê™p‘,z.yyкª©„(ºz4„GtÛó²TÙyÁ`/ÖlOÈÇ£"¼~2gÓ~C±E‹‘á'9——Ç(]#”è9 `(çF9{ÿëO¬Û™’î•‘ì÷Äð~ÛÉ¢þàÓ¯WÊœMÕ‹9²ˆ¥‘ÈRâ39IæÝCæÈ¸LÑ!üÇ ÛÓ =J•‰‘ 'âÂè|ƒCy¬,T÷ŒŠ7dløwŠŸ/…‘&¯Ýb'º¿žþŒ y©$™á†K1p…=—É<ü?È Å^‡ñŽ$®SÄk²ú­.5…p×ÎÈÆVæ¤*Ú½Ì'Mš”Ì÷œŒ{C~~þÂ(\º/‡Ý ŒÆ²Øk®-äβÜÉÑ€àöÈãYxöëì¿ÙeÕ!¤G'Yq ÌÛ䢊$ÍjÛ¦ÍÇãÇ«ÚsĈ_edd윔””Ìõî’ôb„$…óÜÜÉþºNæ5ÍÚø#.ã ?Ãüò¼`pc=pÆÑæ¼`°¬½Ân'‹°Úðµ; ²-sâRÊäæ+‹~X °ss™ë#F0]†®6D‰,úä'€ÅtÀ܊휈¨kŒ»C¾R––3ƒî½zÖî&äác¡#»=ëZpÀñKPKu)è€~^,¯p­„¯Â@w4 sÙ3»²‡†¡{:ÈkÕ[Á¹³€gýˆk¯Tø©‹ývn®ê;³ï†PúY}…&ê´}d‘/}eÞÌKfq9jçü €ðœ¤ß‡¡—’ÅË"¡îAΚ *º2o«ÑÉÑì.‘Źu'`÷ÀØR)CÊÒ!Ú0ÿË구ŒTOA\.‹˜x9žë‹¾›"ä»8Ìëf±ÎE$uBöEÀ¼"iI=gA´†‹8T^„D®¼Öá¯VçÉ#ß· ãNâó±¶#ËjQÌ=Þ`´]k²,ÂéY´Ú8E§ p¬ÆãÈÞ,E¯¶GzpWdâ«,LŒ9ã1óþ Œ•ý^æ…øPñ—w®Âu &Y^$FºŒÏâo°êæ#5zÈk˜!/ߥ'¸bžË䥑¬TíVeïU>À$yíB2oÏk2OóqJ´_­”è/óÂÄÚ¬’ôëüüüï£ðe­"º­Û@'¹H‚]!Há™3åšüLæúT^1IÕAVìrtIÉÉÉK{õìùݸ“OîBãLYÌÕšæ€âcdã™W=?\ÀPXPÉg~‹Œä僫dYJѿ䥑üIÍóvög ¢M€uáþŽC>fË¢mbå™MáYÎG·‡p™Q±*¹"j.[Òúè…ýeÑ´©2¢ûº†ž ¢£½,]âwè„4”—œ3%•Å0•3›ëÖc(6`9ûðE^óÐc‘î¿'‘Ñè«–YØEסsæÊ"7ÞŽÀnß`ž$#¿W|û¡rÍiQºîi²¨-W,ÑV41äDŒ|Y8×ïdÌëgŠ~¡¬Ö@h$sÀgr˜ö”…xæg@`–j§’£Ó¥“Tû^Ž”ðwÝpÕþs1ÆWÈ׿ӵšìÈ<ôæÞ?vQªI“&¥È WÍ“W?áIyùùùÑ8<ÒdÞ‚eaçóâ@3d^ѲH¦òŠI˼øoBl}¨®¹F¦Ì‹9ð0œµ+OOO_1j¿ý*ÇrHß®]»*--í¹¤¤¤ëeÞªšfÈIÙ†QþJ]Ñ ¿7Ù…´ïŠLuàþ]:F%†ïˆÀ9²ßB¬gï06{±_÷EVôãšé!DÄB€ág\o¿o*0ÜžGPÞý¹"™2OçÞ²ŠúoÔc@¿Í~Þ_µ»s¸q©,z"@Ê?Ú²ÖÈÉ–8˜žy©¼Â’{Éê‘„Fò”¡»æ /¿äß«ä¥F D74ÖboÖä?jzÔ^š,úâföËUåaê‹4YÍŽËÑcÇåƒËÂЇÊrÿseÑ÷ªùoÃeiCÿ†xjîÙ’„½ð0ú{:úx5çL¬ ¶gôyœŸÐ“…ì7§ËLOˆœ.²â 75°Æ)<÷)P½Ñ¯ßÈR€Þ´.FE-]í¡dÄç±è Ldtºëy@}S ÿyæìˆ2§UKÚ = (ÆñÜϰ/—4òL9¼÷@YÍ¿·PþWt›Ðsç©ù5\‘8 ûk$s—‰‘ '¶ñ˜ÄAó: û ÿj‘±€Ét©$ÝåÙk‡Ñäê`¤òW=ŒÝ0ÖŠõ<Bï:e|$Œ «o¸ì$óVvãÕ…ßµh¤ûÈ•%­"U“&MÊÄÈÿ½¼–]É2ÏÆ ’¾)á7p0_‰¡OÞñdj0ÖŒ-×ß}5àúYΊ:äȵý¿‹ÆÙ>ý¹‚q£#1Z`¤$¦ Þñ!†ß@~î#¯eÞ0Y¨£#,£ˆ?¸X"/¿û—< WI:à˜£ûqýæw’Wÿ¢B^“ͺÍÔëäu.Y-¯ëFyçùkvÁK‰d눉NÜ××Òþ²Ã óóóc鉘- É:ÄÜ Æ€?BFλ”©õsoòs¾¼b•ñ:6sß=,¢7 IDATëY³ËÑ{O5r^»V¡b ¼/+R¼,’›£˜®Kwø³¤g!º“YGL\ƽú»UúºK44z¢ÃšJNô¸ANΑEÓTùlÏ@ˆ¬¯¿‘ÕݘVXPp¤¯ÃŒH(eþ>¸&ó¬ßÌÚ7@J]!‹Føk:º°>–Ee|” Æ"MÀuÚ8]²#¿[Åœ<ÆùS¬–KÑìÉ=,Œ»·R–fw´ÌAu {hYdÐÍè½™3&’34‹=y%º¾†ù~}°·,*ãPY$jgÖdC”æ¦}´ ›äDöÝÓQ²9{Îåú‰(ñĈùH¤u4ŸÜI—y¶vB ”yn;É«QBß²±?”yÍŠ âg£ùm›N±"!\—”\äbGYýT»eæ&Œ¤Ç!µRù÷Þ2Æ}b~~~K¥X¤a´ø~F­»3CŵJè*ÅxÂaQÈá›Ìº à8L^×b@ê@öóRHƒÓ…€!W™Ý°éÌ=$ûé&€çOóÐ+äÕ»©P‚èÜVç啲°Ùë3 í‰ÓdíìWÝõzضrn„ve8KæÍ»F?ï q9õ2¯ysž)#ýDŒÐ¾èž­Èß[Ú®Ølk2N²H©QèÛ†ê8t•‰®SQQÁÀktó%ŠÐSIÛéûd‘r/I:»ðš è(€h¸Ùªlä{è½ÿh<éþºnßF欮{ (ÞI–»¾~žzÔbá;YH“eŠB¢{ÉjŒD>-ëX²(‚…,öìuØ"¯ÉÈùÅuìóÛe‚x¹žyo/iK êI$q.íž8€ÿo„ÿ ²mÍ6²3Ï–¥È\ŒÇ›Ý¾¿¬iÈ£‘2'ÅXÙÎÈl¸RñZ…Ývvœ‹N<:òh ÄÕ»ÌÑj^ÊÛå²úEgcs¼Æ¹âÒ•š;rØÇdQ@3”‰Ñ›41š>*ymåð}”%cŽ÷AyíŦÃ!¼²âY8ì”S<…Ãn«Q£Ú?Zùʺ§£È]]€^×¼\W  Ðù¦,\îsI«òóó+&MšÔo™‡ÿ¢¦xÌ\¡Oÿ½õàþúð»‡T;Ϲì ß7Ôºó Ë9¸–y-zɼ('A<ìàœ)ó:dC€ìcöêM’ƒe¡¡Ïbd»Hœ$æ³?`o/€_7yažå¼äÆw¿ù²Ô­ªÅ“ñ12d!àÅìׯÞk2ÏÙQÈ[(@[ð?cùÅ¿‹ì‡ë—W9½OŸ%™3êDÀñN›eúó¤ËÑS­•˜¬‚p8XåÔÐ^+K³Í||UÙqú²Ìëz‹šF¤!#JgHº4 bâP‘ YºP8ÄDš,Äÿvî=œz qZ¦Èê/¤È"îfnèo¬g/' ŧ?.,(8VVôñ:Y…±’î*,(x$ÌzŬëÇ‚G:¯d¿;%Uæ}w üõzî«JÑ/Vàl9‰}Û3e:âþ½­ Ä茅qj·€¬>å³Ëo ƒ˜H’E«EvE~ß•ÞüR^} $Y„Mž,r¨2ö>¶Ø)œ'¯±vß6qÝ6ò]9\ã{y:{¦¹c zçÏwT±š r¢U‚ rÆ÷2/Gàô Œ¤Ýdù€Çð™y(òÕ2–~!Àh5ÆA†B™À¨àåR!*åÕw¨ñý¿5 wïqCL@çÀø£t¹¤­þŽ“&MêÌa°¿,Äô‚†R9(¨–Î÷wàž` ôç^;Ë &ºt$ßœ—¼?‘™¯1¼Žæ0~b;Ú£?,b®ŽÅXt„Ä?ùéÚ“naÝfÈ‹œê"ó\í/ó4Ä8Ïd®A|)«]ñ#ÀtS‚„hU£¿,êé…W„r¬Ê€‰»BŒº*™‡óÀÔk!ÆéBΑ!²?ÀZɵzË+Ø.¸ˆa}ú¢Xæé{R!±RÛWèî4æg?™G½º"ãEH€£!*üïu•П„þhªwr“,Z림`pE#ÄÄ!œ ™2Oi£Å/ reu.Do] kgܘ¬¤sÖ•*ü¢Ômñ`—ür¢´¢Ï‘Q±Sò‚Áâ‚‚§‘áßÉ:\Ý&i\aAÁe-¾óPW¡Û…ºˆy\©´Ii—%‹–øW Èo2öÅhY=}±)‹d5”¦`Ol‰И„®¬V„iN-lk.FG»Tâk± fÖ!“É §È"Uú°ïß•ŸüÌ'ëYdÐÙ²v±ÑÝ…²š#³Y¿ãÙ›ÇËÒz?‚¤øX‘¥à¸=ÔŽÏÊ¢úNæY¢!ϳ¿OäyW%ÌĈµIŒ–É(ísd¡òí00¦Ë<«¹2¯z@µ;D8Ð^%/§¼‚ÏVø^åü®TæÉ)æ§û÷þVÎÿ]ž½û]i â~Wå»vEREpÕFæE.$ƼäC(°ß_ž'±«ØgÊëâ!ý¼{Çf»•Ê Cˆ&×ú±"??¿¦žûé¡uˆ,Zá¬üüüuõŸm9à0ì"¯m¤ÛÛ."g‹Ì‹³Bæu]ÌÏåÜëÒzBO÷Å€ž)ó0”nÇ{Óõ€?AæÑèÇ<.dMžf»@0Ž‘…‹÷ÅXrà:{ì*‹~ù?y) Cëçʼ·HÊÓxÜ csà"Ôƒ› xîÂ^[B$¼¬í-‹¬qcW>÷FhUò=°u2ß»ÂñI®½½æ÷‘…9/–E06ÔbQ»Hµ;FeÊZu^Š.(KÅhr86¤rФŠ×É£@s:¥1b¢'@èžålÀy8gu{ˆ™YtØÖFäj'Y¤Á(æø÷2ïpCßµ/²[Èû£ªI©ØAé6–uú—,Õce˜©.üÿn™z>×Êy>V?¯%MÛ<[VÏäÖ±s:Ÿ}ûgx¼íÛT@û ì¸Åq¨Rd6WÈ"ÄVÊZ‡®`{=æH‰³e)t]|¤Ðß±ÝËå¥ÇíÁ{„°[ÃZ=Ä¢'ÆÙ ~ö–…FfÉ‹,¨’U°œûZÀÿ‘囦ÈBýnà -”tóþ{˼ó#eg7DL0~àu­ª\š@e»Œ”"£{a´Î®€ýNÆà×ȼÃ?L“åvÎ`ÝKcÙý$Š£š¹|‹ûïƒrFø ~ÿàe «{¶C ½ÞQ|æÜ¶úá«¥â¼Ï~b6Å·Ç]”S¥¤µa¶¬käÈ<¦kU;º¡±QÑx2ô~¸¬Á½X–úñˆj{B?çç¾2o}Ž m_Ï9ž ¨:»ƒ,‚ë/»ÛªP^8k›-K™˜VXPðZtFûÕuÖyCY^ÂË‘îP#!#ªeEMGØÏæÜ޵KFçrÞ^#K1kˆ˜H“å·ßƹý€¤ó‚Á É!-œ]°QuGh$Aôä£ó‹eÑaWøµ7j|׊ÙÈ K þÍÙ}™Ìû=EÒo ®—4=Œh’•¼ÓåÕÄz’ãù(€´TöêQØ…»³›9CGo¬UëH̆]©ðÓ‚Zrô“EúHF/`Ÿÿ•½} zbÎûµüíyu¨² ÎÄl‹LC¾Þ…” WÇÉœ@ïÊjT)K-rúûKΆ·ëÐÝ;"“mÐòÒÓ~%sEC×Ïdì QñQÂIŒX‚çĈÍHG1ä£ × ´ÆPüE3ÎoLž 5’Pê¶²0Û\ Þж Y2"ºzo‰ïo;cð~ ¬ ùLiâF;Y®ó¸æ*vâ4R"Dv”Õfy]Ò©M\¯Ðq$ºµÆw®ºsÔ¥A®—×ç$Îì4Ê¿·-‘k„¼= h½Q–‹^ÞÀœuEœÆYw­¤Çó‚Á²>“Ë3¥±/Š}ò׫ !éòdæNœÙÿÀ¶‰$Rn/€÷Ó²t©ªˆªTI››ESXPÂÙ”Ï>Ü ás·¤U œEýÙûÝÑçs *2™§kå¯dÛpA€n;Öx†,ÚêUym§[ÓØRõSY]µxŠ l#‹~8XFÔÞĺ%q¾_€ÌwÀ^|Ù^Žîè,Kù<[5›òdy¢Ó!#€ý<Bt0û`5ûæIÈÒ ²È£|¾ÿtöÒ YzÚŠn:îñتÿæ»*•‰‘ 'ZÍ芡0žÍû¸¬Òí2G›ùƒ¬òw¹œè¨Ù‘÷¦Ë˜hÿË]Lõå©>²ÀE0¸še2Vw3Êl-Jn-/êE‘ÒPHò•Ë5'H³¯Ÿ¯#²ª§Ìc~$¶ÄTÃeŽŠýÐ-ȼë+ ÿ’‘·aÜ#¸~÷ð<¤Äµî9.úóId1^ÈÐtÖùBäî丳,:á|þ½ ýOÈÊlͳdiÙݰa>âL˜†]«õÊ–¥ÌæaÿvcN]§·Y²h©§e‘.²ã=ˆµ½½Îö2R¼#ëüSî%F‚œˆÿ‘ÌÁó,4ëYeíT›=î„Á¹AÆœ×ú6yòdªD²ï{èwÀ?…ÔÖþ{C„ôTí¢Ž©!$†T»Þ„3ê]”†‹Î-˜¹yÊĉ+š1g. »»ÌC±©$ÌãÐËâPYŒÁù?—É+½Ó‹ÿ·—×)&Uµ;Ùø#ÂJ}$êFyukVòïµü~³|‘`òŠõúÉ‹êc±FRU3"uîÇ8<tì)óxM“yCå{ €ôyôB•„x4Rµ[ar­ƒØ?Gñ»$™×õVYVU+“­ZÅ£Tw" «q°/ó5Ýwþ¥úä¸#º*y+—¥ ¶”‡°?äÔ`~ƒðz1ñ_të+’þ .m„0ÜÒjˆŒ >;ä3¿èü¢«¯Œœ?³êmYDa1go×\Ásöå³ßüËëÑ1Çú;Ân”ôzõ"Ò_=dÑE§aMã9¿&Í% <–=tŒj×ŒÉæþ®Cç-–yâŸcÍ\Q˾2bÿy©qý!ßñ1zm{(˜|‚Ì»ž#q'¶ÛQÌÿ‰².}eNº)Øï+Ðd Oæ[ÇúNñ‘H-ù Ðaãe5%:"giœ·È¢ôÖ¡;þA­®2ɲN<×s¾Ü¦D‘ïÄHq=b“! ey˜u…fs0§©¶7,êcòäÉþ4 W;"W^È´3Æ:ñÿ¶ü=‡—«9ဈŽ(ù\ÒI'NŒFñÊ2¯ó×ò*lû}6`y‹Œ±]+ë|Ñ"Æ7‘ÝQøyÌÍLÖùÝüüü²0¯“ËgΓÕ6¸DÒ¿óóó+ãP?Ü.óž%ó„4x¸ƒ´«Ìãûkˆ¨žÈV1ì߀‰­ˆ¨ÈŠ×ÅëýV iéêѤ‡èˆîsŽtpé9ò"¹üdg¥j§œ9²a?—ó»M¼¶ÈËûw‘Õqú“&óäy—4á9®— CþÞ™3a+@ÆOxÞ(+˜Uq»¬ÐåñÔÝ!@6Ëêž,l¥Ä×þ<Ï¿$]Åõ¿ÀtÀ;Þ<Ó½YßÝdžø+ÕH´FaAA;YdÅI÷çƒ[ä‡Ê"º¢«þ˜ †Fwýðu ûq"öÁ\æî¿ƒÙ²è‡ž2§L$û¢‡ÌA³@FV—×sÏöݵØWÉÈø ²zÕQÐyÃÑûsS%ýùô³ÎêQYYù:í)ö_]`­›Œˆ>=8 { ö]7tH6Ë'œo9f;³…'Ê"~~oëá v?É\O@_+KaÚÊúÞ%‹@«‘¥l\Ñ’ Yñ¨,5ÎE@7$W.â¹(F…ÁS83ö89Û].ŸCü])¯£S´ì¨þÈðFl·u ø— r">GŠŒ}ÿ‹ŒE¼%V»ŸŽ±Û—Ãky¼<d†SèIªÝù×Ty›$­Ÿ8qb4 ½aÌËËúy®kÜŒI“&¥ÈZù]' ‹@ô&IßæççWÔó¹$Öü™§t¾,ŸðË–"X"™>9ÝK W¹oªq˜Ì!>H^ÊÎN€ãbYD̲ô•!…Ûâm´`ºbvÛôÐÆðv„¢‹nh#/¢¯Î íy†yud\j…ŸtðG:lÁZ%KŸrmj—axo`]ŽÊ(yÂ[rtH­‘E0„[ô/À¼—ËK ¢º=Y©è½}e±¾¿ýãùY$^µÜ!Ë“~„µÊ—…-ß'ëîÐêr‚ ö–—W}^Ó½çVZºX_ªoo¹ô¦LYn~@ñ0Yè% #M²×u6i(#S–'=úéI÷øR9ü㙇y$ääé!ö´ÿ¬A–šÕÓØèŒn_ÍgKyÎ4öÞòÚ›N‘Õ‹XÓ\«°  ‹³çÿ$ X¼xñ†ën¸¡cUUU  ôjîµ!p8ó:J^m“ ²ˆ÷eW³uÛeD#"ðI¯ÅÁýì*«ŸÒQFJŽ„8ª–EâÞ"ëÌQ­s1F.gÚßÙ›«ÕH”öÌ®»ÊœWOÉÒ/–Å(uÕET —¥  ùç¢Kyžw9‹›k«§È"CÇ¡SO@ÀÄHñ7²üÅ ÎA!7¤„’e!˜#e^²¹‰i”0_Fñ]ï7KjÆþ4Ã1F^Æ@™å/šI½Œ£eap=1V~/ia,ºDi 1ðs[˜ÇÐÎà{¸Ä»ÃõŸ²èš-qXLÓåQO“yù*b4Oéàj9t”yèúÈK©è†ÑÒV^ô“#]ä“ë¨S©Ÿ§Vl€`Y ù°B^Š…¿È®#ªZQÓHÆpYþîd^åª΂N2Ï÷è÷^€¨Tô„KÓ¨+Ïþ À×ÅA7"óßAr8؉þ:ݹ׎ŸÆx϶•En¼ÙP:A„×ÜMæU~SÒø(’逑ÝYŸé1²©œ×Ôµ„nØ_VàÔ‘}®cÔ}²ˆ†A€ KØÑZ£n²(›“ØÏ—Jz±y½"m­Œ¾]©X—Ü? ‹"< ½îháW,#r·†ù,¹€¢«˜Û¹2ïð;ÍõP,;J:ïæÛn»vîܹi@àÃŠŠŠqè¾pÆÉìÉŸd5-œ‡¹B­·†D¤ãaæáE¯eSGš¬°ìYôþüî+tí4Yt_'YDZó¥ì˰H v2ºØÔì€îß,+jü´Œx]£ˆ ×}ˆ,õc{­˜ç ¢f±š—’2B‘1›½_¤ÄHŒ9WcO6{ªÌÛÿ†ÂcÅ“õ½?P–Æ ñãÇç ÐS8Ð6ð³ð¿S§NÝó¼N–y)nà·ŠAšÆÑI;¡¨ d^uÃײ¶åzwæççoŠóG;^–ž4C«Åd¢" ƒýdöJ/ ¼y€ÏIZGžx—«ý7æ+Üg Î’WCÁÕLpJ™žò:V´‘yb]-íäȆrôF(ѰR^A\—VQ@pue*äÕƒ¨ÞNI‡pÇ) 7ÔBG¦Ì[zŽÌ»Ûžµ(•EÅÝ‚Aú¢ŒŒÞ(ËÑMùÛ0ø¢,„Ü#¹ªèÂð]ûe©f5¬ÿ~÷¥,O~s ÷éž…’.‰†g°°  Ï»@Ò uœhÂ8G¹6€ÛTÝá'!ºÊÕÝÐõ!‰rX3·‡«ôóvÛòí÷¢7¶Dimd“!E¾|ÍhDgþy/s´4¢nå OEQ„;Ú°ÆÎ†ÚÁs%Ëþ«ùÞ$YäÐÍyÁ`s£Õ2’’’î”tVRRRu—.]v^¹råâdb äÉI²ô—¸Ö›œ³í›#e5o~h¦¾oj4M,ðM_tÓ0öÞ\tøKœwœÛ7²‡×È"%ÂîläëVv«Œ0.áßOÈÇÉœ}9§7ÊHã§dNªU1²axcØË#°1¶ÊˆÙ§ÑÝK¹#%MÿÏÞy‡GUnoûɤ¡÷bÄ®ØETìÔÁ±lÇ.–ãX±û³»ŽFÅ®ÇÞ{)*R¥·! I¾?Öý~³S¦ì Aç½®¹ÈÌž½ß²Ê³žµ–¥ í!«EöbÆÌ ?GNf RE2úckY4"^`B8ƒQ²ü»Zk¤\‰á²läȑΡpE᪵v‹Og¹ë8Ge/w-×ë½L†O7nܺ¢óséú´ ÆŽ[6f̘§0äŽÄQ8ç~6«CëÇHú´™¦qÄ*ö¡’Æ?öÈ#íx†2I«Ò^q´RÒ×¥‘È·²Ö0šw”1P.ôzi$rŸ¤ïšAmŠžüü5ÁÏíÂ~Éó8,Þ4 ïO'œ<˜Ð0[Vc`&çxçÈl¨YÓ*ÖõÀÏcþ? #Çb¤X‡·dQ¥od×Ìýi²Hj‰,ìñ˜ëýŠ“6ÀÃ9©+1ªwÄvàÄöCG¾Ûu&yçhY¸;•>ùLîs/ä÷®¹à¬×\àãý¾&c°*£xÇsílî£Æ€ˆ~ÿ­­·²}ºý2…=q.…ÓÓ^VxcöÃDz¯/-ÿJ#‘–È×*ôQIWC¡ù|´m5ŽecN‹cËtIð+P‚A2ä×ÌÒHä,á[eôòmK#‘Ñè‚deÜAµµµ§Jª¨­­½0`ˆ;q>¿i®ÀàNäÌÈ®.¬ÇœwV\÷´u1æ8dngÎàí‹ÙsýödŸ?‚L†7„ IDAT˜¯¼ÜMˆÚP–Žw¶¤/j”F"ßÈ‚m›!—‡ñÃûÉÒJüÕÈçGd)rÈ‚<‡nÏý€\|´2޽[)KcßU”{G>ª™‘p"õq ‡ü] ÍD ÀÈŽžÿûVVƒ`Sj;Œ˜6(>WMÜ[”2+F¹{»n(ÆÑ‰ØdÅ8?s´3ÖÑ|¶ãç²õm#š±d̘1÷Ê"ŸçÈ¢áQƒs‘eÇa¨?èÑ.­¬= Äf8pýK8ŸŽ´ â'ÖöGY}?íUí±µ.“1bNÆœP‡öÃñì‹#¶3ÀåÅ’^Œ“2§í+ðÐÐpé]¼ÕZÎTKä]2z¡ª4y ÏE­_•tai$òL´ùÁkdé[‰Fƒû¢G?P3+ˆÝ™p({£{o! ÏèÏTöbkZåЖÀÈB%K™í…|ºEƆpm^‹eAŽóùý YÓJ hdi$R øw&{ø{gaöK6Êç2Þ`»­«¢A¹tŽÕ²´ŽIȆ>ø/ ã¶C>Í’¥Ô½ªhM˜úæä3#po®3NŸÔ¥Ìh‚ÜÉ"f_Y„*Q£ìXæ…²>ôk‘#GºÖ¡Nq»jøù8®ó†+ZçXÎYYã1csÔ eô.×ÃõxŸ&éñqãÆ­+ÄûJÆHYí†õvP4³ë3}ìØ±+×ÑùnÁ´…Œy°µ¤Þ(Ä|Ͼq…+dу'QÖó÷Ø}÷Ý …NÀ˜ïìù¬Û›Õ(¿¥²ÅT õŸØS $­ô´À/‘ENCÁfaôßr]ÖÄé×ÊòÅ•Qz3cý²¼äβî2óŸÿ’ž\)‹Š=¨øònË(½Y²(ú¸çøvYgœƒeL<7\}‰›ùnç~-cÌìtdþ›06Uš"[¥‘ˆK•¸ZÒX?Î\i$r Æò ÁPè)ŸoٵМ%‹ZÊêìŽ|ìŠÜÌF‡®ÆÉ™\s¯Y2¦ˆë0ÓÐs·‘µàܵx/ ëPˆcv²ñäÑoq—ùìǽ±Ožã3®íë“ì·xÒBE»×l¥†‹MÆóìÜó•\û.I×&Twä~6”¥ª\¯Ä©î®f̹²ÖÃëÈ“vBwo#RkÑɱƟJZâ²Nk :¹)@šûh”,¸×YìR,]½”lÎùœóEüQ©oðæv Åñ°7ùüèŒÏ%í_OaÚ¦°]¯=dÉȘ`YÌÉ$Î÷ÛØuËbÎøSpòs±2#32àÄ:»ÉòÖ&`H&J)!p -3Ì"}'3I)é"Y”oån0àD!ïq”ã2 ß4õoàÂbY„a èW$*Dj1^óQ^e4Á¾ŠÒ“;+Z|1€T!ô3FÐDz¨èB¿À *­o‹!¾ @ÜTŒ‡%-m"âÖ´í_ò[[ËØU…’þ …Vg¶~ÚF‰,‚ä ÷Õ„NÄÀŒw/Ëh´Ý9;kíTˆ#eå®ÇÉô:ÔãpŽãÔpb%ûEà3—qªÓ°'7Àù^Ò¾ÁP¨Ü‡k“±Lî“t¾Ï¬ \’ÃMì¯a§ËŠ~+Xg Ë•ZaÃ}Ñù?Ë@Õ¥>Ê„žì™x†ë%= …â-T@n=ÊþÜ7N‡­rý=öe¼ûËÛ±l+Å_p²1§o'öL/t×ÁPhA÷ò¥Œ1ò©,Ø´"‰=õ*çp'¥©ÔØ>(BÃÙÜD„ªÆ‰~ø5zÑïôÌV\;KÆÂYžÆG`Ûœ0ÕçùyY*ÛTÏ~lht gý Yáש‰ÈDZ„.K+m‡ž?OÖò¼&Îkôæsm%í …>Uóy2vÍ–œÿ¡È•|Y°sž è~™s‧[.5È083#å‘IëH^(ùù’ë¼ #§­|¤u®çÃÕÚhrg‹¶‹²W7œîÍQì·C¡)Íôücˆm‡c¾•,ŠP€BYޱù?œ›‰€«µ6»&vô‘E¾•¥ 8`££zº¨ÄQ˜#‹š¸ùÛ€cKSc7Œ¾j>?¹4y%=EÒòd¢”F"ŸÈÿbœÝ)K¯¹£4y.‚ˆ\¶¤ò8îÏEÚ²}Þ›ÙaCdù¢Û³ÆK1 ~ËˆŽ´VÈ€œ•ó1„’Q¿• +9ƒ]déI{ ¸áòü±œá<³¼1Fd¯rÎ]]º¼œû}GV´p<Žƒßc† äìϾü݇kþ"6*ÚϯQ%+J|8ë0Mù_)ŒMÉðk¼'Ëí>Hå½;UC½µ/€Yœì³eu¹ÿþ’ncn.MÀ©\ÉgÚÅìׯF ë›í— …jJ#‘pʨéX‰ …f6p¾/æù¿‘ÕH\k‹½0[ih¹Ý ÑR–‚t {aÀ’rtÃ[²NC%•¥©¥×&Ée_¤ë{2p÷ÎQå»d©Óí„”+ ÒÜ€M2Pâ¥D×™®7WË žVÈ‚Šw'’FZ‰ÉØÝdµR¾lFº®’ù™ÃžiLÙ {j2ó þ@W)gî,Y‘Ï…³!32àĺmxóeÔ¸dÆ2Õ/üw'jÓ98zE²ˆhYäg†EwŒ —*Sƒ‘öbNH:F.{¯¯,EcŒ*W¬r,Â÷9ŽÈG²šË­ïØÈã$4jrýJ ûi’þ‹á”‹Øå¶+Ž× œì‹dLJ#‘e”ÐEÉäTQ‰‹!r¾Œ¶}»ŒÑpß±<‚½r¶Œuci$òZ#yÛåŠ¦Òø–õÑ-tjÍ.’¥”*¾¼ðÌH œÈaÎÛȨë 1Š“‘ Õ»!ëŽA¾8`ë%ycä¡3|Ë0{sÎ)\ªht«®1UÆÀø?œÏä4³ä, Y?À‰?xÞ’F–F"Oùܵã3“äE Fþšæ½T‰C³›,Šûb*ç·4i‡£uûêI·C¡D‹’vãùÛË6%¸öȦD@YW84áË@®O+DŽÓ#$½X‰Œ †Bué²{d©0óÑMɲ~6• ÞUš A (–ÿÉÒpz §Êdˆ—ÃfIZÝ„õˆ ižþÜ*9Õ‘%cGœ,cK´“1ŸnŒšé±qÌÉe8Ó’WǼ/ÞùÞRÆÈÙBLŸ%é³D€tú° ’nNwañ†c‘ýÌëQôÎV€`»a›ìÞ[!cÓ–¼UÊŒÌÈ€M>È"D/)ùêäeï 8±ö~¬UrL”úB‘¬Êý / D ŠÔ›W¼L9›"£eNĸ_B²ˆH;ˆ$\u÷ó´e0£äöVªsØ…y™—¢¡X‰c·HÒ¥‘Hç½'Ï3…6’×BIJ#‘§eTñ%‰²(„öCi$r"sw ÅÝ8·”F"/«ñšµ8I£œ_.D.—4£cÏÑ´KR$ºclŽAÔ’9œ!‹J¼"£œ/mƆÍ_i8±”}ërªSa«üÄÞ*Ãùnë9gËëzàð9p¢ÙÔŸ³3 ð)®QÖ€‘ù¤,¢º/`Ûu~ê›`(TËy-éPЦ*VqŸ·ãdî]‰üKñ×OˆÇ9¾˜uÃÀ¨žŠ,ù'ßwy¢khºsÓŸ½øOI&!ÚÊhÙ›ÉjšÜ›àýT ;[$hOÖâÐd+ʘ”{rAi$r2öYHÒ ¥‘ÈÁPh’çm½q°*Я©ÔdÙ•gy_éIÊÃæÜÀÅ´t²éCY:Ç’æú ä%2\ûÜÅòÞï ]†83]­ñ ÄôÎy‘ŒÕv1`ÆdèÝ$í¢ž2v[gYÑÐKƒ¡Ð¼×/ÀýŸ….?= -­ç½Y¬ku3já]€ç:Q9¶ÎŠd c©,½ï%YšÓïʰÂ3#ÉCŸ‰ÏÙ’NGØ<›äuºÉh„“Qÿ_hR Ó»¬EÈ×ÖãÌ»¢™˜ß½Æ©c#¸WÆY•¤5ãÆk.Â#"£­ï,K'ðC©ïƒïrŠ+qfB|³ð uµ¤Ê&î|…B¬fD_E;hdÉ¢:seTÀ 2Zkåç·Qý4ÎÌNÌQZy[“âP"ß™=;_–Z*£)¯Já;ú+ʤÈçÜÝ"é•`(´¼ÏæÈòˆo“±kþµ"|¾ŽÜúCe]{®“tMFKdÀÑ2v‰$~Œx§fE¦#G“Wðïquþ ^û§pæ¶åš XûÝ¥÷fádìÁÙûÁó¹ d,ˆS‘•Nd³_’ãÉØ ÅÈØ >ŸãbYrkIC‚¡Ð®é ØÝŒ|XÄ™}´>Ã>‰Ñ‡²»ŒUòqì©n2vB¾ŒýöksÒ€étÆ3²©$áÈ”ÈrÄ’¼;N‰´s`kM™¥Ûéû¡JOº‘«GtŒ!ó‹¤Ã‚¡ÐTΉØ×Ë"ìÉŽÎs?äÅTŸî½H©ßC–þµ©ŒÉ%dÇg’^`ÏÎo­´Åy}»øDŠbP¾,}u²ø.l8ïõóelÌ«‘+Ûîb_Ö&¹=;oK*M´Æ:þpÎZ¹è.Vßy-DÈ@Ë—e]vVªùŽ2`c€ŠÑ5Øðûh=ì¾—pb}®è`²ù…8¼³1BW{À‰bYc ·šŸ5жÍV4_Ó NdÕ±¶±E%Br9ß<œ®Y2¤óþ¹¤UãÆk*VÇcJCnüPð혫y¶9Š7[³Žœ½\Œøn²HÈŽ²(ywÓ,E)Û¿a¸},‹˜Ï—EÓ½&¯r_Ûª‰RZpFJdLŠ#e…ü:0“Ù/È"C5I\?€á|c#3xBLD­®Ï¶•E=ÎP´ ÖÅZ»Öv8€ÏÈZ•Õ4p½BÖüî¥#€á/²B»/bä–7£è‰_뜥(°êd–·¥ñšfÄ Ùž5à$Åy®äÙI½¸N@ÜQZ»má­8Sâô¸1\Ö~ôvI—Äil»®6Û WÏ` S ¬¨zÖôfYdó´`(ô¨×.a>ÎæY~Àx߇}’…³ðˆŒ©uÒLËç;/T¸OÆìªŽcZÊXû*Ú"ôå$ â¶•¥µ¨t” øNF—Ç9¤ÄÒTî¦äÓcãÙ?…8¬§Išøö»ïžüØã¿ 0uЬkB*cöŽkëGAØlÖ÷Ek®L—1#^å ,n†ì¹ýÑ·ÉØ ÉŽ|ÛËdúrÛóªcöà&|ßpdÞ;²®+?¥b+,tçÌÎNt¾ n…L¯‘ubz­!û¥4Ù}P"+@y±¤ïÓ\+Ä/ ¢€=p?ºj´|dBgFœÈŒ† Ë/eyõCSPDq6g˘åp¢H†Ôîˆbò‚Bغ>á^D•Ìð bäp=o;Ò<Ðáú·»|Ðe8ó¿aÐþ޳ˆ¿¹|Ó ¾3U†ïàÄ:޲Z,£"ö—E¶’QJK­mQ&£û}©håû?ˆ*\™®ñ÷ºµÖAÁE”z;Œ½ÎU!{ï5YŽéɰ) ÈÀðÛÐá•Æ@ Æ­qÂË¢1×É¢)+d…Ⱦbïî«”y¦®²í(Y¤-'ñ5eôI«ÖW†„xp-Š;Âõ”¥*tf]‹=òÇuvqÀi…,êµLkƒ§È"† 8/«”~–Ó6²Hà“’Ær>¿ÇpNÖèj(–‡ 8IÆrã<œ©“cþßuìx_‰[Ó€ÜiËÞ>TF9þP–6ô„ŒýWáãÚ–å¹»®+}¼v6ð2öS-€Â•>°( e4ä _h‚£Ò‡¼%újsÐ^ÖícàL2).YØ0÷ó½ŸÉ[³S°!_“³C”XÝŽ«d@ñá\#r©›êØ3Î>;kéÒ¥¹ÌÁh.::!,cÕúÑJ7 cK$cj}"cI–7sÝp¬Œ!p¡,+Ñ‘#í¯Ä¬‘ÕWºNÑbÁ^Ûv#‹èYÿG>ûž|(¢[‰´’"zŽÜ' HTÅñÙ| z ²÷€‰ê8dÝ@žy'ôœc€ÌoæÁŠöÔÍ2vÞÞò¿öHfdÀ‰Ì¨cì.£YG$©äQÙn²ܯ\s-A:räÈ<—,E£‹±lˆÏÁ¯‰Sp¸k9€¢ŽB{œ‡d}{àXóÞì˜ï­Â°]…#Q&‹\9nܸdk4¤æ™¦3”ÏZVàRY¤Ð®ÈÅYŠ´¹N'Y—CøÙŽ¿9¶ÕFj•Èö3déŸöE¾¬+ÀÖ’ö†B¥aïåËhî72¯K:)‰"±cäéœÑ%i>FYˆkg7fÄ{ZEV&Iáw­6ïç¼¾s>7ÅgyB¸&T8[–RqŠ,0‘Ö±ÏÞ{wÿú›o¾_´hQ›víÚ-¹íæ›»úІÙÛBtWù”ŽêYï¬õ ¨¾pàx€´DöfÀªQئ_p­cdm6vÖé2†e‰,pv+ÂR× GÆîƒN[Á¹ù·¤oëÛ?€×ñÙù2ÆÄ„ h¶ÄÞ¹ ;rª œ}}Öihäñœ×¡û'ÉØTÊŒÌÈ€içHº`â¡®ÓCó{Y”µ¼9<õ.š<ë.2ä¸'rgó£!äêc¬”tä¸qãþ—ä×?‚0ÞÇ­¹׺³†þ–¼ú0'®²¿c TÚÌ|øž5ŸŠcµZÍU~g[çàDŒSÜV†ÆŸ,c äÊ"êÏÈ¢ÌS|tL»—ÍQÄ»Jª¬ªªúÏ©§Ÿ¾EEEEÏþýú ½äâ‹‹ÙÏûöÕÊØ1ÏËjzüâƒqì÷sårîðàÎW½ÕÉ€NüÍ}^®ÁYŠÓ3CQÖ•K[†³¼FQ˜3PsexñmùÎ.ÌcwäO;E ñ9&Ùb¾ë[€·‚¡P*9¯}dÝo>‘ÕzøŠçÙ5p" c&íÌóïÅõÝ8€ýq³ŒúïF+½¿Œù9 @b@˜+äú{íkÖä4œWÃf™Œýûç Îá»’F¦cã´u“±§v’åfŸ{)'ó!æòBœtƒ…íeì‰ö"?¦ñ»rqú®ç\/—¦¿ûpí;pJöUbµLŽbÎÿ%é¦&pœ®–t~Ïž=}ÆS;uê4aWãÝ8ü¸|ÿ¥µµµ}xè¡Úÿ}úiþ9gŸ=sÀ[´Çi_‚Ñþ8÷·|]Eà ÙÃ.å¢7¯^mù{ η·E c=¬R´³Ätöû/¼æa¬–U¯öñþ£Âµ¨í"+»¥,J³ E÷9ZÒ“)샮¡ÓdôóO·Sj´á'¹ÞJ…×ë$î*‹â?(‹®×zôÆ{È¢AÌÊҟgò÷ÿ¢,1Ö³9Ów¬dmâöRêÑsïyxGVÈo¤¤7ÒuK#‘.²èìY'žKS, Ø_ÆbZ)+T9;ÍÇ1KƸGìD¥'?»Çï,tÕb˜>Pþ´"¾çé(YzL¼cOöêÝ€féE'OKš½×ž{n5j’èUÏ3¼Œ-7Z™®k÷³ö’ukhd#Ç®“1—V!óî@‡Ä¶=M–vÕF¾Þ/cÜÌU°M=,Ƚq·R´3ÉçŠv§‹m2^šÎôá»]aîëpøWʘƷKš³ŽÙ5]Ñ)Ãxþ“dŒ¿>øJïªy°3#NüeG¶,Õñ{óÝA™9Á6S†W"ÌþOFó/ÿÎï½’‚ÿOšàû88ÝdE—ðÚXkGe³­Ã±gìb"Šr™¢µ7þ  ŸÇðÚ¦YœÕ.²ÜÜceéÖè9œ—©édS`´”H ½ýÎ;—<õôÓí>è å#öß¼Œfú¾¤yMU¼ŒÈr¾¢)²¿cS. ]ºÅjŒÄ¥ˆsp`f#«æbŒ­äUå7‘Â3çðLí9Ã$½ …þHáÒ­qôk Æóû`¥ºCœ‡>ñR‘]7§e ¡þxJÆv؉g}‹59U–rR‡ƒÔE–1ö‘¬Òú2ŸÖbOÎÞ I{C¡¹i\÷ di–=q¾Oa/d¬È³q|.Púƒ%ؽX×O}¾~1àÇ‘œßSd©$›(ñ–õ WsátY$9Þ±• ´ýNgºdÈÿÉ¢ùe8¹~²Â{nœ2ãIX¿³,ØVßh/kë}²¢Eæ/Á¦ªöœÇžÈ¶Q2Ð|®,å-ÂïëDïPÃds€˜}qÐ]Ún`Õ%ÁPh‘ÏßÛ ‡ÿ"ìÖù2€:"KmmJÛ3 c_Ý+ |ÌzN°ÛW°Û»932#N¤ic¨Pì‰sùí«dµfÈòÇÞÃ?¢Ç7"£ÅÍV3gSø8n—EÒY½;§e'Ú!Fyü½ §cž,ü3Äo(Ã¥IUúk÷ov)6»Kú¼3†ÄrÓÕÍ¥8ÎiKhx‚,/ÝÕvøRÆZx &M÷}ÃM7íñÓĉ/æåå}pL0xØý>¸:ÍÏ Bl!clÄÿµT´vØ–³—g²Ç§É€Öù2–Ç*^5ÍxXÇ#ç±2ã YZÉ`€›dÇmÈüï0ð¼2~ Çi Åà7É"´”Ü/+÷Ît¼ù½…²š)W( º®Ä[IÖµ/sqÃvz²m€ãü¾ídûjIáÐw)\®3sѰà³&Øc#eã¹~åh·—QÞ÷æ…Ýñ>òa«÷°GJ\&c€Æ;zÊRŽ~’1QÓ!+C2ŠýYäý Ÿm‰—pÄwä9þrƒóÜ ›·¤‚¡P}©ž/`3Ô792÷YAèÙØÄÏ+Ú%ÇuÈJ<(ëVó‡šI$»¨ϲgê}I§Kæyl±ÑØ:­±Ooamš¢ug¾,x­Œ™ô(ºÄé;•ªYÃg3îcfdÀ‰ô WÄò7Åß2* C¯CxU)Ú–Î+d[!´ÏÀXÍ—!ý“d,‚Ïq&–ðÿ.U â/ä$ߌ1GÒÏ‘‹r=•uhËÜ/€øL†ÚO˜X¡õ/ÃÏq su€¤÷K#‘Ž2ºvwöýBœÚµv1Â岂mëlOzºb,ËMÝ£hÀ“²<á%i*Ú!#Ê9ÇË}xB´ÀáØ@Ñz'}e‘ðV€m 2bàÃlÞ”‹ò ð·Žt©|Ãö‘ÑþS)~÷„,êö‚¬£†w¸"œ¯az×èTÎæ)²è\{¢·¬øÚ‹ îÙŠV×Ï‘gRݳdѳ-dlkÕžy­‘T•êÄX?ýñ…¤ÁP¨,…õþ`Ïè¢t×h)£„ÂÑ÷£sEg†¡ì¥ãd,‰|YÇ– ‘~°Zöʼ€"ÞQ"K™ª”Êeõ¬¯«i“h[åá¬c%žrÏ(b´Ä)ýËD‡™ód³d³bìÍS$=[ÏZü°¦®äíeÿXÏg 3°a]QÌ“eÀf;ôÕCP¢ºÏ™+è\Ýör¯ d>D8OF?¼"©,M÷ÑPb$²ñ2ESÔ‹dÀý>²â¦5€5‡(S332àDÚÆYDÿmfc‚² Îö(â¯d¹™ŸªþBˆù8GÈ"½eÑj)Zdqµ,r½ƒï=K Y C0]»½ŠõĸA{˜¬ »õ¦#KSÈe®^E‘þ€³V•ÙÞkµòˆ¡1ž(×áˆù”¢Œ“™²ˆÉWÌí µ&o‰òn¡hþûpŒaô¼+Cô¿–´Ô§ûËfoí ‹´ÿ‚q¸=Fûæ2vY”ÄÕ;qLˆùе_ú- IDATv­ø£p®ŒÙU™ R£1ø.º\nÿ™ÈÈÇ)Û”ëÆæÛo‰žyE¦»o*‹:†-d¹+Îá2dÜo î×#qr³Ž‘á©‚}˜£вÑÊ-zZ‰®€13Ù3Èy‡Q|‘¤{RØ÷²”š½ÐÝ*ý‘Ú½e©0ŽE ¨Ù ðk[€«“‘ÒÚL ò‡9±#ßa¾j˜çñØ8u²8HÛ;ïI^ñÐ×á~òe,žKÓ ã»pgÊÀÊõ:}Ù=DïboNg­^•ôq¬€ºÀ‰tÙÿÉÓ9£o"²°'B²Ô .È…‘K͆)ÑL×-G–x± @Ï—#n–µ.õ \ 3þMõºÑ¥=v—ÕžÊYvÝ¡òÙ?gV+32àDzÆp ˆ;®õ< ›«1&Ê踑ŒŽŠ¡ ‚` J¼ ‚¼ǫ៭h»=×¢Ï bÌGÈÏÄ9Ÿ‹Xæ0\ºÂE[†ºQ]‡±êŠÓÕ5\Û¿D‘Ëdy‡GË"€©‚›à`G@þ$£S¿Íœdœ¶ú‡ëJs²sÂ0^²í¤Ð m ÕÆ²™¼¯ZÑ–Ó0侓±æÈý&…¸÷626ÃQ(ÐöìñyìO`x¥Z”îUõ<¥8™ûÝç´óX®h'Š™ÇŸ™ÇeœÝ5ͼzcÏìÚ'—7³öyÛd½)‹Ä¾Ä^9-I²›,:ž'k•wuÌßË¢ÛÏ‚TÇèì|Ö»Æ#‡/C'½$‹’'¥ p&n|YʵžVŠÑ®ÒH¤³Œí1ÙëÑO®FH:ò Y͈ª$¿«ŸŒqW)i—`(4#…[Àµ–âxþ‘æ=–ÏžÚWÖ ,Y@¤ü`öÂZ;U'OÉì+ÿjN L{‘½ï™ÈPÚWä~_ÜÉŠ c¿ÜË\-¬CN°½îE?™‡tÈÅ-d¬”÷d)Që¥=ÔGs„ŒUZƒû’,æwärcÏø"òm;ô|+À¥³8ûÏÈ€Õ9ìïBYî œÙ¥²"—ÿfoV'ø,ëcûU?õç–Ø{#_ÄŽ{7 ¥žåÉ@ìëd’§±Õç)Ú¢øÖðCùB»p ç÷Ú È”p"=ã4 ¸Jº¯#oY›Ÿý8ˆ/p(÷Aye+Ú%#ÁÞ §«£ õî¡h«¿Žü­%ÆOn FµpE,PQå'jù¼»Ž+¨çþå1>«¸V9¯•8«å@d•¢´ÍeŽ“0>’@œó¦-dT·qö2mâgÊ"´§ª‘ô:c†MOE»'ô—!êÅŠ²,*1B~—±¾@‰Î’´"Ý€ÆX{Y4çpY䯃Œi4, ¥Ú«~0Àx ¨2‰{l#‹þUÊRfË(•2*üz BxRTŠXƒÞ2ʰKQ)P|«=c[Yt¨¹þ>ûw%^D²X]ÜYyŸwìŒCð(F}<]‰Œm¶…Œ6ý\‚†`€õ¾*@Ç]“ªÌÄÁtiI¹Š‚ß¹2 ýP£"Öþ¾dŠÇò=W`œß)iL NJ6:c4?¯ªK³ŸKxžå)îÙ-Á–ÈØ0‰²ºãü äçÙuìÏ<¾£òy¦çcsY1¼x¥^ûó2tõÕÓ†”ÈðFè¤Ã9CÓeQÚ'µv×íeé‡5¬ÙJO‚¼ŒSvûiÎâwÁP¨"²8{õBYêF!{îy쯩J¼®ÔÓ°©‚s¸×ƒì«@ÞôÁiuéÎÏsÖ~KÖV.D¶aŸ,™,coº"Îë3€ŸH1H0ïÎ9»]R8I6Y{ˆ> Ûý tÓjdú©¬m¾ ¼¿ZDýŸ¬ÞײàèNò©èrfdÀ‰ÌX{ÔÙÏ€=EFKk+‹l^†Â­lâût€£Ï¶Äh `Ñ áѧÌE#džêÙ+^!_ãù¿,Ïg1¿gÕs­ Y%$‹ö<œÄ^î ‹ôŸ‚@­B˜î$£+gPÛøÇ?qš’Š0~rm[ÙÇ}+EY¬]Å/(´ÏeL—?d)!iétáÛF–>ÑEVPjiŠ—mÍý·àyçÿÝ6k_€Üéä!6cí;+š¢âäG9Õ?%MhFFd6NÐpœ¨sp÷Qãíòbåòyz?`´] èÃ0ÔoGßÄ;¶“12%éܺgÝ^Vh³7Žìhùaoh¯ìÀ¡^KX ½èÇì«RdOt—EÆódL«©u|_Œ¹©,(ñz àj6ÎÚ™8Õ—ªþôϺîuòæ)ÎÐòz¾ãm€Á8ù©Ž¾È»ñMñÞs[œ™íxî»rðÙ'}< EKôúu’^†BÃY‹*ÎÔØ4Ë…ãH. ÷ë,Ü!c2½!K!›æ7ðû,YÀ­˜½}·Œ)±(…”¨Çdµž®ÄŽë€ 9WÆž¬aÝŽ“¥!” ï/UÃéÎñ>×Q2vlKE»PUÊs+¾’Eô´Xg€`ÔÆÌÇo²´™ù~¬7²iòû%žêÀV»SxNæZŸqN{1×{3¢·*‘G_+ZÃmoYúw3¦ufdÀ ÿÇå‹GÈ¢ð™.C7‘1n‘!‹Í%ô‚9Š2 r<àFv=ÀBçg­ç•åÙ[.À½òy(JçuÿW pƒ¬N"tø–²(óŲ¨ƒËW®hUòY™í÷ÈÅÐ>°ç%E»7ø´ÀpÙXEÞ¿½¢5V*XKWöcYëât°+J#‘,ŸŒ”ÎÝ‘(äwþ¢DçºnwÖs3daOÖ¸È#G\ŠÊ"ŒÕŸ­“1SÆHXÕ i¹‡È:¾<-cNÜ3=Zñσg8KwÉèÍc!¼c¤ œý—,o8Þ‘#c=œÅçÏNÒØÏ˜¸§ügYáÌŸ”&€Öþ87+$í …~Hò:—¡ ®“t] {É &“E+ëp&Ïd­Ü¹ …–$ù]qò[~}çgžlx†õoˆíòº¢õl~õaù6TP>@ñ×vØ\Æšs)-')ŽŽèel…ƒ%å8~ü¤G"‘ÞÕÕÕ-<ŽTºÇ¾ÛD¦n.KKÙJl•ôd E^c÷ëdÎYzïÍȲe>ÈÝËjÖ¸‚x–2tÀ@YŠóv²`ÄMȪå>Í_z¨—Gõ“1ŠÛkí”Óìÿwd îÏ’V6P¬ÚYVW£²u.gá1@©*¾'GRm‚ÀD Yç¼1è÷ç‘©p^G°/»Êú³ei@nÿ´Cv-çœDd,£PªTfdÀ‰Ìøóp¹äÇcôÃpÙa÷Æá eê$3\a¶Ë_K²”Ü5(ÜÕ²¨‘ë„ò6Êik’ Ë‚>²JõC™³–²oµ,Úð¨Œä{Ë7Ú•Ê¢ìý,¶lj§h®úr”໲"lS›Ò H`„Áw?Îúš€h)‹tv‘~}ùÙ[ÆÆj…Ñâ¢UUŠv ™ÆšMd½\KÞ ­?u2ÚË@ϧ0Ìžh˜‚A^׳Êò°ï‘±t³ëFÕÍ;KÑ”ªH#g¶=ÆÞR¾»#àI7YëêSxæücp’B\/m­xqô¯°:  -Jâ:½1˜—ÉØ©´Gm+«GÓGøÃzd×®²ˆw/YdñTIS“pöAwÈX—‡)Úb±>`âIdå³ì§Æ½çdTúäOû˲(éD®XWľ?HQšÿÍ’®W¿àtm½xñâë/‡wY±bEÖV~úϳÎ:PÒ‚&+÷ʨî{!ü< mdÀçYÈÖÏÝ>K–Eˆã~ ç«HÆþ½BÒtÁà±8ª#»>C^´ãÿOÁñ}gw’ÒÈhìÉA7•pŽ·À^Ä¿[ ¯~å = 0PÆûÊ‘±ŒnG?<ˆž=™^†¬ù·¤Ïƒ¡ÐÊ&Òs®»àÍ謥2ýqÎi7öÏ¡œó»d…N—Ôq¾¿ôè¾7d€ëvò‡­•p"3<ãYîXúz ŠãkÇ'Êt}Heм–WCû¶£ŒÅ2 ÇõY®[–,"T*«÷1ˆ×ï }q8vµ*òpžV„Ãῠ›#‹¢üËc\®b^—Eð6do'éýpQ•,¾¿% q0 É òBîówYë³’&§3G7ÁÑ]\€°¢9o@ˆBœçnUýdl–ÞLÅœŽ°K›Z,£ÌN•EŸ¦°. ey¾UéJËib]y)¯eѶ»d ‘ ®/ó–²wÛà `keàö]2 ì%è”çb¾ëzœ’C1êê½dE:˜¬à>]§‚/(RÙ{ù²4–1\çDè[¦}Ø{(ÀÞ…‰¨äxÇþ¨`(ô²@ãc8RôvIïùé.£9“ã§Iz/ ǯHeÜã©zäl'ôÜNèºÓÙ{‡dìÏ=dl‡TGgl ?¸—Æ ïåÊçóýWâ„u”¹*N€" ‹¼Ÿ••ÕêðÃ[2lï½[æååýÂ9}Ó‡âÆ e9ýṲ̂¬ë@¸ ä8l£Ù‰€/PüÇÈÒ+V < …ü4\Œq¬ ¸ÍÅ~¸2—õ}¦Ð-ÝúÎ¥v‘¼=£%:ëCäÏ'2&_­ß‹½9zžçŒwå^ŽÅ檑Õãº_–ršÎši-dô¥2Pö¿ì—‰¬ãÜswôܹ2¸.]P W{0¯§Ê‚»¡ÿ2)Ö™‘'|C1Ë9È‹Qô¯!Ðbë4¸‚“.’X­h¡I÷ªôüü»ØýQZ7ÉýºFžŒþ;VUŸ†2|Cq–u؃gÀŠ_'ÚÊÐüž¬ëTêÿFé\I«Âáð_±˜RgIGYáŘÏ%ÌoK îe´Là<Ñ>Ui`S4`Pôä,ðÔŠóó½ŒÝñº|ÊÛLaär[c°ÿÔ\›Z+Ö}S}x+@ˆ€® ÏŒÙ%²´‹©¼~a¯,Ey â¯,ÃzbŒU!W*؃Gʨح´v÷"Wtx Íõ€kM£eÅ|Ïã\ww†úFŒç"E)ÚbýžÆùÍõRY—Y‘Íëyæãe¬¥t]@ºËº-¼žè¾*Dv•¥^¾-idŠôèEFÍ~χ%+‘Q¸+‘Ç+‚²<ö¹èü_8?OsÆn“Egš÷ÄY”ŸŸ¿Ç-7ÞX^RRr¡,Í"[Z_¡4ÔlàúïqßiefÒÆ{¸,‚½1óv½âLõðsõ£fÉê|–&fÀI26ÀyȺ+e©>µØfWqÍJO {Ê€Ý À@-zûnÎØ²TA ¾çLöå2äê{Þµèl%Kù øU(\ÏLú°n+ã÷8Ër÷ãŒßË]ØÈ5ߕնÂýO±SvW3ÖdFœXßFoY!VŠv¢ˆ­³P_áHïËÛÍbµ¢=àňýeגϯvÆ¿àp×qÂ2ö÷j­¹]{Ér7]õëØÑ %ëÚv=Š/‹0—#¯ªþêÕÎ1¸nÂ`¼#¼†9t,‰8oŸ3‘ <ú"cwœÐ)1NÏÛ€€[6ä4»Î ±uuq…yóR|öäãíœùÎYMöm–¤=qffIÚ# ÍKð­’ÚKÚ&Ř˜zOQúàP-Å JÆ))±h]‡3×BVµ¾-€Ã‚Fô÷ÛƒµvêZŽ,B~’ŒŠ;Vþ´²áì¬Õ§ù4ME.÷"?ÿ•Ȟę»ZÁ=+ =à0u ²m𢩠99;ËRà:T\“ Pêê‡ty—ÿ{˜3þ6ó“è<=y:÷ç‡]ô Ô¤º‹Ogñ·çÐW§âèÕļǵAíèðï=r0ÀàæãÕÁÔ(DÚÊØ$gsξàsŸûTL¹¹éž«IZ”³¯6“E²÷D^ß/K‡™ïušèîdŽ~td0ú-Í·8[áYìÙ/pf«ù}½aÖ•F"ùfg ¿‹d)‡C¡é ^+‡³zƒŒ u¤Œ½RÓÈ÷_ÁþNÒ!ÁPh®OWPx%ϸ»Ù$î+ üíÎùºû;‘Nfn쉞øò¦?*ccdFœðq¸” 7êsDkcæ¸.v…ëÿ^ˆí"£Wm/Cl{ad®A°ç(ÚùÂuØÈV´~ŽÖî®ÛÆÓ –d)ÊÀp÷ê: RŽô‚+<ÿç^e(è2ÏÿUð¾5\Ç ªTÖ1w;`p•ÊPk'¸w—Õ8ÈÇ üGj)ÏqÆüÿ¡´ø°Œe1T†ú&8À¢ŽÞ²ÅÍø?Ç®(“Qo¿Eƒ‘¶TRE2€u0 d šö²(D_öH_öK[öO.sá5nî—BÍÅI~4/c·@iƒbnïqöÅÙŸÇý À ÚÃs¹,¢w/󱺩'Æ[{Ä0ó¸×—PŽ“Òœ‹ìuB?¹ØFÔ=ñéù÷¨Ëc½b2{ò{Ck±¬‡ýß®FŽkë2³ü‚¤o㈈åb¤-£ç>’„Á݉s1GÎÑo‡¬ZÉži,Òè:/ ÑŸS×zމ÷ÌöÉ= Cv>ÎâiZ§î²ÎE’†C¡É ~~+œæo$ ÷A•+£3Ÿ;Z ÔW@ à<º¶{×$çŸ%ןàÌ P3Çü„$Á1Wx:Ñn0 Ýç+² À¶Z› äõ^B‡]!‹BWÖ£{†àܢ#¥Švzx [éÀ§†ÖßÕl¸©Ýu}0J•éО}µ˜³µª‰eX E[vvåì_&éí`(´šô¢»p¿‘Õ^iŠB„dA£72+Y ØÊÍ]_ä°ÎàùކB?'h“Œ”¥‡¬’1–>j˜È“±‡/–±ï †BS|xœY0é l¤Zlë+ÙCEÈ• dL¨ÏøýÛ$À„ëVÃ^ì€mœ‡œ˜£ÌÈŒ 8Ñì6(ðá²½$e2Àåúl8¨ˆÈV´¨{bˆŸ€@ÊÅQuèv 6(þbb/£#ÏsýºZ‹JN]ñÖÚ¨ð€å@c%ÔJí£dѩӸNYîâf¼g ÷ï‰Êí“î ¿<œˆȺ©üϯЇÃ9ÌOO”ÕÎ8Á=dL×2± P`º,2=aJªÊ*µ`îÛËX=1h»â°´ô|(“18fÊ¢y¿âÏá;[¦FRu’)(Ù8S{ÊX[-åô> hÅí®Ì÷q8F•²èÒݲದ4P(ÖO–#?‚½TÐ÷ ŽË¢4²)²< údŒìt?s{@¢2öÃ<ö@å_¼Dc`D¡$Ú“Ÿ]ØË•ö÷Ä9GdÓfÈØ^K¼¥A8ݯ#ï¼ç²gæGäVc ÚË8«ÛêÏí]Êi)ù4¥¹¬—àˆŽPZ5cÔŸ!‹6F$‘HaU"Ê€Üq(1æûËØ{4d´³÷\-¤2&ÇC °@òŸAp¿+úð4%ŸJ°`Üí²Èzµ,š› PY*c–ì¢?·?í!£xo&‹ð_©†ë€, á@‰Q²©G£7À+‹s`S]…^šÂÚ}˜8ÛçœÌ½V®¹ÀV¸½›<¸FFÍ…S9Ò‡´¦xG/Öæ{öY“ÏKšAŠ|IåñêRÖh¸ Ä®Æ6z+ÆÄùsqî¿O1Çì=sÔ‚ý{… À®A/Ý€n\ pù€’OÅ9Ÿ3w"­7-òŸ2ÆÏß5E432àD³ù(í^ƒqžr_¡œßÃI–ÕJ)¹c|ÆÁ+Z;ê“å:†Ú¢¤¤¤í¬Y³*§L™R[VVæÒòMK)Âiv@Fk¾¯„Ÿîåþî>—ËsƲ;²1Æî@xP´çÈ"U—ð¹VžïÍÃI˜¢hÚI'Y”ÊuvØWÑ¢ï†C>àÊÆ¬å62†CGžÝËlˆ­’øÔz€30„&tÌF8£º ÒI x¦cdì»°‡þËš}Ľ”‚ÌÈfß=$£ìþ¡&¤wAë ‹Bž c„äâ¼$‹LNLS§íeÅß•EO*3¢¯IÀˆ ÷­eøm1Î Ø{K9Kœ}@Nz6²yûéé¬QfW^yÇ`ê—“û îzïá0 —,¦Œ×ã¹þÑJµ°í#@»c0ššàçÿ)®¯–EÌý;[É"ø®àZöãÖ20·ZÒn >GWöhgžåß)Îõvȣ瑅pT^4›„œº'd˜Ö.ðÚEÑV§áÅÓ1 KGxÝ)YzÀ]²`M2Ž|ù£‘÷K …–&1‡}eQåÑ…kÖ¡¼Ëºžõ,ÃFúQÒ?‚¡Ð´&¼ö"‹±Vûð|­eA†Y’æ­/l?Îýö“²ÅK “¤§^&c ÍÃfø:¹•…ìRê9û¹2šåµ2:ä  z7B¯¦gûlÖJó?YÒo(‰EH«%­‰qŒ½Ž¶û™£hZŠ«¿áRZ ™‡#dTÀ3d‘íþ²èö ðx¢seÔÍ¡8ÎEL4åBS"OÆBéˆÙŸ0œÑUÁnÈWd÷6ÜKì(<è'cxýèãÔ·–ÆCe)uWø}ž1ðÏ•ÔwJº8C½4Ùˆó7GÒÎñt7ˆÓq>Šuœ…™‡s|òñ1%ÆÉ’±\g¤aJ­ãæ8ÕÈ”G¡›\`äGöö›2&Þ 5&‡qBþÁžzîqöÇ‹²:ñžWHô æûÀÀ/SÜO¹2FÒ-2vâWè§Ÿtˆø]u3ƒmØc£eý£ƒ¡Ð¯M|EÌivçRžk$€Üj#ã?€k3d©‰Í2ú^‰ `tD†=Ò0ÑÐ`$òähYªaM kqˆ,0¹!öåý²tÛœ÷=9g}±9À–~~¸‘ë ›ø?²ôèýôçNU™‘p¢ G ²}–,jQ(‹xOÁx›ß—ú ä²”K1~]õ÷°¬_q£×§ÎÂ^\£7vž¢Qýj„×2Œ†©\ûWYŠÁBEkNTÖ^Ô7nF±ˆâ¿A}¿7&¤;Èès{0¯K1–¬Ã Xgƒùu))n^j×Ó6¥®åÕ8ß5lWãºn½e‘à#Vaß%‹ˆ5uÎn6÷±Œ 2€sY&‹"¾ŠS7-Å\õNÌ(À·×2â0eç¢XÆŽÚ„=7Húz;ì,G.M`Ÿý„<¨ðɘ͕Ep÷e_?ççòq { ÌŒùûE8ùŽ ÛØx]Ñ¢½õ9"§áŒÝÍõýd-mÈžîÂ<üÇçë«4é"£ IDATI²zO_ÈjHÍ÷ðê8Bï …&%p™Ý˜“ûp<›‹|ÌaîW&Éñã\|$ X„¥f)в4éŒí¼¿,m${a*²ç5lUͨ€ñõ:j¬¤ë x°78ØûãXI¿$ùv¢)ÆÈÞGü\5@cÇ ¹tF0J´HOYĸNõÇIÞ·KãXÌ^å±WZàî&‹lÀ–çésÎ èsçp…þ½”½‘EGߘXÇ}õewçlW¬½,cÍ"Kw:Qñ¥†4¶/Z`'*éì`(”«èì•kXÓ̈ʃWeìWùKæê=칚$ÖÊÕNÛm?tAûdßû@·òu T”F"{Êp¯J:7 -oLÚ‡}ß•û?' ý‘¤¿Ñ_\îÃZ¼Çu]ÖŠeÁ˜ eµ-ÆË««­›¢X‚ìj>ú%sl2#N4ÝÈ—QǯD€~,‹,|†bõSp¶–EeÏS´¯ôL‹ýü.¢þÞB›­etêe=7Àyè€ ÌÇÐpàÅÒ·ÃkêØ‹¯Ëãíd©“dTÑ{QhmyÖ½dQÒãP‚W"„@IdFúF6†è–²úÇDLe^ňpJ´% Ôé¬y®,òûÆí|5q±$œ BÈ}0€ú+ÚÒw†Ö˲èЬ8»~t—Eýæa°¯ú»oæÚ¥=µEnmÂ|÷A¦´a=\w!×u{å+^“dÑÏr%Ÿ¦‘ÌÈe¯î…ñõ\Ÿ9J–Òt;Ž\MÌõÞ—E±·ÒŸYu}¿+<¨÷dQâÓeÊnò ËáY., ú½ÇK#‘!2ý]½*϶ÃH^#ÿR;Üè†C±‰¬hõj€ÑP‰lÍOµL$jÇ{H–z1\°5ê­°C Ù7õ]#³9XÚÅʈûYøÏÿ´,ø0süª,XÒX`¡#öÂÇȃZ®yª,€Sƒ#ó<@ÜM8\U>É¡|£*§ùx ~öIfDlj®¦É†Èª…Øg#·—% T¸šBݲÅîhÅžø]±ç»É¥‘ÈqØA®ÓÞ#œûÿßΜZ —%cDÝ–„|ÊÂÖ:‹yo%K¹Šï\ÍŠ-¶%s—,x´8MÓ° rf`ÞÏý^ ˆrà^MæØdFœh`âbW™¬ÀÍ3òíY»¶²ÊY²¨Ã*B}«ŒJ×äžZ ®cH¢õ$Zòû/’æ×ÁœðöJŽÑ³g®!oÆÚY*ȱŠÒ>/åu” ½ÍŒôާpè‡bð^,K«ÉÁ9¸ £Äë¹ÜÔ3eÈ"ͧPèÓ´˜@¹ÎÛÉ¢5;Éèë9œå1Àß”ô[é¹8V[Êjüm"Ðê["«º<ôÃp饵;ÑíìSÆ9ž©h½›©8+Kd쬪f@ã݉=0‘ý»¢ï ÎÈþœ ï(‘E´+qÂËÏ/ä=3жõ’ô Æû.Ì£Ÿ£g`[ƒà!?Ï-.ÕŽx$Áº7|dN¸±%úª5õsõ={i$ÒJpH …MQÈ—ücØMbžsÑ•}'âI/Éfû¡k‡É¨áùسø[çøQYQ½Æ˜pûà$mˆM³\–Úù‚þÌBÙHÆ€ì$«uôì:tjΗ¥.¯$ tþÅÇY20ôLÀªÍ±Á†£?k‘ë/hMR Ô~ÚnvÅî8Ù逊i²(ÿ‘ô³,Ý%í:£4i) ŠP—8ó6:`¥,X¹-sqެ l¢¬ÌVЦ>÷@>ÞÄž\Æ÷æ,îÆgÞ¤ø9Ͷ•ë<õöSeÌß>åwTãffdÀ‰ÌHqd£\Ç"(FaŒTûxýn²èÔ1¦å2ÖÁœ5ëá¼`ÎYG¾8+a8:Uã´ Íu¢™Äk²¢hÊ‘eÕ͵è{ü9 ¿£ÙßõNè‚Õœ‡ØˆUmþKöXc{ïo8Ñ@ž/‹ø^œÃtKÎk•ŒõkΠ’•¦}”0õ8{û8桺žû‡£¶g0ú,‰ïÛ@-â:_&q¿/°gwXKd¸ô>8ûsÖ‹¹ö€ƒ—dE¾×a“tÄIÛ‰3TÍ=]¨ú+Y²HùÓȆúsÛÒ¦WË‚O‡a{5wí t·BNwemŒ\zJÒ>áÈÄ»dlªZìÖÐŒ¬NU ²ð+Y’wÕH±ö€ŠÝ*±/+eŒŠWÙgS¬%ïýÉR£‚ÌKGžo ëñûhf‚ÌÈœ1’¶@—Fd…‰çpFû2ÿ {¿ÆùHþumjhtå|þŠ>¨ŒñcÀf?!cŸgFœHÿØEÑj·‡c<ú!ð eÔN’ш[Ë¢ ¯`lNÔú]X¦… IuNi‰ÎG à Ü-CžПs]¹_q¹ÌHm¸ªú'Ëò-Ýh)£_„1´‚õø?Ei»^¥ÕYV`îX ¨5(Öd,…%Z‡ý±=é½9‹É¢C.ÿu2ÐK²¢VÕ/ÊØ gi=¢1âPåó*–Q°{âœôõÞ4 )Z8w Çx:‰3»HÆX#iM3 »J8P¡>£w¤ŒQð¨,ª»öŨ¿W kl8¦ÅjtCc̼Φ®Õï·>ÏC€û¾BÑ.—bgÖ÷.Ö?€PSÇyrJÇC¡Û“ü®Q²t‚Ï‘­‰¶½KÑŽE©´Ùvû­¹f-Xkþ¾Ùýº¢i·)Z/ KÖ™à<ÞÓ- FŒ•1×PŠ2“w`WĶN]×r:}ÛFk§Êm,Kƒh‹­å˜jµœÑ[dmUý,ûËMd ŸØkæÈûTôã¾rfž‘›¥Täò={" V”Q1ëeYÑëª4¯M6s¿3ÏÜ[„{8 %’— w©¢Èßé&òï^²”G±~‘µ™}EñÕEòktD?ÍÖՋÛʘ$ß ‡Ê•™‘'Ò2ÚÈ"Æ}äí0€Ñ?G­ÿ7Su(å÷5¹+’³ëÂï/`<Õ§4ú!ØòP€ÿ«Ãa=C¥?U†*gFz‡Ë§¿‚y•5mÎÆPZ(«P}¿þ\c"ÀyÚct Õl¸§´Z‘6`öQ”]þk!Ï´?…ÖzapM•E,›•Ó†ñT¤hÜN2„+‚ÛCkבÉe½jpŽWÈXK¿ÎLä÷y2êfÄ_1·´@–ã<ƒ».g/°jg ±ºŠŽ‘åឈ|olt`øUFinlOe¡Gîâ“¿©†N¾ hõ˜øw9ÌïͲT‡d Šš˜³6H–Vñž¤Ã“ r ó èy¹ èMäl]*K7¥øj¥Äc«a‹”pFàHuEFæà¨Ö°«ãWÊ¢½µ <ûè›§el½¦vl‘Ÿ†Ê"ÿM©o\¡r—*·1ç­N¯+Tî˜j5Ȇ8üs¿ £§Kú5 ù% Úãp–ÉÒW4b÷õ—1 öÃþ¶Ág8Ô®p¹’ Jx»aƒ â»Wpý‰ËÓ ’S3G‰kÎåž/‘átȵÌS:û$YAü¶²€Àm2VBRõ=Rme)K´vá]/ÐâÒ]÷hÊs”pâï6—gÊÊgÉ: -e(ï18<í8ØŸãÈMàÀÿ• ýB„m œý1àê3NžEH_Š¡Râ*ÂùtYžnfø<(ÚNÒF·ÞzkûåË—?#KÃ8¿#¶#Ø)2³dŸRÝ\ Q`'Ȩ‘m1T¾”E¡ß“]çç¡4ɈØCñ¦`(4CèS ÷­_õútÞg s¹9÷Ù㦘ùÎU´uðE[Ï—Ñc§òúPb1Derúׇq¢ÕÙ©Cö÷‘Eg ·Êê8Ïc¤í¸Óã¹¾}í"”ŠÅ3ï-Iv”å9ûZ‚±,ú9…ßÿMö€cT…d‘ÌJl‚Wqª$Õ–F"ÅŠÖØ& ÍMòû6AöeRüÀg]AG—擎ÑYTïÀ½º¢¶œbW@5;©£Œ­´9€ÞíjÚÚDÏ2ç;ȺC¤Œè†>ÙDÆ$ìÁó»Ni±rz‘¢µz&Ê@ü9œÃ•J?SÍÕ4é Hõ{ŸqiÛÈ@Ó¡è£lži† Üÿ¯ u©ɤxå1ÉÔ>ìÉ_dÁ•q’5 =[Vðø"ö@>Àϵø«d,¥ Œ)ÜÛâ>d{RÝQ|%¬ÕJÖµ.ðëXì~{*ÓÉ,3$Eé·™‘úh+«5Q@‘¨ÂÍS´á¡²ˆe¥r»,J2UM“+¶.ÆSž¢•øëF`àŠ2©O ÕJRnnn^º9󹃿œ5ZSO[ÓædËr%iR8.o÷TÈ~½LRû-¶ØâÜ?þ¸Ã)»žu©Á™+Ë3=G–žs`Åí2ÖŒ7u£œµþBY9PñÛ'kŒÚø˜ ©_gÝ0¨51¥4™ªhÔJÜÓoìÛNëœÀø»[Ñ|ïJÎÆ dÎoÈ›éZ;£JVˆ2cD¬=ÞGníá;9æïP=_‘V(£º/¬ÛÇîXY*L}ZïW†­’¥^¼…S÷qœ«@—1ýîÒÔ€CN+ìÜ' xô¿öòXÇnè§_8Kç²Ve²ˆáñ’†—F"&éMÅI¹™9>\ñÓ¶S­³ÏóÕ[Ö6ý0Y”z%çâ*YÀ¦#Žý%Æ–¨ëþOø¹”3òV¢ŽXi$ÒVÿž@ç”,€š&°ÇÛé"öâ¾s±g_Mâ÷è•å9½.l›*Y ms«%[D˜¬ú™ŽÕè˜78­cöeõ‘1eF¡«–°¯>•1~dO¬nl°Î“K#‘›pŒËY{Èê¶!é¶ÒHä©`(´lÉlôˆ«kRÄ:ß K*CýCV?¨/ÿwŸŒE5SÍ'x™­úáo±g÷—ÕqÉÆÌŒ 8áóØS–ã÷$ #žQ€“°3‚×›ËeÈó£²jìKô×G«Í7}UõÓ‹0®+1JV4x¨sçÎ=1ô[ò=åòŲÎ!sdHü<^‹eQâÜÓjxâ®ÛÔ F1û¡—¤_Ãáð+8S$•7å½”lÀ0”9zhæÌ™?07í¼ Œ‘¬åý²BhÊryÿ)cÃ<§µBÕ÷÷ÈÒt¶P´ÐÔ1€.—ô?8Øë$}£°:(û9±¡Òm‹sL¥MUâ$,ôì÷*5ï"”Íq”±w¯@›#çC޼XÑØÐê{dßìïm'ºsÎ~OÐýA _Ë=Š3íרÄÝ]V_å% ëæ6\!×"Y”¯=Îzg€….¼:à,)ZS% hĺƣÜ«C;ÀºfáL( Õ–F"÷ÉjTŒA×ÿ–Äý×ÈÙãdõJâÙ .Ÿ¿£ÖQ½cGÕ~ä؇§ËjÏôãùF¾|€]ôsü2NÈ<¥^7è'ɈŒ­7‚ó“È8Y?[‰\g÷”|À¨ ùŸ;jÑû“°Iæ —sΚ[ª\.U÷wûë8[èqYáˆ"úÕØ`ÿ“¥,\Ç|o"cªl+rÉÒþ‰M7›ï˜ nÍPÌ3æ­LÒ‡¥‘ÈÇèå3e]6n•t\i$2FÒø&ãÈŸÓdLÑäûì¡eì?—Î5ˆ}øŒ¢…Æ›Kšw-¯†úó­M2PÆËŒÌȤuø(Pž–G‡Bwc{už ]tʼnã„ýŽÀ]€ñèfùwNó g ¹jøÕጨÚz„HìïÞŸ5,Šð@”ØÙ(£#1†þHâ:²çóI÷µhÑ"|á…V#È;c„c,æ3÷ê×J@…gÞÝ¿—ÉÐêÒ  ÃØwù’•(£çp~‡Ãi­Á‡‹1Ï’EþHôU8î‚Q0Y…H8é7ŒÝü~§,ÒV_ÌlYZÉî2:õÖ왕2Já“앹ò·µa–¤¬ à @Ì¿dÑÎÌøk óéZ;~ °ï8ÃuE[–¥…Ü…!:Œs};ÿ®k\ÎßFɉŒ|ß0ŠËåoý–râzdÓqJ·×Â:‹ßsZbäwê.y{”°vy›¨Ö£G]M•¥Ó³d‘É™8Y ‘7å=\ã1ÌÈÂÿŸ÷MÞù•8oÿ•42 %›þ²…,Ú\ÜÇg6“¥½ƒ­Ë¡ÙSµpætgöù@öQ5Îò'²Ô¼ï<à‰Ë÷3¹ÈòÿáP}œV¥°æçÊ:Ñü,£êÏŠ÷Ã¥‘ÈÀMe)gIú_#r½µ¬Èg,ê¾<#ú”Ï\œ&Kåj‰û6öën€ ¹üûMæý[%ÎtÌaßufïï€-½v]Y3Ÿ5 cXüÂÞ«j`?ärŸ—ÊXÓ%í–ÂÙLÄk‡p&rjúà1dL¶,%ôrYáý,€ÍkmAÝœF+Ö·†û®/xºèÎr†•™pÂÇCøÆÍÖŠŸ²}0Êü¿²ˆZñF8窛ÝRëQþµõü¬Q4‚S0á-bŠšÝES£î^UžWuÌwƪŽÚ•ãj<ßá®çîi¨¬Î@ì}»ˆÕ?ÔpÛ>ñžĢßä!\np ”™+؉5èÄÿµam‹íVàŠe)9»MÒuáp8íŒp8œ‹q= ðfϲŠ=ø¤ }žç'P‡²üÑ[Ù£óe'Âá°‹u@I.EÝ1:î“Õ¡¨Œ¨•1"Š)nçÿ—©þˆ[FóA2Šs_þo1 àC²ÈJÊi¥‘Èæ²ÈÆ›’&ÄÙ–lŒµ'e4ÒšŒèü[èX×Fö\Y„·®÷Üžø‡¬Ü2ûmþ¯.ƒí#cOY„1ÑÑKF£î&K©zÖgð5ç£7N®àvr=€<ÍGßxä¬+¼ZÈËý=—sçù½Àó*ô¼¼r;Ûso.•©LÑ"³yÍÁ_€3³ú²—Œ )ÆA†£>:É¢„@Ž«FÅõB_|3YŸ®èÎÞÈA'ºT†)Üó2l•y |×9èŠëÙÃdu|þYAÙñÈú• ÎoŒÊ~ º/Èuã]‡ÎÌÝ?Xã›%Ý …êK‘éž›ÄÙ[ÝÈõsp¤÷¦x0 -ÿ‹È¶–ÌÁéØ9’¦!›žQ4u§@l”¬ðegÎÑ$ôáK€JUIîÇf郞ÝÀ©2b {âg›g<{x±ênù›S é¿I­wÛÈØkç°,¸“ù“¢mAGpO_ËXzÔ|»\´ä>s±åëÛóݰËɘ0+2fCfdÀ ÆF²»dt«xLI½ §ÏUbÎÇ)n'£]¶‘EwŠyµÄ±vNs^Ì+×ó xú€Ç©V¿{ÿ/ËãÌçÄ8öY€!à^ª­gfÅ\# ¡{‘Œ¾Y˳ßϽ Á€lh„â»A¥JÄ÷>«{þEY.^¶Ë\ƒÞd#`dPÑWkG¦ž•µ9›Ÿ P‡[Ê"Jç`d¼&«=-iÑVH—HÛª 0çË¢sO³Ö'¡“⌞E €Þ¿)ç(Àj’+N_Ò Ei$2\FQÍÃÈ¿MÒû ´’ÑF¿äýûéïÓfñï<Š9‹ídtäéõ8WãÙ[ó×#~:@m¬š à¶Ÿù=Iý?9Q)Ë?÷ùù7d »m:Õt0×*»;û}ož¥3ò©‚óò!úûkìO¿Ód³e ô±²:seAœWd쟟‘U]d™sæÈÒïžPÝÍšã(hj=×£ü$ÎÝͲ­ «4Nd†ã0Z-¯xÇù2Êï‰(­Ìhx\%‹°ŸÂ|76¶Èx è/_à@¡#ï`”pOœ˜•²|ä×y&KZUW:J8ÎÇ™ºJñyKÆbùµô•|œý^(þÙ Üú`ŒÞWdÕ§K^–EÝVʘ!§`¶ÁP/cX|Úˆá*YÄdϱ ï}‡gœ¨$ I•F"…;çpÍž{œŒY1ÍcØ:eÝVõ´Ű-–±>öÁ¸íÅ3^•é’±^<€‰ÝdQÆwêyŸK?»‹½_ƒáþ{~þœG_h8©:Åû¼ù‘¤#õ÷iÿÙ\Š¾ÈŒMÙ3çC¡D+×çÈ"ÿ£e é È´–1à×òFîÏÕv¸'o•ŒÑøÎÜ´Þ @¼ €¶µ.ü™‡\ï‡ÞÚ°ÀÕWšzQñ®«ØáfЦÈ^ŒÜ¬Jp-ZÉòþÏåÞ'éZO熋p Ž•1ü¼Ÿ-á³g þŒÓõª¤¥Í¬xe¼²aCtîᬇžCÇ¥Zx:À\ ‘¥æìŽ\-K;ºÙéçÜes6DoÃn_´XÆ,zÀb&F²6d¾ÖfÑ´Bÿ?Çý•}Úp4ÀÅBYÀæAëf}Ú?Ì]otXC`i/Ø>O²f1p"3|£e‘§3dÔÌxÇ…%÷LfîïË¢KÛ(¾êædTAµ\ówš0€Š"Y$i?”âF2e%Æ{sßHZ‡kÃápWYK­ƒeÙk%=‡‹ŠPæ;ËX.¸Ýž²hÅO2ÆK@¥meQÅÑ£Ù2Êû(ñ ùüYÔñ…8”¸ë’sÉ*œÃ;P  ôNïxrÆÕ æ÷^I_ÐfômŒ”­e‘jÇÂèÀ³Ž´“Œò™ãq®U ÏtÐXƶ8fSdôõº ®\öùp^<{†3»“êîB¯håTGkiðë*àgFÓ0÷ƒÑ[ÇC¡Y ^¦ z²²ä¿õ¼¯… (mƒ·‡,%d ûÔumzçî[Ζ«a²-g§›ìéDÁ;À˜]d€á†8Y§Iš …îÁžØ[VÐÓ½ 0„“u£¤'×a;ÊTwW#ãhÖ­sü ºòcYm„ê4|w(bý BÆžùƒïÒè! IDATN,¨ „iÇÙÛŸµïŽ.ÿì]w˜Seö~“é…†*]QQVQl+ê*V\Û*ŽŒ(v± ®«¸ŠkAwu-ØõjÔ±÷µ­Ýµ Š"*‚H—Ó“ßïûýî™I27™ Üó4=9æi Ÿ‘¿Q¯}]&9úèû=–±.DÛl™-g°Öu~›£{|Öÿ#Ï"xà„'-—«Àº$Ö5ýrZ>Q¼'›HO0Ó³ñ7[45þ_ÊQ«ÝRO@EXîq ÖãrNëe$ß@pH·œf¾0aB¼Æñ^0ûq8˜…WJõy°iÆ=äðî.Cí ˜ Ã`oûÊZ.Çt2ìlDSÙH$쩽õo}VR Ëä¤ðä4²–=iô˜1'ÖÖÖÜ·OŸÃn¼þú`VýpéÒ^Ï*æÿº³…ªÛ`ÖmK–íÝÃ@fÜÓü]o0c´Z€žs¤ç­åŽF㬠·uìË nTpUçÝÊ´ÝÁ¦©‡ Ô:À÷ €’>0Ëý¨ôé‘è²a½d~Oà} À» z& rA0û`¶û›@0X$œ« =Ù‘µ¹\†éûí–„Á¬ökò¡~–86»rØŸ%Q€Â§@q.έ¯¯sÚg\‰D† ùYMÏW`Y6ê¾,{i+:Û'û³üØýåÔ(0NºaRÛ+ÉŒÞ=V~qv˜X ËGXª{ý¥ô§™ÄáÆµ™íd›ÐÏzÿ9²Í¯ê6`Ó¦í=AF\0ʸWž™ÜS q5ÈÚ ÿå0×Ö™’¯Ë_ßCÀRSr Ô¿$ßɳ=8áI e"X ˆÆ+—È ôÊ:š—?‚YÈÀ&Lñýž ¶ç€ ˜¼„6X‘ 6þÚSÎå09#Y èð &¬Hð­¯Ge‘ÈÐŒsаƾ¯£A2ìǦÝÑs¦åt•ó.˜ùú×­gè"9CÅà(¼k®T%³¾*Ïh¯}÷ÿÌš<¹òŸ}Öá’‹.Zü‡ÁƒÛëûÖ‚”åḑàZo§¶YÙ̲ý¬@im#ö÷BÙÛ´çœzí|cAZo:d'!]tm!x£ÝÒ P”( ;CAØ) ó*Þ@7_þÄa`ä¾ö2du ”¾]”äµú`m';rŒ3}ÄŒt‚Î-•éì½Á¤½TT+.Ù’{Jÿ¯ ñ5Év«ye€šh HeW8¯¶¶vÝ…—\²výúõ:wî<ôŽÛnë©3:DϵžI²©ikH‚â÷.¢ýð*ªÎD|L–ÞÓíµç• ¯+— ¤xdøäéþëuõºÇ¿‚l A¶áR®Û$uú€L’ã¤#‹<Ï“_ú’‚ïmÀþ GÈŸÚ€†=9̾0åTÿ+u`rè&­÷æ˜? ˜±ÿœÒdæ”êLÏ…'8áI‹ä)¤ÃÑ–Ûœœçp>'{ËØ¤œ!¥Ö;é¨@Ó4 Üè-cL "[ÎÀŸ`÷éx3ÞÆ™Qr*X£û7°Ö6^)3 í°i3Í2þýÀlî-€ Yú#µ_¶Uà?U{ç4Þ80 Ìÿ]N}ÌpÜ G'éM})vpñ /½täëo¼QpÖ˜1+÷Þk¯)rl>3?U^O‰ÍBL¯‰˜5Ʀ+½ÞWN©SF€ÀÜmÚ—éò ö—S™ç¯yEÚŠ<—ÊÞ-ëý¿I€A1Hz¼Ht½­ zš¦\Ç{ͦŒp[]óâ@0Ø NIP̘ÎCâì"[R!{²\ É|-8§‘ëÒê¯0=RÙÞéUÕÕÿ~íµíV¯^½nâ7–wéÜùD÷ÿ@¬Ú[”N ²$vÒwX­@:¤µ[—†sß,¡8O¾G¾@žç<²‡jl½§k»\à@õ3Löu+Ý{È×[ ýËX ûß’ï”&½P1Dz¼,{i§³µC ²ëúµ»¾Ã©°ûP]§çÍ-ö ×÷kÎöŒ×c¢|/-ê‰'-ûd ÷Nðu£¥DÏõ–°Yù‡ÖêÈ^S f.QYOš*ü-|‹ÃÀlÁÄ_W`È (ñûÁÌÄz°QYnïeX '(ð_§óùœ .h˜ÍAÆ)ÚoËÀÎï½{ M"Î{nÏž=¯õù|Õ]ºt'‡×“Ìwä‹@Ðk9£Ãµ·Î73¦Á² Çµç>“jLŽÑ¾|V@@´ Ñ~Bב.ñËñ^–:Üҽ߆@!Ë „,«W\KNȲ®YÖúeý¨ž‰ìÛñmdÝ-Ú=…_£·‚OšÑÙnH0_¥ tlч_÷èuö…,ëT­óœeýQ€Eôßeýëæ›Oéܹs]÷nÝÂ=ð@UȲ~ YÖ !ËÊÏð­mÊ6†+h^,û¶d'œ® ;;M:µ—ìøwÒëÁ³´£×ÿÝË;›ÐÑÛH§Þªý¶Xï»Q Ä\ˆt€®¡%{2Wû{˜‘òÀfN”€Y•1¦ÝuV:èì<‚æéù`3¦ 䘙Q¤Éi_ÒÈ5vÿKå´-Ó|\]²TÑ“tÝãÈzÒzâ—ƒY$¡£tEo9I}õï®rì å¼ûc8žÇžˆÈá> dÆ4H½fÿ܈Nëfüf€™áš(Û­ë7£9ý°Çs:fôf8Áµ¥``ƒî°™g²B–µXš9À_ÁàŠV¾ž\˜¿P`×ñ`0Þ¾ ¥ {¢¿À¦÷¢~ßl8+…>ÆÖÚÃß‚ÀumšÎu1˜U?¤Ø÷Ðÿ¿f¬7ÆXçq sb=È„};šQRRÒµ²²rF§ÒÒÂ믻îÑ‚‚‚›,É`¶D¶îÁHÆàZ(ý,˜À©JõvâÙò{K¥[>|_aÓþ F×õÞ.ÛÙÜýÏ“>ß,±ÛWŸÝY:3"ðj¾>÷S% ›¸†æÖ¹£ôìlÚƒb[¼>L>ý#²ÿËÚ‚NU/­ídÓ†¸8 þÇK'Jw2µâ9»èÜž ö ðÄ'Æ5šùôÑ¿3ó鎾Oÿw18êîh°¹U¼NÊH­ùD­§'©•>×½Š×-”“Фæ®jä~)çù â¹8ëØ£Hø° Ì>†Ø³Ãý`çÊrän30I¬ÏŸÁÆmÿ'õxÒò@$Û¡«ŒîÊÓ£PàC;Ý¿RÝÓ>`æl+9•…ú{£×L_-=»Žzx­™*é¨jéµJ` šØ›{ ¸0A[,º»)K3õúQ à½M²´Nýktl®qöûB]×|Ç÷0ß¡:ÊQÎÀx‹>;‚è)q¦›ªûO£^R‘Õ9=? ¶j9`ȲŠ@PôpgׂÁxkÒ{0ÌÐëÓ=9béõ©`b¡®ôCW}öÕ sb¢ötMÔ:çHÏ:ùêý³€o|>ß›9sfU†êÅBåç€eÅ:ç+0þvSÆTKžôÕÅ`éh¾t·ýKûâ/úÛë‘8+Óè²"x"?bˆþ]¨}R%ÿƒü—Ïum«|¹E;!ýWÙž© Ón 2¼¯„úÉÂn:~€öÑ\$gÛºïǃ=5â‘Ý@ u:ØØ›µJ¶·®Hm3ëY"·ãÀ.ÓYRzYšíAdÕé0wiM½¥Ø³¢À$“‹D=ã߈|`Á,øR ^Ebüvü;õ;ìæ†FYÆë”ìfB¶—B½ÏÛª)—2äÜ?±ök´„Á Ç w ¤{7€¢VNÇ%`Æâ0ƒv½‚®«õ>5QŸ·¬ i/ 2.¾Àð>kòV¡ïÙÞÛ*ÿNMö?ß*;@…=·×Ï¥ŽŸÛéQ¨÷ÉÓsl֥댞©…Mù2׿)pÿ-*x¯Ö߇Ñò,sØg(KàXcÎW•ã.Z '8±'È0ª`R¡kó9ãw… >›µ0ߣFûw•€‹_ÁLú­ÇÛZÛ :)(D>Zà ­å‚Á!˺LAõH¿„,ë_`°ÕjÁÁà†eKÛÎ7ŸÅùòÿ ²¶Bú™˜>¤¶™bs6c)ØÓës°Ê¥ÚçO;÷q ¬ YÖ PïÔ'dY7;\fÈŽD"U3gÎ ÇÜ+¸ë6Ê\›b]ºØ[ãt°Ñ%t–ŸY‹‘¾¾&°'ÿ7,e¸O÷aE{±Èa?“õÑ×èñ½€Ž|éÆíuû€ Œá `\‚ºsäw|(âw4ŸtÉå‰òß×€}ƒB’“ÀÒJ˜ž$Ç€L‰:ÿÈ÷y‰F‚öb†ü«ÝAöÓðÄ'9ò~x vR-•ÚOítïq„êcìÙXó6È>ºWÆþx0‰ó3æÔÐÉ`ýé±rTß'̉Ú'õ ØÎYRWÁnø½þï?r¶šÛ_UºÎ‚Íl?ú`³­rú«@:¬d.8õXwý»ì² .D¬ýqè!'CÀ0¯ÖknŽ]£à{µž—* _!gwìò¹tnýÁ>óÐôˆÐ*ýd–9}Hp‚ÑÑWNY=‡îw²H ´ÆÝаl¥—Àn åû@Ǿ46bÖ«˜Á?œ|à¦t•Ž^ÖÒ{ öC°!cÂe`pIȲÎPõWóB–õt+S÷Hg=à!Ë:*NFG X²?Ø„ïUí©tK$tÔL°OÌ3~3´N€¢>dY/j¿?NŠè²¬q`p¥CÕ5³K\$`-X• p¢Pgg4˜iî$ý÷€ûÁÑ®ëÓx A†Ä8æ>ù½·Kß%s-íô¼Á¥k ƒÀô<=Þ–®,‘žÛ6»bþ}‘táÏZÛ仯r€>éÒËt?rŽ×ë2ÒÞ;¦‹í &mÌ(ÙJ0ó€ÙG êAÓë&–Hµ>o/×¯à•¶{à„'II…”’i®SÖ—b«³Mw€ Mpã Wë}W v'm”Óî,4å$D³,¢N—dÅø^± I™~l¬´QÅ8 n4œ0a‚i¦U¨×UK1Gƒ5æE°)Ó# lZríŸ"4ŸE‹(Û_×èÜßk´w×È™|d5LOÀ6z%6ÞC Åv ›¯‡ý^Zß"Þ;ÍeG{WMr7ZNw>ì•q[Ȳ&%9’w&ÈÐ*7lȲÞk-€" †C–õ˜Áfv_Œóå? ˆ½d \ôSÊ} ïÂòÃ.‘Î~ll;5  ‡,ësÙƒG@MÏeq”Ebx>éÇ£ôäGüdëÍqY?›ìö©@²˜ÆGh§âþšï~¾|©°@ÌÛÈ·X(Ñsª˜'Ù¡z| ²òA}X¶½€Á +â¯Ò¿³ä×O‘¼V:t>˜ìx Xš ýZ¢ï3RÀVýz¡¾ÿ“æ´€9–¯µMt¾¯½|¸Ö<ñÀ O£x:€ë9pu`6ö69v³>1#Øj‹Rç÷X&%×Tgñ^`¦à ‚v.HϾÌ&4Õax'Ý«bG@c€¢° pÖs›GÀ˜0a‚³äÆç`üŽ`Åùp²K²¢€ ÔÏ«å˜ÎÊàû¹Qk~΄1`Ùˆo2AœËnr¸Ÿ3º ¼ÞZ0 r(ˆÒ_¬ó{Š€­×ÀLOôyÿ@É Q1Bûm´Œ‡@hts,<´Â½ñ)ÍÑç Pè¢ûÕCç«»þÝAÎK‘ãuþ(`Ô ¨:†Z·õZƒ•°ûåüvð_£ýQ©G­ cSFV*d0³µ¬C ±©Ã¾¨³ÝÏ¢6í»ö¥i¤Yàx]¶¾ëÇ`·¹ï7[ëkRƒ™\³NÁó(¦Ä¹næ¾¶ÉR?9¾¯H ߬¿÷Aìï´ [âŒÎ.¹@EȲ&':¢WêGÒ&- YÖ—­Pl YÖ^pYÈ²Þ ƒñÐÜÃ\O›œ>2¾š Z|.}Oäg!3$ Û]Àò¡ØÏ`†sOë»ÿ²¬ã˜ðJðÔS¯´¼8¡¬s7­ïYÒ)• X}8šÔ­RŠ“c¸•ʯü\@ÊÒeéòM_¦S@öV_]Ï{¿„;lܨHã^©×µÏÑãéüž`Èp°?®ú·±WÙ ìoDã ·[ È’¢}¿?ìé(+¼,_j €u.Œ6Ïsø=‰ÈJ­÷Xp÷"3ØWžxàD›¼À¬FHEš £Qí-Q‹e•”üVZßú¨ÀaG)ÕíAÔõ\ ÛQƲ]3Ò0{¾½‚¶b¢G`æ|ä¢!;ÀYNÓXð lÚMß ~T£!M½ Kj*@Dÿ÷ ¾Ou 8{#±1]¹2’yˆlaµ¦nrº'ƒå<«’¸î5r$_V'€ašöÅØ4ûQ ÖF^ö®! b˜ŒþØçô9³úÑ=d•,4,—2ey°û1tÒšöp<ºt(rì_ç¾u6±5yWhMàÂJØ= »¡Zg­* Ìs)™ ¦Ü¡Pç|HC~vÖll6œ)¯3ì‘vQzÁµ†ÎÒ·Ú(Ó¯u; Ë4“™zÝöˆ]»_© |˜É{N Û{- P¢Y|kÝ&ÊQ<.: k¡˜y81dYw´ 8ž%ð)NU–‘ @ñœ@¦ëÈž²¬i­Õ°SAÃÿ@†×Pé¥xd˜$¹ ÌæšðKú²¬Xcÿ#Ø£a€ ®£s2ÈFÕ‚}ÚëÌ< fŽ7ÙÏ`p™J|®pævÞù¡ìììÜúúzßᇚsòI'm (ð®ìÑÀwøÑ%PÂ/âP»h=ésžˆY“fÚO ÉÉ:#ëÀRÇ{~¹y=%º7Zqß„uÖã Ù…î`?˜=µ~ùþá§©Ñk°ïDZ ë£Töd˜”{de­H Ùn¼1f‰3µÂÚ×cÀ¾cÓ$‘'›±xÓ:Ü‘}µ“³{+Hã«ð–Æ5Ù »~×: ÷ž2[´ú«lBÈ7r²wkNÁM˜0Á™vöíˆõsc%Ñ™åXå4¤¡‡ùÛHÔÿGÄÌÈdò¢‚½}䨯#=À¦¥>Ýë |f{0x˜À€sZxörÁìÔßõ=| nYµM|÷ÿ3@Ǧë=>ËAv)cX/Ç«v›''g7é›å0Û¥/daŒøÑCçÿkp|ýa'mÒ%f,æù:õÝŸ–ü+RS2d Ý_÷(¥@ú«ØÈqy+éÓ8~kù GÌàݛŠ«óeùÓk’,}Kä¾í&zÝÿ/éž &=ÙBÄcN¸#_èu38éE±·1} ÚkßÖÊPéŒ%`VïV4,Ÿ1• Ð 8ÝÑ“Ä$¢ -6³9))¡Ùºw‰Ög®™2ÏÊ.@•lgŒö‰¯Òó« í"˜Q¬ñÝ7Êðª x„œËÁrXL‡ònrÜ£Á¬Æš? 7ÑeE œLŸ†å ” ð`Ê(ÖÁnZê,]Ê1}. øÒIëÔCkÕU ‚i¢Y»‘ntiTckéiÖ‚°oÀòN`³Êc@ªnŽî׋r’~ƒ=¾¹:ê~¤*@X¥Ïì«ïYÛÄž½_÷øß`C±°n µ`潤Û>« é—Þ.˜Å+ûF<žì‰õðž@‰ÁLy]Ȳ^K‚AQ²¬[µ¯.×šŽ YÖôV(¾Ôy>@ö0^¦Ø:0£û,È™ÄwÊ·Òw[ Û,_ë ²Â„ÅþMý>”Î\ Ú±.UÚ7…ÈœÒ8®íË@`û4ĘF£=pç¼ùóWF"‘‡‹ŠŠºú|¾½ÖXÒK] ÁCkµ'È®:@zn•ÎÃd•î¦Ù%.°U"Ûr'˜á^œbÄô.Èd¿Ú$› 3/€„ih¹£|ŽCdËre«æÉO~L­si¯Æ+É$ ÃéOòï>Aâå!ž´Qñ˜îI¡¡þ°©Î«a7v«ÐÃdÒLFÒÙ¯°©ð¸ÑPJå4­“᮳Гå„_©Ÿ£×­ȸÈUÀ±Ö[Ê”ËD°³õ±`¦®©`tÿk6s  NXØÌl –{Üâ’1+)µãeü+@Š÷`‹p¯ßNÎýT÷\ØìgÆ¿ÀáØ˜Q—ôìÔÕh8¥Â”Åš¦“Iö&vyDýtÏú „è »Ï…³üÅ9£v‰Y£ ØŒÃF1Œ”õÒɆí°öØÛÚ¨µÊÕ}¾À‘rÄW*¨{©ËÆ“ë ö3j®CìÝ\]»ìÔ€4÷óu^Ot  PÖþ¿†‚Áõ-|¿,–÷éLœàµ$ù`3ÉËA¦Í `pFº‘‘§Áž‚ÁD2ɹ ËìÿD3à¤>ÏŒ¥í) b_Ùá>Òc>³_°>§5.éÞ-Cío®À¶k¤ÎèMôzNNNŸºººoÛ·o¿ä†ë®;»C‡ÓT¶ É'ßæ`0ÁµjÒïæ€ý žAætÉY`³Í dÏÛIݧ=ø{š®ée©{H7¤ãœµ“Ížã)'ɧ‘ì$_sAН/Oçq{iïdÉÞý(0âÙ¬J7ûå¨\d7=žƒ±@ÒɲÈ÷ITJ`³Qöƒ‹L=O`ñÝRüag:k±åfóK`ÚS†üa9ã,Ö5òº© „‡ ÃgLo&2ÌH fUbIG7*X"#gº¤' Î ³X]AÆÃ.fÀž—€=5VÈq|©Ïµ‰jšCö–“·5XÒÒUçÒ”¡ýhJ&LyÄB­°ÌÈšÞfüg6©u»‘f¶®{4Øð­›ôõK`ƒÁŸÓ }:C3Ö_ÅP*ýX–#LN@ñ0»;ç;³¥o²¬\ßýßuá=³Àlï=²£¼•Œ£®€àj逹F‚Á´;Ì!Ë:DÁô`0Ñ`m["2T¾Nâó Ë© Xo Ȫè²(NS¹G!XÎÖ À®!Ëúî5Ût[wXã›,?ãÌôéé?PHÆNei=véêÃõ¾¦¯F€Î] So-Ò4ç+è½, (P°}/ÈZžf{÷01TX:ÎØ_ä?ü &:Þ ƒ•Íèê·t»I?ÄsŽÚk-×5ÇÄÒ˜ä@fÄeS õú²¯èÌ-mæz[²6Ýå_´_ ƒÓcüé}:W‡€¥‰ÉØ¿±ZÿI²e[ºŸåž$$~ÝëÒƒ;èÑ^˜ù¹Dφº\ˆ† ³`Ó†ëä€o2Nû 0“·V¿3v?ÓÁPÌœ5ÚÎŽó¦^= 6…¼ ëª ÄÐÂM`àÌ<¦ÚIÏ–3–ÒZ„ñ(oâów€ÝÁz¨®Ù“ÔJ@÷g<8†/MfÏ7 IDATúœüAŽ×n :¯Sú*ØÄîÜì'ÓƒäY0Ë3¤ÝÖ»xλ‚šÎ’sþ»Á‡Aqsê*mz_d;€3N´»ô]_9×Ýõÿíô·¦÷…£ÏÖé¾/7GÏ‹a 5Ía3Œ5÷ü$°¯C_]ãk {æ'¤–nz9l¦Â£ @³äíPßïòu‚eçƒôöãá¸Äe®óû>ÈN¨qá=ý`ïnÙ¬QÞO È0s¾¾ïÈ@083R€K!Ø 2œÄ~>MÎþ× W»°¾¹°§G¬V •fnØMÙVÃ<ù@ûfu kÞ þ¬€ª@öëÁ¨3ÓKàÄLíñîÍ0Ë}Ö{7éшt‰iPX§çÙÄÿ*ØüVþ^*33Zò0Ð^ùEºãùQé}ÚCCèÌMÓë!ý~¨Öá[ù3MMÉy 6«hV3ç·/XÎz¼ÎáéÍôo1ºñ)53IäCí“éHmÿsÝÃ@vÔ‘q5€×é³r˜¤:ñ7ï–`Ò `òÖ+ꞸløÌšg;ÀƒBãä0ü ¢Ä¥ ů‹~_»;|–K÷¯±™Ý±êߣ3ªùz96ÎQ«@†“Z]…M›ê™“DÉq|Ç\=ÚË)0Ôï¡zÍÅ`v£¾‘½½ƒ~?HÅA𚔦C—#s'Xnc¤ÌZþ]Óëúý|°¹Ö#rúovᬲiòäh=ãr ›%gól°[{'w+ \•Á …9[YLãH3R´»tÏVúw)l@5ÏñZçt SjQ»Ùæ"!¿é±DëbšmfR¿‹xƒºRíÕóÀ¬U¥ôõ¿Álj*Ãá P,íåp÷yز½ŽIp·d°PçõL9Ø'è>·Än'`b[û¹U:!Çz”æõ›>k@q#XÊÙ*… ÷íÊÿÖÞHU)é³ ðö YVGW¥ÚÇ«Aúùû ²fƒäºVÔû묕È9ÏLOù³þÕ4ó^Ý@†ÅI ®‹¥+*X{Yz£Pº¤½ÎìŸõ÷´NKAzûK`rf%Ü+-3zí8éµzï) Ûè—ÖÊX§µ\"Æ9ß[€ÚuO ³ùN;ÿ¼î÷ÞˆÑ \àÜNhX2¸œö`såfb,%Û:LŒÔ¤£÷MȲ ¤ïÆËxdÈ.kâóoYf'ÈN&»?oÖš]-ýí±'#@öÄô¨À~/0¡6L¾ó|ù'OXœæ•‰~ÿŽ`o°2c—x¥9¦Ø£çZ0)õL .a€öúj­ŸçÇ{à„')0«Žœ£R9õÇô¬LʸúAJæí :W€å/À¦|›±}¦dÅ”±”èÑQÏ…°ËK|hÈÆ0¥,¦áŸ)15è‹AÄÜLX݈a7<&ëZî´­ ÛBoû¥\¶³;Ÿiª` ‚¬ |uÿt8Ø-Ý­½{ X7–| ©AݳÀLú8}ç}ÇåôW%ñ~ü+Ôê 2ˆzk-{Ëa-‰F³«œ=oL#MSºµ ÌÀ,Ñc)ì‘¢f¦iÆé­ÙÂ÷¹O:æX°ì­ë{ Ȧ ù‰1N)Ôy*éàK“8» ôë–TÝwKÜ:(˜;HÎúù²iÉ:ÃÝ€åØ; º–-@1VÀÂr*Ó’ €Å™rÂ'µÖˆÑ$÷ïQ®æÉNþž‚ϯG·iÖ.K¾C/hkw‘P-pâÿ ƒéj¨iOëznçR4ZãðéúƒãHÿ"ý Ò¯)0ûIg"Ñý‘­ÏÝEºæ@ YÒÑêì}%}Þœ}˧°œ©÷ë ‚Î¯ dœô5üGò˜öÒ,m­ QOœ¥?Žˤ[9uôèkÂáðqöYÖ4ÙíƒÁäÅ®ÚW?Êßy d^d4 dY}À’Õ}ÁI1cü'˜r†Ÿ2µ’•líÍÈV yþ‡NxâžäÊø^"Sä¸×軆ž–••ù,tðAyyy¢§¬ÿ§k}¤áÿ’àu65*Ñ)‘¨Ÿ“©¥=v§ú«¥ÿ#ƒ2DÎŽ'©“l9ŸÊ1›/À¡¬[½›Ž¾ó ì:HNª›ðý Ú·ìQ M5UAXFôw9%s}ƒ€™0ì3†å`˜I}åÔö³‰ú a)…9fj‡sR…)±2ÏÈ3Sƒ6 áôZppeµYoƒÀsX€Â 6´`m}r~×/“¼Ælõ•³9î–¹õPð¹«ÎÛß‘ËÃéûAJý¥Æ6ºÜi>œdò7rG%[–¡¬èî~ ƒKÚØÞÍ£A÷¯p¿4i´‚±¿j_4¶ŽYû¶Õ>?œšÓNçéV7¤1Ãì—¿f@½ ÈùRvm?éòýÀþCûJ§¯Õ™·ô·nöŠðË/ öP9T¶""ßæñÙQ÷Ñ'[³/˜3׺DßïQ}§º Ü£ù Ðkš°ç‚  ³ÁdDgën»ýö5ß~÷]ï½÷Ú+xÞ9çì$ߣ—îÅTÙƒÀ^1mkÅ`ÛA@Àò£Ïƒ‰€C§ÈÖ\…Mû%*ƒ@6ê#Š•¼Òœð¤…RÖ ] Òórd<Ö‚è|9ˆ,ºÚY·¬¬, ¤ýÀ1åååñvËõƒÈú]ºÞ å¾-Ȇ¥XL·íIi]¢ë­³å{ÈüÕÛŽ®ëlÐ}´Oú((ÙQŽÅ4_4âøæÈ`T`ã6»% deܦý$0+›Jã–'§u¼ö]µœë]À ›³‡ƒ³Œj@‡u–Â.£ø d­Pp 2[îTŸÖ> ÅÙ.)û L_Gò å.n»L^²×7PÁË@9z¢%1d[°»/ß›l°²¬þ`×ù•†‚Á•.;ßù =ù"é­»ÛëÁMÙ ,Çé2)>uùý×^» {Ås:¥¤»É‘)­PⱫ|‰n²c—(EÀËvúÛÙ$^ùT7ùÌK{ƒ%$û‚™úJÙÚûA`¼LÚ˜k€(ÒwH¶,$]ÒNàDîÅêL¹0j=BŒ~̲úôñǾKÇ[°Ó AÝåã¿%?|Z ¬j Aàðn`϶ž¯® ƒ‰–©þYgçVYÖ’sx‚tÈ“²ƒ8áž$)%2Ì((Hõ¾SFåß2#@j˜ëRVVöÌ÷Œ,//oN9ÈÐ]£kü¯Áœ VÙ Õìfæ³@”×ÜW(î&:(ofâœÖëÌ;<§câœúâ,ÁÉQ Ýdâôk@‚å =e¤óôújÏw€%6MÑq m½½œ•)X틉º®‘`¿T;ºÅ ýs´@š“awÚ^«kY"Àa>Xº´LØzèPçmJ ¥o.]c¼¤_‡t¿ÉRî!]ü:Â&Ã\3¯éfKwKPΆ»uÜCÀÆ}†y÷\2{7dYÙÒÇŸNžf‚Á-µŽÙ–”>–,Œ@ FÀ‚“@Á ƒr™þ¶º Ð`Ø3àe$Nf/ø •À#Ÿ¾Ã­ò£‚Ì׎Òãƒ>¾Ð¿[ÃOÊ–ý= ,Ÿ¨ÿ[,Ÿ®#È–û ?oÅkMTÚËV‡u2®©¹‚ùWŽßÂE‹Ž œrÊã‡|ð÷`鯢Vlðšìw–çuѾÿg’cIM3ç@v2b¦è< [6d&y,Oœð$Á5í¢|gÃî|ü¹@‰ÀZñwä°{LN*À‰bo‚Ù‡‘åååo5qÝ}ÁÚÊ#Ý(ç0“ÇofuhwÈØžª5v:@/HIîvÆnë C>솇= ôhÐ §»äê5~4,¯qö p6LuRûÍx¸BØ£oÍM–¿öHÚ% À>—C±4g´£÷JI”*ç#Gòj9m'€5”‘4è„\ØÍÒ" ÛÁ :xY€ÍSrAѹr°:‚L…7ÁlÚwˆ1×UçiØXm}úâ{›C—÷Ðç–Qa—tÔpØuÁã‚ÌOôýC–5lÐ7À!`ÐÉû"˜úø'¢ïUȲ:+8ï¯ÿªÑ>\¤½3Mút0oP Æ6`?„i P[Ó×ÇöÜzdP¬Ù “AÆDM]g¡ìè}ºW to“Lmmý;i﬽é†ÎëÓ»w{éÍ¥2‚Ö)׸4++ëxë‘GÞl‹L¬e Äî`9ê-`|ì£XçIÙÀDíK ØßãRýûBA/Qãž$$÷QpP°¸Qó.)×jqO“®Ù)=heeeàÿà°òòò51ècÀ®Ô=A ÝÅ`·áLV~9;ê:GÉ ŽV€¦^{˜ŒZ[‘=\ ÈÔ[Û45ç8ì Ì#âxvNJ1QbÑFöò:ºÌšý¢Àê°öM9¶‰6¬êÎ_RS«S¸¦ù`éËõ=޳€ ïIªíC/Ù†Q:Ãu² “¼­€'Ü„.xWçl½xuä$Ù¥SAFƒ‘`ý) 0Gýr§,0Ë~ßå`éâûH ÿ†j»_•“{D üÔÛJ)“]AvÎRp"Áò¨{áYr»kÖ¿»ÊùµwªNÌ0íçY³fÝ8qâ?ÃáðR°¡ª®Ïv`”© ög¸ôºìéò{Új@× À·>ŸoñC÷ß¿"??ÿ (6]ßñC.•\–þœ¬¿­½¥o€‰ÊÆ1‘£) –쾄ÄXS9ÒG¥3–*&yÃ&¶ Éö– ÅàN!˜É f‹J@Jö# i&Öf'¦ê÷é8h¦ÛõÑF—••ÝU^^^/g¢Ÿ îQ ¢~ ÈðXákï—Ò2T¯s& ïåIš©{)l¬´Ør/žÙQ¸W(˜XöÐøMörí°§˜±²±F¸f9žÍèZ_Øa/VéÙɶè¢Ø;xD¸W%ñÝ eŒÒ1K½JYˆÂ?« * O¶\©™ÁZðƒÁÆt»H‡-)ÀOk/nŒÚµ m|(€'Â`Ö*²†Þ†ÍžX#‡o1X~òœ®É °¬5î N³è2)æƒ5Ø/ƒlˆuM»@0X²¬‰ 3Îïm£”Êt 0 ¬¡¿Ç©Õt€9!Ëzöãö`bÆè;éßû8°OïÞ‘âââÚuëÖµÁá¶ N̆]RÕV˜nÙÕ¶ÐåÈŽD"ׯ_ÿ×üüüS¥?÷Ëu«ä}²¬·ÁDÇï­Äª0,¸¼6L”È6 û‘ÜÚB``2­@qÏ­ «ùGùªÆ§¬w]@ðý4pŽåÿªóç1L· àÚ“Ä% l"u8¿{ §ùrÀžR°mÚƒ™‰þ >N×—••m"˜•——/3fW+ žf“?GfvlŽ&v•3ÝYŠëá&®ûÂHΔï`X»H3ªÅ:›5Râ?뺧*(Yf«Ñz¶³GƒP]¢@#öœøÖ§"œ&p‘‚³S`×µzâ Ò´ƒÀörÌêä„=/ý6Çq¾Ô™{¤¹Æ»WsÁºß}¥ߊñûÓœDôÞOºdLYK}ÏÝ@¿Wß3uß‚ÙöúNsد¢-Õn·QÙAÄ2í—„FwŠ]‘­ûÕÀö6ntñ¸qÊÊʲÛK¼eN‹˜^[C¥SÚªl+ßçKYV=XfÚœVr„tL‰þ~-È~_>ï«ÒV\–CŸ –F% ”Xâ8ïgfƒLîË£Œ ƒn4J>N6Ëz>k¤ï×èß>}ç> £/,¿÷_ hï•óyà„'M“íÁlö)þ»3òg Òø åÓë€ÝÔ,mµeee~G"‘ëW®\9õ“O>É®©© ¢°°ð‘wÞù©~ýú­ð’%§²@N†À´òòò•²gw3õ=Áš¸Û›YËÉàØ­+tÂn6˜ÉQ R Ò`‡€¬Àº¾<pMW}«Àyc¯5 ƒ³=Ølõr´¬OÄ`ØìžÒ—å1%— ð9]޹Px’NÉ0qìÂîÒ»óÁR4Ó,¹/ Í©Ú‰d –ÎüÕ+c\ÃQ`ºîîwYïä*`Ý,§ÚC64 2õ¾™é»Wxg1íR–wî6ónq£î=†ÍšòÕWÿ=1kŽ·Ìi‘WtÖöT ×VegpjÏÛ £§ÞT›fÝ]Aàkªõ”«S<[ïaüªßST2dŸ6˜M$ðË'1eÕ÷dYŸÊ’•eâ+ÀÞ>ó\zë]¥Ïß˯÷‘ÿÛG`’é‰Ùšßå ¾»Á¬ÇhÝÅ+ëh>.©Ie 5i+ýÿBØ×gÅ4YÚjVžÖ¦DåååáÁƒ?WWWwþ¯¿þ:¬®®Î×µk׺]vÙ%¯C‡gú|¾1h؇Àül(ÿÏ—••.//¯=||åååér"K÷QÕ;âXË,íõ[dØV˜ Ö{O•áþ]€Eì‘Í)E¿ c¶ž‹t}Ýd·a¦Ytà“%E¼ìŽþ‰ çO š\ÁN¹aLêßUhùxÙíµt0Uà„— cO‚“u^W×èIú¤,ëxRâA kb]Ô™X.»³5X&‘È„O¥ëö”ƒø^ŒkxEga2˜ý+_·²w5ºþ'aw‚ ö;Ú[ñAú»E`Å÷È,Dæ´›ƒS ½4P뿟lÕm TZ,S¾úª^ G6˜õ$}÷ws"ùZk¢}2ìF¯, YÖ´§û‚`ØpÈ»‚‰Åq`ÙÜ‘níï(©sø†ÉH,c8T׿·â‹»C–õ €Õ*¯r˜(K.²ÁDÓo.ǘ>°Ü÷uÍc&¿ @2%˦¯Y[™"ã‰N¤]²¤ÜŽ(Ñ_kµÌ>=f·×&Äìfüß–rL÷}Þ}úôé·è‘““S1pàÀ™;ì°Ã²œœ3yÁ'ÅX'g´JŽj8#û@Ý  DG­OQYYÙ=åååé ^í¤u|W`CsŽó¥*p„Ö 0ãÿ)ÿsåðVK1®×£Bʲv]œAésÐp‚E;=JÑæ a߆*½çÏ`½Ý—FhÕ¢m Ã[+¨¨Æ `Žý×€@5Øce¥ ôÃÚç“Ñ6»Ê{Òz6#6`i&ݘG¡œf£'Š¥?ÚëÑdVužf6ºJC™Î`"àD¥öw9˜™û›ReÃ-N;û_-çñf¸ß' d…½"§µ>”c¾#X‚2Rçp%XÒö˜ùœ –gÖ³KÀ2È­eÿöÔ>2Í•}Ú'sÀ~ n‹t]¼Û‘ÖûÙ ½Žú.+šû.šSNeû!dYko÷š{Ã.%H…DtŽ’Š­¶L YÖ p{tâ= YÖSp‰ù!¦Æyò‰Ë¼é2ø‘¯{gz(0ÉLúñÄœˆCº‚Í©G%Rt,‰OÁ {¢u¯9` ZDrº‚?X60¬÷Íðf}}ý•~¿nNNN±ÑõpÔÏY åý–••å,’(øŸ® .àÄ`}¯wÑô>H|dY<ÖÔAAB7°ûö`ý]?9n]À>&Àð7b€œc4«å /ÖþXÒ’ñ»œè ØÍ$Ûšô;‚tÅ+]&œû­µÞÕ)û¬ç¿dHÝ ¯ÖÑ|(–Mè›ÕœÂÑ )óagƒra³ª Í׈Î5A„ Ú#`­íʨsòX¸7ìBñÊ{ ¨nX o5r?0ð´â°©eeŠÖ¶i§é1 v6_°9ðL¦õ«Óõ¬ÖzÍSP=Oúw…Þs£ôs5âcõ5ÿÍì­<Çþì,ûÖKv­Ÿ~î"@Ì€ç¦ ò&Ÿ üZ¬µus­èózyª$íþ}[':i¿.O"دW<ÀÌe=À§ÿO•/A Y+™üQȲ>“q‚£¨o`ñXȲ°¨…`Â6'V¸> º›äëy#<6„'8‘tðõˆVBÆù}pÔç- ÄúÁ¦gMIÓ÷)›Ñü]ô|pó áp¸jÆŒ˜1cF\oTVVö&€3^VV6Àu -®d‘Ü¢Ñé¥ü¿o”Ù,ÿèàn)†\+°`6Ø™Þ4ñÊÓÃ…h˜…\¨Õ©v<œÓ,6''¸—•À2¦Ë“9 ŽÑÔά[kv¸+X;^àËeúÞ—"ó'×xâ.Q»?ÌN €9-ÛÃ.Í2 BfBNœ±Uz®¾1 Çózý¼Öñÿû™²yØÈüFºf?°¬-gÒ”1½Ö"v1,ÀhMþ÷ɦ¤dE,“P °Ø(¯»îÏî1´¾ktOVéç5°™r•Z s/M7'v<7•‘vŽk†Ãvø6»c2­»Sõ(„͸i'¢=lÖ^‘ìVŽ—6önƒ¯AöÞ÷zýõ²‘ßÊÿIUÃÑZ—~MØ¿|?€)”¶$1{*Œ¶Ï*ê¦ç¥-}#·K"š8û®$ZÔÄszȲÎËÁÏÙdW‚ ÏçC–õ€Y‰6üT£áË@¶ÞÕp·œÃH‘ö¢Ç’ðÄ'’”­@úØw2ð=À¦—{È!|ÌÖ/Bâu¯GÉ(Oƒs—N¸Qz•ÝK¹'£œ§Ëi>¬.•óz5€O£ûP¤Pr@¹ */idOk¥óä|݉¦i|f\¦G5‹}.ž„=å²D÷°œÎ]½²¬û£œ„jõ‚Vþ®a¨#8Ȥ(Sðs&£Ð{Ò6÷By[,ªõØÌ>Jª)ÍZ šóÀló¯ÒCË`—ÕF·õQl<Â~zŽÕdö7}Þ@¦‰6)þŸt÷ž ÿINö÷àôœ§@pºlÔ–N°ÎI^ üPΕŽ/Y†)ÐdËu‘Mo§û™ hŽÅ`‰D=Gÿ.õ7‘ö[S¿‹~ êçHŒk¨w0UÚ«Áìòbé«EºÇ#AFØÚS&»ë×þ½,ùÉËÙRaÏ—êsûÊG©o$y¤˜²¬€w,Ma¦{söí³{¥-KW}åmèš]í÷!àaVȲ.û¬pØDùãe=²Ÿâmž¹ƒôû\§èŒ7aË<ñÄ'âŽZ ÁF\ۀ̃ãÀžû)pýœÑþ¾Åæè9 vªÀi©Bn}rÆÆÉ‘,#z ˜-iIFd…®¿œ  ,//_“æ{T(§sM#Ny‚çËðŽ ä5QKNºì“=ÀlëEHp\¨FT'ƒZ Ö—G‹aNÊanMg*¢ô8p²ÎÁ:ï§G¯stæ‹É´À.Ã肆4÷žÚßíôwÆ‘¯V<¬[žÖß/Þ©DêK³Šô Ü ë:X^¢àÄF©È š‚ÆûöD´QÐ8Rvòl´þ8HÐh.,[hJL "ØÓ§Ú¬bÇÏ:r¯5ÌóÙú½aÓù D|1€Žp ÐÁ€W¦4ДšÇFùʨç4ì‹ÍÜ›&G.Ö+àRXú8vÒ¿E¯{$6s¹Þ³Wà„Ù›ãÀ‘³{ëZÿ«Þ_!ÅS 6#1×6æDwØÌ3]RÊÌ€0/dY×%âÇÉ“ƒõ˜ à™e½`Nc£Hå—](½8 d“¥Ò–yà„'8‘¤l%%8Ì&ýNO¸ÌR Ž)2u¯•`æì]Ýÿ±ç´w3óôH•3~°œ‹mÁŒÉ8”n05jä˜÷Àr[yyyk¼ÎrާcS&DW°ÃøqrœÏð1¼FiÉJ9¬ûêžE‚¥;!Ë*ç~ÿUŽéå¬ÔJ“m.@æt‘<š IDAT_f$nûм`Œö”W;ÙúàƒéöÝA:¶Ÿtßv ˆÚEÀ„¡ºûÁb½#¨ýdAü$þ Æ®Cëõ‡Éuœ‹XÎï'`ÏÃêKTÞY'w|ÐÌßÏK<’yVgc^†îˆãÞ™Ò€dtš§hû⼦xþÆmÝòµÀ‰G¥Çú !Ì4A=U”i~ry屢ÎcM¬ÀK=Þ³º'lÍãe×çxIósc—'ÿ¿'seW]š4¾³Ø—ísSù¤ßk‘¾Òa·®;• EÀ²eݯ³º·Îõ~ÆËïš²¬gÀ&ü £Ê>úI/üà…–»xà„'8ÑBù]ÏÝ£œ… øi2ÜÀnâ#Z\¤Àm˜…z¬å]&…:ÌμˆÔ4ë6z§8Mç 5‘rSÖ‚ ß"+ÏLœI Ø ‚ü•^pñ»W*¸4ã´74tEb|²¬i`?«}µ÷ö• àûe= ö Z˜h½ý"¹p±ÿ•zôÒ½%½< ìk–ª3’&¥jZÉçL”H‹ï©ó²À;!Ëú@¶ñh'‚åÝ{é÷S4åãÅÁûÛ‘8û.)tøxžxâIÈ)”î°ëŒ£|…@ŠoAFE70{5ì(~(€#äN78BFâk—V68žôß`¶p8"î}¤fÈ gº È>o…{4TÊÿK­¥¤>6¯{DŒ÷¶sÒR ÒzYAg"yàʪô§·ì# i €›@çke¼Š’ÐI#ÁÞ'å!Ëúk \çòzTjßÿ*çþ|°Þó?`÷—Ò Õ8~1ÓLãÉ®`F·?4ö–žé{<¯ß(ú»æƒì‡9 –Ë!3 Ãh[@em3öyžöÜÎ`:™Àà0£vHï½Í—þ­²­Ò™~@ ¶Í÷e±'ìTù)†úÿ.€s@Àëí‡W\ <«@P°—‚¢fmŠìÅ*¯†,ë-Ã#œ¬½¿;®M YÖ³ò}–´Õþjq h1¥G-fN„,+l@{ŽÖ¿£üå'À~%©<û¹ ]ÑFÀ‰=×¥ûƒµo~ YÖ`Iê@Ç‚ŒŠeßp¸ÎÖ“)nZ »ížxàD’²Z ¥ š§d™Ã6_epw"8Ì:×gÁÝ,k{°¯ÂùzïÉn€ ÝŒ›E`ve¸ UºÁ ÓT±¤`ûµÎ÷ƒÔî;Á,KÊZNš4É4cË=:°v—õbýœ{ú‡©[Îs¼6vãª,Øúœ·ÀMcÇŽý5 kÜAë9DØÏ@M¨Ôør70û¶ XÏ|Q \ÜÌKM#ÒnZ«D†çPœ  4dYcÁà2—×¥×黕‚aP@ü¬ó°e²)|Ž=lΆiVؤwÄ­^m¥ÿ/‚]Ço²¸|X!ða.Hþìý°R÷€õ›Ypl¹¼&lÕb°is©~Næ3þR³ÇÙõWãXÇõ ¾F¯{ìÇò‘Pd¼¬Áû%`¿‘@ðùm@ñºüŠûàôXÑÒà",_ioŒLÈžirÇüeÝ&#úƒ ž£×_„,«\ûqy¦3¸ L\`·e½ àM´Œâ,ë'q=>éî?Óz†Ê/Y‚ôëúR åËŸZÒFl«'ZíZì£i!ËúdBí²Xÿ ‚”~ï%i¸€Ç2õ$ æ ¥/˜šà$Ï>ðK™’ñ»LŒÐ{ã`p}œûúMíé¡ øq¤ú‚l}À±¿cüš‚:Øl9f£@ÆÄj}f±‚éÏ^|¬ßµU6E–dë 3Ð 6›¡DØ gsÁ\4lhÆ1šQ›‹¨æÃ"bë`7úkk̇û— ¯”®e·ŸP`6v#ÈdlÕ¡²KÕrZß‹s­óÄ^£{y&˜‘ózü´ê ̯KSŸs~ÙûužÐ^liYêU Ë-¨Ïki@ï—þÙQ×;Bö9K:ä]íí¯Tdr#Íe倥V§Ã.›ýFëô.€Å @ÖâzùKXÓ®`™1`]ìóõ€ìôª4‚>Û˜ªÇˆ6䎅cÀ)G™´Ç²dËGh]ï‰#qÔbWZ{ú04>ÊO‚Ùµ½ïóh`yǶ°¬%~ÑHõp½q7/“,]|ˆtX?Ÿ“>ž“©e*Ÿ ûr4ÈÉ•_ñ¹€–O¬ˆÃ®uËãòge÷KÍí Xy€))èéì²8_ –éºe¼Q©`˜?MÓ}ò““7žxâ J ˆ°¤ººU0 DœÇƒÍg’ ˆv{Kìf&ÈÐnØî‹_ކ¥ŸÏ”ñ,ÀçóT6“&MÚDÁ+À:öù °–Yq3ÚÍ™Ù;¶-eÌ ÁÆ•£HÔ÷MÄ¡ú›‚šõ –^O¼l¬5,¡HÆà뜯{3@Èå®îä,õÓ÷3l¶Ôn ô†ƒtûZ ð²ÀŠÙ:³©Þ¦ÌÂ0̸ÄÞÊñí­ë,‚MG5#×Á.«X»‘äýnlfƒÞL™…kh©˜B°9Ë!Ú3w€ÙæXr(Ø”ò>=×’=•­€äß`ÖöE³¢‚béßCAª÷/ bOÁ˜…Æ(Ú„d}«L©ÚÝ øê dê~“+WH·&#{ƒ,€g´R¢”!î(étØì¶ øn)è^‘‰e*©(ÒÚ ¢¯ìÌ °_LÀÔ@0ؘØL¶-Ð=®lä³rüAçùp­Ór œ `v+7=ÀÓ`¢èš6p¦®“#{lú–&Ë>´„áç‰NlÑR @·3ØÛ`¹Kï{ØáÿŸ O—ƒÚA†ýr9…[‚³oœ§îÏX­e;íÝ5©Z‡I“&™/öŸq5U°™  ªµ‚§em fE¿p©‹ÀgK¯+G÷®À‹ 0Æ| “êq0‹þX;›åõÞA°‰ TI?¯OãÚ6ÂÎ ›õ¡Z°ŸÂ#^ ƒ«2U)+GªŽ–žÈpl ü(êÏ{i­’ý©q¼OWLÃô_3@ÖÌ›Öd›Ä‡ m”Ü)Ÿèpx=–'þY{í;o9<ñÀ‰ääE0ã¹8¿Ý I´f®XÆs¼ŒùÿÀLÆØr¨²~݇ÇäP\©`¶ÆÛ¢®H€‰ó,œ '&^'©Ì¢ŽRà_Ž48¤¢ç ‰{Ô‰½—‚­y  ×âRŒeu{“€? àŸ`p… ûóV°Æþ 9vÍ9t¹`¶u€œÊ!`-wgs9°'¶ {9TÊ‘_f4W‚ô^óóZý~5ì‘k°VË{D›c3žQkoåL¿ ˜îf×uS¦´3Ȉ8Lçó1§õ¼&ÌìÞ¥ë;,s+8óƒLÂÑAžo‚ÖžÊ ±ƒõ@&Ôé`pNkoeÃßËËîpm‚Œ€Z׃ô½F¡a‰ß6 “fG½ÿx$Öƒ"lÜWúoQ+ùÁ:ø3t~rRœÍtáè±-€ÏÁàÚ¨?é#pbºûZÇk·•nY6,ü,ó"$Wûekíé…È|y“êµÊ3²ûºi <ñÀ‰-M3ÀÁ½ú¨åD¾Òæ²AêÞD#ë@Šûà 8¶1¸‡D_2&<`Â)Q`} ˜I? ââ Zå˜ßÖTþà”@08+Ž×e $¸MŸu €§Á aÂøJú®`Vß '.ÌbÜ"§xX&õ®@‘de0‹¼R`J¢e`fd¬™xaFÏæH/›Æ«ëa7V­ÖÚÁ6O¢½õ¼‚§p#¶ûYĤJè|®Ö¿ Á nOÛ”ÿ>`ƒØv `vÊ׺t–}`õ^™/–|‘îºøeu{H2ÎF˜ÑšYg­Ï`þ¾ƒq`pMoS fÿ¢`âD06²öå¶ @=ñÉ>:GHg~›!€Îö`sñ£A€üøŒ£N·ô™=Ódÿœà„_g´Êå~LnKg]ÿ:pâHE÷µü,íã¹²Õ•)>£¦Œa­ÿ–.Ï‚€µ› _Ooãähy¥îH­íÁ •Ó0â5øõúrNƒóãΙœà¨‹,oƒ’Ý‘à8Ñ8œö`C­¥÷^kYMÒYÉËFNUv¼¦ž¸#»€”àA–@cûêZí½¤›È6á*€é*bؘy€ˆb0³™‚df<ìJPÛAÿHV¸t–³ÁÒƒ(À­ð*>þœÎI jÀûݲLºàó֦Ň,k€‚¤]Á2¹³ÁàÊÞ¢îY¤bŸ€†YëPô›߀¾V¾Í)È iº—÷ ¤7œ×µa² öOp$2g,–r|‚eu ÜÏþ`yRé¡ `§Ÿ@VÐËÔ¸8f¶\`Ð~ðÊ 3~ ÈýÉ[O•m^éØ3CeŸÛëÞ†âÜ'8¹YÀNÆHȲ:ÊFÙ9Wµ]×ÚàÄTmœ8Nûêv°„(‘{™ ¤û€ÉŽ@fW;X¯ó:d6&£eýlLiø^^0€Àñ~Ò³½åðÄ'’“Ód”®cå†t€ÝjwÙ:¬WÃÎþ<£ i!¶¼ ¬dL<¤µ8GJ-€‰,HùhHÁo§Ÿ‹Ð–oùˆîy•îy…€© ]¿ZϦy¡EêÓgúaOjðë}³Ðpâ`SûÍë̳SüàÔ˜³ÀFnç"² e!B6Þp^<´WQf¯›n.3qS›0ücÁn×€=FRå„–Ž=ìf8®j4ijoüìÝq›¾«¦yÒR öœxJº°±óÒÌ&:ýÀ4Üw³à…ú]¸-³‹3AJî,0û¸ö¸ØpŸÑ¬ÁÞ[ïqަz—αOöõyØÌ„>öNXâbF´©ëÈ‘ïp‹¾ÛEžu”¬µV°ÝMëpˆ°Q`0‘>í¥‡™fgÁfÀøÁžOÉFðJ¾Ë@VÐ; ‹-£ôeȲú‚l“Þ 0øR&ŽMœ˜6$l‹àÄx=NAØdïi–öh°wÎ.vÓ¿ õ§Uò¿§‚eØSõï è‘Wní)}¹¥Ë¤ÿ‡‚`¶'žxàDbÆ~¶hœa”É@Ë ìf¹Ž›†™ºÙ/±ùôUÈ‚M÷mlD¢‘N »d’—¿™•šV8 ùºžþº–ÀÚZSG]»q¡?‰óq<0¢Þños>Çû;?ÇãÜFâ8Ïæ=sädÆåÊùßIè6:—ÆSÃ,`b"ÈЈwšÇ!^›­]†öTò-ÈZ¡ÏzÌæ-LÀé f]Š@úb›¯«ÃdGaËa÷½¨i£Žz¢û" ,YÈ‘Ž6Àd>.ÎIqfÜ9­ã¼&ÎA‰èí°:›dɉ.ÙsÁ,ë—`É×bØ@jK¾k©ÎTPûh¬‚Ø:ï™_:zŒôMg¿ƒýš°4ÕûV×p¼ìXXBöPk×ô ˆ½OþÆ7(iøØUázŸñ â @q”Ö¹V чÍÝÀdÍïÚç•vþ}]ž×y:¤-4Èlœ˜*ûÖÁ‰Øä°4Úíóš/]±£>cù~íå/UI~‚i_ƒìæê&üƒ·tVvCcÙ7cyGk1öèiO<ñÀ‰åO`f9‘±ŸÍ‰¿¶5Hm¿Dpg)x{­ÓðÒ8áMýÞ¯ç<]n/g³TNFWØc‹|Žã}êäàš†~¦¹_•~7 ¤åÎ P¡ øvr—J§2¤3û0ì¡`³Pß=¬k¯³…kôX%‡~n3ÁLFˆ(°ËÕgvE±EŽ€ÇŒès2"êõ>5QZý®Þáú¯sNd0, €ä€ÔÜÕú¾Í–1(‹ô6˜]¸ÀuñtÇWýî­`Vv€“ÁàÌ8îÇ`†ïS9%)Ϫ‰–=,§f†'‚Í:ã9—~°WÌm~NEï‘¢šõ÷¥§ªµÇWe+ å ýfÖ •£ ÌÖ¨k 0C†i8š+ý•»±£ÑÚA£ÓÌØÖú§>3çs€á)Xö3NÍÙ¡,í¹ýXsØ b”ôÃ[niÍ©8sy`öóF]ó5únÕ.ß÷,骳†”jÏÞNY‘J&…žƒ¬·— »%Á‰©¸.s-e µ:€8Æ>Gº/ˇùXîQãØƒ£´ŸVTüo›±¹ŸØJAËâ ÔYaþ&ûHõT‡Îò9üòú°oÚzYGØ3bí“ßR¼þ~ÙŠ+† °ØNÿç“7W¶ñ]Ä]áª}úÿ]A°x>¶lñk=vÑ=œç…˜žxàDrbj}_)}õ.Ð7Á,Á“Çó5°†ÓPûM&Ø4kn@'µ?×áx›ŸÛ)¨ëª€ÂÐn}Qï›Nø¢†çÌæ9œt¿^çd„£~F#ßÅçx½1B9à¨ÔÉ`ÉAO9:´àß])ü24ÀÂÃŒé÷ëÁZê¯õ˜©`lÀtEZ°7¢×ÀßÈßE°éD†HÔs¬ónÂØ¿Ò ÿˆ82ü!Ëö™(po ¬Šã5%rTOR°sr Œ—Î×̪­³ié»"ǰ˜¥>_ìg`©Ç´8Äör¤úƒôú6=BLõüe XÛW÷¥ƒô@¶CoDg¢Ö>ntvt®*`—6mt€y•Ž×þ?¨áxïh]’íòa—Xµ×5vÖ½,Õÿ 0×qíѬ§HÔw1eWÎë_«Ç×Mq°r(È º£Ü”\»tê‘>£vφ¤ãžÇ€.‚û p–¾×º/w Ü‚ý›Ö—Ÿfó;H¯ß ²ÀV¦ 4S³§À^Ò—‚ÁU­|¦‹@öLŠc|”À:ì"¿¨X~:IçØØ–K:ý*€â—&쟙Øñ'¸œwq½Jt÷{&Ýß¶”öd‘ôR=}Òtvèª\4LŒ¬‘oôž@ŸÕqÞ³¶NƒŒã¶«Ò|ÿ Ó´lÌ9\ûu[Ùœ˜èùwßÿßgŸývß¼ö³ÚU:Ç­ë1>þ†t”ª¹$¹ sbÈßÒÁOô~ ìÓó™@¹­Xˆ%6dT Px.Î1¬~íµÇtæ_.ÔÉøqêŸØ@q¥ìÐÙÄ2Uÿ ’_à0" NKp(˜=l’¸£ü›|ØI‰p”Ž1¾“P û+,ÿë¿`ÉÉWÖ6Td$8!›ÒYçãÇ@0¸¢‘?-³V`߯ ¸î<ù&CÁR™½dsÔÔÖÖÎ<ìØ¼••½ä¿,lágf ¼:lL[ ,ÁÉ;­ N¼«}?ÄM°ÆœØÒ¤X—9[Ƥʥ÷íf"»Ë`ÞÐú#ïtÈë£ V-쬢*£œð}Özïe Cãù5ƒè|v:Lá('¿ Ë Â.;¬¦©Û %¶RNl/'ƒ™ÑÅrfËÁ1“ÕÍ(ÅÞº‡ÇÈP´×µ¯Ñþ@¨E2|[BÒa ‹ç90sæZ %`â^0k6¤Â&JÅô+È:dwÌh%G¤¬¥ž  jHI¾‰Œy1H÷ }ôô«NMlbêW?ù*fd´- YVîŒ~èxË¿þõj$é&ÄÇùZ˜€ÛÀH­ÓVúõ°œªÀìxJkSôýò@æÔÕºÎÇ\ÒÌ>Î6Ûé5‹à‰'8‘”+¸*‘ϸ3*eeeI­PS^^ÞÚÁ6È>(Ø~rŽ~v½÷z9´t^%gç20ûËiî–eœøì]w˜”Õõ~wfg{ƒEzQDE~¨(*P¬XcI4Y3vEÅÞ»(ö– ‰±áè1jŒÝˆ½ 6À‚ˆ€ôβlo¿?Þ÷æûX¶Lݙٽçyæ™­3ßÜïÞSÞóžs@$6SŸ§Îh;ÃL©0dG¼¢ïå°c3\@PTjå|? =6CÀD$Í«Æ* »Ì7¶ñþ}|f>Õÿ|-ç_Í.`ù@í­§å¨6fûƒ¬YV¥Z C.UÀw&ÈkKÎû¼LÔÿEªÓÓPÜ$УœØp§¬hÙŒ<3ÁgÃÉÂÇÒÑN©Æ—ƒétqÁ> ÑnÔéS€øXõ8õ(nÍ P †Ÿ‡êú@vÙ š_~¯– ¾Rö¼BÀÌ¿]f¾lE£ìÐÆD>Œ%À¶ =½›ìÓ;Å~ƒÖ°/JŸªµlï1E÷yq´ó&û·ȨXàÇfØ`Û)¸owpBÁv><^ ]â™"“Á’ªåm¶ƒä‹G»Ä:–’&d€â‡•m¬Q¦|Ù?È·í&.×ÉO{‡KãÅö“îÚM>ú!ò×?ן‚`N| ²Ö,8aÅ‚ˆOÎ@†ôa***Ú]AKØ$gš ð"¦L™/ä×#'ð@pÎü>rÆVƒ·€‹xf/vG}!‡§¦•ýš.'`?ÉR›ÓA”ù5¿Â¡IZqÖï/ z‚b&´a¸ÒåÐK0þXì÷/Šà%sÁ,í¹º¶SÚrJä¨)ã9Tï É1À¦hÔy+ƒvœ®o€‚´[¼ìr>SÀLáà æÎ‰Õ¹’scê—ËTY;n%ñåíç±ÒÑmÉ 9±‹¤ç£Õd2 ÌZÞ¤÷X-0áYDU˜©àõZø»R€LÌ÷²šÌ ÓzÖß'RüÍò ²ƒÁ1É{‚ì¿3AJ~²Ú(äGå/} ²ÌæƒÉ‘±îQr¯À™rªï(h¡¿Odp"dd>/0à(ùã@Fg0AòXŽ5ño\¸­îÇLÙÇö8O†mx’ööö²ß3ÁR ÷B´ƒìšôzuQºFSN] ŽÆŽæ=ÊPüÐO>íÊ‚ý\NÒçôݵ>°ºúµv/·ñ{áïÀ$ÍGÅ~0#€ÓµÛ!Ì2+œ°â¬Ç |÷BË š'‚ÔÆ]dyÀ P)HýLõGëâV¤ƒ«3dT»Ë!üJÆ` H{Õ,)ærÜ‚- 0 ûLƒMÓ˜3QkX ¸âƒSwŸ/ô¬œTÓlï¾ÝægIS@q•ÎÉïC˜ÊÑܹ¤ ~”îÿY Bßäõä(0»¤Õ¦  z Ìê-ÔØË`w3®§é|Tì÷ÏqýY!˜-èR§ˆÑ^ÊÇû 8±RÁé<=u¡åˆU'Q—ïÎ.whŸ–¯µ%i ŒöО›ÅkI³´çYÐ\ Wë}¢á@ûä¨ß/[ð@v)}PÀ2dkí®÷}‡¼*šz¹$(›œþ¤·_à$( x?X ´Dºñ+íÑ ®§€¶+Á†Ú÷‚Í3OŽ -Áoо_!»¡€ë9í—% Ðùœ%`¥6†kã³þg ê._lªüŒA³n"Ÿð=°Ô¡> ×é•í>d'ü,àdX¼.BÖT¦üü^ÒÅ+]~_È$9M±E®Öh¦@¯÷ä£ÔÅyŸ§Èw&WòåßÝ–¾•…¸Ÿ‚%|»à¶+œSž‘S8!Œ¹***2gµföw…SnÐ °âg)£À ʦ)S¦´'Jê•:D¸‡Â¡Ý=#e¹íÇ:Hq9+gêý“JdøÌˆ×t°Ä§‹îý…(EÝΈÃT0stx;›ÛVŽão3Ë*Gí9Ù«œXì÷‡„§‚ÔêåÔ¼ÒÚ†³ÿT㺇®ïp­óy“Á~Q¸×Cå@½ÑÄ`§(»_Në8Ä€’*pè|½äDdÂiNY›åˆ-×=_¨ç`sØM¼Ð£Î‚q—åÒ{;J…Ó ¹©œ ²¢îÙ=±º³€“C´g&M%7Déõ÷3Ï}A@ñ2íÑöÒá¹ £ì[K@ˢ̢ÈÐý½Y?º ÀÓñÌ”FA²µnËÇ9]{·ÀN`)éîò}.”-| ÌÄÞ‘$6>O6äplà².Á¥˜ƒbìè²Cù²5ÿû›ýAIË.`I‡aPFœð€eÁWƒãÍhìzÙÁÚ³ÿÕ>Ýâ}Í8Ñd ¬Ñû¦ƒ åcõ^¿hþ 6•¬JýíZŸ~WÖµ¯Ã/Èä=N¬±¦ÝŠ'—û\ü¤x†-EEE^)¬ž+Ë*ú*0­“ó5 NƒÇÅÊÛ±gE6ˆäž£ëË3:o€lŠÙhŸ’¼ fQÚ¤óÇIy!.‘1 ²e˜óAD<Î$,š ¢R£™,`ºnO‰v­s ’f4þOÁÀÏaæc”l³_†Ðæì‹óu¿ïWÀS…{•¦ãÏ2¸}uæƒ5¯ÿ‘ó‹ŒR7åBíë91Úí±4í½îrJwÓ8PŽAk?oöckO–)Ð\/'ÓŒÛ\¯ŸoÔß•Ã\g²P½7¢"Ó¾=\Î9+÷È&½„­EýAÐq-8é¦4Œ÷Í•Sº-³²Àß"»ö½‚ëiQ€ ƒêi`ü « ØpMáž©½>*Â>:-éÑc¤ï68°Øïßäû6d¼MÔþ9ÅY/x›lG €—e矗¿•Ìp½AP¾,u]0+ÿ€1Ñ'´wwÙ]G‰˜¥nžEXŠzýÏ䇞Š(õ¡ÑùÎ’Mì« ygýàô2[­÷œ°LB#Kz°P¯·Öâœ!ÝöªüýòDÙ;º¾ýÀr¶=uvŸAòH½Y Ë®@`Í:X±bÁ‰°å:¾wª hÔD`E¦”â~r>÷›dùäè/élSÁfF+TM™2%ÖÆÛÔÂýÀŸÀ µ”Ëß@–GY İR:HË_™€ŽÉ)í,ý¨ÑèÕ¹½Rt+6-Òc…t9\ãYã1»¬#¿¤]†²» LIÑy? ã•¢úàÔßP|ˆ(7Ó#U–‹œÖ8gËfj?Bt³_)ú<÷(Yµí¼WMÉSšökWé™>rÂúƒŒ‹îú]ŽÎ^ºþÏLrÛˆl9Ú¸Öµç+ô0 G¹ë¹\?¯„ÃÒ0£óªuvª±õÈäZ±†&ÁKŠ@¿T}¶,3r »*Ðv…éúß Lä,õ“ý‚3’v°ìÂ;`¾úfô÷ó`–ôx¬d*€¹dV•ýiI<ÚC@–a½…{¤·#µÝÁÒŽãôœ‡vh”Ùäü˜F¸Ûx+Ó5tF »oãM鎒¤Ê‡¸_gÝ/@­Agðx°±jOé„¿‚”ñÎ8=+ÖàÄ °¬ðð(ƒ‚½òÁÒÉGAÀ?š6tð›ÉWõ1<ëÆ/ï) âù ݵng½¥ÚÒk&Ï8±®ÉYG"1l\å87€€³Gvã6D§çN¶ìWȬX±àÄÖ2N†u¼œÄ˜‰ÀŠ<8³’éâR•rξVà6CßoŽ!³Â#ÿhM±‹öÉ"¦þ/“µ1xßGåŸ6¶L¨¬„èye| ÂÐá«„Uº‚«† ‚v“³ÿµîsMk°'X‹ý XÒêçóôÆä xÀ^,§#Æs°•!ØVòÉ » U Ñ `IS´ØÛh·A {OD°)pz¶xb˜>(¹ÒK®€¿‹]µÿóhdéL/óznp£%;Óˆ-G"7ºÀˆæžÝvË Pxô0¿klæõ €øçG»ƒ~”å9¹·?ÈL˜ÑúÌÏlÁY?Zûøu‡m9—^é‚ `côî•`f¸-IK-AÏ×¥#ul¯³³5zÝÉÒ³Vði?dI_éÞUj/OsÙù`9‡i~ýW°$É/Ñ“~ sb6€ÃEö«W(}áQþÛ’Ýåüd´'0é•­Û]þᅢlô-Ÿ*[ÁxÂ2¡JÙˆ+ÂÌÙpïD±Ì$lÔ =›í±´bÁ‰ðår‚n3Ÿí&EEEiRŠCÐfVòäHV™©¤¸¿‘ë1j°™-§ø<]OÈ ø¬ýRy¨†ÉÐÑóìôÕç<\˰QÖgv;ÆDLmd_…!5‚Ѫ0²…`Ó¹Ón=*Àï§e&1Í.è3d‚ÔÑÓ`u3ýSAªõŒXØàA°éyèÙA9n&°5 „O4È‘‡µéú:[–=`#N¿–t×kù\àCŠ l¨SàS.dÊPLõú}6Fµþ¦,ÁKO^R@±œ’ ‘ k"Öì7wýù »éïç·b÷{€=N×½øRÎé—!2é`Šse7sô¿ïÙ¸9©`Fï9ºÏéu×ÂJ{ˆWç2N¥Bí^`yƒa_uƒX¦¹ /Xº×Ô—ÊAâ‰zoÁf…ßÀŽüކô“YsÁ¤WÔJFl{AÖg¬ô¨c_“dñ¥™ÂgÌÖšûä×”&Ú¦P¹ë(Ü ðb¿m”tFVp€b•À²£¬Xp""9RÎáƒr„â"Mlî$gó}ÝÕ)—ù îŸæÅ€U‘ f;ŠÀ’íd,€Tâ—Á¬Ym3Z¦”U/0S=¤(³ÊYrfŒÌé»ÀÎîWÁf­´í콫ý7,§œÀwi?¶$}ÀÞÀ±Ô¥»wÖÿ›`åY0£½"ç?C¶æt°|¤PgõGéý·@p1 °¯‘]Z øµ¤^`O‹_NJ¨¶[¦Õ½dJ-r>ôS²½€ˆÞ .ÜIÀé¡T&@Öêþ.×ó2°ôg€ÓSư”C(3À2»[u3À’€ŠœX–l%Û9Ùìmõô£¹Lvþ׆YÂá“>&Mß<¯Îÿ*í½Oåcþ Ëš°bÁ‰ˆe0sû"˜ÅMØ`Â5 ¤ˆ\.0¿&}¤ÉÑ)1Pûi%ˆ–î"…´IÎï|0Ûõ=ȲX#§¦ÎåÌ'ü%­û ÍØJl@ƒi`toÝ“hK0sz„œÛëto«[0x'ƒî 0›öD^»ŽAÏ3WƒôÌJ¬|Àª³ô½´‡ëAöˆõm¥-½ú‘‚Çá.p¡d8Ý2zZXžqöD.XVt‰¾þÀõ`Y`]¯Õ ìȦtzšôù–ÌÁÖ“=< ­ü]·,—º¢Ã 83ô9®SÐý”€š l˜±²¦ÊL‹*TP:ó¡·’œ&àCƒ‚(3jx…€°ùz^ §DÊ”FÕÇÐòèšïVÈv< Û‹"\pb&Xö›ŒàÄhoz½Þ'O=U¨@x!˜›‚¢kT&P‰^W­y™|ªŠx^Œü˜cd¶×y~Àä0&†é¡ò÷‡Ë–˜É&3&MŽ›a1V,8U*8U‡Ð°¶Š)«SÁ²˜®r(N—¼YŽP0kÙ ì?Ðì|³]â˜ýÛ@–Âù ¾£¹'öÊî(gâ"2 mÀQú¿ž >®—ƒãžÎo¿AŽþB‡¯‡Pêá§ÝœªÇ¿íÖ³ÒŠ˜ÙðÝA`Ì€Y§k]©€­5é§dê2o3Úî.1ÑZV/Uçö4°Ü©‡‚›Yžm\„>÷€Ü²ÁfÓOFpzAFÈ# ÿ%Xæñ3¬rb¦d}ºéžö×£¯ôc¡„L8ÍhM³X3ù¦Bà™õ+ÈR\ªŸmÒߘQÀñf*d€}F&è3~ ‚j3aY¡‚É\Öq(€W=Ïߟ™]Ó ièiíÿAŒÇ¢YIzÉð•€…=àŒ£;dî\àñ ìúY ©Qß¿2¶ä¥è=÷U°?JÁñZpœßd\ ÇáÎÇK^ ‚Î3t-ÓÂÔí) ÖKLÖ„yí<²7¿ËŒø-~Ùd™=µnYpšÂÎX]3Ž·L{ÄôyX¢Ç2ý¬Îèêº$ ð½Zƒ»ÀdG…¾þâœN"é#@'YÁ Ócç/%À :½À&Ö£ÀR‚ÒY©Úß륣>`1oÚ^:¡§À’ßÀÒçví—&_e°të1:GŸƒLºoBm< ¸õGù<Ûéçˤcÿ–†TÀ†V,8ÑnÒOÎÓl°þ¼¦¨¨h0S“f!Vµ—‹ÀLÄB9TM™2¥³XÀ‰=øþæëô‘ð• m’ØH˜y,P )–BÝ&£u#Âÿ×_ÿ»Ÿ‚µ3tÖâ’- RåÝ f×Éa~¦ØïokDVW0X¯×Ø`·ž•¤ÀµW†Ãa8Œ×Þ;ÀÓA¼N&Ȳ8l¢ùJ ç0diü^gwý|žÎßËÒ ‘j^Z|»ÎZpúÆ} ¦Ã±™¦ŸÍÕ àËå|ù¤cMCèA`ß|w3“¦Ñ¤»Áäf}ŽÕ vËßX&0f£@‡j8% è8쳇‹À^…Þ{R-·j"hpb>Ž'8q4˜í¿Mس ÂÓt®쬑`R£»~W²‚æ)@ÿDÀÅj51*1Ræ jpBëÑGg£X:g˜ |§Øï¯A_ ðãå·”É«É ˜¼ÑV,8é%óHcª,**&¯ˆà¦cË®Õõ  ×‚}f‚싹 °+§L™ÒY²ÿOËÑ=HC8’!c2@ÁÜoÉðÁÕ|(]ßÖ$Áâ}H£Œ¤¿G82î°óÁlm$AM7°Fò9æ§)pkˆã=γÒW€™Í/ô¹g´’™ð*È3ãgZ5Û.gÑŒ+îö I† ÝÀìÛ:’k˜ —ÊÙ< ìõ, ¦À¤¡…÷²z*ØýÌPO“cm'>SÇ-+V‚ ˆg^©‡ìMô0˜Iýd—|öa(ùàL»èfwY_†‘'›æ3×4š\§Ôb¡¾^ƒ­{=tæ„ÇÎ`rho0it:˜¹µARÛàDÔG‰¶“ÛØè{sûƒ îh=÷–Îi”>[(Ýö¾|‰ÕQ*úiÍ¿Aᘂ²q]u.Ëï–€ »)!ô•H“S—€#¬3AôyéåEHFš NthÙFÎáÿêÆ4)#C‡6N¨é|½“­^úO¯U%ÀbŽ‚˜irBÖƒå!pýn)¶Ppî¾ü€SÀÒšãè'?͵º‚(}83ß{ÈmTÀúq5kjILÐs!Â)Zf8N‘q< ç¢dƒ™“qræ/GÓÕÇy? k8Ö9NÃÌæîùå:ãÁº}+Ñ"òu‡JwS€˜ NK¹9‚‘ií%¦‘ÝBÝÆÁ½BNú¦DÁî÷ÖYº¤þ¿¨}9±Ïø¥È~^v‘Ï—¼ œTRÆëõ§y«Àþé³h±îRµº ¢ý5ÎÄ 7¢Náz¿è3ÎYë,U#¶&C9GÈ;QççpZÑÊãl˺êžƒÌ ?¦[€¢c‚'eÁP„c£3dv“e#^˜íSì÷Gk"Üö 8:œbQóš§÷¸D7€Ì±'¬21æYÎWj}Ò¤ÿÿ– ®µçËJ¼$Õ.ÁVR'¥’¾ˆP©ÇVµóšš‘&¥×S`ÅÞ:øA÷p9 e ùuQQÑ'BV¨è å +å,öŒà5¥à‹AD7&à„‚šT×½3 Co÷.ð¡N pœ:`7{Æ8¤«‘<ÀßZïÝôyB݃ÝdÐk*-G¶,Yf['ëù±x9\ pg—E «ã&Ǹ¼$x»çà+8;&Ãö符ëÜe+ˆ2AânÒ¹NÕ>.W`øØó#ô«ilXÞLŽ(«Tz¿—î3ý ²Á2ƒ1ÞŸ ;`€àÔH?+½æ×†ðzKÀ‰"Å ˜y·tÒ•}BHŠÖ¢‡À‡²Cƒ¤ï2]º²RëõœqØó@¬–½¯L¢•³Õ{®ì^ƒ>ã5 ôñ’@à°†? Åz0é±B@Ýó þ‰  ZÝÇÉ*†NI¨±Ñå:“¿”/ë5{€}+F+ fÓJŸÖ¼1*¯rM»NŸ£Jzó>¿ ¾{›\àÙƒA–êÛ ¸Ûh«¼KrAº—ÌŒ„5«Xl SsÚDo©f}ä¦H¹¬QîÀlÀb›“¬8 lf8Ì,‡+{Ô»7åpÖ·âXuxÐèrÍÚ¥¹îC>ÈŒé¥{ÐO÷¦PAM&¶·æ*eì6À™ù¾TŽý ýÌdÃ6ƒ™¦d@wT@ð H·íï f7F‚tð3àŒ>Œ¶xÁZõ¿ë~?6¥,çâ¹f^`,Xß:¶™iý¤W’µAY¸ëãu)¯Îb:R†ta–ÎhŽt°yä»Îw<ÌÕߛҺ:¹UàÔ†ÚÏ¿èLV'ÉY„‚áé`3àßÃiyÊ6$‹ÔîïÒx÷Õûô^ë@Àü}íåEÒi±,KLp“®«ì]tB/Ï0¬¦ÀÆyëe‡&£y…½ Á¦”#@Ö€©_ÏÔßÕJ÷/K ¾Óó2³Çô7 It6=`&ù,鮞 L^hÔ_÷×¹\ {ôV±ß_§ËNYttæ‹uV,@±¥ô•Où³К$»þ³ÀQ²—͵c±÷S¢lv•ô¶öe]¯7]ºñF騰™ù¾ ²é§Ozíj¸M“»ºÉ+œH\É@'p"j͵İHW€¼³œ§ýÁŒL¾œíj9Ù³dt§1I¦„Œ ð–p¥§‚Œ5زöº©ÒΫ¤ýÜÐÄQ1A‘[2 õ¶Æ:¬)£¿Áéx¾ ÌŒ™ ˜aÖ4&Q¨#“w IDATÀÓšt‘S-@(XÕ¬ –ïœgìa4%UFÕ§@aÛjŸÓ}‹·£Ÿª5©°¼™ìb¶œÂ°6Y6ˆ‹µàÕýH×#Ì0烴öBÝôu~—­¿Í€S•Ú¹lÊ0çÙ°’ÊpþfÄgƒ™ê•:§5I~.÷Þÿ€ˆú&à„,Áˆ†xeï¶•Ž=Lïß]ç­Vgk6Xnñ Ø¡±É¬e]ú¯KsÊ(?2B¹¯9`ƒÏ«dË?“S>Wû²·Þð"ôòh¯•ê³~-à'Ù†r$ÏÔ‹–γ¥/øP }ô¢Á_Mÿœ’@ ì¡q1˜xHpq]±ß¿:NÁ²dîÔý« Ð[ÚçÚ·‡%!8qNŽ É »KG¾ &j¢pVS¥Ÿ®È”"}4À´ Gš{t†/ï V÷MfËìq±bÁ‰Ä—t0cÔGàDÌFjDišœ¢VŒ©Ê]±åˆ¤¹RJ_Àé:\™€}+Œsýˆ~‡(dÊ¡ì­xy+Ê{,X—å fSä@×€³R9`«@¦ÃJ}½ÌÀT§³ƒ€¡8z´øÝÊ<)gõ%9Á4³kšEOƒ“97”òn¦zÁa¶tƒÓTΦìê°œbi‚¯³W ΰäk^ ŸKŸ{\¯ 0ÀBªkýÜëŸ ‡µÐÅ,öBž~oØéM^ßmKÜ€B½tX• (6Ë)2óýF8#Ëôõf=Li]5€úzNG¬'ý~ ˜µŽ&8ÑܹÎk§G‚€ï.:>éÒ%ÒËoÂéÍíÀ§ì{p9XO½ ì³1 -BméÌ 3ƒjß­–mÍÑgjÐ[²!>NK´kÑA(Îb1í ö:Jç~)È*)AÕúVìì~î¨3KØÜ85~6Å]Ò%`’b6: +­ é§9ãáH¾††×‚,Ó9S¬½d_SµÇE¢7tÞƒ€êѲ·ßåx9ÃLñ0MóAöÓýà˜ÖR{L¬Xp"¹‚µ¤†Éii7)**2`Å )»ä ˜I“µDŽÔÛÃ`Ê”)‰à¬~àd„OmK3óǰù¶EÞRö2 Àÿê­l-ƒ#ێОrßÓ“ÃMÇÏg`÷PÀí“EÏu}Ý”²o2èY® ×E7®û¾Õ(¨-w¨5 úêŒ~ €jM‚¯ó$9ôÇ }TJl° à~pzx›<š2‡ÜgÅ<§´pfL™”a U»À‚R݃uøÖêyëwŒ¨q=°%»©! ¦Ú´§#g¼é=NüY€`{HšÎk÷G*¸Í×~)Èö!H1žƒèõ«ðD 6Îì«×žNnø5"K¯s³€–_ĺËÖj¿FÕF¸XG Å~MŸÅ u¦7´2(ØkðIƒK¨fè3ÿM{i}°g°$èöó8YÀÆ©¾‰#@Q 2ŠºK?ÍUàõªöHM'Õ#Ûºöw¨åš‰ ÷Àaö¼›$×|ÈD›5ìj¶}ÐfIÇÞ àõb¿?–ƒ)5=Kn`BnØŸb=lO +œHÊ5ù/˜­–TÄMŠŠŠ ½Øøm?0ûº˜ÍlK¾©ÀS,#£b€Œâ,9³‘8†ÊœLÔ¾D¯¯JŒi®àã(°þ|²Ñ2hùÍ€ î 8Å&4 n› rM [ã \Ýîj «eLW+ØÝ¬¿¯q$`yÔã`ƒ¨À‘Z«ø\ fú΋Æ~ÖXÓgAÆ‹ øÝël@…׳a0Tºó¼ d+”º¾7[­¯ÿWÖ¤÷iH‚‰4É$ÅÚÓׂ ÊŒ\öX)Vðñ)Ü 2p‘¡½°,]zdÏ­ˆBPäÕ{ž Nöè­ýù¼@Š`™^‰e:êoF;4¨, 2À)>}ôüyk EI °+ØW§d޼ àþpJ(”}6=T÷o.XËÿš€Æ0^7 Ìè^&ý\ RÌãPxd¯Žµ«º*0ÓüO0³"Ö÷[@T–öZ¼{N Y¶Ÿ`ËÞ5É"OÌ̃ÁÒªd#¤›ïäP÷Î ù¼ÇËßZ,ñ"€AœU3éT°Ì¶·Îçã olé“•$;­ckiTÐdFÅUÔg¢VÂÜ¢¢¢›8‰Ç‚Y­ƒÁzÝ9R’ñ Òje³£ðZ³ä|øÁlb¥ÝžaI ˜›ª}] ‡±`€†T8h½ëQã L×»‚×M®`Ö¸›°%áJïU¡×¨iò0´ÿFWpгlFÊ=ÖÕ>f µÄc‰>ß¶Qz½M`‡ýŒ&k¸;Áõ?npÇ ‰']õ¼®™à:ÞR 2 —¥'™ º÷•ÍÙKA¢ç9ìOð>XFN€T/§ú>ìcApoÈöz^ÁüÂ6‚Ïz0Ѱ¨×̰¿˜óß’@à³[`DÌAÖléÏñ- .Ðæ ”ØdÛ 27~éÜoØɹ/öû+ô6){ÀÉ%À×q(´?žÔu Ð<mG€ Žõ7_"zãe›J–lÐPóK/Ážaó@н²õ­™&V…äÌ’wÓ™M¦&Æç §¬(]çó`°ŸÒ%¶6È=“/0ç20q¹oÿ¦×³¬a+I´XÙZL9ÁH°f/aE}+r匌ј2eJ¼šÜt¨°^ŽA8€‚GŽïp.œÖéÏ´[3äuì RÁϳœfªˆa-jþr=V¡æJ¾y6™ùlÉŠˆ·lR)³eg‚ ]¢e öYYפZé°2•ø°dÊÈM 6ÿRÖM¼ “o(H#?J¢dö}²|¾Ô÷ ¼Ow”<΄‰×Rüˆ£°‹=1d¿ì"}úØèsas½2©½Ü §‚Œ„AÖÏý¼ ÿ ö±Ùäû{®ëØMú°ìº–É•";ÌÐϧã÷¦'’ã®®üýA õd°à#Ý›šÓû tÛfôªŽQà}¹ÀƒÚ®9UöíÙï|Ùú‹|Ÿ$Sw<:CA°ï(ù ¥ÚsYú›Zýl1Ø;å °Äw¹‚åúï}¦|„ÁÍÞ:g]´ê®ÝæºúÁ2§«Ár d’. 0[ªs\‘$×}£|X4-6lØóA6_¾Ím `\+V,8ÑáŠݦîó0Ë´˜Ý®Qõ© ]ð;—qëì’-‡% ¤5¶N<fŽžë?ç€}*šÎ•ï+çàWF ‘“ƒq¾³|98f‚E œR ÓXÒ4 5Í M£È ­ÑF +ÁLÚt«‚Èvy@ÊMŽÓ÷¤ø3;oÎím:· è&"¾½(vÖ}}O‰'¬4 Þ§‚†+02r¿œÒã´B•n #ð$ñ0€®BGx0õ?,¤ÊöÝfôC þ3À ÿÉ P7@çt¹Îê¿ †ÃTÌ™'×(è«îû@p0‘@ Ÿ®ñV°±h9€'ÀÒ”Õ‘°4jxœÖ! ,™Xì÷—ùÿ)ZË~}ŽU°X ;õ€g‹ýþIh Á©Ëý² ºëìí%}Ý]¾LŠlöZAû¥su†*ÃÕçZgŸ|§~:ÿÿ•ÓÃ܃Yüså_%“ôÁÏßtŽ«“äºïкŸö–Š–d‚,‰› °Jþó3ò™­X±àD'–4)ÍQ xö’‘nCõ8òg&œ Tg'¾³XÃÀ²‚æäDúö0«ÓÒzåu™f,Ú†'Æ8M÷{%œNö«äÄl³Šp&WTcË>up&'„ºgò@ á%r¶æ€5ˆï!8Êug8³ƒYçÿÓ}zRÙJ´?ëi°Ù•aYpÂJS'ô#þ½»ìбÓÏ)8<¡7î 64¥"ãø×Gp{*°;X×÷:Ø”í·mŸ»ìãÏ`‰_WéÅ Ð^U*P‘ ²4®ÒÙ«W@ùÈÔH˜žþf_û€ÌÁË|Ì„Ž6ìÔH°kÿ@°\`€_[èqá‘íþ?°âpFž')ó‚ôèò$aK¸÷ZéÞ³”ƒlØ{À¾fM »¡X²Èp §Ùe£ìì:0y2KgsžÎn™~߯}K€À©ÀÆŒcÁZ2I_é©• aºÖ8Ñí¥ét8Xj©xTÝái¦€ óë?X±à„•¦’*#·¿‚ìý6(8}[@Å÷ N;SéGÈœh œè'cµœ§–j+Mçæ!Ø:›o‡Ò''¥V÷¾¾F…ùd¬î”ӽ̴=‹¤7']œ"g¿§ û= õ2N½o¬íÝÁ’¥WäÄÔÇiÏæiÏÖ¨¶ãDJwNWp>L{Ò­w– ¥é`!Ø|r$˜Í;l¼ I—š(=´JßAxŒ-cWÒyÝSv¤À/`¯×A6s8jø°L3dãÝ ¹‰ÂÆóHºVAeƒž»‹ýþò^×”yüEÓr…óa±ßß ÷-~:NkÕWÁQ98†ô]­ÕÏàÔd%RAfΙÚW¦Aô+mæ"86a7ôx³öÓ¶Z¿4ýaE®ÑYýE€Å"Ùžuòw*;fãÚï' ºYüöA`Ï Ÿ|çµú~*X¦µdš&ZpÐz–~‰$.ë‚¿g¸ì ZÛWŠ'¬eø åü, ¢ œ¹ê¯ ¨˜‡ë#q—uìÞ 8á“£¹¯œÑ­ìÑgAZÛARÎù¼ö³kE`&è °Q¨ÕºxäT^ ÒÒ³ÀlWŽ Ir.6 v`â>rðŸWppbŒž8¥D«à0~ÖÈ,•mX?¦©AÏuÔˆ‰îüÌR»ûõ˜>>mèÔæÀŽÇÀ²‰·Á&Œ±/»*¯ïoK" ¼Òu^R@9TÁ_5Øûé-ÙÖÙ>%{s…ìt È$˜2*¢NâáÑW:ã"‹#,óÈÚKõYïRà|‚@¦î.½ðµ‚÷Of%#ˆ™fžÏY ¹ÒmSt.ExÏMùo–Àr§]l¯õÌѾ5Mgëän¾]$pd®öõj8c¼#±÷ ™cÀ’¦xîgÓkæcŸ´n {|Ì” &Re{ÖËŸþZŸ´G+_Æò+òQ÷Ôp$oèµÀí^Fð½}¬X±à„•­€ŠîRÂë3óäØÏ–Q|M º¶ƒ®AŽìt0û×Z}ë¹`íÜRÀ-–ÛäTýQ€Fg”49w‚5²óAõ»HžšÌD9£ƒÁìä‘Ú¯¦ÌfXûý6bSs XOÿ„‚¹x8Š»¬‘ †3\ÎsŠ+È3ýRê´¿L¯”J9åz” âJõ¼Él”a˲¦*½–é½bú±ÔEq’€×õyL³Ùt}6¯Þo˜ýM´`+øº6YO9ê+Tr{„߬×Ûp@^ÆžÙU¾îhÙÇgÀްýì¬XpÂJƒÉ^`ä)Ó™üs0Kûb›©—ƒý ‚5H†d±ŒNKÔÕsdl/;Pw¶3ênîXàq0«¶vZL$ûôA°³ö/ sçX9Šïƒl”Hêò›“#åü?R4ãô¤Ãɸ倔ämàL˜é¡À¥Pv®€ŒLé5÷„÷”÷J÷hÊzÐñ¿r9âå/Ê\~Tº@ŒÀ¦G¦®+ÎÔœ<}Ùäz͵5HÿžZì÷'Z&ª‹öaØ$Ñ€;(0ÿlÚLиŸö2(?µÃõ{@¼¨`wÚãkš.n'§ü0ûÜU¯W¦ímÜ_-»:d„ì© §A¿ûÌ`NÓ÷­9õYZ›ëÀ¾›ÁÞ)8Œ{@Pä ôy:¿+öû¿‰Bà8¤Wj½fØ ðg1%1¿Ë7Joü Ÿá «X‹Ñ_éÚ·=Á’“@Ð| ~–¯¿3€j®©ìÕw Ðýk >@»ƒ²-¦ú)²w=µæKÀ2Ê',lö„ù—>ƒ{Oš i½´^û€ÚAv,UkµFkôtÂBĶ\:ÈP$pbYþ]u–ì™)áø7‰iÅŠ'@2¤´ÜÉS@ÿu°ÁÔr’=Ø,£S#ÇqsëòŽœÑ‘rB›“£¼Ò[¯”Aî JÛ f€’Ó2GåçèœS8¢%ùŠÀŒÚ)`3´ýÀæ™{*xJkßV¬œ 6&¼d/$¬ˆ`ö R]À€OY–ž @ïzÎXï ²]ÀɰÃÓèF°åd÷DœJ×£Öåä¾àÁ6²wñ'fjïí ¬Ý¬·~¤j·µ Ì•sÿ¯v ÊRL{1ýIIsdX·ÿ;°ÇÁ¶Úµ`¦ð °dmºæî•OŽý¾mö…S𰬵hM[j¦™¢k9d3õ©ÿO€ÍšWÅÛ&«Ìãxp<äÅ~ÿÌ(žñÆ$ëÑ\P¸ ˜a?TËå+<ª¯‹W{:Sàœ-vûÍô•ŽÈÓš¡=ñK3þ™îó;é»XÛŠ¾:ó§€#QSuަø§®µ,HðË”?£ï6¡î÷4é‚`YÉA s¹PëXöèš*óÈhŽä\åÊïm™­1†Íøà Z¿*é˜ûû’#+V,8a¥MÛ¤§Ž³µ¹2,‹dh^3ºeñ*&Mš”RJ«@ªîÜñãÇ·eð»ƒ(ù0ÝV}ô2b)(¬maŸö3Ï)|3lïÊþ¬É쌂>rŠ’Ãu9˜E´¿ðÅ«3ö8Èbš Ö$/kÁìàj9¿^R~3"Azµ^ã49ÑV¬¸¥@nö@ÊïÝžnã5 ÁÌ`9å?Åást³ˆi`6õ0IƒИŒé0¦I—×FÉÎyµè¬Y;åZß—ü,mF§z@Pòb°ä+/ïÖµÚŒfüô|~~0±S‘³@–Û»`ƺ£7†ÎKŽûPm¹åò½^ÔïÇL†ÿD”0,‰\¾X X¶ñ‚ ŠýþH€¡<§Én¤¾vÈè8Láô›Z-ô:ÈØZ†¯UèòA÷Fó€°dÂ\2ZRÁÞ7i[6¬+œH(ISð}ظlˆüÖ)xš –5ÌjO bÒ¤I=@zð`93ܽ`Ýøñã›Cx{É\$#Óuº¤Ûyåx¬oc¿æHùŸ&绋ÖcƒœÈoÀ™2:¦v½[R»5€Þ ̪ï(Cy>W¡éÊž˜qªi`æÛÐøMŸÓìËÝ\±VÏ¿XÑ Su®î×u=6¾, âÿFéÿvÖõ^Ö±†Ý£ûy‚i+VÜ’'Û2L lÆš©­ÉA–Õ?œÄÐ4Í8ÏÐyë f+çË–½+Ф=Ʀƒ%#Çà÷NÒY›L¼¢kZª€¢Ñ¥‹wpi²kA ½Ên×v‘tù'+ï¯ýµT÷îŸÚW•pm<*im~§¯}ò²´gÿ*›µ °IJmAp}Œü®rõO(È.«g4ØOã1ýí5K(#µf#.x@ÆÃG¦ÊæÃbž/¿´¦‰_·­lÿXéÄŸAÜ;m,²+œ°7 ¢È:8Y¸MºÌ ¿(Sƒãgé¯=žŽéý§ìW5ⴚƛ;É^ fœ}²£ó\ÀÉp’& nPа¬ð}>Ëf‹¾d(˜;Z€Ò`Ù•Ríég@vP),ÞíGeIã@ÆÄö.{»ìM1 ×ÌøÍê`}œ’@à|ù'+åƒþÀ¯²$š“ƒäçþ9c)f:ÐPù¹‡‚åÃéZ›E`2î ° ´¥¦ªå÷NàQ«×ÞdhþLÚ,XôO0gš[±bÁ‰¤Ÿ£ýÀæ}û*H¬‘3õ"Xú±1®¯œ4iRX·wº”¸AÎM㩯Ç_áRÒ_Ê Æy»Zø9ž ÓÀd+xÞ5µ“h3²+ D¬Ó\Á=MÀÝD¯\`ÆF£õ®çz6c7ëªôYšS/Ÿ®÷6ÌT„ÞúÿNlVýb<"TÖ2d4·éš;èøPgV{ªKg˜Úÿz]ò IDAT:›µF«Á’ž ZÇj8ýLÄt­ÑûÞQ uŠîÿ$0Ó³lö1ÂËÖ¦8¬åö…¹,Ä×3sÐ÷GËÍ_­tî ìs»a:K)Òñ€ý~nåÿ·™cfÚGi?ËA`VpȈK¤^9)²ƒ-»‘ ÒkÁ,¨»Ó ˜i½,¹©“í»Ôëíö8°ÞA ÚQ²‡™²-ß+˜{{ {4×3daþQöªL*dÉöV€Í ¿à3SsYK{¹$è 6\²$bµç•Î{X¾a{®›™t˜ôÂPù¦Íݨw¹ËGÛEºâmù±»Èߣ{± d‚<+hA5+V,8Ñ!$MÎç!`-ì24ž…CÝ‹™£4iÒ$¯œç“Tl/Gm€¿Nœ8qáÊ•+?TàyR×2FÛ£ R ÅíÁ–ºÌªk*ƒÃ¢h€3Š0Gëê™èiæ¬4èáfY˜F|upÿùš¼–{cÓ38WíëX;»%@€»ÀÆq]ƃ)Á¨³F†x1˜ý\f]Ö ”(W@dF>Ö·C©F[`Õ`ƒÕíä|–ú4F¨/{5¢§hžË5ÖqMStîfd¬Xq‹Ozsg°¬c©~öžôÖnúYK²˜Õœ”¯€9¤E¤37 ‰Û«!E×Û ,á:BAÝ6ÒÛ5:Û³µ¶³@÷?d¥ôÓšW€ì•W.Bç,Ûˆ–˜‰H½¤#Fƒ@çù<)pÆoš}þ…@ˆµhÿÆ¢G‚Ì܇ÀDM¼$Lî–bî+½à•Ïó«|‹´¾ÿ„Ó\{üÆ…%^@çè‡bÅŠ':9P1¤§ž f}|àø´÷T|ö§Ð\9 Ê¡küä“OnñÅo›0¤2Þ dZ|Rëb´×É:dt‘©ù À' ý±NIC.œ^]›<ºÀŸ˜é€-û,TÂ)/Y¢ð=Á,Q¶±+Ú>¢ NäiŸ –Ñ\ ÖK.Ð×+A–H9œÉ q‚‘,°¶ój‰€ÙÍ Q>Gݵûk¿\¨½S׊£ó©Îí® ˆhÅJSõ:Ȭ!G7Cû¦¯‹ÖJ‰FƒµÚ/€#Dãáwð  7Ê©=‰îWú~ÀŠƒ êÜ7È6,–N2à6H×ü]Až¥ko½·Ó@Œ’ßCûZÓYÚ+ïaë Ѱyfll=€Íxê‰é»Ð d«ì²swÖý0=+6ìŠYòϾ“¥1,Ž‘»ìq‘(z¡‹tÁa`éÜöòÝ õÈÓ~]/ÿ{2Øì½¥R+V¬Xp¢Ã™L0ƒó'Þ½¤ èóœ1£BNš4ÉÔH~òÉ'çÏš5ëi°®ÿ‚ ‹î ­p5‚›ðà²@ÆxŒ Í@ 2ʳAé‡ BÞ´y›aF˜Þ †aaXÆÕÁ)õ0_‚Ù÷? ¸¸lÒØn‘\£À<Úµ :^1éŽY;FÂU`V3Ú{?]A×íêâ<fP›B2å°ä™äõV}YiFž“7ýw²Á>¹ ¨µ±•ÿí Ö”§”äoÛÙ—2‰ö‘>|¬¿®NâûáÓ=è–sŒ’­ë£3í‘N÷éë•`¶÷ئ™fÂÆŽ #e ˜ˆÈ”-\oojÇ4K_€I“mdÛ_›g—%èÞû<׵Ͼé#?Á0*Kå[ÎÙ³XlŽ"t‚ôànKи)%w—ÿ8R@OXžû:Î([+V,8a%lñ*àÞl^9JŽAÈø›טÑk'Mš”rÑEillü7HÉ».ÈÍVà– f7¶³eè{{ÈÚOF:]í:91È /‘® ãÐÚ 3£ê5-Ý/²{¸·ÀÀ,Ï8°L¦!Êï³=Ø ï9Ï€¥ë~‚r³š¼w.8‰!EM™½mVš‘GÀÆ«c¤·s@úiSûó é—P´æ³‰€àx®åZ\Ýu/Èfé&FÊæî‚Ω ¸þ1@Ïìdº=Mzp/$2ͺÌǸ¾-ý\Ö^ëSd€™øbÝ+Ódü}¹8 À†ÒGsŸwAÇ=u/wÖÞ7À\˜˜©€|È**¬8 LnÝ ŽðMÿ#½r@&eµÝBV¬XpÂÊ–’*áDâe(fø ˜©ˆUÉÇI Øn{k?)²ÃÐN¥ ­šl0#¾¿œîapjëäðÿ¬àás9YëÐzçë®.Vàšà_n³GV—t§‚,†lp²Á­1Êrø]¥{ù X:òµ@ˆ>`¦ç8­«tMPV(®L@J¹½uVš‘ `y×) ˜ 4mrßd‚å'é,\cG9 ìçr­tçÃàÈSÓ‹¨LÎúG ™Euä~™qÊ]@öÝžúü{*p{l¢» ³Ô#dƒ {§¹hƒìâ °\ãSÙöxMlAI ªàzØ,ro13Ñâ+°ÏÅç–ûý6ÈÜү̀S²/Îí$›è•½[–8¾,›jYÃ) ë&°´ÃŠ+œ°ÒÁîoŽ‚ì õœ¦Àú~9 ÑÎàž#äb0“¬¼NC fýÉ ç€÷ëºw“ƒ“Õ¯‚Tǯ@Äw`ÃÈMº)p¢ŸßŽü«²[4"é¢`î4íãk@:u4J¯»áL@x@`Ó,v† (ÉÐßÝf {ÈQ[©sh¼E~_¼Ø²ñ­™>“ªà(SÁ³yNƒ31Æ”dyàLì1ã‡ëáL¢1ß›`ºé4¯ËŽ6µ§î2/Ÿë}ÍÈ]ópÿny+´Þ™@k¤‚Ù7½õÛël¼ƒõ÷€ãïYDkÀq½o‚@î~ ÝÙ4ÞËt«ßêï¦5í,pÏ©é×볯–.xc| dCì– í2f¼ÚŸ À,úTQ‘€6T˜†‡ÇésôÐç¨{0½¯Ïò#€Å~¬¸ýKŸÀÔ™ßdí6ÊÞ½–­Î ¤8UöõZù’V¬X±à„•*é àR2œ&ƒ{'H³ŒV°t8ô40s¬<–£Œ³‰eÁ¡®ŽRðÚGN©é|½l²Y¥ "¬w½ ¤’ÚI‘é­r`öÁ¶qˆî”“íp €s\MUÀñs+÷Ï«kzB{" Ð$Ì€ÿ"°Êfäœõ2mLО#‡·@n0[W–9äê~d6ù?èû°õDœHl]c _kCCyoŸëºÙooK—‚ž –TÌGómŠâ=Ë1߬{ó%~Ïir. ݹH ?Rº°‡À˜0“þ˜!-ë`:ª»ôÒ9ÚËsLpT‘dg4dG ²#v‚Óp-ÈŽx,g1숤aJ÷g<L” Ò^o³ÿ߃¥ €)íÄM5[’4éé½AÑÒÝ µ¦Á0EÏXWÊ/´bÅŠ'¬tã1L ¡r<¾3ÐÓy†ãnãÁI"ï†ð†ÎüGı»{I 0ìtoFj-PÙJÃ,¯Ö´;Xù;åB¯F r½›NÍ–hšÇU†ÑˆÌ«Àëo`ç÷·A–N4K2äHÝR”—‚€Û+A9¹ÏjO¼¡×zGîÄ4i `—²\z(Pí£çîr\Í´›,­½ ÐÝ B#œñ½¦¹¬a4Ô*ªË6ƒ —Í x7ë¾UèïÜMj]×k†¾ìœæú;·Ý¬säM÷rƒëëŒWézkõµ=ÜO9@Ï&½P@×léë`÷M˜©? ,?ú;"î| ;A C˜Ù|Áõ ò* ÝQ6â$ý¬̬>à't,&…¤À_² Ò@vÝÓ‘˜½8RuŸê>²»éóTÉ.~2`¾G*ÕQ³èté©`Âdo‘äÓç\-@fªîç"¬Øjï÷’?uXÖsy{þ°oÎ¥`Š+LRít:©Q fþ¯3½¯*л[gÀB‘8c¨B‘urúóã¼>;Ý–³È,0­$x¤#¯*öûÝÆµÌf®•Ó}"¶ö(Hé]‡<^®$0EÓÀŒvŽÖ¡»‚ÒþzôÑÏÖ‚£f—„ð6Y ‹ázé®û@Zy´2®^°ôæV‚ ˜nëhƒ= ²NëþÙ÷‚™£8å®@Ù²ñÚ'­«)wpÿp&Ô¸™™p=õ“#ß] „)©ðÀ)£0@ƒ*ÀÒ€Rú¾VÀ*ý|ƒ`2Ô¸€‰:H`×ùLdñ,„ËÀ²¯ `·üîZóP™65ÄöpƒÀÃÔë>]Ëe;| »í: T¹h”n¬ûy€öËY sn!È0{ d}$;˜[¯³¦ìíMº'¯ üíúœñ jSt† A@u?]ߎpÆJÖê,¾¬_HoW¢2˜W á‚’@à8}¨FÁéCu$Øô³,_ø¦$xd-*öû;sé^:X.söSƒö|0û%5It·+Vbh˜¬tnÉT v#Ø}¼ ìñ0›×>E¬…¬øÈ_©÷ŽW®u#'d° 0)=/öûW¹ÎP_é?B ŒdK\f•’ÖÈ*‹”*g#WTwŸ}ôÙ{+8í¢µÊ‚C±7™f|×*¸üÀ™Å~ÿ² /¥—‚û¸^.@- >ÇÅàx×,íÝu¿#ÉnÖÐ~ ²1Nw­ƒûQ#g¿\¸ Ð×Èñ]«½U¦õ3ÿ×”Foú*¸K#òô0÷/KζéÇÐ\Y„{4nj“‡¯É³×`à¡F×¹IÍr°La‰‡Õ N7Áa4ÔjmÜ MG–®`iÄéº÷·(h¯KívGDO°pbº$E÷¸ì/TN™y*H0Ïô+6ñ=Pûäg°ðm?ùÉfáO™q}@œ'»z €?®=Z%ú¢âßÐ1J¡²¤nYUAæÉ£hŸ~fªW°¿É(ÑÎÈÈé´ï>™›lÀø¿^ù #ÆôY"ûg&X¼àÜb¿¿³5>NÙ6WhofîD‰ZÝ(±'˜tØl´û”uÑ­X±à„•Î+ù cà 9‹ À†DÿEðÔÓå}d\„ðþ'‚4ä r~!(÷)*àá@ýìÅ~ÿÏrDö©‡Û¥Ë\®EÔ‹ñ`Ú<9X}ÀfwÁlQÒ›§`Ö¤M@\—êó¯TPºTÏËäŒÊ}ueHP4dOü…àÕô•8¤ÏwWð|¯Âh12 áw ½[7BtƒÞf~w)C ÆA~gökF“×öÀ)p¯µ»¬Áݲ±É³ûQßH)Óý\6p\¦{¾d mÖß¹A+NÙÏßAºø<9âÓµF]ÁæqU`ïžwŒ r ÍhÝ{@æO‚ƒ°/Ëíz¯¦ãþ<:ãÛƒ%Çëë ÜDí07RàÜþ;JõYîÑk661zƒL£?Iïfè:–-úHëµÉ=ž´ È_¦uúdULEtÙ"ézýu/öSPmXõ:Ç‹Aõs˜]¦u· Û¶¡i:[;‚%‡#ÁÞBWwp"EÀÖ.ÒójÝ6ĬhCWôS§êÌ{e—ÿiw˜+œ°Ò¹Å«@ô9‡^{£‚¶RØWa0˜õ ¥À1`Í{Álb"ñ™röJ‹ýþ °6ò:ýì1€ÈQ`ÜGÀà 9ªý>äê³4e;T*Ð\§}°Ìd.è°åÞÔÑ7¨°7 ¬Ã¿V×U¢½±& Ë’)°àF­Å°¶ÿQ0³‹¬½Ç@x\ÃB0åÙrv u_zÂéÏгáôD0¥¦Á&Ý+Sa!Ó¡N†jàPÛ HѧÔÄ T°Äý·VÚŸt݃ ßk«Ýâv³Œƒ@í»ÒÃgNxÀ“užÏ{¥ìŽv­¿[ ²—~Ñù6͇èº|Ú+Ót.>Ö÷m|¶Þ`æôx)…Ú t~_”Þ¨ â|Ò=[6'4͆g€úŸˆ•jO'Kùœ™xrÎ{ÜÜ6Ïlcoå€,ˆÝí ̦YsµtÂl_k¬wéíö²K)Ú#‡€£™gX]ì÷w¦!ŠýþŽÞWÈ#»tŒ|¡uöfl­÷Ñ6»*,k»LŠ-ð´öÅ• iÅŠ NX±‚4’w7Xâ°dTü­Óè3äÌö)£«BxÏ1r¢{ ãdÈa-kGGÀ”q<Öœ®νŒ8gòJŸÖ£@׸£†@ï6r^›´•p2àKåø/©¼+¸›,x½@‡Æ¯ñ¶Ú ‡+ȾNM¤ÔnÓWb"HÇ­Çޯϛ¨ŽqJ@ÃÝÀ1ÅÔ¹À„úŽ tKPãý-)ßótoîÙM³«¿W 7˜u|Gû…Aìí°å€ée®3“%pbçÁé1btÁzÎÿ€A²¶•=™²+Ëù†èuë¥;>³Ÿ3¤CÂØ÷  ºX‚¸‡»Lý¾N¯½Zzë'ßót ]º+Q«@FËnYþ¦Çº6Ö¾§@%D  ”¦µÞ¬{ø¦™ À\ïõPsäÛ@6™G÷ék0IñØßɲ­OLék1XfÙ?0 ½*‚xÑ`²a˜öé“`ƒÝµÒe†hÅŠ NX±ò?Ù¬í?W{åi9Pk[øûl9A™r~CaàßÁ‚ L.–Ã>¤¿`I±ß«&j9¦ŒÃŒÐ‹F‰A¤ ÄY`¢Ÿ‚ C4MËåè.3eóõXª€¤LAL}œÂ4Ö}/˜…¦û<' k\ÖÏWõ˜µü–¾œlÀD!˜Yà¼b¿}_®,Qø X¢´X{ð£öÝDM1VçòUW·Lœ.ý™)Ç~,ØÛ¡±™`¸PçËùepJs6µr<:G»‚Œ†Ã@à3]ÊbÄ~S Gi”u£WºÍLG&[3H?3à«-*¥÷ëz¾—¾^!ûTÄð @Zûå øæJ?½+ž©µÞV‡ëfèÿkA€y®lÓ`¹Èºûœîs\ ›z X6ÙO÷x=˜y À×Å~…Õzq¯öÚ±`²Õk¥cžÒ¹ª âuv‹GëgÿH5¶ôÏŠ+œ°„¤‚÷ƒrg+XœÞŒ!)3dµ`v+”zË#AöÁC`–¼-§&ÌÖÝ¥%Mï7Àó`¶qIm˜)¸[Îà?Àsq/ã( rÁLçPËÀ¬ál9ª‹ä :C‚Ž<+”Órº‹IÚw¥¾n:˜qfv×€tùg|S? ÜÌO.öûWÄév³ÊÃÀfkÇûýtÙÒpÞ –N¼²Ð£ù¬ G`Ä(mƒ¤ÏîÒþmíì|«à® xÿŽè4‘ô*ðßÌ”î«ï=2¾ñÈ\hï)flm>Xú4ÌìËÖzƒ%.iòyêá0-æ‚l‚Y X»Jz2^úÑ#âZ°yhªlí2í÷~²? Ò‹¿º€ˆA¦H%’¬‡Îu®îÛI \ûèsþ [ðf±ß¿ VÚs/v•.:d.™fµßýlþ«3L¹Ù6`2çl½Î÷` ÓGèä#Ö­X±bÁ +á퓞rŽ‹äðþU£»ià6ròVM¡BÉvÖU?f‹‚uhräÀ¢ú;É 5“5ž³ï›# ~§¸ ÌÔ–ëù_‰â ¨ÙF×¹I†¾6‰f®§€Ôä€ãö€µ>Fd™öí 3§,š à°!Ê÷!Oï7§ØïïP ‡(ØG(àÍpx±ß?£¯!ÌÚM”sû È&X‘€ef̽ ´Ê@0óÉ6ôb–—|p˜þç鯿Ä6W¼O€ÇÅ`)E]„×ßM€ÄŸ˜tÕ™Y¥`øUΫ46MfsuíÛƒàÚ0°ä­—~gšûVƒÀå݃¯^¬ÑïÚse€@øùú u ÀpÄê=²7x¢=„’@ XRV„·x:†%\‘êÉ¢ôKÝ.Û¶À¶> ûì7gcÁ¬ñÅ`‰æÞëbmV¡=ÿÂõLIžì´“¥`yÁ+`Æs#’—‚í…3¹7Ȱ®Ï=d6׳áSÝ›úy,? XêpžîÉ·`iÏj$WÓÏHÏ}È”ºdJzÁ©^×ûýë¬ùŒÚ^Ëõ¥»éçë@vÄÓÚƒe!ø>°¹ïD}[²ï™@Ö‡²bÅŠ'¬D-˜ÜNæpù¾MÆ«·œ¸é`—uwè“3X¨ÿÖ_8Q-§ðn‘‹yzýqrò3Àò†¿€Èÿú @Š,Dç‚tåS@ê¬5ªÑ‘T½wiÜ 2r"©/NK8&ÊÙZf¯ŸE ²4Úk‡e=Ž‹e„’@ ¤Úþ `~,Y .`TöJxµØïo—Zßá ¸¸ Xªt>€o°Yžiä:œVQ­€ò!óÁÈî`fü-Œ‹§ÀrÊ&@ÂM ·N? S?åYÒñ = „§‚e%³ýþ‰f×| XÞGk0,O4Ó.¼ »â _§l®>Ê×dwê‰8HG‹ƒ¬–3Šýþ°îÞê ²ˆŽ•Íì'›\g,u½ôÀ²m_‚à\%ZȺH—\¨³3L|ÛßÉŠ+œ°#É’3|½Û©` Åóúú0>T÷®rÜóÁ¬•iX¶lи¤ÏÑû¥ˆBvH3Èw–“ÿ;Ê_®¼ÔJ£­t.èïÿ20l÷èèH:˜M¾V`ÄÅ`CÔpœÖ[dÕëõné¨QdUfpžD/HU} V% Ô(Ø=H€Èõ± Ò‚ÜÖ¯p€/Ú ÐÙ=ì’` €›âÑë"É[·Jï}'Pç«÷ôÉ Ð{‡Öþ&=*Azûl°Üâ\p:Ãá èzª„†0ÎÍTvÖµ~2™>S ÞY›Ôy¤§ µ6ûé±£»4Ùƒ ¿ê|/[±J Tl£¿h鄞 Ãò8°GÈX³“dZO¼ÅŒú ‚§{ko›I)3À²¤†ƒ“ƒFÁé1S Žÿì1dA”iûôúwƒ`òJé±`û;Y±bÅ‚VÚA¼`«Á&i•6Ë!3Ù¦F}¿N×ôoõlºÃÿ ÌÖƒ4Ú[A†Ce”œšT¯— ¤H“C~3½Òº\.‡ód0Sf%zÜ­ «e5œR™pøn .Ðþ›¥€îĨ¾$è"l,˜µ¾À[±*uPæðH0sØGã¸XeÕEÿ¯þÖûüÐ^}LJ®šN3y7x6Ë8< VïPP²<&Iß…*7ƒ}4ŠApí&°Œ¦NNÿjÖ¾¿€ˆYº7?#<à´;X®±-X¶ðWpzM™ ¨›õ— °7È®ØKÏà”ƒà½l˜¼TÒÙ¿U}6h¿Ô‚,›Z»ÄAé†Ùîsä?Œ™T ØZ2À«‡å»‚@o½öáç`)åWÒ-5Íøx]À$ÓaàD•`BÊ£¿_‚¦_ì8[ÿ÷ªôö«K¬X±bÁ +í-y oÕ`ùÃ<8гKUh¾×PsÀæ–™ ½ù0ã¦lì.rhþ 6×r_Kš@‰ëäøœ$ÅJt$[Aýé`©ÌX­o8Ao:8Ro"<­1%žFêþñ€}M3Ù?8ÌÞ5Äè=»êœ©s0 dh”Æèý¶YP‡ƒ ¢¿½èÓZßAÏŸÁ2ޝ°Œ#OûøJ0“þ%Xz1+}õ<Ø@ó@éΡ`ã¸X\2Ñ‚o~9ÿá+W IàJÕzÝ… `‚Óp×Φ*àÛFºa˜lÌö ‹ÆL ñè´~µ0Ê@ k¹À‹_´Þ¿êç¸ØJOd¸Àeò+þ à³$jKIÁ²£AæÃÎ.¿l!81è éÖPzǤhw§àŒAÒÁÒ>Ð^žßi/»Á8+V¬X±à„•˜‹¤š? €í|„–}3“7ªÁLÔ N*l>f ¢â|(jlL¤êºo—#þGg ™‘Ñ”¯×:zu¶ÍÏʤ»yX’pŠ@¨Sø„ 3ëÇêg/ƒe8QŸÂáZo¯‚ÆGAöÂ.ÙE& IDAT‰U™öè#†)`¹ÀG±êùPôS0<À‡Î.öû—·#0qX®Òì»pi±ß¿4ÁŽ^:Huž û²ÅžTð®¤ì…í@,Ó9~I—k]æÀíf‘ØÿCÀ’·® `rA1  d ý¦s;¤Ö/ûQl3©6ƒMìÓš¤6î+ýÑÌJçéïÒeƒgzÈzv3Áìölíƒ tòÚ}õùÌΗL¼7;)@áG ØE{ªRgõUéÓ_µw¢±F†I”§ý<\`Ånú>Gç A{y#x.ýŸ§½¼F÷¯–AdÅŠ NX‰dè9RúuH)¿lÔ´¤OV0 gòÏA6S¦Ç"ШÐÌŠn#ãžï Ò]3ϧgo“góHÓßûôµ-êµfãœyî 6<dœ"G)T)i£—ȱŸ ²\>F Ǫ¿ÄYDÒ´Oî‹a‰,‘qƒÎÂ+: ËbA_ÖžÜ,ØEÎìøb¿m;™ .®Ó~ŽiÿŽ€!ºÆ1 Hö¶öÄN¦ pº²»¿vßôç ®¯ë]†¾NÏ úçMž/öû+côùRä<>2RžpU±ß¿©=6‡Ö÷°î:°Qê `xÁÉ/—uÛ`)Òï+ˆÖ9ùÎ(æFéˆ{ >f‰ãÑwÀ yº–þZ“! Å»¯L—N3}Ö*@údÕývü/…Í”¶f“¼-ºƒÔüz kûÓ¤óˤOg˜²,L/§¸‰Ñö;ÙÔ\p¤ó±*{K]ÔdðM-ó¤ÏÌWå'% XeJŸ ‹¨7À Ò^î 'I“å/Üñ‰»ªJ~ÍfÙǵ1–jß/ aÀŒXF—+œ°b%y Xcz‚ÕÏÀŒå7:`©&’;ìE³,Ÿ‚Á`öµRF´L†Ôôä0z9ù .Â<\Z—ñnpôµq&<`6çI2ÿд2Ä× {}¼~öšÃ1¾O0ƒýðÿ·wÞñ‘–UûÿfÒ6»ÙÞ K]šô" vDPT E¥XxEz}Uô؈("ÔQ¤Hï…]–­ÙžÝôä÷ǹnŸ;Ãd7m&“ä\ŸÏó™I2™yæ~îû~ιÎuΑóþ4V[åé|Œ§¢€‡ÉQŸŽEEÏ^ÈcGŽ”æâ 2z¯.­I§7À©Hɹý©æÉ ù|‘H³ƒR"îô³@×çúŸÛSý#ðªälÎAqõÝq<*å$MŠkî¬c;ÍåÑO´O…b‘Aæý’H‹…"¨b™·;‰½VŽ)Wfa2úÐît¦æg‰Æm•œÕ°¢‡óä°51,"(öÃHð9Ú;ϯI§;ùU.‚êíXªéÛ1‚° +´z«ö£—é¿”BÚv±‚¨Z$Å8}ç)º/M1Q«ÖëG§qÛÝPdv¦4Z¤ýe¾Ž¥Z#ëñ:‡“GPµÏûºnÐM˜tñJÝxzzƒ)ÇR9®’AwV,ÊoT}»Fce,ïI;½€žå䔓vž “çIR8šòù%ÔFóTàlÇï€sjÒéyú¼qún§hþýøAM:½&ß1…õ·ÿ¹®ÙX*EC¾'‰ÔCÄÔJ“›1µÆò"˜ÃÕrtNÇ"”#DJüHó`UžæÃõþÿ«µ’YtV 'ÓϤBY?“§=/H¼G‰ ˜ƒ‘|»`‘Óé$)"¡«S«œ…u"/VʹX9È dnFònÐcø]ˆ˜¶á==Œq(R¸?Öît®~ÚnÀòûŸ–ãþ¦¶X=T ‘þ[bÞ¯kÿw­¡'±ÚKƒá{–Èñž ¼ ««´—Öj¦ø»‰'um‡zÊTŠ$-•$ur&`$î,Œ©c¢þHŒÍõf9k4ž¯Ê¾xI„O^CÇáprÂáè¡ÓzV¹~[L|Y\ÐÍu…œÏËts? k©çÄÄæáJ’(ÇÛ“DKgÊ HÉ(xLNpwë¤0óX‘Õz9ë×Ñ»öŒ=uØw’{Œ” €ß壥>o{¬–Àš¿g’Ç¢—Ñç~\ä@–.ðãBDU_â‹"~:°6œ×Ô¤Óp^‡‚rGb©Ûëþø¢œ›?Éͧðygbj0åÎ?d4÷d m e˜BçûÚûÞ™ïuÕ…C˼çÈ¡ÞV¤I¶Sœ“`³ÄCœâRÚšôÝêuÝÖè;®ÖãÚèØ Â#mÑû‡ú¡GØŸÊ¢ç!#<'r¤Â÷«½rI |z-!4 kÔ³u)×z/`ž&éÊÒ_5M‚¤‰}ç`н6L‘s/Ö=b¡¾{è>R‘^^ £TócàXª­5wZä@ÿk/üÃ$e§DFX¯$»dk’t’-ôû˜ m×°Ncþ¼Æû9Ý›WjmøØ;NN89çîD,%ã bk€ßФx}7ì6dÇËpiæãY&g ZŽÁ$LN9K†m¨0?IFö(’¢Ô¸X&Cï,â»Sºt'"_-¢èk2¤ï•û\¾¯Ô'`EÕÆwc­_ÎSG‰‡_aÒÕÛ±z ¯çÓ@VúÈIXGœV7ç“ ‰>{ ÖÙâcš'g·â³»p¦Ëéÿ$¦Ê…EÔ)qŸÜB8,—‹˜ø8Vh­¯[D |«µÓdCbmq‹Å }p°Ga2ïP4x4IG‘‘:ÂóÑzÍX’üõ*:NeÙ>qýž6ÞZ뇈)ɲ™rý.—}ˆŠ’:Ÿé‡kÙg-¤ÝlEá÷ÃHØ ^)Ównó•X{ùb9lƒ"’¬½u,V»å}ç11Ó‘u ;´æ>]“N7èšTcQþw`JÝeӤ俀“ÇR6êñ¢²ýeë„n:Uš'!À²#`ÙSôU‘¤‹„µêçÌךø§îe‡ÃÉ ‡ã¿7ù)˜ôùó2¶VaíG¯ÁršÛ£ù>KãøˆŒ4V·b8Üôƒá?ZÎ÷L,b¹M˜!âa I4)ñqAªµ$¹œó±´šW4¦«dÄŽÄê´È8¬ß̹íŒEŽp–’׎ Rì¬yqH®Ë_å³[„>÷¬ûÈ5ÀÕù®õ ö{g‹tY§ÏþG¾k’ÈYØK!Ù SÓœ‚ÕÓh/ð˜†É¥&)(תùûG,ÅäU _¨ñט„ûX´n¦ÖÁ¾˜rã1ý½·sr:¦:«?pº±Ö!²·…ûAYôXEÒ £Zû^ÈiG6™òàãbÃ!5¤ÎõZ²þœÞðšfŒ”ÝJ¿û³öÈØú!°]æbíkߦs BJô×aŠƒò$Y^C‘“ú"c§b*Š]1¢½Zß­‘$Uèà±<ìGA¡1Kgz»î3»Èv©Ð/ÁHÑÛ4ÆË4œ(¬OT­Ù",öÀȼÙXzÍ(%ÕõÙïj ‡ÃÉ ‡ã-ÆÖ4‘§ÊY‰E*ƒþ½XÇ6˜¼ó³X¡°Ž!²–ƒòaIA©-elÎÁdŒÓdx†ªØ%‘ÞˆElVË0Z$C:TÁ^‰¥9„\ïæÈ(Ï…QXä­Z7÷®¤ã¡mæù"NîÄ”/çÛ0«ÍdÆj¾|IÊ=ÀWÉcÊŸ?X’oõ€”!ß’!µ#æÌ79 bu‡?ÖºüpVëK¤°(ØXÊÆÛµ>Z1òò¯˜:áy® \{&ÁoÑϿǔ&Àê «óí©ã¾›öÁ12öórÝñy+¹‘ ]üܱ™ße¿1;0Á1 2øí´oï%Ç~Šöê@X„(ò#ÀCX'–% ‚Ú“:€Ž<¨ÔÊu›*2ä­ém´×—iüViÌîÄê(ÍI’o¢¸h…B ½6ÆaŠ¿ÿ‘MÕ"åRíɾ—:NN8]™S±ªÿ'a2Éer:¶Ñ å÷X÷‡×1K’+E>„PS±èêl!W{,‰œ9HC.åFEoŠ˜™GÒÚ/TÉo"‰¶÷ñÜïÁ¤Ä{`Òàl§q.VÐôP×7±Ây­? Hþ®˜baO‘.ßn(D§Š0ÆS"].’AuèŠ!Cø¬0j©®õ÷ P_¢Dëd_‡ÊájÇȶ¿bQì§)¹tèÌ1Ek¥k ¹SR€©'žÇ$àÝ-,[|SÃÔ`ª'‡£»÷Ô*­Ÿm°:(ûb‘䩺/Ö+0Òë~‘ót_Š]WÊu?¯ûðŽXjÆ®r^Çc0õÌbLuFÚ‡Úk™\›ÉLÆŠî†t±;uФCR1¢K½¹@s¿E{ñU»V¼h¦Ãѯ(ó!p 1´Éø:–Ëmœ G`9·Ïci!§v ûb·FŽ=Ñ (Èw»R „TidÜŦC® 5idÐÄÏÇÐ9ÇzDDXd§\4ÉÑZ¬c¡œ›$ʇÕrü[ pSmÕç…¢p1ª±Èý¹úž÷géšÂH*ÅrïwÆZ±]¼:Ä ´ù˜õÛ5éô¡Èq"ž¾Üšg…H¥œ¦Ob©[³´—b¤×ï(΂rAö]OÒy¢NNÏ9{w`Åò>е~ÝÜ\­ÂRx¾¬ýì«X!ÆFŽžÝSëu¼&‡¶T÷¤)ZoûaÊžm0"ð}šŸõ˜:éI,Uá),(°n%ÚO‚š$t„ØAÇN$oF’št¯}@̓"lVhmä¾ó^LAÖ""å"Œ¬½·6“ùFˆ.wUÅý£]1Eç{5î‘mùx!I%‡c¸Á•ޡޠ¤¸8 “Go‰EóƒÄ’ˆhhˆ‰pÄyÆ¡|³CÎq;+´‡cDDHTDÄB\>[JÜ‘õyÍr(ê±HËJL ò¦ ¿71åêȹi£8ýŒÆýLN^*#ö[Xb Im‰õ…:))'¶Á¢Oæ£G±AꉒB¤«èó> \‹)5NÑ8çã³Ë0òñ"BvÕº[‘^µrVQ¼ÒÛiQú–ÞŠ)¼ÕÏOcŠŠbõ"ޥǮ0«/ñ í§bÒqÏ‹v䡯Ç(LÅ·mÞ]ü(íý­$^“÷´HBvBu *I‚“u®³tÌкœHR‡©\ÿÛ."|——±ÐOcÁ€:’ @Q0Jeù ÖÂù "[>€¥’ÓËÖˆHú«ö‹×0UEÇ0›Ë[bÁ’ctÝŸÆTwàä®Ãáä„ÃÑO¸‹"ƒU¿šwÀrk·‰1‹êB!G ÄCÜo;»ú{\ ­=‹àhÒMm£œðz6¡]Üê.(86èõ¡¨ZsD”´38r¯NâØÏc]R>¥±½8k“èNÓÐ#C¶ÂRn¯I§—æÁ€]Ÿ‘?NëìLYðw’¢rÅŽPçaLÙÕŒÕ]¹«‘‘ów­¾ï5ÚÏrE8gadßArþN”óäÒcG¡¼J9ÁÛbÝpöÁRù¦‹°Ý3EN,ÀÔÏè¾°B÷ɘüéŠ!ˆ‘p¼¦{lŒñ0]Nç,íb–~ŸÝ²–èþê0­ 1_çõ¦8XIçúKżOÔÓì]“N¯®Íd*D¾ì |#=gjì1•Ë€aÁ…Å@ó%+B¸“µçNÖ\º #Š×ù’v8œœp8úŸÇ"‰_Ä Ãå2¤²I‡¸Ç}öÏÙ†Q@¬Àª‹æÈØiË"0:†¸Óp.&ý±ŒŸYX'„K€¿Ñ½ö¢ŽÁKP”ô³![‰¥â|ë\1“¤ŽÄŸ±VÂ/ Âyµ&þ3–îÔ&GáoÀM2˜Û0%Å?ô? ÜHÒm£DN௱N·aÄàRŸ‰Ž´1ƒ¢"‰ v é5–$e1»ÍkèÒá\Ý›ÃþpŸœÌÙYjC”F爇uñð:– ¹Hkf%(ب÷i¦sÒÁ¶ï©!î>ž­b“²b¬y7¦ªØQ×-´7}CûÔwjÒéEChžVcÅ.¿†W«€ëd+®À‹]:…לp }zoÈGÿ …E³Ë1Yy=ð=àûºá{$wˆ£Ÿˆ‰r9ÆjIì¤ß­ÂŠºÝ€)Öb#r¼ÖËòè;ÌÃTU{˹ڀ՞ø¦>ºS\|WkkOÅl,•ål9WG>Š5Wi‡.QÛŠ€ØJ÷Ý1z] âôÅP×¢ƒ¤FSH¬ÐcIšcIZexV,v,ê=RïW‡¥w=…ão` €FjLu q'tOã}¹Òëô»uXËâÇj3™ˆäÙEdÅÁºž»Kk3™+†€‚¢\ßëO¦Rû.¦âq{ÐáprÂáÈ‚3<ƒÎ)Žüí-GaÑ]°”Ž/`ÒÐÖ"<ßá‹#rÁ@ŽŸUM,%Ž£wq/<†ªÙ‹#€á±42ÈCNôþUzꘄbm9Ž } ЩeŒõe2¾^ÓóU2ð‹e]”ÊÉ9TŽø¾XT¯AÆóõXý…¥CÄ€œ 9±2ºu"(vÅ"/Ë;«ó¬­Ý;€?b)Sc1òï[r¼޾:oAyP-òa*–9[$DH‰«5H…¸EõZLÑôÖ*iŽë$²!ì—%$­±×Ñ™|Ì¥<§½¡YçÛ1ÅäÖXúW3pVfýpºˆª±´ÆêÑîüOM:Ý$gqm&s¦ ø“Þç¡þ$&t~•$ ›P¼LóaƒæÐj`}?|v Sˆ\ˆ‘Þ%˜"í2¬¾D«/}‡ÃÉ ‡#ßÎ×’Â\Žü´gèÆß‚–ºA× „BpÐGꨒ!=Ф+JUô|ddŠ^;2"*³œü²,B!|~I2¢»çÞŸãßg§udý>×AiRs‡ÖÁz’6w÷Ëx}·Ø,‘ƒ³?–¶ñ.,rׂEærR¶%iÃ6Qo³ ­»ø´«I¢UXQ¿y]]¥Ø8¹0ph–SS<\©¹·“ŒÌwjî„EÃ6b‘×ùXÎù<‘»éu߯ò‰“ñ?N†á 2Ro•SÑXdk¯Kuùš¾ã—ÈO‘ÉPk£-Çû·i|Þ‰Õ˜x’üªl¦bJŒ÷Š9^×ssŸ™ê‚,Ecc'=“¡¾Ád=‘qm”v:«$J"R&N ų[7wDxH‹ªÏ:BÁÅ@„EUKôùtâcÒdkL S-ÂîJwI4–c9XDú¬m ‹p¯¢³"m8¡Qc´?ðóMŒA»®÷ÀCëm´¿½Gëþp,ͬE¶Ã "+î´j‘:%Ñ:Mõ`,.ÀÔ&?"79šý?%¿ó´gUb °k°ÖÈ+7GHô•Ú¿ÁÔD °´”Ûðö凓G9\«t£**r"" ÆÊ9˜ƒEªwÐói$}àË"㪙DžûðVÜ©ö•П~SJ»¡ŠͳE:îñ7 ‹Š‚Ifgaé ‡’ä­Wêùá"$Ð{d€ßÉØïKjH¾Öc(šö%¬ÛÌ(¬;F¾œ½R}F[†óúýX'Ž|׳°ÂµûaJ§“±ôî «±énaΘ|ˆ©¾|ö`"82W„Äöºgѵ*æß¯QXêÜQÀéXdx¸»Î×øѰ-ðg,Í£¹‹ù³NŽ÷Àu¿ÝF$ÇX1É}±z 혒æ9,p·Þ»˜ÉŠõÚ7ö>Q›Éü¡&nØÄþW‰=ŽÂT/ß©I§»£6-bhŒ¬þð·štz]ž¿cJ×ý2L”L¿¾ŽèÞ¥ÍáprÂá(´c±&K‡§R7î©X$b,¢¼ &? Dˆ†|íõ$ÑèWô|H‰5DùÀEÒw¼#rºCo5Äû IªN(¼·ŒÄ“1E˜Bâ7X”r]±:Oµ™Lu»Bßc1V{áæ®Œù~@ '[»pžÊÚEçôlÎak¬ÎǘRã4ÞZÿ¢ÎùpuªK02úf]ãŸ`‘Þún¬ÇõX”z?¬uæ­t³]äÄ",%c+Wk_:‹ÞÿKÇ‹X L.g»KY)Ç~¨ým ï–“¿?¦h:_ÄÄËX·£ûõþu˜’£îÉ˱PcDÖGj3™_’´X%2b+Lõ°£ö„1šƒ_Ñ{tXZX;V£hMì’±Xñí/ëù㘒ïãX]‹e~ëv8× Ñá.ø½·ËPÉQNÒa– ͹:¶ÂäñÕz]ìì­Áò‚`’Ñ—DF,Çòš›€Ö<Ë!û —c…ô>†!+64ä„ÇíAKIr¾«"‡;äÕ‡\ñ‘Ñÿ…Hw†¯Á°z Ti› IDAT`Q"EÝùž#4o _[…å|ÏÁ/Rä*™ÚLf:u>Fçz#–’òfM:ݞ籺_NÔn")vÇ”P!ÍãLË7µ¾úr>%$íúÖÉ)¾Q¿•#âÕë k‡íˆ©‰æ`5>.¡gu‘RX„û9Ôi1ÜÒ\þVGb¦ÖM»œï*=_ƒ‘ü÷c…wŸ—»±ûTP:m)BèݘŠl*IñØyû8p¦ÈXÄÖ­PŠÆ~XšÐt&Ã=}ÿ1ûoLéöTOlÝ{()Q&{îJí+1bùLõqÈ£ÿõmÆáprÂá(ƹþL¢¹/¹k t禔£å´N!IÃØ^ϧêo$EËZåh¬ñ< '#`­Œ–æ<;B…ÀW1å rvÚéLaéŸ!Q§ÄG9IÊLhEWÿ/éÆ^G~[0Yë¹½¨,ÞŸß{ð+,¥â.,bøùÏù ÷}˜"hwºuˆq*Õ¾ðC­á5‡ï©I§ ÑÕ§JåÕ;0)ò—°6w`$çƒXmŽwÒû˜UXÅüs±Èîwk±Ú5?“!_£ØSLÌ‘3u1½+Ø\¥÷98CNåpL›û¼æõùXÔhíß“0µÃû0åÃtíû`$óJLýð8ÖFù%L…±a3„B)FZo!ù``/`6Fj‡¢À«±€ÃÓzÿDX¬ÁÔmÚïÆ`µ öÕž“ˆ¬å:¿W±t®@c‘Ú#%Xºë9º¯—a)=bЉ6íéÇ‚R'á5¬ŽAOëp §¹ ñm솳R…EÍ'aЇm"òa†nê#³ˆI_®{E$Ä{לÂ!Ô˜¸‰¤Eã×éŸÈn;VòÃX[é›±¢„à ë䔉µ;¾·cÖD¢”xëÎÒý&cÊ–=±:{éyª ¢ãpL‰Ô€)!B窭Ùùº&¡îQµ@Œì c¦ÜœŽ‘ËáóÚdǬǂ,‹d§,”Ͳ ’¬yÑ4Ð÷à~X/[ˆ :Nãõ(Fª>²‰ïÖˆ)]Óÿ;9áp89ápÝ\/×ÍzSu^—æ,E(ûËiKÉ0ÚQNëÖ:fËHMÒíd½Œ¬lrb5P_RR2ûܳÏÞq§vj"‘÷·GY¿ëˆœÙŠ7ßuPBóxŽ—j3™[HêlŒêó0×Kú8˰¶p À½ýQس6“™…ÍÛkÓyjM:½h.I¥öš E$üFûS;ðWàÓr°îÐúXŒÉË÷ÇÂ'»xß‘X•úó´n—b ‘?_⺋0%Æ#NL)¬.Á¯ELü‹÷§ä¼SÖüëÐð¦ô.hn‘ð~¬öMOIÒÐB¹Yû嫺¯}Ecùå×,…¥ˆ\«ÿÿðÌ&>#Ü›Hê]Ü¥=3Ô<ERÛj6F ‡ôÒišC;èõ!½4(<uîËIÔ ±àÁ}æz’šÝÖ¹œ¤õ‘2Û`JÌ#tz ¸@{åúñG0¢n­‡Ãáä„ÃQ4(ÕѺ©°œáUÃxœÆb½¹$©,¡˜çJ¬êø3r’ž%waÑz`IyyùܩӦݥq€ìTŠöèu«3k3™‡pmŽ&+âˆÞ†~~ûpúë-FÈÝ ÈÔf2_¯I§{ÝâRЉ@LÜ|±&.ôz/×ç_¤qú&ÇäËÃZ‡`‘µZ#Ôÿ<•µžJE\|]å(}_Ͽձxëìð"ÃC^LÄÄ~X'iºß ?¹ðwbÑÿObê˜Ð±b¸àAÍùw—‘;ý¢'˜üXŽó—õþÙØ•¤†ËW°–½óx_nÔ}w~ô™aO­$©s4 S^Ìa1Sç<^{çî$-ʉîë¡ÛÔZ‘ËD\,ŽHÕzMƒÆ±™·ÖmÊF XÂcP¡„s¯sž®ó…¥]NÂÒ0FbJ×ЫLä͇DPtw\Ÿ®M‰ïw‡“G1‡m~ƒÚ$ê±(ë2P^×cIÑÄÍu h^imiÙù7Þ¸{â„ í2NBŒ`”¼9k¡gÜ£Ô/Ç E0~SôM=±A†þuXêÅ>µ™ÌÀ㽨2ë^ˆ‰ÓkÒéµÞ¶Á ÕZxDÎÓ}t® P‡I—ÁˆÂ‡ôûÉIø0Ö¯QëdLq„ÖÓÝ"?ž‘3ðs,Šü(&~ͧhAQŠuH¸N×ã à*òW€´ Sd œ†Ý|¥§oR›É”cj¹5ƒLŶXý6ºß,ìÃ{U`TvÆ/7äpÈ·Óߦb)W׳i…f_r^© žËšká¨Y2Nç6 S`l¡ç“5CÛóp/މ’6}—úÒ y»1"+Z# Üç+I F9Q¡£4úœ@t„÷î Qg>k ±@ÈêØo¥˜Ê,%ÕÉ ‡cÀ b:† &c‘Æ%X±K¯Üœ_œ \RZZzj濸1ÚkJ°ˆÎL,ªÑ–EHÄ‘Oë´¨Âr½gÐÇV¢ªy2“¨\ù¥@F55ºó£±NG`ÍÏÖ¤Ó« 4¡áç±(ö8¬ŽÍåXúFÜ=¨ZÎÃ|,ê}­ŒóËdXWŠxØëÜÑŠåb£ÿ} ‹Æÿ]ÄÎt¬ØåAú¿Ï’‚ŽÂ ëÎðuíuç‹,Êw¡Êå¿ Kñ8…Ö¨Íd‰òàºî®·"±m¿Õ\9Söö}ŽÙ°@Ó’¬×lƒÕö˜‹Õ¹ˆâïzS•‰1^¶Ò‘:3ô|¢ö­ÑÉRIâûwG©H”’.Xu˜"c ð†ˆ¤ÕÁz¾Æs1Fàu'}£«ï÷I,mªY÷û}+r8œœp8Š “DN¬Q¿Ñ‡$¯ø¾«ßo µ,—áÓÒ %GQAÎvˆ&­«I§›†àõÜ#G{O›}·X†¯ËPþF‚-ÞTêOm&SE3OäÑÇö¶U¨j²LÔË€?n¦NG%¦r¸DF÷2¬ÛÆõXúX|ÞãDF¼KÛhÐù>$R%8³—`*‰;±Šÿ0…ÓÕ2æCtq ¬cÃ>Xþ©Úÿ…ÃX]¯ÏÊ1;ø ù‹ªgcFJÍÞGóîk3™Ý°T¢)XšÈÙ5éôÒ"ØC+±º+{j}Ì˱‚‘7“´îì)fiM–ƒû¯¬¿o/âg.F8}mˆÙ%$ªÆ¢QI’ªQÆ[S÷âºAq‘ ^¦è¸øŒ~“öëEá5ºgÎÀÒtþ±™9X¦ûÄ÷ôù'Òû‡Ãáä„Ñ7Œ9±ëÆQ?T¾˜¤·#€æ"rt·Å$ë`ÕË›û黎Àrµ‘¸‹À¼Šå¤¾"£f%ERPSí¬°èÛ1åÎ.úÝ%À¯†`]JõÛÉx³Çr7,B¹§®÷X±Ì¶¯/•cò9ðGÔ¤Óó{I(MÆR"NAqð©.Ö\©¾û7°tŠVߎîc°v’Ã'Ÿ”Sð˜ÖÎÞ$Ä4¶)ëO°–z+¢÷ÝZNÓ®Àï3)@··§¨Ðµ¯5p²ˆ‰W5£°HK°ú"׉d8¾'ĈÖÏ\¬ÞÂ^˜ÚíóÀ….ƒ’#»‹ä«€Ërìõ“5Þºç÷´q…¾÷1ºç\D¢<)Áj9üVkíçX»Þ ¾ ºrà`¬èÚËÏÖÞÖœuÝ÷ÕÏŽ®I§ÿ±‰ûÎiºV ÀçDLxÑ_‡ÃÉ ‡£èÚOUbÑÆ5ƒí (ÚyÎÑ }9AS€?ôGGƒ~À†-2j×÷ÓTÊá;+NVE’Êœ³˜lôàßXôyÖ¢£@ת“Ԉɂ÷ÃÔ;“uXíÀ† 9Q†u™ØE$Âëý<¾d€ž ñü.ðÚtº>‹P8DD«ÿX­ÍdÆÇbé³µw\)–äx¿q˜„þ‹zþ(VgâÁ.ÃjL~| VóXLiR®ùž7ôúX'€2,Ï}IDJ¤ä4ÕêÿnÎÒ|sô±¾œ¤»Mh¯ZAn+2bI1À»1¢ôRúV÷ /«y4 Kïy¡ëmŠöÝOi.ÜX2\ÎéÖ˜òçho“ö÷››jÒéå]\·[°ºïƈòžØÆGb)Qó0%`]´ÆöÔÛS;]ìÄD0S™œ¢ëT«ùµ”HM¦ÀË'1ry$pˆ¨\c=SÕ}V×êDÍ{'&''Ž¢D¿ËÌóhŒ•éF¯ñ89§ÈØ~$'ü´štzc7Þ£Lëñ|àƒ2üÿEŠŸ¨I§sÕM#ú,­íç0µÂ]lºÎJ¹„÷É!9IDF6ŽÐwøžÎ«+gêx,:Œ^÷ òß ¢?ȆRE F‰t˜$Òa¦ˆ‡irRÇÓ¹c@L6d·=ŒI„uÚSÃóõÚK×a¤o#I«ÄF½O‹Þ«%zÏÖÈQlÆ,'þãú¨®Û0ÅÞQ|=Ê4Þ/ëž>®·i˜áåEÀ 5étcß·«/ðmLqµN÷í뀽ØKG`ª‡m°z?›k§šñK¬ó͵§Wˆ„¹D×ý,‘…Ý%<Ëtï9ZóyœÈ*õMIQdñóØvÏît•ÝõjS\˜Ã°Z7剜Ha ÊïciE+´GÞLŽ®&µ™ÌLír´®Ág€çr\ûF>gD þ#z½è¯Ãáä„Ã1hðU,Úq²œÇ|8IÁèEõ¶ÇÒHö © Q¥kY†E–×ñ2QÙ´bçöãXOøË±\Ї"°hþ§°Œ r<•!üO6QŸBQÃd î"#ïY9„ÿGÏ"{C?Çò…¡gùÞ}!¡>¥yLÖu<®&^¹™ÿKaQï¯È ©ëù àŽ.¤ãerv®Ä”N«d|ÿœîž,~%Gè8QäÂt’Ö„“å œ´ñ 5J"‡¬UÎý}Ï•Ú7cã‘<+ä,¡…¤Cy—sä¤Ë¡µ/œŠEu_àõx´æÜOåĵ÷q½Ubék—‰¤»8§&^ÒË÷›,'ùD̓Û5·_ìã~z±®ÍiÚ£7…Y±8«Qs·¾Ûe¸RkíŸ=KÚgâŽ!Ýh¬>o‚ÖÅýn IQeÈŠ°.bb­Y¶C¦ÐÈ>¢¿‡×®ÊS­ªrsWiø—æ?Ý[¯Ö½ù àÓ5éô‚.ö™ƒ4Ÿ'мº”!TèÜáprÂá8JFã•2zúê •“¨!¶À"µ»Éa-£B묋Խ!Ççqài’ÚMCPò¿— ½¿bŠ•¢rØETLâûÇëÚ•bÑï+€Û∻ŒñC°Èôžº¦ÿ–SúPw¢óà ߑ³üa¬{!®i S?¼ øgM:]·™×ÎÀ"¢'`Qù×tÞ¿¯I§×vqÏœ‚É‘?#GãoÚO^éáßYãÒ¨y•ËŸ®½âMLGg‹ÔxI7ˆGs8¡c%àÑï+H =ghDôšøïÁ©=g+tª‘áR‘Ò¹²!(Z"'jHže:–`r÷er é ±j¡ðA9è?’3ܵDü’æXf€Ïo&Övs=–Ú±ºŸöзai{èÞvéîèæ{”c ´«02!Yÿ¿nÔ”èö¹wF˜w儇îŸ$éÎ1MŽï¡XÐàxÝ·Û °—D*Ú{²ÕdKG3&ˆ:AköJŒü¯ßÙu%–ÂñpLM:ýzÄÄaX—¢‘"Ž~H7Òk‡“G±aŒ¹¿UŽE¯œe±û§c’ìYº $‰h4Șž¥d<å¼.AÑ:L¤þ³äX½Š¥R­Ì\×t/¬pÜ{äPÝ…EÓ_“#y1&ÙF»x´ ¹¿#Ië9kgY,×:´$<SQM‘|‰[Ñ…cU)ô[˜ÒbAp¢È!OîR£ó°´¢Ss8NÕX—±"ÄêHÚ)ž+‡ó,ÞH’1V$Áx’H쨈pE(ˆ—Êr‚r=ÆQü;I!ýaI>ýbŒ„]"¢¡NDD=I:Eœ*ÑÁà,d7Ëy+Ì×9Æ÷`*™ì¤TŠÕ¾xýÚ‘µ¦&‹ˆù4¦ùDM:ýl7œïéZCŸÒ<»S,-éÇ{äX]“Q²–va )ý^Ö:Ÿ¥wÌ•Ýðy’Ž9ŽMïk;‹°Ú#mOà A·u1ʰú"È^8²&~­‹÷> «õQJ’^ã÷`‡ÃÉ ‡cPb 9Ë/ÉÉìÓ^›ÉlÉ:'‹lxkÏö49z ‹6bÕ¸‹ªƒ"U#d´MÃZàü­&^ß5k'Z*Ç¿èÛ·*5`_, e?9W‰°¨Ñt p__ó«‡NÆ$º_–ã?Ð×¶“ا1éý 9Ê¿s¿¸ ‡(…å¬]Ng ¿RÎv_œ¨Ir^·ÄZޓáü+VÓd"”ó„Œýf:GU³óÕcéw\[!¤>dKÁƒì;ü­E¯ï±1ú¹1ú}Kôž ú]o-ä7T1^÷—9eëD.=„)IöÕ½b qŒæûOäØõgËÑö¬FÒá]´ø Îè0µÄV"ÎÅÒ¨úÛÑL?ÃÒZŽÑ©úýt,5,¥1š"‚âaûñ~ô²UW¥$iXq'›ñ˜‚ô4ŒýÖmãMºP8‰,>S­Ô‰˜ÈEl•bª–«õ^§c¤·§P:C e>Ža„µ:¦éÆÚ[àb,úT*ƒeE¨†äv„ -IÒNvÀT ãdT”Éž'2¡¿Ð(çm®ˆŠ¢7îdßW›É|8‹æ|DNᕘܽ/¥na•ŒÈɼRr>>#Âd&i¿Z¤Éë›Èi‹åÀ‡‚—Oȉz€þ‰‚¯ÄÈ®D~|“Ý‘ÏcÊ£­°ÈíLí]÷cdhƒö ±^Ï×èqIëÂf’Tˆ6ÞªR¬ª…b@=FLï¦9ŠmÞIÕ÷þ0Àçøo­ËðýÕýõÆ5étcm&óMÝ[Ž.¨Ídþ'›l¨Íd¦`)5šoÿO{ëŠ<ùíX0á­£»²åR¬ñÖI9KíªÐ]Mï”QÅN6TD¤ÂíuµWN13I„ÃŒh‘!%,®Úø®ÆÒ¢½gSØkÉÚ„‘ÆÏw᫜ yÒ„©XnubÂáprÂáìÅ'·ÓÍv]/°6¾¸Y¶V!#bIÎýn˜ü|"IÎvÝÜ×bѪù2–£ÓŸhÅZÀí&#gÐHbkÒéuµ™Ì·±hÚ–2h—› ¦È±2"'J(pm€(}ãx9‡Óä°_‹ÕØ)QŽ\û&IÁË ±ìÚ~<ͬðß]˜šëHL¦Oéqw¬FÅZ9½§`hGq SÏí+G÷U]ß?cõ@>ªçéP-Aq¤œÂöó¾ÙT›Éœ‡¥O‡¥‘Ü­Çäìï¨ûÏW°‘ùNwy\÷½µ¶cÂd;]ŸPXõúûi:ÿ–A6ùH‡I"\æè˜­½0´ÛS½²S¸â6º-$ª¨Õ"6`dh8Þ«÷?¥;s½6“™‰)&Fk.Ü#ÈS©$.Òg~V{¦‡“Ç0_—ã>YŽó ƒ$±Õrš÷’Á÷6 £e|µËÀZ‹¥œ<‡Õ¿xA$AP|´å±³D‡ ôR‘&O ¦qÖ¸< c0Ì‹r,j¹¬HŠs®”Q;Es µ@ãÒZ8‹¶M‘1}ˆ‰×61çS2®/Īõ§°Ý%˜²(k¥‹Ð€©2þŽÉ›žÕØí¥5õ”Ëmœ(:…íj –`µ?ÎÓy~¡&^•õ²éXºÇ{°@KZD‹Û‡“ÇCÑ9Ë’ãO1rp°Œ’ñX¤´“YþË9@ߣ~´±\ªóß’Jû‡#jÒéµµ™ÌñXuô3€_™ÚLæ ¬5_¡çzèö0“r7÷ãš)ÁÔD‡Š”ØWkå 9ù7bé-m›qfç`Uà˰¶ —`­ íô/ÀjZœ­ëwNäXü:r²–`Rì¹rú†}Ö¨øo%¦€©_f꘡ŸÇkN^H~”sk0’p¦öôÐã}o“%ΦБ_'Êéû]žÎçŒHÛø9pIM:]7€ßûíAï~(gÿX}÷ùXmš§ò@L”h^–a ˆÑ˜be:€ØFdÄLL1JN~XïM$*ˆ—±4¯ç°â«uÖÂÀ“”ûêñ¡ÍØU34þ¥X‰²Æj;àzLò/¬Åò"‡“ÇÅr9ȳäœô†.éùHÝ çbʈýeœŒÕ » “—ÞånþGÆÓº"SEt×XoÂ$Ÿ)Ÿ~y'(êk3™K5g®ÂªŸ¸ª6“¹¹&^[ÀÓ Òâ 2Ê×÷Ãú õK>!gb­á§0¥ÃíÀênDfGëÿÏ’Ó:¸K‹¨ÊüíúÇaõ~†¥–å0­•cR»†,9!ª\Î]ȯŸ$Çn íã3õó$]×ÐQ T{N«åÉj`\m&S’®IÎÖöš§œÅC̓å8¬Xý’R`O¬ðëyøœz,¥cðJÓ8rá5,­dWŒÀúˆæÏ½!¹Fs©¤5ï(L¹°B@ÜJ3̯2Œ¡÷ƒ‘`¢Ç‰úýhÍã ’:¡>Ô‘ ‹„xNûÒ"­ùz §‚è/±¯¾Ç³›XÏUÀ÷°àЀ[£½:¥÷ÈèºüFûópmáêp [”ø8†fb…!_Æ¢®y1˜¢HÞX,J²=&ßMÆNÈíÀŠM-–QòoLþºSF v¥Áx,BÙˆÉÐë} Ì©›&ã.-‡í%,bõ`e”)‘{ëxµß§ ‹¤ |PóªS]<ÒÍ" •XôúR½ßZýÿ5r ZIU| K+¹“ÁçÚ¾'âé( XwBäêû1BµQÄÈ:ã’6¦M$ô²sÙƒc½rØ‚S7YdÃTÅÄŽé ü­×u\Œ©hÞÐ^ºLç: ¬ÎãÞúeà[˜¢ç—ÑZ¸K;:T{ü@ +Vy*–rR…¥~X?e”b­\ß…u•øºž·hNÕ“´Ù ׬TcÖœEZä²£³;]tDdB“Æw­ˆŽ×E–,Ðó¥i×L) ce¿th¯_“cïHa…-¿©9wTM:½:º6G`me«ïc £8ŽaWN8†êuLÔüïr¢6“©Ä¢P»b…ª¶Ç$ã“°èK©nÜ-XûcºAÿ‹,¸€a>Ð(ƒl’ä~%'ä„Ï”#³RÎIÐ4€µ"–Ôf2ç`‘¨óäTþ?¬"ýïj3™›€y9 ‘õÚe€¿]æ«=¼¶¥º®ĺn¼MköMLUp#0¿›×¹Ø«üþ­Å?—aDe±D#;€Z‘0â‹ÏäxÝÃXÍ€ý)lQÌJà°gIŽs² 5¾9}©ˆ¤G¶ãÚ6kßX,'îM9t õ»$]Ãç ÊìiûžZ{í:–¶ë‘S´þ?„)ñΣ¸¦Ü{nˆo‹mùÿ>¬–Áž˜2a F侤×Ä]-Z47×n-ÑÜó3c0².¼>&ÄB žVŠWÑ[L& DtE(ÌÖÞ±8#"&ʵß}Cëä,,­£ ‡Ãáä„Ã1 ЄE(¦‰4ØÐOïû6¬¯w5I±ªõ2¤çÉ`}FÏ—és[ @>úª1‹¤L“Ѳ1ú[£ Ëg~»Œ¾`®ªÍdêDúÔÉ íSëe(†hV om“G¯² ÉŽ¬ïžÊ::€õÅ@Ž(:üLm&“ÆÒNÁ¢¤ga‘Ýj3™?bûæý<'çkLfu“HaÒý½°ô†C±¨y“ºŸcµWVu“ÈKaòÿ/aUø«±‹å¨£\ü/p5p>V¥¾9‡Ü ì'ã¾Psm£ˆ¢m1%C8bû8ý.äΗE_GD\„õW¯½rµÖé2u:Ök݆5Ú^ä$î‘$L ×î}ÿÝ4/ ù¶’÷Ö-äs:Ï›EP|+¦8Ô Þ¯9ôí?Ö\=Kƒû[ŽÿiÏzìÀ 3fc:F\¾D×u¥Z°"Þ¿Õ\C×à|àtÝŸ?¯{‘ùu8œœp8†9± ËyìÏÜßW±¼Õ¬…çë$‘üÖAX+"—“7R†Ü9›Ûb9Ô[Ê8™ c£’$/·CM¹Æ;×óû˜t{ŽÈ±X”°‚$/8YFfˆð¶GdDˆŒ…ÇÎ%Q2õ”Œ° j3™ß ù¤Â©×f2_3òaàLM°§ ÄW»j3™;±¼ù:ú®æY Ç9›!%Fˆ`ú8Ùœ.‡öM,÷øà¥ä­§4>'Bf&ñ?ø=i/Vt`E OÅÔ.ûayñ1iÙA$ÀšÍ£L óZ×1( RÑuÈ–½wDÎÇ×ÓØ#VèÚÌÖµiŽÖB3°£ö‹B%˜’¯Vs匨 …)ÿS޵ܬÑê’hÿ ÏÃÞׇ©?;iŸþ#F^ž¬ýçON<ô s4¾¯lb^/ÆŠ°¶j™¤{÷G1Ô‰íÄ„Ã1Ìá5'Ã?Ǫó¿ëÅîHP.b¼ˆíeÈí(c;T†`^7©0ùõë2VöÇZ´ŽENúQ‹ÀP=ä°2eœH‹1"P‚Â#¼vDtTŠØ(§sñ³ÒûfG‘Ñ"Ç÷Rà_ŪŒQ:L¥ŒÊÃ0¹ùŽ$ÊŸX¿Ð¢î9÷!/:tâX½™´ƒ±Hد°èXGçói,…¡RŽÓ½XÚÆÀš$cE¼œ%Ç£ø – ²ŒmãØ|T¤ÌýX¤7® P Ü ¼CÇ3¾u µ9ë¾¢Äã±zG ˜‚!ß…LS±u=V»ãg""âÏ­îÃæw‘¤6ä‹<(ÓÞZí³£HŠIŽÒ~<2zMeôÚøç°oŒ+õ<ìßeѽ*£õº±ô¤©X‡‰—Ècª<íáñ÷«ÐŒÁÈùYÚÿf`dÙjÒé|‘˜aÝ…>-ÂgsثDz?–âz‚î5N 9WN8†%‘DV‡J"ã®ZdÃ,Lje„6x#HÒZdÔ.éð²ÖWED„jâqjD0r'êsó6ÞŠºÆ…ñºkÜeGycþ„$>Eç(0‘!¾kPb´c5/ŠÖÐÒ¹5bi/Š˜†3;K«ØBFäûIªÊÇ “FàÚÚLæ[›ˆz/×|Ø‚M·’}Rçð8V‡¥®‘ô*¬žÄ…X'œõX±Ë«5g[Dîv,’x€ÇÛ¢¿µ‰¸9Kpr¢xÐ&‡ëí©œØ€E·ÁÈÒ|’)àÝ?+.øÞZô² +*û%¬SÍ< 1"o¥öö$E!;¢}1tŸ)ba´œã±$dðrxTD*„”ŸÒ.ö×p¿ÊÞG;²öÚŽh_j‹îA­:ï¸FD»îm[céa º-Òï&êõ•4˜¤ëœŠÎ©®SB ^18ãgË@èÄD{EDX„ûÓR¬q¾È‰Ñçln^Õ[ÅjŸ,ómÃáp89áÎXžogy€ÖrˆU‘ä~ÏÀ$òÓH*àOÔQ­×‡œðPU| ê—åô¼ çn¦Œhœñî`©Þz:èÙiÇ&9$ Uƒ"¤áLA1SÎLŽ ãR¬¦Ä¦æÁ:½÷ÔÍÏõ’Ð)Ç" Ë‘oŪò_‰ù¬2áX‘¸?`i7÷e9´hî¾K}Öóx ¡Z)[hž?Q“N?©?톥R„:D/aµ_f`J¤|GaÅ/+5w~Ì[ë–\«sߨS[¤ríYk=›Ô šÆÿ“M©YG¢´[=†ú"A H6ëÃê5Gk¡s!Ö–,"£M{PFãÿ'ýn#V¬ôS©¹¸ã_Š)çjHÈ}r<ÆL<~%Yãšë:¢¥5×uºO¯Ù:‚,ÁÒãÞÈ㘤sZ·™}úH,}h Ö!鼃—ÃáprÂáø/K?esH·+q ³1¥ÃôÈqŒ£Rqô¤=2dÖc²71õÃ+2œßĤû鿊âËõÙS}ê ²¢]sd¹Žg²œ°8¹¹â„¡;Î9JM› Hzã„m+çëÍ÷û±S¸"‘ùÄýXáÎC±®%7GÎÍËXäwmƒÏÞ!&ÆcµMN×~y°®M‹È‰˜”{K)ÜK%èoT'aueZ±V´7Ñ5)FJ¦1ÂqI שÑ=¥#½‘Ý‘õ$…†×gõ"ânMY¤EØ? A"NÄRjâ}­¸+À{0–zØÕ[Vã£A㹺Òtй+M³ÆkctŸŽÇ6<6FäMx j‘v¬[M¡”{¥š#¡ u.Ta-v¿ª×ƒ¥yG‡Ãáä„ÃIU‹ÕY.Ñ|±Þ ‹fí(ƒq¬‘`䄈P“ šµXáµåXh9 ]+B‹³ Óm-€Q¸:ïBW©wô?qÑ“ë׌)n¶ó³®ŸÖÈd¬ÛÈ)Xî%Leðwº™Ö3HÐ\Ž©#ÎÖ÷[ícobåØáFNÔf2¡¾LV¸µ£ÀŸ_Ž¥n\®ý¹Së,ÕµX‹Iû«H/¡cÇîyØ «°šgjŸÿ–ºÐý½Uç»–Ü-s¥\P@R¡¿°“˜[é\÷1]³ƒuíu{eÍÃÿÿ™»©Ún),˜0JÏWö èo± K;ií‚l˜€uBù$ú<–Jä…/‡“GdÔ·a©¥x“,•c5“Íï¥c®ùQ‘Û('ÿyLª¹@o`2θPaœ_[ uÖ“äú:91¼Ð,ƒt;,ÍhIßo$ð1L-1[sÿ<¬èßê!:†bõ'ŽÀäú×k 5`mQ?&'xéPüò*v;B{å4¬ëÄn:æbdëwk3™[jÒéúœO F_«_ÿ#ǨVÊ:ŒÞšÎõ%æËÛ™ÎmFûŠ XûÙ£I”öã^Û¾ çzÝ«î硺ïþÎj’7µ7m¯yÖØs$¨Ë5>á^?M÷û­uÌÀÒ0›±Ô’‡Ù-վܜ5ŸKô=†uBy Sõ¼à6€ÃáprÂáèŒ5rà§i ô·AU%¡Äh©3åHì(#{ ý~„þ¯UÆöBLüm{MçÝ‘ƒú^Õänëéºh×Ü}F¸½ÐË÷)Çrá/Ãrã°bßÁÔAC9 ׂEäß üõ]…È!ÝKé‹#ÕNÒæ¯äCØ/1N{óÖ"vÄTd“ä…®9¡øí,ýäÚLæ2àî|EŸk3™ ¬»Í·uN/aíiïT»^¢s{«/1›$ß…®ÝV˜Ò¡?ȉYrÆ Êž€¥éâ:ÎÀºê¬”ã_¬ª¥Ý?#‡ÉúûF‘9Ó}yyæD¥þo_’˜¸3Ôh’.Pqªe¨C²Asâ)úNÞÊõýBÝHH«_j®ÿSô IÕáp89ápôuLÔØ”!ZtU´+«Ö*g×1YïZWŽ#i[Y‘qñÉ`”<-ÃòY,⶚¤\’œ¥qhÁ[† ',Ð:Ú²ÿ›’q{>¦(ÃòÃ/Á:|´ “1|F¤Ä1ÀÇŸj =¢18ø!›®-ÐfbÅ'uµ™ÌRLí²4r¦×ɉÚ­çßÞBn}yD>ŒÔçL‘c;K×7“CR¤7¨¬B§ 7°:9Ïè˜'§x+L=s(V“ã®ÚLæÀ“5ét¿ÌÉóg`õL>®ïþCà;5ét.G¶Cûù±"(q´+T¸›È–µ}8­7×cé ÿÀ$ó…tpÑü¹‘>ª òŒ]°"•;hngQ»ö•£±ª{{ðÞã°Vš³è\C¢UcR)3êô¸ˆDõ¸ :„4ËÁx¿äÄ:ÖúøjÙ??Àj xáK‡Ãáä„ÃÑdìN—1Hˆ r˜$ct†‡qÉ·?#‡‘ “&}ÖÑËe”¼ŠL[$äaˆ;ìõr$¦còôWDÆ<ƒ)DV’¤¤¸Üsèáe=nÛÃÿœŒEÜ&è}.ÃZjnfcØ*#ÿÃXd¼Vc°#2w¦smƒžÚA©Pím%ÑžŠ†îÍÑó¶,‡9=–EGyô<¼&¼opâÊ[ }ržœù:ý½µ&Î&`VÔf2ÇïÄR-Þü©6“¹xy3E[7GLTê>q¹Ð€³€ûrœK6¡Ô޵N éƒ-úý¾ïW{yZ)LIt½îQ¬ÈàÚÎÉL!°Tãr‰>µý-Ãlâ­5â®ýqÿ ÷ñ:·(]‹©Å¹ 7>¬s;ø.ÝWµÔ•ШïȆÆè{·³ùƒå:´¶OÔªur=^øÒápôðæâp 7”c¹÷ØÌ:Æd¨6¾N×*`«"#lIOøÐ¡ Û0é¯îƒqŸÙø>°7‰4;–µ®À"Ióå„ÎÓÏaL]m1x±‰¼‹´nn ŒÞ/w{Í¿Ð:ÎûÖ©˜êàÚ[ÊEÖì‰åu¿Ô 组ÎRôñ9;SƒM94ž¤l Q›«…dG´ßµDNêjŒ¤]‚‘³oʹ­#éBÐF/» Ôf2Õ"pÎÁꜬäåWK{òžRKÌÖX©½êÇÀÿÖ¤ÓuÝx‹Ùrˆ_Æ gg÷x¬}ç…XZRoðÀŸèZ|GÎt¡ »R¬}ï"rÝKÛ£#(AÑ@Ò™"8ô¢#(C¥ðÿqÛìX½8šD© š‹¿ÁR ~‹¥ä|#Ç÷©q1JëiE‘ï¥S=–vq„¹C×(F­tnÉÚ.l©yþ¼Æø4íÓ§Ðý‚¬‡Ãáä„cØÏû±hØeÇýÂ×GFôêÈXjÉ2¶<Êß³1E—farä]ô8[Æå(9[%q±“áΓãõ‚ž/iÑàסè1“¸¿ŽE·6alïƒI¤Òšü±^àFî‹T–£p¡Lci ý9ê¡CPöól‡§#rz:¢ÇÏkôXdË ø"¦ØZŒ¥aܬÚIQ›ÉŒÄÒ7.ÅÒMžÂº¥<°µDŒÑXqÃj9»ÐØëVðg]³žÌë2‘ßÖøŸ üŠþ+¬ÙSŒÆŠŽå­iŽ!­1®½0JGÜîº"šS©,²«$ëÒ=Æs­-:bç:t±úðW͇ê’km]¥$¼Ÿ^ÖpéÑU:˜MĈ©Q8‰Î)£USžEPÄJ&rAmˆþ„~êurZŸÁÒD^Æ¢°kñ‘bBˆHVbj¥59œ‚9À×äVb2ñ‡Ðñ,ø ð{¬(â—}Þw"T¦aiAÇËI~¸¸µ&^ßÅÿl§×¼GŽÙÕÀjÒéžvƒI¹whŸ«Ñð8–ÂrÝ—¼Ö9Sæ†Õ!)f0vŒãpžƒú&(!iŒÊèÎv¬¾Ø€ØëHRGBÚQùo"IßÜT«°âª—a¤h_Õzq±×˜l˜¡y0K¤ÃT:§ŽˆH†leR;oU4´æøîÍtVœ´EÿÞ+\Ÿ@ŒTFDLj.Hp>íÀ·0êÝz¯±´ŽBdu8NN8CSeÞNïò´…!.*±¨Ü¬ËÉÎXñ·mu «I$Å1iñ¦²xN†Ò¢ˆ´hré (îÐuÛ“¤sAJ×ð¬¶Äx]«Ëåtmð¡ë¶Â cÎÃÒ<¿»3áPŠB< « P <·üwèì¡”°”ñr´¾<®ö ½Á%~<Ön9ÞÊ݃DQ±)ÌÄR›ÃH'é=<2Ý¿Ø V<|ˆ·£q•àЈȇ±!6MÄÃlS0r¬Š·vìhÈ„"ZVcél+0ç +1r7ÔhjÌ"(bò¡­‹û\G~@I¡¾c(^©¹;ZߥSL솩€þ G:8‡“Ç[ç¿;©ƒ¥2–Fc9ñ[Ë@Ú‹zNÑßB>|ˆœ­ÃÒAÞÿ:&M].ƒ¯žÎ…ÛZ#ÃÏçIßð[9V!‚<ø&³ž¥kðÿ°úu>Þ=ÂH,×{2°yèÖP›É”Ë!Akâ¿ ûบ¤(vÇ:¿ª_ß‘a£°Ž}´\ü¼&^×Çýðk çk^—Ê™{VÔrSuBRÀZÛé:SŒ¹B¦ÿRqFcõ‘¶Ä­@.„c‰Â¡"räã´” pˆSE—bDùëXªÑ›jl„{N{ÙP¬ø ö÷óùr8NN8GgÒ¢ZÆäl,Z”Ó±ÈVUD\@ç‚m!O¹AGȳ Ÿ†‚¨kõ÷Ðf1xkŽŽbkGËÎ;ÎgÁÖïÉ©:SK|S¬Çò¼$£Ý#Á½»ß€m|/QïoÇþh¬ÎAóÐ7Ò¹Ck´ŽBaÌl8¤r y=peM:ýBHŠÀÁX1ÇÝu®!7ÿ¬-éKýTcà>,ª|T4¿¯¾|ËÛÏ…j¬5èWåÿS{¬ò)Ÿ7¤°N8>€Õ9–$$Ô²E^7’¤•„:UËD<,ÕÏ+õš¦è~0”ˆ¥IšÇÑîp8}‚·u8Cm©°Ké¸Mg§ŽÁr{'cûé:BG‚q$EÛ&éo噑ê©Éf’vµÙÝ:’Î.Ù¹ÒÁðm»lR!Då*è,¹­Â"yc°¨ßØè¿«–““?ÜžEʇ³>z\KR6JkÎq¾qNt—f’üæó€·‰Ä¹ë2ð²“}BQÿ¦œx0Ÿ±K•š¢94“®Ç w7€®æÍ൙̋½éÐÑSÔ¤ÓÀ?j3™Eœ©ù|p{M:ÝзLëgŽÆ-¤*=¯µ·}r"Ô½øV¯¢#ónÁë¯äíX‡‰jÿ¿#þBaÍÐ=$&ŸãtŠMÕ³ª¨®ÃÕn‡£ŸàÊ ‡Ãáè\)>;Ÿ¸*",ÆD$Æø¬Ç±$éCõ@”å 6:">.rç ÇEËRÝxöõøÿÛ³Þ7»ÛLIôý³è\ ÞZ)Ÿ.þW‚/ÓxÜ<+cöyºnOçèÞ.§êÀ‰ô3Ù£•H±@UêyÜÚ°$‡½æ_ìØÕKjÒé‚;Þ*€9KOÉG­Ž*à?"röÉVïè6,åãóÑZ‰¥;]Œ‘¨w_ÁP‡EågbÄ—“Åv,½ìCX•@N¬ÃHÃVö¬ÅX,bÿ¬p¬«%‡Ãáp8‡Ã1hŠb®ö÷á(*…)!.ÕÏ),5ìY¬þÌ‹™ôFPTû9‡Ãáp8‡c°ât,uçtŠ¢ÂÛ0Òèeà¯ÀS˜Ê%“] \ lEÏ Š:‡Ãáp8‡ÃQtØONð$éBŽü¢„¤(h(ž[MRce"ÖA%n­¨]µõ[‡Ãáp8ü†èp8ÇÀB9»»ÊI®/àg§²ì‰’‹1âÖ£á1tþ¨Ä ®Ž$ézS¥ßWDŸQ–ƒ (‰Þ3®wˆ€¸˜lKֹŭ†É0"ë¼Âcv'ŸÊè¨ˆŽ¸CO™>· x¸xk'ü"°¯-áp8‡“‡Ãáp ¬’Ó;‹ÚwEN”DÎsiô<8æ#±èÿh’¹ã15@LTe9N4jä½IDATãq×–  G‡þH€ª,ç>Û¡dÃ@"WËÜŽGܸ5:6ê± XŒÁ¼kùêEa‡ÃáprÂáp8Ž!‰f¬žÁ."(‰˜ì„¥l Lá0*"Ê#â Eçö²%YŽz{ô]w‹É&ÂëaѬcµùõ:Ö`mpCG‹&µCø_¢óŠI‚ìóˆñw,‹Î- M$-zÃg†çÙ­|[£ß5g[[DXÄãþ߉ ‡Ãáp8œœp8‡cHã~àà]ÀÉÀž"'ª"b UŽwì|¯Ç:JÔ‹X%Ò`ž¯Õß6ˆHhˆƒX%§JEtD¤DìÔ'>n3Ûæ—Òáp8Žá''‡Ãáø–~±7ða ÏèX€"r 5"∿×Ap8‡ÃQP”ø8‡Ã1d&aЉå˜ò!V%8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8‡Ãáp8G¯ðÿ„VÍ„ õNLIEND®B`‚paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/intro.py000066400000000000000000000060231456262201400255320ustar00rootroot00000000000000import logging import openpaperwork_core import paperwork_backend.sync LOGGER = logging.getLogger(__name__) DOC_ID = "help_intro" class Plugin(openpaperwork_core.PluginBase): PRIORITY = -100000 # see storage_get_all_docs() def __init__(self): super().__init__() self.doc_url = None self.thumbnail_url = None self.opened = False self.deleted = False def get_interfaces(self): return [ 'doc_labels', 'document_storage', 'syncable', ] def get_deps(self): return [ { 'interface': 'help_documents', 'defaults': ['paperwork_gtk.model.help'], }, ] def init(self, core): super().init(core) def storage_get_all_docs(self, out: list, only_valid=True): if self.deleted or len(out) > 0: self.doc_url = None return self.doc_url = self.core.call_success("doc_id_to_url", DOC_ID) if (self.doc_url is None or not self.core.call_success("fs_exists", self.doc_url)): LOGGER.error( "Introduction document %s not found." " Was Paperwork packaged correctly ?", DOC_ID ) self.doc_url = None return out.append((DOC_ID, self.doc_url)) if not self.opened: self.opened = True self.core.call_success( "mainloop_schedule", self.core.call_all, "doc_open", DOC_ID, self.doc_url ) self.core.call_success( "mainloop_schedule", self.core.call_all, "docview_set_layout", "paged" ) def labels_get_all(self, out: set): if self.doc_url is not None: self.core.call_all("help_labels_get_all", out) def storage_delete_doc_id(self, doc_id): if doc_id != DOC_ID: return self.doc_url = None self.deleted = True def _fake_delete_doc(self): if self.doc_url is None: return all_docs = [] self.core.call_all("storage_get_all_docs", all_docs) all_docs = [doc for doc in all_docs if doc[0] != DOC_ID] if len(all_docs) <= 0: return self.deleted = True # make sure the index is up-to-date self.core.call_success( "transaction_simple", [("del", DOC_ID),] ) def doc_transaction_start(self, out: list, total_expected=-1): class FakeDeleteDocTransaction(paperwork_backend.sync.BaseTransaction): priority = -100000 def commit(s): if self.doc_url is None: return self._fake_delete_doc() out.append(FakeDeleteDocTransaction(self.core, total_expected)) def sync(self, promises: list): if self.doc_url is None: return promises.append(openpaperwork_core.promise.Promise( self.core, self._fake_delete_doc )) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/out/000077500000000000000000000000001456262201400246335ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/out/__init__.py000066400000000000000000000000001456262201400267320ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/po4a.conf000066400000000000000000000002361456262201400255370ustar00rootroot00000000000000[po_directory] data/l10n [type: LaTeX] data/intro.tex $lang:out/translated_intro_$lang.tex [type: LaTeX] data/usage.tex $lang:out/translated_usage_$lang.tex paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/model/help/screenshot.sh000077500000000000000000000074101456262201400265420ustar00rootroot00000000000000#!/bin/sh set -e # Explicitly set the revision of the test documents here, so we can figure out # exactly which version of Paperwork was tied to which version of the test # documents. TEST_DOCS_TAG="2.1" TMP_DIR="$(mktemp -d --suffix=paperwork)" echo "Temporary directory: ${TMP_DIR}" OUT_DIR="${PWD}/out" mkdir -p "${TMP_DIR}/config" mkdir -p "${TMP_DIR}/local" mkdir -p "${TMP_DIR}/papers" export XDG_CONFIG_HOME="${TMP_DIR}/config" export XDG_DATA_HOME="${TMP_DIR}/local" BASE_WORKDIR="${TMP_DIR}/papers" WORKDIR="${BASE_WORKDIR}/paperwork-test-documents/papers" cd "${BASE_WORKDIR}" if [ -d "${PAPERWORK_TEST_DOCUMENTS}" ]; then rm -rf paperwork-test-documents echo "Copying test documents from ${PAPERWORK_TEST_DOCUMENTS} to $(readlink -f .)/paperwork-test-documents ..." cp -r --no-preserve=mode "${PAPERWORK_TEST_DOCUMENTS}" ./paperwork-test-documents else echo "Downloading test documents to $(readlink -f .)/paperwork-test-documents ... If internet access is forbidden, set PAPERWORK_TEST_DOCUMENTS env var to the path to a pre-fetched copy." git clone --depth 1 --branch "${TEST_DOCS_TAG}" https://gitlab.gnome.org/World/OpenPaperwork/paperwork-test-documents.git fi echo "Updating Paperwork database ..." paperwork-cli config put workdir str "file://${WORKDIR}" paperwork-cli sync echo "Making screenshots ..." paperwork-gtk plugins add openpaperwork_core.interactive paperwork-gtk << EOF wait() core.call_all("doc_open", "20990307_0000_00", "file://${WORKDIR}/20990307_0000_00") core.call_all("search_set", "label:contrat conditions generales") wait() core.call_all("open_bug_report") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("close_bug_report") core.call_all("mainwindow_focus") core.call_all("gtk_show_shortcuts") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("gtk_hide_shortcuts") core.call_all("mainwindow_focus") core.call_all("gtk_open_layout_settings") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("gtk_close_layout_settings") core.call_all("mainwindow_focus") core.call_all("gtk_open_advanced_search_dialog") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("gtk_close_advanced_search_dialog") core.call_all("mainwindow_focus") core.call_all("gtk_open_settings") wait() core.call_all("settings_scroll_to_bottom") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("settings_scroll_to_top") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("display_calibration_screen") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("hide_calibration_screen") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("close_settings") core.call_all("mainwindow_focus") core.call_all("open_doc_properties", "20990307_0000_00", "file://${WORKDIR}/20990307_0000_00") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("docproperties_scroll_to_last") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("mainwindow_show_default", side="left") wait() core.call_all("screenshot_snap_all_doc_widgets", "file://${OUT_DIR}") core.call_all("gtk_open_app_menu") wait() core.call_all("screenshot_snap_app_menu", "file://${OUT_DIR}/app_menu_opened.png") core.call_all("page_menu_open") wait() core.call_all("screenshot_snap_page_action_menu", "file://${OUT_DIR}/page_menu_opened.png") core.call_all("doc_menu_open") wait() core.call_all("screenshot_snap_doc_action_menu", "file://${OUT_DIR}/doc_menu_opened.png") EOF set +e echo "Cleaning up the mess ..." sleep 5 rm -rf "${TMP_DIR}" echo "All done !" paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/new_doc.py000066400000000000000000000021171456262201400237650ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.new_doc = None def get_interfaces(self): return ['new_doc'] def get_deps(self): return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, ] def config_put(self, opt, value, *args, **kwargs): if opt != "workdir": return None # Bug report 170: When the work directory has been changed, # we have to make sure to drop any reference to it so the user doesn't # use it by accident. # (keep in mind that self.new_doc = (doc_id, doc_url), and doc_url # includes the work directory path) self.new_doc = None return None def get_new_doc(self): if self.new_doc is not None: if self.core.call_success("is_doc", self.new_doc[1]) is None: return self.new_doc self.new_doc = self.core.call_success("storage_get_new_doc") return self.new_doc paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/notifications/000077500000000000000000000000001456262201400246455ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/notifications/__init__.py000066400000000000000000000000001456262201400267440ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/notifications/dialog.glade000066400000000000000000000070651456262201400271120ustar00rootroot00000000000000 False dialog False vertical 2 False end gtk-ok True True True True True True 1 False False 0 True False 20 False 20 20 20 20 gtk-missing-image False True 0 False 20 20 20 20 True 0 True True 1 True True 1 button1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/notifications/dialog.py000066400000000000000000000053551456262201400264660ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class DialogBuilder(object): def __init__(self, plugin, title): self.plugin = plugin self.widget_tree = self.plugin.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.notifications", "dialog.glade" ) dialog = self.widget_tree.get_object("dialog") dialog.set_title(title) dialog.connect("response", self._on_response) label = self.widget_tree.get_object("message") label.set_text(title) label.set_visible(True) def _on_response(self, dialog, response): dialog.destroy() def set_message(self, message): label = self.widget_tree.get_object("message") label.set_text(message) return self def set_icon(self, icon): self.widget_tree.get_object("dialog").set_icon_name(icon) return self def add_action(self, action_id, label, callback, *args, **kwargs): buttons = self.widget_tree.get_object("buttons") button = Gtk.Button.new_with_label(label) button.connect("clicked", self._on_click, callback, args, kwargs) button.set_visible(True) buttons.add(button) return self def _on_click(self, button, callback, args, kwargs): self.widget_tree.get_object("dialog").destroy() callback(*args, **kwargs) def set_image_from_pixbuf(self, pixbuf): img = self.widget_tree.get_object("image") img.set_from_pixbuf(pixbuf) img.set_visible(True) return self def show(self): dialog = self.widget_tree.get_object("dialog") dialog.set_transient_for(self.plugin.windows[-1]) dialog.set_visible(True) class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.windows = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_window_listener', 'notifications', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def get_notification_builder(self, title, need_actions=False): return DialogBuilder(self, title) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/notifications/notify.py000066400000000000000000000052551456262201400265360ustar00rootroot00000000000000import logging LOGGER = logging.getLogger(__name__) try: import gi gi.require_version('Notify', '0.7') from gi.repository import Notify NOTIFY_AVAILABLE = True except (ImportError, ValueError) as exc: LOGGER.error("Failed to import Notify", exc_info=exc) NOTIFY_AVAILABLE = False import openpaperwork_core # noqa E402 import openpaperwork_gtk.deps # noqa E402 class NotifyBuilder(object): def __init__(self, title): self.title = title self.msg = None self.icon = None self.pixbuf = None self.actions = [] self.notification = None def set_message(self, message): self.msg = message return self def set_icon(self, icon): self.icon = icon return self def add_action(self, action_id, label, callback, *args, **kwargs): self.actions.append((action_id, label, callback, args, kwargs)) return self def set_image_from_pixbuf(self, pixbuf): self.pixbuf = pixbuf return self @staticmethod def _call_callback(notification, action, args): (callback, args, kwargs) = args return callback(*args, **kwargs) def show(self): self.notification = Notify.Notification.new( self.title, self.msg, self.icon ) if self.pixbuf is not None: self.notification.set_image_from_pixbuf(self.pixbuf) for (action_id, label, callback, args, kwargs) in self.actions: self.notification.add_action( action_id, label, self._call_callback, (callback, args, kwargs) ) self.notification.show() class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def __init__(self): # WORKAROUND(Jflesch): Keep a reference to the notifications. # Otherwise we never get the action from the user. self.notification_refs = [] def get_interfaces(self): return [ 'chkdeps', 'notifications', ] def get_deps(self): return [ ] def init(self, core): super().init(core) if NOTIFY_AVAILABLE: Notify.init("Paperwork") def chkdeps(self, out: dict): if not NOTIFY_AVAILABLE: out['notify'].update(openpaperwork_gtk.deps.NOTIFY) def get_notification_builder(self, title, need_actions=False): caps = [] if NOTIFY_AVAILABLE: caps = Notify.get_server_caps() if len(caps) <= 0: return None if not need_actions or "actions" in caps: r = NotifyBuilder(title) self.notification_refs.append(r) return r return None paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/print.py000066400000000000000000000240341456262201400235050ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.promise import openpaperwork_gtk.deps from . import _ DELAY = 0.1 LOGGER = logging.getLogger(__name__) class SurfacePreloader(object): def __init__(self, core, doc_id, doc_url, page_indexes): self.core = core self.doc_id = doc_id self.doc_url = doc_url self.page_indexes = page_indexes self.page_surfaces = [] def start(self): LOGGER.info("Will load %d pages", len(self.page_indexes)) for (page_nb, page_idx) in enumerate(self.page_indexes): page_url = self.core.call_success( "page_get_img_url", self.doc_url, page_idx ) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=( "on_progress", "print_load", page_nb / len(self.page_indexes), _("Loading {doc_id} p{page_idx} for printing").format( doc_id=self.doc_id, page_idx=(page_idx + 1) ) ) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(openpaperwork_core.promise.DelayPromise( self.core, DELAY )) promise = promise.then(self.core.call_success( "url_to_cairo_surface_promise", page_url )) promise = promise.then(self._add_surface) self.core.call_success("work_queue_add_promise", "print", promise) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=( "on_progress", "print_load", 1.0 ) ) self.core.call_success("work_queue_add_promise", "print", promise) def _add_surface(self, surface): LOGGER.info( "Got page rendering %d/%d", len(self.page_surfaces), len(self.page_indexes) ) self.page_surfaces.append(surface) def get_nb_pages(self): return len(self.page_indexes) def get_nb_surfaces(self): return len(self.page_surfaces) def has_page_surface(self, page_nb): return page_nb < len(self.page_surfaces) def get_page_surface(self, page_nb): return self.page_surfaces[page_nb] def cancel(self): self.core.call_all("work_queue_cancel_all", "print") self.page_surfaces = [] class PrintJob(object): def __init__( self, core, preloader, window, doc_id, nb_pages, active_page_nb, job_name, default_filename): self.core = core self.preloader = preloader self.window = window self.doc_id = doc_id self.nb_pages = nb_pages print_settings = Gtk.PrintSettings() self.print_op = Gtk.PrintOperation() self.print_op.set_print_settings(print_settings) self.print_op.set_n_pages(nb_pages) if active_page_nb >= 0: self.print_op.set_current_page(active_page_nb) self.print_op.set_use_full_page(True) self.print_op.set_job_name(job_name) self.print_op.set_export_filename(default_filename) self.print_op.set_allow_async(True) self.print_op.set_embed_page_setup(True) self.print_op.set_show_progress(True) self.print_op.connect("status-changed", self._status_changed) self.print_op.connect("paginate", self._paginate) self.print_op.connect("preview", self._preview) self.print_op.connect("ready", self._preview_ready) self.print_op.connect("got_page_size", self._preview_got_page_size) self.print_op.connect("begin-print", self._begin) self.print_op.connect("request-page-setup", self._request_page_setup) self.print_op.connect("draw-page", self._draw) self.print_op.connect("end-print", self._end) self.print_op.connect("done", self._done) def _status_changed(self, print_op): LOGGER.info( "Print status: %s: %s", print_op.get_status(), print_op.get_status_string() ) def _preview(self, print_op, print_preview, print_context, win_parent): LOGGER.info("User requested a preview") def _preview_got_page_size(self, print_preview, print_context, page_setup): LOGGER.info("Preview: got page size") def _preview_ready(self, print_preview, print_context): LOGGER.info("Preview ready") def _paginate(self, print_operation, print_context): pagination = self.preloader.get_nb_surfaces() running = (pagination < self.nb_pages) return not running def _begin(self, print_op, print_context): LOGGER.info("Printing has begun") self.core.call_all( "on_progress", "print", 0.0, _("Printing %s") % self.doc_id ) def _request_page_setup( self, print_op, print_context, page_nb, page_setup): LOGGER.info( "Computing page setup for %d/%d", page_nb, self.nb_pages ) surface = self.preloader.get_page_surface(page_nb) img_width = surface.surface.get_width() img_height = surface.surface.get_height() # take care of rotating the page if required img_portrait = (img_width <= img_height) LOGGER.info( "Page %d/%d: Orientation portrait = %s", page_nb, self.nb_pages, img_portrait ) page_setup.set_orientation( Gtk.PageOrientation.PORTRAIT if img_portrait else Gtk.PageOrientation.LANDSCAPE ) def _draw(self, print_op, print_context, page_nb): LOGGER.info( "Printing of %s %d/%d ; DPI: %fx%f", self.doc_id, page_nb, self.nb_pages, print_context.get_dpi_x(), print_context.get_dpi_y() ) self.core.call_all( "on_progress", "print", page_nb / self.nb_pages, _("Printing {doc_id} ({page_idx}/{nb_pages})").format( doc_id=self.doc_id, page_idx=page_nb, nb_pages=self.nb_pages ) ) surface = self.preloader.get_page_surface(page_nb) img_width = surface.surface.get_width() img_height = surface.surface.get_height() scaling = min( print_context.get_width() / img_width, print_context.get_height() / img_height, ) cairo_ctx = print_context.get_cairo_context() cairo_ctx.scale(scaling, scaling) cairo_ctx.set_source_surface(surface.surface) cairo_ctx.paint() def _end(self, print_op, print_context): self.refs = [] LOGGER.info("Printing has ended") self.core.call_all("on_progress", "print", 1.0) def _done(self, print_op, print_op_result): LOGGER.info("Printing done") self.preloader.cancel() def run(self): self.print_op.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.window) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_doc = None self.active_page_idx = None self.windows = [] # WORKAROUND(Jflesch): keep a ref on the print operation to avoid # premature garbage collecting self._ref = None def get_interfaces(self): return [ 'chkdeps', 'doc_open', 'doc_print', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'cairo_url', 'defaults': [ 'paperwork_backend.cairo.pillow', 'paperwork_backend.cairo.poppler', ], }, { 'interface': 'work_queue', 'defaults': ['openpaperwork_core.work_queue.default'], }, ] def init(self, core): super().init(core) if not GTK_AVAILABLE: return self.core.call_success("work_queue_create", "print") def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def doc_open(self, doc_id, doc_url): self.active_doc = (doc_id, doc_url) def on_page_shown(self, page_idx): self.active_page_idx = page_idx def doc_print(self, doc_id, doc_url, page_indexes=None): active_page_idx = 0 if self.active_doc[1] == doc_url: # prefer the current page when it makes sense active_page_idx = self.active_page_idx if page_indexes is None: nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) if nb_pages is None: raise Exception("No page in the document, Nothing to print") page_indexes = list(range(0, nb_pages)) job_name = "Paperwork " + doc_id default_filename = doc_id + ".pdf" else: job_name = "Paperwork {} p{}".format( doc_id, ",".join((str(p) for p in page_indexes)) ) default_filename = "{}_p{}".format( doc_id, "_p".join((str(p) for p in page_indexes)) ) try: active_page_nb = page_indexes.index(active_page_idx) except ValueError: active_page_nb = -1 preloader = SurfacePreloader(self.core, doc_id, doc_url, page_indexes) print_job = PrintJob( self.core, preloader, self.windows[-1], doc_id, len(page_indexes), active_page_nb, job_name, default_filename ) LOGGER.info( "Opening print dialog for document %s (pages: %s)", doc_url, page_indexes ) preloader.start() print_job.run() self._ref = print_job paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/000077500000000000000000000000001456262201400236345ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/__init__.py000066400000000000000000000126131456262201400257500ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.active_windows = [] self.sections = {} self.widget_tree = None def get_interfaces(self): return [ 'chkdeps', 'gtk_settings_dialog', 'gtk_window_listener', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_app_menu', 'defaults': ['paperwork_gtk.mainwindow.doclist'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def on_gtk_window_opened(self, window): self.active_windows.append(window) def on_gtk_window_closed(self, window): self.active_windows.remove(window) def gtk_open_settings(self, *args, **kwargs): self.core.call_success( "gtk_load_css", "paperwork_gtk.settings", "settings.css" ) global_widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings", "settings.glade" ) self.widget_tree = global_widget_tree self.core.call_all('complete_settings', global_widget_tree) settings = global_widget_tree.get_object("settings_window") settings.set_transient_for(self.active_windows[-1]) settings.set_modal(True) settings.connect("destroy", self._save_settings, global_widget_tree) settings.set_visible(True) self.core.call_all("on_gtk_window_opened", settings) def close_settings(self): if self.widget_tree is not None: dialog = self.widget_tree.get_object("settings_window") dialog.set_visible(False) self.widget_tree = None def on_quit(self): self.close_settings() def _save_settings(self, window, global_widget_tree): LOGGER.info("Settings closed. Saving configuration") self.core.call_all("config_save") self.core.call_all("on_gtk_window_closed", window) self.core.call_all("on_settings_closed", global_widget_tree) self.widget_tree = None def add_setting_to_dialog( self, global_widget_tree, title, widgets, extra_widget=None): """ Add a setting or a set of settings to the main screen in the settings dialog. """ # We have many setting boxes to add to the settings box. # --> we need many copies of the setting box --> we load many times # the widget tree widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings", "settings_section.glade" ) widget_tree.get_object("setting_section_name").set_text(title) if extra_widget: box = widget_tree.get_object("settings_title_box") box.pack_start(extra_widget, expand=False, fill=False, padding=0) inner = widget_tree.get_object("setting_box") for widget in widgets: inner.pack_start(widget, expand=False, fill=True, padding=0) global_widget_tree.get_object("settings_box").pack_start( widget_tree.get_object("setting_section"), expand=False, fill=True, padding=0 ) self.sections[title] = widget_tree.get_object("setting_section") return True def add_setting_screen( self, global_widget_tree, name, widget_header, widget_body): global_widget_tree.get_object("settings_stack_header").add_named( widget_header, name ) global_widget_tree.get_object("settings_stack_body").add_named( widget_body, name ) def show_setting_screen(self, global_widget_tree, name): global_widget_tree.get_object( "settings_stack_header" ).set_visible_child_name(name) global_widget_tree.get_object( "settings_stack_body" ).set_visible_child_name(name) def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("settings_window"), self.core.call_success("fs_join", out_dir, "settings.png") ) for (name, section) in self.sections.items(): name = name.lower().replace(" ", "_") self.core.call_success( "screenshot_snap_widget", section, self.core.call_success( "fs_join", out_dir, "settings_{}.png".format(name) ), margins=(100, 100, 100, 100) ) def settings_scroll_to_top(self): scroll = self.widget_tree.get_object("settings_scrolled_window") vadj = scroll.get_vadjustment() vadj.set_value(vadj.get_lower()) def settings_scroll_to_bottom(self): scroll = self.widget_tree.get_object("settings_scrolled_window") vadj = scroll.get_vadjustment() vadj.set_value(vadj.get_upper()) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/000077500000000000000000000000001456262201400244175ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/__init__.py000066400000000000000000000000001456262201400265160ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/selector_popover.glade000066400000000000000000000027161456262201400310150ustar00rootroot00000000000000 125 False True True never in True False True False 10 10 10 10 vertical 7 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/selector_popover.py000066400000000000000000000060251456262201400303660ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -500 def __init__(self): super().__init__() def get_interfaces(self): return [ 'gtk_settings_ocr_langs', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'i18n_lang', 'defaults': ['paperwork_backend.i18n.pycountry'], }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def complete_ocr_settings(self, parent_widget_tree): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.ocr", "selector_popover.glade" ) active_langs = set(self.core.call_success("ocr_get_active_langs")) LOGGER.info("Looking for available OCR languages ...") all_langs = self.core.call_success("ocr_get_available_langs") LOGGER.info("Found %d languages. Translating ...", len(all_langs)) all_langs = [ ( lang, self.core.call_success( "i18n_lang_iso639_3_to_full", lang ) ) for lang in all_langs # Skip Tesseract data file for page orientation guessing if lang != 'osd' ] all_langs.sort(key=lambda lang: lang[1]) LOGGER.info("OCR languages: %s", all_langs) LOGGER.info("Active OCR languages: %s", active_langs) box_parent = widget_tree.get_object("ocr_selector_box") for lang in all_langs: w_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.ocr", "selector_popover_box.glade" ) check = w_tree.get_object("ocr_selector_box") check.set_label(lang[1]) check.set_active(lang[0] in active_langs) check.connect('toggled', self._on_toggle, lang[0]) box_parent.pack_start(check, expand=False, fill=True, padding=0) LOGGER.info("OCR selector ready") popover = widget_tree.get_object("ocr_selector") parent_widget_tree.get_object("ocr_langs").set_popover(popover) def _on_toggle(self, checkbox, lang): active_langs = self.core.call_success("ocr_get_active_langs") lang_enabled = lang in active_langs LOGGER.info("Language toggled: {} ({} -> {})".format( lang, lang_enabled, not lang_enabled )) if lang_enabled: active_langs.remove(lang) else: active_langs.append(lang) self.core.call_all("ocr_set_active_langs", active_langs) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/selector_popover_box.glade000066400000000000000000000004251456262201400316600ustar00rootroot00000000000000 True paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.glade000066400000000000000000000034061456262201400272600ustar00rootroot00000000000000 True settings_ocr_langs_button none True False 16 True False Languages 0 True True 0 True False xxxx 1.0 True True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/ocr/settings.py000066400000000000000000000042561456262201400266400ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -500 def get_interfaces(self): return [ 'gtk_settings', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'i18n_lang', 'defaults': ['paperwork_backend.i18n.pycountry'], }, { 'interface': 'ocr_settings', 'defaults': ['paperwork_backend.pyocr'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def complete_settings(self, global_widget_tree): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.ocr", "settings.glade" ) label = widget_tree.get_object("ocr_langs_label") self._update_langs(label) self.core.call_all("complete_ocr_settings", widget_tree) def refresh(*args, **kwargs): self._update_langs(label) def disable_refresh(*args, **kwargs): self.core.call_all("config_remove_observer", "ocr_langs", refresh) self.core.call_all("config_add_observer", "ocr_langs", refresh) global_widget_tree.get_object("settings_window").connect( "destroy", disable_refresh ) self.core.call_success( "add_setting_to_dialog", global_widget_tree, _("Optical Character Recognition"), [widget_tree.get_object("ocr_langs")] ) def _update_langs(self, label): langs = self.core.call_success("ocr_get_active_langs") langs = [ self.core.call_success("i18n_lang_iso639_3_to_full", lang) for lang in langs ] langs = ", ".join(langs) if langs == "": langs = _("OCR disabled") LOGGER.info("OCR languages: %s", langs) label.set_text(langs) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/000077500000000000000000000000001456262201400252655ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/__init__.py000066400000000000000000000000001456262201400273640ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.glade000066400000000000000000000220011456262201400305450ustar00rootroot00000000000000 0.01 1 0.01 0.01 0.1 True False 16 16 16 16 vertical 16 True False True False True True 0 True False vertical True False edit-find-symbolic 3 False True 0 True True vertical calibration_scale_adjustment True 1 False True True 1 False True 1 400 True False always always in False True False False True 2 True False True True 3 True True 0 True False Maximize True False True True False True 0 Automatic True False True True False True 1 True False True True 2 Scan True False True True False True 3 False True 1 True False Scanner Calibration False True False False True True False go-previous-symbolic 1 True False True calibration_sources 0 0 1 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/calibration.py000066400000000000000000000364061456262201400301370ustar00rootroot00000000000000import logging import pillowfight import openpaperwork_core import openpaperwork_core.promise import paperwork_backend.cairo.pillow from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def __init__(self): super().__init__() self.widget_tree = None self.settings_widget_tree = None self.size_allocate_connect_id = None self.scan_height = 0 self.scan_width = 0 self.scan_img = None def get_interfaces(self): return [ 'gtk_settings_calibration', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_drawer_calibration', 'defaults': ['paperwork_gtk.drawer.calibration'], }, { 'interface': 'gtk_drawer_pillow', 'defaults': ['openpaperwork_gtk.drawer.pillow'], }, { 'interface': 'gtk_drawer_scan', 'defaults': [ 'openpaperwork_gtk.drawer.scan', 'paperwork_gtk.drawer.calibration', ], }, # Optional: # { # 'interface': 'gtk_zoomable', # 'defaults': [ # 'paperwork_gtk.gesture.zoom', # 'paperwork_gtk.keyboard_shortcut.zoom', # ], # }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_settings_dialog', 'defaults': ['paperwork_gtk.settings'], }, { 'interface': 'gtk_settings_scanner', 'defaults': ['paperwork_gtk.settings.scanner.settings'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def complete_settings(self, settings_widget_tree): self.settings_widget_tree = settings_widget_tree self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "calibration.glade" ) self.size_allocate_connect_id = self.widget_tree.get_object( "calibration_scroll" ).connect( "size-allocate", self._update_calibration_scroll_area_size ) self.value_changed_connect_id = self.widget_tree.get_object( "calibration_scale_adjustment" ).connect( "value-changed", self._update_calibration_area_size_based_on_scale ) self.widget_tree.get_object("calibration_back").connect( "clicked", self.hide_calibration_screen ) self.widget_tree.get_object("calibration_scan").connect( "clicked", self._start_scan ) self.widget_tree.get_object("calibration_maximize").connect( "clicked", self._on_maximize ) self.widget_tree.get_object("calibration_automatic").connect( "clicked", self._guess_scan_borders ) drawing_area = self.widget_tree.get_object("calibration_area") self.core.call_all("draw_scan_start", drawing_area) self.core.call_all( "add_setting_screen", settings_widget_tree, "calibration", self.widget_tree.get_object("calibration_header"), self.widget_tree.get_object("calibration_body"), ) def complete_scanner_settings( self, settings_widget_tree, parent_widget_tree, list_scanner_promise): assert self.widget_tree is not None def set_sensitive(): dev_id = self.core.call_success("config_get", "scanner_dev_id") parent_widget_tree.get_object("scanner_calibration").set_sensitive( True if dev_id is not None and dev_id != "" else False ) set_sensitive() self.core.call_all( "config_add_observer", "scanner_dev_id", set_sensitive ) parent_widget_tree.get_object("scanner_calibration").connect( "clicked", self.display_calibration_screen, settings_widget_tree ) def on_settings_closed(self, settings_widget_tree): drawing_area = self.widget_tree.get_object("calibration_area") self.core.call_all("draw_scan_stop", drawing_area) if self.value_changed_connect_id is not None: drawing_area.disconnect(self.value_changed_connect_id) self.value_changed_connect_id = None if self.size_allocate_connect_id is not None: self.widget_tree.get_object("calibration_scroll").disconnect( self.size_allocate_connect_id ) self.size_allocate_connect_id = None def display_calibration_screen(self, *args, **kwargs): LOGGER.info("Switching to calibration screen") self.core.call_all( "show_setting_screen", self.settings_widget_tree, "calibration" ) sources = self.widget_tree.get_object("calibration_sources") sources.clear() sources.append(("", _("Loading ..."))) combobox = self.widget_tree.get_object("calibration_source") combobox.set_active(0) combobox.set_sensitive(False) buttons = [ 'calibration_automatic', 'calibration_maximize', 'calibration_scan', ] for button in buttons: self.widget_tree.get_object(button).set_sensitive(False) self.core.call_all( "on_zoomable_widget_new", self.widget_tree.get_object("calibration_scroll"), self.widget_tree.get_object("calibration_scale_adjustment") ) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_busy",) ) promise = promise.then( # drop the return value of call_all() lambda *args, **kwargs: None ) promise = promise.then(self.core.call_success( "scan_get_scanner_promise" )) promise = promise.then(self._show_sources) promise = promise.then(openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_idle",) )) self.core.call_success("scan_schedule", promise) def _show_sources(self, dev=None): sources = [] if dev is not None: sources = [ ( source.get_name(), self.core.call_success( "i18n_scanner_source", source.get_name() ), ) for source in dev.dev.get_children() ] LOGGER.info("Found %d sources", len(sources)) sources_widget = self.widget_tree.get_object("calibration_sources") sources_widget.clear() for src in sources: LOGGER.info("Source: %s ; %s", src[0], src[1]) sources_widget.append(src) combobox = self.widget_tree.get_object("calibration_source") combobox.set_active(0) combobox.set_sensitive(True) self.widget_tree.get_object("calibration_scan").set_sensitive(True) def hide_calibration_screen(self, *args, **kwargs): LOGGER.info("Switching back to settings") self.core.call_all( "show_setting_screen", self.settings_widget_tree, "main" ) self.core.call_all( "on_zoomable_widget_destroy", self.widget_tree.get_object("calibration_area"), self.widget_tree.get_object("calibration_scale_adjustment") ) def _start_scan(self, button): combobox = self.widget_tree.get_object("calibration_source") source_idx = combobox.get_active() sources = self.widget_tree.get_object("calibration_sources") source = sources[source_idx][0] LOGGER.info("Starting calibration scan on %s ...", source) promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_busy",) ) promise = promise.then( # drop the return value of call_all() lambda *args, **kwargs: None ) # calibration is always done at 75 DPI promise = promise.then( self.core.call_success( "scan_promise", source_id=source, resolution=75 )[1] ) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self._scan )) promise = promise.then(self._on_scan_end) promise = promise.then(openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_idle",) )) self.core.call_success("scan_schedule", promise) self.widget_tree.get_object("calibration_scan").set_sensitive(False) def _scan(self, args): (source, scan_id, img_generator) = args # just unroll the image generator. # --> we catch the content using the the on_scan_XXXX callbacks. img = None for (idx, img) in enumerate(img_generator): LOGGER.info("Page %d scanned: %s", idx, img.size) return img def on_scan_page_start(self, scan_id, page_nb, scan_params): (self.scan_width, self.scan_height) = ( paperwork_backend.cairo.pillow.limit_img_size(( scan_params.get_width(), scan_params.get_height(), )) ) if self.widget_tree is None: return self._update_calibration_area_size_based_on_scroll() self._update_calibration_scroll_area_size() def _update_calibration_area_size_based_on_scroll(self, *args, **kwargs): scroll = self.widget_tree.get_object("calibration_scroll") widget_height = scroll.get_allocated_height() factor = widget_height / self.scan_height self.widget_tree.get_object("calibration_scale_adjustment").set_value( factor ) # signal 'value-changed' will trigger the update and redraw self.widget_tree.get_object("calibration_scale_adjustment").set_lower( factor ) def _update_calibration_area_size_based_on_scale(self, *args, **kwargs): adj = self.widget_tree.get_object( "calibration_scale_adjustment" ) factor = adj.get_value() LOGGER.debug( "Scale: %f < %f < %f", adj.get_lower(), factor, adj.get_upper() ) widget_width = int(self.scan_width * factor) widget_height = int(self.scan_width * factor) LOGGER.debug( "Calibratrion widget size: (%d, %d)", widget_width, widget_height ) self.widget_tree.get_object("calibration_area").set_size_request( widget_width, widget_height ) self.widget_width = widget_width def _update_calibration_scroll_area_size(self, *args, **kwargs): # scroll area must have the same proportion than the scanned image scroll = self.widget_tree.get_object("calibration_scroll") widget_height = scroll.get_allocated_height() if self.scan_height <= 0: ratio = 1.0 / 1.414 else: ratio = self.scan_width / self.scan_height widget_width = max(widget_height * ratio, 300) LOGGER.debug( "Calibration scroll window size: (%d, %d)", widget_width, widget_height ) scroll.set_size_request(widget_width, -1) if self.scan_height > 0: factor = widget_height / self.scan_height adj = self.widget_tree.get_object("calibration_scale_adjustment") if adj.get_value() < factor: adj.set_value(factor) adj.set_lower(factor) def _on_scan_end(self, scan_img=None): if self.widget_tree is not None: buttons = [ 'calibration_automatic', 'calibration_maximize', 'calibration_scan' ] for button in buttons: self.widget_tree.get_object(button).set_sensitive(True) drawing_area = self.widget_tree.get_object("calibration_area") self.core.call_all("draw_scan_stop", drawing_area) if scan_img is None: LOGGER.info("No page scanned. Can't do calibration") return (self.scan_width, self.scan_height) = ( paperwork_backend.cairo.pillow.limit_img_size(scan_img.size) ) self.scan_img = scan_img LOGGER.info("Calibration scan ready") if self.core.call_success("config_get", "scanner_calibration") is None: # Put the frame a little bit inside the image to make the # corner handles more visible calibration = [ min(50, self.scan_width), min(50, self.scan_height), max(self.scan_width - 50, 0), max(self.scan_height - 50, 0), ] LOGGER.info("Setting default calibration area: %s", calibration) self.core.call_all( "config_put", "scanner_calibration", calibration ) self.core.call_all("draw_pillow_start", drawing_area, scan_img) self.core.call_all( "draw_calibration_start", drawing_area, (self.scan_width, self.scan_height) ) def _on_maximize(self, button): if self.scan_height <= 0 or self.scan_width <= 0: return self.core.call_all( "config_put", "scanner_calibration", [0, 0, self.scan_width, self.scan_height] ) def _guess_scan_borders(self, button=None): if self.scan_img is None: return LOGGER.info("Guessing scan borders") def find_scan_borders(scan_img): frame = pillowfight.find_scan_borders(scan_img) return frame promise = openpaperwork_core.promise.Promise( self.core, self.core.call_all, args=("on_busy",) ) promise = promise.then(lambda *args, **kwargs: self.scan_img) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, find_scan_borders )) promise = promise.then( lambda frame: self.core.call_all( "config_put", "scanner_calibration", list(frame) ) ) promise = promise.then(lambda *args, **kwargs: None) promise = promise.then(self.core.call_all, "on_idle") promise.schedule() def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return if self.settings_widget_tree is None: return body = self.widget_tree.get_object("calibration_body") if body is None: return self.core.call_success( "screenshot_snap_widget", body, self.core.call_success( "fs_join", out_dir, "settings_calibration_dialog.png" ), margins=(100, 100, 100, 100) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/dev_id_popover.py000066400000000000000000000057661456262201400306610ustar00rootroot00000000000000import logging import openpaperwork_core from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'gtk_settings_scanner_setting', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_settings_scanner', 'defaults': ['paperwork_gtk.settings.scanner.settings'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, ] def complete_scanner_settings( self, global_widget_tree, parent_widget_tree, list_scanner_promise): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "popover.glade" ) widget_tree.get_object("settings_stack").set_visible_child_name( "spinner" ) widget_tree.get_object("spinner").start() parent_widget_tree.get_object("scanner_device").set_popover( widget_tree.get_object("selector") ) list_scanner_promise.then(self._on_scanner_list, widget_tree) def _on_scanner_list(self, devs, widget_tree): widget_tree.get_object("spinner").stop() widget_tree.get_object("settings_stack").set_visible_child_name( "selector" ) box = widget_tree.get_object("selector_box") radios = [] # because of the way radio buttons work, we need always at least # one choice --> add "no scanner" for dev in ([(None, _("No scanner"))] + devs): radio = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "popover_box.glade" ) radio = radio.get_object("radio") radio.set_label(dev[1]) box.pack_start(radio, expand=False, fill=True, padding=0) radios.append((dev[0], radio)) for (dev_id, radio) in radios[1:]: radio.join_group(radios[0][1]) active = self.core.call_success("config_get", "scanner_dev_id") for (dev_id, radio) in radios: if active == dev_id: radio.set_active(True) break for (dev_id, radio) in radios: radio.connect( "toggled", self._on_toggle, widget_tree, dev_id, radio.get_label() ) def _on_toggle( self, checkbox, widget_tree, dev_id, dev_name): LOGGER.info("Selected scanner: %s - %s", dev_id, dev_name) widget_tree.get_object("selector").popdown() self.core.call_success("config_put", "scanner_dev_id", dev_id) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.glade000066400000000000000000000122101456262201400277010ustar00rootroot00000000000000 True True preferences-system-details-symbolic True True True image_flatpak_info True Flatpak 500 300 dialog True True vertical 10 True True end gtk-close True True True True True True 0 False False 3 True True 20 20 20 20 You are using Paperwork from a Flatpak container. Paperwork needs Saned to access your scanners. Important: the following procedure will only work for local (non-network) scanners ! To enable Saned on the host system, you must copy and paste the following commands in a terminal: True False True 0 True True 0 True True True False False 1 True True in True True False word textbuffer_instructions True True 2 buttonOk paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/flatpak.py000066400000000000000000000066531456262201400272730ustar00rootroot00000000000000import openpaperwork_core INSTRUCTIONS = { # 'Arch Linux / Manjaro / …': ( # "# TODO\n" # ), 'Debian / Ubuntu / Mint / …': ( "sudo apt install sane-utils\n" "sudo sh -c \"echo 127.0.0.1 >> /etc/sane.d/saned.conf\"\n" "sudo systemctl enable saned.socket\n" "sudo systemctl start saned.socket\n" "sudo adduser saned plugdev\n" "sudo adduser saned scanner\n" "sudo adduser saned lp\n" "# reboot\n" "\n" "# If your scanner is still not recognized, please check\n" "# https://gitlab.gnome.org/World/OpenPaperwork/paperwork/-/blob" "/develop/doc/install.flatpak.markdown#faq\n" ), 'Fedora / CentOS / RHEL / …': ( "sudo dnf install libinsane sane-backends-daemon\n" "sudo sh -c \"echo 127.0.0.1 >> /etc/sane.d/saned.conf\"\n" "sudo systemctl enable saned.socket\n" "sudo systemctl start saned.socket\n" ), } class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.windows = [] def get_interfaces(self): return [ 'gtk_settings_scanner_flatpak', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'flatpak', 'defaults': ['openpaperwork_core.flatpak'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_settings_scanner', 'defaults': ['paperwork_gtk.settings.scanner.settings'], }, ] def settings_scanner_get_extra_widget(self): if not self.core.call_success("is_in_flatpak"): return None widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "flatpak.glade" ) if widget_tree is None: return None button = widget_tree.get_object("button_flatpak_info") button.connect("clicked", self._on_clicked) return button def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _on_clicked(self, button): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "flatpak.glade" ) if widget_tree is None: return dialog = widget_tree.get_object("flatpak_info_dialog") dialog.set_transient_for(self.windows[-1]) dialog.set_modal(True) dialog.connect("response", self._on_close) dialog.connect("destroy", self._on_close) dialog.set_visible(True) selector = widget_tree.get_object("flatpak_info_selector") for k in sorted(INSTRUCTIONS.keys()): selector.append_text(k) selector.connect("changed", self._on_changed, widget_tree) selector.set_active(0) self._on_changed(selector, widget_tree) def _on_changed(self, selector, widget_tree): selected = selector.get_active_text() instruction = INSTRUCTIONS[selected] txt_buffer = widget_tree.get_object("textbuffer_instructions") txt_buffer.set_text(instruction) def _on_close(self, dialog, *args, **kwargs): dialog.set_visible(False) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/mode_popover.py000066400000000000000000000047321456262201400303430ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): RECOMMENDED = 300 MODES = [ ('radioColor', 'Color'), ('radioGrayscale', 'Gray'), ('radioLineart', 'Lineart'), ] def get_interfaces(self): return [ 'gtk_settings_scanner_setting', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_settings_scanner', 'defaults': ['paperwork_gtk.settings.scanner.settings'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, ] def complete_scanner_settings( self, global_widget_tree, parent_widget_tree, list_scanner_promise): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "popover_mode.glade" ) active = self.core.call_success("config_get", "scanner_mode") for (widget, mode) in self.MODES: if mode == active: widget_tree.get_object(widget).set_active(True) for (widget, mode) in self.MODES: widget_tree.get_object(widget).connect( "toggled", self._on_toggle, widget_tree, mode ) selector = widget_tree.get_object("selector") # WORKAROUND(Jflesch): set_sensitive() doesn't appear to work on # GtkMenuButton --> we have to play with set_popover() def reset_popover(): dev_id = self.core.call_success("config_get", "scanner_dev_id") parent_widget_tree.get_object("scanner_mode").set_popover( selector if dev_id is not None and dev_id != "" else None ) reset_popover() self.core.call_all( "config_add_observer", "scanner_dev_id", reset_popover ) def _on_toggle(self, checkbox, widget_tree, mode): LOGGER.info("Selected mode: %s", mode) widget_tree.get_object("selector").popdown() self.core.call_success("config_put", "scanner_mode", mode) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/popover.glade000066400000000000000000000040371456262201400277610ustar00rootroot00000000000000 False 225 300 False True never False True True False True False 64 64 spinner True False vertical 18 selector paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_box.glade000066400000000000000000000004721456262201400306300ustar00rootroot00000000000000 True False paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/popover_mode.glade000066400000000000000000000050161456262201400307630ustar00rootroot00000000000000 False True False vertical 18 Color True False True True True False True 0 Grayscale True True False True radioColor False True 1 Black & White True True False True radioColor False True 2 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/resolution_popover.py000066400000000000000000000123461456262201400316220ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.promise from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): RECOMMENDED = 300 def get_interfaces(self): return [ 'gtk_settings_scanner_setting', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'gtk_settings_scanner', 'defaults': ['paperwork_gtk.settings.scanner.settings'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, ] def complete_scanner_settings( self, global_widget_tree, parent_widget_tree, list_scanner_promise): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "popover.glade" ) selector = widget_tree.get_object("selector") # WORKAROUND(Jflesch): set_sensitive() doesn't appear to work on # GtkMenuButton --> we have to play with set_popover() def reset_popover(): dev_id = self.core.call_success("config_get", "scanner_dev_id") parent_widget_tree.get_object("scanner_resolution").set_popover( selector if dev_id is not None and dev_id != "" else None ) reset_popover() self.core.call_all( "config_add_observer", "scanner_dev_id", reset_popover ) selector.connect("show", self._on_show, widget_tree) def _on_show(self, popover, widget_tree): LOGGER.info("Scanner resolution selector is visible") widget_tree.get_object("settings_stack").set_visible_child_name( "spinner" ) widget_tree.get_object("spinner").start() box = widget_tree.get_object("selector_box") for child in box.get_children(): box.remove(child) dev_id = self.core.call_success("config_get", "scanner_dev_id") if dev_id is None: # TODO(Jflesch): better display self._display_resolutions([], widget_tree) return promise = self.core.call_success("scan_get_scanner_promise", dev_id) promise = promise.then(openpaperwork_core.promise.ThreadedPromise( self.core, self._collect_resolutions )) promise = promise.then(self._display_resolutions, widget_tree) promise = promise.catch(self._on_error, widget_tree) self.core.call_success("scan_schedule", promise) def _collect_resolutions(self, dev): resolutions = set() try: children = dev.dev.get_children() for child in children: opts = {o.get_name(): o for o in child.get_options()} if 'resolution' not in opts: continue constraint = opts['resolution'].get_constraint() resolutions.update(constraint) finally: dev.close() LOGGER.info("Got resolutions: %s", resolutions) resolutions = list(resolutions) resolutions.sort() return resolutions def _display_resolutions(self, resolutions, widget_tree): widget_tree.get_object("spinner").stop() widget_tree.get_object("settings_stack").set_visible_child_name( "selector" ) box = widget_tree.get_object("selector_box") radios = [] for resolution in resolutions: radio = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "popover_box.glade" ) radio = radio.get_object("radio") if resolution != self.RECOMMENDED: radio.set_label(_("{} dpi").format(resolution)) else: radio.set_label(_("{} dpi (recommended)").format(resolution)) box.pack_start(radio, expand=False, fill=True, padding=0) radios.append((resolution, radio)) for (resolution, radio) in radios[1:]: radio.join_group(radios[0][1]) active = self.core.call_success("config_get", "scanner_resolution") for (resolution, radio) in radios: if active == resolution: radio.set_active(True) for (resolution, radio) in radios: radio.connect( "toggled", self._on_toggle, widget_tree, resolution ) def _on_toggle(self, checkbox, widget_tree, resolution): LOGGER.info("Selected resolution: %d", resolution) widget_tree.get_object("selector").popdown() self.core.call_success("config_put", "scanner_resolution", resolution) def _on_error(self, exc, widget_tree): LOGGER.error("Fail to get scanner resolutions", exc_info=exc) # TODO(Jflesch): better display widget_tree.get_object("spinner").stop() widget_tree.get_object("settings_stack").set_visible_child_name( "selector" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.glade000066400000000000000000000145311456262201400301270ustar00rootroot00000000000000 True none True False 16 True False Device 0 True True 0 True False xxxx 1.0 True True 1 True none True False 16 True False Resolution 0 True True 0 True False xxxx 1.0 True True 1 True none True False 16 True False Mode 0 True True 0 True False xxxx 1.0 True True 1 True none True False 16 True False Calibration 0 True True 0 True False Re-calibrate 1.0 True True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/scanner/settings.py000066400000000000000000000137241456262201400275060ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps from ... import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -400 MODES = { 'Color': _("Color"), 'Gray': _("Grayscale"), 'Lineart': _("Black & White"), } def __init__(self): super().__init__() self.widget_tree = None self.extra_widget = None self.config = [] def get_interfaces(self): return [ 'gtk_settings_scanner', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'l10n_init', 'defaults': ['paperwork_gtk.l10n'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def init(self, core): super().init(core) self.config = [ ( 'settings_scanner_name', 'scanner_device_value', _("No scanner selected"), "{}".format ), ( 'scanner_resolution', 'scanner_resolution_value', _("No resolution selected"), _("{} dpi").format ), ( 'scanner_mode', 'scanner_mode_value', _("No mode selected"), self._translate_mode ), ] opt = self.core.call_success( "config_build_simple", "settings_scanner", "name", lambda: self.core.call_success("config_get", "scanner_dev_id") ) self.core.call_all("config_register", "settings_scanner_name", opt) self.core.call_all( "config_add_observer", "scanner_dev_id", self._update_scanner_name ) def _update_scanner_name(self): def set_scanner_name(devs): active = self.core.call_success("config_get", "scanner_dev_id") for dev in devs: dev_id = dev[0] dev_name = dev[1] if dev_id == active: self.core.call_success( "config_put", "settings_scanner_name", dev_name ) break return devs promise = self.core.call_success("scan_list_scanners_promise") promise = promise.then(set_scanner_name) self.core.call_success("scan_schedule", promise) def complete_settings(self, global_widget_tree): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings.scanner", "settings.glade" ) self.widget_tree = widget_tree extra_widget = self.core.call_success( "settings_scanner_get_extra_widget" ) self.core.call_success( "add_setting_to_dialog", global_widget_tree, _("Scanner"), [ widget_tree.get_object("scanner_device"), widget_tree.get_object("scanner_resolution"), widget_tree.get_object("scanner_mode"), widget_tree.get_object("scanner_calibration"), ], extra_widget=extra_widget ) def refresh(*args, **kwargs): self._refresh_settings(widget_tree) def disable_refresh(*args, **kwargs): for c in self.config: self.core.call_all("config_remove_observer", c[0], refresh) for c in self.config: self.core.call_all("config_add_observer", c[0], refresh) global_widget_tree.get_object("settings_window").connect( "destroy", disable_refresh ) self._refresh_settings(widget_tree) list_scanners_promise = self.core.call_success( "scan_list_scanners_promise" ) self.core.call_all( "complete_scanner_settings", global_widget_tree, widget_tree, list_scanners_promise ) self.core.call_success("scan_schedule", list_scanners_promise) def _translate_mode(self, mode): if mode in self.MODES: return self.MODES[mode] return mode def _refresh_settings(self, widget_tree): for (config_key, widget_name, default_value, fmt) in self.config: value = self.core.call_success("config_get", config_key) if value is not None: value = fmt(value) else: value = default_value widget_tree.get_object(widget_name).set_text(value) active = self.core.call_success("config_get", "scanner_dev_id") active = active is not None and active != "" buttons = [ 'scanner_resolution', 'scanner_mode', 'scanner_calibration', ] for button in buttons: # WORKAROUND(Jflesch): set_sensitive() doesn't appear to work on # GtkMenuButton widget_tree.get_object(button).set_sensitive(active) def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return buttons = [ "scanner_device", "scanner_resolution", "scanner_mode", "scanner_calibration", ] for button_name in buttons: button = self.widget_tree.get_object(button_name) self.core.call_success( "screenshot_snap_widget", button, self.core.call_success( "fs_join", out_dir, "settings_{}.png".format(button_name) ), margins=(100, 100, 100, 100) ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/settings.css000066400000000000000000000011231456262201400262030ustar00rootroot00000000000000.section_box > * { border: 1px solid @borders; padding: 16px; border-radius: 0px; border-bottom: 0px solid @borders; border-top: 1px solid @unfocused_borders; background-color: @theme_base_color; } .section_box > *:disabled { background-color: @insensitive_bg_color; } .section_box > :first-child { border-radius: 5px 5px 0px 0px; border-top: 1px solid @borders; } .section_box > :last-child { border-bottom: 1px solid @borders; border-radius: 0px 0px 5px 5px; } .section_box > :first-child:last-child { border-radius: 5px 5px 5px 5px; } .settings_name { } .settings_value { } paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/settings.glade000066400000000000000000000052121456262201400264720ustar00rootroot00000000000000 False 600 600 True False True False Settings True main True False True True never in True False 400 True False 100 100 50 50 vertical 50 main paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/settings_section.glade000066400000000000000000000036471456262201400302300ustar00rootroot00000000000000 True False vertical 16 True False True False Section title 0 True True 0 False True 0 True False vertical True True True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/stats.glade000066400000000000000000000160311456262201400257710ustar00rootroot00000000000000 True False vertical True False 16 True False Send metrics <span foreground="gray">Give us clues about how you use Paperwork</span> True True 0 True True 0 True False vertical True False True True 0 True True True none True False preferences-system-details-symbolic False True 1 True False True True 2 False True 1 True False False True 2 True False vertical True False True True 0 True True False True 1 True False True True 2 False True 3 False True 0 True <span foreground="gray">Those clues will help us to make Paperwork an even better piece of software, for you. Statistics also show us that people are actually using our work, keeping us motivated to improve it. Here are the data we gather: - Hardware: CPU, RAM, screen resolution. - Software: Version of Paperwork, Operating system, desktop environment, system language. - Data metrics: number of documents, maximum and average number of pages, number of labels. - Number of times you used each feature. We do not collect document content nor any other sensitive or personal information. Still we think it's fair to request your authorization ;-). Collected statistics are visible on <a href="https://openpaper.work/paperwork/statistics">openpaper.work</a>. </span> True True 0 False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/stats.py000066400000000000000000000037201456262201400253460ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -1000 def __init__(self): super().__init__() def get_interfaces(self): return [ 'gtk_settings', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'stats_post', 'defaults': ['openpaperwork_core.beacon.stats'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def init(self, core): super().init(core) def complete_settings(self, global_widget_tree): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings", "stats.glade" ) active = self.core.call_success("config_get", "send_statistics") LOGGER.info("Statistics state: %s", active) button = widget_tree.get_object("stats_state") button.set_active(active) button.connect("notify::active", self._on_stats_state_changed) button = widget_tree.get_object("stats_infos") details = widget_tree.get_object("stats_details") button.connect("clicked", self._on_info_button, details) self.core.call_success( "add_setting_to_dialog", global_widget_tree, _("Help Improve Paperwork"), [widget_tree.get_object("stats")] ) def _on_info_button(self, info_button, details): details.set_visible(not details.get_visible()) def _on_stats_state_changed(self, switch, _): state = switch.get_active() LOGGER.info("Setting stats state to %s", state) self.core.call_all("config_put", "send_statistics", state) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/storage.glade000066400000000000000000000130651456262201400263030ustar00rootroot00000000000000 True False folder-symbolic True False 16 True True False Work directory 0 True True 0 some_work_directory True False False image_button True False True 1 True False preferences-system-details-symbolic True True True image_workdir_info False Work directory 500 300 dialog True False vertical True False gtk-close True True True True False False 0 False False 1 True True in True False True True <b>Do not use an already existing directory !</b> (unless it comes from another Paperwork instance) Paperwork uses a custom file structure to store documents. Unless the directory you specify has the exact file structure expected by Paperwork, it won't work ! If you want to build a new work directory from existing documents, please use the import feature instead. <a href="https://gitlab.gnome.org/World/OpenPaperwork/paperwork/-/wikis/Work-directory-organization">[More information]</a> True True True True 0 buttonOk paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/storage.py000066400000000000000000000135561456262201400256640ustar00rootroot00000000000000import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000000 def __init__(self): super().__init__() self.windows = [] def get_interfaces(self): return [ 'chkdeps', 'gtk_settings', 'gtk_window_listener', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_gtk.fs.gio'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'work_queue', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) self.workdir = self.core.call_success("config_get", "workdir") def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def _show_workdir_info(self, *args, **kwargs): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings", "storage.glade" ) dialog = widget_tree.get_object("workdir_info_dialog") dialog.set_transient_for(self.windows[-1]) dialog.set_modal(True) dialog.connect("response", self._on_workdir_info_dialog_closed) dialog.connect("destroy", self._on_workdir_info_dialog_closed) dialog.set_visible(True) def _on_workdir_info_dialog_closed(self, dialog, *args, **kwargs): dialog.set_visible(False) def complete_settings(self, global_widget_tree): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings", "storage.glade" ) workdir_button = widget_tree.get_object("work_dir_chooser_button") basename = self.core.call_success("fs_basename", self.workdir) workdir_button.set_label(basename) workdir_button.connect("clicked", self._on_button_clicked, widget_tree) workdir_info_button = widget_tree.get_object("button_workdir_info") workdir_info_button.connect("clicked", self._show_workdir_info) self.core.call_success( "add_setting_to_dialog", global_widget_tree, _("Storage"), [widget_tree.get_object("workdir")], extra_widget=workdir_info_button, ) def _on_button_clicked(self, button, widget_tree): dialog = Gtk.FileChooserDialog( _("Work Directory"), self.windows[-1], Gtk.FileChooserAction.SELECT_FOLDER, ( Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL, Gtk.STOCK_OPEN, Gtk.ResponseType.ACCEPT ) ) dialog.set_modal(True) dialog.set_local_only(False) workdir = self.core.call_success("config_get", "workdir") if self.core.call_success("fs_exists", workdir): dialog.set_uri(workdir) dialog.connect("response", self._on_file_dialog_response, widget_tree) dialog.show_all() def _on_file_dialog_response(self, dialog, response_id, widget_tree): if (response_id != Gtk.ResponseType.ACCEPT and response_id != Gtk.ResponseType.OK and response_id != Gtk.ResponseType.YES and response_id != Gtk.ResponseType.APPLY): LOGGER.info("User canceled (response_id=%d)", response_id) dialog.destroy() return workdir = dialog.get_uri() dialog.set_visible(False) LOGGER.info("Setting work directory to %s", workdir) self.core.call_all("config_put", "workdir", workdir) # Bug report 170: Make sure the current document (in the old work # directory) is closed so the user cannot use it by accident anymore self.core.call_all("doc_close") basename = self.core.call_success("fs_basename", workdir) widget_tree.get_object("work_dir_chooser_button").set_label(basename) # Basic check of work directory content to avoid common mistake. # We do not prevent the user from selecting the folder. We just # warn them. workdir_content = self.core.call_success("fs_listdir", workdir) show_info_dialog = False for file_url in workdir_content: file_name = self.core.call_success("fs_basename", file_url) if file_name[0] == ".": continue if "." in file_name: # assume it's a file ; anyway, it doesn't have the usual # name format that Paperwork folders have LOGGER.warning( "Suspect file name found in work directory: %s", file_name ) show_info_dialog = True break if show_info_dialog: self._show_workdir_info() def config_save(self): workdir = self.core.call_success("config_get", "workdir") if workdir != self.workdir: LOGGER.info("Work directory has been changed --> Synchronizing") self.core.call_all("transaction_sync_all") self.workdir = workdir paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/update.glade000066400000000000000000000147121456262201400261210ustar00rootroot00000000000000 True False vertical True False 16 True False Updates <span foreground="gray">Check periodically for new versions of Paperwork</span> True True 0 True True 0 True False vertical True False True True 0 True True True none True False preferences-system-details-symbolic False True 1 True False True True 2 False True 1 True False False True 2 True False vertical True False True True 0 True True False True 1 True False True True 2 False True 3 False True 0 True <span foreground="gray">Look about once a week for new versions of Paperwork. You will be notified when a new version is available but it won't be installed automatically. </span> True True 0 False True 1 paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/settings/update.py000066400000000000000000000037311456262201400254740ustar00rootroot00000000000000import logging import openpaperwork_core import openpaperwork_core.deps from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): PRIORITY = -750 def __init__(self): super().__init__() def get_interfaces(self): return [ 'gtk_settings', ] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'update_detection', 'defaults': ['paperwork_backend.beacon.update'], }, { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, ] def init(self, core): super().init(core) def complete_settings(self, global_widget_tree): widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.settings", "update.glade" ) active = self.core.call_success("config_get", "check_for_update") LOGGER.info("Updates check: %s", active) button = widget_tree.get_object("updates_state") button.set_active(active) button.connect("notify::active", self._on_updates_state_changed) button = widget_tree.get_object("updates_infos") details = widget_tree.get_object("updates_details") button.connect("clicked", self._on_info_button, details) self.core.call_success( "add_setting_to_dialog", global_widget_tree, _("Updates"), [widget_tree.get_object("updates")] ) def _on_info_button(self, info_button, details): details.set_visible(not details.get_visible()) def _on_updates_state_changed(self, switch, _): state = switch.get_active() LOGGER.info("Setting update check state to %s", state) self.core.call_all("config_put", "check_for_update", state) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/000077500000000000000000000000001456262201400240325ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/__init__.py000066400000000000000000000000001456262201400261310ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/app/000077500000000000000000000000001456262201400246125ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/app/__init__.py000066400000000000000000000000001456262201400267110ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/app/find.py000066400000000000000000000022431456262201400261050ustar00rootroot00000000000000import openpaperwork_core from ... import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_app', 'shortcuts_app_find', ] def get_deps(self): return [ { 'interface': 'action_app_find', 'defaults': ['paperwork_gtk.actions.app.find'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", _("Global"), _("Find"), "f", "win.app_find" ) # TODO # self.core.call_all( # "app_shortcut_add", # _("Global"), _("Find the next match"), # "G", "win.app_find_next" # ) # self.core.call_all( # "app_shortcut_add", # _("Global"), _("Find the previous match"), # "G", "win.app_find_prev" # ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/doc/000077500000000000000000000000001456262201400245775ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/doc/__init__.py000066400000000000000000000000001456262201400266760ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/doc/new.py000066400000000000000000000014671456262201400257520ustar00rootroot00000000000000import openpaperwork_core from ... import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_doc', 'shortcuts_doc_copy_text', ] def get_deps(self): return [ { 'interface': 'action_doc_new', 'defaults': ['paperwork_gtk.actions.doc.new'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", _("Global"), _("Create new document"), "N", "win.doc_new" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/doc/prev_next.py000066400000000000000000000020041456262201400271570ustar00rootroot00000000000000import openpaperwork_core from ... import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_doc', 'shortcuts_doc_prev_next', ] def get_deps(self): return [ { 'interface': 'action_doc_prev_next', 'defaults': ['paperwork_gtk.actions.doc.prev_next'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", _("Document list"), _("Open next document"), "Page_Down", "win.doc_next" ) self.core.call_all( "app_shortcut_add", _("Document list"), _("Open previous document"), "Page_Up", "win.doc_prev" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/doc/print.py000066400000000000000000000014551456262201400263120ustar00rootroot00000000000000import openpaperwork_core from ... import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_doc', 'shortcuts_doc_print', ] def get_deps(self): return [ { 'interface': 'action_doc_print', 'defaults': ['paperwork_gtk.actions.doc.print'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", _("Document"), _("Print"), "P", "win.doc_print" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/doc/properties.py000066400000000000000000000015241456262201400273470ustar00rootroot00000000000000import openpaperwork_core from ... import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_doc', 'shortcuts_doc_properties', ] def get_deps(self): return [ { 'interface': 'action_doc_properties', 'defaults': ['paperwork_gtk.actions.doc.properties'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", _("Document"), _("Edit document properties"), "e", "win.doc_properties" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/page/000077500000000000000000000000001456262201400247465ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/page/__init__.py000066400000000000000000000000001456262201400270450ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/page/copy_text.py000066400000000000000000000017301456262201400273370ustar00rootroot00000000000000import gettext import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_page', 'shortcuts_page_copy_text', ] def get_deps(self): return [ { 'interface': 'action_page_copy_text', 'defaults': ['paperwork_gtk.actions.page.copy_text'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", gettext.pgettext("keyboard shortcut categories", "Page"), gettext.pgettext( "keyboard shortcut names", "Copy selected text to clipboard" ), "c", "win.page_copy_text" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcuts/page/edit.py000066400000000000000000000016221456262201400262460ustar00rootroot00000000000000import gettext import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'shortcuts', 'shortcuts_page', 'shortcuts_page_edit', ] def get_deps(self): return [ { 'interface': 'action_page_edit', 'defaults': ['paperwork_gtk.actions.page.edit'], }, { 'interface': 'app_shortcuts', 'defaults': ['paperwork_gtk.mainwindow.window'], }, ] def init(self, core): super().init(core) def on_gtk_initialized(self): self.core.call_all( "app_shortcut_add", gettext.pgettext("keyboard shortcut categories", "Page"), gettext.pgettext("keyboard shortcut names", "Edit"), "e", "win.page_edit" ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcutswin/000077500000000000000000000000001456262201400245505ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcutswin/__init__.py000066400000000000000000000070601456262201400266640ustar00rootroot00000000000000import collections import logging try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.windows = [] self.groups = collections.defaultdict(list) self.widget_tree = None def get_interfaces(self): return [ 'app_shortcuts', 'chkdeps', 'gtk_shortcut_help', 'gtk_window_listener', 'screenshot_provider', ] def get_deps(self): return [ { 'interface': 'gtk_resources', 'defaults': ['openpaperwork_gtk.resources'], }, { 'interface': 'screenshot', 'defaults': ['openpaperwork_gtk.screenshots'], }, ] def chkdeps(self, out: dict): if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def on_gtk_window_opened(self, window): self.windows.append(window) def on_gtk_window_closed(self, window): self.windows.remove(window) def app_shortcut_add( self, shortcut_group, shortcut_desc, shortcut_keys, action_name): self.shortcut_help_add( shortcut_group, shortcut_desc, shortcut_keys, action_name ) def shortcut_help_add( self, shortcut_group, shortcut_desc, shortcut_keys, action_name): LOGGER.info( "Keyboard shortcut: %s --> %s:%s", shortcut_keys, shortcut_group, shortcut_desc ) group = self.groups[shortcut_group] group.append(( shortcut_desc, shortcut_keys, action_name )) def gtk_show_shortcuts(self): LOGGER.info("Showing shortcuts") self.widget_tree = self.core.call_success( "gtk_load_widget_tree", "paperwork_gtk.shortcutswin", "shortcutswin.glade" ) section = self.widget_tree.get_object("shortcuts_mainwindow") window = self.widget_tree.get_object("shortcuts") groups = {} for shortcut_group in sorted(list(self.groups.keys())): group = Gtk.ShortcutsGroup() group.set_property("title", shortcut_group) group.set_visible(True) groups[shortcut_group] = group section.add(group) for (shortcut_group, shortcuts) in self.groups.items(): group = groups[shortcut_group] shortcuts = sorted(list(shortcuts)) for (shortcut_desc, shortcut_keys, actions_name) in shortcuts: shortcut = Gtk.ShortcutsShortcut() shortcut.set_property("accelerator", shortcut_keys) shortcut.set_property("title", shortcut_desc) shortcut.set_visible(True) group.add(shortcut) window.set_transient_for(self.windows[-1]) window.show_all() def gtk_hide_shortcuts(self): if self.widget_tree is None: return window = self.widget_tree.get_object("shortcuts") window.destroy() def screenshot_snap_all_doc_widgets(self, out_dir): if self.widget_tree is None: return self.core.call_success( "screenshot_snap_widget", self.widget_tree.get_object("shortcuts"), self.core.call_success("fs_join", out_dir, "shortcuts.png"), ) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/shortcutswin/shortcutswin.glade000066400000000000000000000010431456262201400303200ustar00rootroot00000000000000 True True shortcuts-main-window 12 Main window paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/sync_on_start.py000066400000000000000000000032611456262201400252350ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['sync_on_start'] def get_deps(self): return [ { 'interface': 'config', 'defaults': ['openpaperwork_core.config'], }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def init(self, core): super().init(core) setting = self.core.call_success( "config_build_simple", "GUI", "sync_on_start", default_value_func=lambda: True ) self.core.call_all("config_register", "sync_on_start", setting) def on_gtk_initialized(self): r = self.core.call_success("config_get", "sync_on_start") if r: LOGGER.info("Starting synchronization ...") self.core.call_all("transaction_sync_all") else: LOGGER.info( "Synchronization on start is disabled --> Just loading labels" ) promises = [] self.core.call_all("label_load_all", promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) # use transaction_schedule to make sure that document imports # are not done at the same time. self.core.call_one("transaction_schedule", promise) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/update_notification.py000066400000000000000000000032571456262201400264050ustar00rootroot00000000000000import random import openpaperwork_core from . import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'update_listener', ] def get_deps(self): return [ { 'interface': 'icon', 'defaults': ['paperwork_gtk.icon'], }, { 'interface': 'notifications', 'defaults': ['paperwork_gtk.notifications.notify'], }, { 'interface': 'update_detection', 'defaults': ['paperwork_backend.beacon.update'], }, ] def on_update_detected(self, local_version, remote_version): random_dumbnesses = [ _("Now with 10% more freedom in it !"), _("Buy it now and get a 100% discount !"), _("New features and bugs available !"), _("New taste !"), _("We replaced your old bugs with new bugs. Enjoy."), _("Smarter, Better, Stronger"), # Linus Torvalds citation, look it up :) _("It's better when it's free."), ] notification = self.core.call_success( "get_notification_builder", _("A new version of Paperwork is available: {new_version}").format( new_version=".".join([str(x) for x in remote_version]) ) ) if notification is None: return icon = self.core.call_success("icon_get_pixbuf", "paperwork", 32) notification.set_message( random.choice(random_dumbnesses) ).set_image_from_pixbuf( icon ).show() paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/widget/000077500000000000000000000000001456262201400232575ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/widget/__init__.py000066400000000000000000000000001456262201400253560ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/widget/flowlayout.py000066400000000000000000000206571456262201400260500ustar00rootroot00000000000000import collections import logging try: from gi.repository import GObject GLIB_AVAILABLE = True except (ImportError, ValueError): GLIB_AVAILABLE = False try: import gi gi.require_version('Gdk', '3.0') gi.require_version('Gtk', '3.0') from gi.repository import Gdk from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): # workaround so chkdeps can still be called class Gtk(object): class Box(object): pass class Widget(object): pass GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps LOGGER = logging.getLogger(__name__) class WidgetInfo(object): def __init__(self, widget, alignment, size=None): self.widget = widget self.alignment = alignment if size is not None: self.size = (int(size[0]), int(size[1])) else: self.size = (0, 0) self.position = (-1, -1) self.visible = False def update_widget_size(self): if self.widget is None: # test mode return self.size = ( self.widget.get_preferred_width()[0], self.widget.get_preferred_height()[0], ) def is_visible(self): if self.widget is None: # test mode return True return self.widget.get_visible() def __eq__(self, o): if self is o: return True return self.widget == o def recompute_height_for_width(widgets, width, spacing=(0, 0)): height = spacing[1] line_height = 0 line_width = 0 for widget in widgets: if not widget.is_visible(): continue if widget.size == (0, 0): widget.update_widget_size() if line_width + widget.size[0] + spacing[0] > width + 1: height += spacing[1] height += line_height line_width = 0 line_height = 0 line_width += spacing[0] line_width += widget.size[0] line_height = max(line_height, widget.size[1]) height += line_height height += spacing[1] return height def recompute_box_positions(core, widgets, width, spacing=(0, 0)): core.call_all("on_perfcheck_start", "recompute_box_positions") # build lines lines = [] line_heights = [] line = [] line_width = spacing[0] max_line_width = 0 line_height = 0 for widget in widgets: if not widget.is_visible(): continue widget.update_widget_size() if line_width + widget.size[0] + spacing[0] > width + 1: lines.append(line) line_heights.append(line_height) line = [] max_line_width = max(max_line_width, line_width) line_width = 0 line_height = 0 line.append(widget) line_width += spacing[0] line_width += widget.size[0] line_height = max(line_height, widget.size[1]) max_line_width = max(max_line_width, line_width) lines.append(line) line_heights.append(line_height) # sort widgets by alignment in each line def sort_widgets_per_alignments(widgets): out = { Gtk.Align.START: [], Gtk.Align.CENTER: [], Gtk.Align.END: [], } for widget in widgets: out[widget.alignment].append(widget) return out lines = [sort_widgets_per_alignments(line) for line in lines] # position widgets in lines height = spacing[1] for (line, line_height) in zip(lines, line_heights): nb_columns = 0 w_start = 0 w_end = width # start for widget in line[Gtk.Align.START]: nb_columns += 1 w_start += spacing[0] widget.position = (w_start, height) w_start += widget.size[0] # end line[Gtk.Align.END].reverse() for widget in line[Gtk.Align.END]: nb_columns += 1 w_end -= spacing[0] w_end -= widget.size[0] widget.position = (w_end, height) # center w_center = sum(w.size[0] for w in line[Gtk.Align.CENTER]) w_center += spacing[0] * (len(line[Gtk.Align.CENTER]) - 1) w_center = (width - w_center) / 2 w_orig = w_center for widget in line[Gtk.Align.CENTER]: nb_columns += 1 if w_center != w_orig: w_center += spacing[0] widget.position = (int(w_center), int(height)) w_center += widget.size[0] height += line_height height += spacing[1] core.call_all( "on_perfcheck_stop", "recompute_box_positions", nb_boxes=len(widgets) ) return (widgets, max_line_width, height) class CustomFlowLayout(Gtk.Box): def __init__(self, core, spacing=(0, 0)): super().__init__() self.core = core self.widgets = collections.OrderedDict() self.spacing = spacing self.vadjustment = None self.bottom_margin = 0 self.allocation = None self.set_has_window(False) self.set_redraw_on_allocate(False) self.connect("size-allocate", self._on_size_allocate) self.connect("add", self._on_add) self.connect("remove", self._on_remove) def _on_add(self, _, widget): self.recompute_layout() self.queue_resize() def _on_remove(self, _, widget): self.widgets.pop(widget) self.queue_draw() self.queue_resize() def do_forall(self, include_internals: bool, callback, callback_data=None): if not hasattr(self, 'widgets'): return widgets = self.widgets.copy() for widget in widgets: callback(widget) def add_child(self, widget, alignment): w = WidgetInfo(widget, alignment) self.widgets[widget] = w self.add(widget) def do_get_request_mode(self): return Gtk.SizeRequestMode.WIDTH_FOR_HEIGHT def do_get_preferred_width(self): nat_width = 0 for widget in self.widgets.values(): widget.update_widget_size() nat_width += widget.size[0] return (0, nat_width) def do_get_preferred_height_for_width(self, width): requested_height = recompute_height_for_width( self.widgets.values(), width, self.spacing ) requested_height += self.bottom_margin return (requested_height, requested_height) def do_get_preferred_height(self): (min_width, nat_width) = self.do_get_preferred_width() return self.do_get_preferred_height_for_width(min_width) def do_get_preferred_width_for_height(self, height): return self.do_get_preferred_width() def _on_size_allocate(self, _, allocation): self.allocation = allocation self.recompute_layout() def recompute_layout(self): if self.allocation is None: return for widget in self.widgets.values(): widget.update_widget_size() ( _, self.requested_width, self.requested_height ) = recompute_box_positions( self.core, self.widgets.values(), self.allocation.width, self.spacing ) self.requested_height += self.bottom_margin for widget in self.widgets.values(): rect = Gdk.Rectangle() rect.x = self.allocation.x + widget.position[0] rect.y = self.allocation.y + widget.position[1] rect.width = widget.size[0] rect.height = widget.size[1] widget.widget.size_allocate(rect) def _on_destroy(self, _): if not hasattr(self, 'widgets'): return for widget in self.widgets.keys(): widget.unparent() self.widgets = collections.OrderedDict() def set_bottom_margin(self, height): self.bottom_margin = height self.queue_resize() if GTK_AVAILABLE: GObject.type_register(CustomFlowLayout) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'gtk_widget_flowlayout', ] def chkdeps(self, out: dict): if not GLIB_AVAILABLE: out['glib'].update(openpaperwork_core.deps.GLIB) if not GTK_AVAILABLE: out['gtk'].update(openpaperwork_gtk.deps.GTK) def gtk_widget_flowlayout_new(self, spacing=(0, 0)): assert GLIB_AVAILABLE assert GTK_AVAILABLE return CustomFlowLayout(self.core, spacing) paperwork-2.2.2/paperwork-gtk/src/paperwork_gtk/widget/label.py000066400000000000000000000101531456262201400247100ustar00rootroot00000000000000import math try: import gi gi.require_foreign("cairo") import cairo CAIRO_AVAILABLE = True except (ImportError, ValueError): CAIRO_AVAILABLE = False try: from gi.repository import GObject GI_AVAILABLE = True except (ImportError, ValueError): GI_AVAILABLE = False try: import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk GTK_AVAILABLE = True except (ImportError, ValueError): # workaround so chkdeps can still be called class Gtk(object): class DrawingArea(object): pass GTK_AVAILABLE = False import openpaperwork_core import openpaperwork_core.deps import openpaperwork_gtk.deps class LabelWidget(Gtk.DrawingArea): FONT = "" LABEL_HEIGHT = 23 LABEL_TEXT_SIZE = 13 LABEL_TEXT_SHIFT = 3 # Shift a bit to fix valignment LABEL_CORNER_RADIUS = 5 def __init__(self, core, label_txt, label_color, highlight=False): super().__init__() self.core = core self.txt = label_txt self.color = label_color self.highlight = highlight self.connect("draw", self._draw) # we must compute the widget size dummy = cairo.ImageSurface(cairo.Format.RGB24, 200, 200) ctx = cairo.Context(dummy) size = self.compute_size(ctx) dummy.finish() self.set_size_request(size[0], size[1]) def compute_size(self, cairo_ctx): cairo_ctx.set_font_size(self.LABEL_TEXT_SIZE) if not self.highlight: cairo_ctx.select_font_face( self.FONT, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL ) else: cairo_ctx.select_font_face( self.FONT, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD ) (p_x1, p_y1, p_x2, p_y2, p_x3, p_y3) = cairo_ctx.text_extents( self.txt ) return ( p_x3 - p_x1 + (2 * self.LABEL_CORNER_RADIUS), self.LABEL_HEIGHT ) @staticmethod def _rectangle_rounded(cairo_ctx, area, radius): (x, y, w, h) = area cairo_ctx.new_sub_path() cairo_ctx.arc( x + w - radius, y + radius, radius, -1.0 * math.pi / 2, 0 ) cairo_ctx.arc( x + w - radius, y + h - radius, radius, 0, math.pi / 2 ) cairo_ctx.arc( x + radius, y + h - radius, radius, math.pi / 2, math.pi ) cairo_ctx.arc( x + radius, y + radius, radius, math.pi, 3.0 * math.pi / 2 ) cairo_ctx.close_path() def _draw(self, _, cairo_ctx): txt_offset = ( (self.LABEL_HEIGHT - self.LABEL_TEXT_SIZE) / 2 + self.LABEL_TEXT_SHIFT ) (w, h) = self.compute_size(cairo_ctx) # background rectangle bg = self.color cairo_ctx.set_source_rgb(bg[0], bg[1], bg[2]) cairo_ctx.set_line_width(1) self._rectangle_rounded( cairo_ctx, (0, 0, w, h), self.LABEL_CORNER_RADIUS ) cairo_ctx.fill() # foreground text fg = self.core.call_success("label_get_foreground_color", self.color) cairo_ctx.set_source_rgb(fg[0], fg[1], fg[2]) cairo_ctx.move_to( self.LABEL_CORNER_RADIUS, h - txt_offset ) cairo_ctx.text_path(self.txt) cairo_ctx.fill() if GTK_AVAILABLE: GObject.type_register(LabelWidget) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return [ 'chkdeps', 'gtk_widget_label', ] def chkdeps(self, out: dict): if not CAIRO_AVAILABLE: out['cairo'] = openpaperwork_core.deps.CAIRO if not GI_AVAILABLE: out['gi'] = openpaperwork_core.deps.GI if not GTK_AVAILABLE: out['gtk'] = openpaperwork_gtk.deps.GTK def gtk_widget_label_new(self, label_txt, label_color, highlight=False): assert CAIRO_AVAILABLE assert GI_AVAILABLE assert GTK_AVAILABLE return LabelWidget(self.core, label_txt, label_color, highlight) paperwork-2.2.2/paperwork-gtk/tests/000077500000000000000000000000001456262201400174705ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/tests/widget/000077500000000000000000000000001456262201400207535ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/tests/widget/__init__.py000066400000000000000000000000001456262201400230520ustar00rootroot00000000000000paperwork-2.2.2/paperwork-gtk/tests/widget/tests_flowlayout.py000066400000000000000000000110521456262201400247530ustar00rootroot00000000000000import unittest import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk from paperwork_gtk.widget import flowlayout class DummyCore(object): @staticmethod def call_all(*args, **kwargs): pass class TestPositioning(unittest.TestCase): def test_position_start(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.START, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.START, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.START, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.START, (40, 20)), ] flowlayout.recompute_box_positions(DummyCore(), widgets, width=100) self.assertEqual(widgets[0].position, (0, 0)) self.assertEqual(widgets[1].position, (40, 0)) self.assertEqual(widgets[2].position, (0, 20)) self.assertEqual(widgets[3].position, (40, 20)) def test_position_end(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), ] flowlayout.recompute_box_positions(DummyCore(), widgets, width=100) self.assertEqual(widgets[0].position, (20, 0)) self.assertEqual(widgets[1].position, (60, 0)) self.assertEqual(widgets[2].position, (20, 20)) self.assertEqual(widgets[3].position, (60, 20)) def test_position_center(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (40, 20)), ] flowlayout.recompute_box_positions(DummyCore(), widgets, width=100) self.assertEqual(widgets[0].position, (10, 0)) self.assertEqual(widgets[1].position, (50, 0)) self.assertEqual(widgets[2].position, (10, 20)) self.assertEqual(widgets[3].position, (50, 20)) def test_position_startend(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.START, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (40, 20)), ] flowlayout.recompute_box_positions(DummyCore(), widgets, width=150) self.assertEqual(widgets[0].position, (0, 0)) self.assertEqual(widgets[1].position, (70, 0)) self.assertEqual(widgets[2].position, (110, 0)) self.assertEqual(widgets[3].position, (55, 20)) def test_position_startend_spacing(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.START, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.END, (40, 20)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (40, 20)), ] flowlayout.recompute_box_positions( DummyCore(), widgets, width=150, spacing=(3, 4) ) self.assertEqual(widgets[0].position, (3, 4)) self.assertEqual(widgets[2].position, (107, 4)) self.assertEqual(widgets[1].position, (64, 4)) self.assertEqual(widgets[3].position, (55, 28)) def test_position_center_spacing(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (140, 200)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (140, 200)), ] flowlayout.recompute_box_positions( DummyCore(), widgets, width=500, spacing=(50, 50) ) self.assertEqual(widgets[0].position, (85, 50)) self.assertEqual(widgets[1].position, (275, 50)) def test_position_center_spacing_tight(self): widgets = [ flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (100, 100)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (100, 100)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (100, 100)), flowlayout.WidgetInfo(None, Gtk.Align.CENTER, (100, 100)), ] flowlayout.recompute_box_positions( DummyCore(), widgets, width=350, spacing=(50, 50) ) self.assertEqual(widgets[0].position, (50, 50)) self.assertEqual(widgets[1].position, (200, 50)) self.assertEqual(widgets[2].position, (50, 200)) self.assertEqual(widgets[3].position, (200, 200)) paperwork-2.2.2/paperwork-gtk/tox.ini000066400000000000000000000001221456262201400176340ustar00rootroot00000000000000[flake8] exclude = .tox, build, dist, venv*, *.egg*, .git paperwork-2.2.2/paperwork-shell/000077500000000000000000000000001456262201400166505ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/.flake8000066400000000000000000000001111456262201400200140ustar00rootroot00000000000000[flake8] exclude = src/paperwork_shell/_version.py max-line-length = 100 paperwork-2.2.2/paperwork-shell/AppImageBuilder.cli.yml000066400000000000000000000053231456262201400231360ustar00rootroot00000000000000version: 1 script: - rm -rf AppDir - rm -rf appimage-build - git submodule update --recursive --remote --init - make download_data -C .. - make version -C ../sub/libpillowfight - make l10n_compile -C ../openpaperwork-core - make l10n_compile -C ../openpaperwork-gtk - make l10n_compile -C ../paperwork-backend - make l10n_compile -C ../paperwork-shell - make -C ../sub/libinsane clean - unset DESTDIR && make install PREFIX="$(pwd)/AppDir/usr" -C ../sub/libinsane - pip3 install --ignore-installed --prefix=/usr --root=AppDir ../sub/libpillowfight ../sub/pyocr ../openpaperwork-core ../openpaperwork-gtk ../paperwork-backend ../paperwork-shell - mkdir -p AppDir/usr/share/icons/hicolor/48x48 - mkdir -p AppDir/usr/share/icons/hicolor/scalable - cp ../paperwork-gtk/src/paperwork_gtk/data/paperwork_48.png AppDir/usr/share/icons/hicolor/48x48/paperwork.png - cp ../paperwork-gtk/src/paperwork_gtk/data/paperwork_halo.svg AppDir/usr/share/icons/hicolor/scalable/paperwork.svg AppDir: path: ./AppDir app_info: id: work.openpaper.Paperwork name: Paperwork-cli icon: paperwork version: latest exec: usr/bin/python3 exec_args: "$APPDIR/usr/bin/paperwork-cli $@" apt: arch: - amd64 allow_unauthenticated: true sources: - sourceline: deb http://deb.debian.org/debian/ testing main contrib include: - bash - coreutils - dash - gir1.2-pango-1.0 - gir1.2-poppler-0.18 - gobject-introspection - libexpat1 - libgirepository1.0-dev - locales - python-is-python3 - python3 - python3-gi - python3-gi-cairo - python3-pip - python3-pkg-resources - sane - shared-mime-info - zlib1g files: include: - usr/lib/mime/**/* - usr/share/mime/**/* exclude: - usr/share/man - usr/share/doc/*/README.* - usr/share/doc/*/changelog.* - usr/share/doc/*/NEWS.* - usr/share/doc/*/TODO.* - usr/share/gtk-doc/**/* runtime: env: PYTHONHOME: '${APPDIR}/usr' PYTHONPATH: '${APPDIR}/usr/lib/python3.11/site-packages' test: fedora-30: image: appimagecrafters/tests-env:fedora-30 command: ./AppRun use_host_x: true debian-stable: image: appimagecrafters/tests-env:debian-stable command: ./AppRun use_host_x: true archlinux-latest: image: appimagecrafters/tests-env:archlinux-latest command: ./AppRun use_host_x: true centos-7: image: appimagecrafters/tests-env:centos-7 command: ./AppRun use_host_x: true ubuntu-xenial: image: appimagecrafters/tests-env:ubuntu-xenial command: ./AppRun use_host_x: true AppImage: arch: x86_64 update-information: guess paperwork-2.2.2/paperwork-shell/AppImageBuilder.json.yml000066400000000000000000000053611456262201400233420ustar00rootroot00000000000000version: 1 script: - rm -rf AppDir - rm -rf appimage-build - git submodule update --recursive --remote --init - make download_data -C .. - make version -C ../sub/libpillowfight - make l10n_compile -C ../openpaperwork-core - make l10n_compile -C ../openpaperwork-gtk - make l10n_compile -C ../paperwork-backend - make l10n_compile -C ../paperwork-shell - make -C ../sub/libinsane clean - unset DESTDIR && make install PREFIX="$(pwd)/AppDir/usr" -C ../sub/libinsane - pip3 install --ignore-installed --prefix=/usr --root=AppDir ../sub/libpillowfight ../sub/pyocr ../openpaperwork-core ../openpaperwork-gtk ../paperwork-backend ../paperwork-shell - mkdir -p AppDir/usr/share/icons/hicolor/48x48 - mkdir -p AppDir/usr/share/icons/hicolor/scalable - cp ../paperwork-gtk/src/paperwork_gtk/data/paperwork_48.png AppDir/usr/share/icons/hicolor/48x48/paperwork.png - cp ../paperwork-gtk/src/paperwork_gtk/data/paperwork_halo.svg AppDir/usr/share/icons/hicolor/scalable/paperwork.svg AppDir: path: ./AppDir app_info: id: work.openpaper.Paperwork name: Paperwork-json icon: paperwork version: latest exec: usr/bin/python3 exec_args: "$APPDIR/usr/bin/paperwork-json $@" apt: arch: - amd64 allow_unauthenticated: true sources: - sourceline: deb http://deb.debian.org/debian/ testing main contrib include: - bash - coreutils - dash - gir1.2-pango-1.0 - gir1.2-poppler-0.18 - gobject-introspection - gtk-update-icon-cache - libexpat1 - libgirepository1.0-dev - locales - python-is-python3 - python3 - python3-gi - python3-gi-cairo - python3-pip - python3-pkg-resources - sane - shared-mime-info - zlib1g files: include: - usr/lib/mime/**/* - usr/share/mime/**/* exclude: - usr/share/man - usr/share/doc/*/README.* - usr/share/doc/*/changelog.* - usr/share/doc/*/NEWS.* - usr/share/doc/*/TODO.* - usr/share/gtk-doc/**/* runtime: env: PYTHONHOME: '${APPDIR}/usr' PYTHONPATH: '${APPDIR}/usr/lib/python3.11/site-packages' test: fedora-30: image: appimagecrafters/tests-env:fedora-30 command: ./AppRun use_host_x: true debian-stable: image: appimagecrafters/tests-env:debian-stable command: ./AppRun use_host_x: true archlinux-latest: image: appimagecrafters/tests-env:archlinux-latest command: ./AppRun use_host_x: true centos-7: image: appimagecrafters/tests-env:centos-7 command: ./AppRun use_host_x: true ubuntu-xenial: image: appimagecrafters/tests-env:ubuntu-xenial command: ./AppRun use_host_x: true AppImage: arch: x86_64 update-information: guess paperwork-2.2.2/paperwork-shell/ChangeLog000066400000000000000000000031521456262201400204230ustar00rootroot000000000000002024/02/13 - 2.2.2: - paperwork-cli: disable automatic paging of output. This tends to be actually more annoying than helpful. - chkworkdir: Fix corrupted PDF mapping detection when running `paperwork-cli chkworkdir`. - Fix `paperwork-(json|shell) plugins show` 2023/09/17 - 2.2.1: - Add build-system.build-backend to pyproject.toml 2023/09/16 - 2.2.0: - setup.py has been replaced by pyproject.toml - paperwork-cli: Use Python Rich to prettify the output of some commands - paperwork-cli export: Make sure export pipelines make sense, otherwise explain to the user why they don't. - paperwork-cli export: Fix listing pipes when exporting a single page 2023/01/08 - 2.1.2: - import: honor the flag --doc_id. - fix 'scanner list' 2022/01/31 - 2.1.1: - Make sure Fabulous is not actually a required dependency on Windows. 2021/12/05 - 2.1.0: - Use system pager to paginate shell About page (thanks to Elliott Sales de Andrade) - doc import: add support for password-protected PDF files 2021/05/24 - 2.0.3: - Fix "paperwork-json show": paperwork-json uses document renderers too - Fix crash when uising "paperwork-cli rename" - Paperwork-cli/-json search: sort the documents by decreasing dates - Swedish translations added - Add LICENSE file in pypi package 2021/01/01 - 2.0.2: - add command 'chkworkdir': Check work directory integrity and fix it - import: Fix: Load the labels before importing documents 2020/11/15 - 2.0.1: - cmd.import: When many importers match, make it clearer to the user that an input is required. - Include tests in Pypi package (thanks to Elliott Sales de Andrade) 2020/10/17 - 2.0: - Initial release paperwork-2.2.2/paperwork-shell/LICENSE000066400000000000000000001045051456262201400176620ustar00rootroot00000000000000 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. {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year} {name of author} 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: {project} Copyright (C) {year} {fullname} 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 . paperwork-2.2.2/paperwork-shell/MANIFEST.in000066400000000000000000000001431456262201400204040ustar00rootroot00000000000000recursive-include src *.py *.mo *.png recursive-include tests * include *.markdown include LICENSE paperwork-2.2.2/paperwork-shell/Makefile000066400000000000000000000045271456262201400203200ustar00rootroot00000000000000PYTHON ?= python3 build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: l10n_compile ${PYTHON} ./setup.py build build_c: doc: upload_doc: data: check: if ! hash flake8 ; then PIP_DEPS=[lint] $(MAKE) install_py ; fi flake8 --append-config $(CURDIR)/.flake8 $(CURDIR)/src/paperwork_shell test: if ! hash pytest ; then PIP_DEPS=[dev] $(MAKE) install_py ; fi python3 -m pytest -xv tests/ linux_exe: rm -rf AppDir appimage-build appimage-builder --skip-tests --recipe AppImageBuilder.cli.yml rm -rf AppDir appimage-build appimage-builder --skip-tests --recipe AppImageBuilder.json.yml windows_exe: install # ugly, but "import pkg_resources" doesn't work in frozen environments # and I don't want to have to patch the build machine to fix it every # time. mkdir -p $(CURDIR)/../build/exe/data (cd $(CURDIR)/src && find . -name '*.mo' -exec cp --parents \{\} $(CURDIR)/../build/exe/data \; ) release: ifeq (${RELEASE}, ) @echo "You must specify a release version (make release RELEASE=1.2.3)" exit 1 else @echo "Will release: ${RELEASE}" @echo "Checking release is in ChangeLog ..." grep ${RELEASE} ChangeLog | grep -v "/xx" endif release_pypi: @echo "Releasing paperwork-shell ..." rm -rf /tmp/venv virtualenv /tmp/venv . /tmp/venv/bin/activate && pip install build . /tmp/venv/bin/activate && ${PYTHON} -m build -s rm -rf /tmp/venv twine upload $(CURDIR)/dist/*.tar.gz @echo "All done" clean: rm -rf AppDir appimage-build rm -f *.AppImage rm -rf build dist *.egg-info rm -f src/paperwork_shell/_version.py # PIP_ARGS is used by Flatpak build install_py: l10n_compile ${PYTHON} -m pip install ${PIP_ARGS} .${PIP_DEPS} install_c: uninstall_py: pip3 uninstall -y paperwork-shell uninstall_c: l10n_extract: $(CURDIR)/../tools/l10n_extract.sh "$(CURDIR)/src" "$(CURDIR)/l10n" l10n_compile: $(CURDIR)/../tools/l10n_compile.sh \ "$(CURDIR)/l10n" \ "$(CURDIR)/src/paperwork_shell/l10n" \ "paperwork_shell" help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ l10n_compile \ l10n_extract \ release \ test \ uninstall \ uninstall_c paperwork-2.2.2/paperwork-shell/README.markdown000066400000000000000000000326551456262201400213640ustar00rootroot00000000000000# Paperwork-shell ![Paperwork-shell demo](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/search.gif) ## Introduction Paperwork-shell provides 2 commands: * `paperwork-cli`: Human-friendly command line interface. For instance, it can be useful if you want to use Paperwork through SSH. * `paperwork-json`: Designed to be used in scripts. Results can be parsed in shell scripts using [`jq`](https://stedolan.github.io/jq/). Both commands takes the same arguments as input. Only their outputs differ. From there, `paperwork-xxx` means either `paperwork-cli` or `paperwork-json`. ## OS/distribution specifics ### On Windows Only paperwork-json is available. Installer doesn't modify your PATH. If you want to invoke paperwork-json, you either have to modify your PATH yourself, or use the command full path (ex: `"c:\program files (x86)\Paperwork\paperwork-json.exe"`). ### In a Flatpak container You have to run the commands from inside the Flatpak container. ```sh flatpak run --command="paperwork-cli" work.openpaper.Paperwork ``` For examples: ```sh flatpak run --command="paperwork-cli" work.openpaper.Paperwork "--help" flatpak run --command="paperwork-cli" work.openpaper.Paperwork chkdeps ``` ## Sub-commands Paperwork-shell's commands expect sub-commands (similar to `git`). You can obtain all the sub-commands and their expected arguments using `--help` (long help) or `-h` (short help). Not all sub-commands are described in this README. Available sub-commands may vary based on what plugins are enabled or not. This README is just here to give you a preview of the most common sub-commands usually available. ### chkdeps ```sh $ paperwork-cli chkdeps Detected system: debian 10 buster Nothing to do. ``` Check for dependencies required by *paperwork-shell*'s plugins. It does NOT check for dependencies required by *paperwork-gtk*'s plugins (for that, try `paperwork-gtk chkdeps` instead). If dependencies are missing, it will try to provide the command to install them. ### config ```sh $ paperwork-cli config show send_statistics = True uuid = 1234567890 statistics_last_run = 1970-01-01 statistics_protocol = https statistics_server = openpaper.work statistics_url = /beacon/post_statistics workdir = file:///home/jflesch/papers scanner_dev_id = libinsane:sane:epson2:net:192.168.42.18 scanner_source_id = flatbed scanner_resolution = 300 ocr_lang = fra check_for_update = True last_update_found = 1.3.0-253-g032699cf update_last_run = 1970-01-01 update_protocol = https update_server = openpaper.work update_url = /beacon/latest $ paperwork-cli config get workdir workdir = file:///home/jflesch/papers $ paperwork-cli config put workdir str file:///home/jflesch/tmp/papers workdir = file:///home/jflesch/tmp/papers ``` `paperwork-xxx config` provides various sub-sub-commands to read and modify Paperwork config and enable/disable `paperwork-shell`'s plugins. The one most important settings is the work directory path: `workdir`. It indicates where documents managed by Paperwork must be stored. It *must* be an URL (`file://xxx`). ### plugins ```sh $ paperwork-cli plugins list openpaperwork_core.logs.print openpaperwork_gtk.mainloop.glib openpaperwork_core.config paperwork_backend.beacon.stats paperwork_backend.beacon.sysinfo (...) paperwork_shell.display.print paperwork_shell.display.progress paperwork_shell.display.scanpaperwork_shell.display.print paperwork_shell.display.progress paperwork_shell.display.scan ``` While most settings are shared between Paperwork UIs (paperwork-shell and paperwork-gtk), plugins lists are *not*. If you want to modify `paperwork-gtk`'s plugin list, you have to use `paperwork-gtk plugins` instead. If you want to enable or disable features, you can simply add or remove the corresponding plugin. For instance, to disable the automatic OCR run on imported documents or scanned pages: ```sh $ paperwork-cli plugins remove paperwork_backend.guesswork.ocr.pyocr Plugin paperwork_backend.guesswork.ocr.pyocr removed ``` `paperwork-cli plugins remove` and `paperwork-cli plugins add` take dependencies into account: `remove` will also remove all the plugins that depends on the one you're removing. `add` will also add all the plugins required for the one you're adding. Some plugins are mandatory and cannot be disabled (mainly all the plugins required to read the configuration file). If something go wrong, you can reset the plugin list to its default with `paperwork-cli plugins reset`. ### sync ![Paperwork-cli sync](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/sync.webm) Update the content of search engine index, label guesser training, etc, according to the current content of the work directory. If you modify the content of your work directory manually (without using Paperwork commands), this is the command to run. This operation is also executed every time `paperwork-gtk` is started. ### search ![Paperwork-xxx search](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/search.gif) Returns documents that contains keywords identical or close to the one specified. If no keyword is specified, all the documents are returned. Results are always ordered by decreasing dates. ### show ![paperwork-cli show 1](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/show_1.png) ![paperwork-cli show 1](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/show_2.png) Show a document page images and texts. ### scanner ```sh % paperwork-cli scanner list BROTHER DS-620 (sheetfed scanner ; sane:dsseries:usb:0x04F9:0x60E0) |-- ID: libinsane:sane:dsseries:usb:0x04F9:0x60E0 |-- Source: feeder | |-- Resolutions: [75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, 425, 450, 475, 500, 525, 550, 575, 600] Canon CanoScan N1240U/LiDE30 (flatbed scanner ; sane:plustek:libusb:001:024) |-- ID: libinsane:sane:plustek:libusb:001:024 |-- Source: flatbed (Normal) | |-- Resolutions: [150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, | | 425, 450, 475, 500, 525, 550, 575, 600, 625, 650, 675, | | 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, | | 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, | | 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, | | 1425, 1450, 1475, 1500, 1525, 1550, 1575, 1600, 1625, | | 1650, 1675, 1700, 1725, 1750, 1775, 1800, 1825, 1850, | | 1875, 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075, | | 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275, 2300, | | 2325, 2350, 2375, 2400] |-- Source: flatbed (Transparency) | |-- Resolutions: [150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, | | 425, 450, 475, 500, 525, 550, 575, 600, 625, 650, 675, | | 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, | | 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, | | 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, | | 1425, 1450, 1475, 1500, 1525, 1550, 1575, 1600, 1625, | | 1650, 1675, 1700, 1725, 1750, 1775, 1800, 1825, 1850, | | 1875, 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075, | | 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275, 2300, | | 2325, 2350, 2375, 2400] |-- Source: flatbed (Negative) | |-- Resolutions: [150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, | | 425, 450, 475, 500, 525, 550, 575, 600, 625, 650, 675, | | 700, 725, 750, 775, 800, 825, 850, 875, 900, 925, 950, | | 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, | | 1200, 1225, 1250, 1275, 1300, 1325, 1350, 1375, 1400, | | 1425, 1450, 1475, 1500, 1525, 1550, 1575, 1600, 1625, | | 1650, 1675, 1700, 1725, 1750, 1775, 1800, 1825, 1850, | | 1875, 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075, | | 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275, 2300, | | 2325, 2350, 2375, 2400] Epson PID 08C1 (flatbed scanner ; sane:epson2:net:192.168.42.18) |-- ID: libinsane:sane:epson2:net:192.168.42.18 |-- Source: flatbed | |-- Resolutions: [75, 100, 150, 300, 600] % paperwork-cli scanner set "libinsane:sane:epson2:net:192.168.42.18" Default source: flatbed ID: libinsane:sane:epson2:net:192.168.42.18 Source: flatbed Resolution: 300 ``` Provides subcommands to list the available scanners and get and set the scanner to use and its settings. When configuring the scanner, it checks that the provided settings are actually consistent with what the scanner provides. You can bypass those checks by using `paperwork-cli config` instead. If you get warnings and errors from the Libinsane, you can safely ignore them unless you didn't get the scanner you were looking for in the list. ### scan ![Paperwork-xxx scan](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/scan.webm) Scan all the page(s) available in the scanner. Append all the pages to the specified document (`-d`). If no document is specified, a new one will be created. If you get warnings and errors from the Libinsane, you can safely ignore them unless the scan didn't work. ### import ```sh $ paperwork-cli import 100227398115.pdf Importing ['100227398115.pdf'] ... [index_update ] Indexing new document 20191113_1255_32 Committing changes in label guesser database ... Done Committing changes in the index ... Done Done Import result: - Imported files: {'file:///home/jflesch/tmp/pdf/100227398115.pdf'} - Non-imported files: set() - New documents: {'20191113_1255_32'} - Updated documents: set() - PDF: 1 - Documents: 1 ``` Import images of PDF files. Images are appended to the specified document (`-d`). If no document is specified, a new one is created. PDF are always imported as a new document, even if a document ID is specified. ### label ![paperwork-cli label list](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/label_1.png) ![paperwork-cli label add](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/label_2.png) Add and remove labels on documents. When adding a label, if the label already exists on other documents, the existing color will be reused. If it does not exist yet, either the user has specified a color (`-c #abcdef`), or a random one will be generated. ### edit ![paperwork-cli edit -m rotate\_clockwise](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/edit.gif) Basic editing of page images. Modifiers must be specified. Many can provided in one shot so the OCR is only run once. ### reset ![paperwork-cli reset](http://storage.sbg.cloud.ovh.net/v1/AUTH_6c4273c748b243c58df3f6942075e0c9/gitlab.gnome.org/paperwork-shell/reset.gif) Returns a page image to its initial state. It will also cancel any changes made by post-processing plugins after importing or scanning. ### delete ```sh $ paperwork-cli delete 20191113_1255_32 Delete document 20191113_1255_32 ? [y/N] y Deleting document 20191113_1255_32 ... $ paperwork-cli delete 20191112_2117_09 -p 1 Delete page(s) [1] of document 20191112_2117_09 ? [y/N] y Deleting page 1 of document 20191112_2117_09 ... [WARNING] [paperwork_backend.model.workdir] All pages of document file:///home/jflesch/tmp/papers/20191112_2117_09 have been removed. Removing document ``` Delete page(s) or a whole document. ### export ```sh $ paperwork-cli export 20191107_2343_44 Current filters: [] Next possible filters: - img_boxes $ paperwork-cli export 20191107_2343_44 -f img_boxes Current filters: ['img_boxes'] Next possible filters: - unpaper - swt_soft - swt_hard - generated_pdf - bw - grayscale - bmp - gif - jpeg - png - tiff $ paperwork-cli export 20191107_2343_44 -f img_boxes -f generated_pdf Current filters: ['img_boxes', 'generated_pdf'] 'generated_pdf' is an output filter. Not other filter can be added after 'generated_pdf'. $ paperwork-cli export 20191107_2343_44 -f img_boxes -f generated_pdf -o ~/tmp/out.pdf Exporting to file:///home/jflesch/tmp/out.pdf ... Done ``` Export a document or page(s). An export is seen as processing pipeline (in other words, filter list). Selecting a document or a page (`-p`) represent the input or the pipe. Various processing components (pipes) can be chained. Some of them can be used at the end of the pipe. There are restrictions on which components can follow each other. For instances: - Somewhere before `generated_pdf`, you must have a component `img_boxes` to turn the input document or page(s) into a bunch of images and text boxes. - Only a PDF document can be used as input for the component `unmodified_pdf` and no other components can precede it. ## Shell scripts You can have a look at [some examples of Bash scripts](../scripts). ## paperwork-cli and stdout redirection In case you want to redirect stdout but also want to keep the ANSI output, you can set [the environment variable `FORCE_COLOR=1`](https://rich.readthedocs.io/en/stable/console.html#environment-variables). paperwork-2.2.2/paperwork-shell/l10n/000077500000000000000000000000001456262201400174225ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/l10n/ca.po000066400000000000000000000447571456262201400203660ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-30 11:53+0100\n" "PO-Revision-Date: 2022-04-03 12:08+0000\n" "Last-Translator: Víctor Fancelli Capdevila \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "Sincronitza els índex amb el contingut de la carpeta de treball" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:112 msgid "Synchronizing with work directory ..." msgstr "Sincronitzant amb la carpeta de treball..." #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:118 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 msgid "All done !" msgstr "Fet!" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "Escanejant les pàgines" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "Document al que s'han d'afegir les pàgines" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:55 msgid "Manage scanner configuration" msgstr "Gestiona la configuració de l'escàner" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:58 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 msgid "sub-command" msgstr "sub-commanda" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "List all scanners and their possible settings" msgstr "Enumera tots els escàners i les seves possibles configuracions" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:67 msgid "Show the currently selected scanner and its settings" msgstr "Mostra l'escàner seleccionat actualment i la seva configuració" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:72 msgid "Define which scanner and which settings to use" msgstr "Defineix quin escàner i quina configuració s'han d'utilitzar" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:75 msgid "Scanner to use" msgstr "Escàner que s'ha d'utilitzar" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:80 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" "Font de l'escàner a utilitzar per defecte (si no està especificada, se'n " "seleccionarà una aleatòriament)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:86 msgid "Default resolution (dpi ; default=300)" msgstr "Resolució per defecte (dpi; per defecte=300)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:91 msgid "Examining scanner {} ..." msgstr "Examinant l'escàner {}..." #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:133 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:155 msgid "ID:" msgstr "ID:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:135 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:156 msgid "Source:" msgstr "Font:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:137 msgid "Resolutions:" msgstr "Resolució:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:157 msgid "Resolution:" msgstr "Resolució:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:185 msgid "Source {} not found on device. Using another source" msgstr "No s'ha trobat la font {} al dispositiu. Intenteu una altra font" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:205 msgid "Default source:" msgstr "Font per defecte:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:219 msgid "Resolution {} not available. Adjusted to {}." msgstr "La resolució {} no és possible. Ajustant a {}." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "Versió: " #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "Perquè hauríem de deixar la paperassa a les màquines." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "Sobre el Paperwork" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "Restableix el contingut original d'una pàgina" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "Restablint el document {}, concretament la pàgina {}..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 msgid "Original:" msgstr "Original:" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "Restablert:" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 msgid "Committing ..." msgstr "Desant..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/export.py:175 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 #: paperwork-shell/src/paperwork_shell/display/progress.py:39 msgid "Done" msgstr "Fet" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "Passant l'OCR per una o totes les pàgines d'un document" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "Document al qual s'ha de passar l'ORC" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Pàgines on s'ha de passar l'ORC (nombre, interval, llista separada per " "comes, per defecte: totes les pàgines)" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "Passant l'OCR a la pàgina {page_idx} del document {doc_id}..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "Elimina una pàgina o un document" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Pàgines a eliminar (nombre, interval, llista separada per comes, per defecte:" " totes les pàgines)" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 msgid "Target documents" msgstr "Documents objectiu" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "Eliminant el document {doc_id}..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "Eliminant la pàgina {page_idx} del document {doc_id}..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "Voleu eliminar el document %s?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "Voleu eliminar les pàgines {page_indexes} del document {doc_id}?" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "Mostra el contingut d'un document" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "ID del document: %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "Data del document: %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "Pàgina %d" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "Comprova i repara la integritat de la carpeta de treball" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "No em preguntis si s'han d'arreglar les coses: repara-les i prou" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "Comprovant la carpeta de treball…" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "No s'ha trobat cap problema" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:77 #, python-format msgid "%d problems found:" msgstr "Hi ha hagut algun problema, concretament %d" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:92 msgid "- Problem: " msgstr "- Problema: " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:96 msgid "- Possible solution: " msgstr "- Possible solució: " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:102 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" "Voleu solucionar aquests problemes automàticament amb les solucions " "proposades?" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "All fixed !" msgstr "Tot arreglat!" #: paperwork-shell/src/paperwork_shell/cmd/export.py:57 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" "Exporta un document, una pàgina o un conjunt de pàgines. Per exemple: " "paperwork-cli export 20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg " "-o ~/tmp/pouet.jpg" #: paperwork-shell/src/paperwork_shell/cmd/export.py:63 msgid "Document to export" msgstr "Document a exportar" #: paperwork-shell/src/paperwork_shell/cmd/export.py:67 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "Pàgines a exportar" #: paperwork-shell/src/paperwork_shell/cmd/export.py:76 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" "Exporta els filtres. Especifiqueu la bandera per cada filtre (per exemple: '-" "f grayscale -f jpeg')." #: paperwork-shell/src/paperwork_shell/cmd/export.py:83 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" "Document/Carpeta de sortida. Si no s'especifica, mostrarà els filtres que es " "podrien encadenar després dels que han estat especificats." #: paperwork-shell/src/paperwork_shell/cmd/export.py:119 #, python-format msgid "Unknown filters: %s" msgstr "Filtres desconeguts: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:141 #, python-format msgid "Current filters: %s" msgstr "Filtres actuals: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:144 msgid "Next possible filters:" msgstr "Pròxims possibles filtres:" #: paperwork-shell/src/paperwork_shell/cmd/export.py:149 #, python-brace-format msgid "" "'{filter_name}' is an output filter. No other filter can be added after " "'{filter_name}'." msgstr "" "«{filter_name}» és un filtre de sortida. No es poden afegir més filtres " "després de «{filter_name}»." #: paperwork-shell/src/paperwork_shell/cmd/export.py:153 msgid "No possible filters found" msgstr "No s'han trobat filtres possibles" #: paperwork-shell/src/paperwork_shell/cmd/export.py:170 #, python-format msgid "Exporting to %s ... " msgstr "Exportant a %s... " #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "Ordres per gestionar les etiquetes" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "Ordres de les etiquetes" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "Document de sortida" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "Etiqueta a afegir" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "Color de l'etiqueta (per ex. \"#aa22cc\")" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "Etiqueta a eliminar" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "Etiqueta que s'ha d'eliminar de *tots* els documents" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "Carregant les etiquetes... " #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "Segur que voleu eliminar l'etiqueta «%s» de tots els documents?" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "Importa els fitxers" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "Document de sortida per les importacions" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "Contrasenya del PDF" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "Fitxers a importar" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "No sé com importar els fitxers següents: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "S'han trobat vàries maneres d'importar els fitxers %s." #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "Seleccioneu la manera com ho voleu importar:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "Carregant les etiquetes..." #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "Important %s..." #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "Resultat de la importació:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "- Fitxers importats: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "- Fitxers no importats: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "- Documents nous: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "- Documents actualitzats: %s" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "Edita la pàgina" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" "Llista dels modificadors d'imatge (separats per comes, valors possibles: {})" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "Modificant el document {}, concretament la pàgina {}..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "Generant la còpia en alta qualitat i desant-la..." #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "Cerca paraules clau als documents" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "Nombre de resultats a mostrar (per defecte: 50)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "Cerca les paraules clau (cap significa tots els documents)" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "Mou una pàgina" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "Document d'entrada" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "Pàgina que s'ha de moure" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "Document de sortida" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "Nombre de la pàgina del document de sortida" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "Canvia l'identificador d'un document" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "Document al qual s'ha de canviar el nom" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "Nou nom que rebrà el document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "Gestioneu el text addicional dels documents" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "Obtingueu el text addicional d'un document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "Establiu el text addicional d'un document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 msgid "Additional text:" msgstr "Text addicional:" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "Sense text addicional" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "comanda" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "Escanejant la pàgina {} (mida esperada: {}x{})..." #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "Pàgina {} escanejada (mida actual:{}x{})" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "Fi de la safata de paper" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "S'ha creat la pàgina {} al document {}" paperwork-2.2.2/paperwork-shell/l10n/de.po000066400000000000000000000510121456262201400203510ustar00rootroot00000000000000# German translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-07-31 15:31+0000\n" "Last-Translator: Jannik Wilhelm \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.18.2\n" #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 msgid "Additional text:" msgstr "Zusätzlicher Text:" #: paperwork-shell/src/paperwork_shell/display/progress.py:39 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/export.py:250 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 msgid "Done" msgstr "Erledigt" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "Scan des Seite {} (erwartete Größe: {}x{}) ..." #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "Seite {} gescannt (eigentliche Größe: {}x{})" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "Ende des Papiereinzugs" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "Seite {} im Dokument {} erstellt" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "Kommando" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "Stellt den Inhalt eines Dokumentes dar" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "Dokumenten-ID %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "Dokumentendatum: %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "Seite %d" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "Seite bearbeiten" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "Bild-Modifikatoren Liste (Kommas als Trennzeichen, mögliche Werte: {})" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "Modifizierung vom Dokument {} Seite {} ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "Originalfassung:" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "Erstellt und speichert in hoher Qualität ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "Speichern ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:121 msgid "All done !" msgstr "Fertig!" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "Importiere Datei(en)" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "Zieldokument für Import" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "PDF Passwort" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "Zu importierende Dateien" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "Weiß nicht wie die Datei(en) %s importiert werden sollen" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "" "Es wurden viele Möglichkeiten zum Importieren von Datei(en) %s gefunden." #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "Bitte wählen Sie den gewünschten Weg:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "Schlagwörter werden geladen..." #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "%s Import in Bearbeitung …" #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "Importergebnis:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "- Importierte Dateien: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "- Nicht-Importierte Dateien: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "- Neue Dokumente: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "- Aktualisierte Dokumente: %s" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "Zurück zur Seiten Grundstellung" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "Zurücksetzen des Dokuments {} Seite {} ..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "Zurückgesetzt:" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "Ein Seite verschieben" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "Quelldokument" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "Seite die verschiebt werden soll" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "Zieldokument" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "Zielseite Nummer" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "Texterkennung (OCR) eines Dokuments oder der Seiten" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "Texterkennung (OCR) auf dieses Dokument anwenden" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Texterkennung aud diese Seiten anwenden (Ganzzahl, Bereich oder Komma " "separierte Liste, default: alle Seiten)" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "Texterkennung von dem Dokument {doc_id} Seite {page_idx} ..." #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "Kommandos zum Verwalten von Labels" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "Label Kommando" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "Zieldokumente" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "Zieldokument" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "hinzuzufügendes Label" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "Labelfarbe (z.B.: '#aa22cc')" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "zu löschendes Label" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "Das Label %s von *allen* Dokumenten löschen" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "Lade alle Labels ... " #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "" "Sind Sie sicher dass Sie das Label %s von allen Dokumenten löschen möchten?" #: paperwork-shell/src/paperwork_shell/cmd/export.py:62 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" "Exportiere ein Dokument, eine Seite oder eine Folge von Seiten. Beispiel: " "paperwork-cli export 20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg " "-o ~/tmp/pouet.jpg" #: paperwork-shell/src/paperwork_shell/cmd/export.py:68 msgid "Document to export" msgstr "Zu exportierende Dokumente" #: paperwork-shell/src/paperwork_shell/cmd/export.py:72 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Diese Seiten exportieren (Ganzzahl, Bereich oder Komma separierte Liste, " "default: alle Seiten)" #: paperwork-shell/src/paperwork_shell/cmd/export.py:81 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" "Exportfilter. Geben Sie diese Option einmal für jeden anzuwendenden Filter " "an (z.B.: '-f grayscale -f jpeg')." #: paperwork-shell/src/paperwork_shell/cmd/export.py:88 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" "Ausgabedatei/Verzeichnis. Wenn nicht angegeben, werden die Filter angezeigt " "die nach den bereits angegebenen angehängt werden können." #: paperwork-shell/src/paperwork_shell/cmd/export.py:98 msgid "Next possible filters are:" msgstr "Nächste mögliche Filter sind:" #: paperwork-shell/src/paperwork_shell/cmd/export.py:106 msgid "a document list" msgstr "Eine Dokumentenliste" #: paperwork-shell/src/paperwork_shell/cmd/export.py:108 msgid "a document" msgstr "Ein Dokument" #: paperwork-shell/src/paperwork_shell/cmd/export.py:110 msgid "pages" msgstr "Seiten" #: paperwork-shell/src/paperwork_shell/cmd/export.py:112 msgid "Images and text boxes" msgstr "Bilder und Textfelder" #: paperwork-shell/src/paperwork_shell/cmd/export.py:129 msgid "Need at least one filter." msgstr "Benötigt wird mindestens ein Filter." #: paperwork-shell/src/paperwork_shell/cmd/export.py:133 msgid "First filter cannot be '{}'" msgstr "Der erste Filter kann nicht '{}' sein" #: paperwork-shell/src/paperwork_shell/cmd/export.py:146 #, python-brace-format msgid "Filter mismatch: {0} expects {1} as input. Got {2} instead" msgstr "" "Filter Unstimmigkeit: {0} erwartet {1} als Eingabe. Hat stattdessen {2} " "erhalten." #: paperwork-shell/src/paperwork_shell/cmd/export.py:163 msgid "Last filter will output {}." msgstr "Letzter Filter gibt {} aus." #: paperwork-shell/src/paperwork_shell/cmd/export.py:204 #, python-format msgid "Unknown filters: %s" msgstr "Unbekannte Filter: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:209 msgid "" "Run the command without any filter to have a list of possible filters to " "start with." msgstr "" "Führen Sie den Befehl ohne einen Filter aus, um eine Liste möglicher Filter " "zu erhalten, mit denen Sie beginnen können." #: paperwork-shell/src/paperwork_shell/cmd/export.py:223 msgid "Filter list is complete, but no output file specified (-o)" msgstr "Filterliste ist vollständig, aber keine Ausgabedatei angegeben (-o)" #: paperwork-shell/src/paperwork_shell/cmd/export.py:244 #, python-format msgid "Exporting to %s ... " msgstr "Exportiere nach %s ... " #: paperwork-shell/src/paperwork_shell/cmd/export.py:253 msgid "Export failed !" msgstr "Export fehlgeschlagen!" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "Verwalte die dem Dokument beifefügten zusätzliche Texte" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "sub-command" msgstr "Unterkommando" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "Erhalte den zusätzlichen Text eines Dokuments" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "Zusätzlicher Text eines Dokuments festlegen" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "Kein zusätzlicher Text" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "Scanne Seiten" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "Dokument zu dem die gescannten Seiten hinzugefügt werden sollen" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "Synchronisiert Index(e) mit dem Inhalt des Arbeitsverzeichnis" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:115 msgid "Synchronizing with work directory ..." msgstr "Synchronisierung mit des Arbeitsverzeichnis ..." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "Version: " #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "Weil Unterlagen sortieren die Arbeit einer Maschine ist." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "Über Paperwork" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "Suche Schlüsselwörter in Dokumenten" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "Maximale Anzahl an Ergebnissen (default: 50)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "Suchbegriffe (keine Angabe bedeutet alle Dokumente)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:59 msgid "Manage scanner configuration" msgstr "Scannerkonfiguration verwalten" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:66 msgid "List all scanners and their possible settings" msgstr "Liste alle Scanner und deren möglichen Einstellungen ab" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:71 msgid "Show the currently selected scanner and its settings" msgstr "Zeige den aktuell ausgewählten Scanner und dessen Einstellungen" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:76 msgid "Define which scanner and which settings to use" msgstr "" "Bestimme welcher Scanner und welche Einstellungen benützt werden sollen" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:79 msgid "Scanner to use" msgstr "Benütze diesen Scanner" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:84 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" "Standartquelle zu benützen (when nich festgelegt, wird eine zufällig " "ausgewählt)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:90 msgid "Default resolution (dpi ; default=300)" msgstr "Standardauflösung (dpi ; default=300)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:95 msgid "Examining scanner {} ..." msgstr "Überpruft den Scanner {} ..." #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:150 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:172 msgid "ID:" msgstr "ID:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:152 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:173 msgid "Source:" msgstr "Quelle:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Resolutions:" msgstr "Auflösungen:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:174 msgid "Resolution:" msgstr "Auflösung:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:202 msgid "Source {} not found on device. Using another source" msgstr "Quelle {} nicht gefunden auf den Gerät. Benutzung einer andere Quelle" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:222 msgid "Default source:" msgstr "Standardquelle:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:236 msgid "Resolution {} not available. Adjusted to {}." msgstr "{} Auflössung nicht verfügbar. Für {} angepasst." #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "Integrität des Arbeitsverzeichnisses prüfen und beheben" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "Nicht fragen, ob etwas repariert werden darf - einfach reparieren" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "Arbeitsverzeichnis prüfen ..." #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "Kein Problem gefunden" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:75 #, python-format msgid "%d problems found:" msgstr "%d Probleme gefunden:" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:90 msgid "- Problem: " msgstr "- Problem: " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:94 msgid "- Possible solution: " msgstr "- Mögliche Lösung: " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:103 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" "Möchten Sie diese Probleme automatisch mit den angegebenen Lösungen beheben?" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "Fixing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:114 msgid "All fixed !" msgstr "Alles behoben!" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "Lösche ein Dokument oder eine Seite" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Diese Seiten löschen (Ganzzahl, Bereich oder Komma separierte Liste, " "default: alle Seiten)" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "Lösche Dokument {doc_id} ..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "Lösche Seite {page_idx} von Dokument {doc_id} ..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "Lösche Dokument %s?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "Lösche Seite(n) {page_indexes} von Dokument {doc_id}?" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "Ändere eine Dokument-Bezeichnung" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "Umzubenennendes Dokument" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "Neuer Name für das Dokument" #, python-format #~ msgid "Current filters: %s" #~ msgstr "Aktuelle Filter: %s" #~ msgid "Next possible filters:" #~ msgstr "Nächste mögliche Filter:" #, python-brace-format #~ msgid "" #~ "'{filter_name}' is an output filter. No other filter can be added after " #~ "'{filter_name}'." #~ msgstr "" #~ "'{filter_name}' ist ein Ausgabefilter. Nach '%s' kann kein weiterer " #~ "Filter angegeben werden." #~ msgid "No possible filters found" #~ msgstr "Keine möglichen Filter gefunden" #~ msgid "Label to remove on *all* documents" #~ msgstr "Label das auf *alle* Dokumente angewendet wird" #, python-format #~ msgid "Found many ways to import file(s) %s:" #~ msgstr "" #~ "Es wurden mehrere Möglichkeiten zum Import der Datei(en) %s gefunden:" #~ msgid "<-- Previous" #~ msgstr "<-- Vorhergehend" #~ msgid "Next -->" #~ msgstr "Nächster -->" #~ msgid "q: quit" #~ msgstr "q:schließen" paperwork-2.2.2/paperwork-shell/l10n/es.po000066400000000000000000000365271456262201400204060ustar00rootroot00000000000000# Spanish translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2023-02-24 02:42+0000\n" "Last-Translator: andres felipe santamaria \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.15.2\n" #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 msgid "Additional text:" msgstr "" #: paperwork-shell/src/paperwork_shell/display/progress.py:39 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/export.py:250 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 msgid "Done" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "comando" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:121 msgid "All done !" msgstr "¡Terminado!" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "Importar archivo(s)" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "Contraseña del PDF" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:62 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:68 msgid "Document to export" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:72 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:81 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:88 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:98 msgid "Next possible filters are:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:106 msgid "a document list" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:108 msgid "a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:110 msgid "pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:112 msgid "Images and text boxes" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:129 msgid "Need at least one filter." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:133 msgid "First filter cannot be '{}'" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:146 #, python-brace-format msgid "Filter mismatch: {0} expects {1} as input. Got {2} instead" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:163 msgid "Last filter will output {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:204 #, python-format msgid "Unknown filters: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:209 msgid "" "Run the command without any filter to have a list of possible filters to " "start with." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:223 msgid "Filter list is complete, but no output file specified (-o)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:244 #, python-format msgid "Exporting to %s ... " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:253 msgid "Export failed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "sub-command" msgstr "sub-comando" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "Sincroniza el/los indice/s con el contenido del directorio de trabajo" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:115 msgid "Synchronizing with work directory ..." msgstr "Sincronizando con el directorio de trabajo..." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:59 msgid "Manage scanner configuration" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:66 msgid "List all scanners and their possible settings" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:71 msgid "Show the currently selected scanner and its settings" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:76 msgid "Define which scanner and which settings to use" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:79 msgid "Scanner to use" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:84 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:90 msgid "Default resolution (dpi ; default=300)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:95 msgid "Examining scanner {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:150 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:172 msgid "ID:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:152 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:173 msgid "Source:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Resolutions:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:174 msgid "Resolution:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:202 msgid "Source {} not found on device. Using another source" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:222 msgid "Default source:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:236 msgid "Resolution {} not available. Adjusted to {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:75 #, python-format msgid "%d problems found:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:90 msgid "- Problem: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:94 msgid "- Possible solution: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:103 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "Fixing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:114 msgid "All fixed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "" paperwork-2.2.2/paperwork-shell/l10n/fr.po000066400000000000000000000504141456262201400203750ustar00rootroot00000000000000# French translations for PACKAGE package # Traductions françaises du paquet PACKAGE. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2021-11-29 21:07+0000\n" "Last-Translator: LAZIC Anna <0.0.0.0.0.ffff.255.255.255.255@gmail.com>\n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 msgid "Additional text:" msgstr "Texte additionnel :" #: paperwork-shell/src/paperwork_shell/display/progress.py:39 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/export.py:250 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 msgid "Done" msgstr "Fait" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "Scan de la page {} (taille prévue : {}x{})…" #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "Page {} scannée (taille finale : {}x{})" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "Fin du bac d'alimentation" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "Page {} créée dans le document {}" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "commande" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "Affiche le contenu d'un document" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "Identifiant du document : %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "Date du document : %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "Page %d" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "Éditer une page" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" "Liste de modificateurs d'images (séparés par des virgules, valeurs " "possibles : {})" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "Modification de {} p{} ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "Original :" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "Enregistrement en haute qualité…" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "Enregistrement…" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:121 msgid "All done !" msgstr "Terminé !" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "Importer" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "Document cible pour l'import" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "Mot de passe du PDF" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "Fichiers à importer" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "Ne sait pas comment importer le(s) fichier(s) %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "Plusieurs manières d'importer les fichier(s) %s ont été trouvées." #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "Veuillez sélectionner la méthode voulue :" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "Chargement des étiquettes …" #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "Import de %s en cours…" #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "Résultat de l'import :" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "- Fichiers importés : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "- Fichiers non-importés : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "- Nouveaux documents : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "- Documents mis à jour : %s" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "Réinitialiser la page" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "Réinitialisation de {} p{}…" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "Réinitialisé :" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "Déplacer une page" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "Document source" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "Page à déplacer" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "Document destination" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "Numéro de page cible" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "Passer la ROC sur un document ou des pages" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "Document sur lequel la ROC doit être faite" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Pages sur lesquelles la ROC doit être passée (un seul entier, une plage, ou " "une liste d'entiers séparés par des virgules, par défaut : toutes les pages)" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "ROC sur {doc_id} page {page_idx}…" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "Commandes pour gérer les étiquettes" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "Commande" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "Documents cibles" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "Document cible" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "Étiquette à ajouter" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "Couleur de l'étiquette (ex : '#aa22cc')" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "Étiquette à retirer" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "Étiquette à supprimer de *tous* les documents" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "Chargement de toutes les étiquettes… " #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "" "Êtes-vous sûr de vouloir effacer l'étiquette '%s' de tous les documents ?" #: paperwork-shell/src/paperwork_shell/cmd/export.py:62 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" "Exporter un document, une page, ou un jeu de pages. Exemple : paperwork-cli " "export 20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/" "pouet.jpg" #: paperwork-shell/src/paperwork_shell/cmd/export.py:68 msgid "Document to export" msgstr "Documents à exporter" #: paperwork-shell/src/paperwork_shell/cmd/export.py:72 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Pages à exporter (un seul entier, une plage, ou une liste séparée par des " "virgules, par défaut : toutes les pages)" #: paperwork-shell/src/paperwork_shell/cmd/export.py:81 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" "Filtres d'export. Indiquez cette option une fois pour chaque filtre à " "appliquer (ex : '-f grayscale -f jpeg')." #: paperwork-shell/src/paperwork_shell/cmd/export.py:88 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" "Fichier/répertoire de sortie. Si non-spécifié, listera les filtres qui " "pourraient être ajoutées après ceux déjà spécifiés." #: paperwork-shell/src/paperwork_shell/cmd/export.py:98 msgid "Next possible filters are:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:106 msgid "a document list" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:108 msgid "a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:110 msgid "pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:112 msgid "Images and text boxes" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:129 msgid "Need at least one filter." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:133 msgid "First filter cannot be '{}'" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:146 #, python-brace-format msgid "Filter mismatch: {0} expects {1} as input. Got {2} instead" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:163 msgid "Last filter will output {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:204 #, python-format msgid "Unknown filters: %s" msgstr "Filtres inconnus : %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:209 msgid "" "Run the command without any filter to have a list of possible filters to " "start with." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:223 msgid "Filter list is complete, but no output file specified (-o)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:244 #, python-format msgid "Exporting to %s ... " msgstr "Export en cours vers %s… " #: paperwork-shell/src/paperwork_shell/cmd/export.py:253 msgid "Export failed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "Gérer les textes additionnels rattachés aux documents" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "sub-command" msgstr "sous-commande" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "Obtenir le texte additionnel d'un document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "Définir le texte additionnel d'un document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "Pas de texte additionnel" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "Scanner des pages" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "Document auquel les pages scannées doivent être ajoutées" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "Synchronise l'index avec le contenu du répertoire de travail" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:115 msgid "Synchronizing with work directory ..." msgstr "Synchronisation avec le répertoire de travail en cours…" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "Version : " #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "Parce-que trier des documents est un travail de machine." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "À propos de Paperwork" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "Chercher des mots-clés dans les documents" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "Nombre maximum de résultats (par défaut : 50)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "Chercher des mots-clés (aucun signifie renvoyer tous les documents)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:59 msgid "Manage scanner configuration" msgstr "Gérer la configuration du scanner" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:66 msgid "List all scanners and their possible settings" msgstr "Lister tous les scanners et leurs réglages possibles" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:71 msgid "Show the currently selected scanner and its settings" msgstr "Afficher le scanner actuellement sélectionné et ses réglages" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:76 msgid "Define which scanner and which settings to use" msgstr "Définir quel scanner et quels réglages utiliser" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:79 msgid "Scanner to use" msgstr "Scanner à utiliser" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:84 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" "Source à utiliser par défaut sur le scanner (si non-spécifié, une source " "sera sélectionnée au hasard)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:90 msgid "Default resolution (dpi ; default=300)" msgstr "Résolution par défaut (ppp, par défaut=300)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:95 msgid "Examining scanner {} ..." msgstr "Examen du scanner {} …" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:150 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:172 msgid "ID:" msgstr "ID :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:152 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:173 msgid "Source:" msgstr "Source :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Resolutions:" msgstr "Résolutions :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:174 msgid "Resolution:" msgstr "Résolution :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:202 msgid "Source {} not found on device. Using another source" msgstr "" "Source {} non-trouvé sur le périphérique. Une autre source va être utilisée" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:222 msgid "Default source:" msgstr "Source par défaut :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:236 msgid "Resolution {} not available. Adjusted to {}." msgstr "Résolution {} non-disponible. Ajustée à {}." #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "Vérifier et corriger l'intégrité du répertoire du travail" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "Corriger les problèmes sans demander" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "Vérification du répertoire de travail …" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "Pas de problème trouvé" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:75 #, python-format msgid "%d problems found:" msgstr "%d problèmes trouvés :" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:90 msgid "- Problem: " msgstr "- Problème : " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:94 msgid "- Possible solution: " msgstr "- Solution possible : " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:103 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" "Voulez-vous corrigez ces problèmes automatiquement en utilisant les " "solutions indiquées ?" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "Fixing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:114 msgid "All fixed !" msgstr "Tous les problèmes ont été corrigés !" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "Effacer un document ou une page" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Pages à effacer (un seul entier, une plage ou une liste séparée par des " "virgules, par défaut : toutes les pages)" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "Suppression du document {doc_id}…" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "Suppression de la page {page_idx} du document {doc_id}…" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "Effacer le document %s ?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "Effacer la/les page(s) {page_indexes} du document {doc_id} ?" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "Changer l'identifiant d'un document" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "Document à renommer" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "Nouveau nom pour le document" #, python-format #~ msgid "Current filters: %s" #~ msgstr "Filtres actuels : %s" #~ msgid "Next possible filters:" #~ msgstr "Filtres suivants possibles :" #, python-brace-format #~ msgid "" #~ "'{filter_name}' is an output filter. No other filter can be added after " #~ "'{filter_name}'." #~ msgstr "" #~ "'{filter_name}' est un filtre de sortie. Aucun autre filtre ne peut être " #~ "ajouté après '{filter_name}'." #~ msgid "No possible filters found" #~ msgstr "Aucun filtre possible trouvé" #~ msgid "Label to remove on *all* documents" #~ msgstr "Étiquette à retirer sur *tous* les documents" #, python-format #~ msgid "Found many ways to import file(s) %s:" #~ msgstr "Plusieurs façons d'importer le(s) fichier(s) %s ont été trouvées :" #~ msgid "<-- Previous" #~ msgstr "<-- Précédent" #~ msgid "Next -->" #~ msgstr "Suivant -->" #~ msgid "q: quit" #~ msgstr "q : quitter" paperwork-2.2.2/paperwork-shell/l10n/messages.pot000066400000000000000000000357561456262201400217750ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 msgid "Additional text:" msgstr "" #: paperwork-shell/src/paperwork_shell/display/progress.py:39 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/export.py:250 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 msgid "Done" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:121 msgid "All done !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:62 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:68 msgid "Document to export" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:72 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:81 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:88 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:98 msgid "Next possible filters are:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:106 msgid "a document list" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:108 msgid "a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:110 msgid "pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:112 msgid "Images and text boxes" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:129 msgid "Need at least one filter." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:133 msgid "First filter cannot be '{}'" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:146 #, python-brace-format msgid "Filter mismatch: {0} expects {1} as input. Got {2} instead" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:163 msgid "Last filter will output {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:204 #, python-format msgid "Unknown filters: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:209 msgid "" "Run the command without any filter to have a list of possible filters to " "start with." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:223 msgid "Filter list is complete, but no output file specified (-o)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:244 #, python-format msgid "Exporting to %s ... " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:253 msgid "Export failed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "sub-command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:115 msgid "Synchronizing with work directory ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:59 msgid "Manage scanner configuration" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:66 msgid "List all scanners and their possible settings" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:71 msgid "Show the currently selected scanner and its settings" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:76 msgid "Define which scanner and which settings to use" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:79 msgid "Scanner to use" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:84 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:90 msgid "Default resolution (dpi ; default=300)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:95 msgid "Examining scanner {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:150 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:172 msgid "ID:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:152 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:173 msgid "Source:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Resolutions:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:174 msgid "Resolution:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:202 msgid "Source {} not found on device. Using another source" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:222 msgid "Default source:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:236 msgid "Resolution {} not available. Adjusted to {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:75 #, python-format msgid "%d problems found:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:90 msgid "- Problem: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:94 msgid "- Possible solution: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:103 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "Fixing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:114 msgid "All fixed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "" paperwork-2.2.2/paperwork-shell/l10n/oc.po000066400000000000000000000503451456262201400203720ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2022-01-05 18:30+0000\n" "Last-Translator: Quentin PAGÈS \n" "Language-Team: Occitan \n" "Language: oc\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" "X-Generator: Weblate 4.9\n" #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 msgid "Additional text:" msgstr "Tèxt addicional :" #: paperwork-shell/src/paperwork_shell/display/progress.py:39 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/export.py:250 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 msgid "Done" msgstr "Fach" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "Numerizacion de la pagina {} (talha prevista : {}x{})…" #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "Pagina {} numerizada (talha finala : {}x{})" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "Fin del cargador de documents" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "Pagina {} creada dins lo document {}" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "comanda" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "Mostrar lo contengut d’un document" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "Identificant del document : %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "Data del document : %s" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "Pagina %d" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "Modificar una pagina" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" "Lista de modificacion d’imatges (separadas per de virgulas, valors " "possiblas : {})" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "Modificacion de {} p{} ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "Original :" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "Enregistrament nauta qualitat…" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "Enregistrament…" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:121 msgid "All done !" msgstr "Acabat !" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "Importar" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "Document cibla per l’import" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "Senhal del PDF" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "Fichièrs d’importar" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "Sap pas cossí importar lo(s) fichièr(s) %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "Mai d’un biais d’importar los fichièrs %s son estats trobats." #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "Volgatz causir lo biais que volètz :" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "Cargament de las etiquetas..." #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "Import de %s en cors…" #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "Resultat de l’import :" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "- Fichièrs importats : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "- Fichièrs pas-importats : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "- Documents novèls : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "- Document actualizats : %s" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "Reïnicializar la pagina" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "Reïnicializacion de {} p{}…" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "Reïnicializat :" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "Desplaçar una pagina" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "Document font" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "Pagina de desplaçar" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "Document destinacion" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "Numèro de pagina cibla" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "Reconeisser los caractèrs d’un document o de las paginas" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "Document d’analizar amb la ROC" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Paginas que la ROC deu èsser passada (un sol entièr, una plaja o una lista " "d'entièrs separats per de virgulas, per defaut : totas las paginas)" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "ROC sus {doc_id} pagina {page_idx}…" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "Comandas per generar las etiquetas" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "Comanda" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "Documents ciblas" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "Document cible" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "Etiqueta d’ajustar" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "Color de l’etiqueta (ex : '#aa22cc')" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "Etiqueta de tirar" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "Etiqueta de suprimir de *totes* los documents" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "Cargament de totas las etiquetas… " #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "" "Volètz vertadièrament suprimir l’etiqueta « %s » de totes los documents ?" #: paperwork-shell/src/paperwork_shell/cmd/export.py:62 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" "Exportar un document, una pagina o un jòc de paginas. Exemple : paperwork-" "cli export 20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/" "pouet.jpg" #: paperwork-shell/src/paperwork_shell/cmd/export.py:68 msgid "Document to export" msgstr "Document d’exportar" #: paperwork-shell/src/paperwork_shell/cmd/export.py:72 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Paginas d’exportar (un sol entièr, una plaja o una lista separada per de " "virgulas, per defaut : totas las paginas)" #: paperwork-shell/src/paperwork_shell/cmd/export.py:81 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" "Filtres d’export. Indicatz aquesta opcion un còp per cada filtre d’aplicar " "(ex : '-f grayscale -f jpeg')." #: paperwork-shell/src/paperwork_shell/cmd/export.py:88 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" "Fichièr/repertòri de sortida. Se pas especificat, listarà los filtres que " "poirián èsster ajustats aprèp los ja especificats." #: paperwork-shell/src/paperwork_shell/cmd/export.py:98 msgid "Next possible filters are:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:106 msgid "a document list" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:108 msgid "a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:110 msgid "pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:112 msgid "Images and text boxes" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:129 msgid "Need at least one filter." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:133 msgid "First filter cannot be '{}'" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:146 #, python-brace-format msgid "Filter mismatch: {0} expects {1} as input. Got {2} instead" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:163 msgid "Last filter will output {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:204 #, python-format msgid "Unknown filters: %s" msgstr "Fichièrs desconeguts : %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:209 msgid "" "Run the command without any filter to have a list of possible filters to " "start with." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:223 msgid "Filter list is complete, but no output file specified (-o)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:244 #, python-format msgid "Exporting to %s ... " msgstr "Export en cors cap a %s… " #: paperwork-shell/src/paperwork_shell/cmd/export.py:253 msgid "Export failed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "Gerir los tèxtes addicionals estacats als documents" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "sub-command" msgstr "jos-comanda" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "Obténer lo tèxt addicional d’un document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "Definir lo tèxt addicional d’un document" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "Cap de tèxt addicional" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "Numerizar paginas" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "Document que deu èsser completat amb las paginas numerizadas" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "Sincronizar l’ensenhador amb lo contengut del repertòri de trabalh" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:115 msgid "Synchronizing with work directory ..." msgstr "Sincronizacion amb lo repertòri de trabalh en cors…" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "Version : " #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "Perque triar los documents es un trabalh per las maquinas." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "A prepaus de Paperwork" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "Cercar de mots clau pels documents" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "Nombre maximum de resultats (per defaut : 50)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "Cercar de mots clau (cap vòl pas dire tornar totes los documents)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:59 msgid "Manage scanner configuration" msgstr "Gerir la configuracion del numerizador" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:66 msgid "List all scanners and their possible settings" msgstr "Listar totes los numerizadors e lors paramètres possibles" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:71 msgid "Show the currently selected scanner and its settings" msgstr "Mostrar lo numerizador actualament seleccionat e sos paramètres" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:76 msgid "Define which scanner and which settings to use" msgstr "Definir quin numerizador e paramètres utilizar" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:79 msgid "Scanner to use" msgstr "Numerizador d’utilizar" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:84 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" "Font d’utilizar per defaut pel numerizador (se pas especificat, una font " "serà causida a l’asard)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:90 msgid "Default resolution (dpi ; default=300)" msgstr "Resolucion per defaut (ppp, per defaut=300)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:95 msgid "Examining scanner {} ..." msgstr "Examèn del numerizador {} …" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:150 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:172 msgid "ID:" msgstr "ID :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:152 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:173 msgid "Source:" msgstr "Font :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Resolutions:" msgstr "Resolucions :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:174 msgid "Resolution:" msgstr "Resolucion :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:202 msgid "Source {} not found on device. Using another source" msgstr "Font {} pas trobada sul periferic. Una autra font serà utilizada" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:222 msgid "Default source:" msgstr "Font per defaut :" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:236 msgid "Resolution {} not available. Adjusted to {}." msgstr "Resolucion {} pas disponibla. Adaptada a {}." #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "Verificar e reglar l’integritat del repertòri de trabalh" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "Demandetz pas de reparar las causas, reparatz-la vosautres" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "Verificacion del repertòri de trabalh..." #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "Cap de problèma pas trobat" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:75 #, python-format msgid "%d problems found:" msgstr "%d problèmas trobats :" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:90 msgid "- Problem: " msgstr "- Problèma : " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:94 msgid "- Possible solution: " msgstr "- Solucion possibla : " #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:103 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" "Volètz reglar aqueles problèmas automaticament en utilizant las solucions " "indicadas ?" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "Fixing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:114 msgid "All fixed !" msgstr "Tot reglat !" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "Escafar un document o un pagina" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Paginas de suprimir (un sol entièr, una plaja o una lista separada per de " "virgulas, per defaut : totas las paginas)" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "Supression del document {doc_id}…" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "Supression de la pagina {page_idx} del document {doc_id}…" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "Escafar lo document %s ?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "Suprimir la/las pagina(s) {page_indexes} del document {doc_id} ?" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "Cambiar l’identificant d’un document" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "Document de renomenar" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "Nom novèl pel document" #, python-format #~ msgid "Current filters: %s" #~ msgstr "Filtres actuals : %s" #~ msgid "Next possible filters:" #~ msgstr "Filtres seguents possibles :" #, python-brace-format #~ msgid "" #~ "'{filter_name}' is an output filter. No other filter can be added after " #~ "'{filter_name}'." #~ msgstr "" #~ "« {filter_name} » es un filtre de sortida. Cap d’autre filtre pòt pas " #~ "èsser ajustar aprèp « {filter_name} »." #~ msgid "No possible filters found" #~ msgstr "Cap de filtre pas trobat" #~ msgid "Label to remove on *all* documents" #~ msgstr "Etiqueta de tirar sus *totes* los documents" #, python-format #~ msgid "Found many ways to import file(s) %s:" #~ msgstr "" #~ "Mantunas manièras d’importar lo(s) fichi(s) %s son estadas trobadas :" #~ msgid "<-- Previous" #~ msgstr "<-- Precedent" #~ msgid "Next -->" #~ msgstr "Seguent -->" #~ msgid "q: quit" #~ msgstr "q : sortir" paperwork-2.2.2/paperwork-shell/l10n/sv.po000066400000000000000000000411171456262201400204160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-10-10 16:38+0200\n" "PO-Revision-Date: 2021-01-05 10:31+0000\n" "Last-Translator: Ã…ke Engelbrektson \n" "Language-Team: Swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Weblate 4.4\n" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "Ändra en dokumentidentifierare" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "Dokument att byta namn pÃ¥" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "Nytt namn pÃ¥ dokumentet" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "Sök nyckelord i dokument" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "Max antal träffar (standard: 50)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "Sök nyckelord (inget innebär alla dokument)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:92 #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #, python-format msgid "Document id: %s" msgstr "Dokument-ID: %s" #: paperwork-shell/src/paperwork_shell/cmd/search.py:97 #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #, python-format msgid "Document date: %s" msgstr "Dokumentdatum: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:57 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" "Exportera ett dokument, en sida eller en uppsättning sidor. Exempel: " "paperwork-cli export 20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg " "-o ~/tmp/pouet.jpg" #: paperwork-shell/src/paperwork_shell/cmd/export.py:63 msgid "Document to export" msgstr "Dokument att exportera" #: paperwork-shell/src/paperwork_shell/cmd/export.py:67 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Sidor att exportera (enkelt heltal, intervall eller kommaseparerad lista. " "Standard: Alla sidor)" #: paperwork-shell/src/paperwork_shell/cmd/export.py:76 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" "Exportfilter. Specificera detta alternativ en gÃ¥ng för varje filter som " "skall tillämpas (exempel: '-f grayscale -f jpeg')." #: paperwork-shell/src/paperwork_shell/cmd/export.py:83 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" "Utdatafil/-mapp. Om ej specificerat, listas de filter som kan kopplas, efter " "de redan specificerade." #: paperwork-shell/src/paperwork_shell/cmd/export.py:119 #, python-format msgid "Unknown filters: %s" msgstr "Okända filter: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:141 #, python-format msgid "Current filters: %s" msgstr "Aktuella filter: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:144 msgid "Next possible filters:" msgstr "Nästa möjliga filter:" #: paperwork-shell/src/paperwork_shell/cmd/export.py:149 #, python-brace-format msgid "" "'{filter_name}' is an output filter. No other filter can be added after " "'{filter_name}'." msgstr "" "\"{filter_name}\" är ett utdatafilter. Inget annat filter kan läggas till " "efter \"{filter_name}\"." #: paperwork-shell/src/paperwork_shell/cmd/export.py:153 msgid "No possible filters found" msgstr "Inga möjliga filter hittades" #: paperwork-shell/src/paperwork_shell/cmd/export.py:170 #, python-format msgid "Exporting to %s ... " msgstr "Exporterar till %s... " #: paperwork-shell/src/paperwork_shell/cmd/export.py:175 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/import.py:133 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 #: paperwork-shell/src/paperwork_shell/display/progress.py:39 msgid "Done" msgstr "Klart" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "Skanna sidor" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "Dokument som de skannade sidorna mÃ¥ste läggas till" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "Kommando för att hantera etiketter" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "etikettkommando" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "MÃ¥ldokument" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "MÃ¥ldokument" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "Etikett att lägga till" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "Etikettfärg (exempel: #aa22cc)" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "Etikett att ta bort" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to remove on *all* documents" msgstr "Etikett att ta bort frÃ¥n *alla* dokument" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "Läser in alla etiketter... " #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "Vill du verkligen ta bort etiketten \"%s\" frÃ¥n alla dokumen?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "Ta bort dokument eller en sida" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Sidor att ta bort (enkelt heltal, intervall eller kommaseparerad lista. " "Standard: Alla sidor)" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "Tar bort dokument {doc_id}..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "Tar bort sida {page_idx} frÃ¥n dokument {doc_id}..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "Vill du ta bort dokument %s?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "Vill du ta bort sida/sidor {page_indexes} frÃ¥n dokument {doc_id}?" #: paperwork-shell/src/paperwork_shell/cmd/import.py:62 msgid "Import file(s)" msgstr "Importera fil(er)" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Target document for import" msgstr "MÃ¥ldokument för import" #: paperwork-shell/src/paperwork_shell/cmd/import.py:71 msgid "Files to import" msgstr "Filer att importera" #: paperwork-shell/src/paperwork_shell/cmd/import.py:99 #, python-format msgid "Don't know how to import file(s) %s" msgstr "Vet inte hur filen/filerna %s importeras" #: paperwork-shell/src/paperwork_shell/cmd/import.py:112 #, python-format msgid "Found many ways to import file(s) %s:" msgstr "Hittade mÃ¥nga sätt att importera filen/filerna %s:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:125 #, python-format msgid "Importing %s ..." msgstr "Importerar %s..." #: paperwork-shell/src/paperwork_shell/cmd/import.py:134 msgid "Import result:" msgstr "Importresultat:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:135 #, python-format msgid "- Imported files: %s" msgstr "- Importerade filer: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:136 #, python-format msgid "- Non-imported files: %s" msgstr "- Icke importerade filer: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:137 #, python-format msgid "- New documents: %s" msgstr "- Nya dokument: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:138 #, python-format msgid "- Updated documents: %s" msgstr "- Uppdaterade dokument: %s" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "Redigera sida" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "Lista alla bildmodifierare (kommaseparerade, möjliga värden: {})" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "Ändrar dokument {} sida {}..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "Original:" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "Genererar i hög kvalitet och sparar..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "Tillämpar..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 msgid "All done !" msgstr "Klart!" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Version: " msgstr "Version: " #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:87 msgid "Because sorting documents is a machine's job." msgstr "Eftersom sortering av dokument är ett maskinjobb." #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:160 msgid "About Paperwork" msgstr "Om Paperwork" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:211 msgid "<-- Previous" msgstr "<-- FöregÃ¥ende" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:213 msgid "Next -->" msgstr "Nästa -->" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:214 msgid "q: quit" msgstr "q: avsluta" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "OCR-dokument eller -sidor" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "Dokument som OCR mÃ¥ste köras pÃ¥" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" "Sidor till OCR (enkelt heltal, intervall eller kommaseparerad lista. " "Standard: Alla sidor)" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "Kör OCR pÃ¥ dokument {doc_id} sida {page_idx}..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "Ã…terställ en sida till ursprungligt innehÃ¥ll" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "Ã…terställer dokument {} sida {}..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "Ã…terställt:" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "Flytta en sida" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "Källdokument" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "Sida att ta bort" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "Destination" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "MÃ¥lsidans nummer" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:55 msgid "Manage scanner configuration" msgstr "Hantera skannerkonfiguration" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:58 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 msgid "sub-command" msgstr "underkommando" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "List all scanners and their possible settings" msgstr "Lista alla skannrar och dess eventuella inställningar" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:67 msgid "Show the currently selected scanner and its settings" msgstr "Visa aktuell skanner och dess inställningar" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:72 msgid "Define which scanner and which settings to use" msgstr "Ange vilken skanner och vilka inställningar som skall användas" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:75 msgid "Scanner to use" msgstr "Skanner att använda" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:80 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" "Standardkälla att använda pÃ¥ skanner (om inget specificeras kommer en att " "väljas slumpmässigt)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:86 msgid "Default resolution (dpi ; default=300)" msgstr "Standardupplösning (dpi ; standard=300)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:91 msgid "Examining scanner {} ..." msgstr "Undersöker skanner {}..." #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:131 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:153 msgid "ID:" msgstr "ID:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:133 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Source:" msgstr "Källa:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:135 msgid "Resolutions:" msgstr "Upplösningar:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:155 msgid "Resolution:" msgstr "Upplösning:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:183 msgid "Source {} not found on device. Using another source" msgstr "Källa {} inte hittad pÃ¥ enheten. Använder annan källa." #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:203 msgid "Default source:" msgstr "Standardkälla:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:217 msgid "Resolution {} not available. Adjusted to {}." msgstr "Upplösning {} inte tillgänglig. Justerad till {}." #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "Visa innehÃ¥llet i ett dokument" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "Sida %d" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "Synkronisera index med innehÃ¥llet i arbetsmappen" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 msgid "Synchronizing with work directory ..." msgstr "Synkroniserar med arbetsmapp..." #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "Hantera ytterligare text bifogad till dokument" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "Hämta ett dokuments ytterligare text" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "Ange ytterligare text i ett dokument" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 msgid "Additional text:" msgstr "Ytterligare text:" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "Ingen ytterligare text" #: paperwork-shell/src/paperwork_shell/main.py:67 msgid "command" msgstr "kommando" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "Skannar sida {} (förväntad storlek: {}x{})..." #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "Sida {} skannad (egentlig storlek: {}x{})" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "Slut pÃ¥ pappersmatning" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "Sida {} i dokument {} skapad" paperwork-2.2.2/paperwork-shell/l10n/uk.po000066400000000000000000000361361456262201400204120ustar00rootroot00000000000000# Ukrainian translations for PACKAGE package. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Automatically generated, 2020. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2023-03-28 18:09+0200\n" "PO-Revision-Date: 2020-05-03 15:37+0200\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=ASCII\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 msgid "Additional text:" msgstr "" #: paperwork-shell/src/paperwork_shell/display/progress.py:39 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/import.py:165 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/export.py:250 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 msgid "Done" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "" #: paperwork-shell/src/paperwork_shell/main.py:68 msgid "command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #: paperwork-shell/src/paperwork_shell/cmd/search.py:93 #, python-format msgid "Document id: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #: paperwork-shell/src/paperwork_shell/cmd/search.py:98 #, python-format msgid "Document date: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:121 msgid "All done !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Import file(s)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:72 msgid "Target document for import" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:76 msgid "PDF password" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:80 msgid "Files to import" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:108 #, python-format msgid "Don't know how to import file(s) %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:121 #, python-format msgid "Found many ways to import file(s) %s." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:122 msgid "Please select the way you want:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:140 msgid "Loading labels ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:157 #, python-format msgid "Importing %s ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:166 msgid "Import result:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:167 #, python-format msgid "- Imported files: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:168 #, python-format msgid "- Non-imported files: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:169 #, python-format msgid "- New documents: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/import.py:170 #, python-format msgid "- Updated documents: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to delete from *all* documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:62 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:68 msgid "Document to export" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:72 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:81 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:88 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:98 msgid "Next possible filters are:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:106 msgid "a document list" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:108 msgid "a document" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:110 msgid "pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:112 msgid "Images and text boxes" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:129 msgid "Need at least one filter." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:133 msgid "First filter cannot be '{}'" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:146 #, python-brace-format msgid "Filter mismatch: {0} expects {1} as input. Got {2} instead" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:163 msgid "Last filter will output {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:204 #, python-format msgid "Unknown filters: %s" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:209 msgid "" "Run the command without any filter to have a list of possible filters to " "start with." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:223 msgid "Filter list is complete, but no output file specified (-o)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:244 #, python-format msgid "Exporting to %s ... " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:253 msgid "Export failed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "sub-command" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:115 msgid "Synchronizing with work directory ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:82 msgid "Version: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Because sorting documents is a machine's job." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:158 msgid "About Paperwork" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:59 msgid "Manage scanner configuration" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:66 msgid "List all scanners and their possible settings" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:71 msgid "Show the currently selected scanner and its settings" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:76 msgid "Define which scanner and which settings to use" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:79 msgid "Scanner to use" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:84 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:90 msgid "Default resolution (dpi ; default=300)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:95 msgid "Examining scanner {} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:150 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:172 msgid "ID:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:152 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:173 msgid "Source:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Resolutions:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:174 msgid "Resolution:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:202 msgid "Source {} not found on device. Using another source" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:222 msgid "Default source:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:236 msgid "Resolution {} not available. Adjusted to {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:41 msgid "Check and fix work directory integrity" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:45 msgid "Don't ask to fix things, just fix them" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:63 msgid "Checking work directory ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:70 msgid "No problem found" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:75 #, python-format msgid "%d problems found:" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:90 msgid "- Problem: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:94 msgid "- Possible solution: " msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:103 msgid "" "Do you want to fix those problems automatically using the indicated " "solutions ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:111 msgid "Fixing ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py:114 msgid "All fixed !" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "" paperwork-2.2.2/paperwork-shell/l10n/zh_Hans.po000066400000000000000000000374061456262201400213660ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2020-10-10 16:38+0200\n" "PO-Revision-Date: 2021-02-07 12:49+0000\n" "Last-Translator: 玉堂白鹤 \n" "Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: Weblate 4.4\n" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:50 msgid "Change a document identifier" msgstr "更改文档标识符" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:54 msgid "Document to rename" msgstr "需è¦é‡å‘½å的文档" #: paperwork-shell/src/paperwork_shell/cmd/rename.py:58 msgid "New name for the document" msgstr "新文档å" #: paperwork-shell/src/paperwork_shell/cmd/search.py:63 msgid "Search keywords in documents" msgstr "æœç´¢æ–‡æ¡£ä¸­çš„关键字" #: paperwork-shell/src/paperwork_shell/cmd/search.py:67 msgid "Maximum number of results (default: 50)" msgstr "最大结果数 (默认值: 50)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:71 msgid "Search keywords (none means all documents)" msgstr "æœç´¢å…³é”®å­— (none 代表所有文档)" #: paperwork-shell/src/paperwork_shell/cmd/search.py:92 #: paperwork-shell/src/paperwork_shell/cmd/show.py:81 #, python-format msgid "Document id: %s" msgstr "文档 id: %s" #: paperwork-shell/src/paperwork_shell/cmd/search.py:97 #: paperwork-shell/src/paperwork_shell/cmd/show.py:87 #, python-format msgid "Document date: %s" msgstr "文档日期:%s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:57 msgid "" "Export a document, a page, or a set of pages. Example: paperwork-cli export " "20150303_2314_39 -p 2 -f img_boxes -f grayscale -f jpeg -o ~/tmp/pouet.jpg" msgstr "" "导出文档,页é¢ï¼Œæˆ–一组页é¢ã€‚示例: paperwork-cli export 20150303_2314_39 -p 2 -f img_boxes -f " "grayscale -f jpeg -o ~/tmp/pouet.jpg" #: paperwork-shell/src/paperwork_shell/cmd/export.py:63 msgid "Document to export" msgstr "导出的文档" #: paperwork-shell/src/paperwork_shell/cmd/export.py:67 msgid "" "Pages to export (single integer, range or comma-separated list, default: all " "pages)" msgstr "è¦å¯¼å‡ºçš„é¡µé¢ (å•个整数,范围或者使用逗å·åˆ†éš”的列表,默认为所有页é¢)" #: paperwork-shell/src/paperwork_shell/cmd/export.py:76 msgid "" "Export filters. Specify this option once for each filter to apply (ex: '-f " "grayscale -f jpeg')." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:83 msgid "" "Output file/directory. If not specified, will list the filters that could be " "chained after those already specified." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/export.py:119 #, python-format msgid "Unknown filters: %s" msgstr "未知过滤器 : %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:141 #, python-format msgid "Current filters: %s" msgstr "当å‰è¿‡æ»¤å™¨: %s" #: paperwork-shell/src/paperwork_shell/cmd/export.py:144 msgid "Next possible filters:" msgstr "下一个å¯èƒ½çš„过滤器 :" #: paperwork-shell/src/paperwork_shell/cmd/export.py:149 #, python-brace-format msgid "" "'{filter_name}' is an output filter. No other filter can be added after " "'{filter_name}'." msgstr "'{filter_name}' 是一个输出过滤器。ä¸èƒ½åœ¨ '{filter_name}' ä¹‹åŽæ·»åŠ å…¶ä»–è¿‡æ»¤å™¨ã€‚" #: paperwork-shell/src/paperwork_shell/cmd/export.py:153 msgid "No possible filters found" msgstr "找ä¸åˆ°å¯èƒ½çš„过滤器" #: paperwork-shell/src/paperwork_shell/cmd/export.py:170 #, python-format msgid "Exporting to %s ... " msgstr "导出到 %s ... " #: paperwork-shell/src/paperwork_shell/cmd/export.py:175 #: paperwork-shell/src/paperwork_shell/cmd/label.py:101 #: paperwork-shell/src/paperwork_shell/cmd/import.py:133 #: paperwork-shell/src/paperwork_shell/cmd/edit.py:183 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:102 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:131 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:89 #: paperwork-shell/src/paperwork_shell/display/progress.py:39 msgid "Done" msgstr "完æˆ" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:51 msgid "Scan pages" msgstr "扫æé¡µé¢" #: paperwork-shell/src/paperwork_shell/cmd/scan.py:55 msgid "Document to which the scanned pages must be added" msgstr "必须添加扫æé¡µé¢çš„æ–‡æ¡£" #: paperwork-shell/src/paperwork_shell/cmd/label.py:58 msgid "Commands to manage labels" msgstr "标签管ç†å‘½ä»¤" #: paperwork-shell/src/paperwork_shell/cmd/label.py:61 msgid "label command" msgstr "标签命令" #: paperwork-shell/src/paperwork_shell/cmd/label.py:68 #: paperwork-shell/src/paperwork_shell/cmd/delete.py:74 msgid "Target documents" msgstr "目标文档" #: paperwork-shell/src/paperwork_shell/cmd/label.py:72 #: paperwork-shell/src/paperwork_shell/cmd/label.py:80 msgid "Target document" msgstr "目标文档" #: paperwork-shell/src/paperwork_shell/cmd/label.py:73 msgid "Label to add" msgstr "è¦æ·»åŠ çš„æ ‡ç­¾" #: paperwork-shell/src/paperwork_shell/cmd/label.py:76 msgid "Label color (ex: '#aa22cc')" msgstr "标签颜色 (例如 '#aa22cc')" #: paperwork-shell/src/paperwork_shell/cmd/label.py:81 msgid "Label to remove" msgstr "è¦ç§»é™¤çš„æ ‡ç­¾" #: paperwork-shell/src/paperwork_shell/cmd/label.py:85 msgid "Label to remove on *all* documents" msgstr "è¦åœ¨ *所有*文档移除的标签" #: paperwork-shell/src/paperwork_shell/cmd/label.py:90 msgid "Loading all labels ... " msgstr "加载所有标签 ... " #: paperwork-shell/src/paperwork_shell/cmd/label.py:178 #, python-format msgid "Are you sure you want to delete label '%s' from all documents ?" msgstr "确定è¦ä»Žæ‰€æœ‰æ–‡æ¡£ä¸­åˆ é™¤æ ‡ç­¾'%s' å—?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:62 msgid "Delete a document or a page" msgstr "删除文档或页é¢" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:67 msgid "" "Pages to delete (single integer, range or comma-separated list, default: all " "pages)" msgstr "è¦åˆ é™¤çš„é¡µé¢ (å•个整数ã€èŒƒå›´æˆ–使用逗å·åˆ†éš”的列表,默认值为所有页é¢)" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:90 #, python-brace-format msgid "Deleting document {doc_id} ..." msgstr "删除文档 {doc_id} ..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:91 #, python-brace-format msgid "Deleting page {page_idx} of document {doc_id} ..." msgstr "删除文档 {doc_id}中的{page_idx}é¡µé¢ ..." #: paperwork-shell/src/paperwork_shell/cmd/delete.py:97 #, python-format msgid "Delete document %s ?" msgstr "删除文档 %s ?" #: paperwork-shell/src/paperwork_shell/cmd/delete.py:103 #, python-brace-format msgid "Delete page(s) {page_indexes} of document {doc_id} ?" msgstr "删除文档 {doc_id} 中的 {page_indexes} é¡µé¢ ?" #: paperwork-shell/src/paperwork_shell/cmd/import.py:62 msgid "Import file(s)" msgstr "导入文件" #: paperwork-shell/src/paperwork_shell/cmd/import.py:67 msgid "Target document for import" msgstr "è¦å¯¼å…¥çš„目标文档" #: paperwork-shell/src/paperwork_shell/cmd/import.py:71 msgid "Files to import" msgstr "è¦å¯¼å…¥çš„æ–‡ä»¶" #: paperwork-shell/src/paperwork_shell/cmd/import.py:99 #, python-format msgid "Don't know how to import file(s) %s" msgstr "ä¸çŸ¥é“如何导入文件%s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:112 #, python-format msgid "Found many ways to import file(s) %s:" msgstr "找到多ç§å¯¼å…¥æ–‡ä»¶ %s 的方法:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:125 #, python-format msgid "Importing %s ..." msgstr "正在导入 %s ..." #: paperwork-shell/src/paperwork_shell/cmd/import.py:134 msgid "Import result:" msgstr "导入结果:" #: paperwork-shell/src/paperwork_shell/cmd/import.py:135 #, python-format msgid "- Imported files: %s" msgstr "-导入文件: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:136 #, python-format msgid "- Non-imported files: %s" msgstr "- 未导入的文件 : %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:137 #, python-format msgid "- New documents: %s" msgstr "- 新文档: %s" #: paperwork-shell/src/paperwork_shell/cmd/import.py:138 #, python-format msgid "- Updated documents: %s" msgstr "- 更新文档: %s" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:95 msgid "Edit page" msgstr "编辑页é¢" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:99 msgid "List of image modifiers (comma separated, possible values: {})" msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:122 msgid "Modifying document {} page {} ..." msgstr "修改文档 {} é¡µé¢ {} ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:126 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:112 msgid "Original:" msgstr "原件:" #: paperwork-shell/src/paperwork_shell/cmd/edit.py:147 msgid "Generating in high quality and saving ..." msgstr "高质é‡ç”Ÿæˆå¹¶ä¿å­˜ ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:175 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:123 msgid "Committing ..." msgstr "æäº¤ä¸­ ..." #: paperwork-shell/src/paperwork_shell/cmd/edit.py:184 #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:107 #: paperwork-shell/src/paperwork_shell/cmd/reset.py:132 #: paperwork-shell/src/paperwork_shell/cmd/sync.py:79 msgid "All done !" msgstr "å…¨éƒ¨å®Œæˆ !" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:84 msgid "Version: " msgstr "版本: " #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:87 msgid "Because sorting documents is a machine's job." msgstr "å› ä¸ºæ•´ç†æ–‡ä»¶æ˜¯æœºå™¨çš„工作。" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:160 msgid "About Paperwork" msgstr "关于 Paperwork" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:211 msgid "<-- Previous" msgstr "<-- 上一ä½" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:213 msgid "Next -->" msgstr "ä¸‹ä¸€ä½ -->" #: paperwork-shell/src/paperwork_shell/cmd/about/__init__.py:214 msgid "q: quit" msgstr "q: 退出" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:50 msgid "OCR document or pages" msgstr "OCR 文档或页é¢" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:55 msgid "Document on which OCR must be run" msgstr "å¿…é¡»è¿è¡Œ OCR 的文档" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:60 msgid "" "Pages to OCR (single integer, range or comma-separated list, default: all " "pages)" msgstr "OCR é¡µé¢ (å•个整数ã€èŒƒå›´æˆ–使用逗å·åˆ†éš”的列表,默认值为所有页é¢)" #: paperwork-shell/src/paperwork_shell/cmd/ocr.py:91 #, python-brace-format msgid "Running OCR on document {doc_id} page {page_idx} ..." msgstr "在文档 {doc_id} çš„é¡µé¢ {page_idx} 上è¿è¡Œ OCR ..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:70 msgid "Reset a page to its original content" msgstr "将页é¢é‡ç½®ä¸ºå…¶åŽŸå§‹å†…å®¹" #: paperwork-shell/src/paperwork_shell/cmd/reset.py:108 msgid "Reseting document {} page {} ..." msgstr "é‡ç½®æ–‡æ¡£ {} é¡µé¢ {} ..." #: paperwork-shell/src/paperwork_shell/cmd/reset.py:118 msgid "Reseted:" msgstr "é‡ç½®:" #: paperwork-shell/src/paperwork_shell/cmd/move.py:58 msgid "Move a page" msgstr "移动页é¢" #: paperwork-shell/src/paperwork_shell/cmd/move.py:62 msgid "Source document" msgstr "æºæ–‡æ¡£" #: paperwork-shell/src/paperwork_shell/cmd/move.py:66 msgid "Page to move" msgstr "è¦ç§»åŠ¨çš„é¡µé¢" #: paperwork-shell/src/paperwork_shell/cmd/move.py:70 msgid "Destination document" msgstr "目标文档" #: paperwork-shell/src/paperwork_shell/cmd/move.py:74 msgid "Target page number" msgstr "目标页ç " #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:55 msgid "Manage scanner configuration" msgstr "ç®¡ç†æ‰«æä»ªé…ç½®" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:58 #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:48 msgid "sub-command" msgstr "å­å‘½ä»¤" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:62 msgid "List all scanners and their possible settings" msgstr "列出所有扫æä»ªåŠå…¶å¯èƒ½çš„设置" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:67 msgid "Show the currently selected scanner and its settings" msgstr "显示当å‰é€‰å®šçš„æ‰«æä»ªåŠå…¶è®¾ç½®" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:72 msgid "Define which scanner and which settings to use" msgstr "明确è¦ä½¿ç”¨çš„æ‰«æä»ªå’Œè®¾ç½®" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:75 msgid "Scanner to use" msgstr "è¦ä½¿ç”¨çš„æ‰«æä»ª" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:80 msgid "" "Default source on the scanner to use (if not specified, one will be selected " "randomly)" msgstr "扫æä»ªä¸Šè¦ä½¿ç”¨çš„é»˜è®¤æº (å¦‚æžœæœªæŒ‡å®šï¼Œå°†éšæœºé€‰æ‹©ä¸€ä¸ª)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:86 msgid "Default resolution (dpi ; default=300)" msgstr "默认分辨率 (dpi ; 默认值=300)" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:91 msgid "Examining scanner {} ..." msgstr "检查扫æä»ª {} ..." #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:131 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:153 msgid "ID:" msgstr "ID:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:133 #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:154 msgid "Source:" msgstr "æº:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:135 msgid "Resolutions:" msgstr "分辨率:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:155 msgid "Resolution:" msgstr "分辨率:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:183 msgid "Source {} not found on device. Using another source" msgstr "在设备上找ä¸åˆ°æº {}。使用其他æº" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:203 msgid "Default source:" msgstr "默认æº:" #: paperwork-shell/src/paperwork_shell/cmd/scanner.py:217 msgid "Resolution {} not available. Adjusted to {}." msgstr "" #: paperwork-shell/src/paperwork_shell/cmd/show.py:51 msgid "Show the content of a document" msgstr "显示文档的内容" #: paperwork-shell/src/paperwork_shell/cmd/show.py:99 #, python-format msgid "Page %d" msgstr "é¡µé¢ %d" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:57 msgid "Synchronize the index(es) with the content of the work directory" msgstr "å°†ç´¢å¼•ä¸Žå·¥ä½œç›®å½•çš„å†…å®¹åŒæ­¥" #: paperwork-shell/src/paperwork_shell/cmd/sync.py:68 msgid "Synchronizing with work directory ..." msgstr "ä¸Žå·¥ä½œç›®å½•åŒæ­¥ ..." #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:43 msgid "Manage additional text attached to documents" msgstr "管ç†é™„加到文档的其他文本" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:52 msgid "Get a document additional text" msgstr "èŽ·å–æ–‡æ¡£é™„加文本" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:57 msgid "Set a document additional text" msgstr "设置文档附加文本" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:79 #: paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py:32 msgid "Additional text:" msgstr "附加文本:" #: paperwork-shell/src/paperwork_shell/cmd/extra_text.py:82 msgid "No additional text" msgstr "无附加文本" #: paperwork-shell/src/paperwork_shell/main.py:67 msgid "command" msgstr "命令" #: paperwork-shell/src/paperwork_shell/display/scan.py:86 msgid "Scanning page {} (expected size: {}x{}) ..." msgstr "正在扫æé¡µé¢ {} (预计大å°: {}x{}) ..." #: paperwork-shell/src/paperwork_shell/display/scan.py:127 msgid "Page {} scanned (actual size: {}x{})" msgstr "é¡µé¢ {} 已扫æ (实际大å°: {}x{})" #: paperwork-shell/src/paperwork_shell/display/scan.py:135 msgid "End of paper feed" msgstr "" #: paperwork-shell/src/paperwork_shell/display/scan.py:151 msgid "Page {} in document {} created" msgstr "é¡µé¢ {} ä½äºŽæ–‡æ¡£ {} 中已被创建" paperwork-2.2.2/paperwork-shell/pyproject.toml000066400000000000000000000015071456262201400215670ustar00rootroot00000000000000[project] name = "paperwork-shell" description = "Paperwork's shell interface" dynamic = ["version"] authors = [ {name = "Jerome Flesch", email = "jflesch@openpaper.work" }, ] license = {text = "GPL-3.0-or-later"} readme = {file = "README.markdown", content-type = "text/markdown"} dependencies = [ "openpaperwork-core", "paperwork-backend", "fabulous", "rich", ] [project.optional-dependencies] dev = [ "pytest", ] lint = [ "flake8", ] [project.scripts] paperwork-cli = 'paperwork_shell.main:cli_main' paperwork-json = 'paperwork_shell.main:json_main' [tool.setuptools_scm] root = ".." relative_to = "__file__" write_to = "paperwork-shell/src/paperwork_shell/_version.py" version_scheme = "post-release" [build-system] requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] build-backend = "setuptools.build_meta" paperwork-2.2.2/paperwork-shell/src/000077500000000000000000000000001456262201400174375ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/000077500000000000000000000000001456262201400226405ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/__init__.py000066400000000000000000000001151456262201400247460ustar00rootroot00000000000000import gettext def _(s): return gettext.dgettext('paperwork_shell', s) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/000077500000000000000000000000001456262201400234035ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/__init__.py000066400000000000000000000000001456262201400255020ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/about/000077500000000000000000000000001456262201400245155ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/about/__init__.py000066400000000000000000000114171456262201400266320ustar00rootroot00000000000000import random import fabulous.image import fabulous.text import rich.text import openpaperwork_core from ... import _ # XXX(Jflesch): crappy workaround for an unmaintained library ... fabulous.image.basestring = str VALIDATED_FONTS = """ comic Comic_Sans_MS Comic_Sans_MS_Bold comicbd LiberationMono-Bold LiberationSans-Bold times timesbd FreeMono FreeMonoBold FreeMonoBoldOblique FreeMonoOblique FreeSans FreeSansBold FreeSansBoldOblique FreeSansOblique FreeSerif FreeSerifBold FreeSerifBoldItalic FreeSerifItalic """.strip().split() # to make copy and paste faster COLORS = [ '#0099ff', '#ff4400', '#00bd22', '#bf00ff', ] class Paperwork(object): def __init__(self, core, fonts): self.core = core self.fonts = fonts def show(self, console): nb_lines = 0 logo = self.core.call_success( "resources_get_file", "paperwork_shell.cmd.about", "logo.png" ) logo = self.core.call_success("fs_unsafe", logo) logo = fabulous.image.Image(logo, width=60) logo = logo.reduce(logo.convert()) for line in logo: console.print(rich.text.Text.from_ansi((16 * " ") + line)) nb_lines += 1 font = "FreeSans" if font not in self.fonts: font = self.fonts[0] txt = fabulous.text.Text( "Paperwork", skew=5, color="#abcdef", font=font, fsize=25, shadow=False ) for line in txt: console.print(rich.text.Text.from_ansi(line)) nb_lines += 1 console.print("Paperwork") console.print( (8 * " ") + _('Version: ') + self.core.call_success("app_get_version") ) console.print( (8 * " ") + _("Because sorting documents is a machine's job.") ) nb_lines += 3 return nb_lines class Section(object): def __init__(self, name, authors, fonts): self.name = name self.authors = authors self.fonts = fonts @staticmethod def _group_small_words(words): buf = [] for word in words: buf.append(word) if len(word) > 3: yield " ".join(buf) buf = [] if len(buf) > 0: yield " ".join(buf) def show(self, console): nb_lines = 0 color = random.choice(COLORS) font = random.choice(self.fonts) words = self.name.split() for word in self._group_small_words(words): txt = fabulous.text.Text( word, skew=0, color=color, font=font, fsize=18, shadow=False ) for line in txt: console.print(rich.text.Text.from_ansi(line)) nb_lines += 1 console.print(self.name) nb_lines += 1 for author in self.authors: txt = author[1] if author[2] > 0: txt += " ({})".format(author[2]) console.print((8 * " ") + txt) nb_lines += 1 return nb_lines class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { 'interface': 'app', 'defaults': ['paperwork_backend.app'], }, { 'interface': 'authors', 'defaults': ['paperwork_backend.authors'], }, { 'interface': 'fs', 'defaults': ['openpaperwork_core.fs.python'], }, { 'interface': 'resources', 'defaults': ['openpaperwork_core.resources.setuptools'], }, ] def cmd_complete_argparse(self, parser): parser.add_parser('about', help=_("About Paperwork")) def cmd_run(self, console, args): if args.command != 'about': return None fonts = self._get_available_fonts() sections = {} self.core.call_all("authors_get", sections) sections = [x for x in sections.items()] sections.sort(key=lambda x: x[0].lower()) sections = ( [Paperwork(self.core, fonts)] + [Section(k, v, fonts) for (k, v) in sections if len(v) >= 0] ) for section in sections: section.show(console) if section != sections[-1]: for x in range(0, 7): console.print("") console.print("") console.print("") def _get_available_fonts(self): all_fonts = fabulous.text.get_font_files() all_fonts = {n for n in all_fonts.keys()} out = [] for font in VALIDATED_FONTS: if font not in all_fonts: continue out.append(font) return out paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/about/logo.png000066400000000000000000000030301456262201400261570ustar00rootroot00000000000000‰PNG  IHDR ‰ãn<gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDª#2tIMEäEíª·IDATXÃí“yPÔeÆŸ‚]Y;¤ùY’N*üÈÜ=¤Ú¤ýlHÕûÄñy_ÝÉt"ÚöëiŒÄê²Kæ¸ûhÔ¤³ýU6[úYZ|'vÒQ`hëpƒP P ¼˜ö ”m?ÜRäí?ï»|åµ ŽÃ¡ðÏ, De~ª/ÍðÙWØ9LÓG(%I†Õ§È¼±d¡˜¼·‘ÔJ;žT…q™<Ô^ærFۉߌªž,£ì ñé{¶*뺿“,²&‹¿!Ü&…˜Žå¯×wïº w²´“žb› ¢°ƒÝL ªšæg¬%Ó²´ýÊ.UVªB[šËÙÈʶ M̪†¨Câ_Pþ”ãgcC§ù)òU÷3µ££ó–ùê[;9jîÆxeP`žò¦‰JÙ´UÈz&¯w×®‰þè ˜öéb° @p¿éþ—T¦\ýá³Mï-2|ôÉ4@w@öÁlãu‘>ÎÍÎщµ"µ£0ÌÞšàâzÄ8~ýª.ÊÀ&xwÊøEËåÞw}ŠW<ŸÙÌ™,É99{þ[ÉÉQ—OwèQšˆ=º¡€ä Ç=•~­Þƒõgçͬvé¼]¤›:¡«£Ík^%¢¢ÏQûœŒô%tEXtdate:create2020-06-27T22:14:27+00:00vP2ü%tEXtdate:modify2020-06-27T22:14:27+00:00 Š@>tEXtsvg:comment Created with Inkscape (http://www.inkscape.org/) þEG³tEXtsvg:title 8#NIEND®B`‚paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/chkworkdir.py000066400000000000000000000067111456262201400261310ustar00rootroot00000000000000try: # Fabulous is available and installed on GNU/Linux systems, but not on # Windows. Still this command can be called on Windows systems using # "paperwork-json" import fabulous import fabulous.color FABULOUS_AVAILABLE = True except (ImportError, ValueError): FABULOUS_AVAILABLE = False import openpaperwork_core import openpaperwork_core.cmd.util from .. import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { 'interface': 'chkworkdir', 'defaults': [ 'paperwork_backend.chkworkdir.empty_doc', 'paperwork_backend.chkworkdir.label_color', ], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'chkworkdir', help=_("Check and fix work directory integrity") ) p.add_argument( '--yes', '-y', required=False, default=False, action='store_true', help=_("Don't ask to fix things, just fix them") ) @staticmethod def _color(color): assert FABULOUS_AVAILABLE color = "#%1X%1X%1X" % ( int(color[0] * 0xF), int(color[1] * 0xF), int(color[2] * 0xF), ) return fabulous.color.bg256(color, " ") + " " def cmd_run(self, console, args): if args.command != 'chkworkdir': return None console.print(_("Checking work directory ...")) problems = [] self.core.call_all("check_work_dir", problems) if len(problems) <= 0: console.print(_("No problem found")) return problems console.print("") console.print(_("%d problems found:") % len(problems)) for problem in problems: problem_color = ( "" if "problem_color" not in problem else self._color(problem['problem_color']) ) solution_color = ( "" if "solution_color" not in problem else self._color(problem['solution_color']) ) console.print("[{}]".format(problem['problem'])) console.print( _("- Problem: ") + problem_color + problem['human_description']['problem'] ) console.print( _("- Possible solution: ") + solution_color + problem['human_description']['solution'] ) console.print("") if not args.yes: msg = _( "Do you want to fix those problems automatically" " using the indicated solutions ?" ) r = openpaperwork_core.cmd.util.ask_confirmation( console, msg, default_interactive='n', default_non_interactive='n', ) if r != 'y': console.print("OK, nothing changed.") return problems console.print(_("Fixing ...")) self.core.call_all("fix_work_dir", problems) console.print(_("All fixed !")) console.print(_("Synchronizing with work directory ...")) self.core.call_all("transaction_sync_all") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") console.print(_("All done !")) return problems paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/delete.py000066400000000000000000000107431456262201400252240ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import sys import openpaperwork_core from openpaperwork_core.cmd.util import ask_confirmation from .util import parse_page_list from .. import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "document_storage", "defaults": ['paperwork_backend.model.workdir'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { "interface": "pages", "defaults": [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.img', 'paperwork_backend.model.thumbnail', ], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'delete', help=_("Delete a document or a page") ) p.add_argument( '--pages', '-p', type=str, required=False, help=_( "Pages to delete" " (single integer, range or comma-separated list," " default: all pages)" ) ) p.add_argument( 'doc_ids', nargs='*', default=[], help=_("Target documents") ) def cmd_run(self, console, args): if args.command != 'delete': return None doc_ids = args.doc_ids for doc_id in doc_ids: if "/" in doc_id or "\\" in doc_id or ".." in doc_id: sys.stderr.write(f"Invalid doc_id: {doc_id}") sys.exit(2) pages = parse_page_list(args) del_doc_msg = _("Deleting document {doc_id} ...") del_page_msg = _("Deleting page {page_idx} of document {doc_id} ...") for doc_id in doc_ids: if pages is None: r = ask_confirmation( console, _("Delete document %s ?") % str(doc_id), default_interactive='n', default_non_interactive='y', ) else: r = ask_confirmation( _( "Delete page(s)" " {page_indexes} of document {doc_id} ?".format( page_indexes=str([p + 1 for p in pages]), doc_id=str(doc_id) ) ), default_interactive='n', default_non_interactive='y', ) if r != 'y': continue if pages is None: console.print(del_doc_msg.format(doc_id=doc_id)) self.core.call_all("storage_delete_doc_id", doc_id) else: for page in pages: doc_url = self.core.call_success( "doc_id_to_url", doc_id ) console.print(del_page_msg.format( page_idx=(page + 1), doc_id=doc_id) ) self.core.call_all("page_delete_by_url", doc_url, page) self.core.call_success( "transaction_simple", [ # transaction_simple() will automatically replace the change # 'upd' by 'del' for the documents that don't exist anymore ("upd", doc_id) for doc_id in doc_ids ] ) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") return True paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/edit.py000066400000000000000000000130201456262201400246760ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import logging import shutil import sys import rich.text import openpaperwork_core import paperwork_backend.pageedit from . import util from .. import _ LOGGER = logging.getLogger(__name__) class NullUI(paperwork_backend.pageedit.AbstractPageEditorUI): def __init__(self): super().__init__() class CliUI(paperwork_backend.pageedit.AbstractPageEditorUI): def __init__(self, core, console): super().__init__() self.core = core self.console = console def show_preview(self, img): terminal_width = shutil.get_terminal_size()[0] - 1 img = self.core.call_success( "img_render", img, terminal_width=terminal_width ) if img is None: return for line in img: self.console.print(rich.text.Text.from_ansi(line)) self.console.print("") class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ # optional dependency # { # "interface": "img_renderer", # "defaults": ["paperwork_shell.display.docrendering.img"], # }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { "interface": "page_editor", "defaults": ["paperwork_backend.pageedit.pageeditor"], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): # just so we can get the modifier list editor = self.core.call_success("page_editor_get", None, 0, NullUI()) modifiers = editor.get_modifiers() modifiers = [ modifier['id'] for modifier in modifiers if not modifier['need_frame'] ] edit_parser = parser.add_parser('edit', help=_("Edit page")) edit_parser.add_argument( '--modifiers', '-m', type=str, required=True, help=_( "List of image modifiers (comma separated, possible values:" " {})" ).format(modifiers) ) # we need page number(s), but for consistency with other commands, # we require this argument as an option like '--opt' instead of # a positional argument. edit_parser.add_argument('--pages', '-p', type=str, required=True) edit_parser.add_argument('doc_id') def cmd_run(self, console, args): if args.command != 'edit': return None doc_id = args.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) pages = util.parse_page_list(args) modifiers = args.modifiers.split(",") out = [] for page_idx in pages: out.append((doc_id, page_idx)) console.print( _("Modifying document {} page {} ...").format( doc_id, page_idx ) ) console.print(_("Original:")) ui = CliUI(self.core, console) page_editor = self.core.call_success( "page_editor_get", doc_url, page_idx, ui ) promise = openpaperwork_core.promise.Promise(self.core) for modifier in modifiers: promise = promise.then(console.print, f"{modifier}:") promise = promise.then( page_editor.on_modifier_selected(modifier) ) if promise is not None: promise = promise.then( sys.stdout.write, _("Generating in high quality and saving ...") + " " ) promise = promise.then( lambda *args, **kwargs: sys.stdout.flush() ) promise = promise.then(page_editor.on_save()) promise = promise.then(console.print, "Done") def on_err(exc): LOGGER.error( "Edition of %s p%d failed", doc_id, page_idx, exc_info=exc ) page_editor.on_cancel() raise exc promise.catch(on_err) promise.schedule() self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") console.print(_("Committing ...") + " ") self.core.call_success("transaction_simple", [("upd", doc_id),]) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") console.print(_("Done")) console.print(_("All done !")) return out paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/export.py000066400000000000000000000206451456262201400253050ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import sys import openpaperwork_core import openpaperwork_core.promise import paperwork_backend.docexport from . import util from .. import _ class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.console = None def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "document_storage", "defaults": ["paperwork_backend.model.workdir"], }, { "interface": "fs", "defaults": ["openpaperwork_gtk.fs.gio"], }, { "interface": "export_pipes", "defaults": [ 'paperwork_backend.docexport.generic', 'paperwork_backend.docexport.img', 'paperwork_backend.docexport.pdf', 'paperwork_backend.docexport.pillowfight', ], }, ] def cmd_set_console(self, console): self.console = console def cmd_complete_argparse(self, parser): p = parser.add_parser( 'export', help=_( "Export a document, a page, or a set of pages." " Example:" " paperwork-cli export 20150303_2314_39 -p 2 -f img_boxes" " -f grayscale -f jpeg -o ~/tmp/pouet.jpg" ) ) p.add_argument('doc_id', help=_('Document to export')) p.add_argument( '--pages', '-p', type=str, required=False, help=_( "Pages to export" " (single integer, range or comma-separated list," " default: all pages)" ) ) p.add_argument( '--filters', '-f', nargs=1, action='append', type=str, required=False, help=_( "Export filters. Specify this option once for each filter" " to apply (ex: '-f grayscale -f jpeg')." ) ) p.add_argument( '--out', '-o', type=str, required=False, help=_( "Output file/directory. If not specified, will list" " the filters that could be chained after those already" " specified." ) ) def _print_possible_pipes(self, next_pipes): next_pipes = [pipe.name for pipe in next_pipes] next_pipes.sort() self.console.print(_("Next possible filters are:")) for pipe in next_pipes: self.console.print(f"- {pipe}") return next_pipes @staticmethod def _data_type_to_str(dtype): if dtype == paperwork_backend.docexport.ExportDataType.DOCUMENT_SET: return _("a document list") elif dtype == paperwork_backend.docexport.ExportDataType.DOCUMENT: return _("a document") elif dtype == paperwork_backend.docexport.ExportDataType.PAGE: return _("pages") elif dtype == paperwork_backend.docexport.ExportDataType.IMG_BOXES: return _("Images and text boxes") return f"Unknown: {dtype}" def _check_pipeline(self, doc_url, pages, filters): filters = list(filters) next_pipes = [] if pages is not None and len(pages) > 0: self.core.call_all( "export_get_pipes_by_page", next_pipes, doc_url, pages[0] ) else: self.core.call_all( "export_get_pipes_by_doc_url", next_pipes, doc_url ) if len(filters) <= 0: self.console.print(_("Need at least one filter.")) return self._print_possible_pipes(next_pipes) if not filters[0] in next_pipes: sys.stderr.write( _("First filter cannot be '{}'").format( filters[0].name ) + "\n" ) self._print_possible_pipes(next_pipes) return False output_type = None while len(filters) > 0: f = filters.pop(0) if output_type is not None and f.input_type != output_type: sys.stderr.write( _( "Filter mismatch:" " {0} expects {1} as input. Got {2} instead" ).format( f.name, self._data_type_to_str(f.input_type), self._data_type_to_str(output_type), ) + "\n" ) return False output_type = f.output_type expected_output_type = ( paperwork_backend.docexport.ExportDataType.OUTPUT_URL_FILE ) if output_type != expected_output_type: self.console.print( _("Last filter will output {}.").format( self._data_type_to_str(output_type) ) + "\n" ) next_pipes = [] self.core.call_all( "export_get_pipes_by_input", next_pipes, output_type ) return self._print_possible_pipes(next_pipes) return None def cmd_run(self, console, args): if args.command != 'export': return None # argument parsing doc_id = args.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) if doc_url is None: sys.stderr.write(f"Document {doc_id} doesn't exist\n") return False pages = util.parse_page_list(args) filters = args.filters if args.filters is not None else [] out = args.out if pages is None or len(pages) <= 0: input_value = paperwork_backend.docexport.ExportData.build_doc( doc_id, doc_url ) else: input_value = paperwork_backend.docexport.ExportData.build_pages( doc_id, doc_url, pages ) filters_str = [f[0] for f in filters] filters = [] for f in filters_str: p = self.core.call_success('export_get_pipe_by_name', f) if p is None: sys.stderr.write( (_("Unknown filters: %s") % f) + "\n" ) if len(filters) <= 0: sys.stderr.write( _( "Run the command without any filter to have a list" " of possible filters to start with." ) + "\n" ) return False filters.append(p) r = self._check_pipeline(doc_url, pages, filters) if r is not None: return r if out is None or out == "": sys.stderr.write( _( "Filter list is complete," " but no output file specified (-o)" ) + "\n" ) return [] # else try to export out = self.core.call_success("fs_safe", out) def get_input_value(): return input_value promise = openpaperwork_core.promise.Promise( self.core, get_input_value ) for pipe in filters: promise = promise.then( pipe.get_promise(result='final', target_file_url=out) ) self.console.print(_("Exporting to %s ... ") % out) self.core.call_one("mainloop_schedule", promise.schedule) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.console.print(_("Done") + "\n") r = (self.core.call_success("fs_exists", out) is not None) if not r: sys.stderr.write(_("Export failed !") + "\n") return r paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/extra_text.py000066400000000000000000000053421456262201400261500ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import openpaperwork_core from .. import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "extra_text", "defaults": ['paperwork_backend.model.extra_text'], }, ] def cmd_complete_argparse(self, parser): extra_text_parser = parser.add_parser( 'extra_text', help=_( "Manage additional text attached to documents" ) ) subparser = extra_text_parser.add_subparsers( help=_('sub-command'), dest='subcommand', required=True ) parser = subparser.add_parser( 'get', help=_("Get a document additional text") ) parser.add_argument('doc_id') parser = subparser.add_parser( 'set', help=_("Set a document additional text") ) parser.add_argument('doc_id') parser.add_argument('text') def cmd_run(self, console, args): if args.command != 'extra_text': return None doc_id = args.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) if args.subcommand == "get": return self._cmd_get(console, doc_id, doc_url) elif args.subcommand == "set": return self._cmd_set(console, doc_id, doc_url, args.text) else: return None def _cmd_get(self, console, doc_id, doc_url): text = [] self.core.call_success("doc_get_extra_text_by_url", text, doc_url) if len(text) > 0: console.print(" " + _("Additional text:")) console.print("\n".join(text)) else: console.print(_("No additional text")) return text def _cmd_set(self, console, doc_id, doc_url, text): text = text.strip() self.core.call_success("doc_set_extra_text_by_url", doc_url, text) console.print(_("Done")) return True paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/import.py000066400000000000000000000135141456262201400252730ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2022 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import logging import rich.text import openpaperwork_core import openpaperwork_core.promise import paperwork_backend.docimport from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "fs", "defaults": "openpaperwork_gtk.fs.gio", }, { 'interface': 'doc_labels', 'defaults': ['paperwork_backend.model.labels'], }, { "interface": "import", "defaults": [ 'paperwork_backend.docimport.img', 'paperwork_backend.docimport.pdf', ], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'import', help=_( "Import file(s)" ) ) p.add_argument( '--doc_id', '--doc', '-d', type=str, required=False, help=_("Target document for import"), ) p.add_argument( '--password', type=str, required=False, help=_("PDF password"), ) p.add_argument( 'files', type=str, nargs='*', help=_("Files to import") ) def _file_import_to_dict(self, file_import): return { "imported": list(file_import.imported_files), "ignored": list(file_import.ignored_files), "new_docs": list(file_import.new_doc_ids), "upd_docs": list(file_import.upd_doc_ids), "stats": dict(file_import.stats) } def cmd_run(self, console, args): if args.command != 'import': return None file_import = paperwork_backend.docimport.FileImport( [self.core.call_success("fs_safe", f) for f in args.files], active_doc_id=args.doc_id ) importers = [] self.core.call_all("get_importer", importers, file_import) choice = 0 if len(importers) <= 0: console.print( _("Don't know how to import file(s) %s") % args.files ) LOGGER.warning("Don't know how to import file(s) %s", args.files) return self._file_import_to_dict(file_import) if len(importers) > 1: console.print( _("Found many ways to import file(s) %s.") % args.files ) console.print( _("Please select the way you want:") ) choice = -1 while choice not in range(0, len(importers)): for (idx, importer) in enumerate(importers): console.print(f" {idx + 1} - {importer.get_name()}") choice = console.input("? ") if choice is None: return self._file_import_to_dict(file_import) choice = int(choice) - 1 importer = importers[choice] del importers # We must load the labels before importing. Because the label # guesser may want to add labels on documents, and therefore # we need to know their color # TODO(Jflesch): That's slow and overkill. There should be a better # way (maybe storing the labels in ~/.local/share/paperwork2 ?) console.print(_("Loading labels ...")) promises = [] self.core.call_all("label_load_all", promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) # use transaction_schedule to make sure that document imports # are not done before we have loaded the labels self.core.call_one("transaction_schedule", promise) data = {} if args.password is not None: data['password'] = args.password promise = importer.get_import_promise(data) console.print(_("Importing %s ...") % args.files) self.core.call_success( "mainloop_schedule", self.core.call_success, "transaction_schedule", promise ) self.core.call_all("mainloop_quit_graceful") self.core.call_success("mainloop") console.print(rich.text.Text(_("Done"))) console.print(rich.text.Text(_("Import result:"))) console.print(rich.text.Text( _("- Imported files: %s") % file_import.imported_files )) console.print(rich.text.Text( _("- Non-imported files: %s") % file_import.ignored_files )) console.print(rich.text.Text( _("- New documents: %s") % file_import.new_doc_ids )) console.print(rich.text.Text( _("- Updated documents: %s") % file_import.upd_doc_ids )) for (k, v) in file_import.stats.items(): console.print(rich.text.Text(f"- {k}: {v}")) return self._file_import_to_dict(file_import) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/label.py000066400000000000000000000162171456262201400250430ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import sys import openpaperwork_core from openpaperwork_core.cmd.util import ask_confirmation from .. import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "doc_labels", "defaults": ["paperwork_backend.model.labels"], }, { "interface": "document_storage", "defaults": ["paperwork_backend.model.workdir"], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): label_parser = parser.add_parser( 'label', help=_("Commands to manage labels") ) subcmd_parser = label_parser.add_subparsers( help=_("label command"), dest='sub_command', required=True ) subcmd_parser.add_parser('list') p = subcmd_parser.add_parser('show') p.add_argument( 'doc_ids', nargs='*', default=[], help=_("Target documents") ) p = subcmd_parser.add_parser('add') p.add_argument('doc_id', help=_("Target document")) p.add_argument('label_name', help=_("Label to add")) p.add_argument( '--color', '-c', default=None, help=_("Label color (ex: '#aa22cc')"), required=False ) p = subcmd_parser.add_parser('remove') p.add_argument('doc_id', help=_("Target document")) p.add_argument('label_name', help=_("Label to remove")) p = subcmd_parser.add_parser('delete') p.add_argument( 'label_name', help=_("Label to delete from *all* documents") ) def _load_all_labels(self, console): console.print(_("Loading all labels ... ")) promises = [] self.core.call_all("label_load_all", promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) self.core.call_one("mainloop_schedule", promise.schedule) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") console.print(_("Done")) def _upd_doc(self, console, doc_id): self.core.call_success("transaction_simple", [("upd", doc_id),]) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") def _show(self, console, doc_ids): out = {} for doc_id in doc_ids: doc_url = self.core.call_success("doc_id_to_url", doc_id) labels = set() self.core.call_all("doc_get_labels_by_url", labels, doc_url) labels = list(labels) labels.sort() out[doc_id] = labels labels_str = self.core.call_success( "format_labels", labels, separator=" " ) console.print(f"{doc_id}: {labels_str}") return out def cmd_run(self, console, args): if args.command != 'label': return None if args.sub_command == 'list': self._load_all_labels(console) labels = set() self.core.call_all("labels_get_all", labels) labels = list(labels) labels.sort() console.print("") labels_str = self.core.call_success( "format_labels", labels, separator=" " ) console.print(labels_str) return labels elif args.sub_command == 'show': return self._show(console, args.doc_ids) elif args.sub_command == "add": color = args.color if color is not None: # make sure the color is valid color = self.core.call_success("label_color_to_rgb", color) color = self.core.call_success("label_color_from_rgb", color) self._load_all_labels(console) doc_url = self.core.call_success("doc_id_to_url", args.doc_id) self.core.call_success( "doc_add_label_by_url", doc_url, args.label_name, color ) self._upd_doc(console, args.doc_id) return self._show(console, [args.doc_id]) elif args.sub_command == "remove": doc_url = self.core.call_success("doc_id_to_url", args.doc_id) self.core.call_all( "doc_remove_label_by_url", doc_url, args.label_name ) self._upd_doc(console, args.doc_id) return self._show(console, [args.doc_id]) elif args.sub_command == "delete": label = args.label_name r = ask_confirmation( console, _( "Are you sure you want to delete label '%s' from all" " documents ?" ) % label, default_interactive='n', default_non_interactive='y', ) if r != 'y': sys.exit(1) all_docs = [] self.core.call_all("storage_get_all_docs", all_docs) updated_docs = [] for (doc_id, doc_url) in all_docs: labels = set() self.core.call_all("doc_get_labels_by_url", labels, doc_url) labels = {l for (l, c) in labels} if label not in labels: continue if self.interactive: print("Removing label '{}' from document '{}'".format( label, doc_id )) updated_docs.append(doc_id) self.core.call_all("doc_remove_label_by_url", doc_url, label) if self.interactive: sys.stdout.write("Committing changes in index ... ") sys.stdout.flush() self.core.call_success("transaction_simple", [ ("upd", doc_id) for doc_id in updated_docs ]) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") if self.interactive: sys.stdout.write("Done\n") return updated_docs if self.interactive: print("Unknown label command: {}".format(args.sub_command)) return None paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/move.py000066400000000000000000000060311456262201400247230ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import openpaperwork_core from .. import _ class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "document_storage", "defaults": ['paperwork_backend.model.workdir'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { "interface": "pages", "defaults": [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.img', 'paperwork_backend.model.thumbnail', ], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'move', help=_("Move a page") ) p.add_argument( 'source_doc_id', help=_("Source document") ) p.add_argument( 'source_page', type=int, help=_("Page to move") ) p.add_argument( 'dest_doc_id', help=_("Destination document") ) p.add_argument( 'dest_page', type=int, help=_("Target page number") ) def cmd_run(self, console, args): if args.command != 'move': return None source_doc_id = args.source_doc_id source_page_idx = args.source_page - 1 dest_doc_id = args.dest_doc_id dest_page_idx = args.dest_page - 1 source_doc_url = self.core.call_success("doc_id_to_url", source_doc_id) dest_doc_url = self.core.call_success("doc_id_to_url", dest_doc_id) self.core.call_all( "page_move_by_url", source_doc_url, source_page_idx, dest_doc_url, dest_page_idx ) self.core.call_success("transaction_simple", [ ("upd", source_doc_id), ("upd", dest_doc_id), ]) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") return True paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/ocr.py000066400000000000000000000055201456262201400245420ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import openpaperwork_core from . import util from .. import _ class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "ocr", "defaults": ['paperwork_backend.guesswork.ocr.pyocr'], }, { "interface": "ocr_settings", "defaults": ['paperwork_backend.pyocr'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'ocr', help=_( "OCR document or pages" ) ) p.add_argument( 'doc_id', type=str, help=_("Document on which OCR must be run") ) p.add_argument( '--pages', '-p', type=str, help=_( "Pages to OCR" " (single integer, range or comma-separated list," " default: all pages)" ) ) def cmd_run(self, console, args): if args.command != 'ocr': return None if self.core.call_success("ocr_is_enabled") is None: console.print("OCR is disabled") return [] doc_id = args.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) pages = util.parse_page_list(args) if pages is None: nb_pages = self.core.call_success( "doc_get_nb_pages_by_url", doc_url ) pages = range(0, nb_pages) out = [] for page_idx in pages: console.print( _( "Running OCR on" " document {doc_id} page {page_idx} ..." ).format( doc_id=doc_id, page_idx=(page_idx + 1) ) ) self.core.call_all("ocr_page_by_url", doc_url, page_idx) console.print(_("Done")) out.append((doc_id, page_idx)) console.print(_("All done !")) return out paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/rename.py000066400000000000000000000052571456262201400252350ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import rich.text import openpaperwork_core from .. import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "document_storage", "defaults": ['paperwork_backend.model.workdir'], }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'rename', help=_("Change a document identifier") ) p.add_argument( 'source_doc_id', help=_("Document to rename") ) p.add_argument( 'dest_doc_id', help=_("New name for the document") ) def cmd_run(self, console, args): if args.command != 'rename': return None source_doc_id = args.source_doc_id dest_doc_id = args.dest_doc_id source_doc_url = self.core.call_success("doc_id_to_url", source_doc_id) dest_doc_url = self.core.call_success( "doc_id_to_url", dest_doc_id, existing=False ) console.print(rich.text.Text( f"Renaming: {source_doc_url} --> {dest_doc_url}" )) self.core.call_all("doc_rename_by_url", source_doc_url, dest_doc_url) self.core.call_success( "transaction_simple", [ ('del', source_doc_id), ('add', dest_doc_id), ] ) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") console.print(rich.text.Text( f"{source_doc_id} renamed into {dest_doc_id}" )) return True paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/reset.py000066400000000000000000000074231456262201400251050ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import logging import shutil import rich.text import openpaperwork_core from . import util from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() def get_interfaces(self): return ['shell'] def get_deps(self): return [ # optional dependency # { # "interface": "img_renderer", # "defaults": ["paperwork_shell.display.docrendering.img"], # }, { 'interface': 'mainloop', 'defaults': ['openpaperwork_core.mainloop.asyncio'], }, { "interface": "page_reset", "defaults": ["paperwork_backend.model.img_overlay"], }, { "interface": "pillow", "defaults": [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): reset_parser = parser.add_parser( 'reset', help=_("Reset a page to its original content") ) # for safety, we mark the argument --pages as required reset_parser.add_argument('--pages', '-p', type=str, required=True) reset_parser.add_argument('doc_id') def show_page(self, console, doc_url, page_idx): page_url = self.core.call_success( "page_get_img_url", doc_url, page_idx ) img = self.core.call_success("url_to_pillow", page_url) terminal_width = shutil.get_terminal_size()[0] - 1 img = self.core.call_success( "img_render", img, terminal_width=terminal_width ) if img is None: return for line in img: console.print(rich.text.Text(line)) console.print("") def cmd_run(self, console, args): if args.command != 'reset': return None doc_id = args.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) pages = util.parse_page_list(args) out = [] for page_idx in pages: out.append((doc_id, page_idx)) console.print( _("Reseting document {} page {} ...").format( doc_id, page_idx ) ) console.print(_("Original:")) self.show_page(doc_url, page_idx) self.core.call_all("page_reset_by_url", doc_url, page_idx) console.print(_("Reseted:")) self.show_page(doc_url, page_idx) console.print("") self.core.call_success("transaction_simple", [("upd", doc_id),]) self.core.call_success("mainloop_quit_graceful") self.core.call_success("mainloop") console.print(_("Done")) console.print(_("All done !")) return out paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/scan.py000066400000000000000000000043611456262201400247050ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import openpaperwork_core import openpaperwork_core.promise from .. import _ DEFAULT_RESOLUTION = 300 class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.out = [] def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "mainloop", "defaults": ['openpaperwork_gtk.mainloop.glib'], }, { "interface": "scan2doc", "defaults": ["paperwork_backend.docscan.scan2doc"], }, ] def cmd_complete_argparse(self, parser): scan_parser = parser.add_parser( 'scan', help=_("Scan pages") ) scan_parser.add_argument( "--doc_id", "-d", help=_( "Document to which the scanned pages must be added" ) ) scan_parser.add_argument("source_id") def cmd_run(self, console, args): if args.command != 'scan': return None doc_url = None if args.doc_id is not None: doc_url = self.core.call_success("doc_id_to_url", args.doc_id) promise = self.core.call_success( "scan2doc_promise", doc_id=args.doc_id, doc_url=doc_url, source_id=args.source_id ) self.core.call_success("scan_schedule", promise) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") return True paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/scanner.py000066400000000000000000000224301456262201400254070ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import logging import openpaperwork_core import openpaperwork_core.promise import rich.tree from .. import _ LOGGER = logging.getLogger(__name__) DEFAULT_RESOLUTION = 300 class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.out = [] def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "mainloop", "defaults": ["openpaperwork_gtk.mainloop.glib"], }, { "interface": "config", "defaults": ['openpaperwork_core.config'], }, { "interface": "scan", "defaults": ['paperwork_backend.docscan.libinsane'], }, ] def cmd_complete_argparse(self, parser): scanner_parser = parser.add_parser( 'scanner', help=_("Manage scanner configuration") ) subparser = scanner_parser.add_subparsers( help=_("sub-command"), dest='subcommand', required=True ) subparser.add_parser( 'list', help=_("List all scanners and their possible settings") ) subparser.add_parser( 'get', help=_( "Show the currently selected scanner and its settings" ) ) set_scanner = subparser.add_parser( 'set', help=_("Define which scanner and which settings to use") ) set_scanner.add_argument( "device_id", help=_("Scanner to use") ) set_scanner.add_argument( "--source", "-s", type=str, required=False, help=_( "Default source on the scanner to use (if not specified," " one will be selected randomly)" ) ) set_scanner.add_argument( "--resolution", "-r", type=int, required=False, help=_("Default resolution (dpi ; default=300)") ) def _get_scanner_info(self, dev, console, dev_id, dev_name): console.print(_("Examining scanner {} ...").format(dev_id)) dev_out = { 'id': dev_id, 'name': dev_name, 'sources': [], } sources = dev.get_sources() for (source_id, source) in sources.items(): source_out = { "id": source_id, "resolutions": source.get_resolutions(), } dev_out['sources'].append(source_out) self.out.append(dev_out) return dev def _on_get_scanner_error(self, exception, scanner_dev_id): LOGGER.error( "Error while looking for options of %s", scanner_dev_id, exc_info=exception ) def _get_scanners_info(self, devs, console): for dev in devs: # Schedule the promises to examine each scanner separately, # so if one failed (for instance on Windows when a scanner is # not actually connected), the others can still run. dev_id = dev[0] dev_name = dev[1] promise = openpaperwork_core.promise.Promise( self.core, hide_caught_exceptions=True ) promise = promise.then(self.core.call_success( "scan_get_scanner_promise", dev_id )) promise.catch(self._on_get_scanner_error, dev_id) promise = promise.then( self._get_scanner_info, console, dev_id, dev_name ) promise = promise.then(lambda scanner: scanner.close()) promise = promise.then(lambda *args, **kwargs: None) self.core.call_success("scan_schedule", promise) def _list_scanners(self, console): self.out = [] promise = self.core.call_success("scan_list_scanners_promise") promise = promise.then(self._get_scanners_info, console) self.core.call_success("scan_schedule", promise) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") def _print_scanners(self, console): console.print("") tree = rich.tree.Tree("Scanners") for dev in self.out: dev_tree = tree.add(dev['name']) dev_tree.add(_("ID:") + " " + dev['id']) for source in dev['sources']: source_tree = dev_tree.add(_("Source:") + " " + source['id']) source_tree.add( _("Resolutions:") + " " + str(source['resolutions']) ) console.print(tree) def _get_scanner(self, console): out = { 'id': self.core.call_success( "config_get", "scanner_dev_id" ), 'source': self.core.call_success( "config_get", "scanner_source_id" ), 'resolution': self.core.call_success( "config_get", "scanner_resolution" ), } console.print(_("ID:") + " " + str(out['id'])) console.print(_("Source:") + " " + str(out['source'])) console.print(_("Resolution:") + " " + str(out['resolution'])) return out def _set_scanner(self, console, args): dev_settings = { 'id': args.device_id, 'source': args.source, 'resolution': ( args.resolution if args.resolution is not None else DEFAULT_RESOLUTION ), } # In any case, we want to make sure the settings provided are valid promise = self.core.call_success( "scan_get_scanner_promise", args.device_id ) def check_source(dev): sources = dev.get_sources() if ( dev_settings['source'] is not None and dev_settings['source'] not in sources ): console.print(_( "Source {} not found on device." " Using another source" ).format(dev_settings['source'])) dev_settings['source'] = None if dev_settings['source'] is None: for (source_id, source_obj) in sources.items(): if 'flatbed' in source_id.lower(): source = (source_id, source_obj) break else: source = sources.popitem() dev_settings['source'] = source[0] else: source = ( dev_settings['source'], sources[dev_settings['source']] ) console.print(_("Default source:") + " " + dev_settings['source']) return source[1] promise = promise.then(check_source) def check_resolution(source): resolutions = source.get_resolutions() if dev_settings['resolution'] in resolutions: return source resolution = min( resolutions, key=lambda x: abs(x - dev_settings['resolution']) ) console.print( _("Resolution {} not available. Adjusted to {}.").format( dev_settings['resolution'], resolution ) ) dev_settings['resolution'] = resolution return source promise = promise.then(check_resolution) promise = promise.then(lambda source: source.close()) self.core.call_success("scan_schedule", promise) self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") self.core.call_all( "config_put", "scanner_dev_id", dev_settings['id'] ) self.core.call_all( "config_put", "scanner_source_id", dev_settings['source'] ) self.core.call_all( "config_put", "scanner_resolution", dev_settings['resolution'] ) self.core.call_all("config_save") return self._get_scanner(console) def cmd_run(self, console, args): if args.command != 'scanner': return None if args.subcommand == 'list': console.print("Looking for scanners ...") self._list_scanners(console) console.print(f"{len(self.out)} scanners found") console.print("") self._print_scanners(console) return self.out elif args.subcommand == 'set': return self._set_scanner(console, args) elif args.subcommand == 'get': return self._get_scanner(console) assert False paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/search.py000066400000000000000000000065431456262201400252320ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import logging import shutil import openpaperwork_core from .. import _ LOGGER = logging.getLogger(__name__) class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): return [ # if there are no doc_renderer loaded, nothing it displayed, which # may be fine. # (see paperwork-json) # { # "interface": "doc_renderer", # "defaults": [], # }, { "interface": "document_storage", "defaults": ['paperwork_backend.model.workdir'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, { "interface": "index", "defaults": ['paperwork_backend.index.shell'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser( 'search', help=_("Search keywords in documents") ) p.add_argument( '--limit', '-l', type=int, default=50, help=_("Maximum number of results (default: 50)") ) p.add_argument( 'keywords', nargs='*', default=[], help=_("Search keywords (none means all documents)") ) def cmd_run(self, console, args): if args.command != 'search': return None keywords = " ".join(args.keywords) docs = [] self.core.call_all("index_search", docs, keywords, args.limit) docs.sort(reverse=True) renderers = [] self.core.call_all("doc_renderer_get", renderers) renderer = renderers[-1] for (doc_id, doc_url) in docs: header = _("Document id: %s") % doc_id self.core.call_all("print", header) doc_date = self.core.call_success("doc_get_date_by_id", doc_id) doc_date = self.core.call_success("i18n_date_short", doc_date) header = _("Document date: %s") % doc_date self.core.call_all("print", header) if renderer is None: continue if doc_url is None: LOGGER.warning("Failed to get URL of document %s", doc_id) continue lines = renderer.get_preview_output( doc_id, doc_url, shutil.get_terminal_size() ) for line in lines: self.core.call_all("print", line) self.core.call_all("print", "") self.core.call_success("print_flush") return [doc[0] for doc in docs] paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/show.py000066400000000000000000000073311456262201400247410ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import shutil import openpaperwork_core from . import util from .. import _ class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['shell'] def get_deps(self): # if there are no doc_renderer loaded, nothing is displayed, which # may be fine. # (see paperwork-json) return [ { 'interface': 'document_storage', 'defaults': ['paperwork_backend.model.workdir'], }, { 'interface': 'i18n', 'defaults': ['openpaperwork_core.i18n.python'], }, ] def cmd_complete_argparse(self, parser): p = parser.add_parser('show', help=_( "Show the content of a document" )) p.add_argument('doc_id') p.add_argument( '--pages', '-p', required=False, help="Pages to show: 1,4 or 1-10 (default: all)" ) def cmd_run(self, console, args): if args.command != 'show': return None doc_id = args.doc_id doc_url = self.core.call_success("doc_id_to_url", doc_id) if doc_url is None: return False nb_pages = self.core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None or nb_pages <= 0: return False pages = util.parse_page_list(args) if pages is None: pages = range(0, nb_pages) renderers = [] self.core.call_all("doc_renderer_get", renderers) assert len(renderers) > 0 renderer = renderers[-1] header = _("Document id: %s") % doc_id self.core.call_success("print", header) self.core.call_success("print", "=" * len(header)) doc_date = self.core.call_success("doc_get_date_by_id", doc_id) doc_date = self.core.call_success("i18n_date_short", doc_date) header = _("Document date: %s") % doc_date self.core.call_success("print", header) lines = renderer.get_doc_output( doc_id, doc_url, shutil.get_terminal_size() ) for line in lines: self.core.call_success("print", line) self.core.call_success("print", "") for page_nb in pages: self.core.call_success("print", "") header = _("Page %d") % (page_nb + 1) self.core.call_success("print", header) self.core.call_success("print", ("-" * len(header)) + "\n") lines = renderer.get_page_output( doc_id, doc_url, page_nb, shutil.get_terminal_size() ) for line in lines: self.core.call_success("print", line) self.core.call_success("print", "") self.core.call_success("print_flush") return { 'document': renderer.get_doc_infos(doc_id, doc_url), 'pages': { page_nb: renderer.get_page_infos(doc_id, doc_url, page_nb) for page_nb in pages }, } paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/sync.py000066400000000000000000000053101456262201400247300ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import collections import openpaperwork_core from .. import _ class Plugin(openpaperwork_core.PluginBase): def __init__(self): super().__init__() self.changes = collections.defaultdict( # we cannot use sets here because sets are not JSON-serializable lambda: collections.defaultdict(list) ) def get_interfaces(self): return ['shell'] def get_deps(self): return [ { "interface": "syncable", "defaults": [ "paperwork_backend.guesswork.label.sklearn", "paperwork_backend.guesswork.ocr.pyocr", "paperwork_backend.index.whoosh", "paperwork_backend.model.labels", ], }, { 'interface': 'transaction_manager', 'defaults': ['paperwork_backend.sync'], }, ] def cmd_complete_argparse(self, parser): parser.add_parser('sync', help=_( "Synchronize the index(es) with the content of the work directory" )) def on_sync(self, name, status, key): self.changes[name][status].append(key) def cmd_run(self, console, args): if args.command != 'sync': return None console.print(_("Synchronizing with work directory ...")) self.changes = collections.defaultdict( # we cannot use sets here because sets are not JSON-serializable lambda: collections.defaultdict(list) ) self.core.call_all("transaction_sync_all") self.core.call_all("mainloop_quit_graceful") self.core.call_one("mainloop") console.print(_("All done !")) # ensure order of documents to make testing easier and ensure # behaviour consistency for actions in self.changes.values(): for docs in actions.values(): docs.sort() return dict(self.changes) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/cmd/util.py000066400000000000000000000006521456262201400247350ustar00rootroot00000000000000def parse_page_list(args): if not hasattr(args, 'pages'): return None if args.pages is None or args.pages == "": return None if "-" in args.pages: pages = args.pages.split("-", 1) return range( int(pages[0]) - 1, int(pages[1]) ) else: return [ (int(p) - 1) for p in args.pages.split(",") if int(p) >= 1 ] paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/000077500000000000000000000000001456262201400243055ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/__init__.py000066400000000000000000000000101456262201400264050ustar00rootroot00000000000000# empty paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/docrendering/000077500000000000000000000000001456262201400267505ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/docrendering/__init__.py000066400000000000000000000000001456262201400310470ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/docrendering/extra_text.py000066400000000000000000000041051456262201400315110ustar00rootroot00000000000000import openpaperwork_core from ... import _ class ExtraTextRenderer(object): def __init__(self, core): self.core = core self.parent = None def get_preview_output( self, doc_id, doc_url, terminal_size=(80, 25), page_idx=0 ): if self.parent is not None: return self.parent.get_preview_output( doc_id, doc_url, terminal_size, page_idx ) return [] def get_doc_output(self, doc_id, doc_url, terminal_size=(80, 25)): out = [] if self.parent is not None: out = self.parent.get_doc_output( doc_id, doc_url, terminal_size ) extra_text = [] self.core.call_all("doc_get_extra_text_by_url", extra_text, doc_url) extra_text = "\n".join(extra_text).strip().split("\n") if len(extra_text) > 0: extra_text = ["", " " + _("Additional text:")] + extra_text return extra_text + out def get_page_output( self, doc_id, doc_url, page_nb, terminal_size=(80, 25) ): if self.parent is not None: return self.parent.get_page_output( doc_id, doc_url, page_nb, terminal_size ) return [] def get_doc_infos(self, doc_id, doc_url): if self.parent is not None: return self.parent.get_doc_infos(doc_id, doc_url) return {} def get_page_infos(self, doc_id, doc_url, page_nb): if self.parent is not None: return self.parent.get_page_infos(doc_id, doc_url, page_nb) return {} class Plugin(openpaperwork_core.PluginBase): PRIORITY = 11000 def get_interfaces(self): return ['doc_renderer'] def get_deps(self): return [ { 'interface': 'extra_text', 'defaults': ['paperwork_backend.model.extra_text'], }, ] def doc_renderer_get(self, out): r = ExtraTextRenderer(self.core) if len(out) > 0: r.parent = out[-1] out.append(r) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/docrendering/img.py000066400000000000000000000103461456262201400301020ustar00rootroot00000000000000import os import tempfile try: import fabulous.image # XXX(Jflesch): crappy workaround for an unmaintained library ... fabulous.image.basestring = str FABULOUS_AVAILABLE = True except (ValueError, ImportError): FABULOUS_AVAILABLE = False import openpaperwork_core class FabulousRenderer(object): def __init__(self, plugin): self.plugin = plugin self.core = plugin.core self.parent = None def get_preview_output( self, doc_id, doc_url, terminal_size=(80, 25), page_idx=0 ): w_split = int(terminal_size[0] / 3) parent = [] if self.parent is not None: parent = self.parent.get_preview_output( doc_id, doc_url, (terminal_size[0] - w_split - 2, terminal_size[1]), page_idx ) thumbnail = self.core.call_success( "thumbnail_get_page", doc_url, page_idx ) if thumbnail is None: thumbnail = [] else: thumbnail = self.plugin.img_render(thumbnail, w_split) if len(parent) < len(thumbnail): parent.extend([""] * (len(thumbnail) - len(parent))) elif len(parent) > len(thumbnail): parent = parent[:len(thumbnail)] out = [ (i + " " + t) for (i, t) in zip(thumbnail, parent) ] return out def get_doc_output(self, doc_id, doc_url, terminal_size=(80, 25)): out = [] if self.parent is not None: out = self.parent.get_doc_output( doc_id, doc_url, terminal_size ) return out def get_page_output( self, doc_id, doc_url, page_nb, terminal_size=(80, 25) ): parent_out = [] if self.parent is not None: parent_out = self.parent.get_page_output( doc_id, doc_url, page_nb, terminal_size ) img_url = self.core.call_success("page_get_img_url", doc_url, page_nb) img = self.core.call_success("url_to_pillow", img_url) img = self.plugin.img_render( img, terminal_width=(terminal_size[0] - 1) ) return [img_url] + list(img) + [""] + parent_out def get_doc_infos(self, doc_id, doc_url): out = {} if self.parent is not None: out = self.parent.get_doc_infos(doc_id, doc_url) return out def get_page_infos(self, doc_id, doc_url, page_nb): out = {} if self.parent is not None: out = self.parent.get_page_infos(doc_id, doc_url, page_nb) out['image'] = self.core.call_success( "page_get_img_url", doc_url, page_nb ) return out class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def get_interfaces(self): return [ 'doc_renderer', 'img_renderer', ] def get_deps(self): return [ { 'interface': 'page_img', 'defaults': [ 'paperwork_backend.model.img', 'paperwork_backend.model.pdf', ], }, { 'interface': 'pillow', 'defaults': [ 'openpaperwork_core.pillow.img', 'paperwork_backend.pillow.pdf', ], }, { 'interface': 'thumbnail', 'defaults': ['paperwork_backend.model.thumbnail'], }, ] def doc_renderer_get(self, out): if not FABULOUS_AVAILABLE: return r = FabulousRenderer(self) if len(out) > 0: r.parent = out[-1] out.append(r) def img_render(self, img, terminal_width=80): if not FABULOUS_AVAILABLE: return with tempfile.NamedTemporaryFile( prefix='paperwork-shell', suffix='.jpeg', delete=False ) as fd: img.save(fd, format="JPEG") img_file = fd.name try: img = fabulous.image.Image(img_file, width=terminal_width) img = img.reduce(img.convert()) finally: os.unlink(img_file) return list(img) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/docrendering/labels.py000066400000000000000000000107251456262201400305710ustar00rootroot00000000000000try: import fabulous.color FABULOUS_AVAILABLE = True except (ValueError, ImportError): FABULOUS_AVAILABLE = False import openpaperwork_core import rich.text def color_labels(core, labels): labels = [ (label, core.call_success("label_color_to_rgb", color)) for (label, color) in labels ] labels = [ (label, ( int(color[0] * 0xFF), int(color[1] * 0xFF), int(color[2] * 0xFF) )) for (label, color) in labels ] for (label, bg_color) in labels: fg_color = core.call_success( "label_get_foreground_color", ( bg_color[0] / 0xFF, bg_color[1] / 0xFF, bg_color[2] / 0xFF, ) ) fg_color = (fg_color[0] * 0xFF, fg_color[1] * 0xFF, fg_color[2] * 0xFF) l_label = len(label) label = fabulous.color.fg256(fg_color, label) label = fabulous.color.bg256(bg_color, label) yield (l_label, str(label)) class LabelsRenderer(object): def __init__(self, core): self.core = core self.parent = None def _get_labels(self, doc_url): labels = set() self.core.call_all("doc_get_labels_by_url", labels, doc_url) return labels def _rearrange_labels(self, labels, terminal_width): out = [] line = "" for (len_label, label) in labels: if len(line) + len_label + 1 >= terminal_width: out.append(line) line = "" line += " " + label if len(line.strip()) > 0: out.append(line) return [line.strip() for line in out] def get_preview_output( self, doc_id, doc_url, terminal_size=(80, 25), page_idx=0 ): out = [] if self.parent is not None: out = self.parent.get_preview_output( doc_id, doc_url, terminal_size, page_idx ) if not FABULOUS_AVAILABLE: return out if page_idx != 0: return out labels = self._get_labels(doc_url) labels = color_labels(self.core, labels) labels = self._rearrange_labels(labels, terminal_size[0]) return labels + out def get_doc_output(self, doc_id, doc_url, terminal_size=(80, 25)): out = [] if self.parent is not None: out = self.parent.get_doc_output( doc_id, doc_url, terminal_size ) if not FABULOUS_AVAILABLE: return out labels = self._get_labels(doc_url) labels = color_labels(self.core, labels) labels = self._rearrange_labels(labels, terminal_size[0]) return labels + out def get_page_output( self, doc_id, doc_url, page_nb, terminal_size=(80, 25) ): if self.parent is not None: return self.parent.get_page_output( doc_id, doc_url, page_nb, terminal_size ) return [] def get_doc_infos(self, doc_id, doc_url): out = {} if self.parent is not None: out = self.parent.get_doc_infos(doc_id, doc_url) out['labels'] = [] for (label, color) in self._get_labels(doc_url): out['labels'].append( { 'label': label, 'color': color, } ) return out def get_page_infos(self, doc_id, doc_url, page_nb): if self.parent is not None: return self.parent.get_page_infos(doc_id, doc_url, page_nb) return {} class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def get_interfaces(self): return ['doc_renderer'] def get_deps(self): return [ { 'interface': 'page_boxes', 'defaults': ['paperwork_backend.model.labels'], }, ] def format_labels(self, labels, separator='\n'): if FABULOUS_AVAILABLE: labels = color_labels(self.core, labels) labels = [label for (l_label, label) in labels] labels = separator.join(labels) labels = rich.text.Text.from_ansi(labels) else: labels = [label for (label, color) in labels] labels = separator.join(labels) return labels def doc_renderer_get(self, out): r = LabelsRenderer(self.core) if len(out) > 0: r.parent = out[-1] out.append(r) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/docrendering/text.py000066400000000000000000000065311456262201400303130ustar00rootroot00000000000000import openpaperwork_core PREVIEW_MAX_LINES = 25 class TextRenderer(object): def __init__(self, core): self.core = core self.parent = None def _get_page_text(self, doc_url, page_nb): out = [] line_boxes = self.core.call_success( "page_get_boxes_by_url", doc_url, page_nb ) if line_boxes is None: return out for line_box in line_boxes: line = line_box.content if line == "": continue out.append(line) return out def _rearrange_lines(self, lines, terminal_width): out = [] for line in lines: new_line = "" iwords = line.split(" ") words = [] for word in iwords: for p in range(0, len(word), terminal_width - 1): words.append(word[p:p + terminal_width - 1]) for word in words: if len(new_line) + len(word) + 1 >= terminal_width: out.append(new_line) new_line = "" new_line += " " + word if len(new_line.strip()) > 0: out.append(new_line) return [line.strip() for line in out] def get_preview_output( self, doc_id, doc_url, terminal_size=(80, 25), page_idx=0 ): if self.parent is None: out = [] else: out = self.parent.get_preview_output( doc_id, doc_url, terminal_size, page_idx ) text = self._get_page_text(doc_url, page_idx) text = self._rearrange_lines(text, terminal_size[0]) text = text[:PREVIEW_MAX_LINES] return out + text def get_doc_output(self, doc_id, doc_url, terminal_size=(80, 25)): if self.parent is None: out = [] else: out = self.parent.get_doc_output(doc_id, doc_url, terminal_size) return out def get_page_output( self, doc_id, doc_url, page_nb, terminal_size=(80, 25) ): if self.parent is None: out = [] else: out = self.parent.get_page_output(doc_id, doc_url, terminal_size) text = self._get_page_text(doc_url, page_nb) text = self._rearrange_lines(text, terminal_size[0]) return out + text def get_doc_infos(self, doc_id, doc_url): out = {} if self.parent is not None: out = self.parent.get_doc_infos(doc_id, doc_url) out["doc_id"] = doc_id return out def get_page_infos(self, doc_id, doc_url, page_nb): out = {} if self.parent is not None: out = self.parent.get_page_infos(doc_id, doc_url, page_nb) out["text"] = self._get_page_text(doc_url, page_nb) return out class Plugin(openpaperwork_core.PluginBase): PRIORITY = 10000 def get_interfaces(self): return ['doc_renderer'] def get_deps(self): return [ { 'interface': 'page_boxes', 'defaults': [ 'paperwork_backend.model.hocr', 'paperwork_backend.model.pdf', ], }, ] def doc_renderer_get(self, out): r = TextRenderer(self.core) if len(out) > 0: r.parent = out[-1] out.append(r) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/progress.py000066400000000000000000000041161456262201400265250ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import logging import openpaperwork_core import rich.progress LOGGER = logging.getLogger(__name__) TIME_BETWEEN_PROGRESS = 0.3 class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.console = None self.progress = None self.tasks = {} def get_interfaces(self): return [ 'progress_listener', ] def cmd_set_console(self, console): if console is None: return self.console = console def on_progress(self, upd_type, progress, description=None): if self.progress is None: self.progress = rich.progress.Progress( console=self.console.console ) self.progress.start() return if upd_type not in self.tasks: if progress >= 1.0: return assert description is not None self.tasks[upd_type] = self.progress.add_task( description=description, total=1.0 ) if progress >= 1.0: task_id = self.tasks.pop(upd_type) self.progress.remove_task(task_id) else: task_id = self.tasks[upd_type] self.progress.update(task_id, completed=progress) def on_quit(self): if self.progress is None: return self.progress.stop() paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/rich.py000066400000000000000000000030461456262201400256070ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2023 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import rich.text import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): PRIORITY = 1000 def __init__(self): self.output = [] self.console = None def get_interfaces(self): return ['print'] def cmd_set_console(self, console): self.console = console def print(self, txt): self.output.append(txt) return True def print_isatty(self): if self.console is not None: return True return None def print_flush(self): if self.console is None: return None output = rich.text.Text("\n").join([ rich.text.Text.from_ansi(line) for line in self.output ]) self.console.console.print(output) self.output = [] return True paperwork-2.2.2/paperwork-shell/src/paperwork_shell/display/scan.py000066400000000000000000000147511456262201400256130ustar00rootroot00000000000000# Paperwork - Using OCR to grep dead trees the easy way # Copyright (C) 2012-2019 Jerome Flesch # # Paperwork 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. # # Paperwork 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 Paperwork. If not, see . import shutil import PIL import PIL.Image import rich.text import openpaperwork_core from .. import _ class AppendableImage(object): def __init__(self, width, expected_height): # When scanning, width is reliable. # However height is not reliable, and truncating an image is much # easier then increasing its size. --> we allocate a big image and will # truncate it when needed self.img = PIL.Image.new( "RGB", (width, 10 * expected_height) ) self.width = width self.height = 0 def append(self, chunk): assert self.img.size[0] == chunk.size[0] self.img.paste(chunk, (0, self.height)) self.height += chunk.size[1] def get_image(self, start_line=0, end_line=None): if end_line is None: end_line = self.height return self.img.crop((0, start_line, self.img.size[0], end_line)) class Plugin(openpaperwork_core.PluginBase): def __init__(self): self.img = None self.last_line_displayed = 0 # in pixels self.txt_line_height = 0 # in pixels self.terminal_size = (80, 25) self.doc_id = None self.doc_url = None self.doc_renderer = None self.page_hashes = {} self.console = None def get_deps(self): return [ # if there are no doc_renderer loaded, nothing it displayed, which # may be fine. # # (see paperwork-json) # { # 'interface': 'doc_renderer', # 'defaults': [], # }, { 'interface': 'img_renderer', 'defaults': ['paperwork_shell.display.docrendering.img'], }, { 'interface': 'scan', 'defaults': ['paperwork_backend.docscan.libinsane'], }, ] def cmd_set_console(self, console): self.console = console def on_scan_feed_start(self, scan_id): pass def on_scan_page_start(self, scan_id, page_nb, scan_params): self.console.print("") self.console.print( _("Scanning page {} (expected size: {}x{}) ...").format( page_nb + 1, scan_params.get_width(), scan_params.get_height() ) ) self.img = AppendableImage( scan_params.get_width(), scan_params.get_height() ) self.last_line_displayed = 0 # We need to figure out how many pixels one line of character will # represent. self.terminal_size = ( # leave one character at the end of each line to make sure the # terminal doesn't add line return shutil.get_terminal_size()[0] - 1, shutil.get_terminal_size()[1] ) ratio = scan_params.get_width() / self.terminal_size[0] # When Fabulous resizes an image to turn it into terminal characters, # it assumes that each characters is 1 pixel wide and 2 pixels high. self.txt_line_height = int(2 * ratio) + 1 def on_scan_chunk(self, scan_id, scan_params, img_chunk): self.img.append(img_chunk) current_usable_line = ( self.img.height - (self.img.height % self.txt_line_height) ) if current_usable_line > self.last_line_displayed: img = self.img.get_image( self.last_line_displayed, current_usable_line ) img = self.core.call_success( "img_render", img, terminal_width=self.terminal_size[0] ) for line in img: self.console.print(rich.text.Text.from_ansi(line)) self.last_line_displayed = current_usable_line def on_scan_page_end(self, scan_id, page_nb, img): img_size = img.size self.console.print( _("Page {} scanned (actual size: {}x{})").format( page_nb + 1, img_size[0], img_size[1] ) ) def on_scan_feed_end(self, scan_id): self.console.print("") self.console.print(_("End of paper feed")) def on_scan2doc_start(self, scan_id, doc_id, doc_url): self.doc_id = doc_id self.doc_url = doc_url renderers = [] self.core.call_all("doc_renderer_get", renderers) self.doc_renderer = renderers[-1] self.page_hashes = {} def _compute_page_hash(self, doc_url, page_idx): return self.core.call_success( "page_get_hash_by_url", doc_url, page_idx ) def on_scan2doc_page_scanned(self, scan_id, doc_id, doc_url, page_idx): self.console.print(_("Page {} in document {} created").format( page_idx, doc_id )) self.page_hashes[page_idx] = self._compute_page_hash( self.doc_url, page_idx ) def on_scan2doc_end(self, scan_id, doc_id, doc_url): self._show_last_page() self.doc_id = None self.doc_url = None self.doc_renderer = None def _show_last_page(self): if self.doc_renderer is None: return for page_idx in self.page_hashes: # we only want to display the page if something has actually # changed page_hash = self._compute_page_hash(self.doc_url, page_idx) if self.page_hashes[page_idx] == page_hash: continue self.page_hashes[page_idx] = page_hash lines = self.doc_renderer.get_preview_output( self.doc_id, self.doc_url, self.terminal_size, page_idx ) self.console.print("") for line in lines: self.console.print(rich.text.Text.from_ansi(line)) self.console.print("") def on_progress(self, upd_type, progress, description=None): self._show_last_page() paperwork-2.2.2/paperwork-shell/src/paperwork_shell/l10n/000077500000000000000000000000001456262201400234125ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/l10n/__init__.py000066400000000000000000000007311456262201400255240ustar00rootroot00000000000000import openpaperwork_core class Plugin(openpaperwork_core.PluginBase): def get_interfaces(self): return ['l10n_init'] def get_deps(self): return [ { 'interface': 'l10n', 'defaults': ['openpaperwork_core.l10n.python'], }, ] def init(self, core): super().init(core) self.core.call_all( "l10n_load", "paperwork_shell.l10n", "paperwork_shell" ) paperwork-2.2.2/paperwork-shell/src/paperwork_shell/logs/000077500000000000000000000000001456262201400236045ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/logs/__init__.py000066400000000000000000000000001456262201400257030ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/src/paperwork_shell/logs/print.py000066400000000000000000000036751456262201400253250ustar00rootroot00000000000000import logging import openpaperwork_core LOGGER = logging.getLogger(__name__) class _LogHandler(logging.Handler): def __init__(self, plugin): super().__init__() self.plugin = plugin self.log_level = logging.DEBUG self.formatter = logging.Formatter(Plugin.LOG_FORMAT) def emit(self, record): if self.plugin.console is None: return if record.levelno < self.log_level: return line = self.formatter.format(record) self.plugin.console.print(line) class Plugin(openpaperwork_core.PluginBase): LOG_FORMAT = '[%(levelname)-6s] [%(name)-30s] %(message)s' LOG_LEVELS = { 'none': logging.CRITICAL, 'critical': logging.CRITICAL, 'error': logging.ERROR, 'warn': logging.WARN, 'warning': logging.WARNING, 'info': logging.INFO, 'debug': logging.DEBUG, } def __init__(self): super().__init__() self.console = None def get_interfaces(self): return [ 'logs', 'uncaught_exception_listener', ] def get_deps(self): return [ { 'interface': 'uncaught_exception', 'defaults': ['openpaperwork_core.uncaught_exception'], }, ] def cmd_set_console(self, console): self.console = console def init_logs(self, app_name, default_log_level): self.log_handler = _LogHandler(self) logging.getLogger().addHandler(self.log_handler) lvl = self.LOG_LEVELS[default_log_level] self.log_handler.log_level = lvl if lvl > logging.INFO: # Never disable info level ; it may be used by other plugins lvl = logging.INFO logging.getLogger().setLevel(lvl) def on_uncaught_exception(self, exc_info): LOGGER.error("=== UNCAUGHT EXCEPTION ===", exc_info=exc_info) LOGGER.error("==========================") paperwork-2.2.2/paperwork-shell/src/paperwork_shell/main.py000066400000000000000000000102121456262201400241320ustar00rootroot00000000000000import argparse import json import sys import traceback import rich.console import rich.text import openpaperwork_core import openpaperwork_core.cmd import paperwork_backend # this import must be non-relative due to cx_freeze running this .py # as an independant Python script from paperwork_shell import _ DEFAULT_SHELL_PLUGINS = paperwork_backend.DEFAULT_PLUGINS + [ "paperwork_backend.guesswork.cropping.libpillowfight", "paperwork_shell.cmd.chkworkdir", "paperwork_shell.cmd.delete", "paperwork_shell.cmd.edit", "paperwork_shell.cmd.export", "paperwork_shell.cmd.extra_text", "paperwork_shell.cmd.import", "paperwork_shell.cmd.label", "paperwork_shell.cmd.move", "paperwork_shell.cmd.ocr", "paperwork_shell.cmd.rename", "paperwork_shell.cmd.reset", "paperwork_shell.cmd.scan", "paperwork_shell.cmd.scanner", "paperwork_shell.cmd.search", "paperwork_shell.cmd.show", "paperwork_shell.cmd.sync", "paperwork_shell.display.docrendering.extra_text", "paperwork_shell.display.docrendering.img", "paperwork_shell.display.docrendering.labels", "paperwork_shell.display.docrendering.text", "paperwork_shell.l10n", "paperwork_shell.logs.print", ] DEFAULT_CLI_PLUGINS = DEFAULT_SHELL_PLUGINS + [ "paperwork_shell.cmd.about", "paperwork_shell.display.progress", "paperwork_shell.display.rich", "paperwork_shell.display.scan", ] DEFAULT_JSON_PLUGINS = DEFAULT_SHELL_PLUGINS class RichConsole: def __init__(self): self.console = rich.console.Console() def print(self, line): if isinstance(line, str): line = rich.text.Text(line) self.console.print(line) def input(self, prompt=""): return self.console.input(rich.text.Text(prompt + "\n")) def main_main(in_args, application_name, default_plugins, interactive): # To load the plugins, we need first to load the configuration plugin # to get the list of plugins to load. # The configuration plugin may write traces using logging, so we better # enable and configure the plugin logs.print first. core = openpaperwork_core.Core() # plugin 'uncaught_exceptions' requires a mainloop plugin core.load('openpaperwork_core.mainloop.asyncio') core.load('paperwork_shell.logs.print') for module_name in paperwork_backend.DEFAULT_CONFIG_PLUGINS: core.load(module_name) core.init() core.call_all("config_load") core.call_all("config_load_plugins", application_name, default_plugins) core.call_all("init_logs", application_name, "warning") parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help=_('command'), dest='command', required=True ) core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args(in_args) if interactive: console = RichConsole() else: console = openpaperwork_core.cmd.DummyConsole() core.call_all("cmd_set_console", console) if interactive: r = core.call_all("cmd_run", console=console, args=args) else: r = core.call_success("cmd_run", console=console, args=args) core.call_all("on_quit") return r def json_main(): try: r = main_main( sys.argv[1:], 'paperwork-json', DEFAULT_JSON_PLUGINS, interactive=False ) print(json.dumps( r, indent=4, separators=(',', ': '), sort_keys=True )) except Exception as exc: stack = traceback.format_exc().splitlines() print(json.dumps( { "status": "error", "exception": str(type(exc)), "args": str(exc.args), "reason": str(exc), "stack": stack, }, indent=4, separators=(',', ': '), sort_keys=True )) sys.exit(2) def cli_main(): main_main( sys.argv[1:], 'paperwork-cli', DEFAULT_CLI_PLUGINS, interactive=True ) if __name__ == "__main__": # Do not remove. Cx_freeze goes throught here if "paperwork-json" in sys.argv[0]: json_main() else: cli_main() paperwork-2.2.2/paperwork-shell/tests/000077500000000000000000000000001456262201400200125ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/tests/__init__.py000066400000000000000000000000001456262201400221110ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/tests/cmd/000077500000000000000000000000001456262201400205555ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/tests/cmd/__init__.py000066400000000000000000000000001456262201400226540ustar00rootroot00000000000000paperwork-2.2.2/paperwork-shell/tests/cmd/test_doc.pdf000066400000000000000000000230121456262201400230520ustar00rootroot00000000000000%PDF-1.5 %äüöß 2 0 obj <> stream xœmŽË Â0E÷ùŠY 3Ió‚2`k»pW¸w>v‚ÝøûæbQ3“››¹%ÁK<%*&©œß’ô–`¹ŠãÕ‘Îr}ÆJÎi|€xíD@ âíÔ!±êP¡Î­å&U³¾X¦Ü\Ö|žëƒãÆd=°ípW¤ž›bê‚}q”/#ŸãAŒQÌÉ,Jú%›¸Õa]Vã>DhH‘Nµâ )nH&ê;z†7NÃD endstream endobj 3 0 obj 181 endobj 5 0 obj <> stream xœåzkxU–à=UzX–l=,•$+’JQœÄñCŽIœ—+~ȱ۴B,Ù’`[B’ÂcãéæÕiÒÀÐ<²Kš… Ý]Ê$ô„^¶cXèž^–f€–fHMÏ4_“!ͤóõ–÷Ô­’b›G;ßþÛ’«êÜóºçžsî½çJΤ¦âÄ@¦ K„¡‰h²oÛ¦ZBÈÿ",C2ü¶.Û„ÏÂüíprdâ‘¿Þw‰ÕB´gFÆ ?ÞòGˆa”ë­£ñhìYûB !ü¨cÃ("öei ñ­ÀöªÑ‰ÌMµ:±-`»<1ý]Ãßb¾‡°]=½)éSu2Øþló“щøÊ&M¶Gˆþ@2‘ÎÄȪBª"=™Š'w=2ø2¶§ a!ð#]5R›aUj¶@W¨7MfK‰ÕFþ?ºÔG‰t¨·#IÒç’‹=EœäaB>’ZWžÙ] Ÿþ¿´¢@~=DN’3ä(y‡\§‚$DÆÈb_/7+]!²—üÌ|…ÚSä,Òe¾¹WÉ—^!ò=ršü|I/!2AnA[ž%ïÀzò L•ù È_—Që'ˆ»úËT1Åø¦àð"ì»äQ湊‘òþa‰Ây‰‡ý¨9ƒã<šñÖ/(½‹Ü†Ï2J L/õ¶Ïÿ7Ñ-ü+Žê6rù&ÙAÆI<±…¿^òúôŠ äˆÚözæÇ 3?6¾KFðŽŽ9Êîø ý__l)‚r¶Œè¾ŒÊÔcöS¦vỊ’¾…‹9ÜB翲Ñì¤j@µB½MõÊ×õ¡ù®j¥ÉÂo³·dcêÝê“­§Ú¯ÝîïëíÙÓêÚ}õ®Î«vv´ÛZ[šwMÛ·mݲ¹qÓÆ ëkÕU•k׬.[å_éó:¬f“±¸H_¨+ÐjÔ*–RÉ‹iÙ2ÞŒúÛüÑŽªJ¾Í1ÚZUÙæFD>Ê‹øR­öwtP”?*ò^\¯è"tDsx§ s yN0ñ[ÉV© ?/¾ÚêçÏÂÞî~„¶úüxÂWSXµš6аáó¡µJ²–oƒFgÚ"h#Ìê [ü-ñªJ2[¨GP¸ÖŸœ…µÛÌڶͳ )(’ºÅ‘¶Ecb¨»¿­Õåó…«*wŠÅþVJ"-T¥¨iµT%?&™NŽð³•s3÷œ5‘ÁH…!æE÷õ‹legض™™»Ds…XîoËoþÀ#‹•þÖ6±BÒÚ¹'ßOç•.AT—™üüÌ Çᣥ˜¨‚Ñ”™þH$PdZDØÓï“.W}=3ôóÁ™ÈLôìÂô Ÿ7ùgf †™dº›„úQÅÙ…Ÿq‰Á{¢)2 ›ÃÊЃ{:Å’îkûE¦,ÈFƒM~ß&—Ïœç }™ [Ð9èaŸOrѳĆ8ÝÝ/·y2èz†аÈD$Ê\Žbë“(Ó9J^<âÇØvöôψª²1züHTœÄìº^ Œß$_vùü33ßS^­ÚãEõjtJ-À¼‘DfL´Q|Y~]pa«Í¾Ñj$=mþ¶ˆòw`Ô xttG…œ½ý¢ÐŠ€U"Ö6[@‰h6ÖJƒ)üIÑêoÎGW2«m¬§ŸŠ(b¢µE$‘!EJ ´ÑyÅ·ÍDZe$]þîþçHÝÂùÙzÞuºŽÔ“p«Ä̵`–­n›é ‹Þˆ+†ón˜ïwùD!Œûûãa)íÐCåç]49Â4Wzû;{üÝ{û7)†ÈIª¬m™¿KVƒ (”ðýŒ‹ #£ |óV|ŠÚ²¼MèpŠ•·y+ß.’ãF3Är¾-ÞªðIí%JÕR:µtä´i¤&êiépùÂ>ùªªdÌ+£DäÔŽ —)$`~¶tP”äK‡”ô|¿?îûGyQõKc“ÜC½¬8ƒú\‰Uï’Ö"g¡›ˆɹ†äL1XáZì\±¶óÍŽeä92?Sàï왑”û…-ß))……Mf] ¤ íǵ—7ᔦzfV¤É<ºYRâß›ñ÷ôo¥Ü¸žÜæºYêËB:¡³·¹ª—¶æY?ÜÝ=+ÀÝ={ûŸ3a]xwoÿ3 0-‘æðì*¤õ?Çã¦A±Œ„•Rƒ—’¦=Ø( ü®çB¦)UE´=tÅäp@†Î22Î$w´šv$)*™"ä¸Uˆ+qÓG¯Y"¹L(T ‚N00EŒk$Ô3ˆù Ö±: § P®Y”ÚCÑgazV'¸dŽiäd ïî»ÒußÞþÓÜ]ô‰5K¦‹cƒÛJ“åÖðèL$,M6ÂahðDðoÇ0ù·£!ƒXè7‹z³„o’ðM2^#ᵘ¢ÀŠOcìC"Hpm¿§$_ú ׌é‚©0.*3¦ßV¡ÇÊðÜðÖ VØ*¼gaôLkã ¤tlAÎÌêØHXÇZ „‰¥‰#ç98ÇÁ½æ`€DòÃE^ãà¥%9èâÀK 2^äà1JJP1ƒÊ@8xŸR§)¾†b¶,Ð~d±{)¡‹Ò.R¼˜ëCà©ÌEªhŽv3M©hZ ×ÇuùëÆÜ•R®ýËð_ H4ÒTa&uú4×9û¯«3[ÀÞh®[_ãkØhö¯4‚ßì3û×TC˜í6ØòVÝüu®ÕñV—çÞ´þ­—ê{Ö7`Köå7´úÏnp5H+Vn¿Å3›üD8D¬VgQq±Î©óxÝ¥¡°›X±aw†Â»­„aÔjóž°Út ç½0瓈±qÌ I/D¼ò‚à…/ð^ðR2’¦sT$½N%E/œX„_ìœTj‰”±ã¨›ê$ ŽºÁ8vù³¾¬ÚíPWËÙpà’7êý+µ ¸¦ÁAmÇ_7Ý|k*{Ãm'÷ëp6vð¨e/V—oýÎ]ó:«ªœÌþSîù R3Ž*œ8XŸZÔ»ˆOKÿQ&ƒÆl¶s¬®'LX0±¬M°YBa›Ñ`6šCa£Íj•/Ùᘘ¤"vÙA°ÃœD;œ MÞ&;;\¤d]̹4G$ P/äÃOJ¦_bð©ÌuÊà5þ•«ê7 Ø+ƒ¾E¨ª„Ê*¡ðûYç‰; Bõ¾Ü>Û,“åÒì]øˆù;öe²–„…zŸÖZZ„)Q¾®ÈÇÚížPØe7±úPXËrÓë ¹"ë ´øuðô:X]ë g/Áð# ÁØÈBó®i¨³suµ õ¨f¨¹v›ÍjÿJÍÊÙ=,ów³ÿ%øƒšªõ7½øp8¾¯öÇF ¬kHu÷]½ûþ½M~(¸ç˜ÛòÏßj=ys½Û×:¼õ^ï«PkãîÒÚê–k¤céXøˆ½‘}¸pu™šÌee*Þ`pªX,ûW®ì;lfó Œ˜Ùkf ¬ÙL 9­ Çh#¶P˜˜¦×ÀÀÖ×aÐùÄAï:Kc@v>i¤9)Ï@³2J%ÿÖà`ÍõÛ¡ êWÓyÙ°´Å`³ÖÕnØo<òÝ©l¶$5û‡':Ú~U¬gå¦Ç|ëÎ{[‡jÙþÃ7çïpVíOcÿ-;XÕýÑ}©WýYJ½Rô:èœÅ˜U©þ‚p¤]XSX\¬-aY»CeÐBaVoÄ9mîî1ˆhr@À!…)•K£º:ÅúFKcm­”CjL ³¿¡ êlu6¿ÙŠqÚh+ظå¶xÓßÿý–šÍ=þÛ­©æþª5o½Õ;xG³i‡ÃK}BŸ1‡ld9*ìuK lF›Ûã$èh§×‰Žv:   [LuwØÀÍy@ôÀ óÀ´’ˆx äâíøòãÁÑ|?»û­ùW;ŸÂGÿö!+>ùù;¹”mv5ànòŸJ²S¿|[òÉÂçê)ô‰ŽØÉ.! ¶’"k‘Ãi· „íªHØÎš¬a“66Yˆš'ðN8ï„NH:邦£¥4”W,DûLÄç7c2Z€'fl”ù©‘ª'²odÿùÌMO^þpþO†áì_e]yêÔ)æ)pÂÊÏn)€•ìËÙg³g²bö¤J¶–îwRüÊÑV;¹$œä,«@£±êY§ÃL"ásÂÌT™ÅîÌŒNm6kt:FV;€¥hTš°ÊrÆ O8á'L;!ㄘTN¸è„œð&Å#2â„^'´:áu'¼ä„¼Èí9¤¢'j¨3¬TCã%ªBæÃöœÑ 7,Ïú%ƒ²Y.4N†ëè|°/Þ)¯k)ú¾uÁSïÏ¿ðØ)ö_šùä›ïÂï¶m^fïüå|¤Ï½S<ÿƉlìqôaN„ª'.Ø üƒ…ãX—Ë^R¨r¯à\NW(ì´k‰5fKŒÚâPX¯—Tn¸ä†ÿæ†ÛÝqCÌ nÃnxÓ /¹áŒ Hî\$ó#Š¿–ÊX)þ•uõº¡5‡ßü{ªè 7[ÔU½VQâæ¢λáu7œpô’nÜÀ»Áä‘6M”oIQ6ZV•|I–l¹Ý0_¶É Q(Á4^²ºAZvih~ýøãOþåÕÍë«VÖ4Õúé+YÕ¶ýšæ×Ï—¼z‹-ùÈñÞÏ/ûªª|‡rŒƒ k7y\Hªõ…: ®ÿ„¨Y5:ßö¦^ÒÃ=<¡‡ôp»2zˆéa•¬zPé1Ý(Ç1=–+zˆè!¤Aszõp‚6Mz z¸H›È·˜m‰”ReIŠ^©YqB¯¯)»Rš$¤Šäƒùz È] ¿Cä-¬·‚žh4†"V÷èµl iRjÔ°¨ÐCmõõmÁººà¾õëë‚AÔÁ,üZûmzžèx£µPmUs6¦ °¨ƒ1ŠŠ¬ÆBµV=6kÙb½þ쟄—¤g¨Jb\Ãdžƒ9x—ƒŸqp’ƒ9¦¤ 8XMÆ.sðO¼ÍÁs|“©ÚGpð&?âàQŽp ²—6ê9XÅ•2¼ÄÁž ò˜®Üñ⋵3Fa`ùqƒ¾°Ž(•[TÔå l<`Ôê/Äj¿ü€±³iuP§“!õþ†ìÙG²­S yë±*Ø5oÀóS^öøç1uQiCCéç]ìãŸïgg%XÉÙ‡°V°’n¡Ê¬Õ‚Á`ã4fºÜ«Í,c5™ŠBa“Qk(Är¦Ð6@‰^ºqÑ'M­º:\â̹2FÞíýkVjUþv<0Ul®ýví÷³Í‚E·õÕ­¸1Lº¸ùæ\ ð,ôk´mîì·‘’‡Þ`Ð:´nÏ <­0–`ƒs MœÍ‚œ¬iO˜5=á<ð’°ÐPy x ã˜z=Ðêz¬ò€‹’±âa×;Xå¼î|)”Ç/ŽÞÀ¿ëD´ô<´zé¨õêÿºY>u÷íÅÑõ7Þ6RÙ˜?õ÷ (ç!zN`¤_Øgp­ÑãIqZè¶hµnbwÛ=ÞR](\Êip'µ²Ýa«ÉˆQ3î¤Ãá1zL<Ÿ;õɧAù(8—ƒyïâå–3Wv+ýBÝâ—•Á)ÍV­´(جŒtÎ`²ÓwnÉ”öNÍÜ:äÛÐÄš{õ×o]óÚn¸xöŒÍ0o7ýƒªÚQ•7ÛýáGóÙ[í¥ñwfƒìŸØSdüFX0J‡ÇÉX HeÑ»%fC1ŽÍVl$Úî0KV`‡=p †ÔŸÐ4xÓ?óÀ=ðmšrAÛìZš˜!Œ^öÀÛxÑÏx³ç>ÜN¹‡iÂ)÷JXhÂ\òÀ?Q~̰38™ãOy`Ð{r ¶Ú\Ž?oÇ™¥ú—ñËÖlºL¹óÖ<Ó.|c±=«¨=Rm޵øyš´²Aä´ÇèXeí—(#§u>Ý»<`ôä+Vi…Z²8-Þb¿Xì,e^ú5ÁWG¤©6¿Ó“¨ô­É•5­d¥r"ÝåÍ%¿ ˜ùùî]Ÿwc}ÿÎÙG"pæìåûaÿ`ö»;"™lÐòJľõÀClç‡k>ÁÜoÛç×>yì*y©ÀóÙ'Ò>DDá&«A£ál…–HØXì-f ÙââÂ5Ψ0ÃÊßcå¿«Z ÀÓ¹ïªç–ø÷!”sëÇt£HЯ™äMãàé×Rô+§¼›–}Å´¤\¬ËŸšpÅ™E=`¶JÇ%É=Òé©9ŨÚóW#Ó]Íž’àº{TÿBWöïüÅ”çÒ{éOåqïÆ5b7®Ÿ‰[Íj=§æìŽc(l(0qVÖŠ³†#Ø.8 Æ¼L¸è€×pÂÓ@üÓp,µ=oéâ © äÍ´„’êX„陕ݽþÔÞìÆß¹ëÄÆŠžLöÒþÑ}ã«Ê῟÷f?=ÈŽ¾ù¬Ðÿ À5íÀÊÌÆ­d¼òïÑÓúú/¯üÚ˜ b5ñ8ÉÿXMÇH´¾lùÆbÌ’‹Ó4â ã7¤LEˆ•i$¬›ô2Òï£GI¶­ø©Òd‹úçd‹ôf~Hš_ŽÍDù¡DòPjld4ï*çkkÖ×ðí‰ÄÈxœoI¤’‰T43–˜¬.lYÎVËïAÑL%¿sr¨zר`\æå{⩱á=ñ‘©ñhjGz(>‹§ø*~9Çòö5ñTZjÔV×ÔT7\¡.gKóQ>“ŠÆâÑÔ |bx©!|*>2–ÎÄSˆ›äûª{ªùP4ŸÌðÑÉß›ìŠSäP<•‰"s"3Ц^?•KÇÆ†¤ÞÒÕù,rGO&~ Î_ÍdâéÄds4}¡e½c“‰t%ptlh”?Mó±xzld‰ƒ‡ø¥2- Y‘æ3£ÑŒ4è‰x&56?„1›H¢Ô éàXf;žˆ§ùÝñƒüžÄDtò‡Õ²)è›at*?6‘L%P«ÒC©x|;‹Æ¢ƒcãcÔ6ME‡Ðcè¶±¡4õ:‚OF'«Ú¦R‰d-ýFû®+Œh ìÍtbüö,qOÆã1©G4û@|…°ãñDâi<ÉËŒV-²|81™AÑÅpàè­ÄÐÔ„'ts&g\t(•@Zr<šA-éêÑL&¹98xð`uT ÍF¦5¾Ž–9”Œ+ñHIZ&Æwaø'¥ÐMÑøJƒèÙ¹‹ïJ¢‚h¯0Tò¹Ô\_½^éÝ8–̤«ÓcãÕ‰ÔH +¸‹´’12‚wï›IœÄwÛQ„†H‚$É!’¢\£ˆåÉZÄ–ã»–Ôõxó¤¹HGyž´ œB)é¥zd’T“BJùzmµíQ¬è Ò•íDù!Ô° 呺X/Oz(f ×YIr„L¡QÄì i”Š#OŒrð¤ ï?§ãÏѯ¡P:O©E»jðSM¾TöÏiC]<õu†R$['¨ý7 .r_çùâ4~i¤Äi+FµJºû£‡r…¨¤ä‹ ím’rõ~I]Øã0ÊÑXæ8‡¨n)'dÍ „G¯^OQ bT.7¶4öüÅ|yvôPëÐ>¯¦x©¦´fl§•qÉ>ë¥V$+ùâ Z"õ;Já(õgŒJKY6©HbÞñ_Û¯ÈF•¸LÒ>(VJ2•Š¿‡é3MûÄ>xjŸå¥}óÔOQêu9ÒHÍPÞ!Äãç2Ï&Ð+r_ƒÊL:Hçå¨2â ª—ÇJ&Ž)+4n“¾•4ÆW¼"çͰ’©<•M"œ £Èù±ŠÆFIœZ*AQ:÷Qbœö-Û6J³#JcWb¡#Èù+¦ŒT²:I1U¤æ…4ããŠO¿+Å®/Õ({pqnJ1§ö¦éž¤ÖÆòc”½-q+=É#§+Ò ùø Ó|“=£Úª¾ÂçÃÔ7¥×µ(†9ârn%PvŠÆCžOr6g¾à¹(õoB‘KÒu)£Ø2AçÇ(ÍÀ$ÙŒµe­“>Õ4Ïš!eÎT+6þÝr’]IêÁÅó#•·emÜ¥ÌþÉü¬›Z4s‘èÁ5h]/’JþÏñË4H³fùª¹û[¿lr6Ža;CíIS_VÓ1Œ ½ {ØEëhz-øÐ¦/¹fu¡ƒ'£0BJˆ"d7 >ØA¶€oiÍønÁ¶ô®†mdù¶!~;¶·"~ .ž^|6áÝ…÷½x«ð–9j#€ï€Ò®Âv%J¼†O ·„mB¬ô¾ ÛønWÞAÄ·á»MiïÄ6¾I´ÒôyTÂi8?¯Í?‡?ƒÐg0ýɱO˜?\,÷>}ñÜE¦ëãŸþ˜­ùŒC¹`ºº¹¼pâ‚¦ÐøÈïÁü›ó›¼ïo{¯ï·ýª¼‡#{¯æ½Ð{Óï‰ï©ß¶ïW,ç5Íñs5sɹé¹×çÎÏ]œ+˜þ鱟2ÿýù€×ø¼÷yÆ{ºëôáÓlä)0>å}Š =y”9vŒÇ½ÇÇÙG®ö>Üîñ~ïÁ5Þó^|9»0wúÁ"sðyè‚]dúp÷ivÁûô\Ã2âÓ‹wï.¼xß‹7ž{Ý‹wv ›Ø¿ý}®û*î»å¾#÷©“wNßyìNvúŽcw0O8w€I‡Ê½‰É ïdû:¯³Îѧ­cû4Ø ö.ì,[Œ Þdºvowo{¹·¤ÎÒ§Æ«ÑÈzÙ&¶‹M°÷²çXmÁžÇÛ÷ùÐÅ#„t† ±ËÛèbÏ.œâ>ÔvUòªé«ØÁroGû&¯±ÝÛh­ýýöÛ5íðþŸž ²B°<‚_pE‡««³õ™ÁØgª3ö1€®#}ã‚‘1Œ‡¬‘4fš5œ…c³½=gµ {:łе"Ü-–õHO¡{¯¨¹[$}{¯íŸøNøŽ£GI³»S¬íé#îp§C@€iLîYŽ4‡ÓéL½ ¢á)|’Š© DîOËX’§“Š4¤qJS!¨ä6à³B¢!B’”ÞŸ&ÒC"VÈB’tZQG…åûÿ¶g– endstream endobj 6 0 obj 7404 endobj 7 0 obj <> endobj 8 0 obj <> stream xœ]’Mnƒ0…÷œÂËt DBH)I$ýQiö"c²àöõÌÐVêëûÍøé™°¬Î•éçðÕª†Yt½Ñ¦ñîˆn½ d,t¯æµ¢U Bß[/Ó Ceº1σðÍŸM³[Äæ¤Ç‚ðÅip½¹‰ÍGYûº¾[û˜YDAQ ŸóÔØçf€º¶•öÇý¼l}ËŸà}± bª%[Q£†É6 \cnäQTˆüz-0úßY¼¶´úlœ—J/¢}RxމÓòŽùˆœg;ä=q!§¬‘ÈkhÎ÷÷ÈGžOúqBšGæ¹d=ñ™¹D¾ð]ä+ÏÉ<ˈÙŠ¹ú§}öŸ¡Éþ“2ûOwΚÆ„ïø¿Pwç|ôôØ”9¦Ýøýìh±‹¾oˆ’œ; endstream endobj 9 0 obj <> endobj 10 0 obj <> endobj 11 0 obj <> endobj 1 0 obj <>/Contents 2 0 R>> endobj 4 0 obj <> endobj 12 0 obj <> endobj 13 0 obj < /Producer /CreationDate(D:20190902205629+02'00')>> endobj xref 0 14 0000000000 65535 f 0000008715 00000 n 0000000019 00000 n 0000000271 00000 n 0000008884 00000 n 0000000291 00000 n 0000007780 00000 n 0000007801 00000 n 0000007996 00000 n 0000008384 00000 n 0000008628 00000 n 0000008660 00000 n 0000008983 00000 n 0000009080 00000 n trailer < ] /DocChecksum /72B44A81E5EEF3D98178B73CE31BA672 >> startxref 9255 %%EOF paperwork-2.2.2/paperwork-shell/tests/cmd/test_img.jpeg000066400000000000000000000142231456262201400232410ustar00rootroot00000000000000ÿØÿàJFIFvvÿþCreated with GIMPÿÛC       ÿÀ dÈÿÄ ÿÄ> !"1A2 #Q8qu‘³$6B%9Rart´µ¶ÿÚ?ú§JR”¥)JR”¥)JR”¥)QL¥q_–‹%?ŒñÏÏ—#_¢·þ.Œ_¬ì± §ûÊÀ)§Ñ3O¨>®CÜBµJäæ÷+m òÑÆw}%Ë}úà·Ù~©F©ë=@«æM>„0ó ]ïEØûTî_”¹ßá|‰—óW~I -£GQ±ÿ=3’øÈª¨¦©|­’7§ñí1ÙˆnÞMºlÊ ùMnºò ­ï[ ‡eKîã°#`Ÿ[XúJîVZã…t݈¨bÕÊÀš¯Ñ5ƉG¹¶.ƒÜåûÔÖ• Ì7½Á±•Ã|Ú¶ë-ÓÔ4€ƒ™ö(xÓñ¦¡·¡ö!¾ßj— ¡•A5N˜¦c $¹DCí]”¥*·È™‹ä¡‹ñ·Ë¾»õ"BI‡­õž/Aé¨ë¿¡¼½¼}5ØšÞö:ÕY¥a¯K‹å :zíô~¯à‘ޤ}?“Çæð¤e:vÐõß]oC­ý†±8 ~«â‹;'ü'á6A1šô>?¦õ_“©{õï®ÝK½oAö©})JR•©\‘þÝüHÿÕ{ÿõiTŸøŠÿb¬©þÿ-«ùÅ[c`k—>Ã_7Ïêí¡iäo.W†YgMÊ ‚ÔTô¥@âA/„¨£  O¹w$¬Î*Ó ” £ìc¹8Ø w©˜uþuäý™9#È›?%\øˆÖëDaµIfL% ²ÆtwÍãN{žŠ L@‰vª»xÂß 7°]~‚^r3öÑäN&IôÓ¹#\i”ítðÆ]¾€¥0¢} LsƒµF¿ˆ'ö2ÊÿàCþ²uåªþá¸ñÚ÷å·ܘqÇÉÜq–bŽ…ÀHÀ t‹3•ÒÍÀžpK·SÁ¯z™q:;‘Í®8ëtN(Ý/LŒ¥½-1&²± È)휉…v†8ÛúJïÔ®‹ÎN Л—¹ç~ Î=Âïä¼þFS0¨°)ÿ ”»0ãUó+ÎñúÉšÊüª%ÒÎ%YX|’Ù¼Ú±Àtˆ+&»µ_9èv‚!ÙAL_œu_Jq5ä9Y¹HùžßŽ™ê /©lšº×ã÷Ö§ó3Žc+ò—-Ù¿=Úî^`~"íTɤk‡-ÒþR¥éÕc û©‡ìaö®îP§Äì7ŽðV µ¯X«níºTxÊÊõ3Þ€SYÓ´ØeE@YS~û!A.„TˆMBXsWgx›Ë»:ïJuŠÒ+NÂI¹‹˜beŠGi?*ΜíÅ9H)ÊAØƯ~OÙ‘™ØÒ<‰³òUψn´F;Pd–dÂP«,gG|Þ4à籉àè ”Ä(—`:¬ÊøÛŒy‡ù×Çs’7Ž-ÞH‹G׃¥#d USCk«ê[øÔE%ˆhÂm—F â¶ǘ¯ç+:Äø}ïqÙç“”ø£Õ|âåº*®>2%ìr€ý$ kA ö­¶¥)JR¨ì·ƒnË÷’¸72CÈÄ# Œ†âd¬©]/ëÙ}9J™ˆm¢&îrh5®ÃíYŽVâk:qêõÄÖ“ØÖ’÷$Û5ZEElCtÔPÉæÑìQ÷ÕdóÞ9›ÊxöŶû¦-ånKuÜCEžänE•DHS(bÆì}Ä #¯ÀÔg2á;«"c¼qhÂÈE òкí™×Çtª…IFñË‘EÊ•3œÀQ耎¶%¯NTˆå°\*É`ë×|%dÒ)bîèW¦;s€hæ#†‹”LýÀSØ}·¯·.=ak§«z]Ù ìž¼2 Âs*E±38ô šA4›¤cœÚ&9Œ&0ŽÆ½Ü¢Å—mãýíŠmW‘Í%®HÑfÑi›bÈCmC&C˜E±Gû«ŽRƒäŸýœëÞv?LÈwuúp‚ëû(EÛ,š‰û}"S°hw¼¹:ßÉW&pÍ×…»+y\q  ½³³HÆlÛE æ9ÕYA:¦úÎ!  U‹—ñÄ~`Å·V.•|»&·LK˜µ * J(°‰D@t?}jµ¶îÀœàȘ‚â·vdÅí!\À8ˆhö âŸîÆM$ݨ©Î“dŽ~€°¢‘Íã:ˆ€†Æa *Wá{θh¼•«kÅBÕ äf¿²+ûüÄ×, =玥ÜIÆ|yšÎ#ÝÃE[,ŠÀ‰Ê¡@J ¢"~Þû -Ùƒ²ÎqÃÐ,sÓmÚÙ^Ø™ ‚zÉ#•G>Dçç*n„X†HâES8€±€5ì5ûnÀsµy¶Í¯,‘†ZÁ7r¬æÛ‘<ƒ¶å0 ËÕg>Nb‹°w½µYì©Ë`¸U’Á×®0øJɤRÅÝЯLvçÑÌG (˜ û€¦'°ûo_l~ãÌõ­’\e ¹ŒåÏ–Ôú±,L̓p…jT›$sœÚËîsLa÷Æq«ò›–ß÷/Æ–´ q1O¢Ù¿k<©Ñ&‡˜ŠíÀž2›°”w¾ºüÖÃR”¥)JR”¥)JR”¥)JR”¥)JÓÌOš-ÌÀé¬ÍjÙO#­™I÷‡›Lë. Î¸IMºM± R‰Îc”<"%.Š"a8çîl\6‹6y êãE퉬Ù3^Žß2!EÂ¥M'JÇy=JmǹMØàSD6@¦»îîgÏÙ‰#~ÌqÆòKT ­òwÌ‹ãAeJšo;¸¹ÃÜ ÜÀSt==õWTÈwu‘ÁÍ…ˆ§²$Œ‰ÌTÚE;hÕ4HíäYw*„(ì5ØD†b~GÎÝ×éq6ZÃØÂós¤Ä{'ÏÛH³’j‘ÊE…»¶Æ銉‰ˆ`)€ ëÅ‘yC9’äqÂÓYRè·[¶wq¤ÆYœkX„Ü™*áÉ€¢±Èr¤±.‡aøôaR6ÍRòÅ_§²öÄ•æY)UŠPxäÊš™2S)LåY5NE ©D5ªÇÝ\¤¼]sv¦ãÝÅ•>W}ðÙ¹FÓ b£›<.…VÉ,èà+¬˜ÊB覢m€êÀ™¦5@É?i/nÌÛòJÃÏ@ˤTÞF= ™úˆ”å1C‘B”å0à3y?&Y¸v™ÉYX‘°0MýCµÄ;¶)P÷1Îc¥({‰ŒùªŽÎä~n¹æ"ÜHpÒû†´¦lDfME™ÛtÖ0™Äx-æH…Œ&0éØh}{•KâÜß ƒ£q<åá/qÛKMÅ’Ê`ºîHäôÆ" T’LU2ê,R”ê1ŒP)¯˜v°¶›î9ÜrÄڤČœ`èì#’XɦñÛþålŠj 0ö(õ0†ò.Zô½TÅYSNãçáƒ0Ö2Aãwíd”àš‡jñ±…5E3€rSQÖ‡uæ¿s¦r€¹^ÅX\C»nèˆçŠÒãpEÇr”>¥"²ÞUC~Á²“¶‡^ÚÞ çWy7ˆnOÄ8úB}óˆ¹×–ü‹Ä¢žG*˜»â.e{ª6Ò§ûøôQú€j'ÀÌ‘žf±N:´o.8…±cÇÙáxàÉçÄJ›tJ½ e‘òDÿPMuq©¹mÝ®—Á\^»2-–ÕÒÍs#3ƒÀHÂUb‹…GD”Å ÔD¢!¡ª|¨ÄÅãë®IHÈ=µ£ÛªgÈ=l)>jé5E²Qƒ€\<]7î}ht;­oåG&r 2BYSŒ—†>€¸í÷ !¦H²~C.¹: ›´œVf'0@NQ(@ bî·bÎÿ„a?Ã[¤ZÌR”¯œ’_÷HäýõÃÿé—­”çZi‡ òz`Bô-²=K¯`Ñ“×ùj»9”šeáKL¤(¶bÀRëØ4j œ“É3—NƳ9½Î±.xgÎ¥î¶Â‚ ,íPð1+Ç2M{Š(&Ù¼`!T]’ž=…çþc‹¹9‘sW(ÝIIÈÜW1g#ÚŸáFP³pšeH²ê†0€z}õØn÷ÆÙW`>Hg[?5]q6b÷dë+®Nyê,šJ°QŠ( YSDȨÊb€‡`ÖÃzüãžGµ²Ÿ5óeÓdös òµ´Õ¬¡SBT;°3”öU.Ý“é7ˆt"×Ìwñ•¿wdK 9s;0á+®:î•~X†ù ~&Eƒ§'Y³öeU1"€©Mõèânå6À>Õ¶œ<ÇøNÑF÷ÙòäËJOI5øìÔÕŒҀé¤ 9I"‡ÄdÀvcˆHÀ®þuÀÏÌqýÄ¥½o¼ž=¯? r¼Šf@:ïY2|’î!÷›ÆC¯ç®ƒÞ¤vß0¸¹v¡x ódºs<«vì#Ë0¯QeÌR¦µíæ)ÄÇ)z‰@@~õ –L‡þ#¶éŽP&’1Dñ–Á¿òÿ:¥ù5dÛŒ9˜k—.gL—ˆ-;ÆÐdÆèµ®B±UûE–2¬¸17ETÀÝJ?ÌЈûTÓø»(çhK®Ëæµó˜¯8Ùc1µ¸‘nÕbޤ’ì˜oÄ>Ç( ŠMï@]ü÷jå¹+öC‘ó»q ¬ Õ)…o\¬í¥#ضXHÜz¨‘œ:2‰”ªù "òhÛU–àzn¦¸«ÈxH©Ž`~^,cUŸîiUÈv-Ä‚ë¹Japs(&S±J>CŸ`íVDzŽ0ÈœW°ñm›”­w·zñ›-eÐRAš©²"* Êo)Šˆ”Cú…jŸì&ÓÇÚy[ž¹·Þ–°"vÎw”Â#å Z·U= s©ÓÀ%8{ïumßXγøLöO^w&[·¡¯ÆwÔ“ç2ɼ”Òh«"X„L«ëÄ¢‚>âcǰf9¯Ë.>^œF¾aì‰zË\‚“HˆW‰¼x‰L%1œ.N‚h”C™@(¦¾â[…gÂ0Ÿá­¿Ò-f)JTlØ×ÑqÏ`Û†µÝ™C8„¤‚ÆQQUA;~¾3 •8ì¾æ0ûûÖNvÜ·®˜GVÕÍ/ù/¨÷íHá²éÿà:G)‹ìÂû3o@\pŽ­›†>Rê"ÙÌ{ÖÄ]²èˆhS:G)‹¯ùD5]3Ö©uC ¹sÛ3&(°~É' Ä4ã9DºÿʼM±¶:föI¥ƒn îØƒpœRR, pl`.Ðò§é®À°ª³eË®%Z7¶8¹beû}4RY"LÜ1tÑçsvMËeRA3Šp6û½€Gq.F·®»ß2f$¡X]W¿ dÞ aY”K­š‘Q!<‡*©Î`(Ì_`«nè°ì{á$½lÈ+$ H’‘È»*fØ ABއÒ²1Pñ0L‰ Ò=¢_±»T ’eþ┽•c±Ôdú·\mƒn4›\v¬’H&èãïû•)@ã÷¸þk"kbÛ=Æâ{z0Óé24jr¢Ñ1xF†8(dmw„å)„›ê&l+º^àV&z%œ“ÃJ¶xHáý C€€ÿÔ+ÁlX¶M’ÜZY–t Qqèµ ‡÷&P é‘ÇXú^áBî–±-ç³­Cªn"ÐQÚAý ±Š'/Ø>Ãø¯e¿iZ¶˜H…«lÄÃÄ‚ÒÒ?d›Xù]y\­Ðȱú—²†Ù ØŽ«‹q”Ô½õ Ž­ˆû•ÊFAy–± Ò|ªFË”€¡Š""m€WmÇñÝâõ¼Ýa[“nÚÛ¯%ƒ•êC(QÿÒ³­Y3bÔŒ™4E»t‹Ðˆ¤˜…/ô‡°FI‰1JmåÙ§Œ­2¡p¦d¥ÒVÀI÷ÀtÒÀ?>ÀjRŠ(·DÛ¤D’H B…”¥Ð{~+)J­xë™_qDvOùsà^½ì“?Cë=WOHõv½¼ ¾Þúêí­Ž¶6U)T‡%ùyaV4=Ĩ— ù,¼SϘˆÑÒneÄÞeS9?i ìa/Ûî#í^lI—ùMx^­ ò§?OmõQTëNþ ÇKxT)DHOLæìm`: ìjcˆsê¬ÎE‰ùwá ]Î-_'«óúßvëyõо=ú޽6mußaÞ‚Ç¥)UÇ"³èº³Ë¿ùe¡|;Õú_QÙR'×ËÐý?~÷Ð~Ú« |È&·]yÖ÷­…vR”¥)JR”¯Ÿ<1âf;Í\~kså¹[žp£?:X6-®'±íaRNQȤ“US)•2ÞUEEÆúÊ_ÚB…X8bÔÎürÌœ^Éש÷]Ë/bGÜVݸA¤¼{¥Ô6á!U-ß² "";Nò:îŸàô|ƒl±tªLd›A0Dn£¬f._V¼f"î=»h„߸VÏc c«o[©‰cm¨Æñ÷÷1R ¹¿©Œ &üˆkg9ÿQÿRxñúEòßÍÿ8H|/æO?Ã|Ÿ [·ŸÓÿ7¯NúëïÛ¯ãugaoöÔù­ÇûDþ‰üµèôÿ%ü[×zß"};ú¿åøºyw¯«·M{n©[W$Jb kÌŒ™‚JÉ[—ôÓæET½“õ‹cãä q(ˆ~@¨6‡Æ³VÚÇÆ^qÊdÇ <†¾ÛÄHɨ^»tÈô‘ 8쉂]:CB~Þî3žQâÆŸÈvŽB ÄÊP0­>éšh.™„(¦¿Q\¨ªtRÑÌC} >ÁS+Añ*ñ|ÓËÝps¨G(Y JvRiJ”L}I£¤ÏÛØå‚Ä.ƒ¹‹Ûꨎ%–÷1‚îÌœ‚—¸'Ú©vÊD[VûI×Ѭ!XGº;t„j²}ÜÉ™C¨a€j¤<Ò°áñŸðþÉ]¾ö]Ôs°ôæ•’Yû‚ï’?A]sC½º” aÑ@¡ö¨—"8«lcì rçØkæùý]´ <à¥ÊðË,é¹AcZŠž”¨H%ð• t ­Ì¶d•™¶â¦(GÌPrp°é”ïó¬•)JR”¥)Ze†øáÍ?ãÿ”1¶VÆ.I%*þEë+‚5ó´£ »¥Nbº&DÆHR1’U1WÊ q)ƒWßpklµÖŸR៙”wpÜ“ª·" JË:?w2{@¥)}ôR6?z×» ±¸¿ˆEó58wvM‘àºÝÆ  ›Þr,Á¡Ì(hçhù QêuÀt5ºÕQfLCrä<Ÿ‡¯XWш±Ç× ¹i4Ý*¡UYXªJˆ†º€"†·î#íVíQVÎÚ/9ZÙ(c¤ rÝÕ#(D.§rÇ:bݰ‘A1 Ñ`N?@˜e6ý‚'lâîscH¨ì{ef,YpÚу62×TæÓjO¥+éÜÎRh¢ õu؆Äjл­îFü•o£`d«8·kõ0âjÝTñò‡ĉ"¹Tl` þáßÞ¡8ß gI|Åœ¹yYN%í˜w°ðñ6lk–íWgLVUeœ¨e$P)4½bO€ùˆnËžK‹ùÈJÙ¼fžyn^ѯ¥ùqÛ¥Y¬ÙRœ¡¾¿ ƒ¨zØÔ‡5á|Á˜¸táË‚ï¶$/»˜¢i$Ù­Sz¢ªRWT¥*evú„ è&ÙïÍå< {bÛ}Óò·%ºî!¢Ïr7"Ê¢$)”1 cv>â×àjglF/ mDÃ::gYƒ¨dÄD¢b&Rˆ€ˆëaí° ÉÒ”¥)JR”¬EßiÛ÷í©3d]‘þº}‚ñ’-|§KÎÙb jºbS—e0†Ê !¿a¬&*ØÃÛ&â{.:Úˆ…ÂÚv²ÂR”TPæ:‡êR‡c˜GEÞ€*eJR”¥)JR”¥)JR”¥)JR”¥)JR”¥)JR”¯ÿÙpaperwork-2.2.2/paperwork-shell/tests/cmd/test_txt.hocr000066400000000000000000000007471456262201400233200ustar00rootroot00000000000000 OCR output

ABC def

paperwork-2.2.2/paperwork-shell/tests/cmd/tests_export.py000066400000000000000000000222421456262201400236740ustar00rootroot00000000000000import argparse import os import shutil import tempfile import unittest import openpaperwork_core import openpaperwork_core.cmd import openpaperwork_core.fs class TestSync(unittest.TestCase): def setUp(self): self.console = openpaperwork_core.cmd.DummyConsole() self.test_img = "{}/test_img.jpeg".format( os.path.dirname(os.path.abspath(__file__)) ) self.test_hocr = "{}/test_txt.hocr".format( os.path.dirname(os.path.abspath(__file__)) ) self.test_pdf = "{}/test_doc.pdf".format( os.path.dirname(os.path.abspath(__file__)) ) self.tmp_local_dir = tempfile.mkdtemp() self.tmp_work_dir = tempfile.mkdtemp() self.tmp_out_dir = tempfile.mkdtemp() os.environ['XDG_DATA_HOME'] = self.tmp_local_dir self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.init() self.work_dir_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_work_dir ) config = self.core.get_by_name("openpaperwork_core.config.fake") config.settings = { "workdir": self.work_dir_url, } self.core.load("paperwork_shell.cmd.export") self.core.init() doc = os.path.join(self.tmp_work_dir, "20190801_1733_23") os.mkdir(doc) shutil.copyfile(self.test_pdf, os.path.join(doc, "doc.pdf")) doc = os.path.join(self.tmp_work_dir, "20190830_1916_32") os.mkdir(doc) shutil.copyfile(self.test_img, os.path.join(doc, "paper.1.jpg")) shutil.copyfile(self.test_hocr, os.path.join(doc, "paper.1.words")) def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_local_dir) shutil.rmtree(self.tmp_work_dir) shutil.rmtree(self.tmp_out_dir) def test_export_doc(self): self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args([ 'export', '20190830_1916_32' # img doc ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'doc_to_pages', ]) args = parser.parse_args([ 'export', '20190801_1733_23' # pdf doc ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'doc_to_pages', 'unmodified_pdf', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'doc_to_pages', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'img_boxes', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'doc_to_pages', '-f', 'img_boxes', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'bmp', 'bw', 'generated_pdf', 'gif', 'grayscale', 'jpeg', 'png', 'swt_hard', 'swt_soft', 'tiff', 'unpaper', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'doc_to_pages', '-f', 'img_boxes', '-f', 'grayscale', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'bmp', 'bw', 'generated_pdf', 'gif', 'grayscale', 'jpeg', 'png', 'swt_hard', 'swt_soft', 'tiff', 'unpaper', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'doc_to_pages', '-f', 'img_boxes', '-f', 'grayscale', '-f', 'generated_pdf', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), []) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'doc_to_pages', '-f', 'img_boxes', '-f', 'grayscale', '-f', 'generated_pdf', '-o', os.path.join(self.tmp_out_dir, 'out.pdf') ]) r = self.core.call_success("cmd_run", self.console, args) self.assertTrue(r) self.assertTrue( os.path.exists( os.path.join( self.tmp_out_dir, 'out.pdf' ) ) ) def test_export_page(self): self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args([ 'export', '20190830_1916_32', # img doc '-p', '1', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'img_boxes', ]) args = parser.parse_args([ 'export', '20190801_1733_23', # pdf doc '-p', '1', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'img_boxes', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-p', '1', '-f', 'doc_to_pages', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertFalse(r) args = parser.parse_args([ 'export', '20190830_1916_32', '-p', '1', '-f', 'img_boxes', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'bmp', 'bw', 'generated_pdf', 'gif', 'grayscale', 'jpeg', 'png', 'swt_hard', 'swt_soft', 'tiff', 'unpaper', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-p', '1', '-f', 'img_boxes', '-f', 'grayscale', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), [ 'bmp', 'bw', 'generated_pdf', 'gif', 'grayscale', 'jpeg', 'png', 'swt_hard', 'swt_soft', 'tiff', 'unpaper', ]) args = parser.parse_args([ 'export', '20190830_1916_32', '-p', '1', '-f', 'img_boxes', '-f', 'grayscale', '-f', 'generated_pdf', ]) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(sorted(r), []) args = parser.parse_args([ 'export', '20190830_1916_32', '-p', '1', '-f', 'img_boxes', '-f', 'grayscale', '-f', 'generated_pdf', '-o', os.path.join(self.tmp_out_dir, 'out.pdf') ]) r = self.core.call_success("cmd_run", self.console, args) self.assertTrue(r) self.assertTrue( os.path.exists( os.path.join( self.tmp_out_dir, 'out.pdf' ) ) ) def test_export_invalid_pipeline(self): self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'img_boxes', '-f', 'grayscale', '-f', 'generated_pdf', '-o', os.path.join(self.tmp_out_dir, 'out.pdf') ]) # must not crash r = self.core.call_success("cmd_run", self.console, args) self.assertFalse(r) self.assertFalse( os.path.exists( os.path.join( self.tmp_out_dir, 'out.pdf' ) ) ) args = parser.parse_args([ 'export', '20190830_1916_32', '-f', 'img_boxes', '-f', 'unmodified_pdf', '-o', os.path.join(self.tmp_out_dir, 'out.pdf') ]) # must not crash r = self.core.call_success("cmd_run", self.console, args) self.assertFalse(r) self.assertFalse( os.path.exists( os.path.join( self.tmp_out_dir, 'out.pdf' ) ) ) paperwork-2.2.2/paperwork-shell/tests/cmd/tests_import.py000066400000000000000000000044671456262201400236760ustar00rootroot00000000000000import argparse import os import shutil import tempfile import unittest import openpaperwork_core import openpaperwork_core.cmd import openpaperwork_core.fs class TestSync(unittest.TestCase): def setUp(self): self.console = openpaperwork_core.cmd.DummyConsole() self.test_pdf = "{}/test_doc.pdf".format( os.path.dirname(os.path.abspath(__file__)) ) self.tmp_local_dir = tempfile.mkdtemp() self.tmp_work_dir = tempfile.mkdtemp() os.environ['XDG_DATA_HOME'] = self.tmp_local_dir self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.init() self.work_dir_url = openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_work_dir ) config = self.core.get_by_name("openpaperwork_core.config.fake") config.settings = { "workdir": self.work_dir_url, } def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_local_dir) shutil.rmtree(self.tmp_work_dir) def test_import_pdf_with_specific_doc_id_1046(self): self.core.load("paperwork_backend.model.pdf") self.core.load("paperwork_shell.cmd.import") self.core.init() parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args([ 'import', '--doc_id', '29991010_1212_33', self.test_pdf ]) self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(r['ignored'], []) self.assertEqual(r['imported'], [self.core.call_success( "fs_safe", self.test_pdf )]) self.assertEqual(r['new_docs'], ['29991010_1212_33']) self.assertEqual(r['upd_docs'], []) self.assertTrue(self.core.call_success( "fs_exists", self.core.call_success( "fs_join", self.core.call_success( "fs_join", self.work_dir_url, "29991010_1212_33" ), "doc.pdf" ) )) paperwork-2.2.2/paperwork-shell/tests/cmd/tests_sync.py000066400000000000000000000110151456262201400233230ustar00rootroot00000000000000import argparse import datetime import os import shutil import tempfile import unittest import openpaperwork_core import openpaperwork_core.cmd import openpaperwork_core.fs class TestSync(unittest.TestCase): def setUp(self): self.console = openpaperwork_core.cmd.DummyConsole() self.test_img = "{}/test_img.jpeg".format( os.path.dirname(os.path.abspath(__file__)) ) self.test_hocr = "{}/test_txt.hocr".format( os.path.dirname(os.path.abspath(__file__)) ) self.test_pdf = "{}/test_doc.pdf".format( os.path.dirname(os.path.abspath(__file__)) ) self.tmp_local_dir = tempfile.mkdtemp() self.tmp_work_dir = tempfile.mkdtemp() os.environ['XDG_DATA_HOME'] = self.tmp_local_dir self.core = openpaperwork_core.Core(auto_load_dependencies=True) self.core.load("openpaperwork_core.config.fake") self.core.init() def tearDown(self): self.core.call_all("tests_cleanup") shutil.rmtree(self.tmp_local_dir) shutil.rmtree(self.tmp_work_dir) def test_sync(self): config = self.core.get_by_name("openpaperwork_core.config.fake") config.settings = { "workdir": openpaperwork_core.fs.CommonFsPluginBase.fs_safe( self.tmp_work_dir ), } self.core.load("paperwork_backend.model.img") self.core.load("paperwork_backend.model.hocr") self.core.load("paperwork_backend.model.pdf") self.core.load("paperwork_shell.cmd.sync") self.core.init() parser = argparse.ArgumentParser() cmd_parser = parser.add_subparsers( help='command', dest='command', required=True ) self.core.call_all("cmd_complete_argparse", cmd_parser) args = parser.parse_args(['sync']) self.core.call_all( "cmd_set_console", openpaperwork_core.cmd.DummyConsole() ) # start with an empty work directory r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(r, {}) # add 2 documents, one PDF and one img+hocr doc_a = os.path.join(self.tmp_work_dir, "20190801_1733_23") os.mkdir(doc_a) shutil.copyfile(self.test_pdf, os.path.join(doc_a, "doc.pdf")) doc_b = os.path.join(self.tmp_work_dir, "20190830_1916_32") os.mkdir(doc_b) shutil.copyfile(self.test_img, os.path.join(doc_b, "paper.1.jpg")) shutil.copyfile(self.test_hocr, os.path.join(doc_b, "paper.1.words")) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(r, { 'whoosh': { 'added': ['20190801_1733_23', '20190830_1916_32'], }, 'ocr': { 'added': ['20190801_1733_23', '20190830_1916_32'], }, 'label_guesser': { 'added': ['20190801_1733_23', '20190830_1916_32'], }, 'doc_tracker': { 'added': ['20190801_1733_23', '20190830_1916_32'], }, }) # modify one document class FakeModule(object): class Plugin(openpaperwork_core.PluginBase): PRIORITY = 9999999999 def fs_get_mtime(s, file_url): if file_url.endswith(".words"): dt = datetime.datetime(year=2038, month=1, day=1) return dt.timestamp() return None self.core._load_module("fake_module", FakeModule()) self.core.init() r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(r, { 'whoosh': { 'updated': ['20190830_1916_32'], }, 'ocr': { 'updated': ['20190830_1916_32'], }, 'label_guesser': { 'updated': ['20190830_1916_32'], }, 'doc_tracker': { 'updated': ['20190830_1916_32'], }, }) # delete one document shutil.rmtree(doc_a) r = self.core.call_success("cmd_run", self.console, args) self.assertEqual(r, { 'whoosh': { 'deleted': ['20190801_1733_23'], }, 'ocr': { 'deleted': ['20190801_1733_23'], }, 'label_guesser': { 'deleted': ['20190801_1733_23'], }, 'doc_tracker': { 'deleted': ['20190801_1733_23'], }, }) paperwork-2.2.2/pytest.ini000066400000000000000000000000431456262201400155570ustar00rootroot00000000000000[pytest] python_files = tests_*.py paperwork-2.2.2/scripts/000077500000000000000000000000001456262201400152205ustar00rootroot00000000000000paperwork-2.2.2/scripts/README.md000066400000000000000000000011151456262201400164750ustar00rootroot00000000000000# Script examples Scripts related to Paperwork. ## export\_all\_to\_pdf.sh Convert all your Paperwork documents into PDF. Takes your currently-active work directory as source. Takes a destination directory as argument. [script](export_all_to_pdf.sh) ## convert\_jpeg\_to\_png.sh Starting with Paperwork 2.2, Paperwork stores the scanned images as PNG instead of JPEG. Existing documents with JPEG images are not converted (Paperwork 2.2 still read them fine). You can use this script to convert the images if you want. There is no gain to do it. [script](convert_jpeg_to_png.sh) paperwork-2.2.2/scripts/convert_jpeg_to_png.sh000077500000000000000000000012351456262201400216130ustar00rootroot00000000000000#!/usr/bin/env bash if [ -z "$2" ] ; then echo "Convert all JPEG files in a Paperwork work directory into PNG." echo "Requires 'convert' (imagemagick) and 'parallel' (GNU parallel)." echo echo "Syntax:" echo " $0 " exit 1 fi in_dir="$1" out_dir="$2" cp -R "$in_dir" "$out_dir" cd "$out_dir" echo Converting for jpg in $(find . -name paper\*.jpg | grep -v thumb) ; do png=$(echo $jpg | sed s/jpg/png/g) echo "convert $jpg $png" done | parallel --halt now,fail=1 sh -c {} echo "All converted. Cleaning up" for jpg in $(find . -name paper\*.jpg | grep -v thumb) ; do rm -f $jpg done echo "All done !" paperwork-2.2.2/scripts/export_all_to_pdf.sh000077500000000000000000000010401456262201400212560ustar00rootroot00000000000000#!/usr/bin/env bash if [ -z "$1" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then echo "Convert all your Paperwork documents into PDF." echo "Requires 'paperwork-json', 'paperwork-cli' and GNU parallel." echo echo "Syntax:" echo " $0 " exit 1 fi out_dir="$1" mkdir -p "$out_dir" for doc_id in $(paperwork-json search --limit 10000000 "" | jq -r ".[]") ; do echo paperwork-cli export ${doc_id} \ -f automatic_pdf \ -o "${out_dir}/${doc_id}.pdf" done | parallel --halt now,fail=1 sh -c {} echo "All done !" paperwork-2.2.2/sub/000077500000000000000000000000001456262201400143225ustar00rootroot00000000000000paperwork-2.2.2/sub/libinsane/000077500000000000000000000000001456262201400162665ustar00rootroot00000000000000paperwork-2.2.2/sub/libpillowfight/000077500000000000000000000000001456262201400173415ustar00rootroot00000000000000paperwork-2.2.2/sub/pyocr/000077500000000000000000000000001456262201400154565ustar00rootroot00000000000000paperwork-2.2.2/tools/000077500000000000000000000000001456262201400146715ustar00rootroot00000000000000paperwork-2.2.2/tools/docgenerator/000077500000000000000000000000001456262201400173455ustar00rootroot00000000000000paperwork-2.2.2/tools/docgenerator/Makefile000066400000000000000000000014751456262201400210140ustar00rootroot00000000000000PYTHON ?= python3 build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: ${PYTHON} ./setup.py build build_c: doc: check: flake8 src/docgenerator test: install python3 -m unittest discover --verbose -s tests linux_exe: windows_exe: release: release_pypi: clean: rm -rf build dist *.egg-info install_py: ${PYTHON} ./setup.py install ${PIP_ARGS} install_c: uninstall_py: pip3 uninstall -y docgenerator uninstall_c: help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ test \ uninstall \ uninstall_c \ paperwork-2.2.2/tools/docgenerator/setup.py000077500000000000000000000020211456262201400210550ustar00rootroot00000000000000#!/usr/bin/env python3 import sys import setuptools setuptools.setup( name="docgenerator", version="1.0", description="Generate test documents and images", classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", ("License :: OSI Approved ::" " GNU General Public License v3 or later (GPLv3+)"), "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", ], license="GPLv3+", author="Jerome Flesch", author_email="jflesch@openpaper.work", packages=setuptools.find_packages('src'), package_dir={'': 'src'}, entry_points={ 'console_scripts': [ 'docgenerator-one = docgenerator.main:main_generate_one', 'docgenerator-workdir = docgenerator.main:main_generate_workdir', ], }, zip_safe=True, install_requires=[ 'openpaperwork-core', 'openpaperwork-gtk', 'paperwork-backend', 'paperwork-shell', ] ) paperwork-2.2.2/tools/docgenerator/src/000077500000000000000000000000001456262201400201345ustar00rootroot00000000000000paperwork-2.2.2/tools/docgenerator/src/docgenerator/000077500000000000000000000000001456262201400226105ustar00rootroot00000000000000paperwork-2.2.2/tools/docgenerator/src/docgenerator/__init__.py000066400000000000000000000000001456262201400247070ustar00rootroot00000000000000paperwork-2.2.2/tools/docgenerator/src/docgenerator/img.py000066400000000000000000000023031456262201400237340ustar00rootroot00000000000000import io import random import cairo from . import words def generate_img( core, paper_size, page_idx, nb_pages, dictionary=None, jpeg=False ): if dictionary is None: dictionary = words.WordDict() paper_size = (int(paper_size[0]) * 4, int(paper_size[1]) * 4) print("Generating image {}...".format(paper_size)) surface = cairo.ImageSurface( cairo.Format.RGB24, paper_size[0], paper_size[1] ) context = cairo.Context(surface) words.draw_words( context, dictionary, paper_size[0], paper_size[1], page_idx, nb_pages, word_height=20 * 4, word_space=10 * 4 ) surface.flush() if jpeg: img = core.call_success("cairo_surface_to_pillow", surface) surface = core.call_success( "pillow_to_surface", img, intermediate='jpeg', quality=80 ) print("Image generated") return surface def generate(core, file_out, paper_size, page_idx=0, nb_pages=1): img = generate_img(core, paper_size, page_idx, nb_pages) img = core.call_success("cairo_surface_to_pillow", img) with core.call_success("fs_open", file_out, 'wb') as fd: img.save(fd, format="JPEG") paperwork-2.2.2/tools/docgenerator/src/docgenerator/main.py000066400000000000000000000141761456262201400241170ustar00rootroot00000000000000import datetime import random import sys import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk # noqa: E402 import openpaperwork_core # noqa: E402 import openpaperwork_core.cmd # noqa: E402 import paperwork_backend # noqa: E402 import paperwork_backend.docimport # noqa: E402 import paperwork_backend.model.workdir # noqa: E402 import paperwork_shell.main # noqa: E402 from . import img # noqa: E402 from . import pdf # noqa: E402 from . import pdf_img # noqa: E402 DOC_GENERATORS = { 'pdf': (pdf.generate, ".pdf", 1), 'img': (img.generate, ".jpeg", 2), 'pdf_img': (pdf_img.generate, ".pdf", 1), } def get_core(): core = openpaperwork_core.Core() for module_name in paperwork_backend.DEFAULT_CONFIG_PLUGINS: core.load(module_name) core.init() core.call_all("init_logs", "docgenerator", 'debug') core.call_all("config_load") core.call_all( "config_load_plugins", "docgenerator", paperwork_shell.main.DEFAULT_CLI_PLUGINS ) return core def get_page_size(): paper_size = Gtk.PaperSize.new("iso_a4") return ( paper_size.get_width(Gtk.Unit.POINTS), paper_size.get_height(Gtk.Unit.POINTS) ) def main_generate_one(): if len(sys.argv) <= 2: print("Usage:") print(" {} ".format(sys.argv[0])) sys.exit(1) core = get_core() paper_size = get_page_size() file_out = core.call_success("fs_safe", sys.argv[2]) DOC_GENERATORS[sys.argv[1]][0](core, file_out, paper_size) def generate_doc_id(core): while True: year = random.randint(1900, 2100) month = random.randint(1, 12) day = random.randint(1, 28) hour = random.randint(0, 23) minute = random.randint(0, 59) second = random.randint(0, 50) dt = datetime.datetime( year=year, month=month, day=day, hour=hour, minute=minute, second=second ) doc_id = dt.strftime(paperwork_backend.model.workdir.DOCNAME_FORMAT) doc_url = core.call_success("doc_id_to_url", doc_id) if doc_url is None: return doc_id nb_pages = core.call_success("doc_get_nb_pages_by_url", doc_url) if nb_pages is None or nb_pages <= 0: return doc_id def main_generate_workdir(): if len(sys.argv) <= 2: print("Usage:") print(" {} ".format(sys.argv[0])) sys.exit(1) generators = ([DOC_GENERATORS['img']] * 5) generators += [DOC_GENERATORS['pdf_img']] generators += ([DOC_GENERATORS['pdf']] * 5) core = get_core() paper_size = get_page_size() work_dir = core.call_success("fs_safe", sys.argv[1]) nb_docs = int(sys.argv[2]) core.call_all("cmd_set_console", openpaperwork_core.cmd.DummyConsole()) print("Creating {}...".format(work_dir)) core.call_success("fs_mkdir_p", work_dir) print("Switching work directory to {} ...".format(work_dir)) core.call_all("config_put", "workdir", work_dir) promises = [] core.call_all("sync", promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) core.call_one("mainloop_schedule", promise.schedule) core.call_all("mainloop_quit_graceful") core.call_one("mainloop") for doc_idx in range(0, nb_docs): (generator, file_ext, nb_files) = generators[ doc_idx % len(generators) ] if nb_files > 1: nb_files = int(random.expovariate(1 / 50)) if nb_files <= 0: nb_files = 1 if nb_files > 200: nb_files = 200 tmp_files = [] try: for f in range(0, nb_files): (tmp_file, tmp_fd) = core.call_success( "fs_mktemp", "paperwork-docgenerator", file_ext, on_disk=True ) tmp_fd.close() tmp_files.append(tmp_file) print( "Generating file {}/{} for document {}/{}" " --> {}...".format( f, nb_files, doc_idx, nb_docs, tmp_file ) ) generator(core, tmp_file, paper_size, f, nb_files) file_import = paperwork_backend.docimport.FileImport( tmp_files, active_doc_id=None ) importers = [] core.call_all("get_importer", importers, file_import) print("Importers: {}".format(importers)) assert len(importers) > 0 importer = importers[0] promise = importer.get_import_promise() print("Importing {} ...".format(tmp_files)) core.call_one("mainloop_schedule", promise.schedule) core.call_all("mainloop_quit_graceful") core.call_one("mainloop") print("Imported doc ids: {}".format(file_import.new_doc_ids)) for source_doc_id in file_import.new_doc_ids: dest_doc_id = generate_doc_id(core) print("Renaming document {} --> {} ...".format( source_doc_id, dest_doc_id )) source_doc_url = core.call_success( "doc_id_to_url", source_doc_id ) dest_doc_url = core.call_success( "doc_id_to_url", dest_doc_id ) core.call_all( "doc_rename_by_url", source_doc_url, dest_doc_url ) transactions = [] core.call_all("doc_transaction_start", transactions, 2) transactions.sort( key=lambda transaction: -transaction.priority ) for transaction in transactions: transaction.del_obj(source_doc_id) for transaction in transactions: transaction.add_obj(dest_doc_id) for transaction in transactions: transaction.commit() finally: print("Deleting {} ...".format(tmp_files)) for f in tmp_files: core.call_success("fs_unlink", f) print() paperwork-2.2.2/tools/docgenerator/src/docgenerator/pdf.py000066400000000000000000000016501456262201400237350ustar00rootroot00000000000000import random import cairo from . import words def generate(core, out_file, paper_size, *args, **kwargs): dictionary = words.WordDict() nb_pages = int(random.expovariate(1 / 500)) if nb_pages <= 0: nb_pages = 1 if nb_pages > 2000: nb_pages = 2000 print("Generating PDF {}...".format(out_file)) with core.call_success("fs_open", out_file, "wb") as fd: surface = cairo.PDFSurface(fd, int(paper_size[0]), int(paper_size[1])) context = cairo.Context(surface) for page_idx in range(0, nb_pages): print("Generating page {}/{}...".format(page_idx, nb_pages)) words.draw_words( context, dictionary, int(paper_size[0]), int(paper_size[1]), page_idx, nb_pages ) context.show_page() surface.flush() surface.finish() print("PDF {} generated".format(out_file)) paperwork-2.2.2/tools/docgenerator/src/docgenerator/pdf_img.py000066400000000000000000000024631456262201400245740ustar00rootroot00000000000000import random import cairo from . import img from . import words def generate(core, out_file, paper_size, *args, **kwargs): dictionary = words.WordDict() nb_pages = int(random.expovariate(1 / 100)) if nb_pages <= 0: nb_pages = 1 if nb_pages > 500: nb_pages = 500 print("Generating PDF with images only {}...".format(out_file)) with core.call_success("fs_open", out_file, "wb") as fd: surface = cairo.PDFSurface(fd, int(paper_size[0]), int(paper_size[1])) context = cairo.Context(surface) for page_idx in range(0, nb_pages): print("Generating page {}/{}...".format(page_idx, nb_pages)) img_surface = img.generate_img( core, paper_size, page_idx, nb_pages, dictionary=dictionary, jpeg=True ) scale_factor = paper_size[0] / img_surface.get_width() context.save() try: context.identity_matrix() context.scale(scale_factor, scale_factor) context.set_source_surface(img_surface) context.paint() finally: context.restore() context.show_page() surface.flush() surface.finish() print("PDF with images only {} generated".format(out_file)) paperwork-2.2.2/tools/docgenerator/src/docgenerator/words.py000066400000000000000000000051401456262201400243200ustar00rootroot00000000000000import codecs import random import gi gi.require_version('Pango', '1.0') gi.require_version('PangoCairo', '1.0') from gi.repository import Pango from gi.repository import PangoCairo WORD_HEIGHT = 20 WORD_SPACE = 10 def draw_words( context, words, width, height, page_idx, nb_pages, word_height=WORD_HEIGHT, word_space=WORD_SPACE ): w = word_space h = word_space context.save() try: context.set_source_rgb(1.0, 1.0, 1.0) context.rectangle(0, 0, width, height) context.fill() finally: context.restore() context.save() try: context.set_source_rgb(0.0, 0.0, 0.0) layout = PangoCairo.create_layout(context) layout.set_text("Page {}/{}".format(page_idx + 1, nb_pages), -1) layout_size = layout.get_size() txt_factor = word_height / layout_size[1] word_h = word_height word_w = layout_size[0] * txt_factor w = (width - word_w) / 2 context.translate(w, h) context.scale(txt_factor * Pango.SCALE, txt_factor * Pango.SCALE) PangoCairo.update_layout(context, layout) PangoCairo.show_layout(context, layout) h += word_h + word_space w = word_space finally: context.restore() while True: word = words.pick_word() layout = PangoCairo.create_layout(context) layout.set_text(word, -1) layout_size = layout.get_size() txt_factor = word_height / layout_size[1] word_h = word_height word_w = layout_size[0] * txt_factor if w + word_w >= width: h += word_h + word_space w = word_space if h >= height: return context.save() try: context.set_source_rgb(0, 0, 0) context.translate(w, h) context.scale(txt_factor * Pango.SCALE, txt_factor * Pango.SCALE) PangoCairo.update_layout(context, layout) PangoCairo.show_layout(context, layout) finally: context.restore() w += word_w + word_space class WordDict(object): DICTIONARY = "/usr/share/dict/words" def __init__(self): print("Loading {} ...".format(self.DICTIONARY)) self.dictionary = [] # length --> words with codecs.open(self.DICTIONARY, 'r', encoding='utf-8') as file_desc: for word in file_desc: word = word.strip() self.dictionary.append(word) print("Dictionnary loaded") def pick_word(self): return self.dictionary[random.randint(0, len(self.dictionary) - 1)] paperwork-2.2.2/tools/get_git_authors.py000077500000000000000000000141071456262201400204400ustar00rootroot00000000000000#!/usr/bin/env python3 import collections import fnmatch import json import os import os.path import re import subprocess import sys CATEGORIES = [ # order of evaluation matters ("doc", "Documentation"), ("openpaperwork-core", "OpenPaperwork Core"), ("openpaperwork-gtk", "OpenPaperwork GTK"), ("paperwork-backend", "Paperwork Backend"), ("paperwork-gtk", "GTK Frontend"), ("paperwork-shell", "CLI Frontend"), ("flatpak", "Flatpak Integration"), (None, "Others"), # default ] REPLACEMENT_RULES = { # Because I'm a dimw** who doesn't always configure his Git correctly. "jflesch": "Jerome Flesch", # Those are translations commits from Weblate. Weblate credits are # downloaded from Weblate manually. "Weblate Admin": None, # Shouldn't happen "Not Committed Yet": None, } EXTRA_IGNORES = [ "sub", ".git", "AUTHORS*", ] REGEX_EMAIL_AUTHOR = re.compile( r"[^(]*\((.+)\s\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} .*" ) def split_path(path): path = os.path.normpath(path) return path.split(os.sep) class IgnoreList(object): def __init__(self, ignore_list): self.ignore_list = EXTRA_IGNORES + ignore_list @staticmethod def find_gitignore(): current_dir = os.path.abspath(__file__) while not os.path.exists(os.path.join(current_dir, ".gitignore")): current_dir = os.path.dirname(current_dir) if current_dir == "/": raise Exception(".gitignore not found") return os.path.join(current_dir, ".gitignore") @staticmethod def load(): gitignore_path = IgnoreList.find_gitignore() sys.stderr.write("Loading {} ... ".format(gitignore_path)) sys.stderr.flush() with open(gitignore_path, 'r') as fd: ignore_list = fd.readlines() ignore_list = [line.strip() for line in ignore_list] ignore_list = [line for line in ignore_list if line != ""] ignore_list = [line.replace("/", "") for line in ignore_list] sys.stderr.write("{} ignores loaded\n".format(len(ignore_list))) return IgnoreList(ignore_list) def match(self, file_path): for pattern in self.ignore_list: if fnmatch.fnmatch(file_path, pattern): return True file_path = split_path(file_path) for pattern in self.ignore_list: for file_path_component in file_path: if fnmatch.fnmatch(file_path_component, pattern): return True return False def walk(directory, ignore_list): for (dirpath, dirnames, file_names) in os.walk(directory): for file_name in file_names: file_path = os.path.join(dirpath, file_name) if ignore_list.match(file_path): continue yield file_path def get_category_name(file_path): file_path = split_path(file_path) for (category_pattern, category_name) in CATEGORIES: if category_pattern is None: return category_name for component in file_path: if component == category_pattern: return category_name assert False def count_lines(line_counts, file_path): output = subprocess.run( ['git', 'blame', file_path], capture_output=True ) if output.returncode != os.EX_OK: sys.stderr.write( "WARNING: git blame {} failed ! (returncode={})\n".format( file_path, output.returncode ) ) return try: stdout = output.stdout.decode("utf-8") except UnicodeDecodeError: sys.stderr.write( "WARNING: Unicode on {}. Assuming it's a binary file\n".format( file_path ) ) return stdout = [line.strip() for line in stdout.split("\n")] for line in stdout: if line == "": continue author = REGEX_EMAIL_AUTHOR.match(line) if author is None: sys.stderr.write( "WARNING: Failed to find author email in the following line:\n" ) sys.stderr.write(line + "\n") continue author = author[1].strip() author = REPLACEMENT_RULES.get(author, author) if author is None: # replacement rules told us to ignore this one continue line_counts[author] += 1 def dump_json(line_counts): # We want to merge this JSON with the one from Weblate later. So we # imitate the weird JSON output of Weblate here. out = [] for (category_name, authors) in line_counts.items(): category = {category_name: []} out.append(category) category = category[category_name] for (author, line_count) in authors.items(): category.append([ '', # we don't care about emails author, line_count, ]) # sort authors by line count category.sort(key=lambda x: x[2], reverse=True) # Sort categories alphabetically out.sort(key=lambda x: next(iter(x)).lower()) print(json.dumps( out, indent=4, separators=(',', ': '), sort_keys=True )) def main(): if len(sys.argv) < 2 or sys.argv[1] == '-h' or sys.argv[1] == '--help': sys.stderr.write("Syntax:\n") sys.stderr.write(" {} \n".format(sys.argv[0])) return ignore_list = IgnoreList.load() line_counts = collections.defaultdict( lambda: collections.defaultdict(lambda: 0) ) for file_path in walk(sys.argv[1], ignore_list): category = get_category_name(file_path) sys.stderr.write("Examining {} (category={}) ...\n".format( file_path, category )) counts = line_counts[category] count_lines(counts, file_path) for (category, authors) in line_counts.items(): sys.stderr.write(" - {}\n".format(category)) for (k, v) in authors.items(): sys.stderr.write("{}: {}\n".format(k, v)) sys.stderr.write("\n") dump_json(line_counts) if __name__ == "__main__": main() paperwork-2.2.2/tools/l10n_compile.sh000077500000000000000000000023111456262201400175070ustar00rootroot00000000000000#!/bin/bash LANGS="de_DE.UTF-8:de es_ES.UTF-8:es fr_FR.UTF-8:fr oc_FR.UTF-8:oc uk_UA.UTF-8:uk" if [ -z "$1" ] || [ -z "$2" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then echo "Usage:" echo " $0 " echo echo "Examples:" echo " $0 l10n src/paperwork_gtk/l10n paperwork_gtk" echo echo "You should probably use 'make l10_compile' instead of calling this script directly" exit 1 fi if ! which msgfmt > /dev/null 2>&1 ; then echo "msgfmt is missing" echo "--> sudo apt install gettext" exit 2 fi src_dir="$1" dst_dir="$2" mo_name="$3" mkdir -p "${dst_dir}" touch "${dst_dir}/__init__.py" rm -rf "${dst_dir}/out" for lang in ${LANGS} do long_locale=$(echo $lang | cut -d: -f1) short_locale=$(echo $lang | cut -d: -f2) po_file="${src_dir}/${short_locale}.po" locale_dir="${dst_dir}/out/${short_locale}/LC_MESSAGES" echo "${po_file} --> ${locale_dir}/${mo_name}.mo" mkdir -p "${locale_dir}" touch "${dst_dir}/out/__init__.py" touch "${dst_dir}/out/${short_locale}/__init__.py" touch "${locale_dir}/__init__.py" if ! msgfmt "${po_file}" -o "${locale_dir}/${mo_name}.mo" ; then echo "msgfmt failed ! Unable to update .mo file !" exit 2 fi done paperwork-2.2.2/tools/l10n_extract.sh000077500000000000000000000046711456262201400175440ustar00rootroot00000000000000#!/bin/bash LANGS="de_DE.UTF-8:de es_ES.UTF-8:es fr_FR.UTF-8:fr oc_FR.UTF-8:oc uk_UA.UTF-8:uk" if [ -z "$1" ] || [ -z "$2" ] || [ "$1" = "-h" ] || [ "$1" = "--help" ] ; then echo "Usage:" echo " $0 " echo echo "Examples:" echo " $0 src/paperwork_gtk l10n" echo echo "You should probably use 'make l10_extract' instead of calling this script directly" exit 1 fi if ! which intltool-extract > /dev/null 2>&1 ; then echo "intl-tool-extract is missing" echo "--> sudo apt install intltool" exit 2 fi if ! which xgettext > /dev/null 2>&1 ; then echo "xgettext is missing" echo "--> sudo apt install gettext" exit 2 fi src_dir="$1" dst_dir="$2" src_dir=$(realpath --relative-to=$(pwd) ${src_dir}) while ! [ -d .git ]; do if [ "$(pwd)" == "/" ]; then echo "Failed to find git repository root" echo "Are you in a Git repository ?" exit 3 fi # we must place ourselves at the root of the repository so the file # paths in the .pot and .po are correct for Weblate src_dir="$(basename $(pwd))/${src_dir}" cd .. done src_dir=$(realpath --relative-to=$(pwd) ${src_dir}) mkdir -p "${dst_dir}" echo "Extracting strings from Glade files ..." for glade_file in $(find "${src_dir}" -name \*.glade) ; do # intltool-extract expects a relative path as input echo "${glade_file} --> .glade.h ..." if ! intltool-extract --type=gettext/glade "${glade_file}" > /dev/null; then echo "intltool-extract Failed ! Unable to extract strings to translate from .glade files !" exit 3 fi done rm -f "${dst_dir}/messages.pot" echo "Extracting strings from .py and .h files ..." if ! xgettext --from-code=UTF-8 \ -k_ \ -kN_ \ --keyword="pgettext:1c,2" \ --keyword="npgettext:1c,2,3" \ -o "${dst_dir}/messages.pot" \ $(find "${src_dir}" -name \*.py) \ $(find "${src_dir}" -name \*.glade.h) ; then echo "xgettext failed ! Unable to extract strings to translate !" exit 3 fi rm -f $(find "${src_dir}" -name \*.glade.h) for lang in ${LANGS} do locale=$(echo $lang | cut -d: -f1) po_file="${dst_dir}/$(echo $lang | cut -d: -f2).po" if ! [ -f ${po_file} ] then echo "messages.pot --> ${po_file} (gen)" msginit --no-translator \ -l ${locale} -i "${dst_dir}/messages.pot" \ -o ${po_file} else echo "messages.pot --> ${po_file} (upd)" msgmerge -N -U ${po_file} "${dst_dir}/messages.pot" fi if [ $? -ne 0 ] ; then echo "msginit / msgmerge failed ! Unable to create or update .po file !" exit 3 fi done paperwork-2.2.2/tools/labelgenerator/000077500000000000000000000000001456262201400176575ustar00rootroot00000000000000paperwork-2.2.2/tools/labelgenerator/Makefile000066400000000000000000000015011456262201400213140ustar00rootroot00000000000000PYTHON ?= python3 build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: ${PYTHON} ./setup.py build build_c: doc: check: flake8 src/labelgenerator test: install python3 -m unittest discover --verbose -s tests linux_exe: windows_exe: release: release_pypi: clean: rm -rf build dist *.egg-info install_py: ${PYTHON} ./setup.py install ${PIP_ARGS} install_c: uninstall_py: pip3 uninstall -y labelgenerator uninstall_c: help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ test \ uninstall \ uninstall_c \ paperwork-2.2.2/tools/labelgenerator/setup.py000077500000000000000000000016621456262201400214010ustar00rootroot00000000000000#!/usr/bin/env python3 import sys import setuptools setuptools.setup( name="labelgenerator", version="1.0", description="Generate test labels", classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", ("License :: OSI Approved ::" " GNU General Public License v3 or later (GPLv3+)"), "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", ], license="GPLv3+", author="Jerome Flesch", author_email="jflesch@openpaper.work", packages=setuptools.find_packages('src'), package_dir={'': 'src'}, entry_points={ 'console_scripts': [ 'labelgenerator-workdir = labelgenerator.main:main', ], }, zip_safe=True, install_requires=[ 'openpaperwork-core', 'openpaperwork-gtk', 'paperwork-backend', 'paperwork-shell', ] ) paperwork-2.2.2/tools/labelgenerator/src/000077500000000000000000000000001456262201400204465ustar00rootroot00000000000000paperwork-2.2.2/tools/labelgenerator/src/labelgenerator/000077500000000000000000000000001456262201400234345ustar00rootroot00000000000000paperwork-2.2.2/tools/labelgenerator/src/labelgenerator/__init__.py000066400000000000000000000000001456262201400255330ustar00rootroot00000000000000paperwork-2.2.2/tools/labelgenerator/src/labelgenerator/main.py000066400000000000000000000053741456262201400247430ustar00rootroot00000000000000import random import sys import openpaperwork_core import openpaperwork_core.cmd import paperwork_backend import paperwork_shell.main from . import words def get_core(): print("Loading core ...") core = openpaperwork_core.Core() for module_name in paperwork_backend.DEFAULT_CONFIG_PLUGINS: core.load(module_name) core.init() core.call_all("init_logs", "docgenerator", 'debug') core.call_all("config_load") core.call_all( "config_load_plugins", "labelgenerator", paperwork_shell.main.DEFAULT_CLI_PLUGINS ) print("Core loaded") return core def main(): if len(sys.argv) <= 2: print("Usage:") print(" {} ".format(sys.argv[0])) sys.exit(1) work_dir = sys.argv[1] nb_labels = int(sys.argv[2]) dictionary = words.WordDict() core = get_core() print("Generating labels ...") labels = [] for _ in range(0, nb_labels): label = dictionary.pick_word() print(" - {}".format(label)) labels.append(label) print() core.call_all("cmd_set_console", openpaperwork_core.cmd.DummyConsole()) work_dir = core.call_success("fs_safe", work_dir) print("Switching work directory to {} ...".format(work_dir)) core.call_all("config_put", "workdir", work_dir) promises = [] core.call_all("sync", promises) promise = promises[0] for p in promises[1:]: promise = promise.then(p) core.call_one("mainloop_schedule", promise.schedule) core.call_all("mainloop_quit_graceful") core.call_one("mainloop") docs = [] core.call_all("storage_get_all_docs", docs) docs.sort() print("{} documents found".format(len(docs))) transactions = [] core.call_all("doc_transaction_start", transactions, len(docs)) transactions.sort(key=lambda t: -t.priority) for (doc_id, doc_url) in docs: nb_labels_to_add = random.randint(0, max(1, int(nb_labels / 2))) print("{} <-- {} labels".format(doc_id, nb_labels_to_add)) for _ in range(0, nb_labels_to_add): label = labels[random.randint(0, len(labels) - 1)] print("{} <- {}".format(doc_id, label)) core.call_success("doc_add_label_by_url", doc_url, label) specials = [ ('doc.pdf', '_PDF'), ('paper.1.jpg', '_IMG'), ('paper.1.words', '_HOCR'), ] for (file_name, label) in specials: file_path = core.call_success("fs_join", doc_url, file_name) if core.call_success("fs_exists", file_path) is not None: core.call_success("doc_add_label_by_url", doc_url, label) for t in transactions: t.upd_obj(doc_id) for t in transactions: t.commit() print("All done") paperwork-2.2.2/tools/labelgenerator/src/labelgenerator/words.py000066400000000000000000000010561456262201400251460ustar00rootroot00000000000000import codecs import random class WordDict(object): DICTIONARY = "/usr/share/dict/words" def __init__(self): print("Loading {} ...".format(self.DICTIONARY)) self.dictionary = [] # length --> words with codecs.open(self.DICTIONARY, 'r', encoding='utf-8') as file_desc: for word in file_desc: word = word.strip() self.dictionary.append(word) print("Dictionnary loaded") def pick_word(self): return self.dictionary[random.randint(0, len(self.dictionary) - 1)] paperwork-2.2.2/tools/merge_authors_json.py000077500000000000000000000026631456262201400211520ustar00rootroot00000000000000#!/usr/bin/env python3 import json import sys def load_jsons(file_paths): out = [] for file_path in file_paths: sys.stderr.write("Loading {} ...\n".format(file_path)) with open(file_path, 'r') as fd: content = fd.read() out.append(json.loads(content)) return out def merge_jsons(jsons): sys.stderr.write("Merging ...\n") out = [] for j in jsons: out += j return out def sort_json(out): sys.stderr.write("Sorting ...\n") # keep in mind we are immitating the JSON from Weblate here, and Weblate's # JSON is a bit weird. for category in out: for (category_name, authors) in category.items(): # sort authors by line count authors.sort(key=lambda x: x[2], reverse=True) # Sort categories alphabetically out.sort(key=lambda x: next(iter(x)).lower()) def main(): if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "--help": sys.stderr.write("Syntax:\n") sys.stderr.write( " {} [ [ ...]]\n".format( sys.argv[0] ) ) return jsons = load_jsons(sys.argv[1:]) out = merge_jsons(jsons) sort_json(out) print(json.dumps( out, indent=4, separators=(',', ': '), sort_keys=True )) sys.stderr.write("All done !\n") if __name__ == "__main__": main() paperwork-2.2.2/tools/plugin-grapher/000077500000000000000000000000001456262201400176155ustar00rootroot00000000000000paperwork-2.2.2/tools/plugin-grapher/Makefile000066400000000000000000000015041456262201400212550ustar00rootroot00000000000000PYTHON ?= python3 build: build_c build_py install: install_py install_c uninstall: uninstall_py build_py: ${PYTHON} ./setup.py build build_c: doc: check: flake8 src/paperwork_backend test: install python3 -m unittest discover --verbose -s tests linux_exe: windows_exe: release: release_pypi: clean: rm -rf build dist *.egg-info install_py: ${PYTHON} ./setup.py install ${PIP_ARGS} install_c: uninstall_py: pip3 uninstall -y plugin-grapher uninstall_c: help: @echo "make build || make build_py" @echo "make check" @echo "make help: display this message" @echo "make install || make install_py" @echo "make uninstall || make uninstall_py" @echo "make release" .PHONY: \ build \ build_c \ build_py \ check \ doc \ exe \ help \ install \ install_c \ install_py \ test \ uninstall \ uninstall_c \ paperwork-2.2.2/tools/plugin-grapher/setup.py000077500000000000000000000017421456262201400213360ustar00rootroot00000000000000#!/usr/bin/env python3 import sys import setuptools setuptools.setup( name="plugin-grapher", version="1.0", description="Generate graphic representing the plugins", url=( "https://gitlab.gnome.org/World/OpenPaperwork/paperwork/tree/master/" "plugin-grapher" ), classifiers=[ "Development Status :: 5 - Production/Stable", "Intended Audience :: End Users/Desktop", ("License :: OSI Approved ::" " GNU General Public License v3 or later (GPLv3+)"), "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 3", ], license="GPLv3+", author="Jerome Flesch", author_email="jflesch@openpaper.work", packages=setuptools.find_packages('src'), package_dir={'': 'src'}, entry_points={ 'console_scripts': [ 'plugin-grapher = plugin_grapher.main:main', ], }, zip_safe=True, install_requires=[ "openpaperwork-core", ] ) paperwork-2.2.2/tools/plugin-grapher/src/000077500000000000000000000000001456262201400204045ustar00rootroot00000000000000paperwork-2.2.2/tools/plugin-grapher/src/plugin_grapher/000077500000000000000000000000001456262201400234125ustar00rootroot00000000000000paperwork-2.2.2/tools/plugin-grapher/src/plugin_grapher/__init__.py000066400000000000000000000000001456262201400255110ustar00rootroot00000000000000paperwork-2.2.2/tools/plugin-grapher/src/plugin_grapher/main.py000066400000000000000000000100201456262201400247010ustar00rootroot00000000000000import importlib import sys import openpaperwork_core # skip some interfaces ; too many plugin depends on it, making the graph # unreadable INTERFACES_TO_IGNORE = { "chkdeps", "pages", } def load_plugins(core, arg): (module_name, variable) = arg.rsplit(".", 1) module = importlib.import_module(module_name) plugin_names = getattr(module, variable) for name in plugin_names: print("Loading {} ...".format(name)) core.load(name) g_current_frame = [] g_indent = 0 def print_package(out, plugin_name): global g_current_frame global g_indent pkgs = plugin_name.split(".", 1) plugin_name = pkgs[-1] pkgs = pkgs[:-1] print("Package: {}".format(pkgs)) idx = 0 for (idx, (pkg_a, pkg_b)) in enumerate(zip(pkgs, g_current_frame)): if pkg_a != pkg_b: break else: if len(g_current_frame) == len(pkgs): return plugin_name while len(g_current_frame) > idx: g_indent -= 1 out.write('{}}}\n'.format(" " * g_indent)) g_current_frame = g_current_frame[:-1] while len(pkgs) > idx: out.write('\n{}package "{}" <> {{\n'.format( " " * g_indent, pkgs[idx] )) g_indent += 1 if pkgs[idx] == "openpaperwork_core": out.write('{}class "Core"\n'.format(" " * g_indent)) idx += 1 g_current_frame = pkgs return plugin_name g_interfaces = set() def dump_plugin(out, long_plugin_name, short_plugin_name, plugin): global g_interfaces global g_indent long_plugin_name = long_plugin_name.split(".", 1)[1].replace(".", "-") print("Plugin: {}".format(long_plugin_name)) interfaces = plugin.get_interfaces() for i in INTERFACES_TO_IGNORE: if i in interfaces: interfaces.remove(i) print("Interfaces: {}".format(interfaces)) out.write('{}class "{}"\n'.format(" " * g_indent, long_plugin_name)) if len(interfaces) <= 0: out.write('{}"Core" o-- "{}"\n'.format( " " * g_indent, long_plugin_name )) for interface in interfaces: if interface not in g_interfaces: g_interfaces.add(interface) out.write('{}interface "{}"\n'.format( " " * g_indent, interface )) out.write('{}"Core" o-- "{}"\n'.format( " " * g_indent, interface )) out.write('{}"{}" <|-- "{}"\n'.format( " " * g_indent, interface, long_plugin_name )) # Do not show plugin dependencies. It makes the graph too messy # deps = plugin.get_deps() # print("Dependencies: {}".format(deps)) # for dep in deps: # interface = dep['interface'] # if interface in INTERFACES_TO_IGNORE: # continue # out.write('{}"{}" o-- "{}"\n'.format( # " " * g_indent, long_plugin_name, interface) # ) def main(): core = openpaperwork_core.Core() if len(sys.argv) <= 1: print("Usage: {} [out_file] [plugin list]".format(sys.argv[0])) print( "Example: {}" " out.uml paperwork_shell.main.DEFAULT_CLI_PLUGINS".format( sys.argv[0] ) ) sys.exit(1) for arg in sys.argv[2:]: load_plugins(core, arg) print("{} plugins found".format(len(core.plugins))) package_name = None with open(sys.argv[1], "w") as out: out.write("@startuml\n") out.write("left to right direction\n") for plugin_name in sorted(core.plugins): print("----") plugin = core.plugins[plugin_name] short_plugin_name = print_package(out, plugin_name) short_plugin_name = plugin_name dump_plugin(out, plugin_name, short_plugin_name, plugin) print("----") print_package(out, "") # closes the current frames out.write("@enduml\n") print("====") print("Plantuml command:") print("PLANTUML_LIMIT_SIZE=65536 plantuml {}".format(sys.argv[1])) if __name__ == "__main__": main() paperwork-2.2.2/work.openpaper.Paperwork.json000066400000000000000000000352721456262201400213600ustar00rootroot00000000000000{ "app-id": "work.openpaper.Paperwork", "branch": "develop", "runtime": "org.gnome.Platform", "runtime-version": "44", "sdk": "org.gnome.Sdk", "command": "paperwork-gtk", "copy-icon": true, "sdk-extensions": [ "org.freedesktop.Sdk.Extension.openjdk11" ], "finish-args": [ "--share=ipc", "--share=network", "--socket=fallback-x11", "--socket=wayland", "--filesystem=host", "--persist=.python-eggs", "--talk-name=org.freedesktop.Notifications", "--talk-name=org.freedesktop.FileManager1", "--talk-name=org.gtk.vfs.*", "--filesystem=xdg-run/gvfsd", "--own-name=work.openpaper.paperwork", "--env=JAVA_HOME=/app/jre", "--env=LIBO_FLATPAK=1" ], "modules": [ "flatpak/shared-modules/libreoffice-7.5.4.2.json", "flatpak/shared-modules/setuptools-65.6.3.json", "flatpak/shared-modules/scikit-learn-1.2.0.json", "flatpak/shared-modules/sane-backends-1.1.1.json", "flatpak/shared-modules/tesseract-5.3.0.json", { "name": "python-distro", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"distro\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/4b/89/eaa3a3587ebf8bed93e45aa79be8c2af77d50790d15b53f6dfc85b57f398/distro-1.8.0.tar.gz", "sha256": "02e111d1dc6a50abb8eed6bf31c3e48ed8b0830d1ea2a1b78c61765c2513fdd8" } ] }, { "name": "python3-scikit-build", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"scikit-build\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/ed/35/a31aed2993e398f6b09a790a181a7927eb14610ee8bbf02dc14d31677f1c/packaging-23.0-py3-none-any.whl", "sha256": "714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/53/ab/82a39a3a7c16bc5bc3369dff693c52f609efed014833a9a09ea81580374e/scikit_build-0.16.4-py3-none-any.whl", "sha256": "c7041071d1b75a23754a54688e9cbe7c45b86197e1ac09dc472bd254246fc5ab" } ] }, { "name": "python-fabulous", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/ec/b3/38ce860b1abeb58b998db83a244239dd716308499e359fa077b0a4d0d244/fabulous-0.4.0.tar.gz", "sha256": "d9cee8a97e0d0eea835994394b6053f84fd6120a48779dbc533c5e6812352c84" } ] }, { "name": "python-pillow", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/bc/07/830784e061fb94d67649f3e438ff63cfb902dec6d48ac75aeaaac7c7c30e/Pillow-9.4.0.tar.gz", "sha256": "a1c2d7780448eb93fbcc3789bf3916aa5720d942e37945f4056680317f1cd23e" } ], "modules": [ { "name": "python-olefile", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/34/81/e1ac43c6b45b4c5f8d9352396a14144bba52c8fec72a80f425f6a4d653ad/olefile-0.46.zip", "sha256": "133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964" } ] } ] }, { "name": "python-pycountry", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/33/24/033604d30f6cf82d661c0f9dfc2c71d52cafc2de516616f80d3b0600cb7c/pycountry-22.3.5.tar.gz", "sha256": "b2163a246c585894d808f18783e19137cb70a0c18fb36748dc01fc6f109c1646" } ] }, { "name": "python-pyxdg", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/b0/25/7998cd2dec731acbd438fbf91bc619603fc5188de0a9a17699a781840452/pyxdg-0.28.tar.gz", "sha256": "3267bb3074e934df202af2ee0868575484108581e6f3cb006af1da35395e88b4" } ] }, { "name": "python-pydbus", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/58/56/3e84f2c1f2e39b9ea132460183f123af41e3b9c8befe222a35636baa6a5a/pydbus-0.6.0.tar.gz", "sha256": "4207162eff54223822c185da06c1ba8a34137a9602f3da5a528eedf3f78d0f2c" } ] }, { "name": "python3-rich", "buildsystem": "simple", "build-commands": [ "pip3 install --disable-pip-version-check --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"rich\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/bf/25/2d88e8feee8e055d015343f9b86e370a1ccbec546f2865c98397aaef24af/markdown_it_py-2.2.0-py3-none-any.whl", "sha256": "5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/42/5c/f44fc88bad850c4a20711a3349ec0e8bc50fece8d8b32c962d2aab70ea2b/rich-13.3.3-py3-none-any.whl", "sha256": "540c7d6d26a1178e8e8b37e9ba44573a3cd1464ff6348b99ee7061b95d1c6333" } ] }, { "name": "python-whoosh", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz", "sha256": "7ca5633dbfa9e0e0fa400d3151a8a0c4bec53bd2ecedc0a67705b17565c31a83" } ] }, { "name": "python-psutil", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://files.pythonhosted.org/packages/3d/7d/d05864a69e452f003c0d77e728e155a89a2a26b09e64860ddd70ad64fb26/psutil-5.9.4.tar.gz", "sha256": "3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62" } ] }, { "name": "poppler-data", "buildsystem": "cmake-ninja", "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-data-0.4.11.tar.gz", "sha256": "2cec05cd1bb03af98a8b06a1e22f6e6e1a65b1e2f3816cb3069bb0874825f08c" } ] }, { "name": "poppler", "buildsystem": "cmake-ninja", "config-opts": [ "-DENABLE_QT5=OFF", "-DENABLE_QT6=OFF", "-DENABLE_BOOST=OFF", "-DENABLE_LIBOPENJPEG:STRING=none" ], "sources": [ { "type": "archive", "url": "https://poppler.freedesktop.org/poppler-23.01.0.tar.xz", "sha256": "fae9b88d3d5033117d38477b79220cfd0d8e252c278ec870ab1832501741fd94" } ] }, { "name": "libinsane", "buildsystem": "meson", "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libinsane.git", "branch": "master", "disable-shallow-clone": true } ] }, { "name": "python3-setuptools_scm", "buildsystem": "simple", "build-commands": [ "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"setuptools_scm[toml]\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/ed/35/a31aed2993e398f6b09a790a181a7927eb14610ee8bbf02dc14d31677f1c/packaging-23.0-py3-none-any.whl", "sha256": "714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/1d/66/8f42c941be949ef2b22fe905d850c794e7c170a526023612aad5f3a121ad/setuptools_scm-7.1.0-py3-none-any.whl", "sha256": "73988b6d848709e2af142aa48c986ea29592bbcfca5375678064708205253d8e" }, { "type": "file", "url": "https://files.pythonhosted.org/packages/31/25/5abcd82372d3d4a3932e1fa8c3dbf9efac10cc7c0d16e78467460571b404/typing_extensions-4.5.0-py3-none-any.whl", "sha256": "fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" } ] }, { "name": "python3-certifi", "buildsystem": "simple", "build-commands": [ "pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"certifi\" --no-build-isolation" ], "sources": [ { "type": "file", "url": "https://files.pythonhosted.org/packages/71/4c/3db2b8021bd6f2f0ceb0e088d6b2d49147671f25832fb17970e9b583d742/certifi-2022.12.7-py3-none-any.whl", "sha256": "4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" } ] }, { "name": "python-pyocr", "buildsystem": "simple", "build-commands": [ "pip3 install --verbose --exists-action=i --no-index --prefix=${FLATPAK_DEST} --no-build-isolation ." ], "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/pyocr.git", "branch": "master", "disable-shallow-clone": true } ] }, { "name": "python-nose", "buildsystem": "simple", "build-commands": ["python3 setup.py install --prefix=/app --root=/"], "sources": [ { "type": "archive", "url": "https://pypi.python.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", "sha256": "f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98" } ] }, { "name": "python-pypillowfight", "ensure-writable": [ "/lib/python*/site-packages/easy-install.pth", "/lib/python*/site-packages/setuptools.pth" ], "buildsystem": "simple", "build-commands": [ "make version", "pip3 install --disable-pip-version-check --prefix=/app --no-deps ." ], "sources": [ { "type": "git", "url": "https://gitlab.gnome.org/World/OpenPaperwork/libpillowfight.git", "branch": "master", "disable-shallow-clone": true } ] }, { "name": "python-paperwork", "make-install-args": ["PIP_ARGS=--verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} --no-build-isolation"], "no-autogen": true, "ensure-writable": ["/lib/python*/site-packages/easy-install.pth","/lib/python*/site-packages/setuptools.pth"], "post-install": ["paperwork-gtk install --icon_base_dir=/app/share/icons --data_base_dir=/app/share"], "sources": [ { "type": "git", "path": ".", "branch": "develop", "disable-shallow-clone": true }, { "type": "file", "path": "data.tar.gz" } ] } ] }