pax_global_header00006660000000000000000000000064135506671740014530gustar00rootroot0000000000000052 comment=896659c6963c14c4e047cff7f3d421977060ed23 onionshare-2.2/000077500000000000000000000000001355066717400135405ustar00rootroot00000000000000onionshare-2.2/.circleci/000077500000000000000000000000001355066717400153735ustar00rootroot00000000000000onionshare-2.2/.circleci/config.yml000066400000000000000000000031541355066717400173660ustar00rootroot00000000000000# Python CircleCI 2.0 configuration file # # Check https://circleci.com/docs/2.0/language-python/ for more details # version: 2 workflows: version: 2 test: jobs: - test-3.5 - test-3.6 - test-3.7 jobs: test-3.5: &test-template docker: - image: circleci/python:3.5.6 working_directory: ~/repo steps: - checkout - run: name: install dependencies command: | sudo apt-get update sudo apt-get install -y python3-pip python3-flask python3-stem python3-pyqt5 python3-crypto python3-socks python3-stdeb python3-all python-nautilus xvfb obfs4proxy sudo pip3 install -r install/requirements.txt sudo pip3 install -r install/requirements-tests.txt sudo pip3 install pytest-cov flake8 # run tests! - run: name: run flake tests command: | # stop the build if there are Python syntax errors or undefined names flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - run: name: run tests command: | xvfb-run -s "-screen 0 1280x1024x24" pytest --rungui --cov=onionshare --cov=onionshare_gui --cov-report=term-missing -vvv --no-qt-log tests/ test-3.6: <<: *test-template docker: - image: circleci/python:3.6.6 test-3.7: <<: *test-template docker: - image: circleci/python:3.7.1 onionshare-2.2/.github/000077500000000000000000000000001355066717400151005ustar00rootroot00000000000000onionshare-2.2/.github/CODEOWNERS000066400000000000000000000001741355066717400164750ustar00rootroot00000000000000* @micahflee # localization /share/locale/ @emmapeel2 # tests /tests/ @mig5 /tests_gui_local/ @mig5 /tests_gui_tor/ @mig5 onionshare-2.2/.gitignore000066400000000000000000000007071355066717400155340ustar00rootroot00000000000000__pycache__ *.py[cod] # C extensions *.so # Packages *.egg *.egg-info *.eggs dist deb_dist build eggs parts var sdist develop-eggs .installed.cfg MANIFEST env onionshare-*.tar.gz # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml .cache .pytest_cache # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # vim *.swp # tags ctags tags # OSX .DS_Store # virtualenv venv # other .vscodeonionshare-2.2/BUILD.md000066400000000000000000000340201355066717400147200ustar00rootroot00000000000000# Building OnionShare Start by getting the source code: ```sh git clone https://github.com/micahflee/onionshare.git cd onionshare ``` ## Linux Install the needed dependencies: For Debian-like distros: ``` apt install -y python3-flask python3-stem python3-pyqt5 python3-crypto python3-socks python-nautilus tor obfs4proxy python3-pytest build-essential fakeroot python3-all python3-stdeb dh-python python3-flask-httpauth python3-distutils ``` For Fedora-like distros: ``` dnf install -y python3-flask python3-flask-httpauth python3-stem python3-qt5 python3-crypto python3-pysocks nautilus-python tor obfs4 python3-pytest rpm-build ``` After that you can try both the CLI and the GUI version of OnionShare: ```sh ./dev_scripts/onionshare ./dev_scripts/onionshare-gui ``` You can also build OnionShare packages to install: Create a .deb on Debian-like distros: `./install/build_deb.sh` Create a .rpm on Fedora-like distros: `./install/build_rpm.sh` For OpenSuSE: There are instructions for building [in the wiki](https://github.com/micahflee/onionshare/wiki/Linux-Distribution-Support#opensuse-leap-150). For ArchLinux: There is a PKBUILD available [here](https://aur.archlinux.org/packages/onionshare/) that can be used to install OnionShare. If you find that these instructions don't work for your Linux distribution or version, consult the [Linux Distribution Support wiki guide](https://github.com/micahflee/onionshare/wiki/Linux-Distribution-Support), which might contain extra instructions. ## macOS Install Xcode from the Mac App Store. Once it's installed, run it for the first time to set it up. Also, run this to make sure command line tools are installed: `xcode-select --install`. And finally, open Xcode, go to Preferences > Locations, and make sure under Command Line Tools you select an installed version from the dropdown. (This is required for installing Qt5.) Download and install Python 3.7.4 from https://www.python.org/downloads/release/python-374/. I downloaded `python-3.7.4-macosx10.9.pkg`. You may also need to run the command `/Applications/Python\ 3.7/Install\ Certificates.command` to update Python 3.6's internal certificate store. Otherwise, you may find that fetching the Tor Browser .dmg file fails later due to a certificate validation error. Install Qt 5.13.1 for macOS from https://www.qt.io/offline-installers. I downloaded `qt-opensource-mac-x64-5.13.1.dmg`. In the installer, you can skip making an account, and all you need is `Qt` > `Qt 5.13.1` > `macOS`. Now install pip dependencies. If you want to use a virtualenv, create it and activate it first: ```sh python3 -m venv venv . venv/bin/activate ``` Then install the dependencies: ```sh pip3 install -r install/requirements.txt ``` #### You can run both the CLI and GUI versions of OnionShare without building an bundle ```sh ./dev_scripts/onionshare ./dev_scripts/onionshare-gui ``` #### To build the app bundle ```sh install/build_osx.sh ``` Now you should have `dist/OnionShare.app`. #### To codesign and build a pkg for distribution ```sh install/build_osx.sh --release ``` Now you should have `dist/OnionShare.pkg`. ## Windows ### Setting up your dev environment Download Python 3.7.4, 32-bit (x86) from https://www.python.org/downloads/release/python-374/. I downloaded `python-3.7.4.exe`. When installing it, make sure to check the "Add Python 3.7 to PATH" checkbox on the first page of the installer. Open a command prompt, cd to the onionshare folder, and install dependencies with pip: ```cmd pip install -r install\requirements.txt ``` Install the Qt 5.13.1 from https://www.qt.io/offline-installers. I downloaded `qt-opensource-windows-x86-5.13.1.exe`. In the installer, you can skip making an account, and all you need `Qt` > `Qt 5.13.1` > `MSVC 2017 32-bit`. After that you can try both the CLI and the GUI version of OnionShare: ``` python dev_scripts\onionshare python dev_scripts\onionshare-gui ``` #### If you want to build a .exe These instructions include adding folders to the path in Windows. To do this, go to Start and type "advanced system settings", and open "View advanced system settings" in the Control Panel. Click Environment Variables. Under "System variables" double-click on Path. From there you can add and remove folders that are available in the PATH. Download and install 7-Zip from http://www.7-zip.org/download.html. I downloaded `7z1900.exe`. Download and install the standalone [Windows 10 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk). Note that you may not need this if you already have Visual Studio. Add the following directories (you might want to make sure these are exact on your computer) to the path: * `C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86` * `C:\Program Files (x86)\Windows Kits\10\Redist\10.0.18362.0\ucrt\DLLs\x86` * `C:\Program Files (x86)\7-Zip` * `C:\Users\user\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\PyQt5\Qt\bin` #### If you want the .exe to not get falsely flagged as malicious by anti-virus software OnionShare uses PyInstaller to turn the python source code into Windows executable `.exe` file. Apparently, malware developers also use PyInstaller, and some anti-virus vendors have included snippets of PyInstaller code in their virus definitions. To avoid this, you have to compile the Windows PyInstaller bootloader yourself instead of using the pre-compiled one that comes with PyInstaller. (If you don't care about this, you can install PyInstaller with `pip install PyInstaller==3.5`.) Here's how to compile the PyInstaller bootloader: Download and install [Microsoft Build Tools for Visual Studio 2019](https://www.visualstudio.com/downloads/#build-tools-for-visual-studio-2019). I downloaded `vs_buildtools__1285639570.1568593053.exe`. In the installer, check the box next to "Visual C++ build tools". Click "Individual components", and under "Compilers, build tools and runtimes", check "Windows Universal CRT SDK". Then click install. When installation is done, you may have to reboot your computer. Then, enable the 32-bit Visual C++ Toolset on the Command Line like this: ``` cd "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build" vcvars32.bat ``` Make sure you have a new enough `setuptools`: ``` pip install --upgrade setuptools ``` Now make sure you don't have PyInstaller installed from pip: ``` pip uninstall PyInstaller rmdir C:\Users\user\AppData\Local\Programs\Python\Python37-32\Lib\site-packages\PyInstaller /S ``` Change to a folder where you keep source code, and clone the PyInstaller git repo and checkout the `v3.5` tag: ``` git clone https://github.com/pyinstaller/pyinstaller.git cd pyinstaller git tag -v v3.5 ``` (Note that ideally you would verify the git tag, but the PGP key that has signed the `v3.5` git tag for is not published anywhere, so this isn't possible. See [this issue](https://github.com/pyinstaller/pyinstaller/issues/4430).) And compile the bootloader, following [these instructions](https://pythonhosted.org/PyInstaller/bootloader-building.html). To compile, run this: ``` cd bootloader python waf distclean all --target-arch=32bit --msvc_targets=x86 ``` Finally, install the PyInstaller module into your local site-packages: ``` cd .. python setup.py install ``` Now the next time you use PyInstaller to build OnionShare, the `.exe` file should not be flagged as malicious by anti-virus. #### If you want to build the installer * Go to http://nsis.sourceforge.net/Download and download the latest NSIS. I downloaded `nsis-3.04-setup.exe`. * Add `C:\Program Files (x86)\NSIS` to the path. #### If you want to sign binaries with Authenticode * You'll need a code signing certificate. I got an open source code signing certificate from [Certum](https://www.certum.eu/certum/cert,offer_en_open_source_cs.xml). * Once you get a code signing key and certificate and covert it to a pfx file, import it into your certificate store. ### To make a .exe: * Open a command prompt, cd into the onionshare directory, and type: `pyinstaller install\pyinstaller.spec`. `onionshare-gui.exe` and all of their supporting files will get created inside the `dist` folder. ### To build the installer: Note that you must have a codesigning certificate installed in order to use the `install\build_exe.bat` script, because it codesigns `onionshare-gui.exe`, `uninstall.exe`, and `onionshare-setup.exe`. Open a command prompt, cd to the onionshare directory, and type: `install\build_exe.bat` This will prompt you to codesign three binaries and execute one unsigned binary. When you're done clicking through everything you will have `dist\onionshare-setup.exe`. # Running tests OnionShare includes PyTest unit tests. To run the tests, first install some dependencies: ```sh pip3 install -r install/requirements-tests.txt ``` Then you can run `pytest` against the `tests/` directory. ```sh pytest tests/ ``` You can run GUI tests like this: ```sh pytest --rungui tests/ ``` If you would like to also run the GUI unit tests in 'tor' mode, start Tor Browser in the background, then run: ```sh pytest --rungui --runtor tests/ ``` Keep in mind that the Tor tests take a lot longer to run than local mode, but they are also more comprehensive. You can also choose to wrap the tests in `xvfb-run` so that a ton of OnionShare windows don't pop up on your desktop (you may need to install the `xorg-x11-server-Xvfb` package), like this: ```sh xvfb-run pytest --rungui tests/ ``` # Making releases This section documents the release process. Unless you're a core OnionShare developer making a release, you'll probably never need to follow it. ## Changelog, version, and signed git tag Before making a release, all of these should be complete: * `share/version.txt` should have the correct version * `install/onionshare.nsi` should have the correct version, for the Windows installer * `CHANGELOG.md` should be updated to include a list of all major changes since the last release * There must be a PGP-signed git tag for the version, e.g. for OnionShare 2.1, the tag must be `v2.1` The first step for the Linux, macOS, and Windows releases is the same: Verify the release git tag: ``` git fetch git tag -v v$VERSION ``` If the tag verifies successfully, check it out: ``` git checkout v$VERSION ``` ## Linux release TODO: Write Flatpak instructions (see [this issue](https://github.com/micahflee/onionshare/issues/910)). To make a PPA release: - Go to Ubuntu build machine, which must have `~/.dput.cf` with the correct PPA info in it, and with the correct PGP signing key - Verify and checkout the git tag for this release - Run `./install/ppa_release.sh`, which builds a source package and uploads to the PPA build server - Login to Launchpad to monitor the build and make sure it is successful; if not, make minor patches and try the release again - After build is successful, from Launchpad, copy the binary from `cosmic` into other suites ## macOS release To make a macOS release, go to macOS build machine: - Build machine should be running macOS 10.11.6, and must have the Apple-trusted `Developer ID Application: Micah Lee` and `Developer ID Installer: Micah Lee` code-signing certificates installed - Verify and checkout the git tag for this release - Run `./install/build_osx.sh --release`; this will make a codesigned installer package called `dist/OnionShare-$VERSION.pkg` - Copy `OnionShare-$VERSION.pkg` to developer machine Then move back to the developer machine: - PGP-sign the macOS installer, `gpg -a --detach-sign OnionShare-$VERSION.pkg` Note that once we support notarizing the macOS installer (see [this issue](https://github.com/micahflee/onionshare/issues/953)), these will be the steps instead: - Developer machine, running the latest macOS, must have an app-specific Apple ID password saved in the login keychain called `onionshare-notarize` - Notarize it: `xcrun altool --notarize-app --primary-bundle-id "com.micahflee.onionshare" -u "micah@micahflee.com" -p "@keychain:onionshare-notarize" --file OnionShare-$VERSION.pkg` - Wait for it to get approved, check status with: `xcrun altool --notarization-history 0 -u "micah@micahflee.com" -p "@keychain:onionshare-notarize"` - After it's approved, staple the ticket: `xcrun stapler staple OnionShare-$VERSION.pkg` - PGP-sign the final, notarized and stapled, `gpg -a --detach-sign OnionShare-$VERSION.pkg` This process ends up with two final files: ``` OnionShare-$VERSION.pkg OnionShare-$VERSION.pkg.asc ``` ## Windows release To make a Windows release, go to Windows build machine: - Build machine should be running Windows 10, and have the Windows codesigning certificate installed - Verify and checkout the git tag for this release - Run `install\build_exe.bat`; this will make a codesigned installer package called `dist\onionshare-$VERSION-setup.exe` - Copy `onionshare-$VERSION-setup.exe` to developer machine Then move back to the developer machine: - PGP-sign the Windows installer, `gpg -a --detach-sign onionshare-$VERSION-setup.exe` This process ends up with two final files: ``` onionshare-$VERSION-setup.exe onionshare-$VERSION-setup.exe.asc ``` ## Source package To make a source package, run `./install/build_source.sh $TAG`, where `$TAG` is the the name of the signed git tag, e.g. `v2.1`. This process ends up with two final files in `dist`: ``` onionshare-$VERSION.tar.gz onionshare-$VERSION.tar.gz.asc ``` ## Publishing the release To publish the release: - Create a new release on GitHub, put the changelog in the description of the release, and upload all six files (the macOS installer, the Windows installer, the source package, and their signatures) - Upload the six release files to https://onionshare.org/dist/$VERSION/ - Copy the six release files into the OnionShare team Keybase filesystem - Update the [onionshare-website](https://github.com/micahflee/onionshare-website) repo: - Edit `latest-version.txt` to match the latest version - Update the version number and download links - Deploy to https://onionshare.org/ - Email the [onionshare-dev](https://lists.riseup.net/www/subscribe/onionshare-dev) mailing list announcing the release - Make a PR to [homebrew-cask](https://github.com/homebrew/homebrew-cask) to update the macOS version onionshare-2.2/CHANGELOG.md000066400000000000000000000231341355066717400153540ustar00rootroot00000000000000# OnionShare Changelog ## 2.2 * New feature: Website mode, which allows publishing a static HTML website as an onion service * Allow individual files to be viewed or downloaded in Share mode, including the ability to browse into subdirectories and use breadcrumbs to navigate back * Show a counter when individual files or pages are viewed * Better History items including colors and status codes to differentiate between successful and failed requests * Swap out the random /slug suffix for HTTP basic authentication (when in non-public mode) * Hide the Tor connection settings if the ONIONSHARE_HIDE_TOR_SETTINGS environment variable is set (Tails compatibility) * Remove the NoScript XSS warning in Receive Mode now that the NoScript/Tor Browser bug is fixed. The ajax upload method still exists when javascript is enabled. * Better support for DragonFly BSD * Updated various dependencies, including Flask, Werkzeug, urllib3, requests, and PyQt5 * Updated Tor to 0.4.1.5 * Other minor bug fixes * New translations: * Arabic (العربية) * Dutch (Nederlands) * Persian (فارسی) * Romanian (Română) * Serbian latin (Srpska (latinica)) * Removed translations with fewer than 90% of strings translated: * Finnish (Suomi) ## 2.1 * New feature: Auto-start timer, which allows scheduling when the server starts * Renamed CLI argument --debug to --verbose * Make Tor connection timeout configurable as a CLI argument * Updated various dependencies, including fixing third-party security issues in urllib3, Jinja2, and jQuery * Updated Tor to 0.3.5.8 * New translations: * Traditional Chinese (正體中文 (繁體)), * Simplified Chinese (中文 (简体)) * Finnish (Suomi) * German (Deutsch) * Icelandic (Íslenska) * Irish (Gaeilge) * Norwegian Bokmål (Norsk bokmål) * Polish (Polski) * Portuguese Portugal (Português (Portugal)) * Telugu (తెలుగు) * Turkish (Türkçe) * Ukrainian (Українська) * Removed translations with fewer than 90% of strings translated: * Bengali (বাংলা) * Persian (فارسی) ## 2.0 * New feature: Receiver mode allows you to receive files with OnionShare, instead of only sending files * New feature: Support for next generation onion services * New feature: macOS sandbox is enabled * New feature: Public mode feature, for public uses of OnionShare, which when enabled turns off slugs in the URL and removes the limit on how many 404 requests can be made * New feature: If you're sharing a single file, don't zip it up * New feature: Full support for meek_lite (Azure) bridges * New feature: Allow selecting your language from a dropdown * New translations: Bengali (বাংলা), Catalan (Català), Danish (Dansk), French (Français), Greek (Ελληνικά), Italian (Italiano), Japanese (日本語), Persian (فارسی), Portuguese Brazil (Português Brasil), Russian (Русский), Spanish (Español), Swedish (Svenska) * Several bugfixes * Invisible to users, this version includes some major refactoring of the codebase, and a robust set of unit tests which makes OnionShare easier to maintain going forward ## 1.3.2 * Bugfix: In debug mode, stop saving flask debug log in /tmp, where all users can access it ## 1.3.1 * Updated Tor to 0.2.3.10 * Windows and Mac binaries are now distributed with licenses for Tor and obfs4 ## 1.3 * Major UI redesign, introducing many UX improvements * Client-side web interfact redesigned * New feature: Support for meek_lite pluggable transports (Amazon and Azure) - not yet ready for Windows or macOS, sorry * New feature: Support for custom obfs4 and meek_lite bridges (again, meek_lite not available on Windows/macOS yet) * New feature: Ability to cancel share before it starts * Bugfix: The UpdateChecker no longer blocks the UI when checking * Bugfix: Simultaneous downloads (broken in 1.2) * Updated Tor to 0.2.3.9 * Improved support for BSD * Updated French and Danish translations * Minor build script and build documentation fixes * Flake8 tests added ## 1.2 * New feature: Support for Tor bridges, including obfs4proxy * New feature: Ability to use a persistent URL * New feature: Auto-stop timer, to stop OnionShare at a specified time * New feature: Get notification when Tor connection dies * Updated versions of Python, Qt, Tor, and other dependencies that are bundled * Added ability to supply a custom settings file as a command line arg * Added support for FreeBSD * Fixed small user interface issues * Fixed minor bugs * New Dutch translations ## 1.1 * OnionShare connects to Tor itself now, so opening Tor Browser in the background isn't required * In Windows and macOS, OnionShare alerts users about updates * Removed the menu bar, and adding a "Settings" button * Added desktop notifications, and a system tray icon * Ability to add multiple files and folders with a single "Add" button * Ability to delete multiple files and folders at once with the "Delete" button * Hardened some response headers sent from the web server * Minor clarity improvements to the contents of the share's web page * Alert the user rather than share an empty archive if a file was unreadable * Prettier progress bars ## 1.0 * Fixed long-standing macOS X bug that caused OnionShare to crash on older Macs (!) * Added settings dialog to configure connecting to Tor, including support for system Tor * Added support for stealth onion services (advanced option) * Added support for Whonix * Improved AppArmor profiles * Added progress bar for zipping up files * Improved the look of download progress bars * Allows developers to launch OnionShare from source tree, without building a package * Deleted legacy code, and made OnionShare purely use ephemeral Tor onion services * Switched to EFF's diceware wordlist for slugs ## 0.9.2 (Linux only) * Looks for `TOR_CONTROL_PORT` environment variable, to help Tails integration * Change how OnionShare checks to see if it's installed system-wide, to help Subgraph OS integration ## 0.9.1 * Added Nautilus extension, so you can right-click on a file and choose "Share via OnionShare", thanks to Subgraph developers * Switch to using the term "onion service" rather than "hidden service" * Fix CVE-2016-5026, minor security issue related to use of /tmp directory * Switch from PyInstaller to cx_Freeze for Windows and OSX packaging * Support CLI in Windows and OSX ## 0.9 * Slugs are now shorter and human-readable, with rate limiting to prevent URL guessing * Uses a new slug each time the server restarts * "Stop sharing automatically" enforces only one download * Users get asked if they're sure they want to close OnionShare while server is running * Added estimated time remaining progress indicator * Fixed frozen window while waiting for hidden service to start * Displays version number in both GUI and CLI * Closing window causes downloads to stop immediately * Web server listens in ports 17600-17650, for future Tails support * Updated translations * Ported from Python 2 to Python 3 and from Qt4 to Qt5 * Ported from py2app and py2exe to PyInstaller ## 0.8.1 * Fixed crash in Windows 7 * Fixed crash related to non-ephemeral hidden services in Linux * Fixed minor bugs ## 0.8 * Add support for ephemeral hidden services * Stopped leaking sender's locale on download page * Add support for Tor Messenger as provider of Tor service * Minor bugfixes, code cleanup, and refactoring ## 0.7.1 * Fixed critical bug in OS X binaries that caused crashes on some computers * Added Security Design document * Minor bugfix with Windows code signing timestamp server * Linux version uses HS dir that is allowed by Tor Browser Launcher's AppArmor profiles ## 0.7 * Added code signing for Mac OS X * Does not disable existing hidden services * Uses allowZip64 to allow compressing files >5gb * Sets HS dir to be in /var/lib/tor in Tails, to obey AppArmor rules * Misc. minor code cleanup ## 0.6 * Brand new drag-and-drop GUI with ability to start and stop server * Much cleaner code split into several files * Support for sharing multiple files and folders at once, and automatically compresses files before sharing * Redesigned receiver HTML interface * Waits for hidden service to be available before displaying URL * Cleans up hidden service directory on exit * Continuous integration with Travis * Support for multiple downloads at once * Fixed unicode-related filename and display bugs * Warns that large files could take hours to send * New translations * Several misc. bugfixes * Added code signing for Windows with Authenticode ## 0.5 * Removed webkit GUI altogether, and refactored GUI with native Qt widget * In Tails, launches separate process as root for Tor control port and firewall stuff, everything else runs as amnesia * Fixed itsdangerous dependency bug in Debian Wheezy and Tails * Guesses content type of file, responds in HTTP header ## 0.4 * Fixed critical XSS bug that could deanonymize user: https://micahflee.com/2014/07/security-advisory-upgrade-to-onionshare-0-4-immediately/ * Added CSP headers in GUI to prevent any future XSS bugs from working * Hash urandom data before using it, to avoid leaking state of entropy * Constant time compare the slug to avoid timing attacks * Cleaned up Tails firewall code ## 0.3 * Built a simple, featureful cross-platform GUI * Graphical installers for Windows and OSX * Packaged for Linux in .deb, .rpm, with desktop launcher * Installable in Tails 1.1+, with simple "install" script * Automatically copies URL to clipboard * Automatically closes when download is done by default * Shows download progress * Limited suite of tests * If a localized string doesn't exist, falls back to English * New translations: Dutch, Portuguese, German, Russian, and updated translations: Norwegian Bokmål, Spanish, French, Italian onionshare-2.2/LICENSE000066400000000000000000001047221355066717400145530ustar00rootroot00000000000000(Note: Third-party licenses can be found under install/licenses/.) OnionShare Copyright © 2014-2018 Micah Lee 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 . onionshare-2.2/MANIFEST.in000066400000000000000000000005721355066717400153020ustar00rootroot00000000000000include LICENSE include README.md include BUILD.md include share/* include share/images/* include share/locale/* include share/templates/* include share/static/* include install/org.onionshare.OnionShare.desktop include install/org.onionshare.OnionShare.appdata.xml include install/org.onionshare.OnionShare.svg include install/scripts/onionshare-nautilus.py include tests/*.py onionshare-2.2/README.md000066400000000000000000000047071355066717400150270ustar00rootroot00000000000000# OnionShare [OnionShare](https://onionshare.org) is an open source tool for securely and anonymously sending and receiving files using Tor onion services. It works by starting a web server directly on your computer and making it accessible as an unguessable Tor web address that others can load in [Tor Browser](https://www.torproject.org/) to download files from you, or upload files to you. It doesn't require setting up a separate server, using a third party file-sharing service, or even logging into an account. Unlike services like email, Google Drive, DropBox, WeTransfer, or nearly any other way people typically send files to each other, when you use OnionShare you don't give any companies access to the files that you're sharing. So long as you share the unguessable web address in a secure way (like pasting it in an encrypted messaging app), _no one_ but you and the person you're sharing with can access the files. ## Documentation To learn how OnionShare works, what its security properties are, and how to use it, check out the [wiki](https://github.com/micahflee/onionshare/wiki). ## Installing OnionShare You can download OnionShare for Windows and macOS from the [OnionShare website](https://onionshare.org). For macOS you can also use [Homebrew](https://brew.sh/): ``` brew cask install onionshare ``` For Ubuntu-like Linux distributions, you can use this PPA: ``` sudo add-apt-repository ppa:micahflee/ppa sudo apt install -y onionshare ``` OnionShare may also be available in your Linux distribution's package manager. Check [this wiki page](https://github.com/micahflee/onionshare/wiki/How-Do-I-Install-Onionshare) for more information. ## Contributing to OnionShare You can set up your development environment to build OnionShare yourself by following [these instructions](/BUILD.md). You may also subscribe to our mailing list [here](https://lists.riseup.net/www/info/onionshare-dev), and join our public Keybase team [here](https://keybase.io/team/onionshare). Test status: [![CircleCI](https://circleci.com/gh/micahflee/onionshare.svg?style=svg)](https://circleci.com/gh/micahflee/onionshare) # Screenshots ![Share mode OnionShare](/screenshots/onionshare-share-server.png) ![Share mode Tor Browser](/screenshots/onionshare-share-client.png) ![Receive mode OnionShare](/screenshots/onionshare-receive-server.png) ![Receive mode Tor Browser](/screenshots/onionshare-receive-client.png) ![Website mode OnionShare](/screenshots/onionshare-website-server.png)onionshare-2.2/apparmor/000077500000000000000000000000001355066717400153615ustar00rootroot00000000000000onionshare-2.2/apparmor/abstractions/000077500000000000000000000000001355066717400200555ustar00rootroot00000000000000onionshare-2.2/apparmor/abstractions/onionshare000066400000000000000000000015251355066717400221500ustar00rootroot00000000000000#include #include #include #include # Why are these not in abstractions/python? /usr/lib{,32,64}/python{2,3}.[0-9]/__pycache__/ rw, /usr/lib{,32,64}/python{2,3}.[0-9]/__pycache__/* rw, /usr/lib{,32,64}/python{2,3}.[0-9]/**/__pycache__/ rw, /usr/lib{,32,64}/python{2,3}.[0-9]/**/__pycache__/* rw, /usr/lib{,32,64}/python{2,3}/**/__pycache__/ rw, /usr/lib{,32,64}/python{2,3}/**/__pycache__/* rw, /bin/dash rix, /proc/*/mounts r, /proc/*/fd/ r, /sbin/ldconfig rix, /sbin/ldconfig.real rix, /bin/uname rix, /etc/mime.types r, /usr/share/onionshare/ r, /usr/share/onionshare/** r, /tmp/ rw, /tmp/** rw, # Allow read on almost anything in @{HOME}. Lenient, but # private-files-strict is in effect. owner @{HOME}/ r, owner @{HOME}/[^.]** r, onionshare-2.2/apparmor/local/000077500000000000000000000000001355066717400164535ustar00rootroot00000000000000onionshare-2.2/apparmor/local/usr.bin.onionshare000066400000000000000000000001751355066717400221250ustar00rootroot00000000000000# Site-specific additions and overrides for usr.bin.onionshare. # For more details, please see /etc/apparmor.d/local/README. onionshare-2.2/apparmor/local/usr.bin.onionshare-gui000066400000000000000000000002011355066717400226750ustar00rootroot00000000000000# Site-specific additions and overrides for usr.bin.onionshare-gui. # For more details, please see /etc/apparmor.d/local/README. onionshare-2.2/apparmor/usr.bin.onionshare000066400000000000000000000002511355066717400210260ustar00rootroot00000000000000#include /usr/bin/onionshare { #include /usr/bin/ r, /usr/bin/onionshare r, #include } onionshare-2.2/apparmor/usr.bin.onionshare-gui000066400000000000000000000012671355066717400216200ustar00rootroot00000000000000#include /usr/bin/onionshare-gui { #include #include #include /usr/bin/ r, /usr/bin/onionshare-gui r, /proc/*/cmdline r, # The freedesktop.org abstraction doesn't allow `k` /usr/share/icons/*/index.theme k, # Why do these still emit audit journal entries? owner @{HOME}/.config/ibus/bus/ rw, owner @{HOME}/.config/ibus/bus/* rw, deny @{HOME}/.ICEauthority r, deny /etc/machine-id r, deny /var/lib/dbus/machine-id.* rw, # Accessibility support owner /{,var/}run/user/*/at-spi2-*/ rw, owner /{,var/}run/user/*/at-spi2-*/** rw, #include } onionshare-2.2/dev_scripts/000077500000000000000000000000001355066717400160655ustar00rootroot00000000000000onionshare-2.2/dev_scripts/onionshare000077500000000000000000000017371355066717400201700ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ # Load onionshare module and resources from the source code tree import os, sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.onionshare_dev_mode = True import onionshare onionshare.main() onionshare-2.2/dev_scripts/onionshare-gui000077500000000000000000000017471355066717400207530ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ # Load onionshare module and resources from the source code tree import os, sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.onionshare_dev_mode = True import onionshare_gui onionshare_gui.main() onionshare-2.2/git-hooks/000077500000000000000000000000001355066717400154445ustar00rootroot00000000000000onionshare-2.2/git-hooks/README.md000066400000000000000000000002051355066717400167200ustar00rootroot00000000000000To use these hooks, cp any of them to onionshare's `.git/hooks`. * `pre-push` runs the test suite, and will push if the tests pass. onionshare-2.2/git-hooks/pre-push000077500000000000000000000002171355066717400171350ustar00rootroot00000000000000#!/bin/bash # Pre-push hook. If you want to test with a different version of firefox, put # the path in the CFX_FIREFOX environment variable. onionshare-2.2/install/000077500000000000000000000000001355066717400152065ustar00rootroot00000000000000onionshare-2.2/install/build_deb.sh000077500000000000000000000012161355066717400174560ustar00rootroot00000000000000#!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR VERSION=`cat share/version.txt` # clean up from last build rm -r deb_dist >/dev/null 2>&1 # build binary package python3 setup.py --command-packages=stdeb.command bdist_deb # return install instructions if onionshare builds properly if [[ $? -eq 0 ]]; then # The build process in stdeb's util.py renames .dev to ~dev # Adjust it here for the purposes of displaying the right filename VERSION="${VERSION/.dev/~dev}" echo "" echo "To install, run:" echo "sudo dpkg -i deb_dist/onionshare_$VERSION-1_all.deb" else echo "OnionShare failed to build!" exit 1 fi onionshare-2.2/install/build_exe.bat000066400000000000000000000010141355066717400176320ustar00rootroot00000000000000REM delete old dist files rmdir /s /q dist REM build onionshare-gui.exe pyinstaller install\pyinstaller.spec -y REM download tor python install\get-tor-windows.py REM sign onionshare-gui.exe signtool.exe sign /v /d "OnionShare" /a /tr http://time.certum.pl/ dist\onionshare\onionshare-gui.exe REM build an installer, dist\onionshare-setup.exe makensis.exe install\onionshare.nsi REM sign onionshare-setup.exe signtool.exe sign /v /d "OnionShare" /a /tr http://time.certum.pl/ dist\onionshare-setup.exe onionshare-2.2/install/build_osx.sh000077500000000000000000000026621355066717400175430ustar00rootroot00000000000000#!/bin/bash ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $ROOT # deleting dist echo Deleting dist folder rm -rf $ROOT/dist &>/dev/null 2>&1 # build the .app echo Building OnionShare.app pyinstaller $ROOT/install/pyinstaller.spec python3 $ROOT/install/get-tor-osx.py # create a symlink of onionshare-gui called onionshare, for the CLI version cd $ROOT/dist/OnionShare.app/Contents/MacOS ln -s onionshare-gui onionshare cd $ROOT if [ "$1" = "--release" ]; then mkdir -p dist APP_PATH="$ROOT/dist/OnionShare.app" PKG_PATH="$ROOT/dist/OnionShare.pkg" IDENTITY_NAME_APPLICATION="Developer ID Application: Micah Lee" IDENTITY_NAME_INSTALLER="Developer ID Installer: Micah Lee" ENTITLEMENTS_CHILD_PATH="$ROOT/install/macos_sandbox/child.plist" ENTITLEMENTS_PARENT_PATH="$ROOT/install/macos_sandbox/parent.plist" echo "Codesigning the app bundle" codesign \ --deep \ -s "$IDENTITY_NAME_APPLICATION" \ --force \ --entitlements "$ENTITLEMENTS_CHILD_PATH" \ --timestamp \ "$APP_PATH" codesign \ -s "$IDENTITY_NAME_APPLICATION" \ --force \ --entitlements "$ENTITLEMENTS_PARENT_PATH" \ --timestamp \ "$APP_PATH" echo "Creating an installer" productbuild \ --sign "$IDENTITY_NAME_INSTALLER" \ --component "$APP_PATH" /Applications \ --timestamp \ "$PKG_PATH" echo "Cleaning up" rm -rf "$APP_PATH" echo "All done, your installer is in: $PKG_PATH" fi onionshare-2.2/install/build_rpm.sh000077500000000000000000000007371355066717400175310ustar00rootroot00000000000000#!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR VERSION=`cat share/version.txt` # clean up from last build rm -r build dist >/dev/null 2>&1 # build binary package python3 setup.py bdist_rpm --requires="python3-flask, python3-flask-httpauth, python3-stem, python3-qt5, python3-crypto, python3-pysocks, nautilus-python, tor, obfs4" # install it echo "" echo "To install, run:" echo "sudo dnf install dist/onionshare-$VERSION-1.noarch.rpm" onionshare-2.2/install/build_source.sh000077500000000000000000000027011355066717400202240ustar00rootroot00000000000000#!/bin/bash # The script builds a source package # See https://github.com/micahflee/onionshare/blob/develop/BUILD.md#source-package # Usage display_usage() { echo "Usage: $0 [tag]" } if [ $# -lt 1 ] then display_usage exit 1 fi # Input validation TAG=$1 if [ "${TAG:0:1}" != "v" ] then echo "Tag must start with 'v' character" exit 1 fi VERSION=${TAG:1} # Make sure tag exists git tag | grep "^$TAG\$" if [ $? -ne 0 ] then echo "Tag does not exist" exit 1 fi # Clone source mkdir -p build/source mkdir -p dist cd build/source git clone https://github.com/micahflee/onionshare.git cd onionshare # Verify tag git tag -v $TAG 2> ../verify.txt if [ $? -ne 0 ] then echo "Tag does not verify" exit 1 fi cat ../verify.txt |grep "using RSA key 927F419D7EC82C2F149C1BD1403C2657CD994F73" if [ $? -ne 0 ] then echo "Tag signed with wrong key" exit 1 fi cat ../verify.txt |grep "^gpg: Good signature from" if [ $? -ne 0 ] then echo "Tag verification missing 'Good signature from'" exit 1 fi # Checkout code git checkout $TAG # Delete .git, compress, and PGP sign cd .. rm -rf onionshare/.git tar -cf onionshare-$VERSION.tar.gz onionshare/ gpg -a --detach-sign onionshare-$VERSION.tar.gz # Move source package to dist cd ../.. mv build/source/onionshare-$VERSION.tar.gz dist mv build/source/onionshare-$VERSION.tar.gz.asc dist # Clean up rm -rf build/source/onionshare rm build/source/verify.txt echo "Source package complete, files are in dist" onionshare-2.2/install/check_lacked_trans.py000077500000000000000000000064501355066717400213570ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Check translation lacked or disused. Example: in OnionShare directory $ check_lacked_trans.py de disused choose_file de disused gui_starting_server de lacked gui_canceled de lacked gui_starting_server1 de lacked gui_starting_server2 de lacked gui_starting_server3 en disused choose_file es disused choose_file es disused gui_starting_server ... 1. search `{{strings.translation_key}}` and `strings._('translation_key')` from .py or .html files. 2. load translation key from locale/*.json. 3. compare these. """ import fileinput, argparse, re, os, codecs, json, sys def arg_parser(): desc = __doc__.strip().splitlines()[0] p = argparse.ArgumentParser(description=desc) p.add_argument( "-d", default=".", help="onionshare directory", metavar="ONIONSHARE_DIR", dest="onionshare_dir", ) p.add_argument( "--show-all-keys", action="store_true", help="show translation key in source and exit", ), p.add_argument( "-l", default="all", help="language code (default: all)", metavar="LANG_CODE", dest="lang_code", ) return p def files_in(*dirs): dir = os.path.join(*dirs) files = os.listdir(dir) return [os.path.join(dir, f) for f in files] def main(): parser = arg_parser() args = parser.parse_args() dir = args.onionshare_dir src = ( files_in(dir, "onionshare") + files_in(dir, "onionshare_gui") + files_in(dir, "onionshare_gui/mode") + files_in(dir, "onionshare_gui/mode/share_mode") + files_in(dir, "onionshare_gui/mode/receive_mode") + files_in(dir, "onionshare_gui/mode/website_mode") + files_in(dir, "install/scripts") + files_in(dir, "tests") ) pysrc = [p for p in src if p.endswith(".py")] lang_code = args.lang_code translate_keys = set() # load translate key from python source for line in fileinput.input(pysrc, openhook=fileinput.hook_encoded("utf-8")): # search `strings._('translate_key')` # `strings._('translate_key', True)` m = re.findall(r"strings\._\((.*?)\)", line) if m: for match in m: key = match.split(",")[0].strip(""""' """) translate_keys.add(key) if args.show_all_keys: for k in sorted(translate_keys): print(k) sys.exit() if lang_code == "all": locale_files = [f for f in files_in(dir, "share/locale") if f.endswith(".json")] else: locale_files = [ f for f in files_in(dir, "share/locale") if f.endswith("%s.json" % lang_code) ] for locale_file in locale_files: with codecs.open(locale_file, "r", encoding="utf-8") as f: trans = json.load(f) # trans -> {"key1": "translate-text1", "key2": "translate-text2", ...} locale_keys = set(trans.keys()) disused = locale_keys - translate_keys lacked = translate_keys - locale_keys locale, ext = os.path.splitext(os.path.basename(locale_file)) for k in sorted(disused): print(locale, "disused", k) for k in sorted(lacked): print(locale, "lacked", k) if __name__ == "__main__": main() onionshare-2.2/install/get-tor-osx.py000066400000000000000000000110321355066717400177450ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ """ This script downloads a pre-built tor binary to bundle with OnionShare. In order to avoid a Mac gnupg dependency, I manually verify the signature and hard-code the sha256 hash. """ import inspect import os import sys import hashlib import zipfile import io import shutil import subprocess import requests def main(): dmg_url = "https://archive.torproject.org/tor-package-archive/torbrowser/8.5.5/TorBrowser-8.5.5-osx64_en-US.dmg" dmg_filename = "TorBrowser-8.5.5-osx64_en-US.dmg" expected_dmg_sha256 = ( "9c1b7840bd251a4c52f0c919991e57cafb9178c55e11fa49f83ffacce3c20511" ) # Build paths root_path = os.path.dirname( os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) ) working_path = os.path.join(root_path, "build", "tor") dmg_tor_path = os.path.join( "/Volumes", "Tor Browser", "Tor Browser.app", "Contents" ) dmg_path = os.path.join(working_path, dmg_filename) dist_path = os.path.join(root_path, "dist", "OnionShare.app", "Contents") # Make sure the working folder exists if not os.path.exists(working_path): os.makedirs(working_path) # Make sure the zip is downloaded if not os.path.exists(dmg_path): print("Downloading {}".format(dmg_url)) r = requests.get(dmg_url) open(dmg_path, "wb").write(r.content) dmg_sha256 = hashlib.sha256(r.content).hexdigest() else: dmg_data = open(dmg_path, "rb").read() dmg_sha256 = hashlib.sha256(dmg_data).hexdigest() # Compare the hash if dmg_sha256 != expected_dmg_sha256: print("ERROR! The sha256 doesn't match:") print("expected: {}".format(expected_dmg_sha256)) print(" actual: {}".format(dmg_sha256)) sys.exit(-1) # Mount the dmg, copy data to the working path subprocess.call(["hdiutil", "attach", dmg_path]) # Make sure Resources/tor exists before copying files if os.path.exists(os.path.join(dist_path, "Resources", "Tor")): shutil.rmtree(os.path.join(dist_path, "Resources", "Tor")) os.makedirs(os.path.join(dist_path, "Resources", "Tor")) if os.path.exists(os.path.join(dist_path, "MacOS", "Tor")): shutil.rmtree(os.path.join(dist_path, "MacOS", "Tor")) os.makedirs(os.path.join(dist_path, "MacOS", "Tor")) # Modify the tor script to adjust the path tor_script = open( os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "tor"), "r" ).read() tor_script = tor_script.replace("../../../MacOS/Tor", "../../MacOS/Tor") open(os.path.join(dist_path, "Resources", "Tor", "tor"), "w").write(tor_script) # Copy into dist shutil.copyfile( os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "geoip"), os.path.join(dist_path, "Resources", "Tor", "geoip"), ) shutil.copyfile( os.path.join(dmg_tor_path, "Resources", "TorBrowser", "Tor", "geoip6"), os.path.join(dist_path, "Resources", "Tor", "geoip6"), ) os.chmod(os.path.join(dist_path, "Resources", "Tor", "tor"), 0o755) shutil.copyfile( os.path.join(dmg_tor_path, "MacOS", "Tor", "tor.real"), os.path.join(dist_path, "MacOS", "Tor", "tor.real"), ) shutil.copyfile( os.path.join(dmg_tor_path, "MacOS", "Tor", "libevent-2.1.6.dylib"), os.path.join(dist_path, "MacOS", "Tor", "libevent-2.1.6.dylib"), ) os.chmod(os.path.join(dist_path, "MacOS", "Tor", "tor.real"), 0o755) # obfs4proxy binary shutil.copyfile( os.path.join(dmg_tor_path, "MacOS", "Tor", "PluggableTransports", "obfs4proxy"), os.path.join(dist_path, "Resources", "Tor", "obfs4proxy"), ) os.chmod(os.path.join(dist_path, "Resources", "Tor", "obfs4proxy"), 0o755) # Eject dmg subprocess.call(["diskutil", "eject", "/Volumes/Tor Browser"]) if __name__ == "__main__": main() onionshare-2.2/install/get-tor-windows.py000066400000000000000000000062631355066717400206400ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ """ This script downloads a pre-built tor binary to bundle with OnionShare. In order to avoid a Windows gnupg dependency, I manually verify the signature and hard-code the sha256 hash. """ import inspect import os import sys import hashlib import shutil import subprocess import requests def main(): exe_url = "https://archive.torproject.org/tor-package-archive/torbrowser/8.5.5/torbrowser-install-8.5.5_en-US.exe" exe_filename = "torbrowser-install-8.5.5_en-US.exe" expected_exe_sha256 = ( "a3aa7e626d1d2365dcecc6f17055f467f31c4ff9558a769e51d4b90640e48bb0" ) # Build paths root_path = os.path.dirname( os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) ) working_path = os.path.join(os.path.join(root_path, "build"), "tor") exe_path = os.path.join(working_path, exe_filename) dist_path = os.path.join( os.path.join(os.path.join(root_path, "dist"), "onionshare"), "tor" ) # Make sure the working folder exists if not os.path.exists(working_path): os.makedirs(working_path) # Make sure the zip is downloaded if not os.path.exists(exe_path): print("Downloading {}".format(exe_url)) r = requests.get(exe_url) open(exe_path, "wb").write(r.content) exe_sha256 = hashlib.sha256(r.content).hexdigest() else: exe_data = open(exe_path, "rb").read() exe_sha256 = hashlib.sha256(exe_data).hexdigest() # Compare the hash if exe_sha256 != expected_exe_sha256: print("ERROR! The sha256 doesn't match:") print("expected: {}".format(expected_exe_sha256)) print(" actual: {}".format(exe_sha256)) sys.exit(-1) # Extract the bits we need from the exe cmd = [ "7z", "e", "-y", exe_path, "Browser\TorBrowser\Tor", "-o%s" % os.path.join(working_path, "Tor"), ] cmd2 = [ "7z", "e", "-y", exe_path, "Browser\TorBrowser\Data\Tor\geoip*", "-o%s" % os.path.join(working_path, "Data"), ] subprocess.Popen(cmd).wait() subprocess.Popen(cmd2).wait() # Copy into dist if os.path.exists(dist_path): shutil.rmtree(dist_path) os.makedirs(dist_path) shutil.copytree(os.path.join(working_path, "Tor"), os.path.join(dist_path, "Tor")) shutil.copytree( os.path.join(working_path, "Data"), os.path.join(dist_path, "Data", "Tor") ) if __name__ == "__main__": main() onionshare-2.2/install/licenses/000077500000000000000000000000001355066717400170135ustar00rootroot00000000000000onionshare-2.2/install/licenses/license-jquery.txt000066400000000000000000000021071355066717400225130ustar00rootroot00000000000000Copyright JS Foundation and other contributors, https://js.foundation/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. onionshare-2.2/install/licenses/license-obfs4.txt000066400000000000000000000055161355066717400222200ustar00rootroot00000000000000Copyright (c) 2014, Yawning Angel All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================================== Copyright (c) 2012 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. onionshare-2.2/install/licenses/license-onionshare.txt000066400000000000000000001046041355066717400233460ustar00rootroot00000000000000Copyright (C) 2014-2018 Micah Lee 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 . onionshare-2.2/install/licenses/license-tor.txt000066400000000000000000000457701355066717400220150ustar00rootroot00000000000000 This file contains the license for Tor, a free software project to provide anonymity on the Internet. It also lists the licenses for other components used by Tor. For more information about Tor, see https://www.torproject.org/. If you got this file as a part of a larger bundle, there may be other license terms that you should be aware of. =============================================================================== Tor is distributed under this license: Copyright (c) 2001-2004, Roger Dingledine Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson Copyright (c) 2007-2017, The Tor Project, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the names of the copyright owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== src/ext/strlcat.c and src/ext/strlcpy.c by Todd C. Miller are licensed under the following license: * Copyright (c) 1998 Todd C. Miller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== src/ext/tor_queue.h is licensed under the following license: * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. =============================================================================== src/ext/csiphash.c is licensed under the following license: Copyright (c) 2013 Marek Majkowski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. =============================================================================== Trunnel is distributed under this license: Copyright 2014 The Tor Project, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the names of the copyright owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== src/config/geoip is licensed under the following license: OPEN DATA LICENSE (GeoLite Country and GeoLite City databases) Copyright (c) 2008 MaxMind, Inc. All Rights Reserved. All advertising materials and documentation mentioning features or use of this database must display the following acknowledgment: "This product includes GeoLite data created by MaxMind, available from http://maxmind.com/" Redistribution and use with or without modification, are permitted provided that the following conditions are met: 1. Redistributions must retain the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 2. All advertising materials and documentation mentioning features or use of this database must display the following acknowledgement: "This product includes GeoLite data created by MaxMind, available from http://maxmind.com/" 3. "MaxMind" may not be used to endorse or promote products derived from this database without specific prior written permission. THIS DATABASE IS PROVIDED BY MAXMIND, INC ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MAXMIND BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== m4/pc_from_ucontext.m4 is available under the following license. Note that it is *not* built into the Tor software. Copyright (c) 2005, Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. =============================================================================== m4/pkg.m4 is available under the following license. Note that it is *not* built into the Tor software. pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- serial 1 (pkg-config-0.24) Copyright © 2004 Scott James Remnant . This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception to the GNU General Public License, if you distribute this file as part of a program that contains a configuration script generated by Autoconf, you may include it under the same distribution terms that you use for the rest of that program. =============================================================================== src/ext/readpassphrase.[ch] are distributed under this license: Copyright (c) 2000-2002, 2007 Todd C. Miller Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Sponsored in part by the Defense Advanced Research Projects Agency (DARPA) and Air Force Research Laboratory, Air Force Materiel Command, USAF, under agreement number F39502-99-1-0512. =============================================================================== src/ext/mulodi4.c is distributed under this license: ========================================================================= compiler_rt License ========================================================================= The compiler_rt library is dual licensed under both the University of Illinois "BSD-Like" license and the MIT license. As a user of this code you may choose to use it under either license. As a contributor, you agree to allow your code to be used under both. Full text of the relevant licenses is included below. ========================================================================= University of Illinois/NCSA Open Source License Copyright (c) 2009-2016 by the contributors listed in CREDITS.TXT All rights reserved. Developed by: LLVM Team University of Illinois at Urbana-Champaign http://llvm.org Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution. * Neither the names of the LLVM Team, University of Illinois at Urbana-Champaign, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. ========================================================================= Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ========================================================================= Copyrights and Licenses for Third Party Software Distributed with LLVM: ========================================================================= The LLVM software contains code written by third parties. Such software will have its own individual LICENSE.TXT file in the directory in which it appears. This file will describe the copyrights, license, and restrictions which apply to that code. The disclaimer of warranty in the University of Illinois Open Source License applies to all code in the LLVM Distribution, and nothing in any of the other licenses gives permission to use the names of the LLVM Team or the University of Illinois to endorse or promote products derived from this Software. =============================================================================== If you got Tor as a static binary with OpenSSL included, then you should know: "This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit (http://www.openssl.org/)" =============================================================================== onionshare-2.2/install/licenses/readme.txt000066400000000000000000000001171355066717400210100ustar00rootroot00000000000000This folder contains 3rd-party licenses for software included with OnionShare. onionshare-2.2/install/macos_sandbox/000077500000000000000000000000001355066717400200265ustar00rootroot00000000000000onionshare-2.2/install/macos_sandbox/child.plist000066400000000000000000000004411355066717400221650ustar00rootroot00000000000000 com.apple.security.app-sandbox com.apple.security.inherit onionshare-2.2/install/macos_sandbox/parent.plist000066400000000000000000000026471355066717400224050ustar00rootroot00000000000000 com.apple.security.app-sandbox com.apple.security.network.server com.apple.security.network.client com.apple.security.files.user-selected.read-write com.apple.security.temporary-exception.files.absolute-path.read-only /private/etc/apache2/mime.types com.apple.security.temporary-exception.files.home-relative-path.read-only /Library/Application Support/TorBrowser-Data/Tor/control_auth_cookie com.apple.security.temporary-exception.files.home-relative-path.read-write /OnionShare/ onionshare-2.2/install/onionshare.icns000066400000000000000000001025701355066717400202360ustar00rootroot00000000000000icnsxis32 NNPUQSOKKOSQUPNDPMBJWWJBMQDNNHPHN۞OIQCAMPKf^IQPLQHTPMQREdYnGIsDSG\AFPQ=uEMYLONRcgUUg\TNOMYM]Em=OMDF\GSD{QPVdERQMPTHQLPQI^fKPMACQIO۞NHPHNNDQMBJWWJBMPDN PUQSOKKOSQUPNN   m  t yy  .$  -9@w!D   +//    ]: !wJd,  $.  yy t  m   NNPUQSOKKOSQUPNDPMBJWWJBMQDNNHPHN۞OIQCAMPKf^IQPLQHTPMQREdYnGIsDSG\AFPQ=uEMYLONRcgUUg\TNOMYM]Em=OMDF\GSD{QPVdERQMPTHQLPQI^fKPMACQIO۞NHPHNNDQMBJWWJBMPDN PUQSOKKOSQUPNNs8mk66::ߟ::66il32NNOONN OQPNKKNPQONN OPHAFOXXOFAHPONNQIDhΠhDIQNPCbbCPNOBBPNPFBPNPI CQNPF<īcIONPCb9VDBBEcDPN Q@V;KOFfNKPNPCCFLOQPNKBNKOGeMKPNxTJBDM[KOGdXIPNPD~ѿKNKLONPDJKPNOMNSMONPJYZKONPIXWHPNPJMMJPNN PMD~ ~DMPNNOPDNԊNDPONNPNCIhhICNPNNQOHBCJRWWRJCBHOQNN OQPOMKKMOPQONNONNNN      0tt0   __   OO              ԕlNV|O , X ͋  ,  <]  / q  ,  /  Q/  . r . F .    3     '  %+( (+c% '  x   3   .   . r .  /;  /  -  y /  ]Q   ,  F k , O              OO   __   0tt0      NNNNONN OQPOMKKMOPQONNQOHBCJRWWRJCBHOQNNPNCIhhICNPNNOPDNԊNDPONN PMD~ ~DMPNNPJMMJPNPHWXIPNOKZYJPNOMSNMONPKJDPNOLKNK౓~~DPNPIXdGOKMBCDDCC[ڋNPKMeGOJPCNQPQQK@pCPNPKNfFMSMJRNORCeJONPKOfFPCNONRAgHON PKOfETNQDCQNPJNfEQNPFxCPNPJMeDQNPMUKPOONNOKSjFPNLJLGOJLIMNNOaJONLX`[QdYYbSMMSbYYdR[`XLNOJaONNMILJO?NJLNPFjRKONNOOPKCRONQDeMJPNPC[KONQEfNJPNQC@RNOREfOKPNOHgoCRNOOIJOFfOKPNOJeAQPONOQN>KOFfNKPNPCCFLOQPNKBNKOGeMKPNxTJBDM[KOGdXIPNPD~ѿKNKLONPDJKPNOMNSMONPJYZKONPIXWHPNPJMMJPNN PMD~ ~DMPNNOPDNԊNDPONNPNCIhhICNPNNQOHBCJRWWRJCBHOQNN OQPOMKKMOPQONNONNNNh8mk ]ֺ]fftt))OOiijjPP..vvee##\\\\##eevv..PPjjiiOO))ttff]ֺ]it32NNNNNNNNNNNNNNNNNNN]iyøyi]NN}}NN_ʼn_NNf˟fNNգՏNNPuuPNNtثtNNXXNNNNPPNNNNmmNNvvNNNNMMNNNMNNjvNNMNTmNNNNMNTPNNMNNNRNNMNRXNNMNOΑƖlVOVlNNTӎqXQLMMNMMLQXq՝tNNMNҊcCMNMCcPNNMNMXYMNTΈTNTʚuNNMNYZNՅ}FNF}NNMNMTUMNR̓INI֘NNMN]^NRՁMNMՏNNMNQRNOLNLfNNMNM\]MNTӦLNLˎNNMNSTNMNM֖_NNMNY[MNMNINNMNUZNMN}ŎNNMNMSUMNMNFʔNNMN^^NMNT}NNMNQRMNMNNMNM]^MNMNcNMNTTNMNCՓ]NMNMYZMNMNMqiNMNZZNMNXyNMSTMNMNQߓNM^_MNMNLƓNQRNMNMÓNM\^MNMNMӓNTUNMNlNMXYMNMNVNR݇SNMNMNR[\[RNR[b[RNMNMNSޅRNlNMNMYXMNMNMNRTNӒMNMNM^]MNÒLNMNRQNQNMNM_^MNXNMNMTSMNyqMNMNZZNMNiCNMNMZYMNMN]cNMNTTNMNNMNM^]MNMNTNMNMRQNMNN}FNMN^^NMNN}NMNMUSMNMNNŔINMNZYNMNNMNMSNM[YMNMNN_LNLӇNTSNMNN˖LNLTNM_^MNMNNfMNMONMRQMNMNN՗INIփRN^]NMNN}FNF}RNMUTMNMNNTNTʈՇNYYNMNNucCMNMCcTNMYXMNMNNP؜qXQLMMNMMLQXqՎґNMNNtƖlVOVlTNMNNONMNNXQNMNNRNMNNՇNMNNPTNMNNуNMNNmTNMNNvjNNMNNNMMNNNNvvNNmmNNNNPPNNNNXXNNtثtNNPuuPNNգՏNNf˟fNN_ʼn_NN}}NN]iyøyi]NNNNNNNNNNNNNNNNNNN   "2HjĭjH2" MM $^^$ .. fƣf CC BʫB  RR  ۷ۓ 88 DD SS  SS  5D 8  R  ӱpW66Wp Ž<  <ƝB )  )    C  ŅM M    ǘf  #$ Ɓ  Ə  ߃   .  !# †    ǖ$  ݉ ^  M   ݍ    #$ M    #ߓ$ )  Ɠ"  ܗ  <2  H  ܛ ӓj  #$     p  !$  Wē  6ܑ  ܥ  ч  * ҅ 6  ޥ ܒW  Ēp  #"      $# j  ޛ H<  2  ޗ ")   $#    M  $#  M  ލ    ^    މ $  ‡      %# .     Ɨ ǃ  $# fM M    Ň  C)  )   ʜ<  <Ǝ BӱpW66Wp   R Ň  8 D4 SS SS DD 88 ۷ۓ  RR  BʫB CC fƣf .. $^^$ MM "2HjĭjH2"   NNNNNNNNNNNNNNNNNNN]iyøyi]NN}}NN_ʼn_NNf˟fNNգՏNNPuuPNNtثtNNXXNNNNPPNNNNmmNNvvNNNNMMNNNMNNjvNNMNTmNNNNMNTPNNMNNNRNNMNRXNNMNOΑƖlVOVlNNTӎqXQLMMNMMLQXq՝tNNMNҊcCMNMCcPNNMNMXYMNTΈTNTʚuNNMNYZNՅ}FNF}NNMNMTUMNR̓INI֘NNMN]^NRՁMNMՏNNMNQRNOLNLfNNMNM\]MNTӦLNLˎNNMNSTNMNM֖_NNMNY[MNMNINNMNUZNMN}ŎNNMNMSUMNMNFʔNNMN^^NMNT}NNMNQRMNMNNMNM]^MNMNcNMNTTNMNCՓ]NMNMYZMNMNMqiNMNZZNMNXyNMSTMNMNQߓNM^_MNMNLƓNQRNMNMÓNM\^MNMNMӓNTUNMNlNMXYMNMNVNR݇SNMNMNR[\[RNR[b[RNMNMNSޅRNlNMNMYXMNMNMNRTNӒMNMNM^]MNÒLNMNRQNQNMNM_^MNXNMNMTSMNyqMNMNZZNMNiCNMNMZYMNMN]cNMNTTNMNNMNM^]MNMNTNMNMRQNMNN}FNMN^^NMNN}NMNMUSMNMNNŔINMNZYNMNNMNMSNM[YMNMNN_LNLӇNTSNMNN˖LNLTNM_^MNMNNfMNMONMRQMNMNN՗INIփRN^]NMNN}FNF}RNMUTMNMNNTNTʈՇNYYNMNNucCMNMCcTNMYXMNMNNP؜qXQLMMNMMLQXqՎґNMNNtƖlVOVlTNMNNONMNNXQNMNNRNMNNՇNMNNPTNMNNуNMNNmTNMNNvjNNMNNNMMNNNNvvNNmmNNNNPPNNNNXXNNtثtNNPuuPNNգՏNNf˟fNN_ʼn_NN}}NN]iyøyi]NNNNNNNNNNNNNNNNNNNt8mk@ 0BbͷbB0 CC:rr:BB!! ee~~ZZff  ffZZ~~ee !!BB::rrCC 00BBbbBB00 CCrr::BB!! ee~~ZZff  ffZZ~~ee !!BB:rr:CC 0BbͷbB0 onionshare-2.2/install/onionshare.ico000066400000000000000000000353561355066717400200630ustar00rootroot00000000000000 h6  00 %F(    N N/N NN NN NN NN NN NN N/N NN NN NN NN NL LL LN NN NN NN NN NN NN NN NSSvvSSN NN NN NN NN Nb(bb(bN NN NN N/N NSS]!]N NN NN N/N NN NvyGyM MM MX`&`^#^N NN NN NN No;oN NN NN NN NQQ¬^#^N NN NL LN NN NN NN NQQ¬_$__$_¬QQN NN NN NM ML LN NN N^#^¬QQN NN NN NN NyGyN NN NN NN N^#^`&`e,eN NN No;ovN NN NN N/N NN N]!]SSN NN N/N NN Nb(bb(bN NN NN NN NN NSSvvSSN NN NN NN NN NN NN NN NL LL LN NN NN NN NN NN N/N NN NN NN NN NN NN N/( @   N NN NSN NN NN NN NN NN NN NN NN NSN N00N N'N NN NN NN NN NN NN NN NN NN NN NN NN NN NN N'00N NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NK KIIIIK KN NN NN NN NN NN NN NN NN NN NN NN N5N NN NN NN NN NOOg/gʶʶg/gOON NN NN NN NN NN N5N NN NN NN NN NN NN Nb(bb(bN NN NN NN NN NN NN NN NN NN NN NN NkkN NN NN NN NN NN NN NN NN NN NN NxyN NN NN NN NN N00N N'N NN NN NN Nk_N NN NN NN NN NN N'N NN NN NN Nb(biM MN NN NN NN NN NN NN NN NN NN NOO˸wEwK KM ML LM Md`M Ma&a\M MN NN NN NN NN NN NSN NN NN Ng/gRRN NN NN NN NN NN NYYDzhM M[[iM MN NN NN NN NSN NN NN NN NQQN NN NN NN NN NN NN NN NL LN N`%`qM MN NN NN NN NN NN NN Nʶa)aN NN NN NN NN NN NN NN NN NN NZZhM MN NN NN NN NN NK KʶN NN NN NN NN NN NN NN NN NN N`%`rM MN NN NN NN NIIN NN NN NN NN NN NN NN NN N\ \jN NN Nj\\N NN NN NN NN NN NN NN NM MIIN NN NN NN NM Mr`%`N NN NN NN NN NN NN NN NN NK KK KN NN NN NN NN NM MhZZN NN NN NN NN NN NN NN NN NN NwEwʶN NN NN NN NN NN NN NM Mq`%`N NN NN NN NN NN NN NN NN NN NRR˸N NN NN NN NN NSN NN NN NM Mi[[M M`[M MN NN NN NN NN NN NQQg/gN NN NN NN NSN NN NN NN NN NM M\a&aM M`UUN NN NN NN Na)aOON NN NN NN NN NN NN NN NN NN NM MiĮʶb(bN NN NN NN NN N'N NN NN NN NN N`kN NN NN NN NN N'N NN NN NN NN NyxN NN NN NN NN N00N NN NN NN NN NN NkkN NN NN NN NN NN NN NN NN NN NN NN Nb(bb(bN NN NN NN NN NN NN NN N5N NN NN NN NN NOOg/gʶʶg/gOON NN NN NN NN NN N5N NN NN NN NN NN NN NN NN NN NN NK KIIIIK KN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN N'N NN NN NN NN NN NN NN NN NN NN NN NN NN NN N'N NN NSN NN NN NN NN NN NN NN NN NSN N??(0` $  N NN N-N NjN NN NN NN NN NN NN NN NN NN NN NjN N-N NN NN N"N NlN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NlN N"N NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NsN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NsN N  N N>N NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN N>N NN NFN NN NN NN NN NN NN NN NN NN NN NM MK KHHGGGGHHK KM MN NN NN NN NN NN NN NN NN NN NN NN NFN NN NrN NN NN NN NN NN NN NN NN NO OuCuxxuCuO ON NN NN NN NN NN NN NN NN NN NrN NN NrN NN NN NN NN NN NN NN N[[c˸˸c[[N NN NN NN NN NN NN NN NN NrN NN NFN NN NN NN NN NN NN NM M{K{{K{M MN NN NN NN NN NN NN NN NFN N>N NN NN NN NN NN NN N`%``%`N NN NN NN NN NN NN NN N>N NN NN NN NN NN NN NN Na'aa'aN NN NN NN NN NN NN NN NN NsN NN NN NN NN NN Na'ab)bN NN NN NN NN NN NN NsN NN NN NN NN NN NN N`%`YYN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NM MDzVVN NN NN NN NN NN NN NN NN NN NN N"N NN NN NN NN NN N{K{Dz^#^N NN NN NN NN NN NN NN NN NN NN N"N NlN NN NN NN NN N[[{J{IIK KN NL LIIN NyVVN NN Nk4kc)cN NN NN NN NN NN NN NN NlN NN NN NN NN NN NN NcQSSN NN NN NN NN NN NN NNN]"]ŰWWN NN Ns?sμZZN NN NN NN NN NN NN NN NN N-N NN NN NN NN NO O˸o:oN NN NN NN NN NN NN NN NN NN NN NK K|]"]N NN Nk5kɶYYN NN NN NN NN NN NN N-N NjN NN NN NN NN NuCuvCvN NN NN NN NN NN NN NN NN NN NN NN NN NL LL LN NN Nr?rμ`'`N NN NN NN NN NN NjN NN NN NN NN NN NxPPN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NtAtϽXXN NN NN NN NN NN NN NN NN NN NM MXXN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN Ni2iɵYYN NN NN NN NN NN NN NN NN NK KM MN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NtAtϽb(bN NN NN NN NN NN NN NN NHH}N NN NN NN NN NN NN NN NN NN NN NN NN NN NN Nr>rͻZZN NN NN NOON NM MM MFFjM MM MM MNNN NN NN NN NN NN NN NN NN NN Nm7mʷ[[N NN N[[ʷm7mN NN NN NN NN NN NN NN NN NN NNNM MM MM MFFM MM MN NOON NN NN NZZμr>rN NN NN NN NN NN NN NN NN NN NN NN NN NN NK KHHN NN NN NN NN NN NN NN Nb(bϽtAtN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NIIK KN NN NN NN NN NN NN NN NN NYYɵi2iN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN N{J{M MN NN NN NN NN NN NN NN NN NN NXXϽtAtN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NSSxN NN NN NN NN NN NN NjN NN NN NN NN N`&`νr?rN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NQuCuN NN NN NN NN NN NjN N-N NN NN NN NN NN NYYɶk5kN NN N]"]iYYN NN NN NN NN NN NN NN NN NN NN NN No:o˸O ON NN NN NN NN NN N-N NN NN NN NN NN NN NN NZZμs?sN NN NWW۬YYN NN NN NN NN NN NN NN NN NPPvCvcN NN NN NN NN NN NN NN NlN NN NN NN NN NN NN Nc)ck4kN NN NVVZK KN NN NN NN NN NM MXX[[N NN NN NN NN NN NlN N"N NN NN NN NN NN NN NN NN NN N^#^Dzufk}{K{N NN NN NN NN NN NN N"N NN NN NN NN NN NN NN NN NN NVVDzM MN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NYY`%`N NN NN NN NN NN NN NN NsN NN NN NN NN NN Nb)ba'aN NN NN NN NN NN NN NsN NN NN NN NN NN NN NN Na'aa'aN NN NN NN NN NN NN NN NN N>N NN NN NN NN NN NN N`%``%`N NN NN NN NN NN NN NN N>  N NFN NN NN NN NN NN NN NM M{K{{K{M MN NN NN NN NN NN NN NN NF  N NN NrN NN NN NN NN NN NN NN N[[c˸˸c[[N NN NN NN NN NN NN NN NN NrN NN NrN NN NN NN NN NN NN NN NN NO OuCuxxuCuO ON NN NN NN NN NN NN NN NN NN NrN NN NFN NN NN NN NN NN NN NN NN NN NN NM MK KHHGGGGHHK KM MN NN NN NN NN NN NN NN NN NN NN NN NFN N  N N>N NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN N>N NN NsN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NsN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN N"N NlN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NN NlN N"N NN NN N-N NjN NN NN NN NN NN NN NN NN NN NN NjN N-N N??onionshare-2.2/install/onionshare.nsi000066400000000000000000000077661355066717400201060ustar00rootroot00000000000000!define APPNAME "OnionShare" !define BINPATH "..\dist\onionshare" !define ABOUTURL "https:\\onionshare.org\" # change these with each release !define INSTALLSIZE 132423 !define VERSIONMAJOR 2 !define VERSIONMINOR 2 !define VERSIONSTRING "2.2" RequestExecutionLevel admin Name "OnionShare" InstallDir "$PROGRAMFILES\${APPNAME}" Icon "onionshare.ico" !include LogicLib.nsh Page directory Page instfiles !macro VerifyUserIsAdmin UserInfo::GetAccountType pop $0 ${If} $0 != "admin" ;Require admin rights on NT4+ messageBox mb_iconstop "Administrator rights required!" setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED quit ${EndIf} !macroend # in order to code sign uninstall.exe, we need to do some hacky stuff outlined # here: http:\\nsis.sourceforge.net\Signing_an_Uninstaller !ifdef INNER !echo "Creating uninstall.exe" OutFile "$%TEMP%\tempinstaller.exe" SetCompress off !else !echo "Creating normal installer" !system "makensis.exe /DINNER onionshare.nsi" = 0 !system "$%TEMP%\tempinstaller.exe" = 2 !system "signtool.exe sign /v /d $\"Uninstall OnionShare$\" /a /tr http://time.certum.pl/ $%TEMP%\uninstall.exe" = 0 # all done, now we can build the real installer OutFile "..\dist\onionshare-setup.exe" SetCompressor /FINAL /SOLID lzma !endif Function .onInit !ifdef INNER WriteUninstaller "$%TEMP%\uninstall.exe" Quit # bail out early !endif setShellVarContext all !insertmacro VerifyUserIsAdmin FunctionEnd Section "install" SetOutPath "$INSTDIR" File "onionshare.ico" File /a /r "${BINPATH}\" # uninstaller !ifndef INNER SetOutPath $INSTDIR File $%TEMP%\uninstall.exe !endif # start menu CreateShortCut "$SMPROGRAMS\${APPNAME}.lnk" "$INSTDIR\onionshare-gui.exe" "" "$INSTDIR\onionshare.ico" # registry information for add\remove programs WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayName" "${APPNAME}" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" \S" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "InstallLocation" "$\"$INSTDIR$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayIcon" "$\"$INSTDIR\onionshare.ico$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "URLInfoAbout" "$\"${ABOUTURL}$\"" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DisplayVersion" ${VERSIONSTRING} WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "VersionMajor" ${VERSIONMAJOR} WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "VersionMinor" ${VERSIONMINOR} # there is no option for modifying or repairing the install WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "NoRepair" 1 # set the INSTALLSIZE constant (!defined at the top of this script) so Add\Remove Programs can accurately report the size WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "EstimatedSize" ${INSTALLSIZE} SectionEnd # uninstaller Function un.onInit SetShellVarContext all #Verify the uninstaller - last chance to back out MessageBox MB_OKCANCEL "Uninstall ${APPNAME}?" IDOK next Abort next: !insertmacro VerifyUserIsAdmin FunctionEnd !ifdef INNER Section "uninstall" Delete "$SMPROGRAMS\${APPNAME}.lnk" # remove files RMDir /r $INSTDIR # remove uninstaller information from the registry DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" SectionEnd !endif onionshare-2.2/install/onionshare80.xpm000066400000000000000000000371241355066717400202600ustar00rootroot00000000000000/* XPM */ static char * icon_xpm[] = { "80 80 174 2", " c None", ". c #4E0D4E", "+ c #531453", "@ c #581B58", "# c #673067", "$ c #906890", "% c #B397B3", "& c #CFBECF", "* c #E0D5E0", "= c #F0EBF0", "- c #FCFCFC", "; c #4F0E4F", "> c #6E396E", ", c #8F668F", "' c #C1AAC1", ") c #EFE9EF", "! c #FFFFFF", "~ c #865986", "{ c #C5B0C5", "] c #EAE2EA", "^ c #764476", "/ c #DFD4DF", "( c #FAF9FA", "_ c #5E235E", ": c #BDA5BD", "< c #885C88", "[ c #E8DFE8", "} c #521352", "| c #B89EB8", "1 c #FCFBFC", "2 c #5B1F5B", "3 c #4D0C4D", "4 c #571A57", "5 c #5D225D", "6 c #D8C9D8", "7 c #612761", "8 c #D4C4D4", "9 c #D4C5D4", "0 c #4E0C4E", "a c #632A63", "b c #DDD1DD", "c c #693269", "d c #DED3DE", "e c #FDFCFD", "f c #F6F3F6", "g c #D7C9D7", "h c #A482A4", "i c #7E4E7E", "j c #652D65", "k c #521252", "l c #490649", "m c #4B094B", "n c #662E66", "o c #D9CCD9", "p c #DCD0DC", "q c #A584A5", "r c #622862", "s c #440044", "t c #470447", "u c #4A084A", "v c #4C0A4C", "w c #825482", "x c #6F3A6F", "y c #4D0B4D", "z c #642B64", "A c #DBCFDB", "B c #F7F3F7", "C c #9B779B", "D c #835683", "E c #E5DBE5", "F c #E4DAE4", "G c #E8E0E8", "H c #713C71", "I c #4C0B4C", "J c #8C628C", "K c #E2D9E2", "L c #672F67", "M c #6D386D", "N c #E7DFE7", "O c #622962", "P c #926A92", "Q c #FAF8FA", "R c #E2D7E2", "S c #6C376C", "T c #4A074A", "U c #6B346B", "V c #CCBACC", "W c #875C87", "X c #F9F7F9", "Y c #7B4C7B", "Z c #DED4DE", "` c #5B1E5B", " . c #855885", ".. c #DDD2DD", "+. c #895E89", "@. c #DBCEDB", "#. c #4B084B", "$. c #7F507F", "%. c #F7F4F7", "&. c #5F245F", "*. c #764576", "=. c #551755", "-. c #FEFEFE", ";. c #D7CAD7", ">. c #5C205C", ",. c #815381", "'. c #F3EEF3", "). c #774577", "!. c #F4F0F4", "~. c #D3C3D3", "{. c #591C59", "]. c #703C70", "^. c #FEFDFE", "/. c #D3C4D3", "(. c #511051", "_. c #501150", ":. c #B093B0", "<. c #B59AB5", "[. c #FDFDFD", "}. c #B79CB7", "|. c #B599B5", "1. c #895F89", "2. c #734073", "3. c #987298", "4. c #9A759A", "5. c #8A608A", "6. c #511251", "7. c #602660", "8. c #CEBCCE", "9. c #F1ECF1", "0. c #855985", "a. c #5E225E", "b. c #784778", "c. c #DED1DE", "d. c #F3EFF3", "e. c #7F517F", "f. c #F5F1F5", "g. c #470347", "h. c #5D215D", "i. c #F3F0F3", "j. c #865B86", "k. c #450145", "l. c #D6C7D6", "m. c #F4F1F4", "n. c #805280", "o. c #E6DCE6", "p. c #885D88", "q. c #5C215C", "r. c #E6DDE6", "s. c #F8F6F8", "t. c #936C93", "u. c #460246", "v. c #DACDDA", "w. c #F6F4F6", "x. c #8E658E", "y. c #450045", "z. c #5E245E", "A. c #642C64", "B. c #DED2DE", "C. c #F7F5F7", "D. c #EEE7EE", "E. c #EDE6ED", "F. c #916991", "G. c #ECE5EC", "H. c #FBF9FB", "I. c #6A336A", "J. c #662F66", "K. c #FBFAFB", "L. c #956F95", "M. c #E9E1E9", "N. c #DACCDA", "O. c #541654", "P. c #BAA1BA", "Q. c #4E0E4E", " . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . + @ # $ % & * = - - = * & % $ # @ + . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . ; > , ' ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) ' , > ; . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . ~ { ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] { ~ . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . ^ / ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( / ^ . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : _ . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . < [ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! [ < . . . . . . . . . . . . . . ", " . . . . . . . . . . . . } | 1 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 1 | } . . . . . . . . . . . . ", " . . . . . . . . . . . . 2 & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! & 2 . . . . . . . . . . . . ", " . . . . . . . . . . . . 2 & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! & 2 . . . . . . . . . . . . ", " . . . . . . . . . 3 3 4 & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! & 2 . . . . . . . . . . . ", " . . . . . . . . . . . . 5 6 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! & } . . . . . . . . . . . ", " . . . . . . . . . . . . . 7 8 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! | . . . . . . . . . . . ", " . . . . . . . . . . . . . . . _ 9 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 1 < . . . . . . . . . . . ", " . . . . . . . 3 0 . . . . . . . a b ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! [ _ . . . . . . . . . . ", " . . . . . . . . 0 . . . . . . . . . c d ! ! ! ! ! ! ! ! ! ! e f g h i j k k j i h g f e ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : . . . . . . . . . . . ", " . . . . . . . . . . . . . l m . . . . n o ! ! ! ! ! ! ! ! p q r s t u v . . v u t s r q p ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ^ . . . . . . . . . . ", " . . . . . . . . . . . . . 3 w x y . . . . z A ! ! ! ! ! B C 7 t v . . . . . . . . . . v t 7 C B ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! / . . . . . . . . . . . ", " . . . . . 3 0 . . . . . y D ! E 7 3 . . . . c F ! ! ! G H ; 3 . . . . . . . . . . . . . . 3 ; H G ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( ~ . . . . . . . . . . ", " . . . . . 0 . . . . 3 I J ! ! ! K L l . . . . M E ! N O u . . . . . . . . . . . . . . . . . . u O N ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! { ; . . . . . . . . . ", " . . . . . . . . . . I P Q ! ! ! ! R S T . . . . U V O l . . . . . . . . . . . . . . . . . . . . l O G ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] > . . . . . . . . . ", " . . . . 0 . . . . . v W X ! ! ! ! ! ! / j 3 . . . . + u . . . . . . . . . . . . . . . . . . . . . . u H B ! ! ! ! ! ! ! ! ! ! ! ! ! ! , . . . . . . . . . . ", " . . . 0 . . . . . v Y ! ! ! ! ! ! ! ! ! Z ` 0 . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . ; C ! ! ! ! ! ! ! ! ! ! ! ! ! ! ' + . . . . . . . . . ", " . . 0 . . . . 0 I .! ! ! ! ! ! ! ! ! ! ! ..7 u . . . . . 3 . . . . . . . . . . . . . . . . . . . . . 3 7 p ! ! ! ! ! ! ! ! ! ! ! ! ! ) @ . . . . . . . . . ", " . . . . . . . v +.B ! ! ! ! ! ! ! ! ! ! ! ! @.L #.. . . . . 3 . . . . . . . . . . . . . . . . . . . . . t q e ! ! ! ! ! ! ! ! ! ! ! ! ! # . . . . . . . . . ", ". 0 . . . . . m $.%.! ! ! ! ! ! ! ! ! ! ! ! ! ! o &.. . . . . . 3 . . . . . . . . . . . . . . . . . . . . v r f ! ! ! ! ! ! ! ! ! ! ! ! ! $ . . . . . . . . . . ", "3 . . . . . m *.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! o =.. . . . . . 3 . . . . . . . . . . . . . . . . . . . . s g ! ! ! ! ! ! ! ! ! ! ! ! ! % . . . . . . . . . . ", ". . . . . v i -.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ;.>.m . . . . 3 3 . . . . . . . . . . . . . . . . . . . t h ! ! ! ! ! ! ! ! ! ! ! ! ! & . . . . . . . . . . ", ". . . . v ,.'.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 9 r v . . . . . 3 . . . . . . . . . . . . . . . . . . u i ! ! ! ! ! ! ! ! ! ! ! ! ! * . . . . . . . . . . ", ". . . u ).!.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ~.{.. . . . . . 3 . . . . . . . . . . . . . . . . . v j ! ! ! ! ! ! ! ! ! ! ! ! ! = . . . . . . . . . . ", ". . m ].^.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! /.(.. . . . . . 3 . . . . . . . . . . . . . . . . . k ! ! ! ! ! ! ! ! ! ! ! ! ! - . . . . . . . . . . ", ". y _.:.<.<.<.<.<.<.[.! ! ! ! ! ! ! ! ! ! ! ! ! }.<.<.<.|.<.1.l . . . . . 3 . . . . 3 . . . . . m 2.3.3.3.3.3.4.! ! ! ! ! ! ! ! ! ! ! ! ! [.3.3.3.3.3.3.5.6.3 . ", ". . . . . . . . . . = ! ! ! ! ! ! ! ! ! ! ! ! ! j v . . . . . . . . . . . . . . . . 3 . . . . . y 7.8.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 9.0.#.. . ", ". . . . . . . . . . * ! ! ! ! ! ! ! ! ! ! ! ! ! i u . . . . . . . . . . . . . . . . . 3 . . . . . 3 a.8.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 9.b.m . . . ", ". . . . . . . . . . & ! ! ! ! ! ! ! ! ! ! ! ! ! h t . . . . . . . . . . . . . . . . . . 3 . . . . . 3 2 c.! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! d.e.3 . . . . ", ". . . . . . . . . . % ! ! ! ! ! ! ! ! ! ! ! ! ! g s . . . . . . . . . . . . . . . . . . . 3 . . . . . m {./ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! f.5.g.. . . . . ", ". . . . . . . . . . $ ! ! ! ! ! ! ! ! ! ! ! ! ! f r v . . . . . . . . . . . . . . . . . . . 3 . . . . . m h.8 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! i.j.k.. . . . . 0 ", " . . . . . . . . . # ! ! ! ! ! ! ! ! ! ! ! ! ! e q t . . . . . . . . . . . . . . . . . . . . 3 . . . . . y r l.! ! ! ! ! ! ! ! ! ! ! ! ! ! m.n.m . . . . . 3 ", " . . . . . . . . . @ ) ! ! ! ! ! ! ! ! ! ! ! ! ! p 7 3 . . . . . . . . . . . . . . . . . . . . 3 . . . . . y &.o.! ! ! ! ! ! ! ! ! ! ! ! %.p.y . . . . . 3 . ", " . . . . . . . . . + ' ! ! ! ! ! ! ! ! ! ! ! ! ! ! C ; . . . . . . . . . . . . . . . . . . . . . 3 . . . . . #.q.r.! ! ! ! ! ! ! ! ! ! s.t.u.. . . . . 3 . . ", " . . . . . . . . . . , ! ! ! ! ! ! ! ! ! ! ! ! ! ! B H u . . . . . . . . . . . . . . . . . . . . . 3 3 . . . . #.7 v.! ! ! ! ! ! ! ! w.x.y.. . . . . 3 . . . ", " . . . . . . . . . > ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! G O l . . . . . . . . . . . . . . . . . . . . l z.A.. . . . y L B.! ! ! ! ! ! C.+.v . . . . . 3 . . . ", " . . . . . . . . . ; { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! N O u . . . . . . . . . . . . . . . . . . u O N D.h.. . . . y O E.! ! ! ! ( F.y . . . . . 3 . . . . ", " . . . . . . . . . . ~ ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! G H ; 3 . . . . . . . . . . . . . . 3 ; H G ! ! D.a . . . . u 7.G.! ! H.C k.. . . . . 3 . . . . . ", " . . . . . . . . . . . / ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! B C 7 t v . . . . . . . . . . v t 7 C B ! ! ! ! R I.. . . . #.J.R K.L.y.. . . . . 3 . . . . . . ", " . . . . . . . . . . ^ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! p q r s t u v . . v u t s r q p ! ! ! ! ! ! ! * 7 . . . . y x n.y . . . . . 3 . . . . . . ", " . . . . . . . . . . . : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! e f g h i j k k j i h g f e ! ! ! ! ! ! ! ! ! M.@ . . . . . . . . . . . 3 . . . . . . . ", " . . . . . . . . . . _ [ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! G _ . . . . . . . . . 3 . . . . . . . ", " . . . . . . . . . . . < 1 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! @.A.. . . . . . . 3 . . . . . . . . ", " . . . . . . . . . . . | ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! N.2 . . . . . 3 3 . . . . . . . ", " . . . . . . . . . . . } & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! F O.. . . 3 . . . . . . . . . ", " . . . . . . . . . . . 2 & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! P.Q.. 3 . . . . . . . . . ", " . . . . . . . . . . . . 2 & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! & 2 0 3 . . . . . . . . . . ", " . . . . . . . . . . . . 2 & ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! & 2 . . . . . . . . . . . . ", " . . . . . . . . . . . . } | 1 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! 1 | } . . . . . . . . . . . . ", " . . . . . . . . . . . . . . < [ ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! [ < . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . _ : ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! : _ . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . ^ / ( ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ( / ^ . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . ~ { ] ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ] { ~ . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . ; > , ' ) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ) ' , > ; . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . + @ # $ % & * = - - = * & % $ # @ + . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . . . . . . . . . ", " . . . . . . . . . . . . "}; onionshare-2.2/install/org.onionshare.OnionShare.appdata.xml000066400000000000000000000057441355066717400243520ustar00rootroot00000000000000 org.onionshare.OnionShare CC0-1.0 GPL-3.0 OnionShare Securely and anonymously share a file of any size

OnionShare lets you securely and anonymously send and receive files. It works by starting a web server, making it accessible as a Tor onion service, and generating an unguessable web address so others can download files from you, or upload files to you. It does not require setting up a separate server or using a third party file-sharing service.

If you want to send files to someone, OnionShare hosts them on your own computer and uses a Tor onion service to make them temporarily accessible over the internet. The receiving user just needs to open the web address in Tor Browser to download the files. If you want to receive files, OnionShare hosts an anonymous dropbox directly on your computer and uses a Tor onion service to make it temporarily accessible over the internet. Other users can upload files to you from by loading the web address in Tor Browser.

org.onionshare.OnionShare.desktop https://raw.githubusercontent.com/micahflee/onionshare/master/screenshots/appdata-onionshare-share-server.png Sharing files with OnionShare https://raw.githubusercontent.com/micahflee/onionshare/master/screenshots/appdata-onionshare-share-client.png Downloading OnionShare files using Tor Browser https://raw.githubusercontent.com/micahflee/onionshare/master/screenshots/appdata-onionshare-receive-server.png Receiving files with OnionShare https://raw.githubusercontent.com/micahflee/onionshare/master/screenshots/appdata-onionshare-receive-client.png Uploading files to OnionShare user using Tor Browser https://github.com/micahflee/onionshare/issues/ https://github.com/micahflee/onionshare/wiki/ https://onionshare.org/ Micah Lee micah@micahflee.com
onionshare-2.2/install/org.onionshare.OnionShare.desktop000066400000000000000000000011741355066717400236030ustar00rootroot00000000000000[Desktop Entry] Name=OnionShare GenericName=OnionShare Client Comment=Share a file securely and anonymously over Tor Comment[da]=Del en fil sikkert og anonymt over Tor Comment[de]=Teile Dateien sicher und anonym über das Tor-Netzwerk Exec=/usr/bin/onionshare-gui Terminal=false Type=Application Icon=org.onionshare.OnionShare Categories=Network;FileTransfer; Keywords=tor;anonymity;privacy;onion service;file sharing;file hosting; Keywords[da]=tor;anonymitet;privatliv;onion-tjeneste;fildeling;filhosting; Keywords[de]=tor;Anonymität;Privatsphäre;Onion-Service;File-Sharing;File-Hosting; StartupNotify=true StartupWMClass=onionshare onionshare-2.2/install/org.onionshare.OnionShare.svg000066400000000000000000004716551355066717400227500ustar00rootroot00000000000000 ]> eJzsvfuSHEd25vkE8Q65f8ise226FOGX8IjesTWrq7bX1FJbtzQj2dgYDSKhFkYkQAPB1vQ+/X6/ 73hkRlZlAaDIJns0qCBAVIZnXNyPn+t3zvmL/+M3v/vF9Rdv/unlL/LVeBj+4i9u37588e7N218e /OnhV19++e03797y0c9++/PD1K5GDbr+1fJZH/hfXr795tWb1788JF3gatLJB779s7sXr1//8XD3 7ddfvvyfPz/87Oc68Xev3n35Uqe+fPP7N1ff/OH3P99up+/fvXinU+kv619O62H9ZZ0Pv/k1p1+8 /sOLb7559f/p5DTnJeuzmzffvv7i1evf37z5n788/GJKtR1SG9vhFymnQ245acz/8+q3L795MnC+ WnLNKbV5rtVfuirLlKa2lnVOvsBuRFm42rQfoivfvfn8269evn73m7dvPn/5zTe3b7588/abXx5u //ji9eHXL36vMy8O//jyyy/f/Nvh5ssXn//roMmqnz28+vKl5uWrF+8OU2YKr381pc9uvn315Rd/ 8+1X//RSM1aLP86f+ZJ//42upcvybz5un/3qK33yu5fv3umNdEOW4bd/dbN/DH3o42f/7bcvf//K q6aZ/e8/75d9++brr168/ddvfrC54Kp/9/Krr7/U2nmOUx2vqr7q/+1/6WM1CX0tppTO77+eX/zw i7ws+/uvh1zPHzGueVqOl3949fLffnn4mzevX8acX79997sgnFLGMf6OM7/99suXb//+9at3mouZ j9aY9F+/+eLllxp//P7Dly881z6m098x4O9evP39y3citDdffvvOe2DZ7qBF/esXf3wJZUxxg7/9 +uXrv3vzX/yMv0hzmq7mluuyLlNu66GUMl3lrF+WlEtdDuOVJq6uVTS/lDavIpt1PkzjNB2mxQ+h QVMaj882Hf/uj8ANud32HE0E8xuR0N++ffX7V69/OXmSawni+qu3r7440daUdO15+5/vcFWnlZ9l XNNcp/KRn7TqT9axzJmN+hGfxHRp5t+9e/m6T5/2yu2vd7Q/Xv36d3qd+9df3L75iuX/Br4gon+t /SD2EueO//YZff3br2Nq/PtnopTfvH31mmsOf+Mzy2e/+fJbnfqrt2++/fpXr//5zfCz4IL/5eXn YnUipi8Of/tP/0O/iKN5Px7+7u2Lz3UB/X4cc/Xi1dc/f+/l9HJvXx7ipL7pX7f/f/jbdy//WZzk 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 dcuLY5p+87ef3xz5XW9tzT8H354c+Wu/ODv85n8f/ey/yc3it18dHZzc8KvfHb/+5suj88Oj04u1 9rc948vzox+Pj36yR5y8ndj0q7Of3t46bmsvYW99fPR29Q6kOEOaBukssd9be/C3Y+vzfx6/vPi+ PoakKtX7BIzE8v4f/s+j4+++v7jrBV8cvbr4xlbEH87PTu9s/LezN1faXlkJv3/2q8//1H7z+9OX 9Zd8znz+5i9np1/aUr6w1by355efH31nd1v74tlf3vBN7988P3/39vvxPr/+y9FPi/phMTS/edYs Prf//8dPz5TT8e5ZWHz+5pkKsvW///jZPvwv++P/2aWfFmnx58X/+b/N4iW/+erZHkHUhf7zevkB TlFg315whQ9U9dx62X7yYv0+L56d8iq8w1fPAIyE5ybZQU38j2JhcuNJMU7CEiJfhOATuXMgEqlw fF+kVLFLKo3LtGnXUdjNWFUy4HriyaLZr5XnNfmkXfzj85t74F1VGXu+1LGvr7QfPIHuavt6ubZf fRG7fRksry/fZrx87f5QoZLAeOX+4+Vr9xcVeLx2//Ey7f/u68YW2qVVM2kxhSmLKbx3MVGhTIKv 3hqU5uW71suEIAlXv6g9y7dcG3/+4ua7bt8iS/vYlGu9UcejaLKHq51sVXqd1i57z+GL9AVQTK1Z rIajVdotJvWlIcprawrORm4oc7+/9vh6WY9Hh8R0W13mnVilmXeK2bNQL10ETjwJDO3S5dWEXHkP yrMp3r3yHuNlfw98nsN6a+5NWcdAVi96C7Rgly5efo/l5dvfA+V+3DNr71Ev+3tk9P31yz5I2uX6 C6qdyxcvvcfq8pX3iCsxub4fVpfH27y4chmGyKBlEWXjp/oeQWO01g+/9sWVTvvVDxAIfz89PXh9 9HKhq4iGRXtdKtx6uoTm/ccLZmJRxSm7ae3wuPbFeAEkiH7tgLnt+urg8Re0f/5rO4SDCUkt1Z4s c4AYMinYywuZIGpX9wll430IHTytpbveqK6q6/fKAiZzWNR0270uNxp3ytVm7DpKMZ1+8vWNz7vc 5ta38sLpDpLe2N32Vpcb3fpWUEoVnghq0G2vdbkR92JFvm+BkaVUzF5/fXWFjV+c3Lxum0vzcnOj a3f6/tl/2hr9/56NWuIWLlMBF1AjAstF/55leqlRnS6KvUlmGCdR9QfFmhEmvu1eVw== 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 onionshare-2.2/install/ppa_release.sh000077500000000000000000000010651355066717400200270ustar00rootroot00000000000000#!/bin/bash # This script pushes updates to my Ubuntu PPA: https://launchpad.net/~micahflee/+archive/ppa # If you want to use it, you'll need your own ~/.dput.cf and ssh key. # More info: https://help.launchpad.net/Packaging/PPA/Uploading DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR VERSION=`cat share/version.txt` rm -rf deb_dist >/dev/null 2>&1 python3 setup.py --command-packages=stdeb.command sdist_dsc cd deb_dist/onionshare-$VERSION dpkg-buildpackage -S cd .. dput ppa:micahflee/ppa onionshare_$VERSION-1_source.changes cd .. onionshare-2.2/install/pyinstaller.spec000066400000000000000000000031771355066717400204400ustar00rootroot00000000000000# -*- mode: python -*- import platform p = platform.system() version = open('share/version.txt').read().strip() a = Analysis( ['scripts/onionshare-pyinstaller'], pathex=['.'], binaries=None, datas=[ ('../share/version.txt', 'share'), ('../share/wordlist.txt', 'share'), ('../share/torrc_template', 'share'), ('../share/torrc_template-obfs4', 'share'), ('../share/torrc_template-meek_lite_azure', 'share'), ('../share/images/*', 'share/images'), ('../share/locale/*', 'share/locale'), ('../share/static/*', 'share/static'), ('../share/templates/*', 'share/templates'), ('../share/static/css/*', 'share/static/css'), ('../share/static/img/*', 'share/static/img'), ('../share/static/js/*', 'share/static/js'), ('../install/licenses/*', 'licenses') ], hiddenimports=[], hookspath=[], runtime_hooks=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=None) pyz = PYZ( a.pure, a.zipped_data, cipher=None) exe = EXE( pyz, a.scripts, exclude_binaries=True, name='onionshare-gui', debug=False, strip=False, upx=True, console=False) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, name='onionshare') if p == 'Darwin': app = BUNDLE( coll, name='OnionShare.app', icon='onionshare.icns', bundle_identifier='com.micahflee.onionshare', info_plist={ 'CFBundleShortVersionString': version, 'NSHighResolutionCapable': 'True' } ) onionshare-2.2/install/requirements-tests.txt000066400000000000000000000002461355066717400216340ustar00rootroot00000000000000atomicwrites==1.3.0 attrs==19.1.0 more-itertools==7.2.0 pluggy==0.13.0 py==1.8.0 pytest==5.1.2 pytest-faulthandler==2.0.1 pytest-qt==3.2.2 six==1.12.0 urllib3==1.25.3onionshare-2.2/install/requirements.txt000066400000000000000000000005431355066717400204740ustar00rootroot00000000000000altgraph==0.16.1 certifi==2019.9.11 chardet==3.0.4 Click==7.0 Flask==1.1.1 Flask-HTTPAuth==3.3.0 future==0.17.1 idna==2.8 itsdangerous==1.1.0 Jinja2==2.10.1 macholib==1.11 MarkupSafe==1.1.1 pefile==2019.4.18 pycryptodome==3.9.0 PyInstaller==3.5 PyQt5==5.13.1 PyQt5-sip==4.19.19 PySocks==1.7.0 requests==2.22.0 stem==1.7.1 urllib3==1.25.3 Werkzeug==0.15.6 onionshare-2.2/install/scripts/000077500000000000000000000000001355066717400166755ustar00rootroot00000000000000onionshare-2.2/install/scripts/onionshare000077500000000000000000000014361355066717400207740ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import onionshare onionshare.main() onionshare-2.2/install/scripts/onionshare-gui000077500000000000000000000014461355066717400215570ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import onionshare_gui onionshare_gui.main() onionshare-2.2/install/scripts/onionshare-nautilus.py000066400000000000000000000072011355066717400232560ustar00rootroot00000000000000import os import sys import json import locale import subprocess import urllib import gi gi.require_version("Nautilus", "3.0") from gi.repository import Nautilus from gi.repository import GObject # Put me in /usr/share/nautilus-python/extensions/ class OnionShareExtension(GObject.GObject, Nautilus.MenuProvider): def __init__(self): # Get the localized string for "Share via OnionShare" label self.label = None default_label = "Share via OnionShare" try: # Re-implement localization in python2 default_locale = "en" locale_dir = os.path.join(sys.prefix, "share/onionshare/locale") if os.path.exists(locale_dir): # Load all translations strings = {} translations = {} for filename in os.listdir(locale_dir): abs_filename = os.path.join(locale_dir, filename) lang, ext = os.path.splitext(filename) if ext == ".json": with open(abs_filename) as f: translations[lang] = json.load(f) strings = translations[default_locale] lc, enc = locale.getdefaultlocale() if lc: lang = lc[:2] if lang in translations: # if a string doesn't exist, fallback to English for key in translations[default_locale]: if key in translations[lang]: strings[key] = translations[lang][key] self.label = strings["share_via_onionshare"] except: self.label = default_label if not self.label: self.label = default_label """ # This more elegant solution will only work if nautilus is using python3, and onionshare is installed system-wide. # But nautilus is using python2, so this is commented out. try: import onionshare onionshare.strings.load_strings(onionshare.common) self.label = onionshare.strings._('share_via_onionshare') except: import sys print('python version: {}').format(sys.version) self.label = 'Share via OnionShare' """ def url2path(self, url): file_uri = url.get_activation_uri() arg_uri = file_uri[7:] path = urllib.url2pathname(arg_uri) return path def exec_onionshare(self, filenames): # Would prefer this method but there is a conflict between GTK 2.0 vs GTK 3.0 components being loaded at once # (nautilus:3090): Gtk-ERROR **: GTK+ 2.x symbols detected. Using GTK+ 2.x and GTK+ 3 in the same process is not supported # sys.argv = ["", "--filenames"] + filenames # sys.exit(onionshare_gui.main()) path = os.path.join(os.sep, "usr", "bin", "onionshare-gui") cmd = [path, "--filenames"] + filenames subprocess.Popen(cmd) def get_file_items(self, window, files): menuitem = Nautilus.MenuItem( name="OnionShare::Nautilus", label=self.label, tip="", icon="" ) menu = Nautilus.Menu() menu.append_item(menuitem) menuitem.connect("activate", self.menu_activate_cb, files) return (menuitem,) def menu_activate_cb(self, menu, files): file_list = [] for file in files: file_list.append(self.url2path(file)) self.exec_onionshare(file_list) # Workaround https://bugzilla.gnome.org/show_bug.cgi?id=784278 def get_background_items(self, window, file): return None onionshare-2.2/install/scripts/onionshare-pyinstaller000066400000000000000000000031261355066717400233330ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import sys, os, platform # In macOS, allow both CLI and GUI depending on the filename of the binary # being executed if platform.system() == 'Darwin': # If the binary being executed is called 'onionshare', use CLI basename = os.path.basename(sys.argv[0]) if basename == 'onionshare': import onionshare onionshare.main() # Otherwise, use GUI else: import onionshare_gui onionshare_gui.main() # Unfortunately this trick won't work in Windows because I want to set # console=False in the PyInstaller spec file, so there isn't a command prompt # open in the background every you run the GUI. Hopefully Windows can get # a built-in CLI when PyInstaller 3.3 comes out: # https://pyinstaller.readthedocs.io/en/stable/spec-files.html#multipackage-bundles else: import onionshare_gui onionshare_gui.main() onionshare-2.2/onionshare/000077500000000000000000000000001355066717400157055ustar00rootroot00000000000000onionshare-2.2/onionshare/__init__.py000066400000000000000000000320571355066717400200250ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import os, sys, time, argparse, threading from datetime import datetime from datetime import timedelta from .common import Common from .web import Web from .onion import * from .onionshare import OnionShare def build_url(common, app, web): # Build the URL if common.settings.get("public_mode"): return "http://{0:s}".format(app.onion_host) else: return "http://onionshare:{0:s}@{1:s}".format(web.password, app.onion_host) def main(cwd=None): """ The main() function implements all of the logic that the command-line version of onionshare uses. """ common = Common() # Display OnionShare banner print("OnionShare {0:s} | https://onionshare.org/".format(common.version)) # OnionShare CLI in OSX needs to change current working directory (#132) if common.platform == "Darwin": if cwd: os.chdir(cwd) # Parse arguments parser = argparse.ArgumentParser( formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=28) ) parser.add_argument( "--local-only", action="store_true", dest="local_only", help="Don't use Tor (only for development)", ) parser.add_argument( "--stay-open", action="store_true", dest="stay_open", help="Continue sharing after files have been sent", ) parser.add_argument( "--auto-start-timer", metavar="", dest="autostart_timer", default=0, help="Schedule this share to start N seconds from now", ) parser.add_argument( "--auto-stop-timer", metavar="", dest="autostop_timer", default=0, help="Stop sharing after a given amount of seconds", ) parser.add_argument( "--connect-timeout", metavar="", dest="connect_timeout", default=120, help="Give up connecting to Tor after a given amount of seconds (default: 120)", ) parser.add_argument( "--stealth", action="store_true", dest="stealth", help="Use client authorization (advanced)", ) parser.add_argument( "--receive", action="store_true", dest="receive", help="Receive shares instead of sending them", ) parser.add_argument( "--website", action="store_true", dest="website", help="Publish a static website", ) parser.add_argument( "--config", metavar="config", default=False, help="Custom JSON config file location (optional)", ) parser.add_argument( "-v", "--verbose", action="store_true", dest="verbose", help="Log OnionShare errors to stdout, and web errors to disk", ) parser.add_argument( "filename", metavar="filename", nargs="*", help="List of files or folders to share", ) args = parser.parse_args() filenames = args.filename for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) local_only = bool(args.local_only) verbose = bool(args.verbose) stay_open = bool(args.stay_open) autostart_timer = int(args.autostart_timer) autostop_timer = int(args.autostop_timer) connect_timeout = int(args.connect_timeout) stealth = bool(args.stealth) receive = bool(args.receive) website = bool(args.website) config = args.config if receive: mode = "receive" elif website: mode = "website" else: mode = "share" # In share an website mode, you must supply a list of filenames if mode == "share" or mode == "website": # Make sure filenames given if not using receiver mode if len(filenames) == 0: parser.print_help() sys.exit() # Validate filenames valid = True for filename in filenames: if not os.path.isfile(filename) and not os.path.isdir(filename): print("{0:s} is not a valid file.".format(filename)) valid = False if not os.access(filename, os.R_OK): print("{0:s} is not a readable file.".format(filename)) valid = False if not valid: sys.exit() # Re-load settings, if a custom config was passed in if config: common.load_settings(config) else: common.load_settings() # Verbose mode? common.verbose = verbose # Create the Web object web = Web(common, False, mode) # Start the Onion object onion = Onion(common) try: onion.connect( custom_settings=False, config=config, connect_timeout=connect_timeout ) except KeyboardInterrupt: print("") sys.exit() except Exception as e: sys.exit(e.args[0]) # Start the onionshare app try: common.settings.load() if not common.settings.get("public_mode"): web.generate_password(common.settings.get("password")) else: web.password = None app = OnionShare(common, onion, local_only, autostop_timer) app.set_stealth(stealth) app.choose_port() # Delay the startup if a startup timer was set if autostart_timer > 0: # Can't set a schedule that is later than the auto-stop timer if app.autostop_timer > 0 and app.autostop_timer < autostart_timer: print( "The auto-stop time can't be the same or earlier than the auto-start time. Please update it to start sharing." ) sys.exit() app.start_onion_service(False, True) url = build_url(common, app, web) schedule = datetime.now() + timedelta(seconds=autostart_timer) if mode == "receive": print( "Files sent to you appear in this folder: {}".format( common.settings.get("data_dir") ) ) print("") print( "Warning: Receive mode lets people upload files to your computer. Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing." ) print("") if stealth: print( "Give this address and HidServAuth lineto your sender, and tell them it won't be accessible until: {}".format( schedule.strftime("%I:%M:%S%p, %b %d, %y") ) ) print(app.auth_string) else: print( "Give this address to your sender, and tell them it won't be accessible until: {}".format( schedule.strftime("%I:%M:%S%p, %b %d, %y") ) ) else: if stealth: print( "Give this address and HidServAuth line to your recipient, and tell them it won't be accessible until: {}".format( schedule.strftime("%I:%M:%S%p, %b %d, %y") ) ) print(app.auth_string) else: print( "Give this address to your recipient, and tell them it won't be accessible until: {}".format( schedule.strftime("%I:%M:%S%p, %b %d, %y") ) ) print(url) print("") print("Waiting for the scheduled time before starting...") app.onion.cleanup(False) time.sleep(autostart_timer) app.start_onion_service() else: app.start_onion_service() except KeyboardInterrupt: print("") sys.exit() except (TorTooOld, TorErrorProtocolError) as e: print("") print(e.args[0]) sys.exit() if mode == "website": # Prepare files to share try: web.website_mode.set_file_info(filenames) except OSError as e: print(e.strerror) sys.exit(1) if mode == "share": # Prepare files to share print("Compressing files.") try: web.share_mode.set_file_info(filenames) app.cleanup_filenames += web.share_mode.cleanup_filenames except OSError as e: print(e.strerror) sys.exit(1) # Warn about sending large files over Tor if web.share_mode.download_filesize >= 157286400: # 150mb print("") print("Warning: Sending a large share could take hours") print("") # Start OnionShare http service in new thread t = threading.Thread( target=web.start, args=(app.port, stay_open, common.settings.get("public_mode"), web.password), ) t.daemon = True t.start() try: # Trap Ctrl-C # Wait for web.generate_password() to finish running time.sleep(0.2) # start auto-stop timer thread if app.autostop_timer > 0: app.autostop_timer_thread.start() # Save the web password if we are using a persistent private key if common.settings.get("save_private_key"): if not common.settings.get("password"): common.settings.set("password", web.password) common.settings.save() # Build the URL url = build_url(common, app, web) print("") if autostart_timer > 0: print("Server started") else: if mode == "receive": print( "Files sent to you appear in this folder: {}".format( common.settings.get("data_dir") ) ) print("") print( "Warning: Receive mode lets people upload files to your computer. Some files can potentially take control of your computer if you open them. Only open things from people you trust, or if you know what you are doing." ) print("") if stealth: print("Give this address and HidServAuth to the sender:") print(url) print(app.auth_string) else: print("Give this address to the sender:") print(url) else: if stealth: print("Give this address and HidServAuth line to the recipient:") print(url) print(app.auth_string) else: print("Give this address to the recipient:") print(url) print("") print("Press Ctrl+C to stop the server") # Wait for app to close while t.is_alive(): if app.autostop_timer > 0: # if the auto-stop timer was set and has run out, stop the server if not app.autostop_timer_thread.is_alive(): if mode == "share" or (mode == "website"): # If there were no attempts to download the share, or all downloads are done, we can stop if web.share_mode.cur_history_id == 0 or web.done: print("Stopped because auto-stop timer ran out") web.stop(app.port) break if mode == "receive": if ( web.receive_mode.cur_history_id == 0 or not web.receive_mode.uploads_in_progress ): print("Stopped because auto-stop timer ran out") web.stop(app.port) break else: web.receive_mode.can_upload = False # Allow KeyboardInterrupt exception to be handled with threads # https://stackoverflow.com/questions/3788208/python-threading-ignores-keyboardinterrupt-exception time.sleep(0.2) except KeyboardInterrupt: web.stop(app.port) finally: # Shutdown app.cleanup() onion.cleanup() if __name__ == "__main__": main() onionshare-2.2/onionshare/common.py000066400000000000000000000435441355066717400175610ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import base64 import hashlib import inspect import os import platform import random import socket import sys import tempfile import threading import time from .settings import Settings class Common(object): """ The Common object is shared amongst all parts of OnionShare. """ def __init__(self, verbose=False): self.verbose = verbose # The platform OnionShare is running on self.platform = platform.system() if self.platform.endswith("BSD") or self.platform == "DragonFly": self.platform = "BSD" # The current version of OnionShare with open(self.get_resource_path("version.txt")) as f: self.version = f.read().strip() def load_settings(self, config=None): """ Loading settings, optionally from a custom config json file. """ self.settings = Settings(self, config) self.settings.load() def log(self, module, func, msg=None): """ If verbose mode is on, log error messages to stdout """ if self.verbose: timestamp = time.strftime("%b %d %Y %X") final_msg = "[{}] {}.{}".format(timestamp, module, func) if msg: final_msg = "{}: {}".format(final_msg, msg) print(final_msg) def get_resource_path(self, filename): """ Returns the absolute path of a resource, regardless of whether OnionShare is installed systemwide, and whether regardless of platform """ # On Windows, and in Windows dev mode, switch slashes in incoming filename to backslackes if self.platform == "Windows": filename = filename.replace("/", "\\") if getattr(sys, "onionshare_dev_mode", False): # Look for resources directory relative to python file prefix = os.path.join( os.path.dirname( os.path.dirname( os.path.abspath(inspect.getfile(inspect.currentframe())) ) ), "share", ) if not os.path.exists(prefix): # While running tests during stdeb bdist_deb, look 3 directories up for the share folder prefix = os.path.join( os.path.dirname( os.path.dirname(os.path.dirname(os.path.dirname(prefix))) ), "share", ) elif self.platform == "BSD" or self.platform == "Linux": # Assume OnionShare is installed systemwide in Linux, since we're not running in dev mode prefix = os.path.join(sys.prefix, "share/onionshare") elif getattr(sys, "frozen", False): # Check if app is "frozen" # https://pythonhosted.org/PyInstaller/#run-time-information if self.platform == "Darwin": prefix = os.path.join(sys._MEIPASS, "share") elif self.platform == "Windows": prefix = os.path.join(os.path.dirname(sys.executable), "share") return os.path.join(prefix, filename) def get_tor_paths(self): if self.platform == "Linux": tor_path = "/usr/bin/tor" tor_geo_ip_file_path = "/usr/share/tor/geoip" tor_geo_ipv6_file_path = "/usr/share/tor/geoip6" obfs4proxy_file_path = "/usr/bin/obfs4proxy" elif self.platform == "Windows": base_path = os.path.join( os.path.dirname(os.path.dirname(self.get_resource_path(""))), "tor" ) tor_path = os.path.join(os.path.join(base_path, "Tor"), "tor.exe") obfs4proxy_file_path = os.path.join( os.path.join(base_path, "Tor"), "obfs4proxy.exe" ) tor_geo_ip_file_path = os.path.join( os.path.join(os.path.join(base_path, "Data"), "Tor"), "geoip" ) tor_geo_ipv6_file_path = os.path.join( os.path.join(os.path.join(base_path, "Data"), "Tor"), "geoip6" ) elif self.platform == "Darwin": base_path = os.path.dirname( os.path.dirname(os.path.dirname(self.get_resource_path(""))) ) tor_path = os.path.join(base_path, "Resources", "Tor", "tor") tor_geo_ip_file_path = os.path.join(base_path, "Resources", "Tor", "geoip") tor_geo_ipv6_file_path = os.path.join( base_path, "Resources", "Tor", "geoip6" ) obfs4proxy_file_path = os.path.join( base_path, "Resources", "Tor", "obfs4proxy" ) elif self.platform == "BSD": tor_path = "/usr/local/bin/tor" tor_geo_ip_file_path = "/usr/local/share/tor/geoip" tor_geo_ipv6_file_path = "/usr/local/share/tor/geoip6" obfs4proxy_file_path = "/usr/local/bin/obfs4proxy" return ( tor_path, tor_geo_ip_file_path, tor_geo_ipv6_file_path, obfs4proxy_file_path, ) def build_data_dir(self): """ Returns the path of the OnionShare data directory. """ if self.platform == "Windows": try: appdata = os.environ["APPDATA"] onionshare_data_dir = "{}\\OnionShare".format(appdata) except: # If for some reason we don't have the 'APPDATA' environment variable # (like running tests in Linux while pretending to be in Windows) onionshare_data_dir = os.path.expanduser("~/.config/onionshare") elif self.platform == "Darwin": onionshare_data_dir = os.path.expanduser( "~/Library/Application Support/OnionShare" ) else: onionshare_data_dir = os.path.expanduser("~/.config/onionshare") os.makedirs(onionshare_data_dir, 0o700, True) return onionshare_data_dir def build_password(self): """ Returns a random string made from two words from the wordlist, such as "deter-trig". """ with open(self.get_resource_path("wordlist.txt")) as f: wordlist = f.read().split() r = random.SystemRandom() return "-".join(r.choice(wordlist) for _ in range(2)) def define_css(self): """ This defines all of the stylesheets used in GUI mode, to avoid repeating code. This method is only called in GUI mode. """ self.css = { # OnionShareGui styles "mode_switcher_selected_style": """ QPushButton { color: #ffffff; background-color: #4e064f; border: 0; border-right: 1px solid #69266b; font-weight: bold; border-radius: 0; }""", "mode_switcher_unselected_style": """ QPushButton { color: #ffffff; background-color: #601f61; border: 0; font-weight: normal; border-radius: 0; }""", "settings_button": """ QPushButton { background-color: #601f61; border: 0; border-left: 1px solid #69266b; border-radius: 0; }""", "server_status_indicator_label": """ QLabel { font-style: italic; color: #666666; padding: 2px; }""", "status_bar": """ QStatusBar { font-style: italic; color: #666666; } QStatusBar::item { border: 0px; }""", # Common styles between modes and their child widgets "mode_info_label": """ QLabel { font-size: 12px; color: #666666; } """, "server_status_url": """ QLabel { background-color: #ffffff; color: #000000; padding: 10px; border: 1px solid #666666; font-size: 12px; } """, "server_status_url_buttons": """ QPushButton { color: #3f7fcf; } """, "server_status_button_stopped": """ QPushButton { background-color: #5fa416; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; }""", "server_status_button_working": """ QPushButton { background-color: #4c8211; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; font-style: italic; }""", "server_status_button_started": """ QPushButton { background-color: #d0011b; color: #ffffff; padding: 10px; border: 0; border-radius: 5px; }""", "downloads_uploads_empty": """ QWidget { background-color: #ffffff; border: 1px solid #999999; } QWidget QLabel { background-color: none; border: 0px; } """, "downloads_uploads_empty_text": """ QLabel { color: #999999; }""", "downloads_uploads_label": """ QLabel { font-weight: bold; font-size 14px; text-align: center; background-color: none; border: none; }""", "downloads_uploads_clear": """ QPushButton { color: #3f7fcf; } """, "download_uploads_indicator": """ QLabel { color: #ffffff; background-color: #f44449; font-weight: bold; font-size: 10px; padding: 2px; border-radius: 7px; text-align: center; }""", "downloads_uploads_progress_bar": """ QProgressBar { border: 1px solid #4e064f; background-color: #ffffff !important; text-align: center; color: #9b9b9b; font-size: 14px; } QProgressBar::chunk { background-color: #4e064f; width: 10px; }""", "history_individual_file_timestamp_label": """ QLabel { color: #666666; }""", "history_individual_file_status_code_label_2xx": """ QLabel { color: #008800; }""", "history_individual_file_status_code_label_4xx": """ QLabel { color: #cc0000; }""", # Share mode and child widget styles "share_zip_progess_bar": """ QProgressBar { border: 1px solid #4e064f; background-color: #ffffff !important; text-align: center; color: #9b9b9b; } QProgressBar::chunk { border: 0px; background-color: #4e064f; width: 10px; }""", "share_filesize_warning": """ QLabel { padding: 10px 0; font-weight: bold; color: #333333; } """, "share_file_selection_drop_here_label": """ QLabel { color: #999999; }""", "share_file_selection_drop_count_label": """ QLabel { color: #ffffff; background-color: #f44449; font-weight: bold; padding: 5px 10px; border-radius: 10px; }""", "share_file_list_drag_enter": """ FileList { border: 3px solid #538ad0; } """, "share_file_list_drag_leave": """ FileList { border: none; } """, "share_file_list_item_size": """ QLabel { color: #666666; font-size: 11px; }""", # Receive mode and child widget styles "receive_file": """ QWidget { background-color: #ffffff; } """, "receive_file_size": """ QLabel { color: #666666; font-size: 11px; }""", # Settings dialog "settings_version": """ QLabel { color: #666666; }""", "settings_tor_status": """ QLabel { background-color: #ffffff; color: #000000; padding: 10px; }""", "settings_whats_this": """ QLabel { font-size: 12px; }""", "settings_connect_to_tor": """ QLabel { font-style: italic; }""", } @staticmethod def random_string(num_bytes, output_len=None): """ Returns a random string with a specified number of bytes. """ b = os.urandom(num_bytes) h = hashlib.sha256(b).digest()[:16] s = base64.b32encode(h).lower().replace(b"=", b"").decode("utf-8") if not output_len: return s return s[:output_len] @staticmethod def human_readable_filesize(b): """ Returns filesize in a human readable format. """ thresh = 1024.0 if b < thresh: return "{:.1f} B".format(b) units = ("KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") u = 0 b /= thresh while b >= thresh: b /= thresh u += 1 return "{:.1f} {}".format(b, units[u]) @staticmethod def format_seconds(seconds): """Return a human-readable string of the format 1d2h3m4s""" days, seconds = divmod(seconds, 86400) hours, seconds = divmod(seconds, 3600) minutes, seconds = divmod(seconds, 60) human_readable = [] if days: human_readable.append("{:.0f}d".format(days)) if hours: human_readable.append("{:.0f}h".format(hours)) if minutes: human_readable.append("{:.0f}m".format(minutes)) if seconds or not human_readable: human_readable.append("{:.0f}s".format(seconds)) return "".join(human_readable) @staticmethod def estimated_time_remaining(bytes_downloaded, total_bytes, started): now = time.time() time_elapsed = now - started # in seconds download_rate = bytes_downloaded / time_elapsed remaining_bytes = total_bytes - bytes_downloaded eta = remaining_bytes / download_rate return Common.format_seconds(eta) @staticmethod def get_available_port(min_port, max_port): """ Find a random available port within the given range. """ with socket.socket() as tmpsock: while True: try: tmpsock.bind(("127.0.0.1", random.randint(min_port, max_port))) break except OSError as e: pass _, port = tmpsock.getsockname() return port @staticmethod def dir_size(start_path): """ Calculates the total size, in bytes, of all of the files in a directory. """ total_size = 0 for dirpath, dirnames, filenames in os.walk(start_path): for f in filenames: fp = os.path.join(dirpath, f) if not os.path.islink(fp): total_size += os.path.getsize(fp) return total_size class AutoStopTimer(threading.Thread): """ Background thread sleeps t hours and returns. """ def __init__(self, common, time): threading.Thread.__init__(self) self.common = common self.setDaemon(True) self.time = time def run(self): self.common.log( "AutoStopTimer", "Server will shut down after {} seconds".format(self.time) ) time.sleep(self.time) return 1 onionshare-2.2/onionshare/onion.py000066400000000000000000000741001355066717400174030ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from stem.control import Controller from stem import ProtocolError, SocketClosed from stem.connection import MissingPassword, UnreadableCookieFile, AuthenticationFailure from Crypto.PublicKey import RSA import base64, os, sys, tempfile, shutil, urllib, platform, subprocess, time, shlex from distutils.version import LooseVersion as Version from . import common, strings from .settings import Settings class TorErrorAutomatic(Exception): """ OnionShare is failing to connect and authenticate to the Tor controller, using automatic settings that should work with Tor Browser. """ pass class TorErrorInvalidSetting(Exception): """ This exception is raised if the settings just don't make sense. """ pass class TorErrorSocketPort(Exception): """ OnionShare can't connect to the Tor controller using the supplied address and port. """ pass class TorErrorSocketFile(Exception): """ OnionShare can't connect to the Tor controller using the supplied socket file. """ pass class TorErrorMissingPassword(Exception): """ OnionShare connected to the Tor controller, but it requires a password. """ pass class TorErrorUnreadableCookieFile(Exception): """ OnionShare connected to the Tor controller, but your user does not have permission to access the cookie file. """ pass class TorErrorAuthError(Exception): """ OnionShare connected to the address and port, but can't authenticate. It's possible that a Tor controller isn't listening on this port. """ pass class TorErrorProtocolError(Exception): """ This exception is raised if onionshare connects to the Tor controller, but it isn't acting like a Tor controller (such as in Whonix). """ pass class TorTooOld(Exception): """ This exception is raised if onionshare needs to use a feature of Tor or stem (like stealth ephemeral onion services) but the version you have installed is too old. """ pass class BundledTorNotSupported(Exception): """ This exception is raised if onionshare is set to use the bundled Tor binary, but it's not supported on that platform, or in dev mode. """ class BundledTorTimeout(Exception): """ This exception is raised if onionshare is set to use the bundled Tor binary, but Tor doesn't finish connecting promptly. """ class BundledTorCanceled(Exception): """ This exception is raised if onionshare is set to use the bundled Tor binary, and the user cancels connecting to Tor """ class BundledTorBroken(Exception): """ This exception is raised if onionshare is set to use the bundled Tor binary, but the process seems to fail to run. """ class Onion(object): """ Onion is an abstraction layer for connecting to the Tor control port and creating onion services. OnionShare supports creating onion services by connecting to the Tor controller and using ADD_ONION, DEL_ONION. stealth: Should the onion service be stealth? settings: A Settings object. If it's not passed in, load from disk. bundled_connection_func: If the tor connection type is bundled, optionally call this function and pass in a status string while connecting to tor. This is necessary for status updates to reach the GUI. """ def __init__(self, common): self.common = common self.common.log("Onion", "__init__") self.stealth = False self.service_id = None self.scheduled_key = None self.scheduled_auth_cookie = None # Is bundled tor supported? if ( self.common.platform == "Windows" or self.common.platform == "Darwin" ) and getattr(sys, "onionshare_dev_mode", False): self.bundle_tor_supported = False else: self.bundle_tor_supported = True # Set the path of the tor binary, for bundled tor ( self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path, ) = self.common.get_tor_paths() # The tor process self.tor_proc = None # The Tor controller self.c = None # Start out not connected to Tor self.connected_to_tor = False def connect( self, custom_settings=False, config=False, tor_status_update_func=None, connect_timeout=120, ): self.common.log("Onion", "connect") # Either use settings that are passed in, or use them from common if custom_settings: self.settings = custom_settings elif config: self.common.load_settings(config) self.settings = self.common.settings else: self.common.load_settings() self.settings = self.common.settings strings.load_strings(self.common) # The Tor controller self.c = None if self.settings.get("connection_type") == "bundled": if not self.bundle_tor_supported: raise BundledTorNotSupported( strings._("settings_error_bundled_tor_not_supported") ) # Create a torrc for this session self.tor_data_directory = tempfile.TemporaryDirectory( dir=self.common.build_data_dir() ) self.common.log( "Onion", "connect", "tor_data_directory={}".format(self.tor_data_directory.name), ) # Create the torrc with open(self.common.get_resource_path("torrc_template")) as f: torrc_template = f.read() self.tor_cookie_auth_file = os.path.join( self.tor_data_directory.name, "cookie" ) try: self.tor_socks_port = self.common.get_available_port(1000, 65535) except: raise OSError(strings._("no_available_port")) self.tor_torrc = os.path.join(self.tor_data_directory.name, "torrc") if self.common.platform == "Windows" or self.common.platform == "Darwin": # Windows doesn't support unix sockets, so it must use a network port. # macOS can't use unix sockets either because socket filenames are limited to # 100 chars, and the macOS sandbox forces us to put the socket file in a place # with a really long path. torrc_template += "ControlPort {{control_port}}\n" try: self.tor_control_port = self.common.get_available_port(1000, 65535) except: raise OSError(strings._("no_available_port")) self.tor_control_socket = None else: # Linux and BSD can use unix sockets torrc_template += "ControlSocket {{control_socket}}\n" self.tor_control_port = None self.tor_control_socket = os.path.join( self.tor_data_directory.name, "control_socket" ) torrc_template = torrc_template.replace( "{{data_directory}}", self.tor_data_directory.name ) torrc_template = torrc_template.replace( "{{control_port}}", str(self.tor_control_port) ) torrc_template = torrc_template.replace( "{{control_socket}}", str(self.tor_control_socket) ) torrc_template = torrc_template.replace( "{{cookie_auth_file}}", self.tor_cookie_auth_file ) torrc_template = torrc_template.replace( "{{geo_ip_file}}", self.tor_geo_ip_file_path ) torrc_template = torrc_template.replace( "{{geo_ipv6_file}}", self.tor_geo_ipv6_file_path ) torrc_template = torrc_template.replace( "{{socks_port}}", str(self.tor_socks_port) ) with open(self.tor_torrc, "w") as f: f.write(torrc_template) # Bridge support if self.settings.get("tor_bridges_use_obfs4"): f.write( "ClientTransportPlugin obfs4 exec {}\n".format( self.obfs4proxy_file_path ) ) with open( self.common.get_resource_path("torrc_template-obfs4") ) as o: for line in o: f.write(line) elif self.settings.get("tor_bridges_use_meek_lite_azure"): f.write( "ClientTransportPlugin meek_lite exec {}\n".format( self.obfs4proxy_file_path ) ) with open( self.common.get_resource_path("torrc_template-meek_lite_azure") ) as o: for line in o: f.write(line) if self.settings.get("tor_bridges_use_custom_bridges"): if "obfs4" in self.settings.get("tor_bridges_use_custom_bridges"): f.write( "ClientTransportPlugin obfs4 exec {}\n".format( self.obfs4proxy_file_path ) ) elif "meek_lite" in self.settings.get( "tor_bridges_use_custom_bridges" ): f.write( "ClientTransportPlugin meek_lite exec {}\n".format( self.obfs4proxy_file_path ) ) f.write(self.settings.get("tor_bridges_use_custom_bridges")) f.write("\nUseBridges 1") # Execute a tor subprocess start_ts = time.time() if self.common.platform == "Windows": # In Windows, hide console window when opening tor.exe subprocess startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW self.tor_proc = subprocess.Popen( [self.tor_path, "-f", self.tor_torrc], stdout=subprocess.PIPE, stderr=subprocess.PIPE, startupinfo=startupinfo, ) else: self.tor_proc = subprocess.Popen( [self.tor_path, "-f", self.tor_torrc], stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) # Wait for the tor controller to start time.sleep(2) # Connect to the controller try: if ( self.common.platform == "Windows" or self.common.platform == "Darwin" ): self.c = Controller.from_port(port=self.tor_control_port) self.c.authenticate() else: self.c = Controller.from_socket_file(path=self.tor_control_socket) self.c.authenticate() except Exception as e: raise BundledTorBroken( strings._("settings_error_bundled_tor_broken").format(e.args[0]) ) while True: try: res = self.c.get_info("status/bootstrap-phase") except SocketClosed: raise BundledTorCanceled() res_parts = shlex.split(res) progress = res_parts[2].split("=")[1] summary = res_parts[4].split("=")[1] # "\033[K" clears the rest of the line print( "Connecting to the Tor network: {}% - {}{}".format( progress, summary, "\033[K" ), end="\r", ) if callable(tor_status_update_func): if not tor_status_update_func(progress, summary): # If the dialog was canceled, stop connecting to Tor self.common.log( "Onion", "connect", "tor_status_update_func returned false, canceling connecting to Tor", ) print() return False if summary == "Done": print("") break time.sleep(0.2) # If using bridges, it might take a bit longer to connect to Tor if ( self.settings.get("tor_bridges_use_custom_bridges") or self.settings.get("tor_bridges_use_obfs4") or self.settings.get("tor_bridges_use_meek_lite_azure") ): # Only override timeout if a custom timeout has not been passed in if connect_timeout == 120: connect_timeout = 150 if time.time() - start_ts > connect_timeout: print("") try: self.tor_proc.terminate() raise BundledTorTimeout( strings._("settings_error_bundled_tor_timeout") ) except FileNotFoundError: pass elif self.settings.get("connection_type") == "automatic": # Automatically try to guess the right way to connect to Tor Browser # Try connecting to control port found_tor = False # If the TOR_CONTROL_PORT environment variable is set, use that env_port = os.environ.get("TOR_CONTROL_PORT") if env_port: try: self.c = Controller.from_port(port=int(env_port)) found_tor = True except: pass else: # Otherwise, try default ports for Tor Browser, Tor Messenger, and system tor try: ports = [9151, 9153, 9051] for port in ports: self.c = Controller.from_port(port=port) found_tor = True except: pass # If this still didn't work, try guessing the default socket file path socket_file_path = "" if not found_tor: try: if self.common.platform == "Darwin": socket_file_path = os.path.expanduser( "~/Library/Application Support/TorBrowser-Data/Tor/control.socket" ) self.c = Controller.from_socket_file(path=socket_file_path) found_tor = True except: pass # If connecting to default control ports failed, so let's try # guessing the socket file name next if not found_tor: try: if self.common.platform == "Linux" or self.common.platform == "BSD": socket_file_path = "/run/user/{}/Tor/control.socket".format( os.geteuid() ) elif self.common.platform == "Darwin": socket_file_path = "/run/user/{}/Tor/control.socket".format( os.geteuid() ) elif self.common.platform == "Windows": # Windows doesn't support unix sockets raise TorErrorAutomatic(strings._("settings_error_automatic")) self.c = Controller.from_socket_file(path=socket_file_path) except: raise TorErrorAutomatic(strings._("settings_error_automatic")) # Try authenticating try: self.c.authenticate() except: raise TorErrorAutomatic(strings._("settings_error_automatic")) else: # Use specific settings to connect to tor # Try connecting try: if self.settings.get("connection_type") == "control_port": self.c = Controller.from_port( address=self.settings.get("control_port_address"), port=self.settings.get("control_port_port"), ) elif self.settings.get("connection_type") == "socket_file": self.c = Controller.from_socket_file( path=self.settings.get("socket_file_path") ) else: raise TorErrorInvalidSetting(strings._("settings_error_unknown")) except: if self.settings.get("connection_type") == "control_port": raise TorErrorSocketPort( strings._("settings_error_socket_port").format( self.settings.get("control_port_address"), self.settings.get("control_port_port"), ) ) else: raise TorErrorSocketFile( strings._("settings_error_socket_file").format( self.settings.get("socket_file_path") ) ) # Try authenticating try: if self.settings.get("auth_type") == "no_auth": self.c.authenticate() elif self.settings.get("auth_type") == "password": self.c.authenticate(self.settings.get("auth_password")) else: raise TorErrorInvalidSetting(strings._("settings_error_unknown")) except MissingPassword: raise TorErrorMissingPassword( strings._("settings_error_missing_password") ) except UnreadableCookieFile: raise TorErrorUnreadableCookieFile( strings._("settings_error_unreadable_cookie_file") ) except AuthenticationFailure: raise TorErrorAuthError( strings._("settings_error_auth").format( self.settings.get("control_port_address"), self.settings.get("control_port_port"), ) ) # If we made it this far, we should be connected to Tor self.connected_to_tor = True # Get the tor version self.tor_version = self.c.get_version().version_str self.common.log( "Onion", "connect", "Connected to tor {}".format(self.tor_version) ) # Do the versions of stem and tor that I'm using support ephemeral onion services? list_ephemeral_hidden_services = getattr( self.c, "list_ephemeral_hidden_services", None ) self.supports_ephemeral = ( callable(list_ephemeral_hidden_services) and self.tor_version >= "0.2.7.1" ) # Do the versions of stem and tor that I'm using support stealth onion services? try: res = self.c.create_ephemeral_hidden_service( {1: 1}, basic_auth={"onionshare": None}, await_publication=False ) tmp_service_id = res.service_id self.c.remove_ephemeral_hidden_service(tmp_service_id) self.supports_stealth = True except: # ephemeral stealth onion services are not supported self.supports_stealth = False # Does this version of Tor support next-gen ('v3') onions? # Note, this is the version of Tor where this bug was fixed: # https://trac.torproject.org/projects/tor/ticket/28619 self.supports_v3_onions = self.tor_version >= Version("0.3.5.7") def is_authenticated(self): """ Returns True if the Tor connection is still working, or False otherwise. """ if self.c is not None: return self.c.is_authenticated() else: return False def start_onion_service(self, port, await_publication, save_scheduled_key=False): """ Start a onion service on port 80, pointing to the given port, and return the onion hostname. """ self.common.log("Onion", "start_onion_service") # Settings may have changed in the frontend but not updated in our settings object, # such as persistence. Reload the settings now just to be sure. self.settings.load() self.auth_string = None if not self.supports_ephemeral: raise TorTooOld(strings._("error_ephemeral_not_supported")) if self.stealth and not self.supports_stealth: raise TorTooOld(strings._("error_stealth_not_supported")) if not save_scheduled_key: print("Setting up onion service on port {0:d}.".format(int(port))) if self.stealth: if self.settings.get("hidservauth_string"): hidservauth_string = self.settings.get("hidservauth_string").split()[2] basic_auth = {"onionshare": hidservauth_string} else: if self.scheduled_auth_cookie: basic_auth = {"onionshare": self.scheduled_auth_cookie} else: basic_auth = {"onionshare": None} else: basic_auth = None if self.settings.get("private_key"): key_content = self.settings.get("private_key") if self.is_v2_key(key_content): key_type = "RSA1024" else: # Assume it was a v3 key. Stem will throw an error if it's something illegible key_type = "ED25519-V3" elif self.scheduled_key: key_content = self.scheduled_key if self.is_v2_key(key_content): key_type = "RSA1024" else: # Assume it was a v3 key. Stem will throw an error if it's something illegible key_type = "ED25519-V3" else: key_type = "NEW" # Work out if we can support v3 onion services, which are preferred if self.supports_v3_onions and not self.settings.get( "use_legacy_v2_onions" ): key_content = "ED25519-V3" else: # fall back to v2 onion services key_content = "RSA1024" # v3 onions don't yet support basic auth. Our ticket: # https://github.com/micahflee/onionshare/issues/697 if ( key_type == "NEW" and key_content == "ED25519-V3" and not self.settings.get("use_legacy_v2_onions") ): basic_auth = None self.stealth = False debug_message = "key_type={}".format(key_type) if key_type == "NEW": debug_message += ", key_content={}".format(key_content) self.common.log("Onion", "start_onion_service", "{}".format(debug_message)) try: if basic_auth != None: res = self.c.create_ephemeral_hidden_service( {80: port}, await_publication=await_publication, basic_auth=basic_auth, key_type=key_type, key_content=key_content, ) else: # if the stem interface is older than 1.5.0, basic_auth isn't a valid keyword arg res = self.c.create_ephemeral_hidden_service( {80: port}, await_publication=await_publication, key_type=key_type, key_content=key_content, ) except ProtocolError as e: raise TorErrorProtocolError( strings._("error_tor_protocol_error").format(e.args[0]) ) self.service_id = res.service_id onion_host = self.service_id + ".onion" # A new private key was generated and is in the Control port response. if self.settings.get("save_private_key"): if not self.settings.get("private_key"): self.settings.set("private_key", res.private_key) # If we were scheduling a future share, register the private key for later re-use if save_scheduled_key: self.scheduled_key = res.private_key else: self.scheduled_key = None if self.stealth: # Similar to the PrivateKey, the Control port only returns the ClientAuth # in the response if it was responsible for creating the basic_auth password # in the first place. # If we sent the basic_auth (due to a saved hidservauth_string in the settings), # there is no response here, so use the saved value from settings. if self.settings.get("save_private_key"): if self.settings.get("hidservauth_string"): self.auth_string = self.settings.get("hidservauth_string") else: auth_cookie = list(res.client_auth.values())[0] self.auth_string = "HidServAuth {} {}".format( onion_host, auth_cookie ) self.settings.set("hidservauth_string", self.auth_string) else: if not self.scheduled_auth_cookie: auth_cookie = list(res.client_auth.values())[0] self.auth_string = "HidServAuth {} {}".format( onion_host, auth_cookie ) if save_scheduled_key: # Register the HidServAuth for the scheduled share self.scheduled_auth_cookie = auth_cookie else: self.scheduled_auth_cookie = None else: self.auth_string = "HidServAuth {} {}".format( onion_host, self.scheduled_auth_cookie ) if not save_scheduled_key: # We've used the scheduled share's HidServAuth. Reset it to None for future shares self.scheduled_auth_cookie = None if onion_host is not None: self.settings.save() return onion_host else: raise TorErrorProtocolError(strings._("error_tor_protocol_error_unknown")) def cleanup(self, stop_tor=True): """ Stop onion services that were created earlier. If there's a tor subprocess running, kill it. """ self.common.log("Onion", "cleanup") # Cleanup the ephemeral onion services, if we have any try: onions = self.c.list_ephemeral_hidden_services() for onion in onions: try: self.common.log( "Onion", "cleanup", "trying to remove onion {}".format(onion) ) self.c.remove_ephemeral_hidden_service(onion) except: self.common.log( "Onion", "cleanup", "could not remove onion {}.. moving on anyway".format(onion), ) pass except: pass self.service_id = None if stop_tor: # Stop tor process if self.tor_proc: self.tor_proc.terminate() time.sleep(0.2) if not self.tor_proc.poll(): try: self.tor_proc.kill() except: pass self.tor_proc = None # Reset other Onion settings self.connected_to_tor = False self.stealth = False try: # Delete the temporary tor data directory self.tor_data_directory.cleanup() except AttributeError: # Skip if cleanup was somehow run before connect pass except PermissionError: # Skip if the directory is still open (#550) # TODO: find a better solution pass def get_tor_socks_port(self): """ Returns a (address, port) tuple for the Tor SOCKS port """ self.common.log("Onion", "get_tor_socks_port") if self.settings.get("connection_type") == "bundled": return ("127.0.0.1", self.tor_socks_port) elif self.settings.get("connection_type") == "automatic": return ("127.0.0.1", 9150) else: return (self.settings.get("socks_address"), self.settings.get("socks_port")) def is_v2_key(self, key): """ Helper function for determining if a key is RSA1024 (v2) or not. """ try: # Import the key key = RSA.importKey(base64.b64decode(key)) # Is this a v2 Onion key? (1024 bits) If so, we should keep using it. if key.n.bit_length() == 1024: return True else: return False except: return False onionshare-2.2/onionshare/onionshare.py000066400000000000000000000065071355066717400204340ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import os, shutil from . import common, strings from .onion import TorTooOld, TorErrorProtocolError from .common import AutoStopTimer class OnionShare(object): """ OnionShare is the main application class. Pass in options and run start_onion_service and it will do the magic. """ def __init__(self, common, onion, local_only=False, autostop_timer=0): self.common = common self.common.log("OnionShare", "__init__") # The Onion object self.onion = onion self.hidserv_dir = None self.onion_host = None self.port = None self.stealth = None # files and dirs to delete on shutdown self.cleanup_filenames = [] # do not use tor -- for development self.local_only = local_only # optionally shut down after N hours self.autostop_timer = autostop_timer # init auto-stop timer thread self.autostop_timer_thread = None def set_stealth(self, stealth): self.common.log("OnionShare", "set_stealth", "stealth={}".format(stealth)) self.stealth = stealth self.onion.stealth = stealth def choose_port(self): """ Choose a random port. """ try: self.port = self.common.get_available_port(17600, 17650) except: raise OSError(strings._("no_available_port")) def start_onion_service(self, await_publication=True, save_scheduled_key=False): """ Start the onionshare onion service. """ self.common.log("OnionShare", "start_onion_service") if not self.port: self.choose_port() if self.autostop_timer > 0: self.autostop_timer_thread = AutoStopTimer(self.common, self.autostop_timer) if self.local_only: self.onion_host = "127.0.0.1:{0:d}".format(self.port) return self.onion_host = self.onion.start_onion_service( self.port, await_publication, save_scheduled_key ) if self.stealth: self.auth_string = self.onion.auth_string def cleanup(self): """ Shut everything down and clean up temporary files, etc. """ self.common.log("OnionShare", "cleanup") # Cleanup files try: for filename in self.cleanup_filenames: if os.path.isfile(filename): os.remove(filename) elif os.path.isdir(filename): shutil.rmtree(filename) except: # Don't crash if file is still in use pass self.cleanup_filenames = [] onionshare-2.2/onionshare/settings.py000066400000000000000000000205171355066717400201240ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import json import os import platform import locale try: # We only need pwd module in macOS, and it's not available in Windows import pwd except: pass from . import strings class Settings(object): """ This class stores all of the settings for OnionShare, specifically for how to connect to Tor. If it can't find the settings file, it uses the default, which is to attempt to connect automatically using default Tor Browser settings. """ def __init__(self, common, config=False): self.common = common self.common.log("Settings", "__init__") # If a readable config file was provided, use that instead if config: if os.path.isfile(config): self.filename = config else: self.common.log( "Settings", "__init__", "Supplied config does not exist or is unreadable. Falling back to default location", ) self.filename = self.build_filename() else: # Default config self.filename = self.build_filename() # Dictionary of available languages in this version of OnionShare, # mapped to the language name, in that language self.available_locales = { "ar": "العربية", # Arabic #'bn': 'বাংলা', # Bengali (commented out because not at 90% translation) "ca": "Català", # Catalan "zh_Hant": "正體中文 (繁體)", # Traditional Chinese "zh_Hans": "中文 (简体)", # Simplified Chinese "da": "Dansk", # Danish "nl": "Nederlands", # Dutch "en": "English", # English # "fi": "Suomi", # Finnish (commented out because not at 90% translation) "fr": "Français", # French "de": "Deutsch", # German "el": "Ελληνικά", # Greek "is": "Íslenska", # Icelandic "ga": "Gaeilge", # Irish "it": "Italiano", # Italian "ja": "日本語", # Japanese "nb": "Norsk Bokmål", # Norwegian Bokmål "fa": "فارسی", # Persian "pl": "Polski", # Polish "pt_BR": "Português (Brasil)", # Portuguese Brazil "pt_PT": "Português (Portugal)", # Portuguese Portugal "ro": "Română", # Romanian "ru": "Русский", # Russian "sr_Latn": "Srpska (latinica)", # Serbian (latin) "es": "Español", # Spanish "sv": "Svenska", # Swedish "te": "తెలుగు", # Telugu "tr": "Türkçe", # Turkish "uk": "Українська", # Ukrainian } # These are the default settings. They will get overwritten when loading from disk self.default_settings = { "version": self.common.version, "connection_type": "bundled", "control_port_address": "127.0.0.1", "control_port_port": 9051, "socks_address": "127.0.0.1", "socks_port": 9050, "socket_file_path": "/var/run/tor/control", "auth_type": "no_auth", "auth_password": "", "close_after_first_download": True, "autostop_timer": False, "autostart_timer": False, "use_stealth": False, "use_autoupdate": True, "autoupdate_timestamp": None, "no_bridges": True, "tor_bridges_use_obfs4": False, "tor_bridges_use_meek_lite_azure": False, "tor_bridges_use_custom_bridges": "", "use_legacy_v2_onions": False, "save_private_key": False, "private_key": "", "public_mode": False, "password": "", "hidservauth_string": "", "data_dir": self.build_default_data_dir(), "csp_header_disabled": False, "locale": None, # this gets defined in fill_in_defaults() } self._settings = {} self.fill_in_defaults() def fill_in_defaults(self): """ If there are any missing settings from self._settings, replace them with their default values. """ for key in self.default_settings: if key not in self._settings: self._settings[key] = self.default_settings[key] # Choose the default locale based on the OS preference, and fall-back to English if self._settings["locale"] is None: language_code, encoding = locale.getdefaultlocale() # Default to English if not language_code: language_code = "en_US" if language_code == "pt_PT" and language_code == "pt_BR": # Portuguese locales include country code default_locale = language_code else: # All other locales cut off the country code default_locale = language_code[:2] if default_locale not in self.available_locales: default_locale = "en" self._settings["locale"] = default_locale def build_filename(self): """ Returns the path of the settings file. """ return os.path.join(self.common.build_data_dir(), "onionshare.json") def build_default_data_dir(self): """ Returns the path of the default Downloads directory for receive mode. """ if self.common.platform == "Darwin": # We can't use os.path.expanduser() in macOS because in the sandbox it # returns the path to the sandboxed homedir real_homedir = pwd.getpwuid(os.getuid()).pw_dir return os.path.join(real_homedir, "OnionShare") elif self.common.platform == "Windows": # On Windows, os.path.expanduser() needs to use backslash, or else it # retains the forward slash, which breaks opening the folder in explorer. return os.path.expanduser("~\OnionShare") else: # All other OSes return os.path.expanduser("~/OnionShare") def load(self): """ Load the settings from file. """ self.common.log("Settings", "load") # If the settings file exists, load it if os.path.exists(self.filename): try: self.common.log( "Settings", "load", "Trying to load {}".format(self.filename) ) with open(self.filename, "r") as f: self._settings = json.load(f) self.fill_in_defaults() except: pass # Make sure data_dir exists try: os.makedirs(self.get("data_dir"), exist_ok=True) except: pass def save(self): """ Save settings to file. """ self.common.log("Settings", "save") open(self.filename, "w").write(json.dumps(self._settings, indent=2)) self.common.log( "Settings", "save", "Settings saved in {}".format(self.filename) ) def get(self, key): return self._settings[key] def set(self, key, val): # If typecasting int values fails, fallback to default values if key == "control_port_port" or key == "socks_port": try: val = int(val) except: if key == "control_port_port": val = self.default_settings["control_port_port"] elif key == "socks_port": val = self.default_settings["socks_port"] self._settings[key] = val onionshare-2.2/onionshare/strings.py000066400000000000000000000033751355066717400177600ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import json import locale import os strings = {} translations = {} def load_strings(common): """ Loads translated strings and fallback to English if the translation does not exist. """ global strings, translations # Load all translations translations = {} for locale in common.settings.available_locales: locale_dir = common.get_resource_path("locale") filename = os.path.join(locale_dir, "{}.json".format(locale)) with open(filename, encoding="utf-8") as f: translations[locale] = json.load(f) # Build strings default_locale = "en" current_locale = common.settings.get("locale") strings = {} for s in translations[default_locale]: if s in translations[current_locale] and translations[current_locale][s] != "": strings[s] = translations[current_locale][s] else: strings[s] = translations[default_locale][s] def translated(k): """ Returns a translated string. """ return strings[k] _ = translated onionshare-2.2/onionshare/web/000077500000000000000000000000001355066717400164625ustar00rootroot00000000000000onionshare-2.2/onionshare/web/__init__.py000066400000000000000000000013711355066717400205750ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from .web import Web onionshare-2.2/onionshare/web/receive_mode.py000066400000000000000000000411611355066717400214650ustar00rootroot00000000000000import os import tempfile import json from datetime import datetime from flask import Request, request, render_template, make_response, flash, redirect from werkzeug.utils import secure_filename from .. import strings class ReceiveModeWeb: """ All of the web logic for receive mode """ def __init__(self, common, web): self.common = common self.common.log("ReceiveModeWeb", "__init__") self.web = web self.can_upload = True self.uploads_in_progress = [] # This tracks the history id self.cur_history_id = 0 self.define_routes() def define_routes(self): """ The web app routes for receiving files """ @self.web.app.route("/") def index(): history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_STARTED, "{}".format(request.path), {"id": history_id, "status_code": 200}, ) self.web.add_request(self.web.REQUEST_LOAD, request.path) r = make_response( render_template( "receive.html", static_url_path=self.web.static_url_path ) ) return self.web.add_security_headers(r) @self.web.app.route("/upload", methods=["POST"]) def upload(ajax=False): """ Handle the upload files POST request, though at this point, the files have already been uploaded and saved to their correct locations. """ files = request.files.getlist("file[]") filenames = [] for f in files: if f.filename != "": filename = secure_filename(f.filename) filenames.append(filename) local_path = os.path.join(request.receive_mode_dir, filename) basename = os.path.basename(local_path) # Tell the GUI the receive mode directory for this file self.web.add_request( self.web.REQUEST_UPLOAD_SET_DIR, request.path, { "id": request.history_id, "filename": basename, "dir": request.receive_mode_dir, }, ) self.common.log( "ReceiveModeWeb", "define_routes", "/upload, uploaded {}, saving to {}".format( f.filename, local_path ), ) print("\n" + "Received: {}".format(local_path)) if request.upload_error: self.common.log( "ReceiveModeWeb", "define_routes", "/upload, there was an upload error", ) self.web.add_request( self.web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE, request.path, {"receive_mode_dir": request.receive_mode_dir}, ) print( "Could not create OnionShare data folder: {}".format( request.receive_mode_dir ) ) msg = "Error uploading, please inform the OnionShare user" if ajax: return json.dumps({"error_flashes": [msg]}) else: flash(msg, "error") return redirect("/") # Note that flash strings are in English, and not translated, on purpose, # to avoid leaking the locale of the OnionShare user if ajax: info_flashes = [] if len(filenames) == 0: msg = "No files uploaded" if ajax: info_flashes.append(msg) else: flash(msg, "info") else: msg = "Sent " for filename in filenames: msg += "{}, ".format(filename) msg = msg.rstrip(", ") if ajax: info_flashes.append(msg) else: flash(msg, "info") if self.can_upload: if ajax: return json.dumps({"info_flashes": info_flashes}) else: return redirect("/") else: if ajax: return json.dumps( { "new_body": render_template( "thankyou.html", static_url_path=self.web.static_url_path, ) } ) else: # It was the last upload and the timer ran out r = make_response( render_template("thankyou.html"), static_url_path=self.web.static_url_path, ) return self.web.add_security_headers(r) @self.web.app.route("/upload-ajax", methods=["POST"]) def upload_ajax_public(): if not self.can_upload: return self.web.error403() return upload(ajax=True) class ReceiveModeWSGIMiddleware(object): """ Custom WSGI middleware in order to attach the Web object to environ, so ReceiveModeRequest can access it. """ def __init__(self, app, web): self.app = app self.web = web def __call__(self, environ, start_response): environ["web"] = self.web environ["stop_q"] = self.web.stop_q return self.app(environ, start_response) class ReceiveModeFile(object): """ A custom file object that tells ReceiveModeRequest every time data gets written to it, in order to track the progress of uploads. It starts out with a .part file extension, and when it's complete it removes that extension. """ def __init__(self, request, filename, write_func, close_func): self.onionshare_request = request self.onionshare_filename = filename self.onionshare_write_func = write_func self.onionshare_close_func = close_func self.filename = os.path.join(self.onionshare_request.receive_mode_dir, filename) self.filename_in_progress = "{}.part".format(self.filename) # Open the file self.upload_error = False try: self.f = open(self.filename_in_progress, "wb+") except: # This will only happen if someone is messing with the data dir while # OnionShare is running, but if it does make sure to throw an error self.upload_error = True self.f = tempfile.TemporaryFile("wb+") # Make all the file-like methods and attributes actually access the # TemporaryFile, except for write attrs = [ "closed", "detach", "fileno", "flush", "isatty", "mode", "name", "peek", "raw", "read", "read1", "readable", "readinto", "readinto1", "readline", "readlines", "seek", "seekable", "tell", "truncate", "writable", "writelines", ] for attr in attrs: setattr(self, attr, getattr(self.f, attr)) def write(self, b): """ Custom write method that calls out to onionshare_write_func """ if self.upload_error or (not self.onionshare_request.stop_q.empty()): self.close() self.onionshare_request.close() return try: bytes_written = self.f.write(b) self.onionshare_write_func(self.onionshare_filename, bytes_written) except: self.upload_error = True def close(self): """ Custom close method that calls out to onionshare_close_func """ try: self.f.close() if not self.upload_error: # Rename the in progress file to the final filename os.rename(self.filename_in_progress, self.filename) except: self.upload_error = True self.onionshare_close_func(self.onionshare_filename, self.upload_error) class ReceiveModeRequest(Request): """ A custom flask Request object that keeps track of how much data has been uploaded for each file, for receive mode. """ def __init__(self, environ, populate_request=True, shallow=False): super(ReceiveModeRequest, self).__init__(environ, populate_request, shallow) self.web = environ["web"] self.stop_q = environ["stop_q"] self.web.common.log("ReceiveModeRequest", "__init__") # Prevent running the close() method more than once self.closed = False # Is this a valid upload request? self.upload_request = False if self.method == "POST": if self.path == "/upload" or self.path == "/upload-ajax": self.upload_request = True if self.upload_request: # No errors yet self.upload_error = False # Figure out what files should be saved now = datetime.now() date_dir = now.strftime("%Y-%m-%d") time_dir = now.strftime("%H.%M.%S") self.receive_mode_dir = os.path.join( self.web.common.settings.get("data_dir"), date_dir, time_dir ) # Create that directory, which shouldn't exist yet try: os.makedirs(self.receive_mode_dir, 0o700, exist_ok=False) except OSError: # If this directory already exists, maybe someone else is uploading files at # the same second, so use a different name in that case if os.path.exists(self.receive_mode_dir): # Keep going until we find a directory name that's available i = 1 while True: new_receive_mode_dir = "{}-{}".format(self.receive_mode_dir, i) try: os.makedirs(new_receive_mode_dir, 0o700, exist_ok=False) self.receive_mode_dir = new_receive_mode_dir break except OSError: pass i += 1 # Failsafe if i == 100: self.web.common.log( "ReceiveModeRequest", "__init__", "Error finding available receive mode directory", ) self.upload_error = True break except PermissionError: self.web.add_request( self.web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE, request.path, {"receive_mode_dir": self.receive_mode_dir}, ) print( "Could not create OnionShare data folder: {}".format( self.receive_mode_dir ) ) self.web.common.log( "ReceiveModeRequest", "__init__", "Permission denied creating receive mode directory", ) self.upload_error = True # If there's an error so far, finish early if self.upload_error: return # A dictionary that maps filenames to the bytes uploaded so far self.progress = {} # Prevent new uploads if we've said so (timer expired) if self.web.receive_mode.can_upload: # Create an history_id, attach it to the request self.history_id = self.web.receive_mode.cur_history_id self.web.receive_mode.cur_history_id += 1 # Figure out the content length try: self.content_length = int(self.headers["Content-Length"]) except: self.content_length = 0 print( "{}: {}".format( datetime.now().strftime("%b %d, %I:%M%p"), strings._("receive_mode_upload_starting").format( self.web.common.human_readable_filesize(self.content_length) ), ) ) # Don't tell the GUI that a request has started until we start receiving files self.told_gui_about_request = False self.previous_file = None def _get_file_stream( self, total_content_length, content_type, filename=None, content_length=None ): """ This gets called for each file that gets uploaded, and returns an file-like writable stream. """ if self.upload_request: if not self.told_gui_about_request: # Tell the GUI about the request self.web.add_request( self.web.REQUEST_STARTED, self.path, {"id": self.history_id, "content_length": self.content_length}, ) self.web.receive_mode.uploads_in_progress.append(self.history_id) self.told_gui_about_request = True self.filename = secure_filename(filename) self.progress[self.filename] = {"uploaded_bytes": 0, "complete": False} f = ReceiveModeFile( self, self.filename, self.file_write_func, self.file_close_func ) if f.upload_error: self.web.common.log( "ReceiveModeRequest", "_get_file_stream", "Error creating file" ) self.upload_error = True return f def close(self): """ Closing the request. """ super(ReceiveModeRequest, self).close() # Prevent calling this method more than once per request if self.closed: return self.closed = True self.web.common.log("ReceiveModeRequest", "close") try: if self.told_gui_about_request: history_id = self.history_id if ( not self.web.stop_q.empty() or not self.progress[self.filename]["complete"] ): # Inform the GUI that the upload has canceled self.web.add_request( self.web.REQUEST_UPLOAD_CANCELED, self.path, {"id": history_id} ) else: # Inform the GUI that the upload has finished self.web.add_request( self.web.REQUEST_UPLOAD_FINISHED, self.path, {"id": history_id} ) self.web.receive_mode.uploads_in_progress.remove(history_id) except AttributeError: pass def file_write_func(self, filename, length): """ This function gets called when a specific file is written to. """ if self.closed: return if self.upload_request: self.progress[filename]["uploaded_bytes"] += length if self.previous_file != filename: self.previous_file = filename print( "\r=> {:15s} {}".format( self.web.common.human_readable_filesize( self.progress[filename]["uploaded_bytes"] ), filename, ), end="", ) # Update the GUI on the upload progress if self.told_gui_about_request: self.web.add_request( self.web.REQUEST_PROGRESS, self.path, {"id": self.history_id, "progress": self.progress}, ) def file_close_func(self, filename, upload_error=False): """ This function gets called when a specific file is closed. """ self.progress[filename]["complete"] = True # If the file tells us there was an upload error, let the request know as well if upload_error: self.upload_error = True onionshare-2.2/onionshare/web/send_base_mode.py000066400000000000000000000254111355066717400217660ustar00rootroot00000000000000import os import sys import tempfile import mimetypes import gzip from flask import Response, request, render_template, make_response from .. import strings class SendBaseModeWeb: """ All of the web logic shared between share and website mode (modes where the user sends files) """ def __init__(self, common, web): super(SendBaseModeWeb, self).__init__() self.common = common self.web = web # Information about the file to be shared self.is_zipped = False self.download_filename = None self.download_filesize = None self.gzip_filename = None self.gzip_filesize = None self.zip_writer = None # If "Stop After First Download" is checked (stay_open == False), only allow # one download at a time. self.download_in_progress = False # This tracks the history id self.cur_history_id = 0 self.define_routes() self.init() def set_file_info(self, filenames, processed_size_callback=None): """ Build a data structure that describes the list of files """ # If there's just one folder, replace filenames with a list of files inside that folder if len(filenames) == 1 and os.path.isdir(filenames[0]): filenames = [ os.path.join(filenames[0], x) for x in os.listdir(filenames[0]) ] # Re-initialize self.files = {} # Dictionary mapping file paths to filenames on disk self.root_files = ( {} ) # This is only the root files and dirs, as opposed to all of them self.cleanup_filenames = [] self.cur_history_id = 0 self.file_info = {"files": [], "dirs": []} self.gzip_individual_files = {} self.init() # Build the file list for filename in filenames: basename = os.path.basename(filename.rstrip("/")) # If it's a filename, add it if os.path.isfile(filename): self.files[basename] = filename self.root_files[basename] = filename # If it's a directory, add it recursively elif os.path.isdir(filename): self.root_files[basename + "/"] = filename for root, _, nested_filenames in os.walk(filename): # Normalize the root path. So if the directory name is "/home/user/Documents/some_folder", # and it has a nested folder foobar, the root is "/home/user/Documents/some_folder/foobar". # The normalized_root should be "some_folder/foobar" normalized_root = os.path.join( basename, root[len(filename) :].lstrip("/") ).rstrip("/") # Add the dir itself self.files[normalized_root + "/"] = root # Add the files in this dir for nested_filename in nested_filenames: self.files[ os.path.join(normalized_root, nested_filename) ] = os.path.join(root, nested_filename) self.set_file_info_custom(filenames, processed_size_callback) def directory_listing(self, filenames, path="", filesystem_path=None): # Tell the GUI about the directory listing history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_STARTED, "/{}".format(path), {"id": history_id, "method": request.method, "status_code": 200}, ) breadcrumbs = [("☗", "/")] parts = path.split("/")[:-1] for i in range(len(parts)): breadcrumbs.append( ("{}".format(parts[i]), "/{}/".format("/".join(parts[0 : i + 1]))) ) breadcrumbs_leaf = breadcrumbs.pop()[0] # If filesystem_path is None, this is the root directory listing files, dirs = self.build_directory_listing(filenames, filesystem_path) r = self.directory_listing_template( path, files, dirs, breadcrumbs, breadcrumbs_leaf ) return self.web.add_security_headers(r) def build_directory_listing(self, filenames, filesystem_path): files = [] dirs = [] for filename in filenames: if filesystem_path: this_filesystem_path = os.path.join(filesystem_path, filename) else: this_filesystem_path = self.files[filename] is_dir = os.path.isdir(this_filesystem_path) if is_dir: dirs.append({"basename": filename}) else: size = os.path.getsize(this_filesystem_path) size_human = self.common.human_readable_filesize(size) files.append({"basename": filename, "size_human": size_human}) return files, dirs def stream_individual_file(self, filesystem_path): """ Return a flask response that's streaming the download of an individual file, and gzip compressing it if the browser supports it. """ use_gzip = self.should_use_gzip() # gzip compress the individual file, if it hasn't already been compressed if use_gzip: if filesystem_path not in self.gzip_individual_files: gzip_filename = tempfile.mkstemp("wb+")[1] self._gzip_compress(filesystem_path, gzip_filename, 6, None) self.gzip_individual_files[filesystem_path] = gzip_filename # Make sure the gzip file gets cleaned up when onionshare stops self.cleanup_filenames.append(gzip_filename) file_to_download = self.gzip_individual_files[filesystem_path] filesize = os.path.getsize(self.gzip_individual_files[filesystem_path]) else: file_to_download = filesystem_path filesize = os.path.getsize(filesystem_path) path = request.path # Tell GUI the individual file started history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_STARTED, path, {"id": history_id, "filesize": filesize}, ) # Only GET requests are allowed, any other method should fail if request.method != "GET": return self.web.error405() def generate(): chunk_size = 102400 # 100kb fp = open(file_to_download, "rb") done = False while not done: chunk = fp.read(chunk_size) if chunk == b"": done = True else: try: yield chunk # Tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / filesize) * 100 if ( not self.web.is_gui or self.common.platform == "Linux" or self.common.platform == "BSD" ): sys.stdout.write( "\r{0:s}, {1:.2f}% ".format( self.common.human_readable_filesize( downloaded_bytes ), percent, ) ) sys.stdout.flush() self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_PROGRESS, path, { "id": history_id, "bytes": downloaded_bytes, "filesize": filesize, }, ) done = False except: # Looks like the download was canceled done = True # Tell the GUI the individual file was canceled self.web.add_request( self.web.REQUEST_INDIVIDUAL_FILE_CANCELED, path, {"id": history_id}, ) fp.close() if self.common.platform != "Darwin": sys.stdout.write("\n") basename = os.path.basename(filesystem_path) r = Response(generate()) if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", filesize) r.headers.set("Content-Disposition", "inline", filename=basename) r = self.web.add_security_headers(r) (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: r.headers.set("Content-Type", content_type) return r def should_use_gzip(self): """ Should we use gzip for this browser? """ return (not self.is_zipped) and ( "gzip" in request.headers.get("Accept-Encoding", "").lower() ) def _gzip_compress( self, input_filename, output_filename, level, processed_size_callback=None ): """ Compress a file with gzip, without loading the whole thing into memory Thanks: https://stackoverflow.com/questions/27035296/python-how-to-gzip-a-large-text-file-without-memoryerror """ bytes_processed = 0 blocksize = 1 << 16 # 64kB with open(input_filename, "rb") as input_file: output_file = gzip.open(output_filename, "wb", level) while True: if processed_size_callback is not None: processed_size_callback(bytes_processed) block = input_file.read(blocksize) if len(block) == 0: break output_file.write(block) bytes_processed += blocksize output_file.close() def init(self): """ Inherited class will implement this """ pass def define_routes(self): """ Inherited class will implement this """ pass def directory_listing_template(self): """ Inherited class will implement this. It should call render_template and return the response. """ pass def set_file_info_custom(self, filenames, processed_size_callback): """ Inherited class will implement this. """ pass def render_logic(self, path=""): """ Inherited class will implement this. """ pass onionshare-2.2/onionshare/web/share_mode.py000066400000000000000000000354601355066717400211520ustar00rootroot00000000000000import os import sys import tempfile import zipfile import mimetypes from flask import Response, request, render_template, make_response from .send_base_mode import SendBaseModeWeb from .. import strings class ShareModeWeb(SendBaseModeWeb): """ All of the web logic for share mode """ def init(self): self.common.log("ShareModeWeb", "init") # Allow downloading individual files if "Stop sharing after files have been sent" is unchecked self.download_individual_files = not self.common.settings.get( "close_after_first_download" ) def define_routes(self): """ The web app routes for sharing files """ @self.web.app.route("/", defaults={"path": ""}) @self.web.app.route("/") def index(path): """ Render the template for the onionshare landing page. """ self.web.add_request(self.web.REQUEST_LOAD, request.path) # Deny new downloads if "Stop sharing after files have been sent" is checked and there is # currently a download deny_download = not self.web.stay_open and self.download_in_progress if deny_download: r = make_response( render_template("denied.html"), static_url_path=self.web.static_url_path, ) return self.web.add_security_headers(r) # If download is allowed to continue, serve download page if self.should_use_gzip(): self.filesize = self.gzip_filesize else: self.filesize = self.download_filesize return self.render_logic(path) @self.web.app.route("/download") def download(): """ Download the zip file. """ # Deny new downloads if "Stop After First Download" is checked and there is # currently a download deny_download = not self.web.stay_open and self.download_in_progress if deny_download: r = make_response( render_template( "denied.html", static_url_path=self.web.static_url_path ) ) return self.web.add_security_headers(r) # Prepare some variables to use inside generate() function below # which is outside of the request context shutdown_func = request.environ.get("werkzeug.server.shutdown") path = request.path # If this is a zipped file, then serve as-is. If it's not zipped, then, # if the http client supports gzip compression, gzip the file first # and serve that use_gzip = self.should_use_gzip() if use_gzip: file_to_download = self.gzip_filename self.filesize = self.gzip_filesize else: file_to_download = self.download_filename self.filesize = self.download_filesize # Tell GUI the download started history_id = self.cur_history_id self.cur_history_id += 1 self.web.add_request( self.web.REQUEST_STARTED, path, {"id": history_id, "use_gzip": use_gzip} ) basename = os.path.basename(self.download_filename) def generate(): # Starting a new download if not self.web.stay_open: self.download_in_progress = True chunk_size = 102400 # 100kb fp = open(file_to_download, "rb") self.web.done = False canceled = False while not self.web.done: # The user has canceled the download, so stop serving the file if not self.web.stop_q.empty(): self.web.add_request( self.web.REQUEST_CANCELED, path, {"id": history_id} ) break chunk = fp.read(chunk_size) if chunk == b"": self.web.done = True else: try: yield chunk # tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / self.filesize) * 100 # only output to stdout if running onionshare in CLI mode, or if using Linux (#203, #304) if ( not self.web.is_gui or self.common.platform == "Linux" or self.common.platform == "BSD" ): sys.stdout.write( "\r{0:s}, {1:.2f}% ".format( self.common.human_readable_filesize( downloaded_bytes ), percent, ) ) sys.stdout.flush() self.web.add_request( self.web.REQUEST_PROGRESS, path, {"id": history_id, "bytes": downloaded_bytes}, ) self.web.done = False except: # looks like the download was canceled self.web.done = True canceled = True # tell the GUI the download has canceled self.web.add_request( self.web.REQUEST_CANCELED, path, {"id": history_id} ) fp.close() if self.common.platform != "Darwin": sys.stdout.write("\n") # Download is finished if not self.web.stay_open: self.download_in_progress = False # Close the server, if necessary if not self.web.stay_open and not canceled: print("Stopped because transfer is complete") self.web.running = False try: if shutdown_func is None: raise RuntimeError("Not running with the Werkzeug Server") shutdown_func() except: pass r = Response(generate()) if use_gzip: r.headers.set("Content-Encoding", "gzip") r.headers.set("Content-Length", self.filesize) r.headers.set("Content-Disposition", "attachment", filename=basename) r = self.web.add_security_headers(r) # guess content type (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: r.headers.set("Content-Type", content_type) return r def directory_listing_template( self, path, files, dirs, breadcrumbs, breadcrumbs_leaf ): return make_response( render_template( "send.html", file_info=self.file_info, files=files, dirs=dirs, breadcrumbs=breadcrumbs, breadcrumbs_leaf=breadcrumbs_leaf, filename=os.path.basename(self.download_filename), filesize=self.filesize, filesize_human=self.common.human_readable_filesize( self.download_filesize ), is_zipped=self.is_zipped, static_url_path=self.web.static_url_path, download_individual_files=self.download_individual_files, ) ) def set_file_info_custom(self, filenames, processed_size_callback): self.common.log("ShareModeWeb", "set_file_info_custom") self.web.cancel_compression = False self.build_zipfile_list(filenames, processed_size_callback) def render_logic(self, path=""): if path in self.files: filesystem_path = self.files[path] # If it's a directory if os.path.isdir(filesystem_path): # Render directory listing filenames = [] for filename in os.listdir(filesystem_path): if os.path.isdir(os.path.join(filesystem_path, filename)): filenames.append(filename + "/") else: filenames.append(filename) filenames.sort() return self.directory_listing(filenames, path, filesystem_path) # If it's a file elif os.path.isfile(filesystem_path): if self.download_individual_files: return self.stream_individual_file(filesystem_path) else: history_id = self.cur_history_id self.cur_history_id += 1 return self.web.error404(history_id) # If it's not a directory or file, throw a 404 else: history_id = self.cur_history_id self.cur_history_id += 1 return self.web.error404(history_id) else: # Special case loading / if path == "": # Root directory listing filenames = list(self.root_files) filenames.sort() return self.directory_listing(filenames, path) else: # If the path isn't found, throw a 404 history_id = self.cur_history_id self.cur_history_id += 1 return self.web.error404(history_id) def build_zipfile_list(self, filenames, processed_size_callback=None): self.common.log("ShareModeWeb", "build_zipfile_list") for filename in filenames: info = { "filename": filename, "basename": os.path.basename(filename.rstrip("/")), } if os.path.isfile(filename): info["size"] = os.path.getsize(filename) info["size_human"] = self.common.human_readable_filesize(info["size"]) self.file_info["files"].append(info) if os.path.isdir(filename): info["size"] = self.common.dir_size(filename) info["size_human"] = self.common.human_readable_filesize(info["size"]) self.file_info["dirs"].append(info) self.file_info["files"] = sorted( self.file_info["files"], key=lambda k: k["basename"] ) self.file_info["dirs"] = sorted( self.file_info["dirs"], key=lambda k: k["basename"] ) # Check if there's only 1 file and no folders if len(self.file_info["files"]) == 1 and len(self.file_info["dirs"]) == 0: self.download_filename = self.file_info["files"][0]["filename"] self.download_filesize = self.file_info["files"][0]["size"] # Compress the file with gzip now, so we don't have to do it on each request self.gzip_filename = tempfile.mkstemp("wb+")[1] self._gzip_compress( self.download_filename, self.gzip_filename, 6, processed_size_callback ) self.gzip_filesize = os.path.getsize(self.gzip_filename) # Make sure the gzip file gets cleaned up when onionshare stops self.cleanup_filenames.append(self.gzip_filename) self.is_zipped = False else: # Zip up the files and folders self.zip_writer = ZipWriter( self.common, processed_size_callback=processed_size_callback ) self.download_filename = self.zip_writer.zip_filename for info in self.file_info["files"]: self.zip_writer.add_file(info["filename"]) # Canceling early? if self.web.cancel_compression: self.zip_writer.close() return False for info in self.file_info["dirs"]: if not self.zip_writer.add_dir(info["filename"]): return False self.zip_writer.close() self.download_filesize = os.path.getsize(self.download_filename) # Make sure the zip file gets cleaned up when onionshare stops self.cleanup_filenames.append(self.zip_writer.zip_filename) self.is_zipped = True return True class ZipWriter(object): """ ZipWriter accepts files and directories and compresses them into a zip file with. If a zip_filename is not passed in, it will use the default onionshare filename. """ def __init__(self, common, zip_filename=None, processed_size_callback=None): self.common = common self.cancel_compression = False if zip_filename: self.zip_filename = zip_filename else: self.zip_filename = "{0:s}/onionshare_{1:s}.zip".format( tempfile.mkdtemp(), self.common.random_string(4, 6) ) self.z = zipfile.ZipFile(self.zip_filename, "w", allowZip64=True) self.processed_size_callback = processed_size_callback if self.processed_size_callback is None: self.processed_size_callback = lambda _: None self._size = 0 self.processed_size_callback(self._size) def add_file(self, filename): """ Add a file to the zip archive. """ self.z.write(filename, os.path.basename(filename), zipfile.ZIP_DEFLATED) self._size += os.path.getsize(filename) self.processed_size_callback(self._size) def add_dir(self, filename): """ Add a directory, and all of its children, to the zip archive. """ dir_to_strip = os.path.dirname(filename.rstrip("/")) + "/" for dirpath, dirnames, filenames in os.walk(filename): for f in filenames: # Canceling early? if self.cancel_compression: return False full_filename = os.path.join(dirpath, f) if not os.path.islink(full_filename): arc_filename = full_filename[len(dir_to_strip) :] self.z.write(full_filename, arc_filename, zipfile.ZIP_DEFLATED) self._size += os.path.getsize(full_filename) self.processed_size_callback(self._size) return True def close(self): """ Close the zip archive. """ self.z.close() onionshare-2.2/onionshare/web/web.py000066400000000000000000000326351355066717400176220ustar00rootroot00000000000000import hmac import logging import os import queue import socket import sys import tempfile import requests from distutils.version import LooseVersion as Version from urllib.request import urlopen import flask from flask import ( Flask, request, render_template, abort, make_response, send_file, __version__ as flask_version, ) from flask_httpauth import HTTPBasicAuth from .. import strings from .share_mode import ShareModeWeb from .receive_mode import ReceiveModeWeb, ReceiveModeWSGIMiddleware, ReceiveModeRequest from .website_mode import WebsiteModeWeb # Stub out flask's show_server_banner function, to avoiding showing warnings that # are not applicable to OnionShare def stubbed_show_server_banner(env, debug, app_import_path, eager_loading): pass try: flask.cli.show_server_banner = stubbed_show_server_banner except: pass class Web: """ The Web object is the OnionShare web server, powered by flask """ REQUEST_LOAD = 0 REQUEST_STARTED = 1 REQUEST_PROGRESS = 2 REQUEST_CANCELED = 3 REQUEST_RATE_LIMIT = 4 REQUEST_UPLOAD_FILE_RENAMED = 5 REQUEST_UPLOAD_SET_DIR = 6 REQUEST_UPLOAD_FINISHED = 7 REQUEST_UPLOAD_CANCELED = 8 REQUEST_INDIVIDUAL_FILE_STARTED = 9 REQUEST_INDIVIDUAL_FILE_PROGRESS = 10 REQUEST_INDIVIDUAL_FILE_CANCELED = 11 REQUEST_ERROR_DATA_DIR_CANNOT_CREATE = 12 REQUEST_OTHER = 13 REQUEST_INVALID_PASSWORD = 14 def __init__(self, common, is_gui, mode="share"): self.common = common self.common.log("Web", "__init__", "is_gui={}, mode={}".format(is_gui, mode)) # The flask app self.app = Flask( __name__, static_folder=self.common.get_resource_path("static"), static_url_path="/static_".format( self.common.random_string(16) ), # randomize static_url_path to avoid making /static unusable template_folder=self.common.get_resource_path("templates"), ) self.app.secret_key = self.common.random_string(8) self.generate_static_url_path() self.auth = HTTPBasicAuth() self.auth.error_handler(self.error401) # Verbose mode? if self.common.verbose: self.verbose_mode() # Are we running in GUI mode? self.is_gui = is_gui # If the user stops the server while a transfer is in progress, it should # immediately stop the transfer. In order to make it thread-safe, stop_q # is a queue. If anything is in it, then the user stopped the server self.stop_q = queue.Queue() # Are we using receive mode? self.mode = mode if self.mode == "receive": # Use custom WSGI middleware, to modify environ self.app.wsgi_app = ReceiveModeWSGIMiddleware(self.app.wsgi_app, self) # Use a custom Request class to track upload progess self.app.request_class = ReceiveModeRequest # Starting in Flask 0.11, render_template_string autoescapes template variables # by default. To prevent content injection through template variables in # earlier versions of Flask, we force autoescaping in the Jinja2 template # engine if we detect a Flask version with insecure default behavior. if Version(flask_version) < Version("0.11"): # Monkey-patch in the fix from https://github.com/pallets/flask/commit/99c99c4c16b1327288fd76c44bc8635a1de452bc Flask.select_jinja_autoescape = self._safe_select_jinja_autoescape self.security_headers = [ ("X-Frame-Options", "DENY"), ("X-Xss-Protection", "1; mode=block"), ("X-Content-Type-Options", "nosniff"), ("Referrer-Policy", "no-referrer"), ("Server", "OnionShare"), ] self.q = queue.Queue() self.password = None self.reset_invalid_passwords() self.done = False # shutting down the server only works within the context of flask, so the easiest way to do it is over http self.shutdown_password = self.common.random_string(16) # Keep track if the server is running self.running = False # Define the web app routes self.define_common_routes() # Create the mode web object, which defines its own routes self.share_mode = None self.receive_mode = None self.website_mode = None if self.mode == "share": self.share_mode = ShareModeWeb(self.common, self) elif self.mode == "receive": self.receive_mode = ReceiveModeWeb(self.common, self) elif self.mode == "website": self.website_mode = WebsiteModeWeb(self.common, self) def get_mode(self): if self.mode == "share": return self.share_mode elif self.mode == "receive": return self.receive_mode elif self.mode == "website": return self.website_mode else: return None def generate_static_url_path(self): # The static URL path has a 128-bit random number in it to avoid having name # collisions with files that might be getting shared self.static_url_path = "/static_{}".format(self.common.random_string(16)) self.common.log( "Web", "generate_static_url_path", "new static_url_path is {}".format(self.static_url_path), ) # Update the flask route to handle the new static URL path self.app.static_url_path = self.static_url_path self.app.add_url_rule( self.static_url_path + "/", endpoint="static", view_func=self.app.send_static_file, ) def define_common_routes(self): """ Common web app routes between all modes. """ @self.auth.get_password def get_pw(username): if username == "onionshare": return self.password else: return None @self.app.before_request def conditional_auth_check(): # Allow static files without basic authentication if request.path.startswith(self.static_url_path + "/"): return None # If public mode is disabled, require authentication if not self.common.settings.get("public_mode"): @self.auth.login_required def _check_login(): return None return _check_login() @self.app.errorhandler(404) def not_found(e): mode = self.get_mode() history_id = mode.cur_history_id mode.cur_history_id += 1 return self.error404(history_id) @self.app.route("//shutdown") def shutdown(password_candidate): """ Stop the flask web server, from the context of an http request. """ if password_candidate == self.shutdown_password: self.force_shutdown() return "" abort(404) if self.mode != "website": @self.app.route("/favicon.ico") def favicon(): return send_file( "{}/img/favicon.ico".format(self.common.get_resource_path("static")) ) def error401(self): auth = request.authorization if auth: if ( auth["username"] == "onionshare" and auth["password"] not in self.invalid_passwords ): print("Invalid password guess: {}".format(auth["password"])) self.add_request(Web.REQUEST_INVALID_PASSWORD, data=auth["password"]) self.invalid_passwords.append(auth["password"]) self.invalid_passwords_count += 1 if self.invalid_passwords_count == 20: self.add_request(Web.REQUEST_RATE_LIMIT) self.force_shutdown() print( "Someone has made too many wrong attempts to guess your password, so OnionShare has stopped the server. Start sharing again and send the recipient a new address to share." ) r = make_response( render_template("401.html", static_url_path=self.static_url_path), 401 ) return self.add_security_headers(r) def error403(self): self.add_request(Web.REQUEST_OTHER, request.path) r = make_response( render_template("403.html", static_url_path=self.static_url_path), 403 ) return self.add_security_headers(r) def error404(self, history_id): self.add_request( self.REQUEST_INDIVIDUAL_FILE_STARTED, "{}".format(request.path), {"id": history_id, "status_code": 404}, ) self.add_request(Web.REQUEST_OTHER, request.path) r = make_response( render_template("404.html", static_url_path=self.static_url_path), 404 ) return self.add_security_headers(r) def error405(self): r = make_response( render_template("405.html", static_url_path=self.static_url_path), 405 ) return self.add_security_headers(r) def add_security_headers(self, r): """ Add security headers to a request """ for header, value in self.security_headers: r.headers.set(header, value) # Set a CSP header unless in website mode and the user has disabled it if ( not self.common.settings.get("csp_header_disabled") or self.mode != "website" ): r.headers.set( "Content-Security-Policy", "default-src 'self'; style-src 'self'; script-src 'self'; img-src 'self' data:;", ) return r def _safe_select_jinja_autoescape(self, filename): if filename is None: return True return filename.endswith((".html", ".htm", ".xml", ".xhtml")) def add_request(self, request_type, path=None, data=None): """ Add a request to the queue, to communicate with the GUI. """ self.q.put({"type": request_type, "path": path, "data": data}) def generate_password(self, persistent_password=None): self.common.log( "Web", "generate_password", "persistent_password={}".format(persistent_password), ) if persistent_password != None and persistent_password != "": self.password = persistent_password self.common.log( "Web", "generate_password", 'persistent_password sent, so password is: "{}"'.format(self.password), ) else: self.password = self.common.build_password() self.common.log( "Web", "generate_password", 'built random password: "{}"'.format(self.password), ) def verbose_mode(self): """ Turn on verbose mode, which will log flask errors to a file. """ flask_log_filename = os.path.join(self.common.build_data_dir(), "flask.log") log_handler = logging.FileHandler(flask_log_filename) log_handler.setLevel(logging.WARNING) self.app.logger.addHandler(log_handler) def reset_invalid_passwords(self): self.invalid_passwords_count = 0 self.invalid_passwords = [] def force_shutdown(self): """ Stop the flask web server, from the context of the flask app. """ # Shutdown the flask service try: func = request.environ.get("werkzeug.server.shutdown") if func is None: raise RuntimeError("Not running with the Werkzeug Server") func() except: pass self.running = False def start(self, port, stay_open=False, public_mode=False, password=None): """ Start the flask web server. """ self.common.log( "Web", "start", "port={}, stay_open={}, public_mode={}, password={}".format( port, stay_open, public_mode, password ), ) self.stay_open = stay_open # Make sure the stop_q is empty when starting a new server while not self.stop_q.empty(): try: self.stop_q.get(block=False) except queue.Empty: pass # In Whonix, listen on 0.0.0.0 instead of 127.0.0.1 (#220) if os.path.exists("/usr/share/anon-ws-base-files/workstation"): host = "0.0.0.0" else: host = "127.0.0.1" self.running = True self.app.run(host=host, port=port, threaded=True) def stop(self, port): """ Stop the flask web server by loading /shutdown. """ self.common.log("Web", "stop", "stopping server") # Let the mode know that the user stopped the server self.stop_q.put(True) # To stop flask, load http://shutdown:[shutdown_password]@127.0.0.1/[shutdown_password]/shutdown # (We're putting the shutdown_password in the path as well to make routing simpler) if self.running: requests.get( "http://127.0.0.1:{}/{}/shutdown".format(port, self.shutdown_password), auth=requests.auth.HTTPBasicAuth("onionshare", self.password), ) # Reset any password that was in use self.password = None onionshare-2.2/onionshare/web/website_mode.py000066400000000000000000000066041355066717400215100ustar00rootroot00000000000000import os import sys import tempfile import mimetypes from flask import Response, request, render_template, make_response from .send_base_mode import SendBaseModeWeb from .. import strings class WebsiteModeWeb(SendBaseModeWeb): """ All of the web logic for website mode """ def init(self): pass def define_routes(self): """ The web app routes for sharing a website """ @self.web.app.route("/", defaults={"path": ""}) @self.web.app.route("/") def path_public(path): return path_logic(path) def path_logic(path=""): """ Render the onionshare website. """ return self.render_logic(path) def directory_listing_template( self, path, files, dirs, breadcrumbs, breadcrumbs_leaf ): return make_response( render_template( "listing.html", path=path, files=files, dirs=dirs, breadcrumbs=breadcrumbs, breadcrumbs_leaf=breadcrumbs_leaf, static_url_path=self.web.static_url_path, ) ) def set_file_info_custom(self, filenames, processed_size_callback): self.common.log("WebsiteModeWeb", "set_file_info_custom") self.web.cancel_compression = True def render_logic(self, path=""): if path in self.files: filesystem_path = self.files[path] # If it's a directory if os.path.isdir(filesystem_path): # Is there an index.html? index_path = os.path.join(path, "index.html") if index_path in self.files: # Render it return self.stream_individual_file(self.files[index_path]) else: # Otherwise, render directory listing filenames = [] for filename in os.listdir(filesystem_path): if os.path.isdir(os.path.join(filesystem_path, filename)): filenames.append(filename + "/") else: filenames.append(filename) filenames.sort() return self.directory_listing(filenames, path, filesystem_path) # If it's a file elif os.path.isfile(filesystem_path): return self.stream_individual_file(filesystem_path) # If it's not a directory or file, throw a 404 else: history_id = self.cur_history_id self.cur_history_id += 1 return self.web.error404(history_id) else: # Special case loading / if path == "": index_path = "index.html" if index_path in self.files: # Render it return self.stream_individual_file(self.files[index_path]) else: # Root directory listing filenames = list(self.root_files) filenames.sort() return self.directory_listing(filenames, path) else: # If the path isn't found, throw a 404 history_id = self.cur_history_id self.cur_history_id += 1 return self.web.error404(history_id) onionshare-2.2/onionshare_gui/000077500000000000000000000000001355066717400165515ustar00rootroot00000000000000onionshare-2.2/onionshare_gui/__init__.py000066400000000000000000000106041355066717400206630ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from __future__ import division import os import sys import platform import argparse import signal from .widgets import Alert from PyQt5 import QtCore, QtWidgets from onionshare.common import Common from onionshare.onion import Onion from onionshare.onionshare import OnionShare from .onionshare_gui import OnionShareGui class Application(QtWidgets.QApplication): """ This is Qt's QApplication class. It has been overridden to support threads and the quick keyboard shortcut. """ def __init__(self, common): if common.platform == "Linux" or common.platform == "BSD": self.setAttribute(QtCore.Qt.AA_X11InitThreads, True) QtWidgets.QApplication.__init__(self, sys.argv) self.installEventFilter(self) def eventFilter(self, obj, event): if ( event.type() == QtCore.QEvent.KeyPress and event.key() == QtCore.Qt.Key_Q and event.modifiers() == QtCore.Qt.ControlModifier ): self.quit() return False def main(): """ The main() function implements all of the logic that the GUI version of onionshare uses. """ common = Common() common.define_css() # Display OnionShare banner print("OnionShare {0:s} | https://onionshare.org/".format(common.version)) # Allow Ctrl-C to smoothly quit the program instead of throwing an exception # https://stackoverflow.com/questions/42814093/how-to-handle-ctrlc-in-python-app-with-pyqt signal.signal(signal.SIGINT, signal.SIG_DFL) # Start the Qt app global qtapp qtapp = Application(common) # Parse arguments parser = argparse.ArgumentParser( formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=48) ) parser.add_argument( "--local-only", action="store_true", dest="local_only", help="Don't use Tor (only for development)", ) parser.add_argument( "-v", "--verbose", action="store_true", dest="verbose", help="Log OnionShare errors to stdout, and web errors to disk", ) parser.add_argument( "--filenames", metavar="filenames", nargs="+", help="List of files or folders to share", ) parser.add_argument( "--config", metavar="config", default=False, help="Custom JSON config file location (optional)", ) args = parser.parse_args() filenames = args.filenames if filenames: for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) config = args.config if config: common.load_settings(config) local_only = bool(args.local_only) verbose = bool(args.verbose) # Verbose mode? common.verbose = verbose # Validation if filenames: valid = True for filename in filenames: if not os.path.isfile(filename) and not os.path.isdir(filename): Alert(common, "{0:s} is not a valid file.".format(filename)) valid = False if not os.access(filename, os.R_OK): Alert(common, "{0:s} is not a readable file.".format(filename)) valid = False if not valid: sys.exit() # Start the Onion onion = Onion(common) # Start the OnionShare app app = OnionShare(common, onion, local_only) # Launch the gui gui = OnionShareGui(common, onion, qtapp, app, filenames, config, local_only) # Clean up when app quits def shutdown(): onion.cleanup() app.cleanup() qtapp.aboutToQuit.connect(shutdown) # All done sys.exit(qtapp.exec_()) if __name__ == "__main__": main() onionshare-2.2/onionshare_gui/mode/000077500000000000000000000000001355066717400174755ustar00rootroot00000000000000onionshare-2.2/onionshare_gui/mode/__init__.py000066400000000000000000000415731355066717400216200ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.common import AutoStopTimer from .history import IndividualFileHistoryItem from ..server_status import ServerStatus from ..threads import OnionThread from ..threads import AutoStartTimer from ..widgets import Alert class Mode(QtWidgets.QWidget): """ The class that all modes inherit from """ start_server_finished = QtCore.pyqtSignal() stop_server_finished = QtCore.pyqtSignal() starting_server_step2 = QtCore.pyqtSignal() starting_server_step3 = QtCore.pyqtSignal() starting_server_error = QtCore.pyqtSignal(str) starting_server_early = QtCore.pyqtSignal() set_server_active = QtCore.pyqtSignal(bool) def __init__( self, common, qtapp, app, status_bar, server_status_label, system_tray, filenames=None, local_only=False, ): super(Mode, self).__init__() self.common = common self.qtapp = qtapp self.app = app self.status_bar = status_bar self.server_status_label = server_status_label self.system_tray = system_tray self.filenames = filenames # The web object gets created in init() self.web = None # Local mode is passed from OnionShareGui self.local_only = local_only # Threads start out as None self.onion_thread = None self.web_thread = None self.startup_thread = None # Server status self.server_status = ServerStatus( self.common, self.qtapp, self.app, None, self.local_only ) self.server_status.server_started.connect(self.start_server) self.server_status.server_stopped.connect(self.stop_server) self.server_status.server_canceled.connect(self.cancel_server) self.start_server_finished.connect(self.server_status.start_server_finished) self.stop_server_finished.connect(self.server_status.stop_server_finished) self.starting_server_step2.connect(self.start_server_step2) self.starting_server_step3.connect(self.start_server_step3) self.starting_server_early.connect(self.start_server_early) self.starting_server_error.connect(self.start_server_error) # Primary action # Note: It's up to the downstream Mode to add this to its layout self.primary_action_layout = QtWidgets.QVBoxLayout() self.primary_action_layout.addWidget(self.server_status) self.primary_action = QtWidgets.QWidget() self.primary_action.setLayout(self.primary_action_layout) # Hack to allow a minimum width on the main layout # Note: It's up to the downstream Mode to add this to its layout self.min_width_widget = QtWidgets.QWidget() self.min_width_widget.setMinimumWidth(600) def init(self): """ Add custom initialization here. """ pass def human_friendly_time(self, secs): """ Returns a human-friendly time delta from given seconds. """ days = secs // 86400 hours = (secs - days * 86400) // 3600 minutes = (secs - days * 86400 - hours * 3600) // 60 seconds = secs - days * 86400 - hours * 3600 - minutes * 60 if not seconds: seconds = "0" result = ( ("{0}{1}, ".format(days, strings._("days_first_letter")) if days else "") + ( "{0}{1}, ".format(hours, strings._("hours_first_letter")) if hours else "" ) + ( "{0}{1}, ".format(minutes, strings._("minutes_first_letter")) if minutes else "" ) + "{0}{1}".format(seconds, strings._("seconds_first_letter")) ) return result def timer_callback(self): """ This method is called regularly on a timer. """ # If this is a scheduled share, display the countdown til the share starts if self.server_status.status == ServerStatus.STATUS_WORKING: if self.server_status.autostart_timer_datetime: now = QtCore.QDateTime.currentDateTime() if self.server_status.local_only: seconds_remaining = now.secsTo( self.server_status.autostart_timer_widget.dateTime() ) else: seconds_remaining = now.secsTo( self.server_status.autostart_timer_datetime.replace( second=0, microsecond=0 ) ) # Update the server button if seconds_remaining > 0: self.server_status.server_button.setText( strings._("gui_waiting_to_start").format( self.human_friendly_time(seconds_remaining) ) ) else: self.server_status.server_button.setText( strings._("gui_please_wait") ) # If the auto-stop timer has stopped, stop the server if self.server_status.status == ServerStatus.STATUS_STARTED: if self.app.autostop_timer_thread and self.common.settings.get( "autostop_timer" ): if self.autostop_timer_datetime_delta > 0: now = QtCore.QDateTime.currentDateTime() seconds_remaining = now.secsTo( self.server_status.autostop_timer_datetime ) # Update the server button server_button_text = self.get_stop_server_autostop_timer_text() self.server_status.server_button.setText( server_button_text.format( self.human_friendly_time(seconds_remaining) ) ) self.status_bar.clearMessage() if not self.app.autostop_timer_thread.is_alive(): if self.autostop_timer_finished_should_stop_server(): self.server_status.stop_server() def timer_callback_custom(self): """ Add custom timer code. """ pass def get_stop_server_autostop_timer_text(self): """ Return the string to put on the stop server button, if there's an auto-stop timer """ pass def autostop_timer_finished_should_stop_server(self): """ The auto-stop timer expired, should we stop the server? Returns a bool """ pass def start_server(self): """ Start the onionshare server. This uses multiple threads to start the Tor onion server and the web app. """ self.common.log("Mode", "start_server") self.start_server_custom() self.set_server_active.emit(True) self.app.set_stealth(self.common.settings.get("use_stealth")) # Clear the status bar self.status_bar.clearMessage() self.server_status_label.setText("") # Ensure we always get a new random port each time we might launch an OnionThread self.app.port = None # Start the onion thread. If this share was scheduled for a future date, # the OnionThread will start and exit 'early' to obtain the port, password # and onion address, but it will not start the WebThread yet. if self.server_status.autostart_timer_datetime: self.start_onion_thread(obtain_onion_early=True) else: self.start_onion_thread() # If scheduling a share, delay starting the real share if self.server_status.autostart_timer_datetime: self.common.log("Mode", "start_server", "Starting auto-start timer") self.startup_thread = AutoStartTimer(self) # Once the timer has finished, start the real share, with a WebThread self.startup_thread.success.connect(self.start_scheduled_service) self.startup_thread.error.connect(self.start_server_error) self.startup_thread.canceled = False self.startup_thread.start() def start_onion_thread(self, obtain_onion_early=False): self.common.log("Mode", "start_server", "Starting an onion thread") self.obtain_onion_early = obtain_onion_early self.onion_thread = OnionThread(self) self.onion_thread.success.connect(self.starting_server_step2.emit) self.onion_thread.success_early.connect(self.starting_server_early.emit) self.onion_thread.error.connect(self.starting_server_error.emit) self.onion_thread.start() def start_scheduled_service(self, obtain_onion_early=False): # We start a new OnionThread with the saved scheduled key from settings self.common.settings.load() self.obtain_onion_early = obtain_onion_early self.common.log("Mode", "start_server", "Starting a scheduled onion thread") self.onion_thread = OnionThread(self) self.onion_thread.success.connect(self.starting_server_step2.emit) self.onion_thread.error.connect(self.starting_server_error.emit) self.onion_thread.start() def start_server_custom(self): """ Add custom initialization here. """ pass def start_server_early(self): """ An 'early' start of an onion service in order to obtain the onion address for a scheduled start. Shows the onion address in the UI in advance of actually starting the share. """ self.server_status.show_url() def start_server_step2(self): """ Step 2 in starting the onionshare server. """ self.common.log("Mode", "start_server_step2") self.start_server_step2_custom() # Nothing to do here. # start_server_step2_custom has call these to move on: # self.starting_server_step3.emit() # self.start_server_finished.emit() def start_server_step2_custom(self): """ Add custom initialization here. """ pass def start_server_step3(self): """ Step 3 in starting the onionshare server. """ self.common.log("Mode", "start_server_step3") self.start_server_step3_custom() if self.common.settings.get("autostop_timer"): # Convert the date value to seconds between now and then now = QtCore.QDateTime.currentDateTime() self.autostop_timer_datetime_delta = now.secsTo( self.server_status.autostop_timer_datetime ) # Start the auto-stop timer if self.autostop_timer_datetime_delta > 0: self.app.autostop_timer_thread = AutoStopTimer( self.common, self.autostop_timer_datetime_delta ) self.app.autostop_timer_thread.start() # The auto-stop timer has actually already passed since the user clicked Start. Probably the Onion service took too long to start. else: self.stop_server() self.start_server_error( strings._("gui_server_started_after_autostop_timer") ) def start_server_step3_custom(self): """ Add custom initialization here. """ pass def start_server_error(self, error): """ If there's an error when trying to start the onion service """ self.common.log("Mode", "start_server_error") Alert(self.common, error, QtWidgets.QMessageBox.Warning) self.set_server_active.emit(False) self.server_status.stop_server() self.status_bar.clearMessage() self.start_server_error_custom() def start_server_error_custom(self): """ Add custom initialization here. """ pass def cancel_server(self): """ Cancel the server while it is preparing to start """ self.cancel_server_custom() if self.startup_thread: self.common.log("Mode", "cancel_server: quitting startup thread") self.startup_thread.canceled = True self.app.onion.scheduled_key = None self.app.onion.scheduled_auth_cookie = None self.startup_thread.quit() if self.onion_thread: self.common.log("Mode", "cancel_server: quitting onion thread") self.onion_thread.quit() if self.web_thread: self.common.log("Mode", "cancel_server: quitting web thread") self.web_thread.quit() self.stop_server() def cancel_server_custom(self): """ Add custom initialization here. """ pass def stop_server(self): """ Stop the onionshare server. """ self.common.log("Mode", "stop_server") if self.server_status.status != ServerStatus.STATUS_STOPPED: try: self.web.stop(self.app.port) except: # Probably we had no port to begin with (Onion service didn't start) pass self.app.cleanup() self.stop_server_custom() self.set_server_active.emit(False) self.stop_server_finished.emit() def stop_server_custom(self): """ Add custom initialization here. """ pass def handle_tor_broke(self): """ Handle connection from Tor breaking. """ if self.server_status.status != ServerStatus.STATUS_STOPPED: self.server_status.stop_server() self.handle_tor_broke_custom() def handle_tor_broke_custom(self): """ Add custom initialization here. """ pass # Handle web server events def handle_request_load(self, event): """ Handle REQUEST_LOAD event. """ pass def handle_request_started(self, event): """ Handle REQUEST_STARTED event. """ pass def handle_request_rate_limit(self, event): """ Handle REQUEST_RATE_LIMIT event. """ self.stop_server() Alert( self.common, strings._("error_rate_limit"), QtWidgets.QMessageBox.Critical ) def handle_request_progress(self, event): """ Handle REQUEST_PROGRESS event. """ pass def handle_request_canceled(self, event): """ Handle REQUEST_CANCELED event. """ pass def handle_request_upload_file_renamed(self, event): """ Handle REQUEST_UPLOAD_FILE_RENAMED event. """ pass def handle_request_upload_set_dir(self, event): """ Handle REQUEST_UPLOAD_SET_DIR event. """ pass def handle_request_upload_finished(self, event): """ Handle REQUEST_UPLOAD_FINISHED event. """ pass def handle_request_upload_canceled(self, event): """ Handle REQUEST_UPLOAD_CANCELED event. """ pass def handle_request_individual_file_started(self, event): """ Handle REQUEST_INDVIDIDUAL_FILES_STARTED event. Used in both Share and Website modes, so implemented here. """ self.toggle_history.update_indicator(True) self.history.requests_count += 1 self.history.update_requests() item = IndividualFileHistoryItem(self.common, event["data"], event["path"]) self.history.add(event["data"]["id"], item) def handle_request_individual_file_progress(self, event): """ Handle REQUEST_INDVIDIDUAL_FILES_PROGRESS event. Used in both Share and Website modes, so implemented here. """ self.history.update(event["data"]["id"], event["data"]["bytes"]) if self.server_status.status == self.server_status.STATUS_STOPPED: self.history.cancel(event["data"]["id"]) def handle_request_individual_file_canceled(self, event): """ Handle REQUEST_INDVIDIDUAL_FILES_CANCELED event. Used in both Share and Website modes, so implemented here. """ self.history.cancel(event["data"]["id"]) onionshare-2.2/onionshare_gui/mode/file_selection.py000066400000000000000000000364541355066717400230470ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import os from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from ..widgets import Alert, AddFileDialog class DropHereLabel(QtWidgets.QLabel): """ When there are no files or folders in the FileList yet, display the 'drop files here' message and graphic. """ def __init__(self, common, parent, image=False): self.parent = parent super(DropHereLabel, self).__init__(parent=parent) self.common = common self.setAcceptDrops(True) self.setAlignment(QtCore.Qt.AlignCenter) if image: self.setPixmap( QtGui.QPixmap.fromImage( QtGui.QImage( self.common.get_resource_path("images/logo_transparent.png") ) ) ) else: self.setText(strings._("gui_drag_and_drop")) self.setStyleSheet(self.common.css["share_file_selection_drop_here_label"]) self.hide() def dragEnterEvent(self, event): self.parent.drop_here_image.hide() self.parent.drop_here_text.hide() event.accept() class DropCountLabel(QtWidgets.QLabel): """ While dragging files over the FileList, this counter displays the number of files you're dragging. """ def __init__(self, common, parent): self.parent = parent super(DropCountLabel, self).__init__(parent=parent) self.common = common self.setAcceptDrops(True) self.setAlignment(QtCore.Qt.AlignCenter) self.setText(strings._("gui_drag_and_drop")) self.setStyleSheet(self.common.css["share_file_selection_drop_count_label"]) self.hide() def dragEnterEvent(self, event): self.hide() event.accept() class FileList(QtWidgets.QListWidget): """ The list of files and folders in the GUI. """ files_dropped = QtCore.pyqtSignal() files_updated = QtCore.pyqtSignal() def __init__(self, common, parent=None): super(FileList, self).__init__(parent) self.common = common self.setAcceptDrops(True) self.setIconSize(QtCore.QSize(32, 32)) self.setSortingEnabled(True) self.setMinimumHeight(160) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) self.drop_here_image = DropHereLabel(self.common, self, True) self.drop_here_text = DropHereLabel(self.common, self, False) self.drop_count = DropCountLabel(self.common, self) self.resizeEvent(None) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn) def update(self): """ Update the GUI elements based on the current state. """ # file list should have a background image if empty if self.count() == 0: self.drop_here_image.show() self.drop_here_text.show() else: self.drop_here_image.hide() self.drop_here_text.hide() def server_started(self): """ Update the GUI when the server starts, by hiding delete buttons. """ self.setAcceptDrops(False) self.setCurrentItem(None) self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) for index in range(self.count()): self.item(index).item_button.hide() def server_stopped(self): """ Update the GUI when the server stops, by showing delete buttons. """ self.setAcceptDrops(True) self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) for index in range(self.count()): self.item(index).item_button.show() def resizeEvent(self, event): """ When the widget is resized, resize the drop files image and text. """ offset = 70 self.drop_here_image.setGeometry(0, 0, self.width(), self.height() - offset) self.drop_here_text.setGeometry(0, offset, self.width(), self.height() - offset) if self.count() > 0: # Add and delete an empty item, to force all items to get redrawn # This is ugly, but the only way I could figure out how to proceed item = QtWidgets.QListWidgetItem("fake item") self.addItem(item) self.takeItem(self.row(item)) self.update() # Extend any filenames that were truncated to fit the window # We use 200 as a rough guess at how wide the 'file size + delete button' widget is # and extend based on the overall width minus that amount. for index in range(self.count()): metrics = QtGui.QFontMetrics(self.item(index).font()) elided = metrics.elidedText( self.item(index).basename, QtCore.Qt.ElideRight, self.width() - 200 ) self.item(index).setText(elided) def dragEnterEvent(self, event): """ dragEnterEvent for dragging files and directories into the widget. """ if event.mimeData().hasUrls: self.setStyleSheet(self.common.css["share_file_list_drag_enter"]) count = len(event.mimeData().urls()) self.drop_count.setText("+{}".format(count)) size_hint = self.drop_count.sizeHint() self.drop_count.setGeometry( self.width() - size_hint.width() - 10, self.height() - size_hint.height() - 10, size_hint.width(), size_hint.height(), ) self.drop_count.show() event.accept() else: event.ignore() def dragLeaveEvent(self, event): """ dragLeaveEvent for dragging files and directories into the widget. """ self.setStyleSheet(self.common.css["share_file_list_drag_leave"]) self.drop_count.hide() event.accept() self.update() def dragMoveEvent(self, event): """ dragMoveEvent for dragging files and directories into the widget. """ if event.mimeData().hasUrls: event.setDropAction(QtCore.Qt.CopyAction) event.accept() else: event.ignore() def dropEvent(self, event): """ dropEvent for dragging files and directories into the widget. """ if event.mimeData().hasUrls: event.setDropAction(QtCore.Qt.CopyAction) event.accept() for url in event.mimeData().urls(): filename = str(url.toLocalFile()) self.add_file(filename) else: event.ignore() self.setStyleSheet(self.common.css["share_file_list_drag_leave"]) self.drop_count.hide() self.files_dropped.emit() def add_file(self, filename): """ Add a file or directory to this widget. """ filenames = [] for index in range(self.count()): filenames.append(self.item(index).filename) if filename not in filenames: if not os.access(filename, os.R_OK): Alert(self.common, strings._("not_a_readable_file").format(filename)) return fileinfo = QtCore.QFileInfo(filename) ip = QtWidgets.QFileIconProvider() icon = ip.icon(fileinfo) if os.path.isfile(filename): size_bytes = fileinfo.size() size_readable = self.common.human_readable_filesize(size_bytes) else: size_bytes = self.common.dir_size(filename) size_readable = self.common.human_readable_filesize(size_bytes) # Create a new item item = QtWidgets.QListWidgetItem() item.setIcon(icon) item.size_bytes = size_bytes # Item's filename attribute and size labels item.filename = filename item_size = QtWidgets.QLabel(size_readable) item_size.setStyleSheet(self.common.css["share_file_list_item_size"]) item.basename = os.path.basename(filename.rstrip("/")) # Use the basename as the method with which to sort the list metrics = QtGui.QFontMetrics(item.font()) elided = metrics.elidedText( item.basename, QtCore.Qt.ElideRight, self.sizeHint().width() ) item.setData(QtCore.Qt.DisplayRole, elided) # Item's delete button def delete_item(): itemrow = self.row(item) self.takeItem(itemrow) self.files_updated.emit() item.item_button = QtWidgets.QPushButton() item.item_button.setDefault(False) item.item_button.setFlat(True) item.item_button.setIcon( QtGui.QIcon(self.common.get_resource_path("images/file_delete.png")) ) item.item_button.clicked.connect(delete_item) item.item_button.setSizePolicy( QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed ) # Item info widget, with a white background item_info_layout = QtWidgets.QHBoxLayout() item_info_layout.setContentsMargins(0, 0, 0, 0) item_info_layout.addWidget(item_size) item_info_layout.addWidget(item.item_button) item_info = QtWidgets.QWidget() item_info.setObjectName("item-info") item_info.setLayout(item_info_layout) # Create the item's widget and layouts item_hlayout = QtWidgets.QHBoxLayout() item_hlayout.addStretch() item_hlayout.addWidget(item_info) widget = QtWidgets.QWidget() widget.setLayout(item_hlayout) item.setSizeHint(widget.sizeHint()) self.addItem(item) self.setItemWidget(item, widget) self.files_updated.emit() class FileSelection(QtWidgets.QVBoxLayout): """ The list of files and folders in the GUI, as well as buttons to add and delete the files and folders. """ def __init__(self, common, parent): super(FileSelection, self).__init__() self.common = common self.parent = parent self.server_on = False # File list self.file_list = FileList(self.common) self.file_list.itemSelectionChanged.connect(self.update) self.file_list.files_dropped.connect(self.update) self.file_list.files_updated.connect(self.update) # Buttons if self.common.platform == "Darwin": # The macOS sandbox makes it so the Mac version needs separate add files # and folders buttons, in order to use native file selection dialogs self.add_files_button = QtWidgets.QPushButton(strings._("gui_add_files")) self.add_files_button.clicked.connect(self.add_files) self.add_folder_button = QtWidgets.QPushButton(strings._("gui_add_folder")) self.add_folder_button.clicked.connect(self.add_folder) else: self.add_button = QtWidgets.QPushButton(strings._("gui_add")) self.add_button.clicked.connect(self.add) self.delete_button = QtWidgets.QPushButton(strings._("gui_delete")) self.delete_button.clicked.connect(self.delete) button_layout = QtWidgets.QHBoxLayout() button_layout.addStretch() if self.common.platform == "Darwin": button_layout.addWidget(self.add_files_button) button_layout.addWidget(self.add_folder_button) else: button_layout.addWidget(self.add_button) button_layout.addWidget(self.delete_button) # Add the widgets self.addWidget(self.file_list) self.addLayout(button_layout) self.update() def update(self): """ Update the GUI elements based on the current state. """ # All buttons should be hidden if the server is on if self.server_on: if self.common.platform == "Darwin": self.add_files_button.hide() self.add_folder_button.hide() else: self.add_button.hide() self.delete_button.hide() else: if self.common.platform == "Darwin": self.add_files_button.show() self.add_folder_button.show() else: self.add_button.show() # Delete button should be hidden if item isn't selected if len(self.file_list.selectedItems()) == 0: self.delete_button.hide() else: self.delete_button.show() # Update the file list self.file_list.update() def add(self): """ Add button clicked. """ file_dialog = AddFileDialog(self.common, caption=strings._("gui_choose_items")) if file_dialog.exec_() == QtWidgets.QDialog.Accepted: for filename in file_dialog.selectedFiles(): self.file_list.add_file(filename) self.file_list.setCurrentItem(None) self.update() def add_files(self): """ Add files button clicked. """ files = QtWidgets.QFileDialog.getOpenFileNames( self.parent, caption=strings._("gui_choose_items") ) filenames = files[0] for filename in filenames: self.file_list.add_file(filename) def add_folder(self): """ Add folder button clicked. """ filename = QtWidgets.QFileDialog.getExistingDirectory( self.parent, caption=strings._("gui_choose_items"), options=QtWidgets.QFileDialog.ShowDirsOnly, ) self.file_list.add_file(filename) def delete(self): """ Delete button clicked """ selected = self.file_list.selectedItems() for item in selected: itemrow = self.file_list.row(item) self.file_list.takeItem(itemrow) self.file_list.files_updated.emit() self.file_list.setCurrentItem(None) self.update() def server_started(self): """ Gets called when the server starts. """ self.server_on = True self.file_list.server_started() self.update() def server_stopped(self): """ Gets called when the server stops. """ self.server_on = False self.file_list.server_stopped() self.update() def get_num_files(self): """ Returns the total number of files and folders in the list. """ return len(range(self.file_list.count())) def setFocus(self): """ Set the Qt app focus on the file selection box. """ self.file_list.setFocus() onionshare-2.2/onionshare_gui/mode/history.py000066400000000000000000000666341355066717400215670ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import time import subprocess import os from datetime import datetime from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from ..widgets import Alert class HistoryItem(QtWidgets.QWidget): """ The base history item """ STATUS_STARTED = 0 STATUS_FINISHED = 1 STATUS_CANCELED = 2 def __init__(self): super(HistoryItem, self).__init__() def update(self): pass def cancel(self): pass def get_finished_label_text(self, started): """ When an item finishes, returns a string displaying the start/end datetime range. started is a datetime object. """ return self._get_label_text( "gui_all_modes_transfer_finished", "gui_all_modes_transfer_finished_range", started, ) def get_canceled_label_text(self, started): """ When an item is canceled, returns a string displaying the start/end datetime range. started is a datetime object. """ return self._get_label_text( "gui_all_modes_transfer_canceled", "gui_all_modes_transfer_canceled_range", started, ) def _get_label_text(self, string_name, string_range_name, started): """ Return a string that contains a date, or date range. """ ended = datetime.now() if ( started.year == ended.year and started.month == ended.month and started.day == ended.day ): if started.hour == ended.hour and started.minute == ended.minute: text = strings._(string_name).format(started.strftime("%b %d, %I:%M%p")) else: text = strings._(string_range_name).format( started.strftime("%b %d, %I:%M%p"), ended.strftime("%I:%M%p") ) else: text = strings._(string_range_name).format( started.strftime("%b %d, %I:%M%p"), ended.strftime("%b %d, %I:%M%p") ) return text class ShareHistoryItem(HistoryItem): """ Download history item, for share mode """ def __init__(self, common, id, total_bytes): super(ShareHistoryItem, self).__init__() self.common = common self.id = id self.total_bytes = total_bytes self.downloaded_bytes = 0 self.started = time.time() self.started_dt = datetime.fromtimestamp(self.started) self.status = HistoryItem.STATUS_STARTED # Label self.label = QtWidgets.QLabel( strings._("gui_all_modes_transfer_started").format( self.started_dt.strftime("%b %d, %I:%M%p") ) ) # Progress bar self.progress_bar = QtWidgets.QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(total_bytes) self.progress_bar.setValue(0) self.progress_bar.setStyleSheet( self.common.css["downloads_uploads_progress_bar"] ) self.progress_bar.total_bytes = total_bytes # Layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label) layout.addWidget(self.progress_bar) self.setLayout(layout) # Start at 0 self.update(0) def update(self, downloaded_bytes): self.downloaded_bytes = downloaded_bytes self.progress_bar.setValue(downloaded_bytes) if downloaded_bytes == self.progress_bar.total_bytes: pb_fmt = strings._("gui_all_modes_progress_complete").format( self.common.format_seconds(time.time() - self.started) ) # Change the label self.label.setText(self.get_finished_label_text(self.started_dt)) self.status = HistoryItem.STATUS_FINISHED else: elapsed = time.time() - self.started if elapsed < 10: # Wait a couple of seconds for the download rate to stabilize. # This prevents a "Windows copy dialog"-esque experience at # the beginning of the download. pb_fmt = strings._("gui_all_modes_progress_starting").format( self.common.human_readable_filesize(downloaded_bytes) ) else: pb_fmt = strings._("gui_all_modes_progress_eta").format( self.common.human_readable_filesize(downloaded_bytes), self.estimated_time_remaining, ) self.progress_bar.setFormat(pb_fmt) def cancel(self): self.progress_bar.setFormat(strings._("gui_canceled")) self.status = HistoryItem.STATUS_CANCELED @property def estimated_time_remaining(self): return self.common.estimated_time_remaining( self.downloaded_bytes, self.total_bytes, self.started ) class ReceiveHistoryItemFile(QtWidgets.QWidget): def __init__(self, common, filename): super(ReceiveHistoryItemFile, self).__init__() self.common = common self.common.log( "ReceiveHistoryItemFile", "__init__", "filename: {}".format(filename) ) self.filename = filename self.dir = None self.started = datetime.now() # Filename label self.filename_label = QtWidgets.QLabel(self.filename) self.filename_label_width = self.filename_label.width() # File size label self.filesize_label = QtWidgets.QLabel() self.filesize_label.setStyleSheet(self.common.css["receive_file_size"]) self.filesize_label.hide() # Folder button folder_pixmap = QtGui.QPixmap.fromImage( QtGui.QImage(self.common.get_resource_path("images/open_folder.png")) ) folder_icon = QtGui.QIcon(folder_pixmap) self.folder_button = QtWidgets.QPushButton() self.folder_button.clicked.connect(self.open_folder) self.folder_button.setIcon(folder_icon) self.folder_button.setIconSize(folder_pixmap.rect().size()) self.folder_button.setFlat(True) self.folder_button.hide() # Layouts layout = QtWidgets.QHBoxLayout() layout.addWidget(self.filename_label) layout.addWidget(self.filesize_label) layout.addStretch() layout.addWidget(self.folder_button) self.setLayout(layout) def update(self, uploaded_bytes, complete): self.filesize_label.setText(self.common.human_readable_filesize(uploaded_bytes)) self.filesize_label.show() if complete: self.folder_button.show() def rename(self, new_filename): self.filename = new_filename self.filename_label.setText(self.filename) def set_dir(self, dir): self.dir = dir def open_folder(self): """ Open the downloads folder, with the file selected, in a cross-platform manner """ self.common.log("ReceiveHistoryItemFile", "open_folder") if not self.dir: self.common.log( "ReceiveHistoryItemFile", "open_folder", "dir has not been set yet, can't open folder", ) return abs_filename = os.path.join(self.dir, self.filename) # Linux if self.common.platform == "Linux" or self.common.platform == "BSD": try: # If nautilus is available, open it subprocess.Popen(["nautilus", abs_filename]) except: Alert( self.common, strings._("gui_open_folder_error_nautilus").format(abs_filename), ) # macOS elif self.common.platform == "Darwin": subprocess.call(["open", "-R", abs_filename]) # Windows elif self.common.platform == "Windows": subprocess.Popen(["explorer", "/select,{}".format(abs_filename)]) class ReceiveHistoryItem(HistoryItem): def __init__(self, common, id, content_length): super(ReceiveHistoryItem, self).__init__() self.common = common self.id = id self.content_length = content_length self.started = datetime.now() self.status = HistoryItem.STATUS_STARTED # Label self.label = QtWidgets.QLabel( strings._("gui_all_modes_transfer_started").format( self.started.strftime("%b %d, %I:%M%p") ) ) # Progress bar self.progress_bar = QtWidgets.QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) self.progress_bar.setMinimum(0) self.progress_bar.setValue(0) self.progress_bar.setStyleSheet( self.common.css["downloads_uploads_progress_bar"] ) # This layout contains file widgets self.files_layout = QtWidgets.QVBoxLayout() self.files_layout.setContentsMargins(0, 0, 0, 0) files_widget = QtWidgets.QWidget() files_widget.setStyleSheet(self.common.css["receive_file"]) files_widget.setLayout(self.files_layout) # Layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label) layout.addWidget(self.progress_bar) layout.addWidget(files_widget) layout.addStretch() self.setLayout(layout) # We're also making a dictionary of file widgets, to make them easier to access self.files = {} def update(self, data): """ Using the progress from Web, update the progress bar and file size labels for each file """ if data["action"] == "progress": total_uploaded_bytes = 0 for filename in data["progress"]: total_uploaded_bytes += data["progress"][filename]["uploaded_bytes"] # Update the progress bar self.progress_bar.setMaximum(self.content_length) self.progress_bar.setValue(total_uploaded_bytes) elapsed = datetime.now() - self.started if elapsed.seconds < 10: pb_fmt = strings._("gui_all_modes_progress_starting").format( self.common.human_readable_filesize(total_uploaded_bytes) ) else: estimated_time_remaining = self.common.estimated_time_remaining( total_uploaded_bytes, self.content_length, self.started.timestamp() ) pb_fmt = strings._("gui_all_modes_progress_eta").format( self.common.human_readable_filesize(total_uploaded_bytes), estimated_time_remaining, ) # Using list(progress) to avoid "RuntimeError: dictionary changed size during iteration" for filename in list(data["progress"]): # Add a new file if needed if filename not in self.files: self.files[filename] = ReceiveHistoryItemFile(self.common, filename) self.files_layout.addWidget(self.files[filename]) # Update the file self.files[filename].update( data["progress"][filename]["uploaded_bytes"], data["progress"][filename]["complete"], ) elif data["action"] == "rename": self.files[data["old_filename"]].rename(data["new_filename"]) self.files[data["new_filename"]] = self.files.pop(data["old_filename"]) elif data["action"] == "set_dir": self.files[data["filename"]].set_dir(data["dir"]) elif data["action"] == "finished": # Change the status self.status = HistoryItem.STATUS_FINISHED # Hide the progress bar self.progress_bar.hide() # Change the label self.label.setText(self.get_finished_label_text(self.started)) elif data["action"] == "canceled": # Change the status self.status = HistoryItem.STATUS_CANCELED # Hide the progress bar self.progress_bar.hide() # Change the label self.label.setText(self.get_canceled_label_text(self.started)) class IndividualFileHistoryItem(HistoryItem): """ Individual file history item, for share mode viewing of individual files """ def __init__(self, common, data, path): super(IndividualFileHistoryItem, self).__init__() self.status = HistoryItem.STATUS_STARTED self.common = common self.id = id self.path = path self.total_bytes = 0 self.downloaded_bytes = 0 self.started = time.time() self.started_dt = datetime.fromtimestamp(self.started) self.status = HistoryItem.STATUS_STARTED self.directory_listing = "directory_listing" in data # Labels self.timestamp_label = QtWidgets.QLabel( self.started_dt.strftime("%b %d, %I:%M%p") ) self.timestamp_label.setStyleSheet( self.common.css["history_individual_file_timestamp_label"] ) self.path_label = QtWidgets.QLabel("{}".format(self.path)) self.status_code_label = QtWidgets.QLabel() # Progress bar self.progress_bar = QtWidgets.QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.progress_bar.setAlignment(QtCore.Qt.AlignHCenter) self.progress_bar.setValue(0) self.progress_bar.setStyleSheet( self.common.css["downloads_uploads_progress_bar"] ) # Text layout labels_layout = QtWidgets.QHBoxLayout() labels_layout.addWidget(self.timestamp_label) labels_layout.addWidget(self.path_label) labels_layout.addWidget(self.status_code_label) labels_layout.addStretch() # Layout layout = QtWidgets.QVBoxLayout() layout.addLayout(labels_layout) layout.addWidget(self.progress_bar) self.setLayout(layout) # Is a status code already sent? if "status_code" in data: self.status_code_label.setText("{}".format(data["status_code"])) if data["status_code"] >= 200 and data["status_code"] < 300: self.status_code_label.setStyleSheet( self.common.css["history_individual_file_status_code_label_2xx"] ) if data["status_code"] >= 400 and data["status_code"] < 500: self.status_code_label.setStyleSheet( self.common.css["history_individual_file_status_code_label_4xx"] ) self.status = HistoryItem.STATUS_FINISHED self.progress_bar.hide() return else: self.total_bytes = data["filesize"] self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(data["filesize"]) self.progress_bar.total_bytes = data["filesize"] # Start at 0 self.update(0) def update(self, downloaded_bytes): self.downloaded_bytes = downloaded_bytes self.progress_bar.setValue(downloaded_bytes) if downloaded_bytes == self.progress_bar.total_bytes: self.status_code_label.setText("200") self.status_code_label.setStyleSheet( self.common.css["history_individual_file_status_code_label_2xx"] ) self.progress_bar.hide() self.status = HistoryItem.STATUS_FINISHED else: elapsed = time.time() - self.started if elapsed < 10: # Wait a couple of seconds for the download rate to stabilize. # This prevents a "Windows copy dialog"-esque experience at # the beginning of the download. pb_fmt = strings._("gui_all_modes_progress_starting").format( self.common.human_readable_filesize(downloaded_bytes) ) else: pb_fmt = strings._("gui_all_modes_progress_eta").format( self.common.human_readable_filesize(downloaded_bytes), self.estimated_time_remaining, ) self.progress_bar.setFormat(pb_fmt) def cancel(self): self.progress_bar.setFormat(strings._("gui_canceled")) self.status = HistoryItem.STATUS_CANCELED @property def estimated_time_remaining(self): return self.common.estimated_time_remaining( self.downloaded_bytes, self.total_bytes, self.started ) class HistoryItemList(QtWidgets.QScrollArea): """ List of items """ def __init__(self, common): super(HistoryItemList, self).__init__() self.common = common self.items = {} # The layout that holds all of the items self.items_layout = QtWidgets.QVBoxLayout() self.items_layout.setContentsMargins(0, 0, 0, 0) self.items_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) # Wrapper layout that also contains a stretch wrapper_layout = QtWidgets.QVBoxLayout() wrapper_layout.setSizeConstraint(QtWidgets.QLayout.SetMinAndMaxSize) wrapper_layout.addLayout(self.items_layout) wrapper_layout.addStretch() # The internal widget of the scroll area widget = QtWidgets.QWidget() widget.setLayout(wrapper_layout) self.setWidget(widget) self.setWidgetResizable(True) # Other scroll area settings self.setBackgroundRole(QtGui.QPalette.Light) self.verticalScrollBar().rangeChanged.connect(self.resizeScroll) def resizeScroll(self, minimum, maximum): """ Scroll to the bottom of the window when the range changes. """ self.verticalScrollBar().setValue(maximum) def add(self, id, item): """ Add a new item. Override this method. """ self.items[id] = item self.items_layout.addWidget(item) def update(self, id, data): """ Update an item. Override this method. """ if id in self.items: self.items[id].update(data) def cancel(self, id): """ Cancel an item. Override this method. """ if id in self.items: self.items[id].cancel() def reset(self): """ Reset all items, emptying the list. Override this method. """ for key, item in self.items.copy().items(): self.items_layout.removeWidget(item) item.close() del self.items[key] class History(QtWidgets.QWidget): """ A history of what's happened so far in this mode. This contains an internal object full of a scrollable list of items. """ def __init__(self, common, empty_image, empty_text, header_text, mode=""): super(History, self).__init__() self.common = common self.mode = mode self.setMinimumWidth(350) # In progress and completed counters self.in_progress_count = 0 self.completed_count = 0 self.requests_count = 0 # In progress, completed, and requests labels self.in_progress_label = QtWidgets.QLabel() self.in_progress_label.setStyleSheet(self.common.css["mode_info_label"]) self.completed_label = QtWidgets.QLabel() self.completed_label.setStyleSheet(self.common.css["mode_info_label"]) self.requests_label = QtWidgets.QLabel() self.requests_label.setStyleSheet(self.common.css["mode_info_label"]) # Header self.header_label = QtWidgets.QLabel(header_text) self.header_label.setStyleSheet(self.common.css["downloads_uploads_label"]) self.clear_button = QtWidgets.QPushButton( strings._("gui_all_modes_clear_history") ) self.clear_button.setStyleSheet(self.common.css["downloads_uploads_clear"]) self.clear_button.setFlat(True) self.clear_button.clicked.connect(self.reset) header_layout = QtWidgets.QHBoxLayout() header_layout.addWidget(self.header_label) header_layout.addStretch() header_layout.addWidget(self.in_progress_label) header_layout.addWidget(self.completed_label) header_layout.addWidget(self.requests_label) header_layout.addWidget(self.clear_button) # When there are no items self.empty_image = QtWidgets.QLabel() self.empty_image.setAlignment(QtCore.Qt.AlignCenter) self.empty_image.setPixmap(empty_image) self.empty_text = QtWidgets.QLabel(empty_text) self.empty_text.setAlignment(QtCore.Qt.AlignCenter) self.empty_text.setStyleSheet(self.common.css["downloads_uploads_empty_text"]) empty_layout = QtWidgets.QVBoxLayout() empty_layout.addStretch() empty_layout.addWidget(self.empty_image) empty_layout.addWidget(self.empty_text) empty_layout.addStretch() self.empty = QtWidgets.QWidget() self.empty.setStyleSheet(self.common.css["downloads_uploads_empty"]) self.empty.setLayout(empty_layout) # When there are items self.item_list = HistoryItemList(self.common) self.not_empty_layout = QtWidgets.QVBoxLayout() self.not_empty_layout.addLayout(header_layout) self.not_empty_layout.addWidget(self.item_list) self.not_empty = QtWidgets.QWidget() self.not_empty.setLayout(self.not_empty_layout) # Layout layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(self.empty) layout.addWidget(self.not_empty) self.setLayout(layout) # Reset once at the beginning self.reset() def add(self, id, item): """ Add a new item. """ self.common.log("History", "add", "id: {}, item: {}".format(id, item)) # Hide empty, show not empty self.empty.hide() self.not_empty.show() # Add it to the list self.item_list.add(id, item) def update(self, id, data): """ Update an item. """ self.item_list.update(id, data) def cancel(self, id): """ Cancel an item. """ self.item_list.cancel(id) def reset(self): """ Reset all items. """ self.item_list.reset() if len(self.item_list.items) == 0: # Hide not empty, show empty self.not_empty.hide() self.empty.show() # Reset in-progress counter self.in_progress_count = 0 self.update_in_progress() # Reset completed counter self.completed_count = 0 self.update_completed() # Reset web requests counter self.requests_count = 0 self.update_requests() def update_completed(self): """ Update the 'completed' widget. """ if self.completed_count == 0: image = self.common.get_resource_path("images/history_completed_none.png") else: image = self.common.get_resource_path("images/history_completed.png") self.completed_label.setText( ' {1:d}'.format(image, self.completed_count) ) self.completed_label.setToolTip( strings._("history_completed_tooltip").format(self.completed_count) ) def update_in_progress(self): """ Update the 'in progress' widget. """ if self.in_progress_count == 0: image = self.common.get_resource_path("images/history_in_progress_none.png") else: image = self.common.get_resource_path("images/history_in_progress.png") self.in_progress_label.setText( ' {1:d}'.format(image, self.in_progress_count) ) self.in_progress_label.setToolTip( strings._("history_in_progress_tooltip").format(self.in_progress_count) ) def update_requests(self): """ Update the 'web requests' widget. """ if self.requests_count == 0: image = self.common.get_resource_path("images/history_requests_none.png") else: image = self.common.get_resource_path("images/history_requests.png") self.requests_label.setText( ' {1:d}'.format(image, self.requests_count) ) self.requests_label.setToolTip( strings._("history_requests_tooltip").format(self.requests_count) ) class ToggleHistory(QtWidgets.QPushButton): """ Widget for toggling showing or hiding the history, as well as keeping track of the indicator counter if it's hidden """ def __init__(self, common, current_mode, history_widget, icon, selected_icon): super(ToggleHistory, self).__init__() self.common = common self.current_mode = current_mode self.history_widget = history_widget self.icon = icon self.selected_icon = selected_icon # Toggle button self.setDefault(False) self.setFixedWidth(35) self.setFixedHeight(30) self.setFlat(True) self.setIcon(icon) self.clicked.connect(self.toggle_clicked) # Keep track of indicator self.indicator_count = 0 self.indicator_label = QtWidgets.QLabel(parent=self) self.indicator_label.setStyleSheet( self.common.css["download_uploads_indicator"] ) self.update_indicator() def update_indicator(self, increment=False): """ Update the display of the indicator count. If increment is True, then only increment the counter if History is hidden. """ if increment and not self.history_widget.isVisible(): self.indicator_count += 1 self.indicator_label.setText("{}".format(self.indicator_count)) if self.indicator_count == 0: self.indicator_label.hide() else: size = self.indicator_label.sizeHint() self.indicator_label.setGeometry( 35 - size.width(), 0, size.width(), size.height() ) self.indicator_label.show() def toggle_clicked(self): """ Toggle showing and hiding the history widget """ self.common.log("ToggleHistory", "toggle_clicked") if self.history_widget.isVisible(): self.history_widget.hide() self.setIcon(self.icon) self.setFlat(True) else: self.history_widget.show() self.setIcon(self.selected_icon) self.setFlat(False) # Reset the indicator count self.indicator_count = 0 self.update_indicator() onionshare-2.2/onionshare_gui/mode/receive_mode/000077500000000000000000000000001355066717400221235ustar00rootroot00000000000000onionshare-2.2/onionshare_gui/mode/receive_mode/__init__.py000066400000000000000000000177131355066717400242450ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.web import Web from ..history import History, ToggleHistory, ReceiveHistoryItem from .. import Mode class ReceiveMode(Mode): """ Parts of the main window UI for receiving files. """ def init(self): """ Custom initialization for ReceiveMode. """ # Create the Web object self.web = Web(self.common, True, "receive") # Server status self.server_status.set_mode("receive") self.server_status.server_started_finished.connect(self.update_primary_action) self.server_status.server_stopped.connect(self.update_primary_action) self.server_status.server_canceled.connect(self.update_primary_action) # Tell server_status about web, then update self.server_status.web = self.web self.server_status.update() # Upload history self.history = History( self.common, QtGui.QPixmap.fromImage( QtGui.QImage( self.common.get_resource_path("images/receive_icon_transparent.png") ) ), strings._("gui_receive_mode_no_files"), strings._("gui_all_modes_history"), ) self.history.hide() # Toggle history self.toggle_history = ToggleHistory( self.common, self, self.history, QtGui.QIcon( self.common.get_resource_path("images/receive_icon_toggle.png") ), QtGui.QIcon( self.common.get_resource_path("images/receive_icon_toggle_selected.png") ), ) # Receive mode warning receive_warning = QtWidgets.QLabel(strings._("gui_receive_mode_warning")) receive_warning.setMinimumHeight(80) receive_warning.setWordWrap(True) # Top bar top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addStretch() top_bar_layout.addWidget(self.toggle_history) # Main layout self.main_layout = QtWidgets.QVBoxLayout() self.main_layout.addLayout(top_bar_layout) self.main_layout.addWidget(receive_warning) self.main_layout.addWidget(self.primary_action) self.main_layout.addStretch() self.main_layout.addWidget(self.min_width_widget) # Wrapper layout self.wrapper_layout = QtWidgets.QHBoxLayout() self.wrapper_layout.addLayout(self.main_layout) self.wrapper_layout.addWidget(self.history, stretch=1) self.setLayout(self.wrapper_layout) def get_stop_server_autostop_timer_text(self): """ Return the string to put on the stop server button, if there's an auto-stop timer """ return strings._("gui_receive_stop_server_autostop_timer") def autostop_timer_finished_should_stop_server(self): """ The auto-stop timer expired, should we stop the server? Returns a bool """ # If there were no attempts to upload files, or all uploads are done, we can stop if ( self.web.receive_mode.cur_history_id == 0 or not self.web.receive_mode.uploads_in_progress ): self.server_status.stop_server() self.server_status_label.setText(strings._("close_on_autostop_timer")) return True # An upload is probably still running - hold off on stopping the share, but block new shares. else: self.server_status_label.setText( strings._("gui_receive_mode_autostop_timer_waiting") ) self.web.receive_mode.can_upload = False return False def start_server_custom(self): """ Starting the server. """ # Reset web counters self.web.receive_mode.cur_history_id = 0 self.web.reset_invalid_passwords() # Hide and reset the uploads if we have previously shared self.reset_info_counters() def start_server_step2_custom(self): """ Step 2 in starting the server. """ # Continue self.starting_server_step3.emit() self.start_server_finished.emit() def handle_tor_broke_custom(self): """ Connection to Tor broke. """ self.primary_action.hide() def handle_request_load(self, event): """ Handle REQUEST_LOAD event. """ self.system_tray.showMessage( strings._("systray_page_loaded_title"), strings._("systray_page_loaded_message"), ) def handle_request_started(self, event): """ Handle REQUEST_STARTED event. """ item = ReceiveHistoryItem( self.common, event["data"]["id"], event["data"]["content_length"] ) self.history.add(event["data"]["id"], item) self.toggle_history.update_indicator(True) self.history.in_progress_count += 1 self.history.update_in_progress() self.system_tray.showMessage( strings._("systray_receive_started_title"), strings._("systray_receive_started_message"), ) def handle_request_progress(self, event): """ Handle REQUEST_PROGRESS event. """ self.history.update( event["data"]["id"], {"action": "progress", "progress": event["data"]["progress"]}, ) def handle_request_upload_file_renamed(self, event): """ Handle REQUEST_UPLOAD_FILE_RENAMED event. """ self.history.update( event["data"]["id"], { "action": "rename", "old_filename": event["data"]["old_filename"], "new_filename": event["data"]["new_filename"], }, ) def handle_request_upload_set_dir(self, event): """ Handle REQUEST_UPLOAD_SET_DIR event. """ self.history.update( event["data"]["id"], { "action": "set_dir", "filename": event["data"]["filename"], "dir": event["data"]["dir"], }, ) def handle_request_upload_finished(self, event): """ Handle REQUEST_UPLOAD_FINISHED event. """ self.history.update(event["data"]["id"], {"action": "finished"}) self.history.completed_count += 1 self.history.in_progress_count -= 1 self.history.update_completed() self.history.update_in_progress() def handle_request_upload_canceled(self, event): """ Handle REQUEST_UPLOAD_CANCELED event. """ self.history.update(event["data"]["id"], {"action": "canceled"}) self.history.in_progress_count -= 1 self.history.update_in_progress() def on_reload_settings(self): """ We should be ok to re-enable the 'Start Receive Mode' button now. """ self.primary_action.show() def reset_info_counters(self): """ Set the info counters back to zero. """ self.history.reset() self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() def update_primary_action(self): self.common.log("ReceiveMode", "update_primary_action") onionshare-2.2/onionshare_gui/mode/share_mode/000077500000000000000000000000001355066717400216035ustar00rootroot00000000000000onionshare-2.2/onionshare_gui/mode/share_mode/__init__.py000066400000000000000000000343301355066717400237170ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import os from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.onion import * from onionshare.common import Common from onionshare.web import Web from ..file_selection import FileSelection from .threads import CompressThread from .. import Mode from ..history import History, ToggleHistory, ShareHistoryItem from ...widgets import Alert class ShareMode(Mode): """ Parts of the main window UI for sharing files. """ def init(self): """ Custom initialization for ReceiveMode. """ # Threads start out as None self.compress_thread = None # Create the Web object self.web = Web(self.common, True, "share") # File selection self.file_selection = FileSelection(self.common, self) if self.filenames: for filename in self.filenames: self.file_selection.file_list.add_file(filename) # Server status self.server_status.set_mode("share", self.file_selection) self.server_status.server_started.connect(self.file_selection.server_started) self.server_status.server_stopped.connect(self.file_selection.server_stopped) self.server_status.server_stopped.connect(self.update_primary_action) self.server_status.server_canceled.connect(self.file_selection.server_stopped) self.server_status.server_canceled.connect(self.update_primary_action) self.file_selection.file_list.files_updated.connect(self.server_status.update) self.file_selection.file_list.files_updated.connect(self.update_primary_action) # Tell server_status about web, then update self.server_status.web = self.web self.server_status.update() # Filesize warning self.filesize_warning = QtWidgets.QLabel() self.filesize_warning.setWordWrap(True) self.filesize_warning.setStyleSheet(self.common.css["share_filesize_warning"]) self.filesize_warning.hide() # Download history self.history = History( self.common, QtGui.QPixmap.fromImage( QtGui.QImage( self.common.get_resource_path("images/share_icon_transparent.png") ) ), strings._("gui_share_mode_no_files"), strings._("gui_all_modes_history"), ) self.history.hide() # Info label self.info_label = QtWidgets.QLabel() self.info_label.hide() # Toggle history self.toggle_history = ToggleHistory( self.common, self, self.history, QtGui.QIcon(self.common.get_resource_path("images/share_icon_toggle.png")), QtGui.QIcon( self.common.get_resource_path("images/share_icon_toggle_selected.png") ), ) # Top bar top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() top_bar_layout.addWidget(self.toggle_history) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) self.primary_action.hide() self.update_primary_action() # Status bar, zip progress bar self._zip_progress_bar = None # Main layout self.main_layout = QtWidgets.QVBoxLayout() self.main_layout.addLayout(top_bar_layout) self.main_layout.addLayout(self.file_selection) self.main_layout.addWidget(self.primary_action) self.main_layout.addWidget(self.min_width_widget) # Wrapper layout self.wrapper_layout = QtWidgets.QHBoxLayout() self.wrapper_layout.addLayout(self.main_layout) self.wrapper_layout.addWidget(self.history, stretch=1) self.setLayout(self.wrapper_layout) # Always start with focus on file selection self.file_selection.setFocus() def get_stop_server_autostop_timer_text(self): """ Return the string to put on the stop server button, if there's an auto-stop timer """ return strings._("gui_share_stop_server_autostop_timer") def autostop_timer_finished_should_stop_server(self): """ The auto-stop timer expired, should we stop the server? Returns a bool """ # If there were no attempts to download the share, or all downloads are done, we can stop if self.web.share_mode.cur_history_id == 0 or self.web.done: self.server_status.stop_server() self.server_status_label.setText(strings._("close_on_autostop_timer")) return True # A download is probably still running - hold off on stopping the share else: self.server_status_label.setText( strings._("gui_share_mode_autostop_timer_waiting") ) return False def start_server_custom(self): """ Starting the server. """ # Reset web counters self.web.share_mode.cur_history_id = 0 self.web.reset_invalid_passwords() # Hide and reset the downloads if we have previously shared self.reset_info_counters() def start_server_step2_custom(self): """ Step 2 in starting the server. Zipping up files. """ # Add progress bar to the status bar, indicating the compressing of files. self._zip_progress_bar = ZipProgressBar(self.common, 0) self.filenames = [] for index in range(self.file_selection.file_list.count()): self.filenames.append(self.file_selection.file_list.item(index).filename) self._zip_progress_bar.total_files_size = ShareMode._compute_total_size( self.filenames ) self.status_bar.insertWidget(0, self._zip_progress_bar) # prepare the files for sending in a new thread self.compress_thread = CompressThread(self) self.compress_thread.success.connect(self.starting_server_step3.emit) self.compress_thread.success.connect(self.start_server_finished.emit) self.compress_thread.error.connect(self.starting_server_error.emit) self.server_status.server_canceled.connect(self.compress_thread.cancel) self.compress_thread.start() def start_server_step3_custom(self): """ Step 3 in starting the server. Remove zip progess bar, and display large filesize warning, if applicable. """ # Remove zip progress bar if self._zip_progress_bar is not None: self.status_bar.removeWidget(self._zip_progress_bar) self._zip_progress_bar = None # Warn about sending large files over Tor if self.web.share_mode.download_filesize >= 157286400: # 150mb self.filesize_warning.setText(strings._("large_filesize")) self.filesize_warning.show() def start_server_error_custom(self): """ Start server error. """ if self._zip_progress_bar is not None: self.status_bar.removeWidget(self._zip_progress_bar) self._zip_progress_bar = None def stop_server_custom(self): """ Stop server. """ # Remove the progress bar if self._zip_progress_bar is not None: self.status_bar.removeWidget(self._zip_progress_bar) self._zip_progress_bar = None self.filesize_warning.hide() self.history.in_progress_count = 0 self.history.completed_count = 0 self.history.update_in_progress() self.file_selection.file_list.adjustSize() def cancel_server_custom(self): """ Stop the compression thread on cancel """ if self.compress_thread: self.common.log("ShareMode", "cancel_server: quitting compress thread") self.compress_thread.quit() def handle_tor_broke_custom(self): """ Connection to Tor broke. """ self.primary_action.hide() def handle_request_started(self, event): """ Handle REQUEST_STARTED event. """ if event["data"]["use_gzip"]: filesize = self.web.share_mode.gzip_filesize else: filesize = self.web.share_mode.download_filesize item = ShareHistoryItem(self.common, event["data"]["id"], filesize) self.history.add(event["data"]["id"], item) self.toggle_history.update_indicator(True) self.history.in_progress_count += 1 self.history.update_in_progress() self.system_tray.showMessage( strings._("systray_share_started_title"), strings._("systray_share_started_message"), ) def handle_request_progress(self, event): """ Handle REQUEST_PROGRESS event. """ self.history.update(event["data"]["id"], event["data"]["bytes"]) # Is the download complete? if event["data"]["bytes"] == self.web.share_mode.filesize: self.system_tray.showMessage( strings._("systray_share_completed_title"), strings._("systray_share_completed_message"), ) # Update completed and in progress labels self.history.completed_count += 1 self.history.in_progress_count -= 1 self.history.update_completed() self.history.update_in_progress() # Close on finish? if self.common.settings.get("close_after_first_download"): self.server_status.stop_server() self.status_bar.clearMessage() self.server_status_label.setText(strings._("closing_automatically")) else: if self.server_status.status == self.server_status.STATUS_STOPPED: self.history.cancel(event["data"]["id"]) self.history.in_progress_count = 0 self.history.update_in_progress() def handle_request_canceled(self, event): """ Handle REQUEST_CANCELED event. """ self.history.cancel(event["data"]["id"]) # Update in progress count self.history.in_progress_count -= 1 self.history.update_in_progress() self.system_tray.showMessage( strings._("systray_share_canceled_title"), strings._("systray_share_canceled_message"), ) def on_reload_settings(self): """ If there were some files listed for sharing, we should be ok to re-enable the 'Start Sharing' button now. """ if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() self.info_label.show() def update_primary_action(self): self.common.log("ShareMode", "update_primary_action") # Show or hide primary action layout file_count = self.file_selection.file_list.count() if file_count > 0: self.primary_action.show() self.info_label.show() # Update the file count in the info label total_size_bytes = 0 for index in range(self.file_selection.file_list.count()): item = self.file_selection.file_list.item(index) total_size_bytes += item.size_bytes total_size_readable = self.common.human_readable_filesize(total_size_bytes) if file_count > 1: self.info_label.setText( strings._("gui_file_info").format(file_count, total_size_readable) ) else: self.info_label.setText( strings._("gui_file_info_single").format( file_count, total_size_readable ) ) else: self.primary_action.hide() self.info_label.hide() def reset_info_counters(self): """ Set the info counters back to zero. """ self.history.reset() self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() @staticmethod def _compute_total_size(filenames): total_size = 0 for filename in filenames: if os.path.isfile(filename): total_size += os.path.getsize(filename) if os.path.isdir(filename): total_size += Common.dir_size(filename) return total_size class ZipProgressBar(QtWidgets.QProgressBar): update_processed_size_signal = QtCore.pyqtSignal(int) def __init__(self, common, total_files_size): super(ZipProgressBar, self).__init__() self.common = common self.setMaximumHeight(20) self.setMinimumWidth(200) self.setValue(0) self.setFormat(strings._("zip_progress_bar_format")) self.setStyleSheet(self.common.css["share_zip_progess_bar"]) self._total_files_size = total_files_size self._processed_size = 0 self.update_processed_size_signal.connect(self.update_processed_size) @property def total_files_size(self): return self._total_files_size @total_files_size.setter def total_files_size(self, val): self._total_files_size = val @property def processed_size(self): return self._processed_size @processed_size.setter def processed_size(self, val): self.update_processed_size(val) def update_processed_size(self, val): self._processed_size = val if self.processed_size < self.total_files_size: self.setValue(int((self.processed_size * 100) / self.total_files_size)) elif self.total_files_size != 0: self.setValue(100) else: self.setValue(0) onionshare-2.2/onionshare_gui/mode/share_mode/threads.py000066400000000000000000000041461355066717400236140ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore class CompressThread(QtCore.QThread): """ Compresses files to be shared """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def __init__(self, mode): super(CompressThread, self).__init__() self.mode = mode self.mode.common.log("CompressThread", "__init__") # prepare files to share def set_processed_size(self, x): if self.mode._zip_progress_bar != None: self.mode._zip_progress_bar.update_processed_size_signal.emit(x) def run(self): self.mode.common.log("CompressThread", "run") try: self.mode.web.share_mode.set_file_info( self.mode.filenames, processed_size_callback=self.set_processed_size ) self.success.emit() self.mode.app.cleanup_filenames += ( self.mode.web.share_mode.cleanup_filenames ) except OSError as e: self.error.emit(e.strerror) def cancel(self): self.mode.common.log("CompressThread", "cancel") # Let the Web and ZipWriter objects know that we're canceling compression early self.mode.web.cancel_compression = True try: self.mode.web.zip_writer.cancel_compression = True except AttributeError: # we never made it as far as creating a ZipWriter object pass onionshare-2.2/onionshare_gui/mode/website_mode/000077500000000000000000000000001355066717400221435ustar00rootroot00000000000000onionshare-2.2/onionshare_gui/mode/website_mode/__init__.py000066400000000000000000000214661355066717400242650ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import os import random import string from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.onion import * from onionshare.common import Common from onionshare.web import Web from ..file_selection import FileSelection from .. import Mode from ..history import History, ToggleHistory from ...widgets import Alert class WebsiteMode(Mode): """ Parts of the main window UI for sharing files. """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def init(self): """ Custom initialization for ReceiveMode. """ # Create the Web object self.web = Web(self.common, True, "website") # File selection self.file_selection = FileSelection(self.common, self) if self.filenames: for filename in self.filenames: self.file_selection.file_list.add_file(filename) # Server status self.server_status.set_mode("website", self.file_selection) self.server_status.server_started.connect(self.file_selection.server_started) self.server_status.server_stopped.connect(self.file_selection.server_stopped) self.server_status.server_stopped.connect(self.update_primary_action) self.server_status.server_canceled.connect(self.file_selection.server_stopped) self.server_status.server_canceled.connect(self.update_primary_action) self.file_selection.file_list.files_updated.connect(self.server_status.update) self.file_selection.file_list.files_updated.connect(self.update_primary_action) # Tell server_status about web, then update self.server_status.web = self.web self.server_status.update() # Filesize warning self.filesize_warning = QtWidgets.QLabel() self.filesize_warning.setWordWrap(True) self.filesize_warning.setStyleSheet(self.common.css["share_filesize_warning"]) self.filesize_warning.hide() # Download history self.history = History( self.common, QtGui.QPixmap.fromImage( QtGui.QImage( self.common.get_resource_path("images/share_icon_transparent.png") ) ), strings._("gui_website_mode_no_files"), strings._("gui_all_modes_history"), "website", ) self.history.in_progress_label.hide() self.history.completed_label.hide() self.history.hide() # Info label self.info_label = QtWidgets.QLabel() self.info_label.hide() # Toggle history self.toggle_history = ToggleHistory( self.common, self, self.history, QtGui.QIcon(self.common.get_resource_path("images/share_icon_toggle.png")), QtGui.QIcon( self.common.get_resource_path("images/share_icon_toggle_selected.png") ), ) # Top bar top_bar_layout = QtWidgets.QHBoxLayout() top_bar_layout.addWidget(self.info_label) top_bar_layout.addStretch() top_bar_layout.addWidget(self.toggle_history) # Primary action layout self.primary_action_layout.addWidget(self.filesize_warning) self.primary_action.hide() self.update_primary_action() # Main layout self.main_layout = QtWidgets.QVBoxLayout() self.main_layout.addLayout(top_bar_layout) self.main_layout.addLayout(self.file_selection) self.main_layout.addWidget(self.primary_action) self.main_layout.addWidget(self.min_width_widget) # Wrapper layout self.wrapper_layout = QtWidgets.QHBoxLayout() self.wrapper_layout.addLayout(self.main_layout) self.wrapper_layout.addWidget(self.history, stretch=1) self.setLayout(self.wrapper_layout) # Always start with focus on file selection self.file_selection.setFocus() def get_stop_server_autostop_timer_text(self): """ Return the string to put on the stop server button, if there's an auto-stop timer """ return strings._("gui_share_stop_server_autostop_timer") def autostop_timer_finished_should_stop_server(self): """ The auto-stop timer expired, should we stop the server? Returns a bool """ self.server_status.stop_server() self.server_status_label.setText(strings._("close_on_autostop_timer")) return True def start_server_custom(self): """ Starting the server. """ # Reset web counters self.web.website_mode.visit_count = 0 self.web.reset_invalid_passwords() # Hide and reset the downloads if we have previously shared self.reset_info_counters() def start_server_step2_custom(self): """ Step 2 in starting the server. Zipping up files. """ self.filenames = [] for index in range(self.file_selection.file_list.count()): self.filenames.append(self.file_selection.file_list.item(index).filename) # Continue self.starting_server_step3.emit() self.start_server_finished.emit() def start_server_step3_custom(self): """ Step 3 in starting the server. Display large filesize warning, if applicable. """ self.web.website_mode.set_file_info(self.filenames) self.success.emit() def start_server_error_custom(self): """ Start server error. """ if self._zip_progress_bar is not None: self.status_bar.removeWidget(self._zip_progress_bar) self._zip_progress_bar = None def stop_server_custom(self): """ Stop server. """ self.filesize_warning.hide() self.history.completed_count = 0 self.file_selection.file_list.adjustSize() def cancel_server_custom(self): """ Log that the server has been cancelled """ self.common.log("WebsiteMode", "cancel_server") def handle_tor_broke_custom(self): """ Connection to Tor broke. """ self.primary_action.hide() def on_reload_settings(self): """ If there were some files listed for sharing, we should be ok to re-enable the 'Start Sharing' button now. """ if self.server_status.file_selection.get_num_files() > 0: self.primary_action.show() self.info_label.show() def update_primary_action(self): self.common.log("WebsiteMode", "update_primary_action") # Show or hide primary action layout file_count = self.file_selection.file_list.count() if file_count > 0: self.primary_action.show() self.info_label.show() # Update the file count in the info label total_size_bytes = 0 for index in range(self.file_selection.file_list.count()): item = self.file_selection.file_list.item(index) total_size_bytes += item.size_bytes total_size_readable = self.common.human_readable_filesize(total_size_bytes) if file_count > 1: self.info_label.setText( strings._("gui_file_info").format(file_count, total_size_readable) ) else: self.info_label.setText( strings._("gui_file_info_single").format( file_count, total_size_readable ) ) else: self.primary_action.hide() self.info_label.hide() def reset_info_counters(self): """ Set the info counters back to zero. """ self.history.reset() self.toggle_history.indicator_count = 0 self.toggle_history.update_indicator() @staticmethod def _compute_total_size(filenames): total_size = 0 for filename in filenames: if os.path.isfile(filename): total_size += os.path.getsize(filename) if os.path.isdir(filename): total_size += Common.dir_size(filename) return total_size onionshare-2.2/onionshare_gui/onionshare_gui.py000066400000000000000000000746241355066717400221510ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import queue from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.web import Web from .mode.share_mode import ShareMode from .mode.receive_mode import ReceiveMode from .mode.website_mode import WebsiteMode from .tor_connection_dialog import TorConnectionDialog from .settings_dialog import SettingsDialog from .widgets import Alert from .update_checker import UpdateThread from .server_status import ServerStatus class OnionShareGui(QtWidgets.QMainWindow): """ OnionShareGui is the main window for the GUI that contains all of the GUI elements. """ MODE_SHARE = "share" MODE_RECEIVE = "receive" MODE_WEBSITE = "website" def __init__( self, common, onion, qtapp, app, filenames, config=False, local_only=False ): super(OnionShareGui, self).__init__() self.common = common self.common.log("OnionShareGui", "__init__") self.setMinimumWidth(820) self.setMinimumHeight(660) self.onion = onion self.qtapp = qtapp self.app = app self.local_only = local_only self.mode = self.MODE_SHARE self.setWindowTitle("OnionShare") self.setWindowIcon( QtGui.QIcon(self.common.get_resource_path("images/logo.png")) ) # Load settings, if a custom config was passed in self.config = config if self.config: self.common.load_settings(self.config) else: self.common.load_settings() strings.load_strings(self.common) # System tray menu = QtWidgets.QMenu() self.settings_action = menu.addAction(strings._("gui_settings_window_title")) self.settings_action.triggered.connect(self.open_settings) self.help_action = menu.addAction(strings._("gui_settings_button_help")) self.help_action.triggered.connect(lambda: SettingsDialog.help_clicked(self)) exit_action = menu.addAction(strings._("systray_menu_exit")) exit_action.triggered.connect(self.close) self.system_tray = QtWidgets.QSystemTrayIcon(self) # The convention is Mac systray icons are always grayscale if self.common.platform == "Darwin": self.system_tray.setIcon( QtGui.QIcon(self.common.get_resource_path("images/logo_grayscale.png")) ) else: self.system_tray.setIcon( QtGui.QIcon(self.common.get_resource_path("images/logo.png")) ) self.system_tray.setContextMenu(menu) self.system_tray.show() # Mode switcher, to switch between share files and receive files self.share_mode_button = QtWidgets.QPushButton( strings._("gui_mode_share_button") ) self.share_mode_button.setFixedHeight(50) self.share_mode_button.clicked.connect(self.share_mode_clicked) self.receive_mode_button = QtWidgets.QPushButton( strings._("gui_mode_receive_button") ) self.receive_mode_button.setFixedHeight(50) self.receive_mode_button.clicked.connect(self.receive_mode_clicked) self.website_mode_button = QtWidgets.QPushButton( strings._("gui_mode_website_button") ) self.website_mode_button.setFixedHeight(50) self.website_mode_button.clicked.connect(self.website_mode_clicked) self.settings_button = QtWidgets.QPushButton() self.settings_button.setDefault(False) self.settings_button.setFixedWidth(40) self.settings_button.setFixedHeight(50) self.settings_button.setIcon( QtGui.QIcon(self.common.get_resource_path("images/settings.png")) ) self.settings_button.clicked.connect(self.open_settings) self.settings_button.setStyleSheet(self.common.css["settings_button"]) mode_switcher_layout = QtWidgets.QHBoxLayout() mode_switcher_layout.setSpacing(0) mode_switcher_layout.addWidget(self.share_mode_button) mode_switcher_layout.addWidget(self.receive_mode_button) mode_switcher_layout.addWidget(self.website_mode_button) mode_switcher_layout.addWidget(self.settings_button) # Server status indicator on the status bar self.server_status_image_stopped = QtGui.QImage( self.common.get_resource_path("images/server_stopped.png") ) self.server_status_image_working = QtGui.QImage( self.common.get_resource_path("images/server_working.png") ) self.server_status_image_started = QtGui.QImage( self.common.get_resource_path("images/server_started.png") ) self.server_status_image_label = QtWidgets.QLabel() self.server_status_image_label.setFixedWidth(20) self.server_status_label = QtWidgets.QLabel("") self.server_status_label.setStyleSheet( self.common.css["server_status_indicator_label"] ) server_status_indicator_layout = QtWidgets.QHBoxLayout() server_status_indicator_layout.addWidget(self.server_status_image_label) server_status_indicator_layout.addWidget(self.server_status_label) self.server_status_indicator = QtWidgets.QWidget() self.server_status_indicator.setLayout(server_status_indicator_layout) # Status bar self.status_bar = QtWidgets.QStatusBar() self.status_bar.setSizeGripEnabled(False) self.status_bar.setStyleSheet(self.common.css["status_bar"]) self.status_bar.addPermanentWidget(self.server_status_indicator) self.setStatusBar(self.status_bar) # Share mode self.share_mode = ShareMode( self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, filenames, self.local_only, ) self.share_mode.init() self.share_mode.server_status.server_started.connect( self.update_server_status_indicator ) self.share_mode.server_status.server_stopped.connect( self.update_server_status_indicator ) self.share_mode.start_server_finished.connect( self.update_server_status_indicator ) self.share_mode.stop_server_finished.connect( self.update_server_status_indicator ) self.share_mode.stop_server_finished.connect(self.stop_server_finished) self.share_mode.start_server_finished.connect(self.clear_message) self.share_mode.server_status.button_clicked.connect(self.clear_message) self.share_mode.server_status.url_copied.connect(self.copy_url) self.share_mode.server_status.hidservauth_copied.connect(self.copy_hidservauth) self.share_mode.set_server_active.connect(self.set_server_active) # Receive mode self.receive_mode = ReceiveMode( self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, None, self.local_only, ) self.receive_mode.init() self.receive_mode.server_status.server_started.connect( self.update_server_status_indicator ) self.receive_mode.server_status.server_stopped.connect( self.update_server_status_indicator ) self.receive_mode.start_server_finished.connect( self.update_server_status_indicator ) self.receive_mode.stop_server_finished.connect( self.update_server_status_indicator ) self.receive_mode.stop_server_finished.connect(self.stop_server_finished) self.receive_mode.start_server_finished.connect(self.clear_message) self.receive_mode.server_status.button_clicked.connect(self.clear_message) self.receive_mode.server_status.url_copied.connect(self.copy_url) self.receive_mode.server_status.hidservauth_copied.connect( self.copy_hidservauth ) self.receive_mode.set_server_active.connect(self.set_server_active) # Website mode self.website_mode = WebsiteMode( self.common, qtapp, app, self.status_bar, self.server_status_label, self.system_tray, filenames, ) self.website_mode.init() self.website_mode.server_status.server_started.connect( self.update_server_status_indicator ) self.website_mode.server_status.server_stopped.connect( self.update_server_status_indicator ) self.website_mode.start_server_finished.connect( self.update_server_status_indicator ) self.website_mode.stop_server_finished.connect( self.update_server_status_indicator ) self.website_mode.stop_server_finished.connect(self.stop_server_finished) self.website_mode.start_server_finished.connect(self.clear_message) self.website_mode.server_status.button_clicked.connect(self.clear_message) self.website_mode.server_status.url_copied.connect(self.copy_url) self.website_mode.server_status.hidservauth_copied.connect( self.copy_hidservauth ) self.website_mode.set_server_active.connect(self.set_server_active) self.update_mode_switcher() self.update_server_status_indicator() # Layouts contents_layout = QtWidgets.QVBoxLayout() contents_layout.setContentsMargins(10, 0, 10, 0) contents_layout.addWidget(self.receive_mode) contents_layout.addWidget(self.share_mode) contents_layout.addWidget(self.website_mode) layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addLayout(mode_switcher_layout) layout.addLayout(contents_layout) central_widget = QtWidgets.QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) self.show() # The server isn't active yet self.set_server_active(False) # Create the timer self.timer = QtCore.QTimer() self.timer.timeout.connect(self.timer_callback) # Start the "Connecting to Tor" dialog, which calls onion.connect() tor_con = TorConnectionDialog(self.common, self.qtapp, self.onion) tor_con.canceled.connect(self._tor_connection_canceled) tor_con.open_settings.connect(self._tor_connection_open_settings) if not self.local_only: tor_con.start() # Start the timer self.timer.start(500) # After connecting to Tor, check for updates self.check_for_updates() def update_mode_switcher(self): # Based on the current mode, switch the mode switcher button styles, # and show and hide widgets to switch modes if self.mode == self.MODE_SHARE: self.share_mode_button.setStyleSheet( self.common.css["mode_switcher_selected_style"] ) self.receive_mode_button.setStyleSheet( self.common.css["mode_switcher_unselected_style"] ) self.website_mode_button.setStyleSheet( self.common.css["mode_switcher_unselected_style"] ) self.receive_mode.hide() self.share_mode.show() self.website_mode.hide() elif self.mode == self.MODE_WEBSITE: self.share_mode_button.setStyleSheet( self.common.css["mode_switcher_unselected_style"] ) self.receive_mode_button.setStyleSheet( self.common.css["mode_switcher_unselected_style"] ) self.website_mode_button.setStyleSheet( self.common.css["mode_switcher_selected_style"] ) self.receive_mode.hide() self.share_mode.hide() self.website_mode.show() else: self.share_mode_button.setStyleSheet( self.common.css["mode_switcher_unselected_style"] ) self.receive_mode_button.setStyleSheet( self.common.css["mode_switcher_selected_style"] ) self.website_mode_button.setStyleSheet( self.common.css["mode_switcher_unselected_style"] ) self.share_mode.hide() self.receive_mode.show() self.website_mode.hide() self.update_server_status_indicator() def share_mode_clicked(self): if self.mode != self.MODE_SHARE: self.common.log("OnionShareGui", "share_mode_clicked") self.mode = self.MODE_SHARE self.update_mode_switcher() def receive_mode_clicked(self): if self.mode != self.MODE_RECEIVE: self.common.log("OnionShareGui", "receive_mode_clicked") self.mode = self.MODE_RECEIVE self.update_mode_switcher() def website_mode_clicked(self): if self.mode != self.MODE_WEBSITE: self.common.log("OnionShareGui", "website_mode_clicked") self.mode = self.MODE_WEBSITE self.update_mode_switcher() def update_server_status_indicator(self): # Set the status image if self.mode == self.MODE_SHARE: # Share mode if self.share_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_stopped) ) self.server_status_label.setText( strings._("gui_status_indicator_share_stopped") ) elif self.share_mode.server_status.status == ServerStatus.STATUS_WORKING: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_working) ) if self.share_mode.server_status.autostart_timer_datetime: self.server_status_label.setText( strings._("gui_status_indicator_share_scheduled") ) else: self.server_status_label.setText( strings._("gui_status_indicator_share_working") ) elif self.share_mode.server_status.status == ServerStatus.STATUS_STARTED: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_started) ) self.server_status_label.setText( strings._("gui_status_indicator_share_started") ) elif self.mode == self.MODE_WEBSITE: # Website mode if self.website_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_stopped) ) self.server_status_label.setText( strings._("gui_status_indicator_share_stopped") ) elif self.website_mode.server_status.status == ServerStatus.STATUS_WORKING: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_working) ) self.server_status_label.setText( strings._("gui_status_indicator_share_working") ) elif self.website_mode.server_status.status == ServerStatus.STATUS_STARTED: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_started) ) self.server_status_label.setText( strings._("gui_status_indicator_share_started") ) else: # Receive mode if self.receive_mode.server_status.status == ServerStatus.STATUS_STOPPED: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_stopped) ) self.server_status_label.setText( strings._("gui_status_indicator_receive_stopped") ) elif self.receive_mode.server_status.status == ServerStatus.STATUS_WORKING: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_working) ) if self.receive_mode.server_status.autostart_timer_datetime: self.server_status_label.setText( strings._("gui_status_indicator_receive_scheduled") ) else: self.server_status_label.setText( strings._("gui_status_indicator_receive_working") ) elif self.receive_mode.server_status.status == ServerStatus.STATUS_STARTED: self.server_status_image_label.setPixmap( QtGui.QPixmap.fromImage(self.server_status_image_started) ) self.server_status_label.setText( strings._("gui_status_indicator_receive_started") ) def stop_server_finished(self): # When the server stopped, cleanup the ephemeral onion service self.onion.cleanup(stop_tor=False) def _tor_connection_canceled(self): """ If the user cancels before Tor finishes connecting, ask if they want to quit, or open settings. """ self.common.log("OnionShareGui", "_tor_connection_canceled") def ask(): a = Alert( self.common, strings._("gui_tor_connection_ask"), QtWidgets.QMessageBox.Question, buttons=QtWidgets.QMessageBox.NoButton, autostart=False, ) settings_button = QtWidgets.QPushButton( strings._("gui_tor_connection_ask_open_settings") ) quit_button = QtWidgets.QPushButton( strings._("gui_tor_connection_ask_quit") ) a.addButton(settings_button, QtWidgets.QMessageBox.AcceptRole) a.addButton(quit_button, QtWidgets.QMessageBox.RejectRole) a.setDefaultButton(settings_button) a.exec_() if a.clickedButton() == settings_button: # Open settings self.common.log( "OnionShareGui", "_tor_connection_canceled", "Settings button clicked", ) self.open_settings() if a.clickedButton() == quit_button: # Quit self.common.log( "OnionShareGui", "_tor_connection_canceled", "Quit button clicked" ) # Wait 1ms for the event loop to finish, then quit QtCore.QTimer.singleShot(1, self.qtapp.quit) # Wait 100ms before asking QtCore.QTimer.singleShot(100, ask) def _tor_connection_open_settings(self): """ The TorConnectionDialog wants to open the Settings dialog """ self.common.log("OnionShareGui", "_tor_connection_open_settings") # Wait 1ms for the event loop to finish closing the TorConnectionDialog QtCore.QTimer.singleShot(1, self.open_settings) def open_settings(self): """ Open the SettingsDialog. """ self.common.log("OnionShareGui", "open_settings") def reload_settings(): self.common.log( "OnionShareGui", "open_settings", "settings have changed, reloading" ) self.common.settings.load() # We might've stopped the main requests timer if a Tor connection failed. # If we've reloaded settings, we probably succeeded in obtaining a new # connection. If so, restart the timer. if not self.local_only: if self.onion.is_authenticated(): if not self.timer.isActive(): self.timer.start(500) self.share_mode.on_reload_settings() self.receive_mode.on_reload_settings() self.website_mode.on_reload_settings() self.status_bar.clearMessage() # If we switched off the auto-stop timer setting, ensure the widget is hidden. if not self.common.settings.get("autostop_timer"): self.share_mode.server_status.autostop_timer_container.hide() self.receive_mode.server_status.autostop_timer_container.hide() self.website_mode.server_status.autostop_timer_container.hide() # If we switched off the auto-start timer setting, ensure the widget is hidden. if not self.common.settings.get("autostart_timer"): self.share_mode.server_status.autostart_timer_datetime = None self.receive_mode.server_status.autostart_timer_datetime = None self.website_mode.server_status.autostart_timer_datetime = None self.share_mode.server_status.autostart_timer_container.hide() self.receive_mode.server_status.autostart_timer_container.hide() self.website_mode.server_status.autostart_timer_container.hide() d = SettingsDialog( self.common, self.onion, self.qtapp, self.config, self.local_only ) d.settings_saved.connect(reload_settings) d.exec_() # When settings close, refresh the server status UI self.share_mode.server_status.update() self.receive_mode.server_status.update() self.website_mode.server_status.update() def check_for_updates(self): """ Check for updates in a new thread, if enabled. """ if self.common.platform == "Windows" or self.common.platform == "Darwin": if self.common.settings.get("use_autoupdate"): def update_available(update_url, installed_version, latest_version): Alert( self.common, strings._("update_available").format( update_url, installed_version, latest_version ), ) self.update_thread = UpdateThread(self.common, self.onion, self.config) self.update_thread.update_available.connect(update_available) self.update_thread.start() def timer_callback(self): """ Check for messages communicated from the web app, and update the GUI accordingly. Also, call ShareMode and ReceiveMode's timer_callbacks. """ self.update() if not self.local_only: # Have we lost connection to Tor somehow? if not self.onion.is_authenticated(): self.timer.stop() self.status_bar.showMessage(strings._("gui_tor_connection_lost")) self.system_tray.showMessage( strings._("gui_tor_connection_lost"), strings._("gui_tor_connection_error_settings"), ) self.share_mode.handle_tor_broke() self.receive_mode.handle_tor_broke() self.website_mode.handle_tor_broke() # Process events from the web object if self.mode == self.MODE_SHARE: mode = self.share_mode elif self.mode == self.MODE_WEBSITE: mode = self.website_mode else: mode = self.receive_mode events = [] done = False while not done: try: r = mode.web.q.get(False) events.append(r) except queue.Empty: done = True for event in events: if event["type"] == Web.REQUEST_LOAD: mode.handle_request_load(event) elif event["type"] == Web.REQUEST_STARTED: mode.handle_request_started(event) elif event["type"] == Web.REQUEST_RATE_LIMIT: mode.handle_request_rate_limit(event) elif event["type"] == Web.REQUEST_PROGRESS: mode.handle_request_progress(event) elif event["type"] == Web.REQUEST_CANCELED: mode.handle_request_canceled(event) elif event["type"] == Web.REQUEST_UPLOAD_FILE_RENAMED: mode.handle_request_upload_file_renamed(event) elif event["type"] == Web.REQUEST_UPLOAD_SET_DIR: mode.handle_request_upload_set_dir(event) elif event["type"] == Web.REQUEST_UPLOAD_FINISHED: mode.handle_request_upload_finished(event) elif event["type"] == Web.REQUEST_UPLOAD_CANCELED: mode.handle_request_upload_canceled(event) elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_STARTED: mode.handle_request_individual_file_started(event) elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_PROGRESS: mode.handle_request_individual_file_progress(event) elif event["type"] == Web.REQUEST_INDIVIDUAL_FILE_CANCELED: mode.handle_request_individual_file_canceled(event) if event["type"] == Web.REQUEST_ERROR_DATA_DIR_CANNOT_CREATE: Alert( self.common, strings._("error_cannot_create_data_dir").format( event["data"]["receive_mode_dir"] ), ) if event["type"] == Web.REQUEST_OTHER: if event["path"] != "/favicon.ico" and event[ "path" ] != "/{}/shutdown".format(mode.web.shutdown_password): self.status_bar.showMessage( "{0:s}: {1:s}".format( strings._("other_page_loaded"), event["path"] ) ) if event["type"] == Web.REQUEST_INVALID_PASSWORD: self.status_bar.showMessage( "[#{0:d}] {1:s}: {2:s}".format( mode.web.invalid_passwords_count, strings._("incorrect_password"), event["data"], ) ) mode.timer_callback() def copy_url(self): """ When the URL gets copied to the clipboard, display this in the status bar. """ self.common.log("OnionShareGui", "copy_url") self.system_tray.showMessage( strings._("gui_copied_url_title"), strings._("gui_copied_url") ) def copy_hidservauth(self): """ When the stealth onion service HidServAuth gets copied to the clipboard, display this in the status bar. """ self.common.log("OnionShareGui", "copy_hidservauth") self.system_tray.showMessage( strings._("gui_copied_hidservauth_title"), strings._("gui_copied_hidservauth"), ) def clear_message(self): """ Clear messages from the status bar. """ self.status_bar.clearMessage() def set_server_active(self, active): """ Disable the Settings and Receive Files buttons while an Share Files server is active. """ if active: self.settings_button.hide() if self.mode == self.MODE_SHARE: self.share_mode_button.show() self.receive_mode_button.hide() self.website_mode_button.hide() elif self.mode == self.MODE_WEBSITE: self.share_mode_button.hide() self.receive_mode_button.hide() self.website_mode_button.show() else: self.share_mode_button.hide() self.receive_mode_button.show() self.website_mode_button.hide() else: self.settings_button.show() self.share_mode_button.show() self.receive_mode_button.show() self.website_mode_button.show() # Disable settings menu action when server is active self.settings_action.setEnabled(not active) def closeEvent(self, e): self.common.log("OnionShareGui", "closeEvent") self.system_tray.hide() try: if self.mode == OnionShareGui.MODE_SHARE: server_status = self.share_mode.server_status if self.mode == OnionShareGui.MODE_WEBSITE: server_status = self.website_mode.server_status else: server_status = self.receive_mode.server_status if server_status.status != server_status.STATUS_STOPPED: self.common.log("OnionShareGui", "closeEvent, opening warning dialog") dialog = QtWidgets.QMessageBox() dialog.setWindowTitle(strings._("gui_quit_title")) if self.mode == OnionShareGui.MODE_SHARE: dialog.setText(strings._("gui_share_quit_warning")) else: dialog.setText(strings._("gui_receive_quit_warning")) dialog.setIcon(QtWidgets.QMessageBox.Critical) quit_button = dialog.addButton( strings._("gui_quit_warning_quit"), QtWidgets.QMessageBox.YesRole ) dont_quit_button = dialog.addButton( strings._("gui_quit_warning_dont_quit"), QtWidgets.QMessageBox.NoRole, ) dialog.setDefaultButton(dont_quit_button) reply = dialog.exec_() # Quit if reply == 0: self.stop_server() e.accept() # Don't Quit else: e.ignore() except: e.accept() onionshare-2.2/onionshare_gui/server_status.py000066400000000000000000000521741355066717400220450ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import platform import textwrap from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from .widgets import Alert class ServerStatus(QtWidgets.QWidget): """ The server status chunk of the GUI. """ server_started = QtCore.pyqtSignal() server_started_finished = QtCore.pyqtSignal() server_stopped = QtCore.pyqtSignal() server_canceled = QtCore.pyqtSignal() button_clicked = QtCore.pyqtSignal() url_copied = QtCore.pyqtSignal() hidservauth_copied = QtCore.pyqtSignal() MODE_SHARE = "share" MODE_RECEIVE = "receive" MODE_WEBSITE = "website" STATUS_STOPPED = 0 STATUS_WORKING = 1 STATUS_STARTED = 2 def __init__(self, common, qtapp, app, file_selection=None, local_only=False): super(ServerStatus, self).__init__() self.common = common self.status = self.STATUS_STOPPED self.mode = None # Gets set in self.set_mode self.qtapp = qtapp self.app = app self.web = None self.autostart_timer_datetime = None self.local_only = local_only self.resizeEvent(None) # Auto-start timer layout self.autostart_timer_label = QtWidgets.QLabel( strings._("gui_settings_autostart_timer") ) self.autostart_timer_widget = QtWidgets.QDateTimeEdit() self.autostart_timer_widget.setDisplayFormat("hh:mm A MMM d, yy") if self.local_only: # For testing self.autostart_timer_widget.setDateTime( QtCore.QDateTime.currentDateTime().addSecs(15) ) self.autostart_timer_widget.setMinimumDateTime( QtCore.QDateTime.currentDateTime() ) else: # Set proposed timer to be 5 minutes into the future self.autostart_timer_widget.setDateTime( QtCore.QDateTime.currentDateTime().addSecs(300) ) # Onion services can take a little while to start, so reduce the risk of it expiring too soon by setting the minimum to 60s from now self.autostart_timer_widget.setMinimumDateTime( QtCore.QDateTime.currentDateTime().addSecs(60) ) self.autostart_timer_widget.setCurrentSection( QtWidgets.QDateTimeEdit.MinuteSection ) autostart_timer_layout = QtWidgets.QHBoxLayout() autostart_timer_layout.addWidget(self.autostart_timer_label) autostart_timer_layout.addWidget(self.autostart_timer_widget) # Auto-start timer container, so it can all be hidden and shown as a group autostart_timer_container_layout = QtWidgets.QVBoxLayout() autostart_timer_container_layout.addLayout(autostart_timer_layout) self.autostart_timer_container = QtWidgets.QWidget() self.autostart_timer_container.setLayout(autostart_timer_container_layout) self.autostart_timer_container.hide() # Auto-stop timer layout self.autostop_timer_label = QtWidgets.QLabel( strings._("gui_settings_autostop_timer") ) self.autostop_timer_widget = QtWidgets.QDateTimeEdit() self.autostop_timer_widget.setDisplayFormat("hh:mm A MMM d, yy") if self.local_only: # For testing self.autostop_timer_widget.setDateTime( QtCore.QDateTime.currentDateTime().addSecs(15) ) self.autostop_timer_widget.setMinimumDateTime( QtCore.QDateTime.currentDateTime() ) else: # Set proposed timer to be 5 minutes into the future self.autostop_timer_widget.setDateTime( QtCore.QDateTime.currentDateTime().addSecs(300) ) # Onion services can take a little while to start, so reduce the risk of it expiring too soon by setting the minimum to 60s from now self.autostop_timer_widget.setMinimumDateTime( QtCore.QDateTime.currentDateTime().addSecs(60) ) self.autostop_timer_widget.setCurrentSection( QtWidgets.QDateTimeEdit.MinuteSection ) autostop_timer_layout = QtWidgets.QHBoxLayout() autostop_timer_layout.addWidget(self.autostop_timer_label) autostop_timer_layout.addWidget(self.autostop_timer_widget) # Auto-stop timer container, so it can all be hidden and shown as a group autostop_timer_container_layout = QtWidgets.QVBoxLayout() autostop_timer_container_layout.addLayout(autostop_timer_layout) self.autostop_timer_container = QtWidgets.QWidget() self.autostop_timer_container.setLayout(autostop_timer_container_layout) self.autostop_timer_container.hide() # Server layout self.server_button = QtWidgets.QPushButton() self.server_button.clicked.connect(self.server_button_clicked) # URL layout url_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont) self.url_description = QtWidgets.QLabel() self.url_description.setWordWrap(True) self.url_description.setMinimumHeight(50) self.url = QtWidgets.QLabel() self.url.setFont(url_font) self.url.setWordWrap(True) self.url.setMinimumSize(self.url.sizeHint()) self.url.setStyleSheet(self.common.css["server_status_url"]) self.copy_url_button = QtWidgets.QPushButton(strings._("gui_copy_url")) self.copy_url_button.setFlat(True) self.copy_url_button.setStyleSheet(self.common.css["server_status_url_buttons"]) self.copy_url_button.setMinimumHeight(65) self.copy_url_button.clicked.connect(self.copy_url) self.copy_hidservauth_button = QtWidgets.QPushButton( strings._("gui_copy_hidservauth") ) self.copy_hidservauth_button.setFlat(True) self.copy_hidservauth_button.setStyleSheet( self.common.css["server_status_url_buttons"] ) self.copy_hidservauth_button.clicked.connect(self.copy_hidservauth) url_buttons_layout = QtWidgets.QHBoxLayout() url_buttons_layout.addWidget(self.copy_url_button) url_buttons_layout.addWidget(self.copy_hidservauth_button) url_buttons_layout.addStretch() url_layout = QtWidgets.QVBoxLayout() url_layout.addWidget(self.url_description) url_layout.addWidget(self.url) url_layout.addLayout(url_buttons_layout) # Add the widgets layout = QtWidgets.QVBoxLayout() layout.addWidget(self.server_button) layout.addLayout(url_layout) layout.addWidget(self.autostart_timer_container) layout.addWidget(self.autostop_timer_container) self.setLayout(layout) def set_mode(self, share_mode, file_selection=None): """ The server status is in share mode. """ self.mode = share_mode if (self.mode == ServerStatus.MODE_SHARE) or ( self.mode == ServerStatus.MODE_WEBSITE ): self.file_selection = file_selection self.update() def resizeEvent(self, event): """ When the widget is resized, try and adjust the display of a v3 onion URL. """ try: # Wrap the URL label url_length = len(self.get_url()) if url_length > 60: width = self.frameGeometry().width() if width < 530: wrapped_onion_url = textwrap.fill(self.get_url(), 46) self.url.setText(wrapped_onion_url) else: self.url.setText(self.get_url()) except: pass def autostart_timer_reset(self): """ Reset the auto-start timer in the UI after stopping a share """ self.autostart_timer_widget.setDateTime( QtCore.QDateTime.currentDateTime().addSecs(300) ) if not self.local_only: self.autostart_timer_widget.setMinimumDateTime( QtCore.QDateTime.currentDateTime().addSecs(60) ) def autostop_timer_reset(self): """ Reset the auto-stop timer in the UI after stopping a share """ self.autostop_timer_widget.setDateTime( QtCore.QDateTime.currentDateTime().addSecs(300) ) if not self.local_only: self.autostop_timer_widget.setMinimumDateTime( QtCore.QDateTime.currentDateTime().addSecs(60) ) def show_url(self): """ Show the URL in the UI. """ self.url_description.show() info_image = self.common.get_resource_path("images/info.png") if self.mode == ServerStatus.MODE_SHARE: self.url_description.setText( strings._("gui_share_url_description").format(info_image) ) elif self.mode == ServerStatus.MODE_WEBSITE: self.url_description.setText( strings._("gui_website_url_description").format(info_image) ) else: self.url_description.setText( strings._("gui_receive_url_description").format(info_image) ) # Show a Tool Tip explaining the lifecycle of this URL if self.common.settings.get("save_private_key"): if self.mode == ServerStatus.MODE_SHARE and self.common.settings.get( "close_after_first_download" ): self.url_description.setToolTip( strings._("gui_url_label_onetime_and_persistent") ) else: self.url_description.setToolTip(strings._("gui_url_label_persistent")) else: if self.mode == ServerStatus.MODE_SHARE and self.common.settings.get( "close_after_first_download" ): self.url_description.setToolTip(strings._("gui_url_label_onetime")) else: self.url_description.setToolTip(strings._("gui_url_label_stay_open")) self.url.setText(self.get_url()) self.url.show() self.copy_url_button.show() if self.app.stealth: self.copy_hidservauth_button.show() else: self.copy_hidservauth_button.hide() def update(self): """ Update the GUI elements based on the current state. """ # Set the URL fields if self.status == self.STATUS_STARTED: # The backend Onion may have saved new settings, such as the private key. # Reload the settings before saving new ones. self.common.settings.load() self.show_url() if self.common.settings.get("save_private_key"): if not self.common.settings.get("password"): self.common.settings.set("password", self.web.password) self.common.settings.save() if self.common.settings.get("autostart_timer"): self.autostart_timer_container.hide() if self.common.settings.get("autostop_timer"): self.autostop_timer_container.hide() else: self.url_description.hide() self.url.hide() self.copy_url_button.hide() self.copy_hidservauth_button.hide() # Button if ( self.mode == ServerStatus.MODE_SHARE and self.file_selection.get_num_files() == 0 ): self.server_button.hide() elif ( self.mode == ServerStatus.MODE_WEBSITE and self.file_selection.get_num_files() == 0 ): self.server_button.hide() else: self.server_button.show() if self.status == self.STATUS_STOPPED: self.server_button.setStyleSheet( self.common.css["server_status_button_stopped"] ) self.server_button.setEnabled(True) if self.mode == ServerStatus.MODE_SHARE: self.server_button.setText(strings._("gui_share_start_server")) elif self.mode == ServerStatus.MODE_WEBSITE: self.server_button.setText(strings._("gui_share_start_server")) else: self.server_button.setText(strings._("gui_receive_start_server")) self.server_button.setToolTip("") if self.common.settings.get("autostart_timer"): self.autostart_timer_container.show() if self.common.settings.get("autostop_timer"): self.autostop_timer_container.show() elif self.status == self.STATUS_STARTED: self.server_button.setStyleSheet( self.common.css["server_status_button_started"] ) self.server_button.setEnabled(True) if self.mode == ServerStatus.MODE_SHARE: self.server_button.setText(strings._("gui_share_stop_server")) elif self.mode == ServerStatus.MODE_WEBSITE: self.server_button.setText(strings._("gui_share_stop_server")) else: self.server_button.setText(strings._("gui_receive_stop_server")) if self.common.settings.get("autostart_timer"): self.autostart_timer_container.hide() if self.common.settings.get("autostop_timer"): self.autostop_timer_container.hide() self.server_button.setToolTip( strings._("gui_stop_server_autostop_timer_tooltip").format( self.autostop_timer_widget.dateTime().toString( "h:mm AP, MMMM dd, yyyy" ) ) ) elif self.status == self.STATUS_WORKING: self.server_button.setStyleSheet( self.common.css["server_status_button_working"] ) self.server_button.setEnabled(True) if self.autostart_timer_datetime: self.autostart_timer_container.hide() self.server_button.setToolTip( strings._("gui_start_server_autostart_timer_tooltip").format( self.autostart_timer_widget.dateTime().toString( "h:mm AP, MMMM dd, yyyy" ) ) ) else: self.server_button.setText(strings._("gui_please_wait")) if self.common.settings.get("autostop_timer"): self.autostop_timer_container.hide() else: self.server_button.setStyleSheet( self.common.css["server_status_button_working"] ) self.server_button.setEnabled(False) self.server_button.setText(strings._("gui_please_wait")) if self.common.settings.get("autostart_timer"): self.autostart_timer_container.hide() self.server_button.setToolTip( strings._("gui_start_server_autostart_timer_tooltip").format( self.autostart_timer_widget.dateTime().toString( "h:mm AP, MMMM dd, yyyy" ) ) ) if self.common.settings.get("autostop_timer"): self.autostop_timer_container.hide() def server_button_clicked(self): """ Toggle starting or stopping the server. """ if self.status == self.STATUS_STOPPED: can_start = True if self.common.settings.get("autostart_timer"): if self.local_only: self.autostart_timer_datetime = ( self.autostart_timer_widget.dateTime().toPyDateTime() ) else: self.autostart_timer_datetime = ( self.autostart_timer_widget.dateTime() .toPyDateTime() .replace(second=0, microsecond=0) ) # If the timer has actually passed already before the user hit Start, refuse to start the server. if ( QtCore.QDateTime.currentDateTime().toPyDateTime() > self.autostart_timer_datetime ): can_start = False Alert( self.common, strings._("gui_server_autostart_timer_expired"), QtWidgets.QMessageBox.Warning, ) if self.common.settings.get("autostop_timer"): if self.local_only: self.autostop_timer_datetime = ( self.autostop_timer_widget.dateTime().toPyDateTime() ) else: # Get the timer chosen, stripped of its seconds. This prevents confusion if the share stops at (say) 37 seconds past the minute chosen self.autostop_timer_datetime = ( self.autostop_timer_widget.dateTime() .toPyDateTime() .replace(second=0, microsecond=0) ) # If the timer has actually passed already before the user hit Start, refuse to start the server. if ( QtCore.QDateTime.currentDateTime().toPyDateTime() > self.autostop_timer_datetime ): can_start = False Alert( self.common, strings._("gui_server_autostop_timer_expired"), QtWidgets.QMessageBox.Warning, ) if self.common.settings.get("autostart_timer"): if self.autostop_timer_datetime <= self.autostart_timer_datetime: Alert( self.common, strings._( "gui_autostop_timer_cant_be_earlier_than_autostart_timer" ), QtWidgets.QMessageBox.Warning, ) can_start = False if can_start: self.start_server() elif self.status == self.STATUS_STARTED: self.stop_server() elif self.status == self.STATUS_WORKING: self.cancel_server() self.button_clicked.emit() def start_server(self): """ Start the server. """ self.status = self.STATUS_WORKING self.update() self.server_started.emit() def start_server_finished(self): """ The server has finished starting. """ self.status = self.STATUS_STARTED self.copy_url() self.update() self.server_started_finished.emit() def stop_server(self): """ Stop the server. """ self.status = self.STATUS_WORKING self.autostart_timer_reset() self.autostop_timer_reset() self.update() self.server_stopped.emit() def cancel_server(self): """ Cancel the server. """ self.common.log( "ServerStatus", "cancel_server", "Canceling the server mid-startup" ) self.status = self.STATUS_WORKING self.autostart_timer_reset() self.autostop_timer_reset() self.update() self.server_canceled.emit() def stop_server_finished(self): """ The server has finished stopping. """ self.status = self.STATUS_STOPPED self.update() def copy_url(self): """ Copy the onionshare URL to the clipboard. """ clipboard = self.qtapp.clipboard() clipboard.setText(self.get_url()) self.url_copied.emit() def copy_hidservauth(self): """ Copy the HidServAuth line to the clipboard. """ clipboard = self.qtapp.clipboard() clipboard.setText(self.app.auth_string) self.hidservauth_copied.emit() def get_url(self): """ Returns the OnionShare URL. """ if self.common.settings.get("public_mode"): url = "http://{0:s}".format(self.app.onion_host) else: url = "http://onionshare:{0:s}@{1:s}".format( self.web.password, self.app.onion_host ) return url onionshare-2.2/onionshare_gui/settings_dialog.py000066400000000000000000001766031355066717400223170ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore, QtWidgets, QtGui import sys import platform import datetime import re import os from onionshare import strings, common from onionshare.settings import Settings from onionshare.onion import * from .widgets import Alert from .update_checker import * from .tor_connection_dialog import TorConnectionDialog class SettingsDialog(QtWidgets.QDialog): """ Settings dialog. """ settings_saved = QtCore.pyqtSignal() def __init__(self, common, onion, qtapp, config=False, local_only=False): super(SettingsDialog, self).__init__() self.common = common self.common.log("SettingsDialog", "__init__") self.onion = onion self.qtapp = qtapp self.config = config self.local_only = local_only self.setModal(True) self.setWindowTitle(strings._("gui_settings_window_title")) self.setWindowIcon( QtGui.QIcon(self.common.get_resource_path("images/logo.png")) ) self.system = platform.system() # If ONIONSHARE_HIDE_TOR_SETTINGS=1, hide Tor settings in the dialog self.hide_tor_settings = os.environ.get("ONIONSHARE_HIDE_TOR_SETTINGS") == "1" # General settings # Use a password or not ('public mode') self.public_mode_checkbox = QtWidgets.QCheckBox() self.public_mode_checkbox.setCheckState(QtCore.Qt.Unchecked) self.public_mode_checkbox.setText( strings._("gui_settings_public_mode_checkbox") ) public_mode_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Public-Mode" ) ) public_mode_label.setStyleSheet(self.common.css["settings_whats_this"]) public_mode_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) public_mode_label.setOpenExternalLinks(True) public_mode_label.setMinimumSize(public_mode_label.sizeHint()) public_mode_layout = QtWidgets.QHBoxLayout() public_mode_layout.addWidget(self.public_mode_checkbox) public_mode_layout.addWidget(public_mode_label) public_mode_layout.addStretch() public_mode_layout.setContentsMargins(0, 0, 0, 0) self.public_mode_widget = QtWidgets.QWidget() self.public_mode_widget.setLayout(public_mode_layout) # Whether or not to use an auto-start timer self.autostart_timer_checkbox = QtWidgets.QCheckBox() self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Checked) self.autostart_timer_checkbox.setText( strings._("gui_settings_autostart_timer_checkbox") ) autostart_timer_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Start-Timer" ) ) autostart_timer_label.setStyleSheet(self.common.css["settings_whats_this"]) autostart_timer_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) autostart_timer_label.setOpenExternalLinks(True) autostart_timer_label.setMinimumSize(public_mode_label.sizeHint()) autostart_timer_layout = QtWidgets.QHBoxLayout() autostart_timer_layout.addWidget(self.autostart_timer_checkbox) autostart_timer_layout.addWidget(autostart_timer_label) autostart_timer_layout.addStretch() autostart_timer_layout.setContentsMargins(0, 0, 0, 0) self.autostart_timer_widget = QtWidgets.QWidget() self.autostart_timer_widget.setLayout(autostart_timer_layout) # Whether or not to use an auto-stop timer self.autostop_timer_checkbox = QtWidgets.QCheckBox() self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Checked) self.autostop_timer_checkbox.setText( strings._("gui_settings_autostop_timer_checkbox") ) autostop_timer_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Using-the-Auto-Stop-Timer" ) ) autostop_timer_label.setStyleSheet(self.common.css["settings_whats_this"]) autostop_timer_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) autostop_timer_label.setOpenExternalLinks(True) autostop_timer_label.setMinimumSize(public_mode_label.sizeHint()) autostop_timer_layout = QtWidgets.QHBoxLayout() autostop_timer_layout.addWidget(self.autostop_timer_checkbox) autostop_timer_layout.addWidget(autostop_timer_label) autostop_timer_layout.addStretch() autostop_timer_layout.setContentsMargins(0, 0, 0, 0) self.autostop_timer_widget = QtWidgets.QWidget() self.autostop_timer_widget.setLayout(autostop_timer_layout) # General settings layout general_group_layout = QtWidgets.QVBoxLayout() general_group_layout.addWidget(self.public_mode_widget) general_group_layout.addWidget(self.autostart_timer_widget) general_group_layout.addWidget(self.autostop_timer_widget) general_group = QtWidgets.QGroupBox(strings._("gui_settings_general_label")) general_group.setLayout(general_group_layout) # Onion settings # Label telling user to connect to Tor for onion service settings self.connect_to_tor_label = QtWidgets.QLabel( strings._("gui_connect_to_tor_for_onion_settings") ) self.connect_to_tor_label.setStyleSheet( self.common.css["settings_connect_to_tor"] ) # Whether or not to save the Onion private key for reuse (persistent URL mode) self.save_private_key_checkbox = QtWidgets.QCheckBox() self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) self.save_private_key_checkbox.setText( strings._("gui_save_private_key_checkbox") ) save_private_key_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Using-a-Persistent-URL" ) ) save_private_key_label.setStyleSheet(self.common.css["settings_whats_this"]) save_private_key_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) save_private_key_label.setOpenExternalLinks(True) save_private_key_layout = QtWidgets.QHBoxLayout() save_private_key_layout.addWidget(self.save_private_key_checkbox) save_private_key_layout.addWidget(save_private_key_label) save_private_key_layout.addStretch() save_private_key_layout.setContentsMargins(0, 0, 0, 0) self.save_private_key_widget = QtWidgets.QWidget() self.save_private_key_widget.setLayout(save_private_key_layout) # Whether or not to use legacy v2 onions self.use_legacy_v2_onions_checkbox = QtWidgets.QCheckBox() self.use_legacy_v2_onions_checkbox.setCheckState(QtCore.Qt.Unchecked) self.use_legacy_v2_onions_checkbox.setText( strings._("gui_use_legacy_v2_onions_checkbox") ) self.use_legacy_v2_onions_checkbox.clicked.connect( self.use_legacy_v2_onions_checkbox_clicked ) use_legacy_v2_onions_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Legacy-Addresses" ) ) use_legacy_v2_onions_label.setStyleSheet(self.common.css["settings_whats_this"]) use_legacy_v2_onions_label.setTextInteractionFlags( QtCore.Qt.TextBrowserInteraction ) use_legacy_v2_onions_label.setOpenExternalLinks(True) use_legacy_v2_onions_layout = QtWidgets.QHBoxLayout() use_legacy_v2_onions_layout.addWidget(self.use_legacy_v2_onions_checkbox) use_legacy_v2_onions_layout.addWidget(use_legacy_v2_onions_label) use_legacy_v2_onions_layout.addStretch() use_legacy_v2_onions_layout.setContentsMargins(0, 0, 0, 0) self.use_legacy_v2_onions_widget = QtWidgets.QWidget() self.use_legacy_v2_onions_widget.setLayout(use_legacy_v2_onions_layout) # Stealth self.stealth_checkbox = QtWidgets.QCheckBox() self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) self.stealth_checkbox.setText(strings._("gui_settings_stealth_option")) self.stealth_checkbox.clicked.connect(self.stealth_checkbox_clicked_connect) use_stealth_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Stealth-Onion-Services" ) ) use_stealth_label.setStyleSheet(self.common.css["settings_whats_this"]) use_stealth_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) use_stealth_label.setOpenExternalLinks(True) use_stealth_label.setMinimumSize(use_stealth_label.sizeHint()) use_stealth_layout = QtWidgets.QHBoxLayout() use_stealth_layout.addWidget(self.stealth_checkbox) use_stealth_layout.addWidget(use_stealth_label) use_stealth_layout.addStretch() use_stealth_layout.setContentsMargins(0, 0, 0, 0) self.use_stealth_widget = QtWidgets.QWidget() self.use_stealth_widget.setLayout(use_stealth_layout) self.hidservauth_details = QtWidgets.QLabel( strings._("gui_settings_stealth_hidservauth_string") ) self.hidservauth_details.setWordWrap(True) self.hidservauth_details.setMinimumSize(self.hidservauth_details.sizeHint()) self.hidservauth_details.hide() self.hidservauth_copy_button = QtWidgets.QPushButton( strings._("gui_copy_hidservauth") ) self.hidservauth_copy_button.clicked.connect( self.hidservauth_copy_button_clicked ) self.hidservauth_copy_button.hide() # Onion settings widget onion_settings_layout = QtWidgets.QVBoxLayout() onion_settings_layout.setContentsMargins(0, 0, 0, 0) onion_settings_layout.addWidget(self.save_private_key_widget) onion_settings_layout.addWidget(self.use_legacy_v2_onions_widget) onion_settings_layout.addWidget(self.use_stealth_widget) onion_settings_layout.addWidget(self.hidservauth_details) onion_settings_layout.addWidget(self.hidservauth_copy_button) self.onion_settings_widget = QtWidgets.QWidget() self.onion_settings_widget.setLayout(onion_settings_layout) # Onion settings layout onion_group_layout = QtWidgets.QVBoxLayout() onion_group_layout.addWidget(self.connect_to_tor_label) onion_group_layout.addWidget(self.onion_settings_widget) onion_group = QtWidgets.QGroupBox(strings._("gui_settings_onion_label")) onion_group.setLayout(onion_group_layout) # Sharing options # Close after first download self.close_after_first_download_checkbox = QtWidgets.QCheckBox() self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) self.close_after_first_download_checkbox.setText( strings._("gui_settings_close_after_first_download_option") ) individual_downloads_label = QtWidgets.QLabel( strings._("gui_settings_individual_downloads_label") ) # Sharing options layout sharing_group_layout = QtWidgets.QVBoxLayout() sharing_group_layout.addWidget(self.close_after_first_download_checkbox) sharing_group_layout.addWidget(individual_downloads_label) sharing_group = QtWidgets.QGroupBox(strings._("gui_settings_sharing_label")) sharing_group.setLayout(sharing_group_layout) # OnionShare data dir data_dir_label = QtWidgets.QLabel(strings._("gui_settings_data_dir_label")) self.data_dir_lineedit = QtWidgets.QLineEdit() self.data_dir_lineedit.setReadOnly(True) data_dir_button = QtWidgets.QPushButton( strings._("gui_settings_data_dir_browse_button") ) data_dir_button.clicked.connect(self.data_dir_button_clicked) data_dir_layout = QtWidgets.QHBoxLayout() data_dir_layout.addWidget(data_dir_label) data_dir_layout.addWidget(self.data_dir_lineedit) data_dir_layout.addWidget(data_dir_button) # Receiving options layout receiving_group_layout = QtWidgets.QVBoxLayout() receiving_group_layout.addLayout(data_dir_layout) receiving_group = QtWidgets.QGroupBox(strings._("gui_settings_receiving_label")) receiving_group.setLayout(receiving_group_layout) # Option to disable Content Security Policy (for website sharing) self.csp_header_disabled_checkbox = QtWidgets.QCheckBox() self.csp_header_disabled_checkbox.setCheckState(QtCore.Qt.Unchecked) self.csp_header_disabled_checkbox.setText( strings._("gui_settings_csp_header_disabled_option") ) csp_header_label = QtWidgets.QLabel( strings._("gui_settings_whats_this").format( "https://github.com/micahflee/onionshare/wiki/Content-Security-Policy" ) ) csp_header_label.setStyleSheet(self.common.css["settings_whats_this"]) csp_header_label.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction) csp_header_label.setOpenExternalLinks(True) csp_header_label.setMinimumSize(csp_header_label.sizeHint()) csp_header_layout = QtWidgets.QHBoxLayout() csp_header_layout.addWidget(self.csp_header_disabled_checkbox) csp_header_layout.addWidget(csp_header_label) csp_header_layout.addStretch() csp_header_layout.setContentsMargins(0, 0, 0, 0) self.csp_header_widget = QtWidgets.QWidget() self.csp_header_widget.setLayout(csp_header_layout) # Website settings widget website_settings_layout = QtWidgets.QVBoxLayout() website_settings_layout.setContentsMargins(0, 0, 0, 0) website_settings_layout.addWidget(self.csp_header_widget) self.website_settings_widget = QtWidgets.QWidget() self.website_settings_widget.setLayout(website_settings_layout) # Website mode options layout website_group_layout = QtWidgets.QVBoxLayout() website_group_layout.addWidget(self.website_settings_widget) website_group = QtWidgets.QGroupBox(strings._("gui_settings_website_label")) website_group.setLayout(website_group_layout) # Automatic updates options # Autoupdate self.autoupdate_checkbox = QtWidgets.QCheckBox() self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) self.autoupdate_checkbox.setText(strings._("gui_settings_autoupdate_option")) # Last update time self.autoupdate_timestamp = QtWidgets.QLabel() # Check for updates button self.check_for_updates_button = QtWidgets.QPushButton( strings._("gui_settings_autoupdate_check_button") ) self.check_for_updates_button.clicked.connect(self.check_for_updates) # We can't check for updates if not connected to Tor if not self.onion.connected_to_tor: self.check_for_updates_button.setEnabled(False) # Autoupdate options layout autoupdate_group_layout = QtWidgets.QVBoxLayout() autoupdate_group_layout.addWidget(self.autoupdate_checkbox) autoupdate_group_layout.addWidget(self.autoupdate_timestamp) autoupdate_group_layout.addWidget(self.check_for_updates_button) autoupdate_group = QtWidgets.QGroupBox( strings._("gui_settings_autoupdate_label") ) autoupdate_group.setLayout(autoupdate_group_layout) # Autoupdate is only available for Windows and Mac (Linux updates using package manager) if self.system != "Windows" and self.system != "Darwin": autoupdate_group.hide() # Language settings language_label = QtWidgets.QLabel(strings._("gui_settings_language_label")) self.language_combobox = QtWidgets.QComboBox() # Populate the dropdown with all of OnionShare's available languages language_names_to_locales = { v: k for k, v in self.common.settings.available_locales.items() } language_names = list(language_names_to_locales) language_names.sort() for language_name in language_names: locale = language_names_to_locales[language_name] self.language_combobox.addItem(language_name, QtCore.QVariant(locale)) language_layout = QtWidgets.QHBoxLayout() language_layout.addWidget(language_label) language_layout.addWidget(self.language_combobox) language_layout.addStretch() # Connection type: either automatic, control port, or socket file # Bundled Tor self.connection_type_bundled_radio = QtWidgets.QRadioButton( strings._("gui_settings_connection_type_bundled_option") ) self.connection_type_bundled_radio.toggled.connect( self.connection_type_bundled_toggled ) # Bundled Tor doesn't work on dev mode in Windows or Mac if (self.system == "Windows" or self.system == "Darwin") and getattr( sys, "onionshare_dev_mode", False ): self.connection_type_bundled_radio.setEnabled(False) # Bridge options for bundled tor # No bridges option radio self.tor_bridges_no_bridges_radio = QtWidgets.QRadioButton( strings._("gui_settings_tor_bridges_no_bridges_radio_option") ) self.tor_bridges_no_bridges_radio.toggled.connect( self.tor_bridges_no_bridges_radio_toggled ) # obfs4 option radio # if the obfs4proxy binary is missing, we can't use obfs4 transports ( self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path, ) = self.common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton( strings._("gui_settings_tor_bridges_obfs4_radio_option_no_obfs4proxy") ) self.tor_bridges_use_obfs4_radio.setEnabled(False) else: self.tor_bridges_use_obfs4_radio = QtWidgets.QRadioButton( strings._("gui_settings_tor_bridges_obfs4_radio_option") ) self.tor_bridges_use_obfs4_radio.toggled.connect( self.tor_bridges_use_obfs4_radio_toggled ) # meek_lite-azure option radio # if the obfs4proxy binary is missing, we can't use meek_lite-azure transports ( self.tor_path, self.tor_geo_ip_file_path, self.tor_geo_ipv6_file_path, self.obfs4proxy_file_path, ) = self.common.get_tor_paths() if not os.path.isfile(self.obfs4proxy_file_path): self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton( strings._( "gui_settings_tor_bridges_meek_lite_azure_radio_option_no_obfs4proxy" ) ) self.tor_bridges_use_meek_lite_azure_radio.setEnabled(False) else: self.tor_bridges_use_meek_lite_azure_radio = QtWidgets.QRadioButton( strings._("gui_settings_tor_bridges_meek_lite_azure_radio_option") ) self.tor_bridges_use_meek_lite_azure_radio.toggled.connect( self.tor_bridges_use_meek_lite_azure_radio_toggled ) # Custom bridges radio and textbox self.tor_bridges_use_custom_radio = QtWidgets.QRadioButton( strings._("gui_settings_tor_bridges_custom_radio_option") ) self.tor_bridges_use_custom_radio.toggled.connect( self.tor_bridges_use_custom_radio_toggled ) self.tor_bridges_use_custom_label = QtWidgets.QLabel( strings._("gui_settings_tor_bridges_custom_label") ) self.tor_bridges_use_custom_label.setTextInteractionFlags( QtCore.Qt.TextBrowserInteraction ) self.tor_bridges_use_custom_label.setOpenExternalLinks(True) self.tor_bridges_use_custom_textbox = QtWidgets.QPlainTextEdit() self.tor_bridges_use_custom_textbox.setMaximumHeight(200) self.tor_bridges_use_custom_textbox.setPlaceholderText( "[address:port] [identifier]" ) tor_bridges_use_custom_textbox_options_layout = QtWidgets.QVBoxLayout() tor_bridges_use_custom_textbox_options_layout.addWidget( self.tor_bridges_use_custom_label ) tor_bridges_use_custom_textbox_options_layout.addWidget( self.tor_bridges_use_custom_textbox ) self.tor_bridges_use_custom_textbox_options = QtWidgets.QWidget() self.tor_bridges_use_custom_textbox_options.setLayout( tor_bridges_use_custom_textbox_options_layout ) self.tor_bridges_use_custom_textbox_options.hide() # Bridges layout/widget bridges_layout = QtWidgets.QVBoxLayout() bridges_layout.addWidget(self.tor_bridges_no_bridges_radio) bridges_layout.addWidget(self.tor_bridges_use_obfs4_radio) bridges_layout.addWidget(self.tor_bridges_use_meek_lite_azure_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_radio) bridges_layout.addWidget(self.tor_bridges_use_custom_textbox_options) self.bridges = QtWidgets.QWidget() self.bridges.setLayout(bridges_layout) # Automatic self.connection_type_automatic_radio = QtWidgets.QRadioButton( strings._("gui_settings_connection_type_automatic_option") ) self.connection_type_automatic_radio.toggled.connect( self.connection_type_automatic_toggled ) # Control port self.connection_type_control_port_radio = QtWidgets.QRadioButton( strings._("gui_settings_connection_type_control_port_option") ) self.connection_type_control_port_radio.toggled.connect( self.connection_type_control_port_toggled ) connection_type_control_port_extras_label = QtWidgets.QLabel( strings._("gui_settings_control_port_label") ) self.connection_type_control_port_extras_address = QtWidgets.QLineEdit() self.connection_type_control_port_extras_port = QtWidgets.QLineEdit() connection_type_control_port_extras_layout = QtWidgets.QHBoxLayout() connection_type_control_port_extras_layout.addWidget( connection_type_control_port_extras_label ) connection_type_control_port_extras_layout.addWidget( self.connection_type_control_port_extras_address ) connection_type_control_port_extras_layout.addWidget( self.connection_type_control_port_extras_port ) self.connection_type_control_port_extras = QtWidgets.QWidget() self.connection_type_control_port_extras.setLayout( connection_type_control_port_extras_layout ) self.connection_type_control_port_extras.hide() # Socket file self.connection_type_socket_file_radio = QtWidgets.QRadioButton( strings._("gui_settings_connection_type_socket_file_option") ) self.connection_type_socket_file_radio.toggled.connect( self.connection_type_socket_file_toggled ) connection_type_socket_file_extras_label = QtWidgets.QLabel( strings._("gui_settings_socket_file_label") ) self.connection_type_socket_file_extras_path = QtWidgets.QLineEdit() connection_type_socket_file_extras_layout = QtWidgets.QHBoxLayout() connection_type_socket_file_extras_layout.addWidget( connection_type_socket_file_extras_label ) connection_type_socket_file_extras_layout.addWidget( self.connection_type_socket_file_extras_path ) self.connection_type_socket_file_extras = QtWidgets.QWidget() self.connection_type_socket_file_extras.setLayout( connection_type_socket_file_extras_layout ) self.connection_type_socket_file_extras.hide() # Tor SOCKS address and port gui_settings_socks_label = QtWidgets.QLabel( strings._("gui_settings_socks_label") ) self.connection_type_socks_address = QtWidgets.QLineEdit() self.connection_type_socks_port = QtWidgets.QLineEdit() connection_type_socks_layout = QtWidgets.QHBoxLayout() connection_type_socks_layout.addWidget(gui_settings_socks_label) connection_type_socks_layout.addWidget(self.connection_type_socks_address) connection_type_socks_layout.addWidget(self.connection_type_socks_port) self.connection_type_socks = QtWidgets.QWidget() self.connection_type_socks.setLayout(connection_type_socks_layout) self.connection_type_socks.hide() # Authentication options # No authentication self.authenticate_no_auth_radio = QtWidgets.QRadioButton( strings._("gui_settings_authenticate_no_auth_option") ) self.authenticate_no_auth_radio.toggled.connect( self.authenticate_no_auth_toggled ) # Password self.authenticate_password_radio = QtWidgets.QRadioButton( strings._("gui_settings_authenticate_password_option") ) self.authenticate_password_radio.toggled.connect( self.authenticate_password_toggled ) authenticate_password_extras_label = QtWidgets.QLabel( strings._("gui_settings_password_label") ) self.authenticate_password_extras_password = QtWidgets.QLineEdit("") authenticate_password_extras_layout = QtWidgets.QHBoxLayout() authenticate_password_extras_layout.addWidget( authenticate_password_extras_label ) authenticate_password_extras_layout.addWidget( self.authenticate_password_extras_password ) self.authenticate_password_extras = QtWidgets.QWidget() self.authenticate_password_extras.setLayout(authenticate_password_extras_layout) self.authenticate_password_extras.hide() # Authentication options layout authenticate_group_layout = QtWidgets.QVBoxLayout() authenticate_group_layout.addWidget(self.authenticate_no_auth_radio) authenticate_group_layout.addWidget(self.authenticate_password_radio) authenticate_group_layout.addWidget(self.authenticate_password_extras) self.authenticate_group = QtWidgets.QGroupBox( strings._("gui_settings_authenticate_label") ) self.authenticate_group.setLayout(authenticate_group_layout) # Put the radios into their own group so they are exclusive connection_type_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_radio_group_layout.addWidget(self.connection_type_bundled_radio) connection_type_radio_group_layout.addWidget( self.connection_type_automatic_radio ) connection_type_radio_group_layout.addWidget( self.connection_type_control_port_radio ) connection_type_radio_group_layout.addWidget( self.connection_type_socket_file_radio ) connection_type_radio_group = QtWidgets.QGroupBox( strings._("gui_settings_connection_type_label") ) connection_type_radio_group.setLayout(connection_type_radio_group_layout) # The Bridges options are not exclusive (enabling Bridges offers obfs4 or custom bridges) connection_type_bridges_radio_group_layout = QtWidgets.QVBoxLayout() connection_type_bridges_radio_group_layout.addWidget(self.bridges) self.connection_type_bridges_radio_group = QtWidgets.QGroupBox( strings._("gui_settings_tor_bridges") ) self.connection_type_bridges_radio_group.setLayout( connection_type_bridges_radio_group_layout ) self.connection_type_bridges_radio_group.hide() # Test tor settings button self.connection_type_test_button = QtWidgets.QPushButton( strings._("gui_settings_connection_type_test_button") ) self.connection_type_test_button.clicked.connect(self.test_tor_clicked) connection_type_test_button_layout = QtWidgets.QHBoxLayout() connection_type_test_button_layout.addWidget(self.connection_type_test_button) connection_type_test_button_layout.addStretch() # Connection type layout connection_type_layout = QtWidgets.QVBoxLayout() connection_type_layout.addWidget(self.connection_type_control_port_extras) connection_type_layout.addWidget(self.connection_type_socket_file_extras) connection_type_layout.addWidget(self.connection_type_socks) connection_type_layout.addWidget(self.authenticate_group) connection_type_layout.addWidget(self.connection_type_bridges_radio_group) connection_type_layout.addLayout(connection_type_test_button_layout) # Buttons self.save_button = QtWidgets.QPushButton(strings._("gui_settings_button_save")) self.save_button.clicked.connect(self.save_clicked) self.cancel_button = QtWidgets.QPushButton( strings._("gui_settings_button_cancel") ) self.cancel_button.clicked.connect(self.cancel_clicked) version_label = QtWidgets.QLabel("OnionShare {0:s}".format(self.common.version)) version_label.setStyleSheet(self.common.css["settings_version"]) self.help_button = QtWidgets.QPushButton(strings._("gui_settings_button_help")) self.help_button.clicked.connect(self.help_clicked) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(version_label) buttons_layout.addWidget(self.help_button) buttons_layout.addStretch() buttons_layout.addWidget(self.save_button) buttons_layout.addWidget(self.cancel_button) # Tor network connection status self.tor_status = QtWidgets.QLabel() self.tor_status.setStyleSheet(self.common.css["settings_tor_status"]) self.tor_status.hide() # Layout left_col_layout = QtWidgets.QVBoxLayout() left_col_layout.addWidget(general_group) left_col_layout.addWidget(onion_group) left_col_layout.addWidget(sharing_group) left_col_layout.addWidget(receiving_group) left_col_layout.addWidget(website_group) left_col_layout.addWidget(autoupdate_group) left_col_layout.addLayout(language_layout) left_col_layout.addStretch() right_col_layout = QtWidgets.QVBoxLayout() right_col_layout.addWidget(connection_type_radio_group) right_col_layout.addLayout(connection_type_layout) right_col_layout.addWidget(self.tor_status) right_col_layout.addStretch() col_layout = QtWidgets.QHBoxLayout() col_layout.addLayout(left_col_layout) if not self.hide_tor_settings: col_layout.addLayout(right_col_layout) layout = QtWidgets.QVBoxLayout() layout.addLayout(col_layout) layout.addLayout(buttons_layout) self.setLayout(layout) self.cancel_button.setFocus() self.reload_settings() def reload_settings(self): # Load settings, and fill them in self.old_settings = Settings(self.common, self.config) self.old_settings.load() close_after_first_download = self.old_settings.get("close_after_first_download") if close_after_first_download: self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Checked) else: self.close_after_first_download_checkbox.setCheckState(QtCore.Qt.Unchecked) csp_header_disabled = self.old_settings.get("csp_header_disabled") if csp_header_disabled: self.csp_header_disabled_checkbox.setCheckState(QtCore.Qt.Checked) else: self.csp_header_disabled_checkbox.setCheckState(QtCore.Qt.Unchecked) autostart_timer = self.old_settings.get("autostart_timer") if autostart_timer: self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autostart_timer_checkbox.setCheckState(QtCore.Qt.Unchecked) autostop_timer = self.old_settings.get("autostop_timer") if autostop_timer: self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autostop_timer_checkbox.setCheckState(QtCore.Qt.Unchecked) save_private_key = self.old_settings.get("save_private_key") if save_private_key: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Checked) else: self.save_private_key_checkbox.setCheckState(QtCore.Qt.Unchecked) use_legacy_v2_onions = self.old_settings.get("use_legacy_v2_onions") if use_legacy_v2_onions: self.use_legacy_v2_onions_checkbox.setCheckState(QtCore.Qt.Checked) self.use_stealth_widget.show() else: self.use_stealth_widget.hide() data_dir = self.old_settings.get("data_dir") self.data_dir_lineedit.setText(data_dir) public_mode = self.old_settings.get("public_mode") if public_mode: self.public_mode_checkbox.setCheckState(QtCore.Qt.Checked) else: self.public_mode_checkbox.setCheckState(QtCore.Qt.Unchecked) use_stealth = self.old_settings.get("use_stealth") if use_stealth: self.stealth_checkbox.setCheckState(QtCore.Qt.Checked) # Legacy v2 mode is forced on if Stealth is enabled self.use_legacy_v2_onions_checkbox.setEnabled(False) if save_private_key and self.old_settings.get("hidservauth_string") != "": self.hidservauth_details.show() self.hidservauth_copy_button.show() else: self.stealth_checkbox.setCheckState(QtCore.Qt.Unchecked) use_autoupdate = self.old_settings.get("use_autoupdate") if use_autoupdate: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Checked) else: self.autoupdate_checkbox.setCheckState(QtCore.Qt.Unchecked) autoupdate_timestamp = self.old_settings.get("autoupdate_timestamp") self._update_autoupdate_timestamp(autoupdate_timestamp) locale = self.old_settings.get("locale") locale_index = self.language_combobox.findData(QtCore.QVariant(locale)) self.language_combobox.setCurrentIndex(locale_index) connection_type = self.old_settings.get("connection_type") if connection_type == "bundled": if self.connection_type_bundled_radio.isEnabled(): self.connection_type_bundled_radio.setChecked(True) else: # If bundled tor is disabled, fallback to automatic self.connection_type_automatic_radio.setChecked(True) elif connection_type == "automatic": self.connection_type_automatic_radio.setChecked(True) elif connection_type == "control_port": self.connection_type_control_port_radio.setChecked(True) elif connection_type == "socket_file": self.connection_type_socket_file_radio.setChecked(True) self.connection_type_control_port_extras_address.setText( self.old_settings.get("control_port_address") ) self.connection_type_control_port_extras_port.setText( str(self.old_settings.get("control_port_port")) ) self.connection_type_socket_file_extras_path.setText( self.old_settings.get("socket_file_path") ) self.connection_type_socks_address.setText( self.old_settings.get("socks_address") ) self.connection_type_socks_port.setText( str(self.old_settings.get("socks_port")) ) auth_type = self.old_settings.get("auth_type") if auth_type == "no_auth": self.authenticate_no_auth_radio.setChecked(True) elif auth_type == "password": self.authenticate_password_radio.setChecked(True) self.authenticate_password_extras_password.setText( self.old_settings.get("auth_password") ) if self.old_settings.get("no_bridges"): self.tor_bridges_no_bridges_radio.setChecked(True) self.tor_bridges_use_obfs4_radio.setChecked(False) self.tor_bridges_use_meek_lite_azure_radio.setChecked(False) self.tor_bridges_use_custom_radio.setChecked(False) else: self.tor_bridges_no_bridges_radio.setChecked(False) self.tor_bridges_use_obfs4_radio.setChecked( self.old_settings.get("tor_bridges_use_obfs4") ) self.tor_bridges_use_meek_lite_azure_radio.setChecked( self.old_settings.get("tor_bridges_use_meek_lite_azure") ) if self.old_settings.get("tor_bridges_use_custom_bridges"): self.tor_bridges_use_custom_radio.setChecked(True) # Remove the 'Bridge' lines at the start of each bridge. # They are added automatically to provide compatibility with # copying/pasting bridges provided from https://bridges.torproject.org new_bridges = [] bridges = self.old_settings.get("tor_bridges_use_custom_bridges").split( "Bridge " ) for bridge in bridges: new_bridges.append(bridge) new_bridges = "".join(new_bridges) self.tor_bridges_use_custom_textbox.setPlainText(new_bridges) # If we're connected to Tor, show onion service settings, show label if not if self.onion.is_authenticated(): self.connect_to_tor_label.hide() self.onion_settings_widget.show() # If v3 onion services are supported, allow using legacy mode if self.onion.supports_v3_onions: self.common.log("SettingsDialog", "__init__", "v3 onions are supported") self.use_legacy_v2_onions_checkbox.show() else: self.common.log( "SettingsDialog", "__init__", "v3 onions are not supported" ) self.use_legacy_v2_onions_widget.hide() self.use_legacy_v2_onions_checkbox_clicked(True) else: self.connect_to_tor_label.show() self.onion_settings_widget.hide() def connection_type_bundled_toggled(self, checked): """ Connection type bundled was toggled. If checked, hide authentication fields. """ self.common.log("SettingsDialog", "connection_type_bundled_toggled") if self.hide_tor_settings: return if checked: self.authenticate_group.hide() self.connection_type_socks.hide() self.connection_type_bridges_radio_group.show() def tor_bridges_no_bridges_radio_toggled(self, checked): """ 'No bridges' option was toggled. If checked, enable other bridge options. """ if self.hide_tor_settings: return if checked: self.tor_bridges_use_custom_textbox_options.hide() def tor_bridges_use_obfs4_radio_toggled(self, checked): """ obfs4 bridges option was toggled. If checked, disable custom bridge options. """ if self.hide_tor_settings: return if checked: self.tor_bridges_use_custom_textbox_options.hide() def tor_bridges_use_meek_lite_azure_radio_toggled(self, checked): """ meek_lite_azure bridges option was toggled. If checked, disable custom bridge options. """ if self.hide_tor_settings: return if checked: self.tor_bridges_use_custom_textbox_options.hide() # Alert the user about meek's costliness if it looks like they're turning it on if not self.old_settings.get("tor_bridges_use_meek_lite_azure"): Alert( self.common, strings._("gui_settings_meek_lite_expensive_warning"), QtWidgets.QMessageBox.Warning, ) def tor_bridges_use_custom_radio_toggled(self, checked): """ Custom bridges option was toggled. If checked, show custom bridge options. """ if self.hide_tor_settings: return if checked: self.tor_bridges_use_custom_textbox_options.show() def connection_type_automatic_toggled(self, checked): """ Connection type automatic was toggled. If checked, hide authentication fields. """ self.common.log("SettingsDialog", "connection_type_automatic_toggled") if self.hide_tor_settings: return if checked: self.authenticate_group.hide() self.connection_type_socks.hide() self.connection_type_bridges_radio_group.hide() def connection_type_control_port_toggled(self, checked): """ Connection type control port was toggled. If checked, show extra fields for Tor control address and port. If unchecked, hide those extra fields. """ self.common.log("SettingsDialog", "connection_type_control_port_toggled") if self.hide_tor_settings: return if checked: self.authenticate_group.show() self.connection_type_control_port_extras.show() self.connection_type_socks.show() self.connection_type_bridges_radio_group.hide() else: self.connection_type_control_port_extras.hide() def connection_type_socket_file_toggled(self, checked): """ Connection type socket file was toggled. If checked, show extra fields for socket file. If unchecked, hide those extra fields. """ self.common.log("SettingsDialog", "connection_type_socket_file_toggled") if self.hide_tor_settings: return if checked: self.authenticate_group.show() self.connection_type_socket_file_extras.show() self.connection_type_socks.show() self.connection_type_bridges_radio_group.hide() else: self.connection_type_socket_file_extras.hide() def authenticate_no_auth_toggled(self, checked): """ Authentication option no authentication was toggled. """ self.common.log("SettingsDialog", "authenticate_no_auth_toggled") def authenticate_password_toggled(self, checked): """ Authentication option password was toggled. If checked, show extra fields for password auth. If unchecked, hide those extra fields. """ self.common.log("SettingsDialog", "authenticate_password_toggled") if checked: self.authenticate_password_extras.show() else: self.authenticate_password_extras.hide() def hidservauth_copy_button_clicked(self): """ Toggle the 'Copy HidServAuth' button to copy the saved HidServAuth to clipboard. """ self.common.log( "SettingsDialog", "hidservauth_copy_button_clicked", "HidServAuth was copied to clipboard", ) clipboard = self.qtapp.clipboard() clipboard.setText(self.old_settings.get("hidservauth_string")) def use_legacy_v2_onions_checkbox_clicked(self, checked): """ Show the legacy settings if the legacy mode is enabled. """ if checked: self.use_stealth_widget.show() else: self.use_stealth_widget.hide() def stealth_checkbox_clicked_connect(self, checked): """ Prevent the v2 legacy mode being switched off if stealth is enabled """ if checked: self.use_legacy_v2_onions_checkbox.setCheckState(QtCore.Qt.Checked) self.use_legacy_v2_onions_checkbox.setEnabled(False) else: self.use_legacy_v2_onions_checkbox.setEnabled(True) def data_dir_button_clicked(self): """ Browse for a new OnionShare data directory """ data_dir = self.data_dir_lineedit.text() selected_dir = QtWidgets.QFileDialog.getExistingDirectory( self, strings._("gui_settings_data_dir_label"), data_dir ) if selected_dir: self.common.log( "SettingsDialog", "data_dir_button_clicked", "selected dir: {}".format(selected_dir), ) self.data_dir_lineedit.setText(selected_dir) def test_tor_clicked(self): """ Test Tor Settings button clicked. With the given settings, see if we can successfully connect and authenticate to Tor. """ self.common.log("SettingsDialog", "test_tor_clicked") settings = self.settings_from_fields() try: # Show Tor connection status if connection type is bundled tor if settings.get("connection_type") == "bundled": self.tor_status.show() self._disable_buttons() def tor_status_update_func(progress, summary): self._tor_status_update(progress, summary) return True else: tor_status_update_func = None onion = Onion(self.common) onion.connect( custom_settings=settings, config=self.config, tor_status_update_func=tor_status_update_func, ) # If an exception hasn't been raised yet, the Tor settings work Alert( self.common, strings._("settings_test_success").format( onion.tor_version, onion.supports_ephemeral, onion.supports_stealth, onion.supports_v3_onions, ), ) # Clean up onion.cleanup() except ( TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile, TorErrorAuthError, TorErrorProtocolError, BundledTorNotSupported, BundledTorTimeout, ) as e: Alert(self.common, e.args[0], QtWidgets.QMessageBox.Warning) if settings.get("connection_type") == "bundled": self.tor_status.hide() self._enable_buttons() def check_for_updates(self): """ Check for Updates button clicked. Manually force an update check. """ self.common.log("SettingsDialog", "check_for_updates") # Disable buttons self._disable_buttons() self.qtapp.processEvents() def update_timestamp(): # Update the last checked label settings = Settings(self.common, self.config) settings.load() autoupdate_timestamp = settings.get("autoupdate_timestamp") self._update_autoupdate_timestamp(autoupdate_timestamp) def close_forced_update_thread(): forced_update_thread.quit() # Enable buttons self._enable_buttons() # Update timestamp update_timestamp() # Check for updates def update_available(update_url, installed_version, latest_version): Alert( self.common, strings._("update_available").format( update_url, installed_version, latest_version ), ) close_forced_update_thread() def update_not_available(): Alert(self.common, strings._("update_not_available")) close_forced_update_thread() def update_error(): Alert( self.common, strings._("update_error_check_error"), QtWidgets.QMessageBox.Warning, ) close_forced_update_thread() def update_invalid_version(latest_version): Alert( self.common, strings._("update_error_invalid_latest_version").format(latest_version), QtWidgets.QMessageBox.Warning, ) close_forced_update_thread() forced_update_thread = UpdateThread( self.common, self.onion, self.config, force=True ) forced_update_thread.update_available.connect(update_available) forced_update_thread.update_not_available.connect(update_not_available) forced_update_thread.update_error.connect(update_error) forced_update_thread.update_invalid_version.connect(update_invalid_version) forced_update_thread.start() def save_clicked(self): """ Save button clicked. Save current settings to disk. """ self.common.log("SettingsDialog", "save_clicked") def changed(s1, s2, keys): """ Compare the Settings objects s1 and s2 and return true if any values have changed for the given keys. """ for key in keys: if s1.get(key) != s2.get(key): return True return False settings = self.settings_from_fields() if settings: # If language changed, inform user they need to restart OnionShare if changed(settings, self.old_settings, ["locale"]): # Look up error message in different locale new_locale = settings.get("locale") if ( new_locale in strings.translations and "gui_settings_language_changed_notice" in strings.translations[new_locale] ): notice = strings.translations[new_locale][ "gui_settings_language_changed_notice" ] else: notice = strings._("gui_settings_language_changed_notice") Alert(self.common, notice, QtWidgets.QMessageBox.Information) # Save the new settings settings.save() # If Tor isn't connected, or if Tor settings have changed, Reinitialize # the Onion object reboot_onion = False if not self.local_only: if self.onion.is_authenticated(): self.common.log( "SettingsDialog", "save_clicked", "Connected to Tor" ) if changed( settings, self.old_settings, [ "connection_type", "control_port_address", "control_port_port", "socks_address", "socks_port", "socket_file_path", "auth_type", "auth_password", "no_bridges", "tor_bridges_use_obfs4", "tor_bridges_use_meek_lite_azure", "tor_bridges_use_custom_bridges", ], ): reboot_onion = True else: self.common.log( "SettingsDialog", "save_clicked", "Not connected to Tor" ) # Tor isn't connected, so try connecting reboot_onion = True # Do we need to reinitialize Tor? if reboot_onion: # Reinitialize the Onion object self.common.log( "SettingsDialog", "save_clicked", "rebooting the Onion" ) self.onion.cleanup() tor_con = TorConnectionDialog( self.common, self.qtapp, self.onion, settings ) tor_con.start() self.common.log( "SettingsDialog", "save_clicked", "Onion done rebooting, connected to Tor: {}".format( self.onion.connected_to_tor ), ) if self.onion.is_authenticated() and not tor_con.wasCanceled(): self.settings_saved.emit() self.close() else: self.settings_saved.emit() self.close() else: self.settings_saved.emit() self.close() def cancel_clicked(self): """ Cancel button clicked. """ self.common.log("SettingsDialog", "cancel_clicked") if not self.local_only and not self.onion.is_authenticated(): Alert( self.common, strings._("gui_tor_connection_canceled"), QtWidgets.QMessageBox.Warning, ) sys.exit() else: self.close() def help_clicked(self): """ Help button clicked. """ self.common.log("SettingsDialog", "help_clicked") SettingsDialog.open_help() @staticmethod def open_help(): help_url = "https://github.com/micahflee/onionshare/wiki" QtGui.QDesktopServices.openUrl(QtCore.QUrl(help_url)) def settings_from_fields(self): """ Return a Settings object that's full of values from the settings dialog. """ self.common.log("SettingsDialog", "settings_from_fields") settings = Settings(self.common, self.config) settings.load() # To get the last update timestamp settings.set( "close_after_first_download", self.close_after_first_download_checkbox.isChecked(), ) settings.set( "csp_header_disabled", self.csp_header_disabled_checkbox.isChecked() ) settings.set("autostart_timer", self.autostart_timer_checkbox.isChecked()) settings.set("autostop_timer", self.autostop_timer_checkbox.isChecked()) # Complicated logic here to force v2 onion mode on or off depending on other settings if self.use_legacy_v2_onions_checkbox.isChecked(): use_legacy_v2_onions = True else: use_legacy_v2_onions = False if self.save_private_key_checkbox.isChecked(): settings.set("save_private_key", True) settings.set("private_key", self.old_settings.get("private_key")) settings.set("password", self.old_settings.get("password")) settings.set( "hidservauth_string", self.old_settings.get("hidservauth_string") ) else: settings.set("save_private_key", False) settings.set("private_key", "") settings.set("password", "") # Also unset the HidServAuth if we are removing our reusable private key settings.set("hidservauth_string", "") if use_legacy_v2_onions: settings.set("use_legacy_v2_onions", True) else: settings.set("use_legacy_v2_onions", False) settings.set("data_dir", self.data_dir_lineedit.text()) settings.set("public_mode", self.public_mode_checkbox.isChecked()) settings.set("use_stealth", self.stealth_checkbox.isChecked()) # Always unset the HidServAuth if Stealth mode is unset if not self.stealth_checkbox.isChecked(): settings.set("hidservauth_string", "") # Language locale_index = self.language_combobox.currentIndex() locale = self.language_combobox.itemData(locale_index) settings.set("locale", locale) # Tor connection if self.connection_type_bundled_radio.isChecked(): settings.set("connection_type", "bundled") if self.connection_type_automatic_radio.isChecked(): settings.set("connection_type", "automatic") if self.connection_type_control_port_radio.isChecked(): settings.set("connection_type", "control_port") if self.connection_type_socket_file_radio.isChecked(): settings.set("connection_type", "socket_file") if self.autoupdate_checkbox.isChecked(): settings.set("use_autoupdate", True) else: settings.set("use_autoupdate", False) settings.set( "control_port_address", self.connection_type_control_port_extras_address.text(), ) settings.set( "control_port_port", self.connection_type_control_port_extras_port.text() ) settings.set( "socket_file_path", self.connection_type_socket_file_extras_path.text() ) settings.set("socks_address", self.connection_type_socks_address.text()) settings.set("socks_port", self.connection_type_socks_port.text()) if self.authenticate_no_auth_radio.isChecked(): settings.set("auth_type", "no_auth") if self.authenticate_password_radio.isChecked(): settings.set("auth_type", "password") settings.set("auth_password", self.authenticate_password_extras_password.text()) # Whether we use bridges if self.tor_bridges_no_bridges_radio.isChecked(): settings.set("no_bridges", True) settings.set("tor_bridges_use_obfs4", False) settings.set("tor_bridges_use_meek_lite_azure", False) settings.set("tor_bridges_use_custom_bridges", "") if self.tor_bridges_use_obfs4_radio.isChecked(): settings.set("no_bridges", False) settings.set("tor_bridges_use_obfs4", True) settings.set("tor_bridges_use_meek_lite_azure", False) settings.set("tor_bridges_use_custom_bridges", "") if self.tor_bridges_use_meek_lite_azure_radio.isChecked(): settings.set("no_bridges", False) settings.set("tor_bridges_use_obfs4", False) settings.set("tor_bridges_use_meek_lite_azure", True) settings.set("tor_bridges_use_custom_bridges", "") if self.tor_bridges_use_custom_radio.isChecked(): settings.set("no_bridges", False) settings.set("tor_bridges_use_obfs4", False) settings.set("tor_bridges_use_meek_lite_azure", False) # Insert a 'Bridge' line at the start of each bridge. # This makes it easier to copy/paste a set of bridges # provided from https://bridges.torproject.org new_bridges = [] bridges = self.tor_bridges_use_custom_textbox.toPlainText().split("\n") bridges_valid = False for bridge in bridges: if bridge != "": # Check the syntax of the custom bridge to make sure it looks legitimate ipv4_pattern = re.compile( "(obfs4\s+)?(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):([0-9]+)(\s+)([A-Z0-9]+)(.+)$" ) ipv6_pattern = re.compile( "(obfs4\s+)?\[(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\]:[0-9]+\s+[A-Z0-9]+(.+)$" ) meek_lite_pattern = re.compile( "(meek_lite)(\s)+([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:[0-9]+)(\s)+([0-9A-Z]+)(\s)+url=(.+)(\s)+front=(.+)" ) if ( ipv4_pattern.match(bridge) or ipv6_pattern.match(bridge) or meek_lite_pattern.match(bridge) ): new_bridges.append("".join(["Bridge ", bridge, "\n"])) bridges_valid = True if bridges_valid: new_bridges = "".join(new_bridges) settings.set("tor_bridges_use_custom_bridges", new_bridges) else: Alert(self.common, strings._("gui_settings_tor_bridges_invalid")) settings.set("no_bridges", True) return False return settings def closeEvent(self, e): self.common.log("SettingsDialog", "closeEvent") # On close, if Tor isn't connected, then quit OnionShare altogether if not self.local_only: if not self.onion.is_authenticated(): self.common.log( "SettingsDialog", "closeEvent", "Closing while not connected to Tor" ) # Wait 1ms for the event loop to finish, then quit QtCore.QTimer.singleShot(1, self.qtapp.quit) def _update_autoupdate_timestamp(self, autoupdate_timestamp): self.common.log("SettingsDialog", "_update_autoupdate_timestamp") if autoupdate_timestamp: dt = datetime.datetime.fromtimestamp(autoupdate_timestamp) last_checked = dt.strftime("%B %d, %Y %H:%M") else: last_checked = strings._("gui_settings_autoupdate_timestamp_never") self.autoupdate_timestamp.setText( strings._("gui_settings_autoupdate_timestamp").format(last_checked) ) def _tor_status_update(self, progress, summary): self.tor_status.setText( "{}
{}% {}".format( strings._("connecting_to_tor"), progress, summary ) ) self.qtapp.processEvents() if "Done" in summary: self.tor_status.hide() self._enable_buttons() def _disable_buttons(self): self.common.log("SettingsDialog", "_disable_buttons") self.check_for_updates_button.setEnabled(False) self.connection_type_test_button.setEnabled(False) self.save_button.setEnabled(False) self.cancel_button.setEnabled(False) def _enable_buttons(self): self.common.log("SettingsDialog", "_enable_buttons") # We can't check for updates if we're still not connected to Tor if not self.onion.connected_to_tor: self.check_for_updates_button.setEnabled(False) else: self.check_for_updates_button.setEnabled(True) self.connection_type_test_button.setEnabled(True) self.save_button.setEnabled(True) self.cancel_button.setEnabled(True) onionshare-2.2/onionshare_gui/threads.py000066400000000000000000000125331355066717400205610ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ import time from PyQt5 import QtCore from onionshare.onion import * class OnionThread(QtCore.QThread): """ Starts the onion service, and waits for it to finish """ success = QtCore.pyqtSignal() success_early = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def __init__(self, mode): super(OnionThread, self).__init__() self.mode = mode self.mode.common.log("OnionThread", "__init__") # allow this thread to be terminated self.setTerminationEnabled() def run(self): self.mode.common.log("OnionThread", "run") # Make a new static URL path for each new share self.mode.web.generate_static_url_path() # Choose port and password early, because we need them to exist in advance for scheduled shares self.mode.app.stay_open = not self.mode.common.settings.get( "close_after_first_download" ) if not self.mode.app.port: self.mode.app.choose_port() if not self.mode.common.settings.get("public_mode"): if not self.mode.web.password: self.mode.web.generate_password( self.mode.common.settings.get("password") ) try: if self.mode.obtain_onion_early: self.mode.app.start_onion_service( await_publication=False, save_scheduled_key=True ) # wait for modules in thread to load, preventing a thread-related cx_Freeze crash time.sleep(0.2) self.success_early.emit() # Unregister the onion so we can use it in the next OnionThread self.mode.app.onion.cleanup(False) else: self.mode.app.start_onion_service(await_publication=True) # wait for modules in thread to load, preventing a thread-related cx_Freeze crash time.sleep(0.2) # start onionshare http service in new thread self.mode.web_thread = WebThread(self.mode) self.mode.web_thread.start() self.success.emit() except ( TorTooOld, TorErrorInvalidSetting, TorErrorAutomatic, TorErrorSocketPort, TorErrorSocketFile, TorErrorMissingPassword, TorErrorUnreadableCookieFile, TorErrorAuthError, TorErrorProtocolError, BundledTorTimeout, OSError, ) as e: self.error.emit(e.args[0]) return class WebThread(QtCore.QThread): """ Starts the web service """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def __init__(self, mode): super(WebThread, self).__init__() self.mode = mode self.mode.common.log("WebThread", "__init__") def run(self): self.mode.common.log("WebThread", "run") self.mode.web.start( self.mode.app.port, self.mode.app.stay_open, self.mode.common.settings.get("public_mode"), self.mode.web.password, ) self.success.emit() class AutoStartTimer(QtCore.QThread): """ Waits for a prescribed time before allowing a share to start """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def __init__(self, mode, canceled=False): super(AutoStartTimer, self).__init__() self.mode = mode self.canceled = canceled self.mode.common.log("AutoStartTimer", "__init__") # allow this thread to be terminated self.setTerminationEnabled() def run(self): now = QtCore.QDateTime.currentDateTime() autostart_timer_datetime_delta = now.secsTo( self.mode.server_status.autostart_timer_datetime ) try: # Sleep until scheduled time while autostart_timer_datetime_delta > 0 and self.canceled == False: time.sleep(0.1) now = QtCore.QDateTime.currentDateTime() autostart_timer_datetime_delta = now.secsTo( self.mode.server_status.autostart_timer_datetime ) # Timer has now finished if self.canceled == False: self.mode.server_status.server_button.setText( strings._("gui_please_wait") ) self.mode.server_status_label.setText( strings._("gui_status_indicator_share_working") ) self.success.emit() except ValueError as e: self.error.emit(e.args[0]) return onionshare-2.2/onionshare_gui/tor_connection_dialog.py000066400000000000000000000130011355066717400234600ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore, QtWidgets, QtGui from onionshare import strings from onionshare.onion import * from .widgets import Alert class TorConnectionDialog(QtWidgets.QProgressDialog): """ Connecting to Tor dialog. """ open_settings = QtCore.pyqtSignal() def __init__(self, common, qtapp, onion, custom_settings=False): super(TorConnectionDialog, self).__init__(None) self.common = common if custom_settings: self.settings = custom_settings else: self.settings = self.common.settings self.common.log("TorConnectionDialog", "__init__") self.qtapp = qtapp self.onion = onion self.setWindowTitle("OnionShare") self.setWindowIcon( QtGui.QIcon(self.common.get_resource_path("images/logo.png")) ) self.setModal(True) self.setFixedSize(400, 150) # Label self.setLabelText(strings._("connecting_to_tor")) # Progress bar ticks from 0 to 100 self.setRange(0, 100) # Don't show if connection takes less than 100ms (for non-bundled tor) self.setMinimumDuration(100) # Start displaying the status at 0 self._tor_status_update(0, "") def start(self): self.common.log("TorConnectionDialog", "start") t = TorConnectionThread(self.common, self.settings, self, self.onion) t.tor_status_update.connect(self._tor_status_update) t.connected_to_tor.connect(self._connected_to_tor) t.canceled_connecting_to_tor.connect(self._canceled_connecting_to_tor) t.error_connecting_to_tor.connect(self._error_connecting_to_tor) t.start() # The main thread needs to remain active, and checking for Qt events, # until the thread is finished. Otherwise it won't be able to handle # accepting signals. self.active = True while self.active: time.sleep(0.1) self.qtapp.processEvents() def _tor_status_update(self, progress, summary): self.setValue(int(progress)) self.setLabelText( "{}
{}".format(strings._("connecting_to_tor"), summary) ) def _connected_to_tor(self): self.common.log("TorConnectionDialog", "_connected_to_tor") self.active = False # Close the dialog after connecting self.setValue(self.maximum()) def _canceled_connecting_to_tor(self): self.common.log("TorConnectionDialog", "_canceled_connecting_to_tor") self.active = False self.onion.cleanup() # Cancel connecting to Tor QtCore.QTimer.singleShot(1, self.cancel) def _error_connecting_to_tor(self, msg): self.common.log("TorConnectionDialog", "_error_connecting_to_tor") self.active = False def alert_and_open_settings(): # Display the exception in an alert box Alert( self.common, "{}\n\n{}".format(msg, strings._("gui_tor_connection_error_settings")), QtWidgets.QMessageBox.Warning, ) # Open settings self.open_settings.emit() QtCore.QTimer.singleShot(1, alert_and_open_settings) # Cancel connecting to Tor QtCore.QTimer.singleShot(1, self.cancel) class TorConnectionThread(QtCore.QThread): tor_status_update = QtCore.pyqtSignal(str, str) connected_to_tor = QtCore.pyqtSignal() canceled_connecting_to_tor = QtCore.pyqtSignal() error_connecting_to_tor = QtCore.pyqtSignal(str) def __init__(self, common, settings, dialog, onion): super(TorConnectionThread, self).__init__() self.common = common self.common.log("TorConnectionThread", "__init__") self.settings = settings self.dialog = dialog self.onion = onion def run(self): self.common.log("TorConnectionThread", "run") # Connect to the Onion try: self.onion.connect(self.settings, False, self._tor_status_update) if self.onion.connected_to_tor: self.connected_to_tor.emit() else: self.canceled_connecting_to_tor.emit() except BundledTorCanceled as e: self.common.log( "TorConnectionThread", "run", "caught exception: BundledTorCanceled" ) self.canceled_connecting_to_tor.emit() except Exception as e: self.common.log( "TorConnectionThread", "run", "caught exception: {}".format(e.args[0]) ) self.error_connecting_to_tor.emit(str(e.args[0])) def _tor_status_update(self, progress, summary): self.tor_status_update.emit(progress, summary) # Return False if the dialog was canceled return not self.dialog.wasCanceled() onionshare-2.2/onionshare_gui/update_checker.py000066400000000000000000000210541355066717400220730ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore import datetime, time, socket, re, platform import socks from distutils.version import LooseVersion as Version from onionshare.settings import Settings from onionshare.onion import Onion from onionshare import strings class UpdateCheckerCheckError(Exception): """ Error checking for updates because of some Tor connection issue, or because the OnionShare website is down. """ pass class UpdateCheckerInvalidLatestVersion(Exception): """ Successfully downloaded the latest version, but it doesn't appear to be a valid version string. """ def __init__(self, latest_version): self.latest_version = latest_version class UpdateChecker(QtCore.QObject): """ Load http://elx57ue5uyfplgva.onion/latest-version.txt to see what the latest version of OnionShare is. If the latest version is newer than the installed version, alert the user. Only check at most once per day, unless force is True. """ update_available = QtCore.pyqtSignal(str, str, str) update_not_available = QtCore.pyqtSignal() update_error = QtCore.pyqtSignal() update_invalid_version = QtCore.pyqtSignal(str) def __init__(self, common, onion, config=False): super(UpdateChecker, self).__init__() self.common = common self.common.log("UpdateChecker", "__init__") self.onion = onion self.config = config def check(self, force=False, config=False): self.common.log("UpdateChecker", "check", "force={}".format(force)) # Load the settings settings = Settings(self.common, config) settings.load() # If force=True, then definitely check if force: check_for_updates = True else: check_for_updates = False # See if it's been 1 day since the last check autoupdate_timestamp = settings.get("autoupdate_timestamp") if autoupdate_timestamp: last_checked = datetime.datetime.fromtimestamp(autoupdate_timestamp) now = datetime.datetime.now() one_day = datetime.timedelta(days=1) if now - last_checked > one_day: check_for_updates = True else: check_for_updates = True # Check for updates if check_for_updates: self.common.log("UpdateChecker", "check", "checking for updates") # Download the latest-version file over Tor try: # User agent string includes OnionShare version and platform user_agent = "OnionShare {}, {}".format( self.common.version, self.common.platform ) # If the update is forced, add '?force=1' to the URL, to more # accurately measure daily users path = "/latest-version.txt" if force: path += "?force=1" if Version(self.onion.tor_version) >= Version("0.3.2.9"): onion_domain = ( "lldan5gahapx5k7iafb3s4ikijc4ni7gx5iywdflkba5y2ezyg6sjgyd.onion" ) else: onion_domain = "elx57ue5uyfplgva.onion" self.common.log( "UpdateChecker", "check", "loading http://{}{}".format(onion_domain, path), ) (socks_address, socks_port) = self.onion.get_tor_socks_port() socks.set_default_proxy(socks.SOCKS5, socks_address, socks_port) s = socks.socksocket() s.settimeout(15) # 15 second timeout s.connect((onion_domain, 80)) http_request = "GET {} HTTP/1.0\r\n".format(path) http_request += "Host: {}\r\n".format(onion_domain) http_request += "User-Agent: {}\r\n".format(user_agent) http_request += "\r\n" s.sendall(http_request.encode("utf-8")) http_response = s.recv(1024) latest_version = ( http_response[http_response.find(b"\r\n\r\n") :] .strip() .decode("utf-8") ) self.common.log( "UpdateChecker", "check", "latest OnionShare version: {}".format(latest_version), ) except Exception as e: self.common.log("UpdateChecker", "check", "{}".format(e)) self.update_error.emit() raise UpdateCheckerCheckError # Validate that latest_version looks like a version string # This regex is: 1-3 dot-separated numeric components version_re = r"^(\d+\.)?(\d+\.)?(\d+)$" if not re.match(version_re, latest_version): self.update_invalid_version.emit(latest_version) raise UpdateCheckerInvalidLatestVersion(latest_version) # Update the last checked timestamp (dropping the seconds and milliseconds) timestamp = ( datetime.datetime.now() .replace(microsecond=0) .replace(second=0) .timestamp() ) # Re-load the settings first before saving, just in case they've changed since we started our thread settings.load() settings.set("autoupdate_timestamp", timestamp) settings.save() # Do we need to update? update_url = "https://github.com/micahflee/onionshare/releases/tag/v{}".format( latest_version ) installed_version = self.common.version if installed_version < latest_version: self.update_available.emit( update_url, installed_version, latest_version ) return # No updates are available self.update_not_available.emit() class UpdateThread(QtCore.QThread): update_available = QtCore.pyqtSignal(str, str, str) update_not_available = QtCore.pyqtSignal() update_error = QtCore.pyqtSignal() update_invalid_version = QtCore.pyqtSignal(str) def __init__(self, common, onion, config=False, force=False): super(UpdateThread, self).__init__() self.common = common self.common.log("UpdateThread", "__init__") self.onion = onion self.config = config self.force = force def run(self): self.common.log("UpdateThread", "run") u = UpdateChecker(self.common, self.onion, self.config) u.update_available.connect(self._update_available) u.update_not_available.connect(self._update_not_available) u.update_error.connect(self._update_error) u.update_invalid_version.connect(self._update_invalid_version) try: u.check(config=self.config, force=self.force) except Exception as e: # If update check fails, silently ignore self.common.log("UpdateThread", "run", "{}".format(e)) pass def _update_available(self, update_url, installed_version, latest_version): self.common.log("UpdateThread", "_update_available") self.active = False self.update_available.emit(update_url, installed_version, latest_version) def _update_not_available(self): self.common.log("UpdateThread", "_update_not_available") self.active = False self.update_not_available.emit() def _update_error(self): self.common.log("UpdateThread", "_update_error") self.active = False self.update_error.emit() def _update_invalid_version(self, latest_version): self.common.log("UpdateThread", "_update_invalid_version") self.active = False self.update_invalid_version.emit(latest_version) onionshare-2.2/onionshare_gui/widgets.py000066400000000000000000000051141355066717400205720ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014-2018 Micah Lee 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 . """ from PyQt5 import QtCore, QtWidgets, QtGui class Alert(QtWidgets.QMessageBox): """ An alert box dialog. """ def __init__( self, common, message, icon=QtWidgets.QMessageBox.NoIcon, buttons=QtWidgets.QMessageBox.Ok, autostart=True, ): super(Alert, self).__init__(None) self.common = common self.common.log("Alert", "__init__") self.setWindowTitle("OnionShare") self.setWindowIcon( QtGui.QIcon(self.common.get_resource_path("images/logo.png")) ) self.setText(message) self.setIcon(icon) self.setStandardButtons(buttons) if autostart: self.exec_() class AddFileDialog(QtWidgets.QFileDialog): """ Overridden version of QFileDialog which allows us to select folders as well as, or instead of, files. For adding files/folders to share. Note that this dialog can't be used in macOS, only in Windows, Linux, and BSD. This is because the macOS sandbox requires native dialogs, and this is a Qt5 dialog. """ def __init__(self, common, *args, **kwargs): QtWidgets.QFileDialog.__init__(self, *args, **kwargs) self.common = common self.common.log("AddFileDialog", "__init__") self.setOption(self.DontUseNativeDialog, True) self.setOption(self.ReadOnly, True) self.setOption(self.ShowDirsOnly, False) self.setFileMode(self.ExistingFiles) tree_view = self.findChild(QtWidgets.QTreeView) tree_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) list_view = self.findChild(QtWidgets.QListView, "listView") list_view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) def accept(self): self.common.log("AddFileDialog", "accept") QtWidgets.QDialog.accept(self) onionshare-2.2/screenshots/000077500000000000000000000000001355066717400161005ustar00rootroot00000000000000onionshare-2.2/screenshots/appdata-onionshare-receive-client.png000066400000000000000000013015711355066717400252670ustar00rootroot00000000000000PNG  IHDR}VzTXtRaw profile type exifxڭirܸcr\ adv^Ub p3rsS|.Gq=)ߎ;>>"E=09^~\~ܵ{;Iwy=Pnr߃`Xa]<)$請$fFI'N};عϏ?c?{(O1zsyیB_^fD>B|E(sYWܞY&cF6hߐn8)x"1n"cd#1mϹ;[,p//9н* 8PHH'}iF% '̝q_!V ?j+=yNW|v{BĽ R 5c 8v3yL9.2J%7)Uӣ5-<_QRM@$+BܩYxTJ^F5\KUalVZm6^z>q$ :}1'7 =zrƜ+*kng]vm=hh֜u6O8ɧzgynnϬ=k9k5e,?YpkCIQX́7eʙ!)g~DDcA#Xnݏ1oWsJGRܯyMl> S.v}MlDcHk9Z7 5-#c|F9]Kg*Kf;w(+QNa~ L뱨Js0YT|BM;-tV9^kesk\ߙ㜮Z[$۷o30,Vock}B!>nZl;k>ux#X'+]f}_5H{ZZ>C v_3mY%÷[ڷY<#sJ\øt'Zm[KUpLȢG;U}o᪥.enAD3UK&B߭s&Xrf]-0M!S>s :EHзvz_ ?5BZhs S =uW)Pϐsȕͻ+{]pO`^)ԣѦJNAS~p<2Ӥṛxq]Z YsMn{ΔyGcU 衎h30 B@J͇P]|b]+I9-JylNi#`rL|O (ay4 X'-k =: QPgItӓDZ}jDϋA u zkj9nĎ~B[IkkEO *A L-^edmj`L:C)_ X!R6@I"8䦖  Ps[(\*VlX$]ow!Qr@c֦@s?-e%"tP6XVt\ԻTN" XiY@ԊSLȧ,)Сk^us9+1*?y -ݭss:)L7tpVHNQZ_/܄p)V3Tv 6 7f=+ -] [΋ RHg7e-a1eFA C&Rd{a^YP#E@8r@7@`I啷^nA,`\_Y~a]ֻK:굻A䕟7K@e*j4eS,c M(+w` Xg)!=B$f~P{aNby~';>3GW`HeĬ٤Bfa?h@!!$p7 ^Xy]zT$#xГ׉3`Fy 66P3WPc]Bcrz+Q1>12 #=(НǼѶ۝:%DFPLO0ZPb-^.2g@s 42{:NuHBdBІތH#ڐ$g-p06qO?|aCm h {!tfCrg_>A=XK>h*%PVG}"K=I #ҍM6U E{]K`2 bs $X1zԷy)'TL[<"иq* ytd`0'}#oJ,t!yX}l]w#Zl#j6"1 %" )a.>`|iӨ+ t8Ÿ]YVV9 { mEMsT@"~-q@H'o66HĜE;cF/p`M2D|V#,!;nY= 40!@i*X6]gT_jl@ dzN[:IqUBY O„@$!Iy g2 zA^vFjv^+!b[H@KBt$ez3jR!TOuTe6l*8VhB_$,ŮM@,ksZ&%Z&Fı0Oq‚Lin4XdF Qke탂C?Dɸ3 Zq[5[}@V3̨|ix Q[%FbSK#%EXl~nm{7M#R:?7v}5%cDŻCr1{<E,8|‚ĎI8mh#2WE雅F´gj T ){(^fƈEbx.1: qcEf\P\JI!7th#%;,C`Ƀ}NRaA>4n*FFf">8Q@ETuA1p$7;;0Xm  NF}!רiu,08ׁaJ+^G -1h8|MÜAЗ6voMc*lU,C]OΓ$IO_x~pg7m4y6AO>J=:?xPQdxѰqxa)Iu&ZskamABIA 9rڵ^r9E7CH2:-7\ߞ"MxDlA=.1!R;Zu.A\s&,A'RL0*ը-1)Z9 &F0RŠd*Ϲ"&UG؜5IC< h?ˁO)ՆHE$5) ˋOAD9[ymbQFsf &hl_U'G]j*'\&-Ŀ`ӣxԽ[=,xЗ@۾6B5DˑÀBA0w`T{F v0`yk4u3), lBw v.5g,{ l8OEeh^~`k'GCA %ggC9001|Dr*ꑓ?`n};Q Agi_P$=E?}@I94!8r"GuIE~(=W53n.*/uԞ=ő W$QdT䋍ھщà_mk-8})S6tmڤh>9 06 o ӼlHyvփ39g Rq{S[(K 0Zxm `q 8!ВdVA]xZ!v|Ku(Bz\Y7'FuH?Td@x!f|G"ZBzicDbVپ 'eq3= УjnPTofHgap >-\/`ƋD]-tq@A9wЅ wsk ~^jiS;ߵ<<:g'{XνuBOpiU#YI,hh$IP%6tN3+ʱ R˴@!0>";oz\L{ #&ظ3 @r9pW;WZtaro&L= ɏZE3D.N~^bf[$s(a9l QO  *K+$y?rc;-Fɾ6ǟ4g)+ѓ^ O׃P R* Ǒ2{IY?Smihh[eiTXtXML:com.adobe.xmp C0bKGD pHYs  tIME, IDATxyeEyUuadY$ ;**A( ƨq{5%1j^ A4(.l=s{`SιMtE[caAc@DQ!#sD:Z "^ת#֥SZ[kk}kuŏk&1X=cuX&}<佒5(]9^|.5ާ!RXÎhsqV9_Ktmgp̞=VcUUUUUUUUUUUUUU&'xո>,50& ˅)0 "8/|!~`V2 SH`a ؑf5s6)Sc&Bs=1< Bm&]w&C*o,`߾O''=gZ6>W\S8"YM}zͩc#f5o<`-h#w^a)L94e>SX,0Ƣmo2?D/k, #k%xc0?ϋgP|`X"%E!Oz-pz0/!M1502wΦuzFE֓@``9O3iuy-t O= J2Տ'w.>H|LZ)x+zEDhk׬yYh!$H+(4R%`v3(9@d4+p@&@yq-h#md8QS328gAɴOiHX8gsjGdZ8L0Api7[|mv]>;ĚM38q?5tFCiKJ,;N Ziqy!5ٕZʮ>JBָ(\~t0r_tO w⪪ߣBXfw;`a$חhvuįGǂ;.@÷Skr W2P֪TSKdVb:688HOeșl*ӕ~lbsG- 1f̮Mrp\Rc$;yl='GK`i0B-T,z#u"_+X)Y œ6!蛬2@m+bF{$XvEgL t;Cxp9Ð| -|mUUUUUUUUUUUUUU@Ӄ.m195'qtOfD67q"Rt0qlUFSt0hf'hiIh㏍''9mX ?ⵇlY}q NcԑiG(ƕ͹FŸ:ۼk\r۰̫t*ufPڶ\(+ Q?Tֺ|HB/Rsv7g9ǜeWqh͑޷JPaOl<"2taZY/̋Hm1bky{q[aN1e&Z 0 L1?DaiLbc~jl~ KqZQUUUUUUUUUUUUU4 @d܁ԘpBPn B%k*+4R p*b`d'1#OtzRG9ϕ:ѪS =5 +Gl@C=KĻF6;|4Et$h, z: iH噵o&N|>S]C$йyP@:)l-`,|!PMe7xPaٓt 8%FCTXYCI:Z-sF,jXWXUUUUUUUUUUUUUdAxf$!"SqaxTujY'̛ iqW\Dۀ<åcZ]UAPCC_:a6tjm c|4zuNqtz_bYǎS\Vr65M_ilt .&Um;HPf0dɒ:4Z)TmwhmPHo020jPr]FxxMl$^-B*T28g"q^2X4]Jy TČ p?BdA (Y:0iK6RZ qy],(\g-n?kkD9Kv}פa,3"1%s1.?.F6:䁋!v(C Rt٦(g~x!6]$:V5x)0 |C345~/Ⲓni %bYqM7][Ğ 'ƛDҍ~}9R@gyH&Kn>#y["u_s0P!󰪪j)v 00ٌ%Pwpk/1cMfTj&8ؐDG"sNӬx6סc"c\b%?=G*R]f^qY>l* ohv_R1No&^s=xߪnxֳ[ebi"b) S(if/҄1.Bf!>wd&[F(]TAAZp8=Ŏ7-y̞ê|Ls KE~$6EmDPm<Ma\-YM M`C4#7iᇰ0zf@01-UUUUUUUUUUUUUU  }‚&`kpcOY0_-tRP t BF]k/0?a9 潔\D0pOBt סFȅTs v`F15b! mb㙆b2C'vPKS +j{/.ae0x26ի@C.=MYoW#K)IR%%U-ֺ |Ly=6;T2ԭ6%ЉKnq桟aTWUUUUUUUUUUUUU=^e{,lߣl Xe <6KO9OvB NK!nt!˲[30 ^ !wHFX X5@NHz/">a&V^w_K9 kmJ{"q:w=1^#bŪ:; k{ "|AWJ-CJ+|P˛I,2D⇀i#A\l6a'_#Yv) o`iz8\ΜՓkB\鱆}eo?H.Yw(N h,L AyUUUUUUUUUUUUUպt^! ~͉ |4b')A.`.p y|gB [(S%#)isx4>%nkQtƸ\4 .1R"K/T6p6f]f ?t𕹘.3V >d#LF;(JؠcϐCw6?ݒ,|lRPP1j %&rFFL.+]PyEJ%"6) Z^Q҃EȦ,Q"p#Nc Ib@;lu|Ƈ%dpƍx#Xbב[aC|zPxB>WM4ku\nO7ݽj.|/Ƌv|SӿvSW7 >9x斷??Og{0iGrB;`ECc (ga=,l.~+xpal`wQUUUUU뮿a?x-[M f?_X|mv~ ,' [|7rSrG\/ͮ5OsG} $dfMaƪ15Y3 rB9xv`Ʀu WgP00s)hƩmɁB6+uQg&C8I.kaw"[)Ԑi^Is)|^bAf&2[ XL %͐*(ȼ=FL5偐bke _+J[f9פr3:M3 Zkoc&PNE\8.E 6jG~:MOTیXrE\@pj'7Չ$Xfx2;{،Ӷ-IE#n=1x{q.㠉qG>_y'ǞNaߋ%nwmly܀§_k@o??q]}>[%^{{>s|3qWo*zy3q={ikWsw>O;׵ 8i8ތ' nl3mA3X%?Y|Ig 8}[bC3>^[9gl?y$Eۏ·&x_O7Sw1ȔvKٿ[p3oꃠ6xG?uxa%={xNOv|7a+ߍv1&_<}n|q Zu]\wߟ p|UUUUUK|Տ0? M:@/zGS߇ŧ{.v6q@d8H!Wf +6ȼy011QDfsNC8K ΧO*ɀ.d T,3?] DנfE\ӏSˡ9ai2s_ٜm_g~ >8mY]ht.4@]0B{r-|,~P GzN]jh[o{OvImڹѠ->Mݹ#C2+Zi_פokaK4Ƚ鮙#dk.QpXzHo1x3~ǿy[+_wc-ngprAXV5Xb‹I8gr<at{ǥի-Y~v>q굄x}aV,}v!v='7qԋw*,_c1OA?qþ[y,{`-f|(^7g^us͏tp[aᡥGX ? Cz"le  =z@k ;77`Z:ELUUUUUc-رg+\}}(8Z{'~t} $luD7=y 5zޘ)@c~^}ғЧwc>/fɯx~|65W_m,_,ŗ_l<k&Av+}Zcc 8էO_)\; 4;ã\<أӾ:x?Ǚ/?9x5f~ѱj#z\󒰮q/ŵ__o:d.]_q=v4{E}}1nS{x¾bK0A IDATګ`~"7 Q\76}UUUUU4paX[6帮3xF6M6PDW9,Aa64c[,#;օR2VDhijVuh瞀nyk\Spdcxm>]{, иЕ%}dd]JbF.x^̂ ;#PAUuocM3B F`qYgJ 5Q|NrE_2>cf$r"X]@X?BwpJ;b_5fO BBzl^fI@S7+?@Ã9c=4eVҦM5j7G_eoKq K`[8s,Wݏ,ַӖ`->;;.->JY߸wM/Ģg/Jчp#bmp_%7{e3 ftEǾk_^p5:|=G`1h}<ĵ_뮿]c|}GQ_Z 7>n/{x}=X%U0S-oXvw]h-X *|u(Ŀ~q Q\{UUUUUa&7;)׺8!WDZL9EcCHFA1sqblb#;=vĢsP*οf㱂'n͵f0O f(jz}5 ~"}sΦ!69HIƨs9.!>8'},`F6)j-msNf궑h'xl>>߀l$ arr*ox sg18do4#EY\I-CM~%-n6P#P;Rn݂|lFQސCYlrsߟu|wvR}k7 P'nj)u'm{␃_+.fg|v0 L/5_j8L:x̣zO/Y?gtW;| 3,37}<W||l8^?{ pyWnaOtc96lq0{qާ_'.¿;߁+ | vaހq &^+_?|p+ /=H~_gy1K=خ_z]-k7lxA1Cڒ$;;=c0 AZϾ;_ܝRl3`"GͶ-{$B.. &P#;ZDF* O['1YysDC~`LVRK8K <գl \ҙ Wً%#M:.z 7++9%_ )<.Yg}35ATR֡m#ykc'|:c3{ښ*-]j{j/Ҩ42I{|C^s @!g?4Cž+D&R23說O=fs->/|7l{ڻ=Ѣ~[]psc@߬6]k+lTw9^ bO\ \s-,ko|yww~-0v%ގ5ol>}\p{~GTXߺdư`-0~Yw_m߻wy݋pߢO_L?#5ap+o7쎣"νdC?mǃ<ؚ(f:lhp`~v48zFaض(5D'/eGmϖ$h3D.?J4NLLM W7f$ =.}^0 dPJG8Y.(Y uQҹLj_jOm+֪G6#`\ ][̛e%4 g4P@$!T&9ʄW@AH1PL Q1\}N1N\@OBj?M&;x⚤Hcrr2=8+,`2{ d n.n;;C&bj js!`",UUUUUUA .؇psw'84~F񹯽 ҝӿ#9޼9a |y1X O."?Or  +qs 8\ |  bތs? KV.pEܷ^=~qW`"fs7?w`@hJoJ[ÚU?]h~how+;;_Wݱ K/)< . -3s΋1g=X:v:&p=o=C muU',PcEř_?<00h;~hbqh Xf6`zh= V 6wyx.獳w緹Cg2ϯUA9LqܘƁ!-Qk<$MWD ƖnGf.atX DLaEšaNc$)< ?L̢2Cf?i_S1x<ѩIj& FN8:R`L 2q2>upJ7$h|x4= Ch!A=\B`O7/-k6c`iĘǰ@olk tP\``Ac4YX.pI<F3>>)P0^3|d\#sgE8j3$Ն1XĜZԠpP"ұY8Vie0bKȪU[A$eYZiw?Tr̔1y!qrl7Tp5b}2NW늜j?h.uVmWoq)h\oz]DqR@L:XQ ,] %Go^"!߼2P tў5\UUUUUUUUUUUUUuov^zC'֬AcĚ0!P2RlL”> z|aWx?DN(Wm 3 \_Ϧ)^B'SMqףOfm,pa+JYMP#u(nGIѺ̔zT7 03S "w<S7+o1=hji"5Hů7 bbK.^d$KMj# VR}5k'` @LɶuN3dhkV-=1^>%tzHzWS ,uq(~?zQ[f^vP=]^UUUUUUUUUUUUUћ 6k6 >Ě5?Nc{19?s}azHdÍK& -!. cmuΠmCneN+f]c6̅-VFՍ¬+\/9踜Vi&S B(JTORQ4V4S1pȐOөuߏ\?fn3Vn]F9m*|0~fP}[t}C%"zfg8+O>-l6M@)P+KAi wt̥2UڸYF?lېu!bEWUUUUUUUUUUUUUUp=Lǯ!: c-&LO-ܹжֹыRtM^2~i ƝwMcRVtkE;阽8ۀ 1h![=VMiH78&LE$_c ?T2BЦ/6s2%׬a!0qx ]y1#*QZK+6츽D&d\(m 4Zgtrq#&rF-|[ؔ65$gFJ7Ċ2U`]atovdn#1_pDQ]r^. Q52}.RHYŭYUUUUUUUUUUUUUU5>,Z64 ^ v5xhC%07| IwKE{5mmS1$T;/zb$r O[mxYq)V&1Ȯ3ɠ9 Y0JKV]J4uFH8*JRU8V|.Ǥ{MB\ZTNOLJe7DS[o s-.H\jkPbܦF,*N'-soqʀF~3K3"IeAYA 2lŌ7 Qv2UR!Quc:n\ZˁF^3>oHKRN_&H̾UZRUUUUUUUUUUUUUn-|ܶOزG/k ?΍S A(t㮻ng=Htɋa$.#@oӉx _g X6K .feXcf3ц-^I&gUEFmP, &K:-|U;?m24nHS,vD-]U2*_M1*}SercSvʌzuHuQ/Fyޠkߙ;1km:p"P%ND%bpܧ`cÕLvEn㥍8>yh-JLS\˅Z|RJZ_ 3u%l̩t_&,N ^9I.&4|ClysFQP%i=T[(KK%P}6i#WnK&7><ȑxq&c._k:?GioB)hr7?esU`Gl/V[rAR 1\yM*pAY )4K !"=ތQ,F 9k\"Tl*X\f>Yļ6Go4CaɌ|@D TCzSo0KݪCx.oy4,o2kls!'A&RɨthD51@,,+lSR'4KFS܋}=y_y_s> Tƍ sPdBs"P+7XuLdvJ0ٽ(-+:[Z@HnIKίGFΛs.гFƚ4ӨhDG|2[#\䇃o )Ǎp 85"'-ᘫQ\ljY˃cLd ұ["oh۠܅ll̲\L%5m2IfP4,̨bqb6M ?C>'2JbY$;1^N9pr}2bmnw E-HbiBd'ն,3(_P> z0pRll~cJ]9:,Nr IS~`e:O.3'Q2Mg{k7,M8'_mZgJfg!4ޣmX7? @=]ޣ̹(O"' 8$3N83DN8Lڝp|rD\IH6m2- ,#n==."?m\/qX#QQu`MM3 x<"An.^dka`Y`&f*w |`nN[RyCY"/|#F3Ux]$!ԲD$:d96Y)|RKlamQh`D]IY4`$ƚEX܏toh2Iysp \? ;7h/@NCt[6 Cmdm`(6C.rݴ!>qE;<;ZgҘ58j4)J`Ī81"zfkeVpE4(ҍC\ea\)7ف9& ]5pjr:^`B1+11ᢐlV/(iFn~n e 'h*)(SE{Γ5sAn ѶF'"F-}Pl]!E l}Mm6z/ﲿ! `I\*@[pp!!HLUUUUUUUUUUUUUUզUXw_0(r /˹M+^l-7&Ar1)#T)3X<!&*bK ZccX4%$@4dM\B12 6tYz."DŽy_#RX$GU0Jҳ kMQ^ǎ񹘵dK #ʳU^#ü7LdUDY-&|q-cG(yf.ЛTW7Ee?nF\x^|HZ_-)Mw\ >1RR" #'IɥL~NF?ط4cNtDJLf|XLACo SSlUUUUUUUUUUUUU&sm 4mczT"3)0jf]=m}1g9-m5 IDATsV 7]x\6 +9=V-(]4͟?W5H1؈I%AiA`0%o<QEy׺L%~)̬,o+ vz]&w'ˎ4 &Ŗ-̛^ZGB1?%j<z+(n Us]na7/FihI:VK\UUUUUUUUUUUUUU 9ޤt- Z0+1Wnj IGl8TgPE$@M49<3&`mm^["{b k ,DZv*-B6z.6F~B l/ 3YD?KlCFqXMRm¹FA;vq%&dfe"YuCbvpD3؅Nγ> PNxHNus hNd/TrFmV*gƛ5_H8d@6+7Ǫf-0^iPp -sfb#:5-hbd(ԉs0eX>:DlUUUUUUUUUUUUU&8=/Ns6`Bbu8$&ż+ q_d!k]b`ed,иc}LOP*-w"th01dן64= jWGIL(xT~_ TׄO>Rfcq_IZJ$e0 œ,s!`=%Fq} G(8Д@_dc:jA_C&^C2ma0H Ĺ tySKPhYbݴUepcf:!$795.)Cb`X[C>T]V;NVV[xygf]o:^UUUUUUUUUUUUUU#%eF 44[0nC@$4K@c+}G @u4I!0c?äRF5!h} |!(dԱC>ZLOsc$nAʨn&^jȬ4o;#xěOYT<c~W8X8mżͱrJtd"3R)N+DEG`zDaX(U1nFx K,B@Ѝ-(,fͶK)P8и>DǠ"i/dHD9nL  i^卩Ehv{ʭ&e1ʶمn~{Ǟ{K.}qݵ}x晸k77ч[3ڵkg^߇wa0=O~3~mo;z>Xܓxguw%Ks?k{ӵkbҥ1;=xZG o/o7x%ƪ8$cC2_WB,JG-]a'f[-QX߮E1hzЌCbeE &4WYD$a0s1x;R! 2> ku38+ 'Li4&Xۃ5dm!R.LB`w7FGy||t^!l0 #kȂ`kq~5-bmy)!gF m(ė@mQYu@ zW@xE]D l3Qe~zkUD3E#MCtӰu$$NߔZ||5|øWH׵f\c:/$yEmW\~9N{k0Ͱjsmgsُ=!/9|K_̞=Gy$uê+q7֟6 /,b ߍs>zkn9#6*#B b!VO'!?*S5S5= h 0q}0?= ی#ci[^?6?%Ҽoи1+1!ZCv< ~SHϹdRC1M4 .ȤXtPtӯaX=@FIKWf+._qh1U07thO3&̀$v P/)J&/5P2R\ gExǙmii$}gh0^&˘!ί2rl, e |.,"LH\2 $>XJ*ţW>•9V|0t ;'346 sJ6N<Xtq*i#}];n喍Ny+qaᒋ/.>w衇bzz:;on 6~e>XlYK;tw Zr%`{H'WX;飯Z?dNP*z c #8AҒ,KGu8ZXۃ_0Xq B>ȏcz1ALؙ~à~.bWp8X3I.4@= TN-YNӰDAR%Bł% Ò px^O~r1Z4Mb3u9A .M$"4n6i "p X3kp,o=@FưEFc憒deI(_+sst7n2AN2vT2+t#1$^F-gwHHf[{ps戭ɐ!".j_ /lT js &^6ٜ3w.N~˱Z \pnKM'l=Sӎ;bTZgs {o}v/xzkLOOnŋfbwܗse'EO~2f͚{^pn&|<|9q}eg%ݖg|>nagxM^bv‡N?k֬9瞋=yQc=Cᜳ6ltfϞ\=>=lɯx'9%KK睇_qnj~pzSu߳18qcwNJ+p;^ZZOYkzm*6D^c\c3ݘP*5Z8OEcv4hf/l88 0 CN1L16g 8 o ВԤ" &; Mm1@a @PYk p֦M7 ׸82- ama:듟Z Ӡ1‡a98M#5kB XB|; #ra$M!`z S@N;s/ :ln=B H>Cmje҈T HWJ28fC̻dçkBRNCw|?9Z{sTU˄@*>bAnn!-KkWvѦ>Pqm "@4 o$y㜳^k9ZD{~ǨQUs+ErLZq(\h9OHJ#q9^2RxDZ-Gxԅ_vJFa?80yMɹ3\SKF(^S_˓/e^}pȑ;=~qn&~G믻2}/xe_Ws= {.>q#\ѣGxQz=:#G+~?5w>̋^b^W}?<9 ]^W WU=]K_wogj]|&u^D^}7󪪪mrBkB2=Y@1 Ke)dȣ~/% L`tԂ5 $K3aFZl?s *&V Bp2#D8X2k\FR} όBGc m}S2ƀnWX]Cp9"b6q@JSZK@ 0*hzS+!xmYps*wEb\tcf y, k-ә~2nJq牌aY#:0 ,6Aw]@,RFA¬JrYXx-2BC`{drfAڋO=b% P|vm.6O'yk߀5yOC.Hܨs kaٶA9\szK/o|y}9󬳸袋x0/.ԧr铟h~/e#:,^WX,X,oozPg>?y'{1o{Ts9=zW~iO{OzғQ哟$oy=\r%tqW\q_&[Պ7 {ZSלmO:OxiUW]g?Y{_B~w]>Os-pYg +^\~9sa/iЗsݛ|O|ӟEUXUUUUUUUuoe=K@Y8}H*TƦfRbd}DrIu24T*D=B,* nET9iqM cdUO=8 W%h]^A"f 44rT0$id#V"1@=Q)=jr१c0hk.* h OwBf/`!yW 149 Z̑5$&EacX]W_944MCK?5(=".O7ĩWn#n1k$eO'pHe^kM3Cc!ԙW䥿kXE/~W]W}([]Ƕ^#)RB2e3\XDs~{̶AW`[Q!;)q_S<|S(L g"-9yt?޿Ϥcǎk ,Żh⟣W]u]^:t |uͷw %&Ox|w߿3:lbo4MÑG+ﶉ}??/{z>я&Pu nqo38c`:|Kys!.B~W~J~i8sx#7/.y׼fm``Z38 lvcx{.4Ms|Oq_/?wog ٥iYGb6&tiKE-tW ୻SNzccb@UfЕb0dt R[9%fF,ƙu#ɹw뭷 ?kÜ)\ ̽qF# Cs*yf6,e?$^V2=OlT%Ɣ(uGxgmeRVR his>}D1'?rT cC]q~B8p]qgU3 G6?jnG=Gr?-o~3}_bSpr IDAT??kNĘǺS]]╯z~:O~k@+xz+"ַ^鞾#G~,syxaMҡC _jV%{.?s?.tyܟk@oM>O*!"9>m4 δm]U''.Lz$,.(FҜh@,3icǚHW IQkZX7gss*}âD wl!FbTf{|M)L!RXcm*N<_C\s%p?J>kx#< >Orѣ\СC;vn^K-_r/9眵:,n}k}stn wT *2CM"JA X1il-mb h,mAc7;88>Lu7;1Gw5aÂ;X7O=3N?_C籹u`46Ncs,8g3ƹӘ1?D̈avv!fbƹ!:-nmz1M*_NT3!#:!E"e_ +k[DBtifMMiPǴۘ LD0EM 0\bY¢j0EԮff74jǀLc r:): ]bqC=8/9P+E|dž\'Ď36?C*{Ėmv(кRf%퇋{2FQ:D<CҒ5g`4R:l]-2Cx(Cט& ޗ ZX(bO7rM71<ƪu(_m4=0__>>c GXeq6sƙg|g>;?pƙgO?{[ug}6L}ϻE]Ew;g5\ã( ]tgy&[_r Qz9xr]^r?f33iyϗ||׻֧=>NiާÜyY|EXk.O~2is7qo/?T~#/k-Ozғ*>p᫪V'H8q8b|7FXqHv^`a&mղ#݁ٻ'hrpiyyM~{wwt9s=)N;N^8Q紳P0XL.vuC$@l2;1LSj7 Š3t4}]vf [Xq]U[!t],1#cR9dEȘ}tШ Y}q60J@B~qKPH2`3MAbjam#\̍hGCqY&%ñ FE\0yciui곸SdhL$F KL{K Mk0$s4mrL7bL.QusT{ _ղ T\bl~Wx3?C;/|??sW]|1_|]~W^:w\ve|}cx\l뾎|Krꫯ>){O??Y'?)=\>Z+8t/z9!%|S˯u<~PUz~{nikmo}+iyϼ/~yk_{<͵~0w\Gq1? UUUUUUUUWfчm*`\j5 vQk&"6fs\ Ib ۠q-Q{일-e8<D<_A `Z0'clLըJdPih [Xc1G?6#b6kEjE;A]IDZK߯Hq$ KwḌҨ@4t]sg}קuU~>i{Of@rQ*:IJs0V]_4ACk6ͦ31ZQ6rbiO2ORئ;c olMSuz_0[ 1n;:cجAS[⤍7EJ|O:;Ddھ'fw8I0kx0K~;As8peƲ.U^s~VUMt!e^ VUUݵk_蘭rbs91(<xKf, 6` SŲ_\CukXU׊f^r̟3rCɍi5p%DK4!ߧ஘1hLs$PgC&)MnX#a O̯ٚ8ml ybNri;pKB TnuYفh86!\jS^w* ,1 RHKqs#|tkmš8>4w9-)MJ#o|Yvkn2oڦ<@@ 40N\2p?cYH pӇoM~>>@9?o?؇z3G?_zϸ}VﵪGm'sv'1Ws8Xv!A8kRTXMc4L;NY/\sMeέw\O1a=n $sʳ m>8YHgeZ DAzbp&8|i9!d+ܓx%ZWX_&`AuI=`m*EB\hqҨw1QC8`}I3`bc:!j*~5jv:5)A38U].#G)ŸF D*0[$66L \v2%]yxTU C1N" \:c(ɘTu 0s/+n2 #e#T-&ԘrtR2BOp4L!PɚgqJ;RX2m]^UWUUUUUUUUUUUUU=Z,|=K~4hr]@r6"ۤQdaEߝؿl<;C?54lA1ivIA(N怋14Cf(m2KX1`ޜFX8'n%@6Xt}-F2XcG!~Awi14aV:Wk$9}.hQq|Hy"mHĵ{{`3Mn=U B832ZuaX[ScנLXfGZSWr\<+q.6Zx!@rq c$X+ׁPm ruhY 8Q&?D;Gn؂$h*TB*[,A;DP)Z svc #a-6(g[bBsk* )'K. PA."IѼ d֠m0ڱ"-f 8/- .RΉ~?&(Ptu"l3^nN[ZCN8N9QqZ2~}tY˸=ñGp:=3o` SMgcfmDa>b91LZS! $\5g Jlbm$FT: sYt~m.*nAXt]''ò;$"-Уd#cԢjP88ǚ9j" vaAKYs&cF }ۇp+e"̮>blC ji-ju߯ka4F|DUb@snybf}j8Z d*nH&dq͹SoA!R[J;Dn #)&RnaԤm641VXqpsd[ʔ|ZFzЍ;K 5هҕ}}Y7ʌSJ>ʵ^onBDk먈Cr}HSrE ж[x ! 4B0#H۶. /ٹnA;'nGh;nh-5<:ɬ%<i1l-mBafM*hD"X2`/GhX4VK^Ҷ-!Dvβ˅XD!'bbb(i}}{"=h`w\c0v a0M{1=M=@n>|1 Vص~7wC:3sqk7\덷f- k1icm(L`>CnNqr>f%FuNaX >o79%\w@=uwjq^W_)^)3%7?|u[#C;9ur~zf"Nმy-qβ:q+1.1:ݷn@EmAna['6:v~#nM !O9kWMEvl`F(F 0C#lն 1nb$5?#C+py,jt'L1%&w? 5xU0..lBȯ yaP$V1 E Ӵm:gk>KqY&\rB'^ hٞDUvB dDq 󩍺7}l ^. c^fpǛT'h5:K0d& Ō,cyGڜZgc""V}C}.3JJbm ")4sIkCVr,fQ &=ֺ7#Ae*%3ئٍfD%S .-ɍq, WBLQ`|(!{vCD 3K l4ü:WtFъJ[( l~~u#l+;w23ka~3 7DÝZS}ތN0GԻKȴe ǛGOn,o:Gq;ϭ]^g&L==3N?A۶*ub':tBMT4%(2ow;8It:Ip3lAv,6Cmi=(x(a1U8/ƵtyV^(,%ެ1H1;0VCcO= x֠CRc<MT,\%c :r$8FbLf пP] B6si`y}9Oc !DiLulncŇj6~)q69JT1nX,Pa4܂q(8 QǨn&"rB'Nd\9]p! 1jgi!r2.EeIw Kܼrd[ H >ʄ2c3Xc9]sdoA /zD݄Q4bpx7GM열YPX65M-D|l?h7~;@: Bnr4b1h.( 1u+CgᩎͶ%} Tabl^>*fX!Dwg[fΙ5f#"tu+V]wZ$2 \ > 3bkXg>N3CȋRщ99tQMsM/@83gޞi-/-qS۩ohK"22TYqM5uNcЫXG&\ I@SIsdp_!hP'ks Kw:Zcrj~T0L{ct.8c5up[+8m+6kժDG`/IrȄX?a R,:M9{]Xa9|(&F*m j  6a+$n! i!qDRnTPC,!`!A@~BtI%$ Ӱo¹{4*Q9:LJJZl=vct>Ҹc ]Q IDATEIrAs\8 fHɊ0T$ewX76֥2COJD4*\ۊujr].J\8szX7T1¸VN|7m]w;b= [`r֢關t-)CaFz¥$:587L6t\iw8K@.9 T a},3 '.{;IIQJ㱖/#M q:@ᦞzd+٪Y֚GBG8؈;BKԈ|YXBf&W:6,1mD1(}`&D hL)Uc܋14F uw~s[D"}߳yQ,= iF]׍#2iۆ[%cS|8m繇kM1;,fh*Ĩ xN.KnM7@0ULԝ#zzipm̰Tԯ 2;xݏmf(Zl\aG+_"mǬ&蒓'oN0w(;c>;5%? 1rVU=  D#h:kgbb#fV 1fhpHyV7i\x&wN4T"*X0ݪ: Ƣal3UlFB dx0PڀZ%s 3g _&q6clS,yyi292.zYN܌6|^%HLH@f2LSB&mم66>Ǭ#i]v1W%)jij9ugyMsg\ VUUUUUUUUUUUUUU=+|`h 3K*hDH34 0jAaAcBUچu-N'#vX=Q3v#m8~-l?-DM=cbN|u.{"02~Y,w$FI35%5st@wG;wc-q|a4*E B0\)T̿#"B ɀC0q"()"UJ"f$C\fNQ%$ɌGF 1 eM @plqd~N )z58 QiYũpozX@2p'7 J^:ZƔ.+0& -sMbqNcB)zA#! QxXfi"B1l"ܥ8,.us. _xn3ɨ$ֲpsz o-hW{vB0b2!u}m̀r3G`Q~uvIC4),[[gu4-KP8AdB$G,.t,NZh)j܌9HAAƍ ApnF `ʘxLYq.?8L`a{4MCu*Ǵ h&% f%4|aIqs@gd"Qq pOUolC db׸~qCJ1q\)*18nx1V*Cu|HZh!$SMzm2L'޼B :kcrz4 !o0Z%f,C I$I? 0G#9QBX2R3\7k`h~}(}}|}>yy̹O'qqG'wUCU?ͨ[.B!6-6igԼHj7Qlqc~NWv##O߯fsaxd-G>Gv%3MK{K5r$!ti_}bQ#3mmc)(Fl\~}G! %FCP* BZ'U*XZMӬJmAe2ӰGҨt~:6fLZGRz#B虵-,V18B4rk}:'\viaXs:!jZ`&CX7`I4R<`0éSpzZ58umM@-kcPED !ީeښ\P9@J]YX;R'u)JA'qj[ _:Nڟow=o~7{̷4 :>>şxogLWUU}uW}U݄#2 i`$',{BZ 4)شVf1sTDL"^q( T4gt hq,tǏUw4&}NF!"35s͓#AATA TY`m'F43qk3"CɐҤf3V@`QDuc &6q'68kiOd^fI b1XYKxv]Ě fM)辔2q.A;.m~04qS_9xFic Sivܢv+]7y,t\rqnO+Θ?@Ԓ8 ]޼NpBj-sǡmx|8"moɓ, 4碝D%Cс85,х9PRfo 6- >p ~kq5!<_ʷ_k>s?[/:{wvv?}x{[ .=\z7ߧo?uwwoo`\o>yYZ7-a!]Ywt+i7EMu.Aý27(_x:? ?>0Go~7Yyռozt݊<#/yɽٟy./ˇ;&!뿞|>G>kE0UwނDm.pdaOm}i[-iR73V|0u݂Ȋu:ֶXb ѡ7ֺ D+ؘF#xKiK x{=Fn/x!xء"q@{%ń84k-}Ѵ-67 '8D376Ϯt_#شWDyO?srS𖿰-s-c[ț a@.9s7c.AL ItpļF 1Y(bID4$3}֡$\s67L!`jr5kfh1.+s {S[33TkYq 4n'> MN'x*~s󎜇G~#y[^O~O7)s~/~^ρ#{ι\v/rM_|l}{Oy Oo;pw^1-ٟW{|g|w֍ߚ?.OB\@#`[%7KfI2 :0siÂ("NbcZMX¹^#s 3ٌah1CL$>i [!H!v[c MNj̭=lKhcv`X] s;=F;8K{OKݭ,Wwfe{ƈ! >1b^_2v{ewA>tށ  :QԠ8bP{g-A"0^Aq ѥpg\Ìzpx @N?ꜽ{>}J]{s*(6e~u9Hi>16ۑ ,R)|E=MV2_ .-ͬ[8kSS'NraHVF(s|^J~UC7x5;jѣo_X,8p?#/.{Pڵ{~Vi/{?q ǹxۮO=>?p%ۿ+潿Nݷ_űcǸ_?sB{G||# `OriQUUUUUUUUUUU_Bu%,.ZDd@5h"PXoQR-:h,ȆFk,GA0f_l6Fk:h9!tPB 1 Bg1GuW+ߌ1XMj CŬvjvAyf5"!Zr+BiĀ-GAcZa6-fD9O# n1`>Ł,Gݎ@CqF#U-i- T&&e$J,WIS6#TKqhg+&ƈ{t4Rc̦HnlQ㋵+=Љj 1,Ѯ@*9 3-Sz@R ## d>(e2 [(cYd7FcTɽ0|REaB,NT N]^cO\,L 2O K󍽂M#~_I_qg~5=<~spn?Foi]O~ǽK5X/Ot1~e+_+ 08{_ɗ~Mo:c_㎺\UUUUUUUUUHB9&\nVZ kvN'Wu4mCts.z`/JinaT4  4rZi )sF#IXBxEZkM̨,J)y#)\`F=qV',!cDDK|rD1*=8LLf Jm 04v2qΡ{5'h(1H7MipOBN:A*󞾷yqe ćN%F11F KOqԥXO)%`Q%.DhQG8J̗ ( D7;dCexX3 H L~Ȥ7 X&Oc7I"w`+I sOj8 InmX+n S8X !S*S(yc xWE~jGux;^y=Ygpe}:Os w}.z!{˞{3,O/2?W{n9~RJ.}|۷;\x!wq7/c)4 W^sGT+>_?CUUUUUUUUUU#G:Jwwc =J uу4d:B !"ć4!٠c T%S["dZ%DKpғTUSuޣI ٤%үGӚEV-Q=|7?c[Hic JC@*9QiOF4{f7 zʜMZS\w'_qi#9!1RZć%9 Zk!FfI05 >x_CQ)sJL&4>v\JibHӰ"宽t[K$1/:uӞZIqÕqշĘcyB>6]\Rz*\qڥ@Hȱڸp}|ᓟÜz֩y~t>v8y:^<7ͨ?ǁsa6ן˷rc7|BDܟv_ͱ˷wpE/7̥^:{^{ W^y%}d>sҗ P=^v״8kU".ZVdjv$"G1ѬEsEh{2f'mh0F7 i >?&;0bJ#iصDTQ y~xMw|Ǖ_ͳ> 1r&.Wқj6n im!,3),%134kݐtY(Zl#ΐqAԌәg{l{c?ӚlbZ#C$ڔ, v܅aK)LD8'Wىa0!1t $)"c7l#t;\_:BD1ZbSq:70B2 0Ġǥ0¦yh)dM>}Kr : [}m 3?O_ϞO3/87ɛ`~Lk8s7],n /{^bk^ ?Qtݒn</q{Ws.x;zY[[СC|>+>ѣ\{5 ~ok_y(Nyo: r)%પY-PR@PXgݵ6ѳnβ42( 1, C-]wЂvNT8D T A ѺEHkRJRi=B!>y&㯉08SPGJ6R!)@EIt[K !k NI.MpaŠ4vS8LaG9eT~qv0 ET!<.-fmK  rlڂ'FIEʆuC<HwVouU'F7 U$P4RBaXj(kI0+@_;V#sDauk kO}xxLJF<2 GBD4\蓹o#x?q`&:Fw)⎏`ʴ1 #G.~uQG?`T't?{=ǎEk;}x泞|s//|!ַbIOz^/7կ+_u:xOugy&Ui6+xOz1kr)FUUUUUUUUUUU}#9*31xoAh))F,48PNPmZFI/4t\LIbp#B({'&}@q+O+\!Jɑ ^)Rx"GL"h|iXg#m66B% }*KKeO$ZLc.1!+eZmĹO{R'ge&XJ%cfX{Ddyg]bK2'G㠫x4w'.GCc^H+_(ICqIHs (kXAŊM hn.=M(lnNq8nbQrbA)=Zo~Jpq VCz7W%`DxVLIrKdʋuz_ ;E(w_o Ժ9/{O{w`|>_>?R^F[z =Q'_rGBZ,%gẎc" nhQB lAx5Udh;4 .~3Ivx[}Bp+ # ƱWןzPJ5ݔR!Bm"׺A0ǘfpD`clw>ߜ0bup z<6!<1̞;P c   y]0(Y())+^o'rŷ<׾:\X 09qXr{o3Tl-Q[VƼ`c qf5rJԉ8=P`-~ݻooG0kn[[KNZ[ټgmt*^U۲{?1tw D!oJ!X6`[p2Uu%e% } BhhN )a ov(D `A zB$uaQz6p#5&l9C*˄7m\KM7JhJ¤$h-"= T{xك'N (20vlydf4!%1\È9f4 ; )<"v`4z6 V,Rk특iTzJL_5&H|yOŰV;sJ:Цih?(ecjcb''ḒXb5WV}f=B FX1ԡ#y]&ݳ0\sz#rђ50J)%λܑ8.Z\~1BZN׏Lcoa]OO)x9\K{+~Veo]u zzDA!̡_"TTszhLCpA BF'G0f= 812HDC{QjY#:>lhmX,6ܺzV%[ɀ!GuLL}b&$$hXRb]6)rl݂;(>xf OA]5Hq⾅HCB9IfAX#Df.aѴRr;ȽNU1 }osn%UZ@tw0hT[qM$|W\IFT.Aqz!?J0}"MK!pmLv)J]DZ!Nc̀du酼=ӡ1nwwY*!LfW\%;vF7xqr,vtr/S?a 2^{ZtS/Rj(<ڬ1t8gGEsmZ1x|#v(զ1fL2()MgHit);|tOgm4iPaΑ#_"F'ʺ|Vs8H%(c58o2l?8V o.MJ1 $ko`SrdʌepHZX Ӛ5XQI mO%!#ާ`;l!w6A1z`A,[rM 4H2GI9pVF2yY!uxQ%%0$d߷V ">tZ·b$sǑJ#Hi++*o1SJuva?OJ۫!뽝80+ t+}nlO39"A'.F&.r#ڬ&T-sz| A% ~2R ЬO`YQb7ܺƬa>X\(ߦۃ.Sdʕl1W%.ڙ)R bI>Tsڴ,̮c¥*.4+H#K'H!:  FdnnnJQ|ӛ1mZǑJO|<2[[ʋc頛B6S80AY^ a&Z@N?y S7rLIi9"^ _ Nï,^]5؛G% f@́{ 5C'eEXIE 8p~b7-2+D&Pbqܺ~zTG@ ;HJ l F&6nqOݬ#ڶv [hedtk~:%FJ}v7Bt 1ۦ1#N>b&Y!=EI>`ETu N%dj)Bui<#x$:w&R8o 5JsBam2ե>(F+)NRmzoLٔ7 nRJCr4A a-ى(y#%F drs2Xt-BOa8'\_uxyyb"JWR|1h  (%@GΓS3C8JqI#ME7*/`Oeم7.[C#aiXnMAunz=BY] L#,,B5܏rBV=B=ٹ ]UUUUUUUUUUUUUU(ƈb0LɠELh)ͨFh"\u(9w PXn@!hT 2v8Q lN>O"Ď-ѢrUDlvwGA sj/$DOC9:#RĥA(ކ5 VD +1"?4iA9TbxQڜOVhz؎heJf&#uقj%,0&e!Ө%Y 5#IF6Hq]'&͵\v87 N],E`& @U!ibɓO D`wn̰*CC]r2jYRbq ђ0}z BIaGIk;3)2M;pI@_r0s !U\ ,cUUUUUUUUUUUUUU~I,"9IC>`ypt_@h:VO-Q]]xoB1k7-Hz1hie4:d70wtcZl f<.hYMcn | h*}LN+BD˦9Y7/ 19nҨZFZC1fzrq;8p~ecZ }ֹ87@AM,M)јU:^O܁ٕGhW6F6d DVKNP72sqe7-ޖVNr񥔬ښcY|![zCMV!81r;9LJ'.Z]1#̥ۯ܏1awqzF@VxF IDATnD_U!҅WoBUUUUUUUUUUU& qȝ4k  >bX;JBY#ʒof32x!.|w:ARG w/4Y#-P.^IH.s wZ'W琜V)Q9VK|<صZfZ A+]J]ǡ# aֈP8"- Dtxk؇s\B : 7 awgXk3;o6 *ϋ1d"s y3дlDCAiDu+cÛ)F$c_> 7Jݸ"EpmX~#B8R8͘Liae ڞWx[I #S r[^)By%W'r_ ,O+jXPN W) !U7+{UU?ns&TUUUUUUUUUUp3-NJ|JH )(Zc:.Z#Xhb D)Ӱ+CG" d[;bhQ9 M"@*w%ϵhRloqZSADFp.02, &򬵧8MGTzAD}h@ڴ :o݇V1uï0@``Ȧ|ʤɭITqxbfHKK qseKC00`A&2pa#ESK/-v҉\V Jg-_W x: Vrw_.L xΏ!3 Fbox Ϳmw)5%+jr^:)%u uI\ ]9r'\G:`,qb8cpVBU E$ !4C3@ i8Z7DiאD|n4JMåJ'gZ ODkBa\5:+c39!1D$1 Tk-DhRy`5@ @k<~(9_vBz@Zns}A f*(3GcE ny/[ m9O%2A6/јEÇHR4HNކ(E*!KjR`cڻq{949&ldmYΥec y8pWJł勅:HJ,j-sO1 ֤iWi'kӈ@3 t1wR9'E9αP#4Q7A[b&0?!={5=; ؔith~&G8Z2'Z#Çsw\.r1vڍ1li޽{1&B ~KyYs;rKBM1u̮S8y7=cֶ{PReCV"TJtF{GEw@^H~j6GuLS3#:Xnb''dzG Xpu]XO[F!nlEd]' BXM =l TKJ!K|  cdu Ņmh: H4 J! ,GIC;+!G+MȌ.S4BR-'q.ݬ2|;Ww` j{P>~VN8 < f919EQloY.0i̢ߦ؃ 4h GRsT|Psx1MrEtpؾm $6$8&N<)%Zk35֨YZ%fH <}NQJL#Jj { #}oi8Jhe%(yp-BCGt[Hc 1ĐBp?L_x0ɛFUt ) ೳ3ҾBKoc1*)qaBKpBIqTÍ*Ysv<ϴ_Cf&r]8|_FvL^ܗߘ!D1Uu8"wDc%T9f <3`QJ2+f1MV(q1+&e. Hb8ł|3s]ԎkQ:.84/صLZ΢_9 fT)a)#>ZSHG܁h<A[dwHNz"Zp=i -ߢYۃ!u*|@vHZ t`X!f[%A~6Rk]6wMt ;->+-b%R%V#Ea9` $"Հwгt Wo-*DC4M3, 'ZWD.yl!;&9K6;(>@?\ذBK14(gVW㲃CO7L12H㇏:gc`8=rXqjGh+1Gx"^2 c>;2-/Q%DDJ3'0q=!w? +*Oⓟ /'\:kqzm\G޽{w}[9m)=ia7#&2Q~D{KTX0۱Wq, n|"e)%aCX^l}~ם'غI#& Lky&hv~u>_Zdяz~:v\xŜ{̗wgƁΨ7a1\p~q8~ʇ "1h[G8t&* yA7Hibbx=| F5 "zr6 #$LZ _ Z ->JTtQA0Z!IP+KƟ~O`[x\ea8O$%Z+m݅rgyA9nB1Tdd:,HVΧQW~/A73YwFMLyrNFd,0Ի_:'@5N'1"Epo#!d;W\w:礓+?A@@ 6(dPCtlt=[G{J'I1f}v)LB\CVr=[jRzMK~i|d2l/6q4 ޢEOp=FH-enbֶlXBKNigtr)yM}4\5Gk=A$D@4XPκK ;r$84-:mX[cr[aN/s*֔Hb!w@Nή8!V\f66;EN;Fկ y@Pe18ޤ/7_U=sV(1\E`И7Q17*\hhB j\ШE\#Y" d9u~TwOa9sy3S]ULKz+TEq2q@,Nu}tl6MCqcfwM;ƞHЅ1LXNc*0ƓO+wotJ12Z"&-S| ͑,/sd[{zC=7xC= \*WUr\*?u|++BiF=%bхdhtt|<R)0I,^-JjK3Ȭ5@g#tD;c̉"P=3x4W1>M~,E'eRlH&S, ,hn KFH͓)]{KIc?ZdVj1^B AHن1.] FYrBp,2xAD2v2g)=1 .bչ1<+NIEqI?b]l O&Iu)[D"QRK-${M5si*"f9`0,9l&>ؐ0߂TF ڶbL,:lCz *2h* xXT8Gh#aC \a%-YÄ9B*-Яt\|@Z`y9e_ /F78l"@ "$Jt1C Ʒ$A> =039$5$hiE<_C^k O)!؀5k>fy=FS[L 5Uց̠L5H%:7ڄ6yο &a"WV9B͝qAd&¹v'a@Wt^y< #RũA>HF)%sIZ)RH L\.nZ69׮/Ӭ1"6`h1Ϝ7WɊW$^< FaKˇ T5 ciZ[@g]u"Yu{1-4?АRIt(R`!E,<)UQ$hQ$sX"*kҋ@?7rO)LQE ʘ>I)B-xWba466r}<wy'k֬og…9j{ҤI̛7_MV}ϥB}Ësd2uJll*=8}\:ܽ pɷ.2Uie^J~?(uWmAީ{|9A VFJRg͢,x.@"Bj 6_y(kj|_`L1,AЌP>^EA<*֎i($԰a`f,:$4 z=|ƦOXn 떲q -YlYTvQ W25UGpa+lPx,0F*~$ ^c>&t^)D?Y[|#Eܲc #^xy>h.r3\v0{lNرcݻ7'x"+V{'j.Z=_?wz'kly^E`cc#W_}5_que?SUUŋ/0^pmqo}viW_b[u{{W%lgmYZ?|jkk۩;`ܸq<[gsu/]^z>|3vmy}<_fϞMCCuu 0!(I9뚧x1R`"Re?w_[{QD*аk-&6@<~E\3RS+>YA8iմ47bMG2Zh`P m ȇyܭuuB2Jr-L]&"2(_СVQ`+BkJFr,UX$t}kbi6%ϻy.ϋ%mRՠu-ڠDd5myaz#Lүtf?3͂p$&IIF [`@,JMxJYwi/^DntomSCI8Ѐ(&"-JzBjr%v9(Ugd"uOA ėx;8Tr0'tϨH'XX, `[؆a9spcx$f⨣:{}nW{ҥ6zA6ZVb]v)#?uֱnݺwG0e^~e޽;ݻo;Ջm Y|73D Wzvx_ݕ/̻kYj9A? -Akl}I:wBZ˛aްstR:_@im:FԭXG*0Fdb3n! xm XU4vNX~B~R!j~xye[\.av}g\tE >C9qƱhѢk׮+`ȑz衜~_)˾꫼\r%|…q 6o~K1z*9f>l;0 gQ_6駟-[opASOqg3tPF̙32e #Gd\veITg_|S2l0ϟOCC_~9#FC3whO='tCg? }ټz{cnyCOnt|I.]ʌ3{ `ԩWG;7oO>$wy'<+V࣏>b^(btfʵ-jܹL<n'2yd֭[G]]C aȐ!ձn:&Oĉ0nj,p$]9woŹOҪ k虇6PeG`7r2NkLINZhk^!A$ V0*`,6ߌ sTTU!~Gz^J1|XkTT!J e|Ky6߯A(ƕY涵:_`S  hksA ?RTFR:26!P{r0Xk<6lz^:nzmX)AEƧ&ۇl2;SWՇ5}Ԃmń&&SE*BRr̢TBT T Ugd{d2AT0HBm +%F@h !T9,Ř^*Fk4\^:QXGƄ)l6zFYL}1hfPBET6Y .!`.JʉAxll k#:PD*& 68b uUuX 2s'1*M$&[|Drd!D,Fx?>?b9d!{}Iǣ>B}}=~; ?f~zŬ؂$H-??w)H-Awg:_1cNi>~͛QggÇ/g9\<ߒo඗G]?̓O>I]]_|qr袋Xlw_5jsF/:Zv\}\uUtkNm /dw^{eʔ)455%twܑ~^z}ه /)/k+NSNW^|ɱpws /ЧO.RfΜɟgn6yMlwuGuFb|+_/gݺug}VFJz- ~ʌ3Xf{3TUU1vXN:$>裢_|\.iYg^{œO>ISSS (f͚Ő!C}}p t֍qgfРAuYJ)5kÆ 3ϤO?SN9ѣG`xYZh'NdĉEGg/^y-ZD[[l0l0ƌ,3f ƀfh"^ym0qZ*UY'x}\{k SW';F6.4k8cَhxX8iwx bčSx1` Jtfztߕv ) /bm0|E ^SǾ__B%cP/AäƮ,1hx A!(@5׵ӎu'IhvB63,n69f1\_lxG9oܹq3~]czw c0aBzɒ%{q%ͶݽsƌLRI^{榈a@O.(bZR}#IѶ+Vlww1ݻ7+Vl󋿜՛6_=~Xոx^\pۗvډ믿~!w?1zO?]veC)^wu1#FlЗ>%Kp9P[[;yWt}먫N:իW|Nesm5"gNHyȑ#w}޽;Gu~)]t=zx̼,^W^yK/vډL&w]cx≢e׭[nݺdիFӦc堃SO=K/GaFee%r J)䦛n3w^2Wlgnjzϧ{ۗ;/h^vK9KK@[󨯯keܸqڱ(bԩ3X=c1bUUUsskذas1,^[nL&E%R1+Zt)kR5kְ|rNMM 1x`jkk;{Я_?c8p`Uz-BrCO"eF;Ƥ ""5_Ok @2YyOJp,:QpBTJ D)r(d;(D I$ 0L$C>O5d5JI$-`Jɢ@l1 X! MVvqr]] S@Hjr2TJtuQ0!H~ڝnј)?>z3"IV,vl;a8p͊MOJ#D2l㢹; &7Sy+WdŊ <9spBOv݊R6VW\q&L`ɒ% 0.$ vpRnf͚ESS#5p]׾ҥ,^,mY1oc,M-᧯Vas2R>oZgagf IDATH>C. Aiʕ+7nwMUU ,vRJ[Gk!~i lg٠R5^ϴi6ʍT_r%;^{7xcroR=`VZ;^jڴil֙,eRNnߝ':;wfwm&N'|#dN;4>^|E<"tssRJio߾ 2?+%|>_9햴Yr%G}pG7Z6aguYL׏SO=5quv[fQשZm[fY{eΝx8QCsr_ۋZͦuUi!vځj᷇W].c{ۅd!<АyWc mkh^&Ll  Ғ sH11g4f+]H)#J2 ɐ'hkETdErd*+!t+&\3ي, BL8ʼn:e ,BXQF+!MEpi4FK,hH ȲyJ*xN&ea#9ZVc _@j}%MmBD!#p|>ԟ?{TXn!8V89c*"Y*1Œ~: 9cM?;J.U`Ƭ2zQ_ ,chhhDG oub#ٲJ&KY7=܄WpI("b- Pqs&"[]^%~9":evIr RMZz*mKsi!<#<(YYY߿?/뮣Kε|ХIp'pk={v˿2>kZZr{t#$%m%Z7r^iIŋou x7^{73<$U%i|@[[sUUU.⤺ӧ3uTou>ՙyM/?o޼Dڃ\+WҳgOos7zh}J =J?M˹# _`&{GVgsK~cճgdzK--݇^{5&O_QҠA׾ԩSyg8;կ͵?c Fڵk@̹:~ '9+Wkٲev \W 5OLR*֯/XCHz葼߰}7VLv!y jkKyYmݸ 7v-̊ >0`6A.~~{TWWr‘#ywqWv"HD[@ݎ\Ÿ)#\;rbqL_n^Q`|iCOUT&k*!)6Ҍp^QJꩍ1cPcL*Be+f-X`CBuMM"ޔcs^k[)lljk~|8o wl&%}*++g}ӧv}K,[oMΟ\Ϙ10 y饗_ћŎRJ[L#G2yd-[VQՙy07nF>c0d|펏8S9s&Af"ЧEf͚O3g0'`ѢEwqw:|Sf曹kXh-k֬SNjkܒe;ӭ[7&MDss3+W}ѼlwtT___9aHN>d|A-Z1Sr:jРAh?~<~!K.;>;=c/-\=x`vah{\qvi[tUZt́V}e477!.!cܹr9֯_o]Mz^dƌ3[n 07xuaaٲeEْnv=uڡd+׻-,W!Z싽u]8A>J5?m} '<Ăg qjPkKX^pp'a?p 1]_"^hB),iP*kvBeY(>٘%F Ak;a@"<L'JA. BXFLBl-a񔏶a5:lE|<#ta.9.`<OHu h7[[ѹFr-k S"۝^t֛P BwQ0 5m=x~7V쌒uHY+*Ch,ʫ$NuN^%@R}|.WȟrU|߅H|_)E>OY I1W]UDuѼ11$IPL)FZ EX#0F3jKb/>4rkL!1u!:%, ؛03) .0Ic/m+qo,uvFzaS;jQOҋ,٬Ĵ7wZhˣ7~#d'cFs?5\ H1C;N: _Ϟ=Y/7_% ʁ?[%0,>o/}?0sL1ŋS5sf2vy`UVV2j(?2v1k{tuf⦛nb„ wq\r%ɍ9W_M>׿5_~9?ON;0N8~0rȒ+Մ 83hmmo߾uY 4hѣGrJ.rV\Iuu5C嗿ew]n&^{7̬Yy睹ꪫMՎ;ȤI8q"R2h nveԱo*e>dR[o &o|wߝ/^{-h^f;:dzWYv-wuwuWAwߝ}s7rqu j&Mo~=\r dW}n |PĆqWtR9䐒uGk"`wOLmGq sݻw#`ٲeZYF/}Guu5z(:(^u}Q [n}هo,Y.Um\yEESLIC #( vZl]vم^;o%0!i}~^ ݧ?|NŶe$҅h - %/o+0Ǝ_\}5[0 v3 Dp c2V,Fhx^-y0V:!)ECBOՁd&ZǬ 6!d HCml5Ztd("V0@(QVH6M(兴 VflJ+Pn.1 "0&@) "+AeFyXpx+Jy.# ujeF < yRxJ9f OX6춉CX J+Zp2)ϹBlxub^ETR"=hGcL'bk!$ါ“XW,q}2#ETY3?NRrb@@L{$>{ZHBVBZrXl c0!$M3;< 566rL^832xpSfϙ=Ƃ o47jf~_%&Lآy<3u*̥3fܴt<Ѓn9YQY4n60>tٳg3uT{o +V`̝;QF,cxy]#n刽Ͽrp b|Zː!C?FO5_mV\km’8ꨣxw}m\?{w_\*We[KS\pWdȠ$m:*eʵ]>%>\Ro~[s#b: 1ȃNaa|$V $4?Cb3%A>XRU L.ltᡃflB!,: (}$4eBBu}_GCUdJGNu{YС,Mij[w#46bJ'ؑR)A˂ 1 )&}xcUTTNf80p!C25|s8 XaMס Zm a~6()#-)v_R }0zPE,IE:H^+f~<}X#@(y&X܏B"(4[ueFJ"b?,]2:B휅8I$11INͽ^ S#jkkYxnrٞ={rl}zŧ+Vb&$~b={8p8@^xyޝnԷ_?<@}. IL 2ڋӧO$O5{^{\){}A}F;׳h{,Y/9Rv℡k+tx[ru){)%7t}-)M_OZ+䍳S:-vU9[@ 6܉N:PPHln;mm=B@dj$ B/"0aCDc)4Cbme($ S#ThY, Okf0X7J;Ff*@kBP!u hSڒ2 M'4H$>uQvC$|WJ?!%1ag28$% '$9>wD1ԞahJRgc%IaMёW $G(Ev HZ`"bA3,.ņ)ui!0 g-Z6K !1"_9dd0)AhG6Z&T┲4J$D B UQ79 Ժt;٩SyY;{䘑pVz9p 3fE޽KfVWWol,}%'Τw X͘OdL'ܷuUVVrG&0[[;`ܑ/2~xeo~:?xˊ+m^BPI[^N!:._ps50mbpm /SV3 /[FX\n@pSS$±)%"DE36Je|4V"<=ã [A2ǚFTD*& !ǡ(a!{zx@@DHZhn kT j"oD)сX,LjvkZJ\cPUѝx ~@Mj@V`L6h~TUfH,:SN\0/]5xv;}z[ey>o3CjCQ)Q")i-JmH)8N _y_;/AI8| bJbG$6CҔ(EJ$5ùtwUWZ÷T3LRg뜳/j~_O lp@.`> =&*^QhPQ##0q/Is9]{lXGDnI'J]}~\BrXyŌ3D^cЭU`f3e.1e"!33B?~|Mʉ(`9QH6Q҄Yp {WVaaS+C (޸mĵ6ɮ i 6`9 >!ێ\f$eTB)ce-7zN1)-/v=qX6 i1[wR15gQ:ϽƜ[_;PJb;ukǣG75֗׮`v7װ,t{n9t}/s|UWW׼|{gyD!Fif~qހ:N3otwf@ƒW8L_C=TT;qw4)8p,0G?YF@S>%'FQWo e>-D؄^ml@ISF-=°%<_xz4=J& gۄxF>tõcz]?|޽{_}!/o^^ >7^~w~QހK_[UJ!eW aO*dH6, eW\m=0RB갔}VU 1HNc^ Lha=&pYMrdNG #bϱc"00_^;PH91GLHHnD"&  A+X`΂ha:AM 솯#kRi&39_ryi>@)VlL-a$"wn ;%5f,b@hBJ/y)c$tϰיG|=c.7(DE5{8Z#vv["y}ŝn-[h7] ݲŭ^Q\wpρ\Xarq`˼vx;^=9uCЌc rAS6^7`QἸ"z(ps$Tk8>{ /MM|[v̯||3Ỿ뻻>SUR.g q _z/}oM5*ACT5?i|'@bP3*'5YeEg+FʈpL*N CDl%?&K)đ;0auʵPٍ鄊2 TG$O)s6|=$\ B.q~|g qϲ+5jVR!͉q13RNC[!q$@J B.8e7L\+L*,MuexG5Եu5v,'nf+[{R0b6#bbgeE V!Zc^r{./ۖ~=7@.:3Ӹ[aVQ:; ݝ_O󮀰SDwO~1f0z>m݌[g;6F\Jӟ4_~%yi83KO|{>y{zoB3cN_K<^: A}ox>1jѓVWQW *+iΌqv*׉x縼x9yzqOΨku"V#y(DBTJΐbGz 0=s6B&o! ~ D?2#$R4-۪ 0 e]ϧӄȰ8I OSbw>E(N_W a* G s@raK|걷A3Bh -oXC Lӑ)pSuc)lYO7@Zhm<+jۮ$DBz46hT OUq S=&Յla&\AI5Jf+~e!KP<2[mݔ ԁ6^Yg*\c[F?<ŧ?>я۞mϽn8KDÇL% _/wMfE#~o tuuuuuuuuuu}-ξ(OoF6a +h;Z-Y*3g|ū|ΙG8C0}nN9SfwL)W$m+"9%81fwfa2WaNBmgdv|YBkqـH`Fr*MM*!T۠v9^+6w F&Jsfv43]]`KӌK"2 $L)q _:Z !b@*(1R,CE1,MX#V)\@/8MhZ+=_rT+ sf,+ޝ:2hōn$u8D6s@cMKnMH+ ,z1tynx7VX-@qsEhr{-RP =rues^6"bk r1uR{X]|Mqg^{5^~eI)qq;wcg}PvuuuuuuuuuqMFvT뿆 DǣGs-%axR!2]?DaDP0|gܠS&`N?̰bHHi C\c)$*HB>\aw=weCL솦s:0 ,F>uvRDj+ AghU2UB);PG\&1"Y¡DВxۉrbjܭ14v:p^ >b̵-1B➔GTJ Kgn8w ʉQ7` ('@$ks7CX:5i (KYyi5""q)+k^zQܡ^Atp~~" ԎDuģ٬uI11K/,HI+7 C%h$-C&mh ,0 ܿýzA{Q@FÀpGg 1HFqpCR1Fen4> ;QRIX) DL9;sH)#TR21 M%RtZP1r&[d0K Jt؁yP݃P@yt0䒉!2bbk  ơA%.V# Qyg`8'[i2S0Ƨ@|$ 'L@h4%&J 7in I),򷔯8L/k5-2 wAiBiufSr9:ܭ''TȺ+ű `|: 0s _pct (ya7q&Q=T~? lF@tKliPb٩݄벯û@Ή%) tl$YU)Vn|_t'˱y/a&nۮXכG!?f4' )gEv{Z96#t@U k0t(2qox~/6똈"d)UZ=%AlWWWWWWWWWWWWWXo}{=|$#ה;Ȩ !5a1"e>3G /~{<8( >Ra@l#MCq XDLDS0E)ie[xv 1B8Mg!՘'Ƶ`VfJXnA3Bch"N^΀rԥ1v 1DiZ!5C8_8Ը8*"c!6~;pJ@nRQtqdgF<媌):j+͖UX)[lu;ҡ*F ֮;_p}ZmG',C=:V@A'ۺFs7CsZ_A5,(aFَ_NƟpߓ:[nO\[ 1#$8":iOe^0|.53 I)bMPS2OhjĨK3HȜ!}5VGxt@Èj R.ĐkDBhVf<`(1t`3$RR14W(D)0)\cEQc#jEZ,fj]6R!35iT(eDT|f qp`J>Cts QPMT]miY7rm ՚uq mSB#1.k+ ܭ+qmϹ;L k[+7W~@m k7v)-xLdq0koh7L)uuۥeX`Rz۵Q3Vv-^,n8Y1ʍ pWWWWWWWWWWWWWCRaQe7K&iJn: x>+J(kHEsZf@ eъ80Ls@R$Kv @` !;paE (|H?朙gG嚫ëLrs3պːWU៟ٗ򖕛x_XLm l|1OsAl,J\澄zyv%6rk4J dH7j~̫3Ee[ L4ڙ֠'@,Xω'N5T*j'mAZxv݁l`6mϓsYMX?t-YuTlz/Nw` #-vF6n/1du3g~h׮7^{` J#Cf(qM `fΙld" ]pm\R7Lʉ28.!JIX1!FMV24SS<;@N2#eKh0 SJh 3*hDW"9{M\aK 1,4ҜAbqfNOspx8%Čq g12D9T))C.P+'y5}ky{2H[=|^: /в}A4E^+?]-lVz۰-p9(}1g]qU87=gc7FʈXvwnk%ru/}dfijwy.0p8l2!d ;{Tf9`wvhX:sr% 招/y8`kݲY rGM؜oѶU{íNZYޔ>6;:$VVƠCq}}$ɿxtPh1_Yvr~`W]diVCeoތtҝX"PK$Y{y [f?ˆa!l׺>;clWWWWWWWWWWWWWXS~:9#Yq4D'O4lgp:1s V|'aΗ_>kdGbiW}j\ -򜗥9g2e>`\"6q,{tt*10v@un<'D!LǣCT˘iM; eܤXJe5OU !RJomɔfF<]#ux>CR1RܥgM(fNFiA!wDݑS3bR(V/Kl'E}4.ܞ%Y--ֿfy>z#]t Zd]m'B䩧ncf@PR=tC7@:==]ZS@'T:'2 ߊrNWAj9Ձ[=J;*(A,#$bf ` r"s@Y>kdj}죭ӊ\MgEZ0tO?s?U~0|6,>i5g>F~}E~f製bq{ g?L8W taFEj Kcjϻv_Y d9C!) m[,@`ez?@DByJ\ _|/`-Æt@8=7f䜉HNb:2#!`H*H!p}dS:ZsF%B)F (pifLKj"4y.( %B5VPrJսWutYYH )\ 9%blqB/Q䢵A !"d| h81&qa>. :V3l1y!.mF\a]\z*2v9Žu抬ȶjT S4 -ϋ'Ot5ܓγW[BIJ@ȰNׅvA] .' ȓEN? 鱕?Yc6 ~nd-hɊ>ym|'7p3d/e&~ |> ?_/P׬'"\]\q}q-/~?A>y;9U)0sO9MOyVl\sJ#Ha$U0Āι>zw_!3HQo#秸*t0*SBÎlհT DaMfZew@F@5BȰy[9UY[[֥ͥ{HSdEAۼ;ye0c$TDdKTjd cdI]<jt7+ S*93 1) M$:H:Pŋ f)7n8Fp,5l v˭w+j'vB 'op6NR]7`#h]AQ /\f,&Q-DՍiǤĥdv^z_F7َo^ϻs_Yk_N)'ǰ-ܺDl !/,esq-,}X "Ͻ-'? M{zE*͉&̏g 5׎~5{q5c~,?Oq'1鮮7rs `嘧s+H8FhE9't/ys Lttvp/#<'T$;#s j)'@! ˁk~XO1if24 XkZ2D;)VH@Хn2wN KFc@-̔By1i 9_ +yu\H.qwVaŀQ%*dS%4.Lq&S(Ctr^Ǡk|r^bH!͏ru_p;TDue7m>·V% (& ăDb[al'T  6h\le͛I+vY%ki]{  9kkn9m`nvq[ ^|"'3)xl_\O]UVH['zŮg+/˽eȣu nϚ'X1/Tu#=j?Q\zkA)suqa}.o}[y٧@>fW~~!^ 9'@ɛ>ʠHn6/ 뇿C7zn= 9qu83'C[] "j!D 9;G**J:;;؇+408b O. sJƑtE)ubJ3؄8Tۍgr&;=Z!O޿w/nqt'%Nj}SJTeV0`Jݥ UoC&5݈xRJub:B\-)]9_*0Qr"DġeG6#N񖒌@G!Ra7p9_W.~ ,3ī~mb15=w1[:nV8ȭҘHsom6Yc= k޻swͳ~= d$7'9L &Fm)KgnϩAU\zrvQyu . 8O|߇?(7v...}6}xg:yϙ^~㇏G>/|Ν;'H %_Movw`9~?O/=Fl=kq|| FLՉ4+n ضװ5נӮf`RPtegNvӌb C&eWN 'fNZD[pۙ ܭr܊1x{plפ,e1.K[h^udk]v 98??Ɵ֏[l!ruq?G~?{OB "$? 9'i=;Tzd$Osn!!zdu*03ȗF%j$ei1 !"q`yǁ r5WN9+b5H.w ,yQ $w |DHn1^'`= H)?a׸szR ]qAל4'bL爻U^K9q8=1!"󌆀Y!hݯPk{%%u8*ܾse3#ODVΝneq 0t=v:ܶ+rmo!͎A=֏n`Uo=,=.ԨMd`T[pkH>Č1+2KܰZ @6I,*1LL}yᜊl͹]tIR1TI]]l55yUډ\{}j Π1xK*zQJef*^ q,a5gaB.H8yɜ7^Xnh!E~[ 6[k ?qړپ}{ο{AŽ?|Le:uԩSN:u鿍d9גK▛H]J)ʲP%:$MCs$XJi*] Ĩol1B dt!,=2R BXu,J UyG)BPR>ăka8yP(U1^u h&r1c7UXR @l“eQW|tI\_օ%MeT/ş7 IDATˍE5\M}40nQ-{sb֌C'8BFw "[\wG ^K|fdy0??|!kLJڿo~5PR!wtb^ל3 k;6sG.i`;uԩSN:uԩS_g9)(JO"ucqQfJ*ʢT&'6;-t7)pEf7`ߥ4W 3:!6<9-iA( 6zV,+C)LXW VRUmLWJ<;Z]ZBAY &i0OwR m~hΣs s NFR5,ϳe#c"(TeGbv+egm¡,=XINyL@ 2>syO|J4 Fs Ɖ\KHrꌑaO1d|8א W+Bŵ:s(Vbf:7\Lg"AC"SozuZ+Ӆn,l~bMHc?|307t*z܎^?sI)ytãwe셹tOs;C)ʠjA;{1'8淎aTU24?]~?Kq=ZKy3yرcUU1999#9cx\|~r7sm裏2==s~{I'IJeZz|_dռ~wԩSN:uԩϑ჻NH1E`(~7֢8B,Đgy֬y#2 ܁e&#{X;A1MuE1$#+Dw_f)s)S(@eX#$H-!=d5ZF$.5f_aE1/qaqnXպY9iq,y\t J]p^E,0!Q6RH TKUEGՒ͸Rg.γS>X_ق(LD=B)]B>ò.+^Tx'2XHYI+ ]& 3O ܅ͅzyCEpߒ=7׽uw%܎{)Gg&7\:n_.o7<7Y.B%K0>> ??W^y%y__>\plڴ +Wzjl߾zz~moC~cwԩSN:uԩnJ"p=B1lĠV.)c+JyrV\-?dxO)G){ XG傌ā ZmXWGT"8a#— Ax;/[J-L' RT8 ZRzH1aqe2JlLp&oeYw - Zk 4E_6I q":#qErk0[Dsw0fC2'R=B7-e .PT3El;.fԴ Ouuc!q]a:s |B72KDFr5[wdsЌM :ECric]@i bLܑ1Sukvֹ =iLMSK;]wqnco-Xlэŝ;v=k|I>`Wyg326BI?_t3.>b Ï;<8[x{׿>qXn-=gnsyeFGG->h&&&s}Qjn֭[~~?9c[R\r 6mbwww}[oݺ /|/}K ~?_Ǥ.ݩSN:uԩSN?_Z B p(U6\p".X<# {HQ`G A! "U ( HS/&k^+#R/ !*l5@4胝KAӣ˜:[X%Jc3Ů"qo]u&s2P:s]h. Tz#``^ӽ?zq7;P JcJ DB ҁm1 BBJ8;EaMpT`dm΃C 5cp|I`Nfb[0MQζsi/m06l"L`QD3Ji)k؄ii%'[3vc @Qb2y5/Y(.d9L)𖷼W|fÆ z4;83w+Vo;^y7vN:uԩSN:T;Y:"NXL _U*\5 PH5XN* u+ :|nB* 3j`iq^B@1bLtWX3ĺp- HÛ*FZb'c %HCq8 l Q(CC7u'fJBOAUƺmY(BW  TROc0>Xt5*Gcbl&Fgbt?F{{lLf!LXzK`blFU)R`- ovgg.oxSwoޚ]yyPl )EJ ﶠcs]p!#rބ"Q_i5D"8lRlP Ѝ |V1o9@<HL`2jn qzb&?ּN d6g8n󀊰֛kKw~N!Uty*)|ΛyGVTwNrW⺯^Hɥ" 3w<>]1tOLQr5'[n`ڵ?r ׯ'? 7?~/ssYgqu'|5ys88蠃27x#֭nmdff,s=9ꨣ8餓(Ym{vv6_ǥK>1LLL4f.%=_}ަR)qFZ6oZ{s 'p 'h:G'pzիXn</yK2xGkX~}>_V裏Ol uԩSN:uԩӯBW3ch BT AN EJFgI8ge#a187y>؋#up{Ƙܵ @= ;z貓~9pG1M0h@S28s"'-JIʄTfdEQ2 p΢ucpxSahݧD@( ѪyW>D# eIWsqm,Z JsHS)$}LU!kpz=Vh)*? H@6[fXz?wF2#=K-^C ˑTVJ;+dG nu)%"C@rC !| \;'C3kg\j98s,Ru8ds}sMrcqz\)ZO]AéVd ^p.D!f;eesi3նǶJ)vnKzO?;L̮& ʐR[YƗs _pηf~ 3lkȭnݭ+WZxׯgEQ0 7{GIزe 7'?In6V\ '5kx'8 jyngϒ%Keɺu7+8#~||nc||p<ì[K.dCp,^|sOp{VU}뭷oKrqqc}}s-0ߩSN:uԩSNF`z>G^_kq֞gRc#JeVUV*|SP`Ta&_<>gg:j>lØ*C;R&|ŦMZ [-}y=7nnOfa1Z*?۶m+_ Zַ(sΝ|3{SN:uԩSN~Hz#˨K$ɌYX+3a eb.hRgP"r<1SyRjsC\7vR7$&a~B)uxX[!#2|Ʒ.JsPѐD#FI`@_A?z25P1^7m,'8٢ GIJ(Yଈ`" W*l/pXL{VDsVH!XbB:c>N I(;'AYI „xl5㱡" v!f[=F4K`v-i~|1l1'H`g[5+1xobkos_ƶSJrJ؎45 FC'cnl+fH|/8?sy=LmM{oQ |Ejܱ;95l۱-,wǩӌhGmoe5r==eDrwginn7 O͛73>>[`լ^x`<Vj_|{c8rǶ$ykwFN:uԩSN~.PzQQJIA5?vAFHJ U35:l/ V2*DBZk[J) f1]CBùh~9 lE#/ BbPxWhtrj5xKi3X3BIew @x*&&! 4ޖHQZyHiq~{1JFǖ*8ϔJR.#JT2`UU1D /m.<¶Xf%yIT[cхFǫY2t:p3Qj山1<]~dɒ]T.=)?2x۲e no[k͛&N>dn&Nmƍ~ω'iFe-o>ۿ}cO977ceYrG ׯo:蠃PJ155˖-SN:uԩSNYk C}0wa @}\tYc}]Q({=`gpJy2EQ7Fdmqg 5b$ׅZJ;44͹;9R SC֡uHizFi, Ѕ, &3e.OrTy&}hKa+ix)$ޗù_cŅR!9Pٙ`:EdZ@ u0.׽:KJR&" 3g}3jV‰M0͵`X]Q!tZ1T(nLminNȳQ8|nN<7澧׭ډ's7?\)r})󴷝sy.Qt/g#[w8ٲe h/_ʅ8֭a+r=eY266,SSSLԾk_Z^255ņ ذawy'\{}ٟ###e-[9 {زe sssҽ 8IO>$]t]tϼnSSS?SN:uԩSN3U 31!*EyR»!~8OW Ud΢:+|(lنL246+ -E%^ʀ1UG%GRTf%%Z@3DAc9TQ1J `1bn01!,ƝڄTCm@YAQ) QZ_`fְ*F@`. #īh" Ώ3LMo qh(u'.*$ zbk[RpUQs`փ[c O%:6Z]ixn>.h4c;h]\aWwuwkE2 RtRegNV pjnsEn0JP& 02TvEnnEŢAE+FmaɒIvAJ,Bz`XS=07=CMdc9F:S~Zμ!_w;>pLLKÁ.4S[X]?m(^}'$.%LmBz39~b$H\nOvW-S)›Em'w1p1ǰvZ~ssUWqg6w>)n|0K.oڈ<_k֬iŐJɹ٩SN:uԩSN esQB!!JFޣʅ!{ ) `xl]@Ez~!y}8 :wZlBU P,J9KQ*gEh6"UN:* +a|l%e! C@Xg΢,qvjn0`ٚ])΄aUD13hq΢BA*(!J|(Jʄppv0>B$񁇸G TV`ehJBp;T4B"!}@ ztp l8Tk^W(}qn&O1;DKN2!5g5? 5]+bTkƄeJLTKuBԐ/D]tn@gELG1{Z\W M8>fIik۷X`hF%*hu<Ἣ~SZRwγbdRIz{**&٫؋%x>mGwm;9ܳQZ!I B/_,]n̏~#\q}dxvP@Pu"R\t▢Q;› CɝK[6`nUx&bl2s>[tz)ʂϟy/ײRs1q/@JΝ; -sqtgTH5??l빻 6pWs\ owwu=pꩧ>OיmwԩSN:uԩSR9pnf0c-Ɔ7|5yIQ9yZ>^ *c gA(T9ElJ Fr ;ߘ  GHJVS9BxPoPkB"_\`@i"e8g0Ʀ[(2JeT =xxW 8r HQd^EX2 %c)cyVr΂,|SeЛӣ}:^*,&k xXRbmTa5"[9Nb}c`}liC9~^)CdʈZݍ>hA^dJ-7TnL*}${M"ᨬy3}JWY3C.?4Y:FHv$t>^^;\uZON}˩۞zYb9:?@@jRgy_cEbae/.c?;Zsi>83L699{۹+˞ys^{>_zS>O}N:uԩSN:J%8;oG,<!}4j֗bcDA , Leq,1Y^twBD_|#Qw5ßJ)T45%`#qޅ أ>kbJP( RCpHYE%Bf秘<H(gmui{eQ @隅hQ*\f< *#yI:4zMk U.o6twZeܫu 6%eCo4yߚd ]p&]sF " [)+9"%'[z<6gaMoyG K'm?ohts×BdOe:+%lpTyÝL IQ`cEٜέlT2Dj( # a hC{Mva3U[WZsj'|yk89("{an3LLNp?^T>|>W*K'Ë4xN?t9ki=/K/կ~u}h뮻[ر/}bz(شi\p?.ٱc_~97xcў{ wƍ~3:_eYqFc333\xOԩSN:uԩSR)@N9083sCQ"p8UNq/zq (‹-df@lBbb65 sR)t*/N)D( H0`lTD(԰0;S*.19H.MЎ6_ BITbd8bR*16F~un%ȳSd4䔌>'5X #CtI Pg]wȚj"C5E`}EEDv7ǹz&\Kc~]%h# 4LF_겐TK4ΛrquaErU

dǓ;X6-M'w<ɩ?_y4ygQ};2>|!8?^/=rּ_*r _~9W\qK.133gu/x ~\kײn:/p衇{0;;w`0#SNyV=򕯰~z=\&&&DkΝ;پ}{.yk_aW/| \s5lڴ+Ve|A^Wl2.b~2>>ΑG|r:,."J~<9֯_ƃuAaRŭQ(PޡM:RF*R24Bk *qTJ#0xE37@ #^ER QN!]kb %u&2A)EQ>k-eX1ۈ| ȩ ExAn8lzuR]Q7( ,9k܎s*BƉqMh };]I] SSSl߾Q: ֬Y 'Sngx3"pqDZ^{quױa6l@Y~{{챍{g?|tM{<<v^C9N8e˖=z~m>笳`>o/|!N^uQ\{lذ^{qqqXzN:uԩSN:`%q*ZXhp )xX,7cNPԊ`xPP28#C8x\~ JHBkkP*Ee,Z VJJD,GΡet)j L"ȀHSR3y#BzE( T}@F?Sh&vZR27:k)ʒ(ڬUUEQSJf!EnMsL!<>ZjkBRo,}WapaL$U˃ U׀mWN׶bu * 4 !=Ҙl&/Q9s.6: "mӻ;g2A?DnsYRE̒ۜG/hDmc>CZrm4t a_Eùh͛fΛw 3>ΩfK( |?QLhi@meí1^GXq(Dkr ! ^~RH&M+>ȪVuI:uԩSN:uԩӯd-Lpg+R 4( Z0DK(^|Q윝ߋ=hbJX+(5]hU*'#%6J!tXRIbQqjVDyAܐ~oCd,u(- lkS3֛AЎm7s!B<_'2.t.c?kiBr39it.5[aay½B<.C#U-$p'd3[ψ2=Yz p9ϱf{kd<#bAIc@b6]siTl"ƙ]-Sn%KVryq̲.TU}9 Uz*Mٌ֠j]uD8x.-qαsS~~Q) >O~H/þyJw֡bŪXn. 5_9}9X}ǹy(,S`A}֩SN:uԩSN:*NYR/AXqUe1xGQ]8bQjL V*<,ݐAs;rW><\)V (Rc\d2" LX^hxd}'(-[g`lCp u*d Q (L^)^:s ֥)\QJl,̣rB,bp`?R@C 0*9Na!'5 ZBLWZo3*d4W<BŽ"K-DW b=Xƃ.3Y(eF,F; L\w5xs9Q筛\|>Mcә60v yx^9e+ijIBxcE7hetlwmoh<F#c7~5x[^~g[ 8WP3vi$ԩSN:uԩSN~=xT=$ WXt@5ZE((zLjT1sxJ9 JW>{4Ni g GkܧUpj1 E!VF\YBDd.#o{_a@xOpY+p;v*-Πe efQmRJɝXb6bMi5iDY`zB!:p8|އw..u?rj8 OL%ʺhLN5@^hn W m'Dnur ]/GS/4c'g: 3Hks!xLcky~͟X.0Bl@]k};zeܨܬ͑h!+t^6(ln :~-w ߟW+N"u=pr$|{yL.^SZp@Fg&Psc릻K-ZjtW+;ةSN:uԩSN[;G'@!JʑeP,A` QhM\2lPM3ܼ26Ep/,1Ɣkogӝ~B.]埿3?%G_D? 5DZZk~v5K'RI{侬=gr9vԩSN:uԩSN{Tva5CQ`FYEQ0{kٖou9紻>tq۸1.D !QL+l$RM("$@+$$j9رiv_Ωלc|_1ƜkW'RioU׮Zs[weI7pRti+޺m,7Л2%qg_2^#ve;)uHl1gf|f}uPVP=(Qa%CZm&5vOxa{(luv#L9ksNƲ;5‹ڱc1bԚe^ݣI3?G7+"+[-T۰b/*ngLa1/xN@f> mvez6i ASZ#ʼC#0s_Tѱ wס~{v}5*]hOcp~3?wEI!w8?6,ѐO{o==p-/Q>L/}ۿ^~rXr֍B!!Y"u 15ȥqJ1IVzO‘BY~Yg?Lw@ #T PF^7|VTnq54m{S`}177)up ƈ 0ړ۶]S`]JeKnoէ1f)e%BN)wۗAo1Cn(d]b̤U3A5ػ8?Ypu1c\;Ʊ׭>WJ 8v8\]G|8H>̐Cd'mnB{Н ?bï;,qc`^pĵE\"$/cYuبp|{l;xO3?4/a([}RXg~3;B;}.O/G^{nSSSSSSSSSSSSSS_򲑤qn1ES_e}VrMح=*~wǞ¯U绿__]V(wMNJ)1ZK˅R*)er8u є0q-ORKw:mG_C҅l]ǁ-]In.^vPZ>c9YR+̔ [yI\lEV.X$|5Vgl7(C$g1OoL~ ȂD8;|\G1Κ^>mP ShNU#Xk=rZ2mfXr^~i|so\G؁$t0g= 1`4g֦#{;?na1ezwy 򛾅o~o<~1o}>>_iWxO>=<6$Rb?'|~gIcN b(#͛$c{MgȷUP+؇'<~/9/5yB%G= ڱ:TTI1{t~mGHIض5l[]zdͨ`R힜nGK|n}.b,Ǵe_"!S]P*9pu`Xz3vs{i鄐H|7J5rG_#.al|!iUC>}>yß$/2~~?|>{7M>"Ryg|_x;_~Axoq O?!}ۄSSSSSSSSSSSSS$u:7{)+nz ˂ݽ@1!y- !^Aɦ)A5V';wkokW'/)$TR+լmĿX붕ӱP\̐ZY\ϯ%K&V|h[Θ_D+ꅜb[gE8ݼI0@e}Z0*w'\Up{)؊HKr`8J [ H"/gLq-FYjw[uB)[t$' xPnňʀI}yj<1W_ o/g=w+h5sYgG"qùjH+5[k(m&G~_1R+װ M ,D:t>5ןb܏?Aom7ǟw }QYK<'o=>Sy!/o>KzPK%GGc ~ɪ֊kB%) ]J"=;(U$UDįG@=??H^3g~J2VlҎVuVGII)^]0@-i+@JY FBA>==A8:y3t:q\vSN+ .7r)?nqci6"Ŏ$8O^pJZZ5gTN$ X; IA_s@343WJ Rr<$'Ge~I5#Db-iv}PbYCd]rczXr;U0E ճᗎq=SuCvW ݕnHAqyvp <bDUŸ 﫽{7@Xܽ#Y/ww[}.NMMMMMMMMMMMMR}LO,}@Z H3 AEdMX*ٍ3ա=kOt*[)dݷa8\5S+1gG_C]Wԍ l#m98E6D3 ף)Fo` _):T`GNԥ gGױPT/ 7FѪՖertmbчS7>缌aY' ~gCze0Yimג4aV@??8ԔR/K@ jX[H7ؽQ˼-}jo#갿]=m}mWɽîGľs;Fyys b{ӟq;ݖ;/fF^~՟i^2GϷǤ=Xkbל41MH5|v#C^t=I2Pb۶dj)1T8oq4y8V %*ʽ ,cj*;˷GHIe4ScեH'Uq,/^ &2&D8ir# 31(.5KVP@k`kRG`iQ1<6ʶ5&f a2[S;y-ڝԕoR4KݯrpXƾ[9ǿqk1=rу%Adwʙovx3@\6x]~ooЩ_$IH쬒S*sǫQˆ iA̱9»YS:xqeYƊp +)Grf29p)%Swic&uv`[ gqNuGq4qsֿg]F`R *a(LČ%gu zu&ٶ 9 浕%)-~,o׽oT%QKmڵv<px[].,p!fj. jq︸/ N:W=»Qو#W~}Nǐňl8tDs{p\㛧Ħ"h~ƾҼ5#ϟ03g:gg?sb<~#V? ~?'>5tMMMMMMMMMMMMMӢx>o6 Y,JAFa9I۹Dn O$iyg+9-W%zڿ 7DHTvV_( Zn6RlXg9=}B'vd%7(I뺍곔S (ACTj-ޛJqԥ?}^3;GUu\ܗ_u6qSANez]RXoOBŭ Q+,HFj@895Wt!UM~_Ưz&Þ8z/ĂgJ)Ժb8lڱ׆1"\{ pw WñC^?}EϠ'?q_3M7555555555555O@Q"g.1 @)UT XN>RjDmb;WJa9 NStٖta} dMj='D(e7oXkUh,cm[) 9E-d͔RX%zW:>՝{nfHF-|luV TsHg 6hϐp-2x*ۊ)zMwn~n =9Y(쐊#lܨGH֍Ɣ*#ȡmg:qRR ڶTcbjڙXV{`jp+~CRq;\R-..N0?)jSݏ;;:"J#gp~vv^>T{x%ce>*#zuMם|\8n=㽩}1܉qK q]*i4͟SSSSSSSSSSSSSS_%o}Hog&VH4'V*+i )/@q#_LJf84vmu]ÉW+nF ̀QQ+Gwmt--|zĒss)Lp<1XHOgrVPC[pp6Rl,p҅[۴Z+ŀN^'zXNPsClX}NݞQ.ϨsĝN i`om1p#:nݎHw6 @4I|=zAT~|h1*fW=ѕv`w][2wewwwju+X}$F!\:+uU^pD<*; `|ݎr2>P;,q}{jjjjjjjjjjjjjj=fVP[mۢ~MI輜Hw鴰_"^KlBu1QE_5Jz`8V ;ro@:#V)luG)XVU]-źV*ssz3S*5p%7(I0Id$H(Q,gm}I`+R^QLnSNDnx]Iꎕ$RQ*yV_ ^*!.'.ɔS=r-b rl0q%,%/j?VwձkvA}8lz@iNKuaFhYsVȸ;+a\cz"^&U9LWp iv2,VF[6bI3O ;5555555555555U %P iT-D^b$^u^氜NkO}gȲ+#/gǸEʹ##pZ%+Ho _~?G>?A# Z_ÇqH/ܗdbu_Qa.Q#Qpk2[+ 19 0QY8 1_JGtV[Mtn&م ra+l '҆MlʈXR<4mativ\ԠWjK'dtJ)uhO+wPAޱV?,?8;@1x,ԫp@t΋Э^$<.}q IDATvUt>tJ#S~؏tnV;d+ô:@"8{+Gд/:Q*ۊ CuIbm%T#g-[%\)euHW7g#KF\sseit3"ՍZ6RUQK 7NJ8Z^{9[it储 =mxRu!P4(VYq7}gTu]#&|zz^ft)hӼ4נnx-${ЍH3b]@X.6Cc`%yTD7.+_ vU[M]Y79lV{3Zree_MXiyXR **60\nsع.{tx|J㸵 :vf_a3h'߾y+óx {h]v# ~w^}x|q};` 8zt' ;5555555555555Uj6Z/+33|:S #c8jFE8kZ,j_rRJ!/KWIiA ~,P֍t>d|f+K3E%sj`3k)ga@5ŢUX=(& 9dyD܁F٭Ԋu7nP9)XNM¥XʞĴ.XzX0QjȧGTN&qj$bͷVTmp:*^3ӆK )_[d z͞ }tA}t:P|ꈢ3"6:d&iOc8D؈qՌGa*ޣA1 k2'0ڹ\jd^*v㜗;Dƥp@y浈5Aܻ%cvח16ŲB *yMi:'(xryE>=mKjv"4d\`9<5FTSΤPKte]Ye0lTٶm)$1hur>g%"֪@AI/ +Is"oc&O7\{\D:8,倫 x~+NK沽c4Ӝ7V.bv9aLH u{/7gF4'zgCѨ+"r<5)hrKK@hU u^ǥ݈LVv[w vؕ#qxXݵRcFC^mXK߯i=,4+a6 2ι[_ cbN:14:`w護$2NMMMMMMMMMMMMM}ȱhoG2Q1*j-wC"z wfR RِKUNuPrJJR^;4U#<~7zy j[R)SY* $k hJ`Y'Hyt=j5Y1⧂#>N^}f-Ȳ@Nx$4+KO1r:%6 ) V6ܕa.\CݤV{=U[ \*ꔶ˖p^."}EPQPhr*;bCs @׸QT60wPp) wwepkF2Bo:\؁5%m+0xD]=?q-{=&v!p\>r8,kkjjjjjjjjjjjjjjW^Δ(H?&"%e9I*!^ W oۏ tY6jA%*lz D)u̎;lzG^u *u# Tj݅*c8U UΒm $lz:ASE '̜uqTñ8 vwpE8EݧOL!zvg:l;­/=J09ۿz7a@/Y]쵷~~jקtBZ*~ߓ #&N=J)Whq<5555555555555 9 m)1ڶrLeYpz0Fn|Ʒ?HNʣG78-sr^a_g$\v0-u#Y̶$j#̓o=NXCDPTIpq2}{A IE7:L)҂YȔm 9YN +F] eA,"Uk65!+Tg-A.bF'( >b)^v7/N:d0Nǂ;#Ae|ػ+,n\g/|3_-ϰ֍}7;t؆FvhknFCkQ;5Jѓ N\Pt={6NMMMMMMMMMMMMMǪ%vs^(;I5nE`)."E?nijf=^;¯=ۗ;\5]@КCP'O嫃؀Ļ1s{^ sv%\G.Cӻ {>#q!@H~{Lu^X2*ˬESOL"+$ʶ-ȂZYr56bN'וw^SMsP L#1"4˨jP' `.fRO Wpxp i'baV+Tj:ItveF3wkm5t6U%:cUZ!LYI7K. /qVW׍fvWؠo]$ް,7[SH^NMk ,tkEM9ycXac, ^Is@^GiF̹CmpߛRʰ~p4oZ~;,}rG=cx?:γzKͩJZiYF= P$ZuZR&URv0q1.(Zu$͌"/y.FTQsC$q 8Ns3PVJaY 1/d [=Y?8ֳ PތaXN eESR,hunou 5xsҩpi~ GYk~9t .;EݜMJ[8G*G:\IQ74)ՔZ:5;KΔIen];%`FH.D؛.>\ڍ-xtjqp{{|+@8U]êXX܏wupw<֌?׶p|\=Bvczw߃25555555555555բ0 6}#nTkT wg ~mŕ喜N/4 :Eux5,mZCӢlHEII mEܩO0kI׶sn=pN5`3ƺWCtqat)q/0: P\P4.$LI FTfvݩ11=iutut؇}vgΫ&xoܞifĒE{o ^/VmJ^ظCouGl\ { 3zaNﳈbG_#33cL806*zJ?ujjjjjjjjjjjjj@"rn=$U "VZ7r>Q]EH8M'HD5@3r@a{Ъ]tӑ˲`&lq: [g0RfJC"X','̣g/M(V )-ȋbQچLbݹ\.>{XAHbEVF|ʽ׿)%*vO"*%eM g݉8)'!j`bS* bFS( 콀CoJ;dwҐ0+=RGiu6[w߹# º>+3!Wz;CнP5V~^׺6,G{e">>񌃪o8n[@M2=iN ̄r!jRoFUEJEә,8\Ů;CR t o96W=ѐ苵|} ^p/<"9PH9B ;_嘫N?x]Ͻ*5; gW0p@^_qaiT5h"@y_gok} Gwy|X+!3 q=]D \D'qaVZl4{"WGtp=.+eϚ ҩQcム2,4x*jqPH*/Hy pQ7yaYN$= #h Wچjp8Z+&׆`"v.^RLf+[ܷJs F$Vw&7q"n7 ɷh>h8' 3,ౌ,B֍ `Aۺ]1NeYH7'L:ʶmHqBƺr-m趻$;D涿aOvrxA&}^GQۺK<^@Dy.A57KX!^G{hRW?`/"6|xk!%A>PbWEǬxϮQ#|=fSג`ÞYG-ϟSSSSSSSSSSSSSS_U]oԂ T9qcғ T79 2H)ƶmJm=g>x;QIJ):H IE/mVgr4 hUS3M(d vi P o̤ւĚ, op}˙Nѽ} %mIޘsE8왓n6P! d^ VWP`,)8T")}âFM߫Ww6vupe}cY8 c4qq HanZ0-n HjFaeO?0;hoIͽa(e社pkxȻ{]oqUՒ̈-W9!ߌ 0֔{9biFj_%K Y4wHj'mq]2DJ[pZbn_c6+cqt-Fc.@Җy~^ĺ[Nw1pDž]]~}mw1q cn/i ji.þ𡁫Q98p/߯R1Ϲ; vNȸQ7#'}ٹ~?kܟ맦{va+H(ceЕR LjN7ض"@j>Ɣj2OmCOʙWI 7_HB#d<Ӊ8˒JEPHI@8o4,kVR|dzj\|wa kĶŰ5YY MV址y,+!qٶf/!c0U+yYp:won Qc25q`^÷ֈͶcH,}~">+}+khҠU> s㵻#q0!0278 rؤgʈl@Ŗ8EGwTpߓvvq! VVt1e2lJ9Ź59k|fWvͣw~//# t{QĺX+UWRDU ^Z9~/p#__!~s축+RtTۆ&i^u%x%n(Z/Oe3cQh(.-ٜ}oܬ v$ `4c>x[yx|u'N˙bY*JuR|ʙ38^9R4\Ru߼,l:-mW7|c|/ 7j3\STgkpKh %)V6(r\Ct汕ݨ}m(I9e9o<}J^2Dm/B-[l2X5 .αBMq!m#nc<#VAӉRznZ]g.`N^v އ Z2׍ۛ~o? ~C̺418-aΧNĒK|:h I84{GHWiOq56֕H<6"8ө{— /_q/ 9Iߺn9Fe%yaࢃ)hV˲nxD%c4;ۅ~?3j:Ҧь=eY70 IDATXʾbdl߭JUL /%`fuFFc`Q%!Gdy M, mtB$qZnC,hv.+k/BNgDu]/ネȂXSm4|EӢc%pG/X0W~;wL P8k<4";p𪤴O4j߳o<ŋIl brŇ׮Mw<Ƈjh[`_M;<1zX֫232:4;5ۿ4~?-5eTN@+{d?isZk}ňn#*Ws|iSSSSSSSSSSSSSSS֭bV唝w^Z,9bbCOeHE'4jDLyirxŻ?w|U6HDMf1 90$ [fk"8ԭHL{ZҪq:=H6!1XApQg"n )`GYNTUr")@_KRc+ᖼŶsDqU'%eO.k&B;,)YэjOmCRrtƮ_ k=BfQX+{c *׺w{d q3k-}LDDdw퐭}5p8&;ɟޯ[5^xMr}t׵:n4{6ܾK);5555555555555[v"8,OPɤcĥo&h iɰ<"Io1Z[h\"ĸrUAdZJq3D'.5mBm[=J˜>M *.^i&-e Ob,KߛܪFH FvH|mcK;f1`a!" #/-a`@  ji4LOTսdQ]U<#8$CoBcp"hZU)+q3)"ac&[q$u<BqyQ%'t !pJM#()Mx?s&3ή1:a6q..Q!!/3g"88rʋ\8^d#*C@U8/R8ngn$cHǻ%B؀Ob kX8:/J;B;e#MbrsN>+jƅj/WWF)WU+.lǾ{*J#AX-j]kZSXPNu]{iY Zzz{j6ak^F)jJ;!?lGGGGG#λ *CyG?(ٍ3?r'x~yIJ^r -yð zeϲ[_H&u]X/ ŔJj^%Ou+klv`j7iiZb?cvttttt1~u~x{|o! L:)gxwDEFw))|ҽĽ}/~g=YcF.%=Tgt *셕ŬD^ۺJM*ض$<*Q%ȰrKTefyi<>*)g6\6<i%c0׬•\}?GFst@lr )V_Iw;x󏿙~m<w$;$Pp8x={?^^/_xnOx1džĕ!Sf v|шDž 6,EsBQ|5qV(SlhXr+]x[o"~{oxiF1E^6-$h 9 && /g! (N)Lpy;C5ޑc*uJERR(J&1%\ƴ 'ips;Cs xG\h%GJqs#xƅ;p5OMkD!)55Sf5X#bW[Y_-V VV UeekGqQnNꁆ|[Nl5pKfiN%KJw=ZhUGVwư|HϢ^v]䠾9_xo?ě7aYɲiש_߿/_|nJi)a_(R£ӫ& l\K<5;޸yd^H%w/}ňFfvnG1rp!g%iDD,dK6%Уy2+o"DsVjQGl\0:4 hD曈i!\881I(9;kS 8%cZ]!ֆ[ezS2Zc! @ҕح/ ǔ3NԜ8/B3ζq~<.?C!\)X|!EA $%7OnݞN{Fi곴{ڍsWR XW>b40jkKo-Ӑr,dJj嗀˱sˍ 1'*{zn,)mb4-A[\Ly '7 ?2썟cIy W}Ͻe :::::::>> V k w;1f2n i 3 _х/}I\8)2;.r|.vw0m`-^BLMuR"Un0v~ 5UcrՉy:ÏKCoD'6Hx6\qؾ&< m;Y_?Bu<8ŹZy*a`fJNWj˕-fE#ew,Fڣ4[IV fα 䤈7""F[ܴΑlXّx K4䅠evK}K笽,Y9{F)uhUL&۴s^_U+fd%D_~N̼]r}f=/{NT@}O=|۸|, w NklX.-?7_ͥ][!$w+SyLs#ws OW ¯;ix qGo3%b 9'H!cy\RI I1>0b/^s §۳7crJ ,4\5!dQKTrIumo?O-giH´tcw6V1ت[Xa WllkI2<-?xRm)YJ`TVSw8c:X°Wa˼ڻ)^6,/6_q])cOUionh4roœ?OGݥ'jw+Wknw5`GGGGGNJ)dƞ-AuN|fg6]TPhp8E?ٟ Æ{<1%6a(MoCu*N'#N"~ncեX9|ۼ0yJ1!NH)ZJKwEZk2ŔxU/8:9W޶H)QRK`ZQɼJ,amaٟ+֨JrJ%RbWjR1Ew䤋Eֵq99`&bA,V'E'UZVxfUpFMc,h\ Kx[ BklGGGGG@՛hx?!SoO&V}_>#utttttt|d]3XDV)WD^G).$t)Xj:U*DM"kIdVB;R%3ˆǜN&)"tH١u7(EJBLFrrfv|!S&AN'n⥻p IiUU1V\ܕ9ۖ*ٌR-C-H-cI4Gkk~?jpYbsVQ}}ړB*Ayr"~yN]Uզ B֭jV%ZjΎ#7+)[px\-qö*֢[v]-m/8 6_sy-QC(ZfKVgR+{m]~\3s`GGGGGAko%/hÏwSIE1 (,-|rs݄lz@c•^/[֬ o3%7rO9'; ~@Z.Z.ЕnVf1vEʸ+# bn]Me.s Җ@pݨ'ޑSDI)8 'DD_a0~`E -Y[~=Q^ȃA)?)Em*j_q4\'DsΆ};5| ?e{FsGGGGGGG[: J\s!y{vFHOqdL*МpSH%6!T+e)e 11E U qG'&ЙӵoAlb&7\@҈($@Yd# cdͲ< O(8l."d?VBZf`@8Ue7p{!veshy kjn* IDAT̵z H.Nq /d17TJ=U_xc!Xo=^0mvݞ_Zj%~sʰ.̻UyW%؄+jȚ]X] qWYlsJ*5Oi^ٹKpm51ЖTzZ*l%HBZ S\"^F9 j~[],d^[Va}B6`Uԑ|>?NXh IoQw5{.`GGGGG sҋqKAޠpDJq)ƁKD!er "Fe{7dcJj3Y3HJ 2T,V]u[ //_!Rq f=oUM6Cj3ej͕=j#ܪ&\[}+R6b|+LZaKSVx?,WW*Saֽx4d6 7FE!YEEH'jc([JJVv#p5Ǵ6*Ki~kio% *7ڹ"wo.g}9@>%;257py"n #)F)WH/C@\ĵi!"{+j3U-h\:W<3:<.ll\U¸a7͐fd*xgڀ!jsn,MKknIGc;DW4Y^VnE|q.06R%nܼJf $TCȚLyq)D˭E8oztR !\٭4D Ԙ˖.+ Egadrp)*Ԑq-'XUoT-|2Rȡ9|m&+E"ks!\vNVV #Lr:ݴK1.*Ŭa{w vf9BAmO%EY zAfsZ찐UeYoլPdv#! $ȚoRx„:n," 9<:W.r|1wu'/zy6G|Xv';Nob=|sܼzg1 G厴.*ec&5ޣQ9~1{/,kx{4fLcYI9+qy32 nJ$gA F8#,&͸d`K\1)HqkN<2N q$FoE4m͈ FHPsPŞC!88>x')']DL'h2ͧdM8>bEH92L@"9Qj_b܄r Aܭ\2gq9H9BSZb<άX#r!Λ ;rw:(%msyj-VJC/ay9yaw[=RҦ^k"Ym7<]Ϋh2屵9^ԕ_SK?>.e,ىz(.բ2BUXZ0_~U٢tttttt<>Q'"{xC|ʿc"˗.s _BY.qdz~|>ȃpk7//k]<{j?D_kE/Qwttttt|>tT9GVav{ 'ٞ<9ƣZN87)E=YXc٪*s@6Z񣑉Ժ#RƍZߓpac)͵J֩lr&x+disDِZ!seY$GPy)!yZʩe;2R༰=e4Řޝi{V#m^N5CHtI^U=ڕY{5opWZ~P7o>'[>2[lާwg;ن-/yKx_}|3yg=[6 k>G$m+nQݝ8㽿^>{o~Û99L{p >8:oo%K#+abJ lnX& H@w8dqZTV(1h}_wEYcdGXfy!b˿#Òw7C5 -BF ġRm.#Nɪ$CpۛΠuGSp☦3Dwź@UJѭs*,$_HEKv_R,܎';TE'*ޢVr6R1 Dq^0ҴtUxZa~lRS?i9u;PIY~sxU xp}ᾞ q.ae~bO%Ͱ;A/ۙCuC&>o| z2--ۓUqڛ- ?F_yW.\3w9/nhpiċH)Se \|yG] d7fL@ދ)0lFbȥ f VQ+WlObr$M72Xs<ɶM?e| ' GfC#xLb/x\Qq4rS3N\@6p-/+diR69~YwSZh!EiNB$iXNlcH}Y͒VqkEgea=D% g4 =@54P#h¹ aa5K@ 1=H"g bL)q%9djR/SC WK.Ctm m_{0RsĠXSIEjXaߓY{EgR+ه5ǰYjodF)sz\Y{~=9zbڏu$w5)۳-W~Wruņǘ_'#5R(rŴ88<@<iP>} ѕ#~&q2c:_c:FߠIيJ/}*HQ 8Uo%,.֎c*ǡ1h<#97a{v8LP'6q@5 MvCbAgHc9.yY'a*sZ<!xbL,淬 _Z>#^uXJmQw9|9;ްdr^ R02O6Fh՜>z89o@;oŐ|/__ŕS6 J{v;{Qb}9/u+|ˋdksTEGrN8}WWOM'`2O Æ8oK'3_i)E |LkV>d')/m9q )8"8 8vZ{+&+"s)0NB\&' RWjDWIG2#s:#;AV-R88uhgO?m?o|KSǪsA98:sGGGGGS >o!LZbgtwJf lH9D|@Bdp♧3y[\!ooWw";i2R>2/75ċ9[SgCQӇ-?,-Hiv޸48\@B`4m 㱵ҳ ݴuH'#.7U{~V$ńn1+).֡!:8  qJ#ŊkB;%cklŎ#" ͥ$mM7l(լ$:+1a#=VBa?}jӀK`Ky*db%ۗ Y(MtVcob#2z,-q1.Ԛڪ"lUu?!{u`j`w{'Ӊ[[^m*!m3\i!1kr~ι=/E)d3vttttt[k {ٌ!7aum\F%K6{B VഴOʢujE+X[rv㨏_j3Vvlf-~?-U9HcwR>_0RTbeb^P\2B[rmU\gǐo5#GP5 ?lb<oj^M b+yeX1r+O׏/bHʏ}}=)>)F9qQfD'JJ~`䓞~; nN&Yp('7o G͓. 蚑1ͪk% \gJ[aN%NMv*Yn+'DF\|cwUtEkf 7R(wL3q cDFb,ndb7$dr)9f`v_Zi,/gkT6 0800O[ٍ%DV)t=$#K{nUS[IM*Z{mYq3_@ˋm]%bرD>?Ow[2T-\d$Tқu8[I2Y^m1B14DZ3)f1'84vzMe1w`GGGGS|׃|#ٵXΙ0NorK|뾎Ub=mI!NUUq:c.\?am-nH5ebߕypF]!hwĘ )q><;Fg(ZdIbx4_!0om*Vf8=T#2@0x6q$Ι68-ޕ~x/s$3|E}qi!RrsF-)^Me7IwaEU׋ҹa:הEFeW޼ng2R=EE&Ѽ٥b-bN{sCe-Eu_qYjN}L}x;sBCݚyoũJHVf5G)~{yOY>+,~vܾF::p%^0nr\ϱwttttx$ /K/{`GGGGS OyR  ؝|%|CAH`* 9cs 2BдE| dyJހ$FRΈSbܖRU#S1$)_& qubQ Y̐s"xip xfZo q$'Yl-0. Z5m$dLcx|0YL0/&v/UgM' m%楨ۖ4 o5/jjWLՕǭƶf-d歮gLm?(`./)kZU5wQi[+]LR Rxڜzm s%9agsyGGGGG''"<̎QI'w ,s\;{6oCJ"'D9yG"<γlNZ6MO@MY3pOV,r&Lwi Pd`g~#|Ï)&R?Kd1~S2\eWXaXx,WHPb.NFx[<VΈBuĴ-W-šWZ-9Nib3*i(zK0~|O|3ϼ7o'ΑgL#x"D^]#Ð!%|Fd7Kx4}hMvB#ϸ|O~+t6Y'Muʛͼ߿x*ZvnL !IGҐ"9O8wHDG*oȶ&L43&Ȟ{OVV~B5ㄈcmhR7AJAL1@Y_8o@q*@$d!Q!Hy)gHL)Nw8K\+occ\21w8#ˀJFԔv-GE#12Oc%\ٵdy`'f,OcfatȣJ)7CX%XWNITL|* lyi%-6v=b !,_"jʒ?X٪ca0µ>n][Q|;?ؤ[iG*r4FUIuu!3HqxAD؞ny<nZj.9 ~ ķ9;9ygsjOdЗ`{_c<Ѥ{DyμtoVvttttEc$WHge T`U/a.$/ej9v9s+#b{`Ҳ k3!!drZ-ZDdʡ-5n;nE#"$,*p, T, SK&E*fH,2$;io ks.%3b瞳Ϛ=yg}H̤_1J\H(Cd5!Y<(Zi WҪRNYq:P]5#XgP$[݄|3M-(ױ=|ߢbuiE)"W$JYf̘1cƌ (ԇo0߸BN1!D~r|p'~uкoprLʢ>oy^1cƌ數cKXY%/(+ " =>[Kq9C;?&vK z$V q+j3U.bL6WOtm~ ֐jB%^J)֦y: @T j٧0##D<Kg/h6MiS&qIZBjܕ%*KGG^ǺLBu D:pȺ>.qn1XUYV{V !ɑu&+CrC4I)B}U!BuI9yE$= #՛]sP* IH(#UZ"ԊfdWoFlŚ:% C1FbFM}x~RaٖL`u_Ob,o!M~NSo*a=.!Pk3Y *mGD`rg̘1cƌs7ޚ~iIϨA,Kz䖊s~ww,W}~ zOH-_LºmX?\}osܹYO[x+_jVΘ1cƌ5 Ng*,=1VQê"jQ2fAŠ'wk>CL5(oݒAs"5ɕxK-b1VsD*Ku*C2Lb {bwL\ 4CڪbdE+$7uJj&>ZXn\3x\LK\"p8khڎmR8Z d GIMnI(IC=1A0s~Si.v[kJ]țNSe5p1gjz8Xa5BJRQ-So*=ɧ B*B~MDTwsj@IzԹJl_42'أߠt5s @sΏE{ IBQB+g̘1cƌﶷƟTuߴH,7wLɫS6 xsp |B6,T;m;: h?|*U`q5Q7r}f̘1cƌ~7\<;t,,ʖw<)7ϳaʹ}BHjs/{?rO$bj\#I<4y&rށ(-̤VݏK,cK [q kАGbdIi`;5cppI;9>^$.1=6ax Eac=1`Z*)6Nohuj|^b,#9BX&/dMCfJ; !T?1EPk6^6FAv|.Б5Jլ+j-dmafԾ2 crQo(")\m6Z`xX*J_o̞6# Djzs(awϥ&'(svLdcqZ1cƌ{_~@F *V~5ɿ1vO{_mJf4gydy_Olg|* C6!&>?3f̘1o ˟7=xW<^kZbʳw_|铟ŽMȼG4ivlpyٲ2#SR91IY5JӴx҇bKP%ƞ(!%e_SAFN rbloh~7hvЯp) M.r&el %EB5 wʎB!C91$)0ٌ="]~SA!ceЎ;Nm%ږXklBX PKM>+;dۀc CIW˹ɢ]E <ƪ`&կOR౷dK@4cƌ3fuCYLmcXJMU)(Vɏ_y{xwsgՅ KŽw˽>y{>g.Z''ExFHyTkuRb$8#1m3.e<E'BN3f̘1,wX3gi ͭ&&l9Cd//Jv hgOm$7v@;ȟ~{xz??sEihX,.wwֻ1ZZ.|{_|r'*YMDXl.#9 Y8C:X^^x'|33f̘qA~'}ʟ)k-[_Q|ZPcp"1>V}#y'AF \(›H>s`Cr~h1S^ZBFC_6Z%hs-E5[4B4k<[젒M<_՚CMR +}$bhJA 'Ff3q0 Zw+$Zݟ񉿉}ӔB.fj2_$xfG-O8dSb!%_Á#WÎ, AԼR`Qg5V5xNcnɻ3&hy@l:KmȩWCN?ib&ے. J򯐚9j@Tpe)xJ敶HΐXGfAS_.:R1*SKQ\Hk}n6`;tWvƌ3fI~|-17iF0aYx=~ۻCr;oy6W_YCy2r3o"klzojӽ;lX,1 J\rTl:7hr$-?} 1pc̸Q],{1,?ll"j6iYNd^ES_갚 t]8V kYP&vX1/ 1W-a2ˠLVRB@Y6dR͌HQ;U:"TcZ裴ҕ{m& H7U-Y<݈dg̘1cƙF}oET&m=I]zcc<<<``1VKvBx[-\9`6"-<D$dLh>ny w}:IGZR(wy?xNm_Dn}37cƌ3<_6-M!:p!]aW"ֳZ1 b#!<12Ŗ\kxMg.Y^"D@q#ZGw$vhL#TESˮ8zAR`qI|N;"BȜ`U?U"kI_&ݬuUgyWOd(Ms``Tn' 1KلڎUkMf\",G=H 'FE$qSd#݄#+dҔ;JR )5d#u&;|' DJEi-*3< 'ԁ|Lb<X4vl#D9k^9]dMDj9fI2N%RB$UcMfϸA؛˾BVm&qD+,Yǭ3f̘1c1%'V$%C;W!r拼M\Mpko?{{E❿Ni& Ş5 lExjeV{3$јě87## cI7ƘHCp4MUVX_GXJB8AwTBxk,q:W ꯰WU܈,ǗSR-Lec2hZqZa7]eD(emJX)1T/ڃ%y^#0{+,Cp!olCB IDATsCNHǢe/A8 V @|c(owwV҅0-_/&ۅg̘1cƌ3;@矉ӯZId}ѳll>oKR+27m>rsˏƒzOIO~>{NϟO=-?~ 7k.~/BK%_tb?0_XUu}3f̘1cEpD{5}㲻0ƈuÐ)䞀~6 M 1bb%ǫMj;(q3K4"%B DD­XK *@%`VuDkTK4 #Y!Yh!5X5Y$p4YY '5%5'aH_;RjP3yiTj-M۲Vb8bZU&`ZY`qW)VňIV{rcX! V`BmӌgfDEc$5jph81@^òw!]VpfB s zEXr TvݢfL B?8kݒg/*_Q*ઢx*`$1ծ^R23W r`Ϙ1cƌgVɂZ)ʿc+Jn4|4Wv/xe|\zہs;#7[~1-1Sݣb vMxoo÷Ԣ#!a?tU՗ף2Píou~g̘1cƙ5 !D4XQS:QBUZTTV1a}F14  ~E%S% O5g .u4$bl* 9cJ [eARy%4ĘlQ"l`ny.&^A }چԆ,墓74ib};BQ8,fB%GYMm`ɱmSSThǘMB0OWbdr3ǗxhM/j5mf֓BQIH!`lJ;N)7QT^!8T^*B5,* n$@FD%#RNGdV/TFpX Y7(B2K"`C%BNP5500ΧCijtP+{> U˸λEk }_3f̘q&WK` /JU9;|s_SlmMrWNUZ_𮷼 {V{B(KKG>hbcDb_KM~_/U;̣Q2zSs2d-\|E~~1cƌg;{`ag7l6 }0.RxGjM6y> "nE.kj쇵rUV\$,?It$=}X51鏰Vz;Xb*hlBLjEg=}t4Ky{7 xv/9^݋z=0` bAU9'"$SD'6D9o:j6%f.!f16O@u6ٍC;hKK.z R@la#`gFmIVȿr… 4FSHah8‘LRbaITt"X8y,)^r'!lr^F17\X$Kq,SddA 4UG%):LQ'ܓY Wgk=I]z׿s̕kVb>y~4?Xͺx2p|>\-664o7$+2 яsans$t{ƌ3fY<7r!19Zb@b[k5nm*Xb]L ˸ X#B/CVj6i-` acm5=}8*/AqkZŨ\}ll\qt]L-FQhPi*qYDBRD^"ffk Ie*Ɋ"kW2Kfs5@$)1QfYD$N\,*⹒WbB4MSg'30RFԦے%'Q"ѐ!JBFp2=XbQF"5[㓃j|I Hd:7Z7ՍJUޕXHαuz>!LB4]2\ֱyh -N< /v3ԇd?3f̘1⎿̒wmozo8i~a5Vݗҋ O>k;pYPUe!߽}b,a)x O{8^cs5w3f8x7Ҹ\āŋX 1H(Bc]RӠBТlK~o]uDXעaWT<8oQ}Xu@nOe* Jε܊ajs,Lt%-@\l=c1j_mq&7A)i#G =>DCr'+q8Qr'5s&md`RDuυ 1{|Lef́R D+S[J^DEFS3RLQ8Z1Q?Ǒge[&LjbNРMG8c((usMj%e$BSXe*ǹBQ\& c$ Y8ؕq{8lіI;`)-q\/kSwaD 1cƌ3uw܍ŖdP$1xswe|?S\J!Ooj~ ͝MMϢM ]vMRB}tn~g̘1cƙq'*:/+w=DPx0-]6I!b.>(EKz./I$Qw @l]MЯ'%R_%hxzɅ &a"rRl,i&(AWX {5ĨV^$q2%ЭƱK(GWf"]{'ϧ&g8gΘ1cƌ3{?q/w~N1Cn'Tvy=T;~XWENH>QE˥{.׾Hƒgcƌ3$XLJ>1BZ TPfH5#p(p5 Qə((ZqF@Wn 0aTUW "=YT$ؔ'8ET49z\=OuÊ>vĸf]"}+X~ Ap~fA8OX7s7n=%z*Ď{vobkۡ[XfC Wr50qM"Q\j-.j<=%k{ee:[ AjT"bej_{4[R`I{v N 7m뛼B[Iא+ ׺z t,9Ь?LΘ1cƌ㩃|>/{>g":ہsɢZv`GGGރDI #"ESȶpM9%qu3f̘q&a]4~H"%,N BXkBdu&Ǧ }X g,ؔ 8Xm@"kVxKXc0Cu8LQ6{`EY6eR82Mb+ Gzy|{T Ϙ1cƌg W~ʔmqpoo'dkgkL>R2lAEY,|ƌ3fIc#F9B ]ߣfn0jƓ|roiE5 ڣp! 1T5 (c8jFB$+1.441#, jko[] jQchۦrV,74M7c4eY9Gb9LP簋sfqSVᘾ•xI(Bd8Z=Xo6*XSP+JSD;vnbs[Od1qh 9:OaRc(tڞ;.]Y//#^uRqZ Wl.D3!!y< 4r&gYu7&sx(_1Z\=؆kXJ<1͎$$hsvZO*9cƌ3fM;kI߾jo}auX;/mo`F*BtBeBgvucÓ䪶|k(3f8  >0%3/)"CbE)Y`*|uƃscBsM*D+bĂ &7-@ aBŸMHKakQ 5A b쿢Qiۍ0Ub`dΦf=)ХrR1br'q/Ib]1D8zb e4s5&Qݬqf:X.1ibaԨ6@郢gT"A7k#Llm%%|c Ʉ֚uA8FxVH9zp**Tnx"Æ\.bMAXI!+p i9(uc"1ߘ'sxYTVOQ;!iW[>8-8%-ӵcd "UXlۃT3f̘qqߝUl{pps㹼M|Dmߓ Ȳ>yͳoR3S\~g̘1cل*&!ɱh-5_ X|iۦKZu=5)ɪ3 oaXkvd(NC@cR'AUqM8` Un\bCqE&T~kfAY$f1&L"8A}Y嚖apF]5-d#5-..b._66mT7i fvkwPm*ׅ9$99K^7sx IDAT^k&1DB_SG7APu}GZ 㷾G-!%/.צ&-0%{υCa,) LeUw< 6b5"!ڣLNb*&DJ0>ױm|ABPs_E&iy$c̟ӡVRcP1m?EXKLM+S3f̘qqxpb-ysx^nN:zjNx3fcځ%<ȥeSdPv:ʈDEw|2mQX7,$&~ #b6|1cƌg$$ 1=$H7H"iƈ5ƀĈ!Fb~1QZ!uX%%A>5ǐ瑈ƘӔ뇂k$2 xl4`\(IEh#W4&kq lGiLެf[uCP}Eq9OQ]4D,:BVEZ5&i/l2Sf"F3N8iG=FN3y9tN'Q!40D1|l&F ֺJ@B}VF꼡 'j:PBrRo3A! LׇRt>lѻŷ1ˠZG+v]T.c>|mi#5h R\c^/$ κ_3f̘q&aPYÕWxw|Ow^)'xz4J@r>>y^ ߟ{E}^KX+^Lf]?( )Iٍ |Ղ0t'!4=$u{O=:k(Q8G%!o%n-m2g#;[ FYeZἯ}Q#6X,Dy-$$5P[fR"URcɷيjuk2AVRafTs%XɪB&PMV4}bFV$4aJќW°*X9&<&HDFL9G- ՐFWI;应msYD1g9[gݖ6(&(}#~a1cƌ3 3I9FZ}3ې^0\ ?^}Hj vn%O([6m۞R$8]l|h%[|~mx6j>΅~ ]=x=wк6a2cƌ3&bA߃ML4 hpB*뫵Ca ш`;A5LtI2>$!5@2soE 1 X$D}q&cF=BmEؼ_T׈i𹸭>8?tKkzTMGD̎,;[+^_#c1cƌ3"El,1dǶ-Q`%m6E 0GNu3gi< hS FlCրx58kDb耈q`zU%g-7bm6,8cqStNk2Hx:fâFB:_!Y*w"&]̈́3%,:{DƐiP K`m1]8·;T0r20X(ݪC 4ލܹg{`Һ=Z{{0Jk% 43#2f"3qȈbdRT&S53N0QD!dHH~/瞳z7zk}۠j0_7k_mCɤP#X:Z[T\#T}#Φa{d/^6Oᚣ7vCnCM8Y5l.$d֦\PZp|,Gf~nH7Wo* Ⱥw>jyL}{ '%s9ָ8GVXbŊ; ﹜3kp4aj$M $ 1p~<_;̻—!g8eZܔW@M Xߣ'''s5oW,bXd)UW˯9.]&_bŊw$a &GheUpV,'Z%bJthkyJim?DC; Y - Tx wepDĄϲb_V)Vf)uӁ"ƑFCQmˢ $ K H-+ )E -Y"Y?'¬4s`B:;yȍO1R b̌Iv&yn3V1eJJ]U֜:UY*ʼ?y3IGz^Qw͗RWE|8fvNM?_ߜ؛[XJ7gU~PQR\ϩy9/MIQ7<֠Mm). Wy{"7qn/UhvLZvŊ+Vܑ+Z+2GgJ$(KZ<@|{n[{j}oEWf!ʐn$Y '8 4_efrqMw.\Ь;=t+VX⎄BLEUxiwΑ8`q* 8EҎ0t4(o(36u8CeD0+Ʃt*KC$nCJawN-c(L8H\bf#HVy߁9R xM7WIװ: :oқ'ňs\:h:G9*OaN=KH:EMԮ*j0DZJsArr\[r5R:Id<q͂,M}mՁeb[-[ 9>9?%&=[ .x^C]ߵ7wĻ8pmxO_O+VXqG"fB0<b#aNL8-lˤ`|iZʄ9\-O-UMCC@ ĸ#tHwHaHfnވpC)ڀܾ;!KSlNϮqX %SEd+m-*BDP<7ktԖRhys.ϕmMy&͎߭9іQ{%>YͯC]e{ob}_l xVXbŊPqr天y͸Gy~ANzy=/?WcN.\?eD<+Cx"۹QO %F 9|WoꗹprᖛV{_|zXbŊ;1E0JX pP?bqQ7ba$XyjHH911I! N!8Ux 1&==J2Edۖks{mJ {X"/1-HƍOmD#C8#J0fs bl/rvc5f 1fto9RAOwn!:/ 'E5r0^džGHq)8\Jn)3B@+%$)gfCsrvtLzD;r dRıIJBUI5v6D^VKm%B2M!3RL6%w쪤rfV4l!E&D\mm8^1*?Ǿ\99xOreŊ+Vqp"8//yt+3 .sa7:Y+[M}2ȥ˗x?|7osv,ہ9OTl7n7=?N.,2 NO{|Ŋ+Vܑ_]O<v=Ac?u]_#:A{pFG@ls Jv02ψ&xEc?iyLeSuIBp)!,\vَܢKTF#<\cc7:YB{` !8df%dLqDoHբDQ[bxw:\{34~)Zcq\q6M.Q]$)EqB+aWL*Y+'X*xIÉcٷ&3+ږV,ےU5oI. "e+7aV[WQmLYlaC~.Ʌ&LTB/4Kܷs@M #1$>Ŷ][m9k_$pNrQ2\[uY jvŊ+VܑxF=. §?Z}bj9/z}}v;DN's;Y2#"8x//̹!O{`?YUyW?_<.yD{&ۑ1xzXbŊ;B.x`6 t! 권5R8jA-1B ;vGW&vX4nfs]#!Ybʤ tsrN2&fwP8J4Z3cNTуcm.Tx .;UgjP"J\bQE0! ?g<ª 0'''O< #z$߬ {RJ@CWyџŋ6י' bŊ+Hx_tyfhPǜ OAQS-h1b O&Ml;G!nNpe\wnsK;a eVq5j RxD0s8A}&,@9'0qTL )ߓ6Qq!BtɹeDL֙eZ/E3)K*+EMVRmL輌3:y[L\d`梓) qi?DsIJ.k'Z;lL5wCȂ@ۆк$A[OY&+kG7sUJN'-)ޥP%+$+VX+ml!u|꣟ʭOc]EuBbNwEf}|Oթ ؁\oo~Xؚ@_bŊw$jgd6gŠEr^2!l/=D:͖1C9SwC-h@+uxIȜWK8b/+ardz#HPqJ5ݦcf<,*ҡZtYCw~|5Wg-51 X~<]#Xn-FC p7zÜ1nuv}pTG%Yi.٢gbB޹ě8SBنZ,:fNy!,‰Y{T1D٬ F6Z(Z+雝$\QIXPM=L*#H`r"!d[l=vn\\ ^LUM'iDV2&˜ܹ`FD\kǝ?+vYSE[\QK@,z3Wybi6`yĘ*ۜ 'RmR Y:)0ˌo)1Y%@et"sb FLrsf3Si$eŊ+VSqsՏ_%gUgg|/k<skky  IDAT\]>ځ?۶B͎rsYO+VXqG"&cq$?K0YkvCK^&)Ւnc%.쫅PKn8!Qw,tBp'u\Ǒ4M.P2CE̢KJ|7N>s,}F:BBip*J+BDr`0Ŋ4  82+2:Lm1#Z,DCq[/Vi"6oBZ\Iy#Ya4KFV.ﵭKT(MXKX|*Ģ/֟͋B6jNuxתK)eayj;WU%\$[Ήɩ189/y`xV2VwjfW%fS[9. ڜ|Wb<$ѦLʬ]hŊ+Vozg qϫT8q:z"c^0;Dzځ?ۑBH<Ϣ bŊ+L0FU4]5`T2 JjiFfEјVꪺnG6Eծ1+H9,bړ7Ru$ Dܶ Uܘ1XnKdd=0."="9]ULFv)! `u[1!l.!"Lcl ɨXeqJY*mnWEIa -q"{ݑcZ21_¹\BH[w- pYaR<`mIe' 75N4x2׻ѹ#2l%%{-_srȌ5Sn_-g-'^fh˩vڜ˗FpXIB\(ޕHM1emqvvZ$1_bŊ+T<>3Abh\|~)W]m]gK>5x^@Dځ?׶KQI_^bŊw.Zt[!RVYfn,=lqeSqu}J}ɬDby%&2;AҀIQ8w:B0~3u.%v7YnM&nClSd0~s`IQ~{$=cr?jOPq@dYtdQ!H1Nx˶wNtezHfb#BSY!sk3p-LADoٖR2n:8կɚZ:bt1x5uYs"y~G68Z)G#f'ۜa֚Mu?[ό 꽟iηx(c2LV[xN6eL> Ov"SEPUie%{Q;S#&YQ1XbŊw"N{?xy{_{O'Joo6'}KAIc5 [ ϶smՎ\C}9XbŊ;fv0/N&[h,` !݂=)fqfs~^{o˩R*J?f!}?T"*BX~q뉂Q]*l6+:2㘜τYuG\o!)nȖd5Z]޶ 粰,HJ#r|IJ)ߥg(7Qu oKH^A堿\Dweǰ8DqhsTk<;n6Te؉bI'ŧZ2"# "䩐r U]FqÊtz~de/ؘ,. J3.Δv{D%MoQTLC~>nY3 Ґ*Rm;$De(nbŊ+Vij,.^}k\gοDɹr︗vC |bNݦ/{!͡sm]Y9\Y{zbXbŊ;BH:lɌbg!6^(Ax0ojq^wccJ$l O=Vb,.H(v0ހ g)]҈LAb냽(11o? ! a˂*u&s.zEe!4X{RO"\qWr !fbUÕeԓswa9c7 8ҹab\P'l7Q=pogIg֍ijb[jfFחsUPsBٛbchs]ގTW);)3T띫xa닅$i{|.iyrݎl_f͏̖0 8'VR^?:vdŊ+Vܹ3{7yW1Dy.OH'J b[^͟ux>.Hϗpu;)//b6$^}<x{k~qۂB`^\+VXqǢfWB*H*ysYVH_LK=-!xjm }RB37$BW./_y!/)J|cQΥ-}:Y㉀MMW.<ގ(j-q)8OWfux-APəJIJ\~1L/{Z\WlǫwŊ+Vܹ>Mהduć>TnOԞ;:GWz#w?nyr%Y2UGy}7o7oyuKǼG^2nS;([CC;B\榰:ق)DSm6  NwKWQ=Q7sWgJ)ϱ8; sbY7-ܱIs,bJ-myi֚0d6ٟYaEe_XyXo݇~YsbU)Ġ4^nfa_ha*PJm`%ZO&* ˼#d!rMeZ܊SJ8qxO|w+Vcm:g}O]8⋾ZcUɯjyK_>~AVƢ/ܺOuwG􌻑|}9/meF9%_%_/g{m%bs%`ˇ~C|wwqto_gg9x ?ZpvQ_ RRQk/r%VXb})SY?b7GAB}XĘ^ƯP"?u ; n1Hdppzœga~DZN `d;o'wiu,]GP`eWc8C 0 6)ʀZ@mD%B$`vR8k20Ii@$%`gز(,=i-6{y[f6[TU?]bŊw$u\ 0[.7l7X?Wp{JOW|WprC\}jێW>߷FSJ!p~z+y?OLq:lk^·>-$al[~U>o6?c]ۯa(z CQg}᳞ {Ŋ+Vm31fDɢ"Ժ;Dr%8u97DB9?h-uHș]Mţ#I/MKNv߱4CNAJ&$*xF7ة#K E"1qHlc, b%kl7P;栿Ht'l・#$m 2␹3٠zF,3r^!icӲ c:sb.#Rsp5`u]. ~xb2XJXbq1Un>̬DVWs9yP=SI/`d7}aF7f<5SmV9r"}|*=[2SϪF S UB[%^'ַ_@g$f]bŊw4n<|~?I"ш:>uSok\|{"eB7C8==em/7--$O!~s8WWڿZ/4msk7/y' p0 C`{ewsgrS޼-SU4)9|+VXٝᚳsj&m`da'Ȱ\* e=cjR0qg)!$Yw%ͤYãg/N )k\͇qc6ٮY 13|,y6 1#ƈwgzC$.RbD&%0=L_H5#q*35Q>~2͒YiiE0(OYVRI*.@wxb5جXs꫒j1Y%2+Uoq6R.0 S#&&T23m"nte?tƐJOCOEΒ[f\3 @-K]wݿ^2Ob;yO%Ji7Y'@&(!gKxM`}/+-<êü[vŊ+Vܱ-~ v{ <30\<:6M !ϼ}>^/wwp-ZmvD]%o .d_VF 2)RŬU[}R93cjsWi6 !Bbv*",q1xMj=m\ɗArf0uusk||' ]sH^w Wۜ>,A[bRI~c?kiΩ^Ji@o*@:RtMw Oz\Bnu៚+X{R XpNIiNh߲+VXE%>^}>|n=\Z9?=_r#ot "L)~>O__7My3yK__lss//x,hWO?=gɥb= xȿy^_ G{/җ<+VX.tq*X]1eAx#H7n%n®Ͳ {OiO,"!f?)>n"& ]B57I(>I"!a]/G8 "~nG#*7>Id5ї8^n6ӈp~sYVrR9ɹI!\O()G\׮~l0M:66W,EbC(L&@YɽqH!i(:ahNOUewk~kC)1Za0Oɂk& bu*F๽F|oJ*qU" XEg [t+V[zד-YInU4η 9_roqy! -KT9?D\-ѷhf| 4[D2^bŊ+Vܹ*|Kx__!xvm.Lp{W櫈!"NnQ=ߴ3kH(n|#'Cqpܖp{Y[.}3GYG#5q~m[:^/%_[ VXbŊ;" # x0I9y02RԪ= ̠X`]w¦7p$B q 1 BFERʳ4 #a!kqn09;{w) LD"qlx)mg%nb'hh<~OCNTRz ÄsY9˜NfI18ˤ +ɞ8;0rJU9J3!dűcVx. 3Y)][ 8]`eV h-k_u4Y}^'rެYI(mIawwšW-2k孹t[shf,g%w jΊ@ھNͩue⼄eXbŊUQI5߹\釹q搒 vQ:tm5[v&k;T!rx7oVS11[HcP٬䖛u)&^W'+Vx ~GH1gKqCL10- Cq<vpqt YToZ 45õشit -DJ^p]H9B<'0`@BLsiw.g*a&FLQ9_/%0,Y)j) a;"&A#@68".o$r[s/}O kOF*d[Z+5S5 -!mv)[3|]y'DSeOCx IDATB(ޕS;Δ{8GU͋7j{Y15kcoܛ󈰷_w8γ!z?.ycUR:#t3#߲+VX)mG߅XqW^u|ZN+v nߣف}/dr~#')RV<ϝJ3r+-iPB LϣXEy7rޭXbŊw:eY;0- LD qk,r ud D] 1^c]%CuBl0(Br=zTqCD{7 fۣ!Y@51mp}Бp되rLOsxwjRtH.> 10wcTڑKIeRy֔6+JQAGvs_@$ RHGHȳFR=VDZ19DBñ@1ascPDď& 5o"mޮw ={ܴ7,ywuF՟eVkϺެ(Ɍ,ȸp [^7'+'lc^}Y(3?.QfBJCy/'˲%lZWqIim^bŊOpwㇾxRo}JXbŊ RK;"8O,ﺮq*͑"N(w0d $ 5'qWd pqM|wts0]CҎ$=ns4pe$1;&::+s+NѾY9W`darJJ/'`X)$1B8%5O<^zO*sB2P=B[:dK6 bª(XJI#۠]\D" ztAeeـEHmAoRnX<:0%Yvz_$v]bŊO)__$y܄ݼ,`O_w36)$`kεp Z~mhk[f뿜~}k+Vxʡ1~ہzwĔ 34$H )$5bM )E0&*H)l7XTN!2 DT;Drӭ'˪.,N}./i] ֢*gB(CPU02aL{?@uܠ9NqG 1s=HY(x5 ' ]8 ᔊSRB3gW1b@=bf܎nkVu$#R&DNǿڠJJWXbS :uqI|xr''ίN>OŊr'}cyo#f7gm󛰏˼߰7SXbŊO9EmQQr(),|<]&씴;%3Dq)"Ä4]!;Kӫ4fҪc\ȕ9)"t #q8r۰hJ+%+1%Prlnw9*uKsY(%fEdoVlJ"NHj10g82a⩊ BnޝHOIr9,ńw=))?|>)gd7moUs7E6d.-ԩ+66 PAڳ&-VIe'@SXA7W d+YbŊ+03N𺷼G8? +p1G.>4 x'v+;'~¯l_{qup-j]bŊOIcB'I8St6;BlN;\<}z4p4Ł2iXܑ 8$W%]Qa\`44"")sc6} À:ڛ%8Tpnl|GN?`oq3&gB粘Jɨ\\1X 2#jV{pȪ iAED}M^DhͷgNͿg5U: ÛJ^~~l1U7l5I s-L~h. ΥyRNDݼdazb$۷W3֤rاvЭXbŊO%kWee9F?;+p%RL^$w;{^*a&5efț!s;^|2 gfy ?2}zrŊ+VX)9pXl,kvQD0b !B1Lg<8c܅:j%PQ:q37]a)7F1lj a@∦v8b6m;R!jɛ`%;%pNbkS%@cbܱ8#EX'U1jG2#|w緜gv!{fYy{Z{9Ow0  #!q0(H*%)e%bcI.KTREb;R?\*WʒX * +R3Kw>|k7^t#7zקW!270 !Dq^KnMr9Ո+ akVSr  aM)|4üqܿ? m:SlY-8sn0w"%Фg8eq=(E?f=5oGWsX5[w{̛}_WWWW״B9ȯ{3 n1gqwt k2om1 qxu_fs a`{ #DΑ{^ p=nՅ֣<3XX!10G!pQfb8Lj'SBA׉;9Qo&1šTnSEdcR ܺu=j<)!3bM yX$DKEA`cF Z*~Ϋ5vC0m¥.QmgD~KXHG/`&.s/j3,M,TnHY,,5`]Oq-3BS܊MDL=20pթbEK,laN#lWWWWפz}oiOY:U:t>1|_>߾Hsel]m)~"o;o~n[g<,-kZK/Šg i[M[bj-"v;rvv3݉;`8 a?}bcyJ`[Fq gO&V1^³YnrtLT6b ~zIw'$!9+)+b.5JD8'yf FqET6 v0n ti枱v'Lb`C B8[/J=sksx:O F_c9\R1! ӤXӭ~D?V~J ɮs!L9;d,PMsۮZ)6|uZc] KHp= ^hc91ӼdMJϧM< y&ȪD#Y!s] :꼠K7Yoݗt R;r\dUyh ? R di헜rq$ny: <テ3#Ms{0 ^x㏼7ԮM]~~CZރF :T38"&kGPelgbGs͏OBC2n41%!X W1L=ĸCj;O9`9@%RFƉ-npnc+)k,I&v[D)N` CM̆(K;mƍt|ƥ2) ֔n>5 yZ~i6T/ C=I6M>-.QMyC]O\T.=VM{Cqqucj5Ł"Z#Nl n_xXѴZTmʶZg?K^8 n X1JReo]]]]]_*gNwֻ~ o <M|vPJhey?kxvGzJ>?1" /-[m{oWWWW׼6Mކ#nKT3iާqylYc!͆HĨ~ ;M0͚@^fޝ9{v= OnhxHo`ģr 뎱.2=莸Ҍ!5TOmb щ lԻk K!`lr8TS;#&f!q͍Fg gQ&TF"C<ٌbu‚$1lK y5nǼZ{ > ZoyԮFicA{γ[_KAGiqqP*ABn Y6tVo shIFoGĮFxˍ-.qq j!ݬ$vuDDoS8r,Е@4LEXKCsc~_hwٮy("|GO<Ճɧ#tc W}//X/>~!"G5 R[ 汷9 pccoWWWWWp҃u[wu'1mcqƇh1N1='Ei1*pJAeg KABMQp  Op.3ͧHťk> Tf2%]QlD~3Q^}%`e&q`FӘ]pKל~N1[kk2CZ T6I3;!&rӨ{!sYn Cr%2T%Ec:L- N#1o 4pXXSô2_n [zAk1 +6d,IɅ0uR6""5-洝X/\b3sQ,q~n5 F+\r FWCE~y2O :;194XksCu.c",\,פs1X;V H!۱/ 㭿V>֧0sᇐoۣ-0^~[~w;x걧0֤>yM}wWC={w;o!/0 liAJӄw/݇_WWWWWW#;܍۔ԀCP4c.an$ DnqKX2I#1#9 ־P㯸4 -oj#r𥒿.s9xܵpgȐfZ6ǹ^z#̲@fL aqͥ p- -my^!/r%pgdK:wU0lWuMc=: L6{cjK5 tuuuuuk?AR;qzxƌ: ZB maK R ܓQkvSIu`g^Ja%۶ݖ9-K/^&[[%J[ɶ IDAT\ׁ#"Zr&C(k~ݭ/ɡBxѫ_z^1UH;31Ž-{~?~ۻwć?0re4ӖҖzGWWWWWJkERfҌHӜk JS1̊`. 53 2bL&]E#[`曄cp\Լ4pqj2us1w#A#FВ)W]eq6}qyF_bmؘvN}BHQf4Y c6yHXyZ1`uAEY+-r11:R0~)׼0?,b7jj6æ8 JN j)|!"._!hӼ{1fӥl8ͼ?_abVK&5lA`"Mf]75˂m˼d)Uj]eXKd0Kr~MNK\`{Դ~jT?U~o]]x}!+m'Αy->}88>/N ?>28?9q>x?}7y{-f0l6B^\|!*p{]5Zt!n`sb 8'#YLxS2xf?Hn Wqbts607Wh8#S`D gu`åg{،LQaߟu{AS"tH19rAb40]mRX4<%p&cҙ2"i G0}ٷ&Ҙ֝X|w 4M~UW02祥g+JuXLE˲OݰK59BsaGX-ūx))UB†B=qUSWTMsEp[`Ӎ\RdB  l!{ HԹljP7ٌ-˗aP g3S )+/)8 y6[D!r!>#`o?yYkq|[Wzh7b ˃>,TQE7XqK#2N0ZQ1m3zV\+" Ղ_ˬAY9ؒS7#d;Y9R`V1a\^\0l]yN]9. ,/_`aaYi] z똳֯Yj9Pd꺃Kz??C?gO'\>OSEشj4szvhG88>]8{W}ϫx7? GGl7!؟9=9%~c;{N-O9?=g GG cCŸO>/5Zz7;}snNCi_n5CH%b7`9B(qD?zT-@AkB ˨lHƪ"BE4.bA ƥs~ #519D˰C3ƒ#dx&4/;!rOBu.ڢ <`KHbIa!LdšqhrxSrJ2@shqn f!M*cϏ,[ nRum5Ʈn ^V RKڗ]t˰+tLkЗl* 7DS BR!2_]QtRs{auiEXxdq݌#ecm{܈ս)_UV%$}`WWWWWVy?8O| |N;U<ؤxI i C1szl>gfa|#<P~//3X=oŷo~~->~Z#j>\kӆhD.v5m#b5'QE%dsс; cF4So2 Ɨ [ 4'D, jFҔFl1Wdu Ɛ[GRՐ9F\5&'S GVQ? cF\~hJ~?c,ۦaG1lrOˌĆ­ҽwͨ"'3˛ۈtBqMY&V{8bvkzӕ .,}hsluq:Kzn@Y9hfmSաG;jl.gl@qXyk,q߶,ĭa#.hS ``|{@O'ٿֻ~R5, Yyz@}ۺ&(7X[r#Flv΄q5bM8SUs5JYzSzx] gfւ.iKT K")lM2#Ks%N Œ(X.st5Qt^L quc2yD"q"cǀš##SN!+߶vMot' Ӗu%j44-mT76SZ!y,m`;b+r&,b0$>)O*^]xE*P-ȟk_Y[Bv]ޟCP_<Zglc8]]]]]]OGe=ƿF?O>qy4TwTr)v$2 w?nxz5@vuuuuu} 22d&NE4z6Wp ZE%۝RhNZ*+ZPV~]ZH [Q3".n4s[d_Wl x+%"SZJTê.v֥J0ZᕯV\73\3\cTyњ6 6Ǭ\u:.RiWWWWWWSԫy7?KOi_h~8L H{__;g?fL]]]]]]OWn:֨43<]H@rDPc&K\f @؀s6o# 92S8&\ o!se9}7! ;TS]!sӄ:$3g?Oe!88xyFZ+짉l12sTf`ZMuX5bl\J_Hl܆cD=؈avs1E^1r1OCox'?d^i-/6F w?n#o;w"6]]]]]]]yC/2 O5X{zsDgt>n"L-BLʼ?A9nl!BN|| tqdãqb?#NkkLؒNIh.=LN<ĈuVKw*1&e%(8]|ڂOI}D W89 %ꈵi?Ƒ"Xb8g{p/`ed&5aH-4$(ܯQ$g=ht81Fwq@dM<=,b̃ZJ>B+^{" yF-~:͐.d̖+a@;FsCL1-9HS"g㲨,3 V_k" :Z?$K{r.ˬeФ1.;,O+0M4P5ߑ@lQ혊<$[N|}, \NL6[o|?֟ٯw)K⏏.sjS$nx͟y ϕg\tuuuuuu}C |eVsre>͹S%φaH3BjŀрΐK6̚yIn(apLOtF!!Έ ;>~wt˵fs#~MK DO˘a8C⌱i_jFbm'ŹZɑ5%{mLOiG%Fs ѧل!bA~/3ӧ~Ď#~18v #F=a`{ .-Ie<ĸ'=8ws"g!bbVGDF*Ѽ+`]m#U_[QiiSEYϿ1`cy2'N#U[qe݁ʶ8j:/Xm[1ƕ/F .Cjtms/Fzۻ_w/?>௴ kTL{ oxx_v5tW*+ EYOˬ`ڢ`0:a#4LaŽ3dNtX" X{D$̨20ss9^a J#![=An`mA"|:$מМ cM0s0ǐJ5&ՃT F hVƓ4+=Ա'Tv[2+`0ρ zf1..dd p ;5vqF'j6ɴ& #"~&2 +شtKd6УM0m6%v\Qg=/-`ly_4, Ųr-Wnu\h^0f|d_,d+}(Zeh/!AG:ǜ? e Ϟڇxn'  g_\]]]]]]_B_{?:͹w=FM||P(ƈFn3㨻uU bӍ\%s0EK_1rY8F&ሳO=1d Tle\~6n~1j$hn"`1la*M>LLYK=Q֎ZdCj. !iΡ14.YfM[" 4ic5XZGcK%# ..rCK:AUp0ЮcWWWWWW'4. u/j~?0gOuki5~}K<nū0gwGg@9̔43psd1lPq`' iX7#6Ҁ0Ms98/͸#MZmRC P!dRcʥ8 ٲrKȺI"(]pm|cம/.>Я{xpzhILռN {}蕘jo{^׼s[WWWWWWחFW g|r."# ǭIpv\ae" fcb\2N#!V<~)*@%0wf )=~*,<ɧ>60SX9` 0.bFqY\ǹ_:L[!O L9Gasp٧&"bz$clJNT;&Z<ͩxL!,3Yi,N1xlj1n WHgĐqm1?XA}*1]5nܦ5H\ҫއ!!x|سgy$X#}R|XnI]@!F 4ktMk?9ԙ#r >CJ˩KD8e /)??Ȼn>;go0&,#F\?jLHfȸ+<z^+Gw\tuuuuuu}yBisIFĈ% EX&͠ ݄u8]dcjH4QX3tbgk(b,:T"tǗ(}1:#|OW2(PVjrIK&nN? ,Ǝ Dk!N mQq+~Rb[YEys~1hXz"Tc.еZ&78G Tg-d,oTBtpjn=hvQV.MDb1)spl bVT݋MLv1W"Q{#1Lنkg/BaNSW[KqMcCjp/}BgٱT(.%֜S3,cMJPϵUs9B]]]]]]_m@pOMWoVv;skAr,Z#4ghfmqjm)aW~1z.q~DyXn87η\BjKaz.}kmcK ysy0rlp}\$kSEj>6iS7D=Ä5;hfN+gŕ&Da6ACSy0ƃ+l6)rB6vĨCt 1d'ٌ# L!40q%x1Q0qp.:ۆ$Xqn)XLp"3'A|+&:1A-Ѵ 1qlJrc5-<ێGD(vsRYU;=8Jduwks %,q6r[^c\2 8TxYn;3 K \[1+ h+8ˇl{\zV:{^ИK:U%+ˬb,Kt[|b_ơ:Twخ)3ݵߓ\}Υ_ܐSlĔ߀05BJ q`P1 C,Agv'y T[ >0Od(M[s1ns;xph=Db6#T HB$h@lA#X뀈BcIM 5}*es.pUjL+uæYs2#KDG׎k{SPb[bҸjL+뇦Y{"V̴3D))_]O LLMVN@UOq-pJI 4\7 kmnMio)FY7ZW aei܏zxYD~6p]rRYGSs]pWWWWWWWWWWWWWW^ϼ|_'0O'I0{x@T08Bq DB\ns4̨ -0r؜F9X4ό<ϵx&% mOA+˹6SJ7amTSv):Mx y_g#npR5 t.صu^(f˽„L c"J %^H6:H3!G$ ٖN~!uEWY)H@ ҕ{V Dlv3,F\=!n ,7#m@Grۥv S, 骕Iqy'5U5tt}491a3:tRv64,7B$ )-Y[Kn+1p XB%jԹ+~F@T~*KID1F4I,f2Qx9q ng1~O{q1A%cŀ/10Msd K0ߐyZ0)# !( YX0 Xʨ҅ Z3X/zbb\{q΃M ,U27P$GIph[om[pIMVeʼnߴDk0Zlٖk0pʸvWc-Y]2OGJRֱdZc9\\ec`_82707ZsځytBXp==j0^͵]5X]so<0{0̣z`- (%N8.1V̐ a5+0hP%Qj69ld0 XY1P G:k_2lӨQQOÇK4,=>5[ fyH }<(Ǧ5%OÆQiðV9VfZ97&O5u0gژԺX`1&֔Ad苾 jiI’JE FLmmUn|نGpk-lu%YEd[g:q(0tl^V@VʋSnH!nH8w/78 % DzK|k7خq|SO *4 xv"2cap΁(XlBڡ*lwplC5)nipq:qN'~BqXJP1E hLBY0yT]Nz:әy*C9W<τ~N8#vH*QUi,& *f⶗غHb>lO30-!8s0c< RghE K3Cw}ҡC).''fh潯lG5k193d dvDQ fie$[kxs;>(l+1CHlmq:FX5텦奐Ĺ!@{sg02VڍSUZo|sJi` 1 JX08T,b s?KFr=A#xH4"G؃CC&n j9)jd9!dz}68NիWb bR kc1)- y?pc?%xVFe8KHƌU#0l![.{\y~.7o࣏~{=B!Vwޚh]\\1fH3YkYbl*H J.H@/ 8 8J`̓k|,-(d d A:_K妕9"k,1a2g7yZoƦpj^;󌫖u姵x ,L[w|֥g9:kmYY9ڷsNUQUP]U«@Ҕ1$$HbB/yM4~0$DҢRR)QO n^k933ƘsS\^=kk (ɏ1'Dgax7l%׏NJ[e;gk¥Pi}g?)F>Fmu}V$! z(cB Ku%#1޼aĥ@bu-!Fv"q\8wNc"]iY,ڧeo/Ǐ#=Dq$1v a5f=uA"լ<8bm,'vG-%Y9k,@1Dž% ;ۋG/>#GG Q3,,c"N@Ih羯?ccu;i \:2+q,_L#,WPV.z K,Π <ER !yaRE%Oj[}~ŵX&,cH;ub=r#s7Ǡ着NN5k]&m^ܹs|S_ǰb363Ъ=V>t!'1WyK>f2泎 ^*+ϷD6v 655555555555555=*v8Yju̲0IcQ7_ DMUSu!` t]uC(,Y 0ֱwJ!!Yz 1G`v﹋Ëg?w$:  7aE4AfJxج/Rm1< *`+{}ӡѧ}z;'84{䝍1_}6q[Y%֊KX 7EvAwSƤ-N]tӒ.Mh\sX sg,Xuŕg琋(pf'fQoijjjjjjjjjjjjjjz{;6?q8Ӓ]$&W| u8م܏%DJ@5i18ՊkԝSBR%¥9ŒĠ$<.Rz9=,'&ސs]kYRpy@0:BTWFKO&fLV6skV}ӉHmc[}sk`X7pHPyBkp[/9-l,xc%m <8VV玸f[}Ըs}M 1g0k\@ۦl}c׋{I#5+do>1w-.]ijjjjjjjjjjjjjjzu> ;C IDATHx$lcG9;%"@9ð`duZ(4M;O c#e N u oG1Cn$"Hi]=̬]gl¹} xP!a}Qʪo$ (na85ڡOQRf$\1p)dbm"Ɇg?\uxCckBX3AXt?`|y= DJ#\]pG0n[Lh u{]Wy7S 6${+' ]aS!bqM~v ^q]h$U眭UnX;78uK/ R,'3v$yO]iHu_c~͎*ljjjjjjjjjjjjjjzJHqV<0: 8!cwvBPgzsMl" #6%R X];Rؐ:AJO݌k8c@H8. ~ll⣸F݋oq6ye5E y%ڔb*n'Z5kt#^q7KaWGB`m"MF Xr-l Ɓ$ v׹̑2zHG1c5Rb`v-9־=I 0)IXfx}fb9Z:k1)akbq5ޠB>`_k݇{RZc8{ I0nɢeؒ$<_x~b2$<"9m؅t8gل DuyOJRpj41G ꈛ́]!1\f}vSW\MpPiv;ΠR^}; v'}rB7H}š3˹Թ-Wz~d+:yx_DcR=A<<(ovny42]k͢2Ne]rO-755555555555555=9JI|ua"&acN{ y=p8͒³ƺ_ B@y( c"F"/Q,cX?u#RR\Bf [aؐd)+?cJ]Ҹ 2`dDDG- $Nf,YG$# q`=O {} pt~p+5$̘dv)ëU8Y' JXG d<`pvG#!e@0r𑌂7E ldsNx{'㨦Frz[i5vd8HvmSn>17sf3V?S=>ŘutbsEz7|dW$ÖoZ0g=CIX]U`1]ŘJ>&tPS_ZsIʗ?,).q3c`J֚8Q9$D¸`|xg cR#!A9eD.pF-ÈZ'1בu8g}aOl A,8q$lc."td L1đd $,!$aWceLDt,c^څa(]cBq}wD$z]B6dWˆp:^Q p]TѓCXlsdv ,G+h*3nsλb,,x(Cz_Sr;pHD-H̫zQ9aXTS'Ɣ&0VJcUl&ƀus849?Kz>i]SaĚrˈ7`SSSSSSSSSSSSSSC{b9*!*<2S#Ր$9N 8gFp}Sd"fED[Lqn< oqp%I Hb@ԡka&A.z0D0:Ơd:b !d ;!D ~X?8^xsZ]NHGCLjE>x~`EF$DL!yT5 &R2<,iM4NmGbX:MXI Dǐ3c),ghr/Do1JqkO '~z⚛VQ_?{]: qLrWnS@Y^g1 8?=N+ŽKD7V vz[]UB]FH*.8cN; XyM}O֨422ҴYk>1zNnPAg5MMMMMMMMMMMMMMOY$H0czؐǘD^j>nHXdYlo3lw %# \Me[ICe>RX!SęK?AwI.a`f-+6Y#/'DxW^+@[ q/,DK8a0=1$ !g G1HĻD !D(8k1)HH89mPg0ùg]q Q6hHb/ QݡCP%: V?fs\uMq\NoM] : |I-_ + /#PmvIQFmlIV8d˵@Se)XLse8$ꈆ"P0R_</ԙgklN݅ )TV1Zoc#VBHțmXGL~yZYImat?_ƥc"90$kƬaA8w 0/Q2o{ sS$ $drzT1# \ "5"$DD.ݒ(=)&bfv@yBfdZL# 8ak]̺˷} [R7ɘeE֛G]p.uD"R}P2fē@>|IHQON cr<<={evO [#(uOWlx⦦'_c1!)!$?ً$#ݒd0YqfML, V51!Ā]v7LBdKRlG{Eu83(9b;:ު݅ŲvV𯰠L0v pL@ )݉@g AcR 6X]pz5} r2kQ9,.RVQrQcw G2w!8!I$d f j_#t߅SG^BX&C-3|d&gf}zv'Pa 92;uMp:"Mtլ2u ~v&:] [ϥB<;% #5[LqQ H_fg8~qk$1,!X3ҫ0 I(X+D+/H*;My<$nGv\%8pWlv>rzeDljd˛\<3;f"և/Kԕ]X49쒤S=gX܆1/(@*. DB]dmHj?un3t9WW !?/ro}[x_Λ歯/)'.WeDHPWwy+ƀ#z<1FDFR8cS`:Ƹ"%"+I\qvaq >,Kcp뗐'L{uity-a}GIE0N=NU! tK8E+1hr5 KG%/~!q/00ce3"R731 Kr4Mrt]8W51(t+,l)ƀd< g#FvH i6@JBX88ف%)3`DL]-cj;zq !`zei6 c)Z9J›Gl ̪`̈NHaorM|u41=_Yy%uiNKvz\i*%1=bvS=]T)9nx`"fE9h&b@t{yYV9^̙3\s5E/e/{Y^>}t媫joJ 1n;b`6,v$&#)[%i}aΒb#vvw!.0 _#8!u/aE FI[XӋ X s-X.vƓ$3# }%8V ӗhfd9B ګh"B!mSW'J$ƱZo;e:iDi<; I#pV|C]4nֈHk%;EvA:|1ew1 FIi&<=xcg_z)"Gk~e)>}Qw uYw5Oo4s [CN܎,j a P5+bLۏz kL4fljjjj U[u9 DZ]ĦLB1HH#XKf/֤4_ܿJሣ %˝ JcScaEouaqgF!l]R $I\ k36l5/m6!ֺ9 +[)K}kT9=nI)25g :Yɭ7392 csh^kO}dџ+鼦YdLB Wv6txggRv('=Aok1{UKd骛\~z%.\wlorK0l>*𴎔>Ys}ڎDLrs0}GpZg\/ОXuic3;cvޯhQlNƦK/^:u޾{wb?ٳgy衇l6g=畯|tse=_k/ry<x7|$#'g?˃>pn&~G+)|5^kO~y< @\uU<5y \sMfijjjjԻNYb`C(9$Dq` ;{I֓Oqc?c\{;?nfnᆭc|#oo|#|3/}kC~^{-oxxs.|K_y衇x 73MtY(b1nap0t#60:$8 x "W)͆H뺮'#nfG@Vs~Fi cw|Hw%b31P-$Qxٴ+ABZW1~cq6-#9$rOb)fql1aJD{5NR1 rm>\R媁̪c0UYkϫ#ǝLOrY@d Q).KtgTN"IRY[XqMBcEDA>بhgBH.xU1쀳7EN<R]ͨk%s;gdf zO¸d,6W$$Nq[-)#o uRA:0;]JT)!)<}c[t&555555=U?aOO >pmqܹ}+W,KΜ9-OOe*Gz=]xK_OO?W'~W~kFq:8^3ޛf^qppsӧO󲗽wo}45555]6*?O XYHKR1]H0]+eowNG6bX9w厞nA7 b0~KQj`"y4ՌUQ)1s)!TQL{ " -z~k"{?[5eZTOowݖ L9f>wealBV#޻ 1d,zi %E,zRqʮW\.++яHDyrX`N(Vp 9$:_\Z^K"/┪9iDZ +ʥiVZ$%S$ 1cu'Pg;'1, "a  Xw 7s}uMC*fkdL^-V3%3,6./FnV@#7p7x#7xc9~ocϟS~Oto>gkx_IÏȏ}|͞kZǻ{SN;;ljjjj4Ze؅Q4*1d$qn`d`8@8 {K丩ul@tQ89?`sqS9:0G{Rql/b] kMj޻iY5kg VAYW9cadX^u]1Z&-8K:-̦8KW`{ߋ1L`d{B}RY]y{!>FuŞX 1Mkǥ|BTeFq5S^׼[n?XviģDQ1ݔƂɀ+x0^QN So_@ 6/c&<5X2r><Ͱ/!M}'W'=bNt(pXࠒev'N­f`j 8h̰O|f"W_}5O咾aVt'w|믿w=k{qW\rӧOoˏH+ p]?Œ5isPDsÀG,vwY40GaMF[MBqXgg׳ t96X-|8F3C i7 %Do/yMݴ,"` eOBc=|exb;2#>_4L>Ͼ1Gil.>kIV_9`,UoZu ÀI@B@k/0Po/k$Cx\qm_Arni|c6d{Wb֠G:bfPr0_Mԭ7̺ixˡf p \XtszO¼ՖYޛ742}N(mY[GtZIOo-' b>Xb-̷-9R(>o<%-m-ᔸ^ǶtyӼuu{}yys=!O/| /2{x+)u]wmJou ðX}}kn;3gwn|~/]wݷ\njjjjjz*Kn` w:x1g )lq~y a}~ ְ^2.B"Ƃ1 !*xpݝۙjؖl׌yg b++$ƈ.5լ58,\oǑ!l 8{W|=7ɡWjHaؼA^y\c QbMWbuX2݃"8tc}ݒiu͚b@ 9b4p9c~RjZqw f6Pg Z?Ns(}KwO :ٰ~Zȕk˘AJ ۱BLr) Mug#qn\_LReurKǸlݾ"c.ٜ"MMMMMMM7M7h?ٳgG?WUx{ooWGqV^ǥVw׿A%DBvM=yMTXvY"36ʊn+n꺛}3EɑazXo̹n#9ZLMb^..pty8R/l5Y~פV6^.MMMMMM㵯}-wq{oN~cۿf}3 ¶r}xի^ū^*>n6>Zۿ[ԯ755555=啄aذG/H)(lj+ %j<)n,;9gp@0t^BMylqrAԑrպ2n֏u;d_%`\ƌSsqL&P)8Iq@d}^E&R Wfv+VXUUUUҩuo/x?8r'}ѩq+Ď;==\}ٸz3~Fkuݪ{クkuuxߏ>w9ר\UUUUUu.>0ZwMӂ1FN@>u'84 333G4z<<'BӘd"m #xhxz# E.Ak!j cvѹغu}Ɖ֭[g?۷(n6,//c׮]7s97n/eh4|wwyٳ{L&lݺ\pmxs[i=" mF@.xesy~z9F#8Σvޅ;Q ((ay: c j0h8ϳB;j``ii'w0L;߃`Hр g9CJlJk\Vr)Innqg!:gJ2v\2ٿ ϒއ{lMkA*d+K31$AORlR=AI"Jhp?g%4qpc@1^Bj ([i%윋eJ5ѕWSǂ>Z3zh,:ܠ&7pNrmѰ2:)FtnpF]UFUQ אPƙv䐎]Z4֯_={\XU"!kQ|h}* PI WjW`UUUUգOwwSnl۶ _~e8SW}cF|Ď;O~rPJ3> /O~u][q9 vZo矏Ѣ/~qw?nDq_ SUUUUQ9Xg-h`n 3c2Yl߱(P DЍyE)@+P`ƣT-@fitZtY}h;11wXTH+$2>r;7w<#=CIMN#·990dEjgrNXfG" p֦( xx-6ϸif`"s2 (>,C*O:°2"n+-!Sv4OKۯMa]\ IDATu!ﲑX;, |h/nJnL_c8$DyRnRe^7$'Jعs'{s&P , D|ȪG'oo7x#~{2BFظq#:(<'xͺpI'oo/?}vLSbÆ _5vi8#5qUW6oߎ6l؀g<ؼy36nܘ .~4ᬵ1oy[}]wڵ }ߣm[r!x򓟌>xXQUjF-i`4̀E7ك:tEӠ{&v *5jc`.:S330F1#718f;Ќf˫130]^cFPʠwlFJ]l2y69Ldy e. D t:MLK nD1m rӇnǘ6-݄MӠlCb3q!:gۅ|mଁKrdž6zc3h-#Md3K,d{0Ks r En0&++~$ovԉ  cɱe١/{ ] &N@c*PT֎ϦcXqv.乃ᕥ5I kgHt.Ga*2d}s}:h@b:ف2#f-wmY:`H+:4 ɧBh*=KpEF'"mTӢ1̿1-Oj`Fsb!Ś;ƴJɐxm }|~h"Gq!햝%i&ߵ֢iLWʯ}iVڶM&. n)Eu@0,GE+Кt&H ,кM J#d+DqyVaι˟sgs3$V)bs0MEl!(YvŅNFKFN60Npg.~>XVIyQx(c*<*gL!U?gaYJ\\|#EF>0U ϗ,(XvФa`yq7vٙ3k׌a)8LL%'K)XviS5 9̎ 0vE,u%F(B3^8_͹+&AIҎT1@g5M30XIVvIH2E%F^NRRl {6OZkt]bXG80$6Mp 8Ѷ &-OM^a튨jBkkXġsȉuqHP*PCjsc7Q(O\[y}R̿υ$ x`oѝG+fEd̮J<6yƢkAyXB)?KEЀbHpWUUUUUUUUUUUUUUx:n  VTtMZ,/.{wЎZ46v9u}ri ]pZy6-aXhQ[RӅ<7m qdNAA)hrHM!q ""J4Z""} 5q8JMƠd1YhfGd=R1u2c*Ƙ8[SyIQBk]vo.tƌa(s.\e8 ohM1R>Z.LUvċf 0 Y"Ur PqXaXBojˎ9EŐ 2C6g\357k9ˍ>/Ǧ=y8R3B&:Kqc>Oc9u~X2(brvEMKb>\VUUUUUUUUUUUUUU2l0wsX,Cz,w=v-M`>x8g0p uDRaEj`*ul\:Fסl\FK Z.gCfeZA%4_ V\}bo#K\aD/Af]ˢ-2-ʊ.x P)?t o;i^"q2cO>d<9~Ϥq'`(1(FalQ%p꘶K"?pJ4h,Z=FwSvi%t´-v-,a]0mقn?1GEVnJ6 HvP rHNM`t_qu|U^lx qYN:k>92sGØM Cr cжbA0uS4M[)j܊v}'iLl2SH%s5 Oy (K1 b  SBY Id{9yn Ex",B '\~ ⷾ-J%t<19+[R449|\< 2Re'-!D۸E|N9N ˛#YT(EsWK(D\.Jn?@ Hfh 0u|3)KW dKXVpz- ilz!8d<|61ff 2m9[PDMEuSaB((==MDP'RqXq T\{Y myzT 4Mb%syz8gSGX*O;Lr: |rqըF4)^\Bͮ#ČŻm;\RM1SJM@0O."!q[JEZTq,MŊclr7@N2=qp8O؂ꊂa\5C:UCT"X?[%b1rV?d|fXF1.bDժ6Jmf1a`Zu!`4jcAJڔr5ǡ]'*b9 ZD{e_9ddKdsVTDCr¥OHJ7,J1TOJRZ7Ec/$ Z'ŚZ^ك X/\:\10# =ʈp T*:W~#+{:LqɜHZ$GUzm*ceTXAkqU݆VUUUUUUUUUUUUU46-Z=bn 4wt YxXah)$ ,#N'c ְ1Kk\kz(cyq7ذԌF0]bF٢EW%7`A(LmZ+4MyҬl?)琸1 cs f۶m 5'gF6$E|ŸdM d-31 M-HA+*uo&C 38 N2-0@4/MHq_HPƉ2;@D@X-qBi/DeEnphYraX^J΋nFw!W~> [\yCe?@EcI1>QZf2sAQRؐrncN%˴ ^𷪪wЪRìGصN,oyuP!4f> 0Zsahg8 :m3ZYnm3\? hy';)n!pz|Rơuk')U,P9E\73CnP@57 K=0pQtI_Kwy X(wޢ13ppP1S٬Je;(d|1v@`e12J+YGDJ J0)70Zp_h4) Bvb8zx>DQaqqHr]Rv0),D:m+ZV|C뢛Ə\w-x2D!>g7^c)Fi#}q!]'&&.a1|X=652ѩXʼn :vʨL1UGyza >bXfm&\5r!nf vR 2!1R  ) *aeЩ||^e7$+-HY=PMc?vu 3`n4! 9 M(_zcZ~N QI/ /S!f QbB,Š̾B2YiLyP @cF0FsӲ&: 6z?sq 2^v :k^vL$/luNj t },0pC@UvpYqu> c+3)lBv$h*aX'K/8M?@dv"t>y^PW2^뗜+֪,F)8Iؽ{r-cn?#ECE`UUUUUUUUUUUUUUՁ1!,sxA0333PJaY[NH7J;=TkG*{ v+gbHFhSTj0`8 8. U-\JRHz;EB4bb7@iRH~qt&s.L09?He&+[rml!I癸Oh%xv7OZ/GĪ|T 4q{cGV&x=  *3톰"P GАr4O\8!C+ϯD!" R!}R&/|Cf|>+ۍ_Ė\@.Y]0PCq%曯KsBtq!nuZrΟR إ(B0S O~^|.2PCܜ{lWUUUUUUUUUUUUUU@0 {|5k3efn}W0Z#x3069aTk4 AQˑ@@ bc- { v,-Xkc 2<Ij2c8e e tDjt69,G{=G=V\`$"hr9GiR[tr f"͚qM` )xBe0B4b[4iTIL]u>JX -&W faXd4ӄ|rr᤭6]V0Rʛ!%">aqlWȠEsqjTB|!%7$Xbzfz"3n^ΔYXI!ءI eam՘8)RdfAsY ;/f&! FVUUUUUUUUUUUUUUX)&Ό0nФkY^Dz|XNG#.}E(-w80vU~F(c@J%Q4ATXADp֡ s]dy(\8PS9v)K3aX o?f<˨pECu](N2{PZ8g>+ Į|,)O1Fc9u=@,~ hۆ@hj9N396ӂil' G^5Ng07`KrɦJYYQW >@㛡F>T>,ʖ`~nl^ S*ąTHk#vVj=&2+4h;+1|l]lUUUUUUUUUUUUU֚h ~cbCAZ:ƌA 3"ށL@h m[f{_CIr7AC] βд loel\}eb=3hC`29m0]  (@t*B%p_HLZ;_]( 4MӾڶA,R, @a(RJ8[0i =Z"4 EoȢC0pȞ=דN` 82|"C'jxT|jM.X>0/&VdC OKïmF R0AiR4l1G~eᰰDE[q1lAg~,E%79x}5rca(2*YO2f[l_6`hfUUUUUUUUUUUUUUՁxg\_H|14F(27׋בO p*&&Ŧ <6l\3pG2_~P9!;,V{i$R!> qTjj:XLށ:h"Y4 Kw%4":1u]*&7"")\m{8'{xP ; 5{EhB nyZ``F vCiJ0 GU]ZsfS13FQ \\*#x1G x7$cۋøh CrQɀeG01+f."7CA@l4i\It_^@2`Nr\˅3˖V,BUAiH)LJLs9c8k ཉE(#!dSi6t8 3.'AIF'M¼}D:<J\^Cmu\oOyWqX.[UUUUUUUUUUUUUuf|$H)ڠ%ŮY,..!֢Gc B?`e PFEG1Nf1K cc :<ﮛƦ]|X9PӠifRhhfA]@?YuÀ=b,pNM4VMzty_A#/ES.fޢFo.f9JbMt0tSM2jUA[0|Gb蝃7>3Ik}-_ e9f!bWnË܆CÍR̭(݊qvBc,`Vus F;,PXQ<#PBJdUqET8Q^-*< u,@q_A!׃m{K}:u7㢋.%\kec~~AxxSr=y=ދø1q`G."|s ^Y$~<?__>osu;<|e]׏g=YXf^ׇUUUUvzɴt =j8cXJAi-9q` z9.lZLt%1v4 &y t"h@)\C7 pPCú&5z |:4f>5Q} R*C?KӮ˱v2 *K⽏i5XsC6pCMf[d (r:r)[ҌľoLyreFzeC*^ Hܢ r꣓.C1.f;$ɐE PBSF,7p5 ش7MC\-Z98%,B4-ٲ|Dbb0+.qTg;XSB6VUUUs=z*7`nn;vW^x{ރ'< /o=?R׾~<8C:k}̤_':׽n_P?ֲWAݔgI+@i~5P!:4MRFL)u5sxbA3xe2`,5׭l7A!%pheW )`֌fL):4O]%h54@n( ݌7BF4,7M)i҈3@h8# ׸b`a,#leDX: m4MGw@_3+(7"͐} $#ndQy6uv1$M^I^L;9|<_ٮ:`ǥX1!1MSVUU׾M6}zOݴi=X|?㎇GJ OqI'{hYYeffJ)mhxzm'=Ilh-~=Ld 3m g=r23P@cѰ`=P (2ڶOY.f `xkњvi7èfle' m!>:W֥JWJ>UUUfggW]ƛv<~7~gq}{_q>еΝ;q[n >}Mx;/v-[Wrkx8{/^ߟV#@kYUUU1]ƣt cبKS' vd0,)(V|d!J)vEau)htA=v/ABi<v4i4hg?#yi'PƓ qJC-XSJa4a:SP b4X^i {M*+@YZel*5)D/.(/0GR(`Df9O8õ켣l㯇b.s6`xf4<'gM, t|i-e-k' e4猺s}tCghY`a\ЮvKY^q+Jο`)g?͛7)}yӞnmb=mۆ]v|3ݻk֬u].8?z׻{n>={>ߗ{/] ?#oߎ??Æ pW;Ϊ|_ڟJ`߶m?|l޼>/=q_5uAFMeZxRhGcQUNf8:ҚI6PZv.S$ y8S P4ayPt#Ds#( 1Ȧ3mZ~FYf<,tzA63(;9R pɥ0Ӱq,cA5J]%)[cLUseukMk M# j@@'Bsmr^n<ɸyW ѠPcu7C'{"P/"rXq( }yVDf976LJ_lVB1hٖP0D ùD2,Z6@lQk1Ƥ:vڷoߎdO>9AE8S;Spoo~Zg>XXX׿uE/JkyI'a֭򗿌ū ھg?ݖ-[g>W_}5oߞ`ڵkqQGa͛q5ছnJh}׽(@<+w-;w7ߌ:+E<_;ڗӃ~aap 'E/zACxߩUڵس8 ,-Y\i(J|B~-{ 3cW)# ^)"~pɈ E$ى"2ʍxg"7mS=t$I&,5?wh(8RbR \I"G܄9t4Y"hۖٱ\EO`P7(0 +l+hd:T'H_y *(r͆QTM\,r0#q*-H0=W@s1خKē/Jme&WX#[F1-d~ /G|U)#%H$E轍6T&)`i!HDZs`<|__y{~_~s=;EJs1ؾ};ٳj͝w Hh5k`qq!_˃վaO|'#۶m{H= wy'v{8裓 p˖-8?6l؀>Uiii!CYk~ 'GY0~9\pظq#^4q^yx߸o}{ߩUSC:AL-|lUhA =pANA+gK?cloiys6kچӅJ#}e`1)ˠ8L1!ؔn$"!]x.<J}?hX.ilhX~@"4&iAi5pgfVw)}(Į1`:n RmHDV`jsrS)Ch<<1jb&e#=.8$0ǰQw?pd%UdP z8$R}'7B..ˈ3C=v7<މY!X+;!(W)}` Ԋ)?e m²eUUU.l޼w}7>/ƛfڵ }h/,,Xh_Y^^V8J0Pj_w_җ|^z)qgSOvys|۷o<կ~5`2`GJpX~jƍشin6lܸw}7>hs1pinoomnv\~;~&Z\ys\1~yVZأhv0<^<}t:G1׆gU@TUUU*ib;Llӎ,]ӘC۶}1tM1 LV1kzvX1giD&+td9RPH杇PFႃrY@+L!0]\`L>i EƁ\*0FC)z cpGuOT4XyQSp5X]A5 EX*h{K!N$0amK,(+ϛ3VsdX(/fS9teYn?P-rIgkg< -CM1lR&>Sir+o)B^{!aL[賬ypDōsΊk޻ :n\sӦM8q7 Wg%tm&_ʵc/})^җ?9J??nwqaÆ >ιctmɟ{;~GnذGufffp1ࢋ.®]}T|#8cw0/>݃GY$dD_ϺnGկ~5>K.+^=ףsASUUU+S0p.ih"@rEq("ft#͸16Ay.Vc"\jꕈB"@q'y fZg{4um5<ôwKXZ^@ӌ0MT ;LaA]]DhN;e bĜ%?c:bl&f$Qt̊s]c;[^#Mg`јL;4d|3c8KAF#<Ӳ,&Qɱ'Ol8Q)FZBA&9:ʘVsunTy{sƌTN ND;toMVWy8^kbE먉/)U9 SC7@ ( 8WI Zl-[]Uu-v%xs ExN뛭}H: ڳgOo4u]rQGm۶aڵ>Pٗmhl۶ _=?O%y8`"?s}RtgeӦMimuߺuY߷=q?C\}xPLzTUUU*T B!'(Ԥ5 a/6%Jsxz w[AI"JAFc\ׁ] zôMF9@蜃1-lסi LSh&5Rl )AZNaDy?\DƲ)vU }֨<%cz` 4Ff3L@")(U)$Zn3$i(yؖ[ežExdz}694P@Ҷ-PJDϏ@&^ m"~">{;yJ3i`mm78,n\B w8C3 ӽ!WfYޡm[UUujnnr .ܹ'pfggsN|_֭[70q__a}ؽ{7.R5/NW\M6ᱏ},~3 :,;v7ވ%حtQG᪫ӟZ]w^`۶m?{Vg}RtgC$\~8C177j9]z;o{<}Hnioħ>)}p|K.W\q.}sUUU(gK USsJkܻg]=.cBK6ڀ :1q,@!ޒ8: AqCua:U0 FCAd,nk֣s{eWY\kKB !& XH*|e(ĂңR(*JX*;RVDE@E0|Ę;{9.cdFL^"^@i 0%a*1r$x=5%FP08hm0 [n>wZpw6}}p+!xXűi͇P\mam2XfI KI1@;+ MS0;.¥,ko; 9~/TA"Ү+ynZą `1ehHͺlBq#X1+_y>K{Fhג ?s?W g}Cx׻ޅ׾8'XwGr-Wu=ix_~?5'ױwoyܽ{⤓N¾}piM>wcXK/ŁgO4^O|~X,v_m 'o}L<)OW^;|_r|ӟƧ?ip 8q|v\tE>{\|׾G>??bYg>җmhz{Wxߎ~}}{_Mگ Rl(xG@"!*F[D;e/c5O8PMQ+$P xbH H!YAK|6G ~L P8&ŵ91j|D 8Dfj aHZ#2b&y^܃t9g"@ɘp3ǬU04-,balc?O%vmf ($ڒ_En4ҊA")VEyO&fF]-7C7j K'LHuuko?mፓ/G f`h9J] tl,-)`26 W_WuY P,Bؤ4: cz.=S_|1M7~8tEmo{[߈v>%۝ P$ @.vF9 ,HPLfX/Á̓x`0V/@0i)DpÀ Yy!eE V[2m0$EE7 eH1b\ޏb!gkEz €JILp>y465ϴ0rj1a=\R\m8Zt n8Iq\ڢ4LyRfظ)]4ƺ@'@V\tV " Ik@iy*zC.W* dV(m"mE2,{&w[h05-aӽ15=ќɌv)Qn}^ӯ"پG.Z]٭)nV G5]]]]]]ߝ677qw x ^7L7pwUT`P5JQS Z2cF떛 Hk(DM)`L\r(d@6)W{1n :Ds *;BLH6HqGhY`S-SmZ%x@+ĥ+~'!9.$45p O%<gU`I~ ic`%.<3)Xmn82;N6] .}>_>ceojoK-57˖=h}J>|>!)Q3K`xS.]<.څ|[dg!ޛCX[bP`]DȱK F((υ-c~6>͏M(՘2SIY*ǭ6r 0cJes8!O۝A{@WbšSiT%T\ :p+cjVM,ߴƁ+<.Bd N9nCvQ6:Nn$C6]4HFL 7r X`EҮn>4ӚUu{6G%6#um| u'$[k<JK,B+Ua_e0Բi3~SJpƀB8jm qD ƧgpSi$Ҵ5MԬ(<) !b7s s &|\b B<oAYcFC0_߃|qU~TٓBtdEpuu<&/Bvyk@MbZ c4ƚL 1oRЈs߀q;b,#qŐ c!Dlnސkun:niR ?^cgxFT5L1(.PjGwwM Q[] =w}ap0Av( KO7Ĭ+knBpV=2/Qmaw\tvʞB}ɕY)L N4_@5-D>r} nRR N*ٶ4wuuuuuuuuuuuuuu99#4XMAloJ,b I)ؙ` k`i0 !Vx֠uRˌ@LJ)1sY.X[ x2kMMgHqy8@bhf$~_[QdqڵmV#`M?j :/6:D_PסKHRתac`ë/jG4GoS'aWWWWWWWWWWWWWWב֡27N58Pw'Q0βO>c-rÄa-#|6C ǐJms8l2f`4|HHqD㸄44T"$Jp}hX6/e/l:3YkMU2#6|d6 Ð#:GܶO銨 TJAяycj"Z$gZhYދq5==Ƽ@\f\Ѻ*\DHi.B1F&)q<7Q8騸QEj[čmĄ C>&Wvö&j-9 Qiq H)kcKȕjԲ<,1iS@(Ҩ%ᔓ̴9{PuVA-%K%@De[->i)%a6zRSyy '75(&v bJ/U 9r`صhEJKİ6! p֡C'@s}Y &H LkK<ے]ι_B`$GQIZgm)s{sh-x5Bo&h+aeNuι&ZsOЉ\@EUn;bO'.,QJi%E(shV" J?Vc\ζIoBsns#4ss|$N=մ$xO9<JOU܀՞)rRu(WaiSq [J%rP^j5tK1MHcch#D޳ˌ݄>`>9Z`ҘXk1 3y4Z^bF8G_ $? !$1  (0ZݗRrsچPqK ?$M11t jr_Q\hjWXvT ]+qMFWЬ%З MnZQ @mnP(W el*AbOMVN͔-&%&RjKJ ɔ=$R J-}-C.)Gsf@mF\=VTIɤsŠ'D8[{}G;lWWWWWWWWWWWWWף@ʓsUZvɟQbO۱R3P\=c,b(EW@lWWWWWWWWWWWWWWבRfws((C&g]aRR!c68!e7Z3HcFH q ]g&"PJ@'0J!ം58slnֈ٥WV[@plkk c`wvi6lr:Rg֦ STaCul68ZX dԝc1Zp9O011 ~H(ʣ,REKfY ]5U']lәoP\R<#/%nL3Ns!j 7H[M``0@Mr LyPVї}uShf\ԡ'U)IZnfkSdʵSq:5)Вӱ uP`-Jsh@YJR\*-l^S-hy =S 1q Tj Q-(S@Bĸ\bs@`]=|`?6xZ^;Q1$ҀqH!jfbª>^n[[plV]MU Hk:S"}JO W.hԞZ k}jm8qÈafKN>B@9jiFe&m*|ғU;Y\9L]əz,vY&r'a+_+˱bU8 ְ$`y/T8'e.#c%i,Mf2$(9qb Ȅe&/ +UGlBzhJB5 "ՔumoJc2Qf1-eu 3[nDi6I]6e( ;fׇ2f}n}R¯3jkrL9%SQQȊ !!% wrA1`sk3(`4 MIJ`57![-Zm O- b"ĘIAPZX $bxp4+@k729,ÌmKe!9]\wBʚx6(84ZяPJ9WbmmlX~64iBf?Hͨ=$@%(e{cq7MxjmrUrj"ytB*@5kQ0PP)BQK[x?bX#(ET\v ,k [,O NkWC(1L9rD:hԉ cmrafpYۄu꼷ęUWKuLqW]eu75E#ΤX ƕ]wݷ2W@~Y!MWysi!ZkXWZT:؉˜Rb) RneAPM@1lEgLJm0mCm巄z{J%CʈF|ĄEcȑU4%r6z:x.hXȱ8D"RJ!"qZ")`k\bc TGε cf=G9B]C0XR25+mSNq2n{߰\R׶.kk!98=ZA){RG)85-ŶsӢfVB7I$> IDAT-י\8 f g9v&M,"kH}57fiT 9Ugd*ͺ?%9o_[KFĖ*j |ewtEe&oRDsLE :*s4C1je8bIZ 4#EsmHc}TƗYc`.YDq*l :1E$DrRA7)BL\TC%6 wu ,_<301BA 0ǟKKijy\,e)f!ڦyGk g]8XP'bӣlDߋ 2 쾋M{,6V(Gq58R@-Pj שhqIkV"ÐH%-$jX'g|U7wZ~UIӶa&*?N $$ 4/;Mc4ӂn[b>?r\l909OJcnǯ*UueZih[(6P`ҺAxKyĠ5,nP,x_| (m@:ڒX; 8dCbl=ആ!=@JqE1 b Na(q§b MC@ JB+&-cx-te8 lyZXcї5 oi[!Yl,Cn00f[gA42H.R;/29N\⩋FsI~(U^p %n}m%-(YS|^!xU0THYeZl"Җc!u =ZuWX܈&>˱꽈ZkĂ :LhfGZ:3 #(%<PǪln.8e!K(gEʠq*$$5@ ߧR87`ӏXz "l0P+hEa @)¸@kT&hHqAT\{!I2R 84둈bU%J3=s0`GX˦07e:3,51 ^Q` ^UjydrĐ(;ͲShbZRfRQo1 M za`kJ9H Z<p:Ol-&h&XC[8X2 eԄ%")r4Vi{r MqJU4`*Fdۇ"N*:*8&/R5\.yrs8X7CHˆD)Z s4K8 f Qeh$X$RJa\0 [wCXfF 0B>ֈ0B$kۡ M[ż5a-y}ِQ'T+k(%*J'q:2P AXE[J9ڔ(ɥ#0FJ|QDb3RH)d`T .9*Po&%e Q(aq_(E=Ӝ6V`YXӜKHb:8s|IɌ)l#kA|^^yM>T(t*Z^8sĚaR4)'e% {]W{]mWWWWWWWWWWWWWWבwt.؂ V) # 4 L [[HD G/|LF#\J <2x@"0>x(~#nRcڦbJk|PRfq.%$ k%5[[HoDa7%gBLZوZ幀#*kZs2?2"DZ?; d:gӤ=y1yw1!G{8tX)Hh'%w3iOɼ+T<ːEvHmn.$e!5U%þrSU7 ɪglZ>4!{ʼnIˏmTiiN`뮔Mvuuuuuuuuuuuuu=J@1Ad#.ΰgR;`w \;Xh%xԎ< GhBD } ∴0bwewAZ:Lҏ s20*$D4x5(d18e^ߔ딲D9vR"PN`sm+hDZ +8qJ fÐc*$1bPxΝ]̉bb<+ 07L O$,GݴK7A-IV\%ZZXI{S\pfzyX"hke Hm`m]R,]8?-  kQt'$b>qaJ*pP~hzz?~?GsAXobQkرc> 4e{vFG-ְgn(ha@JCi.Zap;w`}6 R@;p48MT:dmevd@ZY.$ABKvPh( Ә~stZ["\xA!b kqKaXs\Jgr6e`6B"Zkh=).hA]J-%9:tT e]1.]*U[Yz1n9+G`-P0:ysbɛ+($y$IoErľ}ף_h޹',泾!]]]]]]]X)g0JQÌABcGh˯AL82Ƀwc&X/xߎ 7JHXXkJ[-;` [alȽ׌PZ! 9!@!Sm`—/9J ٜ.Ո)*<܄9IR}sn[XSLے-1J+c721y.kXbbkّ]uzɌBqt(De!'mCn|q4&,@n7~f( on 1ahl96rdKi q VAt*Șt7_6R:]{5.u BeJ綈ʜ@-Rv4l]]]]]GV㺯܄'=O>Lv=5w{?ƛqfuuuuuuu=B1pHIa 9cB 9ʯdq#J[@Ʋi9PbľAa`A"~ gۥ@edyYf0sk:ܿ>I-; P"JH1q rJEM9p Fa vR0•q,Zl$?kA5F?UҮ KDtEk)&(@0 C<6Ub*,xRV($3Ҍ;j@U!W6NŭsLrmӮ0X҄Fd ҊS 2ۮ-J4-22|:@FMy5%R>ɚUy`jJ̺B@>ɬ&AJ%hRnB2WPzjJ/ ]X_['PN,0.13ccq)2"^7`B"m,"%nɏ rXu rUB Iú~bj\kGU^T"٬85O Z,$Ĥa5CZ 5cQnW~%(ףR .q,`1C٩P |5%׺y$~OO&Lc?T⢋+ )5ʐע5Fxy4-'ef)P(GC^QPF}i&{bgiUNMX^XHkmw)NlzPRLV*5Wtqzth߃qܱG=<7E]pJa}9{ x<[R5(%D?(Eޅv܅8("lx & 6@k@&Ȍ9a>GbVД?.sq {AV0HVH1 )Z(x(1B(~ըo>,>@9ҡdv`;Pؕpb CyԸZ̍M 0@OFQ %ÔE&VM=4dߺ*TKMBJ,8B+ų5HJC;HJ#Rìie e#MX 13 %UR3, pq)=&Ð| !MK_qdUYD`0 34(!Az  Sp0kwfR\E8qJTz, 1gkj4ƈ#LNjca1xr۶_6PYڹZ ;8mǦ4vFW]()),;E+nLfPųtvӆ_ZB9FqfbCn#c\h ,47_JT9>ng8, 8 o Tgıo]W<8DY>k}}?s&N;4|3Yg۷KC-IL ? J+XkQ{s(QL0IsofH &,s>繃 sD @qcck c9bFs 3 :1$%uԚ1b|gTX6*q@4c b=rMr%}:'')NZL{9Ʊ2sĈ[Y)q#HO\Ӝ( ͵3Fb$+!&m`8R+06r^x)Պe= `RSv4;o+` =CYgspFs(AA@Te*$BOyHr/Z+? Ta]z3>6f͹N$H*aha,K@xt#I X-\ 1Dk[*@1\f6\ 4M|W bG,(|6"ie-qSqf )L}e!w@)F[+˯dy ̕R ~N[Z@V 6f,5dPc=Y*E!ƸLk&e*- Uf2ͷ1յ{uz)1#J| [VDDX[[+K/g{˿N8{<\qN: Ak|Moz=\e]?X[[8?Z^x!=Xٳgy&>ݻqEo|#^\xxғݻw}nU}\~X__ 70 .s vލ?}pg`Xc//M˪u;wv܉]v%/y 9|ӟE]O<;:ލ7ވ:N=T|i]]]]]G\\B8 `dр A<?8xIQnM18s,;/98GRj̲O_IeGl3 6 p %%J)a) ʳmJP(2rÀF|Ieh72.K@LvjZT-{q֕kT\DTCO=IZ @,6+,ś̀ P'xB@lW % DD9X.ATT!ZW[ Mĵ: Un:aAJ, TrΘa[+SnB݈yPZ0y ֡YDˮ SƱCh,%"]]]]]m۷ /,fx{ރ7 x; _vm'qx_s=]w9?cyW^?ꪫ&{_o\p.b۷^{-o. q}+_ NĹ瞋o|?R^:s|y睇n ___8q9+/}Kӟoy .wկ⮻«^*s97o~񶷽 <:s=xӛtc}'v{8kWU8x ztM8񲗽 DǓdmom#"/ŏȏ&>pOFtuuuuq9T\Ӈj6@ !լ00 Kc0 e0 u& AXE[KEc ّf2$"1!<Ӑp)!-2 IDATAX.UHDւ02CCCi|)||ۿ[޽{1xӞ??;x;߉yK.d^_z饏'r}=};|<un g8餓w^\ve{]s5{{صk;8\|vuuuuq`0m5ư{@ YX$S+cȴF`?hͭ2_01 !wGhUbJ!!l#!Һ6rYc`t11t ;b؂QYm3;GJ@ t`ײ:OMKfWҤJiz9YYZSܙ kV̔B_uەA||%a kU1"&*𱎎,@Դ j`:`Zp8mM֘3q 3km8` e!bT1P39ۇSN!z(X a6ʫk8uԶLau2o5\[SR)-Z y] I#ڄpnc|m*tuuuu= wqz뭸Zh8[nԧ>uSN9oE뮻p7ݻqy_2677qUWNST+Be&,53qf&G@p ;ȸ7jc߫W}%J̿H믿1R!|M~jkՉpka<}sе>iN=*B!hj!%H:05 9˱k$hm^keϚjg8uh%J/IyL|VJwuuuu=vX,w^ݻ'x"~g~z׻}h\,ɮ]<W_}5 /:N?t|_UW]%}Googy&w2 8N~KAy{O|W_}dC#~K\{y{o|{p~/뿓=nu\6xx~J.0n !Zq n਎SK1B . f7#sg CF"TI'L8Ae̯x6> 3Hӆ] ;f 8]&m ̫v͠6HgwcȣҶ[Y|N\ϨD|c{9W\1&s|6c&iOW<,mBPo ̝K Z9(:3Mm[bH*pk]p @=b 1D~?NZ_U@Ecq p9V-$Kngr34 UpC#e D/ӵŬ4r> +'e~au뱧_zERQ7xc_:N=T\}W\q~~ pYg᪫*`kk '< xk^/\r M\['|2~~ ^?=Ծޗ˿;NٟaP8^{)xZ'ĉx 7o]]]]]G^JR 8NF trdgVaP Z6`-A5#s@xI\lC̠+XW0րbaSzE@PGKt((Sĸ ծT `N 9Rn !X,DZ$+|`>TJPx3VByD9ӰRejԶhUPuX yR|/J )ߔ&?51pߚfacꨣ&ZKj(CysZkqI{!+OMF4#{1%2Wf.MY\beLFTsBۘܺ%eW#ȉbV DHYjX1nm݆o'ۿxs;iO{^w~wpw`cc\r \p8/|pgⓟ$n}}cx/| w}7ygg7 _BW\O>_˚.kZk\s5c~d|wwq=SԶ~[ߺmۢ+7}}S/>g=Y/}ܗU=|gmv^-oy [nʯO~rimm 7ttIxys?_|1Nr-袋<0[e 0WR̜KZ.wA4$- l(QYd Jj;ΌH53 nzK0H-c=V,{w9o97.6KFSZ"j' @QP@v%Hh$5UB`!B V\ĨM#5%>^7?1n1PZZk}s9\[޿?}ߏOtUOOg~g^gc?c_e o͛7ozӛ𖷼__w3>3RvO<7 }6__'|W֭[ov}~?8^W'~'?m?TmoO<׿uk ߀'|ozӛַ__;w൯}-RJx?~7k>׽Yw]xWW~Oo]W8w5y 7kkp6hjjjjjkFGe72STaS.=vX$zSP;+`sn" WNH0A@rnC >Ώ)*(x9ȕmkn9yp~p:OjD,~LfN3Ő3RPXkSmFil; 3" T7j.Ǻ7 d:jg' ^uFVblSpoքf- /{mw9yct>#x0  ^@Nga!ZrTg^h3zrf$mi#D2Gz=ԊRģݼZK6,ʬ#-9t{m/VQP}:4P9c_ Ohy./d{A oة13BuD9+ Rdۀ!h=+4$-:_s'_%Y) 9*|fQMЎ'#ED|m u!Wfؤsf1H(b {o-"p#ڃЋ@=h.P{ 7})cxK@w#lEbʄ6!KmM^a?ֺNMMM8S0mߋeٙ}C P&]M#x`d but5 -r!6XX=7DiCDw|]`',(8]>|FN v} k)f[JO !^@9P~e#8CQ؎5${$8mvV("{{{ e02 }a"`](Ts=^*T8fYf/J͞H_e|Ǵvqdܼ㲮 -6Jñ{=&/Diدn&HίPa||[ON[Ksz}Fǘǵ xi G{܈?z;FLMMMMMM}rv:ZD7GZ?? ܸF`7|7x ާ]B~| ѡq61HoНu5&Kכu2unEix2/;PVρv.wԒZR&<xh?_dw0^8}?⥏a])@m ySI2555555{1D RN*?QHA`$}5!BNg}_ٸ5h{ =8͚3uЧ@vyv#hа|穩ܾWx3;?MB#wn ܹ=SSSSSSSZpi]ȥ47q:ʀ ;@P&P|caP`pmu1!`1Zfsՙo΍BeYvĴm,::3!H.6 & TO'|+ĸB* 1R9"R,SUҡ:͸ yڙXkgιuޟ @J) Ͳp =m/@apF +SM ;q,~d}(#Tmw4ךw <4CzD3b65555555555555bк, -$$HX5.8=²{rYbcIDr["Gh#}FDƖq-zle'H6Ϡic:0RP$¢8Tgr;!詃0b\mx ;z kZX`?_~]סj!X!vs@":஼eKJ|uhŸVhHj80-c8ZhУ`Ɋ; Y˭Qj"R ( α#RJCjZE]EL)-a,(2#@<<} IDAT XT͝7DC]JNXDT Bɂ%,H kh 밲 ` l1ՠ[<lk3K9 # v&zk/hƺKK Fz_csh0c;G.QO[0=YE.\=Λk,G{;+P͍."s99@6^ZZp}en`]03}]1jPZkE]nwb4:kNñj0z]T`{Œf\]SSSSSSSSSSSSSSS/*[6a7Z3 !P0 gOǵ5gƇRapEHθc fA#3P2rڐJXܭPA\ךpk:T8wl^ OyCΥ¶)#V2s@[ );Y.0T6޹P[p3 iV31 /af\gYhgH)bjP]l;fm+!ݬ мXBzX}D\+h,RP)RpMܼ8`"e7q\Ve(kuyY_;Hf:44G-<_1bYV(A7 UvNRVl@#llء*4~C qobʂrcXf&Y$S+ %Xu 9%9Vp9Rh4T0DqfL,cC8mSmt0 ꚡ{xx梯{Poykn JlA?} РHnHĭ֣PZRR4|5f ԋCqYPXNx}PJbҖ($X% 1"\Wcs@g)%qKQT?Gֵ5&`;W<8Zj}n"džeYOsEqt>A@s/1rzWWh/pu8B)*wGx²ᰋ27s[뼠59 !@\}E@/ƈ, EIΜ"QqC{Xa.B Ǻϡ1^,.55xY[#8$J(xhVakSth}=!cm5gPx㍱84ކ]هQ_z a3}&a[ 8F?ȊCC! SU" d"TmYDC c .1Ncf1ᩧB .Ku ibDqޞ=wKN;9㑛Q%֋#Tlv!#|>#'[*!SQlW 1xm!6ï٭`3 VT@c@Jy ه p@3aC񈫫{QF'; *C<=z-_>>P*.Sbͪ;wǙMk9qͷ~NU\W'>_ pom[8kh-}k4 ,n4XuI9!rpԽLw= _K|AD[˄SSSSSSSSSSSSSS/&qu5 ǣb͆ wN"4"ƞQBr@*!p1" 4x]Gá5"u2nֆ[MK* p%u*sB T,1"rNqD)Hd`E%C8>Mf6}iQ텶m}  f6g K N,f5SC%@ u)˕ktti@O4!rc#ޤ́Ca׿q3/VK9 XWՎ#jsa>{Ѿ̶C;_g~Ű!L spZ RR6Q,߲SSSSSSSSSSSSSS/n>nr>8A7V& i 5@,,Cn;m[\RO:2ՙx T-k_FJRJJ-"af @j,b1.poS6,ay cN ۶A )=.W(3zo5 [юe3-*lq=snEmLz뱪"qޞ ,V6*KO}1,3cf-N(i;T ˍׇ CDUKz#L Z-y 4鎸a}F=qT',qΡ{b~1~ ]/G*hTڹzj{|sİ1nR}h5wοe^`|䓍gTTb P\ލr$a 9"炰DP` XД@(Ph0dB/n4H6>˹ ZnRu#naX0L/V#ܘ -rH%nx :3te`:1ZG%7Ѯps&#Ø< FcD  +b$~*Jg]*5hA4=:dH-rqXU6{Mι=x ]ل5  "}h~/,Y]'.?;?t(E'])gks̱)sH#a/K̡~XCԩ^-w2 Y}{@TVCkحҖ@JxţHQn)}q򆵖sb9 SE@* )ДJ` ʹ,rCuB JO86/0Eq- j.(, H\@p t!BOB8m{VUvMVFmR(%# "9t:J=%c.#mMgR"9ƭYE{PS7aXo5x'Yu`Cm~ t5'*6aFRҮH,A5׏``sRPoXh$ᒽ#IA&P);hPVh?ZQGHdWyg8{#=]wINMMMMMMMMMMMMMM0F)rN -G|C9%\s]Ʋ@ pX"K:x17\2X޸%F\v,q"h`hĈmbR ۖ,!)6PNG%VHF`J8_G]f*a@g}(R;pY'#*!mwcl?/뺶T" +8,02 m=SGJvJlvA7U}D{pG 1c0 "Xnj%6 0R%6)82RN@ d1R,rD7:1ָ R@m&v圑RjκQ̆\ьjg.Fc&B l&!lX㊅۟( @gtAĺ\ ,RWהC"a(nִ{FwH-UtX(HX:}D_GcY!|>ϡB1MY[@Jne#/z?#CeϿ CɆ,*8}ʣ獸y^kqi.|}?whyWpKGds(ZGٝK$3u(8_">zu%39a%&ZVV}-$-@)`i |FXWh%"HNr%"$&c=$Le&VL2RJs+3.gpW(Hr*6;4#cP&m]T/NJ^%Z<ƓEb>/Sïԙ}Ι4#,Xlع=O׈"EK)w.tǗsC'h҆H:eE_{,qݩjwz>Dh@pf,hWqbwq^ۃ#TG;ģ Jܯafrux+2ggVξ65phvd=q^B OBq\WR[t40|*JV &2tX,7 %#mu늅{QG` r%!1\W`m[_[bV "R]m˲aB%ggR@b ܇Y@J E㣠B%@˲ XK[KDϝlK {4o;G >M\As*.u#9=)qapnίXp'J^H !ی}aJm# VBz=Z:oO +B`C;&%}{1UX >{_*,[֙o-jxǸv\a(yJd@B WG^D69Jƃ +PcCwй(9K@ Tq< ZrpxS5jаl.B}""CBT+vxHG8DH-8 88lcVAt:C .Fdm3SWHi,amlHVRz+9+=Wk ךC BJx9s+ @0l,n~ܛW㿭4DN] y1H H; $M37j؜|W(@Ue$W=&8TQqg ryK$4@:40݋N@KXb\s]ktuC!`D -힚]}罹>tOf}͘a]KaA[J8ks5zF=gE(%ܾf ÁApulϜ\ 80bMZs !X3&BN H"$ ~@Ĝx!b 7l7 +b 8d80(BXAGP4=l]D8u,?esTmT^-aYAA9혔%04oXC-@11}J[Tç`R<8F+hI Q,ti#aJ'Jo9|!^W[jGb=z;9xT!J?T2Xis|FـԨ3qe頏۩`뵹Z>ϲKJC/ؽ4NMksa`'7ԇۿs#~EEx_SSSSSu'_`HK\mJxBU!9㑛7p._PD-'Hq ` #)((RqTHDHFdjsPHc@~c SFE#Ԛ> 9TpW3hp1pP* UxB7C<P)Nt. RB.gm qYPr/pNe652Lj-m!6+AI` tX{/FZ7:| Q^^ု u ^]ko"cFQlm*^N2B^P<u1:Bec-rc?[laڑs FGG!Q@e]uG~z1}k{c_{!.8ut-;55555? ܈| |s#>tOm,cCDFz7U[ú ([-XC=oj0 8m!wztvqȆ}$QH`,KD0#bbP]Y3r8 .wp#r^%[zn \?V~]^ 3τ EWf()xdam>33Eb{%= pXitJ}2 #?%鵸#^l v^N @G pwڈZ "{֝t\c>+~ ctap[fzz> o ~.rot6f@u ZspeP#G&|Y95555Q(7>,yXjϜg)6 ()g@uW\ϸ ف%eh^Ls6zX"jB."\/gPRAm^j)JDHY"0Tm&`%GeSBI O`qzk R P, RR²,mz1"^xf1u]w9VMcUs3F*'@qVͧ3J DZ=>K* yPTQVw!2t7t]]r it7?~6X=6an볶xm" h /xHCSpMCsp~W_ s~_CD5V uF f-#7n FْGzx*(XLw6HM*Җj0Z,9K=?TU O kd1FH#a( Kb Tslh$LƮW Rkqtd%ě#hFR=<73-GgM&<[yI: l[{]}氬 xt!3C{Fz=x܄SSSSSS_ E)`eQ– Xt7ogܹq!BN) $'k E΂@ 0coXfQ9J)XVk&c@q/到`qn M!rF.'#+9o DeY!ʠ*'\]= КJ-#&tz]8.\2R;|Fè>t.۾/RKLa1w9$[ep2Xv5Գraj+9<_wZ|wÜAM\ _r}q v6lQ:ȑyGamۊl_ޱܮupE955555555555555Bn3Ep6SNyVIm9od<ʶ IDATأ8 L^nYbKkϧUHJlZB\ 9-#͖%B!XTb\yu9Mܽ(ʁm[K2x*3͠&  ZWMP890us;04POՒC# oy(qg.RD9x7xj|{mlm 86/â-;V\\0wls uztK5|=<=/1q頲 -sz.}_R SP!%5_rmȀ04㾣~_{X1K-i\vj5vjq ;5555555555555"Qo3sͅ|K./,F:oS:cbAabݹҖj|43MY `=fH.`\#R H c6O6V.+,A?a^LAkï5)C4A`cT:t6*b!U98޸)b\!`>#o8^Ryb ]hLQȼlNM\R 6[ #B0^5@VfB=gnPl<1Y<1꣥ڡc{rV‘я@P--Jsّ\{@cDjT3v/شe-c9uo"m /om>_fȥdלsc* =0 j0Tγ, D!6]Db% Hb1T0ApJ ` >bԩ3RK5J1wR@8fN:!Y˺"ڴ[K7 ,lE&&J AR  V\x $[ W1F@Ѯۯy-p z=9)JF`iX~}vvy|!Ԋ35S I g1Z{3e0C_5q=\?Q*y@i9N;(Z;Ǧr̡l}{fT#4"ʨ/31a4Utw(ubHpjjjjjjjjjjjjj ˢA h >,Jq]m%yu?y1 $b]W+/o JGGh3+sz O  ܴ(R"^՜2Y0j+"eCA"s[60= ]: T KsFbjkU4@96" $Hy<QtG['^0o MaD7spkQh7Fh_cwRs%Cwk;$"vʡ,)ꩩ2s!23eic|1iXJf>]Z;B`@3x٣@]<coVcIJsH5`X=Kk]k,&2PXGم ! (pXk#HqL kč ν`s E2>Ճ /Gr vR)pTy}@;#tHtHj ˲}(鄒 €^ ,Gh@sacLx/yD+,inY׿'"{oGd`)p`iv֝v-ZÁylVJٶ_ {#60u훍2sdec 豦~?`F6 9c JIq>[R[neQۢ*8A6JXxANj@K>R BVnDKV6Rص-!,Ɲ}Ed\]b0 Ez=DkTxU9, !2>"B%qqOKoN'y ^~k?M?#?{|/y>RQ@2p&k)Hm&C\ܨGM-ug`dƺ-*|={3@(A>7pW@Uɶ vsV0֘ QEN!ZQ eFwڜCB [Fuܻ(X6(PN `;=xDR!XqX9=) JY&R^Ҷ2Z^+Q!BUl(>ۖ{7] Sγ2ܼIZG Ro6НܠlzMwq-;X'Iw"V@}_4HV M"9ww6Je_$,>n=z __}+~?>CϾ᳿7>{WWīo=c1Y&| Ηg|?}>SSSSSS@*6;."3rcD Q+I)YvM^D5P@[.Rpy( t&2l|&0ΧUvY)Dr\hIeIJc]"%CԠ) ir2$;35"eA*g1!H:YQ ,Є+n u/ +}8\8ܨ*@).͜RA^ !Zu.!zz҆T+D]'>B .C#626t7#JuKrY{:aV"l9fG~VBҝp~ FIXvo}ݸ>[ nN<+pصW/Dvn@D^mMjI9 ;Д^OMMMMMM}xv|k?߅77gp7ނ;~ͯr3?K_R@_m_ofeOC߄)|]|&|Λ>n~Oxo})K++055555A*{އ%2޺ >0lQ6OUP 2Ru50".ƀ|KF$+ߩ#R)R+ÊR m`۶^ZphUh-'bS+XH1V#вf$ ! \RVDO!]=TP8{k}k={0'iA Ѐ$j0KkJi-%HF!mE@Ū0J"`# 0~ֺ߽q]Z~0 Kv޽wg~g%nP#8kTEsضDJ{Ն]RKˊ];pXKV;[811wul -o<W on s X4I_}}8 t) AH<:}uq8"qN>}{!a SnAm^ qj K?}߀S߉ /|_g|o'Ok{߅wwG o'/=?"7ӿ}8}W|=Oh3^A=*>7aXZZZZZ n<}{`K oz`A`jҌuRA+p#b00ꄭ>VTAUzE 3QrmG)ַwtF%U N"2 л֐7wq-RA>\qg8mwyʋm[w;݀xeݥvRF֗!%Hyb`1 b۟Fm@CKZ FJ@'@{ED@R7׫ĢrpDՖl7L):w?dX:;_k}:uZa;plk 08jE1Vp,/Ku2HWÑ}B=PiZw@L<ǞS?1(viiiii韃>w~߂w~xm?gz{Fo\ ./$~a].O_O}z}G;?{7;?ww=?AXZZZZZ"NP&Up-6 ъ^y7K6fĹD JtCMp(G?ᣇ<2F\R+8R S=) X CV bBN Vc>H9CZmS1@{w!vBCl;Ώ0¥yH6 <1W Pc˯G i4EmaJ*hRR4(!NFүvٻ1gQ^L1浗m}+O4mH~!?sߏ [k}~*6\n6]{rAEC A@ we*F2|#Z0j8"]n@hR1@QBlȺVmDcO $qc{` e:KCι{z{lJjg1m߷,Nl;B N50 jy]sк#掬rrّqATEk`2*B.`ޱo7 TrHKn7,.ji Ew_3ם_q^(GxͥElz,5⪣r*A/Ekŏrwkz4:;4}~3$bh@@?|{'34U~jb;֜WzN=4@j_b𥥥_@jn|[ MN~!{?OO_{˿qc.7~o[??{jkha7=:$ˎC4Goдᨭ;1 }sN_h6s v* 3݁g;e3)Bb08N4hJ 2Ws@3d#:s( 8N{ 4T &&_i(Ґ%//GPv/Be@̨ZH~q߄Gڟnρo^|M&:_FF88`X;'˨45yrjOqś•g0qA}9%ڠv"'h^KccO,,]~7vߒ%`4 IDAT7x;x z|z9آJD(p|ka@L/YkR>cо.no.܏OU>Bý@3\-KKKKKKK;__{ߍji3?}I'U-xQߧow_cߎӟ;wmo+RN~/kވ} kވۗo#}[ r\q{wPz5&sHZ? =rII޼3jli 9'(fR-eGsV "-GS&=KmpD Hۆ ι#O>HSRD 04(VSwJ2gR:Ĕ\)6f劣]AR~݄ )U|8-k$TRZ3 7)Tw1SHNn9]vfgp#)&;np> DyzsF6ArIK%cW<2˓鞜H@x|@!`gX2]X[vʹ}b\gjA\yCQV!/VE{߳.ү(=z[P7c5hJ0 1g |Do=) ν9gq{{ 7DJMʸ=J@_aVwn5P+. xxG-+2eGaxPM\r$,9̙NsS?c7`c6MzcAw@N1Y(w?7:ld=_42,q'ovIs8kus5ώsv!Ƈ4a4|_v'ע94σ/cd ,-------------VؒEkk@{p6I]攐18mlAhl. GEr4@60xM,Ppf%p{ҙH;`2Χtrf=> &c 'dAuxzu[0sώ#!@wo^B=>w/^,TKq^W!Gĸp8^s7l皍i6up5. q8wə?״v{cs#*|n6 c h֖h . eP,?Z=g ׎^JŇSN#1ܱ" 8܈ 14`kd tox&rKKKKKKKKKKKKKKK'
j09>8bZ-Z=Z\.Ц={9'{>꼂SZ26K]tT{R괃Nڪ0X(x )1׮nR7nUQ 5m ͵hlh:ZmJ6?Ϩ #S8ec6U]0 jXЊ@0UL  Rs1k#4V ؁DUP=/1Dcp ak $1ѦwR*XݯR~  c0@FL/0ō!cVh==sE/߸vobFx@C1_ ":?4ub{T@?sܧֈ'b8W[@h#q œT:1U9iI`wT[NһA\.-(i8ZAhPJ3 =Nd۷lB1=|"6jnCrͶAPcΑT.ya#B d<|{b쩵S>Ucrض (wcy#jK{D8J9S8ĆdΌxngn! ""8'ڮ33ui>aЂp2_PpJ}@֊} \zĄ^gd1JX7%e K=2D6Mx| B23 'S_;b9")%]8c"ǚ N[3I~{l72"ĒDV$ L9Tl~ m%܄l%Ҧobĭ}Tk>i\zrAǴtq)oإ׀m*2T&ndrZD'.3ȺS\w 4ǢF [d7)}@E$9Xf<ƒ /;4p,ʈ}loإ׀>#1飦ip'}p/)JǏjkmƤ%Y c6]X`߲W1\@4)hZ(p[xp[\nt(Y@юbc>J7F A(Y7Z1'#dFTW^~]=q,7bƳ~Xʨ#yf5Nha؃,{LjЋ'盁{0sC8ôJɴz2c.V9ѽQ EJF2ok4N+QḠ>"]|1ap1"89}"5c9P gSQ݇1bLȮakS GēMxwDҫo{Ax& rrl[-Z|NOGASA:շ#Z >^x(3 />~)%\[!#JLyH:KjUU/H i9o6" N^57=L"VZKINh٤ؽۭ $=7v,ߞ#x(%X6>/q Y?  xG`p"> iSnC Lr|Xz~;ܭGv-՗ksyN'wȈ$$.ŀx5S΃bx1*"'`LB{1P/-kg|J\ZZZZZZsEXwiiiiiUr`wyE20[m:v7ޜ,;f0XJ1 eiˆͶ:Jl Ath2m68<18a4LE^R`)'Pqy$")ydR(ṳpA+pqSތR~Mqk;Zn0'EB#zRC>i|l AtE s=Ꝁ-P/'s4#j}zy}c xSS[F/z{o~?VF>v\Sc ETdWΖS{/TL r8eWxč/------'/,6JݥR.1EsBDMDSSabaoaV^+s`۽/eW @v͈\vA6U`2 jHH$ ʄH99@3!'q*b€զ7~ŝhS0pZ #=)k`{P%IYj5 3 ;/{Cش*PEQKbeC P갊!;r:a|د} 6T}y2Ń/ dor):<@dg 8ᦋ{112@1Qǵt9F8,4`~@zdz!Ao({q׿[_r॥_~u]ZZZZZeUv'\y송&D#f( jm:wv \bpsg}4R!H*ZHdjHssJEZwLlBs2gmPo߸@+f -N,G۰T@*`$H'ͯa\9+~ΕٯV0?ă3hbk6؅C΃UrOPtc ↇCGFciWι$ 6a@qdF/b|ه0xZɈpIu3 :{c}q=FFa`;/#J{Z-f! pC{/4UG!:vXr9~v".------b/~;lA~/~KKKKKT(>d˿a){7FDA6C#%:iZߵ7u? ztrXE uۈC'jlh9<a:݅4EseasȤn']31'*rvwZDŽq?ڏe~z_}'o~b3ƿ۾_e_.үH=OIH^5'mHDfXU(D!:IlôxK89+p}Uw#=) ?q|vߤEd wG@62~9%G'bדzL6tPdK!ک3.% \L} GepRi) cB?:8 shQwμp4LjJ}D0t U6Ċ\Pp>"J<["-Of{UaDDQyDzznS x[viiiiiiiiiiiiiUֳo4ֺTP[CN 2J)} RTS4'K%S&88dlZAn/'8oSZ9: +XJC60QSr'Gվ^ R w<˯"¾mo LSsī4ۂ`bS C9@P)4EbL--{Jx-}C3J"NAb]X8E?a" `*q)WQN3_Nqxޘ4)=Jn]E$_^b"r6p٦1_FݠNo1ޡ69-ϯ?1Ȣ>n"(1=#"̀&27/-~ډHO{jy^M) OQȧ0fBcsCrXRSTũnf qKP[RBSAf=x4ŖU >~- CLjض bҀ۶s+M] 7OA]uJS4Q7ǵY[k8ÍrҖ7{gBaTI;sYQml1 dbljmOPXzO`O=Z_ccbZ2ay::b11jOGJ }VXOߏɡ>M?bpth-*puKis'g`k16JC݉xvPxG\ ѿ?;挵ڐ l匜ipSƟm\Cstrݯz6P%Z'8sSmzꈱ]nl0|7-'3WC[S_ca9 6q ܯeKJjVФ@. iAJ8Q'c#점e=3=x)Ai{@ VT[R() 9A37?N\E) 1'5OGtө+>B 3@V;-'4(\ߵg70M_#k~{p GΩ^,t[s z-FcQ'K?,zt {G!e\gրG3ѽ*m3!U0- E`ǁWHԱP/wl+)L=}G"jblpx:rHh4EcQDc6Ć7I @*`pv9^CKBm$ fK (!pJhu3[p%ՊŐbHLط J9@LPi}$|2߳R jm V&Pٶm;P@ Fk9:FG(0$o =7g;"1hPm@zQH 1 #;ڙN=Gcrq# W\9gw~]SXPN*_,󺱽Fʯa!EwFYm s+piiiiiiiiiiiii5g^6ZCliqx|{[*n9)ϣlҰC̄ڤGs`Ɠ3ofD{g^}~~\+PMNKƵ53c7@a 7ǍgH+fJ BNE(z׆N@ 3NJ㯵Im`m33W3yaJ41#B!4< /A- ;weyWaQXc11uiy[mNXt/F|oz AwGl4k֪y&S7\s!d/m9 Yl۵5cC'wȈtHr IDATҫ-"2Е2^ >^:\@F4Tw6 XC98}x G iǒdb}# ς U7EbhD m휈Ąrv2"b`):)A9C{Y0`@߅HN\ƺݑ8 M-<+s9#o;Jw;R, |Ļ=y$@TfH6cc9xU1^1>4ig94Zf?(#=DŽ(VJt4+4b { *X v*y r=e rī Ddҡ]("8C #V0!bW'cV2@?"¶F>Xz՚Xl6- iAE!1oCgȧClc_۶aށ8@[N< VyFr(9fUw6l1F/lCA~_M0ͨ#"v.nRڪo,;bM_1kKG|h X8|'izqFfJPWp$$9JM e^ c>g<'0e0ewi@StxiiiiiiiiiiiiiiS8 >1 8Q9[G^pQEU3jm*&FUz`p0 r܁waibNeNZAAiD=N:_Y}XK}"\XUX9dRza8D8,M6l5wCjEL0 5@;`!7e gsY-O*IEҖf1Cfwwg-Vlzߟb0('vݞXVa1SBA@؍V恑#q<ݘh0J<#L|8"-1b@řXEl\ZZZZZZZZZZZZZZzUjŖ}pYl TTA&:w?'"j<09U6Tvsn#rHT \tf 8IP%jeÛZPc)';p :`4Zc译s'ǁyjZSS\f.v;۾;wq X+:5 7 o/+= D {'Fɇ#;|FZd3GO]hP^AT"1er/ht9qCQy7܇-T1&~>t줓Q09;;0Ȩ2j^O'Qj͆=}#vv |5[}3cŚs!r^ZZZZZZZZZZZZZZzՔ4R8)ƾ>JD XCUˏ:g0g]+/ʩ "}-wHT"z`nN9p llrC-,"uVUj,z/ jm+GN7"ݵ5z{qo{VlzO&6cRl}sƓ[\ o5x>`` `v/Ӝyq۬xw]qW%ϝu=c:A9=C6i\~9U+REqGytN@;>OYNlKQ{5b&#}RvB3Ιyf+zL qG_\ZZZZZZZZZZZZZZze=~WpOP|c= %4@ 9dtuDeDДGSpڰ]naxԖbUڹOe[k>x=e[F4gԭ_ne %a O#p3pޑh!ᨈ@ [k=Vփ .-lаV9p,!ȈbyЈ3Y 2d@FukkĉEވ~FM0nj<(FQh$ je~`L䥥WW* {JRy38-@-LM۶U 1ȸCR!VbF%5kSM(tھTېsq'&RrσB m#ٿmΪ*^}-zتA9R_ U݋SfRwf5C3/bù7Lr2ҪS 3Tp+rp2&e1_{lΛEXc`0 :๳/O7zq ,jjQP-qvR8- Nq}68g_p,?+/O}q1r"b%c֏m7"#{68b1XWj+4@4tMfxگl~>bY|uW9}V:'UWYڐgǯzӛp<~ rUAj"bt2)@k NnZ+'L ԎS[/1xjtHyb<|$eR6D a!LP'[tApˁ0 ?I9@^&'8BH5c>@B'9!o݁v<FDяւZ D GF1l{yN%?_#>9 @91f^+F]캬+eíS<~PmNW_GS ĵM9b`jTjh@ CR?z H})5\`=ڴ7$Y*18dcl9?gN%&鰱E@#H`]}h0+= 7~KKӹ3zs|8(-Oqaէ"vnV|ހp[NG8g%6y---------------r(~g>k9,O9S@69Ƭ+0m#'H9,! Bˏ_z5&@e_;xF:T W\)Ŝx[̖0瓋Ih{ J9a7~@_ν!P%sߨ3pG`j@O[C9}@O&s#,N7J;(MPڹ{0MpGhΪqcNVKiLRirPqуnip50eS&r%~> Mnߔe8uHlj}5&L tԗ3}tLLHwk /pcM? 1죵^jmH}ZzQ#tbN|HufqM/----------2dr V-}jg}7 ڋ ׂmE74>7hE-*_5Raaq[b Ղgo. O* I >vK$xY-ɓ'}@4NmV+צq0&i!+phyCmJfu>D)w N834mY)93۱pz4erq΃?7åx NHȀVGB1s>х8ٝnSn,a3, /X`5Y_|8Uqye8tWn^_(|T.--------------RPR`*Zp=]vj+9%";@-?zR"oWY RpcΒ ^ 0sbpwG)g%ЪߚjA ӔS"9XW1P.I8[q-j=lٹKJ 62ɯvZm'v)@e*Gy>+>b]œl8h;9y/CkcX{)pF`Ai6|6ܡH';~,gj$wD_99Z3qR_+s@gH~|8e'N LJ%u:l`ƹ;0/--------------"N cBEZCG'[ */x鸂!Py6A$1%B;bο30 /bzhIɼyXZZZZZZZZZZZZZZz)`40 DȜqm׽yg\bFS뵣 Aj!)!zT̨@E+wO'jiT2*HpmZm38gPJ[̧irI)As8xn'CGlҰeFJs3̆@vP{ۗcude>'Api&WaΊ㎁wzp f(lطK"n::#Z3/t,Q'@j~BDhc"N<1=FL!8\yfH)wG]C~Dtg(ss_b?rgκt6R <fk9͍?3֚K0^/ANFf(\.-------------T7}{xzL$@ hAխlGl-tc9I8VZh[AMd2 1I ;{8=7ܗ|Yp?z~W 0o%-B:^[vb1%UĢdD2X>`LK,` n@!ᅄT:1t:J.A -Ah@7jLNArT F匉!&m ׶R@K3pB;*ZC|H}4PsLFP(k"稜WP,3BdJEguyTQay IDATBv9dnK< - JLgpDY|dKg-D\U,r*RQ/lɤs5kEF.ne܃RTL$+=Q6+'!WTTUUUUUUUUUUUUUU8f~R"/BR+(!`(H:7uBAxF P'5cgu64Z?Ey{JQz >tBҹYǎ6&nEf^HT<"AT֑G1SIcRQ,;u0{hMJ8*_:hۖ5{ !ݍnMD͊k9y*%sp<=`1tI g Nj,wf}uP,Qd ,mñ~H% B6M(My _Az]7:Z!ĥy S]mlbk("Fm5g !(rv_8yME( %)Gw7op1I(dEUUUUUUUUUUUUUUOyׁM^z7`BR l9=;,$&!(vL 01~`ƺ#K:ELG+ k=!si L}RI@I %Zk+#=Wzi 0Rq`0!\sd@&PX;vp !g!Wi@5 z[@ PLk8"7{!q@k; fdӁe3»)d`ArQK PQB r,;Dhh1f^.h>y)Zf8L;o4C.bh?* QI uN&cȹTd"cl٘Atuβbδi>CU>=8thv bV=stUW/իw^/>~EaUUUUUUUUUUU^`0/83%1XPfB:m(FƶpJz= 016Fv`aaCk<[ ic f? BuPQt;mK G)h ٶ m8OJ /h8+N2ö{I) Ap hB5f9+)$edD <"ߑ2{JHDt# O?%lm:^4T@xO >, y/_f9(!?C& 9T=st>~7I_:>5| kXUUUUUUUU{mJP#Z7O3x˅8{WTUD?;}Hrk` eч@k=픡}c||!-%z7J x1M|pQ׃:@Td*Lۢ;pΡQ hӽxkaΩ))TP5bm_y|X49FFG!@Z}0k}hFS\tnRiH%Bi@Hhݠ 6/8!nCsְAE0a U CЩ`1RD^BT`l f_sj-5шb2L t1f2䇃[yssn(H`7&X(  < 9ι3A@f6e"r .[Rv92La#C|z`Q _m]wu8199Işٟ.{^z)fggc~8#|S\{970K/s9+׿{̛76m6\ve{u/o|111|x;X|9FFFj*=Zksez!h{^z)VZ!,X[.__Ԫ}Lfcx#Q_}(\Xr|KxcPj|9@S+onێC>g ~7cK> 96W6CRB-Ch9ސg$ZJ0X@#(cg r *ObTKFM֠?gaGC7 *t00xBIkZPAs;BgqBiIf 11p5fz= 4 @`7ѦAB*M\'N'ycޣן >pA ֳC>k, )q(3%T[HGdKHg)lqz>1 "2@a1VY#p|VdSGTX㇔e b"s39g{n3g0/ϣȬ Oǯy8q% \WkxUWaڵXv-^ W`ۓ5W^-[xoojUUUUUUU>nGsJv69}G->8lJVݏccK߱o#s?{ncf&;Iu71Ug .7$#kUi 3#Rqpޣ5;ZlǦ;H9CE:B g`} f NxIpN323ޛA[  Bw`CpQ-h8AHk>`-Z L;Jޜm0T]H;oitU儔l!aE(p qE+1Ǡߧs|02OsܮKKz.2 uQFQ69ܜ6^`Md()^c7m> R^*eE é%E`C}4p2D9Bc밍% ~qrF(*"KNb=3㹌|F% #4~9s>8-p99 %W@'x"s88ӱz꽊NOOcݺux_ 3sټy3֬Y3<K,~{u+O~˗/6maxߍ|W_}5e˖/|Z}sG>w]x׻pBs9W{キ>UUUUUUUU,ym8a]Khצfm4濖p'}k-^? '1v^t8 mo߶m3YS@ 0ХvvlM 11xHBޔZU3W\m؟(`/ Ym ! )dK I<]4rJBZ@k}HRsϱs㮼?ƣұ! 64xˮUŹ I4Eos`J7_Ǣ>a1 xXuO.KE@G 3NTr3 jBuEagqꩧkEݹs'`tt4t\vAqc^Wꫯ%K`jj/˿K?xGtCʕ+qSOG?'}?&''jZvC -c; ]G7C_Ǽ߆#MA͟;lz +n};36r±[A.*=Ģ*1e4}3lHbnc]L;V4v'tr1m)LPT%<ځҬqBJ  A3OJ(zLNƫyF(DRAzE A h$W:n8xf u=X/0[цxI S`Zz8=x@*z Zh4xXO MB"@56x$` 40:0@sϦM{kSs-KҐE:cccs?CEQZdO@b> j62#pt g !9\|돯=5G-k1R;2|H)`touֹ9_5'ha.cjmõ ,t{xdվ/˘?>nFLMMᢋ.g>?(J3HK,k׮La%7\r!hpZ ~Oaƍ1331<PTUUUUUUUU@QLf]n_nQ+ .ǖ/|un_Ǿ?ut 7o^6k#MyK@&$MdCTxc@RPNo2a^ 2 >nHA%>$3`Z!FlIBե0u@^xfZ3=hj%%L;`pt~^J4 i`gW&X$wpK#Ņ]̴$<:no=n@i,D4h˝J3uÇp"8OQcτ'W:Hv3ml哊1kƩ{fy.AD>`wpN"F燆$ZK>tw |#1+u H6wG>>6Ř1s^ a! dW?oaa k. ˼h$lW)rU/{~ӟbrrw}7FFF"pV\ t.uQx+^>l\uUx{ރ^z <@OO0>>5k+_ }oO} ^x!=P=;0/op{pq(p]wa7XkuV|_yv IDAT_x>~_=wҐa}ӟ}݇-4կ~56n܈wݸ>l~{~s=v>arr/{ZUUUUUUUI-.c{á1Ŷ M7݄:뿎}kO>UUUUUUUUĥx< bl/yQφ}l ּ<:?W>yӱงnZU}׮E)?矈;o+~i?{TԱϩl5OO O6xc.b%d.BC6X,JN"3!"[Y}&V #.fgR1W;g܃G= ]FҖ$4Ee+km(|MIRc c꜋ȧقJ1Hy3h]lo/B%Qϴ-tE sҚ9P< UXs`w(ntVJ5,ě;0&X6LQtp4HHα ssΉ)vr>4=$~(cY,>kX3Ǖw2:]TK,Ǧ;/< Q@<)UTdE%32IR K).Hp_t}y8CbŊ_깜p zXzu1UUUUUUUUUgVPcsoT! a\`S  Tq^avH#&$%$>D#d4 kĪVhC0RB AM K hrEtJ:'6Y\ԁA%[Zt.=0 n1-h: jBiHƘXț'1SSIUm8k!>(t ӫ-PQB oe?`C;:iěɯ1< @,fXvWm'fsbYfA<=w& )e>6l޼ LNN`]1>(FN8ԙyTFҌN8!DiFεt~h[Ch$ l;[()aZ8gXx ;aܒ]{!i rME'>9)VmCwd^ZaKz/rqA5W4sfP !8"˿_ӃpKЌ*:87&# B^А)6-30pSKϔ5(.҇Or[s YA4A#)2:1N6>?Pqęc %,48 bxyIUվø8sTUUUUUUUUUU~f䦓Jx?y> #x?Ji`GF46lZd!HPP  lMN@p=>p(uQJη c91xEj@` v(`0 +IHM¸ @·PrB@.pNBI< oaly,\`9X3 aLFKh%!@X4-qJYh)P: DX/!ű"s2 [ɭ 94E)zy+0Ͻ#U᧵F wZHC3Es-=XJrȥYx1,8nr!^MfDW>2s0$ Lعz +$9SNkd-iV_)+TqN` C|}~}𫪪Li}l`6"@84<Q.t4"8; C -\%Q&* XKIOr0b=f&SPRyʺl:1IA,Ƒi>6Q>& N;FRƶPa}ɑrppއB>&NȳBJ8 h]BQ۱c=Eclmf{p&yУ IS70`cykI}Sn*"<*',49Ee5}ɂ΋~"2YNI9&mrI)#F|!B Ř{ӇUs>n /}"ÔpGKn6yWVUUUUUUUUUUUUU= f_FLC-i3c9+n'i^y C{['SQ-'瘧+!1Hϡ/hJ&ǠO+zxkY U@2nVcJPwN:7#x8( $TRzHEmֵ0l[J;*RúX(xxRDYla$\'1q9[]h;mHǃhsM ! жi .5zxGdOTp( 633&Vd;]4opiL[d\|, I4Cz6k\OC cUUUUUUUUUUUUUU/Wnl޹>4&A/@Ũ J~2D|i4(# "L'6||9˂y +]0D,dAu毧1r}1&;_~&'㦛@~ % o`!!_IzXpHpNyAJ@ 3 c$Z38iu9w%ˊ5l k/ <2*d_"(a-1NJLl(+(r"Te($lP5x`'8r@>+JA63z:X>OGXƱ\p/EҐyV# \+O#ʢL$,gaǸӁ hR*XccPJfK +2s9/2\YHWYع2Wy: ת`-m۶!i4epa|ֵ@+ept8^J]᳖ܶƪ4Q#5QZ;$EmiV= 2H=H™[Nyá\u2NtUDZ7sC 6TUh~Eh'`4>?M'gO2F`b%'R; Af!Up d22%XG!c,iPd>qs/UGe02s*?T4l"Eu){a'#~ {.u6Х'JziFO!te\0iICb@[SYv[dvKytm_SݘIW^_4ߏ2G$(7!TLZw i C.`םR*52|".YK3RYf41=fG瞨,Z$tU~cdLԀS[fW(Yƿ~Y1`= "(/reAXpJQ`%2nA]κy3!; }؄Edc*t@$.(gFbazqF!b:ކrE M˂ bZW5bi0?9Rb^kd"bǒRd|*A_i-˾aQtU9eceǚ.~-Ob%ݐaW[J*J 0LZ(X.ZVc*qP#e9}Ygzl]ز.JUrGl2YZ9JH.]#sy,keK|Xj޵[daJlEFؗ8Qf LJ̟?!x(Ҙy{<ONj!.o_΋,WrWsr|_trF^WYALNBJF2e'+cI: ҟm% HGS){δgma֡i:00SKr zNfSD_soRZ+~O>_nďi8kM@u'W7]5u7c*zYA @oUUUUUUUUUUUUUUO  K JÛ"Dғsf28"a*29R­Xb<܃n&\ȇi3"vc=֭{tN1ñĄ7F`%)Vxt z~#Gؑ3PNj!gR D.f;xR̜x耰fZlCqT=[`48=XJ9eĩhȭ-| m}0*^l,H_jy`5$ȇ؜_-e|09Ӈ `liS, `dj-L8&R»6}_Z~1== ,X>xs9Upwo|#.RuâE~כ鮽Y'go}[xzիtҧKꩊ""[p!e qy& GwJH3g5-q1mJf%ǝ?3nZ\]{ (l#ԑ `A\rC97=p`E{lj֚rdkZyБ`xf#lwYnetMI <96xᡠ))D}6Pd?8l1*.e$X ͺYV{{8x -,|HA0%Mg5'Ktaa23k43l$ƅ`(uٶ# 0ĝ+Q_r]ifЩ $WWx?p_ʕ+裏3Ă `իxk^zi׽Zύ7ވg?8Cߛ6?jO;l'?m݆s=8_D LU0<qY0ρ!@Z<cn_cki edJi| nSBºT3d'#1JNDY-53b$'}dxcv&qo)MJ%!7<*/wǦy1/,“Ev<|J7i*E *LϹ- !2Ye`x70 8zpr(#-zyXi_*]P"םFc4 ږcшWdRC0m(fkð2m%7}]?0NXk R 0M,_oQN;oލ?Yp> {A '''㟷mۆ+Wb˖-RI'Nc .q~;v`rrrJt[7tfgg`xqyt޼y{,^vnMo=ѱ`Æ 馛}v!p%/y 5\{ qGO~퇵oٲ+W֭[!N: s޿7ko{-}ы^TzFOtm|~z*n&/_Oݭ=UUUUUUUUUU  V > #m);g7Kb2HÏZhE%< bb:oyFlܰk#·`' <1r-tN y`uS IDAT}s#P9硻 QhN8wZ `A?Y!לz.9x0H U@ a6M{'BXfᜉ!wREnr&"cj)Co)UNLxѭEx"aHntöK)]D7墴ǖ- 3}*eImQM# L&dI!ThfNDZքy첊kb&-支̃+e|_ 7܀5ko~\uUo7ox}{+^ X`n?'x";ykx sυ_CkD͵װݵ5k/9<Ƚcw{wrUUUUUUUUUկdcaF< KGR:2  GDa>2d N/8fTdgޱQv`+,gȫF_c wf?m4QSr Z ŇCwu1,feVlٺ[nm0;3 c,Rt:tnф:_b7K-)B, @-m$T<l>eElMDj+_rЉxhax(J7!6{H@۶?z_[?mkm")0]沅BbZsD|B'=4||"w49ד` bU{.9|;W)lذ333x _c˖-_O<RΝ;9c=011: qFαE#xBMo<ga֭lzXlY}.6l؀~Gxٛ x*d}Xx1^_rUUUUUUUUUվ*9 S B(wLD b 1e>q.`˦ۧnbZلLd1< _enC n㽇16D yXd s?_l4 fff0:: 3 vų222D)5|<ϞƪU1;;;'6T533t333Ov6{r O͛ܓcw{ff =9 dceU|g"ERӜŒld"wR` %"r N004aYR3{EG5!q()‹ %H򹄜xeUQR̨x33p\6וi#j@ Za!T$A7|EtGSj tBi0%rf)@;eVurݰCm|2f'q3M1O/Bs h$7l\ߩp"q+L fg0fZCj5Ee1-NN%-MO .^pLʗsۊ,THYn*R8z=vH˜heM00N ]p Xm5IJ p|9A*,Ql^0N29_eic'7by):nB\weqi̙S&+bn9.5DCԴbCo-KdDWLKZFPds=98&`9&}x}Q{".p;:s<Ǘ3}MLL%/y ~o`0@… qs9Xr%/{ŋ/~cdd/{p7[n~;{^(N9z뭸曱㏏@po}ǗehqGSO5\or :(X<8n?guV\˻BtAs:~ʏҗ4k>餓?k1vwR{,_uUvwegsbU$.ϭ˓}JrhefxʼnA.e 67%\,]ZFpΣQg09AµPtXMd1V=\+HAH*mSƜ)."k&C\r Oź%sHEl)΍pBcds 9X1>'K=֬kwqRTQ T"7;b4#ъ6HlӭQҝ5ңi1!Z #*1=4MPS%l( R%׺gyֻ")}^ֻϼ?>яL(։ ts׊N_^7gPrƕ7yrL:.Ǫх'ϠVcx888 Zk>eq-c.ʃkz=Q::ڨA{F9TBepnp27a<ϗ[So܌1xzg맿_>  9~o8UTHnՠ**^b{%QܕЗKwn7p.XP( BP(W^6櫩é32SG.̤ (rm|lwEIaJM:0$,nɭNn?a,%cy-e9(FipTK '?׃hsCy5pM}buVoy̖Yv4Ϟ.4bDyw,8J9MWց+JFxXM3~Ha@GCf$_xm$0bfc^̤!FZFF|Fla j[!@Ug<>E.ϗ^f%qr)t< 5k6EaʄRvzP˥ԩSxk^׿K=.' BP( ſ&7/VRMMPcR-iF@jSp}m뤵' moZzifm\|5sz)N6UᢼD p#\Gv BMSR lH<wcL\қ漙nN^{Je_$w4i<^5&a[4ZЄ"~ް&7kvFvRF:I^7Ңd>_oRK|?n֦VH((Q<ƞ\K/7p)]Va^=/.\s5P( BP(t/ܐh@%o62cVp7@/z p/npu*GcDH Ij6,3JY\yIؒ4`;5_7puJ9&]/HLZO#E`I^ZkuiM|ѦY|6g iUmYR_ݜC-3Wk( BP( BgX )tysIW`bgk_;j 0c*uE68OJf9HlhYvX{v+\WxXF$zYGNܨDgLp,̵1wmEq 7|r$N;lfgṎ, ԧ4b UmtAW8s ݘ8tf*;iʶYO6Ky讛$wٗ l@LӻkO|<`' );/]~DzbRCO^kU2nyn[&U64ŧ'CP( BP( i4Hnҏ[mjn#!uzJBuc Pr[s#u PWF~50ef(_ءjpuvY]x3&cЏl8~VDeY&g*7udL y[y*_& hH9R m0ݐ΃85\-aM7 @ +178ا_t1b3~ P( BP( aM?9!utt2 >هH6AM:R/Ru&2B %<Ϙ@;4YGSm}IM9blkhn$]?_Ov dZ#Xy2h )HiA&a~ q0E6!8ێ,&=XS ~m,; e` h%psBwX8&فUq ))4;r XբWߞì=g+>s ?3 BP( BP(t&Xu#{e >TjpoucύT!2.:k%G O}I3OnCwぜΘL8t(|-98N8JV8T$Z,2Lj+٥lյ KUAU=zD@}Uw1M6BXz'OIft4o7حE72XӃ"۬@,~}@79ȋc.o[d]0:h%}{YkFw,E6 5*7|*Zۻ~ Hʳuzh(+6oگҵ$/ BP( BG c?2 29w=`2xMT5'`;R,Cɀ}a{;=h01 ޳utRU{7~;ϙ:rT]?mrQ|te<f,3Cs-zd_2ݓ0וesHHh 6?,rZbBݑM1%3lo:O^ׂ>Jޡ<*~a=8+jHmɜ ,U[:|m(s2r6Pg hM 48\x]rI9-߲gN:/zn:uZR5~ubBP( jv;\xᅸK>Y_ȿ=B_r%86׊YwԄd5&gB[,׷B`F`}2IԶj"5~D&im[e~OputU/֞  BP(:q-h,=X+&>exEep23YRC2l0bI"m#&kzX϶7 `Yv8G'\Wd%+ơ%-ʊ|jeƚq\4#AW5Ԩr̮S`GxvŲ@E+m4&z5 O($f>{/* ۧ&yނ880j qv+vQRl5 \kvq&V\H8> Oceqtޢ$@,? ^C\@RơP( B{nX{dm8欸TeLLL%+dޜ#_iSCJYIx30"P)fÒäIʢ/JFUq]=ǁ+[rtl43U#r3`lʮ{CBF| 9:1ΣxAYNr5#cer=.7pibPHy psU=ug+mZ1vpY36WPWk ڀ~>=d:蟄%jrC<vdOiL UVF*EItZp L6mUCnƍ#6LCP( BP(t~Eˏ\oEf~KVh ,pݙvli+i#˝ȗ&G^{febG4Wut@۴Pu鉝:1xþFo|v->b\R1'_G92rn8v-_0Z~38hRhu,iCMQ|A뤸B`%uxZܚtS*(e-Y6PӾxvMtպAIwʵu.湁Qu ڦ5[ݑfRtޯP:ss( BP( B3<83Kg 5)6mr2lF%-шq`wk?[jᤳ^I* F+cZrh)<ȥɤ9ػ܉> e$OWe_l]+r}{G~ r IDATZ=b,yވwsld{6?sq^njG?L1RI3깏 ئH*[Pd$ɖk,pJ.‘ #k[?3ֻksK+R\}O.j ՘ BP( B"x.[YGVZZd-;w, GU4k9}rL]1v1k jY^qWyX; 88xޜTm"%Gs, ژ46QH( 4;,+(%)u疦`&kWeB{u7'㳷rݦ+9E-$覛0 Q7Q]Fv`TP6Fk>ʢZDT[h6.zl,y7H4NDC:[Jm`爯}fs &R/*`O?S BP( BPlҢ\[0hutW("R:ZӘ5|dsjثֱ+Z8y$ g삐Ӡϛ"]y5feaVv6G|C$2o2h<ƾuȳ<DwKTC[9?`vqi4)mb<Î~gLiv/^` AWqi% +e76U7#$\@%o?P( BP( QU. ̑g>Rx6eI ̑VZE8XnuIǢ\5Ø M:ߣi38+j5Ի8֭uǕKZ ވf|U$L#ܩ%;a&3X"Nj֚ޔ\;-I?AdX*wn!X}k-9Dq*ug SŵX{öyvٺ}c̃3u_2{}warhv ̺94`[%j-kaBP( BPl\#TA6rU抃jo9|8f  :6el4I;,pkPm62R58mӭ9[o#b}gǚyKgֆ㯎d;aKo6NZBzUgJ.rVLԖ4VUUʑULm|0~y۫6Ӭ}Ι4TyZy0µ2޳ꦗtF|4xBsuwA dӌ~~p^wبCP( BP(:s4:?/9Q7 UnJ:јKw XEpe;)5Z9iV|o:RJH&槮܉|ɟ,ච:qoceƮvf뺮Lʦ|-6wk`a'|ˌ(FO;p@:nU). }2ֵ!gk& DmTbvxvk* Zc|MA6٧]q .[]U:>hmz0 ֵe,:lanW7Jwn2ȧK}vsv'`V )}llt@CP( BP( Ɍ d#f@o<)[Y:!:fܝ<c<4jȂf'drKqc&䃤[Poip4{} I#,͸y?hL5PkE3L{ a B 4Y1#,H:, ;s95zٕ=sr5.d(ˢ0`Ȕڪ'D/GzYw&12 BP( BЙҦ; C .Ǧəf)ĢnRԤ;C#2*or 2ZCO+V)my-`!yFIIFy)%Զ='e8pi>.{dԢD]u:Q͍*xxl4)e1SnjcNXMiE,+_ s4ظ,ޘgAYJ,ic#U.|,q\zc#)vp_JEݕ[6OC8SJ( Жֽ6*s-dʼnsjA~ٵ<˟rڜrR`CP( BP(:]I3b@NFF뻮A˲h2#=rJ4`c粲 $\.KucΘJR`9dc]SܭLSHQg1t!sI}\gruz,UNe)`lf<׌SٟL:[=2PWvx]5:Zۏ*iƔ;l+m%w\Z`lq3r*HHӰʭoXsIW _Q׆R2~/mzk GkYF#ȳ@7ݸP( BP( μo)0و/sv4ʯ&rڍa%, 20&DB"?2L\>UvmE0J @hx%xsQեQSZр~|:\|]42xR(=焜.9&Ų@|b^ !,NDTl͵ج>W.(ASMyX!?;Rf,W("<2υι`]O xoFY/~j3w/ \cb@:W_G]=h+n͠PFIniÌSmSnC%>BP( BP(tf;FGAL uMXR1͗ȌCc X4z>: ĆuǠA<{?S1i0܍h,^1~h>l4w{?O JCYknVQ;Nhs,NVZO>vD3(|P;X4@dkU\.>BByj mХ4Z h[l!@Bʦ%4;>|9ZB:=@='(64/W%^ _GRK] f'b( BP( BCPݤp 4iVY 7] GrEMF@R 6Fa(sӨ4Fe(H jyY᜸]MwZ]hj /mz+8Ñ躖)Hr:?`فS9&81er~!i/+SRP F6Xq(%-fe qjW-h %tt j6F ld.}~b 4~l3 ar2n#Y4h4JV8'hjh۽;,\#rVBVdhQG H( BP( BgSqe17jhuҘWGYohmܘ,(erB_YGy1:"d)OņNV"bYp7vH{Go]XH%u[9dM‚F|7cwۺqx˨6s&?"2^puC)%{ȁ&iHrZa4ї>xGp\r^hpd_w֧6[0ofk)SCabks0뫥fc)_ڐCm{i&7mKJERj螪%X/k BP(颋.E ,6%ffb3qPm!V^:~WH3Zk P/0XGQ*kMoC#ugW-W7& Ɇꀏ~wl~yӕ/XJՆ_:,%ebscDWmݖ(i(\A|&\d`o!h97P(N)\LԶbUf'+as" di 踛[tsENqC9}el59qh&."]:i귽c3tOԋ/?' PKOBBP( zv;\|xq̛OHwcwq+o56Ĥg1'=uu| #[hyE1+ b؄QlSX`,51G4%ӥc! ؔ{l2e+S׵sZRv9)s vX_r~d>{xy&&*O#yJ)#G֦%iNhfBGoA]#^׻Pʂu]@ Ɯ^VV|w3sXN?uc V mws >P6mc tXҚܠoyoٳHN_  BP( Tʕ $9{:Tm%~q^)F%07`}gCJ)7'u?9\bvPgY~u ϻuHz${3`Pve9 s|WYQHMuuВ/rLY Fz %`ߘ_ g6NnNmCͪjvFGtVoˏiB6@5W).9 MY,΅hCW"n%'ຸ'?Sc֍ys=1?PgΣ-ED BP( BP̊T>=2lT!co~α*]vkNCA 5/wuXG:l VqgcTpTώ|~ l.DZ!؋??<5SY]ր<fq--ٌϙ?{0i*°ã"(q1eJKp_GrYB\Y8LavmHt+j[Kl`wmYAlvx~mDgzw#vCb|ػ)~ۑs9 BP( BP6_9MԦ(ǚѺSH I*8hD 5@Vi4R3ؐycALjVT3)$ISZٗ4~R'] hLyNd4:{O+p޹ ӑzyerG_D7:XB`t\ R%â-ɗF6RSFRKn!SYyo [\3ۧԴrrlOxMh6SW%\R:KMMϷA"hsy:פ;M?"fq=BP( BP(t6hbY%Ùw bd,d橊Y,Ւ6~l=Ț)z#ltڊ-8c0~/ge<ޭM "ҝzNwCpGk{TP:VeS6Y&]4lhqyCbқLKA:Zk wƢ4!aAJfw$i8p~qMQ !o؏ґ(i&ۨ1j~swlb]gJ_ГzΌC?xP( BP( ΜGp}_㲭57 Z&/?BVQ JvJˉme-d_ƻ=t#f F^#J♬:e8܍+qHi_n?q>67a3do33aCP( BP( !mG!fv nlOfZqU1Ґű֛sMja 8~] \D)2&Զ _AS֩S|c,Kq`ϒfKqq*8 qu[2 *n1m&Mc\[tfeFvŪsgw>nGpI ut9 ^(AZx>ze;{jVmu|s*T<NJnDlުt<2{X*hm+HI읜(q]klf+y{11h2JCP( BP( Yb%45zaV97;7hF,6/#,&eYCJC‚v)|d\( 6NƑI1f`9-'GK֘$3LEx5sNv aiyf$%)EXJvaJ ] ib2k\s4IbCy@t֪769hvȫu*zIk!^vPs`/ov\:g]?h`aɦyj&y|@7/r f-z[MH#+曬%,r}P-<i~ks <(h" شNq\߄ }~ܥE1 $MZ;ѐdZ!}i6i gm &I ZQh[m;ǫO#Ӥ! : YmǍkxS1s;BZD!hղ[=څ +X~cļ06&)ƌ]y/:gytodˌYUil_SCOn֪:'gpirtxL9F oGzRk>pBʹc {m-8Ѝ&NP( BP( :@M0|p52XQ/-e78BGJǧ>yKǙQ5FHJ . H+e;HLsXAF&զg9ٕgS|yΔ2ֵ!Eۏ=? z{X!@՜Dh-\Hj8^Jʵd.ʘ5XE)-mm233֨Y eIQۺ/l0mI7$4\pO릋sa{6#Z=45]U)8h+:w'dn;{68\_쳌skF:k 2S\SNr4>{kIp=c}dVL|<r.{Ss:k>~ˆBP( BP(t,W9s\t7Yqu#llPn@gA̙)`җ0Uer}tgtD Ƽ&Phxo/ ZkssCn#M3#~Z@ld7&X+zy3F"ԆE',XYFb<<WM4iҝ+t3'[MS񖐴!ZЀ:ڛQd>bYO^u9,;G`jϘ[cfg@v;5v1]L?+ 1(W0BP( BP(tox2 &+gnQ6l;`SVicrAG>:ȖZ3_J1Gh-j|Dn[e^ɔ6l\/{akpVfVJhQAam4$/)Li_'Guj+׺I"2㚧E6dsDTX#X+d%h-5k)HA$i)nZ߶:WsQ,6iэtqh4Zo(i6g/O0Z%sЧ0cIu,Xz"TBǀ}|!?ACP( BP(:4ĥ~*?3Pc?$3Ze 0&aĒkíBm٪{J")Q3Ja2ޮ̘\8&*oRI';7qRJO┌\xi2/< ȏuIftiXFk#Ԃ5fKZkE] gǪˍ PU{b[]8jk2d(Pm6NCy3ֵ2QFLs9p8']mUe#4ۓfm<&TEFiZ)YRs }áP( BP( άcZt\ țHy )`:qmnVDo`?r#-H3LF6 p?GKD6XpFF9[rTbp4``f1kҦlxoo2} >MJ 9H\9`kn°Œ!jنd4u%f#2 YHneatX]) sF/ez[fIٵ A҂4ݴ 6E&<+\Pvِ~.ˢYzNK$͓tm 9C| Z8CP( BP(:$Q_K11))`HĢ*`PwHu3<@E#iCQki.;®7G1q5g]0F坃Oa'N Yz߆qoV*_|p.Y'Ǽ-9r6ѕM Q>pLsUJuZn6XK. ϲ+稺^hY>HLιŗm,1 耳v~PZ":ƳIAfuugGຮl < >\K*Jy/F)wsF> BP( BЙ:ɿ-.+#$~ j\#Z_Fg\簤-I{YG圝 0ep%9{#¹ icx?x4&1ude~ O5eKqfI\\3Ȍʋe1m{(l Ԯ Aw2+nM SH?gҠquV21gk|nZ%kϦЗuɼkpIJ0n@BV3 mJIt{znߜMYAMP[.l _ª0O $[, //LԜч< dASwl;Ud\EsG̯d{OۜCql'b( BP( B3+oӎAb,h9 61l%Mzoc01Ym4-%VE<Í]4iIJz~!d%½=s乗kKN]'N\0Q1#hƪja#J):2ZWLnHz9^T\2^ [_u 8'\wu1P3F;K)(e7kJZ*`|,5Mߛgq9JKkln3뫽=CacP']#K?,ÖʜWޛ߅YBŭ(ƽ7W0 BP( BA h 0{{`%}x3;ctUCRKS8w>4 erhmAw[p eKH89, 7yCfRl4=+8S^s mʏ~9/ȩ 8®r)E79~82SaiɓZi䦘3mV5m$oFk]9̥ݲk]+zf7Sg{2 pΒǎF6i=[k8sOA܍2Vt~qɞvBP( BP(:4'ܿywEVHa9":sH+V 6:򒼉z㗀7=nv#= ySvЇA䢬ՊV}H}ُw\Oc×~0;;h0))PSfk:K~挴 A;iv2CǛ"|3;Zd|Xum gZ+XPe @W(9}~n>66"SJ{9M#Be#ױr.8+>$c̽y*- BP( BV)WG\5UrgvP9@8Rt왱Jp }Dc̰.9]0k@ Tv}eJWC&37cv?ՙu#sgՁC?džm7qdY6\)ˋI}명b,0zX׽9ֆA&yfEʨku׽slP[n<i*g2Le.|lI,j<֎ +3k6S`H:c:~z=_lsLleFB6ԔxH/9>+9t(#'d%&Sw]]Ik+8eElkct[.azۈrNirDfqYlwP[ fE ϐi=g 1ݬ->! 丰Y]DM+JRx2:ZkC ( Zy͜Ypr&,>Le`$ >v}}6 BP( B!1e6ks<S@Ǻ,,%4R“|5ws3PJUW=_W"9SVJс1ufGdf*c<[YAùv U-UeT RJhN3i /s}XC20:zn h3 |1L*Q@=mݳVΞgpl㕇pX(˺IZʿ7qu9=[ p~fX.)PK?H1VS3j쭙,Lk靗tbz,߹_\l( BP( BgX<&l.k,f$LD`f`s")\zT\lò,àcȌLQ1bn_^ŚmnúaTTM}j=/%Mqa\;\NE Ⱥ<=+xñ}ޔq&pC s.Ñ&'X28\ ,=b6/>qafʠ~A:ܰ:/m4w,ˢ4h @]tm|+UmJDz(SIϯ7+7kFwL?X&BP( BPP:= "68'b +$qj}o-wE@umudӭofwC;rOe33phFk*9&Zym |ptl"Sv|0r|#Updsםtsrl-5FziХLDmࠅxmz2~džBP( BP(tE([r \Eǩm GƣCz=4(ՁwX!5Kzf!UX/G>ۦdm iV 2nҴ͕l@/zN6\"dEޔb6% }6m^%M3H9E4O?v-۵wJ5c#vugùX'&_:40o݄>z=o4޲؆m^,VwBP( BP(:+bRhD.#%rw@ºwx~z^9%%ibs09rp 2+a5H_F_ޢ+/0 1bX\O9⣿yj qrsizV\_#JXm8iTukEDH;V\:y죵fm%̹s/i]ie 4E6 ^Hhѭ}جU /eٴ"g%-iF[ƮzD BP( B!p1 uG`*5Π 83ϟw)0Òz7ܜ0,Hi[# +N>j lF9Wme0.q sLC펋I8GsA c0(λڪkvAuz0Lܙv݌s۽T˘Wq }c= Ny48$M YgW2zHXs3 .vG{-221~l כ} hg~KKb&؆J){ppf\sVn2_7ݎsF]-Fb_BN'q;~v7ncj19Y}o{KK>4kj!~ˆBP( BP(t,/nޛ : iǵZHK.H2Ip2y1,=J2,o2ft\i M m"km%ןnfX\A9BrW-$pzd-Ng~|W :e}CP( BP( i'h0"G 4^#QXWxaMtAKKSZY g@ghߗzY a6LD|dz$)C.JbW}pV{|On}d+Ǯ:mvW*bg)`_@gک, OΔr}b2I8σ,tiWgǟй(xt{GNS_{ٝ#6gmci!mbjczjmv_|B-RݴY7g̕tHshP BP( BPGigДXqCl -s@qe>ę+%y1bpHg<\kZk„:gL:kt3 ήL`6kKoR$0ދIM֕ZZ5ٮ7R 3R/gebJ"y!}heSY5uG`,iuy۸,;] m =i͵ }0sM<'bC۱3%;nHZ5m\Agۡa_P( BP( 4 TjXƿ%^m ,N jIwMf-zei6Jdy9AR-p$TS@8*etjF\%,19 kYؖu`ӵ033r.^#QX:'u $c.>~jTNVXfCg<;LF fC/t@upFCˋ(ֽ^$~`o {Oﳌm Yyw?'pΛcN ih;moaɶ(aCP( BP(: }ngQe\> DLr#Y6juNzf[(FdFD3YNVG#KPXf|LalK)nj2u]d;ݽ^9/rEmo2B%X7(o7Zb[i ś:X;F٤cvmmvRBfnԭʜc\  BP( BY DչDcWG>rR uUs*`:f }K-9_v [O! FdfCwtÆ0Eir;)ZC^߾'6ofFQ}vR J^B^0Eh:ED.\iS/6+?lEs+oil-Í'YWY>`.2 T?g99ND:6> и\BM>ek5>@-N2Mc( BP( BAi3/oc,Y3ࠍ긃Vh$,Rvhmyi(0䢍 FvӦ]*MO}8 r.:Aspx v:JIeMn#E. h鰤_K<~#x6d>7)u+X ͍˒ d<9lj ^BJ 9$)s0Mū*rxrE@ն-|(bMHȮPnXb}36aYs 6 k?K>`i"~ݷtw '\5Z;eHFl/k$& BP( B 3#`'SaFϲ6 5" DشdΥwǹ7m ml6i](փߧZo߯P( BP( a-jlSl3Ϊ?'9sTXI61-qT${nHdzb  aJ;MzcUͳr.HW]׌|KX ,Y+*wB2۔zkdZf' z$n~ xA)Gm39G>XfKY,&훣xP\γl8dӍ5k,2-p‘v%Ʉ~w<*3R症ϻ,漸5bdx e \SZ3E{x=]⼣a>}<\SG[No~M^i\x%xe߄g_}9~7Mo q}o{>/t =/yƫw+'ދVK<ŸK?7<G=ڷ?~qx_?gr^*ŗb gA,2Ra7)ǯ1VȽ 'ć%*L̦)<},[K.: :еF\%f.72XhEM36ـds.)B5[\)<օgm1KYa3e06audۓ|  4dZnf#vfE#WxC?pmoUx|g[<}Q_S|S~naƫ~Ex-s؝$p?[O? e}A\{?q-?x֯Qz_~tcNKo} _3G9O^~ou<]?oU8]Q9GP҂7_w學KΔeߌ'\\wCo?ß~q{u˾ ̟?\̿LO|9y~/w<v^.F<לs]j/BP( }9řr `3/ <::uݏmjqX?95' +H  K,Rףi BfH$<O Ov76a1:fsӈf%doTӱv{NɗxWZt^r=ȱ0 aʓRu42?+|n-)-Z|sBqE7 !p5*)˲suؐ,# V/"39msg3Bho 6[Ɣy,,0 ܈['d~)n%$wt_7<}WS\t%x֕{z5g oqzW>);Oy%seo|no9Z7 _qL퓿<;/ cw{oK>¥ ~~!`sv'M_Q9|;n>ɓ>WN~/TcOovovGc/O]aگ;> z^~~𰋾_O1~]_/޻_-oOqyW]}jJUe'DH@ "nek7΂Mõ }ȤЂA  $LRgk~z$h~r޵o'\^;7pY?UW8_naNv"z6oԏ۾x{g?r/or\.9J)nl(heTdF+%44#QY-tT:V4դM\J }qEBb &宻v2Wtc;*uqCVhqcm+BjAkvQ^IP$xSMmfN_5|ֶȿFhs0CD.1"Y7!36T1ϳS"+%F[](ZCDJb&Vƫy{Ÿ#g Vt /Սۢ[dv]ZxǶQ  0 ;*RޯKK^ہW_|ʷg;Ⅷ:>x§3~|wckQnʛ=z 8rS@ͭ[o?gC!.?{wyss܆np?̷/o6_38A{.C\¦C7NvҰ~<\y+oo܄}}Go9<ws~9Wc}H}]ſ 3ӏy=5j=7mĿ7?^S} λWWW/9Cw7qo7A^=o_m\wuVWh}~>7qp!OGG,pj<<؟n">y_&\5ùgA<|/ Xs>K7XwB}oks+οOp]ݾ_m[|fe?p~{nm|ălN;c~7['XĐp!|/r!{t\~ߙ<_?⽗.x MǼA?y>GgA1G>~ o_z,zK{}j{sOyJ-ǽy? V=7s 9ѯ;ؾ>?!3r\.uߒi i8a((nI|P J."E+Є m%PMy):'&{ǛeCVpYpoB3 B.2W.F~ (:`>}04YĤFۂ@}V}??,:*3 l;#dnVB[M3ji`Υr 9)Ŏ2y dmEAJ%Ңѹ.Pz[,sC(]A4Gc(EرcY$?,嗮r,ZS,L %š\XnKY@RV@Ip'=/S\/[.7}?6}qۥ}|>K7_5/?#:bߓ}]s}p{*j-U|NI?]֭7` @?+<;P4QG<Ƈ^z>}K,vg=n Zp&p_Ҙc$l\w${ʫ/!^zCuo{wAi QR3nz8Pgr\.ZTU84K1fE1K4" UBՆ*72Ԃ!aD)\Jh&1[vjgqvB}\}9+^ˬ y7c4`SY9JY?ytV`JF^..aQkXZZ|~9o."M^ԗ&L eaR)&gK2LѺɔ:֎lmf*͖ڻܤρi /I\|;@`LHa\8o~]Pn;kgߗk6|WgC[=4`oq>܌\G\k5~W ٸ\.rz-Bۨx&pѵ2_"&IEJTLQNfظR*.)rC7Ew q,ÿtfԀ&Q\̂1k@ K mc]_|FJbO'ZJJVؑB|>\N\cxϒʼv@ +rs˥8jTraculÀƙo:xQ^,׶h9ʸ`+^xqՅxfq242$h>&-|1 4pbgG`-jYF gL1a>L|< TI)nIޭf]x؆qKm.ؚz=8zFW#=ON~劯M\8+XJD-xA%^x:>zSۿE,8z:6kovxAg-<Þ+࣐\"?bmyKmwv i{m<.?ns>z{ۖ~t_w8fq^ux};=U ~r\.4.n PWc4բ[j' HXqY_8]IQyjQs -9KȄ%O df]!K0!]?bFDd~MAGUJx䊬(%kW .K)13f},m?F_M3˺F=Ln@3g  bQInƬ͝+0*X Xml7U=<ƃ5Ô\Sc"g.|bk5Bn:`FuQ@[?Nf >Ԟf3jfy-3arN׬BGϵw{në>p>y;V;7y֯:pԾbK~ sN~b\,„]eDZM꜓~ r5>~[|{/oWplj=I?_|Kq${'{..p7?z>Қ=GwRubl=p`Fl[HyYfLm8p˻L`顺c`{kq0mN|{U~OzO7nC\=6.r\?f$8q0bJ6Z aRfZ'QnS.`K`}fS0UeWQe++A\LӟrQ|VJA"; ֬Y}Y#QmRZS ̥= !\5s+ba:g(k` z Kk IDAT)-s <#ҋ|M bHbdɥL!(:苑l̾K@8{\WM˄rJ5*WMyvAnL5FTn*I_|-$=7(rJ ymCmlz09b]Vfޭ 1|K [v܂G,]w܌~K' r<ė#_~[0ceǭЗވz[y-mčw^r 69x=^kno>X5[oo_ve &e-KvdYG=</Wc^kߍ;߄_}vvS1e\p_~ަC]y- tKߊ۶ހ?}žx?O\6)8fq-}{ʫ~{czV k+qη| >7}Ɔ+߉!-=$>v{;p37 W#pMu?ĕoy?}7oc<w_O].u 0Kr\.UGy VcFJA Xcf4a8E#zcЂ h%"H_:ܢوGe?f3&-4Vdu'kVA^g m)y@7 }kv9wޛk8fqߏƇ}~]st %X3ۀ^sMg8Ч'ZճOW _7|xށ}k^~C\x;8`8N~nU<[^V!vg>6|?y*a8gṧ =lwqƓ-W-0ty-X;ۀcZC7<hܱ8'>y_ٳވ5KqE=/xĿNezkO(9'6>}듻<+vE7fO?^sPǮt!< o'pKz#vs|ixÏ|vsع~l"0C65*IRQU0 b=X6l-!CA%KYIh0OG!.[ 7wFF85O.ĈP#(ԙ A8[@aS1EVvUβ8~ayv c0)f&j52[$W&ݲ5yn(2SP;lJܘVLK5l7v"a-=$am4/0xW>\ xŜ6e(!u#1p41k˵k,x_?O>%xiq=zOsNE_p\.ڃJiizshH3SZ&JC@ZŪJ*(rº\{vc9߃gm(.r\.R'_zj.Jg5qx0MX-h4J^CQG_ H*Z>fY̬`hjGvqҎST`Pks3m6uaHPYE.5VÀg,WiÄXaӛ4DDLֆɭINZ$+qL/}U\h zμW]/|І% ԱkfpW\& 097FE8箃dc xD)#R`?`ak{1t>Όې[1Zz}j!Mr |[}$G\>;׽О~M.r\_0H.64lZ>0 𚀊ZlAr3G'v6',v/5s:BXPKe_+bDWHj]Z{QKQt\ ̂"* nv9Z SkS祐_ xtݲeY$PqB&m8̃{vFZPz h@T~ۖk3& U~ |Y-6v+d"]6$mz{ӈ!}Z_W`l=yf0sʺ\U7=ѿA{.r\V٩rFqAŃY4OK\CַZ#Ș@Qj^Yg /v Ivq@-i]o\* )Eqy܈5ˀٍ%G}8iYv}\pG_ !*_4_]~쮛>]%YHiSLs[pm:p2f9 m3g}MYSU5KKRxW.е@FQ¤NU:_?e].r\.Êw~.N4jL2 ? T")MZYZkʨ;!Uq%6551}h$9̉5܀ZJ6K# 65R8#rohٖD>mN+zedWNb}[+WDHZts3ucqS=.u'Vy]JSƎ8vUk"%`rZi~$%kIL='?0us|b̆ ,˓OuӑͮK\.r\.˵7(%q`!V$LXE5m,,kQ`4ymӇF=Fc&d"aǚ bXBR&412x4˚,}ѤLsǥ,(?QK{܉=S~B̥NXXi` κ.L,} W#X9A08`v֚Yt5p:lZlaI1k׮n*Q]ebT[uE3P x~&JM3J9Hjlna_H~Dc8Zs3 _#jmZwp2r\.r\BuC3*, 0 / dpj2%) 85h7B9w<V_O9bL%g5=l̔RX 0gl#Es52L>:.ƍ?"c|/|0[X;ξmS/aS#"0!VP;oqd!>f.0 BG9Ɇbcƍ0۷Dh#Ȃkulם 1snoi6H8 /=`r݋ A@ |{bVd_|B4.r\.r560 3&"l s4(W]\]!sl’ޞ'λF |<7/%n]tЌ`g\t?a>wꔋ&C kQ~Æ '眻K[qA) a|?-8t\$F궠TnlDT ςSp67pj BCLun;29Z!ƨfi-t.;JQ[@&Ӗ^="w.2ԭuɂla.z;n)/!WD/`SJg,׊ۦe^/Ymˍr\.r\=/}8{= Y dva!ο z$Z$B3H3=3jKVi0yW7O}iB%+뷮ХYcgO+Xk*1 {u !ײczVYֽLuzmJ*q p +gjPko^$ߤXms[iVABUCbpI5d3;5ɹrX=iHBED+JEj]w<YZd´][gP :OXr\.r뮘 eb}*Lϭ+GXYbS4iq@˱qa^SϓH/`|l* e +rRؘTmKĘ8nJiÙ> LNo .)h3Mf/bsM7XsZfZ#;#u@ov5.PrML.80um\n;mSF+h07f&_0#|+dL)`_UR:^Ϋ}Y}tf`or\.r\K O^0փ&![lyGfvf@ Zd~ۢ P\My@J3v V0a7^2qybLv帼LKA`6Z1 P(mә}˥ݓ!r|-.cpKKp,5Lr\.r\{N8l(Q S>SBj'~fEs(JY>lC)0}B4f7@5!D.% ;J,T زes+ Yp3#fRSΓsʹJU&S%YS %΍yv ey%f{#3Cf DF{jgʅ?¬=iK.Rs%BF&lHoDU 0G^)ۍPnFu,˩Sc~k|M0C%B1Zh9Fؕh]||9$gbu.ϋׇ~xz0+r\.r\{X٩(yldJiyDQe-@DS sЕ@-)`)Ecbڀ)ǐQg)L]d&sAQK5r-)7 (1 :nnju6aMrԢWFfIauqޕX-;a6-9@J,y9_b):Z1!ț].; ys.J)׬Y2TmKJ0PZdX%L mߢ]-n!n]3o5͇zBc@͹J~ږ٬hr\.r\.מ90)Ch$4YUgY4Z[Oz"Vi|{&4mYřHRMhgJҚ[Jq{1!&65: "< f[21"A{,(e_! L3o/꒬A)ʗD=o&Z&u+krK#82YZZEDZ$/öK6K_D jI0_s$w\u Պ4$Chj)kl׺e0)6Q鬡٧?E w 5V2FWIOihjZعN Z+1kL( m{ K&hmDV j-`FJ9p٦"~&ShQq o ֒i>moQ%{š5skqZKySӆU MglZalCuZir2fJ=)iUNi@)Ůsw\.r\.˵5*i~^\`;9l[lK-V"j%w,|Ȃ/&;v̲[ڃjgFlݺMǖ)RtG;ngꒌg%\=#9y]GE-pkeXR(u^9d mf T3]iGhRȲ Z`fl$suBsߐD)ЏaClܸ `.-Xҗlubv\Ax?-L<_$^u6*-n S2.t\.r\.3{>;/im30ߩCf"S0 a@5FfӆaeY6n*hcz\(Hَ {N_x@1gF|}hG Vpŷl9 ݋]7w|-wи.嗵9@;jMdCqd.bg10 Hn& \N I JzYehɈ.犻l$tF4UR7|= ۸ EݓHl,=޼ uaBA>DhV,G'%uWC].r\.ri }<j;9\! AظJ:9vڀa@/&RAHnךLo@#4Il'V:6^D;: o%"q;RdKF83_;m1n3hT~BQƳK[T_cWR-KDvi-q̺uEe V宴 Q2jf3X2bJM4lCj 1SXkŘG)E#Za{ɉk`!?3)!QZ+b]&] K4kk3]W%t\.r\.˵>=_i4[@"6^ń$;:~b ,^A35vQjǠy8Ε{4YcGMBQiX*-2ԅn JFcHc郈okfGfR7DNJ@=eo/A&PsmA[)΂~!ITj$Q־D:J;=mơcVޓjӶatAE%g%.^3uc۬r`bȎ>Oܻxmm?PRxYre"fl6n ݋dD7ohujcki1gZZRZ-~V/!0ũ TZ1t O?T3޵V:B^r\.r\{F +NSUֵG w (]f'2Jv"+sAX5bi)Ʀ*:[Sw6UhTZi Rp/e!IT.IuB(h5BW@\5i7܁*Ϝ\qI**Jo$Xj2z棛lmCm#8R !DZh^Gdu%̶EZBmfa^Fc+2߈aKkmQm#TYCo̱s:{ekHpv\.r\. &#r1UkҢV[,R5 cL)o9QЍGY}]):`XSn!P-f@cȱFe@__1,sRǺc[Kj<E`ljʲ7}P|YE#@Z[g4s%Y7͎}n,{~v [0Kc::0`g"éi#!H0Cr KJi1 ւR4X'$oV!3YCrt_GV΄< yPwn2Gnmd|DJ==tZg6&pX3Z¹q.r\.rm f݈Z=r+Vc_6j,62㰐ўCӥގmW85k`#`~'_xKcFОIxM{IiQ01[q݁ԪL\ _A* ̀qڔm?.ai] ɔ>$S]s0P_Sش"#Cش(lt$N*ٙXr1[pX1DB\Si @;J|i1G?D신`0S@@Dž ,`챘lb)j ]s\.r\.˵Ȗv40ieN'-:Хf&,MӋ.rgtGi"JrRn8;\y!䬰26xRShf)&ŚA:YX)vM*6afWqRbllN:|al33Ltv x'CY[j4xdnOEtVEgڦWCDžb|I @F&tl EL <_ ?R+4 ̧.TٌP+XDa|XdQ,"iuN*] &9 zf3S6rMz/$߬&P䰋EZ, JТҩ @U'" R}2L;dt|z/&0P&QʲDdyWbbC-9UO7-Qa{,}8tǕ t Q)9٨jr\.rQ4[Q V kl Tme#,o(K2Y(ψ-%FqWk@m uqs5fҔ{P 9ݓ*̱8܋9NibA/X>ZSjE-<8 bg& a `rMq1VqUJDAZVdӨ@kgbRl#A=`g$jMƯ LykV&Z?jiH<f7f7u!̬]55wj?U7wr\.r\{\d>C6; 7k vH~2{q,S ir (ة!"g`t Y0ũArb^RJgBiiz)1^*vR朻Y>I8TLb()(hs|VB [l֭;u 1,%Mh|B <1PuT쩓 D;\p/C+ш#d%if)5r]T# `oLYkmV(VrR7 9dq4Nq߂aPNnƩsG>Ft3~lkgN Izkk5$ys0WOYr\.rb<̓#Nsn4DdJ21MGKĘ$QZ,h˯|4n|>JρFyp4.<;/2\a6%YRƮb@kQيjH[\sdaI1r-z/)vYZ c8!ZxE$[MHlh\b8*>`  6q f'[+{Uvai,W뱋yPIl|lnTksr)ۦ곹}7LIwi'rژ5ၝSX/.//}r\.r\BZ| )RWM2a!n@m%>03=^q -YR8r9Ti34*騺X3|֏ujժn֦gf<Ok"ˡQm`K^#`YI\ˎ3f@)ͺ *n6+_ZP\tnG~APZ}PQ% .r\.r"&@"2i"Sv^lyt樣2xBc !ӟAO@ 1!3b:" Z%lS/LDWqGrgjhjYql UR*f`Ֆ|(ZPRzꤤh!iOL*g illˏnjXȋ 0b2 :S8u2\?zmre0B*+n =B5Vb"L/*K!Ⱥ `qv>i:V\|n3ZM+u@hr\.r\.מ4(chDZw.kx>mChfD 30C_ndqͨ(" 2ZJ5UfFM}Y!qDȮy. MZlҩj"Y5( O{5Jznbe8 {-gjv wn,IENDB`onionshare-2.2/screenshots/appdata-onionshare-receive-server.png000066400000000000000000012316741355066717400253250ustar00rootroot00000000000000PNG  IHDR}VzTXtRaw profile type exifxڭWr$9{E߱ -,6B;u.hFLWu13נc?hb*5-bwTy^?ͲwEϫ|>n()ykmz ܽm?m|k?]J;`;k B =}}Evnso{["| uA.}y/aP$kZܝ̼Wz`;1?}ys f{bźje(sH;c>5@ sen3HsdOk^"N,2` Tq䧳rd3܄IN{䟏B($+DXB&SI5s1s¨^B%\J^C5\K| @Xjjkw& ݹsEÏ0H#2hOgƙfef_~EYuշ۔Ҏ;ˮ~N.m'8Iё P^996OS$O\RrS`Χs_fRWy˜Q?2gWY[2J R*6Z!<6^lxcVͫ5RX$wKا6lmQ~l[_ Wǎ唸Ȭ-S܅<ǹ[O/jzK͚?Mh2J_na{q()hkmg__ y[ԯ!dbOos:ܩg;mI+S0ja$U*+M0FnjgTِK-҈3 f :1q@@~ h0gkxJOzrL(,?FjgZi˰I6Ϧr=>*Y{u@EDٗzboWeǦ35`i8 <6f4nmGMNjl&GS0MX"ۏĈYGG;[b; <|6c!:t朋dB ,ͻfЍ8gU͞ZW:$kavh=qJ˷T jb&R!nV1w60a;$˵u[zSso2H7ڸ3 MU' S2ZFJ&QtWiJ2E` юM3横_EOM!L:ĹiT9f0 Q\YR*PrO״O e]j2Χ<%D/Db+#hmb*N^)0sŜ/cmwL}>/2?ƿ^uyt(էRt`QX0T7F~ͼbgk@Xw;A@ GhycLHu`c >mGו-sAV4+DT^ Ig|f[s^o3 ?BdtxdAZ4>O #KaZ?Zuih`UQ'^̷xj}V@V:^Djp=?6 ׀ #HR^o4 ~CsGQ"V62|ֶc!XZ9}; ^Ͼ|tsD:rG ɴJOVV,+rEI2~ 3&mz;) AB0qY}ruި@\t3)9yw jf!ZgSJٹ:]xz ksBCYϾh.ߴeg[ b(jhesY#P!nL(f]~Jk.LpRp8121)>G34*n&  mD2eo@Jo4Q_ПB!t?y=ԧQ9t_&MȀ˛v/ME(EN-ٶNJ̲֘Ǭj/o#\[ZX Fj^C54 O!bҋ2yO1Cm& aX|[O:J)@ ON J#Vf!yjuDc6H =` P 3q5KO \pX&S[!x@Q_p'`i~9թإqiHrDFe.AĚ1E3JbWAx:OڭmO_X=kH 0D#W/xl׊F@)D<_;~@9`OKqI pQ0kBh"6elc8V '5u;^,pPB=n0u \!=Օ:xvD`* Z`JH ^7$zhHF \f$nB<)AV;QY2b-"Zi鰌IuPN6˜|qI1V\{9rdGD/LåNâ+y]"NDݰ1#6SnԄJZC(q;B0R-ɲ'2pZ$esG0htjBC|X%&[jamSpB\[j6wpP׼vTdѹ8<|Y]8.q( *5QM[Kau |r]2+0w@*Qudk@A&Kڊ<p.uXC+ +R:YdTm䞂 x&0nC%c.0H V6*ujw[ǐ}R: ZG!3QID{6!tҭѝS[1ԛy}4B \κ9Z66sؔ&huaI+%Ak fU`oUpac7-a#< Z#>:$:[|JE v*VfUhݿLI2 eHH{/ AT=:*\91kmu`ځt;`G@RC>,G tWl`NA!nAjZ C]6w?* ꨅAe=vg1X`.{BE!6.`7ҴX}(WNtAY2چs!+GXx~ud;u/*në*D H8$*Qn2C`JPB)Sar72)#ދ93\ɱ{ϢO`0 4{2A"p )vxgD`bY={Eby顥/xc.T'z j<اtU`1Qvm,n0 칂8y*ߔg {lEїaSɨPdyGUx%̅O73DeӲ^QoqDPK{ |Vz U^DJX I1g# ,MP7U@WFՇr'H 1Z–IAi k%d:L>ZR/m5gd#I%yE:w}SI\ \+K\әݟW{M{/E ƣ,TluywT(307H JGak:zPn|"h~!5;^_Jq0[{T`&t_]8zS?v%"ÐO7< wm}^>]HE/u},$<嬧 =2 BM~`N:z*[a*SxR EϿP.|XbX 8~f"Z|ðq< =2Kҙ#Sh[O'ܧ^7鴡9HaUOӬ^O'"21(a?<,Iyđ{q\ js:kH* s?qxO`8wR[xF o7}q}mBr\Gjr|@ Xml\A.IqgI^wX\Q{N.ѿ] %LӡD^)fA4.HamܨɜţLcN l=##6f)kpaCŹK12T%XGkX`4^5UO d'8(Fg {}΢Z56$d2<"E{-6\Jm6 tN[:tO7MORɘ`vuzS]0viٻ[agD=ƌǀjI `y=yH *wа+b02S \pUGRzhFnK b_];Vz%c4iTXtXML:com.adobe.xmp obKGD pHYs  tIME?ur IDATxynGU&V~県0# La"2(2)ހA+Fe }'QEPehPd aH|>B@?/Z5ޏ\3߳M9چXI,h;i_h\;s&⟃y2RY/ych[Wϓ3sB=?}{65c}ڊ(/a%i wS'ss>[y]=?yC@}FiIE{7:ٱҎu1N b}YC)1;d, "O>~cG<4~7{rس0R܉g[ۣw0HˢtmJ kG7i{OR{6){cgߧB{WB):baߦ1rO)X1=o?E㙮è b؄ьKDt 5B7GasJc߾Kz~)ؐ3_e1 Hi'Li s>TPǬ Dܚc֗y֭-eam9ڸZ`r~s9`tx)&o[%Y.z\>?w}9g//׷eüXژ)ﺌ(׋wv9k}-kjS nNi垹٬{Fv}BiUdn\Ya z&Ԝ;͏#iʾ/_hoܮWRYSZ{2Oho6Ϫ>l??}OTD>y^mV;sl1{7x^)uVq_H6bJ뢙_iQ_vߩňӔ"LzPJɱ%vR,~ɑ@듸|2Ma8bA&vj;v6WM`HtO3,s"u#4PnDh^u 9Mdc;*NZާ]n@!9>yyu9nv@رc roS2-6p7m+Q`3׌W} $["r=v {mjAo4qŬO`r"5QG J;o8c͉{ 7=0@2ĸrs1 Tt_B^{lN{z몍/:R׏CBui#|lJqf2@}g,6@-=w^/{qA7hoyAԗ< 3;qXR[g fmql qnڜ¯\s߁Z> nn .L|[k^ny>מͦCٰOa׍UH^yơn,:zXd@au : mDn]`y>!Vg.?tƳb2B Um`@ @Ū$h <L/ tpUWcq9ϳW7 ߀뮻d}iaL$Qv}Ё~.M*R m֎2q$fcȍr|~/cval4ӱcĶQ[Cf<. h -g_TP61A,X7x^4|ꓟEu59粿A^06E6zSS8iCS=E޺Z!9J`ryK'w&o}H>ezy.̓Ϻ{.!_com}W~s ڵcKLota6هRBi J|ڇ<(p~7K04@r> "p$ܳd᣻Kl} OnT+acr+v=MCWAnB}FX0=nDKXd^l|'v8-u !<[Bh@b=ûX (5ڸf_R@*l7n"\ֲȢ3{ծ;\S )mDrf6'ٔ+c msI˰anv!7yVb_Nr@qrLtk,8[wKr@i!d׺:/ C*NvޓTik5B{oTl~PznŰȿkITv]# N Z ܮ`n/-5zC"RyD6 9.U%X6IZ޴6syD) րKh/ϟ5tR]EM`3a MSk/lGDGb(zfi N'ң6q .>T c?(.KPC[3XŜ?^%IƚwBr.!| Cm>,mIm]'$`*TJ7CT]Bq;VOXjqImŔ+uM|XYL$eehfJ[a X=Zv_RPDZ,]hRQaKY׈!s:]-y 8M z]˝D ?i~`&z|lN O:bޡ-en˜SpMmѷd&I S5 VGڰQf(`An OcT]olM_3ӂDLԕc|]|{e]v֚e7N_˨'#z3vںvN l}jDzl [VB#LeiPSe ْ' g<@̱Ѳ -Cve Ѡz]~^z镕=Ne%KEK }U-_`=e>Ԁ&E):ߨ͙ X\4q ,J)Hui׵<,6Bm2a<{)ɐD3T H3܆b0Rqfsa}7޿>Kydf\KVR 8V0?(KSJX5UʋP )M|,6.~dSCK!dX/tvFAߩe# ).EJ.f1ɴ{C@ʹj TQ+Y6 g+-o *$`i_L/F+ґiQ҃Y $RLصk'#,J[T{4pV~Wt؁iٗ0q2x)E@* iBC\"]B* %1@bVF#xM/5Z'CP17S: X{ V XuK[U 3sY2|oS#A?KI_WxFZ*ݵmחɽ ek/^׋g]-v=yk1̢}>D҂qbKyej $TYF^N[t㻂Ta^yccO*˙ `.5bgZz)%F66h>L]D3s[Y,Rˍ(wylP y˻yTaS.t I;FOLJiy>N>6,\Y-],5[pp&6e2Ƶy,7H{&YF%s(QAucZeyxF'qAsp +津Va3vli8oĦ'ĥhIgJ{ ec\u6.*oW\ȅ͹ ^b%Lɗ-{+iBіe.iRu371Zf/l g D`dgն98I*ȑC~FQo6|Nqu哚 Lͭr2Ӷ gMvC.e6P&E^e*ݱ4H W/˗&FʺdlՕ=SǺ@C_ IDATJAV+U@XvQ(^TӶuN٤ Z&\+YKle:ͪ = 6#b4Xvqv2=S-,Ry',oK{g| (n[FVضb7{??׹6zFe|j`^7+AMílT|} UK+{ٱ&F%X:#$u(:q]Gx?8wg>}Ţ2Nʨ|^j9j*%8,(dB<&0Lw{3 DmAj_Qѳ-to-v؊4.lBa/* aJⰲ01Ņ: ,|z]uMYr'e~4A7wZ4/;gWp[D>9DA0΃T/T,D׿:ryޮZ"\8iA-n^ 6D{jPrKS +$m%;2%APd IJ5E2fyOHg &/c*ukռf0P+LՆmo)xlepV*'mlnTZ]=FeS:]8)-^Mz]tpM.]uqd3yŔÕ_K&?tF'h&R==֭Y~c5ςa\ @CL:#ie=~ҲM3_e2s\)KyȵZg`x53ʍy4 M;F>Qs\wnPTC=R*E8A[9Ƨ?y+ќDri[X,4Taf(}z[}=T(6w-P%WMϲϫhY՞5;zޙk޽׎99cRb>x]-6C/a箄8g$o_T4`vn=UnYfk>js:HR3Z/>S9oUx1,*4Tiׁ(?2Q:I5[{K2'h"eF/Hs|Rt 1mŃ|KC'#\kn;悝5?ZƖl;Yawc- xMy4.4K)8-~1I$xF=AEMtV~aմ–ؚ|e}O9&uZ5S}sk40u7ҏw~:U}ZU hyXW`!J 7iFϭ^0Kta/sxO% 1h&bx~ TVu`Kn50m"oe):T/QVm^E0TnR&l&D_ )y~Q2plhJ@o㛞SrF89ٝт mz6}b1ɾDE/6 OݤIK+en)CPq> fh PAN]T\o$Ǝz6ߘi1h+œgW~U6' ̎+mcZ;3VIE7XJ9Yt"}.>Tgv1muUܽ.a/,9N6cqqBghsEBm9pI"w.n@ tp6eѕb ʎ#vA/4OR9t*{Y5:2kk@ ZؠYLy]Y5Qt}/m f.L* w@ݻN`qD&wp@0$XZ`ݭ њeo-ojF#ڧ WJ)MB3hf8н%EPZwxo>wi#kv}=kZnNLi߾Ri찬jYEcOm?7¯w^eZUd#iVۮku>=28{ Lla~2&yJ۠cS_ʬ`u0&M2WP[NӖ DRa+d\|r)NKۖj_t%^XO0X*ry~[{#IO: b7OF?40JaΠ`5DL&qRk2\R'/jЂZqj 28r7o2֒V4*B'$HZCMp;2K":I%;- fnM7'9/5s 7++/#'8ο,OͤCJY8iBV;/\1N>mb-lJ9s߬:)Ôٔ]+ xⱸ=uV"4.43X+pGb};z}y56'* `-B7f4זk<6/J66"2t-{2Rʣ,gj?]~iݯ.ynj2Hn#'"[VW>: g/{tw8\;vAZquvؤe@7l/\Ѿח e)-& lLXezVD/toȆ[$m2SmdʉB[KYX-q?ݙCI?T@yk "-+6-K1nsDyIk\/aEѴˬw_ۏVD@Wkal^xMsƈr@σmװ({\.ji^X>C{N;.a@žSN5=-"'?`Ͽ~sr6eV.Fb:?ECyVX\Z=klsNPs?_%|į!:{?qiϦ=;!yak:qA7ёf2+dJ{&8X "᝵}nam:ɘ4ʹll夦:_ 㒎UznƲ]ٱXJx`/Z 'M&үњ>wgxorr Ɔ$l+$V$fˬ<8E/Ӵ4鵽OdfM$;>tKB>/bj֒VGeJP=\z݊z^^L^C&#' ./kԃVL֘=RhIsr;N &%xtRh-M {@үI s!giqdL;أg>$q}?Rǝ0u1e `с Cs+&ű7PFb:'쐀PIpBs@p(_R'(LebȶKD&((tCdZKgSI\>{^b˸\Bqekt녩ZliuN.hZA(Nvƿ}ғ/~覶2F41Op>I8w2.t {E[b9v0JW0Eu/wPIw͖Z p=:Z×{^1uX:+`szHECH4B+<9BhMK~&]Ԙ4Fa9[:+S]|͈~f)P!!ɽ#ب[iTCBqe^:H16˛hD7ȢQ&%K{/SqE› ^RjlZ ^K4-ZhUTxr8`2׭Tw z.{-iIh4Ķ2梽3>π#vœ]wcBqc5~g{h4/"UKP'! t6YӬ bw oZV1 nFZR=62W1Y^RLJҪf-7F+/ټXf"A#"uUl@9[|^3E3k80F#F1bĈ#F1bĿIjx1[bLIf#-eem{bDkӝnѶ*>RcbcM0 :ht?=DlE VwP&- R7A`c C|iUkauMX_Z?;gLu!HՁK-ǰ\[^5ЯR_&7:=:)GN}w6H=вg!u!`)Ug$գwwWpe oĈ#F1bĈ#Foy18VˬVL ޱsv\5g5`7t异Gu f0b(r˄g4Y4,J!~Fʃ3ۦ ůAqʼnY1.k^DMW@ӨV8ڒ(GJ׳z( 1 b-(e y^`s`mJEXD8O@ATSSE8,MHZ͍$* <"!!|ŸŎWEC )1-cJ[AZ'_̆S;RfG1bĈ#F1bĈ#-#ƈ+q`Q (S/}TʹBH'ũ͊3R^kΓK}lTju܌nل uTҪG¾lWgJ5*ƙX\T2Pp l1(@p-9g{S + ̠6q AVWˎ+3sVpVlҗp5*w5choa݁-ٟ;4iۈdqN\c_M5Q)_7]11bĈ#F1bĈ#&KM7u:{8`3aQ.P2fȘpJQgȑ}h|Day*rd9;GXJ˕񦈦,xn/ւG #RjVZTX](;\0EB||\,fr]zMPnqE4Ukqi!7,чЄ]v`aV-kQ[h:<^z]_*ȨBhCVwJc1bĈ#F1bĈ#F|"{3&Z=)vVO@8k0cjJ1? Igʮ\ZƮCcM$-1NjIh \`*XsɁrz54g`ũڴRgh _) \:PGJ # y0J,7BJ}X.@9MS# fak$8*4ДD ˈ司f͜0BUAKPaI[L0P#F1bĈ#F1bĈUp*jL&7/fԪD/qE[yN'`Z2 c%|m7lnk@cdBTÌ[bӴ2Soj ~7)ZZ*ƴJ;|GPVÀhBD!rs^Һ딸XJ)VynrByr|_.Q`8J1H2,70M#WR4r})EǍ̀J{XiErT9#F1bĈ#F1bĭn[&nעLlBa escY .ɕ[&ts/q X'gDom@T8NOI[Ds+ci:'hM@,ʌrJm1bĈ#F(|݃<x]F2bĈ#Fw]%'uvDGN^ew]T!ʮ o-BV)=#!*B$ĵk.ƜHqް#Pفz 41G]hq$c'+E.s3LΘK+Vм3ڀ AʦB*V SF"sJjn$YEAWSޓz TDp+Q8BKCp'ZfP  7|jTKqbZzt4:baإ0,׮Z`C_U+62jKmû2#F1wqCއ&<ܫ:>y#F1b9y|fi v'\w5K7T5ٰ  d M˂LRv]rDB3BT5 Rz|/4pGvCY)S_,͗gsh22}d+FKJ'@~nV Qe ˂ҋNPW ƁE.FoTvi"+kr)Xi0 .E87^6LBC"rWV>*2:D2=0tLPC09i#F1╿Kx=wjjuo['_n(^ҟ =OEFVgϊCC]հWaT&JMrL=&`kUIO:7h  eP[jJ鲺XG; ӀGG1bĈww~g{4x‹_p,^/|pgxw9XOWGVs^xW>>g |KC9x-?|3Oa7VwSV×=θ]_~sNBo4~o|ܑoe/{KIX,Qwsi^)kp]6-X~ 67'5*M}1?j96^h.#AqɘX `BPu;΄´! k0HijSJ1€x̸ HCLki/`kmze^rH\i I4T#F1b5))/C G@y7S)x7|(|7bSN7_]X!_h綸ƘƱ|4e60 ͗Az&uߵIlD [maB&+F З%G4GS+DRq 0 !|Z' x6eA},]F)I-*8aƊB!*BkWM?*ቦ!3yoLT]̽ D{Gְ1bĈ#-}0?Sw:K tpV@]۸]fB ~Z}zDC 쨛R 'yY2y|֖@K T+*($8!MwigcZ[ َq&i(֚ M|PSfiAR\Sb- x#*BkĨ 6;_?N w"3qOs7-K"'.{qir?㚡|2bĈ#Fܪa>k5h^hq|E8(y)Rc}X& 8{/mbeKa \<˶IŵP+NSZ5BPS+U%╡z*{=\LwbPXmm!b+1!Pd }?(ˢ;z]?Ӕ&M*ˎqmafPC4V=>B#"">iD|E;MyRE_"loStC gĈ#FCG/ y/ ^'r ľyOw~4O{.4ߺŻaO'v죸q99Hyxǟu8*g߉]~}0xK)xqwq `wÝ]k8bĈ#nc|-wqv sXNo9x:ۆ;@L{R+f ^%cf8z,J*B[_1C WaLXd˃s5`Mc O"ƺT.NέzMA,c!T]or+-P6&;g`F]VYmݘL[fEaga5Ӵ,BeQ-S@gYlQ'-n¥.׶ /¨nALW M^/>\{/Z3bĈ#F݀y/y< ~C{n7\nΟ>S |auX >p@n9Os w3R TpFB5r-= 9=PF1bĿZo~S4cGJ >O}*]?VF"7Xuэ15Gu G&jkHfORBiJTb5h$E̺)!E1P0PS2X#R]E<@=Kc\+5OXpgJbSRC @EHy ۋ>dvCC}X T"7jYWje)GAf *:=bgFEU@ ᆢ@e=#RT;ES@O阛rr3O #F1bĈ#F1bg?GN^߮U+Wnw>|]YըSEJUYnl?pɮH1n`TH LXLJ \_sp_ymVc'|. WRDzo*+J3ŰdeAs|5k>ȚȢr,5RѴ\;Ȼ[ &SQ1 \6huJdMJR19R,x3'<yD\\଍Ֆyh 9!sc[A”[CbڡH4B:\'4ʠ6@sQؽgBܲۍ !DqQ\~ŮV 8 9aInı q~DM*?Ly;W2[iUʜFO+B`] 9G3!pW1+8մxDه|xS\˲ S9*wvGR:6!r3v L#G8f7 d!x'x\L۱uo΍㭤]kT7guڅVj gCZDV]V:Jĵ!s\;Sl@P#F1bĈ#F1b)qqU7 A@,,{c IDATo4!keB MBM XĆo@ ًiJ5r(LR:3 [k\&4;}-T1u,S7j bH=3ȐD^o +!P2 כ*"FJɸZz܂NrPo67\s-.9%Rm(CJʿձE<`(Z ,~r!lm7s|cͬ;u\)c k#=bĈ#F1bĈ#F3θFl!b dlJB”VڱC 03!yU-4a 5 :s̶y` RZ!gãgtr`5@#a-M +%#_IGls#}B _LH1Wř1$c@,|G<7-)9On;me/N>dE\*F U,w U\íׯ% Nt:Nt:{^IR&PAˆI@>N9ݣ|Ɂ)_z4x=EgVRn$|]ZDrkvƄH9]jшӂBiF]]l'n7VˣflűI'ɉb{lj[p+5z\3nϜ[xeѴD"00kE܉Fc/3dѬ|wbk:!"KcOsTщ\n!DDwF4ѰCd 00<n=M$wb&#hm~Sfq53H n%e֥iP|d=#o (PPQ+uՠPع07bݒP_.nJk8Y .8mvM*'p24+^I' KVÑR22Q)bPrJFĐ|\p\]Mr۹VJ+ j+2]VOڠEb'ׄ۴r)VEǼW ֭#Pup lG6r6bHXmΩ?2Ds689I[$^EvOGFzt:Nt:νpz/}$1F, (CV˳eG.SE"؍CO5b. )*%T<1uCl:0͗UQPX`KHMHRn!AHՐU5\BS**V/Z+\2A BN0\\$) X!)M#!$(PGuH&hμWm7~"l,t&nI~`}m1p ޑhQ1R6 yt>f(lH &(Z֋vo8-nt:Nt:Ns/Pd QLDF0BvgiBEW)Q|WQM\42 AE\g;002򪡺TsP,Q̰RV(>N@Q892J\^#@,0đ똄[Xf>?p?R( gXI7/Ű\VIVk5jfF %g9(P\U+ߊ9y%'qpQaK5hȄ_eBy\g_KF)U &UCTW% 2x^3q@jf˳ժ= DفrCG!G$VQ[;\ ';>l["k##ĩwگKW/m8pnMl?ToMMw.Sclsr&@V =';Nt:Nt>X$%*s#cܻুF.0G_ؾ,:P.4_PMrdJ6E/00~5(C`&BHŻL &0 5-1bbU$ ܾ. C=bƠ-؞g='Tht7j ,t t:Nt:νB邋ǙРbasF<*6vR7D8Md]{ͨ k4(^'UY%9gqp8b`3A P\P1rc0# d/b׳iڼ1ۭ^hZՁRHn XE~L d|ijn"|uY wMmNXUlk:]^cxqk&ܝ:Y"߷asj#-.΋s Ch1S(wšϝ" O%*'h9r˿dbt:Nt:hn^h;@3{D"w%(aӦsq=sNȰ#!P^NQ4 h0r>"%S|Qޣ!FpUUa7[{E 9E^F8rݜNZ~iNњY̵ŊQ(#R a[iZy Fnߌi)%aTao16v!OX5^bx%-Y]!Roc,u9Eh\6\[%m) bܮs W1./z}}x, .A+˹:$vKt:Nt:{|eJ5Duq=y@ʙq(I)3XLG\21R2Fz*41 qc*Ʊbfed!h$+r~Ãlܺ|ϸiv#$Xs++C}վ|`N H31D,͘\!asWv5ܢ[IUAr$3/f!чL>GnnkDhEN+RVJy$k45'egQ+[)vךpsŹw=/𛘧\9qȸ mp,HnZvx6eɛ7_J=kuHGB ӱŖm@̻ϱt:Nt:NQG7(D(nNyTkBUV1jbk&dE#{UaB0=mDG Ja3--WV¸8cFqNL|&؄iT 1*!jlیZAn&2鉨9b>l~RMD\Rv\|~bmI6+¡ iesv!"rJ4ͷb]֥ak]rڶ{N碋:fYhɟ;;Nt:N6/# Ĩv2:ViE(\vǴp8/a!UKpF@L`XgۣpqNx V"qꮊaC  %Y`! -|DBոfVH)-c`dD=Ag:;!䫽}ihnjuY>f.J6\s3I1b(ڭ ^}BA0Gib~ _YiL9U%{2\RNF7yVnu٦?޺ [9Y;HC܇r+4`XΩu$"b~*st:Nt:bqc'άD ڻ)'0DJډag,Onq@d!P5.N`eٗH)!,Ȗ1 23k$y:A@ %J L=q&\{!%,su8sp Tp ⶵx!Tԟ#0[rbaw($j |072-hBC_[ zVqn xUQ&(lDŌ(2frEh-7,۸-a{sSjw+fȴmCC'\d; iNʭ]t:Nt:NsOU@S"4Mu""cItgPѪGdOԁ9eݞK[Z0T)k31KF¸GJ$ .&PmX2 01%TaXJ&i0 Khс Y:Vr=vN~5qF kt:Nt:N@4N t;#4w/z2.u%PraFrJW]jiLfdH!̂Q1 JⵥfaX57 V"V=*Dqj *e$!:a@buX/u18:";1r$͆xBnzqW8a9pFmmÊ(=̺n9b-V{:B}1Oǡwbۋ؜g ka}s{TKif 1߼ܷs);Nt:Nt>Xhs!܀16<׮\k+rIL|iw F)Vfr0lvxv)#A#\1c*%4ylϭi=bJF=V +rkP\i94ϨF.X6rs DC6b`:NU?#kY3ȍk9gyŶF&HS˅nX_?^Xc[g_B沝)nPC;E6͒L/K&tko_X:X Xߖq\Yv}}Pu{6*6]r3[moat:Nt:R)\oɋTJa Xeۖ4sK($4x5#ĚG<'̤n=3"4@txucv~CVQwV'<{|9X5 DCp+ᓶo1roO^3\ IDATyF׊lHzY 1beժZ<8C=6u~ ];W汋v=me-eblλ1kָkc,Ƃ])]VK&&~@'Yf J:~ o-'zΖr""3fM+h*sZa*60粈19&˲pov0ԞNBEZYf?6w:Ny2>Oo5?9O;^zgNt~<#Vb3VfRv!+ +{  14FSZ8xQw OY@g9QPJCܼ|j7)y Rkj"FdyUJ>p]mo;q1s^r=nqeOxaU>w)yLY73p*aqCnfloGw sCWӝіЕX}nK{t:kg?oOv2q#I~~'}LNCx<~~>owa|I$?L?Իt:ίpJ)hIHNt@P0; pNNǫ;Pܸ4dtnGqRTe9$-L7KmEftDs.ntFa߻ кLlmؓHkf^pDTԝnêѫ!k] 4'qİ:"LL8[& 8^:10!]{~,{4QjVZ[mj]35ۢkx!<-" um,DN~իvOޭײMD\RE5.]af3LKzmn %-~=c^t:{x?ysyްR(\{syѳ ?awu>׾w XfɛO͇$Nt~b3%_oenQ2R E2ŽAr2rYP)Aή24r"=9'4(a{lB9YKԘoat}/'sPi<[TWNUtrճ~ ZM<ݜʈ &(t 1&4x]^" DrN.Vd[dwXK^J~_gm?tC?|؋`8W?GM|7yOʛt:νD(3Ōg>E:3c7xD&ܡv5\՗)Us*H]u*#Hp.n IMi\SD3s">ʌ1af q8}kƴbbX0JտZDNDũv5h;0""\*0kҢbFH8Q)GjN #CR^">6`vڲmɥQEmW߶n3yӮ'_]-.y7.7/9&]ϯK)$ڼb:K@m\ӓ xs+oo[r+nO7dt:νMGy?;*pe×g  L>q5s Kx^~G>pӇ#7yWo`4܏}8b.w||)_7_Gjᱷ<=C/ |+>yϻ䋿u/p9wWt:f_g0!cD5]{&*i(F!2euI[PYs\oG+ygy]nA) Wi";to Ą!(u 7}GnkTĵ̖aip\2f[#Fח0RqU#4XI41Orib2ctw 9a,bIGzNTNtZpY-N$,/B6]\ss.m&l'7 w#PO7hX[mǒNUb?v8ɵQTMX4f@JC CZouNNt䫿#7T x0˳x+>g 3?/!?//~/~-oqoȗ\uŧb\|Ͽ%/y(/r?˧_>]_ī~9|k?ɇ:Rom|o3ywI,o}3Oί 7 t:{l3=V9is.XU ͌MD1\&LGD IyjJ HVGbM[RvDAd8zxV̟'daؑ\ng%td.?Rx_ ~~#yn(~~77v:NstuJI5+.YbF4C9rq^PU69O'xU@BT퀑awN .DP UWJ{(RZR %[ B XqoBt8aFՍZ0R"P5e]di8#L4/ȵT:|?L@ 8rcB4AkJJװ%}SDl~)%Fj0/K'Mtl*aJBamŷPq|+UIm;$M!F~W'zw-ډp8Ghˤ bl"b\]Mn£.M\tdt:=]Y|:w~^{.۞NGIv-xoao}s7-y׿_?)GPx?~pQ ɏ~/ozdqޏ-W~|ʟ=>ſ7?/]?Qt:{'4^LmBuqV\l٣:RDnc*\0TwaĽ;D1q1,& aB=QK&&AdOPp$r>"09d"t miQ0O3g7uʹeZMbP1ñ°hHL\znwZܺ)1J+Ss"P0/Kmwkڍmt@ ϡfj|^?]lU[]q-~6#i՚, 9zg{ ߻.l#WqҸq>n߾q!"B[Yf*pt:.&^ǯç~7{s/xWkr`3? ~??Oc/-\`|xo~ǧ"q[L:Nky_{5ٿ;ϰxW&O/| o[{5ow|HrկFWk}?Iz{[H ;8ޟ?ȷ;Um=3?_A?N __1{Goju>G o_t:!׷9w#oⱛo#8BPAu!5$^c6@s.eE- j|֏soIGSa W`4PHyg7=n?(dD3j;Q %O{uJQ<ᛘ-=L1֝wح[0fJwӁ9wqۙUspǡ%4J. W+, 'ہwipqlۡ8/ϲGjV s'^7,,q` Dz;QL.Dz^pǟaU* >?P]1Thc&Xc@6]l}ؖpZYCNtuOOq0w|* <_ß}໸5xH~y_1 `/s~qun<+b'%?qr#?/KuO=qƍ/ryW-Ļ~&~ ן<\+;7Wt:8P KGb:6ހ tcsrM3 {)5lsEAj%as!A˄#9 z#f0@3jJE Ցy\Mr!9+J!č,Y\I@fx;wcƭwrqǸ<>Ɣ8LWdBN}#9;=! #q<[R quG0䔼P ECmM8V|ym]쎂dNh:dY-e qPrM7-fqu}i2g}ǧ!q\=1^k:hp)8@13;RJ%D=g1M72<; 42\f 5$D":~>q-cz,!(<&h\"p|v#X/6ؓ|?jJ3*PܽU_ꢟp޵{P;ܹ5S}TeᚃnvѡFOGX()  s0Sl&'_uʵ#s.(u#[\xF_K @ s~g͓1SggŵWUwH~CB004375)u$T 9~좡2!FrA8yr/,ґqI93Ms]gUruIbF,4!,:WlM9\nN;YkEtߒVpۿלrT7ilucPJQa,fv~MmEŬ 9w < oSzӱE}-'~mwF]nXRA˥t:Nt:νB.A*##[^LMi=y͉w`lʙ!5j 1,lLapi@U9s:z3c !p yf"mPۓ0D nINzM5 B.Ɖ8O(bgA0.)ZQf"솑T2َP!(%$X%';BdK9B)࿛5Ż2qU!Ofl-'k%(Qя'"Y,&\]*c.7Fu)rrm!rhX91@HYH D8d]VI^}t:Nt:N@udP k^'WCKVNiǼF+ ˨/9e%RN# 옧#!D\z9.!T#.)MaX 9g=iND Nu4q(39\55w>v+UGrGcJUL1yf IaREQݑZRI#RRxF9\EǣJmێT4{"*h5Ɓ۟{5uc*\ű5kRG3iMZJFjx]9b;AQkAZ?bc'B_6s%t:Nt:NG !H#e"W 3Dȶ6Q3{j,UB Whh-1FR򏃆ERFuG 4@*!iN6T JF&JT17076 bT AQQ2כe~&@"9'4U_QJ9@qc]{aDZ$# H^Qg81 Ȯ-KNf H*ks-/YPn}xԡ5&Ft2ȱuƭ7YbS)-Fu5odluڭvʶXos^|nQ xG9q!nW"`t:Nt:N3T;(%;q AVוb0g[/1r5V"A94 ɍkso2`7e\;tqXjXbBuխݽ|*icSI ~u '}lڵĻK|r0XJ^~@WK! )-]lr V ">M@lQfwqF:+;Nt:NtJ[Ɣ]P$Rȳa;m@鈙P,r@m8>Nz.-Hr>@)"HBTJ12!_2c:dn0 (qOЁ8"$&9_1Ogb-۲s9UuomVb X9y(Q$"GQJ Eq "!c"Nw@vq?{oUZsØsQˉKUuk?X+o Ū~Mpet:~ JeQxZ.(+^+5wLRe7WJY8ϔr60z HFo6#4͔__Mi(@^!VR}׉~pMi= ckYdY"6ѮZW~/GVlYƧxw+ü{t{C8 `0 `Q\*;DŖ )sHizY)8Mo,fa'oqlz}E)WJPºL =)IBs%g7n2`,Bq WZ PJdz`x|Bu% g>Y -,Z}[_,iqF`0 `0  )Q4㥂]'y%/_}r>cHp Nwoch9S6"BYLb"8IVe- jNG<A=ڮm'.)ފ]x>7bjr^Z`0 `0 7( B i:QF[Gj2t*OƄCc^?ZWDt[ݻvw555}?ǜD/:qo?S< f `0 `0|/FRbYwm94'9oᮗu=ΪQĨ4a>}"Qʞzۑ] m"D0h] +.nn&{a׺h'&7evh{7FGfs!ppvf?sC]y"Oݎ׏՗?l]JӦ7`w:lߏ{ m 3 `0 #S/Pg]`EH\`};|Gm ]ǮkJUQI37%.+^ǿMo|z܍W#/aﲸ2`{ S{뷃L 9Oٶ ^=|Bis@Ʈ>dkVIMMovMjQU;l"b%܅6峢 nz1p:c)(E<8킡FUpƟ{_4M#/ H-{/wO=1;r{ Q â!;"xG|/A/]F5SJX1c-Y7YoD ,~0F@`0 `01Z,: _|][ 9o^ B;pRfmId&0)U7 /_+Xe\ XK:Rʲ]4Mc9a5%hzM)R_x7x_|gAk6,VHOŠmH_ߞhֆ`Ү9{wZw)z8fHHyvp,pmWwIO6: 7A%%[ⅺ;m.8F`wɍ hfNJy{p.fږv t"}zSn\62.,eDnB`0 `0 >jVTg#:a;#IHey@S9)+k D$꺆R~٬c3 թ׾9)O-Fc0[^ˇWөź¹P\ n$TB"nraNR0O '=>bN&1 "٦$sZĝSb±Z)cM23j3uhAe۬(-|4պHiaK9\R8\TË>cwЕc!ႨvGcn֍e[o{9uڅ]T0P"~ve9gj-Wa`0 `0||'.ˊc3L智^\%KFOoc&m".ufgܝu]#Z2J +irC "~A!,j2&w#$-H~fRDYtª{ ( V lUxD!+B wť˙m"]׊RJB[O6 >4Ozi( /VN~`uܻkOIG#(9{vL%QmP9vM &2juRn}D˱ѷoj6!6Lux8UE&:6`0 `0 GD54Eu̺.-OqZzr|Yu傦jTEu3b+)) cmn\Qq)4e]I-%jfGz4!^LJݒPW q"oS_Mva󍶮QؗycP)Sm\6o! 6ߗ qc}](!Fv= zgjSaǢlHmQ..&^ saP@Zc{OY2"i:xqqua&r$w Ԋ5W`0Hs۵mB`m5 6\m[dVj}*$J4Q,S=I iw!)!6!y3ua:gr-HrB͊a)l&90w6Kt) RKö_٬4]H@ˇo/`! ζ= }N+u'\yw7\G=mqw Fybj ƕRk,n\<>1l{闶xhŚcwU;{ac|pd=N;\`0 `0 >jT3'2)PE%u)N!1еTFh;ՙ0iJUֲ"(-+%^SS8䬒R+L9?+k'XV;\~HQUeAUI)*&4M}ږψpkC $R=mfZQ-b"kp=&kCT:ZH9|@nm¾B`ĭage[ +8{E-Y{`yX%=V;rN|w}PoVB)GT=if$mnΧ{n )M[`JF s0 `0 ࣦV.H Zx+4͜`׊[NJPׇF/[Y\Y "4j9)l &dTd?AOO43{&ƒyՋ/j,Ӎs4ŹG^_(.kAsӰ8#<5=G&qֲrXnU7#>!'!fݪ WDPŐt|5:Th{Rm &W pdS6oMyģ˿!c^0pɇ{նLymssWm"!J2rS`مTԬ֐cڇ.mc!:`0 `0 Ti>_p+XeYuEM2˅iN`W O#Ǘ2!e%˂)G$X||zJ k"1!!.IsU<˜uƠtBZ\sS9?0"!Qœ' 2m~)5Jh-N)wBHrDe}T3"w["X IDAT`7z.z-7C&E9aa}V772uׅ; ~>kM^Sq1prG8:u;{8@5%9x02l8 p0 `0 h,N^xДHb,yƪ5yS _T8yJ3)i TyΔRc6SSR˶2Lnk}Kt7"ڭ@; C5\!㠆es鋺΋^P܈rJfc9E|;CO>8`0 `0 GjXMNpV!KDZeBD9qzV-xJ$} IRDk%5cWˑLyb.ht)P jx&xN uҟ]I)ŀh)׮ 4mb,#/X0M5UDc6Q[\Nc07ޛZ oZUt\sŃvѻN/5a:~qCn7_cmT-l}Iw_͵;Jb[okvp8zs';vs=|F~~xp ź8&碔DGe0 `0 C)W1W3"x,h:M31[S͊<ū|ǺA^wrjR8O1Rf؛9.EuyXsHɷ޼؅?є635ʃ@g;jjb6 wFG>Q(pg_ ,MT nhb%ףڎ;@bm'`":}- 8`0 `0  X4eD"lW0߱>$J!q]_FŝC ଏ+^~TgO1=IДbCHgYI)NSj,k~8aZˊRֈ 9ǒqҴUmOE8\h ¡i:TũzwwRê4\}땩]$ҷfTͣ fE f[l}ݱշe8ZqS퐁pIz` fňe_nKDzśϛٖ_=~*]=J[^QDe3{wvb<.|nn@}[fKwQD>i*q?{`0 }/^;|_o6=3ވ`0|K^_|O d 4NȢx- y ,WxE)&N, .Ԇ3T[1AFRrX#"44M)+iJZBj7$)ZM8Ju4eՂJON'˂k]9P-)j$U[I\ԺX{Ϋ'br˽G$m;z'1^[ƭ7)¾ƛX7A"_MC~|FasI24A_~rӇ("N].oLjpz 2DYJY6aZvr0 `}~>sg>//   Zq?NȄ3@O3V(91}0WQ=u]QxMPnEbd "b[rTDPDI"œS˗Ȼ0G2dѻoc6"q{Wܸ^ZwŒ|t}mC~,۰[?>㶱 iªsr\m`V6A/"鰠 :'9vdϓ`0 ny??7{~?S?5ތ`0|Kf傞3Hܘ\Pօ[)uy OL9SR G\q)^hzN5`HƹRݱD'0NR>@=3J 5aw:V}hpJϹqCnୋGte;^A礈PCU}xts:b `0(boy `5}EꂫT.zLSܙ; T1@gHRfK]xHgwm\ڝ)OeSH zs}Vm+m `0K MqH^˅; I"p][wCJIS&@qYp?i8)oԏZk$vw\&r}ė+SgD  iHSFѴI<9=g{BNOє܄XݜNmp1LyfY^J(Tsֲ¡s)k=_]L{f}V-' Ak[]yQ]@MЊQbM<./98B&I҅0^9:ay $6!q|u3zOUH+ۇnWѤ_`0 ߄Gk0 o5tF%T.BIy"x #ψWNk8uA(!Vjݩ ǁֻ'CS<=Ϙ&j]ӖdJʊ脨Pl=vJ1iuh<[jSx\xXާڙyzkhM7iPY>ʲl`,N$KTФ11u՟̄0g-;T..xW7Ɗnvp t~ʋt Bi|G5tqn}mׄlLjWNwbL/+=>}y] `0 `0Hifg@+|w^܁$t/Y8O[L΂.圶x`^ \˶0f JgAbUcX$ **{m2'{~@g|LyJ> )[s_yR>y&MOBJJu4O#S6!ibY`z$ia,wj-q~0*+BW 7mWjvםĉڭ;[nMl6]X4sv^;ίoowAL_W;vş}||~/BXt|gv? xEA9 `00Uޏ-j`߽OH-h[4Q͙:Y<ݳ̹Th›Gi}895x) @|BjXkS45 uGNN'qZ!".T˨kݺCxr&Ԥ5tH:"Uq<4m&6uvA'~M7!VI.B+*=Zk7?ulw=hFoWZy=-)M0&u]eN7qc)F^?{;\k&ۇ܅wwmC'G\0j]`0 ?~(?~[? `0 1eEDY=t 2NNJ-Lh2!Ms9GG*ɔ@B+p;ݍ-\ M%Ly}?"O12r XfVR8'f9-Wvk-~@ifzm_QMۇ6Z,Vjc]#3lyB0V\b1X6bw큀Ǽst!ş 8{ m.¸>30ݽnQ>?o\q[f0 [{g7]~`0|i:QmEk6hZ=uk`vE)f d^Hm@VTbmdđfd*^\ճ'tzAdWRJruz7oD$eJ IJ Xiqa1!BRIpg)D&M]p+LӉu-x%V_[6T7ԊHk&(9LSf-+a&ap,.K83ғӉ*QmkQN9NwgeŚ)/>rҳ)gj5yuYӥrVoل>\iG+sr p 6Rat ,od=R|L)8d,1Ң}Pׁ8,<DŽ-~}< E٣=]̌N~}\uDwIb `0 c`0VDUqmJp[|Չr}t1<E(GNw1񴒬VXKBº>"-K ՙu&'O%1;[%DCUVD+<.:G8X<\.-Z-m3Us |m%>6P[TV5\9Łjm⟨"Ns. L $}=yӫ@ÑHއA1 RB;9YERAӃ5+8t|< o;`r95"?iVK9+}Humsw2̜g34d<=~~'<{S<~e}yzbH2%Oo.ЉK^=~J"MOVZn$/5R^+[ |RQ75cBsRX׈vzЮm ըZ)mܺxx '9Qkm lup'Cp{6.<"0k! Ucgh=xnq1wČj ߰n/i'm#E18v|FS_=8qc% \^!hv\'}h8 `FE//E/_4:`0 ?9c-b:MUQ Z te sCu`ɘ^W OqBN oya:Qk Ftqey|*+izFain֪")&E$*V0)VRyJnkRjĀpQ|CQ$0ׅ pj]$Eшy5 ` 9CdVDZcUG;d{ ppvZ5;c:idot]ĒF\x^Bi[9{\59no=$e@{݁Ga0+K5ݒKFmy0 `[  ݿwc|S?Y} 7W>7ywxS讶3˲$"ȔO?RP}DVD)+~]I Lsf]APjR+VFZ9bo"C) ./y.I3zETr%5P3բ;0uSDqHhj\Dnt*&{oF<w FC !Cķ kVpEZ{ssEZCԤxHo⛫w񅰶MÛ ^y}ݗ`ѭv?b]tT`0 u_O"W}t7?#8 h^+/~~O$M;w/}/񫏟w7FWzu_ům||oFQQI HeX54erX1oQ֤sI~j㲊kiL:^V.ﱖGDRs>!M'.XۨTi q ESŰJ]HP ) 3hªsr3I [CRj! x-;,ahH =Ne)$Mky.@o0kD.ziwx6Dz4z7b{|֬`VP[{ T }ƻSaZl77~{?#( ;!9Dٮw0 `Ǐs˻M w?ȟ7"./w?3 9g:>oos.}+M{+_},*|/"պ>7x_zuf; '*Aܰb&u\AN`iRD6o]"z^snk{}3 qU/}J|1M]ۢ IDAT/f󦟲uǕc4g1*Ta 7ƄfrK`摦eJ07뙙^h<4ж( )1s q-\;FB%] K( LU3NʲLejj-ڬf1f (3U125Ma,݃Z12#[V;nQZI_Ktpd5L4 ]~qFIgV[9;t v_!^s p Ct:y}l|l8 {wbNaڴS~b-3e)އJV#KA>5 K?>"'< {c^_JR` {2?)#8 gHbVr̓Gȝ_p|+l~_~t?wG=|cdzK6/mK96j:s잿z윭_-'a.u:D碵ѰCoJ,ò]2PEROģF_FZc FFF ݆Qz"ǪoP0 ֺqGT|C`ute}Dw"#9&we"暛qxܩX!Hr&b#rrF<ϰa1د8XF⻵ ~" C=쿤J4=o8 x_N~O_7}QιdQmPFOTjto/S/`rǾz3x0,3+yĚrk9̯!G.g9rOIZ~v>cX5o/c+SE.-Db{H5(jDm GU)2Hvk71 e1jD 5G gClMȰ(jSͥm Bq؇ #KPXq;UZ n uzZMS) J7B~k=UMlbdCChSZ@]/gT4K[Xt I:sԣ?xQI뚁LQX9цe!97T2Y E,0V"q>Ĺ|ax1iY )?033bDH΋ѻdpͽ㯟I7#inaSJR&}C& *KR"Az@XTTTTTTTT#ocx#89'>?y!Y{<;soN+σ<6~0~o.50>O~ 6 o4xfN9_xy{m}k?$Nxy|P,yO5^?`EqlZ;ڛf5kXaV[ l慵r{~#r;\v1_>u _dš=gyVqTqoV3V=|kȏ\3ņ#F wWkN)GNeנCR@h8,21;P тxESU#\LEtMh4b "A)TccmPzHCӎ 6ܧk5ix4u5suj4H_bىV#G29+ipcfVQմ ml B׶m"*%Hd3( "DT26{47di4b7ծ]j"mXzJqt2K@5)NTuw N6+%Ե"|35Q*0CUxs,@ dv*6$7aNT[Qun +@ 6px#,n_|QFK-sI|oDna/%]7pO8څ|n9=Wh>`fX1{_]>m;?k^I N:VjeU!߅~ZoO`/Us9yftP㈇c.+ow_q?ǟ3m__ew~ljEpܽ& rf8siixg5O]5ܫY,)yW+9VE.^7J'UoKb6\X ,-2^TBWж0fes+AǦb,,ciK7V6-J&,6r&k[L]'rĐ@!Ďhhc60UOa<(G=R&4F7B՗ he[ w,cð9z묎9ӱqmnxqn^؉Hq=y0 !7ND,B(:8}4c0tPLĦnr\L 7_d^I>zEr=O ^۾0}/yɡo8s8)Vw;Ž0ci_OW|S~{.nFm9w۩d>K>!ˏnWb/p8jAV<|ә3+n1kFl M =i#_9W{2Us ym[3ϱ:/V8|)nhsx S{/ aHFmFf J#|@*2?Fi(1h:2"]".i5>''%\>UZp 3h*S'5hz,|,uch7qf:|j18cH:‰-(iaC3R5ƀsё---"C,f;aܦM#:AIH1c+.D5+}DEK f0pLE\luNdt2xQ雖X+=lZwqZRL>d8v]aw!C1 M|swϧ/T l:񱾉8F%K/@v ]2]9!D~ϻqD)&~|}܅7%|]>0繏;_1poKz73x'5_ _ơ}Za +*94oqM+./|S6Y(~̙o9}I|lQxஏg̝o7g5 \?z9+:wG{y=ug^i¬ XinɍlHv^gm˗._DWMυ|Q02m#YD͠3q"KX7A!h ֢ThxTu m&$lփAy(Pb h$#Qjg L_Ƭ$Fg"VD2,!4xS?D5zT%֔\XZs`KͶȗ"!4N#RႡM <>+B !aŰ 8Ԅyv2h? rLr71!jP1&wtp!M(aC){pgZf t.J:b\oh K}߮O'b?_2ܝ;ty۟Ϟ1{~҃bbnܛ'ӷplp#G++Tpf8|xwz-qfN^ISx汫Fyù7?́M}o6,oeZaGRŸQ`CicYǿ{lpʠpx 0nΡ%BT96BJfFbJ͡m *3X#F_|@J hup^1^hDwcK77FxDǰ$C6.AM7R]=F5;CM#]QQQQQQQQɵ}k)WɈ1D*\?cM*X=|yB9oγVݕ&T8O*m5ȪcxCw)ߢI8VS71\1ֿ}g.Y۶,d9G=9g ~Yt<8َbG>cJoQͦ?U;zC}-5{!}{9t3}b=d:jڵdaG<>[\rECV~t<uxԺy>p,_X=vQd<5zT|2;)a~sN$pнq5zNrGݳfٴ"l]Ͳf:5 E'H&}6-`  iQot3 a .P$(7HgJ@TJJ@q[-}!!(80& mt%s,4M64M1Kp"b-v;{2#1xPfc]:\~[\5ģT765mjl3W%.:RjpJ)kFk`֞o28ars!SF9' 2{7yM134c2#aה(L7'sՊ=qO^tV]^{~-/~g8vn={WKa^?t.@ť#C=y}?R~[EENN>Hz_޻M(D`mdFiY SpJk1JÑiIU )C\cƘ/3g;8TpMt;9u2B)e%:h>x;X,(.'+k읎;>_0;uw}&a8׳6nfhowioO|G@%{ۣy뾅9ψб6uܟH.j"J|TaLPի@(h#ՊE-b!`Wt(qC,Y>;>vR5/M!zމiE3[UURWN}kZ4-UUѴ-z$m +DG1Vp6PW#mjxi S8Md+3NBma\s/P߉o}}<&I"mRnXA`bq[AFnhmM28l}c2M2H-+ݾ hd-t7˰O&\ybT,뗁f,)`tMmfp.b35x1)p>L8ڴEo80Be8%9K,J7zwJk]j<>,9ƒ-|戲JUe Lz(lcYy]w.C)********ڰa^x!g}67oժUX 6^{v5ۼm齏^N^v,***=R۶u9ԔTԐFK΂÷@nC2$f8O 17P!",]fipmHZC=ǻP2 b\=yx}gd`0oxtsHP/=!dۤ ii6`H}D7`.:(:(R%@ AD!J Q ݍ} ƍgw[\{hLTp YP!( 6BPZ<251Sx@ōVSkQT#aZ39PUk=JmMY^mf+Jx->1xRKEնmvƸu<莧i~`-tT&fۖiWT(_~.(|QE&3;/¯STV]qHt"λTM 7X c."  43Z.3ݟ5{ Æ^XnޏsH5Q$ IDAT_ RL%+GctNE5xQ?_W::B)hcЂձH6->Td۶҈Ƌ|WLCcet, GD8I-a#3FmmW냧r8s9Ń(HUp&c 1HJ)u<#5֕AʼXk5}ykYg@suMjsl^A"P}fJsq9w8d斗|Z6Kϝ,Ncz 2L{ZB{h>xE1݄Z/ <#1~5XTTTTTTTTTTTTTTt+Rp,-- B!Ѻ Y`ؔmG3e@Kjb7D@#J/ j޶4I˸Y AZkhv@SU(=sy:f]U}U]uJKQ_A *C&Ma^3:#:25=Hi0F#A "2J bQbTp-gEdt]_#ptyv-~7.d1⡓?ή9bksѩ<\ݬHn[׫I3 b?ߝOvV|.J4j +WB`۶xF0v qisH~M֓LG߭G}u`a[XX~ #1/ ݖq-}Zϡ;1bg 1c*]G(htиiZP o \8Nk > vvmS76i2*Ck[`XAhhv% FAaF6H,vUbǎd(l۠$$bSL%)lS-ǖ* F=F ^9mL@%sxiS+F&w }L盌F7\pQx".ȳ hk>vaY>A|MlYtpӿ_1K6!OP&_ yrУMc%jL(t)ǖ0LO/0EEEEEEEEEEEEEEEA7Ƙ FkMJII(x+xZF@ctMx-xޅiMi-`,GDm1FT*Уl{(ULJy;[Oc =.9y8Wi ^]B,. "a%M#РeGcR.vB5_t⁈Oxn<e!}KN .VH HYd 8S8D!#±&<p=Կ-}~mruq\Ua%PcG #X<f%`]b AUz]ZBc6([rE>.T[]n{f0Pp W8ފX91ə1ZaxH!!;ǒ݁ұ(F EH549#B9L+!:NiRh&}T+^0}:j"x1_ UI9\g1V-Fe,~v'ysXDC\p߹z ?P)^MDvI>fn`.שtO"Byaޛ5V A\ $!*ŢsCd.YTTTTTTTTTTTTTTTtPRP Ic|p68c}aw=J!bPE\V*L ] &"(S +PcײcؔViO]1:Ъ25֠ہ`TFFM\f;WsG\4!J!,Ac xQh=[{{!@0mLn]ZǾ TLz֦ـ40fAJX*eZvEZtߺ+ꮤ"s0hUl䏝v]+qJFv{8]Hrzxzk B1tk1/#xd1,JHupًDN'EEEEEEEEEEEEEEEEkΡM!ND%* Ԓ"mm43(gm _zZ.ٙu!X HB۴]lZ (E[/'1ZPR$ e~ m)KKqޢC9v8.ths.6 ̃sTUR2̀d.\m;g+8QQTzQ3x?ƹ'/gӅD1hKt!W=hXq9f<{'a|]wٕAeQQQQQQQQmS{lY_I_җ~tvGǹ|O56MC 4vxPTa!^Yy֧2TSA0)m;yۥ< q[Q~6xBƤX;(( b&Bt8'-֍YҴZ EW(8 ecZci&;+TpJCg`aqoØ>LaTwB}T5BDb.F;KCr9Bxa7;zL3z=lνLE(+r> C@'HHBD} ;9A`(ԝQk=ᾌovڋni-3c⒀1T$kǴu04-Z XdF8"zRoEg[mJc *T/80ZEFLb-&R!&uN(: Gl챈EAcj@g Axצ1rD =-b1;\2)mp^S"J:)($b]ֶkoǹ,Tt6rXxN|W cm,1xD[9:h#,r͐1;~BκX\qIeAaƓ1|W:!ufʫl3A.rybvYi$Etwvi1{h0ҒSy~P\!{! A9udv?>-28r=#K܄;qxʠt:>ŧT"Y[E|-_NMi:.W|Ko3ysޒ7t8co쯺p5_y˟=WGQQQQQQQQQQQo@V*/S8&Y;!0g-uջD4hSR(U!BKӎ}~ 48r-5T3E]"Y5iDJ$a2>GE`m>8QTUt,j qӥfskoAQ2 f FU( ӈ1XȒA,.mb5,,]C㶰n%%_K@BdnTz%bf5(m҈lV9l| A:Bf1w+$W],p}Y};kEB o|BnAGfhh A 1t̐2[0ի8 ıoHOƍ6vth,?6%{.oyy|y|‰, {<3|KYk\y_g]O ʧN{ޒ+܃_0[9?}']m|_ُ̓f^Y'ȁOyo/|`+Suk_&x6]TTTTTTTTtۖ2m#LDh QUeĄ\`bJ\ m h6xuZܹf8tYWd_SG.*********%߻ .t!ۀwѽg,~Bpx/fJ@Z-}FK0FWFb4@۶LM"F@j\x0eBT'4Sh-h6DX{bVXS1(:_.͕ GI_2&xmױц`>,ul@k}ʸ* 'Y L7Yt"òar7+[f禙_"m.\@7鞗ɯOے>$НO>a鬧=,d"& ]=ܰHnal˹<(1ޯM>;G@= g'-eε}roG}n湃zω_7\|7rysaUs<,PQQQQQQQQQQѭLb6(SB4h \ET <[h Dh[(RkB,C)a8fZMT,AWK9g1Z#BjV5"4âVZzswp&VKJԩsYj3:Ga7.qBRDeTU&GH1ng,qĹRYy_[xweGWW'盤պ"FvmWg ]gRx2Ԡu.jpMrw`ٲt. 2)lSX&JGrIH3=p|yPVnη <9Yw?qxS^?c8.?M=ײ]OM&;~Ox"Ga=ḱG<(l=}}c9qpOY =r }" ݎ-y~1w=GqZx],p-'q<ku^.^{sǽײv;qsy vzX_ߙ>c8dߵ s{8oLo|:n<o}n;Vbծw3[h/ ~":pO'z ͗_8p؁v7v[e/{v>_|m`qa1^ϚUZݎx ;kY䏲WZs=֮a>s?|_gysN߸^'5׌=rwSi&z xa=O敟n╇垯?}^܅p_=`=ﶖ}3>u|}{ݗZ}?qk"n.ֳvc<}&vv߃ ?{OPk-YdžƟd7~/{_9O!G>kװf9-gYEEEEEEEEE7ils}?R9`C0xKz6)Ѣy.(j,-F.vBMJginI a`2t2e'14Mu e#ַ8 % P1ۏ5#`*CUWݨ:hөmBv甙TӌR׆7t_hz Ϡ*t3&]v mJi^o"xmu(DHE"x'ӓռ7ihDt_`EO70>7~Ɔ٪ 1qv!D$C?(Ps >B$a>&q 3ېZbx?^}-{^yʇ>8^x [}kp?}X^uCy[?]/S{yZ_{ s0<`W9yG׀ k8l4;$/_n^u,?<Oo~ֿ}̧̍^r^Wq_>oO p;b3Eޙo͜\I0`;D{7}w_⢯\i^khv߼uǰ܃_,څGS RUw{tzAAPPAQb/[kCc7+*"[L&^kÙ{c6t o~s]3sξ|Vz۩~{]~7WoTKߠW/5-^˵ g}WrowZA IDAT=#Wu튰sɤ3z|.8f3 jlgY]u^ iSx.39<)lR\7Zձ rЙWsZ3⦳e{l  ;r%gkƂV:ͷQlEZ8_]pg|ӹat`&_lM{C9vaEkc۞psx(3MW |2ihCNS`.|g::c+[؆0t[ԌdK}o͘{p˾y*W WU8t 遹rʕ+W\ִv@XŌG)цІhm( +LAȘ: ʂNxQ|k1`LEi߾=;'Oe1̘.~ ٢a)7a2Wl[}{*,O4\G>$0Gya;ܦxAWZѺگ?w 6u:SRБ6afMz93CK@b6f>lE%)%>3Soc.~_EG~sWYr>zFe;Ż|h5])~V[%yyI:n5͇qYǿu^U֋/H5}w=hmԍu+> hZBdI o ]*n6g\qf?a?:{mwz.x_mJLyMF0 ]_МA[!1^ >kϭ콩ćS>n8mҟ6ؚ-7/?6ӱ`Y}߲m{09W2|y_+rʕ+W\rZo!IS~2N"7a(U()!l+֠V & 4b Kʋ9 ʥ9J`CL袲4Q 2w7̝7c4~ϫr1 +I-vI% ň#cc 18gL <<ܜ@!(~yrɕD"FQ6WJj<~!*Ls&M:&-.Uc$ ȸw&qŎ=ϓQFD `2"1i&9'*5͡sLž4w0Q'Pr&"K2Rge ڋ #ۊqYkxr/ڙo#tZE6؊üZ7'sEMPr)[gn}Z;{Mt;[/yW.5zP(}1,UDG, j ⎛s9mVe\WȎ2Łmt%憉p?e.IExN]鵳+9Av%,I󓮳EHo*ԗ<.9`,nq㯙@v7lWe&q%-qF6W0nǗ>n:M[OD,x c'\b_Ӂ z&;g7?= x{CŴuӽ{sK HnmͻꂥqT߭]{7׊`7n}#?jڋ k?v}ҶW8}‹-L/D^$mzy_PPEύ7]z{G5Tˁd{%&XmŅ|a>o1f QV}lW^d_~/FlK4O'^gٲ"|Or_Λ3 بkG3`5 :tҗ=6f['j^>ϫϼ)^8K}8q<>[oZS]bd?:.}0ʏ?^|'.#E^Mظ~AZcKcMfdkڵLK_z^{S^O^LqHK6HMW0Jl@;徾J\rʕ+W\kV"f Oy ؋a\jh3&uN.ad% j\,Zp<5VCnW5FE@@&ОBU5GT6PU@ dLn2O(@DZFP(8Ӂ5KeQ~KW0\`B DahBKA#"LyB/Bb H[O|S7eDЈGQ2U()Ke.+Ȱ{<)]!Y_wP) s*%.mӹ._D)XLZ'ͺi!DSz -(K9u#ڨ(D^&qe[|\2rrc.9Eu]X㒐TaEZ!`w0W^<} y ԁݏ YN=NMLߴ 6?cݟƲ3espɣi9(vذb7|Rބ#\מ/m93O)\7zTuhOv<Ofhg# 77N9t8h˫7_죶rGpпrҸ}Xv٨%y,Թ#DzGqDz=c2hPGҲu 쿞gn\^k5.ކ5{Nlҵb}eKVZ\|BZôz{VuD;wWu)Wn~.5w;tJ}VQ׊U!o>|7 ׹~+vަc͏bhSfp%]>;]SG>?^DЃ wR~Wol,n[=fF^tS9bxw  nN˖0y^깊bn/:,|:몯rv]ưp} ;wUy9;NfgqȀ:>5sRl?y = ٗοP2=~;Z!iC93 Oډu 'GrN-%~:ã\5 &;H>忾?}%z/xkw%7 ʕ+W\r5eM昅{Ct^ b`=q (`XӍivEX$;GX#- 3CYIs^L%qpǴFmE^[3kUt{sCKΝ'FI1]wuEOgNOg\U-oƸ?̗܄fCd]h W]tWQUKxS;e c"Gk'n9Gs?#mكM'e߳T3wK'w,ڱ[zDPr- ږ3.jS梱1-lN1~`UV)7gᔽfiކ. ({yŅ"v%UO}?*ڰ'rڕ+=_vɿ91/P4ԛginr9r7XZ#3}Wu.ڡuX/:Sݞ\Vso8}/*Ѭ A~w)y7> o8/ Pu-Y`vRpneMwg]ƅ<=ow2,Ay~_-^V-;SW*a>!0W\rʕ+XB@C BIFP]v!)Z6@c²R*J!h]ƪ7Y&1"Ea֎(FF#褍b hyPJ])5Klˬ1뮻6 .p#uIi!БMG bxvq~:َ!Vn-_e 4gV!֏}a4G"¦$1X2?`P* tCulbLL{xt-S(&Lbc~lD:ç#„Ñ+Wݲཏ^˱=NNby4W\rʕ+WF&i&YFWCH\lʨ # ),F7% [LJ:HmƵJB){BV.YD܃ax!aXra#Tzj:xFZ)SSӊ@]e4 )BiQiQ}I烶er5)Phc BIhcD*,DƱ"RTS_5 V~ɼEטuʕ+ע.gcalsMiF\rʕ+W\;%\4ryQWkxRspa+@(q/(UQS:h&$Z,6&Y:8bP!K)QHTR<% rU^5U6TUպ^%𜙫%C, X aHS,dbp磤":0 M,F;w맰h[F*CP)ڄd tAH:%]5cML7nc{"OK[Q6^6N3[AknY%{J1:'_ Gmn=& IgL\ŗP\(%]najg\rʕ+WF\rKe868%&҉4.#ں9vYҫU]QB&]F!)p%%,r,"='6s0(/6-֣ ( ~AP2B!9F)%6 0kU CmKGh4^Hmb;Bim3#RT.JJ)cmH.,,q[OQGKTtBR D ťm#$.bs4o^Ϝ93Y?!e# 񈾗*]. a{1KU6V(en'9$ y|"=˔L r~b_<ڳ.SxIo˭;ʕ IDAT+W\rʕ+W\wZ A~dcZG3A HMMc T5!}$F͹1w2!|(F<@K `Zii(5|B_p"x]t٢<8A2b(i'ĠIE ˒B|k h@baZd?n\jB^A#ቈiY mWęvsR )vZ)Ԧ&Qո17m 4PJ/lKD5bi^/$s}W$s6=%'sEEG9MµƸO4t3 mCN,3-٦aǘu5ʕ+W\rʕW>c4ם^kµLzi-;cwS}riڄY hpܮX,s(5CI'8[ЄkJQ~[i٬=h,% ]YJ;$̜y_Q(($Eim ͛UQ~5Ȑ@7!"Ī%n]tX܅BEp"#I!JɚSE_֮[BZw_p4)@ )-:IKA M] )986oWG=YwւIS r}iF):F ,HOalv7P% o ʯŘ"4Y8si,YoC#( QZ4A*QpGC2kPI/&dFYx r}Ճ#!!XE`N K]9[Qk}bf*rKdd9 M^ L2gR!d0K]vi;/Ww,6VDuIfZ~mUjvt7*)1D$8}X 9: o̕+W\rʵj]3ݽ̇Z+w|Guq}3e(ZĝW/\zt>5 0\޸d;ĭs2ӧ^ǶU˻>=Np5V=]Vy N|67[ҵE5U kwoViKkUC ݶk_&sפh]\e~|v.?|{vw"mW =y>v/zv9< Dpi8q:H-';՟siǰ%yRYN=93?:z7.y^7cWKfs&x̜AicX42)c%Y~xY~o~ 5z9} Y K5j Yh{(rZ*l$|EJK #kʆxқV<kGkJ UD8~",AXjS*5Q*AUM5cnrݜ?% bEր"F h7/6)fd R9JCΉ}Ȩ:5t2ZCF c#p{Ehe{mT4K \T@cl&!ڔB#I\wz Duf>kulQ}Q,ɼA!t{cP)Ŗ8TJZ 9M<֊ Mdܲ6*Xqh0%9h2q\rʕ+W\+Z}fС :ͺ6 U[zm=}o Wлs+j jZdSK xN"~6ݛ jΣ޷UShֹ?{_ On;P sɕ$l߶B vBm>FkZjZwc72eAqW_8r~tm[Oѯy{]3.=p]ZTSH'*ls+ǖ  yZ4T7б+xf6|mۓ -^ƚ^g؋41qg6߯?Mכnxnf櫀]?O䰝g3•h\)9%I8vĵ{k%Bn`a$?DqsDᜈju1X)U:lD0z<TpcPMfiZBJ/9vY5(Tf/shd&zsavo3=te!x&My+W\rʕWP31}֡h>ueq2m{yj 36όj09^ћw\O%|9c~PWsؑwwOӝܯz#Ȱ_ʝjICZ̏r15l.{`ZO{ ?]MG>i$Vz "xiFĪ~e{YޚSpᓫ:i.&]ҙ (΅;$1= x2''n+5h5d?cėsهj޹so/M쪶>GHA=Obʼ;Tn+]'f?`oRZpwL3WyGCO5}ZkSOB>_Q=,:(Y@ӦXJum( Yi8ihb)iI5keo.b"&bݢ7w_yQE6nzq/)Æn~eRkoH^65\5Cx^0xËG HIu5ܲmu\VKvtfj_rIi}c4'_I4j#$G L@g* %2T%]F (> K HW+F#iQF$14a+6b<) C|K祟g9TϳQB]쥔kGvQgDx%7"#'kr锫JXW7qϋsMq$yG*QkN]{]gSج2="s,o=(s줔Bu\ƎF=rʕ+W\֜w嬳z|j4eeY[3v9u}{/>s Gy8mi)UNS[2 (,{ڟrZfڇ2]c?iNMz]!| oקo}h:#6I-^е3ۻ3[Y"Bsv h3),~ȹۮԖ[y?[R,ߏbk8?s:rŠUx4ta4s6ۀf^GFzp9<OunzU f/PQʕk#^O$L 9մ1(!Ɣ]87P ?AaXX^ iE@Xd1B KJkLY+|O'2L)6 )PQz6fCƋT vк•yQR2YG\6:o$0&⨫̀B&;ֆh |GqWB4׎=7u5 Xtϋ` X:?ي08QZۤ̔ZkT\6R2sA!:GR"#3 rʕ+W\r -ߍzq;uVM栃XRv)?fċp?r˹d̝ &ZC\‘-1:N$1ZTB*FϖmRLA1(@#j!60=0&2} C.F6smuHdah:[1z\E.K=aًK\rʕ+W\~UxwLZ<3BUi.ua3q[6>}23NWMM6پ/{wۗnfwm^>[̥۟C3oy"!_={}8r#l>S 9nW{)~7x<_w,gDw=A2LivzιKwk=I{'#n?B>f43Z>n hϝ5T @ˁ'E]N=9GMvs1JrYy$Me;JIJ2ʏuu K : POX*!ēȳ5mA,aٍ"tD*)SYsY|߫Lhߣd$E1 3m46ARa}7WP4I:bOIDdpsL(p06c\[r JJTZ6Y`YKԂ#!((kL6<P(n}q[1K/s6L6&Z!1Q5xN^Wb1x$mi9M;Dw}-crǑsynDYsʕ+W\r1Nla3<6Ka, o'Kfo; ]ӗV+lƜĨk]e)ҿ>bNrРV c9};أw+9a'N^lsAQ}GN`&Y`F=avs4֖9-Od91>bݕua nsݔzNܕKg:. %KDڷY`Υߊ:5[o.>ȤûD~7.܁QwY:oÎǎGq騥&}=JspVdm{n5'C Zȓ Dm7[PϕkMZhQ3kQOMIpԠ.9 JE°Kobf<|4VB@XK`GWƯ0Š.f<~%2q ^zA9L:!1*L~„Ba#–dn-^ &J`´B)| ^$vaZlOmE{RM%hD@Yg"S6FTy --Rg݃64ZlMhyQ7@bnqڰ,cQ̙ H? $ef?a0Z 5gc&q Xffٳarʕ+W\ o'"ׯ ͇g{v/\}rF IDAToO<r(l2MF*뗔_F)#T aXFEIry!_硵AeXRZ%X!1ƒ|_Pn(F^c'8fA, L 0DI!oX  L#Ɣ(xHYS֖Ѧ kC QX{EBPȈmAʟ /e.SQL)EdtVI@C E<02۾󲜦ވ "bkȬPQ1:b=eD{J7޿lZT%3Q;J9Ndg /ufG\rʕ+W\rPfo5M9>9˕+sij\[8bǝAK?['>g2]0Q< C og66aD*pEqp|<"JPOQ$KTԮN_t|5'| @ȖU͐Ca%@ Rddj&OR,MaT6)cM2OJ0JFb("m * ϫ'H1iӂ5.X#Ql^+MBӬGoDJSt?[B=Ux~ Y4b%^}@,n`lA+,03E)RH"E) )R;M2VF5DBƅH)rF)_`^vVcq9Q*rwZt(Qn62WZB1 <3[Gh];^)%ab d(=Wb .e2rհYuROD!u#06G$4+0" /M0Ze Z$ؓ$\=@)a% %*hm/|Ty}P8pU;M7L$8& /JʤF'`1x1#%ZX P,}E 9_Rn!)? /XXJX'q(ȧLߊ}@"E)RH"E)RHØ<ŠLBdcB"R8D)TH%F2>A1ڑk.EFDZRa˜_e!]^DO ^JYI`Z7 e!ص˘!zWb.U ݘrsTGyYn@VX%TBIj+ME x^zNLLfFZ!,MȇyyTBn !QIɋvn@+߸< +P)3Ҧm%/uIRYޑ(dZJ12Ium@p7"$R5lTW0V4%Lv<gZj:LHMU&eHcYxI2[r{.»B{^h{ؚiyޟӄ=.6MsͱK則gxկةyr4_L|&~JM8n(EɒLwؗvOrO"E)R4 uS%#ǥ%X WOJ&&Dz^Q$HD,օ[੦6SЄaʆ/ѡ Ss"5bX+Q 3XkE!U)x,N*.1Z <0 EM@ z~0tbt}$]HeZkxN2Qo䙱d1ƪ귘<Z~lYr ͚gQM|aRd.VEJzϑp$ıe98XG2 SLW H [[*N.MtzIH"Jq brUDZ[.T<2ݗ>rǰ8k)Ԛt;.Y̝6jF_2,/_>K֕mN{yp B^H}=qrfֳEsugY׳ߎ&~_'so^㖓fh׾3v=Q R!+ӿ!HԚt7|38+_#A)RH"F`LH>wbN).kf- Ǣ h#qy8$h[j%c7&4y(/r|Z84B2@eaJFRA@Z#2-~J5A 0lH}D!H9w:%~~)«9%oY<)B2 y*:,*aU=;̻8BT8QhA$eHEVHV$,Ry5Y|]KpPoaLĹ)˧lB"ԘZ 50 Rk>":H9X=w8uT~nrTQ"&vƤ_!|DR۽Pնdgqدqqg9&a8'Y>:OEmcG˂,H )NރA;l">w/ƎaƲfyލC_+gp׉r[WFM i2n,2iumwKlt#99jAt؞Mzs}oUl)RH{(rڔó8AI,a"AXaLي ZA#(ePRtHc#"T ˱EXԅE!T,V&dN䌉Mc\K,V)Ʃ !qcC'3Z"G,*JΑ ͕FaB6uJ5!:\`(pKo.εKHaL$בګSX\$!"Y j2E)AdUQ BP3: aXGntRy%Θha2Vrs{1k;ap%ý4l؃NҮc/zz)GҏMWѹncH0k4 \E&}Kxx55lOJ*!nz xoQ9|9Nw0ݪө|T/{՛tjGU xx-J9[˔G.]ӥ-U]YQ}Pvڼڵ]^li:aa4^9&1Cvۚұ][f̛,_4G#bdNggPܤ٥ߦTUu.ùY9ܾo;*++i31>z:}{m9}oBUt;'\"UQNMWշ57bi{SڷmGk3p5жʶ;sGh۶wg=Χkn׎lM`S}ϹM/:@pc2\;!=}6iO o$cF\wؙ-Kv;|~*幫OcnImoJmO/MnGty+}n7jRc}ٱ=f>>uӺV]NJ?6l`Y>~.8nוҡ@zVrƁlݫ#u6rĆ_Zn6*^8xh>˿gJ*+8jT(vӉU]\5z6h5n|V3^~lUš}U/݇֕'߽ǭX9&~<>]:Юm]̰ UomN6N#-(ؓ޽vW8['b=8's>x̋sD"-" Zu}NEjE)i7HZFcǏ+W[PAƊB Hg]EĨM(pE1E4aƛtCغwoW/N 9-|:~.|=~_),WƾtӴMkXqq fn&Y$l׷Q_>ΨoInlW{75ȪtX(wF ~G{ڒXʯ9d օƃ9W:E'^Eˮآy^SA):|\,f^Є6RxW̫+}Ve[rtzhٛ1<2ۜ6[bT?v-oÛ8Un}ȸ&3C4m݆` s~CvF3eX -ZL}x/{ P٩ mAT\|_ΘWВiږVu,}|5e)jFU* (tʹ,ajtfY2wKƨSڈY6ۇ̴ٟ2\Կ+ L,DCok)/(kәM+3:*fьEMf9?r*zJWS~8Dngr/[Ϥk?>ӊ]ڳ|$p?˗mIv5Y;2v5̶M4o!qeXɫ8q*WNeV4]?džtzVX{ gg*kAe>K_?MZį[mV 8 FϹxlՄyVF/۰|x^uVإy?swQTu=];6GөS>`.}ټ:3qunڳig O9da[1y8VT^c1FT\X!MÛSl ڶQ,#^B&L˓c`n=mWQ+VФu3yL~*NXі79I}m_Cڥ/_{Ѿ7/9w[{>y!޾h _/_Ѻ5L{;Nx~ժZa}M`҂QCKx)x=a߾^"E)R@PJEdT[L`Agu6XE8\(0M0B:(mׄ k3aEcJ J"P%FOc4SXnP91 8&:`c#:r$Dh~ lts8ت@[UˍDR5!+'vV_2&m` :qq]>Yf]QA[G-E(ET6ƿeβ\Cq$!qF!)N-( )NHTDQ;,7x)xR2~o{ hW[Q)ྒྷٵf0Bni6N])_iۜ3|UɌGyՏo?Xr%c6S>3>>T1x>.c7ύuReoAɋLSimR,W|K?2q}Le <ԍ7OX-ߊK^ydR^v^/SN y "{| h{>dȈ Zgaʛ/Scx7[%Ϭo,_8;;vƿ|HY>y.s|y#*C9]s4s=ffϘ=r󶸄1}7d@=gK0ɦӂa31Mbv^{yo,fMë$r?66:KoS]]ĿH7.s\YV[^ƫg0}ZUvސ= ;Is=}&͙F/W멟0Q5 Ozۏŷ~ۆ?qӄeNGw?ztx\ƎϷ[&p70~ٯ<(ߞvoEq^.zcL6\͠a=טu޿|Jng<RZj?τ۞kq9g,/=D vk,2ꏙ>9a<ǬI˧|D2MoZMUt_)RHG\.>1ffﺚ;!#?PN ÂbD|WN' 6AT5`SɈG2ZjQL0\_IbROG>QDoswh]u qi9y&|Wfk05y*}屲5s6p{Wy&(~םykt`jXh/kwv= :orGi|I_9\,}~{!ݏ8ChJH.jN9v>'3{CfNzplVTVVu`L#{nؿ־sk?&;>mֺz4t'R ?#B>׸Nc )kR{zҍ(!Rev`E |EСɈOY+XՕ?}K"E)~܍IDR'a&NϳQv|HJzXm]XDh0!ߌu0H"gj`-::"D CUζ,Ua'KBŜPm abAdBK ^G^DR6`Mvmm2I-$j?!8[6Kh;l<U._(@1!㎃0]ΘQB=ZIE"r4]С-B*8aQ8 >g4iRN]] Nlȉ1&nW<"yۄc_L6^ܮ}b5qss5yq3?Y7[|'% ~w14-i1KUD|M6hD9?}+2 ;G@;nN;n=9rk( P ]%kD1҈>&kJTGRwGoIq@ڎh3G 3~K@S<|_ 1{܆lLV&yOmWd^Eߵ73u_2~4o^e¸w[zУR׫k?Z,zwx}h|t>cs)"E)R(Y/zV=|P+ve&%ی&y%zt1-RѻQ*oX{ 0yyBHUA@[>*SNb;mL(z$i"/&nЈR:[qp - C ©!r}e +'ZbE5)Ge!h#5Su,T8S"_AI^kaA1@ quM`IpFqͽTZ1?@lY-Ѳ(%VխLCܓE$}?*( bcm+-M %~|O>k[kN-˩oϖ[nB3{ü@ 4UnGv`v(, Fdȋ8_0b.-s6_μФ?z{`,ag_ȑ#y/9S9R{sp~-W< f[M]M- ac:PtfH>cc4ٲ/uk!TJ{?Xy̐n T Z6`4JbÀ1Әimނl >a&iR梑T~u =d:L]f< P<.| ?a{ʨ?\͘Z(hv]Ø˦l.h}4Z ?ٟXQ'ωG初YI ₇n)'s[3"jȑ#9?'͐ټf1c8#v%\^K0mBAl5Gż3|@0[l9  %ύy6mssviS8y_ڡW^*6~Yrg'@ݏn1}4o ?fz۷@c 0K~ȑq3hϲ ̷,~*n~3ܛר=nQh@Tξ ,YsIϯ£φ]7}pNد|{/fG#RH"Eq)lYBFc뮱&!Ҝ,% C݀ZĖڌuv[ yAHQ'KRh|铑> Ko 4yDAZy7&'Ex2gg$bO0,#-CkL<]ctd,NhїaaEp(N$ CeL:k|:!P%h,ktfG_&ękIjv"]Sz^x sBt+. $#qDDh^dLRs$v7sDzݨjێvUʉ4XAA{,CN OahZ-DjRO;][ ُp6֧7];lBݯbBJҺO_*ʱ\ݗ?N/f^]ݧ;:ugepm:mN{ Wk0£sMW{qrq=eյ7}zt7UAtT|xvC@ܫ\47c'#KNd,4lݾ9~Ӈ=3٥ `Z"m^- G>'3ǧq/s۳1߬>##48]ʰw^qDzg61ؤ/} ?䖩! 4$l#W,6gc9flV â'Oep>K&veЀ&Qڕ};{sӡ|z_pГk_מ)nňnS}AK֍>ia@Z\`_t ]|O̐=pKڻ;v3ʱwG^t=e,>{_hl NޏFQN9wsD Ӄ=0&Y[V@Çֽ:w`sۇ8Fꗳ<?x8{p֘=nQ=c2٬?}̓_id9ȍrO[|5-uOj7[,G,bNGě@ZjR/(*jI3X+rM>*DAec)JU9ѣ⌎t,ۤ}?[R(MLL)=)7,hs=ԥ5RE΃kG)~xin9eO\)hgONi>Sv\r@ڗXM-~UF|W.U'e|TЮBC̻}:ǜW\lUou[rϜk/ZgڵE<+<}LWҦ*"+c{6k%]gn[ \|tyqLMS;drnEw8!@yRq<[Ց~BD Ql߫, e=$Oe)i P*~5;\\,GZt"|-V(pC`F QtCҤ͚I'+6IMza? &f%`zn@؀ l% akjr0x2D k*?;%lpzKR^3&o\XB~byty<~\Ny6+N&~-A9kyM8?.\H"E˜1cvm9}=ITBJ|FI*DH,؀ i:<ϋb Byh[)t~9.w!T3/F&TT4g #8wx"j {WDa2!>C̢MAtS iA \ 1u:@*24[F Oe#Ƙ| l<eL39sa>_3-sj,K'mMhI;鍴qrfObι җOueg^ny[Nޛ-w]9K Zěp%׌sO+R YDNTV:ǩ,BFah( ,%y6HVʋ]X,L<ҫ@r_mjyQ~SDAQER6O)!JKYk !'gq#$"Ck=\m;tNħ 1B`%m ȅ˰Q,(DDtAK/&`)]]bk# BjjVD #LŪ7\G$r.qWDHDTDbmaZIq _|^0n_l:j]K&bf ^XWP[ەU0_p=d~|:vV2ֲxuVtqїZѾ6Ӛ*$5_t՟P6v 30sL =N<+ܺ2ڴoJP_N4Ǎ8{|~1)[017ЪI׉\=SV}|3-wʧeGlgUH|YO]ΰmӦ"CMq7Ipeנ S wqΡlݽ &2xߓq7N׏>Λw_o^ؓLy9/yKv4H1_~9#e)jr38c^3?FZmS|;l;0h ?ʖhJ9TC|g Ba&\ ˲@["m1 _8¶m|> :iZؖcu6!DU6R l&D?' rLN';y@. .+l;M#=qvy^DGdYҋz&B|a\dPi)0aExR O.!r CFPM9q"+0|nd0P2raxeDnG2WbOB{^ wJ~%sI7łghbqLuIz@n2N|ux`,WNEIק6VڈUu|v桕zP^z, Y7>0Y5'Y>Ⱦx<;3`ӂ}oGeCtw;(uX_ E*=~F"圵-V }k;5 p8+>^ Ԥ^uOValNq\$nCfHSwRYjzo lۇ#~m2]%CظtFraq  >"v^UW|-6yiW?8/3e7ӵEBiNۿ⹗f ԭ5G2aOTjZ29'?#çcf*g$^~H@i&; 3+V,ΨWVx';}g*UO>6mݺuGN#eYH ,j(t0![J%ܠ pCtlF ;)]?|OI> G-k,4pm<_@+-ˊswJ9L<L .i&j-sYEۼ)%QBVH 8r h@\O+o&Dxq| 7VCJ]#d:Ŵ=aĕo\dv11\IpEV#u=,s~yœ:mGd6R!]C@CJ0s xg7ixObG|sFa{ G瘉#X0z7LtnQ͓߰^nP VΗ K' %)Z(vs> fĕhZ*KVUc͜ݾ$K(BJVxj&=0EKW^z,uK-N 5hk KNV`oO)1y3[ץRtҊrtOiw7 ZfN5餤"89z>޵q]Rv/lUO8-~|tk9E¤D2g+oY\ul 3h4I=ߌe+Գ_y00WT"PX6K^kZ(K:{?*U Z+?>BZT=A@{驤&_[ԔT[:<>Jd$k,6II)L"ϳrվKN-tzƫ B߻&t'=5Ba;ұH )i,um@E(Z]o{'<'wԚJR? |Y^u,=t}_v5)^:\'S 6*V,5Gd7Kr]\sY.N'fWEQSfS4iNN}i|xGYv~&3Xl=[vAVh1D/l; Q$V8PV29d-zoG^4/;#L-% DBUb㦃aM*2W?=L[8͹s㖟SNXC|b>hBvAӦMO޽?v&Q ֶlpaMu4s5f :BavL:44ݣ p2n |cA^d(Eb\*)IJMp0hg|.~C ]7\vA:\| EDd)%eEa߇fģDBODf@ӓ*l?Rqؖ%F1t=/ ݈C*mm /FZ\C<-"oh܁Z{Oy?Kj}ơv6fFQih,ex FCEB!m0{"*5wIsD|lBT6˟M{fަh qZ1zdgcNw X})J<G׻gg>\v{,!)Rbrx?W8 w `3ؿldl+ٻWA0ι%/ʝbD*ԩA1cgY=D*5\7Nr .2+Rbʦ!_ϙ7(} ?ؾh Voe09g0yFMZne YV 0 69)cl[ uw8t׿csN*qp4ܛu?.3eq$j4mٗ+r@i,]Gl /km]39vr$$%yxs_=i9Nm su_x)hֹ͌+2u%Y[7WnƵooOs}S~HŪQ|gav]嘞//f, B~b[ZEWbŊ/O/ J/xLG<> :G i<MYl !l.])9|)[l]SjMۺQ&iBr,0,!#Kao[ut%7Y`KE,㠖ds`DJ ʖL&w=߾~;_X ?)%~+[|VEv]oC l:V9<^{m/,QyGᕖ}4 RlQv ˳]gsI_grdIʶ.X] -6>kv&+y =3;$$Cd*l/c[K9pXVaaY6g~ d)q>!ڍ8RI䩙tߞ̩_[p WH7rƗ: [>܃2jҩ}q22o c̏?XVT>[SE+CVK۲\ǏQ4Bt]ǴLga[N3qp^liALQd'FMD4]sIZ`I25'U*mYUa8(;aJIBP^.a8>:fr}H%08AK" ?(#:!t%PQhW ;d zx̹h`.:6h;P\:o 'jyy?aG?enuɠR耯۴ugYy[ҟٸy%/.1{, A֜y#Wފ5,X{`X;oT&+=ҍ|~+[6/`ddD*^aNYνZ .u^X1iU<.cڟxUjLrIxvmCZ4wڈ|M&/2#| ۍlݺPܫK)g9GO6y}~0I ("3?_v\.6_SK{QV_' z4}c& ?C9ۖ@HCfcтX'irK-({ֺu}{r2lZ=6*-&f +sz񶴯fm,Зlc|,!BlY\ZqKa;遆^#]jvٌM_J)ձ 5>xz"[C-[ؒ15B~Ov V[nו >e*N*"{,A?X9e,zk+ Pg3ƭkx.管 ;*Vq`#hTiX;ѰΑ_~a< 3+'=]%i7(k,?X 4\\D>“{9[B@hz6ԯ_Y<:bhh0_d)XWtmN\ث mx9~~BL_]ď&Ѳm=n8ţ0A^XM~XC+NҩM^,P}3;Y s9#RѽOGZ6nDb -[A\hגzСf2WCߟݚymO33%.Fm.^m=ϼ  ^Y7?]}ony MO>D($@/~l3vTa$'*TcJdONNr^^ z sI=-mVj4(GX2W:qŧ Ѣ|<9Z.&iA =&e/BP9hV|k/re/N ~Wof9]2 {wD*.:~Ճ^&.)᫹<;{ו+7 e5)dQ#ZJE8]/֚AW':UOoL5}*}:P\ b`8n| (Gv1w$_I"m/H=xg8* <%jsZ N%81l>bkir 8 q[CabEѶC2^gS)Ec( ?2y.ӳ3{Ob Ȕ_+`ĿS&4g/|k1' C:'VX% Ur䓌U"N~U,`ܽ2Ehn*4'J%H UT:o~7!-4v;BӠO|*RFLe}fգ]T^ikn#IN؃e%ظ ڴu `J W_Y7>IJǪsd|Osir^_06 z;o7ݚ:}Y"pnpuLL+cÕ=`Wn]tiiEiy3RZ&Lt]BW5+5k/ٵ B^e:>+?Vzg ŻpM;RlT{a6,Hn#%`m2M2<_\w;9 3gQa~YEjR_=oYs5/.@|H²mt<9 Vr4MDz-4]CKwAmM& 7kU>B 4PPn^ev2/t-%"LhsY#P4#jPM7VIn" l3 Ӵety^(MCӝGc>{2(zX-땨z=B(4hf )֟:.&\ϕF wZ.~y^f8۷ 928эZ.Jg=CkQv_0.煔HɊbJݗ ;od0Tu^yQߙ[.|Wu Tp! ?bRԩ]0jj!PkyOJ UkS/@hR{no#F0+x>H";#bib^4NU` ~?`:>/O%c\UBG?˽BEb׳dV U)_C f n6N%ѱ:#O>[ v a) iWa"TFY0 g`fNԬYуW #1b87_;JfT)NB\ѹ  둢9}(uZ +.Fa2N\sTK!pm˖t/TUxSӗ:BuOQWZxO=>o0O-9mtޔ82T.}t9ImzѶ8T[wlvMSh+8E:ӣi\ޚldo&J$dPۛ>q OIZ:kc˷^Cy{70b҆*VQf ǿ~ы9ƒbʑ\= a կWJ=Ҵ}C[۹v?Ր,x);x|4mߒ|[⛤a0މ1gS~Z/멿ޙ>ͦU.-CnV3c[VFL!],_ZtcleיB85JqԬW VbGyuh[5Z6F:4ZFzZ ݙF*U*WXb;>{9?fI^Fu)n/aCNc`C|J9{'aF-,6m~'䱗|^SQ]E2iUp_|ǰ!C1LrM&drjsy3|q~ū| y8P49+;eYanЭǒm;71c^xrH4N 鵚ki"T:4!܎ ၈NGiByi'\.P ށ#L.sFf-+m-vZ;\Tdqydd?#ˆQ:ٌ0xA/—qMo0uw3*:rQ0ncDh&(̂d \S@p7X<~3 LSI 9r$H͇1 Ѻ$.i݀|3䛨pq F\ancpoyq2FwSPJvNm d1Rl-A/D28 xv9=VbLɁ}Psu4@ӿ,ZI29U[g,ቆ>t'δM]S '8|܄0xfm*M {$F)(Qʉ]>;oV_ g֏ +XL:鿆_fؼcChw_/4C LʌKGE~u-@ЉnưfƔBqg>G6;AiM}sR@f>uгkL/Iz2ߜʖD?6ƝyeN'3Q-su1?OY Omuz\:g-?/mAνh\fkޙKqK F._8`NZϰ:#LiEf.БvKD+Q5s՝V%;Hкy&~u݈c02f{I:إ)8=4˫8^k_Ż׼/n޷X|edؕeIV?m%;H5)avq=F7MχPw: >jź0?rԣC1G^1|07yhAܘAfeI8xW'y8Wo;y`u7Aٿ/_pP7@سf>\C|z4,WnjNOrY߸厫hU9 _p?[2泻#<ܡz&n/Q'i]7Z1bxߗ[#:E<5k@u/E3ٿ+^x{ A^3>-kSƉf M-5m}"׏RоL:iZr6&.-z\9 wDWsIQG L]v<9ӽ5ۼ7 >*v9UStm9$y{BC[XϝWȜ 3חC%E=SdCڑ6O䶛{] \N yDϋE:r﨓fL*\H.?!>գTu)6o_yQ2%%2eʰ}D*T>|B́FRl꺆X +DǁrbXNT蚁2L*V[ ! y@) 6MK8m  P =~rC$- *i';lG!>]ǴMgjX!A(*l{!(OA%0Œ(rM`Uf B` D@vBDuAu@DTGDb01IzP%aYyZv:>l :>~LYF +D/C{Ri.8JTPJ$t$rLE] /დ<ˏu,_zM yi [(RZf&fb(}u@$j4&DE29tBR.R(3e޸- dOvBqVM߈Sf}i׼)-:]N|~Ev| j78/zJn<2 Qz!ʔđl|ku j3itk'jOB;QRRDs}J\io1KM})FÑ s/ҔMr`Keܧ<ME &R s/O(XM;6|)W0r66`tU޺&YiaY6N-L]+r zvp +mHF)hO.)ҍ> w;{U eZ&^w:(W5&#V_|CQA KUR3oro rgk| $L2,~"_R4MCTsAV0ȶ3oTz%jD|g[9I/;O`HzrØ EXvΫv k4܂Tց>b {ۖԘf/rl(n'}o|)pK7.] xtjߙ+ ηQ!Ӟ6mD1`/@Rn4Yo_.^n?!(؉>mⱴz V6z6~bK)w2y 2i :ᶱKI%f~| Sޯf3:i~|g\[ҙDQ8Ļб}zv=Zz_;xb@i֌wJDdU]\ʯnيj)´83yz٥ /iNqP2϶ 2.OQѽ]{z:W(O$M?*q;W_`=wquY}UWkxel,UTe~Ho˫b#V5k5nLoֈJe+dߘ|h(Ҏ`KϏe`9 ?R: ϧcZAD R8~z6b¶L Ag@!(Dؚ4.Uo2 %2;3(!q4)@uE(Dg0O:EB5:4-Ly%|-Gœea|NiOcX7"Q./ 7 ;VrTF!]>u:2aHeHu*U.Hȏ5!(0" Ǯ8:qgE.ƈ/.68ծI^ IDATwX(:K_J?oGqT T3n|Co;xɛ_bw-=NfrT(om{b5s]ƝB4}n c,ʿ;գNۘZ^}5%j/W7` XlUh1tk:n`HE$ eYX@ t͇mضwN.jBx^~nH hU>[YdW!4#̮eCS>DYvB ģhB:d/cAm/.B(8t  n88 '+B@QT`ba`B7<` a˲ |hn ض{ippINNNOrtWWUа+X廎V0=aйkH?ƿǎe`a;'h#Bk(^t^:Ҝd:H/0$+%>^Jdɇ0p@HTh 'G#y p[4_abX*VUVLmoޮTP*6]ڽ]FAU/y'mU.ߐwn}94B6B|5{arFRIZthA(Bh:2xLDS|r@ HEe"U& [ `k')gOP2h!,20 $%gB0͛py1tr &hF7('!N(t(_6iPtp&!5?p} sPP-lt'/6nG1μ1a:e(RJ4i?ǏgBDSO)44444444444444hI2I1:U7煜R86S˗(LZ9'JۈH)QW $0VH 8QhF*Sv,hF"aӭ;8'4Y, ׅkɲ>.vmją,t3ϰyQZHREE .7YDΔVp> *YϘ 'n1vMoC..NrѐãPfu?;"{C,׬nAj"%mT3#l@or_oxS{Fm${v|Gb}iS? yG} shhhhhhhhhhhhhhhQP F۝x @Ι$MJJ]2u])qY[Z7yXV**)d1j)H)(tYXT. u^^Dz7GBB>?u!{ltu'a_q]:KEwakHmj4m8SGދ-)w~PնkϏm%GxhhhhhhhhhhhhhhR,:c k1@/k)7AUEb,'?-VnawIR9ϸh]I11H UJRJ5]7זK]ըvMzRnXk}H=[ 3'3n4]gpTI)K((WQ=)'t8]=IO]Dn'tBҒ@D9cwŏB"lYbUi@.Ǵtp{TfH3Eׂ蠭1ۇD]h;mPx4_~~ ׹R낦z%$uuܰVqsny\S@a Lw n\BJ9xL]UsąIm~0bWX!L)eUxDS͏!1\oCK:==t~IC؉ul5sUj]˺_#3)Sj ՅZoP![PEQ \5QoC8DZݺf :UBRx yAnGPԚHmN[xKheAco.:WGsIKZ4["$z/ 4k$G 9J=G] Nv%k ƒgAϯY4MJ|t J7^0JxnLc_l?x%xϽ\ebn['n݌GPh><(; {|7܇Nju#ޛ];3j & =Jwj1aBRֲS+9z%iƉ Rά3tJYΤ"nqCũpxlZ 7^J"#rCnnb.4.4TA<^;OBrkRqp-JƭD&Nx-\EU#i`+N5| Z֨7m80 vHcZ|`j'\nGu ss~|=|1(\ f+E{glP->=zFw+}Y3k1H^uwK|SI}1vc!gRz$%8]]Ţ(뺒Rjh+"jWEZmD"F ND1<;1IiF4A~A4 V ռ8%tBYx.9j37UDiXyO+" 5RRݡpB2k)onv9o v+CCCCCCCCCCCCCCCnuY98u R4QJm=`U[)o9RHzKBsW3r5 Z ]+-R8b` ~7\=i$B!߾)SR |r^fσgt"Og"UEt "^Nt 6])%z[:唀jʬZfJ]Z;SVi-2r/h.ݝoJN֣ s҃pXa;šŚqd? RݮA 1Bm(%܄\u/GC"Bmf1RܪRNT[jEY뙜5OPZl*DP} >#Բ}~Fl,9+:WHHbՌ$:sW\QKBP}ż;$̃EY-xfk4G Yǔ&rM5K`ф&%&43\-. m9nWq`$bI\L@(ˋ^w|P̍tPV jeYZlPKp*;*m#%Vc!o7MSfaY k}pEyO6wnqhQm@z,P"HiJYc@#vgVIX{Ah?A+Z}Ks~phhhhhhhhhhhhhhh],Z MiK-s{{w̜j+WsA}[PaX-zFQL8TT V,bXaV+4L3]$Erتh6u-(kf&SU+θ;>g Lpg 1%-c݆uLiGV0M14nK'vxkAu~?jp bE_߾ۓN?a} }4Jx{Cmу{; \E݈Y CZ[ݯC X4 Iu =27N7-ЦE]II(BJ!p%8h[6[l⢄wYs]ƆawպNY[0ptyD"VJrAA;y;U|}>砩le}߈l`7"ZW)"`#JE"ۗjSJxuRVJk¥95XhRRXkʒi:Q)!u5J< I3˲Ҩޛv#!jZ`]Jzò>2RƫlĂ:WrGNWTVt]R|XׅbPG9ך"T[p%U䂦U)9gJ)%ֆ{}dw;i K : +.@?~O8))f=6ͅ]QXwDn4+C RYm~=|[y ga)Sץ;S+gLۙМqv~ = eYH)o,֕i6R7GJJc "kjB{Vd[ ܖnpL IJ\Sb#J3)O"bg EbB۸9g\T/SG[UkXJin*qS!un݁+xa]7u3[0RN$T%:[5;bXNdU{/#LI. \պt펶ޡ;5;ۜqk$Pڣ;ޭ"{= $f_wŐHP5m`Nuzt>۪mR![QnmhIiOz_z^pLRV 'z'a?󈯈 ZW' eYQIXRD3C1jrES&R @dBuTZbc&z!+@7Cs(%b&)d(eD_gd4ӽ=L IDATq v7c#P.Z__ٝzݤfՅJ54SWO1O0[H9F6Z 'IP-*wh[ׅu5ju 470Z0/䜶n$9R8J S)%RcBfr[) ,ʼJ$"Y-KJӅK.^TT3N;u7^_VlM?tVOmZ;P 릛#2bz@Gwa}tsWlª={h}GRvs6 N5+CCCCCCCCCCCCCCCD1%WZ37rT+ixSR$hHsuEE;#3\cD<,9&NO5u=i'}9XdkD?HXZ1R@氺-w!5\JJ@AOD7Z&jU Y@RƢ<":O["DJemӵ9FV wA䳶`,do^җmW.n-^e(JzhLJp;a -KQXUwm%8:5AL7#OJ(uc'4]1Oʺ.mjujaIN6x9_JZ# "@1nu6zaϵ:o7mK8|h]-|Xn1C%59}#\;$Gmpob e_tb6GrlV;Ek7444444444444444U6 bnZZ Vu!RovfR*N :`iOzJ$*4gЋkc,DƨjPRbJ u+y. x)Q솀8`t9#zNk1q_^4e겄ьsbS~S9ܻ=.7$T<6e*wMYdOA͗0?pͱEz $C궲ۋny<u3"rqp.\cM\-›x5;0 XI!*{t:cgMs =+ķbg=Qo2L)FW΁"$!@j>1JǛz^A , yHj _ND/89Ozs'\?B9SKKLSbcgjd=E\y!iۇ0'%a] ŮY9%6v(1ׄ󔷵Z"65k}'ov\ۚqq5u=SNXҶ}I'xr8lo<{tctw9[`}$Dbbi8m!tq.X u܈;S9:bl卽 .5V^Dp-.1nm8ٝѝ(/8GM7oa8o I_>>3dhhhhh 9xK.kTRur@Rj f(Q4h iQ4`kD$zr{Է!z~[͹nS;}Ev["a-^۟7%cr L(csGܯ1  aN6߾mf Գ_uohhhhhh_~/<=.ЯCRsMӴU 1+Jnʔ h˺1MbNzxS-"-xF(Vj]8MOquyۼ tF52:5iϤRjAP4eAZ9[S4Ĉv]L)8V SE络gLR¥nAufҀ9O-ׇy+gpAm,tD+ 6؞.tb"kk{_!ƒ]ȗ-2{;:Pk7iqğp\>Ep(c)]Iş~sɝş?<ЯC9up B ci 5@|ffX]1.gj9T\N(ڒJ-v栴4cdzi~ tzo wg-7, ɨnAú}\}̓um?}W {루?[ohhhhhh72CCCCCC.;IaAU,S<,1a k Wj[ pGS=ShITdOX XJDvEѮBwuwa!!m-w;444444444444444(ȝ=A93匤DM73B5sXۓ'ER$!(ĆSajjκ^so~EiκZI8QR1 sz^5 o&N T4)k]q<ϲ>z%+L뛛-=kdyԭZ/OSě[w40Oћz[ą]@li}Jr51TK>j;F{־>l.=mMXCx}@#Y%y>ޡfiu [?o'vn`~_T2"}ehhhhhhhhhhhhhhPg)v*t:9%e[bf#?4+TR+gr@&iuLBʙ<`>L̺hZθ-(3܄, ad_hvrêZHqae3Ι[$)yIBtE)k\ºۺ w ҸVgYi# y!Zc|A=9'}'} [tTi'SÀ".SJmZ9D_ n2> vif6vx_}0c̴Qfvpyt#vGߣqzNwp =J)IKQ{&x Xqs|6t[)QKŭlQ憬^%Guhn5L ߉R ]O\@[TS$O2bNrR K5ğ +@mRArEKtNyxЮ¶!effkr.X>RK t$ _k-{-pP$5C#ڊUxnNIw{iQ-o 8[zr`hyzZVT"mC/eUZ5 .bÒH3+- ɡ; _s77wqSK/mq# p|cR5:z7c j Hm[=i1+4tAwe_q ML:8444~ /Ƶ-3Wí ,7~Mp.XuRh[͚@&$MkA0*tt79XK]1TpsH)1eb7Ĉ5};׽]01*#n4.wn?O$^ W[mḶ3ċqz1q7l'qߎ[ cC$B9Sl'۲p\'{A:z k=z1/'~_n_+uoߋujCCCCCCCCC) ,D"VuimGtΔg ڶ& UY(5&' EY2 cЖdMȚH#Iΐ̙ ƺ{]eW{_Kb%sG1X]cv]õWWNcܹ2^NNqz%ynQ7vlT$$UrHA4t < T ̔kU]HΉR֛kf&C\s,kئ厑_}F9bx8R՚O*lŒ:=vkc^N!{7i< 3Xwߑvce\sR=a5CCC^JQ4oo6_/|ÛB-|<WTw^7{>oF/Aе{xݯ$O/o}k>;/m̏awc}7 Ɠc&yoV>|xYy'o>og/Ω~7u&^+o¿ͭ3_$?ͫ~_9L05|9wO@z~+WkEW؛ނ穏߼/C7KON+|/>;|C~m/ {x>[!k#&KyeN**ZE;ju߁[klB3nDiʍ_ŨGGBu7T93;FR?k e!Rs )R.xY p137 7緢TR)#TKū UXe}hu04@sy'sN MwLLjm}f1luߞt ux#21NϱmG4ʡ/~qvQca~e;nN85Km;; mnQliwC'BMa~'>Skky~ܿ_k }=OsM<g{~s럻Ωϼ ՜'x7;J~-~;yE<_>E.2X?J^>y|O~w?7K{g'yyw~=/Fo/͛?z4` 3~N9O$qlHm *'ݺD9)M3ejWDVIr}_3x}-;))GJiV97c<Үj`EJ1%Ql__sW9?4B|4uC QNK["@4gbHۇYED]ifX R súv br 5mJlI[{٨j](Z75]}e8;yZ1Z㴘oB EDXR/ݐn !l@<-"<44&?~ş5_y񗿑7΃_8fm+[<|<|?>{}Q޿?ܯqly˾ fC++x۾7o:o"}q{o'YUroU,â D![b\иDnhqEo*nE\@`Yz{8{kfPcO^ꦻsOTWyσ}'>v8{^ZO~:\woaa baEa3Ȗq Kg f]- :}Xua}۲{EΚ7az{;IeOa]/T̬8zcOOZ]OpnAqݹK6_-{k(********y%Dy|-@}[fn";YΘh[sM4PF:@UUܾ"FmU 4W0"O3TGhsET hWH.X cFy]vìʅp.LJmz59*#alTځ}ݘf<|\ҵ%.✡д (FeAZlXJ6;8S>ξK>pw|ѐ_twz9==>t"ueQw^~NmW E+ Q&!Ku۹l<*vz؃yzf>SXX ^̳噏v 30!/AXdk?ήg!s|+κσ^"ŋrS,3"RW.Q&hYDf"yyb ! Q%>B-!1mԃTf$}6ԃ 42=@)֊_FD:>< j#FǙQZ]*Ap(0O>j@!f*bc)#m_6=} #sx:A>.蕂dՕ^ .8kͷuGWg셞PuZlյ|#7:5ݺsz fE"jiAP3 #&7kT/Ld@d*nݝM,{1ڛf0>cݟcnkb)7n{wV6fto6BXw%/ixԿs'_,Q/\SƗ>~a+Y[".#5{&;5q-  ?!Yf_M?eW0Y7PVcԄaapE1dci2a ̚U(И0ҏwe/fp_~@c#Į.]TTTTTTTTT65b`&hhQ)c5H|^׳mcنx7hU6yL@`nvOfigSUҪZc !E*d@,`ˆJy&N 3bb 2lS(_<;$7 Uh:ZBBt\6};jZ;ղ |X֑c&q_׏f S8v.{A%BMG;q8d c'wb2`jRHj$*u?j!!]o )o65;.5cpian1䢢?_Oxp5߸fCykNz sY|O|.;ln>ɖĦg LwfǗ6uc }v`3SO?[_'rϯc]Gb{I4;3gt|S|6 ~駱7YE)unxgecW=pތ8 ˆx0Bg *UDAz4VƇ@ ȤiMt(nGEL&&hěLX]}5f["33ۏ˪T]z|imv]%mܾ '^cÉg׿.$1"itjU)BAXĶ=8nޥ$CΥ5 )m4Hp]XGت=N \TTٴ#퉷®6k}\Sٴ^pNe'rs~e˥>'n}]9og};Qtx9Tv/_:KM̿l|;d1g>x:v#0jG_/~uWX.|v8] ~yD`+c>"_aZ69v;~,vfXzr?A-wginr.]_1Aun7?ï760HK6<~zvcndrטir".]TTTTTTTTTTɂwdM@i6LRe#@gk zh JMflAEQ$g- yRXcpŨm5ΡEbnwl5h܈'bJVwd!q-` c#Z@G*:j]8RCj0d~.֘4ێm.@97l/vSy+*#k';?_}k7QGUI8C={M`D44̈́F-WZ#XBi܄a]3̓E"^A3v(=A!^IV֩0 "HpTzȰ^gP@t%.,gcgz6@rxp- x[}C6u/Ҽ=<"uŤYƧRi"''nT,Qe,FP:\F6&BBA<6iӅ@TzlO'[z͹y}}OSZct׬,S8İ!Hhn~`&Qm]m뮛aeLvF`Xb[Qu^kK0l0/AEEEEEEEEEEEEEEEE7y#OPZGk@rWb٬LJV V\3 (]Cѱ9MPn'UU(=ʠt@5(qfuȇ4(3V ږwI$Z9Bh@*!p@U(Pv֖ 芠f;}lT ӺVBMgfb8̳<*`Zt2Y.F< CM,)Z-ҳv]Dl1m6:gҽ1LiAYaښbyk7@%ÿxlG.='".FU ݊١KDpBh]|]08k┞1Ǎ25Վ܏SMeЊ[d384ɤUTURx7*5H(  8BI ]$B.ʢ Ǩ̂Ad2ԑo2aq*# #2"Q2 QT»q1i*L% g%Ci&R4ڧ 1!YP,,`3]*7fgZnōc BzPu*H%DۤH["AW.;qP4}T|S eJ1뎍.1zni=^>W7#15LϣCp))\TTT|9\:S>6:nbXġuj1F$:٬Ay5%XbiFm ~u,AߺDb"QhOM)B'J#J7&[z/LI!,(trA-V爎YB8Ae[diw@VC\gDbx9ljPW7 V4*` ck1Y `svx[e(s,-\b4(MӸ^lXoby 9J 1|o= ۏv}ΕUF^]AJ7Ч'[/;I/K{67΋n2F!.$!T,5j&RxsT7ށbB@" UVhFfbvvqdzP$xD}n۟+hǠsfyq)**************yH":A ;},#4c$CTu4Q&XІiVP{j+wHxAOj=5A%(Lg 7:Zڒvx1L£Q+XSh6QRoAٌDCUm1RU&bs`$ˮ ob5=]l!EniyVx$hUrfBte?!A" 0U0oTksε ߒGAMJ)&\fMiv@Uچ'Qzםʫ^QQQQQQڝ&RW(IL;]%6ZKMlU)!FWfV8 J. xo&2IO.]: I{&zIYL(5i& J{pM@f%Dc"꺍0|hgF 㽣jli&-+-׵C %;U-.28@z5?7oڵCSz:G\SF=Aa{80.F6jᗯ?_Sv KZg:5XB?k9}s;W?JޱlBQQQQQ@yA1T)Yp.n#4#8Aۙ8.xF)`m,p 7 hS3;ܑY /m]]g4 91cpN:`Mk-އ(U=q7c߅Ov.⎛1F{f|EP-HnK<>/+4T@+KwF.#$nS$5B;.Fn;G\Wl0pBαyM: 6&5zcڹ~*:t|^6~Gl.v)Z0n$HI;?=GlM&Wa[ N}v =gM2%\TTTTTTG)X}> "mrR(mѦ"O][6 >+eiq h*$`tEu o@ E_bW` X3;1V ^GblZ|;"ө#wF(k3Zۂ~|Z݌CE,KJË(*****TW3h-(l@7B;L0h@%Eej14èx2+kXbJfvmˠ%JF`l,* > C Qt<)"F+V k45~VU54?1vEkT's." ai'8oq!iL]vi ;D&4auk m:C87P0: ^?#NM^5x0бNpOg=WZ0!Gwr70+[9#. yMZmB>j|]|Gc=-o~7.ů,eL}Y'1<쐲!EEEEEE1vCWQL#g) PZ"HhM(+W˜Yj k]c,"hblRHhp@Pe Hkږ +@jNPT RtZ<f f4ףt+!q0M$l*\/ň q]e .m$~ "Pbzx#Yg}&6Scfз-}$ T#Q u u0_GW*2Ζ~BzCȑaj NDdcZggjQg+, ufa7<&D"ݜ6h9(`݌! Ba8㹦A!h-6r(4J >DG#Ҁ B# h]ABc 讚sjR15jR-/E&XR|+M ӽvczQFvul֥u Ac]# *gJSLcT8uݜԱC ލ~(BU A[ F[(؄ROb4xf4aqy  B+X-#Ex=AiшRRh,A@1J E(hw,RYMdBij QU4~R&h >VmQ<#VUt&b.͠+:ek@CdJm pF7":\h@+T ˮw'S>ʋU ]sd܀LM5#1XM:$B:K.5z/ -"+0xNКcU M P ut|)ل0x"A0ƋFD@tJk:V̴F5mbS39 a02Mv{F hV!$ڠ 49nBgLx9EO[ .-k w޻)w^:4  cU9VhR~އ]KH:]ɗ[/J9t:|,fُFdn93T`DKd+X)o|}0J$Lj(;dh9k,ޏQZi0JWLWD#hgQ&*D<TQ( +G's[[a`%1r٬)mӹ~*!΋)Y 0 Ҟ ;mryH2СEϢoSV@~T@"!t#uuuus|φ@!~Jtzӎ֋VO)bhQ b'(Xqq!Ex3cqmfdZ}قʷ{`,***************T;P vj bVѸ{-!@pG]aŹeD OJzAAtӪ>TBјz@ M^#z#"֥Md?6ϚDXnߍ38!L0ڢQq{ʥ{%Hkmr28NzF :6 f=-5ĝZuy{]2.8`[yI (R6wc|8nmגLeAJNutC$;TIA8q`W;COV'|oF~;-_?J-]RVZlj5Z9h&cJd= @z JY2xqC@G*AEe*B]Y&ȲT& V3|ۑwVh#3@Yc~*6_ɨFzYU]RIBN> [U&`6ۍߋ1YAeb,n8΋ó\t!Vm Lcv_С:L&ǹ%%x qH` h7 !~S@ES]y}sM1B: ~p$|x_nS`QQQQQQQQAkgk~?o!}\~sï|#lx݇͆>ͳ٬ǹ!&([ 7A1kgf8c#*拦95:IӠMB/ժ5ѕ: 2s&IJ18|4(2p4M4a3ѸlkZшFh]'x !0TkSAҺbR\T\15٪jysHZ}@\6]L9ԾQ =L8Ϙn_ߺTpf!޹C{.BR;nZ*ۯ,wv.`[_Zkh޾tkM-ΖKGN䯋~Kω>[0W>qc'Ac9R{9זǃ5><ò_?ҍ|cxύr4/6~QNe :ǟ 6HO:}waMnxK{4`.q׷W|=j˃8C?CKԽYYǿ` G>|[:gxجV}SE'ݲIGYTF$Z$NKas$LHhM63HH*Ը@i` PxrV-UUǸ2-km)k\w`#e/_- W1?5KKײx [byy62~=-?cy猗faZfyxp 5ELmk<cSVX&`GF?FGGO ]6@_ʿ5m掊}n\:I'> iRcɍ[XDf#PCMsws. ;3kUɉhIݵw!}xilLk6~t;̚nMg?\pڗp_\׮ZNOo{/8qgg~ c6Ͼ$>3_R^pt^?YQ%v|/xKEo%IaKb338͏fčW}Os_w~ŵ~!}ӂ'?j+䠇~mNڗv8?n9MO?쵆kO?M?\Yev]~|?X.5ǽ|3؆Fmz?o+ﳆ_ϼ?:x{O)>}8_x;p噼\C<sէ=;ݼESd}ׁډ~)<Giy;o'ǧ1wsy)]2 j~u>9'ူ֩[r۽.ͯ8z~n븡D$ei D4:Ve5[9]B*ci!cnبS5ݘ9k-!fv'A͢j` W]Vb+ egAHEܑ7I)CR ZQ|Cѡ%&4#DN U 9j3pj; @<t ZSo*JAŒ2L(:bU}]~~*O]zxĊ<ܜbiK9ZІEzqb5m̟kM,%ɺ[;w/N;i~Aȶ-I.қah~ A)F)*********d{ݎ[7s?{H3|wKpAp_97>Bs2ױs*yޓ9怄Go]ww-l>w>/{q .|88>;S?g>&z7Mj?|Goo/9j{x_7{d鈓x'ro69)gNVÿ4bS'Ge7>R ڷwG웏1W| - ;enKs|wJoUMՃ[[R/{M?3o0x˕άdhy٠??*]K=ow<'{uSзOGJ)netE|QPAġ8/X[G+E76MJ@'(A˭։'Qm"c26SY`*\c|pf<5 !"8B0&LE>4$`RcGm,C;D@Y*;LE#^5V`T,YAy55Ed&L 'Hr]{n8ve!83/Hlc{{1E"}cġ֣uE&'W%[kRX3}-:WO8䲅y8O#Sx f;2fC_4Rlz.EEEEEEEEEE^Os[#$ryȁ;b#wS?iž=Xڇ̅^E~]4{u{jÝӊkxk ~Q1yxG>ˆ?_;7{G_g#W/k7پO7{_'~<.'2>w/{&^>C,p^Ox##x־eo ^+8g7MUͨ{wٵJ.u{ù.H@ IDATo|tw]pe?cx nǓ>a[oN;|[Dq 4yĉtyk>?vebuУEEE"28G@Ta2HF<4ݧ4MK\(:V87 P5r8״k;.xuZ lc تBQt}gcq[h_(tl8 8qcT2 f520F1Lʬbqs1ʜQmڭ5p(`ikٶγd]H\ma[z'Hwy4񸡍灆m]9.K0E@[**>)\u~ULW}2_Ɛ3L$H7G)XisቢF< |x*<搧~+]SFX{vI|hy?F^̦O{  gg/ᮽBK.a+y9|[N_=\XwE\3W:72wkZ~u)\<G/>|r?6Q/K_vRs7*vmW9G#n>Øw!|]9{qYZ++vbċ.؃iN>rlqz seߛmOҫj;5}ƚׯmS-.EEEEEEEEEEqN=gا{n9 }XK9ocGʥG?ړ$["[8Lt.t?dCjp!쥧܂TOawЬsnJC ߽W|[G`n a]ϸnծ6]^ȧ/6u f.xw~ǡ$]zs7?=!;~g}x)y&X9|G`5ko-Ga0 f?g]꟟Ʌ_[Oy:w\J.gf3EEj !|rж4UU1AU6C.X;OhZ3 U1b z`  f@Qf %̽U u;wsaI$ρ0ܚizuRkecX) F 0˂HAa_%i G{P)D l7x9#C w^S)Cs\Ja<0uᗹ@h1Mm/Q/T.hO%f11dW E 0 LHOv]ێanC4D(LC)*d܅Yl4RD Q*""?<# X]< EC')#&H<0b# _6Cg F`bXG$[,w@xO<`Z  !ei0DW2}N9vtK^F?F n8'ڮt2jx;jNJ#{ZwcVo<{tk|7+7Qyë́`[wpחqϙL$G!?3ͮ.IQ(o ӴKT)سS[;!O<^,Ӈ])lx6-7 g7w G_YiG`K׿r4Ӄ ;ѡqM_ zao3Ho5~ß ؤ,ߕ>]7]w[<4,^?w-g>xUͦ|/GѦVknW(6/|/AB摢_|'wII׶5bO|WovW>৽YRDrT7ɷK=}-7>u7OIǼzr]3Is'1zx@:jI.7iJ#WO?ΨwKk8G.} mVdϸ6=ϵ{!' YF-.Sf 8K7z;v]#q>g|l֝3.;K7;l*4BogIt~W=V# ){ˆ?SK*2hNA"'vTW{9N}k9lo3\IOisߨw+,Y,g4K$͂oɵゟxhlAҭi*zl6o? G@bc'sF͘O"Q j(?B9 Hųi)^k0ޠuUt*_ }+j %Rlc~?X0#(_2xO0nh}q]~NI61a<{0ǔUԭ[*er?d>y%)~׶ĞY3=IxM}?duŻ?:?}ƽKqX!]0JW$Z'╓G 8-/ɞe0xF5U˶>NJ$w|2(u (ᭋZ<95:ЮrkyJALxonOlb_K6>b?3s n!fd|^8Ìql 7Կt" 2'v&zZX2eH'%:ofP8A^n/CqJosmK"$JzEyg4Il'D0,LL,@۶A)P2+8C`HŽjq0eZ~FD<續bcV YD#j0 50|!qliH /X( R(\ !cC8YoGiIZ{#D]F"0L#A '|nɈ)<兪HF{ b@:Nܝ)-5m۱z2`zD q%]0x7["6ظ#]׉1`Pe8QE(cbAڗQjx8w)  N~a%$q{[a24A5k^LYM 4MF~=zW$^ƳO|NJnb 6m$&#f ]-U™B>՛rT8zEϬHϊdfcp)-]"jߝ}rZ4KJdWK>ܷy *>ОǑS*Ǵ,~8ߞᴜ%}_BәG^޹9'?g=OʡU5ΨHff&3b{{ФV%r*סUyežCDMGбaurrR~o}lONN/&~4lFnN695r9s1L9c_hv{|.=+}Myꉕ^hGV Y9i ޺uv'VˡRl"_n bҧcsU!;+N>{ˆ/^v'Gq=ֳ/g_=$X3BƟ܂cV$bu||?fn-W-8v3qw _̰V*jBKb2ԧzNUq™%;E΃_ydffm*\v m29wjpb}ܲAmp#0231i%z^(f>>-F(a(vq6UsNgf]sS%s N>p.'i@lԣ}s|>wݲ6rP nࣅ xh`w[*9<ԭե)*R^}xA[5wu\*egS!ƫ?c@rraxWMFN=q89|s?a8qmmQa.[?eZPR695ߪc&t].Iff&j H0,+<uP)=/G''d.xw#_[#9I$?;ޟWSS9v"%+^/d^i lU+ )q6U5\p]˲b8pI eƶ#~G4F.H߆P N?oY`HTaE9Q,ˊg!QK@"(PaAj.:V'j &=@zuݢ!P(ƱqwI HX: @HU$6KH2|kGt  ET|0'AS)lP^J%A-B}n.=1$?Zb<7PXvĨOr,@HӯPP{33Q7ìބJϿ+| /r0 b}9>zyWcmEZ/O9-+f_cD46x\С/Nz7<5Q$/_͙7G9fT2˗#cVVϝg9TYKiv~r3 ;LVn 2㋩7o⓷Q7MVlOI RxNOREy,^)`o"Оb<}'LkZxOPm/3P`%U疢i*a;>j]~MObsw2n%T}gunaһ]Vly|t~؟G/nHQB+ҫ,b4-d>W1i|{J[X9+ˈwPp/~w[i|l=O=DӔB6~6;9k,Łd׮EisO]B[RػÌQΗIr~Ӈo垡p$zR>.7? m3թjDv@ۃ\6Z[1;/;~Zټ*$8K8_`;9}Өo`)las1 spmrE<=]WEMG>w wK>Dzp,*dc8+<EV*&u ݅6(|Ã9c:0[fi#57ԧ<ӯ2E-EOp6[q-wsQ68[=-1}p2ϛċ*|~콂΅uJj.8u냜Gx?QOB ^wLu12I70VTۙ5z  w=Q6^fBQӼ?61sYHw2;>I%4 4L"$,')驨'BЎ-4Bс̏ЄlH3t"qQ ;(,܁VJS!z >1 tP(##+.JJ81'ʒL84ngEDp(@i8jZ!Jk @B7\J!a&qg+1O.-L5 RBWDs}Jl(H" H@qX)0hjE,nB ȸx_⟏C(I<@DB~i$KC9EcVZI˞qW?ƶ(Лy٢Cx&kep;;sOKǝ@8Ό_SᎮ'1ǵ|vkONn4%K'Ѽ: >[H6y2&k*&g\Rf}^Aab1Ĭi76b(;m`=/zԧsu}BfpQ9^]~#%<Թ:ߞwvOu|6JV,G+y|{;dS7~eקAV/ ٩?dhm}Ggoe#d(o6F^ 5|4w խ1?iDVMHKʪ6I 4kVٚ'v thV&Qe.<0{E6Z,xfrִ縵sOP{jZQ0酻8:-/YTi_d9ұ4i6RgY&?9:O̦tZGsm 9HΑ OI=assuax^}sЩ-i nlY2>LdRaRg/۶d'2p?-EC/Mʤ2/xymF4hϾt!C[ʭ_7t>8$H"$K܋*GEqRkX4) XR`ʫp;)$-P:Qeฅ([D:{RqaxRXSH&oibe-(RF⊽XVP GڄBZD}8&6Rd2p]4ZfaP(x%1~- ATTJ{҈+q6T %7-ʯWuzAFp@dFk2O'}e^ح46D/N&zG"I"؏}k׵BcOm lMx*Bߢ)/]uc>}י:w/0Z=Nt0}*sIiDi۶lGusq>d|Wl)}8'ԦAK@7DB:.xèJ0mV̦ore f`ʏq;aY-cMgҥEjȥY[HAMgwZR9'rjmUX0i8whFnv9RD h[~)'L; Y*ߖGvDWQ/ߏgrY=b`QjPlU3>5j6.,P93"zUhgK-nXp1;X㬦QNc%,Yw/ɋ;PZ 5jJ~X{/P׸ Է%` ˿zw+6qͩLыwIj3+v'rgv*|-tnW:s-[.En-3?`k\S]`948|t~ò߱ihߩ rRۭ%Jbb˳QalG'&7G}p֥Z+Y,BpO}Ljܹ֮q|H"$H"\JFW@0p@!vqBa|Y/A!R@c0JgFm[Elݺ{7Ht7Z R" I'B?@Ev$J9H }O!E?P'?=4ۄ$d "@tJ=aXhqCܐ[9i@qf;!I;h;vsʜm Vo4 ,Ta,B!;rک4:z&:Բ?r^lʃ}u>Y?2-L׫hrH[@FHh`ˤHbvi-)Ӧ<ûcy+uk,At_l֋iGӏGxXM-2ft;λ-Ӫ{\Zp'#q\;iN_gd]ahQ^dT$L5f˴4z%Gcj\2 snamR¿F# pJWAwђ|<ąt|59+p׫(\{ ̋xV4ka[4H!C,8uЁALgƨs#fS%V0ql[_V`6BuY<HmùN'e8wxvpnQE892ˀS2 %\: +9%2Ql}9  ŲD )4iHƶ;zsv>d5U7GDZj|H"$H"#]q])a.NF"PFaB`Ai05NEQڷÆ:R*ckX( a!\^TJ!\.d߾Fe /Xs&qlgG6(u0Lha='Z 虱Z!0B؅lRe  }UN>QUr ΫqVPM4 4B),CA8: 5-B'aرl C@j cJ@3 ԁY%bV['G+x?'/T)Ĝ'E!hL"E:X]$4Ҍx*c)1>@ 4ѺhB)" E Y5;" y8H2*աnݺe-ÜW)AV9sOD˘x46 4e# 3׷y](Q[x9ǘl-B2bFtg;>'gݗy>5H?0gy۞bkiyRW(v墱ӘUT)pY}:?~O?s5 Q4j~Y~W4jVjVdrֳzc emlKv4iЀjQ0ϢfF4L?j¼[.2sXrahݨ> 5Zzxd5iB%?yr"̱Ms#ӳfFz僼3*g|S$L Y ~?_,Ep0q4ߘT8z]$';˺E ^֮?\0t@~e+ )^//G=,}-; 3y5pT:+g֚*lZjco"vf=*k"qxe ׅuِQq[ e>shhvˇOQLK*)gW^.nڔj)sJr[Ņd6jBbJx./e HvJzKgW@f1Zh\j _N U J¥,6J "!B6eV9Wq88Kz}(1Mڂ_]{pj*y5.$H"$HV{TD<\rB:.. -2#+\+T!qa{ !K޾+\]?e Zνضk ;ֱgqLiPidj9DJ2%3\i#tU#T" a .N!CCH!CMfYRd#5!A K |B#մ,F('Dj84!3YJbe63@ LF*;\l$SQ>iG쫚`NGdW_xqq r`$:.R߂,cuOةXr,Ez Cz"6fWnS~c$BBZ(( _0uEZrû2v\ѹsi>]uqi ɛ^;O>/n=QosC^`dOn`MdI@F}ν/\&>uBY;wv~^;@m>Tyq&p0 }1CyѮ Y+cw1TؽHA|93>PTJm 2FEpS8iP;8X4&?;='KQAݳg.d9\ 5 1G%J&Ⰶ@ņWnsbT)kR;.ߓ K0P^ivΞ̣ѵfH>W'^؀ޏsmJ;X6D zQ( !4{-D<ʡVC\J~%-; c\S.`ԀȻ?-r,,XwPmZק\ fY[%3%/g\9ᬡ6 jEek/vUIiPIʔx#ǔ5عn\yR8dx-su)wŅ }<_Xyic+TQDŽ N +s1ۣO]pEi]uSB9!qʹt\֘o,!&32qugk8Xӣl۩d5I 1}N?wC!WK=J:*b` v|3TYLD n,(WìAFxx]66ʖ |1Wwz9J/sN|'/lŨK;P\yPBq-pzQ'qu}4- rd1Oƕ7a +3ZeGAG/g y"asw3e\{A{oZBϬx[~ͩ)f8wH֛#tPcP]| ˹כү!oyeIj6>/Pc@ J>I$DI$_!M 3$ʉ(35ūM" 2a +c1p9'8NfX4 l@e8NGȰW{O( L3mDHVa\l4C>ZE=0p/$S 40B8⡢e0%J $RPnۍzA"A^eƈAqRzjF\P* ѸAS(`Nl !^3i1"*(U~QD R!HH"*~P0` S$$|WHG$_ 1mqgX Ob4Bv>)$ uOXT;cȿi3٢OAgеLZʴ7V2g 1ja2/̚c^}rUnE,=F_ErJdT;30Wl;vDȮG L)!=,6iѧm΢m ZsX}S\uӘY 9ޓ8 sweք'E٭gdN!N 2vZO\0{33~>v94qV%Pea|^^u}*;#<-7f}W$NKrˊCP-oy73dwq;qSj(%4A\w#cS"RJS.'VMQs{R_KAzy5HZ)xʄ{<{Y٣IɬLzQa*vWӹkls ˥eL!Fg%/]֋=nr{LrOfύOe׈ǹDEZ,ru%΂rq>FkԦNvNI8n¢bͪ:411\Ur|x/A,¥/C X *idĐzX@˞#xͯX3V)9ڐ/üRzU>[ ҳrW -+۠rs<.TϤw M')SXNٛؾSmS{<6nUB=FL`o#y~LHL O ;Gȭy8?j-{3vhίgt9 N{xg eP#:C-oG6}UjM9y#r8|lI^۹c5 Lkی_Ojj5|YvƗ檦BYc^{D9VAˎMh88Pݡ>;i{n'ࢗwъZa;F orp+^dňO=<xD&JH"$Kv^T*@jMĎbjBF,P!(^ҭiu\,ӳjiZDX%<H ?oN48m#DiÔ^7WaFcF2B^M@qCZN遲iI(DQ,ˊAW%O X/ggҞu!dxJInR<_ V Ll'0HiH,@cx"D@;qaq*PUǂJT&&r IDATEc%7_eB]A'glÉWxuAUHf ;oK%-nUM[d ?[$Eo%`/+ly˻kW_1CjDIsqZdRprL_5l% Y'bAJo~䋾#%Rr|[Y=REJ` TEILML'r=_\gY!G%6/؋DXXxRxWhԸEAr@nwۓqg\U aƈ˃(c ޹ o;; 4Y_I$"lqomy_" ΢^JdyDo[I$DI$JyJ6i( *DeYB(DH $h\ܥմdR \)!ylưL0D+ϥJ)!H5mF+g4f:Ґ0ZL.(a"nSa tR 5ℛm `uA4Z;j7Nd6UujK[=)`?^AHY`Lx:~o)HAJGcLB# m[\aH"$H"$HZH"$nR V[G;XiSEX(.(\,#DZZyLKPݍSXF@)hBKRc!8vԳ:\\7i(Wzv` Z:_#D",R~rZ M|.,P)8X! :D#{0eiYF! '4Q׉2* Zi/>(JEOqX"ֆ‚)(I%xڀ?ӷVYax- B+ ϳb^jIiĊ8&ĊQ DLs0 0\@PƭʼnSE Oc'E,&{fHNgu\-DI$DI$DI$DI$8B |i% OhJrw#Zl# 5n0תh9QK&.å˛gd/~,MQ 8;ksZ&񰪶6h2x??odooUegg뮻jcMh4Fh4L@"YM9)>w]fݧ9;߬.]ǁe q; dVg9f3༳u8q9E e9x>V}8}zC.卞opy_qy|~@J~HB׷݅[n"Uce6>n3!Bw8"emwhR9@c,&,xbtϴ'KhƘ(6a)Q g;A >E+ZZ$M@qywvL<4bS}" 6;R:1MU9k3ut8;g*L5~[Ey(c/f۬hnƐu08\b^Z"s_FvCqgg'XM'oԫͬXllFˑZ8/񴜓s[МvϑS-ɁYirO){;t3o>}ûx'_?h?s-򗿜jqy]]\r%Mo8\sMRh4F㫀ȉ?vW=l\Ow[loГ]sxKRx!"~ 5B$&jգhK(@]ct͌.v[I6}%ם})M8΃56nd3c}qɆm^Vm%L\ X舖X9ZZA9@X-NSn#"7%ا ס"-89'}˹*/9rG;8 <Ǹ#9r?S|}?K.B.y|?m>[>< 9󘧼7\71'y\Kk>[Guȝi ĕ]$^w̭?B.<,}?C#_t!g_ \_˹gþW[w=q\q\x飹뿇'|^ŏ~2GnMw-?SWtM|_94n7%Oxl q4J!A:zt8aXl -#AS PH2=B߻b28ۯpnry/lm]ioEG udwHkr>rgdƹ4 ;LB郯`&pН|( iPLj[hv$qm\\~Z" κJ5_-׍%\ì_oV/bj/;^I {:ŏ' ̛xVs2I9^\pwubpȅWm6@2摐!)_qy_ᎥPS]Z s16J|Eѯ>k_ʋMqo#S uR.]w+~0g_YYvwq}R.tNhfx[6 c8,˰ 92OugsEqbo<"^@UEPr~2N6F^;qmYcRt1 *|"H#)h2SIqnuǡj4gRٵ4c?3cPIqzlq:1{0.TfRI~ariUwj|ׄYbY0te1[ͳ 8 8 1h_gӼ/;+fވs}9G|,<[6؇&m,ƕGVuF=J8?s%QPBWz[g?v,xՕx?K|7_0/O_kX}F>ڿy]9t~ǿK g^yp\~楜wכx7-_wW=ͯs~]߿[x3^śeǯK]K?\}m h4F*Sϰֳ[=LJ]=:.v }9Ym˪?Đ)9$툹,eH6gLz.DUQ;ҟ77F|pcD]Ӥt,ړ˃L:E6_byXדԚ8J[t ,HrN,]ORʼniέ-kgU8 9O`'7D&|r37l8<)W#d֛[ǧA e,CDi",yWyՁXdewEFOa͇ ,VXK'HN+fMGȟϣ#]EV໾QpW-yp勅TjE2?f\xg'^}G^jEؿ~t@9|+:.y8obo '0gVz|C僻JxGx# F?y,_Q>?ƅgُ>|wt+ܚ~{~=>pOk4Fh4nЅ~/'q8'>o_7fy圸FO۽l4¨&4I){DcI@z|J,7Dak\|f8cԩqr;\q;A롘2)rHiMJOͽn[8uvvOݻݻ?Q}8 puqas;H Mޫ6u&!E.S\vBf<=ecu$<#N1Ft&"Usk չ9Z4Ls8.L}ubc`HigMǴN}}?ˡ \ޭ}z=;DuY9kNW'RDSerDyL ACفR@ms+ҧ7Kx޷yOfǽg~;35|co|'U~wg~s;~_x?DR@o5Ͽb!I5]w{K/=#Gp!zFh4C {sx?uO||x ^ɵGoݼ͵p޳Eww\6G`$)Չ84 +K~М3+D"D:xT.8RNU`^Ӈ@N#Qi(QmQ|0 LS[iχ4(@X޷a:+jjbqhRe#M,uMNlLIpr%DMLC!r>@U5<7a5iY j9WqVlygMI|RB-=v\nћWk__ˍ+;=鵖AJ{tV\Tm!t^^O&s=;> \^wJȱl_fux:5[1xow#K<@-ď:op$Gm/S}=<_o D❼bع@ٻ׼{DŽU_}\~oĻ8z\u9\|#9/pgI(I@=ɄOZǔ u,+$ 귁jԁb { x.I<1yQ1QM2VQq> \@~@$![ڭ{!6 qG axA$\ s8US\uA:`]lQByZhκ]vmZ pVr{fo \-Hp>.5X݆$8ݐ4S)sLxVI)k_}zKQȀŲin^?kx=G^_q7 ڿĿ~)c˸[%e|ϳ}+]\enO +7yr/p9y{821*᪗kG5/~<꺯=,Kx8_sq♏G?\|#x?x;~N IDAT4%W~6O{ԧ>{|=i/X׊HV RZāw#!t>t[wgqpBùx'j-%`o6,1-g3$rU`XsˮU(ah.yH~SiE7?OZ=}"l3SqϚ'e{_b:Őn@qN&11oo\<+3{~]q·͟)/'z gO_Q^K^`ع'S|ܞ'~˹:'3g})WO|O>ֿc 8.xɿ_^+9[sサt= @/<}Bke/{x+x+^^2Eh4Fx.Q:|7GIs˯4ݵO}-|~=|v6_I4[T59('K:'j q "D!f%FE$ ɼe1::=3}$ގ/Rc;BQrqYYHQ m''|nEz}} C攫f%xd*]YPzQ]1$@:P@bm] 8A(N`x3^ xpbIai0Dj"S.qٵtVvVL?XXv'Y]w94i\LK5::YT g&,蜐Ҹ80K)QKM.C$JNQCg>qvzD$zqOFh4ycx:~cf6|Ciٗ]3~͆w-ozD|ݼ÷u{x]*^z_)OyW/ s{HݙzDQC|n{r'ueUWξL)g'qkzs#}Q:'';x9ҧ{\'䄠nl^Gc+0dCg3IS"=눹y%œDҭH萸Yu0{E%u>sd0?%{_.fsd9uWE@6,c<#E6{6gǫ3(;/UYmP)%~HZ,ZFQJW_f$eVazߢҩ *FNJY))dI9&\"[n<u֔4_bv>Vdϣ ZrC o fQvwhžp-O)OjYEy~<):RLI R?ejs~͒ounFh4Fh4"Z7{H& yBCqzRfX)_bĒTQ6ˌy$"%;'&yx˦ eEa¥,%u(0g\ !ǯv9w^V2#$/xʆrڇh4Fh4Fʼn\@נ[:a6 }Pp4$P{yiU\ o1˞@;F}SܢS}vzzZ7$ί]>E4ueW0Ϧs'r. syS$~4Fh4Fxh EѼAn 3]m Ɣl# du[Vg0VHd'X'4)h+~Ujc8V%[[e$6a%ƁO5}ӈy4@E}wjw qHѥb,!r6S6MMw :CX[$Il4+))^m839rk*مkq1ܥXcS݁Yp[.p>P|[SW>"UEkN1`u^)jC!yF9=; 7g`UaЬ[ȤZ$z^/Fh4Fh4 FB'3C^4W&Ta>LO!K5[G|ߓu[xlos`1Zj{E HKLģBXB"R]Hq)#2\ Ō0.֥@"oq*Tzxlf8|;-902TfuzJ%i…Y9}]2V-.J3y_b)tnuӺqճ"&":IZreX -Pޘ#Mz0 qnuUA.R˯exDe18.y뾶Dt.c,oD'jow2r}jAsiޗ9,St Fh4:/^݄FgLp(OS2xO֎:,j.'3)"E;J\]_O_!`ghow8-XMVR‰:sONp(YrΕu*IVV[Z$bC "au-vH)yn*eSR;7[_OnRpN@۹$6dz| gAQ$]V\hQ*V^a^"3UMU49U7Fh4Fh<HoJL |8I'9~vT]BqFeͽt~YA̩yɊl5jIjuc}#q%58Hx"m#g.;ZX !buyodE{2}(C].IE؃e4!lwa5ti2Uu躮κVX.֙b`$E,:"uDzLd!rI uy8ypc/cRYGߵ17殫0cwzxЕk#ҳ`n :Blqg/ԍFh4Fh4&Y#w~(0BN6e*{<~ C4PM8ړ;j k` kdo!}R20IVߑuÈ Y'X{/e%[_JmI{rX t"b݈e™em1urrZV .zq%@d֬^blcvտBg/Qnegu-bmYӢp]E|"c֘ׯB沃*u9g>Ld7q*orҕ8GR=YϪ:Fh4Fh4B=9 3^!5@Vt\pǃ~:M=1_!8qm,<'HqLHM_CϘ.4@ǴԛaH$mT&4930$M}_BrB{[(ES뽛D?a~]9FH1E,ZgtEs1|"Ħ\~YΎ:8;rx\苐7sU\3a//>2U-cBV>bK]ש\v-E]SΝ΅ق$.?sٽ9p {{kjx?3~z=+h4Fh4F;dm4xFp+àEKYL4KeC!I }Li2u9Y= )ԌYxp1 I1\G4Eck]Zuv#\LpyUI^y⪠ge=?ϑޔ,,M]o$vgYxwiڞ/͎LwٌVO@&'nd[Fwms8Y,؅I 19fT?tO"ӍYT?=FLEu^dfc Fh4Fh4| ҅[aU:RL4k&qK#Yu:DMn0JRt,5!dHxx4 x̀=0L&7=1FPHeܵ|[1 s!Ln뺎q'=GsbZ>>Yd]VЉ#"ZWah4Fh4ƃO!P+xr[fmG@6uy7'?S4ZҪB'U7"3ESI&~}O8Z_} UdN,39V~Uf@pL3 &*5\ ^М -+X< Nf ΋u^pI)1\Fd-WgbMo)N"/k&"~Qx/S9I0{#:$/W-&[Εe5^yJɌ4)C' rr/|߮-h4Fh4F!=?DFPIyFq'adGSgmE "|S\wfMJ 8P.)i1YY4RÇnV-9)u"h&w~2Ř&1MDc42֋*8Nš3,†f-",t8ՑX֤xqrWcKӟmpWgI{db feTbxӗuT_|s'b"B]=}8"_P,7%Tvur)=XE\ YPY'j2+':ߡ1E:OqF#j2}gGB7姌s u]8.lnS]m.0 AɑGy6'hԍL*YXyDH"klxG5N:ѼqFaݕ EQ8֑ɷѻ6|#UBZDOrİ>ruNyyxm.N]X/sĸOKQ⣟ȳҗbĺ@3<} }U4PuZ86atiE~k4FUɫ_vF n 5i?z)~z=8Fͅ]-w4~+IG:<]rmI؛tZ*˒*UGvCOE!Y|K\+%\rlӇV1~M9]}օXi]yhJ MLh4Fh4F>VȤ{ utaq .Rcl1Y.o%AFr+)Y98:}ǎ\gȤ!|1Ez bĵi-DBVu=}nr9s\#r̸WQ IDAT))⟿M`(y"X7rzsЕIه܀qQgc UdkěQy~̮*Z_.esY=8~tU45N`l4Fh4FxM[VĔ9tI")9~ ]*CZ9e98g498xC QT!Ɓed]!ɉɬ8\gZNU_NcWsfq$) .x:[uےoJwy{>:eQ"10'~;}G1dPl݌},'rJI:Wm}@O35ҔicBαbBgaqd(٬ڥZ&kϟ|ܢ_*I94嶽 :[^=*UAto=xz靈SP**:7E~7?cǎ4ÉC䍁h4Fh4F`|ǘ#59plRv?N~)F>Q:D:2&މu a.i#I̱#!(xp> Iʀ6~Yw$b<|{< + NdzIWҪntµQ:N B. U&+w$`U-d6O\~SLbuL Q˄Tf=îjyb&)j' BVuΊ+"qcVg(buhgw'W,UA-Oqן~U\4gʊ!C ƄR^;{bycRh4Fh4F!@<2ġ"&pIU֧>D1{1~u_8r7)f!Di-wL#]ߛ6w=O~udU>'zGmc!"xQTQ"oM"L4]`s̙gY;gp?g_q-q9ʱ'M /h)F4YNeCުQi+9W{lQ7-lY RuM3t[3 k=xOx|ó/4aUuWBM$͘-SfEX݄\bMu<:-9t];|rh4Fh4FĉHZ搮URXR.@{Gl7gׄEYAϽF><>s b.8)K:A)y|:0bJt]7/Uf(!e;eMXUc*9%kvu2A;/o\ﵫLkv#]ױ^'{o+ʅt97'gYbqlYГyxvZ_WT\3FHg>ynWQԌ; ^4[yW|H+}_9:ABmڹWɊ S$ZAKqh4Fh4F&%{i"L/9pG`w7^FrIv" k"seaY w,qRZ{}s6y ēh9f" ij:L31b0ɫݘ i49iY:ͥn f$w9ɣ7c+ 軞8&r$L[*Y`R&Hb Ҿ)#epa Ըr@FLi4( 6ؑ1 "9Yg+.*TCy-¼+"(DhL8嗛 7WD߹z{Q0Z50Ac'ASK4Yh(y?97u%O46s6Gbh4F`y{ >[}kn42N6#91~D\DŽ0  Gܙgqn2}T~|ɽ]nNwޭp8BPʰ9Z:Nۃ9܉I!ǒ"p).M)`9 }#+NMrNĿ:0 );^,m]29AQU񥮯JoEӺEhn]N0kUeujg_|mָq{[ogϩW]bKNh2 pWyCoU猓++. (M˽\9e83slxs^ٗ_@lLq17T!:2o^'WCh4Fhբko_1;~B?m8'2N!~??>FhlLP@L/Wg>UP`kLvC#i}hf7ZDߙSB9!E  t(a=mSF|L;8){f#`a E b"0!30pz|pbŜ*@E@8Ai 3]Q=]TUo?~v~y~_v`J["ך\h35p<)4iLh׬ 6rpBMk uK}h(!>(Wk¤{0W_܉n:aQ+"2wzg\HTaT}6[o.uFh.Df6< C!Mh|% a 08jl˨|Pd s -='S⧮Jcvv}b9b.e%4jޅa _e9bs/>}z4 KgIy,s3nVi@[gh&r8ѯτopQ;Ӿ$da+OUci$Ci] i͚G(9#TndpN MhQ[#rg(n|܊}:дQN"΃9XH}Ǟe_.Obgc~%W]uW[+ֳsmfy/P8إ%yP)j;3kktt}1_EYl{i8J\}Τ16l$ZR򊚒,(KjT5^z[Wn^Kz 5^_[ ^-*h!@+b0qZ#GhS& Bk|iJaK Bn,7%-,)M>_!Ha1OxWbe3jŐ/SKplZeη_S)v0u}B"d5|>#>3xϾ5U+q}שe#(VӔ%e:2uB[H׈2qΰ^WUؼ?kX3a!qtuw5הҁ:cs kN( ۠1{CA=D+ e!Va-iPG1+Tڌ O+j[:A²9?]sH Io1ݿХy|3=Տ1ծ\ܲgK.L-r?w4NgXѕ N0֜Zz(0Zƫ=G_q:ChsͥK9U[rrCCG3__aln'n[ /qRG6 м/MĎ\:ezGϓmOlXF^"rTmV#׃ ?o{nf8!ѷ0y8iH;6Ӭ~d+w9{/It& ߹,f͚Dú8UJēS=sQ8 1J9),/L{kk{Ǟ~4NJQ@?UMU*--Κ* vKG0%v\Y{r\TZ ;w-Kzyb/ni-3Jf+Fjq%|Ҹoa">y,Z8  ??O5$-tC|j7'=Kv5;;?ZZ~Wzj)+" n;#À4?eWmP.vGrFZ^sIbó\w Z39RG]qr1=ޞrܴǸx| Vv۬LR: =ռ~b9p ܋:DbHW6v)W9XL`g a_:n l`}?>]g 6[Mwx{n-_2zl<<ߪ'CGf69뱦jC y-gz7VgxOj3L7G/<)^zğ薗-'EYl{x \<%"R(i۱\sAe dAov,FxJ-릱1%RjHW*l;Ϸ˗(-pN#--Ҿ&X IJ /H8ڄcX$.h$$ Ki#eMaW y$ ?y_hO :0 D1*(8Pj2RT,2: Cc\(57m߸}4&#]1Հeޱ#{\)+Or;#5_^n,w+t*}ONѤGw w< #w]9onUQPܚGǕ>Ыyn-q&6uG؜FESݡ;g0 D+_ӤQ!-w`%"tNўfͰxs`(Q2:~"}aAUXsǴߥq̰V;2+t=sNٝV-~lcϑ(/oFA gfD2 Ki?$/~D':qzqY }pvپmē1/$N2rr83)zgg0j~l׺s47s^(*.ߗ M8スVuUF[#i^>-]v݃Z0蔳9{cJ{f> Iq [veo]= I6m^]c[MŇ`l&4*iʾv~cM2'd+E[_{ꝛz}GwYl,[;2h@~=+y?W(-IcFQ[B֌7擼J%o#Flb͌