pax_global_header00006660000000000000000000000064126314226520014515gustar00rootroot0000000000000052 comment=41a30dd4e47520fd271af7ee925f018261f47b14 onionshare-0.8.1/000077500000000000000000000000001263142265200136705ustar00rootroot00000000000000onionshare-0.8.1/.gitignore000066400000000000000000000005741263142265200156660ustar00rootroot00000000000000*.py[cod] # C extensions *.so # Packages *.egg *.egg-info 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 # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # vim *.swp # tags ctags tags # OSX .DS_Store onionshare-0.8.1/.travis.yml000066400000000000000000000004131263142265200157770ustar00rootroot00000000000000language: python python: - "2.6" - "2.7" # command to install dependencies before_install: "sudo apt-get install -y build-essential fakeroot python-all python-stdeb python-qt4" install: "pip install nose flask stem" # command to run tests script: nosetests test onionshare-0.8.1/BUILD.md000066400000000000000000000133141263142265200150530ustar00rootroot00000000000000# Building OnionShare ## GNU/Linux Start by getting a copy of the source code: ```sh git clone https://github.com/micahflee/onionshare.git cd onionshare ``` *For .deb-based distros (like Debian, Ubuntu, Linux Mint):* Note that python-stem appears in Debian wheezy and newer (so by extension Tails 1.1 and newer), and it appears in Ubuntu 13.10 and newer. Older versions of Debian and Ubuntu aren't supported. ```sh sudo apt-get install -y build-essential fakeroot python-all python-stdeb python-flask python-stem python-qt4 dh-python ./install/build_deb.sh sudo dpkg -i deb_dist/onionshare_*.deb ``` *For .rpm-based distros (Red Hat, Fedora, CentOS):* ```sh sudo yum install -y rpm-build python-flask python-stem pyqt4 ./install/build_rpm.sh sudo yum install -y dist/onionshare-*.rpm ``` *For ArchLinux:* There is a PKBUILD available [here](https://aur.archlinux.org/packages/onionshare/) that can be used to install onionshare ## Mac OS X Install the [latest python 2.x](https://www.python.org/downloads/) from python.org. If you use the built-in version of python that comes with OS X, your .app might not run on other people's computers. To install the right dependencies, you need homebrew and pip installed on your Mac. Follow instructions at http://brew.sh/ to install homebrew, and run `sudo easy_install pip` to install pip. The first time you're setting up your dev environment: ```sh echo export PYTHONPATH=\$PYTHONPATH:/usr/local/lib/python2.7/site-packages/ >> ~/.profile source ~/.profile brew install qt4 pyqt sudo pip install py2app flask stem ``` Get the source code: ```sh git clone https://github.com/micahflee/onionshare.git cd onionshare ``` To build the .app: ```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 --sign ``` Now you should have `dist/OnionShare.pkg`. ## Windows ### Setting up your dev environment * Download and install the latest python 2.7 from https://www.python.org/downloads/ -- make sure you install the 32-bit version. * 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, and add `C:\Python27` and `C:\Python27\Scripts`. Now you can just type `python` to run python scripts in the command prompt. * Go to https://pip.pypa.io/en/latest/installing.html. Right-click on `get-pip.py` and Save Link As, and save it to your home folder. * Open a command prompt and type: `python get-pip.py`. Now you can use `pip` to install packages. * Open a command prompt and type: `pip install flask stem pyinstaller` * Go to http://www.riverbankcomputing.com/software/pyqt/download and download the latest PyQt4 for Windows for python 2.7, 32-bit (I downloaded `PyQt4-4.11-gpl-Py2.7-Qt4.8.6-x32.exe`), then install it. * Go to http://sourceforge.net/projects/pywin32/ and download and install the latest 32-bit pywin32 binary for python 2.7. I downloaded `pywin32-219.win32-py2.7.exe`. * Download and install the [Microsoft Visual C++ 2008 Redistributable Package (x86)](http://www.microsoft.com/en-us/download/details.aspx?id=29). If you want to build the installer: * Go to http://nsis.sourceforge.net/Download and download the latest NSIS. I downloaded `nsis-3.0b0-setup.exe`. * 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, and add `C:\Program Files (x86)\NSIS` to the end. Now you can just type `makensis [script]` to build an installer. If you want to sign binaries with Authenticode: * You'll need a code signing certificate. I roughly followed [this guide](http://blog.assarbad.net/20110513/startssl-code-signing-certificate/) to make one using my StartSSL account. * Once you get a code signing key and certificate and covert it to a pfx file, import it into your certificate store. * Windows 7: * Go to http://msdn.microsoft.com/en-us/vstudio/aa496123 and install the latest .NET Framework. I installed `.NET Framework 4.6`. * Go to http://www.microsoft.com/en-us/download/confirmation.aspx?id=8279 and install the Windows SDK. * Right click on Computer, go to Properties. Click "Advanced system settings". Click Environment Variables. Under "System variables" double-click on Path and add `C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin` to the end. * Windows 10: * Go to https://dev.windows.com/en-us/downloads/windows-10-sdk and install the standalone Windows 10 SDK. Note that you may not need this if you already have Visual Studio. * 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, and add `C:\Program Files (x86)\Windows Kits\10\bin\x86`. ### To make a .exe: * Open a command prompt, cd into the onionshare directory, and type: `pyinstaller -y install\onionshare-win.spec`. Inside the `dist` folder there will be a folder called `onionshare` with `onionshare.exe` in it. ### 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.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`. ## Tests OnionShare includes [nose](https://nose.readthedocs.org/en/latest/) unit tests. First, ```sh sudo pip install nose ``` To run the tests: ```sh nosetests test ``` onionshare-0.8.1/CHANGELOG.md000066400000000000000000000052701263142265200155050ustar00rootroot00000000000000# OnionShare Changelog ## 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 bug fix 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 zips 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, Spanish, French, Italian onionshare-0.8.1/LICENSE000066400000000000000000001046141263142265200147030ustar00rootroot00000000000000OnionShare Copyright © 2015 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-0.8.1/MANIFEST.in000066400000000000000000000004631263142265200154310ustar00rootroot00000000000000include LICENSE include README.md include BUILD.md include version include onionshare/index.html include onionshare/404.html include onionshare/strings.json include install/onionshare.desktop include install/onionshare.appdata.xml include install/onionshare80.xpm include images/*.png include locale/*.json onionshare-0.8.1/README.md000066400000000000000000000064171263142265200151570ustar00rootroot00000000000000# OnionShare [![Build Status](https://travis-ci.org/micahflee/onionshare.png)](https://travis-ci.org/micahflee/onionshare) OnionShare lets you securely and anonymously share files of any size. It works by starting a web server, making it accessible as a Tor hidden service, and generating an unguessable URL to access and download the files. It doesn't require setting up a server on the internet somewhere or using a third party filesharing service. You host the file on your own computer and use a Tor hidden service to make it temporarily accessible over the internet. The other user just needs to use Tor Browser to download the file from you. Features include: * A user-friendly drag-and-drop graphical user interface that works in Windows, Mac OS X, and Linux * Ability to share multiple files and folders at once * Support for multiple people downloading files at once * Automatically copies the unguessable URL to your clipboard * Shows you the progress of file transfers * When file is done transferring, automatically closes OnionShare to reduce the attack surface * Localized into several languages, and supports international unicode filenames * Designed to work in [Tails](https://tails.boum.org/), for high risk users If you're interested in exactly what OnionShare does and does not protect against, read the [Security Design Document](/SECURITY.md). ![Client Screenshot](/screenshots/client.png) ![Server Screenshot](/screenshots/server.png) ## Quick Start You can download OnionShare to install on your computer from . You can set up your development environment to build OnionShare yourself by following [these instructions](/BUILD.md). You can also install OnionShare in your Tails persistent volume by following [these instructions](/tails/README.md). ## How to Use Before you can share files, you need to open [Tor Browser](https://www.torproject.org/) in the background. This will provide the Tor service that OnionShare uses to start the hidden service. Open OnionShare and drag and drop files and folders you wish to share, and start the server. It will show you a long, random-looking URL such as `http://cfxipsrhcujgebmu.onion/7aoo4nnzj3qurkafvzn7kket7u` and copy it to your clipboard. This is the secret URL that can be used to download the file you're sharing. If you'd like multiple people to be able to download this file, uncheck the "close automatically" checkbox. Send this URL to the person you're trying to send the files to. If the files you're sending aren't secret, you can use normal means of sending the URL: emailing it, posting it to Facebook or Twitter, etc. If you're trying to send secret files then it's important to send this URL securely. I recommend you use [Off-the-Record encrypted chat](https://pressfreedomfoundation.org/encryption-works#otr) to send the URL. The person who is receiving the files doesn't need OnionShare. All they need is to open the URL you send them in Tor Browser to be able to download the file. ### Using Command Line in Mac OS X If you'd like to use the command-line version of OnionShare in Mac OS X, after installing open a terminal and type: ```sh ln -s /Applications/OnionShare.app/Contents/Resources/onionshare /usr/local/bin/onionshare ``` From that point on you can just call `onionshare`, like: `onionshare --help` onionshare-0.8.1/SECURITY.md000066400000000000000000000110221263142265200154550ustar00rootroot00000000000000# Security Design Document ## How it works OnionShare is a tool that helps users securely and anonymously share files over the internet. First, the sender chooses files and folders they wish to share with the recipient. OnionShare then starts a web server at `127.0.0.1` on a random port. It generates a random string called a slug, and makes the files available for download at `http://127.0.0.1:[port]/[slug]/`. It then makes the web server accessible as Tor hidden service, and displays the URL `http://[hiddenservice].onion/[slug]` to the sender to share. A final OnionShare URL looks something like `http://szbjzh4ndjo4wexv.onion/sad4vq2qvvp3bbszwioh2jwlgi`. The sender is responsible for securely sharing that URL with the recipient using a communication channel of their choice, such as in an encrypted email, chat, or voice call, or something less secure like a Twitter or Facebook message, depending on their threat model. The recipient must use Tor Browser to load the URL and download the files. As soon as the shared files get downloaded, or when the sender closes OnionShare, the Tor hidden service and web servers shut down, completely removing the files from the internet (there is an option to not shut down after the first download, to allow the files to be downloaded multiple times). Because of this, OnionShare is most useful if it's used in real-time. For example, if a user runs OnionShare on their laptop, and then suspends their laptop before the files have been downloaded, the service will not be available until the laptop is unsuspended and connected to the internet again. ## What it protects against * **Third parties don't have access to files being shared.** The files are hosted directly on the sender's computer and don't get uploaded to any server. Instead, the sender's computer becomes the server. Traditional ways of sending files, like in an email or using a cloud hosting service, require trusting the service with access to the files being shared. * **Network eavesdroppers can't spy on files in transit.** Because connections between Tor hidden services and Tor Browser are end-to-end encrypted, no network attackers can eavesdrop on the shared files while the recipient is downloading them. If the eavesdropper is positioned on the sender's end, the recipient's end, or is a malicious Tor node, they will only see Tor traffic. If the eavesdropper is a malicious rendezvous node used to connect the recipient's Tor client with the sender's hidden service, the traffic will be encrypted using the hidden service key. * **Anonymity of sender and recipient are protected by Tor.** OnionShare and Tor Browser protect the anonymity of the users. As long as the sender anonymously communicates the OnionShare URL with the recipient, the recipient and eavesdroppers can't learn the identity of the sender. * **If an attacker enumerates the hidden service, the shared files remain safe.** There have been attacks against the Tor network that can enumerate hidden services. If someone discovers the .onion address of an OnionShare hidden service, they still cannot download the shared files without knowing the slug. The slug is generated using 16 bytes of entropy, and the OnionShare server checks request URIs using a constant time string comparison function, so timing attacks can't be used to guess the slug. ## What it doesn't protect against * **Communicating the OnionShare URL might not be secure.** The sender is responsible for securely communicating the OnionShare URL with the recipient. If they send it insecurely (such as through an email message, and their email is being monitored by an attacker), the eavesdropper will learn that they're sending files with OnionShare. If the attacker loads the URL in Tor Browser before the legitimate recipient gets to it, they can download the files being shared. If this risk fits the sender's threat model, they must find a more secure way to communicate the URL, such as in an encrypted email, chat, or voice call. This isn't necessary in cases where the files being shared aren't secret. * **Communicating the OnionShare URL might not be anonymous.** While OnionShare and Tor Browser allow for anonymously sending files, if the sender wishes to remain anonymous they must take extra steps to ensure this while communicating the OnionShare URL. For example, they might need to use Tor to create a new anonymous email or chat account, and only access it over Tor, to use for sharing the URL. This isn't necessary in cases where there's no need to protect anonymity, such as coworkers who know each other sharing work documents. onionshare-0.8.1/git-hooks/000077500000000000000000000000001263142265200155745ustar00rootroot00000000000000onionshare-0.8.1/git-hooks/README.md000066400000000000000000000002051263142265200170500ustar00rootroot00000000000000To 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-0.8.1/git-hooks/pre-push000077500000000000000000000002371263142265200172670ustar00rootroot00000000000000#!/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. nosetests test onionshare-0.8.1/images/000077500000000000000000000000001263142265200151355ustar00rootroot00000000000000onionshare-0.8.1/images/drop_files.png000066400000000000000000000037631263142265200200020ustar00rootroot00000000000000PNG  IHDR<qbKGDC pHYs  tIME4luiTXtCommentCreated with GIMPd.eWIDATx]oG;!QZJ *Pm4G/XX4vfvH{3gΌ7g#ܷB%$XBS@UEd#Vt=wI'4U5s X+)mVzq%4iPPo(olp8H!2W|=IU|E'\YSW迕#Ab %$XBH,!Bb %$KH,!XBb %K!B!B!B#1 %$XBb !K%$XBH,!Bb %$K!B!B!0GA׿Սdxwgoq^a5iq핮 xiiqmGMg5Q@Go-mnb)'^bu1uaHe(_3sY,merMaI YT/L$MIaަ'D6z3KؽRO20gyT/Ӥ08 <mKL 9:)#97OoPqKcP[务iE>3QwŁ< 9r =sz>rjsf_za)v܄P-r8W@/I'2zWt;7I._һ:h[L!Bֲx +IENDB`onionshare-0.8.1/images/logo.png000066400000000000000000000073601263142265200166110ustar00rootroot00000000000000PNG  IHDRPPbKGD pHYs  tIME2}IDATx{PTW? Vz'hGjifAktcƬaqG1h԰e&T1qtEBJF@2ը`"+t4зowGYs9{ Љb3ېd)t`0 X+8<7 7*Imx̶1<@|{,v&B'LC6$Yʏ70!$K: %Yrģ1g3ۚP |=G﯀Zi`Lj]B2\*xVkL4Q8v?t+)D}нe$K ;MmfX=84ʍȲ,4ʍ8x|>_,\K⢁Ml x4*~,,X[ J#cb),]~[˽{/:ύ+7U}ڪZjԢ7uQk?Jt7Q`dOAo3'3cQӻ\uwطz =bTV $Dt ,۔@>9x <|'?IL^̊10ƒ>zdIr _ղlAoj_o#!1S#_(i9K40j'})x>AX~`9*vux 7bhcN*nqDZЊ.;]zLgaC!Ȁ48F>=K{'Y%#69!DbVYňFtɈ/&癜HIr[|p2&ftٔ#cb ҰOGcĀ*tl;REv:G͏Tr {ЮJU%Yz]`5Yt=s;,ݻ о.]N;cnJ2ggj~ύnpe5p˾V1w9\?h-ol!/7Q#%zme:Z[Ft6/ zAM" qSpnZdYfޥXlnpT{XIYov5ݯ7A5"ÍjƼ2W7ʔ4ErSQZ1eEQnd龥yBv,b֛BKܥ=tOˢR^^2gO  \(e3 AijZE B^z:{,˧/ofmDE,]6tp5"_F:}C3i恍XܚzLj^ `K@ZMv(9%9  lY%n;|r) W_>uAx@tc;b7:"kq|RS5("uC*8PɋBn}&&,iy MXu!u uqBh0(:XDܨ(>RvD;PU}Ksr>󵙭mG|5Q'ryf./eu2()/ +U!)52wx6u[-LMRy9紫jUL&&pb |^_D4({ż_*Yyf=Fɱ6R%Iʙ+=x6]v]ᢿO8o.Bn7F^Q/Bbf{Q!k-rM$[OAQ5v*>EPQT@3vZlWGjUnU"w":j(ÞFrɉfQh|[o 0`/t)/`4hG|kjbŘn)[nEoG$Yjs&JIjcJ4LUt3m $S$0)TRr*Uj߬( ovh(( +-^7U5Sl^"+6lE g?M.^rֲBuTtSpݱ-[xAQAi^)3̠XbEX 3̠4T xE,-?̞K'sI 40ȱ\q \6-gI*cFe|͠*^__Nh+ԉ(Hמ1 0OMl@SՍ ygD,=F)1*I@~u '0.{ r+@{.6d<5XPg*ɒ1Wg=; a?ZK%IENDB`onionshare-0.8.1/images/server_started.png000066400000000000000000000005321263142265200206770ustar00rootroot00000000000000PNG  IHDR bKGD pHYs  tIME9 LRtEXtCommentCreated with GIMPWIDAT8˵ 0Dnt^E,H 3Pc,*ID@ΰ, c qE*120} तX;))`, {mXyJHEk{c$W&T`aSQK#ZOV }0Dae`%;ZlIENDB`onionshare-0.8.1/images/server_stopped.png000066400000000000000000000004361263142265200207120ustar00rootroot00000000000000PNG  IHDR bKGD pHYs  tIME9ܮObtEXtCommentCreated with GIMPWIDAT8˵ @ 'z+\Ԁ{qq8C &HќVxJ:.X>]:a6t>]l/L&;0+F`=אut|c?ЕIENDB`onionshare-0.8.1/images/server_working.png000066400000000000000000000005221263142265200207100ustar00rootroot00000000000000PNG  IHDR bKGD pHYs  tIME9$y tEXtCommentCreated with GIMPWIDAT8˵1 0?3y^zAȔS$+Xؑh\ D8cќh9?!h@[lj,[gnvb)5R %{L"$rY22RL3Iy A&waI>l\e_/+/2IENDB`onionshare-0.8.1/install/000077500000000000000000000000001263142265200153365ustar00rootroot00000000000000onionshare-0.8.1/install/build_deb.sh000077500000000000000000000007311263142265200176070ustar00rootroot00000000000000#!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR VERSION=`cat version` # clean up from last build rm -r deb_dist >/dev/null 2>&1 # build binary package python setup.py --command-packages=stdeb.command bdist_deb # return install instructions if onionshare builds properly echo "" if [[ $? -eq 0 ]]; then echo "To install, run:" echo "sudo dpkg -i deb_dist/onionshare_$VERSION-1_all.deb" else echo "OnionShare failed to build!" fi onionshare-0.8.1/install/build_exe.bat000066400000000000000000000010221263142265200177610ustar00rootroot00000000000000REM use pyinstaller to builder a folder with onionshare.exe pyinstaller -y install\onionshare-win.spec REM sign onionshare.exe signtool.exe sign /v /d "OnionShare" /a /tr http://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\onionshare\onionshare.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://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 dist\OnionShare_Setup.exe onionshare-0.8.1/install/build_osx.sh000077500000000000000000000025401263142265200176660ustar00rootroot00000000000000#!/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 python setup.py py2app if [ "$1" = "--sign" ]; then SIGNING_IDENTITY_APP="Developer ID Application: Micah Lee" SIGNING_IDENTITY_INSTALLER="Developer ID Installer: Micah Lee" # codesign the .app python $ROOT/install/prepare_for_codesign.py cd dist # for some reason --deep fails, so sign each binary individually codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app/Contents/Frameworks/QtCore.framework codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app/Contents/Frameworks/QtGui.framework codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app/Contents/Frameworks/Python.framework codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app/Contents/Frameworks/libssl.1.0.0.dylib codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app/Contents/Frameworks/libcrypto.1.0.0.dylib codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app/Contents/MacOS/python codesign -vvvv -s "Developer ID Application: Micah Lee" OnionShare.app productbuild --component OnionShare.app /Applications OnionShare.pkg --sign "$SIGNING_IDENTITY_INSTALLER" fi onionshare-0.8.1/install/build_rpm.sh000077500000000000000000000005661263142265200176610ustar00rootroot00000000000000#!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && cd .. && pwd )" cd $DIR VERSION=`cat version` # clean up from last build rm -r build dist >/dev/null 2>&1 # build binary package python setup.py bdist_rpm --requires="python-flask, python-stem, pyqt4" # install it echo "" echo "To install, run:" echo "sudo yum install dist/onionshare-$VERSION-1.noarch.rpm" onionshare-0.8.1/install/check_lacked_trans.py000066400000000000000000000056301263142265200215030ustar00rootroot00000000000000#!/usr/bin/env python # -*- 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') 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') pysrc = [p for p in src if p.endswith('.py')] htmlsrc = [p for p in src if p.endswith('.html')] 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.search(r'strings\._\((.*?)\)', line) if m: arg = m.group(1) key = arg.split(',')[0].strip('''"' ''') translate_keys.add(key) # load translate key from html source for line in fileinput.input(htmlsrc, openhook=fileinput.hook_encoded('utf-8')): # search `{{strings.translate_key}}` m = re.search(r'{{.*strings\.([-a-zA-Z0-9_]+).*}}', line) if m: key = m.group(1) translate_keys.add(key) if args.show_all_keys: for k in sorted(translate_keys): print k sys.exit() locale_files = [f for f in files_in(dir, 'locale') if f.endswith('.json')] 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-0.8.1/install/license.txt000066400000000000000000001060451263142265200175270ustar00rootroot00000000000000Copyright (C) 2014 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-0.8.1/install/linux_scripts/000077500000000000000000000000001263142265200202445ustar00rootroot00000000000000onionshare-0.8.1/install/linux_scripts/onionshare000077500000000000000000000016421263142265200223420ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 try: import onionshare except ImportError: sys.path.append(os.path.abspath(os.path.dirname(__file__)+'/..')) import onionshare onionshare.main() onionshare-0.8.1/install/linux_scripts/onionshare-gui000077500000000000000000000016561263142265200231310ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 try: import onionshare_gui except ImportError: sys.path.append(os.path.abspath(os.path.dirname(__file__)+'/..')) import onionshare_gui onionshare_gui.main() onionshare-0.8.1/install/onionshare-launcher.py000066400000000000000000000020761263142265200216610ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2014 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, sys, subprocess, time, hashlib, platform, json, locale, socket import argparse, Queue, inspect, base64, random, functools, logging, ctypes import hmac, shutil from itertools import izip import stem, stem.control, flask from PyQt4 import QtCore, QtGui import onionshare, onionshare_gui onionshare_gui.main() onionshare-0.8.1/install/onionshare-win.spec000066400000000000000000000031471263142265200211570ustar00rootroot00000000000000# -*- mode: python -*- a = Analysis(['onionshare-launcher.py'], hiddenimports=['onionshare', 'onionshare_gui'], excludes=['_tkinter'], hookspath=None, runtime_hooks=None) a.datas += [ ('images/logo.png', 'images/logo.png', 'DATA'), ('images/drop_files.png', 'images/drop_files.png', 'DATA'), ('images/server_stopped.png', 'images/server_stopped.png', 'DATA'), ('images/server_started.png', 'images/server_started.png', 'DATA'), ('images/server_working.png', 'images/server_working.png', 'DATA'), ('locale/de.json', 'locale/de.json', 'DATA'), ('locale/en.json', 'locale/en.json', 'DATA'), ('locale/eo.json', 'locale/eo.json', 'DATA'), ('locale/es.json', 'locale/es.json', 'DATA'), ('locale/fi.json', 'locale/fi.json', 'DATA'), ('locale/fr.json', 'locale/fr.json', 'DATA'), ('locale/it.json', 'locale/it.json', 'DATA'), ('locale/nl.json', 'locale/nl.json', 'DATA'), ('locale/no.json', 'locale/no.json', 'DATA'), ('locale/pt.json', 'locale/pt.json', 'DATA'), ('locale/ru.json', 'locale/ru.json', 'DATA'), ('locale/tr.json', 'locale/tr.json', 'DATA'), ] pyz = PYZ(a.pure) exe = EXE(pyz, a.scripts, exclude_binaries=True, name='onionshare.exe', debug=False, strip=False, upx=True, icon='install/onionshare.ico', console=False ) coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, Tree('onionshare', prefix='onionshare'), Tree('onionshare_gui', prefix='onionshare_gui'), [('LICENSE', 'LICENSE', 'DATA')], strip=False, upx=True, name='onionshare') onionshare-0.8.1/install/onionshare.appdata.xml000066400000000000000000000032511263142265200216370ustar00rootroot00000000000000 onionshare.desktop CC0-1.0 GPL-3.0 OnionShare Securely and anonymously share a file of any size

OnionShare lets you securely and anonymously share a file of any size with someone. It works by starting a web server, making it accessible as a Tor hidden service, and generating an unguessable URL to access and download the file.

It doesn't require setting up a server on the internet somewhere or using a third party filesharing service. You host the file on your own computer and use a Tor hidden service to make it temporarily accessible over the internet. The other user just needs to use Tor Browser to download the file from you.

https://raw.githubusercontent.com/micahflee/onionshare/master/screenshots/appdata-server.png Sender sharing files with OnionShare https://raw.githubusercontent.com/micahflee/onionshare/master/screenshots/appdata-client.png Receiver downloading files with Tor Browser https://onionshare.org/ micah@micahflee.com
onionshare-0.8.1/install/onionshare.desktop000066400000000000000000000003401263142265200210730ustar00rootroot00000000000000[Desktop Entry] Encoding=UTF-8 Name=OnionShare Comment=Share a file securely and anonymously over Tor Exec=/usr/bin/onionshare-gui Terminal=false Type=Application Icon=/usr/share/pixmaps/onionshare80.xpm Categories=Network; onionshare-0.8.1/install/onionshare.icns000066400000000000000000001025701263142265200203660ustar00rootroot00000000000000icnsxis32 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-0.8.1/install/onionshare.ico000066400000000000000000000353561263142265200202130ustar00rootroot00000000000000 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-0.8.1/install/onionshare.nsi000066400000000000000000000300751263142265200202230ustar00rootroot00000000000000!define APPNAME "OnionShare" !define BINPATH "..\dist\onionshare" !define ABOUTURL "https:\\onionshare.org\" # change these with each release !define INSTALLSIZE 31616 !define VERSIONMAJOR 0 !define VERSIONMINOR 8 !define VERSIONSTRING "0.8.1" RequestExecutionLevel admin Name "OnionShare" InstallDir "$PROGRAMFILES\${APPNAME}" LicenseData "license.txt" Icon "onionshare.ico" !include LogicLib.nsh Page license 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://timestamp.globalsign.com/scripts/timstamp.dll /fd sha256 $%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" # application SetOutPath "$INSTDIR" File "onionshare.ico" File "${BINPATH}\onionshare.exe" File "${BINPATH}\license" SetOutPath "$INSTDIR\onionshare" File "${BINPATH}\onionshare\__init__.py" File "${BINPATH}\onionshare\404.html" File "${BINPATH}\onionshare\helpers.py" File "${BINPATH}\onionshare\hs.py" File "${BINPATH}\onionshare\index.html" File "${BINPATH}\onionshare\onionshare.py" File "${BINPATH}\onionshare\socks.py" File "${BINPATH}\onionshare\strings.py" File "${BINPATH}\onionshare\web.py" SetOutPath "$INSTDIR\onionshare_gui" File "${BINPATH}\onionshare_gui\__init__.py" File "${BINPATH}\onionshare_gui\common.py" File "${BINPATH}\onionshare_gui\downloads.py" File "${BINPATH}\onionshare_gui\file_selection.py" File "${BINPATH}\onionshare_gui\onionshare_gui.py" File "${BINPATH}\onionshare_gui\options.py" File "${BINPATH}\onionshare_gui\server_status.py" SetOutPath "$INSTDIR\images" File "${BINPATH}\images\logo.png" File "${BINPATH}\images\drop_files.png" File "${BINPATH}\images\server_stopped.png" File "${BINPATH}\images\server_started.png" File "${BINPATH}\images\server_working.png" SetOutPath "$INSTDIR\locale" File "${BINPATH}\locale\de.json" File "${BINPATH}\locale\en.json" File "${BINPATH}\locale\eo.json" File "${BINPATH}\locale\es.json" File "${BINPATH}\locale\fi.json" File "${BINPATH}\locale\fr.json" File "${BINPATH}\locale\it.json" File "${BINPATH}\locale\nl.json" File "${BINPATH}\locale\no.json" File "${BINPATH}\locale\pt.json" File "${BINPATH}\locale\ru.json" File "${BINPATH}\locale\tr.json" # dependencies SetOutPath $INSTDIR File "${BINPATH}\_ctypes.pyd" File "${BINPATH}\_hashlib.pyd" File "${BINPATH}\_socket.pyd" File "${BINPATH}\_ssl.pyd" File "${BINPATH}\bz2.pyd" File "${BINPATH}\microsoft.vc90.crt.manifest" File "${BINPATH}\msvcm90.dll" File "${BINPATH}\msvcp90.dll" File "${BINPATH}\msvcr90.dll" File "${BINPATH}\onionshare.exe.manifest" File "${BINPATH}\pyexpat.pyd" File "${BINPATH}\PyQt4.QtCore.pyd" File "${BINPATH}\PyQt4.QtGui.pyd" File "${BINPATH}\python27.dll" File "${BINPATH}\pywintypes27.dll" File "${BINPATH}\qtcore4.dll" File "${BINPATH}\qtgui4.dll" File "${BINPATH}\qtopengl4.dll" File "${BINPATH}\qtsvg4.dll" File "${BINPATH}\qtxml4.dll" File "${BINPATH}\select.pyd" File "${BINPATH}\sip.pyd" File "${BINPATH}\unicodedata.pyd" File "${BINPATH}\win32api.pyd" File "${BINPATH}\win32pipe.pyd" File "${BINPATH}\win32wnet.pyd" SetOutPath "$INSTDIR\qt4_plugins\accessible" File "${BINPATH}\qt4_plugins\accessible\qtaccessiblewidgets4.dll" SetOutPath "$INSTDIR\qt4_plugins\codecs" File "${BINPATH}\qt4_plugins\codecs\qcncodecs4.dll" File "${BINPATH}\qt4_plugins\codecs\qjpcodecs4.dll" File "${BINPATH}\qt4_plugins\codecs\qkrcodecs4.dll" File "${BINPATH}\qt4_plugins\codecs\qtwcodecs4.dll" SetOutPath "$INSTDIR\qt4_plugins\graphicssystems" File "${BINPATH}\qt4_plugins\graphicssystems\qglgraphicssystem4.dll" SetOutPath "$INSTDIR\qt4_plugins\iconengines" File "${BINPATH}\qt4_plugins\iconengines\qsvgicon4.dll" SetOutPath "$INSTDIR\qt4_plugins\imageformats" File "${BINPATH}\qt4_plugins\imageformats\qgif4.dll" File "${BINPATH}\qt4_plugins\imageformats\qico4.dll" File "${BINPATH}\qt4_plugins\imageformats\qjpeg4.dll" File "${BINPATH}\qt4_plugins\imageformats\qmng4.dll" File "${BINPATH}\qt4_plugins\imageformats\qsvg4.dll" File "${BINPATH}\qt4_plugins\imageformats\qtga4.dll" File "${BINPATH}\qt4_plugins\imageformats\qtiff4.dll" SetOutPath "$INSTDIR\include" File "${BINPATH}\Include\pyconfig.h" # uninstaller !ifndef INNER SetOutPath $INSTDIR File $%TEMP%\uninstall.exe !endif # start menu CreateShortCut "$SMPROGRAMS\${APPNAME}.lnk" "$INSTDIR\onionshare.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 Delete "$INSTDIR\onionshare.exe" Delete "$INSTDIR\LICENSE" Delete "$INSTDIR\onionshare.ico" Delete "$INSTDIR\uninstall.exe" Delete "$INSTDIR\onionshare\__init__.py" Delete "$INSTDIR\onionshare\404.html" Delete "$INSTDIR\onionshare\helpers.py" Delete "$INSTDIR\onionshare\hs.py" Delete "$INSTDIR\onionshare\index.html" Delete "$INSTDIR\onionshare\onionshare.py" Delete "$INSTDIR\onionshare\socks.py" Delete "$INSTDIR\onionshare\strings.py" Delete "$INSTDIR\onionshare\web.py" Delete "$INSTDIR\onionshare_gui\__init__.py" Delete "$INSTDIR\onionshare_gui\common.py" Delete "$INSTDIR\onionshare_gui\downloads.py" Delete "$INSTDIR\onionshare_gui\file_selection.py" Delete "$INSTDIR\onionshare_gui\onionshare_gui.py" Delete "$INSTDIR\onionshare_gui\options.py" Delete "$INSTDIR\onionshare_gui\server_status.py" Delete "$INSTDIR\images\logo.png" Delete "$INSTDIR\images\drop_files.png" Delete "$INSTDIR\images\server_stopped.png" Delete "$INSTDIR\images\server_started.png" Delete "$INSTDIR\images\server_working.png" Delete "$INSTDIR\locale\de.json" Delete "$INSTDIR\locale\en.json" Delete "$INSTDIR\locale\eo.json" Delete "$INSTDIR\locale\es.json" Delete "$INSTDIR\locale\fi.json" Delete "$INSTDIR\locale\fr.json" Delete "$INSTDIR\locale\it.json" Delete "$INSTDIR\locale\nl.json" Delete "$INSTDIR\locale\no.json" Delete "$INSTDIR\locale\pt.json" Delete "$INSTDIR\locale\ru.json" Delete "$INSTDIR\locale\tr.json" Delete "$INSTDIR\qt4_plugins\accessible\qtaccessiblewidgets4.dll" Delete "$INSTDIR\qt4_plugins\graphicssystems\qglgraphicssystem4.dll" Delete "$INSTDIR\qt4_plugins\iconengines\qsvgicon4.dll" Delete "$INSTDIR\qt4_plugins\codecs\qjpcodecs4.dll" Delete "$INSTDIR\qt4_plugins\codecs\qkrcodecs4.dll" Delete "$INSTDIR\qt4_plugins\codecs\qtwcodecs4.dll" Delete "$INSTDIR\qt4_plugins\codecs\qcncodecs4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qmng4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qico4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qgif4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qjpeg4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qsvg4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qtga4.dll" Delete "$INSTDIR\qt4_plugins\imageformats\qtiff4.dll" Delete "$INSTDIR\Include\pyconfig.h" Delete "$INSTDIR\_ctypes.pyd" Delete "$INSTDIR\_hashlib.pyd" Delete "$INSTDIR\_socket.pyd" Delete "$INSTDIR\_ssl.pyd" Delete "$INSTDIR\bz2.pyd" Delete "$INSTDIR\Microsoft.VC90.CRT.manifest" Delete "$INSTDIR\msvcm90.dll" Delete "$INSTDIR\msvcp90.dll" Delete "$INSTDIR\msvcr90.dll" Delete "$INSTDIR\onionshare.exe.manifest" Delete "$INSTDIR\pyexpat.pyd" Delete "$INSTDIR\PyQt4.QtCore.pyd" Delete "$INSTDIR\PyQt4.QtGui.pyd" Delete "$INSTDIR\python27.dll" Delete "$INSTDIR\pywintypes27.dll" Delete "$INSTDIR\QtCore4.dll" Delete "$INSTDIR\QtGui4.dll" Delete "$INSTDIR\QtOpenGL4.dll" Delete "$INSTDIR\QtSvg4.dll" Delete "$INSTDIR\QtXml4.dll" Delete "$INSTDIR\select.pyd" Delete "$INSTDIR\sip.pyd" Delete "$INSTDIR\unicodedata.pyd" Delete "$INSTDIR\win32api.pyd" Delete "$INSTDIR\win32pipe.pyd" Delete "$INSTDIR\win32wnet.pyd" rmDir "$INSTDIR\onionshare" rmDir "$INSTDIR\onionshare_gui" rmDir "$INSTDIR\images" rmDir "$INSTDIR\locale" rmDir "$INSTDIR\Include" rmDir "$INSTDIR\qt4_plugins\accessible" rmDir "$INSTDIR\qt4_plugins\bearer" rmDir "$INSTDIR\qt4_plugins\codecs" rmDir "$INSTDIR\qt4_plugins\graphicssystems" rmDir "$INSTDIR\qt4_plugins\iconengines" rmDir "$INSTDIR\qt4_plugins\imageformats" rmDir "$INSTDIR\qt4_plugins" rmDir "$INSTDIR" # remove uninstaller information from the registry DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" SectionEnd !endif onionshare-0.8.1/install/onionshare80.xpm000066400000000000000000000371241263142265200204100ustar00rootroot00000000000000/* 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-0.8.1/install/osx_scripts/000077500000000000000000000000001263142265200177165ustar00rootroot00000000000000onionshare-0.8.1/install/osx_scripts/onionshare000077500000000000000000000020561263142265200220140ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 zipimport, os, inspect original_cwd = os.getcwd() new_cwd = os.path.dirname(os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe())))) os.chdir(new_cwd) zi = zipimport.zipimporter('lib/python2.7/site-packages.zip') onionshare = zi.load_module('onionshare') onionshare.main(original_cwd) onionshare-0.8.1/install/osx_scripts/onionshare-gui000077500000000000000000000014121263142265200225710ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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-0.8.1/install/ppa_release.sh000077500000000000000000000010521263142265200201530ustar00rootroot00000000000000#!/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 version` rm -rf deb_dist >/dev/null 2>&1 python 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-0.8.1/install/prepare_for_codesign.py000066400000000000000000000020361263142265200220700ustar00rootroot00000000000000""" This script is from https://github.com/kamillus/py2app-pyqt-codesign-fix-os-x and slightly modified. """ import os import re import shutil path_to_app = "dist/OnionShare.app" def move_func(file): print "moving %s to %s " % (os.path.join(dir_name, file), os.path.join(dir_name, 'Versions', "Current")) try: shutil.move(os.path.join(dir_name, file), os.path.join(dir_name, 'Versions', "Current")) except Exception as e: print e return file def filter_func(x): return x != "Versions" dir = path_to_app + "/Contents/Frameworks/" p = re.compile('^Qt(.+)\.framework$') for dir_name, subdir_list, file_list in os.walk(dir): dir_name_short = dir_name.replace(dir, "") if p.match(dir_name_short): print('Found directory: %s' % dir_name_short) print file_list if os.path.islink(os.path.join(dir_name, file_list[0])): os.unlink(os.path.join(dir_name, file_list[0])) list(map(move_func, file_list[1:])) list(map(move_func, filter(filter_func, subdir_list))) onionshare-0.8.1/locale/000077500000000000000000000000001263142265200151275ustar00rootroot00000000000000onionshare-0.8.1/locale/cs.json000066400000000000000000000054721263142265200164370ustar00rootroot00000000000000{ "connecting_ctrlport": "Připojuju se na kontrolní port Toru pro nastavení hidden service na portu {0:d}.", "cant_connect_ctrlport": "Nejde se připojit na kontrolní port Toru na portu {0:s}. OnionShare vyžaduje, aby Tor Browser běžel na pozadí. Pokud ho nemáte, můžete ho stáhnout z https://www.torproject.org/.", "cant_connect_socksport": "Nejde se připojit na Tor SOCKS5 server na portu {0:s}. OnionShare vyžaduje, aby Tor Browser běžel na pozadí. Pokud ho nemáte, můžete ho stáhnout z https://www.torproject.org/.", "preparing_files": "Připravuji soubory na sdílení.", "wait_for_hs": "Čekám až bude hidden service připravena:", "wait_for_hs_trying": "Zkouším...", "wait_for_hs_nope": "Ještě nepřipraven.", "wait_for_hs_yup": "Připraven!", "give_this_url": "Dejte tuto URL osobě, které dané soubory posíláte:", "ctrlc_to_stop": "Stiskněte Ctrl-C pro zastavení serveru", "not_a_file": "{0:s} není soubor.", "download_page_loaded": "Download page loaded", "other_page_loaded": "URL loaded", "close_on_finish": "Ukončit sdílení automaticky", "closing_automatically": "Closing automatically because download finished", "large_filesize": "Varování: Posílání velkých souborů může trvat hodiny", "error_tails_invalid_port": "Nesprávná hodnota, port musí být celé číslo", "error_tails_unknown_root": "Unknown error with Tails root process", "help_tails_port": "Tails only: port for opening firewall, starting hidden service", "help_local_only": "Nepoužívat Tor: jen pro vývoj", "help_stay_open": "Nechat běžet hidden service po skončení stahování", "help_transparent_torification": "My system is transparently torified", "help_debug": "Zaznamenat chyby na disk", "help_filename": "Seznam souborů a složek ke sdílení", "gui_drag_and_drop": "Táhni a pusť\nsoubory sem", "gui_add_files": "Přidat soubor", "gui_add_folder": "Přidat složku", "gui_delete": "Smazat", "gui_choose_files": "Vybrat soubory", "gui_choose_folder": "Vybrat složku", "gui_start_server": "Spustit sdílení", "gui_stop_server": "Zastavit sdílení", "gui_copy_url": "Kopírovat URL", "gui_downloads": "Stahování:", "gui_canceled": "Zrušeno", "gui_copied_url": "URL zkopírováno do schránky", "gui_starting_server1": "Spouštím Tor hidden service...", "gui_starting_server2": "Crunching files...", "gui_starting_server3": "Čekám na Tor hidden service...", "gui_please_wait": "Prosím čekejte...", "error_hs_dir_cannot_create": "Nejde vytvořit složka {0:s} pro hidden service", "error_hs_dir_not_writable": "Nejde zapisovat do složky {0:s} pro hidden service", "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" } onionshare-0.8.1/locale/de.json000066400000000000000000000044361263142265200164210ustar00rootroot00000000000000{ "connecting_ctrlport": "Verbinde zum Tor-Kontrollport um den versteckten Dienst auf Port {0:d} laufen zu lassen.", "cant_connect_ctrlport": "Konnte keine Verbindung zum Tor-Kontrollport auf Port {0:s} aufbauen. Läuft Tor?", "cant_connect_socksport": "Konnte keine Verbindung zum Tor SOCKS5 Server auf Port {0:s} herstellen. OnionShare setzt voraus dass Tor Browser im Hintergrund läuft. Wenn du noch ihn noch noch nicht hast kannst du ihn unter https://www.torproject.org/ herunterladen.", "preparing_files": "Dateien werden vorbereitet.", "wait_for_hs": "Warte auf HS:", "wait_for_hs_trying": "Verbindungsversuch...", "wait_for_hs_nope": "Noch nicht bereit.", "wait_for_hs_yup": "Bereit!", "give_this_url": "Geben Sie diese URL der Person, der Sie die Datei zusenden möchten:", "ctrlc_to_stop": "Drücken Sie Strg+C um den Server anzuhalten", "not_a_file": "{0:s} ist keine Datei.", "download_page_loaded": "Seite geladen", "other_page_loaded": "URL geladen", "close_on_finish": "Den Server automatisch anhalten", "closing_automatically": "Halte automatisch an, da der Download beendet wurde", "large_filesize": "Warnung: Das Senden von großen Dateien kann Stunden dauern", "error_tails_invalid_port": "Ungültiger Wert, Port muss eine ganze Zahl sein", "error_tails_unknown_root": "Unbekannter Fehler mit Tails root Prozess", "help_tails_port": "Nur für Tails: Port um den Firewall zu öffnen, starte Hidden Service", "help_local_only": "Nicht mit Tor benutzen, nur für Entwicklung", "help_stay_open": "Den Hidden Service nicht anhalten nachdem ein Download beendet wurde", "help_debug": "Fehler auf Festplatte schreiben", "help_filename": "Liste der zu teilenden Dateien oder Verzeichnisse", "gui_drag_and_drop": "Drag & drop\nDateien hier", "gui_add_files": "Dateien hinzufügen", "gui_add_folder": "Verzeichnis hinzufügen", "gui_delete": "Löschen", "gui_choose_files": "Dateien auswählen", "gui_choose_folder": "Verzeichnis auswählen", "gui_start_server": "Server starten", "gui_stop_server": "Server anhalten", "gui_copy_url": "URL kopieren", "gui_downloads": "Downloads:", "gui_copied_url": "URL wurde in die Zwischenablage kopiert", "gui_please_wait": "Bitte warten..." } onionshare-0.8.1/locale/en.json000066400000000000000000000052461263142265200164330ustar00rootroot00000000000000{ "connecting_ctrlport": "Connecting to Tor control port to set up hidden service on port {0:d}.", "cant_connect_ctrlport": "Can't connect to Tor control port on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.", "cant_connect_socksport": "Can't connect to Tor SOCKS5 server on port {0:s}. OnionShare requires Tor Browser to be running in the background to work. If you don't have it you can get it from https://www.torproject.org/.", "preparing_files": "Preparing files to share.", "wait_for_hs": "Waiting for HS to be ready:", "wait_for_hs_trying": "Trying...", "wait_for_hs_nope": "Not ready yet.", "wait_for_hs_yup": "Ready!", "give_this_url": "Give this URL to the person you're sending the file to:", "ctrlc_to_stop": "Press Ctrl-C to stop server", "not_a_file": "{0:s} is not a file.", "download_page_loaded": "Download page loaded", "other_page_loaded": "URL loaded", "close_on_finish": "Stop sharing automatically", "closing_automatically": "Closing automatically because download finished", "large_filesize": "Warning: Sending large files could take hours", "error_tails_invalid_port": "Invalid value, port must be an integer", "error_tails_unknown_root": "Unknown error with Tails root process", "help_tails_port": "Tails only: port for opening firewall, starting hidden service", "help_local_only": "Do not attempt to use tor: for development only", "help_stay_open": "Keep hidden service running after download has finished", "help_transparent_torification": "My system is transparently torified", "help_debug": "Log errors to disk", "help_filename": "List of files or folders to share", "gui_drag_and_drop": "Drag and drop\nfiles here", "gui_add_files": "Add Files", "gui_add_folder": "Add Folder", "gui_delete": "Delete", "gui_choose_files": "Choose files", "gui_choose_folder": "Choose folder", "gui_start_server": "Start Sharing", "gui_stop_server": "Stop Sharing", "gui_copy_url": "Copy URL", "gui_downloads": "Downloads:", "gui_canceled": "Canceled", "gui_copied_url": "Copied URL to clipboard", "gui_starting_server1": "Starting Tor hidden service...", "gui_starting_server2": "Crunching files...", "gui_starting_server3": "Waiting for Tor hidden service...", "gui_please_wait": "Please wait...", "error_hs_dir_cannot_create": "Cannot create hidden service dir {0:s}", "error_hs_dir_not_writable": "Hidden service dir {0:s} is not writable", "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" } onionshare-0.8.1/locale/eo.json000066400000000000000000000054511263142265200164320ustar00rootroot00000000000000{ "connecting_ctrlport": "Konektas al Tor-kontrolpordo por starigi hidden service je pordo {0:d}.", "cant_connect_ctrlport": "Ne eblas konekti al Tor-kontrolpordo je pordo {0:s}. OnionShare bezonas Tor Browser por esti ŝaltita en la fono. Se vi ne havas ĝin, vi povas ricevi ĝin je https://www.torproject.org/.", "cant_connect_socksport": "Ne eblas konekti al Tor-SOCKS5-servilo je pordo {0:s}. OnionShare bezonas Tor Browser por esti ŝaltita en la fono. Se vi ne havas ĝin, vi povas ricevi ĝin je https://www.torproject.org/.", "preparing_files": "Preparas dosierojn por kundivido.", "wait_for_hs": "Atendas por hidden sevice esti preta:", "wait_for_hs_trying": "Provas...", "wait_for_hs_nope": "Ankoraŭ ne preta.", "wait_for_hs_yup": "Preta!", "give_this_url": "Donu ĉi tiun URL al la persono al kiu vi sendas la dosieron:", "ctrlc_to_stop": "Presu Ctrl-C por halti la servilon", "not_a_file": "{0:s} ne estas dosiero.", "download_page_loaded": "Download page loaded", "other_page_loaded": "URL loaded", "close_on_finish": "Halti la kundividadon aŭtomate", "closing_automatically": "Fermas aŭtomate ĉar la elŝuto finiĝis", "large_filesize": "Atentigo: Sendado de grandaj dosieroj povas daŭri horojn", "error_tails_invalid_port": "Malĝusta valoro, pordo devas esti plena nombro", "error_tails_unknown_root": "Nekonata eraro kun Tails-root-procezo", "help_tails_port": "Tails only: port for opening firewall, starting hidden service", "help_local_only": "Ne strebu uzi tor: nur por evoluado", "help_stay_open": "Lasu hidden service funkcii post fino de elŝuto", "help_transparent_torification": "My system is transparently torified", "help_debug": "Protokoli erarojn sur diskon", "help_filename": "Listo de dosieroj aŭ dosierujoj por kundividi", "gui_drag_and_drop": "Ŝovu kaj metu\nla dosierojn ĉi tien", "gui_add_files": "Aldoni dosierojn", "gui_add_folder": "Aldoni dosierujon", "gui_delete": "Forviŝi", "gui_choose_files": "Elekti dosierojn", "gui_choose_folder": "Elekti dosierujon", "gui_start_server": "Komenci kundividi", "gui_stop_server": "Ĉesi kundividi", "gui_copy_url": "Kopii URL", "gui_downloads": "Elŝutoj:", "gui_canceled": "Nuligita", "gui_copied_url": "URL kopiita en tondujon", "gui_starting_server1": "Startigas Tor hidden service...", "gui_starting_server2": "Crunching files...", "gui_starting_server3": "Atendas por Tor hidden service...", "gui_please_wait": "Bonvolu atendi...", "error_hs_dir_cannot_create": "Ne eblas krei hidden-service-dosierujon {0:s}", "error_hs_dir_not_writable": "Ne eblas konservi dosierojn en hidden-service-dosierujo {0:s}", "using_ephemeral": "Staring ephemeral Tor hidden service and awaiting publication" } onionshare-0.8.1/locale/es.json000066400000000000000000000041301263142265200164270ustar00rootroot00000000000000{ "connecting_ctrlport": "Conectando a puerto control de Tor para configurar servicio oculto en puerto {0:d}.", "cant_connect_ctrlport": "No se pudo conectar a puerto control de Tor en puertos {0:s}. ¿Está funcionando Tor?", "cant_connect_socksport": "No se pudo conectar al servidor SOCKS5 de Tor en el puerto {0:s}. ¿Está funcionando Tor?", "preparing_files": "Preparando los archivos para compartir.", "wait_for_hs": "Esperando a que HS esté listo:", "wait_for_hs_trying": "Probando...", "wait_for_hs_nope": "No está listo todavía.", "wait_for_hs_yup": "Listo!", "give_this_url": "Entregue esta URL a la persona a la que está enviando el archivo:", "ctrlc_to_stop": "Pulse Ctrl-C para detener el servidor", "not_a_file": "{0:s} no es un archivo.", "download_page_loaded": "La página de descarga está lista.", "other_page_loaded": "La URL está lista.", "close_on_finish": "Apagar el servidor automáticamente.", "closing_automatically": "Apagando automáticamente porque la descarga finalizó", "error_tails_invalid_port": "Valor inválido, el puerto debe ser un entero", "error_tails_unknown_root": "Error desconocido en el proceso de Tails corriendo como root", "help_tails_port": "Sólo Tails: puerto para abrir en el firewall, al levantar el servicio oculto", "help_local_only": "No intentar usar tor: para desarrollo solamente", "help_stay_open": "Mantener el servicio oculto corriendo después de que la descarga haya finalizado", "help_debug": "Guardar registro de errores en el disco", "help_filename": "Lista de archivos o carpetas para compartir", "gui_drag_and_drop": "Arrastre\narchivos aquí", "gui_add_files": "Añadir Archivos", "gui_add_folder": "Añadir Carpeta", "gui_delete": "Eliminar", "gui_choose_files": "Elegir archivos", "gui_choose_folder": "Elegir carpeta", "gui_start_server": "Encender el Servidor", "gui_stop_server": "Detener el Servidor", "gui_copy_url": "Copiar URL", "gui_downloads": "Descargas:", "gui_copied_url": "Se copió la URL en el portapapeles" } onionshare-0.8.1/locale/fi.json000066400000000000000000000056051263142265200164260ustar00rootroot00000000000000{ "connecting_ctrlport": "Yhdistetään Torin ohjausporttiin että saadaan salattu palvelin porttiin {0:d}.", "cant_connect_ctrlport": "Ei voi yhdistää Torin ohjausporttiin portissa {0:s}. OnionShare tarvitsee Tor Browserin toimimaan taustalla. Jos sinulla ei ole sitä niin voit hakea sen osoitteesta https://www.torproject.org/.", "cant_connect_socksport": "Ei voi yhdistää Tor SOCKS5 palveluun portissa {0:s}. OnionShare tarvitsee Tor Browserin toimimaan taustalla. Jos sinulla ei ole sitä niin voit hakea sen osoitteesta https://www.torproject.org/.", "preparing_files": "Valmistellaan tiedostoja jaettavaksi.", "wait_for_hs": "Odotetaan piilopalvelun valmistumista:", "wait_for_hs_trying": "Yritetään...", "wait_for_hs_nope": "Ei vielä valmis.", "wait_for_hs_yup": "Valmis!", "give_this_url": "Anna tämä URL-osoite henkilölle, jolle lähetät tiedostot:", "ctrlc_to_stop": "Näppäin Ctrl-C pysäyttää palvelimen", "not_a_file": "{0:s} Ei ole tiedosto.", "download_page_loaded": "Lataussivu ladattu", "other_page_loaded": "URL-osoite ladattu", "close_on_finish": "Pysäytä palvelin automaattisesti", "closing_automatically": "Lataus valmis. Suljetaan automaattisesti", "large_filesize": "Varoitus: Isojen tiedostojen lähetys saattaa kestää tunteja", "error_tails_invalid_port": "Väärä arvo, portti pitää olla koknaisluku", "error_tails_unknown_root": "Tuntematon virhe Tailsissa", "help_tails_port": "Vain Tails: portti palomuurin läpi, käynnistetään salainen palvelin", "help_local_only": "Älä käytä Toria: vain ohjelmakehitykseen", "help_stay_open": "Pidä piilopalvelu käynnissä latauksen jälkeen.", "help_transparent_torification": "Järjestelmäni käyttää Toria läpinäkyvästi", "help_debug": "Tallentaa virheet levylle", "help_filename": "Luettele jaettavat tiedostot tai kansiot", "gui_drag_and_drop": "Vedä ja pudota\ntiedostot tänne", "gui_add_files": "Lisää tiedostoja", "gui_add_folder": "Lisää kansio", "gui_delete": "Poista", "gui_choose_files": "Valitse tiedostoja", "gui_choose_folder": "Valitse kansio", "gui_start_server": "Käynnistä palvelin", "gui_stop_server": "Pysäytä palvelin", "gui_copy_url": "Kopioi URL-osoite", "gui_downloads": "Lataukset:", "gui_canceled": "Peruutettu", "gui_copied_url": "URL-osoite kopioitu leikepöydälle", "gui_starting_server1": "Käynnistetään Tor piilopalvelu...", "gui_starting_server2": "Tiivistän tiedostoja...", "gui_starting_server3": "Odotetaan Tor piilopalvelua...", "gui_please_wait": "Odota...", "error_hs_dir_cannot_create": "Piilopalvelulle ei pystytty luomaan hakemistoa {0:s}", "error_hs_dir_not_writable": "Piilopalvelun hakemistoon {0:s} ei voi kirjoittaa", "using_ephemeral": "Käynnistetään lyhytaikainen Tor piilopalvelu ja odotetaan julkaisua" } onionshare-0.8.1/locale/fr.json000066400000000000000000000037451263142265200164420ustar00rootroot00000000000000{ "connecting_ctrlport": "Connexion au réseau Tor pour mettre en place un Hidden Service sur le port {0:d}.", "cant_connect_ctrlport": "Impossible de se connecter au port de contrôle Tor sur le port {0:s}. Est-ce que Tor tourne ?", "preparing_files": "Préparation des fichiers à partager.", "wait_for_hs": "En attente du HS:", "wait_for_hs_trying": "Tentative...", "wait_for_hs_nope": "Pas encore prêt.", "wait_for_hs_yup": "Prêt !", "give_this_url": "Donnez cette URL à la personne qui doit recevoir le fichier :", "ctrlc_to_stop": "Ctrl-C arrête le serveur", "not_a_file": "{0:s} n'est pas un fichier.", "download_page_loaded": "Page de téléchargement chargée", "other_page_loaded": "URL chargée", "close_on_finish": "Arrêter le serveur automatiquement", "closing_automatically": "Fermeture automatique car le téléchargement est fini", "error_tails_invalid_port": "Valeur invalide, le port doit être un nombre entier", "error_tails_unknown_root": "Erreur inconnue avec un processus root sur Tails", "help_tails_port": "Seulement sur Tails: port pour ouvrir le firewall, démarrage du Hidden Service", "help_local_only": "Ne tentez pas d'utiliser Tor, uniquement pour développement", "help_stay_open": "Laisser tourner le Hidden Service après que le téléchargment soit fini", "help_debug": "Enregistrer les erreurs sur le disque", "help_filename": "Liste des fichiers ou dossiers à partager", "gui_drag_and_drop": "Glissez déposez\nles fichiers ici", "gui_add_files": "Ajouter des fichiers", "gui_add_folder": "Ajouter un dossier", "gui_delete": "Supprimer", "gui_choose_files": "Sélectionnez des fichiers", "gui_choose_folder": "Sélectionnez un dossier", "gui_start_server": "Démarrer le serveur", "gui_stop_server": "Arrêter le serveur", "gui_copy_url": "Copier URL", "gui_downloads": "Téléchargements :", "gui_copied_url": "URL copié dans le presse-papier" } onionshare-0.8.1/locale/it.json000066400000000000000000000012431263142265200164360ustar00rootroot00000000000000{ "connecting_ctrlport": "Connessione alla porta di controllo di Tor per inizializzare il servizio nascosto sulla porta {0:d}.", "cant_connect_ctrlport": "Impossibile connettere alla porta di controllo di Tor tramite le porte {0:s}. Tor è stato avviato?", "give_this_url": "Comunica questo URL alla persona a cui vuoi inviare il file:", "ctrlc_to_stop": "Premi Ctrl-C per fermare il server", "not_a_file": "{0:s} non è un file.", "gui_copied_url": "URL copiato negli appunti", "download_page_loaded": "Pagina di download caricata", "other_page_loaded": "Un altra pagina é stata caricata", "close_on_finish": "Chiudi automaticamente" } onionshare-0.8.1/locale/nl.json000066400000000000000000000052721263142265200164410ustar00rootroot00000000000000{ "connecting_ctrlport": "Verbinden met de Tor controle port om een verborgen service op te zetten op poort {0:d}.", "cant_connect_ctrlport": "Kan geen verbinding maken met Tor controle poort op poort {0:s}. OnionShare heeft de Tor Browser op de achtergrond nodig om te kunnen werken. Deze kan je verkrijgen via https://www.torproject.org/.", "cant_connect_socksport": "Kan geen verbinding maken met de Tor SOCKS5 server op poort {0:s}. OnionShare heeft de Tor Browser op de achtergrond nodig om te werken. Deze kan je verkrijgen via from https://www.torproject.org/.", "preparing_files": "Bestanden om te delen aan het voorbereiden.", "wait_for_hs": "Wachten op gereed zijn van HS:", "wait_for_hs_trying": "Proberen...", "wait_for_hs_nope": "Nog niet gereed.", "wait_for_hs_yup": "Gereed!", "give_this_url": "Geef deze URL aan de persoon aan wie je dit bestand verzend:", "ctrlc_to_stop": "Druk Ctrl-C om de server te stoppen", "not_a_file": "{0:s} is geen bestand.", "download_page_loaded": "Downloadpagina geladen", "other_page_loaded": "URL geladen", "close_on_finish": "Stop server automatisch", "closing_automatically": "Sluit nu automatisch omdat download gereed is", "large_filesize": "Waarschuwing: Versturen van grote bestanden kan uren duren", "error_tails_invalid_port": "Ongeldige waarde, poort moet een integer zijn", "error_tails_unknown_root": "Onbekende fout met het Tails root proces", "help_tails_port": "Alleen Tails: poort voor het openen van firewall, starten verborgen service", "help_local_only": "Maak geen gebruik van Tor, alleen voor ontwikkeling", "help_stay_open": "Laat verborgen service draaien nadat download gereed is", "help_debug": "Log fouten naar harde schijf", "help_filename": "Lijst van bestanden of mappen om te delen", "gui_drag_and_drop": "Sleep en zet\nbestanden hier neer", "gui_add_files": "Bestanden toevoegen", "gui_add_folder": "Map toevoegen", "gui_delete": "Verwijder", "gui_choose_files": "Kies bestanden", "gui_choose_folder": "Kies map", "gui_start_server": "Start server", "gui_stop_server": "Stop server", "gui_copy_url": "Kopier URL", "gui_downloads": "Downloads:", "gui_canceled": "Afgebroken", "gui_copied_url": "URL gekopieerd naar klembord", "gui_starting_server1": "Tor verborgen service wordt gestart...", "gui_starting_server2": "Bestanden verwerken...", "gui_starting_server3": "Wachten op Tor verborgen service...", "gui_please_wait": "Moment geduld...", "error_hs_dir_cannot_create": "Kan verborgen service map {0:s} niet aanmaken", "error_hs_dir_not_writable": "Verborgen service map {0:s} is niet schrijfbaar" } onionshare-0.8.1/locale/no.json000066400000000000000000000011461263142265200164400ustar00rootroot00000000000000{ "connecting_ctrlport": "Kobler til Tors kontroll-port for å sette opp en gjemt tjeneste på port {0:d}.", "cant_connect_ctrlport": "Klarte ikke å koble til Tors kontroll-porter {0:s}. Sjekk at Tor kjører.", "give_this_url": "Gi personen du vil sende filen til denne URL-en:", "ctrlc_to_stop": "Trykk Ctrl+C for å stoppe serveren.", "not_a_file": "{0:s} er ikke en fil.", "gui_copied_url": "Kopierte URL-en til utklippstavlen", "download_page_loaded": "Nedlastingsside lastet", "other_page_loaded": "En annen side har blitt lastet", "close_on_finish": "Lukk automatisk" } onionshare-0.8.1/locale/pt.json000066400000000000000000000012351263142265200164460ustar00rootroot00000000000000{ "connecting_ctrlport": "Conectando-se à porta de controle Tor para configurar serviço escondido na porta {0:d}.", "cant_connect_ctrlport": "Não pode conectar à porta de controle Tor na porta {0:s}. O Tor está rodando?", "give_this_url": "Passe este URL para a pessoa que deve receber o arquivo:", "ctrlc_to_stop": "Pressione Ctrl-C para parar o servidor", "not_a_file": "{0:s} não é um arquivo.", "gui_copied_url": "URL foi copiado para área de transferência", "download_page_loaded": "Página de download carregada", "other_page_loaded": "Outra página tem sido carregada", "close_on_finish": "Fechar automaticamente" } onionshare-0.8.1/locale/ru.json000066400000000000000000000020061263142265200164460ustar00rootroot00000000000000{ "connecting_ctrlport": "Соединяемся с контрольным портом Tor для создания скрытого сервиса на порту {0:d}.", "cant_connect_ctrlport": "Невозможно соединиться с контрольным портом Tor на порту {0:s}. Tor запущен?", "give_this_url": "Отправьте эту ссылку тому человеку, которому вы хотите передать файл:", "ctrlc_to_stop": "Нажмите Ctrl-C чтобы остановить сервер", "not_a_file": "{0:s} не является файлом.", "gui_copied_url": "Ссылка скопирована в буфер обмена", "download_page_loaded": "Страница закачки загружена", "other_page_loaded": "Другая страница была загружена", "close_on_finish": "Закрыть автоматически", "gui_copy_url": "Скопировать ссылку" } onionshare-0.8.1/locale/tr.json000066400000000000000000000011601263142265200164450ustar00rootroot00000000000000{ "connecting_ctrlport": "{0:d} portundaki gizli servis kurulumu için Tor kontrol portuna bağlanıyor.", "cant_connect_ctrlport": "Tor kontrol {0:s} portuna bağlanamıyor. Tor çalışıyor mu?", "give_this_url": "Dosyayı gönderdiğin kişiye bu URL'i verin:", "ctrlc_to_stop": "Sunucuyu durdurmak için, Ctrl-C basın", "not_a_file": "{0:s} dosya değil.", "gui_copied_url": "Panoya kopyalanan URL", "download_page_loaded": "İndirme sayfası yüklendi", "other_page_loaded": "Diğer sayfa yüklendi", "close_on_finish": "Kendiliğinden kapan", "gui_copy_url": "URL Kopyala" } onionshare-0.8.1/onionshare/000077500000000000000000000000001263142265200160355ustar00rootroot00000000000000onionshare-0.8.1/onionshare/404.html000066400000000000000000000005161263142265200172340ustar00rootroot00000000000000 Error 404 404 onionshare-0.8.1/onionshare/__init__.py000066400000000000000000000013671263142265200201550ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 onionshare import * onionshare-0.8.1/onionshare/helpers.py000066400000000000000000000117311263142265200200540ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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, inspect, hashlib, base64, hmac, platform, zipfile, tempfile from itertools import izip # hack to make unicode filenames work (#141) import sys reload(sys) sys.setdefaultencoding("utf-8") def get_platform(): """ Returns the platform OnionShare is running on. """ return platform.system() if get_platform() == 'Darwin': # this is hacky, but it ultimate ends up returning the absolute path to # OnionShare.app/Contents/Resources, based on the location of helpers.py helpers_path = os.path.realpath(os.path.abspath(inspect.getfile(inspect.currentframe()))) osx_resources_dir = os.path.dirname(os.path.dirname(helpers_path)) else: osx_resources_dir = None def get_onionshare_dir(): """ Returns the OnionShare directory. """ if get_platform() == 'Darwin': onionshare_dir = os.path.dirname(__file__) else: onionshare_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) return onionshare_dir def get_html_path(filename): """ Returns the path of the html files. """ p = platform.system() if p == 'Darwin': prefix = os.path.join(osx_resources_dir, 'html') else: prefix = get_onionshare_dir() return os.path.join(prefix, filename) def constant_time_compare(val1, val2): """ Compares two values in constant time. """ _builtin_constant_time_compare = getattr(hmac, 'compare_digest', None) if _builtin_constant_time_compare is not None: return _builtin_constant_time_compare(val1, val2) len_eq = len(val1) == len(val2) if len_eq: result = 0 left = val1 else: result = 1 left = val2 for x, y in izip(bytearray(left), bytearray(val2)): result |= x ^ y return result == 0 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('=', '') if not output_len: return s return s[:output_len] def human_readable_filesize(b): """ Returns filesize in a human readable format. """ thresh = 1024.0 if b < thresh: return '{0:.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 '{0:.1f} {1:s}'.format(round(b, 1), units[u]) def is_root(): """ Returns if user is root. """ return os.geteuid() == 0 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 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, zip_filename=None): if zip_filename: self.zip_filename = zip_filename else: self.zip_filename = '{0:s}/onionshare_{1:s}.zip'.format(tempfile.mkdtemp(), random_string(4, 6)) self.z = zipfile.ZipFile(self.zip_filename, 'w', allowZip64=True) def add_file(self, filename): """ Add a file to the zip archive. """ self.z.write(filename, os.path.basename(filename), zipfile.ZIP_DEFLATED) 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: 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) def close(self): """ Close the zip archive. """ self.z.close() onionshare-0.8.1/onionshare/hs.py000066400000000000000000000234521263142265200170270ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 import os, sys, tempfile, shutil, urllib2, httplib import socks import helpers, strings class NoTor(Exception): """ This exception is raised if onionshare can't find a Tor control port to connect to, or if it can't find a Tor socks5 proxy to proxy though. """ pass class HSDirError(Exception): """ This exception is raised when onionshare tries create a non-ephemeral hidden service and does not have permission to create or write to the hidden service directory. """ pass class HS(object): """ HS is an abstraction layer for connecting to the Tor control port and creating hidden services. Onionshare supports creating hidden services using two methods: - Modifying the Tor configuration through the control port is the old method, and will be deprecated in favor of ephemeral hidden services. - Using the control port to create ephemeral hidden servers is the preferred method. This class detects the versions of Tor and stem to determine if ephemeral hidden services are supported. If not, it falls back to modifying the Tor configuration. """ def __init__(self, transparent_torification=False): self.transparent_torification = transparent_torification # files and dirs to delete on shutdown self.cleanup_filenames = [] self.service_id = None # connect to the tor controlport self.c = None ports = [9151, 9153, 9051] for port in ports: try: self.c = Controller.from_port(port=port) self.c.authenticate() break except: pass if not self.c: raise NoTor(strings._("cant_connect_ctrlport").format(ports)) # do the versions of stem and tor that I'm using support ephemeral hidden services? tor_version = self.c.get_version().version_str list_ephemeral_hidden_services = getattr(self.c, "list_ephemeral_hidden_services", None) self.supports_ephemeral = callable(list_ephemeral_hidden_services) and tor_version >= '0.2.7.1' def start(self, port): """ Start a hidden service on port 80, pointing to the given port, and return the onion hostname. """ print strings._("connecting_ctrlport").format(int(port)) if self.supports_ephemeral: print strings._('using_ephemeral') res = self.c.create_ephemeral_hidden_service({ 80: port }, await_publication = True) self.service_id = res.content()[0][2].split('=')[1] onion_host = res.content()[0][2].split('=')[1] + '.onion' return onion_host else: # come up with a hidden service directory name if helpers.get_platform() == 'Windows': self.hidserv_dir = tempfile.mkdtemp() self.hidserv_dir = self.hidserv_dir.replace('\\', '/') else: path = '/tmp/onionshare' try: if not os.path.exists(path): os.makedirs(path, 0700) except: raise HSDirError(strings._("error_hs_dir_cannot_create").format(path)) if not os.access(path, os.W_OK): raise HSDirError(strings._("error_hs_dir_not_writable").format(path)) self.hidserv_dir = tempfile.mkdtemp(dir=path) self.cleanup_filenames.append(self.hidserv_dir) # set up hidden service hsdic = self.c.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } if self.hidserv_dir in hsdic.get('HiddenServiceDir', []): # Maybe a stale service with the wrong local port dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir) del hsdic['HiddenServiceDir'][dropme] del hsdic['HiddenServicePort'][dropme] hsdic['HiddenServiceDir'] = hsdic.get('HiddenServiceDir', [])+[self.hidserv_dir] hsdic['HiddenServicePort'] = hsdic.get('HiddenServicePort', [])+[ '80 127.0.0.1:{0:d}'.format(port)] self.c.set_options(self._hsdic2list(hsdic)) # figure out the .onion hostname hostname_file = '{0:s}/hostname'.format(self.hidserv_dir) onion_host = open(hostname_file, 'r').read().strip() return onion_host def wait_for_hs(self, onion_host): """ This function is only required when using non-ephemeral hidden services. After creating a hidden service, continually attempt to connect to it until it successfully connects.. """ # legacy only, this function is no longer required with ephemeral hidden services print strings._('wait_for_hs') ready = False while not ready: try: sys.stdout.write('{0:s} '.format(strings._('wait_for_hs_trying'))) sys.stdout.flush() if self.transparent_torification: # no need to set the socks5 proxy urllib2.urlopen('http://{0:s}'.format(onion_host)) else: tor_exists = False ports = [9150, 9152, 9050] for port in ports: try: s = socks.socksocket() s.setproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', port) s.connect((onion_host, 80)) s.close() tor_exists = True break except socks.ProxyConnectionError: pass if not tor_exists: raise NoTor(strings._("cant_connect_socksport").format(tor_socks_ports)) ready = True sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_yup'))) except socks.SOCKS5Error: sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_nope'))) sys.stdout.flush() except urllib2.HTTPError: # torification error sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_nope'))) sys.stdout.flush() except httplib.BadStatusLine: # torification (with bridge) error sys.stdout.write('{0:s}\n'.format(strings._('wait_for_hs_nope'))) sys.stdout.flush() except KeyboardInterrupt: return False return True def cleanup(self): """ Stop hidden services that were created earlier, and delete any temporary files that were created. """ if self.supports_ephemeral: # cleanup the ephemeral hidden service if self.service_id: self.c.remove_ephemeral_hidden_service(self.service_id) self.service_id = None else: # cleanup hidden service try: if self.controller: # Get fresh hidden services (maybe changed since last time) # and remove ourselves hsdic = self.controller.get_conf_map('HiddenServiceOptions') or { 'HiddenServiceDir': [], 'HiddenServicePort': [] } if self.hidserv_dir and self.hidserv_dir in hsdic.get('HiddenServiceDir', []): dropme = hsdic['HiddenServiceDir'].index(self.hidserv_dir) del hsdic['HiddenServiceDir'][dropme] del hsdic['HiddenServicePort'][dropme] self.controller.set_options(self._hsdic2list(hsdic)) # Politely close the controller self.controller.close() except: pass # cleanup files for filename in self.cleanup_filenames: if os.path.isfile(filename): os.remove(filename) elif os.path.isdir(filename): shutil.rmtree(filename) self.cleanup_filenames = [] def _hsdic2list(self, dic): """ Convert what we get from get_conf_map to what we need for set_options. For example, if input looks like this: { 'HiddenServicePort': [ '80 127.0.0.1:47906', '80 127.0.0.1:33302' ], 'HiddenServiceDir': [ '/tmp/onionshare/tmplTfZZu', '/tmp/onionshare/tmpchDai3' ] } Output will look like this: [ ('HiddenServiceDir', '/tmp/onionshare/tmplTfZZu'), ('HiddenServicePort', '80 127.0.0.1:47906'), ('HiddenServiceDir', '/tmp/onionshare/tmpchDai3'), ('HiddenServicePort', '80 127.0.0.1:33302') ] """ l = [] for dir, port in zip(dic['HiddenServiceDir'], dic['HiddenServicePort']): l.append(('HiddenServiceDir', dir)) l.append(('HiddenServicePort', port)) return l onionshare-0.8.1/onionshare/index.html000066400000000000000000000100231263142265200200260ustar00rootroot00000000000000 OnionShare

{{ filename }} ▼

{{ filesize_human }}

{% for info in file_info.dirs %} {% endfor %} {% for info in file_info.files %} {% endfor %}
{{ info.basename }} {{ info.size_human }}
{{ info.basename }} {{ info.size_human }}
onionshare-0.8.1/onionshare/onionshare.py000066400000000000000000000134111263142265200205540ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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, subprocess, time, argparse, inspect, shutil, socket, threading import strings, helpers, web, hs class OnionShare(object): """ OnionShare is the main application class. Pass in options and run start_hidden_service and it will do the magic. """ def __init__(self, debug=False, local_only=False, stay_open=False, transparent_torification=False): self.port = None self.hs = None self.hidserv_dir = None self.onion_host = None # files and dirs to delete on shutdown self.cleanup_filenames = [] # debug mode if debug: web.debug_mode() # do not use tor -- for development self.local_only = local_only # automatically close when download is finished self.stay_open = stay_open # traffic automatically goes through Tor self.transparent_torification = transparent_torification def choose_port(self): """ Pick an un-used port to bind to. """ # let the OS choose a port tmpsock = socket.socket() tmpsock.bind(("127.0.0.1", 0)) self.port = tmpsock.getsockname()[1] tmpsock.close() def start_hidden_service(self, gui=False): """ Start the onionshare hidden service. """ if not self.port: self.choose_port() if self.local_only: self.onion_host = '127.0.0.1:{0:d}'.format(self.port) return if not self.hs: self.hs = hs.HS(self.transparent_torification) self.onion_host = self.hs.start(self.port) def cleanup(self): """ Shut everything down and clean up temporary files, etc. """ # cleanup files for filename in self.cleanup_filenames: if os.path.isfile(filename): os.remove(filename) elif os.path.isdir(filename): shutil.rmtree(filename) self.cleanup_filenames = [] # call hs's cleanup if self.hs: self.hs.cleanup() def main(cwd=None): """ The main() function implements all of the logic that the command-line version of onionshare uses. """ strings.load_strings() # onionshare CLI in OSX needs to change current working directory (#132) if helpers.get_platform() == 'Darwin': if cwd: os.chdir(cwd) # parse arguments parser = argparse.ArgumentParser() parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only")) parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open")) parser.add_argument('--transparent', action='store_true', dest='transparent_torification', help=strings._("help_transparent_torification")) parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug")) parser.add_argument('filename', metavar='filename', nargs='+', help=strings._('help_filename')) 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) debug = bool(args.debug) stay_open = bool(args.stay_open) transparent_torification = bool(args.transparent_torification) # validation valid = True for filename in filenames: if not os.path.exists(filename): print(strings._("not_a_file").format(filename)) valid = False if not valid: sys.exit() # start the onionshare app try: app = OnionShare(debug, local_only, stay_open, transparent_torification) app.choose_port() app.start_hidden_service() except hs.NoTor as e: sys.exit(e.args[0]) except hs.HSDirError as e: sys.exit(e.args[0]) # prepare files to share print strings._("preparing_files") web.set_file_info(filenames) app.cleanup_filenames.append(web.zip_filename) # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb print '' print strings._("large_filesize") print '' # start onionshare service in new thread t = threading.Thread(target=web.start, args=(app.port, app.stay_open, app.transparent_torification)) t.daemon = True t.start() try: # Trap Ctrl-C # wait for hs, only if using old version of tor if not app.local_only: if not app.hs.supports_ephemeral: ready = app.hs.wait_for_hs(app.onion_host) if not ready: sys.exit() print strings._("give_this_url") print 'http://{0:s}/{1:s}'.format(app.onion_host, web.slug) print '' print strings._("ctrlc_to_stop") # wait for app to close while t.is_alive(): # t.join() can't catch KeyboardInterrupt in such as Ubuntu t.join(0.5) except KeyboardInterrupt: web.stop(app.port) finally: # shutdown app.cleanup() if __name__ == '__main__': main() onionshare-0.8.1/onionshare/socks.py000066400000000000000000000473441263142265200175450ustar00rootroot00000000000000""" SocksiPy - Python SOCKS module. Version 1.5.0 Copyright 2006 Dan-Haim. 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 Dan Haim nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY DAN HAIM "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 DAN HAIM OR HIS 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, 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. This module provides a standard socket-like interface for Python for tunneling connections through SOCKS proxies. =============================================================================== Minor modifications made by Christopher Gilbert (http://motomastyle.com/) for use in PyLoris (http://pyloris.sourceforge.net/) Minor modifications made by Mario Vilas (http://breakingcode.wordpress.com/) mainly to merge bug fixes found in Sourceforge Modifications made by Anorov (https://github.com/Anorov) -Forked and renamed to PySocks -Fixed issue with HTTP proxy failure checking (same bug that was in the old ___recvall() method) -Included SocksiPyHandler (sockshandler.py), to be used as a urllib2 handler, courtesy of e000 (https://github.com/e000): https://gist.github.com/869791#file_socksipyhandler.py -Re-styled code to make it readable -Aliased PROXY_TYPE_SOCKS5 -> SOCKS5 etc. -Improved exception handling and output -Removed irritating use of sequence indexes, replaced with tuple unpacked variables -Fixed up Python 3 bytestring handling - chr(0x03).encode() -> b"\x03" -Other general fixes -Added clarification that the HTTP proxy connection method only supports CONNECT-style tunneling HTTP proxies -Various small bug fixes """ __version__ = "1.5.0" import socket import struct PROXY_TYPE_SOCKS4 = SOCKS4 = 1 PROXY_TYPE_SOCKS5 = SOCKS5 = 2 PROXY_TYPE_HTTP = HTTP = 3 PRINTABLE_PROXY_TYPES = {SOCKS4: "SOCKS4", SOCKS5: "SOCKS5", HTTP: "HTTP"} _orgsocket = _orig_socket = socket.socket class ProxyError(IOError): """ socket_err contains original socket.error exception. """ def __init__(self, msg, socket_err=None): self.msg = msg self.socket_err = socket_err if socket_err: self.msg = msg + ": {}".format(socket_err) def __str__(self): return self.msg class GeneralProxyError(ProxyError): pass class ProxyConnectionError(ProxyError): pass class SOCKS5AuthError(ProxyError): pass class SOCKS5Error(ProxyError): pass class SOCKS4Error(ProxyError): pass class HTTPError(ProxyError): pass SOCKS4_ERRORS = { 0x5B: "Request rejected or failed", 0x5C: "Request rejected because SOCKS server cannot connect to identd on the client", 0x5D: "Request rejected because the client program and identd report different user-ids", } SOCKS5_ERRORS = { 0x01: "General SOCKS server failure", 0x02: "Connection not allowed by ruleset", 0x03: "Network unreachable", 0x04: "Host unreachable", 0x05: "Connection refused", 0x06: "TTL expired", 0x07: "Command not supported, or protocol error", 0x08: "Address type not supported", } DEFAULT_PORTS = { SOCKS4: 1080, SOCKS5: 1080, HTTP: 8080, } def set_default_proxy(proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None): """ set_default_proxy(proxy_type, addr[, port[, rdns[, username, password]]]) Sets a default proxy which all further socksocket objects will use, unless explicitly changed. """ socksocket.default_proxy = (proxy_type, addr.encode(), port, rdns, username.encode() if username else None, password.encode() if password else None) setdefaultproxy = set_default_proxy def get_default_proxy(): """ Returns the default proxy, set by set_default_proxy. """ return socksocket.default_proxy getdefaultproxy = get_default_proxy def wrap_module(module): """ Attempts to replace a module's socket library with a SOCKS socket. Must set a default proxy using set_default_proxy(...) first. This will only work on modules that import socket directly into the namespace; most of the Python Standard Library falls into this category. """ if socksocket.default_proxy: module.socket.socket = socksocket else: raise GeneralProxyError("No default proxy specified") wrapmodule = wrap_module def create_connection(dest_pair, proxy_type=None, proxy_addr=None, proxy_port=None, proxy_username=None, proxy_password=None, timeout=None): """create_connection(dest_pair, **proxy_args) -> socket object Like socket.create_connection(), but connects to proxy before returning the socket object. dest_pair - 2-tuple of (IP/hostname, port). **proxy_args - Same args passed to socksocket.set_proxy(). timeout - Optional socket timeout value, in seconds. """ sock = socksocket() if isinstance(timeout, (int, float)): sock.settimeout(timeout) sock.set_proxy(proxy_type, proxy_addr, proxy_port, proxy_username, proxy_password) sock.connect(dest_pair) return sock class socksocket(socket.socket): """socksocket([family[, type[, proto]]]) -> socket object Open a SOCKS enabled socket. The parameters are the same as those of the standard socket init. In order for SOCKS to work, you must specify family=AF_INET, type=SOCK_STREAM and proto=0. """ default_proxy = None def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0, _sock=None): _orig_socket.__init__(self, family, type, proto, _sock) if self.default_proxy: self.proxy = self.default_proxy else: self.proxy = (None, None, None, None, None, None) self.proxy_sockname = None self.proxy_peername = None self.proxy_negotiators = { SOCKS4: self._negotiate_SOCKS4, SOCKS5: self._negotiate_SOCKS5, HTTP: self._negotiate_HTTP, } def _recvall(self, count): """ Receive EXACTLY the number of bytes requested from the socket. Blocks until the required number of bytes have been received. """ data = b"" while len(data) < count: d = self.recv(count - len(data)) if not d: raise GeneralProxyError("Connection closed unexpectedly") data += d return data def set_proxy(self, proxy_type=None, addr=None, port=None, rdns=True, username=None, password=None): """set_proxy(proxy_type, addr[, port[, rdns[, username[, password]]]]) Sets the proxy to be used. proxy_type - The type of the proxy to be used. Three types are supported: PROXY_TYPE_SOCKS4 (including socks4a), PROXY_TYPE_SOCKS5 and PROXY_TYPE_HTTP addr - The address of the server (IP or DNS). port - The port of the server. Defaults to 1080 for SOCKS servers and 8080 for HTTP proxy servers. rdns - Should DNS queries be performed on the remote side (rather than the local side). The default is True. Note: This has no effect with SOCKS4 servers. username - Username to authenticate with to the server. The default is no authentication. password - Password to authenticate with to the server. Only relevant when username is also provided. """ self.proxy = (proxy_type, addr.encode(), port, rdns, username.encode() if username else None, password.encode() if password else None) setproxy = set_proxy def get_proxy_sockname(self): """ Returns the bound IP address and port number at the proxy. """ return self.proxy_sockname getproxysockname = get_proxy_sockname def get_proxy_peername(self): """ Returns the IP and port number of the proxy. """ return _orig_socket.getpeername(self) getproxypeername = get_proxy_peername def get_peername(self): """ Returns the IP address and port number of the destination machine (note: get_proxy_peername returns the proxy) """ return self.proxy_peername getpeername = get_peername def _negotiate_SOCKS5(self, dest_addr, dest_port): """ Negotiates a connection through a SOCKS5 server. """ proxy_type, addr, port, rdns, username, password = self.proxy # First we'll send the authentication packages we support. if username and password: # The username/password details were supplied to the # set_proxy method so we support the USERNAME/PASSWORD # authentication (in addition to the standard none). self.sendall(b"\x05\x02\x00\x02") else: # No username/password were entered, therefore we # only support connections with no authentication. self.sendall(b"\x05\x01\x00") # We'll receive the server's response to determine which # method was selected chosen_auth = self._recvall(2) if chosen_auth[0:1] != b"\x05": # Note: string[i:i+1] is used because indexing of a bytestring # via bytestring[i] yields an integer in Python 3 raise GeneralProxyError("SOCKS5 proxy server sent invalid data") # Check the chosen authentication method if chosen_auth[1:2] == b"\x02": # Okay, we need to perform a basic username/password # authentication. self.sendall(b"\x01" + chr(len(username)).encode() + username + chr(len(password)).encode() + password) auth_status = self._recvall(2) if auth_status[0:1] != b"\x01": # Bad response raise GeneralProxyError("SOCKS5 proxy server sent invalid data") if auth_status[1:2] != b"\x00": # Authentication failed raise SOCKS5AuthError("SOCKS5 authentication failed") # Otherwise, authentication succeeded # No authentication is required if 0x00 elif chosen_auth[1:2] != b"\x00": # Reaching here is always bad if chosen_auth[1:2] == b"\xFF": raise SOCKS5AuthError("All offered SOCKS5 authentication methods were rejected") else: raise GeneralProxyError("SOCKS5 proxy server sent invalid data") # Now we can request the actual connection req = b"\x05\x01\x00" # If the given destination address is an IP address, we'll # use the IPv4 address request even if remote resolving was specified. try: addr_bytes = socket.inet_aton(dest_addr) req += b"\x01" + addr_bytes except socket.error: # Well it's not an IP number, so it's probably a DNS name. if rdns: # Resolve remotely addr_bytes = None req += b"\x03" + chr(len(dest_addr)).encode() + dest_addr.encode() else: # Resolve locally addr_bytes = socket.inet_aton(socket.gethostbyname(dest_addr)) req += b"\x01" + addr_bytes req += struct.pack(">H", dest_port) self.sendall(req) # Get the response resp = self._recvall(4) if resp[0:1] != b"\x05": raise GeneralProxyError("SOCKS5 proxy server sent invalid data") status = ord(resp[1:2]) if status != 0x00: # Connection failed: server returned an error error = SOCKS5_ERRORS.get(status, "Unknown error") raise SOCKS5Error("{:#04x}: {}".format(status, error)) # Get the bound address/port if resp[3:4] == b"\x01": bound_addr = self._recvall(4) elif resp[3:4] == b"\x03": resp += self.recv(1) bound_addr = self._recvall(ord(resp[4:5])) else: raise GeneralProxyError("SOCKS5 proxy server sent invalid data") bound_port = struct.unpack(">H", self._recvall(2))[0] self.proxy_sockname = bound_addr, bound_port if addr_bytes: self.proxy_peername = socket.inet_ntoa(addr_bytes), dest_port else: self.proxy_peername = dest_addr, dest_port def _negotiate_SOCKS4(self, dest_addr, dest_port): """ Negotiates a connection through a SOCKS4 server. """ proxy_type, addr, port, rdns, username, password = self.proxy # Check if the destination address provided is an IP address remote_resolve = False try: addr_bytes = socket.inet_aton(dest_addr) except socket.error: # It's a DNS name. Check where it should be resolved. if rdns: addr_bytes = b"\x00\x00\x00\x01" remote_resolve = True else: addr_bytes = socket.inet_aton(socket.gethostbyname(dest_addr)) # Construct the request packet req = struct.pack(">BBH", 0x04, 0x01, dest_port) + addr_bytes # The username parameter is considered userid for SOCKS4 if username: req += username req += b"\x00" # DNS name if remote resolving is required # NOTE: This is actually an extension to the SOCKS4 protocol # called SOCKS4A and may not be supported in all cases. if remote_resolve: req += dest_addr.encode() + b"\x00" self.sendall(req) # Get the response from the server resp = self._recvall(8) if resp[0:1] != b"\x00": # Bad data raise GeneralProxyError("SOCKS4 proxy server sent invalid data") status = ord(resp[1:2]) if status != 0x5A: # Connection failed: server returned an error error = SOCKS4_ERRORS.get(status, "Unknown error") raise SOCKS4Error("{:#04x}: {}".format(status, error)) # Get the bound address/port self.proxy_sockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0]) if remote_resolve: self.proxy_peername = socket.inet_ntoa(addr_bytes), dest_port else: self.proxy_peername = dest_addr, dest_port def _negotiate_HTTP(self, dest_addr, dest_port): """ Negotiates a connection through an HTTP server. NOTE: This currently only supports HTTP CONNECT-style proxies. """ proxy_type, addr, port, rdns, username, password = self.proxy # If we need to resolve locally, we do this now addr = dest_addr if rdns else socket.gethostbyname(dest_addr) self.sendall(b"CONNECT " + addr.encode() + b":" + str(dest_port).encode() + b" HTTP/1.1\r\n" + b"Host: " + dest_addr.encode() + b"\r\n\r\n") # We just need the first line to check if the connection was successful fobj = self.makefile() status_line = fobj.readline() fobj.close() if not status_line: raise GeneralProxyError("Connection closed unexpectedly") try: proto, status_code, status_msg = status_line.split(" ", 2) except ValueError: raise GeneralProxyError("HTTP proxy server sent invalid response") if not proto.startswith("HTTP/"): raise GeneralProxyError("Proxy server does not appear to be an HTTP proxy") try: status_code = int(status_code) except ValueError: raise HTTPError("HTTP proxy server did not return a valid HTTP status") if status_code != 200: error = "{}: {}".format(status_code, status_msg) if status_code in (400, 403, 405): # It's likely that the HTTP proxy server does not support the CONNECT tunneling method error += ("\n[*] Note: The HTTP proxy server may not be supported by PySocks" " (must be a CONNECT tunnel proxy)") raise HTTPError(error) self.proxy_sockname = (b"0.0.0.0", 0) self.proxy_peername = addr, dest_port def connect(self, dest_pair): """ Connects to the specified destination through a proxy. Uses the same API as socket's connect(). To select the proxy server, use set_proxy(). dest_pair - 2-tuple of (IP/hostname, port). """ proxy_type, proxy_addr, proxy_port, rdns, username, password = self.proxy dest_addr, dest_port = dest_pair # Do a minimal input check first if (not isinstance(dest_pair, (list, tuple)) or len(dest_pair) != 2 or not isinstance(dest_addr, type("")) or not isinstance(dest_port, int)): raise GeneralProxyError("Invalid destination-connection (host, port) pair") if proxy_type is None: # Treat like regular socket object _orig_socket.connect(self, (dest_addr, dest_port)) return proxy_port = proxy_port or DEFAULT_PORTS.get(proxy_type) if not proxy_port: raise GeneralProxyError("Invalid proxy type") try: # Initial connection to proxy server _orig_socket.connect(self, (proxy_addr, proxy_port)) except socket.error as error: # Error while connecting to proxy self.close() proxy_server = "{}:{}".format(proxy_addr.decode(), proxy_port) printable_type = PRINTABLE_PROXY_TYPES[proxy_type] msg = "Error connecting to {} proxy {}".format(printable_type, proxy_server) raise ProxyConnectionError(msg, error) else: # Connected to proxy server, now negotiate try: # Calls negotiate_{SOCKS4, SOCKS5, HTTP} self.proxy_negotiators[proxy_type](dest_addr, dest_port) except socket.error as error: # Wrap socket errors self.close() raise GeneralProxyError("Socket error", error) except ProxyError: # Protocol error while negotiating with proxy self.close() raise onionshare-0.8.1/onionshare/strings.py000066400000000000000000000042241263142265200201020ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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, locale, sys, os import helpers strings = {} def load_strings(default="en"): """ Loads translated strings and fallback to English if the translation does not exist. """ global strings p = helpers.get_platform() # find locale dir if p == 'Linux': locale_dir = os.path.join(sys.prefix, 'share/onionshare/locale') elif p == 'Darwin': locale_dir = os.path.join(helpers.osx_resources_dir, 'locale') else: locale_dir = os.path.join(os.path.dirname(helpers.get_onionshare_dir()), 'locale') # load all translations translations = {} for filename in os.listdir(locale_dir): abs_filename = os.path.join(locale_dir, filename) lang, ext = os.path.splitext(filename) if abs_filename.endswith('.json'): translations[lang] = json.loads(open(abs_filename).read()) strings = translations[default] 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]: if key in translations[lang]: strings[key] = translations[lang][key] def translated(k, gui=False): """ Returns a translated string. """ if gui: return strings[k].encode("utf-8").decode('utf-8', 'replace') else: return strings[k].encode("utf-8") _ = translated onionshare-0.8.1/onionshare/web.py000066400000000000000000000211561263142265200171710ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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, mimetypes, platform, os, sys, urllib2 from flask import Flask, Response, request, render_template_string, abort from functools import wraps import strings, helpers app = Flask(__name__) # information about the file file_info = [] zip_filename = None zip_filesize = None def set_file_info(filenames): """ Using the list of filenames being shared, fill in details that the web page will need to display. This includes zipping up the file in order to get the zip file's name and size. """ global file_info, zip_filename, zip_filesize # build file info list file_info = {'files': [], 'dirs': []} 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'] = helpers.human_readable_filesize(info['size']) file_info['files'].append(info) if os.path.isdir(filename): info['size'] = helpers.dir_size(filename) info['size_human'] = helpers.human_readable_filesize(info['size']) file_info['dirs'].append(info) file_info['files'] = sorted(file_info['files'], key=lambda k: k['basename']) file_info['dirs'] = sorted(file_info['dirs'], key=lambda k: k['basename']) # zip up the files and folders z = helpers.ZipWriter() for info in file_info['files']: z.add_file(info['filename']) for info in file_info['dirs']: z.add_dir(info['filename']) z.close() zip_filename = z.zip_filename zip_filesize = os.path.getsize(zip_filename) REQUEST_LOAD = 0 REQUEST_DOWNLOAD = 1 REQUEST_PROGRESS = 2 REQUEST_OTHER = 3 REQUEST_CANCELED = 4 q = Queue.Queue() def add_request(request_type, path, data=None): """ Add a request to the queue, to communicate with the GUI. """ global q q.put({ 'type': request_type, 'path': path, 'data': data }) slug = helpers.random_string(16) download_count = 0 stay_open = False def set_stay_open(new_stay_open): """ Set stay_open variable. """ global stay_open stay_open = new_stay_open def get_stay_open(): """ Get stay_open variable. """ return stay_open transparent_torification = False def set_transparent_torification(new_transparent_torification): """ Set transparent_torification variable. """ global transparent_torification stay_open = new_transparent_torification def get_transparent_torification(): """ Get transparent_torification variable." """ return transparent_torification def debug_mode(): """ Turn on debugging mode, which will log flask errors to a debug file. """ import logging if platform.system() == 'Windows': temp_dir = os.environ['Temp'].replace('\\', '/') else: temp_dir = '/tmp/' log_handler = logging.FileHandler('{0:s}/onionshare_server.log'.format(temp_dir)) log_handler.setLevel(logging.WARNING) app.logger.addHandler(log_handler) def check_slug_candidate(slug): def slug_dec(f): @wraps(f) def slug_wrapper(slug_candidate, *args, **kwargs): if not helpers.constant_time_compare(slug.encode('ascii'),slug_candidate.encode('ascii')): abort(404) return f(*args, **kwargs) return slug_wrapper return slug_dec @app.route("/") @check_slug_candidate(slug) def index(): """ Render the template for the onionshare landing page. """ add_request(REQUEST_LOAD, request.path) return render_template_string( open(helpers.get_html_path('index.html')).read(), slug=slug, file_info=file_info, filename=os.path.basename(zip_filename).decode("utf-8"), filesize=zip_filesize, filesize_human=helpers.human_readable_filesize(zip_filesize) ) @app.route("//download") @check_slug_candidate(slug) def download(): """ Download the zip file. """ global download_count # each download has a unique id download_id = download_count download_count += 1 # 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 # tell GUI the download started add_request(REQUEST_DOWNLOAD, path, {'id': download_id}) dirname = os.path.dirname(zip_filename) basename = os.path.basename(zip_filename) def generate(): chunk_size = 102400 # 100kb fp = open(zip_filename, 'rb') done = False canceled = False while not done: chunk = fp.read(chunk_size) if chunk == '': done = True else: try: yield chunk # tell GUI the progress downloaded_bytes = fp.tell() percent = (1.0 * downloaded_bytes / zip_filesize) * 100 # suppress stdout platform on OSX (#203) if helpers.get_platform() != 'Darwin': sys.stdout.write( "\r{0:s}, {1:.2f}% ".format(helpers.human_readable_filesize(downloaded_bytes), percent)) sys.stdout.flush() add_request(REQUEST_PROGRESS, path, {'id': download_id, 'bytes': downloaded_bytes}) except: # looks like the download was canceled done = True canceled = True # tell the GUI the download has canceled add_request(REQUEST_CANCELED, path, {'id': download_id}) fp.close() if helpers.get_platform() != 'Darwin': sys.stdout.write("\n") # download is finished, close the server if not stay_open and not canceled: print strings._("closing_automatically") if shutdown_func is None: raise RuntimeError('Not running with the Werkzeug Server') shutdown_func() r = Response(generate()) r.headers.add('Content-Length', zip_filesize) r.headers.add('Content-Disposition', 'attachment', filename=basename) # guess content type (content_type, _) = mimetypes.guess_type(basename, strict=False) if content_type is not None: r.headers.add('Content-Type', content_type) return r @app.errorhandler(404) def page_not_found(e): """ 404 error page. """ add_request(REQUEST_OTHER, request.path) return render_template_string(open(helpers.get_html_path('404.html')).read()) # shutting down the server only works within the context of flask, so the easiest way to do it is over http shutdown_slug = helpers.random_string(16) @app.route("//shutdown") @check_slug_candidate(shutdown_slug) def shutdown(): """ Stop the flask web server. """ # shutdown the flask service func = request.environ.get('werkzeug.server.shutdown') if func is None: raise RuntimeError('Not running with the Werkzeug Server') func() return "" def start(port, stay_open=False, transparent_torification=False): """ Start the flask web server. """ set_stay_open(stay_open) set_transparent_torification(transparent_torification) app.run(port=port, threaded=True) def stop(port): """ Stop the flask web server by loading /shutdown. """ # to stop flask, load http://127.0.0.1://shutdown try: if transparent_torification: import socket s = socket.socket() s.connect(('127.0.0.1', port)) s.sendall('GET /{0:s}/shutdown HTTP/1.1\r\n\r\n'.format(shutdown_slug)) else: urllib2.urlopen('http://127.0.0.1:{0:d}/{1:s}/shutdown'.format(port, shutdown_slug)).read() except: pass onionshare-0.8.1/onionshare_gui/000077500000000000000000000000001263142265200167015ustar00rootroot00000000000000onionshare-0.8.1/onionshare_gui/__init__.py000066400000000000000000000013731263142265200210160ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 onionshare_gui import * onionshare-0.8.1/onionshare_gui/common.py000066400000000000000000000031451263142265200205460ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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, inspect, platform from onionshare import helpers def get_onionshare_gui_dir(): """ Returns the OnionShare gui directory. """ p = helpers.get_platform() if p == 'Darwin': onionshare_gui_dir = os.path.dirname(__file__) else: onionshare_gui_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) return onionshare_gui_dir onionshare_gui_dir = get_onionshare_gui_dir() def get_image_path(filename): """ Returns the OnionShare image path. """ p = helpers.get_platform() if p == 'Linux' or p == 'Tails': prefix = os.path.join(sys.prefix, 'share/onionshare/images') elif p == 'Darwin': prefix = os.path.join(helpers.osx_resources_dir, 'images') else: prefix = os.path.join(os.path.dirname(get_onionshare_gui_dir()), 'images') return os.path.join(prefix, filename) onionshare-0.8.1/onionshare_gui/downloads.py000066400000000000000000000052621263142265200212520ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 PyQt4 import QtCore, QtGui import common from onionshare import strings, helpers class Downloads(QtGui.QVBoxLayout): """ The downloads chunk of the GUI. This lists all of the active download progress bars. """ def __init__(self): super(Downloads, self).__init__() self.progress_bars = {} # downloads label self.downloads_label = QtGui.QLabel(strings._('gui_downloads', True)) self.downloads_label.hide() # add the widgets self.addWidget(self.downloads_label) def add_download(self, download_id, total_bytes): """ Add a new download progress bar. """ self.downloads_label.show() # make a new progress bar pb = QtGui.QProgressBar() pb.setTextVisible(True) pb.setAlignment(QtCore.Qt.AlignHCenter) pb.setMinimum(0) pb.setMaximum(total_bytes) pb.setValue(0) pb.setStyleSheet("QProgressBar::chunk { background-color: #05B8CC; }") pb.total_bytes = total_bytes # add it to the list self.progress_bars[download_id] = pb self.addWidget(pb) # start at 0 self.update_download(download_id, total_bytes, 0) def update_download(self, download_id, total_bytes, downloaded_bytes): """ Update the progress of a download progress bar. """ if download_id not in self.progress_bars: self.add_download(download_id, total_bytes) pb = self.progress_bars[download_id] pb.setValue(downloaded_bytes) if downloaded_bytes == pb.total_bytes: pb.setFormat("%p%") else: pb.setFormat("{0:s}, %p%".format(helpers.human_readable_filesize(downloaded_bytes))) def cancel_download(self, download_id): """ Update a download progress bar to show that it has been canceled. """ pb = self.progress_bars[download_id] pb.setFormat(strings._('gui_canceled')) onionshare-0.8.1/onionshare_gui/file_selection.py000066400000000000000000000210451263142265200222410ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 PyQt4 import QtCore, QtGui import common from onionshare import strings, helpers class FileList(QtGui.QListWidget): """ The list of files and folders in the GUI. """ files_dropped = QtCore.pyqtSignal() files_updated = QtCore.pyqtSignal() def __init__(self, parent=None): super(FileList, self).__init__(parent) self.setAcceptDrops(True) self.setIconSize(QtCore.QSize(32, 32)) self.setSortingEnabled(True) class DropHereLabel(QtGui.QLabel): """ When there are no files or folders in the FileList yet, display the 'drop files here' message and graphic. """ def __init__(self, parent, image=False): self.parent = parent super(DropHereLabel, self).__init__(parent=parent) self.setAcceptDrops(True) self.setAlignment(QtCore.Qt.AlignCenter) if image: self.setPixmap(QtGui.QPixmap.fromImage(QtGui.QImage(common.get_image_path('drop_files.png')))) else: self.setText(QtCore.QString(strings._('gui_drag_and_drop', True))) self.setStyleSheet('color: #999999;') self.hide() def dragEnterEvent(self, event): self.parent.drop_here_image.hide() self.parent.drop_here_text.hide() event.ignore() self.drop_here_image = DropHereLabel(self, True) self.drop_here_text = DropHereLabel(self, False) self.filenames = [] self.update() def update(self): """ Update the GUI elements based on the current state. """ # file list should have a background image if empty if len(self.filenames) == 0: self.drop_here_image.show() self.drop_here_text.show() else: self.drop_here_image.hide() self.drop_here_text.hide() def resizeEvent(self, event): """ When the widget is resized, resize the drop files image and text. """ self.drop_here_image.setGeometry(0, 0, self.width(), self.height()) self.drop_here_text.setGeometry(0, 0, self.width(), self.height()) def dragEnterEvent(self, event): """ dragEnterEvent for dragging files and directories into the widget. """ if event.mimeData().hasUrls: event.accept() else: event.ignore() def dragLeaveEvent(self, event): """ dragLeaveEvent for dragging files and directories into the widget. """ 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.files_dropped.emit() def add_file(self, filename): """ Add a file or directory to this widget. """ if filename not in self.filenames: # make filenames unicode-safe for Qt (#141) filename = filename.encode('utf-8').decode('utf-8', 'replace') self.filenames.append(filename) fileinfo = QtCore.QFileInfo(filename) basename = os.path.basename(filename.rstrip('/')) ip = QtGui.QFileIconProvider() icon = ip.icon(fileinfo) if os.path.isfile(filename): size = helpers.human_readable_filesize(fileinfo.size()) else: size = helpers.human_readable_filesize(helpers.dir_size(filename)) item_name = unicode('{0:s} ({1:s})'.format(basename, size)) item = QtGui.QListWidgetItem(item_name) item.setToolTip(QtCore.QString(size)) item.setIcon(icon) self.addItem(item) self.files_updated.emit() class FileSelection(QtGui.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): super(FileSelection, self).__init__() self.server_on = False # file list self.file_list = FileList() self.file_list.currentItemChanged.connect(self.update) self.file_list.files_dropped.connect(self.update) # buttons self.add_files_button = QtGui.QPushButton(strings._('gui_add_files', True)) self.add_files_button.clicked.connect(self.add_files) self.add_dir_button = QtGui.QPushButton(strings._('gui_add_folder', True)) self.add_dir_button.clicked.connect(self.add_dir) self.delete_button = QtGui.QPushButton(strings._('gui_delete', True)) self.delete_button.clicked.connect(self.delete_file) button_layout = QtGui.QHBoxLayout() button_layout.addWidget(self.add_files_button) button_layout.addWidget(self.add_dir_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 disabled if the server is on if self.server_on: self.add_files_button.setEnabled(False) self.add_dir_button.setEnabled(False) self.delete_button.setEnabled(False) else: self.add_files_button.setEnabled(True) self.add_dir_button.setEnabled(True) # delete button should be disabled if item isn't selected current_item = self.file_list.currentItem() if not current_item: self.delete_button.setEnabled(False) else: self.delete_button.setEnabled(True) # update the file list self.file_list.update() def add_files(self): """ Add files button clicked. """ filenames = QtGui.QFileDialog.getOpenFileNames( caption=strings._('gui_choose_files', True), options=QtGui.QFileDialog.ReadOnly) if filenames: for filename in filenames: self.file_list.add_file(str(filename)) self.update() def add_dir(self): """ Add folder button clicked. """ filename = QtGui.QFileDialog.getExistingDirectory( caption=strings._('gui_choose_folder', True), options=QtGui.QFileDialog.ReadOnly) if filename: self.file_list.add_file(str(filename)) self.update() def delete_file(self): """ Delete button clicked """ current_row = self.file_list.currentRow() self.file_list.filenames.pop(current_row) self.file_list.takeItem(current_row) self.update() def server_started(self): """ Gets called when the server starts. """ self.server_on = True self.file_list.setAcceptDrops(False) self.update() def server_stopped(self): """ Gets called when the server stops. """ self.server_on = False self.file_list.setAcceptDrops(True) self.update() def get_num_files(self): """ Returns the total number of files and folders in the list. """ return len(self.file_list.filenames) onionshare-0.8.1/onionshare_gui/onionshare_gui.py000066400000000000000000000263531263142265200222750ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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, sys, subprocess, inspect, platform, argparse, threading, time, math, inspect, platform from PyQt4 import QtCore, QtGui import common try: import onionshare except ImportError: sys.path.append(os.path.abspath(common.onionshare_gui_dir + "/..")) import onionshare from onionshare import strings, helpers, web from file_selection import FileSelection from server_status import ServerStatus from downloads import Downloads from options import Options class Application(QtGui.QApplication): """ This is Qt's QApplication class. It has been overridden to support threads and the quick keyboard shortcut. """ def __init__(self): platform = helpers.get_platform() if platform == 'Linux': self.setAttribute(QtCore.Qt.AA_X11InitThreads, True) QtGui.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 class OnionShareGui(QtGui.QWidget): """ OnionShareGui is the main window for the GUI that contains all of the GUI elements. """ start_server_finished = QtCore.pyqtSignal() stop_server_finished = QtCore.pyqtSignal() starting_server_step2 = QtCore.pyqtSignal() def __init__(self, qtapp, app): super(OnionShareGui, self).__init__() self.qtapp = qtapp self.app = app self.setWindowTitle('OnionShare') self.setWindowIcon(window_icon) def send_files(self, filenames=None): """ Build the GUI in send files mode. Note that this is the only mode currently implemented. """ # file selection self.file_selection = FileSelection() if filenames: for filename in filenames: self.file_selection.file_list.add_file(filename) # server status self.server_status = ServerStatus(self.qtapp, self.app, web, self.file_selection) self.server_status.server_started.connect(self.file_selection.server_started) self.server_status.server_started.connect(self.start_server) self.server_status.server_stopped.connect(self.file_selection.server_stopped) self.server_status.server_stopped.connect(self.stop_server) self.start_server_finished.connect(self.clear_message) self.start_server_finished.connect(self.server_status.start_server_finished) self.stop_server_finished.connect(self.server_status.stop_server_finished) self.file_selection.file_list.files_updated.connect(self.server_status.update) self.server_status.url_copied.connect(self.copy_url) self.starting_server_step2.connect(self.start_server_step2) # filesize warning self.filesize_warning = QtGui.QLabel() self.filesize_warning.setStyleSheet('padding: 10px 0; font-weight: bold; color: #333333;') self.filesize_warning.hide() # downloads self.downloads = Downloads() # options self.options = Options(web, self.app) # status bar self.status_bar = QtGui.QStatusBar() self.status_bar.setSizeGripEnabled(False) # main layout self.layout = QtGui.QVBoxLayout() self.layout.addLayout(self.file_selection) self.layout.addLayout(self.server_status) self.layout.addWidget(self.filesize_warning) self.layout.addLayout(self.downloads) self.layout.addLayout(self.options) self.layout.addWidget(self.status_bar) self.setLayout(self.layout) self.show() # check for requests frequently self.timer = QtCore.QTimer() QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"), self.check_for_requests) self.timer.start(500) def start_server_step2(self): """ Step 2 in starting the onionshare server. This displays the large filesize warning, if applicable. """ # warn about sending large files over Tor if web.zip_filesize >= 157286400: # 150mb self.filesize_warning.setText(strings._("large_filesize", True)) self.filesize_warning.show() def start_server(self): """ Start the onionshare server. This uses multiple threads to start the Tor hidden server and the web app. """ # start the hidden service self.status_bar.showMessage(strings._('gui_starting_server1', True)) self.app.choose_port() try: self.status_bar.showMessage(strings._('gui_starting_server1', True)) self.app.start_hidden_service(gui=True) except onionshare.hs.NoTor as e: alert(e.args[0], QtGui.QMessageBox.Warning) self.server_status.stop_server() self.status_bar.clearMessage() return # start onionshare service in new thread t = threading.Thread(target=web.start, args=(self.app.port, self.app.stay_open, self.app.transparent_torification)) t.daemon = True t.start() # prepare the files for sending in a new thread def finish_starting_server(self): # prepare files to share web.set_file_info(self.file_selection.file_list.filenames) self.app.cleanup_filenames.append(web.zip_filename) self.starting_server_step2.emit() # wait for hs if not self.app.local_only: if not self.app.hs.supports_ephemeral: self.status_bar.showMessage(strings._('gui_starting_server3', True)) self.app.hs.wait_for_hs(self.app.onion_host) # done self.start_server_finished.emit() self.status_bar.showMessage(strings._('gui_starting_server2', True)) t = threading.Thread(target=finish_starting_server, kwargs={'self': self}) t.daemon = True t.start() def stop_server(self): """ Stop the onionshare server. """ if self.server_status.status != self.server_status.STATUS_STOPPED: web.stop(self.app.port) self.app.cleanup() self.filesize_warning.hide() self.stop_server_finished.emit() def check_for_requests(self): """ Check for messages communicated from the web app, and update the GUI accordingly. """ self.update() # only check for requests if the server is running if self.server_status.status != self.server_status.STATUS_STARTED: return events = [] done = False while not done: try: r = web.q.get(False) events.append(r) except web.Queue.Empty: done = True for event in events: if event["type"] == web.REQUEST_LOAD: self.status_bar.showMessage(strings._('download_page_loaded', True)) elif event["type"] == web.REQUEST_DOWNLOAD: self.downloads.add_download(event["data"]["id"], web.zip_filesize) elif event["type"] == web.REQUEST_PROGRESS: self.downloads.update_download(event["data"]["id"], web.zip_filesize, event["data"]["bytes"]) # is the download complete? if event["data"]["bytes"] == web.zip_filesize: # close on finish? if not web.get_stay_open(): self.server_status.stop_server() elif event["type"] == web.REQUEST_CANCELED: self.downloads.cancel_download(event["data"]["id"]) elif event["path"] != '/favicon.ico': self.status_bar.showMessage('{0:s}: {1:s}'.format(strings._('other_page_loaded', True), event["path"])) def copy_url(self): """ When the URL gets copied to the clipboard, display this in the status bar. """ self.status_bar.showMessage(strings._('gui_copied_url', True), 2000) def clear_message(self): """ Clear messages from the status bar. """ self.status_bar.clearMessage() def alert(msg, icon=QtGui.QMessageBox.NoIcon): """ Pop up a message in a dialog window. """ dialog = QtGui.QMessageBox() dialog.setWindowTitle("OnionShare") dialog.setWindowIcon(window_icon) dialog.setText(msg) dialog.setIcon(icon) dialog.exec_() def main(): """ The main() function implements all of the logic that the GUI version of onionshare uses. """ strings.load_strings() # start the Qt app global qtapp qtapp = Application() # parse arguments parser = argparse.ArgumentParser() parser.add_argument('--local-only', action='store_true', dest='local_only', help=strings._("help_local_only")) parser.add_argument('--stay-open', action='store_true', dest='stay_open', help=strings._("help_stay_open")) parser.add_argument('--debug', action='store_true', dest='debug', help=strings._("help_debug")) parser.add_argument('--transparent', action='store_true', dest='transparent_torification', help=strings._("help_transparent_torification")) parser.add_argument('--filenames', metavar='filenames', nargs='+', help=strings._('help_filename')) args = parser.parse_args() filenames = args.filenames if filenames: for i in range(len(filenames)): filenames[i] = os.path.abspath(filenames[i]) local_only = bool(args.local_only) stay_open = bool(args.stay_open) debug = bool(args.debug) transparent_torification = bool(args.transparent_torification) # create the onionshare icon global window_icon window_icon = QtGui.QIcon(common.get_image_path('logo.png')) # validation if filenames: valid = True for filename in filenames: if not os.path.exists(filename): alert(strings._("not_a_file", True).format(filename)) valid = False if not valid: sys.exit() # start the onionshare app web.set_stay_open(stay_open) web.set_transparent_torification(transparent_torification) app = onionshare.OnionShare(debug, local_only, stay_open, transparent_torification) # clean up when app quits def shutdown(): app.cleanup() qtapp.connect(qtapp, QtCore.SIGNAL("aboutToQuit()"), shutdown) # launch the gui gui = OnionShareGui(qtapp, app) gui.send_files(filenames) # all done sys.exit(qtapp.exec_()) if __name__ == '__main__': main() onionshare-0.8.1/onionshare_gui/options.py000066400000000000000000000035711263142265200207540ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 PyQt4 import QtCore, QtGui import common from onionshare import strings, helpers class Options(QtGui.QHBoxLayout): """ The extra onionshare options in the GUI. """ def __init__(self, web, app): super(Options, self).__init__() self.web = web self.app = app # close automatically self.close_automatically = QtGui.QCheckBox() if self.web.stay_open: self.close_automatically.setCheckState(QtCore.Qt.Unchecked) else: self.close_automatically.setCheckState(QtCore.Qt.Checked) self.close_automatically.setText(strings._("close_on_finish", True)) self.connect(self.close_automatically, QtCore.SIGNAL('stateChanged(int)'), self.stay_open_changed) # add the widgets self.addWidget(self.close_automatically) def stay_open_changed(self, state): """ When the 'close automatically' checkbox is toggled, let the web app know. """ if state > 0: self.web.set_stay_open(False) self.app.stay_open = False else: self.web.set_stay_open(True) self.app.stay_open = True onionshare-0.8.1/onionshare_gui/server_status.py000066400000000000000000000144641263142265200221750ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 from PyQt4 import QtCore, QtGui import common from onionshare import strings, helpers class ServerStatus(QtGui.QVBoxLayout): """ The server status chunk of the GUI. """ server_started = QtCore.pyqtSignal() server_stopped = QtCore.pyqtSignal() url_copied = QtCore.pyqtSignal() STATUS_STOPPED = 0 STATUS_WORKING = 1 STATUS_STARTED = 2 def __init__(self, qtapp, app, web, file_selection): super(ServerStatus, self).__init__() self.status = self.STATUS_STOPPED self.qtapp = qtapp self.app = app self.web = web self.file_selection = file_selection # server layout self.status_image_stopped = QtGui.QImage(common.get_image_path('server_stopped.png')) self.status_image_working = QtGui.QImage(common.get_image_path('server_working.png')) self.status_image_started = QtGui.QImage(common.get_image_path('server_started.png')) self.status_image_label = QtGui.QLabel() self.status_image_label.setFixedWidth(30) self.server_button = QtGui.QPushButton() self.server_button.clicked.connect(self.server_button_clicked) server_layout = QtGui.QHBoxLayout() server_layout.addWidget(self.status_image_label) server_layout.addWidget(self.server_button) # url layout url_font = QtGui.QFont() self.url_label = QtGui.QLabel() self.url_label.setFont(url_font) self.url_label.setWordWrap(True) self.url_label.setAlignment(QtCore.Qt.AlignCenter) self.copy_url_button = QtGui.QPushButton(strings._('gui_copy_url', True)) self.copy_url_button.clicked.connect(self.copy_url) url_layout = QtGui.QHBoxLayout() url_layout.addWidget(self.url_label) url_layout.addWidget(self.copy_url_button) # add the widgets self.addLayout(server_layout) self.addLayout(url_layout) self.update() def update(self): """ Update the GUI elements based on the current state. """ # set the status image if self.status == self.STATUS_STOPPED: self.status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.status_image_stopped)) elif self.status == self.STATUS_WORKING: self.status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.status_image_working)) elif self.status == self.STATUS_STARTED: self.status_image_label.setPixmap(QtGui.QPixmap.fromImage(self.status_image_started)) # set the URL fields if self.status == self.STATUS_STARTED: self.url_label.setText('http://{0:s}/ {1:s}'.format(self.app.onion_host, self.web.slug)) self.url_label.show() self.copy_url_button.show() # resize parent widget p = self.parentWidget() p.resize(p.sizeHint()) else: self.url_label.hide() self.copy_url_button.hide() # button if self.file_selection.get_num_files() == 0: self.server_button.setEnabled(False) self.server_button.setText(strings._('gui_start_server', True)) else: if self.status == self.STATUS_STOPPED: self.server_button.setEnabled(True) self.server_button.setText(strings._('gui_start_server', True)) elif self.status == self.STATUS_STARTED: self.server_button.setEnabled(True) self.server_button.setText(strings._('gui_stop_server', True)) else: self.server_button.setEnabled(False) self.server_button.setText(strings._('gui_please_wait')) def server_button_clicked(self): """ Toggle starting or stopping the server. """ if self.status == self.STATUS_STOPPED: self.start_server() elif self.status == self.STATUS_STARTED: self.stop_server() 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() def stop_server(self): """ Stop the server. """ self.status = self.STATUS_WORKING self.update() self.server_stopped.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. """ url = 'http://{0:s}/{1:s}'.format(self.app.onion_host, self.web.slug) if platform.system() == 'Windows': # Qt's QClipboard isn't working in Windows # https://github.com/micahflee/onionshare/issues/46 import ctypes GMEM_DDESHARE = 0x2000 ctypes.windll.user32.OpenClipboard(None) ctypes.windll.user32.EmptyClipboard() hcd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(url)) + 1) pch_data = ctypes.windll.kernel32.GlobalLock(hcd) ctypes.cdll.msvcrt.strcpy(ctypes.c_char_p(pch_data), bytes(url)) ctypes.windll.kernel32.GlobalUnlock(hcd) ctypes.windll.user32.SetClipboardData(1, hcd) ctypes.windll.user32.CloseClipboard() else: clipboard = self.qtapp.clipboard() clipboard.setText(url) self.url_copied.emit() onionshare-0.8.1/screenshots/000077500000000000000000000000001263142265200162305ustar00rootroot00000000000000onionshare-0.8.1/screenshots/appdata-client.png000066400000000000000000001734161263142265200216400ustar00rootroot00000000000000PNG  IHDR@bKGD pHYs+tIME il} IDATxyEs&w  p߇("(* "!"EPETTA@@BHB8LBkg1ӳ=3=n6.o>鮮zJ]=b(4֩Op|:´T:yr2z]TUi r%˞DeVBaR%ףwrwhGʒ2G%R)Y@a^g݄):)*rXv>-\vaӽ(̶K,*]P]/2zkmLVVueUۧr;ZCHt'^pʽCvG .Y;m2E Q 6pIoK.Ru ssP2`gvߔQ@+G=`+&k_l :gNX =S VPF(v]rV@XtU~HKZ:]tǣrSIæ%2*.,cLa8fuTe["kV@Qr0:=1MT߼ ­TrY UITi(KNؕ*(^P̵eLj+ vj8S~rgn:m{}VtGS^~ESi-1#8;Ptx*]r_uOa.mVl@\DptNŐriM[R6sS,n]"܂6QF  B]u"N|T =7={o@42;eW9aJnQ6It/N+3Pi4XN9"O?V6k{3ݑ ɳ}`crWkwӂu~s=To'z'z>[(4)ExUdOYq9 1Ӛrls+VV g/q}YT4QU EG9#e=rLvOZ ,풶zn[eSJ+4of NWݭ֪J;B9u^E"6TR:ݞHJ9RtV)*nLBi\uv 59μ:WS1,?_fX=- te}UkR|,uCbQ aʫBThh斆rU2V-Yҁ U.CBmv x~ڊe͖xܿS9(,vؗ._Y˿#^rۦOǬK w:)eڎ;G1'OQM2'_ G?cu 7"ғfzh}˱Y,5] I|3,C; )<SMUJ}.Zgo+gmm:ϹcZ ͈J'im9aLBl%@8r(V(vpXWBH.-EvTUPN/#`i` ]@3ޜvX*5qS hF|oE hGQ{2s)9`^(%8ʇr1@)%ܻi3K$JaaGOT"KAFMr 3r6>OMD8gxUvHtIx-4;+͎NYvxaK5:]K@鱓iI=80P[8y|OTY-DDiq?7?sg-GFvdoL{Y4`Β 3s~bk’W~ϐ_){8H%(*{?v*}xC,`C٪\_ԨN@(}Ӻgեt+O՛JY;H.(jPf̛g9"d$Eq9Bw͕b"o7Rɚrנj+%Cl,.eVn rz @([ ҹk ;g-SYnsK }UF *ՇC  *WkC0]-ױ\),0Z|洕D#8n iZO#/_oe9/X.\&t~"[ۯjxKm3 [j v[ oPR/2,Iy^@QSM m\H*Or/N-sk{C.H]XÊ; ͕θ /:m (2brPP4r0pD"VBhR(|ttv^PNkgl^Ki0ih/ӄxAUCWYoE   5/PxHɼ9ofü!E]]1Bf[Be2Ilsާ"ȋLjϧvh\ >[uF'-@y U,3֭’ϔѤmD$5R[G  f*2?g[ ~[ȵm:b˞`•Ƕ&"2F GAA~C) ̧̱?MwXZk;nZ i/W/$҂֚?PxQ4M<7>\" }>}:lY8X)k ddfS{loGK" =y&9A~ ƚw_<Ʋv*GN м5+~y.κ5jO YWC I.'S%   ;U>JB+ n^n]ep:#]X(OdWfudJ/s{ FTxRј@x=J(5r(xK&AFNsq=s9C Udy92 0a/>QQ_MBinn"K`Z) C}pAOWPv m$,xRU&ҁtHg/x>G;f Ӄ/W6Q8u^+HZ4vtP>$A,X4J"JcJL1<^W{ʶpp i哷pYI$Q 6Evʿi*O*7C $F 3d^p ~\  ɃBGsS1:n^?#UaZ7&b @%]kk"fx^ xyg>FZQAAA@ .SZkJKMݧ=Oq X,$;Jn:-\哪Qequs5LgߦX,AcPb(eŰF6lX2;6 iʡ9>3% wkVN3o7.Q%j9s#V@m+yKk0*au𥣙mX&i0_Ķy b[Gh1P?4۠r(S&oW$!~_sj[+/_Yvͤ˷ˠD'}cLb\C7_kZv?|Si/>ymq:/ ?Mٗ_3g`Zzk+eumoHt~ >ؼys3ǁd\@f?OwUq `53KEH鉱6N<ϰ1ԨΉ6"XQDZ9hnrY_<_ʰO\M_Ĩ>ƛfx}9zs.=b(??6څ/_+xqZ>qOڄ{8/{Vy!!\SE~o.d& ԚG-'>9A:]drۙ}zyq м.Dz@Ðj:Oq&cvYi^$.Xb?3/VR'q?F́W$-&I DcR#uTw_aMRI~xOnNc8Dk7AAx=/ڱ c @3RI_ś[g];ߜ5e${.5nbݗ)D(EF: >X[kkhɸ{?n C9DPh#Pb6 a|Aat[1%Vgߗ'17Cײ4k<,G>`w<#z,9)?SՎ֫Z:ECssdNK3ξuJ'41=Ͽqu>"@J^YeuZLP=P9\aym%ߥ7.- 9n4A0;=4iP {/ T%qol=[nן寏EMx&s؊   $c"_Tu~2cdO:. \v5L%t]I<o&nǠP&y۶ҢRwtx w̭T1gRU'a%̙Q q ک.d<6A[g坣\9KXGx~;#sg GP⃴hKu 3r5~,ӏdtJ'I5M q/iRJUJOMiKV"喋ϵ=Kj0exf >YyOeAqxnY?\q>s<1s㼹{WHn ńtݻa5,ݒMZba1ö8}~21?/?9`xX FQIhӫ%R"-$LPX_mz`"ظ痣w";~Ϣ  ?:p[M/Cy]fE   (,{?# Ex-;P!( ?M&KPf=fKk?%wk!~/_I0QJ),m|JA_ɸ6mu\%F;rnZpGϛ:cۊwS/&\M/^ 8\|*_:z&* xUxÃ!Z*^7__1$*ռǖ⩨%p<=Opq{1n8Xr)kcl \ןɇdBaѱi%-O9EO7 TVznNN$ U(#H AU3<7µ(J My~3   ˲YЁGxƒFӡHmTݣR#[g/Nh~^y=zK BTT 0 +H$?۩q   BV.Pe8 C@X#\P Ǡ"䍄ڒXNPa`Jx{<PX"ƍ\㪨AAA-ޝN! xW87 =\ zy=E4AAA^C7AAA(la?M8!G AAAA P8Tx|Q   Rt/772B}jAAAaW*)#GWCL&%'Vr RJ2AA{?':J)-t _,ib&L,²,x^da&Jq5 ϋ0 Q  ey-{ +' b8uu{=w.#F`Ȑ|>u`$>P-KH$b˖ͬYγm~|>_AA>no{P:G[ZDci5֬-,&H7MX,9{q7f{%,>udʷ֚~_7x)ݶ(AA1hiCxPxC(<ϔ$N+M2X5E_h4֚xt0e|:˲̢.5Ocs?."RQ ~i2`>ӂ iVJSJFcBa~?2r(ɤL}lc B.)8^ex2JkկFWW`0 AADPNAO<@k͝#FL&3Ѐ?uzr-$\ZʁTٷ,FYuGAc'Gd>BڞYYgkQ.bW^u cƌMUZ{ȷRޞVJm x2}l NGʫ&e%AA_H.J-+ @hiӦq衇ݳNapd*@k#秄K@ Üm[=pM/7LBy3iA$AA*Se+0*Q(lͤQɔ#Osg[(jf".N?L|>_Fqzv0TW*3OVK#wfNp)۾0rX㫧A$SAAO.boh+r\ЏF-{} MX} 2#+v} ɸ3g,ǹ:=;RVnGoYH9E̢o##DsyKUsf2nxikE_CIA[OTkh%?=?]1ؿv$c/*yu<,o~˲x<+yGNjX5jF؟cN<&W\=!F`PڦeCD׎b_/̦.{˷Tmn[x,_@f9L m2.FQcI M_g_A[2˚pܱ17sCn&ne_#g2"寋[SF)f$z4䓬b~a*'_ONw\F$ WK30b+[qGN(=O '͛Ĩa/nEV~43DZhK.3Ւq$La12˱_Zk],q$K%+Qs7S*IUz7n/G[F}d?~5Z8h`Qsb{/˪mQ g+o@61;ɷeP5v_NĄD)'y|4p)PQQ9K/wminV `ɠݥ#f,(>&;YS!iAA'ҿrS|OQ3Mny}V6/saޠ<%[$6|,zNj0zpYhމUI'_̅G+Q|/\x1km6=};MRFJ&=!/6U^=wѥ 6뮻6nM?8̄ɠA 6,c `n 8swm8cUdup<Ăf%<.*{h F'`.+a&pڤ :ٙO ]Gۿ͌14_zv!c]h:ӎF=[x㑻S6>x-66gFU2]au/3_xaϜJ2JH yfj>))%pM Fn˚ѷwe%ʫGgZ]#]G'WsAANY;&<`< )D^"y9d$=KOgWZc|温< :fp l1n$8*>ut~󛴗xFVcWOFYWv[/7d@Fojj*^aӂiQQQR5+3F,iSh[> (㟬YD|_1j=ރCyyuYu2j_COnb7s#j̩É(?$6ªCA_tV^7i_D-oā9b3zmJ3oCa_&ͭ,g Si卥Mk-,^ &+_g)' 2qL2~}s:vug59ꉰ3[奔"yZ׎?ӪyelṆZiT.綈2Œ:|n}?<#\Ki94:s16K,[.#?)uRYK[eirY|-9yTHx _z^g[*k[L{w'N橧.O7=A? ;۟F'^kNcv{E p4x|1v{]33vX9VI" 1v،c5BsI@~,~xzb"#P7,e c /Fv[5U^lIin̨CNfs?䲇~cnK#\O~~w;ߘHͷj"#7=h*{9e| W|+|Æ |a3aw/hll 7vXBIc%w_$6bTB9ʛ(AA7dߥNUh"GSouF-|\>rՋvٻI&[cm`v:=f^$O'Mz<Ƥ+*?x @yirQ3[!pg0& L40H&Oyާ/ϓMS)!G27{aͬ[Xֶ@Fq5} 1Kn"1q~,Zچwu:JmU-,=AM UJ`u XDu̬eU0* Վ]+p4Q =h$Ý2܂5wذa7prK|[!fXƍ-x}x俋<'X^R:w  ®Sr=Ipʩg~q)+6;mzaYI,3sZ@3,h_̣O<'5~nYLͼ1 9| /@ MUFoI?9VzjZe9I32a%IfFeYx<̾Na' ČӾW\O uXxaeZ2KHSO+pQC?/r͇#q9{֖En控L>ƚc-/ ?"~ғ͵,&g=p6l\O ?qjxQWgOT”m)v(Wriћ6{qegr SnG<8kPS<~*h/_i5̋JkGN¯6sǟ溧SʡL^wYe=Nk~Oɍ%Sʼ&8ÇݖUߞ]S!LPJ6m:o6K;%d4TD9AA괭fm1X 5kvK ΪZL&,ױ~gjf;vY~ E~.%%aYPtiדO|A."L$TQ  @ĞJ)gNxUݎ5 d"a"c?7gd`k4{]Gp @n.\?v6ZkƏϧ?}--"̤ L%  20PB  st IDATFDciXhbЄ  {}Ȝ9s9s Y˿,Wr BEx NJ%|n~/9thc+ؼ^/7of,XM70kD"' >GybQ?R\ l')Ce2O&(H$YB4LߝSx8B.%L׏ܵkrwp*Ȝ8;V x^!uKAA' 2 *Px@2TޙCk|^OoFtMML%| 4^Z<'aV̪  %9dAAAA"Xn8~3P6   Px|`˟WeI{gh,N,nLz<^~/0U|AAAA)E,aRQEԟ~EoԪHҁI,gSS3mV& z3-4M"ZX~uՕ \G/[<   (2oJGhwaY F *a~~?U$$ZyoZUP/\   a -ZUZ3K8D Я\03&6/ţ jdu5lڂ   'R j@,x B"e llzz_eΈƆ%K~:**Z{1~„'mYTWXtaݺu[S[[˰aÈF԰dVXY9rZBbӦMl޼iӦa;G駵w! 2a„WeS[[n&Zt)5jW_ӧK vwԒ0|.\@ee%i~z֯_Ϟ{{=.ֽ5= ;a M?q7Nb.R蜿?1ce[h'se>+c >tV @ ~ZڣV9hxGii~P +wr~]ɾ==qťW7po#.]ʺuk B|>MVvaSh*!:: vZ/^ܹs1cJ)/_ڵkٸq#eov>< eY,Z+VdGQN9n>O_ןϦflڴi vxwزe.[4yy饗z_~!mmm2)=/^[w/5֭C2^J+ ݃O{Ÿ(,Xʂ%VZ… z|_㏧ f4fcaxocT\ ;i|[MuE`@>?yx?{b=q;UnJg5[ Y{1<Ө f= K*wY͙g|#O<#9r$gsA8 }P&/Pt]MUM-x"8(xAJ?z-GBUUs [ 0?S^ݬMjnrܲl2\yASA~ ~uop 5H7?1#w|w-h%=:::`3_HKKCbbkMZ* 88v۶mj{Aǃ Wnn.V\kf\_ Àm)%y+[_ 0փ tBQ<ӈ&Fe_Vz,`Xt)l6ۨسg1k,466"//l<_Wk$blvCkFGG'6mgg&%bl Zl65Ѱllx*0w"DX$ gQ3 io߂ZԾs/|:ܘV.mx8zUUUZ(Jwbvk9H)<䍵ACG*++gϢ'O4+U]]Yfرc~]]]裏GxoV/bÆ xkG[[RRR r/+&N{ غu+z)3ՅGTT_կ\`[oף :iii/~w pt?744gFrr2<>C$&&bZr8NݭBΝ;h UUk.:u ݥbbb"466B#''ӧObm dۇ6)%;zɓ>x ՅP̛7O;gUUEnn.N8Ũ@CC֬Y_nn. |CQQ<"""r>8cǎr!<<-q. Bhz' ڮ7"((V>>h4YƁcD]$\>бb46ڵT7Z9n,GۂW_q=)дt؝ M] ,阵l)rbLgذ vL+P8g+W2mPT*cᓨP A`aTbۏ (0Gbekw9s$Ygg'js?PgW(B_{❑;OQ&,V#]Nv3|p)vc{^9^垾(++` W_~UHLo_gWd5nZ,fxtZ^y?hY555_# G膩i,--EEEv;zք^QLɥڈ&r H)QQQ XVdddnxŊ{Ŏ;PWW8cʔ)0_?OO??8^xdeeAJ?شiqDGG/ qXl.]gy*6l؀*wNÊ+\?~?J<쳨ӂ;Wx饗*~a###?0f̘)%^xA3 kkkS*mۆ &`ݺux ?>bcc2tttj. ZuiiM)%ۇGbܹGqq16oތoQQQX!!!Xd  ^Gyy9vVfQQQtرcJJJ0w\̙3ݻ%%%Xhw~,.$W_}$t#:>Fc@H1pۿ۠4iYzGUs*!v=}]uBUUΞ=;@MM =;Pq$Z^.T1k٭HuԾعq;B^diX|lXM**뽛-^ܘfN=QyX< 2EpvG3<'L}(}$,lODܳI&(p˧M~V^p+nTT9Tl@s<~d8m$>{@2A7oތ'N`_gL>yn9hoo޻z:NƆc{n9Ւq!@i+WmX r`m!~?-jh26ժCʼnRtƹ`OpIV$>q ::wq;>sBQ2ptP +Ns@ !6'RPIz755@z=n7V+hkkCZZbbb:d*44gT(\^eeex܌?<N̙3qqxg؈oXn?9ã>{< vލu!**js=e?7>N?>֬Yłz >(z-X,%lem3Ν'x$-- nhh,^Z ~\\|Ajhs&c0n0a233a0p|۵򭯯jٳguuuZgbڹ$-Ia455 A,,,Dcc#n]\\*9sn-9ƈGll,.mdddhU%%[3န66mɼX2o]iӦ _~%VX] Ϟ=/R 2 g7aH2j,Ǿc$,'AoAA ɉF#=H ꏿ-YZ@cxR$nBؼapߑ{Z2Ґx[3+DIIqz0ل`-Dkd"f%@/%tXSq.3x(//Ggg'fΜ*nG ̜9~-P]] ۍ~O?ϼ{GFFG3 q)I|=&a!m}1sL8p1l6<O#66зGs|)9Gs[{;F8/j4z7lzFP)))(,,@CC,XӧOb s z444`֭jjj{4߿ظq#V^=7e&DN_ޯp .̕`D[1?w[V d!%Xuu h‘MQ@1 aDLJz@ژBHH f j[hisL L|I㴑 +*MxnF̊c?ZP ?H5uHp60v i(8ΞEXZ8?5v—_~x}&|d2 ZĞ={ࡩ MMMHOOv9 MC ,'?#5Z,++dI\!`4}fhDPPN>ݗ@GG)))p:(**hDpp0RSSQ\\"<{uup15k,DEE!22gm6c89YAHHzorfm@M &ছnBff& r EQPUUE\]]aOBBF#JJJpIAQm<z׽ >?mWp|p8ꫯ|n0=>):ƈʈz=P@`PX\7nAM]wl^GQi[甔^?~^YYYXz5f`@DЎvt1UPc7*p5U Q9/ I1FXOX"Tq~t[ Xn£_ǝ۫qjxK1Zb]bocqӋccq=98-SVupN?.H}Rf50edl+GSkcˊ,aatHKM``ׅوζԕBw=N:3gcIA '#jsXp bMHdfeўzL&=Z q„o[=HSՊEa۶m(((@||vP&$$111PgϞŋGVW_n1Xf ?d2!==| N>'|B㦛n›o EQ0sL8455oF[[wu_w6n܈nmGDD`ٲexa2;wܜO>Avv6P{n2fx^z !!!X`v鯥emr\xבP>]]]>%((&MÇ!@ll,\.:::0ydH)q!d2 yyy CppnkƍqAkQg e|>ѨUgѺ2nbXa3 KPXR}l4l2]իqa[kc7b&D#$ɃGЦDaf’9Slؐ)6yȎCjE3Sb`ph1ME+Œ6|w#6yȌAjCWh:Cy,qt;01>M ?1Nآ܈8щ]x)g{vFWK &&L@{vxh݃pH[D}EZ۫:n)Yv7{^ 9˃.LwqQ4`0 jő#0!t !b5-- RJر;v@\\<Μ9 tuuK, xnv'O~W_E{{;RRR^{,>(G_F_z5~m]wݥe X|\E/~ ^KQX dK|҂,^xk3f@gg)=m4m˅Hp 늢 ++ vBFFi#񠱱6lywD (,,INj-`@nnH@(tfꫯF\\ڜ9sc \-$$dmnۜN'<=.""W_}V?w\ |;qcX,(,,ġC( RSS1i$H)؈ÇkwLJJ¼yܮM 1{l"%%?s@^ {bwa8Y6$&bB\ fd x8uꔟ |}Ǧc͋0a’pc7sk|W!=3ٸ~I;n.ozKbÌCwGF$,^-;6|O H_4&hϑVV3Ӓjϟo?/Hpv  n W,uhlstQn;Fz|{Q"H*$(8z( DtTv9 CrBmkkCAAN:՜#)) YYY#C]w?1^.wsrq3߿EEEXv5b둕3fhO<gφ~D,X`Loۅr`Μ9Z }?~ |[|o[{^hhh@EEt>ڂӧ`Zj[z=6o߇UKxP>^E;1zm^(uYASq2N>رc;GcѢZd3ޅ:$+; ۷ns(>Z[04T6@萘1݄z1qQt}GD)>AfV&NATH9g'ZNLJh96 8s%j7ׯ_Պu ߴiEAtt4Z[[k!::[: b-gx<(--Err2)%jkkQSS!G'_.>Dt]E/ܽJs_,NQlHI I3vn%;}:!!! j+C‚XǺ1sJF$'Ġ N HMM>\(,= 0`mrgAyy9Ng}v}e.UUő#Gems⩧bX˹466m.WBd˖-ԩS4|}hnnFtt4VZ϶&""try0_ #+Cw#ol” R`N>扈x͛|':yE5ueH?&. @/tA@ ; rt9B {R*Zpf_^Uv'fdObODDDW:X,C.fXP_"#W)0xmD4 Jg03{"*DӉ)iIK)qD9jQ)eAb Bf!ߓ5vdϑɨ1 $$DoD6:LF,s&tn}8|:X83FG%""" ThX8^At0ЀB-= z̙6%'++/HKOpvvg(`DDDDDD: E$&0 pyR @ ~ 36,=""""""1UKH} ]y|K"v7ڿQ_[ 0Zf?BvQz?c]*np;hM&tuug*n"2:"E}KHH 7] 'K U @ M&bbҒhAdtL^Bߛ <$"""""">kOM!-c2:tt8"WM]TW"5}"Ix ;OJDDDDDDtyiokCtT̀n{Pt:~]^<7Lfϴzl 466L7Rja/ٯ """"""ˁ'ߟ ͆}$^ _ LHL]jسw/<vZ'YDDDDDDD|PjPg=%XODDDDDDtN1T> `?Ѹ;o>RVZcGNPdfMErJ갟=?z"""""""n7ڲ --ə4fdY)ٍ%%Xa@_PYDDDDDDDW_l](n HKOö[}W{S|^a?%rڊUEB緔GeW!%r,""""""Kg΂Np_PUۃəSP_y:~7@DDDDDDD˅Ĥ$HU [JHU )1m>d@_@֟].UJ>' j7X~@DDDDDDtԋI@tG) ާ?w?'hPU\?p ,%3ڿo̮$2V.DDDDDDDߢ7P_ w_?i𿉈WWKRJ-C*?@DDDDDDD7Br@b הDDDDDDD0)wR@˞Ob%袐/}CɞĐYDDDDDDDq^]z t!D)EIDDDDDDt eO;M `63@DDDDDDt9߿߻_z.O """"""=5O}K 0@DDDDDD4n """"""$DDDDDDD~3@DDDDDD4 """"""73@DDDDDD4n &_.DDDDDDDW4e`v@MDDDDDDDc4W%ˍhLa""""""+ 4fDDDDDDDc7~I0@DDDDDD46 b -8X + .DDDDDDDD@X   """"""k??'dh~ @o}?[}J3?#&eOA?%5dhL>- """"""|}m DDDDDDD4 _« `ODDDDDD4xw DDDDDDD) NMDDDDDDD4hcv`W""""""Gj"]/H""""""qG?-"""""" DDDDDDDW@@DxJј#[x`?տN_V+SDDDDDDD4v ~""""""qAO( ƑAB|%CDDDDDD43b47.1$v """"""O~)}LBzG2@DDDDDD4OdhMt'ODDDDDD4^ODDDDDD4xE޿{ Ѹ{$D_+1Z/e$C=AYODDDDDD4v ˞nޠ""""""wO;MDDDDDDDcM GX ~Z 7@7G;g?&fߊ~CDDDDDDDc/)DDDDDDD`h_xпdh\CM|w ODDDDDD4& V/dw.DDDDDDD〿:} """"""`LL7'%$@DDDDDD4˾iZ@DDDDDDDc0^1`') [3e#laN d3tg)z\P;(ۃ潯(˅. ^dz -! w< OpBuȊV,iUd`puFTPx3*snG[1]b=ڛTdOD#q#Q\?IKV j2""GfvĪ Fyp=w/B"Ob`^@]M9'^;PbODD[ں.6`>P~Q(~]d߿Ob@U8|%M"":=@~@Y}x+x?bѥ!7ڿD4ʬan2heBDDW@~U}.rߣ1Y@D4ڒowGQ.,#]Yڻ:@zbq,"H6V/D4l9PCq=%"+SS`Zu)&d$O&h^C+(kLh bߏ>!z0@DΘ8 ] &ea1cEkL^sL6(PAi '@{t"MnRDDD*s#K5.0P+ Qw"  IDATk xNDf;.%GK $M$i %<}L˃1],F!p_OQWYىf(,+ۤkX=onyݾ҈&θOߪ~9ʀ-V=;YiՉ lN*>? uq{&߅;՛f&0g^=hvՍ*UqZE 7?|.{׵%COR0'ZA 7-S*k|YƊ9QYX71! MD28F;p^`aM>N *L *LI:1ZO`q-)xna^ QtqF\+ ֌ړ)َޥFE  vǗűng1`\~iLOcz_wnn*9#]^{4  %ta6 ̦CV@'xcEfs O 2&(# vMs(@DUa &t8y'Fc/ہ{&u/Z " +*/̏ ܴ؈0 1Ɉ'g&'bgU?O@Z lriTO~yPzVQgǭKTW<?}nXȈ bǺ!Q>7H ʾ/{2ޮj1(? s hoHnB-=˄YKgmK\e|\Ј$wV}iH'4P*^c1Y9=GOB Q""\h0 dp݁':( ̰cRƠD~ZY9e }NHl*5aNG{no[:LמUӄZqWj7!-63RmbKFʾ3?e4teON<цg;QF0[HK 60Jl rddwQ_wazl*@0`|?Q0gvGr|bC T@A)V'@lڌC, f[[ɀR̜a,2'&Ȱ zD/7#ۈTW"ƅ6 2‚ى Wj7#j`sa Z~娴,rU*اLŁo+QЬ`5!3 C %Ze߇x"Ռgc#0=9WIa'M '`ǭ'xD7NJ|Ĭ(|,N ȰuCEHXXؖ.W`-mNZ[#[DÁ/cBqg{;Р~2R$y7י1pﻃ1lkH}r1* )vX ڻnSGJOW ='&coYz9# QgǗۆf|CV#_#qkEU;Ίk=+"KG: 'أ[ILMM1ԨQchD -l{ٳXtwy?ys|g|>2tL',to)|Ȫ'@F?5]TFRLDL(a7 Sӿ3N!4wi mRݼp0#s>$gv8}s o[Oe8i6^z'׿[E}F.c\էyĜYʁ&&Ӕ n PH8Xkwc40R1hjehS9@wE eB{KɫO`D<4 *QKÆX"5ѺS}w#3Iu56 4@tGo;D]gw1`cm)=hQIKeIgIKIM~2-vGF;NaIu2ɰT8 ͆d{T6H$iSU+p LOKS}4/納N cůxH;Lr@0ty{̍}7ݿ?D0g.14¦fsh). RÁyR"S,֯m+,|ZX- :Qx㩮dSNr$w?+FW ޟpUnRZƾ9'wv5X?p唧 `LmJk .%!CD*~8U7Rjx>D|ad6mp4!ߜ'#|8mHOضFc]N~"rI\Q>.x33m:d$Xo~@=TFVˬ1afui ^-%A^cr{np = =d@Uycu VMF'gL'Ý~ 6 =lS .A;@"q;c1fyk,v0:"PÛ$+ۤ9n+dnn2pZz> N/de~fs-x|\@Uo29!^n;~ SIcyhJtr.G~~{lFH v^`_ mA~5CrM^{xX7Chs+(KfԀ}"癆ac7lG%{Fg+j2v7gbLOw1)*yڟ7/b'Sp]ߎ8|CAww[yI~ 8>뗈3 F-DC`CYtqѣPYq 0lc[mF؍m6پkr،cDܴRkW\<g_G^;i3._߷Q`7Ei{)%wBAlĻ`g|ma=.nS}gP45Ĩj|`#MFg304m'–ysX<5$nn nSUgMILu3}o;~1qJd{!2=͌sIAnyfnwx^` Wc2;ƾ tG{ו3҄~"r$:F$@D?K@Q8QOn*|ؾˁaw\ش ]j58WGMeGm _ \$f,vԳq_ 4RyƬVyypIwz^͟78˸D.:td06|<݇IZ+P00np̎}";Dž²[?ɠC,ƘDtpʌZga>ħ)<`Q; ? /%kEWg1M|((!7j2Y>;/8so%I,e|apQ\3āomriΊ~<^E)yj?˂ N\kOқ`l}gMq8EΞFo V嗈Vg;E"M ~dg;d~vMB|8L8ն8Tͫ;,.ܗwiemq&9\ML\^)idgg3(w 9)DWo&Ά:z9b\$fe?ɋwe;aq}nG}AvDϜ՟_u8px9NF 'ƀȿ6%m7$kr%u!mkCyϢAޖnۥEǠ<Įp2.1*ClAvG3IV1sN-6+9%'1"^nz N_>uS"^S rO98|i[Vp{WȐ$c]Ig$Fgz|m*+W6;ļ<\_N<*׭}lՆT*9\Q8XUA#[O46 sp\f>>j/9g4+o/ކ58_okN. ee!6X쫴)4ؐo2qQ1UZK~"ٶn^/fo Q_SXUr䔴2ڭ?Pֱ=AnqVpF;gq>쭱I>3Ii\­VFn?/f7|?0I ݉:M2ܝr7by)LΌU5耐bUI=ogU8[U=. u\6Oؠi0_dK׿;@M9jlTrbw}*BlLFYA l|7M0wwESNʬ8<1Y? iw)}|?ޗfG9 x: ֺg@AxLh݂|>lhu<*cF:Ox>1:cŹ;k[ ksIr<6Z;;]IZfߖSSHut厛?ԙAzgp>&GN ُCgmMaB 2;٤u(eЉ\z<)VRIZ/}d1߰is=T\!MĚ7Ī2pF#lYnj>'c#Vj`gqlYc ^nvS6Y]^I޼.Gmt;L%_BJ 5yHߑXK9#2{Ŷ_~f ?(,?UwNe*p.r-YT/WRue$Dn~Bu><w\Z^vʻ,< cq~jWwq քx >hVwVEc#>~m*wY5tuMοwWRQ4_W#;~7׽[w~O?WvW&Rxkma3'AFQ^uu|Aah$9Q\vr"Nș&/d_Q?+_JYVbMfXfbV]cv6a-oK]A Y>1nR" 6SXycU9+L ^Q*A&rqlX6½gmqvc_ sg{`=[װr{($1Cmůqi#\4* &%kXbZZNg:vck4TYѵUrRZ[b7N^HA9k$vs}V{.:!N@]E-آRֆRyMMzPwJl,ukw3fF&2!C7@v-oAv}vu+PGeEU5u5DLǍ/>Dytv2ʪi+pǑLzZ)ܱV;Iz姲./dzC |2*<7l멪6}l.'nxpGwJvm+*g/9Ï#i4eسu~1,w`>~3f.^q*JJʩoOrr*ޘ|v9م o9sss۵:`7u "'?7t+`۶)``0H0$ `Iɼҋt8 a븹H'TbH͈#5'FӠAc\=oחӷŞw4$?vS"n2' y8,%9K%ujq#_;aãN/#ʶ8|Cn`(qpEbzvY6m)eiuzHLv;#'v&II:yߕayؘ2'9'vyo}~WAI\&܆H߾}A汹~ȡtO%"an=CuY!WT6Iw0c6M2 i 1uo6;c}Q+x}MS`20S*9FN;I[ DĎ;R(W IDATNd$i@"{zmeϽ.h( ץ"r ]`[ull7""w;+.q:baC3;6#1jycH@y'mf2 ˁ""}=>;$ڽPfTDp,HhC`B UaD&x9.فbQRV},X[j)H>4K-=%'y|q8MB "y#64gnr@D+]5';5pꯥGb|߸dW[8hhAoZtORLcǠhw3:}]9de+0<5"*GСG]Ez& >yF!"=;ݽa߿,ca:?* ) m"r #ryEu""r,F oܣt."G`3K mvPI9tR>SyH) @DP+} φ`cEDXMLI)o*I'@DW[I92M`֝ͺ۶BAYӉa|e EcE(+|@ǝ1۶Ãvcu04AmxDGV ݔHmaXr#qasEDW2 pTӰs?M; *q"Gsv>Hٷm/ݭADDDDDDo訁"""""""}ȱV@DDDDDD&J!uhNI\"""""""&7&?fjEDDDDDDm """"""ҷ6`h -h ~)mWQo+k.a:,$DDD [a:R1IKx%쯷UL T[Fiq%Ơ7\la3#_İ{iEl̙_䈉DťCg^CZSnl#~(Fye w"N!{jJB:hED c+ ""ݯ[`K'lʥ|̙\r~xg'qtM٪WxbB>zyV;"':H9"46͛( ,N:)/^`iAάkgs-YQA-S.lזs6{(g3nPڽ6l!{6bctt{w'koJ hU/sK^ŬYLΊE( ""_C \VˢѷqhjlA9s alz-EpYzXv()S綳Z/( 82frM)##Āso_0j4Ffz1eX>^v ܙ8uD "`5h D7\9fOd``^.^BYO5pb٧0~p^Po=!V]vO[O##֢sQmxM`i3( aS[dw 짼Uƿ`E3qC7ȏmC <4ߤѤZB~0&q{-ذzNIrC7k`UgFyL&[ugMKU輌@O( 2K'у/T ÜH&*پs14Ɇ arݥ1w/vRa\p]&^fuY`v;$"BFG!H4 (L|j7N0"m9\z%\XmQlti ix*lR*j8Sr8415 ;i4>7]̨x +t3 ,zkFAɸmVZ^{r[D}w\zpmWLn&ikX5qܤS}xE Gplܫ',|Of|cߺ͕jdK)dR}b&/J V&d28Mk=쩌/˽S9!':rf1fTS:ƢxOyQDD(܆u0TF""͗j,2Iwb?m<˙"ٝ@-g3kq{7@[-v QbD{Wn'c0rVPVL(Fԫbaux:j>]I73kܛ`vm۹wFw.v|dgbQaT&:&y]%,Ya/dd A=TFFY|vFԻj(1ƈ5.TF|* "+d':0t(_ĖL"Pľr~Ŝvaj]Xށ̺|67VQ۟ W@CBBelٓ@M;mMx3!a7{j; Z/Ojeh~!JW338 ʌP°8 XIY]uV}%@;WSpu7CihoSs%kG0| y0R(ʗ>œc9W;8w'_x[XH^@?3ki!qppsx0X} 8|Sݳ`r %bV!l]\'W&Gʗx_C >uݶ$ to7ė~#'Y\Ɨ+u1ÀYrp?^'yVVoCxӲ#ÍZ'G~J6/͋'Ƅ?3Mpt#| l| ! $d1(L` qV}ZƤ+`cء:6aY#/ΠJwX""1U""rYSP~kmB@1d#.L#)~m qԉLɶZJvQ:x+,:N\&j#[8IuC;"˼D|V sɰ!@p ǧBŊ=i|euq؜osm>M2ǜES,o݇~Y|iz9oKC]8Ɨ7Spٗr)޲ŕqd0g=[vwd̥DZgHJOocҊ ֽ$lV ,\I`G?`M[NÓ7?)F\.'&ocʘݹ&qcK^gNo?>7_dH9bn:!;fc=z ^&pj 5 ""_,%DDyyElUog۫ۘO 6u;ck5ιd:~~ȺVMmm,K?k?P|sطu+X\x]D=XGLV˫./4Ν}wv`iX쾘:Z"Ubj❬X;)Τ2#41j׹.X ϔ1iL9w<)=Z 4H9Qo떱V زKnuOjg9.$o]|:5!PEtrzwOl_ """00Ie[M m!T$""""""9ɏ~ 7J0Ķ-,+P0H0$ mĤd^yE^)ai80 Sc=M۔sJ]vī9`5URhD@DDDDDDDzvD: 4/"""""""GSoE44XX`7&,;<"""""""E5gm0pͿö1[u 6"""""""}ۍiU9"PDDDDDD/1c/""""""+ """"""'- Tu3 L,V~ho&3Vcj """"""C'nJ?fY7>@H_g45DDDDDDDzzl"""""""[ٴߺT񈈈}J*7^o3Q@DDDDDD/k>XXH_T[[C($ c&l[+""""""ғtKx0h"""""""ScawvSHr]謀G%DDDDDDDz`4l3]Hy#4yfBvK"6y3W"@DDDDDD& ;*- H/7l1k@DDDDDDc@AnDH/5!#)1DDDDDDDH:]Mso @DDDDDDwaPH #[vEDDDDDDO-cTHg"""""""}MTIL"""""""ҋĨ7[r"""""""43!3 """""""~2+WHbh( """"""&fR&0;+ """"""vH+74̦HDDDDDDic47W7g3UHBMYY AD/C4ϬL M"""""""}A@"""""""KB0fJ#*@DDDDDD#FoJ( vjm17 0)"""""""=t;<qLjҷ"""""""MǍMHIt)`"""""""}"""""""}=uS~{#( """"""GJp%7"HQ (""""""rLP@DDDDDDO[ ?rT FDDzc~slwoQKYL`]q%OĘPJR'^^ǎY< @cA]DDMv;ӕ ax9#5g$SrF2*>/6'DDD*NP ?}Ώl R@>?x V5; B*Lۮh Y]j3!~YL"ޠcADDn;" h5Vc5qw>Z5n7$i̗8kH"6/7syy;/Mwuɭ\>k(IF8JB ~ _V{Y-}y>oZDN|! g3sU`͜\r7sIsPc<됷s1$qywXYO?ןXx?GvvJ1Èh0sVNK Oẕla)&92k}Y:;$}V ?Uy܌rަr> Nę7i ο?M;˕xw C9ο2hr m8'=<b?  V$3yYvR`uCe*""DŽȁSDDGK=~C<e7m *>痜3}͟Y hGi8邟:<}WbA Ϸ:'3gq 3] 3Sc^l\غi=\s<1MWx;zEN~S2d9\,?wNj(xkNeԩLz"{M=j?ɿoX*S9f 3;/5+:wvc@h##ˏgܱT""r,P37 =y%W1ƙMSH71cd&3UWʮGA!8Lz{lW+F 4iٶ(A v8޷-lzH2̍w\0~#+VvGYd>xrCMy\ȱp"""I* /!]tXv8o575۟w=ʂ:|3g 5-7rVw0q;z!C$*Jc'|7f4qף RҲA2c&o/7#=l ""5Sqˠ'xNg/fp5}i4WnuuX,f\<w/ڎL߾͂rΙ1c'2[ƙ\P~70WcnT{ IDAT)x1V""rL%bQj?. A\\寥kWCnVmyug0+.3L \|t.U+mw7o*8ce*""4=@DD ~Uop𙵔̒=[K.~Y%&wFO9F%DDDDDDDJIF1V)bm|SH[7+7Tl"""""""& Ž1^Iu-53;[h|H_|rGiPӧpDDDDz{޷M""7SDDDDz##:f*l@H;:?yEDDDϩMh^(""ìm-fo;ke'o/8!N'sfƟ_K{b3g/4ͷx{/K2Ok+}72k+dx8x`,#/c95*9W=yF׽$[/'D.'񗻹pOm:EDrDDD'rʥ獣jz>^?3ŌI|7O=x)[џ-fWC.)q+:9λؗ^ s7d6W\s'<KʭЯ=̜Orū<ʌdGzt{,sɹMNbwp=Q@m <;90$N㒛>MWĂRK4v C &yyyzrtǗf[898c#\qokY/ ?ኋgX/B7xgy/s˩_E>r7W?_/_ȐVcv2Wh (7b{^jvE<;;Xqil!."" ${y+[/㈸ >87, 7^s~sS\vك[swL&45hlj}wKƶ"۲!TMy]ܡ¶?ER$uP+fW1^cQiaj{s.+#u˙X++ʢ] cPYE=IDDh;ƿ>@DDz7m'|V }o>7|5}y?O_Zw.;k~9H*2C<0w%4]\sa5qXjO+3. \3U-䍍:DD$fN6я~p#K^;guusefB/-w |ˢ|҈`&x_o :8:y'_Lk+mY];z-Or._2MS鼃67N{f,}R~ 3@ϻ~Qzڿm ~潾;ofu9\r|9 .Hu|uW"&v8oo4Ts1;w.?p[/#a,g3)zM6TG\Xw\1w)Û7|o"#sh w.y.Rsw~F4hjn+^Ud?7p% 0漛O7o~o 7HWYqL^̐Z-_ $.c8^s'w!}tHHKWuR@DDaу͝;ѣGwrA Y_ÒXě{s+#ջ(Cp{yrIyO֚-|_sw, {z!3=#~x c*_=ĚVy,-~ۙgF#ǹcg<~xiG'AUCI 6>X[r Y.8.U:]]G=Q7py=K)\d~k&oݵr؉: udj_wMM.V-@X.93/BSxv9pZp{W=<}uvEā?qMڐ8o}_-^>gL]ŮZ|-`P%Նƕ9w|'Uw^,fZj`DdJVWneXquNJ V~b/[aƠQdPa!"rLgj< FfyU_{^Hh֐^*iqж;'BVfΈ~gܬS/'k^oY~EB4cZo\=yKt)ޗ5{09wޮ+͍:[4qkY=M/TiI-.}O&=TVVm\N:;&m:f.uz3v ]qeAtwݍ:%-G6M9-k ݬt= ֚^NM:ٚpa:}5YJ\yYOޓ ȻNF;Uv͝n>x IecҺ3t˥F.H3}_?1-]3u=F'CpJHZ5=qźoJjmv!IG'U#_Ud9rpo:(99OZ5w4]?PqE#j}u14>9x^ڴdiVJ۴5c5`UyVM2Egq$饗^Rsss ’%K8>TJR6t:-++R*R3TS֦5xPsםɷ)aJQ$ȑc92IEggg.?"ylk]w5駟N%}H@I9pc@ )Shw@0PGGG4~x&@}%ln@7AX0R& `Ih & @C%mʤ@$ͥL.*\or0 lݟ.i&@/0 z0 [g$)y@=1Y6 1U)-;z@m3%_V/%3/ @V?ĨmaB![pr\o< PLIm,=KjnnwޙP<gڴirhl @BD ݼ>ń&|L h 'p 9$H@ I w޹_YcGw~שzZШ]|tQ z}utPu]Հz~~,q~$G᧟C%VkuӥW&ӃmYp2͜nz=Q;S/HjKn%:gW{UF4gok]}{}utm޼ 3ҴOtqZ싚)IQԲ&Z[ʍѓup?ܬtڳz棎OףiV'B Ҭ1<]Z$?IN=_{~xMkmUʉ4"w'3:jV'uu'hGCדZue~9ڡi9;[WM\X_٪ֿ&K4':{5VS3^#!ԤߞK|RY-|q\u3nUݓyzUz69pj Z?hY3Cv7-I͝{ߖF춷6z<7՚+/z=9qCѯOx\^x.٥ ]qݧ?IO.Ry }:1]yBAnZhUGds.CK*ɦVhi{3I5D9ͷR_QWE l|Ziz?7.x-Gw;[_ݡ+Z0`[tkAnw[q,uA}mui:7j}Wsz_ J ~9"7y]1kZOlHs\4[kF +yId4d:=Բ_zv  @@- h~;jSS6hs}}C\?8Ӫ:Mחm)] ќ\̕m^~[1 kߧRc=.дL z4Ͳoܙ7֏OW#Mr[9B=p&M:5WxYuM:uC~Suܔ 2C!*wDFHYK^ڗK-'Pss6NVLǟg%NvPc˟_;铅V5ؑ슏\iS.i@\W txWh V+}?52Vm&{q}T/4Qs/"k[k?ݢӾ\B=gXgxZzeIzb=vq8q&NϹ\FpӏУ;@y괅tJNRn8Z}gtݝg՟U^2*oלH.SW?\|JkiH Lq9W>8{rז탴sSuXBjעv4L oR>E%Yy。ӧkwN:oi<rjz:>zV7fl'}gtڤ?ꘇ|_\iSi$ g5Mt拴<-mP%4$@zуhfi"q2vX:q2s>UG܃҄;>QGOakv>B} Ԃ:D%-xZVd*ynzl}PWjTT- ,Vq,ۡşAt$IR#%5)rkkJK>_*T\9öӮwҺ?_; Fy}=^?'GO?Vj>qM矣RO tʽ_j.քmV(5m~42o)=CrKJ3&*aku%-)@ݻ8F ]kyZ5T[=Q5fCZghA|wXk铏|i? 41y 5pI9w#ޢo;RW_7Yhkf릋Π_䉼?׃W=CS}6yqz4}EsiUYM5Ky^KkWqr]uhD{=Y۬~Y9iqw7ꔌ#o$4紀yQ_Az4cCOAZP͜=S7ܽv/&_ܯ#,t.ߠ.N\zt?VVܠ _CGԱzjEW6Vzե/^#NS_g0%RޫNZqqQy2:yHyZ[ЁwtәjS^ց翨?lm =#lgֵW'/!Nq?J=^Wxxn䋴Gҗ?[NZ7k8loV?kե6֙0|^PjuԖ%Kp}ƩQJdmZtZVRW*T*TgJTMk𐡺;uɷ+a%}uQwr= $h0?3 $`-Nܢc]]]`ZLXuƍΪnggƏAIƷ뮻r"N67^4`4L+M0 1tw@&ޙV:]],F~yhdFO7 d) 0 NH_FfHPLp2 pPLQF:<=h!D@F,@ǜIPg @1~ @vϴ[II+ߡd'\A,ӝ`@9_Chՠ"&V`Ā֛3ԕJ.'t%LB9*b`L&5bpMy itnO65z-lJ$zիܬTJ|y2Ec&ZR! Cmj[֦ٳ>o5k:ܯFwI#1s pP#aÇwH>&`Zӽ Q?HJlo]0,X j@NS_ܢo]ImH:K(0 d7(O@$$))k2 PIImD.L)|f|NQo$п'l#PF;A?ꇑ`!R\=g6 7*E^NpO:b LwPSRHuuuQQoHǖ/_iUڋ38w?{.R:ƦZ|Y&N_p@ Xo$@Z-\@C*IzWn |KSZ:;|R| 7͛8?sʑQW@0h6ijΜٚ,ٴUSf 6\cA{U:ـߺK@M:l^:aPs#zPk `?u&(Z ,٘?idd]/7X5fW蟟O$@;/[jØ1c4iDO~E6&l{S@_$/`BqvC~HJ6*mۜDBWҀ-I? 86U[ / 4X |Y7emKoWto ݽsV~#@oJB҂s5dȐ\П8`9 7r( 2XoN-0 եO>hQrg~^Vp/`2?l6fK% s3gV^t:5Ws8F#Fq\qdAyX6}$pRK,ї鳙X)ܤAjkAg7J+*mViuel++پRzD{)J3؂Qr7=Or AGl|Qq'rd]W?`MEG)ײ5!g? +PEJ}&ؔSTĶQܢkU cbq{k60ec^T fKaVu 9 D.+|қGcsݸCzt~vrq#8292(}3+G&Y#krg>tv (kt5ݽʽfzj(mѩļNQ &Jo#wDZpuw/Gq]aJިUE^F:lOF2ɔu.R/Xy-S63-|*^Z⒴Wk=%>|Ɲ0E3 YLu$S7[#-)+f"~Z8L='/nS*:JfL`-Hr7JQJ$^7 x|X~IrLr'(+~4&vB (ףܡg$'c?Sa22>dR@ (׼Tȇis5S#IE) e[Í͇VCk/J*+պ\*.L S_=UNk\XzJWLL@фu LaCJ~ dò)6D(,Zrsڂ?mA\á!w n"xIK0} `L̆ ?|21O"vQhŮ;[W{ ٬g-[ؔ?r g2_3f 5Y_ƘtU)cMx&̔^+Tf ›z:Q`JAat7{;<[@U:;jsfZMZ_iHJ22jqZJ4lZNLW*' 7m*텓8ݣ}܇)ưn^aqr6ֿNomL[:mp 0|dg;>ot31&<& wW!e x Bl˲=r #N<n`}C6[V)Sj׉ڏ4 PE_)h,o8DGmvr18֗R.dow{2J&͹ήR>(yGlǎYĄ9~"_[Mc/>ܽͮhVlm3yUYf{*01Y0_u6(e8PU[ezAz˶v_;n=bޯ4{-Ɣn,\(`BB smlxܘMPF- LlWDgL3$mvoؖ(z&]0ӒD5o.TL̟YЕn9|g%epU,G-^jAa|ʕɍrA*c*ڗZ Rz#RbD67䢆(]2"KH) #ף)0"r6 prCr/ 2E v=SΏL-؂A`?fݏ;[}Ͷ|t+Y'fݴ:/t.,T-*N#NN9)qh4^rNH @>%}[[:pܹr+ ߸z{OTXA`,ɗ<>Ũ9E-k]OX[E=wiwP-؇>rBSD/*5[a^BFMrG#o}JR!4_ H&nk*/&[t1M^;⽭Ž=豸eo)#7L)[0U؂?njA ل)tF4bܫ(,!V՝ @dUqzk~猷A;pdwk+!$۟5ٙ!5G$cdU?e^6sClHʏ*K3nj¦MURl=Lt3 "ՒL|M6`~D-y݉MqpBeKA"Sx:O_'AU5bw[\1} sl| sI_֠ އfQLsF8e|2]qӾcCr'訥0 L5R25J-7_ZÄ]"qu7uymJRⴐ^bT *`zxҁ~P[8v/ M $|UKn鷹Bڤ3u(G^) mSu`3c+-h N[a4drXG:[~qְyL}䚼;JQs27kbA\B&!>D:6ɶʞE&7$uWl&B((PjR4«mmR:[dE)}zvKe,gyeP{?2-[=ۿme5(#y|_tzxe E)dt7L^`96;cl柶ʶLumj|k"4J/;e?U: +#.jŏWC kz)QO;8##cmdDKD9b4~k)oyh jE mUAbaU'Ie&RE0^klijPQTqĚDf&aRr$wQ)cf?m떚/,/u!oR@/p@I94ӊUvP@FilݾtbimN h ykoy֧c}[FkFCrSF*˙dDuϧ'UD5BJE7|EA^KtYM2Jʭ W8PϗSClx͔m>o;h4-jc"V8SV{Muo;MWdmI{꙽dڇƋUc H,qБStrϐgZaiB]c?M@wEi@;E$ z9q6\+kpHlMq~d㔆.,+ˈU$ 侢+r zFqim|*W6l:԰;~P52D$_6UjR}TrqB3va6Ejgj\Ta(aq%l&f+,z2<$aS4@䈦JG*~ĠVLܡ%88rSEm,d8$Py[R. `3f\IZ3̱+-it[uQXET<"'BW>es$Ʃ dg4/9%ARQP&\\x"|zz:gtP_*ƒ "!˨=FMu]sT@>e]ܚ\PUu_nVZԲ+\AwUsuJ-)Ϸ5$$P9ԟQk^v(KS>e o9\kYjgqg[m rM'2[N ~% { *{kIENDB`onionshare-0.8.1/screenshots/appdata-server.png000066400000000000000000003375671263142265200217010ustar00rootroot00000000000000PNG  IHDRbKGD pHYs+tIME , IDATx}weUνB'BD(OGtAA3(1y8H 4B:TUWM;}νBY:a}^.^v<#ovտq7]!ij6qA Ro!5Inm} Fw]S{5ߝ@`nVw훒M53T~Nj>F1[}kbz|(5ߵD FT?W+QsTT+ 07GLD$ז gK{,cqd|=y$Yƾm M9?oй= *m}ۼRҕߤ-հ.( ױuSmv%K4nB?Qm"pkq'ZRWuۤh2cuЧ gZ9XTz j|aq$eN&,'ܸ{[W6Mym l_U젉spljII{nEfϫDiej )UZ|}2)i<R?F[PuhbUmGn0_Gwrw8l;ɈAxm^X*_#BKqRpBxYlܵrsN"6y`kvq%%" }78d[5BC ƍrNKHCYj>K=W#H Q,(R`R PՇr80BmX-'lc%ȓ1)m,*ȀB4!RŖrY,6khVw./edN2H'4Ix^JQdO/ ]V!ɓplE=5Jc:2éR&h ;ARN["6NDbAtpƦ l ,hJBr]$,v]:66SU×! KiwdnzK8@%#9pp' Y)&"H1bMGDз?$'$dJE$,aYX?|i3,ݜ ՍX j>9h4h_Srjw=$} læOAL|UfQ=q0i+LyB. KKg.k9Hx.UwzumSs[zS3̇d?[&ƮИ!D&fhzMPdo,j|@0???J$2^-|^61i7٫ԭ4z}B 9l]9U8``{9 8tjrG7$6c @ShjӃ['S>ƚm3SQg8wzߍ5}DG]U=.B-UPhqJ`ɰfJ.3!7}\fCѪSg'D1|p=']ŸLp™IOl e;_ g<{\gp<ȀᵿPiNm C7]6)GfcB5YH@NDb5Mb]ಛbϤ[B 2 B&-+=jw$u &']ZR B1&&=a*}Q'KV],k9;3¤RYK}RF._ ɾR-c˦Blaa}tTNBFҒ귦4i6knӧhu/$m Wl-|*bĀZPjD#TAjQb"5?D?̈NM'o-S+};2%qpCg4%_1Ur$pHVf =r\}8 Ig; xMb7ng-և oBɾ Q&k fyslڈb6@(t ZR jH0t1j{=FBo1HWW$`,HYpD%U @i7Kf-l[1A'cN`xj8B!Hd02iE2ӱՋλIsaIܦ { t ` Mٚ4V#A&6j<+Sc0 $Ms9_6A}L}hRֹI@3޿N&"9@3%O@9MYyH!'I1 T9̓E"#a4M' ԣ&9ҩTmDDء q>Ρj؀ifPFQt,yn ?+aD{Ec &>L(:="SOYԳUaNѓdeNsWX);T(1E3g!4\MmN[Q6sVH0c "XQԧL ` B R֙u56O6r։n ֨ԁh:Qw8T*gRWJuOf i]&{wL!" Ȼ :͗`1L&Ov l~cLnk= ˁj96*oBǪgb;5k+=,آ!֪kgSl H&6m3رm@dF K 3iVcE-˨󶤮lYaHWD+T%TKH5Q"G2S#2c $h0 QXv^*g'MQK\aJ_ҳEYLge)I5zLעA43}D t6]4mZu[k҂ٵ?8hH[:Z"OR =FL9xm{1 8cD$LvL -"z90#'G):&NV5V4i”'@DGnX?9KYf47@d12CÆܤPHtV2 Ej59;ivgrзhQu@svFa 8ojUYl:LVm-7,F,jjTa01g3;0mLH~݁c,j:g_(;JHL2dGF'ZW FN枴xrv" <yh#"XN.͋O*SSdb%D&2ZHHvJ5ׅ |'g54Dno6")ǍݤqM%KkbUMyb0*<rdOۙdI&E9BwwcC 0IPgT7(T=usigdF8aß}+LIAh˽8z9l&S(gz|R*#붞edR\d,Q3C=p*fIBY,xj)qf84)ԉjjC=}ysiES1q՞md c(ˈQcVo7z{@4-+L21Lj# &FM&;3I1Ṕ`XZH@-?޺chpǭZ._Us1Sx u6b~̚-kpp+W1gl#B,F~zQ*j$$GD( 62p"'ɖR܃O=r=wE3i؍;a9'<^H@&oނEj&8\a;PA@"9s!B@ ؆}mG5 I=H1#JKI;;vΪO!؝mĀ?Yw."IVF&2сy7=whjp#QX `hIM pXG"\W՟"xb sc߯cZY1?XD 8s8J%9c%Ǖ : [7 bm:8" Q].ā ?6t3)2*Q{Wغy+6oĖlD1Jl n[>Nwxx4F%#dfFcc5@uP oj7@ (M6dA~K ߪ~T El 5iYZ/,fGO1kկo{)? i5lAd}\1 + c$ˇ-&+0,v! hvPw 6\tJ "oЗC/;o^B33c_RJ,\.#ßkcehF}xɑj~7xzݸ?/o AT swowMFK=p[ވcZ PSI&/ŵPuk-r\3 j6sAkO7I@rcR!w=DVtY.ÖH Jox{X9A+hk"f3>XqV8AH\.6iqB;xmf=YX3l+DAFFpX@el0Va<:Zu [or:݃v_(keFi+J===Xd1l,ks1/"YVo ɠ WWPÅW߇Yg=ز'J(}(<ГПp7{9ǐC# b|dJ1rycbv;=k?N0_ga6={񏧊\? [G0>:JM]PA]܊q*պܹcԅãކ23\ f[-;L5P&֓{#E61j?9@$ 3;%i_ɴ $u ϱz4}TQS=?96q˄aV ^7۰{f]Y/`YĴ !LY lsF) Nr'@>[g?vLLP*t{d$s`=43{մԅ?>3p(a]w88nvOl-뤓^_\JmTV w kn} +攳q 7=?{tKsq[އYEsAJ_iE(}!o6D5/>+D(m^uwNؼYD.#q|؂__t>qп k.ÄRwkf\ GqϮwox]si)sZz#x?G!֍{ʛCĊ}?{\|<,ă{⦇p㏯O͞r63  '73֕s,'wY7z6$U3éWm G01d=y-,A=فt hOd`S*$DŽG:J– \HYhX}ONI؜_V>!5hwM*2im̖ ;gˠ_?I\.cyx|19G,\0~a=877GPB\흅RrT*[lٲEYVȿJxU°_UGw7 _>gaxJ]]t"c0^ȍj_<<ȫ9p>| ƷnF)4 X 콱?\q3QAY,Ęp{t&J WJ:o{ː)\U 2m։.S1 Mk=q>74`e&ߕxjꎪ2Ks.4X}=`kZ;Mõd)+ @hA@;aWmR38Da/aCXOL5,_&&ްґBh)[Ŗ)O] hԯ#jI2 D-=-pWG<1r2\u:ʹ(^s|cegoĢߋϜ'J՗p[]\ ~:\vϽt~dž/7@=lfj AaX/$쾨8ENUiKoF3掽|^ȁ[$T_YͬhC[{` Nr&^6w du_VG6c!S<#d&ֵ~F=pe%Nk\i#쾪wwO{#~gLRG kIFh;̌/).F 8۟jӘSx:s*rR܁p@\L2t5:]5{4?1hL6/}Ȏî\.ڑ2*ո#|<>ݱ/ cš㢿</.cϺf" 7" qlZ"r9gYрMeHyxvs_] ]Wp dӼAku{,vhE5QW?oǏ.E8]݃^q}l%w93 wxtU{7/;xfKj6_O 2!"e2 7U#Apʤ4MfB@I v PͳIp(Ghy¤&E\NY#Yzi ÅdWʛu( H ڹm,:/;hgS lj G{qtHh<8[poǁߖ,ҦI-:&Y*MA $V )dPY~ֲB$j}VN1z~|(/1o}N_ߋ.l+=ϻ(Īgo܄E'{@yy4gmþ,ŖCEm2Tth۪KvF<57`S׾8[r9Byxc<^1L7B(UBPnL~lрJ)4,&* _ ˉw_2ԭHԼ,dnU!J4@kȴ L!+gRum5e$C˕jcJRb# } ׅ4, @ %+w"ϊ ~|Z~UpJtXpw/ru6@]]y2L8i<؆[ף26 mR88ah[Fr(T˯ul[@`g [ b`YGn-gpVkY!ׅ[.&ě9q>k6p%g\6=׼ ߹$|䘹8wߊFx'~=A7-bxYp)6gNČ؅DH~BY*0\[̢dO$6'i#qmz94B&gI-u!6`,;Ǟ0ݍ|O,*a1PRWF 79|<{L( k׮{BDDc]==oYٔ,/Q) yؼ^?o~}{1bZ]$.r^gcY#5Uy\B(nu_;U?vqˣ돿w~rrr('^ҡXx!<<6lFs.ŏS}6V+zlsո@&Tem bjh5ݽ=$:ũi(98|u."ö-!ކf>mRPPB>B>\@gzYdLSylb M"hQe34}F &E`'` !H!4 c27! )(WIܵg4zr' InF 'aD} ޸dKfu/ϗczB^#ֹYkFτy2$Lv4 r֐U##g #^NhCb6]vεi/耝 vktc RtD*X6C V(+$${ l|鏾9fF'?s m{ːPI#<P`,#(_ IB li Z3 "'Ԉ!#dI&*5AEht-m]ډ*%ϵ ,kÌ]3p&ep"e*&hl| ?!bvr`3uf,}Z!$_ĹEF XHorY16ޣ X1ӓM!=]97`aP,z,(sJy`; 1.x=\dI&4 @ChTCt%#TR-Hf ?i}F- Ip%l~U{mm_Ȏ-lpBXd+LLdI۹Фs;MYX}YFlwE(a)ǕD=tB5y=5/C/I&oII~lulc3ɐMYGL2$*Vb(õZ%y'D]6(A2l/$*촞 "HΌ*6;$ / j@'$w'HYr.AjZ⎀ zɚ0Rg{f'=JC!|Za 2 Է82 !rl'Vz/) L2$ zZkFHC6޺0V-K-سVsBa2;-Z% 0_e;cEͿ'\}ΎP:nLTzɤ~ >&RaaN'>-Mi6_vhD(pl`̦LAl,*-ьL2$/ *;Vi,)7)ή%iY֠'QВZża7QCA"@OV_tܱ:i; 53ߤ̎fAA6l^ٮ SsbDP"-Ui-B;Bx#NIu=/gI&t 4{T~ՏfKZI|umI ӹHwYi@xpmHB^d )|aSj[>/tZ dbmnoF3w"QA+y+'B; \MC6xasɈOxbL2$L3# Ha&O~NJy j6RfE }眵pEuTWXBjG3->`,2Ԁ3ِwx#˩LF7y2X |rmxup@Fs#*TmY[(q t*SPLNTIͯLN׶ UEE-1L2$|)gS YP[ٸt{e!j&*njyWnFI=um7m$N$:m Aʝ2l}R9ce!`?%3pөXb=Bٲ2Vw)|D@%&.r[(߯,S坔;T)JR;nA&d2i$W(=Ucf3xd>cEḅ ,!f UҴ"‹jA!BY5ۃLj2!$'R)0dJe6o4p 0蝈дbo{SF`OuvTiS* ʘL|[ǵ=F\d6`B)8\YZGuL&2$#7pm[Uk(j;BTz!cwJ svD:GqD^5 Chr69-7b8O~n[̤ w ȔD+҇B|فd!8?;{k'+_a`84DaĶ3L2$8Ӛ_y^PҢa;v"x`,Mg0^ݩ!6l@|m맾8\[6/AYY6[lt4qg;S^&3u2sQ!J>gmݖXdI& <$1d3 ߬3>h1xlBuϵcTk&[#4AjDEE'x}k򆭀줬]HFGiKވi$2Z݃ݽt9"׮aNڽ+JN 91$]A=̚5 ccc qۋQT*l3#ctuuP(oƑG}L2dR9s @LOEAaa,l9Ig-nwB#)d }qۆIpZGbֺ?dgV0sIka\ٛTPqmad}߯'|2dzMiFa5ॕ쨤D&HAR-[P,QrQLL1{ls=XzușdI @ԫ~@FJuX)8iJcҫD#7PF6aϯ%Y 3p ^U)dzI|^:Al + 1}=*=--ĩ˻?ۢk7Sԩ`N|}gmP,EBb\q7v(QT0kV=PL2$1׮N IDATl]QlA׎,fdIL!ـH o I4Vܠp?) gk'c%rxm:Vvm >WVz\ѤLJ?*`w!Nڊdܱx74 dU#DQRR _ 3{` $Ll&eb@эQ9YtBR1zNqI6xCtZ yLk"5e ;6Df\'j)NԯMx:~څ`!G E#5]lvZ1se$8=D1͏lnCyhа0o<,_\Q!7ʩdJ\.< ?g6Wn ȶVӔx]~RTOȀZ~ٚZ1 8#k2Wo;ؒ,;6?3U {f1wbt5u\p>$\7aϮI(A8le_0 orD(>z=9^?Y zN-Ct: bxO<[bVG hO$Dk:t D_v.'I? Ywly;zb;dC"R5K}.2{6S7mӟ>L6j_l\RҦ:&A^%MTӺ\ey>kuMnTwKDr}Xr쾨lb]ٟwo{7>T~jt<vwƬښxWx ⭷oo8Y8[?2Ǣ~.;]w^{ %¿ k(??~b|3pygyOWFv7|GaQAx;n_Gļ\:q_kq+PoZ<`\]jd|ӜK·A^W;@Zu""t42Ik[40Tzi擀V!j䲆v!IhYڒ`g%e6A4>g?KC*LDHJJ=9C}*`lnJdx%孚u5QAl*Qm#׼ .#>ωeIa9N8m{@"ԇE\A ÷qS|8>%ȃ/3Mp>t;.{?z&h~y9E=#8 𮅏য়D%#'z`sr/Wi/tda)<>G 9{"ZtH,_N]W|>LJu'G5kؓ+< ^P=)<羨v.CE8mV-kиwq֚qcv[w >Spܚ5X_ac/ˎ1Okk4n8u/9Ɵig}3I9~;k 5t1١fv>׵٧)y77H+uـ==R|?||L.ԕtڸ>$e%ԉ^6@->yA%3(6&0jȐa+xr4Έ1!KWZtDGO°jW;نԁTR5`8(e5?}'n]]5 9.= #voڀK7͇/ k7ڻ8}ลn]uy7[?W_t$Tq̫?l9DBGqeo~w΅x*`//ťy.;Udѫ.'Nyz `wGq7߆9?x8c0l$1a s?v7]0v?"īVT#JOށ{{zJ̪}ƞqfTfa#VMή\sztx9.XwOpy{rԕEb+q=QYXxf&3ABu)RJCάR!+mfH TWHjn>@r6{:lk&W+ JGiy͎]$xՆ-CCgWJܨ%XHG\ l*b\56os2 f>:l'h)(cB6R5[>3R:P}7ѽP*دd8p6CAWkoǖwmOb8C@ا׫?rXrV VAksk8vEkp%5h<{¼Ƨ[pŏno <}9 ;h7=:|?];Of^;VZ&pߋ||C<缋pœͤcҹ:@a[KNG{뿎_l ڪ2CB\X @CY{a~Os.܌Ce&yp.|7dwe#V,\kȱ_] EthW_B k$\ o@5|{WAB_4cX&<+4Vq \91ة&0j& iw}m4.u[9l:€5u8"XC/JE &@>z_6a[Ygj{+W3)mX{F`z ]w`]y>z΢ia1;h.qxx4v_O\rD@K@qo߹aeXi }/Сq«z)o|4^uGȂLTwAAw֐AB&R;ڮ 0d~MO{)Ł KrcJY= ՜GE"Qj_5|-/;aHхZS1{Pwo4[$Z(A''z@Hd\ĕj+_ _W _z^ Jb%ogUKzC᡿<"x7/ǼB/QXIm[n9yGl$'/ao9vl cPqlea3<Ψxyq a K VUɞ<>gq1ZffL6L9SSnX'϶d1%"(x5zTM" TUkޘy!mSiq6Dh"& uaɗb ?Υ9&7; r,d$90Մ$܆ك;3%t(cpGy{wJz!؃>;6lhpz_.x?BoPچRsX4x'0n<}n=ñ-z N]Ċf׍53$q[QXlj(}B5cl ޺^\`C!mExf *R'ݿp1tggn I =7N1{=2aγ" ׆8.CwQ0.jSތG6W€`a/#eU05 7`^.:2֝.z9VsZX%p%Ҥ1#1AJ6$+M.Dʡ!f_-BI\vjʘy8[)^8S,5_V=)l^v?.1{#7*> Xlm%" pm0zb ԇP _FQe=أ_SV7W^,{;NX(~b|w=?s߀/m\b/k|S~Vl_|忟ngXǍ&F6cÝ G-.e}}wg47 j` =5DR2nU*pP"ۣWOiLQNߖdwߏ*D& &Eڮ~DiݳQsOEcl)>I30Q` $f0>chQ ]l (@>)o}3%y矅=hϳ׭E߹ зek]uC+??hCO-O~+KsW?SL K^x?w]-zy.Vj/{ۗ+0~7/>sqYA h>>=G?|3PX޼vs^ϟW5WWoR fKDh>}(}W8f>[]Zh^JcEtssz:3x"|7,=_yeE/g0tgqGXagOgShX?\\Wᘽd/3>%<~ax, ݢ|(RP7 )kZzke KiѤ)|:v(]ts1֮P!+ 8 D&+.ˍ2'O20*}U,/"W-X[sګ*Zz6#pX\IQvcfT#\u7]w܆#:zg?;0JU㔻 a@,uG`"2 zx_H-CMoxv|wΗ}zhM7\<$3v[I9P@&S#Ѽ#׮~Kı F,^<3ĉ1IR3aP6Z )鬘j$U"W Y>'kJgPv, 4 7 [Rb}I~݉E;N R!b%Hڎl6__E :n9$"y=鮃˄XVOEڌ)!>&m"Pݭ%9hR3)`ſoz9Fx 9ƈv9g}4>'>vAӰ pο(2PA)auYPpͶ߈ߴ1Eo |e߅|`&/>OMbjh7",0Ѧ3px+O_ӘtGH&$i':dmˉ~z:drVv@7=ļm_H;!8*:)r!Fhد6|4>~#$CaӪ@0L2$Ӵ#XY$])7 s%˒]dBJ5 i}8]ٌ4YJ̱ 8$7$7@th!d >{=z|uan_y!UfړߙW/}N2P7DٙdI&Yd NUNuDyH:tl:l`׸JN/;sqqzۈxYF:4$: gvLB A”`p$ 1wrMu6?`ppԚf^$&\ҡy)c̛7Oo̟??I&dҹ UBDzMxy1𳐭זZ;*0msS"J39L۳$"lDHȧ1u3s$BB2|%r3$!.mNBMSc-#kLva0e$L2i?xnνUfF,Pñ;Me\rBW"Y-ւWn#BxA~/nL9KbBDS?^uMD!'SV; d.fI&fFԡy4q9=#0hiں\pU`EJpN$G"oY7 }AHTDܖJn(n4vF&snezHjqjӤI-L2$L&l%YWۅ)$Basegm[.ቶ@sԦ+9H}QtF)N $qMHeFP IDATL~!aCϳ@L SI:F&dI&;L-T DzQaܞy-K'::lE3eْljD>j^} 2~mzHLre2IK,9r;"L!^dI&LIasjR洋oĆ_862T$ܦo{Os5q @ZmJeleC,WIcGMSXd4D^dɎ']\Q|$kLz2hB [F(ٵ5TI@+5i:l@_IFW#p?-絯d;s,v;1#՝ Q}GI!eq,ED`,Y$dɌi5ă*;o#HW2L _GLIbwр'!#cɹY#%ahqI3}="kkw&"r)F-X|1~yAoذ;ޮsߦ-Yrc  >@QB % !ؔ Sݍm!Mn%[]9U*[5ֽ{1לcY+Wb޼yϕV%K6\C1`mxUmOSNOIu*&1c'Jm'b%wn9RK2[O9K$]"t̾$TL9B+DA ,`?._%ܷaʕƃ>ݻw7_v\= "̙3V¬Y҃,Y)m E2R_$|Sco|Ba,kч7PU߅jm\RCK}gʣHM P '6WAD:G{1].WئKdYwy+̌9}G8ٳqG s1vcMgdzjU[ά6CUP bܛv- eȳ p'C#: ns) mm}ocdBVS;,&!THO!*+L'Ĵ; qIkj> 097^ucmzهa.t2:=78Q&QZ}&xé1w<:y6Lm\^NV)Is*fN"S۴>ٴ& t/~Ÿ|a2mnot\)3sv̍w~K p7උ^ݝ6}7NC+oyg{s<//XDzO/g/L ̘Tǎ!psJ lQ JU;_`N\tbܷiJ"(Y˲ {k'qpqES$R1_< R5 Νcm?Ǿg= 5'\:^5pSO!&801c186zL_xq%?_q4f9v/Mu|KomWo{}Os^Ya5݁GK+<0~ p ͵up ?r5 @?{?Z }k> +> 5; 4%?5_t2‘/+o)N!$K֩;9`.+mb? <Oş]z>ιX{FvoO˟{āsЛ? :>sAP˟ŭ+0;ȟ6^a8QēNY>|{ 8P%߿aN*HɠTZJۛoKໝ|=㪟s ,96 2]&hr)lRP-Lm dɒOdejK3#t 0z507BaA|B'JAJ'@UCy7noo~a)/›/W}+Va5G jO\Yl؆_~}Swb5VX`=9'W` `>񪳖czm aaKm5#bRt²Fd֏o{X>(6غwvGy'x'cSǮͻ@o}|ęxql61u1#Oa6sFd3w { J6B3JsgԂ$sݳ? %n)T-vz/kr6"VDH,eGkXIoCVٌŶDaß,Yez񔙡?7~_ P=j5PmTG>QT ¿)w/Y Q܌3qs1wB?wo~-`8'>v9n=;>QOkx'6j nA~<_ ܰ#}s18 {&>Ł[_{)sɗ 魛lz3 oD"%kc>:!6钐F.v7A$n+:fNCv|K=}O;A`|~qc>e5eKb\wCv 0 Ïyplw~` UKݛsA hNy勱+?|re`ctܑYX0vXcUcN±s5 8'O6&į6KyKUO$lcn`_=Erq*4I whS_E͜oR;)kEY(nۦf6|d7껷{+j;Bm&Է=|&件  A:(A\g``(`nAonhuYÏ>ϷA{\{/2ng~kndIJcKٸOjX|؁(rtE⬕ 0j;yu/Qblh~6,;fb04oUUč?z+^r8¼A`dp}a01T,Զ``!K h5/hU&@\I]_ZT᢯z,y.A/=in8r& "^ZyDXOy6p^.WB !2~o=0έP#sI[+KyJiI5%Nd6]#'F7xfX8 ZA:PAO=j9PoP=G^g_T<3VU=w{xp!xb?|_G`q lKWn\y3 ˏAc]x"ǁaՏŻoÝOLԃ#`*slW>:\n +s0/gTC밶]??۟w_=`e^| y;oox7 @>ƽdp~}.x~2c>;w`,72knm;3ނ_z8wbӝXk1N=viO6M^nleGkXDVbb 6Q'+l: */1=c+?3H}("#VB|xǷ~졅UJC8߇W/ n.>qԗkWuسp'7t| ã5^#_ޭM0[ۉ}m` VS^Q`p-^ \vX*ly|1=Bt΁?){Tnt{W\ش _$[u}vV$%SBb][M&2VlR 즋- k x)[s [`ܡenV> n|QgF93`䜣Fs|E˝߂g{ٺƛ0y'FҟDvm$"j@3$:3肗ሷ}t W98unboG^f/~h JU ?ʼn'KWF2e}G>2"!CF]; a w)̜H'*  }{}n{::}ۻzTe3`2mCzuYr#Kԍ|i]u\$4ˆKC" 1* ZR2pR>s9+*A@kwu3O"2{ &4x16n}Mkjqg74O:oh !Q W/>8dzP}7t* qDK 1 sIawZ}W1a>nCҳUOuLpr.j ; ziL J7%MI)ɩ4V&9 k&l|7=5qb|d4: YQA͢~EAy_ @y3Q CX,-<ozq;sdW8{t+ƕ2Cx?ǀU6:]@_Z'n~l<fRE8C^(gYz;:h(Zl_x]V2fZ{n$%"5ܒ<=k˝Bae8WĔ܄TCތަxxOOPFGTS7 nnIhph2,>xcBTA1]FZ"tq]:1!wXc؊:o/dlίRهY>ܫ#}Y:Qi/9v4%m>zsylX9 52`5cJ8lU v4zȋ-5`G/``L`fvW2b"kak܍aJ=ZX]#`s`4s *@j@sx󎃀(,Y^"V*hM.`r@?;=||TvW C4ߪp{> FW)T@U g$xFWD{XBDKVebpauF#1T* Lx;ypBxWk C:6dp.V7'#6χXf}uB˿CyΫPIkuݢg.2%~XBjg\{>qyϣ@bl֊}0H,ٴ0׼DQ8WK?.iyNv)se%a;7*D o97%|V&&ppdO"?:W`a b"!ΡW d1+orSI 2[&|҂Sﱁ,^8dɒ_RmU :贽e !HU45 (KWUmvF܎W{3/$;Z.%13_3.p:$rV qYwAAqu Շ%G:Bv`XpM-(I $"P}uX(ܥk2+R|*$)<>=2W_u7EHȉqrrK Kרz0|+p0',Yd]6 +Wc˹R5:|y\ߘy,Ppq4ȯh EN FPg)5~EʾWE8đ14D^1hSޏTY5 d @sV~v} t"Xut"@ dɒ%km2 M Y 1'Ljy0;X і MUBnz83T{'%_:wG `#1)P#*ɽ51Qe/hFM)i$MLV& `Q[ML.vd̠\^B EVTejq1Gї&R zr~G$c5½ < .U?0Ƈa޳B- % kdɒ%놻$&. iTWW1W !Tq`Xu}t;Jčk X2E7kd qu_uIXJ($Ʌ#g8Ůu˨b^[d%{)TR |-js`a6Fܯ [D.Sݗv:6yIK)yb"g!ɒ%K /Z|cB wWYOM`bPI uuCX1K*Jr}zm.Fξ=gdG uOd"V"TIB&FqafB+f臑dh iPL;|!AYo}? `$PP5$=R6dV|Y@Y grɒ%K, :s)[xT񩦕>);J.b8f:2:Go~<%%Z&Ѱ,;¢NcΚ!Dp3=[08 L VWc0bR)vܹ,%S+=DAE/94(խm" nhg]f ~Gnq9')?Yd:5,GLL.SҙQ;Zl%%_yF?jd\]Z>-O~%?s`'_ym)6#YTaq1΢'6םiƌcȩە􂬄1X .x)3*.4=ܺ}cbsH.^K@Irdɒ%K1 snxyC _sy1ޙ{V325b [Rhf`{A`qvb^"sWQ̆//Y*ʬD-2\fIug;˄f82xXU+P:sVh\3 %ς<(;%ꄴv2+Y[ jC/:#7!Ɏ'(ɩݷ0  ihK+g>;)Ǽޒ%KlAVBzc@~'CҾ-oZ{Cu{drrO}}iZ+"DUɇ'U>I1%*1fU`vP\; 6^Em={6BJI2TrKݱqlɩ$ no_H(H`w8Sۦӊ|N(Hb!YdVSgv~~h?Ǿ)f(IH{ͬ@ AQ d*9RW#}DTrLYdɒłЎ7̇Q瘹%99ft3os*²z:rТ7D '%.UNaZ-${0\Ala5Tc(j_-^vR4vA&lh0rL;pQHˉDʽ–tS1,<-,]Z H,Y2 (xU/ǧ:>Dp$J1ǙD,]%piy-@!VR:;Ĉpe։ w>#DA2)UKے@ #aNj`U^T LSeku+Y`2)«E?!47^i: cB?}Edɒ%K6U\*^)XR>J~vwf~ncVi ~=5yYG\I5dOjӥ3T^,5^B9k-j.s3budɒ%K6:Xp)15xXV6۰~l~w7r~mZY$ \txI .Za%k2xp=ѭ?bwUY"T}W>7sxOO՜uaTJBZ;;"7V+XBDp=̈te5ƽH$KNj[ZARJ,Yx[v]a;_1E0E=m.-\^mWY|-X$E+2=s?e2sVQ2p'<܅k>X5򵯼GBo$&>fILjQs&"Ҿl3ó̤k=JODR@dɒ?S$Gdž4Yi|΍RfRh Ja$ߩw*Br6I(@SI1B~r)0˦ !{,3iiMf ڰC9NS%d/9cF ~z~<Y(*dɒ%K6@2' M8G[/ b\]N}Րj:!(dVzHo5?dXܫ'ae+/ ,WqS~!P!ú'6pL:yık91/Yd+<R"iz{7fkwds4|;eo***m-H,-H5HT!#'s6{xvB,\TXWl,p^= Ogogy%7QdɒM;ץokZs' Nj*3 *[*e:O̐Q+;ژ`4v,VE?"MPq`bّR0txDb/Dɒ%K6 ]޾h&(_婏ޮm=oRTǴ YD4i6\1" S"-r<$?>}LwQ C ?1ĝkcDD+4xN&Odɒ%KesӻOFh*TH Y.]~`v{45ٖ5m2?}I@31b v#K!NԨV.)<PbP=LJ4ܦr0^8z}d+xٵQ-$,Yd"b ?I} s&sM~77Y aQ*eϣ8Cd j7-|Ǖ9|tL2cAYz@ ӧ[(V|ԇR@"{0wV ;yq>v5t{5=$K,YzVLSݧ ʰ)0 e2#G DI-}B ;^] 1-Ő0+38)YUI%ch7Ϝh!7 S| c+#ħ$=;(G U]͝7N܅WK7w'[,YdɺneG3Z _ A^B8o^2fC*(]-U/**ݱ6u >d[J|9DWU!M1| I:Ux*j'dɒMe/WJUy[͇ XQyg^TBc"M,Y&YQ=+)SyI=tBU۴ @L_S1W_2<YG ё$Ą֝W0& 4MRBĐ7Q 9`[/,2:,eL,}R?UC'}!]_)|'$ 'K,Y/|&*E"y.3gOJz$hpo6C)$ZĄ˃j%1IeXw|nw57]̗z8&uTmSZۀ]c-zw[m(ڛހ&7I3S`d JHϱg\%gpl l8D!!ɒ%KF/D"zɵR Jn:j*2$J AN5Hw%ms}TSš~܆4sHBJO_y|iA~yƁ^j avt{xOaH+(Is"@dɒuCt$asf*<$JGڔakM&!"$XfevFTS}..gw|Q$5=n,DZC2 q{[c?ymuu]+EILS͜7o*ŵe{Uá>ե$NdZ7YdɒY/h\")ɬLӸ5] -_"_k}VuHSs?5gP7H/Be5}Ŧ9"#}SZ7aQE+M*yZ} ĮP4P(T„='>^LBvdɒ%)vKN6VބyMWђirqz ^n9J&0ChhH!v CkE!RƉFPeXeU)1Ր\u\mC2ȃ#C+&Ydɒ% CBTAm%dޗ*ץkxMҋ/1{b Ve"tՒm7 K0W_=%#B g$ d*f/,'Zj-%!{\N99BwC2LHD#YdɒMGSk9wO}8TIr*6im`(b' TrF+BV *d`#LC UHL tPX ,+9~LǰşgҶc/xmSAp0a(?c6S\^=Cꓐ*(WPl9I+Yd|sY7OzA*2TQAd Q^94HA-P rs%7Ջo_T4]ibx0 \`2gSp[P`Oۮ<4j$@ݨ;Zc,V?xU +9JO,Y1V f(kcEAչD! ђ )W$w YLjEvł"A4@Vw,mv%7sq)5rKln]^ }mRS]$#>mCYQ &J sZz:6+hS_"Ydf )cedyߣRcɜH02GL Dѩ(.U>4)bC7bp%AK\y>P$].(y33;R$J/3M@y٫/'P ƅQ3|,rX bwИ*оk/]zȔO56a׆Z I,Yd{QCx;ɱ,KZVn0&/!bֽ\sA( )!S1'FR _α>3d>roa06;`IRy/|}꾝qj{?#;}WpUlXxΏ)2Y۞Gdɒ%KXU@j=-U\|dM[{gOř9T'j Fb}ۄ ̄`9#_=Gzʁm-%TsP܈j@zkVq^.*]KҌjBɪJ%Klo25l&kFXe`[aդг, ov ]S5}!Fʁkf;b;D@ lE T&DF1cY|tk)vjWݬ1Nz}7U)!RZ55URetp ljv݈O~SOdɒus~?d,cJ;3$P%4j%]~G1՛qLak-H+\}| `?$@H!i@UTFTu atӂ3\p+CL]/-.=bi Ydzb9~߷%% 1xJ$$gvɵgPٺZ+Hr)Ygɤ`= rxk[S#vJ;t&&jѦJvYd^}cy]>FWqBH|0),yX̛EB G}t]{_5!<%8y|DhWKC;y1a {crJ@ZH,Y8055u͞;(I<%M32Qqlr.$dع2QVSU̼~֊гϭ9 $wydJ;Qɒ%K*dIJNV#˱y*ExU'|O弪Щva\v!1AcvƒȈU\光W(L.Aqυg\T?<y߱4%`Ja+8H$G\,p4BN|If/yB|ɒ%K Z7)Y643㖎V#8efZ3Lَv#&AK/$ϑ?vg&i!7i t^';.6'T}VkXI ~ZUײ\ؼIQj^]B9pm#ҪI"Iɒ%K7E~o 'j)i b&AX޾7V0Rrsa( X@Jp@|ϱ˱ h}CJѮO%,vcs T.HL(Ҿ &,Yd{j, }"6bURб/CvJVav ] 1XY>PyU~Á} x+=KZ;Iɼrߎ&LZɊW,jz U?D@;( %XM$Odɒ|U$mUE *^BS檰EԾbB@Y4j2B8TMxEHFH\Jx]ATLVS_KҰB8mb @ոмUN7=XXN5L0/]x&M;{3Nɒ%KDz*{4!{`FLIn4'|Z>jIhfe߯F"صMazI>7_؄u' k|8kI@7  -ꨂDL][MhqĂv&QOKD 'K,YY@ [YŶU7@U Vc(MKcvc02C6:;zrk#L`3f~f$= veA^Ud@̾U#Uk$JN;GWE2`׬cxc&&$kHKIߙǂYԪҩݐXm7WW3őw:##A $ Cfc֜DRߤI}SodºG !@~ rA/%":ŚaZ@1ǖHs g\Bo-5Iw`Άٶ3]JM@[$Aݢ䠔jj>N &D}ǜN :ݼ*8զ! U =cl߶}}g~}0416[Ž[`bP`I}znK@FKJ=9'7ҸU{(=h⨪{K8W hoCJ{9q ^UyLzW(- XCGAA08N;׶!"!3k7! qDtLL1&,$(òˑjOLAD`YS{i$xZK@"oѦ˖Ỏ\fŃUQɹ<ؓXǝذ+wnSv?m;<_ fKuj{qfO /5GG7[~[Ưn&Е1'ddLF +/NSӃtM? iQONZl>!X7֛g+8/ʤ]zD^%0l`_su;:LL͗.%CDҝ4NdX):D"k(&-Cj 4HW/צX)pC+[ȍ 9oU,<ܜsiEn:DZiu<Ė{F WFcxWWx'0'yO쮃;h__0q][O2Ww5&nO}Flxt ƀ.=o&>ƓSݾ;!IWofp 9~V!Aʏg*-#cwH.r 8P]ugyU`&W~bf35YX#e1B-H@VK&W:b]9abX&DyF$رsW, )/+v!R$aڰb]]9U/XiV}98ϻ-=1@Af}3دsN\ݾM8lx^=ܴmə3:5ΐq=7IF/~_>6^Na+qGbjϹuo[_|V\\,YC0)߫o, n3PuF2Q ,2aAA*"cܣhd樬SNa;#3@̠,Մ^DFIhjrg"J!8,RnccTiw,˞t$P(gM.@L:~ey?@a6dtx5D} l}y5Y,҈9n^ƿ9r03ȑ7mo- >B#>|2enO ha!8mYئ V~6XPꛍO*wOM jA)qӵ06&2zV >@hab@iCQ`c`qYq`X}O`dx޻qOg%WuJud2j<PW\(\&P#$7G } j|FW "@L QoKZo^MJro(0G*Ȧg/M o@ND eRr.+$-NN H¨axJøbHKRYrL=Y p 5*,˕@eϴFrssKv7<ʈ6r '@a}dkfIK GC-cH{Ihpٱ)>=k 7G%D̬M6cj#(M YY7'fn,;y5Vnw(=@RW`]܉B CXt` mZo_Gl(Ap^s F,Z}| ~tQx%Ga~Ʊ ߍG w8vC1#t:za(o.=Dq 6o?\#xtv>f)SzѬ_e>XOkTrFp~Űf:$-9t(`Sr[n_CWf,U|5"JHwuAjs}IpR\3:`1o&|%ߋr H=sz()"ņ?(2.2\ƍ=Z<qA˰x8rns_q'a8ڰw}zp]عH}1 OF26(­1ͷ__ncN;+aݷ_܆9 dO_ߍ'9 X0vbPK#{9o"a `uojؼsw[r<E/c-?o7 A 3 o~wm xi\iCN|NYl{ףv8iBGou7=eǟ M7߈)Kڈqi`|B^S7 Ě߃u #w?~WsN^l_ơg⒣m Vy]sfPߎ{nCqڹaA$|'~9xcŴ[&|>8A/.~KmG^.#d 6WbST*ޮ<;尛b#y&PrTvGkzz:l_O?7\XT 뾍u˞<\YqX~8~,ŧ܅L`%K$q[a \scX(〧Yԏڧ™6➇ưqQY OHȓwGgŵݘ3qQ wmk~G>и1ƃw?^y:f? X4l{'tIgc|l<ܥXl:fa54x8.>,tN(v@[aԱ54 _ ˕'`8'y%8x7`A8hVn=7Q2v FwJ~zF0>a|p:_諒nHIĿ 8"Ƙ70\a%#MJ\ر{*DmݷLE2#aOHTՉR13o;d>l9T,1ej} Lu<5 l2 OVֲj#0ו$j6ObGcwg8YGj1G. w?x~a8쀅*Caj2O}~xX4<Kup>`ǃ[v,X6T\fsO[^ƂQߵYXx43ߌ]ʱ5rm6&߈o=lۮ1UiDA9f܄jiM>O#o׏1c9chprlَ ?&v]c9x({iv yP qӫ*HJN((0X@xIʄUf"ʓH(Gc?Ƨo'KV' ӉP1F{5P uz5I D45^jְp3ac~Q/֑+=}p1,b+X} @D U᾵k_k9 2=x97B+8`;ېnO}Ѩqd<+} 609@ 8гq$0jŬ܌¾q>7[{3Ձ9砯8cqY+dԤ h)NT,ןY󲈾sgR;:Iw*v e%Y%ЌjW {bxT"(Na=8B9nnvKw*F ^l4$?2G?g0K9(WX ,?/@};so6 I @mkժUuiZVmV*T!lD&q3+{s;Ӿ"\H”-%Y3͙R ߩ%$kh$Vb)[Cau-\f9nU,֕Aea-U%B& Q: 336+X3nȐ}a=c]T_Qؖm)Acyh4_HY}'k7ԡPKJѯ|́P!m[ww*T5;۱q\7>Ѝo#;Y7qp@,obOno*D>^„Pר#eR_VBXn`sC>5e9Jb扸x8A* _yNսH&9ac[wOPVL0IܻkU)Qh=3뤂"fI'#Sm9K(͕ܴSؽ~k}iL* 5ֲ.]wbfrJپ~'Vȋ =1XanOƦMKV 5Q3&Ԯ3G,1=*LdvUѽ}~s)&ZPohZ$bAiA*ca788]fb:JU)h|tw*Oڌ, dZ41Rɀk&--$\LfT%E@{Xd=,y4 +)7%ҥ^GEx\ K"ȡe9{EA;J0Bt% к] ~28jETϗ2*)Q%f" "֝Qե]l^5es@ÆҭPSa軄4 ѡeM,]SOaNKѮk,ރ7L;yK0mQ4w^QsMM6GrDx_. OYҿrg]ǑtC8YV7!˺ppu5%!C?c}16Nρ_3cJ=_B}1IuQs~͂O ң }q= vb>5"^#:>~#$,сVTiGvs4ظj#ή3{[Ӓ%}4@ZB:oxJ{}gJb*M~[?kiQ}9 ti*4A1uk02?Ir+qd/5Nfh!MKӘ+@7$c`::$̪o`$BXr#5Y樐dJWy"MEF^~> ~A^}cdxlU"$4BhHD@ Ah20H @-bM61- Vdљ7it u%cs RZ>5|ߒ?k1|*3T*Ysn?,L,$&s5M!ޅ)Qp#e28vqH3ٱɎMvl2([s.X3%HiPj7A9{$ 2X~@ ca ߧ 4:90̊)PϞap6J P9&Kc`&)4n,%9*wl1u{,a$oLRXtpXΎMvlcId{?2g8mpQЯĐήŜ S!zf;V97+;!k,ĩkN6BO$XZC5׿c""1t%3X~R'b@,ĿsheқL@bPxwc498LE*oF%fBd45a 虬_zTR=n)S<~7%U0NIb'\$g? 7xOo\̩dP҅d ׅ&=Uu^ ڝ'cԅ q|/ {՝`[v:wJcCCMDʓRL-],fش&2~RsrXl ˳c4=ϜsE utJ M>2ao&}+q[V_SiNZD  e'p2/?aSR :~58oxwtʕ |72ev:6X˖оC%EEtjmu]gwm-+-A蔗͎Mvlccd>ȁD%lº!l}c.a_0`BxZɁ: |.M23in>t.-_ W郯y˯զG6ev.Ïs}gzj)mrs#'GHRߤ]ug \,.iPP֦6QٱɎMdvl[(̒X ̦͂?^҆JpXNvhn58@?h yɯNkI<< 2~4%JQ'0׭*.wh}QAhӶ]q4CdKOlIpZDqU)8I,-Gk /O_{4e hyߐ*Z/罊~9A (~Q9*;%FaqrQvJ.`CuWa-hgIzi *SpJաhfs!!1Ko%[%[2u erl)Y9Ʃ<+hXM7sUnچǯڌqv/4;\XJwFpO Ys}OSKe@dKdZ{Rus% it5"!Ni>M`&=ihN -ў?)pJ4u·Spo-$5K?Mpҹe٬^ْ-ْ-* 0'2Ҕ\9Z*GB)nQ{<[8gU $%o8M.s7XH]QU| 2Vf_ٲo6߫IJJlۈD2K%[))iMiy4-}.i7'b ߎW @xwJdwʜY*I;8c8˃Ssrָ+N{{pݜU1u…@VYÒ,MiժQӫ)e̖lɖbͷYj9$"aR2KcNءP1Ip#ϼ~BK'Cs_#fdkalnf+3?"n9~S麽uϾ 6frYcvoʗ5;ls5(uhG&Yv_sWTA?x/~ҁ NWI 4&/y$&!7oW~6P%[e?V.d^TufW R&FoK9.Հ(&r#+?n~ٙumQQ41ΥC.YcP#ټ&)aճRWlh1j^s 2mܒvQXXdRC)IK-ْ-ͻnZnkغ oO{":Ӫ>3Tm[DptD$ƿ S%dUibB7`}b7X­ZKnl& nRәnpNӆ4AISPv$t_M6$Z~y |ydG0f Fp-ْ-ͷ֭;^' 5n}T琖♓z?r |$2ђğ0KG|-#zΙ(%{St&oUY _YOi+-3Xo<~Yyʎ>gn@i)#tЈ At*J#WJs9zc a/H/cN?5~cc-&ˋcX:bd)8?UҸ")(Il}MC9|ZF2/ ecp;_콃5*`3Ǥ~!'pMP"[7?[ -O:oxb2s)DbK:fϽ7;"ѾA N"̜ESQՉBy5i{BIk}RZ6N po~cw"RhM]ὍQւd~Vc^DJJ0 S} >]'$I#vE(īt_j%UtYe:>ߎEI3ϻr IDAT@kABwu;C:аy%V*O #2Ym.kUguQIr]r:s\ڷEXlcZ=k1>i2 (ӳ$v'.Nymya3?^ǃeKVFpwfop4]kH4)f#D.JM|&Mz 67=4o" 6޵ fX؋+h"yԌuuUa/Y1lJr>]*a~5R&#,lׁy /@' j1u"јpUF!\Pjs_եx/9O>0~]+|Ak2:|^|-oygo{lj4 G+ˈÇQA X̜&0}gѴ2kNТࠃP-ri7`C{W?Ԏ,^x;n=;^R>#[2I5ILp@njvj?`AP늑9qlKRyTyJɴ81QF*|U+/!dQ(%њ+>'{kݶ9hI8[VaAIԳ?iScY3w*. dŶ{)Ư+;uMFlj݇!ksb$Aut=zg]3 )9=+fxwM\qAOȞt]G@e妝4:$/L PO h'Mɩ mɉleKm#u籢5ÆUut@ץlI B*Le$^ZBǸ^q`pLZ2v}z􃈦_n[XrZCSa2Y][#S@>)^kҖD9TUA"LS7q$Q_ӵl1 >[NU@fEiy< kE19[X:ufc B!Y/ftZv#{ᔮ蕿O^zGr2DXƛ/!)>NCϟptF$10LYO6iul#^Z%PE.t"H$o.u"0c[1=ɭ]NDh""#1dR9g0`ɬ/-\8b$CZ4]5 ,sJh>[\\ k^6MV*wK2D7 Br ]}iX{k${0ag Kb58`H1 zU $Ģy0pux(N",JMK$'!|l2 D`,]P$0bBJsXL`|$Y1& g31s ` 94w2WwD9+9rE}Y^3G=ѣ#̣]g205<9i{D+:z68ipCN ,&nE*t9ч|Yok0H|+ 31zw+~Kc1U: F.7op?ҶKhDքy,R81Ba>{ALZI$8;!O:_Z <;#i+uµ&\8v}sU5fAp׶t6PȀ]5{{"I(^[ p=iV" J*#%gj N7Y28a Pʤԍ^>1ҡ I- I(.x=2ťDbJ)щJ-%Q`KI4TG'"uƯz?[8oԃ)]͘!wdl=M|N>GmߢhLp ӷws \͌(nrկ'3{&4S]‚ֲ!4B!\ޜ*ǝpR'Q!DHhh4o!))bhm#vQ8ʚuz-L^78s- Gs)j;RSc9<}MMCDZbFoT[4 o[dRnvAfFcM8P*7Sad`Zsژفdi ((!_ncL2 Ѿ9hed6v3=e e |7u" t(okMxuG񳪜{grI]OhOQE #h * iO:ػ@_F""0J"CB.{ o o'{ >*[qm~ N2Tl(/ V"`lJ 3@*XON]jxK`UzJW*0=0iVA}MA"A \$^s͂)u$˅'ryݹ>Q#yu&e?QpX%%&-K$&i9}7k3VyZNGYT*`JNҏ'n K&Q@.],Bf؛~EK3P|&MXP ܳ'HA50*g^ֈ{'o|]\7Z:/vP lM^XʘL,٬d@Qhn0+CJ|:Q@۫ws+PT–Y8x=>R~Ig7T9[椿u8wXƷxDAKZq#8ꪌ9J8'[RPP`h˄utp3)Co'[Ki% V^ߴH K5 𯉤{X-Q$]xM(=͖Otna_e,L4*O'ߵSX7bۙ`U]IPg8$PzrT:XP[*_fk US$i``L,,]ڧ$!=? Ä֑Ifsz2dvZkn6b׎#Hq72߫Tu8t}Q $h!-([e%jL"n¡0}A]?b=CkyL]R/\λP ZX=1Gb_I'mq±/ /f|PoKr/}\dVyDp# &iP+꼊d(ME*20g*`8lN ɶa-/NɚUTUr.=zd)L1}m,.q3˂lɖ8Ve&?FwXLLG2#|qq])WKy m[wξ?1Nq-(m4}'r @'oY/D1$ʔ㲏z|(8xx'bfqy"Mn̋9jo}G+ zi WLjp q#YbfLݻ'mdˁJ ݺSӣgj:Z08)Wy4H? Y:6vq6kݯ)uln`{ԏ{Ϻܐi$(SR&aJH)9Up҅kHY.1ͤnKZ!E85zM([%[% y9F{ %j&@Z*Un@K¢ƞ*˚`[D00E/>RavpmvkGTľɁ XڗTtnOh+ْ-ْ-'GL2]VA7Mҥ-9=W 3G.u<MN(`&!>JL{Ўۯ|֔\,3fN9 ْ-ْ-ْ-IdJ0]ؼQ;06J`[a! Q@sir5_+0Jf ȄV|iH22ͼ,ҧ[K |ٟ)?Nm1pz$\&m/ĥ nO-ئTlɖlɖl M*",w?ӅA!$9Aղ^ ,\xɽ(IW$RĿ=0'cK,/0g`a0LxL/0w,堪CU 8,^K܋H$570Ump!YB-ْ-ْ-@B2PΥ} $o g{6^FK[N50&})n|4 _͐v$XRsYg1 E뜲\^d wnHw@=c&o/k?Q$![%[@$~3KL~T'Jl:^.r#aRIOㆉR1A/\T:x6r%%AӲy-ur=S3$ӾM-ْ-ْ-Ϸ敔Vi?D8DWͤ}HHج #- ͯiCcLMn.]n-g*"~9𦐊6" %[%["] Tb /" vDK~KKi *)r2hpzbM=^A,&p9 ߃#=9^zG*QCnDI7_kFaӬy9l՛ݰ鯽wz yo. 7FfˁUtv,zߘH7e+ ;TfEI@lʩۮU \fpBóVhA90ՕT{@v*S~ʔg*&"@+bϦίݝl4ӷxqmbWlKNӧ~ߍ(nFžoK 7ERefoF$҈Y>?%SRҚ6h)VJ7wA&|+Ӫ*,Vz!.t Qo *]As-l&(lwT7\@3@܉,48vCr qyʧ@T{4pp:ӌCY`eLʓ Ou9.Y09EwGb$W>LǶ_w>gE=BtSV@nNЗ]ϭ!EKͳ&$wRJVZA^n5zQPP^~vk]U\ݵE#)kF 9@z` zU,pTܽIj7AP|U;ȗϳxe*uºAj;%,@!؇01/pNҁHrY?>7\[cofg \dee)NJG${|&_[j%8⌟qIju9?,Iy,_F /Gz?>+ߌ㛡s${M9yx;CXLCUܱ{~ƹphCZEϸ1n? X[O=,gGrE?Q]O=:Ӗn#[Aҳ"\;g{'[9uܷD,sm^qb_nۥɓY= 篧+Hc֋ՌvFkRqC\30"cx-;VAof IDAT%w-0ab67/S#gѯ?,}>3u[ʑ "Vm73RʵjwuNnȵ>v> ,gcrZηS?dB=uO;yœwfm-UI]is.xiKc ~h. ) T:@epx&j#@Ns;9ƶmx 7m$'g_u&M@o#mI+x ǿ+,,g>,j>[6oMԻV,N8EB4],*GPT?\ܓ}2/!~xkqnp.mH 2+ca y9hfh'v3 шb8oX 2~[ꠒ,;%nnQj8ު^®2&f\ŷ^ rZ! [,Ykch>ЪI<K=qjG}9?}8/ʜ'aQ糹n_m=;frjΣS.D6M{y_LU~-^}箢VVvVZX'KyuaOpͩ3T hXÛwg)\0۾Coc]WdM 7G^f]j⣼n0C@d7j%!M[wӮdj%wbe|97 .Gkƶp# }֕ڿ ӟ%h+~vy?V~s'us{#ֱ`w> .׊ƍx p%8r]~÷5[*.K}=]cLl+|V?7oW~6Zd߉[JIUj?i&Zl+dl~OQn w7tck˴#-@-Hq>Gs*qaVci֡6F&2!AJLr|3 K u5x`!mx[;crq xYKu{;@QW- ^Sn8VЮ0 y\4Iyǻ">=tJ A猛NH-?qK"4 8%h)Eu iSXXD}CKz|^!I㻦v/t Z% zZ%fEaAV_Iu\D'a h;~l[/oH/ɾ["W:=*Uftf29$\F5tT)~ *}A-J`Qoe WZ[>_%ҳͳmIgMӹn%#A7E+z֍д%,W;n̩挃+ RzV~ !$4zb5V2tl E1*ZPd$kZN)T({ͮ x ((nPcF(,{TBڌ\7z!8dJ~fL!<V(Ɲ6u 6UnYդ&4Yda.*n(`?QaSò lWĠ8(hewa՜D еuH1=t=zF_#>ZëjfN']͎2닏XE”BaR>_'qydB欃:# ^a[qG?[+E/>ۍ;kKc%ϡKxy|Fd$ .o簼$\@s:9i] `uz#uMn./5~M&tzGp;/هF{vil$C/+lM6@"z~p o_4hGפmh┅>kZQ]c0[7DNacoQ| UNT<9j]`+f"\K['QlVc*=k}JXʀ#: %eP-^3&g3O DOk3u/<0OWzf4 %IkZ c|Dp]>.PS8vz1J=[R"T8?f?pJnhɴ_c*_PS]N^f:+sk(pѡÃx=~d e.֭ ~ǭop{r x,Fu9^^۞SLrGh5jRT[~%*WF6}_| ְSpIg=^p" [{&wUzltn{/{.{{OlK㒧WYҊhc0#O1gFmcȖqߩЬt?H;W)s'饕E-GOuwʒdu>X=ƺ=(S0/>'q˻ CN5ț؄N|0n24b97>t*9btd̜NBO=d#n d6}9Ĥ'aې+8_4|#r;7🧦p6KS?TL6:F_E,4 kw!hU՟/?:ejv%_WHr(~4I$ЋJzu-\_$ϾSkjgpOroo?sХR6[1s"nj BͯE(\r]K;.fHMoH6FZ1_1sY<u|s߸ s$cсa @f+sd'Ks~lǃ;/?pT!>3`' `/= J=PzM^52/ڜ&F @\휢Xʜ@(6`A8G1Bufn`TGUGvΒ`C?ˀNi%濥E \˄2j cN2DGGHt~v{dwp/dOǵI~qbF}gvkq\Z~{yh>{Y?gˍ#˜mN>ϹoE(Jlnt]LDֿ-W=ηe23^]}zE&/DCN[#.8oKnhןQ_SXǮ)Cc?%5e8FnT\M?/YpfϥrωmjG \d-'yi_7_'_tk`h\&O (BB#FH #Ú߱Qع)AS`LMbE~"$M<=/07m G6ul=o8.V~:>VOa ygl4F]U ZƩSZ mK(f OHl93&N&%?QH&ę9 z 4[}{{m"f|u9M IZ1(+ SӐH$l@Ѫ$i~$nB@rtV_nX~h:6 KIpv}{.'^#jMY͍uC ǟ|ǩ۳~| x[u]FV 5ڲ7n87{䪳]# EjBCK)bq)Hß*>jV7 KEy%6񣴝ɌQ=qHKf$v}*ھN A%EuVW5N`͍:RXt Ҵ4F)kR(Z䔏(d˽UY*h]DW@GƱYRS7U[̐k^#&}^lAz<n SJ|" lFC.WA*ȀZo& u*i)m0HEXะeh4% !)&!,Ihԥ ۟%Nf "+us>{;"dG]> 65y_l_2y˷Ҹ?4=ru)c`6 u&@J6^~}翘|>k&S' v;LY&?}ς?JH$L?NdƬſ׉[xItωDUÉ]GƳpGvDl?;wLd:_G}FwEk! \79[# k̙ϗ_Π1)f$w;hA1 n i$Zcz%M6Z~Cp&"ckpKۑܾ=a%h i- $M,\ WX+ _e%UKJdljfhUa,MD%lu}`2N.'1>[ꦻjײbۼ \Q{[sX1e, IDATU'x`  QTё6D{iسj*/筥VҶ~)W߹7/b(h?cι \V~kvzL*0wMSsM^zk /?>(hC#\/ڌyߢ1\N#/s\0x%cri]ȉ?{-Ap&~_듟fܛ+sE\qѴYrpZ.8C)^;/?~ƇTr=wrjeN|fgxkDA)=+{>f!fU^s`rge/.k}'J51 5ːB*@[ . Ag i7Mv!2MLg4@զ:`ѱ&3ȪFoa@N{ҦP03PGU"JHÃ6eCwo*91\zzG*w)k֭|YO]̩a6|*_vq# uܹWV>{yf䜫{z?󎓢Hzf66%`99|3ÈYQDπ̢Y$J ,gcSeL SO3nwJ*NK9K閾9{G=7sxZ9.'\3jPc;Wcl#pm4iJǪuݟ۟mA5U_~r-FYt"c> >ٹ"Ւgsek7<3\̳X b-cR,CjP2>ͪ8>զ{PIGhO;U%UoDNAvt~YSh+V`޾^{DxCD<"+aQ_ZCB㫓}4ݶ6Q= P}9gU{g%ZL|'N,ݔ%HV~o=IU i#e =ZH}D(bebE/BMjF5WV~|_v^=´RodQ\i]ϧҝQ~ӭ+u3fq1^*[ѳg0s`6*Y?oŭ[^5r{9*_"p=\?0_O"ӝ+Y07쌰iD)С=0^aW \E!1``w{k~{b b+3YU~ 3ot4}w+8 mLybޗrD)W-rz3x@OڅG'nſ?\GOw" ׁefsU#jU6w65=*;NK(1LY:{)OsJ+>ULFaLi2o#G &C@nk1c'I?ͧvfxoBW 6䵂%BhQUJ++Y6ƥcc[fmo \dW(}^>C؍TAźYm#ֿ #Dؿ3S/K1TU!zݓLJXKtB MKWePNVuۈ)rcAVul>~q^>2ニ"t3=?{/{x0MH}Ƥt;nNߪ='nvdw+s\GzV%]Sw& ~թs~?{MeUUm}C{p6XUmGn9Ƌ8C@oqa9KI񭭓I,v"5-"T3m,~oJ5x{o \=͹ArCG֔;`^\t˟#F7b _~NV߱'k`/E[%3r<fb/";Gf^_¸ys}Y0ޚ76^u#g qAvxg80Zզt—KE|j3ZN HJk;%nW| 0v}[,]IV͛6`ѣWn; Kh}aa9JM:3+R'SKJ&S|=DX1B6:sjC hC6D~^2M9OUdoDmmC5l ?-cCd+D&hj5\dG#FQڧ|zd cXEֈ;dP˧ͣ 9疋8j_fkǍaHh:2맞I~`pUgbB{kz|L&Ċޢ$''O魎F;^^{_uקy燓kt}UmD:,Js_ڻ ߋ˜s(-<T}˂-w]R3n `wD(/"ƞʀ}kwp!3pUiϋ#!tiJ.ٝm~+Gޤ_̞Gt p괒WF(Ĩ}e| JKrXAZz:{гWoBSkz¹3~"󭚀Hcd9boX TNw,JKUM-0 ^mXU@[g&^Et tkG¯B" Quh25p{, DڃN?g;p^H\j6 a_ o?3 ϨjD.^gE;x:EBK.rL^~{HU,[VZѡs{R{юft!m57LzV'g6~9߁.q4}IVxbYZ[%|bI$A%+?xbC9wt/_jXHZn': S ^9ї 5˩O z~vce Q&PawP7z/~]$+>ksąCh-@ GE[9ԉyba3cDz q&uuMQBsL L|cI{~tN`_¼tb[Vfi jA9]qȢ, 酙i֍/ kq7/~0"Cy F]݃4#AtGdC(޻Ɯ'#Oqe5CCd[mO 51m!qwݯ J[ow:6nVܴ:C G2I.W;)_6!cJ|c2.{{\j=,owt:y"WOt8{2ڷFÜ'wKq?UźZ Eouo?A&pE%<~^Wl;|_F @Z3!)re|YsUg1WB&$tsBr/7"-&8#ͱWywy$zKHۋV'0ukH'hμ$ƶ:w_ȤУ~mp%3xӡpp>a:8gltvKB~5>u!rʞןgG1RWDqϜ 1^VW<]KWeq XbeܣaW+yӼGW2p#Xs"qiFoYNӭ:ӝx^fL~ɆMrc;;R&So?RM*>HFD*Ƥ3^w'Y.O&Z1bDkĐDeW}6ZW]ns{W1syqFe73ܬiՈ%+xhII{F+a25%BZc|#mSN  @&n> ^^^\]:Wmx́ $@X7q l!AL-G2[2;9¿uWx g{Hln>&>+um,]-;<>9WM@0x/B繉M$ wu/e{Ht3?3gnȮ?Xkۣԃy3%6kac%O0,Kx`5{d]t ĭĝ.i{U,:[1TAD@ $%VͪF$wryiL)@vo/^+I^n<ep@g_&;6I M0^ E%OmV:ZA rPm4{Y(@ZZ﹊gn%RgH~(͎&*y\ޏkbk K?Q_ (mc~Hh7~7 $@LZuog>t O<\~9 ~U~S+'ԦG(er~FҹD~?qoO/n'#\3l,m#%Q K1'S&?.flB{v9[c6:)sM<~*!An#9_^=Vƌ?2Dva,efL~?_*d]ńNh⵼@nD]&@ZC gUV7kG(b?t:Vx"c!63U4հI0kDM?fB5Oj7 pηH L"sʡ7}p{| Ny-^;btݳ;o˶9k粴 ^EdRƪY+]Ng gf4w#ٲ3^|!&t#;:ռ3V^<.<>kߓyb<"#)[.fӷȌ Ft1gw ZegQ5bۺʹΩ>*QX+H ;7,DXRIdga1F10;Z IutȯD$ԞB:Vtl~b`7´cٜGX*-EuFPKo, v 8@tKyl* _Kíg Cn[,9AW^e%Ih6ecu0(۟Tɢﰡ n#`PO7 rxGl)[o-oˁ_1}˞կa r4"択t>>g.˷Gf挭t9z.8ڬ[~ Q֝ѳOgO3>"#Ha6.]q1\@Ļ!7jec${z\@0Sw##i]M/} -UA|LH!d gAоdխiitޝp2lbdbΕ,~%岘E߯cS:Yk+0E1<_$$J7WYMKQ]~ ech>6w*X"{f.lN=L.~xQTD%lK~9L`w{?4e:?o 4E(PhG8=uz26d4 R'@ kVNtW鬍BELjO6KutQ{ G  $@W*-`Eϫ?Ԏ{P<[Vn^W+1r/鸙go=k8{uhoa HFn`̫7ף{׃}Qrp\v}\{ ʿy/g~@iɊ 715e_BKt*3cIkhK%BOoɑKA;@4B~]9iH[֥gvKH /Ϻ@#PJ>;RT_a F>d eh~{cUd؇.q:$@^Ȩ-;-Yk"UY#޵^9ҍ}œYkpK-&R1`\}?9Z>ygۃAH ;J+\pIW(P"tKhs~4o,<y->FϓwUN`$wz a>S.FZDe{?pd7L!x}ͫ/>\5p =;Fxi?PObjYapp>7yNࠁyDJ[ihΧ|W\@a~&hKBza& P P87'] Ĩ5h:{$~LhvrVRN7{/45FaLA +OS7W?$."lVD߼Aq<8Pbj!fo[fwcrs"0AapŭyzKIFBFz-gұNN8{2ڷSy{ǘEk3ӞsŐy{Tˎghkeys/2ۙ J'dG4zt=h=)<=oUZe(uIGsHcP Ҍ=YHЅ2 ^h Hq 0a! !00!0Q@h .\`)E5?^!X&^ۻI4]Xo E H ;ftMxFǏBLW 򸭌Bsp0?Sǻg-;k $H 5cu:oNյKċ@N=y9]iZ/}e@";PD~INB+?*~wtԣK $@,BztaIv2őOިIrsG:fUϠ`,շV~vXqKg^N8$ӬbxS$KGc@x0+7^O4%cp $@iEH~V't9Q!`'jU^l_ElOB v\s tm'P򑜌e<~7$No ]T*8&<"O>dZ/>glsZ>H K]Zo$IѢ _SSdV6~di }nha l8 S3ؠuI'tpNyl /hF Y@ $@rge4^^'UsjR:^,?,6-_يr7aRS Ą$k6 QxHp2Q'>'ڑHĉXzHܴRSxpxK H M Eש֫ƒKZjIE ƣ.𭡼g]߽P$Se$>[e#,{lR6ɁВ Yq H5^~?Bq?43FKqVNdI $@t#y$7&h=mrdNֱ)Mk5u|JO0 $j_[bW2d.Dq$@|ü$Dc]n :"Rd 4?7r~H@܉I $@iRԑZlrZ0.ԫPdmF^kis̕ vHC BG&BS$QM']wԋ֏Ƿ9v!' Bt#28!tڙEda6րWh%:շdLq+ z%u}XZٜKϽD)qہ5$ŃMc:A=?JtE_Mrm dyy]m0yZ Z E뾊O%y>P%"`WgXM$RgN7KKٞ'#r/2tv#Sr+]O;ɨH];=V/̔8^d-o؝s*=RhvK-dy0iԅQHHqz,v =ul1pU#\AkLs %4օgBVe5^|FxPz5)^oMŷg nAJ~ 6;&CcB'#X2f/ddh99 4ŭv\/weטY?nc^R6|Z;$ޚw6(4/C 6U Q2V]"N>3s0"޷G?2EP VʖT zG4{}6"0z'xklZX1IBY1p#֚TG/}MEN[-l.(vξ}'EaK؍RXt3YX\1i=8u_Icw|V QϞп‡dgQQ{C~d|ptM̦-D233پQjwi Lj(^>+ί*1;E,:2 qj-רJkQHun1@3! A ;Oj?@ [umEVST&\M%Uޞ7Zx}1dtCGKظ]7-f&-:oƱl(OtVс[Ǖ6^gPvcB5Gwc#PGe%?ob=mM} p©6-F‘hU}/,[ls7iQ.k)PH!L E:3/6/5^{$WC%so"HwQ"o:|=7@^HK?~~-$+JHˊ+ L8& l%K;[t PΦIz^|05=v3^1 +a{8|Mg}eŻy GuKY2fO۾+RxMd# J)d™ǧ!`ۿ"#o}\Js03%-EyyYxY4O/mˑ9K* 4Y WWڗE]TL/oWrے\ٯ1 'j ]:WZE<9 vY&`Ρq_@Vel>z1sy!L}󶷈7. [=l{݇Og/v@ڤo#RJ]vRkNWt+~߼M~r/< 퇬cL k.r.Dr󧳽La[do.1G/+q}o13p3' lV.{nY*Uj=B^)n^1/dS}}o 1,Y:ʃ fjmt吣{t>qˆH颒RP&]ҵ[7zƘ/⢑i>?q\ƥVVюF #/M% w8Q~&ł>%`DLe޳i*GHEM|)LGRUir:69 ,GE ^8_n^ 0EoH,E5?H x_W_9 ݲyj(x`@vI/~BQؿ}+ ;v$;Mp7 g۲y~7-xzy/Snu| Ɔr[u5:Ntlc5Ul)5}Fx}8gjIF )PLO*7 \Au,Cͮ%koH%pӨ6^3^Nҭ{>~|UBa_sV>tx:#l|5C]3#  X N2uY͈߄5"H55&ȹUu<HmGk 1 R٫$)z@~VQ\͔Q 9>\vV_yYrY8,h,BF mUd66 uAqc I*˩")M,~J 5%<qxm6~!Gvm5t.u/O\rpG-o :?.3Z<]n;v>+!Q-W|:5T`lp>l浓u N$qcbP>iF6-`#UY:7҈j/w0Iֶ3Wل IuR"M'DcHb2FQbL]z~$@;Pl4P:~.s g=xg=.3N IDAT#:!$B0 0#j> 1j? ?Ԃ@ : 6!dͿ嫠l bRI6ߥȫ_qa(U١UGQc \21]R&5nTIHVM5/ڡ,W2f?oIejE.Rc.=h->~H[a3Z+W9NՆV}ajW2%\{+lW|->BqWK:xK2:K't|"nQ@:kIQ$z^@ 9$BIwHTH3$;d;\ kco bَm0]P+H'4V^W_hP^#s˳t 2%aً01-4@HKa㷪+pW)eCx'׆qx>wC<#;"w]śUR*@Z2J@A8AO"CJSBeSeCgI:j7]|QV<߉k6&&Od-5`FwN l._O2:|U=US)6|705W ų)oL8Wh\ $]E¡PXg{Ó1<+#$a#hӶMCmsB!w) mk)!̛:bկKe4D]~7=|H,ߑheIjc5$^TNP%ʽOVuT9)W˼HJ[oT _z@Zt5h@Q|2F,RlyָKpռ@8B|Ch ӧS 4u" 'FzR~qέ&gj {>+ثwuH*; )mQ r7.zU ']ԟ:c4 )=T_(r28&H^}6l@:p,,b2ڷP7~ٸwi@ٶuKі8&2u;6V"HnKg2&fW^qulǤugu!+RIDk'|3lI%KWc%΍]gkHɨ3jz&|! #8n $@qY"+F^tR2RsQ%]Cw8ZuL]P1V]Bv3T_$ ɱׂ33PtIͦڻj$Iל[2ylBQWlҺ_$9T}AxT]@ $]Qf<Թ~tE_/Ho 'sq*-9P4_VQod<^ J$}vZը҇r4}YKF[hTu ҖH0G;Uiyҵ}D:`I$vkË:c9tBIVZ$\r8ԙS ଁH (rGdQc#Jݙ:dZdmLvR'& E*+f͹2>3uK/#Qo5 F76߂tx(HxgS8 BKW X*\]׷pF:Ru˭NegaKBt%•.|>m֗Dwξ"}fd$@ٵԡTv-5S@(>rǶH LLh] wvx:lB8" ->Kew#~~w+24T&- 衭=T6{γPg5ez%Re3Kq]0Sa?P#BCXLnc 6+0\JJ&Ȣ}H 1[dKpiFS PY}?DIox *Iˮ#2nP6K➫t,t;GSivsI- ae[uǞ t]iQ'1U.jPDggz6_7IjҝI <8]Um+az-*"IW'XhUU} ;!)`@ G ~PhEϱpOV?}nJ듮dE* p?ϩMǐM(B]Z  p>vge=3tX E-~'AJI LAԴf#3ds ,ַ P4llyW-AbפuCٷ-`ub'}YO'0s$@I;Tgxס} vn(~;V:HRɶJQ3MxW( ZS%8-x`dR7 /snzm=MoGඓ3Ɛ4UGbI9H 1pFJP$N%“9R=ޓ%nQhC]]sҶK o JLl|:Z1zN8՗(kȦ)w1$kpS*6t Dϡlc,Y'|BA6 *N5jr-.d(Y5y[uo@3qpӭ-<[~\ӕӤ{ ,X2j4f"/dȝƇuw+ ȵ~\ky^w#鐒ěZ2agMVC*|-{f6z 3{.l9̓U*9{}ի8}ruAh\[XhUV.'R');"3ۯc]䔛s=/^|omduf>'r \=7K6);bҦN*Jis^</Gv4(c޳Tu!#R\!2wSU.iK E>tvD?$ Idu]D(֞ӎdSb[?LtkیZI}J C jH$^+sVׅp\:Մl>&k9kT֥ҧsEz#m6&Bgs2]b2FXUEa: @g"/>Ϛ Ɲ:w79J$c8JnSo>Ccb*P><۵F-)[%SQfus{c#LdOt?WàusY/LG-KncQw3B@t(ܿƞG&Ϲs='So^W>erBm yqhoZ [+Y}psɜ[Jgr6fzVf-e@8x[@ݾG?x,RnHhzŒP׿sJRkF/n*99]"Vc\rBxw Bv*w)j2/[qь=mYObiQI s]J~@K+G)F_7ܰ/N]iώM(~lˬ)\t hBq{~{גdv$UaPw$0MeA0u{,Z={Gl#5(Օ\bY><9L+F^x%FH%''DtS,~8g`n6eO,)OvV.i "m)K| Ny-^;bDbubG"x?o^XԑN>˻Wyyy$ F&=;K̦E>[9}MYP|Rä%wqܻ5U>}jw/0sqVUϻϜa0 Ҕb {hԘ7Xbܘg53jl`CFKb"s^{}Ιkk=ϻҳ&`)v=zEatoVCmF7*]U7S|IRq_k|ubX䇈@ePq Kj[@E#lк utry~R«oUk#/ cbP]|2?1(g*~~ޗw!:@[&d *G}}FWۄϟ=q%c /n~/|5en ?}bq{vewpA6or}XYhsLܣ (6,%϶.@r3} t 7D Feo٠j#+ٻwV{C` \x9ا؁extq!;-r"|)/s%U_;?/>:?W >=6^+eDnw}0J1=WbCƘ2CXkk<%(Eﱓ;}5`ec@]}=*cny< \P?47cwt<24L.؊O_agngrKľ&=D9qy~t*)S$ JdbpgQg?!F(a[ތe EyqLpunaUG\% uw5a-߅4D"eL4e,xf) bxbOЩ{ (]mقDLw%_sf_:*nu`h\_U uxW\I]1| lJ`x/Aee4N:j⒅#!\x(ڞ'6b$ЅWg')δͅ jwmh@@ U'.sg`΂ϱfK:'4& T*,Z 9qeۦ dgX!Q=JPٻh܄- PR^]%wޮ}xЌ!ڸ#|\HAAl*Ҟ%1:̜/|0 "!?.'7 j]ӑcQɸvsΎF̹9N~T`wջB֒46ݸ`PGk`~1y,iA6 ퟚ1u@!4OT923\.+޲.ŊVbOH>cBmk5QS Fp F |J0{8>|#w%;xxĬUK{l+ckyNF}&| B_#1d%8Cxk1}_a|m]x/}1;{$y11RH`[q0Q=8Ӯu  -?^ bdŒ8mdE_{XA)?OEr+H(+Q%I@?[^h&>r~ϱo *X]/a \wIhΒ}'ҽB;9XV>?-晭"Kz0?rk]ꪲtϘ| A4p Bb:Wp ǣ6 .]иM$hk!PF MΈ[w$}`nD`[dkn޲m@ FiXK$``UL O\.YUʉMa887 IDAT?z0 A:-GJMa;P5$=e$Ё9͸=X<@S1/jlLw>CsAW&^ɾ&`z :¸Ł['Kk ,\Pg j&ݒX|,|}! <c aZeJMu.&?^w $)7+- tNJC%+"EtIVQ 0Oa|mrv`ła6Zrie$[|'uyaɇ$SNV>xgx5+V6b;;?$D"u`'s0l*Er A8J*``yzx6^?q:mZcǜ;0cP=̾`OpX8+_OtUɋxM=H m«s>FA=_} Qn /VY]/ouMbEt{1uZ_}(T6,܅[F%R3sh\ ͙}0iro̚}xt0slL#Ӟغ&a}Op7n;S&%㾹[0{aXGͰ>1:2񆯰@Ud4DS %7q±x烏{o<475S9L%'_;&(CͰocF⛻Ĵkg*_1CW$1Y=D%t8k4<|ύx3Gw/1+ˊ{0qc t솉K1Ӱ{70O+!:GԾG֌H;`/AQ [w"KOԷbH1 d9uK<@$*+ib t6WL(d+ײnͫ|J4+1&|᪺3LWBwb“a\Í]y_{ذ(g3keq)O3~&\]7нnFq)VVEH^U}kPUքo>|,F7mwOg ᄫw.+.~CSEz.z3'W]UV)aF *-& .P SVN6.KZ~X#8ca,]2ͥhS_K?Q ^gҀNee3dq DxݺSY")$|w_x~:U3yZHv'nUڄx8qxYviia ĉʜijmI,GU{%ݖ͜]?s0lf#ϱBZ6j+8y. ՠ?Z4CD_v&@9k7b0i\ P$D*j9T0I>xeBz} 01^a\YR@c%%ғJ9PBk}y C9lߓc\r"Ph>ʌK]R /oeDI$s. z'a>+WCrI[-׍-K@[l0IC]  C26tDEeE-]6 lj  5,R>OdI$DR\tfɖr"X`?p;c2xHcg,GUv hQ4nzăv BT췂%qَ{P^gʧjwdDI$!9!E҄ԭžZ۸<'*6NQFR3j"K PB$paزwN-q°k.@fB:ɆݑaY6ښ DC~- ,H"dg.\~|yva;'zJ'T\: ŤGZQj~rGr eM6!bg Wp=eDV{'DI$ւk)r vN,~Їڝ󼆝&;|TĀ%B4ڜ'kdoPQQ4b kj3UD3R%3х' i])@(Zi:H"dgrXNfMVHt+ iix*rSdNRon4bʄE \.^ZB86P}.slN. ׵.zJk&H"e,8կo+B MKr !z5`l>&gJe;H=&y$]dS17FT,F#ٕ W`{>̫naII$Df g\LZYY*RZ P_j4ʁ|}sR;AL> b(pQ\)I<Y8uK,FYpW2P [^jWр$H:WdE;. }tZb B: )~k%P@bPNBB @L':ױ7RZl<_C\Ȗ`QҔm?֖'7IT6Zdtk.b? BƟ aFgn91@)Grrq1! ΑHсhhAgHz5jrxNJo-HO??^FaK ĦExɗxs x.őz3hQv3ORu$5,!=12tCCHWBa@bW@v؞%VI~3 ݚF !][PU9`,h!fNe-B\&_/~m1|zTU[ H"ϿTIJZ%a%c(񖴳Q b1)Dc w rY{3Vv[R.γ"nڅp成 3<9#31"cuߍ 7B1l`l4Ò6|a#-<'|'m@p9QԀ +?[sgbOXԝDIQ\>'q|S9dUY)6/h@*LI矃;Zq%^{x)d&qb7<֧zS#8L‘g#GV1*1o5(>Sk+^{b^³':i-|.<8}bdȡ],c/g_Kף)?y f|܍@i Fv.8mԽ4{o5S: =w?7>݄Di FzD >;yo(6h$0^͏AD+RxKmo@ʋ_M^I\w-i agm YMf?ER# f_č$#q ,![(4ǂITdw+L;mpSsfQTX'c;*oLj~gg}{x }N!ezakwEAnIb`Ջv`+}j `;V,Xt!$-=reثiKiz:6M_kŒ pN1[QvWAN}1bnUoN ZQמxWoc/ď`_N?~o#;`Cۂߍ FĐX:râ>_~e X26L>߹"dKY%60ݦLv5I=Ф4xL "P5#(Yn~3*ۛ3N60Zh)jl#R ޭn"j x uhNo<:?W >=6^+e#NB=[5ظd!S W1_ݥQRbaqSIC}tE7>ۗϫp~FF w= W AooOA,mF'e4 >2Cy0n0J7WGDW*Eﱓ;}x}}XՔ` \x9ا؁extSzm^Gnn `y%3ҧ1~LgC͚Yx^r: aH*GWqZ}1>u_c5hT0guu8yHjbsh|v=

c(mJ7hƆV`G-cZX,gUt#P;#'H h'"\r9Q 5W2 "Nv*vX]1 q3j.#0YsmrlˬZ}ƕD6Afg~Bڟt (B8)(:eo2pNͶ܊C~Ӷi\-NvN"CSuf?B~Ҵ#|%Xe &/ c YcU \x@2Sf}۵dNѯ0 .>И]yfbU2]'vu|Opoiy" +ѻg1/MʤHN+ [[hr6x;ݰsnYZ!Bh@tEMXbFI{d[勈I3UrUnk%هT|2xYbn] ClJ`8x7^cu`S€4 Ű|EbǒyqdmBϐȥ{0aHv6  \(^42Kʸ6LV=Yˮ2  aji^}9Ƒ{@7FV-XY_ 1%3iE,+qk0zJ/~%}yMKU%)]C(oo=[bb,X uXTM9 GOA1t`52tf6aႯw~pVjG /G!8 >ȹR9W_- ɩf6|Pӯe֢gy& P9FVOƖeocj0g4~`{A;t ~]rQ޴ izrX *jCU(ur>>QH/`䐳,K)W >>gXK\&!V?Ik |`v\yg4k"jЃJmg5Z&Ȃĭ#J("*0}4 liIVކ!>KTes%nK#߳\T/joivWU8~K*]GUFBǶ | ʚa㭗[+Ec1 w'pʤ^ؾy7w |8 K[=mDϣNEx ޞx=pOnJo{cqyy4t;0 /[y߇eWDCjxfxn]+6!ϖ*㻇_a{!ް+-Yu78f=+^{| *(a}y/c u8dX5 _a+ǠEK#Fa.̅8;q)8dT b:xPtok:C1az"s<?8v *7 GPijxzKw uX-^lW9S-~xDmVˎw̼k3ٿ_x8L<<ݫV9n}^<6y.[O:<kS1Taҏ/1Oz5f@3OD8Tay7n #0LNjoƂǦMI#~v.N]႕c挛zSJ'R^=wMiï/k3^m>DZ (yw`\˪C/ޅH ,LPt6F3<_gFs;?k?p.9{#x\B*-oi^޷<~8Wn?Q3xWZ${*~@YQ8bAܫWzxYx/b*F%HƯP5ubڔܹ5GjDl"˱6I̮t| A "Gswh;)'|rA\06m׆٧.ײEUMڍqi e/+RIp4/k> M:r.IVI` Cͻ;I,> e\N~XW2)rf01`0'H$RRgx:Z[RW'\b[/ߞiWnl$M J_HAIDsnk$Q#ySW`D=Ibgx[SL<=YDIˈU=t O IC ̫xEO:L!m+Ep>([=7G`'XWǦ0dnTLJsdrv%Ea3#T!"|׀ $(UeU. M銉vgT:ԇ΢O~c6" R?>W<DI$i9v*b!X6\/<2 "҆?^S'K 2R2#j&@(qϓcÿƻ!W'M[b0|XQ*OqsuNHm%%8XCMs{"ORmŵ{qUNly7uG4ͧVjMW_̏s߆JA%ߐbæ*n"H"dWf, LQIkDz1c)f79_l9BaFوlt?ҀIvvG HZTq8Vql"60%ͫyW ivM>g v YN SphVaHCD1͘pdI$DZ8IP^`i(9Mzc<͏Ir_8FjLwk]=Z` $"Ĝ岋~tz~>"ÎSu̙B[ǙރLM@5FI DINvbLM{1TR_N&UYEI$X7%(=VĹ,QN#(>k(v08Ckp s\F'BtS(x,Ixk"qБ|w7Lp:6"yrlBW9 )O&=k9H"$df́|UWB;ҾX'PKbRQrNfsdž ^wINâtZ_c%9Z@JMJFCi6ljgoӖj`bJƥ]å -Y!CS)\DҟI$D}4*mn)ڵ|\Qa;[:]j7 -fӶDf$_YޜR*@L!ڪCO5YH͂@.7k0&%_"7=LTGHWO<;B$Lށ})op~mCnX}(} b"$H"U@8. (']m|6%hs!YyM-uMdrK6,暭P̦C]l 0CaS.Ydٜ|BlC+Eo3 Rktmūv!P<NN1/-\FV$Dn' {+ Ζ= )48Xg=ZQ9iQc5.dA'kk*$]Me WKBV Ws\[lJ B_](OK nlD~GI$gW3edLEoß!۲ !A>E05p;%"`vL$ť}Ez[e!ԖYf\=N6kXו,@8/®rw<\*Vr#$H,33Q@UrV_@ٰrEr`}!BKnؚ/*BaJ.ׅL. ق#.]jPU ,l ҥm.*vp\V⿪I$€HZk<^P ,BE DI$($i`xÒ سaWݠєMx|P5`8ja |$_+,uIec"k)&QLǵ-ޗBIbM]J0@l]:Vw 5Sʿ]8$G^C mHdeϱ3)+~sAsW̺DIN" #3Reɼ)|GN,=q"B x#sME~W$ 4AuH= 6#WyPFS;ߔxS ˭D6;`F0R_ 2D }Nr .XQ.E^XA*Xaϙ/y(h d9)D+&͍ /}FBXBD3N@gE.쮸,OKt)ԅƛml-P\ ۣ(YrP@zk"WN7.9 R2oͲU bd7Kz ݫc g(+ȁ~ کRp?=PZFvρ/I2K `B=N<$Wx$!=g9 +v$v#}UEY9T5Ӕpe)cR!_ H?}dM!K0*SV]2 ҅mwO4 B01 a?J&O& ?]`.k׌!)[iljêVL :v rl&AEɴJ"*fiod9|t;K CUL*oze%~_L54$g+fdg$^$4y"5Y0Yy gAĩ)&L"챗svY&!^:$4< gjwTրt2B@\"$HMÖp3mQN~H$$}sSids(1V ɥK,nwCվɆ5(+T>V[+ _[\Qo6*=wm2: M OZbkZ-mrߗIH$?Z? D {$IxQNNi~[Dfg UG)lnx0yA~J"&LYR(Re 7(Ĩ$bips+t*#N|eH@YWt%=qSD$O@!'>KU ,Dqf1iLm%f~EΦNT=+I?UK5BaS sW"ЊZ\ af<NX|YZ9 >' e|q})( dL/}mE` wCfbmOKq3 a硱̤w,G$ΉsÈ)AH<.,#)3[*n_|s 4J̫1a4DW=MVueKQU,FE-b7v+ݬL<(f ,ș~!KRQ dQgC} y~ \u Pz0HI;{+ӞIſB+=pP`C$i Õ0"~L4OOF 2s F'4eh}0Ag.2h-|j ]D(D>v+$ b)jXwΑiqfFBE=<} Qcv [$kv T>`> Q#۹n&??U?F`Og^ɗŇo1 =$Deye瞚çQFH \v6, PH S\Ctꠚ.t--nW:-vykӹU THvXOZlF@p#B 4 FʑY'kH" Zh5YH"M9).wΩ fh g$}L7I'[24Y*xPדGNo2ʠ"3f@.ɏ]о}g2uZdGxpR7L"$, @dl$- ו1Iރ)Y$IEr4ѥ%$;ok۵0̰&wT&Qlf́DŒ_"М$e fQa}sb0:T11 \]]ZEu.{W~]=+IrIԂG 5- P$zXN@v;Y `&u#"!弜7Z4E-:N4z0ed4%C v_<+&67چ&:R_DDMɤbɇsNzLqr961bTR]uNT07tu) F/f("tld| HٹH4#<r*eƅ @ۻSbl6~cՠٙ?Ȑ)9EJEէ Y}XH(:ffDR0bԓ4BQ7iɐ-:DTQ~t<=f#)2jG@~TͿq !b$*oG?]hIENDB`onionshare-0.8.1/screenshots/client.png000066400000000000000000001703671263142265200202320ustar00rootroot00000000000000PNG  IHDR!i0ObKGD pHYs  tIME5;2l IDATxyT?gg}_Q#jŸL4MLhL򋾛Iޘh1Fu(*# Oops{f`0$}H@ z͚5߾qW|4H w]7,'&ݤlx<ވFnWs_"\d_=9I[?3Jf$ǩ40ޣjGѧO>}L0Э}=wڵ o߾D"ӓ59ExJt}]b)4IJ?ﵘbX}w3^4%$'ArN>]ILݖfZ}sie5#ߧO>}۷ٹse'}ZhZL{EI[v9yZٞu]zkg:O4zSC|ߧO>7;;vp^;'ϼXc+ Dk6l7pz!ptHR-z84i{Ƽy ضIH3ߧO>}? /K7A1SZ󖓡^'(M>hڶm(/0F`A/nm73: ـOb;AS6ߧO>}Owm"P躦L:N/ [ĚKD^Q^tMɶh43h܈>JFFDe3km>}ߧO֭[](a:GW/ I JgI$/w~fb ^}ߧO>';6mrm'[1|_rI0T& R0"ҝh8H>3)zdh DI-OG.CϣfpY/F v 4uӋ wiַͳ }w6mj # 2 X0LQnd$A"8IT3(y8mHob9"SlGuSx^Zж(E,&OL:^6}@/gsTtM9ݣӀ;qjF󓝝Mff&όFJ?:{ l/@M=3?̗>}?lذR,tl4@׆ِt{=$-;/2Kn2JW*7`Kj+'X[8󥥥P[[K׮]ԩyyyiӆ@ z)JͽnK$ÖTGG{)ԱWꔦΪp4FDQݻwK.](**J*do|ڼRMI tc"}ߧOڵk]7yiW텙TЄ3D Mj6ƝDiы+Q.ǩ-OrDCQRR8 >=z,t˽܏fĶm7mX#;v`Ŋ8CN(,,L!}G-tp9Y S䀄hKl/###EvgFZA|ߧOκu\/,g>2.&c*[z߫/aCIF{rs de5WWGuu%Sz na2rQSڪ2_~K*n'#lUw;Mj{'g!=N0 ׆NF"(ltDѽBVq;@ 3Pd/eY:dD)W4KFV6 ƊM ~5gmۂ N=ܞ0 dee~'=b(O[:ﶤrmڴO?]6"$6k^^*rk̇G2]s桩7^WSak'<Ivx_󩶎"`!;;<֭[G/Sygoym :QG:K _[Y@n XZ1>K,h r$Tk_x<|D"ApjrssPT]W(_(9d\L$h LnnjHH4?NI-6I'~&P~D5\OdILyB ̖_Md;vO޽SUC` O[)5C5UX-aR"5~KZe&SiSӵ45M+ )z5վ?2 "56iKF߾}iӦ ;vH97ҕ%7kqFʹ4RU is̓2ČKVȾx=.Ch4o2ͦV:ȧO>re8۷4`TEu~[Bq&ck#˛\4YĨ&/|E +@͚̄ [Q,ѥ 8. պM)n{9fZЛ--[9rd +M,zM&Yt9l:9Y.myZo|6eE=^zlco|zђ%oỈ'ƍS6_rg1 &ۓê|yVRMG:6K0.iݔ<DVߧPt0 -4 Z'ڳET-HLY\M*fC쩬u3h߹=fuh5*WדKAnfuhڷ)i^`{ϒөS'OΆw5m=UF fm꒛L9#i F';L?|5̉@N2ĴoR9'--^Oc}Kdu'֭'n]GVݺZ{%_(xiʍg!QW|9N:CQ1,܇:\ѥpCCF)coL㶍X+wޤ_O2G{Y4l5|mr/laNSWx7g?./coݭ_gN*hߌp\r S.E?n 6k,HXص 5硥}G~s]+/Ҋ`ݻ7%%%)to`1`*-u9 "-Af󫫫Kf7!%4K냖G,Kv@%I΅ ߧOmdP]]TJ Cuu u4REuu% spՕDG%-M U5 s1m8 I @Cj9%Ix FD"b-t=I|qfS- ܴCimt\>ןskd4σyUȬ?~ó|p!o=[,37>pppg5<7EߣѮ< 555ɶkkkyS06tޝDR<+^os?;HqiHNkMPGoNuFcʿ&Ʉg,+*bh706)/.=s]bּ俹̗T2z_C^|Myؼ(& 6(BaMj cܝ#(uq쉍 ZQ/hE9{b#ˡd>8$ֆ8Ĺ99 Kgi6 5#8{ON9J VNlp[zۇ].`뻏pq w|/T7sw2nܕ|R}?2/m> [W^yH$‹/Huu5Ģ|efwv~B ^{YgZeނyTFyB}^<XV-%^|&>cs0/3kvUpI}k;\r +-fދ#o. SCw~zY]Ο9o^Cmr{u&/pwx.Nf_Bp}98dp&թ9ZB} ROi!33I&`^F~dff$Jǡ;v4jRV6CP#w/'r<2BScm%DscY ,-5俴IS6x3xu=t-t"ߖҧO "<S>,2ƝLp|,O"&倶8C,؎Cŗ] 6)bJ>R7u) |%kRzO'MrRL &DF \ץ7B bֹZm Wt׽RdVA9͇СXE1ThxP ֡lt,ZMw.= K"B l{<^v!w~} }NԯKo_Lc98 }M^_ .9s 2=?- :,D#02}fӫ%ti4m [:ߟ jKᔑAfffJίU%Ƽ`Ս_l\%3p@\Ocuu5v[yQk6p8 aU3!^#ҝIy1~rL͑^c1-ң忉4n|c#[S˥@ntBFdIʔL+̢ t(6oN+ar3(y( 6m%Ԍ,p36ꫮ@ @NNN Öt$5V^,]nN Zr6-V`ޟ9[fv;nU{.nt?o;gA2o1EbevBGg up 9y??ucVcE7|==? Gwfz!p*\%=ne>'OWzᥝFJ &bJJג.N:R k^2wܤP56w\b~~~Jbӧ}w {W^ɟ/ZrQG }?C&'P[ttIGCf_x0%|]L'f%PY"U L -ǙȘo~L}EZdNmRtUZmy( FU:-Uɫo>󓛿o#pϋw283FBa&$8.f\.{?yc9k#uwl dAr=K;GO^A%$| 93c_3ɮnS%t]q14.LóݯPv I^C=lrt6ais4Ew[ӭK85@ EbŌ;æ0EEEՕ 7ܐj5kӦMK[aE[YP zKOƸۤPhNbn6ߧO;w}5/ѩ .Aj慶42k,KFI1 'Aڄ+Cٴ-&%-\ӥ:v=z |GtII.| v&&;w.4ysiuY'y 2W҅hf6`k,uN IDAT=p_x׿;%.DQt.iM<5LĠHt+Ձ>H̠7 Om]wXؼy3't:thݖB͖VIVjVW^ykmO09ٙIb o7'p Xk':dAu W? , !+|1[{D@,\YYY v]ÊY8lz̃}dU_K&k&i,g#HIm^nrI KW&Cv5-j@NM@^Nl:Vl({־W>ywంڲI.nCS75M#έg ۰=3.]$ڴib7 L`Ekğe+Ӱ6`nfز;Q6_xor,+S$H7)&j𲙹 PQ__%Mu)r2O&'c;w$'' .p8r:',iU&t-UK)"S?3~} /L=gܹsr B6mpСVk+e7B[q K$I6}Usd 3}@eO>Gg\}wF A-OZHj q;t8)N:R7 433Q.& VXKva}?q5ܩHT' s,g&t[/yZ)p:I`0SFvpJBaY͜Rddd)6YasiYeKhBoYiTQ##u *ٟޯO?6w̡9兵õf=H5ZW<45^u1<6#Zr n _&K#Ǥ[K`嗵s<3kZn:ߧO-;YV6,)Eco ̻ cR)Qbf|]ADI]V4)qlWUrss';"L\ۂ^vZָxmyap,ڱ AUGK^( (#u:t> ''>o\9iktX֑Hʗ; nL_$ -1Fkܼ/}wg|k_S'oUos"ӛޓ(FY lDzCD") X2.{@h{d&jkk wlܸiӦ1tFiv[7cx4כڒ\oi?%VjlJ=֚洣ӣ j)ݥX СC:v￟T` ?Ki\%ĪK!.<ښ,-eH O.LIl ]-G&>}]i^=P!Y2'Wܳ%ϕV2"Jer\ ĬR0`Ǐ'///Ima+lְtJPs/,V%voI-p?^A:OK۷}?TUU}xvddN77tt- ~Ѹ£m)kxck`lx^2KQ6l6؉ƜIlJCkQx:KZDA҂z<7S]qAe^2!I[O 4Orl)tcpg[A}b'_"sk#9Ru]ΗTl$c?2<˃mIp\Cbl<$LG:t?Sr:y7ej]c[&ӖrtXNd5X|9~m9seHlMO9!в$j]Ë?tմW"FMS7ԖѶmr]Ӯah #eWP?kD-O&h,C[;w XP0rC#ѯz冷o>W V Bӊr7Gy JkPPjEK B.l& 6s^Z1 ^蒠1nSfe ʑ׀p>iįrj-lW< ^/素9ʱz)>jB:UY*d-$6eNW8ɍJ̦KT5G X ՐK|NUYKG'F(5$Æ uC=~ WQz+n664hhjFOp%%yy1̺?4RÅ?44h,g6i*/Ci6g=¡zsC.XB]BFr#7mՐdikPHsשً?lr=m6}4-"7!)e;?*6>Xhyh@6eGZڴkiP+(m9j'IizIOgst77?KmŔs, FGFZq[66W&zՂ2W;V=6 ^wz_m}\C^rIѦ>,6wބ5S0+F`HG=gZ'pۚMi8hpؔ<Gzj׺ȵ;Ol^/ÑVаiՇ$m慑kXE)RG:C*6?l~ Hh\gjʞ׈Sr4asK>ԲTC2cD= Ѹ4@+*+hJꥰh>lٲٳgsgpg$SW pBLBϞ=mNZR|ȓfjiWm~ vV3wk!pmւ̖fm[N^[|KCZ`5UlB.Db ސAJVm1kͦ66GA+6l_&C-^ 5.[Лvꃘi8QfјtGKCä2>mʛ^mIۏÆy'@?sjWa;x胹d?Z:&BV27m~=6-P6}kp>sWcBl [mHQ]B^S7J Ū݇l+;*(dSN9C{aٲetޝ4dO 'x:֮]Ν;1b:uBelаD"A8+wɌ-ѯA~3ii4fi%)(6-. X6U{-:L[H[@]=Fo۶J.F.G.s%N=T}YvM>}Z>,#ixAAAJ&CZZêU8СP(%mVH|_gp]p8ȑ#֭-K.VxrX5nd2W4NJπۂW2A[n[=aۙݙr!ʨ ;;;% ̖ H:ՆG"EٲqʔiLʽA* f?F)gǎk׎mFj,c͚5,]'|o3f1Fj& K8˸ks=r˗s3iҤ͚̤;m6h7V*^x!S L̵~W6)U 2s̔Wѯ)hۨ&Zy=aFF5غ}/7~ygO0.LNnf#W&i ~ >}$]RԘ$KgϞÇ{Ջjڴic=޽k2zhٴi7oNZ[IjVj=!E-piX_?y7ϯ賹rU[Di;f}Yyd"3*~ͧeevY8N=>v>t=)3 \DG4Z}/ڵS2.GΆ|73 [?AMԷEt,2g ˃\l ?yW{fyb-? ߝN0l}>^O懓q%Kfn|Qd6ofwX_nP 2q!KmeTu{ƛy`7i} 2 ^!ixFʃ!>z5lO0#Ɵ}܈Ԗ0o[yPL4=XCL9C=k}jkkYd ۷o'PPP@Ν1bk֬aʕr)omygǡJ] IDAT CzF_կ~d\} >ws|q}rMxGx6v!%?3^x222K;v,_^` 0Q@@(O>,ZrssgS!_2:t(}\x,[3%ĹQv'NبHOyJ7y˔|t͇B!^RTT{v.0A(דO^''̕cUL6~NnLlw>߾Z;r]p·\4^0ZDUOdY4KQWؾ}{2IGieػw/mڴ! RSSCݻ-}c߾}ٵkC +V0vX p]}RUUEii){i8у˗5Sxh88i\M2v|'?+ƯϺǦrI8Mmw|uq8o>~MXpdi<}7]wgKͤ_Kˎl=ߔ!d|iDnլX>Gs4X|:J~r~?ΆԁD3N8L>|…4Շ_f_i-F/]£o|bCV^Ś dC&M/GIu8|k<ǃ|'WRk%.@A XeU8YRޞ!=ofBz^ц&f˸>n\ExZvwIbWYYk׮mmyH+RTTDvvv2&D+׏+W;`tڵd\/\nc2o[}+rvǔq fs=eK/D"/g/b222xy;CdY9Kz.+I=PIs=re1}tk`-߶=2<$nsimP`eV@VU 7(f%ュ۹謁I+5Ols5.(sũL*ƬFS:l wo?7>ʞnJshza/;'uOq&-ZD.;vSOF|JEp8L4w#Etkر#6mJb]Bزe H$kdJy˖- 6,c7B5~ {zLqvoyp <+(rܲx'wݍ{A~ ;?83&_ʜOf2]*c=w0'aؕ1)a3?&[G_>%'pq}yj=[Ư:zz]Idpo uxc6%iGo|9XrR9nFE 'blyy^^e ):Nvvv  nSы/Όu)fx0nkt,ޭbhR}t?ٰGY 5O>NƔR^|dnÍ!vJGY'_99uY7N tJ|:l`jBGp/s6fn_.#Ncn Oݳڵ^j2MWِe?2'9=uFuCd= ^YGr:#u oID"P8˧Ug,)ẁ჈V|SW\w]NԁWe!W2^k/g1wnz~ k> K6QKO>6m4Vvb6Tڴi㩈2w\ׯFJ^y***<-KB22KYY={TTMA?? >k> b1?8?OZl)l|=锁tn`

u #sIW5x0qصk0nܸFϏ7;vx/##`0Hٶm]vԯLv'㝖pOo:]f27J t6*(;)hkLM 5hw0?_Y Ffpzv.O?m ٽ;Yu m_*5QszěO- [v ܔł96hrݷ$;;h>c,\djjj3f W]uU#KNeN~@.D"ʕ+ٻw/Ia ٲe WNQtL81~]m#SXXƍĒ:u޽{9x ۶mkb9>C ȊG8{"2gxUWJW`Ϧ1K%9m??< ߻ ;sWn:eƯ6\<0{=w<ˡ먉\zoзC>EE[cu4:n-:k<gԯ~d3 |?~r呻~uǗpތ>Jy|ff|9o=.m}~SbOOy\)&_w&GWrUeM17 3=~7CYc;!E.2&?\ˈ?,홤wNYg?sX|LAp'E?dX,f]+10kBzge:laQnM,].#8sٽj: >l_˄3+/˛+0WorDNOu ֳa&bط} 2b왴 C7xqUߞ;FPV&K<;8+}M=aZռq V]Fg;w-Be TG2KNWA۴ MґU̙Ͻ3[&ϲ)w_ޗuo̲2qrb=>\yj_|MqXa'SRtH#^} eNkP 7󩎄9<.8\:e]>j(I+O" Ⱥ ` 㴟i'mdrub/j׼UQοZV.W_o{rQf!`'^w(t"nI+}555t%qVK?tc:ի)//obc$L$hӦM#EUbJn\r H> H0vX⊔@1i'aJ] kkҊq#W}t;,`_ՓGe˖$&S*yfroY:##{Ο~&{t? 7Mfn}R9q*Tqh^2dA:̓ƷfΜINNdee%qӦM*:@ee%PQ9l޼ݻwӶm[BP"#''Q.9]qdVf5;wR[[ƥOEEEp8 ,DhL~{mC7O/ySޟa?a?ͳ6s[ˇE\o,Bfa8%U|f{DEgÓ#3_qM~^_tȡzS*0y3̧~h־ ~yya›@Ń:7֕fň7eڙEĺ|Dv %L߇÷okE7ɣɪ+cذq)g>Y[̍NqF7<ʯJluy@?=.~4~v@n5bn{T_|څ9"2(#L=Uv ;]0K>VG!w߻~"`@WF+ :ax'M>iy0A܀;4D)\z[6/dœظú1sMܝP].%8s ߽4‘{` |Fh=3s_%5n@紙\q`&O jnPTso5ޭ[76nK$!''K/4x:w-O h0S$X<O*mPY~ߜrssO>tؑJ)3Ͽ:&M?_ΰ+yA.l|p L8XK{v*o4s5< mO]ϣ'7lT`$uٸ"D"[q(VO1L8d"zq.uT_~t D( rRCan.f<ȍƾ=Av+qP8!JŃg_NjV?8DgJ ]O:6/col{8 'a& i"UP'vXIwX9O`FXw{ }쳔ѕ33iVDٲz=mkGJ?{gq-۾ҪZŲ,ɽw `!@ F&$䦑Kro $$B5b&[*[4;;JM 9Zvڙ9s3D;50{6bM'f=L̬lڴ}})l}p96*Nh)#_p:H:uFCn2cޜl! ^!0qtY/:hkY N!w+vAnVoB^%|s;]w?˷Gy{?Top`:Չqka:Tr꧴e!WdUy^e ;;?:f?ʣ.zG2XLA5`|#]vG?Q`ިIǞʤcO%czmx{#8/}^i7ox۶59phd}L=5 {+4^_ $߼7"`K /6F=wu /p p_ׯTc^'I/^ڵkAlqN9唼r.3>]jU*vT*(||9߾獁d-ھZjMUSJuũYA{3ˍP`$Q-6lE߾B$di=y_W><!U3{*",N4id25HH$d2T$T%F4 ^IIIκ:vX***D"[Jvܙ0߿?ĪwzizOؾ5.{9OswȊr0d- ٿ?O8utW 6,紪|rs "͜p<q)2߱80 >^Jo*M\A eWqRD6 o+﹊Oz"m# Z/8k}ן;h!u^9PSCe&`a173N;*]_hƇOF /ȽW06\@{ZV|͋Ys.uxg?mPRu_6IJq>w,0Y=&()] u'2о9X09-N PVŲJ 7e9JA.:SPp{ L,3_:@lw566ڎ_~9?g}xW]˜w O'I |O3!dxjطvy+v)-% 0YxslѱRyilbވiӦqrwpmqm|ϪU4iky$`x;LULb˳O/ЙJm[?lф-VsBjlݺ75y2ze`#Ay෷ rB3{wcdYH@V.R=㾍7%zs[o=h,NwODr?nܸt'KS4Vzpծ+v0^cҥykcII _|1%%%u1Xmw?ql;IosNC9V [Oyڤ1R>H˸&$<6-'LĎXv `QM} _Gq :j0nlj~Zss3wfȑcj&3fj*bXnXv-XѣG\gPk6{eƎyy1SeUs.e姖pvE|e7<P%:ErE{o._3 Teϲ(GC㙟g/`rշKgΌ94XK/ϸW|ӯ?o9_=a.ǷX3n^忸K'poѱIuX'z5_ %7=c3lk`E$[Yi yMJ wnx>sԳljGE|^yO\,cR֬xuHzc^MBY>|yϖr[c# OdO6e1rxe%F=nqÛ.y/M^ت)Wথw'ҁJV837_n%I;ϖ31N͏.凯```".Y?=p3+fq*h!|̗C"!>y'7={?_<$nnӟ:_;!Df^NЄEP>~q+wq-Usl+<&po;RĊ=kfn*`VX5kHRp ձg~i駟ΤI *~dפH$¾}hii)xΥ^k]z5W^ye쳳'{YtiN[ػӾq~w=%(kޙ|}_qXr%'4Knگ?w1\> 8#}~<ٟӦMcyۿ??ٹsgNY LmSdN TEW=U?wq˖-+r;MP/?>^xaKSkӦM~zTa2Ft>wGϛǵ#qmaĉ9CUL57Js]tE;{_6煞]VQʖRfno'>ȇ?~qUF77[x ,ӺXjabmmm?fׁ:nS[[kn}.8b1z{{?ΕW^ɯk~_K"`Æ !)xDJ:B% vޞ$R>Hb8^Iq =oۀX,u]NJ+Xh>L&3fȋu1WH=wXn9~]=i"bEҟ{ꩧܵɓ')jy3p/W~ yW;ݷ1sH:- =q.R^@I_fƍ .I7kbXzu.J FSزe ծʬOSO@*b޽O{{;z׻r vQU;*&Jo?g/ޕ;Vv冪jU5Ȯ_N(|_pQQ|cSxd广Ɓct~H7WF]GE#C}e5eGu]cQLuwh9Cԩ`k6*% 76ŸVSr,{ȴ~7'_ZGױeīeon#7h V`$z/&1 AP~I5%eFƘCv07n'yٸq#]]]4773zh͛;nxPm )++c͚5̝;7/#v|ex(_|1'p@ @("]]ƽT %HinS2?R;ÆB!/YhڵD"E+5]ͱ U(3EqƼ۰&___z׻ojU]Mfo4Эٟ5+Lk׮e4440aٳg<k֬iӦ1~xpjPsmv$?!`mwM7~b]1_~o`ؗ'>kJ 1|^y,XVQeUXcƌAO)ۣvބum6aFիپ}{.誼fN>\ZC9kXg󾣪so6ʍVs=ʪu̺χOɥRsxL G@oT?w8/m#0/ w2sDi_QQggqX/~dinnfժU466P4mTWW3c ,YG=l?O^/s5پ};ssn|>_wW٠sʩ*K,)^1ߟgtYU] 68'>L1:޽{ٹs'w嶺x\qVS\nݺqhii;'15sC4nkd[F3#=KR7T*E43w\ n<Ö-[8S(+++nӔ>~?uuu3vX \8MUii)<75e꣪cTb_Uj_mL5Հ~gHR}!t3ZUWS+hלS&ePג )?<uYymNu;L i￟3grI'! =T*E,cҥ{z)vuu1m4q c*LիHm>p8MrN]_&p‚NVU̚p?_/]Zsk\jU>ՓMժDeժU_^dB;Lo[UVQ__Oyyy~YHx_ed2P+8Z Mf0sf_>9WVN-*Y ]T]tVSLm׿NA U}~E؜9s馛())]:g;] 듐~ظq#<7sFQƷ_/dnlB}}}nϺ銎n 5v-[FUU#Fꯧp{7;t?h}ڞ;1Y9v-4jM;E&P[ >M2?O6WЙC&bcTL}c/í'Tjku?P۱ؼ/<ɇiGz?dPDcs=nAiɹ &:,;Cuu5 jJ'b̭յ\hMm웱~\oM>yUogg:BB!*++ƮeJ?9&jOg-ZPCu}M=U/_d]' ˥'jb@$&EI޹zYLX5E&&&\YA^}Uz{{YhpLc[UC| ip2Ñ7Ã.Y,lA&[][`&bd0;J/݈úfGՆ'ONܜt®;뚬jjnDWLwFtOMgU']4m& zʡGee}IPMnjLu5YRC_,4 =IG>t .:sS]S\] >h(w]qQL߭)ɇD薦֏#-nL&$M\1p h+S0rI>Lբ΅zj%Hˇz\n5oI>Lm[L>#_ شmcn uo2e.]_^*ֿP4nw^AVǴtK6>R5HS}}饗xg3f cǎ BOWW{e˖-lݺ r1x SuЕE:8I]]t -ck|SԡM'RuC\f6CڞH[M}gjܮv FzU0Y)4^}iOtnJB1LG_UF"ӢkcZncN7u<g[L>MfZ\EF| S~˥1|Ҧivs$&0ױrdRCLX?LVQU>LC~ &i7+Z?T9~y(p+]>^/`ڼ#~ 7J]ի}w;sMe)ְݦG蘎#77+SCveZl'o5{ ٲe 6mbϞ=tttFTVViii`1-Tj{;D5wMl]0*#lڭf03)G6q'*}3ɇ vo|YL1e2-ngd)fmg78ӉigdC;.]Y.~ˇJ?wQ5ѯlVZnRYQu_fI/ЏB)nPz.tKh_n[%@ U_OkHd}3gњ=B@ݵm(KzꂦOκ߮'TB}u#;\tkd&_K=[-G 2a6~x%[5U-&^?-SnIӿ[_,na::-([zC^ n]r;*c0Pdzt\LaRb+e~~$4V_~ˇna> "jGt jL>RGW"y鑤nb~nP G>&{]̓dZ|ԠȇiwCX]dS*&{d]a6Yuo8a:11YJT>6)2ߴa-&mTsecqa]>Lb nA1|.`j0)pt?ˇ$a Q7EPw<]>L5G1AI: W>|} UrΗXP(h<7͏Z=psȵڵkvn;bL?݂gRVMe󀹥rxtKT̲--mor6-o3-NtkǭL~qmoDCCCCC"noGmذX2SQS癬 n;?ObE}}l꺥Aҏ L Rc.ҋ mLGnycMQzEdw2`jc_[ۨe2=4I{L>t@wmQ}L)(v p(ᖇYw7-nGzʇm E=ϳ)r479M IDAT2|昡ȇi>q, g|)m|oa.P׏ʇo[Z+iz+oQ,Õu5nܸ  a.3pbD4  fضm]]]TVVB0{(  ›J#5t{{;d=\  › .-t۷NUAAM%{?*  2MUAAm(  (   ʪ   ʪ   *  *    (  (   ʪ   ʪ   *      (  (   ʪ   *  *      (   ʪ   ʪ   *  *    (  (   ʪ   ʪ   *  *    (  (   ʪ   ʪ   *      (  (   ʪ   *  *      (   ʪ   ʪ   *  *    (  (   ʪ   ʪ   *  *    (  (   ʪ   ʪ   *      (  (   ʪ   *  *      (   ʪ   ʪ   *  *    (  (   ʪ   ʪ   *      (  (   ʪ   ʪ   *      (  (  6'M *TqBf X^<% #v,'E*ztOӻw~ oSW0{&{yc>%AUAw!T,PFRndK# o/&g&{g<"_X8X8`Y ~c)3?ɕ  _/g?E_IkXaN=gBx6YQVM?K`|;t-׽v,,d!d~{C}X~l**VՋ~ZmQ/I+7'ԩd?Gje2tlK}d.Nbm)ȕ^5b|.KMZyP{яXŲX oUyvHn3[]$o p ӧ9+c;i9z Lޖ;&KRzy_ESeUx_IFWxڑo1PwY%)|vQ!v<Y{^ јM½?ȅ=$PVn1*f}1]gxv`o6_JC h ' pg'z(~gfN`IQz*Z"TWԿbfuau0"C:?_7ޢ*l::>|/֦zKQRD/cu(_DY2tQa$]j;YuN;ϼ{[$AW4Ɔ cuo&<䡸a6;ϼk+^I; *峯2R<<]2Y9?\}  r2^{r!S?Nx-^R\KRS|D\7\Uf/9@ v hkv&%!ڣ/3(dOqas+TTzdʜB<|cJ/E+Wz8Oyk1(ZqOuWTa cd7A[i;eߡymc*+7О 8JrzɁqpBOtN:SJ< "a /EMt9hؿ*84Nϯvm||~#g/TǧUZffz:RVkk. lL*'/F yr`z ~y\gQZ\{892V#|QVܲ)ȿdI!ӿ4?MXd*GpMSoyr ǘCWS.:[|4߰޼ZȄisӛm{+Q> ?uA^]X~;@8/1fYdtg2& 44|aN`iϩAP,;-CɔvH:6)W&aul?XC8R $XmQe~k.n'g~Ib?_?œF3vhƍof쨴$OXkV擁IMHTVϧ*IIv qiI8CT?$'mZU6AU-WVŚ%BhQ2u[xs>n7&f(J|aꋲl~^gL=;Ξ^;BS\g~8e-<[)80+Ǯ_ϟ,,KI$ԾpaDچ8kZYnW!cv-Q5(XI/oui,I4S^;fȌl౸`YQ8Ǟ⪕ϣbXkXcSYպi~A?P^j1mkr^uϙSUYMg_< m㘂ƜuAX_v(ñ 17ccN+Pxc͡XWVpH*}Gf6  CPVdf@@-ΙVOXsnn=TBK^i9o rclϼpQ~i ۣvnzicxC+tgD3v,"\o۬͜9 TVsVtdSycMsFuSa0|WVUSfo:?_DYbZv >0^wJu͛[40y`)eq~ ͳ+:3JcgxpTthF.d=om1i$jV{`W5z5%&ecvL)Vtxyͪww/3.Amмu՛ƴcbcXD\`<^Iez;oZSqcz1h4yx?:%eo5~+gz|`yzvck-ޒbdo%7Ao( eͺiCff_l>/ oeK;pmGr~혩[&}LfI㧅~+sR˵\:l2.6<|#ǡ}O]$"EEsKX0+ߟIr[뀅Ĕie%A,۷ -=K5TASMH,9=fKZ"v@Ww ':Q^N'x}a,R)VgۙԁcV V>,R_CVagF,ÐjV[\*R"e5XVo~tdOCIpl[C<3Nq^(1wNB"TUxa+Ey5HaY鱐FbP۬$bmMSq ݱ¿[A ;߳7'7"T5 c{xdK~h{H$Td?O;y[-/pݲ 0yZ3/:c(!@`8e~nݐb]bhVr|}_IJ*ju.:bk9iR"YFn沢0J7]9N]:\V'1Kl=:ρZy걫PR5؝kF 6銭~nE}sYa!8V70I;'Y,=J 'ͮ]IzOh\-ƻy (ᤑ>vMi> OC4ψv<伍4QÎx濓ydPw+?ݼ.>ݭ㧕/ oe-@5b6=[ Lh2~V~}^r\ݳW123P;RVgeb;8{ɚr86wr:M4doLd Ӧ7&ݟ]xy;w`g@/;-#ǸvY\AjCKqTt×y׬ts˱ppxk NMY9ټL˞4|96)ax'mVv84*pL3)ǛJZ?/I`9ѲIxJ*|53n3Od^EN_4@_z$IDM{of5_YWFp}\“yAW^O`U[0k}8ܺ2w 2mQT V#4bYDYR˪m9);ޔ.cߙ?NQ3zGz(т,%ϔ%d.V֗vXenSѶbDQ\uar]eœ{l53@QU`VBR!)8*knlwhGwWR`mڶ$X7OTXc'\Q%k9b<"LZyy}l:؆"ͣ}1^i%^vxdE PC VV&1jmP Giyxr]ݖ?֦8cA>!/Vج[1OA†Oeܻ1'WWY΁d&i.Pl}}ođ`ɣycZmK˒ȿtT=d[wjUIk q4ac=zkgY긩e1/K1| * k@Agpb/~&6Ku_v?{wT}}6iҒ[X"T-8P07써0np΋~1o/𺆓p܀LP|`A*PZmih&M?Iz"MNNw]:'X.TAy6CkfaT::>pczqѪhCۃ8+j/f=~*Մ>;IP0oWO;LB;[t"GY/vzιy넑iibPߋ>CnC CjֆX9~w n :s:NrqwPzS&cg7[pBumF "PΧ¹WX'{mY{{x BDxXůӴZjUGf 8y/__rhҩcdzty<ޠ6o"n,9KL,;xVNRյ;x)|z1mjnti$RoYW_\㡞οЦoڶw .J;aK0vA\W^o;i9/ ]Fj\uTvѕ%<8ŭ>˚ܝ,Y<^p5vMP:?n5p!_:Ii폭l[zhiZgw}C,`^C.*\ %7oV>;'C;]d1gy3mj U=o׋kg=k7ixPS=êjfX[Wx_}W xmtT On뾱^=w`M[XMVࡤ,Y B۶i}<˖BIܡ.aYӕMqLnn kXwӄҭG,^^o#T@p3b!62hyR|8bzitM?{خnnOo !QOѱ1{-X>x.vKo㢮e5a '<<ŔRrR[[Gcb4nK.G[s:54 0"Dj48KXx]4Moe|raa BP].nB1 5/jggIW#BB0a x1wr MƠe8WK}#n]i '4!<>6nl<XVK̙)IjCyyUX-!ofu9'ngMBpxuٿ.V=3}MCª\VҩѠT tn0K3~R]zjz6pjf/aKtwPqc 7Y,X;8^?lܙ뾻y?gO]^0is~VӍBtjnw7#4ʎ"_1UTXP!%3o @Y|7Pi iڦ>w/wo`h_tDKM^v u5j_Q7̰T{ & ?ck(UV[Nś7׸ Suwmo' =7v0aHAV5|Ӳ_-WfroR^qe6'/[v3Bv!f#1TCx˦* r047ޱv-{9,r\3?i .u+ԅq?$Ѵ/;y`5$ی֦V<7.z$`.pc_~v*/*_E*nOLn#A\|=i=|<9x_;(*T;V]_wbLMjE~I=1` +ŕ.kDy5xkR`Uba?ux.OK@;[=f_j04put #84L{_YT~_l6654RxCH(IF3{1'5k Dro7`G*WyȮ:;@m:{khiպCA;_ M1xGqZWU,?@;5}Wo ㋶wo7;LQX+Y[:?\IShS{|x{ -]RMʯ*p(ʕqfKD 6FZ/\'c`ª\9'_M+Z 8_5 cJf:uPsv-ϵ_pek3*ʯMckC) re9?ϷD[g|UF,@s"Uԯܫb-ېۜ^g*ʯo1rfR}JQX+͋1]Ldl<;^^k6|=Mu8TK[+t-.w 8Hʯ* Fjorb@ª\=N -!F KHJZ.+5=6t,mlUq[x|TxZz ʯ*!F1pfR**ª\*.x+=Yv-xƆ)]5Coiv ܝ=w|m<5a7\{ &F'5y{:|ǰɏ1"e:Kugm<6=W5ٱ췼_~ P{wy]DT* ધZ\1Y3n0.H(BKc{LJow2xOrĘα}Yi`~2iav<?t+9̀(L!!β?0 d%K=Gټv {]N8x8W}]eۑ$9(~Fޘ%\5 Z 'ܒLaʿs YzoMWcBMn{5a7a SġX6>(&qCִ$ݛ*~ǖJ9db2hpfp`'?#ºœ֜*"o~sw;`e΄rk4½FBzՐDj01Y,҈o]ʝ-O$|'&݄ 3PXC|CZ-B1$YM':.͆jՈIT(""** knsۧ;ajFLr{gMrrlT:]5=l>񨥪ڋ16u%z^TU{0Г1{{Z@ IzDG9%ܝ׏~[ijq1}qE$E@[sC0E}dOR>x(7w1ͳꖔ NgvC}:s5Y x((KWz% Mx:|vz YYH^vŮ sz D[EؿqwCtO{黼߲7?ÞxhFPm% }14WRoWlOgOw|quGT{~/F{K3? >=V7߿v[u I+͜-9jVkDD^ \qDWSM$Q3 ;=\o/|Gymn9 Փ~xum7D8vzF)r t/T}JU=Il 3/VuT*yݸԱU|jGx#Mai> 'w*@NsO?_CjĘ1<Ƿ4yU\D_I{}0ygpseA^}NdId`gP JEXn|'0f?WCᄊ #n9oX51ܜy+ &3!/jvc26C['<'vmoo%$ٷ`Ŗ H٧N-PߨUpЧӥrVစ3c@* C"*gjfp0 U'(o%5s8wuz#QaH|'8q0SL̑"|y<3.N*bߧQ~0׎yAC`rng`^uz IDAT#*n;3o-FT0QUD4}ш'vn& Gڣ,[#1&1';_Doy@9PGid'EA$ؚ~%;>yJ߿y9/o('?Vs?=Edӷhuu@GmbxM(|K8}d%[> !܃b783ઠ*S}G2QрR>N}Fvὥ\J[ê_ȌIhKM p(laMfzvٖ>wq7?x-\ž6Y30$Du=8U`?3PYyGv̄מ5 vrmuz߇X0LՋz;?Bz|vV'%&x~YHht9VŠa^Aq_74p>ksw5G|NjhyHdf!+Gr?PiWWDVE y+L&_uV]v/@ϴ3)#׉|h{CɈKLi 7m<Sx*F` VGN2G<BI8_* GG+IUG9ԋ3MQI Hjm夾"xU oibM!4VSm^KKo`DZj !1wYf+8>#T=ÿz\W^d7YkC︃!@-{7CCzSRIqi ؁#ֳ5Hy=D1$#wvP킈d2`$"B<%߈DvQQD۠n7曟5CI$-0wjǂm]Z zzNr{:t5o^ʷ佽'd뫂.GK*Z"6Ӵ3o"u`HNNj5HxB?Ԕ@yW 3n'%aMخNs@)u=!..˛r8%arG:Up nܔ/Tpz G/m6 n7=жۑ=zFb͙Vvfc3_4:$"W~~>6 ``۶mmCwz>w[UzêUKaUDDDDVEDDDDVEDDDDaUDDDDDaUDDDDVEDDDDVEDDDDVEDDDDaUDDDDDaUDDDDVEDDDDVEDDDDVEDDDDaUDDDDDaUDDDDVEDDDDVEDDDDVEDDDDaUDDDDDaUDDDDVEDDDDVEDDDDVEDDDDaUDDDDDaUDDDDVEDDDDVEDDDDVEDDDDaUDDDDDaUDDDDVEDDDDVEDDDDaUDDDDDaUDDDDDaUDDDDVEDDDDVEDDDDaUDDDDDaUDDDDDaUDDDDVEDDDDVEDDDDaUDDDDDaUDDDDDaUDDDDVEDDDDVEDDDDaUDDDDDaUDDDDDaUDDDDVEDDDD VȥZ "2Z "_1լªª((ªªª((ªªª((ªȕe*0n@}5DEDVEk*gf΁U;:mN8 22'yjz 0he^I^;,|#[mǹƜ_Q#m\;" @D:dR<7` #"04%"+n܂&ĦW=m)"r%fUD.j\Atug!&8}Kwj]a)мW~5 `;GRRDDaUDR^6ʶqDDuj#uO1/W90шYEGo̅a q<^2gٳ4n!j`Kye>2#t:*؟:97ղNQ[&7e_Wy0Ict;?'sۖ/<6bmq*c%gg$Xl dM{U`3_ZYL-|/rΦM|i=7vRVmR+ɱ9kذ$3k"gd@xj*"VYwֲvmӿ<8=T+ͼy/{"v A5/<tH7):[O[ImA j^7&8hyJװ&>bzSPus [6{cn98[{͚l`9SEVx+/~5kp]˹'):YgSύ;3f)p RO8[oAk }ٵIi͹ǓO2w\>j\1 \ ]ug9R9""MD"9"6nf*…7q1OiMA= fvuQ,@z܊bGa@-Ue54MiLfm{mw80iϜ^;i#nc44}c?1rqV3;+yy{,.06` hu_QXo%;XufZjSSgXf-uQ^2y,t/3yy%}j_Ix}ym!0 -~.1 kg`*wWPY-e[OmSXoO{G#'_j"sr_큹-o6Ϭd=tQvVEJD.>eDX *Xc2a 2w'cYVLqY[,#&eɔv CVl"rH_f֘T8(-.m$6^^k ,1g RmKX_Ѧޢ{09Ye˖Guɩd?ܙX`5_N|dk "2Mi,ڰ[b]icۍ@߬V" "rU$o"BsmsWR«EYAeq>ooIQ& imWs%`rF,/╬Y̽#9fL77FʘYjxQa(iHdzf~dҽy()iw?I`NN`I Mew} Vy+^^$LFp"Nojr*6KRNy" "ruUaÆ}98uSY} o3Xg!+ b[ũS{j8pr.%H߾ ^=sa!}݅57jRQX )H:eߛ=q;pV9zl.Sc̝Ulɚ? p56wb Ñ"*)cRXYs߶ʜ~@}I!~@=$m@ 4Ou^ h"62((ȗTwy?bc_ ɘʈo*gaNTI0Ew~FHOuw/RTì``3OY$y'KIM׿$r`b>41lp'>AF,W֗go`%| lF lX _jqr<_g;b6_Ǧ0/?{ 8f5li"cwn'ח ͏1E;V\-BL0X#TџC%+6bf0yғݔO`Mgm 3YsX,p=9g1yL:65ϑ[e8[] cObӹgd_PuWsӛ^:SPq.N@߬ Auk2:p{*bkJ 6vF+111lpVfx^""_dVųۿ>m8q"gϾj7,;)(jsgw'bU2EptsA:xI2C=T*~ҲǑlUl_s+%)CS TY:ZKf`0`0ضm[PꯨzͿ555 "W:T/[PRXê\%.GPՊ5Uow}LZh"W¾<曵2EDDaUD\Z """((ªª(((ªª(((ªª(((ªȗ¨U r',,ޓ'"" "ryر] _FjAAV(KUDDVEDUDDDaUDXEDDaUDXEDDVEDUDDDaUDDDD!4Ϊ79@ a,d)%3~x`KQ]9id`T)9KX>#—g >ZNmL#Nqsїsr=*e&"`32s`6u wnX"h9iy-3+_lr2zv%b߆\\ɧ,atpr99(_DaUDZElF_Z>; e]GL`0q*9E/ECvm' sg!ByT IC̝ր87="h؄Yl6>I `Ϟώ0M=x$N|O#&pӞeuO owfSUUEL͊56Yޠ>{,+u,R3"rnM#{_< 5) 8kk.:,~Q: oNS_p;xdټ{aM=@G|A4e/M Y̚$㾠ZUiiL}m%y$?H?=]Ҙ&@̹p)YGEVH0rD}EEVE-9Xy$瓗ǧ<β7>`{AY葀4dgʼ\>^@7r&/aݏ~?UHOdن!Ywwjc҉䖐ݖY٧pVPkOM@"VbLr2OWs}(\ɤڙbm ~:H='}rl`Fz Y?Ja&gś\xx}ܝO^h6p)/ͅ`kI72.[} /H*x9dS .dTR'?KSQ&odkH3s1L_ؙm>6eLIP{}pߢ9]0mw[`%f"rTv 8cuf0GG1${*[bu.vtLF|'W?~= Fw8Xch3u}kAU)"2`*^ ,W 8)?5!T2T2EAF<Ȇ^KdG_x^Mfv;ږrUlKboG)^,-73fk8، S5uo)..*_{_i, h6!" ""-;ÂǟF[#LfKygx|/uЧq_@VsaV fNL!( j~x,w)yUYL,y kfE,r5o,k;/:5}⥌cۻÎAƚ]fLhGW#s1Hě'SNԕXHN8`en-N#ԩp3L3DHl)*u<<~';|_?IKM1)ofтEi:O]$ .oMf|%4U'ެ<<فX%_1ǎLZK<:;s 򽮑_W>!=-;}}HK/M[[[rAYr_W+2 rGǜՃ9^۴<_< 4wS_SYWڎܼ _J&ACo@E]Ys󝇴գ|‰)%ӝ$_~LgkkIU?sz}&l<- ={|_#rmۊ*Le\Ӝyi*oݲ%$k#7^מO%[{'|nk2NRȤџS"IЮq ?oj*KsB9RW*pQ^{[ꇻr r$ɵk:33G^;6Rα#.IwORjK7_ S3)秾8Y}羯]+?4}QxN9Yio,偫7Ifߚgdď&Ij'$:ߘv]ҤW6eܫ~ F=]YLRJ2??>5y֗ċGO!}pHTf|6ۖer&ʺ}sPgY=ْOBnh1ׯKRw~n,X֖$& b,W}YpcҜs??}bH΅Yv/s'ynpVTK+W#?Χ._X^ؒUO߮'k=O~!$[͊B$9弛r1=F/̨lwޓի 2&@|$R7g_C[)oOcӵ9SkZfu9s4 >Wt`;j\3:nX4K_b2ؕ}!yଘrY֮7Nw$ظ'|x 8]{۫T'JRͷܗ\ưՔpX=0Tzs_qȖXY9椮?O>%=үW31sIcu)teޘ$yLR1>3~X۶oMғ_Yŋ3.IY(˻ l<&gY<NK,~L#w|c$IתH{†s$Ŵ,ftlk62}o\de6r^s}N#KpEw ̂+FƬTݘ9榩"x6ߺK#'`ۗ\<۟k2k޼4MH{s7;ɵX}*K`pp;nܸO3$a/vuu=C;x;OvIENDB`onionshare-0.8.1/screenshots/server.png000066400000000000000000001114001263142265200202410ustar00rootroot00000000000000PNG  IHDRGgmbKGD pHYs  tIME6' IDATxw|ulO$n)"(MEzzwY@,TTPB#5 A 7ݙ1F |?1Qtڃw #26J6APogQHcZۭZCy11ǵpӛY_8j/w1;ˮbyʶpvHk|_D3ӱ|Gln#p7~CDLE9E$/e-ҵW=zUy((;f2*[|:] 񠸬aYᥬV]v%fNZQ#}\Ph;ԨjoSz|/4B=!UTTPZ^7.N-/2ĵ㖧L$4M8]ٴb#3>Rwq5y%7_(e/Kѷmt>-޸~d/t~PkP.7*@%k?N7s~StqBlab?MӬb&T %4$ Wn:ێYA,i4=*^idvee".7xB eQ.|m?+vaTE8}i'sD{^f-݇$Ѿ_C+c7{!Z+a7x2anYYo [^y/Y 'ƶ$c oy*_}6v JwQ64y oj>5 ڛ;.av nwrŀN|\2s7)C(߼_@o6{|)ː=޹%I݊va;c=85QMM-P].)(ho]V\1MQ̚vpEQ4[9=ݹ=nnzl<vfqPQV{[]SۓK\x"b" @!'w -c]ܧĶei=@m[u{o&Lƾ_?3Ӣi߻0 d_ĤĞƔ`q-:;~o+,!}UP[J7|ӧӮt MٓĈ~nqqmkmd3t<4N#u^կYpVMIۇlU3<ķYQ*И>mgӬzid_Fڋ< 8s2MLs.rP:2:xh=/<%[4w& k\?;!ɌG\WٚomWRmm`bUT7T]=M#y{>ͻ?l娶lYjUu:fZ9fe&bTDu{UhiB^7w;+rV7Z?EV[A_w3rpE9E4k@ Ҋ?l V&2/s_+y_U[xw{>iLw !UI?-M$41J#6MPӴ`ZbҎQ}<i,eO6@7a4 4@7O߬_4e;,ᵏ拸GԤwկG;kiM=;0ٿLyfݪ:ÈVF$ʾАa`ȀBYY9IǮ̢ϥ PkQ%@U)++s^Ⱦ,.EHH(XsTu,-/o3rЧ?ѡ_Gann~>xb)騪Jo9,|K%ؽe7=t{7̷XZP?¸v1LiLLP4Gɪm摯TҖ& Nx] /f'cw>^/y?`*5mo~ݏ=C'Y0U@,(Ķw2vW^۱ñg_6o•[x @q!y[c{7K f0ykpoidBTU!3y^Żj1EE ȁg$Rnd٬ڋ$Һ[!~EkD7BT¢ÙٛFtՅveʬxfgߦymrb.>}0XUUc&CCqoW":Lkj\ՆȘ?kB$+ބqc1M2Bf\&^Jκkn?ѯ]NiX5T(Z8;8\/K> 56Տ5TpbbႻ>w&ޜ¼1~[.A60I72 מ^ @Ct1߼6ֲFJ xE7e˖z}hkFK݀ ѓ{h\{(eBbF p5=r|h?LjE:Iùh"?[Wn«~G`s:017>[^Ʈ55u@~^:ݎD=eWVA㴫`y~*y^hᘖ&34 MK7PWd]x":x|"rag2(-7o,xV/6/ȶU(y`W:&%˄8\8nڴIQ!bS0ᘑQ K!r>+i(BQ!$BQ!$BQ!$BQ!$BQ!$BQ!$BQ!BH8 !BjPWav]ElU!)*BNDOΏIMz6RgBoê*ܼg}6֭ RqU4M<躎a&(Bll,]v%%%ERq愣(Y=Vχiil64iR}`rQ]uš:B3'm6Z=k4MEs~iI||<@@Rq#@VVVuF[g8 Po޽Mdd$Zm۶lذARqzcU5^]9Uzu]'$$p )//2RRRhҤ BӻrT0EAu|>_|d0vӬY37nax^)..0 gO*lal U% &&V+( 8p"(--BJKK)**w~~>^ |>N5kFӦMu/_,Js2[kk]EsK~~oa;/r> s\T_#$eqݽϱ,k+{OƠAqˬ9Œ1 3]ᮿO}9 E GUUQUsQkݎavv;NȪ8UaPYYIHHaaaDGGWg,;y.zI […hM@e+^ڗ2Ō̌( ΢^;%|sKg0h> oM5oA;&ҧy[KB?Tqmcxr!ćkHO'=-cy^$?wVH]96i҄f͚KLL Ѹqc&&&&MM||Vp]}^k.˗ɯ3ٻq:֫Al/ih*7W<Ԓ'ͪ~!nZf=t\3S{׭<;Y@npK*w!~.}KaT=/Y*ţ8i^o}>at:)-->!\UU*++q:n>iح=f;i^.{۽ t|'Y}K@qE}2p ^7(ޱE^0pSPWrh{n`9a6q,:pLfm6g^Z;'4Nc , v.hY=Sz kɿ>H6yzEy_!8 Oޱyл x?! pM2olVJNƼ7R%]9G=I  SdTR7]I {B>$DUU>Kll, sYgEll,M6iӦjՊ(G*bٛ1"@+䩡3 b&S ?8U֭|p@37teMAjfNfL[Q:).ٵB_NjUR/$Obd{pvIw_y~Ea>wu;>Nm{r||sho]rW{r TCؚ0,@n_F6WVYHam ѡΜ{!dlw@k%) ^8BKU],92m&.z|p*Mд#_[DrХ`.Vs>_/|ȝL\l"<=Oo^Wnp=ING擭@ _>gևNaG\gcgtn~w(~ ^zGkgOAvLZN:'pיLHw"VfR@U~F|xdR?0YtzB ~|Y>q悶a2{mfMPp?:[`Utx<t]BBCCql6p8]UaV|g7$o eoS@K p!c#&н \wJsWQ ZA>!<:?)PQAfu)#WwȀTRnM<%(bhv\D 5kq%+r~)3r44MǪ=<\Gl#;8CqOquTL<ǚU\x#i\~i!cM䇫ԩ*G ">,ۡ'y0Yr%EC G~#C ڎk]uzOՕy~?P0@XƲ{6>d8.DʪTTTt:?Uu9~BBB,zX IDATp:a(iA4=MֵQcJ~Ng8V}WZ4"##"Xu!'K8 !ΈpTf͚ EAe@fTP ET8Ti]4 T놂j( /(hXcs99TlUIT3`aU4L4] Wb 5 \ ӪHQ ߠiT@4@Ÿ{B4tbGk,O}}*N5NE2ſb,dguo^CY/&=gyƂö n31G1i\(w's\g< 0zUƿbQ)p<* (CU0  M oST s úV|tݚ zT={)qOÐ7k;ֺ5+6W?m!LIA%TVVR-dC+i*Nؘ[ьWq/NgOFr/4{h6gS~`<Xi V*!xܕniBNUа6Xft6k`H#XmBp:iX]n=4nvo&3&oཟkrQZ|Cugք {+*9,xvBuu׻+8- zﴯ5]ܻ)foy6;?0x)A0IͣqYxC]YU+X>:+#U?eWڴhA6=z&LAf ~KH8bb /%p%xY'ܢ ;pQ!ZhGvA>GӂUS޾%7|ךoSSj63v|GFyahN/ mɟ?3 û%F״ذЌyi̜4C4i=7'5kEYl ܷA6a{Se7IVOr2rm9;̫?gx^v`طs 73U~^5hbhIo(We};!TAck?{#Ln&O@`a>aYBf`Udk\UEb6*B[4JiPoШU^ϵsp]5V Vv?@`wG3 <^ KWZGaj{C#h{f"+s ogyRY _I%%%Lt/fTGSBM5VH+xZ +*XAh7Yfj=`5G׬S%&1@q1^o1[#ۑ6^n_{fd7M|9z :R[4~+@Y+(f$1!0Ox O?\m⢤N0F*w ]|7w![Kj9a F UsfO@ @d{L֕FXPZ0.1v"Ks*(Kϟ !qqqӬ9AHՏlز 6j?ͭy|`ydCӂGQh*l05#8V'W}P ܩZU(jڦ>;} j ^G!_U AS遥'SiVeӨBQMnUeRkt~38YcntBT*x93U@Mռe˕aZbaclvYa..Q5ׂ'}cԜk4[!!!l6 /َ*M4s<M4AUU~l3r|Oҝ,1G[" f0QbÊOsnꎰ^B]Ȑ~.ƹkjty ,v׾(L[Wsh5R&y]ZCFQ~ggޒt6%K4˝Cy9KϒOiҥ/tjZ&}8l8BN/[wg/?ЭokkGmآ&|RY–;)ZTؽ/"b<g.ᔆcHHs_zI2`gV&t?Crvd~|d`m2{jp7;2YTcN!:tYa;wne6|WXԹ]tr7`̑*+`Ѽcas`:eU!h챁i{ٞ'/M- vc;P0''p_l?9K>߻^q+VzK{U[aYb.n>榬ᰶs /IC#}9VoaDǾ՝V3퇦`)՟tGpÿhA&}Ȅm[Ӂ!1i,XQ5nm#6w] JkFyɬݖOC孋?aޚ@$I}QZv䩓$٪.֌l]b]5aϛҪE]0E# .ipefnV:qdPӭS':KaI9Ɋƈ#ā`px6FZZZNJtk2y9L_C(fYf7G^-׎eV>rNS~֤tBN2xe3f7-ؙ `_؜ƶ~Hc랢|01td;I+G)7?cҞW]E=mQv K7 tię$pvG9>V:6y9gXޓ)Kxujt>ψ=h׫Mo.r[v 56'fszư{*P:p tnEG@N9)nd_&5/~܉?+wǦCՕ [QQ:N1yvd*OO!ս%gg׳<2nUeTt8?uwО3Cr.k-g1ؼ֮ ?"=v5Orw[1zu_F%rfq[Zǒ /"\U߭e\!zޫ=䣶-xҔlYkˮ53IJ4!&xrߑj#9Vv;e-gs1;cV-ź`#I1-Ze#[^au{VmOb7ж]\6kt8HsJeq&ǜD{vیp9||^}G)UZ;\!yPlw&}IF{af@?FR94>6يF|9 6Q &)8q徣9Fq8^ԝD;(ɣ[{ؾf+AοQߴ/ʬa]qYX]QΪyu %eApqP_)}Rhhٮ K~}@Қ' >`T<8(ߧsDtJ@ӭ*ەwrqs>4;H˄7}nazQ<sJVV@lthڔ6}g,uRk2^җg3`G=}e0W_ ط$eO)%m\lF|<#6k4NhAhM;M)NzѴi 4mڞ~PJSH)#1 ~,Z ?9%_i)/:pv;5| +2KΘ\6s6mF x場f̀8B3`d4LK:9zQ^mJwȍB鷺' ?lIǼs8#vų4B|a>b!K;&WL5}xu C;6x9֟+"ѵwFDi҇h8F8Ns2_>;7p=\sPsmʜBH8<#nQVV&{il3!P_`tسgǜRC tJ_Hv-T4z !{P}?T͆&44~DB돶l8h07KNUUOڛCB돸{S9*/ U BQ!$BQ!$BQ!$BQ!$BQ!$BQ!$BQ!BH8 !BH8 !BH8 !BH8 !B~NV=렵aݸS]6i~JKK)//a3h՛p8xE!!!(yG рgL$&&qHyo=v0$|+__.o@fuC̐2 F&?&+o>b1ƿVz#֣$Iǽ$ΝU(kWvGk2m>ڜR IDAT3pW']|~YWv#.!cuT.sg\ H,ҿ_qvad[XO\lvMƪ={aG3ػDk-v֝a*3 -ShaVmiÿZwirq}{[9ȩ$AZ*-~0C;CJ܆qO &1ޖwfېsիϝ:ˢzrF~yߺc}2f0߸1<}{Pro38#H;1u-EKDkc'Uj.Foj~$wϩÛvd!Fpom\0Xpǿk]t=ÂXb^? t_0#D&':+Flo$sAA?Yǂ߶ Um;3mHRYc`7|#YP3D>:@NVh۬f^cJZ-{2cuU7 8%#,ŷl# VHwJNQMND5#= QqO?E%YOi'6bskkzT{8 cd}U*NqL*XҼsg7xl&i>\qH (Lz{XuL^MhgFUl|< )7U/xf@[S $]-Y1q;&Lpv(P`negƥ#y SLBԱ$dkզQk4$YMM0f'qfɜ&Y渏0)s%[gȏnw:;;WY8yȪRIKʼ,UƢ z72 3]]!{]S2a@?]O#31?DWyx%Lmlξ..N^OFnTOc32ue8/=ޙoLkt탗:khSuv@8̸3)'pkN 04eA EqM'TuȠ'1 NO)!Q?ϰ:&&{{{^HN*QW FFe3nLe&,i,FPs;*X ޾q ˙QoZa^A59PD[A VthhR2Tz~2cccnZ- Juңzu;!JS&ŕ%5ή34`b 5aXZZr*3'/[h.c`n a|x-AoEw3ݙ(&cBǮZGsܚ[Оtj<4˗@.p1]S9 V #\.'--M:-'-- \/vEbΜ9CٲeTҿCL&vo0h4j׮KV$Iܽ{trrr7d}}}033rʔ-[ wI$5 $ q"qC&1Q|x]BO1U Y4@ q!@ Q 8 G@ (B@@ q!@ Q 8 G@ q!@ Q 8 G@ (B@@ q!&0+_KޯQZy߉`޷빭K, &w.AWZG  fHgʊrJ8G/''xECzlGX8'UɾyD ^8>Je#Ӕ$QbLr.ŪFNCqt>'Dg/x`mN77E &YG4=pOt/2:FhRׂUGPoT߉`hTpeۆE0˴;FŏwWigo OIanSWT!5Gmº8&fYY F=Uwp69~k{B O]W4zn87."=y&T}F:aep4wuICRrss7}}J.M2e066==7R^/)[$ \A!%@yt }0@yi Ư; %&H@;ä`$:J JgRVIJRiD%RR))6H>-)b&L :x mrZ vʝ(9?K }4b9tJ"݊N< uFvTJ'[ \E:W[~PbbKD_RJzy)~ \q⪝mޏbT*؝۷ .HQQQRzz$xKQQQ҅ ۷oKZ. 8kUQ~l=' k1+˩ \̹&yQ|"m~OK c|8v>u3Y}W` HxmѓU3+ŕo8NJ`cEd84~@ ,1G bY;j 0-ɢ'0ڡuL1z9QnD.ˡ p\”N@Kɢ'1⎬398/a$VqTѶ×OʐLzq}Ӿ*HfCi4ڐs|Axi T|5rZ,Zv4q?;+] 5  ¼F8 C91L xѡ duYKLW*!a fҦ]B75mm+:r[%"| =&˹x<r;b'4^GU*4lPy *PBQT1GkՊGm 4=&F'ـ]W4/>:#ahZ $L>(>%LBwԵBoX,r :~ 99"NңY(R|aBm$(Sܱ<=\y\@ 6! A~?QwmlYTϣ.&pnSNYzr F0M6p ^ .Ԫsuqg\6Џڼ[BfD]yԷEEՆ@ش6ir}Tc&:F==hރGtex>EeZL´S:o.>I.cJWJ߿?A+xEjne2YO 3ȉ:Q(c1la!ԜfV:$rw!Pzi4M<9L~s9k跁r{ҠI/;^و295V`ӱip*O$}f9*~m]zA~6tyPxߎՉ1U$ɭ۷؈zZM0(R{t_bbSP*k Ͱe )MfWFZUyB5 MV~66)V!piU}Q/Z/i99TXKYԥ57׏[pH['k:9@}m'+fGvuϋ,YH`DA3;ȅw]}jbŊX׊ Zڻ!H܉OAs#EMnJKFNSX@fxV™Z1aS5:5gV>@YZ|#`$X7yJWf|]@0HdT=`#Uߏ}b~RkA~|~ !MτH|TԧO6d)'(7S3\ʊh4*N\Om_vMs"EHs5D ?YѤx5Gc36M ehejHrmu"!Z!o -eGڊs.7/YzKƱȯ=ÃQ9ko|4j>Yn`vBHw8J"槡9րx (P2$+9}6Jp̏a`^DY.57iC+,:ߓZ#,Hrnԃ3> _}1ə]cP`٤+uK * hWY-tC5Z f)A@NaLRfs~R8}I=F{V/kZ^,7C}۪VVu|Z0wƟupl$f, tVX6ZTZЂh)!eqӛuj@ }12NJ/%Izvr(ͬ50gܟhThgsNZ#7nLe'n>:ˉ;%]Ϻރ׫/=RrәP*\5jT&R ݪ9Ȱjj}+SHAfRj‡zy1@MYB$gAFYnL r JɝL5XX(tB&:Vi9Os.|$C-B67+F ۿ6J%GmcP,gƦXXtRXX.a ż+rF2{S |K^JNɶc4Xɾ+kt^B`|ęG~|qoұj6+NYxBnFñ6y3zNKJ?-ueoEqr 3]W> ;GF^Lh\;8* ȼ_]5m >p0"^ QOk z,鱱,5M6VhR[ĥ@LzX]֎TSSIMM'e~%]7QnR8ӿ}b 9zV͛GdqطE`щZٳa Yɞ17Fx0*bc-KP{ [~Np` cx1{'#:kƠ̂dn fpPh(RUs*cn^e?10"23L%Ⱦ9'tBo/p ITwq۠pr[k&<+S֝ke4l]uZItѠL9ȏ"e\{iqGg8Bew㺼Υmu'38Ĭΐ%!d%0aLgf_:xEHU~!WlyXnC5,1.=;i\,#7)kP> } w%oVFtpCm=l1z[m@S|$9CJC ค2ŏ'cVssbtW3bxƏψ U' C&'M+oޜSjˉea7vĩYǷ=8$吚J[NJaNZFL9GD~dY@Μ#;ɩY$. |v rnr<)/[H#9=6-"Ñ'ΠHĎ)ح}Q IDAT//6&M͊ .8 Qл8жd%ngvUnNވa' |'Fahw҅2 I>\(=uۏqOn>1zQx:ϡ Bz@1C#Xc֙0sr?,enˮy9俌s}˶qwjtG/`kt\]P(~d@~–}~x>;{8gbEoαIO>@q 0A!ݱ)n2r9ܓEwNs磬l ֶ[Pqj",\]-@CF*ČLW{JLYL$:ܲƏYܽTb(*9ĭX䓚ƘiI]pՏO~z^155-N>WI. s">npX0̴zo/r1L.+3A50?!|#ܒE(:kL4yFf%5ԡ|/?-yكӂYx բLmkЬh_\x4úPa]dWz: Hr ZYE'dO,P,M5f:一=C[R^], ͕o]_G E'Sϊ;PP{mÉƟ6ϙ5m4MdӀEtnƱ"uV}3<`xրK3[{,9)7jiC#X(6ng NN)CݚڷGYnƕ o?S;ZbR 56V~ΚYn L̔Ng*aJ ? W< H e6s[׉4ͧp ECtWyG0d mF*pAsmk};m /2Z21+IJ c9I34u(Cs;oJ.F1NsY9h=}g}4 s+-$+|=AQЬ%.pa#O@ϡO%j8FmA. ) u z/Ǚ(Fq*}hcҎr@);^^]X֩w1 cqb"hfDΠ߸K L-L_mp ç$7p h+2}ՑM'حMF!RZ^|>.5c:0 }NJ^[~ck >uY Fd{YqԷᗳ;0ZՀ='Ϻi^oXrQ/t{b?mLmXϋ!`VNcCe <۟+1LjMșUf$<>x\$KΣg`M8z0w'\1{m{kޝuJ2T|oJ\(5mރ"O%%ǡ+huqC娑N@`fgݣcXNvMNVUO,N!ü{p"F;wWdhen5եvp&]`XWݺ,؄r>܊2`*.\ӏ_#,0^3iiion 蔷.6U &47UOGA z^23t; Wr»54^BRjjCQ;&o>۵0“Y. C/&miRjcfӾ} #ax!:EZNo շMgT}Bs LU a'wd00eneeİꋎD2apv 0B ȺڅNH\&<`>rnt d^BSBZMV|v>42I'22H""ӪwϧP3cӏ=kqop:!&&X2űDȨZۆ 28Z-T߿^ḴlٲܸqC(ƍ-[j9j{dҌſM"'^=y4O+]eRl  לU 2k »] Ftҥ#3(yìn1^֭e?h_\0t"C.߼CatNWC~YY]6֚hnlk76)oBFg/h-~ρ%@*V3C2b-֍מh8{O{qڔz76:2 8miԭgi5Omȧ>~q k>pt@Xn8,,{}-X[#YsvMzW 5mnU@֥aUD[ ܔ*3T ~37u˗?$""ڵkSR%bTh4XZZ9[/KO[ 'SG-La .vThg2V`^Td”9OC$߿ݻwIOO'''G|CUSaffFʕ)[;5KI_3fq&cbSU'ɹj4şIm+ppN/®)db$ F$IB_8!ïϨ䐕c- 5u8dR>=K7ɖRXi+&m˯a9KBwlRƼϱK4iEWƦI["ȩޤ5lu_gPSbg`29tʟÉ 3 jm4?kS0jL3iӮ\#kdK%kmc^ߞ-wҠ=PajݘZ!R/_W}3d~7Y2:&(?h#As r|!TwTD`BMBm6.y}N_B>Zt(gcܺpH"##}/v1,kC)?VkȽ"W/[c- JP3ڄ \}Ee\F.:15nm`6>U*U1zdvF({OEC֐~)atb{G'l\uiZ0>yd5S&ڑX[d[Kz ue 4ci/]=]=a2Gc7b3J}c/k1g[/1x = `;oz 1ܱYIp oN bN|3 #w=R)2WgrGB#caxOf +Pȋ))(LQScy2*05=U$ ZXY3G@ w#!@ Q 8 G@ (B@@ I)37 ƻ]M& i%I7R*Ow{QA6߲uL>F/' Kr٨ #wDzؾX,YO^=<& լ\#P܌ϑ[..Uùwo[VΞUfT*R<=U2DNY4EU5d*3+0='|hk%?+!#&r9)qq|Դض;GӨWRvlOL̎b`-'% ,OsRv콾r?)]@B0p Ƙw.X p /(as{h:7>i1eW4,ψbF='V۰(xCj5 ${ !ju]ٹs'AAAq d' {ҩvqaK8l'1]+-sj1,2h*_ rgVZņ]aćB~ QY~^qͅÉXH {zdBZ=G?o.bfpʛ1nKk F{U싈` Щ1kFP!_/+pp} +ANĪ;1Đ. [>6%# nIV/跅Vw 4GQ0c@WP"(AbB&ɠ 8h,MʥXڡrVEQ`7 w\¹9]!gR(#g.[ -=qˉaմ/ 3>#@CVF5cCQ'>0IطF3ͶgD.Lg/zlȈ1;ȰN^}>A]04][L쳑[P9=<ړ$*SBe [\l}P M0v*gK4Tuel3I1ۗY~K|VC\5 B1dHQO4fTxanelS4/!e@ rk$<4}濆9'iZ7uۻA~~14 ۙuAv%ZZOC~&tm=\G"| bNGIdd{0[c&O^:[ ?r]Ң8Nژ}2k -CND%}h 0!( p.jM5g.On=K~_ieƴq ˘ܴȭDM9f 0(] ӵc7ɣoB-ڍ5i75љˎW7ߏ=^7ܩ9cў?z/=2317_&mDzmb{>b}6*R3Ȍ0}ШHR/ﺡ)7ܑ Z+9'3B#!G@ (B@@ q!@Vsa9 G@ (B@ Q 8 G@ (B@@ q4WKd@gSjyS4)\i~>Æݮ3 jdς~n_Μ,K&w1ٮcTmZ\.?'KN}'r=f']7i9^-ͦkF(d3~̓WK( iHi~TuKh1]Z1.(P Xof׾ a<{5oEgȹ}80K>= deͲ8b &14 dϑ_F; M2f[q^}swzPʬ!`jW OIA#{;+72HLV7]c}B=Kԭҧd[&YӼ`dPAS'Ѿ7MeqY3!KB/PP(PTʣZK`m7MXMLNMC@o)[4aV_ɁOyfFhG$9@nRc6_*^E3T7Y;7s]g &KdM f@o/nG N=sQzٱ-ΐ%jo~|OYɻd"3uҟO%\Pk:3j'u+4Nsy\fM#޳:k~>+47sVsEfDM듺x|˞%Pe"MsvN8жRR  ˉ>ǂ=[1X _XFD?ui1|sX<&>WI. s">n8c{- ;χsVغzrK'Οf=#/xuu|>bH?׳yz<eK7'z3Q;1$xuNEawmIT5Ѯ?8tgPsTu֦ b[|.}8674Al\К)8-jǎǸ6E+ VMk pm׍&4ǧ[fҩscJd 6 2nWx+OouLI;o Da ER>Y5K{Ͱ3o,0ʹ9p]IDAT&-ygοfPlIc_O\jx(:4{WߥFec'1.poݛ^.w@MM~j,:wO|9np4f2 #`* j߰|kG,W LײX'Ν,ռR@iTӡ; 8  -iXU y] eq$"Ig# ULt{6;K״m=KBW P1+]+xs / r:tkŚ 58M qFp? Uz=YW T\/*!<ggJ3 2rd_>*ܨRQ 2r^Vhк/šLL¹hFqcX|7Q?ƲqdW >-ˬfnIFi04ULo^}Gl kq-;A ˆ |N.ejyHm ]RR|" vA7w@rqMpud(2CmG-:rgePQ[asYVP%t`Wt]:pQ&dxH' ހHh~\bB7RkjPLM/{֖&:YQZ$=}z;TQ4P#IZTlQk5V13a0ȨZI1!+*4׍LF 2JN'gjD6)J8. \d^"UQg2-,.9zU0UFԩF T*o0KJ-T{ZSY!jiuko:UQ(H4wwѫRTsmo0"!t6ګNPcVF+U[S5TPeZ6G;w>+W-*XWCN.tx#KƳpt(a&g5 ^O Ivjg0#h>zNlE{c˹p6~FiV?z?ӟڪ-|y+D,kF^ Mks$ 6Xorupt²FmSQk|%ܟfzmz{;C& [ }$ IxmY<*p z{+ٵ`4Ne5AdB0{GgZDv}0}6J[gᾬڗUፌXoѭ.dӮ[V޳P|&cvax|^5^>*h#5t$$ʢ+s)xz\|=' [ܛZ,vXrL q^{>\~}%It>`=﹮@4?̑twY&>I̺A#9q-ɤ&ᵆWr (Olj;h=@}&Laˬڑ̾/qd|g'܃75=6)3Y'amZz/7ӫt>NNc?9M pp4B:Dh4wg~Nٽ`@~c$&nmt+2&Lfȣ+ :6go~6]~RhSlʊwUZCWZTqٙsGdfڐ7̾އu&¦9gVٙ_yFL甁 閙tܘYƯ0M ]_eh:_Z PvfC!dR>(Bb=J c92O}UhRR7ߋI=d{ZWˇ=pT2Ǿ> bf.s707۳UFSxT*2ZsS0]bSH:wxW0 X#M9zX$I6hPiUmAoCوg'D#51ZOwk?R @d_?$I$Iz5SޣYT1 tlbsmne-i0jZH~dt`pbr/zI=w\fOqRÑ;ڪB>No (9o6%>Gv`b9hq|!_nmYz \ִkŖn^ʲN<0sz\==u1u<*獕eHxs / rݜp m+sZsT̖}!xJ x xǎ7q+x]0h&t/uWi&!a[dR(KgI0xq(xE'Xg߮Iɦw}TA뾰 k21) Rw,WG vr.b?P|]c-,ͤ\2)\=ϨwJe{\SL\:CQ[)3*V2 8\7[mK6|c5)CGi>t-wS<M7(iPd`Oс6ׇ@}g5jaa0(+*wIXku2KNT]d1d\:k~oԚ#5n Q6ׇHeY~A!| `:P(ui Xԏ(&0M_?+ޒ<j0,~mvQ8ME 3AX Τq2n<Çuǝ߳>&DžF nj̝؝9+22/ miݤMD̠>}۞AG:NPP}i x_|YZ gNx8g~";b9[?(zF9K!^?rpLV=J \d$ t_7z. *NRWJz#*IńZFjVSE'^e@tRg9=&H eZ?%[[X"⢴H 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, platform try: from setuptools import setup except ImportError: from distutils.core import setup def file_list(path): files = [] for filename in os.listdir(path): if os.path.isfile(os.path.join(path, filename)): files.append(os.path.join(path, filename)) return files system = platform.system() version = open('version').read().strip() description = ( """OnionShare lets you securely and anonymously share a file of any size with someone. """ """It works by starting a web server, making it accessible as a Tor hidden service, """ """and generating an unguessable URL to access and download the file.""") long_description = description + " " + ( """It doesn't require setting up a server on the internet somewhere or using a third """ """party filesharing service. You host the file on your own computer and use a Tor """ """hidden service to make it temporarily accessible over the internet. The other user """ """just needs to use Tor Browser to download the file from you.""" ) images = [ 'images/logo.png', 'images/drop_files.png', 'images/server_stopped.png', 'images/server_started.png', 'images/server_working.png' ] locale = [ 'locale/cs.json', 'locale/de.json', 'locale/en.json', 'locale/eo.json', 'locale/es.json', 'locale/fi.json', 'locale/fr.json', 'locale/it.json', 'locale/nl.json', 'locale/no.json', 'locale/pt.json', 'locale/ru.json', 'locale/tr.json' ] if system == 'Linux': setup( name='onionshare', version=version, description=description, long_description=long_description, author='Micah Lee', author_email='micah@micahflee.com', url='https://github.com/micahflee/onionshare', license="GPL v3", keywords='onion, share, onionshare, tor, anonymous, web server', packages=['onionshare', 'onionshare_gui'], include_package_data=True, scripts=['install/linux_scripts/onionshare', 'install/linux_scripts/onionshare-gui'], data_files=[ (os.path.join(sys.prefix, 'share/applications'), ['install/onionshare.desktop']), (os.path.join(sys.prefix, 'share/appdata'), ['install/onionshare.appdata.xml']), (os.path.join(sys.prefix, 'share/pixmaps'), ['install/onionshare80.xpm']), (os.path.join(sys.prefix, 'share/onionshare/images'), images), (os.path.join(sys.prefix, 'share/onionshare/locale'), locale) ] ) elif system == 'Darwin': setup( name='OnionShare', version=version, description=description, long_description=long_description, app=['install/osx_scripts/onionshare-gui'], data_files=[ ('images', images), ('locale', locale), ('html', ['onionshare/index.html', 'onionshare/404.html']) ], options={ 'py2app': { 'argv_emulation': True, 'iconfile': 'install/onionshare.icns', 'extra_scripts': ['install/osx_scripts/onionshare'], 'includes': [ 'PyQt4', 'PyQt4.QtCore', 'PyQt4.QtGui', 'jinja2', 'jinja2.ext', 'jinja2.ext.autoescape'], 'excludes': [ 'PyQt4.QtDesigner', 'PyQt4.QtNetwork', 'PyQt4.QtOpenGL', 'PyQt4.QtScript', 'PyQt4.QtSql', 'PyQt4.QtTest', 'PyQt4.QtWebKit', 'PyQt4.QtXml', 'PyQt4.phonon', 'PyQt4.QtDeclarative', 'PyQt4.QtHelp', 'PyQt4.QtMultimedia', 'PyQt4.QtScript', 'PyQt4.QtScriptTools', 'PyQt4.QtSvg', 'PyQt4.QtXmlPatterns'] } }, setup_requires=['py2app', 'flask', 'stem'], ) onionshare-0.8.1/stdeb.cfg000066400000000000000000000001641263142265200154530ustar00rootroot00000000000000[DEFAULT] Package: onionshare Depends: python-flask, python-stem, python-qt4 Build-Depends: dh-python Suite: trusty onionshare-0.8.1/test/000077500000000000000000000000001263142265200146475ustar00rootroot00000000000000onionshare-0.8.1/test/onionshare_helpers_test.py000066400000000000000000000020121263142265200221420ustar00rootroot00000000000000""" OnionShare | https://onionshare.org/ Copyright (C) 2015 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 onionshare import helpers from nose import with_setup import test_helpers def test_get_platform_returns_platform_system(): """get_platform() returns platform.system() when ONIONSHARE_PLATFORM is not defined""" helpers.platform.system = lambda: 'Sega Saturn' assert helpers.get_platform() == 'Sega Saturn' onionshare-0.8.1/test/onionshare_strings_test.py000066400000000000000000000026451263142265200222050ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ OnionShare | https://onionshare.org/ Copyright (C) 2015 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 locale from onionshare import strings from nose import with_setup def test_starts_with_empty_strings(): """creates an empty strings dict by default""" assert strings.strings == {} def test_load_strings_defaults_to_english(): """load_strings() loads English by default""" locale.getdefaultlocale = lambda: ('en_US', 'UTF-8') strings.load_strings() assert strings._('wait_for_hs') == "Waiting for HS to be ready:" def test_load_strings_loads_other_languages(): """load_strings() loads other languages in different locales""" locale.getdefaultlocale = lambda: ('fr_FR', 'UTF-8') strings.load_strings("fr") assert strings._('wait_for_hs') == "En attente du HS:" onionshare-0.8.1/test/onionshare_test.py000066400000000000000000000022251263142265200204260ustar00rootroot00000000000000""" OnionShare | https://onionshare.org/ Copyright (C) 2015 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 socket from onionshare import OnionShare from nose import with_setup def test_choose_port_returns_a_port_number(): """choose_port() returns a port number""" app = OnionShare() app.choose_port() assert 1024 <= app.port <= 65535 def test_choose_port_returns_an_open_port(): """choose_port() returns an open port""" app = OnionShare() # choose a new port app.choose_port() socket.socket().bind(("127.0.0.1", app.port)) onionshare-0.8.1/test/onionshare_web_test.py000066400000000000000000000021511263142265200212610ustar00rootroot00000000000000""" OnionShare | https://onionshare.org/ Copyright (C) 2015 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 onionshare import web from nose import with_setup def test_generate_slug_length(): """generates a 26-character slug""" assert len(web.slug) == 26 def test_generate_slug_characters(): """generates a base32-encoded slug""" def is_b32(string): b32_alphabet = "01234556789abcdefghijklmnopqrstuvwxyz" return all(char in b32_alphabet for char in string) assert is_b32(web.slug) onionshare-0.8.1/test/test_helpers.py000066400000000000000000000021261263142265200177230ustar00rootroot00000000000000""" OnionShare | https://onionshare.org/ Copyright (C) 2015 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 tempfile class MockSubprocess(): def __init__(self): self.last_call = None def call(self, args): self.last_call = args def last_call_args(self): return self.last_call def write_tempfile(text): tempdir = tempfile.mkdtemp() path = tempdir + "/test-file.txt" with open(path, "w") as f: f.write(text) f.close() return path onionshare-0.8.1/version000066400000000000000000000000061263142265200152740ustar00rootroot000000000000000.8.1