pax_global_header00006660000000000000000000000064145657336010014524gustar00rootroot0000000000000052 comment=c4202556568647e83f4ef0485d3620e50ea338ec torbrowser-launcher-0.3.7/000077500000000000000000000000001456573360100155425ustar00rootroot00000000000000torbrowser-launcher-0.3.7/.github/000077500000000000000000000000001456573360100171025ustar00rootroot00000000000000torbrowser-launcher-0.3.7/.github/CODEOWNERS000066400000000000000000000001031456573360100204670ustar00rootroot00000000000000# All code * @micahflee # AppArmor profiles /apparmor/ @intrigeri torbrowser-launcher-0.3.7/.github/ISSUE_TEMPLATE/000077500000000000000000000000001456573360100212655ustar00rootroot00000000000000torbrowser-launcher-0.3.7/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000010331456573360100237540ustar00rootroot00000000000000--- name: Bug report about: Create a report to help us improve title: '' labels: '' assignees: '' --- _**Are you getting an error?** Sometimes updates in Tor Browser itself will break Tor Browser Launcher. There's a good chance that the problem you're experiencing has already been fixed in the [newest version](https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/tags). Try installing from Flatpak (instructions below), or [build from source](/BUILD.md)._ - [ ] I am using the latest version and the problem persists. torbrowser-launcher-0.3.7/.github/workflows/000077500000000000000000000000001456573360100211375ustar00rootroot00000000000000torbrowser-launcher-0.3.7/.github/workflows/python.yml000066400000000000000000000006571456573360100232130ustar00rootroot00000000000000name: Python on: push: branches: [ develop ] pull_request: branches: [ develop ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Install system dependencies run: sudo apt-get install gettext python3 libgpgme-dev - name: Install torbrowser-launcher run: sudo pip3 install . - name: Test torbrowser-launcher install run: torbrowser-launcher -h torbrowser-launcher-0.3.7/.gitignore000066400000000000000000000005461456573360100175370ustar00rootroot00000000000000*.py[cod] # C extensions *.so # Packages *.egg *.egg-info dist deb_dist build eggs parts bin var sdist develop-eggs .installed.cfg MANIFEST # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox nosetests.xml # Translations *.mo # Mr Developer .mr.developer.cfg .project .pydevproject # vim *.swp .*~ torbrowser-launcher-*.tar.gz torbrowser-launcher-0.3.7/.vscode/000077500000000000000000000000001456573360100171035ustar00rootroot00000000000000torbrowser-launcher-0.3.7/.vscode/settings.json000066400000000000000000000000551456573360100216360ustar00rootroot00000000000000{ "python.formatting.provider": "black" }torbrowser-launcher-0.3.7/BUILD.md000066400000000000000000000016621456573360100167300ustar00rootroot00000000000000# Building Tor Browser Launcher First, clone the repository: ```sh git clone https://gitlab.torproject.org/tpo/applications/torbrowser-launcher.git cd torbrowser-launcher ``` Then install dependencies, build a package, and install: ### Debian, Ubuntu, Linux Mint, etc. ```sh sudo apt install build-essential dh-python python3-all python3-stdeb python3-pyqt5 python3-gpg python3-requests python3-socks python3-packaging gnupg2 tor ./build_deb.sh sudo dpkg -i deb_dist/torbrowser-launcher_*.deb ``` ### Red Hat, Fedora, CentOS, etc. ```sh sudo dnf install rpm-build python3-qt5 python3-gpg python3-requests python3-pysocks python3-packaging gnupg2 tor ./build_rpm.sh sudo yum install dist/torbrowser-launcher-*.rpm ``` ### Run without installing Install the dependencies: sadly, not all of them are available in virtualenv, so you will need to install (some of) them system-wide. Then, you can run: `TBL_SHARE=share ./torbrowser-launcher` torbrowser-launcher-0.3.7/CHANGELOG.md000066400000000000000000000171751456573360100173660ustar00rootroot00000000000000# Tor Browser Launcher Changelog ## 0.3.7 * Use Tor Browser 13.0 new filenames * Adapt AppArmor profile for Tor Browser 13.0 * Set the TORBROWSER_LAUNCHER environment variable to make it easier for Tor Browser to see that it is being run by torbrowser-launcher * Use a proper rDNS ID in AppStream metainfo * Update to latest version of the Tor Browser OpenPGP signing key * Remove some unused code to fix a warning * Add dbus-glib to the rpm package dependencies * Maintenance of torbrowser-launcher has been handed to Tor Project, and the git repository moved to https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ ## 0.3.6 * Tor Browser 12.0 no longer uses locales, so the download URL and local path have changed ## 0.3.5 * Fix refreshing Tor Browser signing key in Flatpak package * Fix issues with localization files ## 0.3.4 * Ship with latest version of the Tor Browser Developers OpenPGP public key * Add several translations * Various small bug fixes ## 0.3.3 * Switch to Web Key Directory to refresh signing key from torproject.org, because everything is broken * Use proper version comparison now that Tor Browser 10.0 is out * Fix DNS leak when downloading over Tor * Various bug fixes, as well as AppData and AppArmor fixes ## 0.3.2 * Switch to keys.openpgp.org when refreshing signing key, because SKS keyservers are broken * Use new Tor Browser logo ## 0.3.1 * Ship with latest version of the Tor Browser Developers OpenPGP public key * Fix bug where TBL window stays open after Tor Browser is launched ## 0.3.0 * Switched from python2 to python3 * Switched from gtk2 to Qt5 * Switched from twisted to requests/socks * Use QThreads for async * Removed modem sound * Only refresh gpg keyring on verification error, instead of every time * Updated AppArmor profiles * Updated available languages, and fixed locale detection bug * Fixed false signature verification error related to twisted ## 0.2.9 * Fixed crash issue related to Tor Browser 7.5 changing how the currently installed version number is stored * Updated list of Tor Project dist mirrors * Fixed edge case crash for when stdout isn't writable * Updated AppStream metadata * Updated AppArmor profiles ## 0.2.8 * Update URL to check for latest version, which changed in Tor Browser 7 * Automatically refresh GPG keyring, to prevent signature verification false positives * Improve GnuPG code by using GPGME if available * Updated AppArmor profiles * Added Czech, Hungarian localization ## 0.2.7 * Updated Tor Browser signing key because they added a new subkey and verification was failing * Updated AppArmor profiles * Improved localization, and added Russian ## 0.2.6 * Fixed bug related to fallback to English feature that caused Settings to crash ## 0.2.5 * Fix issue where Tor Browser Launcher failed to launch if currently installed version of Tor Browser was too old * If Tor Browser download isn't available in your language, fallback to English * Avoid re-downloading tarball if it's already present * Verify GnuPG importing keys using status-fd rather than exit codes * Various AppArmor improvements * Removed unused dependency ## 0.2.4 * Fix signature verification bypass attack, reported by Jann Horn (CVE-2016-3180) ## 0.2.3 * Removed certificate pinning to https://www.torproject.org to avoid issues with upcoming certificate change, and hard-coded minimum Tor Browser version in the release * Fix issue with detecting language * Make Tor SOCKS5 proxy configurable, for users not running on 9050 * Improved AppArmor profiles * Added translations * Switched from xpm icons to png icons * Changed "Exit" button to "Cancel" button * New package description ## 0.2.2 * Tor Browser Launcher no longer attempts to auto-update, now that Tor Browser has this feature * System Tor is now an optional dependency * Fix issue where downloads fail because of unicode URLs * Removed window management code that stopped working many releases ago, and removed wmctrl dependency * Removed test code that caused signature verification to happen at the wrong time ## 0.2.1 * Stop using RecommendedTBBVersions and start using more reliable "release" channel XML * Converted settings file from pickle format to JSON * Download tarball signatures to verify, rather than SHA256SUMS and signature * Implemented IPolicyForHTTPS to prevent twisted-related crashes in Debian * Some AppArmor fixes ## 0.2.0 * Fix critical bug with new location of start-tor-browser * Silenced some AppArmor denied events from logs * Print less console output * Remove support for accepting links * Added better support for updating over Tor in Fedora ## 0.1.9 * Added option to disable accepting links, to workaround Firefox/Tor Browser issue ## 0.1.8 * Added new Tor Browser signing key * Fixed removing alpha/beta code due to change in RecommendedTBBVersions syntax * Fixed opening links in TBB if you originally opened TBB without clicking a link ## 0.1.7 * You can now pass URLs into TBL, and set it as your default browser * Hides TBL window before launching TBB * Default mirror switched to https://dist.torproject.org/ * Added AppData file to look better in software centers * Exclude AppArmor profiles in Ubuntu, where they're broken ## 0.1.6 * Updated licensing confusion to just be MIT in all locations * Fixed bug related to TBB 4.0's new folder structure * Updated .desktop files to comply with standards ## 0.1.5 * Split source code into several files * Several AppArmor updates * Prepare for upcoming RecommendedTBBVersion format change * More verbose UI when updating * No longer detaches start-tor-browser as separate process * Temporarily disable AppArmor profiles in Ubuntu ## 0.1.4 * RecommendedTBBVersion URL change * Many AppArmor improvements * Allow installation into a virtualenv ## 0.1.3 * Force installing stable release if available in RecommendedTBBVersions * Removed Mike Perry's signing key and added Erinn Clark's signing key * Fixed AppArmor profiles (thanks to troubadoour) ## 0.1.2 * Updated Dutch translation * Fixed bug with loading mirrors list * Huge refactor of AppArmor profiles * Added OnionShare support to AppArmor profiles * Suppresses output from detached TBB process * Uses freedesktop xdg-user-dirs instead of ~/.torbrowser * Removed all signing keys except Mike Perry's * Made tor and python-txsocksx dependencies to update over Tor by default ## 0.1.1 * Added TBL_SHARE support, to more easily develop without installing systemwide * Modem sound and python-pygame dependency is now optional * Support for updating TBB over Tor using a system Tor * Removed support for stable/alpha preference, forces stable now * Added French translations ## 0.1.0 * Added Polish translations * Version 0.1.0 marks first version in Debian! * Changed GPG release signing key from 5C17616361BD9F92422AC08BB4D25A1E99999697 to 0B1491929806596254700155FD720AD9EBA34B1C ## 0.0.9 * Fixed AppArmor rules that were broken in Ubuntu * Added support for basic RPM packaging * Removed un-used dependencies * Fixed URLs to deal with TBB release filename changes ## 0.0.8 * Removed older code that's no longer used * Updated list of Tor mirrors * Replaced certificate for www.torproject.org post-heartbleed * Fixed URLs to deal with TBB release filename changes ## 0.0.7 * Added AppArmor profiles for torbrowser-launcher and TBB * Removed included libs in favor of adding new Debian package dependencies ## 0.0.6 * Fixed URLs to deal with changes in TBB releases for 3.x ## 0.0.5 * Updated paths because TBB 3.x changed directory structure * mirrors.txt now has local version in /usr/local * Updated TBB signature URL * Made optional modem sound when launching Tor, because it's sooo slow :) * Extra check to make sure the latest version is installed torbrowser-launcher-0.3.7/LICENSE000066400000000000000000000021271456573360100165510ustar00rootroot00000000000000Copyright (c) 2013-2023 Micah Lee Copyright (c) 2024 Tor Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. torbrowser-launcher-0.3.7/README.md000066400000000000000000000042371456573360100170270ustar00rootroot00000000000000# Tor Browser Launcher _**Are you getting an error?** Sometimes updates in Tor Browser itself will break Tor Browser Launcher. There's a good chance that the problem you're experiencing has already been fixed in the [newest version](https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/tags). Try installing from Flatpak (instructions below), or [build from source](/BUILD.md)._ Tor Browser Launcher is intended to make Tor Browser easier to install and use for GNU/Linux users. You install ```torbrowser-launcher``` from your distribution's package manager and it handles everything else: * Downloads and installs the most recent version of Tor Browser in your language and for your computer's architecture, or launches Tor Browser if it's already installed (Tor Browser will automatically update itself) * Verifies Tor Browser's [signature](https://support.torproject.org/tbb/how-to-verify-signature/) for you, to ensure the version you downloaded was cryptographically signed by Tor developers and was not tampered with * Adds "Tor Browser" and "Tor Browser Launcher Settings" application launcher to your desktop environment's menu * Includes AppArmor profiles to make a Tor Browser compromise not as bad * Optionally plays a modem sound when you open Tor Browser (because Tor is so slow) Tor Browser Launcher is included in Ubuntu, Debian, and Fedora. To install it in any other distribution, see the [build instructions](/BUILD.md). You might want to check out the [security design doc](/security_design.md). ![Tor Browser Launcher screenshot](/screenshot.png) # Installing You can install `torbrowser-launcher` from your operating system's package manager, but it might be out-of-date and have issues working. If you want to make sure you always have the latest version, use Flatpak: ## Installing in any Linux distro using Flatpak Install Flatpak using these [instructions](https://flatpak.org/setup/). Then install `torbrowser-launcher` like this: ``` flatpak install flathub com.github.micahflee.torbrowser-launcher -y ``` Run `torbrowser-launcher` either by using the GUI desktop launcher, or by running: ``` flatpak run com.github.micahflee.torbrowser-launcher ``` torbrowser-launcher-0.3.7/apparmor/000077500000000000000000000000001456573360100173635ustar00rootroot00000000000000torbrowser-launcher-0.3.7/apparmor/license.txt000066400000000000000000000030661456573360100215530ustar00rootroot00000000000000TBB AppArmor profiles are based on https://gitorious.org/tbb-apparmor/tbb-apparmor/ Originally written by Radostan Riedel -- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the names of the copyright owners nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. torbrowser-launcher-0.3.7/apparmor/local/000077500000000000000000000000001456573360100204555ustar00rootroot00000000000000torbrowser-launcher-0.3.7/apparmor/local/torbrowser.Browser.firefox000066400000000000000000000000001456573360100256610ustar00rootroot00000000000000torbrowser-launcher-0.3.7/apparmor/local/torbrowser.Tor.tor000066400000000000000000000000001456573360100241440ustar00rootroot00000000000000torbrowser-launcher-0.3.7/apparmor/torbrowser.Browser.firefox000066400000000000000000000136231456573360100246060ustar00rootroot00000000000000#include #include @{torbrowser_firefox_executable} = /home/*/.local/share/torbrowser/tbb/{i686,x86_64}/tor-browser/Browser/firefox.real profile torbrowser_firefox @{torbrowser_firefox_executable} { #include #include #include #include #include #include #include if exists deny capability sys_ptrace, # Uncomment the following lines if you want to give the Tor Browser read-write # access to most of your personal files. # #include # @{HOME}/ r, # Audio support /{,usr/}bin/pulseaudio Pixr, #dbus, network netlink raw, network tcp, ptrace (trace) peer=@{profile_name}, signal (receive, send) set=("term") peer=@{profile_name}, deny /etc/host.conf r, deny /etc/hosts r, deny /etc/nsswitch.conf r, deny /etc/os-release r, deny /etc/resolv.conf r, deny /etc/passwd r, deny /etc/group r, deny /etc/mailcap r, /etc/machine-id r, /var/lib/dbus/machine-id r, /dev/ r, /dev/shm/ r, owner @{PROC}/@{pid}/cgroup r, owner @{PROC}/@{pid}/environ r, owner @{PROC}/@{pid}/fd/ r, owner @{PROC}/@{pid}/mountinfo r, owner @{PROC}/@{pid}/oom_score_adj rw, owner @{PROC}/@{pid}/smaps r, owner @{PROC}/@{pid}/stat r, owner @{PROC}/@{pid}/statm r, owner @{PROC}/@{pid}/status r, owner @{PROC}/@{pid}/task/ r, owner @{PROC}/@{pid}/task/*/comm r, owner @{PROC}/@{pid}/task/*/stat r, @{PROC}/sys/kernel/random/uuid r, owner @{torbrowser_installation_dir}/ r, owner @{torbrowser_installation_dir}/* r, owner @{torbrowser_installation_dir}/.** rwk, owner @{torbrowser_installation_dir}/update.test/ rwk, owner @{torbrowser_home_dir}/.** rwk, owner @{torbrowser_home_dir}/ rw, owner @{torbrowser_home_dir}/** rwk, owner @{torbrowser_home_dir}.bak/ rwk, owner @{torbrowser_home_dir}.bak/** rwk, owner @{torbrowser_home_dir}/*.so mr, owner @{torbrowser_home_dir}/.cache/fontconfig/ rwk, owner @{torbrowser_home_dir}/.cache/fontconfig/** rwkl, owner @{torbrowser_home_dir}/browser/** r, owner @{torbrowser_home_dir}/{,browser/}components/*.so mr, owner @{torbrowser_home_dir}/Downloads/ rwk, owner @{torbrowser_home_dir}/Downloads/** rwk, owner @{torbrowser_home_dir}/firefox rix, owner @{torbrowser_home_dir}/glxtest ix, owner @{torbrowser_home_dir}/{,TorBrowser/UpdateInfo/}updates/[0-9]*/* rw, owner @{torbrowser_home_dir}/{,TorBrowser/UpdateInfo/}updates/[0-9]*/{,MozUpdater/bgupdate/}updater ix, owner @{torbrowser_home_dir}/updater ix, owner @{torbrowser_home_dir}/TorBrowser/Data/Browser/.parentwritetest rw, owner @{torbrowser_home_dir}/TorBrowser/Data/Browser/profiles.ini r, owner @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/{,**} rwk, owner @{torbrowser_home_dir}/TorBrowser/Data/fontconfig/fonts.conf r, owner @{torbrowser_home_dir}/fonts/* l, owner @{torbrowser_home_dir}/TorBrowser/Tor/tor px, owner @{torbrowser_home_dir}/TorBrowser/Tor/ r, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so mr, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so.* mr, owner @{torbrowser_home_dir}/TorBrowser/Tor/libstdc++/*.so mr, owner @{torbrowser_home_dir}/TorBrowser/Tor/libstdc++/*.so.* mr, # parent Firefox process when restarting after upgrade, Web Content processes owner @{torbrowser_firefox_executable} pxmr -> torbrowser_firefox, /etc/mailcap r, /etc/mime.types r, /usr/share/ r, /usr/share/glib-2.0/schemas/gschemas.compiled r, /usr/share/mime/ r, /usr/share/themes/ r, /usr/share/applications/** rk, /usr/share/gnome/applications/ r, /usr/share/gnome/applications/kde4/ r, /usr/share/poppler/cMap/ r, # Distribution homepage /usr/share/homepage/ r, /usr/share/homepage/** r, /sys/bus/pci/devices/ r, @{sys}/devices/pci[0-9]*/**/irq r, /sys/devices/system/cpu/ r, /sys/devices/system/cpu/present r, /sys/devices/system/node/ r, /sys/devices/system/node/node[0-9]*/meminfo r, /sys/fs/cgroup/cpu,cpuacct/{,user.slice/}cpu.cfs_quota_us r, deny /sys/class/input/ r, deny /sys/devices/virtual/block/*/uevent r, # Should use abstractions/gstreamer instead once merged upstream /etc/udev/udev.conf r, /run/udev/data/+pci:* r, /sys/devices/pci[0-9]*/**/uevent r, owner /{dev,run}/shm/shmfd-* rw, # Required for multiprocess Firefox (aka Electrolysis, i.e. e10s) owner /{dev,run}/shm/org.chromium.* rw, owner /dev/shm/org.mozilla.ipc.[0-9]*.[0-9]* rw, # for Chromium IPC # Required for Wayland display protocol support owner /dev/shm/wayland.mozilla.ipc.[0-9]* rw, # Silence denial logs about permissions we don't need deny @{HOME}/.cache/fontconfig/ rw, deny @{HOME}/.cache/fontconfig/** rw, deny @{HOME}/.config/gtk-2.0/ rw, deny @{HOME}/.config/gtk-2.0/** rw, deny @{PROC}/@{pid}/net/route r, deny /sys/devices/system/cpu/cpufreq/policy[0-9]*/cpuinfo_max_freq r, deny /sys/devices/system/cpu/*/cache/index[0-9]*/size r, deny /run/user/[0-9]*/dconf/user rw, deny /usr/bin/lsb_release x, # Silence denial logs about PulseAudio deny /etc/pulse/client.conf r, deny /usr/bin/pulseaudio x, # KDE 4 owner @{HOME}/.kde/share/config/* r, # Xfce4 /etc/xfce4/defaults.list r, /usr/share/xfce4/applications/ r, # u2f (tested with Yubikey 4) /sys/class/ r, /sys/bus/ r, /sys/class/hidraw/ r, /run/udev/data/c24{5,7,9}:* r, /dev/hidraw* rw, # Yubikey NEO also needs this: /sys/devices/**/hidraw/hidraw*/uevent r, # Needed for Firefox sandboxing via unprivileged user namespaces capability sys_admin, capability sys_chroot, owner @{PROC}/@{pid}/{gid,uid}_map w, owner @{PROC}/@{pid}/setgroups w, # Remove these rules once we can assume abstractions/vulkan is recent enough # to include them /etc/glvnd/egl_vendor.d/{*,.json} r, /usr/share/glvnd/egl_vendor.d/{,*.json} r, #include } torbrowser-launcher-0.3.7/apparmor/torbrowser.Tor.tor000066400000000000000000000031131456573360100230620ustar00rootroot00000000000000#include #include @{torbrowser_tor_executable} = /home/*/.local/share/torbrowser/tbb/{i686,x86_64}/tor-browser/Browser/TorBrowser/Tor/tor profile torbrowser_tor @{torbrowser_tor_executable} { #include network netlink raw, network tcp, network udp, /etc/host.conf r, /etc/nsswitch.conf r, /etc/passwd r, /etc/resolv.conf r, owner @{torbrowser_home_dir}/TorBrowser/Tor/tor mr, owner @{torbrowser_home_dir}/TorBrowser/Data/Tor/ rw, owner @{torbrowser_home_dir}/TorBrowser/Data/Tor/** rw, owner @{torbrowser_home_dir}/TorBrowser/Data/Tor/lock rwk, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so mr, owner @{torbrowser_home_dir}/TorBrowser/Tor/*.so.* mr, # Support some of the included pluggable transports owner @{torbrowser_home_dir}/TorBrowser/Tor/PluggableTransports/** rix, @{PROC}/sys/net/core/somaxconn r, #include # Silence file_inherit logs deny @{torbrowser_home_dir}/{browser/,}omni.ja r, deny @{torbrowser_home_dir}/{browser/,}features/*.xpi r, deny @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/.parentlock rw, deny @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/extensions/*.xpi r, deny @{torbrowser_home_dir}/TorBrowser/Data/Browser/profile.default/startupCache/* r, # Silence logs from included pluggable transports deny /etc/hosts r, deny /etc/services r, @{PROC}/sys/kernel/random/uuid r, /sys/devices/system/cpu/ r, # OnionShare compatibility /tmp/onionshare/** rw, #include } torbrowser-launcher-0.3.7/apparmor/tunables/000077500000000000000000000000001456573360100212005ustar00rootroot00000000000000torbrowser-launcher-0.3.7/apparmor/tunables/torbrowser000066400000000000000000000002331456573360100233310ustar00rootroot00000000000000@{torbrowser_installation_dir}=@{HOME}/.local/share/torbrowser/tbb/{i686,x86_64}/tor-browser @{torbrowser_home_dir}=@{torbrowser_installation_dir}/Browser torbrowser-launcher-0.3.7/build_deb.sh000077500000000000000000000004631456573360100200150ustar00rootroot00000000000000#!/bin/sh VERSION=$(cat share/torbrowser-launcher/version) # clean up from last build rm -r build deb_dist # build binary package python3 setup.py --command-packages=stdeb.command bdist_deb # install it echo "" echo "To install, run:" echo "sudo dpkg -i deb_dist/torbrowser-launcher_$VERSION-1_all.deb" torbrowser-launcher-0.3.7/build_rpm.sh000077500000000000000000000006001456573360100200520ustar00rootroot00000000000000#!/bin/sh VERSION=$(cat share/torbrowser-launcher/version) # clean up from last build rm -r build dist # build binary package python3 setup.py bdist_rpm --requires="python3-qt5, python3-gpg, python3-requests, python3-pysocks, python3-packaging, gnupg2, dbus-glib" # install it echo "" echo "To install, run:" echo "sudo dnf install dist/torbrowser-launcher-$VERSION-1.noarch.rpm" torbrowser-launcher-0.3.7/makepot.sh000077500000000000000000000001671456573360100175450ustar00rootroot00000000000000#!/bin/sh cd torbrowser_launcher xgettext --language=Python --from-code=UTF-8 --output=../torbrowser_launcher.pot *.py torbrowser-launcher-0.3.7/po/000077500000000000000000000000001456573360100161605ustar00rootroot00000000000000torbrowser-launcher-0.3.7/po/be.po000066400000000000000000000151471456573360100171160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2019-10-26 19:51+0300\n" "Last-Translator: Viktar Siarheichyk \n" "Language-Team: Belarusian \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Запускальнік Tor Browser" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Аўтар Micah Lee, ліцэнзія MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "версія {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Памылка падчас стварэння {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} не можа быць запісаны" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Не ўдалася стварыць каталог {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Ствараем хатні каталог GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Не ўдалося імпартаваць ключ з адбіткам: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Не ўсе ключы імпартаваны паспяхова!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Атрыманне Tor Browser упершыню." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Ваша версія Tor Browser пратэрмінавана. Атрымліваем найноўшую версію." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Згружаем праз Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Запуск" #: launcher.py:174 msgid "Yes" msgstr "Так" #: launcher.py:178 msgid "Exit" msgstr "Выйсці" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Адмяніць" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Згружаецца" #: launcher.py:238 msgid "Latest version: {}" msgstr "Апошняя версія: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Памылка падчас вызначэння версіі Tor Browser." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Правяраецца подпіс" #: launcher.py:260 msgid "Extracting" msgstr "Распакоўваецца" #: launcher.py:264 msgid "Running" msgstr "Працуе" #: launcher.py:268 msgid "Starting download over again" msgstr "Запускаем загрузку наноў" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(праз Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Згружана" #: launcher.py:393 msgid "Installing" msgstr "Усталяванне" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Запускальнік Tor Browser не разумее фармат файла {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Гэта версія Tor Browser, якую вы паставілі, ёсць ранейшай, чым мае быць, што " "можа паказваць на атаку!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Атрыманне Tor Browser ізноў." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Памылка загрузкі:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Зараз вы карыстаецеся не стандартным люстэркам" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Змяніць на стандартнае?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Паспрабаваць узамен ангельскую версію Tor Browser?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Няправільны сертыфікат SSL для:\n" "{0}\n" "\n" "Магчыма, вас атакуюць." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Зноў паспрабаваць згрузіць праз Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Памылка падчас запуску загрузкі:\n" "\n" "{0}\n" "\n" "Спрабуем згрузіць праз Tor. Перакананыя, што Tor карэктна сканфігураваны і " "працуе?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Памылка падчас запуску загрузкі:\n" "\n" "{0}\n" "\n" "Вы далучаны да інтэрнэта?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Налады запускальніка Tor Browser" #: settings.py:50 msgid "Download over system Tor" msgstr "Згрузіць праз сістэмны Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Прымусова згрузіць ангельскую версію Tor Browser" #: settings.py:66 msgid "Tor server" msgstr "Сервер Tor" #: settings.py:82 msgid "Status: Installed" msgstr "Стан: усталяваны" #: settings.py:84 msgid "Status: Not Installed" msgstr "Стан: не ўсталяваны" #: settings.py:87 msgid "Install Tor Browser" msgstr "Усталяваць Tor Browser" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Пераставіць Tor Browser" #: settings.py:115 msgid "Mirror" msgstr "Люстэрка" #: settings.py:131 msgid "Save && Exit" msgstr "Захаваць && выйсці" torbrowser-launcher-0.3.7/po/cs.po000066400000000000000000000167611456573360100171400ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2021-06-20 19:42+0200\n" "Last-Translator: Daniel Rusek \n" "Language-Team: \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.3\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Spouštěč prohlížeče Tor" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Vytvořil Micah Lee pod licencí MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "verze {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Chyba při vytváření {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Do {0} není možné zapisovat" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nelze vytvořit adresář {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Vytváří se domovská složka GnuGPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Selhal import klíče s otiskem: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Ne všechny klíče byly importovány úspěšně!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Poprvé se stahuje Prohlížeč Tor." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Vaše verze Prohlížeče Tor je zastaralá. Stahuje se nejnovější verze." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Stahování přes Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Prohlížeč Tor" #: launcher.py:128 msgid "Start" msgstr "Spustit" #: launcher.py:174 msgid "Yes" msgstr "Ano" #: launcher.py:178 msgid "Exit" msgstr "Ukončit" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Zrušit" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Stahuje se" #: launcher.py:238 msgid "Latest version: {}" msgstr "Nejnovější verze: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Chyba při zjišťování verze Prohlížeče Tor." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Ověřuje se podpis" #: launcher.py:260 msgid "Extracting" msgstr "Extrahuje se" #: launcher.py:264 msgid "Running" msgstr "Běží" #: launcher.py:268 msgid "Starting download over again" msgstr "Stahování se spouští znovu" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(přes Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Staženo" #: launcher.py:393 msgid "Installing" msgstr "Instaluje se" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Spouštěč prohlížeče Tor nerozumí formátu souboru {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Verze prohlížeče Tor, kterou máte nainstalovanou, je ranější, než by měla " "být, což může značit útok!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Znovu se stahuje Prohlížeč Tor." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Chyba stahování:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Používáte právě nevýchozí zrcadlo" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Přejete si přepnout zpět na výchozí?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Přejete si místo toho zkusit anglickou verzi Prohlížeče Tor?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Neplatný SSL certifikát pro:\n" "{0}\n" "\n" "Můžete být pod útokem." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Zkusit stahování znovu pomocí Toru?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Chyba při spouštění stahování:\n" "\n" "{0}\n" "\n" "Zkouší se stahování přes Tor. Jste si jistí, že Tor běží a je správně " "nastaven?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Chyba při spouštění stahování:\n" "\n" "{0}\n" "\n" "Jste připojeni k internetu?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Nastavení Spouštěče prohlížeče Tor" #: settings.py:50 msgid "Download over system Tor" msgstr "Stáhnout přes systémový Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Vynutit stažení anglické verze Prohlížeče Tor" #: settings.py:66 msgid "Tor server" msgstr "Server Toru" #: settings.py:82 msgid "Status: Installed" msgstr "Stav: Nainstalováno" #: settings.py:84 msgid "Status: Not Installed" msgstr "Stav: Nenainstalováno" #: settings.py:87 msgid "Install Tor Browser" msgstr "Nainstalovat Prohlížeč Tor" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Přeinstalovat Prohlížeč Tor" #: settings.py:115 msgid "Mirror" msgstr "Zrcadlo" #: settings.py:131 msgid "Save && Exit" msgstr "Uložit a ukončit" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "Chybí balíček python-txsocksx, stahování se neuskuteční přes tor" #~ msgid "DNS Lookup Error" #~ msgstr "Chyba při vyhledávání DNS" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "Certifikát SSL získaný od https://www.torproject.org je neplatný! Možná " #~ "je na vás veden útok." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Chyba při připojování k Toru na {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "SELHALO OVĚŘENÍ PODPISU!\n" #~ "\n" #~ "Možná je na vás veden útok, anebo může jít pouze o síťovou závadu. Pro " #~ "nové stažení klikněte na Spustit." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "Chybí balíček python-pygame, zvuk modemu není dostupný." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Tato možnost je dostupná, pouze pokud se používá systémová instalace Toru." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Tato možnost vyžaduje balíček python-txsocksx." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Přehrávat zvuk modemu, jelikož je Tor pomalý :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Tato možnost vyžaduje nainstalovaný python-pygame" torbrowser-launcher-0.3.7/po/da.po000066400000000000000000000133121456573360100171040ustar00rootroot00000000000000# Danish translation for Tor Browser Launcher. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # scootergrisen, 2018. msgid "" msgstr "" "Project-Id-Version: torbrowser-launcher\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2018-09-30 16:24+0200\n" "Last-Translator: scootergrisen\n" "Language-Team: Danish\n" "Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser-opstarter" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Af Micah Lee, licenseret under MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "version {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Fejl ved oprettelse af {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} er skrivebeskyttet" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Kan ikke oprette mappen {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Opretter GnuPG-hjemmemappe" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Kunne ikke importere nøgle med fingeraftryk: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Det lykkedes ikke at importere alle nøgler!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Downloader Tor Browser for første gang." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Din version af Tor Browser er forældet. Downloader den nyeste version." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Downloader over Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Start" #: launcher.py:174 msgid "Yes" msgstr "Ja" #: launcher.py:178 msgid "Exit" msgstr "Afslut" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Annuller" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Downloader" #: launcher.py:238 msgid "Latest version: {}" msgstr "Seneste version: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Fejl ved registrering af Tor Browser-version." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Verificerer signatur" #: launcher.py:260 msgid "Extracting" msgstr "Udpakker" #: launcher.py:264 msgid "Running" msgstr "Kører" #: launcher.py:268 msgid "Starting download over again" msgstr "Starter download på ny" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(over Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Downloadet" #: launcher.py:393 msgid "Installing" msgstr "Installerer" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor Browser-opstarter forstår ikke filformatet af {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Den version af Tor Browser som du har installeret er tidligere end den bør " "være, hvilket kan være tegn på angreb!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Downloader Tor Browser på ny." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Fejl ved download:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Du bruger i øjeblikket et spejl som ikke er standard" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Vil du skifte tilbage til standarden?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Vil du i stedet prøve den engelske version af Tor Browser?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Ugyldigt SSL-certifikat for:\n" "{0}\n" "\n" "Du er måske under angreb." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Prøv downloaden igen med Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Fejl ved start af download:\n" "\n" "{0}\n" "\n" "Prøver at downloade over Tor. Er du sikker på, at Tor er konfigureret " "korrekt og kører?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Fejl ved start af download:\n" "\n" "{0}\n" "\n" "Har du forbindelse til internettet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Indstillinger for Tor Browser-opstarter" #: settings.py:50 msgid "Download over system Tor" msgstr "Download over systemets Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Tving download af den engelske version af Tor Browser" #: settings.py:66 msgid "Tor server" msgstr "Tor-server" #: settings.py:82 msgid "Status: Installed" msgstr "Status: Installeret" #: settings.py:84 msgid "Status: Not Installed" msgstr "Status: Ikke installeret" #: settings.py:87 msgid "Install Tor Browser" msgstr "Installer Tor Browser" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Geninstaller Tor Browser" #: settings.py:115 msgid "Mirror" msgstr "Spejl" #: settings.py:131 msgid "Save && Exit" msgstr "Gem og afslut" torbrowser-launcher-0.3.7/po/de.po000066400000000000000000000134161456573360100171150ustar00rootroot00000000000000msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2019-12-15 21:28+0100\n" "Last-Translator: René Mario Baumgartner \n" "Language-Team: \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.2.4\n" "X-Poedit-Basepath: .\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser Launcher" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Von Micah Lee, lizensiert unter MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "Version {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Fehler erzeugt {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} ist nicht schreibbar" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Kann Verzeichnis {0} nicht erzeugen" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Erzeuge GnuPG Verzeichnis" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Konnte Schlüssel mit folgendem Fingerabdruck nicht importieren: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Nicht alle Schlüssel konnten erfolgreich importiert werden!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Lade Tor Browser das erste mal herunter." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "Ihre Version des Tor Browsers ist nicht mehr aktuell. Lade die neueste " "Version herunter." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Lade über Tor herunter" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Start" #: launcher.py:174 msgid "Yes" msgstr "Ja" #: launcher.py:178 msgid "Exit" msgstr "Exit" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Abbruch" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Herunterladen" #: launcher.py:238 msgid "Latest version: {}" msgstr "Aktuelle Version: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Fehler bei dem Versuch die Tor Browser Version zu finden." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Prüfe Signatur" #: launcher.py:260 msgid "Extracting" msgstr "Extrahieren" #: launcher.py:264 msgid "Running" msgstr "Läuft" #: launcher.py:268 msgid "Starting download over again" msgstr "Starte download nochmals" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(über Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Heruntergeladen" #: launcher.py:393 msgid "Installing" msgstr "Installiere" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor Browser versteht folgendes Datei Format nicht: {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Die Version ihres Tor Browsers ist neuer als sie sein sollte, was auf eine " "Attacke schließen lassen könnte!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Lade Tor Browser nochmals herunter." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Fehler beim herunterladen:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Sie verwenden zur Zeit einen nicht voreingestellten Mirror." #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Wollen sie zur Voreinstellung wechseln?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" "Wollen sie die englische Version des Tor Browsers stattdessen versuchen?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Ungültiges SSL Zertifikat für:\n" "{0}\n" "\n" "Möglicherweise werden sie angegriffen." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Wollen sie das herunterladen nochmals über Tor versuchen?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Fehler beim starten des Downloads:\n" "\n" "{0}\n" "\n" "Versuche über Tor herunterzuladen. Sind sie sicher das Tor richtig " "konfiguriert und aktiv ist?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Fehler beim starten des Downloads:\n" "\n" "{0}\n" "\n" "Sind sie mit dem Internet verbunden?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Tor Browser Launcher Einstellungen" #: settings.py:50 msgid "Download over system Tor" msgstr "Herunterladen über system Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Herunterladen der englischen Version des Tor Browsers erzwingen" #: settings.py:66 msgid "Tor server" msgstr "Tor server" #: settings.py:82 msgid "Status: Installed" msgstr "Status: Installiert" #: settings.py:84 msgid "Status: Not Installed" msgstr "Status: Nicht installiert" #: settings.py:87 msgid "Install Tor Browser" msgstr "Tor Browser installieren" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Tor Browser nochmals installieren" #: settings.py:115 msgid "Mirror" msgstr "Mirror" #: settings.py:131 msgid "Save && Exit" msgstr "Speichern && Exit" torbrowser-launcher-0.3.7/po/fr.po000066400000000000000000000174731456573360100171430ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2016-12-02 15:16+0400\n" "Last-Translator: Andrey Kunitsyn \n" "Language-Team: French\n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser Launcher" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Par Micah Lee, sous licence MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "version {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Erreur lors de la création de {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Impossible d'écrire {0}" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Impossible de créer le dossier {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Création du dossier GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Impossible d'importer la clé avec l'empreinte : %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Certaines clés n'ont pas pu être importées !" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Téléchargement du Navigateur Tor pour la première fois." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "Votre version du Navigateur Tor est obsolète. Téléchargement de la nouvelle " "version." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Télécharger à travers Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Navigateur Tor" #: launcher.py:128 msgid "Start" msgstr "Démarrer" #: launcher.py:174 msgid "Yes" msgstr "Oui" #: launcher.py:178 msgid "Exit" msgstr "Quitter" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Annuler" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Téléchargement" #: launcher.py:238 msgid "Latest version: {}" msgstr "Dernière version : {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Impossible de détecter la version du Navigateur Tor." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Vérification de la signature" #: launcher.py:260 msgid "Extracting" msgstr "Décompression" #: launcher.py:264 msgid "Running" msgstr "Exécution" #: launcher.py:268 msgid "Starting download over again" msgstr "Télécharger à nouveau" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(à travers Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Téléchargé" #: launcher.py:393 msgid "Installing" msgstr "Installation en cours" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor Browser Launcher ne comprend pas le format du fichier {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "La version du Navigateur Tor que vous avez installé est antérieure à ce " "qu'elle devrait, ce qui peut être le signe d'une attaque !" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Télécharger le Navigateur Tor à nouveau." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Erreur de téléchargement :" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Vous utilisez actuellement un miroir n'étant pas celui par défaut" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Voulez-vous revenir à la valeur par défaut ?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" "Voulez-vous essayer la version anglophone du Navigateur Tor à la place ?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Certificat SSL invalide pour :\n" "{0}\n" "\n" "Vous pourriez être attaqué." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Essayer de télécharger à nouveau à travers Tor ?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Impossible de démarrer le téléchargement :\n" "\n" "{0}\n" "\n" "Essayez de télécharger à travers Tor. Êtes-vous sûr que Tor est configuré " "correctement et fonctionne ?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Impossible de démarrer le téléchargement :\n" "\n" "{0}\n" "\n" "Êtes-vous connecté à Internet ?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Configuration du Tor Browser Launcher" #: settings.py:50 msgid "Download over system Tor" msgstr "Télécharger à travers le Tor installé sur le système" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Forcer le téléchargement de la version anglophone du Navigateur Tor" #: settings.py:66 msgid "Tor server" msgstr "Serveur Tor" #: settings.py:82 msgid "Status: Installed" msgstr "Statut : Installé" #: settings.py:84 msgid "Status: Not Installed" msgstr "Statut : Pas installé" #: settings.py:87 msgid "Install Tor Browser" msgstr "Installer le Navigateur Tor" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Réinstaller le Navigateur Tor" #: settings.py:115 msgid "Mirror" msgstr "Miroir" #: settings.py:131 msgid "Save && Exit" msgstr "Enregistrer et quitter" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "Le paquet python-txsocks est manquant, les téléchargements ne se feront " #~ "pas sur Tor." #~ msgid "DNS Lookup Error" #~ msgstr "Erreur de type DNS Lookup" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "Le certificat SSL servi par https://www.torproject.org n'est pas valide! " #~ "Vous pouvez être l'objet d'une attaque." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Impossible de se connecter sur Tor au moyen de {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "LA VÉRICATION DE LA SIGNATURE A ÉCHOUÉ\n" #~ "\n" #~ "Vous pourriez être l'objet d'une attaque, ou il peut s'agir d'un problème " #~ "de réseau. Cliquer sur Démarrer pour télécharger à nouveau." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "" #~ "Le paquet python-pygame est manquant, le son de modem est indisponible." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Cette option n'est disponible qu'en conjonction avec une installation " #~ "système de Tor." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Cette option nécessite le paquet python-txsocksx" #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Jouer un son de modem, car Tor est lent :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Cette option requiert le paquet python-pygame" torbrowser-launcher-0.3.7/po/hr.po000066400000000000000000000136331456573360100171370ustar00rootroot00000000000000# Croatian translation of Tor Browser Launcher. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Milo Ivir , 2020. # msgid "" msgstr "" "Project-Id-Version: Tor Browser Launcher\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2020-01-22 13:20+0100\n" "Last-Translator: Milo Ivir \n" "Language-Team: \n" "Language: hr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.12\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Pokretač Tor preglednika" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Autor Micah Lee, MIT licenca" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "verzija {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Greška prilikom stvaranja {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Nije moguće pisati u {0}" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nije moguće stvoriti mapu {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Izrada početne mape za GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Nije bilo moguće uvesti ključ s otiskom prsta: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Nisu svi ključevi uspješno uvezeni!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Preuzimanje Tor preglednika po prvi put." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "Tvoja verzija Tor preglednika je zastarjela. Preuzima se najnovija verzija." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Preuzimanje preko Tora" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor preglednik" #: launcher.py:128 msgid "Start" msgstr "Pokreni" #: launcher.py:174 msgid "Yes" msgstr "Da" #: launcher.py:178 msgid "Exit" msgstr "Zatvori" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Odustani" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Preuzimanje" #: launcher.py:238 msgid "Latest version: {}" msgstr "Zadnja verzija: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Greška prilikom otkrivanja verzije Tor preglednika." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Potvrđivanje potpisa" #: launcher.py:260 msgid "Extracting" msgstr "Otpakiravanje" #: launcher.py:264 msgid "Running" msgstr "Izvršava se" #: launcher.py:268 msgid "Starting download over again" msgstr "Pokreće se ponovno preuzimanje" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(preko Tora)" #: launcher.py:293 msgid "Downloaded" msgstr "Preuzeto" #: launcher.py:393 msgid "Installing" msgstr "Instaliranje" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Pokretač Tor preglednika ne razumije format datoteke {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Tvoja verzija Tor preglednika je starija nego što bi trebala biti, što može " "biti znak napada!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Ponovno preuzimanje Tor preglednika." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Greška prilikom preuzimanja:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Trenutačno koristiš nestandardno zrcalo" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Želiš li vratiti na standardno?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Želiš li umjesto toga isprobati englesku verziju Tor preglednika?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Neispravni SSL certifikat za:\n" "{0}\n" "\n" "Možda si napadnut/a." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Ponovo pokušati preuzeti pomoću Tora?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Greška prilikom pokretanja preuzimanja:\n" "\n" "{0}\n" "\n" "Pokušava se preuzeti preko Tora. Je li je Tor ispravno konfiguriran i " "pokrenut?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Greška prilikom pokretanja preuzimanja:\n" "\n" "{0}\n" "\n" "Jesi li spojen/a na internet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Postavke pokretača Tor preglednika" #: settings.py:50 msgid "Download over system Tor" msgstr "Preuzmi preko Tora sustava" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Prisili preuzimanje engleske verzije Tor preglednika" #: settings.py:66 msgid "Tor server" msgstr "Tor poslužitelj" #: settings.py:82 msgid "Status: Installed" msgstr "Stanje: Instalirano" #: settings.py:84 msgid "Status: Not Installed" msgstr "Stanje: Nije instalirano" #: settings.py:87 msgid "Install Tor Browser" msgstr "Instaliraj Tor preglednik" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Ponovo instaliraj Tor preglednik" #: settings.py:115 msgid "Mirror" msgstr "Zrcalo" #: settings.py:131 msgid "Save && Exit" msgstr "Spremi i zatvori" torbrowser-launcher-0.3.7/po/hu.po000066400000000000000000000166171456573360100171470ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2017-02-16 00:55+0100\n" "Last-Translator: Barcza Károly \n" "Language-Team: \n" "Language: hu_HU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.8\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor böngésző indító" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Micah Lee által MIT licenc alatt" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "verzió {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Hiba a(z) {0} létrehozásakor" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} nem írható" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nem sikerült a(z) {0} létrehozása" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "GnuPG könyvtár létrehozása" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Nem lehetett importálni a kulcsot ujjlenyomattal: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Tor böngésző letöltése és telepítése első alkalommal." #: launcher.py:85 #, fuzzy msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" "A Tor böngésző verziója elavult. Töltsük le és telepítsük a legfrissebb " "változatot." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Letöltés Tor-on keresztül" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor böngésző" #: launcher.py:128 msgid "Start" msgstr "Elindítás" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Megszakít" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Letöltés" #: launcher.py:238 msgid "Latest version: {}" msgstr "Legújabb változat: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Hiba a Tor böngésző verzió felsimerésekor" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Aláírás ellenőrzése" #: launcher.py:260 msgid "Extracting" msgstr "Kibontás" #: launcher.py:264 msgid "Running" msgstr "Fut" #: launcher.py:268 msgid "Starting download over again" msgstr "Újra letöltés indítása" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Letöltve" #: launcher.py:393 msgid "Installing" msgstr "Telepítés.." #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor böngésző indító nem érti a(z) {0} fájl formátumot." #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "A Tor böngésződ verziója egy korábbi verzió mint amilyennek lennie kellene, " "ami lehet egy támadás jele!" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Tör böngészőcsomag letöltése újra." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Hiba a letöltésben:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Jelenleg használt tükörszerver nem az alapértelmezett" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Valóban szeretnéd visszaváltani alapértelmezettre?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Ehelyett megpróbálod a Tor böngésző angol változatát ?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Megpróbálod újra a Tor letöltését?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Sikertelen a letöltés indítása:\n" "\n" "{0}\n" "\n" "Csatlakozva vagy az internethez?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Tör böngésző indító beállítások" #: settings.py:50 msgid "Download over system Tor" msgstr "Letöltés rendszer Tor-on keresztül" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Kényszerítse a Tor angol változatának letöltését" #: settings.py:66 msgid "Tor server" msgstr "Tor-szerver" #: settings.py:82 msgid "Status: Installed" msgstr "Állapot: Telepített" #: settings.py:84 msgid "Status: Not Installed" msgstr "Állapot: Nincs telepítve" #: settings.py:87 msgid "Install Tor Browser" msgstr "Tor-böngésző telepítése" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Tor böngésző úratelepítése" #: settings.py:115 msgid "Mirror" msgstr "Tükrözés" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Mentés és kilépés" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "A python-txsocksx csoamag nem található, a letöltés nem fog megtörténni a " #~ "tor-on" #~ msgid "DNS Lookup Error" #~ msgstr "DNS feloldási hiba" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "A ttps://www.torproject.org által adott SSL tanúsítvány érvénytelen! " #~ "Lehet, hogy támadás alatt vagy." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Hiba a Tör csatlakozáskor itt {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "ALÁÍRÁS ELLENŐRZÉSE SIKERTELEN\n" #~ "\n" #~ "Lehet, hogy támadás alatt vagy, vagy előfordulhat egy hálózati probléma " #~ "is. Kattints az indításra az újbóli letöltéshez." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "A python-pygame csomag nem található, a modem hang nem elérhető." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Ehhez az opció akkor elérhető amikor használatban van a rendszer szintű " #~ "Tor." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Ehhez az opcióhoz szükséges a python-txsocksx csomag" #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Modem hang lejátszása, mert a Tor lassú :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Ehhez az opcióhoz szükséges hogy a python-pygame telepítve legyen" torbrowser-launcher-0.3.7/po/nl.po000066400000000000000000000134161456573360100171360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2016-12-02 17:40+0400\n" "Last-Translator: Andrey Kunitsyn \n" "Language-Team: \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser Launcher" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Door Micah Lee, onder MIT licensie" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "versie {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Fout bij maken van {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} is niet schrijfbaar" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Kan map niet maken: {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Aanmeken GnuPG map" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "" #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Tor Browser Bundle opnieuw aan het downloaden." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" #: launcher.py:100 msgid "Downloading over Tor" msgstr "" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Start" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Annuleren" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Bezig met downloaden" #: launcher.py:238 #, fuzzy msgid "Latest version: {}" msgstr "Laatste versie: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Handtekening verifiëren" #: launcher.py:260 msgid "Extracting" msgstr "Uitpakken" #: launcher.py:264 msgid "Running" msgstr "Uitvoeren" #: launcher.py:268 msgid "Starting download over again" msgstr "" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Gedownload" #: launcher.py:393 msgid "Installing" msgstr "Installeren" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Tor Browser Bundle opnieuw aan het downloaden." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Download fout:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Probeer de download opnieuw via Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Fout bij het downloaden:\n" "\n" "{0}\n" "\n" "Bent u verbonden met het internet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Tor Browser Launcher Instellingen" #: settings.py:50 msgid "Download over system Tor" msgstr "" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "" #: settings.py:66 msgid "Tor server" msgstr "" #: settings.py:82 msgid "Status: Installed" msgstr "" #: settings.py:84 msgid "Status: Not Installed" msgstr "" #: settings.py:87 msgid "Install Tor Browser" msgstr "" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "" #: settings.py:115 msgid "Mirror" msgstr "" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Opslaan & afsluiten" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "Het SSL certificaat geserveerd door https://www.torproject.org is " #~ "ongeldig! Je bent misschien onder aanval." #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "HANDTEKENING VERIFICATIE MISLUKT!\n" #~ "\n" #~ "U wordt misschien aangevallen of gewoon een netwerk probleem. Klik op " #~ "Start om het downloaden nogmaals te proberen." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Voor deze optie is het python-txsocksx pakket nodig." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Speel modem geluid, omdat Tor langzaam is :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Voor deze optie moet python-pygame geïnstalleerd zijn" torbrowser-launcher-0.3.7/po/pl.po000066400000000000000000000121701456573360100171340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2016-12-02 15:35+0400\n" "Last-Translator: AreYouLoco? \n" "Language-Team: Polish\n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 1.8.7.1\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Launcher Przeglądarki Tora" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "wersja {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Błąd przy tworzeniu {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} jest tylko do odczytu" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Nie można stworzyć {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Tworzenie katalogu głównego GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "" #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Ponowne pobieranie Tor Browser Bundle" #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" #: launcher.py:100 msgid "Downloading over Tor" msgstr "" #: launcher.py:111 msgid "Tor Browser" msgstr "Przeglądarka Tora" #: launcher.py:128 msgid "Start" msgstr "" #: launcher.py:174 msgid "Yes" msgstr "" #: launcher.py:178 msgid "Exit" msgstr "" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Pobieranie" #: launcher.py:238 msgid "Latest version: {}" msgstr "" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Weryfikowanie podpisu" #: launcher.py:260 msgid "Extracting" msgstr "Rozpakowywanie" #: launcher.py:264 msgid "Running" msgstr "Uruchamianie" #: launcher.py:268 msgid "Starting download over again" msgstr "Ponowne rozpoczynanie pobierania" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "" #: launcher.py:293 msgid "Downloaded" msgstr "Pobrano" #: launcher.py:393 msgid "Installing" msgstr "Instalowanie" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Ponowne pobieranie Tor Browser Bundle" #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Błąd pobierania:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Błąd przy rozpoczynaniu pobierania:\n" "\n" "{0}\n" "\n" "Czy jesteś podłąćzony do internetu?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "" #: settings.py:50 msgid "Download over system Tor" msgstr "" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "" #: settings.py:66 msgid "Tor server" msgstr "" #: settings.py:82 msgid "Status: Installed" msgstr "" #: settings.py:84 msgid "Status: Not Installed" msgstr "" #: settings.py:87 msgid "Install Tor Browser" msgstr "" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "" #: settings.py:115 msgid "Mirror" msgstr "" #: settings.py:131 msgid "Save && Exit" msgstr "" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "WERYFIKACJA PODPISU NIEUDANA!\n" #~ "\n" #~ "Możesz być atakowany, lub mogą być to tylko problemy z połączeniem. " #~ "Naciśnij Start aby pobrać ponownie." torbrowser-launcher-0.3.7/po/pt_BR.po000066400000000000000000000171341456573360100175340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2020-02-09 16:35-0300\n" "Language: pt_BR\n" "Language-Team: \n" "Last-Translator: João Vítor S. F. \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.2.4\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Poedit-SourceCharset: UTF-8\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Lançador do Navegador Tor" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Por Micah Lee, licenciado sob o MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "versão {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Erro ao criar {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} não é gravável" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Não é possível criar o diretório {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Criando o diretório inicial do GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Não foi possível importar a chave com a impressão digital: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Nem todas as chaves foram importadas com sucesso!" #: launcher.py:83 #, fuzzy msgid "Downloading Tor Browser for the first time." msgstr "Baixando o Navegador Tor pela primeira vez." #: launcher.py:85 #, fuzzy msgid "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Sua versão do Navegador Tor está desatualizada. Baixando a versão mais recente." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Baixando pelo Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Navegador Tor" #: launcher.py:128 msgid "Start" msgstr "Iniciar" #: launcher.py:174 msgid "Yes" msgstr "Sim" #: launcher.py:178 msgid "Exit" msgstr "Sair" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Cancelar" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Baixando" #: launcher.py:238 msgid "Latest version: {}" msgstr "Versão mais recente: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Erro ao detectar a versão do Navegador Tor." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Verificando Assinatura" #: launcher.py:260 msgid "Extracting" msgstr "Extraindo" #: launcher.py:264 msgid "Running" msgstr "Rodando" #: launcher.py:268 msgid "Starting download over again" msgstr "Iniciando o download novamente" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(pelo Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Baixado" #: launcher.py:393 msgid "Installing" msgstr "Instalando" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "O Lançador do Navegador Tor não entende o formato do arquivo de {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "A versão do Navegador Tor que você instalou é anterior ao que deveria ser, " "o que poderia ser um sinal de ataque!" #: launcher.py:446 #, fuzzy msgid "Downloading Tor Browser over again." msgstr "Baixando o Navegador Tor novamente.." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Erro de Download:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "No momento você está usando espelho não-padrão" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Você gostaria de retornar para o padrão?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Você gostaria de experimentar a versão em inglês do Navegador Tor?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Certificado SSL inválido para:\n" "{0}\n" "\n" "Você pode estar sob ataque." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Tentar o download novamente usando o Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Erro ao iniciar o download:\n" "\n" "{0}\n" "\n" "Tentando fazer o download pelo Tor. Você tem certeza de que o Tor está configurado corretamente e " "e funcionando?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Erro ao iniciar o download:\n" "\n" "{0}\n" "\n" "Você está conectado à internet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Configurações do Lançador do Navegador Tor" #: settings.py:50 msgid "Download over system Tor" msgstr "Download pelo sistema Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Forçar o download da versão em Inglês do Navegador Tor" #: settings.py:66 msgid "Tor server" msgstr "Servidor Tor" #: settings.py:82 msgid "Status: Installed" msgstr "Estado: Instalado" #: settings.py:84 msgid "Status: Not Installed" msgstr "Estado: Não Instalado" #: settings.py:87 msgid "Install Tor Browser" msgstr "Instalar o Navegador Tor" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Reinstalar o Navegador Tor" #: settings.py:115 msgid "Mirror" msgstr "Espelho" #: settings.py:131 #, fuzzy msgid "Save && Exit" msgstr "Salvar && Sair" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr #~ "O pacote python-txsocksx está faltando, os downloads não acontecerão pelo tor" #~ msgid "DNS Lookup Error" #~ msgstr "Erro de Pesquisa de DNS" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "O certificado SSL fornecido por https://www.torproject.org é inválido! Você " #~ "pode estar sob ataque." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Erro ao conectar ao Tor em {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "FALHA NA VERIFICAÇÃO DA ASSINATURA!\n" #~ "\n" #~ "Você pode estar sob ataque, ou pode haver apenas um problema de rede. " #~ "Clique em Iniciar para tentar baixar novamente." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "" #~ "O pacote python-pygame está faltando, o som do modem não está disponível." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Esta opção está apenas disponível ao usar uma instalação Tor do sistema." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Esta opção precisa do pacote python-txsocksx" #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Reproduzir som do modem, porque o Tor é lento :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Esta opção precisa do pacote python-pygame" torbrowser-launcher-0.3.7/po/ru.po000066400000000000000000000211461456573360100171520ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2018-07-07 19:50+0400\n" "Last-Translator: Andrey Kunitsyn Sergeevich \n" "Language-Team: Russian\n" "Language: ru_RU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Gtranslator 2.91.7\n" "Plural-Forms: nplurals=3; plural=(n % 10==1 && n % 100!=11 ? 0 : n % 10>=2 " "&& n % 10<=4 && (n % 100<10 || n % 100>=20) ? 1 : 2);\\n\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Программа запуска Tor Browser" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Написана Micah Lee и распространяется по лицензии MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "версия {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Ошибка создания {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "Нельзя записать в {0}" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Нельзя создать каталог {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Создание домашнего каталога GnuPG" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Не удалось импортировать отпечаток ключа: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Не все ключи были успешно импортированы!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Загрузка Tor Browser в первый раз." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Ваша версия Tor Browser устарела. Загрузка новой версии." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Загрузка через Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Запуск" #: launcher.py:174 msgid "Yes" msgstr "Да" #: launcher.py:178 msgid "Exit" msgstr "Выход" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Отмена" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Загрузка" #: launcher.py:238 msgid "Latest version: {}" msgstr "Последняя версия: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Ошибка получения версии Tor Browser." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Сверка подписи" #: launcher.py:260 msgid "Extracting" msgstr "Распаковка" #: launcher.py:264 msgid "Running" msgstr "Запуск" #: launcher.py:268 msgid "Starting download over again" msgstr "Повторная загрузка" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "через Tor" #: launcher.py:293 msgid "Downloaded" msgstr "Загружено" #: launcher.py:393 msgid "Installing" msgstr "Установка" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Программа запуска Tor Browser не понимает формат файла {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Вы установили новую версию Tor Browser раньше, чем это должно быть. Это " "может быть атакой!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Повторная загрузка Tor Browser" #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Ошибка загрузки:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Вы используете нестандартное зеркало" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Хотите вернуться к стандартному?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Попробовать загрузить английскую версию Tor Browser?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Ошибка, связанная с SSL-сертификатом:\n" "{0}\n" "\n" "Возможно, вы под атакой." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Загрузить снова через Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Ошибка загрузки:\n" "\n" "{0}\n" "\n" "Не удалось загрузить через Tor. Проверьте, что Tor запущен и верно настроен." #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Ошибка при запуске загрузки:\n" "\n" "{0}\n" "\n" "Вы подключены к сети?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Настройки программы запуска Tor Browser" #: settings.py:50 msgid "Download over system Tor" msgstr "Загружать через Tor" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Загружать только английскую версию Tor Browser" #: settings.py:66 msgid "Tor server" msgstr "Сервер Tor" #: settings.py:82 msgid "Status: Installed" msgstr "Статус: установлен" #: settings.py:84 msgid "Status: Not Installed" msgstr "Статус: не установлен" #: settings.py:87 msgid "Install Tor Browser" msgstr "Установить Tor Browser" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Переустановить Tor Browser" #: settings.py:115 msgid "Mirror" msgstr "Зеркало" #: settings.py:131 msgid "Save && Exit" msgstr "Сохранить и выйти" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "Пакет python-txsocks отсутствует, загрузка не будет производиться через " #~ "Tor" #~ msgid "DNS Lookup Error" #~ msgstr "Ошибка запроса DNS" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "SSL-сертификат находящейся на https://www.torproject.org недействителен! " #~ "Вы можете быть атакованы." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Ошибка подключения к Tor через {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "ОШИБКА СВЕРКИ ПОДПИСИ!\n" #~ "\n" #~ "Вы можете бы быть под атакой, или имеют место проблемы с сетью. Нажмите " #~ "кнопку Пуск и попробуйте снова." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "Пакет python-pygame не найден, звуки модема недоступны." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "Эта опция доступна только при установки Tor в систему." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Эта опция требует пакет python-txsocksx." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Играть звуки модема, если Tor слишком медленный :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Эта опция требует установленный python-pygame" torbrowser-launcher-0.3.7/po/sv.po000066400000000000000000000166121456573360100171560ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2018-11-10 11:36+0100\n" "Last-Translator: Jonatan Nyberg \n" "Language-Team: Swedish\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.2\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor Browser Launcher" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "Av Mika Lee, licensierad under MIT" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "version {0}" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "Ett fel uppstod vid skapande {0}" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "{0} är inte skrivbar" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "Kan inte att skapa katalog {0}" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "Skapa GnuPG-homedir" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "Kunde inte importera nyckel med fingeravtryck: %s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "Inte alla nycklar importerades!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "Hämtar Tor Browser för första gången." #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Din version av Tor Browser är föråldrad. Hämta den senaste versionen." #: launcher.py:100 msgid "Downloading over Tor" msgstr "Hämtar över Tor" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:128 msgid "Start" msgstr "Börja" #: launcher.py:174 msgid "Yes" msgstr "Ja" #: launcher.py:178 msgid "Exit" msgstr "Avsluta" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "Avbryt" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "Hämtar" #: launcher.py:238 msgid "Latest version: {}" msgstr "Senaste versionen: {}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "Fel vid detektering av Tor Browser-versionen." #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "Verifierar signaturen" #: launcher.py:260 msgid "Extracting" msgstr "Packar upp" #: launcher.py:264 msgid "Running" msgstr "Körs" #: launcher.py:268 msgid "Starting download over again" msgstr "Börja hämtningen igen" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(över Tor)" #: launcher.py:293 msgid "Downloaded" msgstr "Hämtad" #: launcher.py:393 msgid "Installing" msgstr "Installerar" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor Browser Launcher förstår inte filformatet {0}" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Den version av Tor Browser du har installerat är tidigare än den borde vara, " "vilket kan vara ett tecken på en attack!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "Hämtar Tor Browser igen." #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "Hämtningsfel:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "Du använder för närvarande en icke-standardspegel" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "Vill du byta tillbaka till standard?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Vill du prova den engelska versionen av Tor Browser istället?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Ogiltigt SSL-certifikat för:\n" "{0}\n" "\n" "Du kan vara under attack." #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "Försök att hämta igen med Tor?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "Fel vid start av hämtning:\n" "\n" "{0}\n" "\n" "Försöker att hämta över Tor. Är du säker på att Tor är korrekt konfigurerad " "och körs?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "Fel vid start av hämtning:\n" "\n" "{0}\n" "\n" "Är du ansluten till internet?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Inställningar för Tor Browser Launcher" #: settings.py:50 msgid "Download over system Tor" msgstr "Hämta över Tor-system" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "Tvinga att hämta engelsk version av Tor Browser" #: settings.py:66 msgid "Tor server" msgstr "Tor-server" #: settings.py:82 msgid "Status: Installed" msgstr "Tillstånd: Installerad" #: settings.py:84 msgid "Status: Not Installed" msgstr "Tillstånd: Inte installerad" #: settings.py:87 msgid "Install Tor Browser" msgstr "Installera Tor Browser" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "Installera om Tor Browser" #: settings.py:115 msgid "Mirror" msgstr "Spegel" #: settings.py:131 msgid "Save && Exit" msgstr "Spara && avsluta" #~ msgid "" #~ "The python-txsocksx package is missing, downloads will not happen over tor" #~ msgstr "" #~ "" #~ "Python-txsocksx-paketet saknas, hämtningar kommer inte att hända över Tor." #~ msgid "DNS Lookup Error" #~ msgstr "DNS-uppsökningsfel" #~ msgid "" #~ "The SSL certificate served by https://www.torproject.org is invalid! You " #~ "may be under attack." #~ msgstr "" #~ "SSL-certifikatet som betjänas av https://www.torproject.org är ogiltig!" #~ "Du kan vara under attack." #~ msgid "Error connecting to Tor at {0}" #~ msgstr "Fel vid anslutning till Tor på {0}" #~ msgid "" #~ "SIGNATURE VERIFICATION FAILED!\n" #~ "\n" #~ "You might be under attack, or there might just be a networking problem. " #~ "Click Start try the download again." #~ msgstr "" #~ "SIGNATUR MISSLYCKADES!\n" #~ "\n" #~ "Du kan vara under attack, eller det kan bara vara ett nätverksproblem. " #~ "Klicka på Start för försöka hämta igen." #~ msgid "" #~ "The python-pygame package is missing, the modem sound is unavailable." #~ msgstr "" #~ "Python-pygame-paketet saknas, modemljudet är otillgängligt." #~ msgid "" #~ "This option is only available when using a system wide Tor installation." #~ msgstr "" #~ "Det här alternativet är endast tillgängligt när du använder en " #~ "systembredd Tor-installation." #~ msgid "This option requires the python-txsocksx package." #~ msgstr "Det här alternativet kräver python-txsocksx-paketet." #~ msgid "Play modem sound, because Tor is slow :]" #~ msgstr "Spela modemljud, eftersom Tor är långsamt :]" #~ msgid "This option requires python-pygame to be installed" #~ msgstr "Det här alternativet kräver att python-pygame installeras" torbrowser-launcher-0.3.7/po/tr.po000066400000000000000000000135311456573360100171500ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Oğuz Ersen , 2022. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-27 08:41+0300\n" "PO-Revision-Date: 2022-03-06 09:00+0300\n" "Last-Translator: Oğuz Ersen \n" "Language-Team: Turkish \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0\n" #: common.py:159 #, python-brace-format msgid "Error creating {0}" msgstr "{0} oluşturulurken hata" #: common.py:270 #, python-brace-format msgid "Cannot create directory {0}" msgstr "{0} dizini oluşturulamıyor" #: common.py:273 #, python-brace-format msgid "{0} is not writable" msgstr "{0} yazılabilir değil" #: common.py:280 msgid "Creating GnuPG homedir" msgstr "GnuPG ana dizini oluşturuluyor" #: common.py:371 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "%s parmak izine sahip anahtar içe aktarılamadı." #: common.py:378 msgid "Not all keys were imported successfully!" msgstr "Tüm anahtarlar başarıyla içe aktarılmadı!" #: __init__.py:71 launcher.py:528 msgid "Tor Browser Launcher" msgstr "Tor Browser Başlatıcı" #: __init__.py:72 msgid "By Micah Lee, licensed under MIT" msgstr "Micah Lee tarafından, MIT lisansı altında lisanslandı" #: __init__.py:73 #, python-brace-format msgid "version {0}" msgstr "sürüm {0}" #: launcher.py:86 msgid "Downloading Tor Browser for the first time." msgstr "Tor Browser ilk kez indiriliyor." #: launcher.py:89 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "Tor Browser sürümünüz güncel değil. En yeni sürüm indiriliyor." #: launcher.py:110 msgid "Downloading over Tor" msgstr "Tor üzerinden indiriliyor" #: launcher.py:121 msgid "Tor Browser" msgstr "Tor Browser" #: launcher.py:140 msgid "Start" msgstr "Başlat" #: launcher.py:190 msgid "Yes" msgstr "Evet" #: launcher.py:194 msgid "Exit" msgstr "Çıkış" #: launcher.py:208 settings.py:147 msgid "Cancel" msgstr "İptal" #: launcher.py:247 launcher.py:268 launcher.py:277 launcher.py:316 #: launcher.py:319 msgid "Downloading" msgstr "İndiriliyor" #: launcher.py:258 msgid "Latest version: {}" msgstr "En son sürüm: {}" #: launcher.py:262 msgid "Error detecting Tor Browser version." msgstr "Tor Browser sürümü algılanırken hata oluştu." #: launcher.py:292 launcher.py:397 msgid "Verifying Signature" msgstr "İmza Doğrulanıyor" #: launcher.py:296 msgid "Extracting" msgstr "Çıkartılıyor" #: launcher.py:300 msgid "Running" msgstr "Çalıştırılıyor" #: launcher.py:304 msgid "Starting download over again" msgstr "İndirme yeniden başlatılıyor" #: launcher.py:316 launcher.py:335 msgid "(over Tor)" msgstr "(Tor üzerinden)" #: launcher.py:331 msgid "Downloaded" msgstr "İndirildi" #: launcher.py:439 msgid "Installing" msgstr "Kuruluyor" #: launcher.py:448 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor Browser Başlatıcı, {0} dosya biçimini anlamıyor" #: launcher.py:479 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" "Kurduğunuz Tor Browser sürümü olması gerekenden daha eski ve bu bir saldırı " "işareti olabilir!" #: launcher.py:496 msgid "Downloading Tor Browser over again." msgstr "Tor Browser tekrar indiriliyor." #: launcher.py:568 launcher.py:582 launcher.py:591 msgid "Download Error:" msgstr "İndirme Hatası:" #: launcher.py:570 msgid "You are currently using a non-default mirror" msgstr "Şu anda öntanımlı olmayan bir yansı kullanıyorsunuz" #: launcher.py:572 msgid "Would you like to switch back to the default?" msgstr "Öntanımlı olana geri dönmek ister misiniz?" #: launcher.py:585 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "Bunun yerine Tor Browser'ın İngilizce sürümünü denemek ister misiniz?" #: launcher.py:607 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "Şunun için geçersiz SSL sertifikası:\n" "{0}\n" "\n" "Saldırı altında olabilirsiniz." #: launcher.py:610 msgid "Try the download again using Tor?" msgstr "Tor kullanarak indirme tekrar denensin mi?" #: launcher.py:620 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "İndirme başlatılırken hata oluştu:\n" "\n" "{0}\n" "\n" "Tor üzerinden indirmeye çalışılıyor. Tor'un doğru yapılandırıldığından ve " "çalıştığından emin misiniz?" #: launcher.py:626 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "İndirme başlatılırken hata oluştu:\n" "\n" "{0}\n" "\n" "İnternete bağlı mısınız?" #: settings.py:47 msgid "Tor Browser Launcher Settings" msgstr "Tor Browser Başlatıcı Ayarları" #: settings.py:51 msgid "Download over system Tor" msgstr "Sistem Tor'u üzerinden indir" #: settings.py:59 msgid "Force downloading English version of Tor Browser" msgstr "Tor Browser'ın İngilizce sürümünü indirmeye zorla" #: settings.py:69 msgid "Tor server" msgstr "Tor sunucusu" #: settings.py:85 msgid "Status: Installed" msgstr "Durum: Kurulu" #: settings.py:87 msgid "Status: Not Installed" msgstr "Durum: Kurulu Değil" #: settings.py:90 msgid "Install Tor Browser" msgstr "Tor Browser'ı Kur" #: settings.py:97 msgid "Reinstall Tor Browser" msgstr "Tor Browser'ı Yeniden Kur" #: settings.py:122 msgid "Mirror" msgstr "Yansı" #: settings.py:140 msgid "Save && Exit" msgstr "Kaydet && Çık" torbrowser-launcher-0.3.7/po/zh_TW.po000066400000000000000000000132651456573360100175620ustar00rootroot00000000000000# Chinese translations for PACKAGE package # PACKAGE 套件的正體中文翻譯. # Copyright (C) 2020 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Koala Yeung , 2020. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-03-23 15:47-0700\n" "PO-Revision-Date: 2020-04-22 23:31+0800\n" "Last-Translator: Koala Yeung \n" "Language-Team: Chinese (traditional)\n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.3\n" #: __init__.py:65 launcher.py:470 msgid "Tor Browser Launcher" msgstr "Tor 瀏覽器啟動程式" #: __init__.py:66 msgid "By Micah Lee, licensed under MIT" msgstr "由 Micah Lee 編寫,以 MIT 特許授權發佈" #: __init__.py:67 #, python-brace-format msgid "version {0}" msgstr "{0} 版" #: common.py:100 #, python-brace-format msgid "Error creating {0}" msgstr "生成 {0} 時發生問題" #: common.py:102 common.py:180 #, python-brace-format msgid "{0} is not writable" msgstr "無法寫入 {0}" #: common.py:177 #, python-brace-format msgid "Cannot create directory {0}" msgstr "無法生成 {0} 目錄" #: common.py:187 msgid "Creating GnuPG homedir" msgstr "生成 GnuPG 目錄" #: common.py:254 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "無法以指紋匯入加密金鑰︰%s." #: common.py:259 msgid "Not all keys were imported successfully!" msgstr "只有部份加密金鑰加入成功!" #: launcher.py:83 msgid "Downloading Tor Browser for the first time." msgstr "第一次下載 Tor 瀏覽器。" #: launcher.py:85 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "你目前的 Tor 瀏覽器不是最新的,正下載最新版本。" #: launcher.py:100 msgid "Downloading over Tor" msgstr "透過 Tor 網絡下載" #: launcher.py:111 msgid "Tor Browser" msgstr "Tor 瀏覽器" #: launcher.py:128 msgid "Start" msgstr "開始" #: launcher.py:174 msgid "Yes" msgstr "是" #: launcher.py:178 msgid "Exit" msgstr "離開" #: launcher.py:192 settings.py:136 msgid "Cancel" msgstr "取消" #: launcher.py:231 launcher.py:245 launcher.py:249 launcher.py:279 #: launcher.py:281 msgid "Downloading" msgstr "下載中" #: launcher.py:238 msgid "Latest version: {}" msgstr "最新版本︰{}" #: launcher.py:241 msgid "Error detecting Tor Browser version." msgstr "偵測 Tor 瀏覽器版本時發生錯誤。" #: launcher.py:256 launcher.py:357 msgid "Verifying Signature" msgstr "正在檢查數位簽章" #: launcher.py:260 msgid "Extracting" msgstr "正在解開" #: launcher.py:264 msgid "Running" msgstr "執行中" #: launcher.py:268 msgid "Starting download over again" msgstr "從新開始下載" #: launcher.py:279 launcher.py:295 msgid "(over Tor)" msgstr "(透過 Tor 網絡)" #: launcher.py:293 msgid "Downloaded" msgstr "已下載" #: launcher.py:393 msgid "Installing" msgstr "正在安裝" #: launcher.py:401 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "Tor 瀏覽器啟動程式不了解 {0} 的檔案格式" #: launcher.py:427 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "你已安裝的 Tor 瀏覽器版本比預期的版本早期,這表示你的電腦可能被入侵!" #: launcher.py:446 msgid "Downloading Tor Browser over again." msgstr "重新下載 Tor 瀏覽器。" #: launcher.py:516 launcher.py:525 launcher.py:533 msgid "Download Error:" msgstr "下載錯誤:" #: launcher.py:517 msgid "You are currently using a non-default mirror" msgstr "你目前正在使用非預設的鏡像" #: launcher.py:518 msgid "Would you like to switch back to the default?" msgstr "你想改為使用預設的嗎?" #: launcher.py:527 msgid "Would you like to try the English version of Tor Browser instead?" msgstr "你要試試改為下載英文版 Tor 瀏覽器嗎?" #: launcher.py:548 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" "以下網址的 SSL 證書不正確︰\n" "{0}\n" "\n" "你可能正被入侵。" #: launcher.py:550 msgid "Try the download again using Tor?" msgstr "要試試改用 Tor 網絡重新下載嗎?" #: launcher.py:559 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" "無法開始下載︰\n" "\n" "{0}\n" "\n" "請試試經由 Tor 網絡下載。你肯定你的 Tor 有正確被下載和執行嗎?" #: launcher.py:563 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" "無法開始下載︰\n" "\n" "{0}\n" "\n" "請問你是否有連上互聯網?" #: settings.py:46 msgid "Tor Browser Launcher Settings" msgstr "Tor 瀏覽器啟動程式設定" #: settings.py:50 msgid "Download over system Tor" msgstr "透過系統的 Tor 網絡下載" #: settings.py:57 msgid "Force downloading English version of Tor Browser" msgstr "強制下載英文版本的 Tor 瀏覽器" #: settings.py:66 msgid "Tor server" msgstr "Tor 伺服器" #: settings.py:82 msgid "Status: Installed" msgstr "狀態︰已安裝" #: settings.py:84 msgid "Status: Not Installed" msgstr "狀態︰未安裝" #: settings.py:87 msgid "Install Tor Browser" msgstr "安裝 Tor 瀏覽器" #: settings.py:92 msgid "Reinstall Tor Browser" msgstr "重新安裝 Tor 瀏覽器" #: settings.py:115 msgid "Mirror" msgstr "鏡像" #: settings.py:131 msgid "Save && Exit" msgstr "儲存及離開" torbrowser-launcher-0.3.7/ppa_release.sh000077500000000000000000000014231456573360100203610ustar00rootroot00000000000000#!/bin/sh # This script pushes updates to my Ubuntu PPA: https://launchpad.net/~micahflee/+archive/ppa # More info: https://help.launchpad.net/Packaging/PPA/Uploading # # If you want to use it, you'll need your own ~/.dput.cf. Here's mine: # # [ppa] # fqdn = ppa.launchpad.net # method = ftp # incoming = ~micahflee/ubuntu/ppa/ # login = anonymous # allow_unsigned_uploads = 0 VERSION=$(cat share/torbrowser-launcher/version) # Make a source package rm -rf deb_dist python3 setup.py --command-packages=stdeb.command sdist_dsc # Sign it cd "deb_dist/torbrowser-launcher-$VERSION" dpkg-buildpackage -S #dpkg-buildpackage -S -pqubes-gpg-client-wrapper -k927F419D7EC82C2F149C1BD1403C2657CD994F73 cd .. # Push it to the ppa dput ppa "torbrowser-launcher_$VERSION-1_source.changes" cd .. torbrowser-launcher-0.3.7/screenshot.png000066400000000000000000004213531456573360100204350ustar00rootroot00000000000000PNG  IHDR9Bd sBIT|dtEXtSoftwaregnome-screenshot>-tEXtCreation TimeTue 06 Oct 2020 04:47:58 PM PDTe~ IDATxy_eyyɬ7ke hA\mzm]޶Vv{z֋[Z[qA@PYuf2]Nf I&03g}}w;ҳE=""* ?Tӯ yD AQţ ".QATŋs@|xBN#ZǴ75 8*CUCq+W"R%&@4.Gј.bH(t*uLBLUh,Qy+/|(XgB=i"2Ї(#4F lf(WՔ؜Cmmh|J C.tXfι(G7HbxRN|Pg\Z+T1?⢈|20qxBwt 128/=Y.D@%Qb=i͕(ԯքpb.c9,XhQfo\V8;yxć 含4JgtBH 8 *xK%=O% A@p1?CUpQi>& g UӠb},IqUki uI:(OJ~q dIJEZ;MY4k]PNP.ꑘP)3/+PI.hMGFGs>"I#*PL\e}qZ=ޥOzg.*itd=Շ:PgxXϨ5슋$*xu1M;U]4 Th.nuC5{v3G\Ԫ| +̺P}|Cm+}%ó z$6XMvR%k(k yPUi&Sv(h%a >/KoHƖZsQy vq9aAshtzE>@|Vv#aU>*IԄ*A| mo:/~ iVTb{ ʉϩM*@#4N"lfL`eU2ւ8rxBwXϊe>6Sk4Z`5dߤ(?4 >>A(/Si(ȎjЋ.ׁJUQ&qAuMU&?+ϊ0&~v2s qN~'-Ig&?B}?IV޶k5l`tX>xR{D_V yj%'9sQjeETB)LD5l`SM]2кWVJuW|o}o+Ӕ*Ly9{5^ju*$9g7G[~֜M**CJ-ʠ$d_e 4F緞7z&*YH䬺JMX|;%'Ix]Uhp4ct³PSZSA*۠OJTF) KY3Jb_ Rr%j ŧi%5\ѫT?K9$I|^HԦ}K0LMk(IQƃhp s'F_S vHpRF5)1B$55v@bd<\T'{MD4NUjIIViKA6<@D}P潏2SdOch.z~-STPzfNm4_'ňJ$YPCM %v 22)j2Ss$c*799d+G"w":J{ vޓ8w1'^rѺ!ЬJ: &h\1S[+/PpPXujE|W2",Src9-d$%Wdt5uHQWΌjbRK$I;4K:Β"iD9u[R]*(L )uYK|, 1,85 =[vGpJNc\"Y%=UФbs]֜$6*YGJ?U[@}%T\ԭR$H2>vK,FEl'VVTeKL(A$z;HT hZDLD[\\3uYVQN(dbPSۯq" BЂ*RTNlA.۬Hi'Nf/5Tv.eyHmHcgDD OemJ9[.UU'=XS Ug sSY|Bl_C%1=HJe" x1,$+ѱYԃaZY%YPnv;IƈET`p.ȯ'tA: A&-NÀt$;gMi2#P4:^J2 Z Ey 6G* LUNFܩTn.˔bUd%F ef{ntid|URwWF̧+t QTP1FdH*OHWr: X┚U]|&$Ò3OYg \Qx-I:땘>bJU]s1r!. 6Z^sYi=)Υ_d:颱F%ׅV,ԆHrY4JqY-et\==bz~s쓆`MKY&- TOsU#Ilby8E'_Vi΅e0SR]4 FSɧ,MU/u0SN»%N?uujԩT4jG'k*[NK޲O%/j 2ܗW3`U'WF>Uu,XRuWύ2\N6׵fGNq.S+xKR`sYvh\{k+qZ]ޙ#GHU5VJjNm87º9Hs9 e0I4 p}R@wKDAܕޞ4B-YR\rRW2jq9V41JFɩߛl@U5[ u)niLI^]%IW"Lꠇ47ݛ@jzWzN }T -;yHE49!xuz^[cޒEs򙺼hk!2pVZKurlKbʏ$'u_%PJhOf);)ho P9.FfE2 *qFɁ::-aH$N NKG_ 0ӫS@բO{)[hMI DEQ ykׅ )H}ATa|x_A#[;!Ir SjXuުUJ${Z%%BmCVUo^-z AzpwjUJxlO{Tr깮S9W rWg9rIJɉB$fgC 5\v|H 7 2\18DRTS+W[Ġ̽#ɡF!T~T `Cv S}֌1OJuG9Ȏ2H&*ÇtjF2I ͨHD7!rϧ2M#YB%ERۨdL1 W%^='#k.,e,iH5 pёJk2DQ+ݐ&IDõ.4MUgyVHrũ2D}[ӀqFÑFs &e;t_0)֔,!Шӂt4YEa&Y %֎/Ղ Xx MFF&NzwH.dOȶ"_\TUPϬ24*㠲F"r!x՝&iqqFSI.kYTIX -N(5mr|dvQOQ.ڤGcVYȹV!YCiZ;Ul(!@Iȓ>Hh04$E'ˈĄ~n]%gu$"⁂4%Eõ~s:E纍:* T54/kH,-Hn7FJ{]Ҝ=嵦+qRDӾmG}&j^DzVpsrC+K*%TRUg؋h<3/U[8 Qɝu9j)Krʪ4[5<8ϖj:RUK_R Y$PU;\V˺a֮S= w$?Ke/L$$lh(jvJEk.ܖ$ʌ$EfUw?ZOPy^=8Lk%(|_K\ <Xf2Yr)d}H0M{ JdžPv-dHt>yk^=e,^M7s40K:bU!9 EŒtT25&#Iv~ɵ*J2uPjZ'ojWl6Yy*N>X~tÏx|(iDߑ9!IFsZޢMI2w6\uauŀPt*YՂyKU?gʤE=I*Bu& Ie?5y5 J>U-XGq(#^Z$`?Q-9T8 yons#iEM'DY";9SI|mxfTkͤ'9PS& OhihUفkZBboONAcu.]72c5ё:]io+#\/iahmAv.}Ⱥ rʆDz."]snc␴Cm7yFh1e9xW+zKetuRId3SH $ۙuJUBj(*HKSGu]½w@IO$AQҀpŒg\fju4+{_,F*C'Qe48\8Qx;V KVILCM jMuLjVKOZ*_^+$2A@\@ 6Lf)QJ-3-!58$[rhRZ$eHS)Ak+n22|dk"JvGLSh%ny9>&OZWiiGli[hBuzB_ Դ!NwL)w#7j3 &U9Gz3*TR+r8)NbYRIAј\ Tjc,R~u![U_s R Z@kNS]1.kjqyHʲ*0IhKTZ3Dq9} H_gI6kC']I PzD )kHA8 OIDfܲNUsXJzeTJ*&1隚NT3h|tJk@㧌|=vBG4Q|V >Y1#p'G}iP}B &YVUnق?l6nqd*e Wu'<*|nuD5>!B^c: A29/i&fWX% 1UN%;U[J58MuXOX Ux \jZ=EgJ.}qr$[zeh-i rbciJ|-Q>Z*Ї苉O)QSVuSQ>\ni'仧Rr>-*FMm80;ۑrL[k%!] 4}J Йpel5$֍VUGfd+/nL64ug}VF?5ӲP((}3ϖ 5O雡sDW>4i[ރ!'3sئr'Z^Z5d$U rZlSd~tp-|gwE{GTIKg}~g?*΄?搮G(6r XSM eN[A[[A5f: :P .rrzt>U|o3^}=V'?^9-O'D΅/x*穎Oʓ&~)BsD+o:Nj%{_tZܒIޫ㴉׍}N 'rgZݻ-ݔO#dL/Te~l&5I~ ǎ[/VY&(ьslv˱ pR!3xV˥O$ V2DDs d}NVY6cOL[De"i2 Ε32Z242HfF84۷SkdhK}i8mI4;-\@OwwXnaaa^,Kزe}}}H *f0f"1iUyV0 0 0 0&c޼ytuuMZaܹEΝ;4>'" N$WA}aƓv.;UAf 0 ={ .*? u_n0 8p)rҹpsp׾wUaa< (ޖcM\oo/EQLmak|œbxqsB!Dix(a8?-7 0Ys%,m_]ǿGiVZWrΫpw^šC&6~IGzXv #m]v^aOi7Nz+i E|tM?hse͚5|Cʛ؋Ӟ/q}p$nGC !>Q{0 ctu}dD#ޓ6WPOC~*NOyt!ł+Y [ܸvh/0 0*& 9stMoh[V/ui܋8<pqS=4??PaƬ8Y+.Z~_lk\UVC:9̋XMϦ?ֲ/[} <wof=?g=FW I²3^b?Z-┗S0ʃ?2PpȚWs6Wn\GTi^?=h1{;irwogn0}k^YurȡK)֮y:YZ:8Wr抂曷nB{O%/;ȕ?\h9i?O^0;?GB*'s ;#Xwm~6Fj=aO5wJ}[ @́} {ԟ c p q˰4|w.2 0fÎNhj:w_m^wNH<>lΕ!cƲ^ Vϣ)iw<{ |}id~`d4qч0lЦ# A}16(ö>>olcã[(W,kB:e%KXn-,fa:G/8m,r#1ߧOQӿks (↵s_ԃadbc/|ic5upx{!B1_wC bahcMxpq4p>g ޕp폱}%8fG㦵C{/9`>Ⱥo&[s?uO#M@?7{s}`Mz z%wܹCdh=EZ(2-\¢Ưh.[BH:v-^L(#9iEu$'3>wnt}.=g}]ˮ ҹ/0 0C.'سRòAU q4Bp Wmoa&`%C<~tkq3rQӽ1SqO+81=#iQ_7v> O;Cxo-F~c T_n^?{/=u-lT\[su{4g8sb:iٲ;OfѼ,Y]:FGh6li/17`x+9rݯ箻yhXE %r8*v 0 اi53yVB!+o6 sP| aA+' +9VuKWq&9QiqΚ8 75|la=vsxyGӳXwO#q: Q.;+gtqȆhnⶫf'z!,]Lvw\= )GձobmAd1-fc,)ŗ)c/aj*X)x<ԄLa>Gt#xFv|BV~exGbʖ~ŏnfksfap,?CR^}0`N[?7Va2 tuuoݫ*wo9 L}^ _ S}9qdaƬ0GBc#۳uT9ri~͏ld[0褳 n[=?r{jwA5hx/Qd6 0 0 0 c,{31x0zڋ" 0#_w 0 0 0 8@~Z7DJ]8_߂|0 0 0 8`V+ NihҰaaaa"/oç( 0 0 0 @"ك"x#"8'8oaaaz.N){qG?0 0 0 08^\xi}M|?5 0 0 0 c BxTAxiBq~ߴi,%0 0 0 0$}.-Wā_Ƒ{(i~`ѢE0 0 0|pmw.|^|Uh@>ޢ޷<;6 >d`aaCA5nG _^+0 0PTm_0 SDѮ5'"qy'xJa1)0 c 0 0>'KЯhO zu4>WToaaW,7 0c>P}6p UE M7 0S0 0&fO}=^@]UGC;~'aiPnAaa̜1 ? )My a^Es 0 c_0 F 0 czI=i z6 i$^~7g0 0&{30 0*k' ̧v S;$}J< ϥ^WWx31yoag:dOwlLc쎋燝Ja)zl'0 ,ߛaa_ VyGgg'W]uո/B6lmݶSfl2|ztaӉF' ߉ ;i|H}ȽH4Yg}6wq}=?ø{=sNv @YرM6OM:;;9묳k_Z˹K.SN9kvRgl0Q=UD| 0 #S}o:Aؠ}Qk yc`/BPO4ۗ2,XN8.?|.][;vpWsuk^V^MGG6l_:smmm?';pqO~^s=}3Jdg?>9.n?䪫SO= )۳e}OM0 0&0^?Q}/݉sqqͽ=\{g=܃uV>l\w/}|3~odÆ }ݼ0<=yٰaä>r 7;-*&{uꫯfڵ3~+>W\z饓n}ncDŽa;3>Q>ߧ0 x2Q=vDl>x3݀oo Zh*F7/K֬Ymݖ [o3FK'wu_=/zы8Sعs'{,Їضm\s /x 83w$؛Xbw[UK 'c)hOqfTAa,ȟ,CٽN'AhT =X,Y-ܒr-9X~}˽7of…,]{ƍYd4Ci7_^:4b7y0Iப OY;0 0$[[===tttOφ>Q Upai}.}{w;f͚ݟl6Ďi$fdL>E}=|0dj͖-[PUz{{ioohTal6~-Z3 m>bBpO{i#|;|o9= .˗\dbpHzTQEݎ瞽f'0;Xhߟ6ڛh=0]k?:n6Roai@tnc؞kټc$=:a}t|08,7g&>mkaEUq%}o8P c*cwATUCC(b%0 0BLO;aa.+om;˞t%hc#F0 0'dGEda1{x[Og WyDP '!W3aa<}1{aA卒E0V:k{҈b`? aSF-7 0'ΒFŽ8kEL]s./|yfO;_/P߹w Gi80 S&?uaa̜.ӅA^3ėw;c`}O҈=*8)g=UixѼ{0 7؈aa~oa NvQ޲ewY/gHO92mR0]? x0 0ft׏Yoƴ=s274׹w=J/6ц3pNADsoaS`aSx/kdC>38u*\O%ƓEIƘs={>C{_20e9qa>Ɓ@dƍ 0`뿏v7& ?].}nWA.g!w0GyiX0gqg\⺵|I;\qo?w!Ʋ3yi s+11\O_O2>rեk˷N)_Fc99s@_7#m Nûygs₾?/}Wڣ|OD bn#Xk~o?})_2@;N{,aǿ~njGC^~a,[0;?}{Hj@r;~:9mǧ߼N<}XN(q4lۥ,\q2#_͇~kѧ\q'sؽ7`#q#~_amx|l'-LOq^qEU~X0_%/H' &Y+?6S4: ?~:R8'>x'! >O,aJYeCEw( O Nt-q.Կ3'[(b*9M˯˖IUgM>!KNfB 9aSNWW }}}8,ȟ!Ry衇`ddd 0T߼l3E80hr?'G9OOּ/.=^rt/~x֚׳90x#7C󩷿_xEkxo>Q @5r#}{ɕ~޻7_p;U}=6ۦ7G"w)pyJ7ǽ︊~t%,~9]z:ioo(2 .gSe`hop)1c?мNE-mx '7_>4,]<~M7-]Cy9 @]ņ~sRq q\{OѼ_':/\}7_3Ӿ|fC7ЎAWm<ݯ =6{XOZՖI8K8i^~ nj=#S00^,wp%;︝_oE9ۆ47OBrVك<i4OvnW<|1'.8~A-l]h( ]ʄ_Q& ,}N+"̝;mFѠ =LQ\v- ,,7 06M -N9EC+ڔﺂo޻8ɿs#&h2{7QP>t37?83לI١X;\Wѽq=9hUϣR>r_Ϋ/:pﻘ3ķB=-8_﬎h߷ӿ-$>/zY[sG7>^|x*ȷo_9y?1^^{MY(KJ 'zFnN}ͻ]7Ʃ[F6wQksPB ū^۵^koEŮł4E@( l9qvH|ٝs{3WARMy/\3#c89Rgfp^`ѵΑG'VZpl+oUgSWYNJi̳螸P@CBMa:###O8/jԮ((& YڿHJ+ofz'wJY%SBF2\"X+"m*f 7>85umֵ-n\R'm2v%YLKsI|,m ߦ?ȋr2naCJ.n{(!6黷gZh477~ii)6;]^QEQEQһr^eI>Hqq1$*ut}`.]4Nܬ(YEQF`γ73ۡ4,ƻ9A [&/ۭqe:r*x.,o{Itn#һ}+NݙL&Zn ޽{v!/o]}]n3x`:wLll,lٲ 6PZj,-rw[o5z,7v= WC4/0]4| EQEQE9-H e"ןn}RzkƄ{&f>I&{5xU1g@.Ýkmt%ޛs3ڳL3u,̨װϤˆ9)yYF۰ n5RWiU޽9묳Xx1tbۉyMܟ?l(((JՄ-'4 !Y=sgH#* nT_U6nwvcw߱~z߶Rn֭[ݻ7&Mj#d*Ju(q&uC?Ofߺ4ƽ܏O!~W*=U (qRmvtE<'O]@\H'bv}aÆ&l+**C5u3{((g3f4RxRS4!ЅY^`LF\{:7ʉ뤔u #ci"AWo%44&V%-Q_ǘ\1c33w2NysK.SUXM~I6X5+eYlJ[̑"cd偟5W GVUY5IٜFއ-g|#Ď$/hڕQ.R o8ܥ}7v-ۣ!)`c"26V(L&S]gM||Z˫Kj; >(Xl1ڶWՆݱcGKHHN,Y:UvEQEQK.$k!4ti3ßMZq\׸iiӦ{0..p}򲳳 ߟ\@PP_}q7#Gv̶ ֻC՚ !5pݸqUu9>B`av<ڟ?>D-kNe[Mv:E'9w3yj8+җc&ǡ5 [۳ְ7'RWQrۅ.`NO=6:EE8nUUSVpF D]WpYvװo:8$ڄu%¯ v0$R̚$)}9BGrNNQ}-N-ݻ7:u" M(**B׏]d̘1f~'_p}y}v]tDDD0`6n@bb"lڴm۶QRRرc47Ҽysz͛} gݺu,Y!Cسg%%5^|l6_M&G&99*PQmHtttmڰa:ubƍ/u.6vl/25k۷o_~{nrrrj^UjjfK/eɒ%,X۷ӱcGbbbHNN&((J)oj6akEQE"<<ͩoKݞB||$BHiB%*̻u؃ы֡C:7lfRR]y@y-[N|[J\\_~%̛7Rv˵gMXXYYY&a&IsoGW3-_Vmud)VY0kVRRrѯhLLt@k8ؖW[NZ>RUb\ E0*=HxtRXUm۶$&&2~x>3Ȑɓ'Wzmff&͛7'11fSb^748W%']  7| mPQ]>mky5 j>AAA $p1m{UmlذK.,RRRسgo@mEQEQ$Ҙcˆ1^K$F|#GH؞Mp\X,jڷo_ w\hZ\էd2DKll)@ZQmp??cFοm0 i),%h;ֿNoﶗ&r p7_:f{36Wgߥ;,>Dt@V#pI'D &5 .3>u2VԖA:J[–Ln}7벯'-[ΕW^ILLo3*͙R_͛;woQ$.N4HEM _[~ֵWSj;)NڶWՆ{ٲelذ֭[DŽ Xzoڶ+C4PEQI'A.Bn70Itn unݺZU`P"֏13g6H'~'m7,ƹۈvv ׃M 㐥կ.j"h k8>x .p&OrNE)4 lM6lL[I)v7/Etϖ0h dž t]FFFrJm֬kDﴒxˌ%i;p|{:Q~WCW۱idnSTT[W^ݛ?JYfMS7AQEQ  HtfB$RJfHlt*^*/)++5%+`=XRtB>}}ޠAN2x.@)Jpʷ+?/cv_ۏ/ln^^~Y9?s &ak@-Awn֬XBd EPcGQt¼`Q-hK^t ZC}ŅtfL DDa3МOBG.w;\Zsq׾ևngĉ 4h &>>ѣGNZZyyy$''3dBCCBТE &OLTTȇ-ZitWGUrss9p&44ɓ3CJJ $ L߾} `۶] m?tnoj;iiiѿ_Rϳ:w.msWi(PvEQEQ &$ȐϏ1ڬ:&LH*ֹ7LPku!{"Ac`5>g&L ܹ3 . w0V ЄЖ!l8YT˷4; IDATg,uIFO>eUߊ?|u)%9iy D\H'ttMR?$NCQB=qA#9w3 s.Ha +R.{=_YX(t5c%i@JKKYd } .n:޽M6zϟСC1~z22<k֬aĈL&RRR;w.FbرoU?| ĉ8rs=&ϟgؕɬYm?kyfL֭OOZO?ù(**bҥDGGc2us222 dԨQt:9ty-vQvEQEQj'+M[HaFx#=چ dwd_\zM9qu{*Ҵ*^̪xn. i3%%%lذd5[QEQ:JLL]v=_t9|xzc>-5}ABw!&:ñ='Az˗؁=ٺu+ K.,uVEZȞeE7RMQNk&0EQEQEQjsrIH0iRxR{fDW^kX(,,߿΍rcFGaa!6(!ֱR.\… OjBIg' KI~-p/&K((()F:сs/5/y1(,, }* ; Hų*(((&kBƒxBMJ4DGJX^VH[,q8tIqq1REQEQEQS8Gzxh:]jHU:Frj^{EQEQEQoO'C@yKO~Mf3fF n7999Mwd2 g)_QEQEQI5R{zUxt$n4Mh@u(bi :Dp!T* (((MH c;R3 !44 @Hc/.rFz؋_Pwp7ȗRv)** L&O`*EQS\gjSXXHbbb]n]pm^N漗wM#/aIP{E9eS<>m:/|S:'S5#45c4zQf$F|%'Vfl6vݎ?߽ʉEQ(gzNW}6,37i?/VwI8BXwip=+WAрNښy>=伨f뼿B3ǘ`o ԗhbB$p}rЗMMԭioo:%6;-#'* am2smz=&)w1s+;K0ª5>iNR+8mbnNClq{guRK*>Ѳ$=^RL& L͍p@&sZ%QͽWEQSM|%D}}Qbqt epk2u^"X9=*iMnǐk@+*J#@ncz=hۄ\ 1Vjv+()tϖ/{Zj#K[xr^@Y^|>_Ksz#=y5򿿞&G1n$-&gRc|y2 pj! ~i\}s /:HFt 3,%Y~[V&akٛGjX}o&T7x&o\76l,>&WEw3Pw|Wnaoz!r-(eWqK߳f8z22|ZNUnbb<[0%H@;=7#S<]ͳ-ȼ |Գ7o{m =;L=}+(tۈy7_ۅ}?}okvE$/t=+)EH; n9|fjݗC:Kw Yq_](>;hsxjTF0 ȚYuhUmY\7C_>!o^R{CtFM#=yTcyUo治iުMӣw_@ R,@Hc+TEQoĿ'};z.݈^Ỽ<&59 I(a9_|8n(tyՔL_Jm'ԺkK|;Y˗5`y4bf@`(I,Bb!ݵa|(BEx^H-|?Gt1w:?3̳bΫ7 y,fVAC~'~]D?&JEwZî`jzg ?8Yxacge*z2`!z]/QDy9hAO_ê z'ɔDư~=z Dh\':w>z1=XٜN6=w[\_=+]Y7g9?^a=;ZLٕ|,Z[o'9O?C !Ռ'Jd] :+ѷ3m[mwRR&tZO:wCZs.t reK([Ytbڙv?eb| 1114'(N%5n߳,Q/' 伛CzEeNNpr a@? )HBWfm YSM:II9ʹ-=퍡嘷H#50ۂ(Be[xٔ=ML mSMO}.Ư%1WLهSfɪwqٽߚvn\RG{֫QA=Z>ކ++Zz%N .c(K~~&dnf_&k 6f.Yҥ^yQtk{!esx~ gtoCO߳Q+pXwyO<_V Zn\{.g?xnYƥ{b t.I hӎ-^s.aٻ3! )Inzr9ߘ ;T jbZ?dδ [_4|om#iCJINn.CVGFJ FR|] 0I9JMHEQoG}v .4@lṭ_0;2F^ sqK8/߼5CG?y{9riB'CWoߗGh2.Kgzvd!sWr;K/a0>NtI#!!ܭ!$.| O&w! =1s~YXG; #ԯYݴ<?~_~Y1]wPio{b{m/j_y9X MNC&bCWS1{RqWs{cmq׭c߭]zuU@T:›{.&U9h /-QEt䖿P9 zbs۞t cłu~IGn~>.Mn~>9yḙBCzֻ&LH$f !;;K'tipMۂ0A0}^E/ׯW2AdS`r˛&[h)3tL+{ Is Luo9yha5w2x;){<)<_P.t~et֊@M~={7?}{x{iaљX?'J6!"ѽy),_%2o/eb̀}W~2\V= bџ)gpa=;%pg?쳼|Y% ƤKZ}3nw7'x{8Lyjii #>z}g#u;?z{ռzwg7paF)LxLg7>'޳͸Տ8d,7'~t j@ݳF'k">}a>!HxoMd o#/>==U_Iڍс2sW?M G>rVbmݧ|͏a1i4=2SqѷZerUcR1!<“XܬYsnB !{hcC *x-G4RxZWkv"??^- &!!^QN/2}&Wv/g {/PEQOD3NRx))U!>.wG>d;}}h}B`u ]z; Nke\>~<. #T(ɦtGOg,Ǐ>æ*WE9 o<"fƱĤf)$h"MT< =y_QEQEQ$ߞ)Ѕ@q#,ƃ|z h:hQr܄&&<: ((('#A҈݀.AӅqGQK] 08ȨrOR$ }D|LTʧ(((Ұ<ƌ{Mt_izƲzy o=߰|OJtL 앆#1-Gs(((MH] !#D5Y[_aFB=ICP| M#,2st(((rzx}4R| x;Or^'X-5u3THx0fɓȢ[(((ʙ͖֌wnY3{$%s*D-S.-++vE~~>999ME9텅Bk|ݻ)(( ++$LQ'""ڶm[2q tX IDAT` _3 bfOyzQX[]8MI5&I. ؟̂ڟ(4vd2ѻwn1ٽ{wݻBp9܆)J=_={Ю]:=.#S^ :o[Z )) !0K{6O1ػGJZ$~""8dz>z&cwDTP~?!1M RbFHT(JSgȑM E9`j0l0zrݻ7K,s5FqV=WDwIlZha~-'S?+9ユIeWf<I,A((M~[N> r0?h;=')2d4SQLhₒc+-'?taɘ_~ TM,&mhoDP,,0#]"sI2l.\rd"L/agZ2W:}ȫq/c[u%_?[z odg_ȈJ^V!K~X/7uEQEQxen.x6|B ˍޝ̞Ss5όxIUN]8IFx׼gƺ渶ؽkFoVżW4L$ڙ"w.&͂UؐHtܾJ 6Ѣ[ Lf䥸[?>@jR6@ 탰@*]W57jNAkŎ/*wx-_6Cz>ݿ s]{`&[ Svk]/O#l^hh2sW$o=H͸mgz_M\tGz=I)$"6S/c}2R'[Ǐk1SS7MQEQ!t{lԣ}m,߿NÅ-}OT6Οa"ezV~z.eԯu;[]]n¢ =־GdF$5#ȗ_z!В3 @X|Ixҋ21 ::.1{tnpNRHݜ͖2|:~9؍>ӞS"$,VN5׌o]wx+KpJ/O_=vh?^\>TD5#Tf_92/O\0~t>^]V}|-̸</]ܩ,:Vˆ0R%`#3nJp35Vr|GPh;2vz)bmnNlB?s?,{0M ])s[hj~ޜL?l6lU_8$-fЦYv;~DʐSx{E:S o^%U@ZmwahHqw'1S}t14ý}l†[te3slKpYlu~uf,DKHzq<<_5ofF7N)&A3 }a;?x[4#B}Ìyv^]PVf&}]F|v;<%F - ̠m| bdzY[gq}Gj1xq _Dk"$.7u7min*7yWQt7B Bz/"( vTDAAA@TARH]Wi !߻;ߏ[CQ3zwvwfwϜ3gn_9OT, ~D>گ>etC$J&.ϘNL\ kaVx/?[A R҄"TF3"Rc5l) :Y-j$̨Z:8htYg4BжT1 .CvspeHJHERڱ}Yk"8 m6ʒ_vY9Qc8Vs( @eٶb?RG.aJ+vв$s܊ToPϯ5߱ 1Iy>x4BWg(b2yw7rf,no]Byc7OWF> ͮ5tttt&UFXXCj@1R0K^:]\SD E֢3i?k\[=^-BP"T9٬ZvlJ)K#X~VF:W6Lb`PRzK|(|=# ?EPߟ/#c̑ :i/_C,AF}k:Eܥ15Hϳy{1,-`B!?NlI),dZ 1UPfMj֬IU(fyn|i;y9{8w)6<\;l+zU/ <Z.ÚӱY&6ͲsVrLw" 8j'v!ݼSsUҏ󠥿̧~`XzT,^7O* [J==Q"i6x:#TLerWtk}S|۬})1!u=J)K|3KKJἶ!*]^u݄$~{ÛK-'hꇷD}y8aw͗6-bhWXs.!1Pt-)$f&h҄ -[R 3f-jt/Jo:8x(g[f^ &'Ix;KugVLXP3N>nz1qh{ )'t(BHNH( $8 'cn$&eKKs[./:"?naSleWz'6潅#79U+ e{=r}t<Ȩ472E8eEL[ILЈ8-W:gV7x]7f򌞿k2eT-l-FͯՐؗ?ߴU{1_M{lV9dszfKx6nISGgW[^~/>쳖NVHy,]yQn-& Ň¡)qp$!AcYJb3g\i&jѮb%l5Pʤg,SxC~a߾Ҝ9K$僴8bsujW\%$QYMm4mAu;YZ0jtjE ǚ }=>Ş7PH5{^br"#yt{9gK OE&56cok& ֬fb{/,ncol=_qMi~Y'F]5^'^JgfEʭ[m<^Ŧ*tp` ^nDFUl}9SRX3nI+ֆطeRnƟS?3˿睦q0 C]9ݍݧ,m ~HϪ9ܿY:{]4͢_ΊmI;~]&7h~㥶}s>}şOvv0 ]fhwd:7Y"{8ܐuX43Ąlٺ*y7ń,͵(p9?c ҌDHMj((y{X}53WUE(ސEoCFqa v:MP,e'fiXۦk-w;m+iHsTѼ?\ωzd$vg]&84nw">:W!1Bݔszn&meW_rB]˩8uFBy^|VgxRo-FKr0 nrKqxsበ:StxHJS(ݨ+95%we޿Q땵[}֞™}Pߙ6C3z84C! d.ǺM `D4sT^_nL[GS&G_ iՊFg}ϱ-e Дdg}<Ḋm;Uޟp =r~DhIs)hFHkYk|pH!R̽jw`9R&2⢸&>^ÌINH%>*CM \t^l&d*ǧ\!Rq1(]^˟ wP)zpE<|ܨZ߲3cfU_&ܩs#>:'%1ګ'旡:VhDT:Y<|a=xuNZM8v"^R@ ,RSP#׵s.tucFk8ъM1_8Ɖ4vJ@k{09%_am1?Nf嬟 uzCDQ717ΎxUlg8ؔlC 7}{0%$s~^y}eݔEQ ڄD-z˱WLtKǾĦe9OA;Rѽَq1% q)H!nハo9M|w 1R.4J-Tp5ѭ% {|~y;~AjQE:ԯBbE(QyVh+|/H `>4jZ![бڽ={mRf2DCR9zj3{*6&H*GBmFۺoH=xx>EyG"`Tji0P(zmⅺayc'Z_Ə BC-%D(¢ M wFTLHH4S] FIF$3FRb KDkjt*8"i7se@z\?.}}-$)G(K=kpwv4a\:yҕk\˗Rr`qF~6s7e^zG oCTܱ$wrBjdŋXF$o_o_n 0ahFrB _yL⌛Ú?=ttt?Ҟr3+=$A(+AFV-&4}Y܍x gȌY߆29<ynoR* 1WSbxެb~DRiLs!e~%~1SKРn1-tTp*L)E氒K[42Js,Oӝ˘ Ƶ)aa]],K{%? ش,;wru'SdN)tԲd/&s9H(T!8sT_6,viѮ6&cGlqvm1h3f1xNb`ct kUb.3wc6k m~WM : }c_Owg8).@RXUX,'AQhV]<ݽX6v]'v*>34z`xi@I8&jncS2 NJ}Τ IDAT*]xaMVm,\zWbWZ URB{?T1Frz) 6W|! MӐR+iQCٚTwe֣6 hvl=Vf U=@&\rn@K$.^''s 'T=JX=Ukcb;SI,Ѹ&:Zc|鴛X2Hhqv}f}0lbN{E/'@H5Ӵz2!*}PqD:4[;[ݰT3~:_v]NK锪Sz:bH Z*էS0e:{yL{Je9Sy>m+T/99|q޾??c`>OP%3iߟ&e A=3|m ZW2vo VC2AMaG90/ *íG,K[?LٱOShj ;N[j#T bI)=OFrrzkLHdĆY^PMw~E&ng򈘋;}K'v,hYx'kHB>8ػ'Mt2>P ^^fxq_i͌AT7dR *9{j*9j_mwNW,.Y @!hț}_<S8St)Eӭ;2<|O#Wp L+/SSh0#Ņ;~`Yd ByĝdߕT >޸+~"a a gٰ.9ݤofPhH2-zO(<{4Xr??%Bīx+DP~CfƠ:QsTЖi!|HО#E0:|ufsZ[e4gNG Jtn.6T _G0zZ?vT3|G4ˬw&K| eXmƫl5h ELDgFLz(J3mJg,a҉'fɄ ј})ҊȘ.wY#LyvD Jw8PX4oNOOicV- y'S3Ƅi{y3Q*nԄWN'@=F*~͈s0Wmh{s.aghp7MKBu2~xvGNL~6t`I{:R,sywg4<6WxG{][ҿL@U{asR5L_9%HԵ{D -;iߣ \ޡ0?-M.ŬjD‚yFş2sr?+k\P| xK bGCo3ݩ,4V&-eIud!&1:+ˡc|3"Ν#!!۷CGGGG ___<==)[]_F[0cﺣ-/&xɏb1] a7b Ŏ-QWrgVdI!7@()5-#B lJFLEGX}D Br/&TTU#MMAڢ[ rK58:1ugn‰P ^~\9}aX{!M4yآr!Ο?Orw6K)U<\KԎoyv$M ; -A-VCQ1KiqǗnQz9Ң#5hd&52Y\sڔxK՚o]OS5ifowHr|*]BU?CS5ȯǨ@ƍ٩u:::::7!!!lݺ߿7i+WVYjWzgu!0Vđc'Pe]VoLц9w(eHkf@w1n8l2[uttttrrm]y˴p~wMY,B s]®Q :E f lUV|YKyͪ{ <\t^GGGGxjz oGg%GbMM!lP,~l5_cH͌)6w|iZk!}4䄔-#h,[%tiT&e4tɈGѹ[Xe_ =yUO@t>j`9Q?/,NO>IԮ|'}AK^yuEWB(VX k~Uj}}@ZCX 5)=-cJ|Lt{d uƕHTm)Hn ^bOʴf (T<1u}h2?no/\ M&gX;G݄1g- |q֨e1ap=I )e:bjA"o3a 5HOVDQ1#f4vv;:::8nFBI_@D¬S(_Bpm434rzHGV-K[RQ..T@JxQ0sҲ)Y9&2][=^-BP"T9jvٳEn YR;ƯH@ :K ~K;tl6&/nI_'J֩{+7H;^es6'-v#Par"3ͧfɯ7й3U X~"N,%R&qrX )Eb`GR" LoI6Xڗ~ouv)_=|)V)6}$}+ZĵM3Q<jHr9z͖IhZ ^ч0%nQ6ow7BJd_,~+uYbi5gYy/IOzRTT+W3EEEyn6^XBIE %IP(nI"ASIlt=k|F% V}y*r!>mЈ8-WxmT{ 8l1m)y0a v`rS3&n. /;HԼobӾtN]@rFo^l!L~fbgo"mX<׹"=̱8]S9"FQ<9x%܏+yESgg;WF3xuzL[jn$}5%ri_oSˆC,ݓ"[1<$|] WoWpvIl/kf} H (=:hA_bC[E+x.ȀvVlK1復͝}jic'uLOÄc_~رwM._#;cP #\|ڞ=q}zf`?H=:*}۾+ GRJVZc_ǎ+SυPPP,KK[|=)(*RGQ-Fϴĸd.%Oa<<niչ3R&cwGZ8Zѭ:::=*QGAyj2͞+Eܺ/ -lJOHI\Q(^s?BZ$UQ0ue/d64~ՔJXhҺ!w>w^\=5̮/vMqXJTOG摟.%(~Tk֒w> IDAThܜUa/l0k[Mi\:@ 빸d,&mjS MGX%LDX:c)Q'tgE/,edUHIs)hFHkeSˮK ՟(a5}2 _cW,װYc G7▾w*N q`Xh[Z4qмYiRfW;?%bR iՊFmMߩΒo닄uLyZofr(@j9'KWŗ=e.T=sG>i=Ӡe;´ol.1P}!{}OD:tCر=qD %DHbM{H4q@=_ ,RXZM`NWɅ3qdꭠ󯣩i$%$qN]&ZI˸{L"&ք748f'̵.}i>?SZ Opk7Lp^u/4"⊡-;q5ǽ@ر#;vDB"Q DQba@ F .BHli _J{LkΊfE'`=aHe`OCZy۶t<0d3F鸛?Q_ͣo{g 𙐛槞nhM3#mtY{zk0"WjG:lbYքϿ'#g%lZP^{ey3ػl%WKu ixa&ObO1sW=_nv[&SaZ3^hZNYU v,=e'[eY5t=}Wqr7zUڞ/$&Af{i߹ ::::Lpp'KMCjB D۳f 0Y&K=C^j> AjdX3% =uZ-(S5O\jvDͪF.e{<;sVTfM ndөspq ㉉ӲW~vKJ.F8RJY˜y)p/߂!k˔<>9sʧŰaJ"#?e7V 2+RlLz9^@BM*3sʜ2'gd|,q+R۸d\۶3JUjV12gN>ĮxWlMK]RJ eRPOP,( {*Oi?g!j\޶5Swh{t}! t{ܟd>6{AOzMAAAw}lE/fQj",+dФ]9LXH)-e# οG" 7|qbI$$J\\]O"GB{1q;(\k,kZ$ ʽ˨grQ.vzT'x|\e-+X+נ"o)ի)()_|?wOW>̧uWk:׷ /| hqx 6-p,۔FQTHh);[d%}*s<]?W=F GYڦE 7JI]I;yɉ4-geQ j p=҃f]e@:/9F/5.{-g ML_CāogҌ^ ?y70$=LSHtkŰ!i?}1i9qh3H]4HHUD!k+Dn n<'Nwq9't#%ݹ 1/~)[0&ek]E >ˊGFO1;XzMjcFԹ-,7n$!] n,3'Ѿ)A`o|؟&7J5M >,1K$ҷMc[YaZU;·p2J_}5Vnw3.2q<;#ٟru3(gx5Ī3;$7eF͎Tȵp6r5xe7>b؞LMr _A{M( (@S,z(!xK np"CɮgFWutt2n@c@ZI ͺ!ФFt:v7!qFڴil7bsٿK%pe zq G>Ma q Ckݬ{,"y:h,vt\m*@}8mXjw=3*p}/49Yb|.C{O^~a |w|_5p@Foለ[n2p}(s=s!ǂp$1=n Z؇ ""h-F2x|ڞ`Fӎ2NW^!8FY~<+̿`n8!mL.zHs#EDDDDDDC6FHFHI <䖤DDDDDDD*+ӆBێH$i>Biph@p0'ʂ[Wh/""RmFɓ,zAmm-+lVz4u[,i oy70`@>szV1-\2ǰxvz"""Ud :wCTuYg}>szV?=[ֲ-wg;kDDD?A ͮ^[(O17 5|=0,ӳ\J_DDD9?6y4ee7琵cʒFgGk,ӏ.C6b`4$ @H1sdz2`YKo$"N$j,`Y:p^\ߑ{ā_;ܤ_Y*]m=^WȃN` ~l仛b E+oy3Ϲ渵H,fVfj=7,7Y /#&q$4v91x᳗9wE\y Syԍ9੝03yOn -m]_\9& /~s9xT,;76:zj)a#X!"1f"y,N"""($>ʕK nyN>~Dn?Iwߐ{wcn!;{3\?wq[ݩ ۜ|#f6sZڶm~s ]JKpgd\v?Hޒo-T;o<6ֻѨM'.?7@ڎt֏?ڃ*YgVb( \*eÝ}rnur=U[mVl䇻ٰopٮo~n;o^hhWmb<:Yw@ j@(-'3DDDK ;Q_>}y]ՖVOv?fM絯6suײ7pv;ϑg 9irtTKd?k-ߥxSںw׹ĝ``ou_w9{>4 ^m3Cg_) `g7aM_nSx>E6ͤ8}aLuvΚԮ}.3k ЎvQ-lf~u&?_Z?ap =`?=`\ /v/37/;_ܛc?/;v߉v?]p-71mܩ{Uۉ=c_J瑳wa5Vwtғۃ 3w'7e`Zj{.j]K*͙{m*}ӭߪl{516#Җ/ 6jXw759ކv7ϏG`Z WljOYw'9awP-9Vw~5NKS_uzl IG0K˶՘qM&vԯeչq@޺02/>ǨO寗s[^.>,8y >ߜW9/ji|='+$Nv}1q.=x/%L`sh}@DA&m;Q("""UGA=:Ip9.a+5n4}릗lo?SNfW>pӚ=r]on΋؋W^F+q_eqGgGy7­3K KsWs k#9q:xcN+weC kc~u-jfS.}qNX>@9NG>w.z^d:b*Y6@A\4[lhۻl9?߉G0JsFYߦ_z/rhGǹl:+olǷ9MIV;~ 2_}_} j|?3x-L =Yܗ5k8L =Sai[fcBb!FO;Yi1YX,rϻ7}<~>$!a;fnilf6X{Y{c89k\=}}-/۷\^҃'{9?luُGل3@~m=Sy'pk<9 هCwߍI7[ B& NC=wM.ff_оKG}>;H3;e龅2m=lQ nY!ϗ[=`&>BɼNof7Ȋ]#.}]:׸x#\zYw<+]<'3$wOc+U܉~?n>ůW@壘*˗ at8 DHQP7(Cfwogg@[Z>>9Mxi+)Ⱥ P7e;?؇͸;ciq^lro矰3extJs&;WE_}glzݍ^NIe4]suz+?zwca'0 |vL6d2n>m6f=ۮ׶:ݏ{7? lz?]gaؾ8/k˪kQ[1zO;`eRx1Z^J9i` -&}?$f#nY&i6ʊrRQPj8x}wu夯!kˠpw߹ k ]vƦ|K#dM2ӕhs\׍9f1cPvќkߑ3Cl|'lr'g'txv\6~4ZcZ֗ͶZ)Cƿy'85;f3{R G#ҩdMqa,A G}Nd)Fϧž;A' pOg{N)_~b ;cVKnVgUi_ͻe3Nxn˕s͏Y"5/ywސ1c^9rt 9w酡L7zL/+~7 oםk 緞/vݦWѧq凱w3v]g0[.۱pwu{ڷ/Г[Bd%a\{qLj/:%Ǜ?ߝ׌F \tcov=b IDAT$xWe:v;dƹW0rzb@~o|CokڔE\EN,/Xe9$f}S^|Ywц%cs[şK9?0:{5t͙l/o g}5mе'+5K55͵':.ن^+΅[՗ޗ\|\fQv.dΘbNWl͏߉-EhNa!G0ܱn}{tuL׶ΠqCA,*DBtw̍:=Cks'|v؁]wNKiȮYt^!k9FL."-Bcmx^%W3 %Yہ{dT9nf!Wo/ xflgK/_5d-<?1п5YqSi>WaItBeDDDNknjB¯7%ww?~_M c貛rj{2@uu4y|$>d7S_xPt_:n!]ٙWzRs|6|N/e%9$sM*֟V>JEdf >뤅}i*t_=`{B$5dQR"""2CmZ HuQ^dף]` >81wϕtl׆={0m n,ʹ5ԭ[7bT1Fu6z݊Tn\CӅ{ O,СsgB0v;yDYsux"""Zr or{!oAZDdVdq//`?v-@?價=s)[Wm,"""ۥA~6 =$!="""-Sy <}z!w2W/""RޫsZ}Qo4·O88I:i`a<ӊ"""[r=c'I(=+y-m'""" ^+uԯ&]f3L-܌BJ$̥H5+.\jCn{ϥfÆȼ5 EDDUC־u|N&>aV3s'QHK7km??]H˅f-߸L4KA>1G;NLLP#^_!DDDD ~y>0+_"""ծq!~Sʺ' fV3K#?(Mi N E} Xw roN.""K; We+ ֶ,bε77lĺ\~È """M]q]\ Mp mqa_1(%˜0ߢ݊)oV|J7ȹ:Oϊ>fF!f ^DDJg[M}}!J[o]Z_/ڒ›}Y/]g,|I`_gKM|7KE7oc u81+th~39 $mH6Xz,&Eb\G_4XY޼pcBҙj+ډRH])_GmgBt݇cR7u*멏I?u$|С,sF߼0"z#%Qs7+V2P)o=9r>k O35L+ +]WWӑvӯ.l+ J*ꚮ}RXI&s>I1,*Oi*xB|/nNЋȒlҍ77|}9߇v"""Һf䧗J rEDD5iئyoMD0,m[}j:xEOlSY4Uk7{sg/c'-J;뢟ӵ"̽܋uo][DDAKZ5v[-XiBZ#'q|"""fKoP)oDDDdZG`fG;n,8H25$/Y,\vߛព׼,IB>?ri}im3^DDDHzb㈥r}bLW 1$fI7'H~dCDDd hW"""nngW" 5Hi` R""" AS*LHY4U##<` B$xZvʏ EDDԢ!DDDDZGr!dI&:2YpGDDDDDDDD˝M苹D@5s"""""""R-I K˻G HR6r2p/""""""RM8y$xHi%<*b :A&wM I}>u1"""""""RܳE, y31'C0Y܋T <өdIfc ]OEDDDDDD93 BbxL%1-=Txf!Ct' EMۋT؛4[o`.g@,-ŏ1._DDDDDDzK5{$X 1ۋTg͈^Y$WOB ?FߋTyia_> q F $5mQt/""""""RMc!s-dHS~6Ff&I""""""",ҧ=i$K-Y,"""""""E#F t;{2D dɭGVEDDDDDDH&8fY #I@A:%_i{j鿙!݉1 Hbd1s#!HODDDDDDDE 5djjnfx $0Bzjd$deDh½HUq"xe10K%YEj'""""""RM,r{4b4'n,._DDDDDD#fzs @?!݈ wODDDDDDDy.[iJۋTljj> #Năq0/HDDDDDDDFfrS1Fb[>HU4w"O!kEDDDDDDxL9|9I3 EDDDDDDIn}.[@x:|nĢB-m&Yfn@3k葯DDDDDDD{+sNGVSYH5 V;׹8IErNY VsUn$PYnT^6oi|8`t}bwnFbjx8Ie ?E' ߉z"""""""UŜܜ|jw!IkъH93rӬw`u=2."""""""Uq"oeqK{["/^DDDDDDDPd1M[=?GZ^DDDDDDywri~ps/""""""ReOK$TLM 1:!G,v7#Wj0̌Xn~@IpOz\:_{jRG:w{v9S&3.2!,/|Hu0,u^rlջ+tp:ңO?YG,"""""""EG)S0#43ܨ%hN :g\,"""""""E̝ 0۱{gR7i:S"LGf͜N]6K:v"""""""U%X/ !Cb7'qY@FEDDDDDDד]#fDwI NFODd wƵGC }i'oxD$:r x=N҅xDRY i1#x4^#I 1K'|%;N$8DN,zYD+ٯ|6?o#uL<)1 xk41/ N>TDDDZE`D[H/"""K3ctҞ`m1m&/7^7qa+8i|_v"Y>a)}pSx/"""vڲCl7܃{G M^2+n|" "]N 0DDx.eH` 6]h+"2/F:542/[ijԵCa<w?ˑߴJU[4d fgsBn.~i`j'"""G_s˅szg럔\d8ґ-9o0`aT#=>uZ^DDD7_&\2ɏסgRŒl EDY>X/ Cf$gсWDDZKCXg,3j;P?M⋑cx߯܃2yr<;cWg`uWggBF&ıOxxw>eFomwl:Y'u3yw!W$CVabѭW-]GgInw{7yl}UyQ1yT#J7~-k^j{ cCo0/Mמ]Х=uL8_>浧ƽe呭[Dd"1K K'1L#c_DDr֍DZ.gl gfϯo?d??ugY2vٿڛZ|eqfߓw$dJnS&}v[mG/מs'-RӶݏކNۅ.;Uܦ]Ƕ^+5~?=I̺99ϖ{m\|>-ŕ9$ܶ}[9d9q),7>'1˰{;}/N^z~Umk .v`Gg~c]u]ztk_ެk.;qcgqE77u\\??+:w8gM/=оc웎kqxθ(.IM>]g|Z.B7kg_9{gqOnViԱm!kY_a0IЖea]֣gv|9)˾N<}{qN޻+k YMw\]]uÁ鱳0s&k֌FAclzfW26} 竼=C}3&gnԴ)lChס"YN>7ftooӶMm[qje%' {c)[io>l/ŅZco_3u4ڴ=`5Yy ۙG_|~b؎n#{*Ԁċ9O'"艸 םMܝ$ t}tâAEDf/w-t<ïz[ );ʷiߓ÷\w%G_Ƿ_Pvϸ~0;Eѿۏެ28}Nb>Kp5GkWXu;gi f5:ѮC[8v[ ~ŋLMYyNO*ѳo7~u1%S$!#s Mse˲M{fy/);bUĤ4{?]{va-W+k:,|>Ϳw߀_^ m7XSh IDAT9y7涏xS|؇o:K?1FP}o~0cXnï6 Cvݠdۇ*"K xt,箋f<1b30G)"\x2a5mNQMЖ_\Ӓyn4VYoE:uȷ>P14{zI7Z;4:0Vx;:dgYǼ[dQ??hy,{}ɶ]wb- (E[qޭmk(駑k{ͺ S'N+[wjMl=o=qdk%cG$5Q>;?Qq,zҮ,22qDRE""RW7}WU26xkvc/[?9~fwqxiRV^RgȮ ̞}oXv5}WF5d6dғ^D:hokUBT6vlV2WO*n?SK4βnw4HoҸ) k(|=Maf֕TFfݶ%ЍI=;kbR;cS267sED %z=ql+?Iۅ0ːSY,Vd%|k[Myoϲk|jס-]SN }_,|5Oz͸x}6ݩ 8dX~eJp[bMWMAAs;J˽A=+fO+y}_+boU LņwX_^LY{_mo}c/ڿsΪ7n7u&\s4~>hUw}MsxвiC ukNƳv""$8ɐC6DvӋYãbiNc.fv˭tO6{m? c Z{w^yQecl~Vʻ7euW,Z8T}]g{]ں0l{3+ܬ}N; ۢ~a%}=Yw՚lظ${UCDdQeC0K!DY  ZPj'""\q-\y%?<֌ˀΚ^Wܷnf6͘:$on Q?e 3T[qSV%ݙ9}'LeOQLVp g͚'0, _'~7-*}+]`Y V9EURX&ѱ|bތ$5wqz?T #y+flk7C<_JoY%[_/Fn}‚G_sW,Ø>xc1eW[j˶ݦQI+yg"VXu.4:6ʎϚQˏ{/Oe1u&uuee3wcpC7 -\tuңSYURҢeDDGi}.!u0pKOЇy``Q{yŞO*վo;:XkɥZi^0[w}=)H߰fShA=ٓν%mD|Ar}o޸O_KN?|yNhݹyY4DD7 u {]y~+a| z""wc͉ =>.}5;)}5](m~ ;&=nܪNI]~UTP*I ;_'#Gnzv%`oUeyӤnE=-9%g1 13\`]9qPu7p_Fpe's dfdV)wߨe{…c娪TMߩBc5* vY%}qӪѼCwJ%=>^3kdSW7,\Գ];t}ϞY'mC@| |""WsF bF(p<=ȍREDʣ^-Ӓ?xD@y+yגtYlo eaօUE< *mN..+އwEK*o4mېV=̙~. LYhuڴ>mhڶa^3*nCO vNQYF""9bJ$J7=y㟾>oG%g1 7/Gv/{@oZ0a6%}}~G'ˬ٘Km+) X,+i[eѺssFLqFo/kk6ƾtR>WbsZxgU&$ hޡ13Nsr̢@ c88Vs니H\3 ?e\_rwՂ~zSPa2[~M3<)^BE;'7.9rB #G٥v$<=uц TO/͹7HM8/'p˳Wf.br wYؖ'~Y[1qQSIsEȽ mO(ahZ+u6>~e|Ҷ#9߄Yx |<yJ̅؛A`pIsòT-_Dt=݋.=cۖmcrp}~y|1{NH>lOJ|ɟOgՒہN=~O 35D-iѱ;k|ӓVjzζ -=+>Vs{BQߓp >xyf)J}V<~c~լ[$ ǯ|+8o Ł'~03l[3дm#:7C_Cck֛\"_xhe‡SJ}X8s >>g]{|b[:b؟O(MAF3lT\v_KPa-61/J^"g_w|XRje$ے3dʲ}?|DⱙqraEN!Z=nWK{.IoBAu 1?7%Vl9'L`x>|NUEDv 0G >q#4p8Ի"",ZlTZ%5^@Ƶ,_C#=OLwbzksr+389sތ}[~8LEǦ 8m4Ozm^nBYN̞-9s~G)[,֮XOioR^ueú53捯wkۊGѣ}Bg Lz_}8VmKנc6x¾Ԫ_#8fqU,ыn:m}˚f2O1wI[ا O{'>sL^nuբK>T t"ГzYjVM1+e V%=;ɟO'w[Z xO[ٮw$G> /=wV|ÙO@5TtED~%[͎\X'`Ȟ`8a~>rA@5""),>)("kkҺN 3GsNkY n/kgD1gOH$^7FrX{4^DDDD~00|D""0_z O ً/{pۧzyw+E"".^"`$*>a oofiZ禧/K|N+:5UDDp;<.phbDQnJ&u۲7lћ^V>#|<#9 ]תS3λyo/1oTVo9|,ÈD}_N}}[Hx"X{##IO'Y6tJ6EzFldU{>|a,l&T"V ?D{ ){+>'~SDDDDDDDvC㮦iBڴl[N׾{3fDsr1yМ{]<A=趭yx3EDDDDDD$a΁x03{D,^uNH10>0A.B4b{0SEDDDDDD$xS-,/ÓQ*QyX_{"bّ]$Lk ߑ '{?I)f8JjD0s-8ow\ OHJ/G$nۇ=91;潁ws/""""""R<>MyO0t'J{ރgܛ"{ ĴzxY|O8>|:m$7||pν#,g EDDDDDDRJ9fKqDI1f-1cEph /oa1p<o>1^DDDDDDDRKuO4pH?H0w㉆\|C'""""""Z\w?s EDDDDDD$XX- >/G50+""""""" ,L73<>\b*"""""""EĈaA3yg 9WEDDDDDDUyXXN{>/"""""""pD©Nx\Z ODDDDDD$䗾`px`DE+WS|/"""""""`3 莛0-/"2?kFA=[zUfzo#Jl|/=qLqI;'ߏp7wp[@G/ͅŏtݯcmޙcܜaoE޲xptڷ]Vq<'8?- ~qR6н ?#oS0rҼ>,v4!:+d^Uq^\b?qx|dt;Sbۥ>aoJ&r>%7$_3NǓ妧L:Պ<W?ɀ1!|I<=vǸKqn{!Χ633>,G۟{޻V=A_~| EIlԲ>l|m,.}mTaoO{8JlI}Z뭴k`4W?I+^ܜF ey;޿ o./ڷ.;c?F.F-'/⑱ /((K: kqsWxgɣu4o߸l, 0D%7lf _ʈfxU&~Vc1Xkլ\3]urws}wLkJ:Pg{O 8y79H͡WƳq=D#mڗ0HIwQ+w+Wsս%n.<[yX^c8MEwW֯Y]Nso8jW LI}+_|Nrj_by2}}}J{}IpRz?Ƭlny2_D7xjx Dü»`EJ;Hݖ<éW偿 WsY|:~&<9~XDvwtza\҇ϩƼ9o>mħbԴ'SfF;0ت^;v][2q]>{G59ccfrsX4O/{~⭉|6ĸw&Ѩe}e6ďfxrZthRggPzc"SD-ħ,ۧ󿯩Z=#)KS2믤뻠΅} >M6a8a"_Zzۙ$d[7'/:jGua&/\3~3Iy#hwkÁ\ا뻠-$ VҰY/O2_o@iEhy+Ϙ8㔥6=?]fQ-/gQܵQۅ;_D3\X+paqqx¾L'_YyRJxNe>d1}T~ްe:QV&Sm,.;нg&[Χ,7ȫO#a]ypPԑ cI?iC!ȉg@ɟsCM{c9]wPaHKo1}Z뭼_\Kg;gP9mĖMhԼժ5{[7.ؐ/6ҊzkEDa%.^\{p1нTFDڛo9#QP>S#JmlA ~Z cO22o%ѽgׯZ&&ٳE{~!,Srȩ}/q%/agOmN8xO&rO=w{.L=uOY;_Z47Úyͯ0Êgv> '/Ekگޟ @p}s]w`nXlrz۝eY4n^mݿ,}ռCc.4v=Z:qw߮~hӥ/r|c"DbyO.h'p`_DLG.45MFfκx5G/{Ϣ9Rv&MZ7W/>̟8"{нn9F~ңg"gsk7Ɍo撵r=iXmrM'+P`k1 t-:4ዷm}XV[lE&Ԫ_#v}Ro>^};е_Dg߱Ьm#&>}OYzȸgD"Ԯ_=zM%CiS6pz?:jG$M ejcnN_5Ӯ:&`/XS߹svD"qؤ);a&p TA&u8/{qcϙ,"\=Sgvg/1?r?ϤE&4mېkL 量H*3 pƋ;p8PZH%pEpg?n¢Q\3#ysWpOӽg"Ѳ2ǹ?Ƿx=eAX1-}BҪDiz΃ n} n`87t?~kc^dmPhWŧM`mŴhaY :u/\y&ͣZLV/buL'ZwiMpλr>y27GѠY6ofr%>QRPٲikxQ\p˩٧k?W:Ǽ+paj3Q>޼ ;#dkT]TD2ߴO+/H%2zy+C~iU0a: k܇[ًw5M[`ElrrzK֖tp>`x^4>xpF2ED*(uG/ai E*GZ}Ky,""z<8ށ K އLuGDD*335{w_xE7GDvx`1w_i!-1pTJ%?-'뷄%νwfHG00g_DDDDDDDRLX3?AJ~|sô|DU_Gs>=\> 7@_ ދ 7 ^EDDDDDDRXX?iވDEq}ڞSZHJ1, 'yo>"""""""B,# 0ϫ…܋HX/{"¹sA{IsF |0GGă """""""""| ̬ .Zm>4sDpxdgo${& r5r/""""""* 0g8 fA8ޅ9 \~]=paE|x< ׶ϯouSd/""""""B =07 G_/Z ODDDDDD$xC >"bDp{}.'""""""")"s 35>ރ/""""""JֹI!x4OwA7 Wp;3DDDDDDDRFX%p}½a>ü5sDyHq8,H+9sCHj1|}8>>>,?0畖/""""""B@X7 G4y>Kk^DDDDDD$ Á\|ވ~)I1 {퐎Cjz`>a>AǃA4 |g 4t/""""""Bʽ?c0wzΡz""""""")^)Y( {AI"""""""0ѻyOԈyo5d/""""""j,qGafD=׹JI){,no>,x> sH6WDDDDDDD +ax 0ouDDDDDDD$e$sx|"=ߛ,>oaW-"ϻ {p!>FxuEDDDDDDRXμgJ{a/""""""")ă1sᠼ7xj>D()_DDDDDD$0Xdux _qODDDDDDDRߡZ>/7Å|""""""" A=!oD,^EDDDDDDR>iy xa|͹I)tA|p;P=q2EDDDDDDR=U4^DDDDDD$%׹so|T)[8*|<po//"""""""!x y㉆# fb""""""")%WsF ypΑ""""""":kIi,XnMH޽;v , n:sk~:,Ip7"/{\#J#8y^gk%ۻ'#Fv)Aڵ1b:'ҊnwxaxƂ|,"]|;,X""""0bZn͡-`-@Y^/EeK ǃx91UtwΌWt3Dy [|?0# FDIn""""""""Ey3O|{Ǜ'𞴊n k5|Ɩi_[5+dSh5mM՞٭/WtsEDDDD*xb>1 pA3G4{TIu9f҃l70 Rj5bג3Ys~3::'_UQ{`uN73z"R {#k?~KSh=,֮$w""QM'vއZǜM^jֽ9ڧUT:c9"x074^D[ew]Mn}hzLcG1IJVzMz=jr"/dCə?zhH ^Lby<8p*v y;6c78"{?,˼O7\oVwDp8s{ 7sp2[!{92uϻ=ߒM+/l_ƪf晻3\<0>p>f3o,0,|oT{ƲWdo R.=޺5:fwD?O~bud'Mip2c >W<J<!f0gx\~ ^Dߎ!auθ% XD*}lj 9 @xҦMx:g\U^1/b7`i4߬}!ض<-J)-Źt|pb_R+U7%{h{>Bқ4"kR{4,=n[ֿ"-Q[?֏|8 1tP ֭[WMJ[8Zo>qp>(f]"o[&̚dv˦F3fuϽhyw^P']"qh4ΣIs;o &frrrȠiӦ 0֭[1woO>=zc_s9tuw,XDȠq>+qfw9쳋lw`֭|deeF_>/}٭߮u1m4Oڵ+I"RI9{<k'@XmLjRC IDAT*]2s;X,ƀh̜֬9w}%Kp)*m_f Edx<.bAH< p`Iyނ j͓RuYA΂ԨMFпo 63UTsXd۟->ߩvN:=zгgOԩCjhРCM۷zҥKwxԩSuҢE =P Ĝ9s;v.2gӦM\~ٓƍӢE ?p8 ,XƍHUvm~ڴi/";%^C!| 3.p>x=ӨYi 񳷊neT͏൏?OjFZ೉~l"mT͛أ;^{dZZ5.]J^^h6o{nj3ӨQ#:(ڴiyXx1AФI;8Zh)ܧvcƌVZ\xlܸ~YfafjՊN8o?mx5kUT_~ 0PN9W_}[oŠAh۶mا#Gl2.DZ_͜9s;w.&Ln(iӦtޝ'rAM7OΝo1,}{ϫʲe4hUVM1e: UVhnݺѭ[mٌ99s搓C 8ꨣh׮]]D~|Ȯ. ^/X,Ɯ9Gz"z֭"Z+[@ӆh֨Ɂ'c?H0r1w[KݣSp'f [zzA|r^>~'rrr ꫯyf>ÓO>9yש^:C aС4k֌gy 3"cǎcW^a۶m <뮻L^x~tܸqݛo0j(/_^};vd޼ysΥI&̝;7i{.ur'oiڴiի-e||?3^xa}EeժU&n?OVV_~97tݻw'-"۠|U o 9! s=E~߂kAyl]A?ޢ}OPJrrD?&f0FXqbX*tA,kNm۶\s5?ӧ3fҥ G}4ua̘1!CPF _ͤI0`W\qEq{ʢ^zmڴW^ZٳgsUWQn]O?G}kUV0lذBmҤ O?eŊ&Fww%10^:Q^֠AfF$)r}lڴիWm6222֭o6̛7ڵk'owoi6n܈sU&S>6mSN嬳΢N:)ٖL֯_O;D?Kl_&d)ԯ_?񜈈Ȯ恀/1CPDʢ~Z##m??ض<ۖfT|H֭&R)իӻwo5kƃ>ȢEEnBfyꩧӧ{.X{7iߴ4 **Ż"##-[2ob8gFZ$Bz$Ek7 om8ڝְt%yG}pi0oօ<&(iR},2X}gsD5"h'se˖K13/^LNN Hl .,Evf{q:v3gN[6m;wna̘1}a\R@~VO;8>ly7R-9zW_}ڵk .''_؊+ۼ^"W0WA=)|{3bf"<FXh F^N9ٛª"#w2vWNޓ|Q5֤7B+uhu4{!iwp)̓>|ŋYnk׮e+4k֌-[R^=:wȑ#YjA0w\ ƒ%K7oXӧ3y{AoߞUVfx RSƋӱcG.\Ȃ ۴iYfMUYj;=RCVVYYY,Y>znݺѳgO aR~}&MĖ-[Xv-|Ibsh4g͌3S-Gq7fL0e˖tR&LO 6lH裏ذa9993 6$,"o 88yi" (T-&QbD#6&Q$E%FJl AA }azKvX6yյN,3_4` q1V $.*?4{?o QN=Pz- ¢EHR4lؐ]s9^|E^-[FƍӧZ`};%%%lVx< :tI=Xy@6mo~;jݺ5K,~ԯ_H3g[v8$_~e&L_N;v,cǎf͚4mڔ_ٳq~8Æ nI&~|WymڤYfz 6mrJ]jԨgo/ $?8ٳ'[{,/"wy'fF-83h֬Z Q`/"닙8x&'ɷ[ɰ|OKwzתWwo3Giy̓,pf}*uλ6_OUiN=Zxx!386 :DDo߾L0ʁw߬ډHulLY16ľSy )t:[o{Y?'!z fIB=H%xt<" 9O4=l:̜F\ s?r~v#5XZH__ip F{/{y$s'f!m $zf JD~^j'?ܧyŐ)ۯy{?u6ׁԘ]k*kČ& 2j/M7kC n/cݗsf~K/ܒAò듩;$^Hl"4;&7~f!ԩۿH$Qs'2yxYwW*I%Ojnݝ=Bۀ^&Sw_n HE5Bdƽ;$k>@D̒L+܋ N}>z'G>&]vC,k5dl|sNmw.w9P'ԦѱТ}XZlzev_c@:FRX6>$nh҆كpР|)MZ^0z˧~EΡnX7t7l-fjΟ3q(X̾?mͦtg-IDmc13RcuIZ/"jފ?AΠfmiEm RajS(79’F3|5"""""20 BwF=۳<f!o{YYS&I_0׻c7joߛI5jJS̼)v2˾ѣX>eu8w=թWݗ!""""q2) 2fc!EtY2,_E"5L+#ΝâѣXdg,"ՠ1E64ZڵkG&xꮖT3<ѝK'}ꭷD_̢n~z}$_;tuv~xc9$"#LvY!f[ ݋-f6MhUwꮎ>k""%#X f#$Y1"""""""#s;fIJ4ǰ|) ˍ݈$|<7"""""""ܓ{O͆ofC̡l勈 7ǬtZ}{L DE"""""""R͜d@eX3F '{"""""""R "z8F4`yN:`sܓib{BB.vNH:ꝤKSN=!3?flٿ'^DDDDDDDsHθ\EDDDDDD Nf/]β]I*}K2dB|‘,k_̓Dz]>]o@K^{/ EDDDDDDp$z6gy6~'d~rVr*"""""""{%ꓠ$lϽA$V[]EDDDDDDdU!ɔGm諾@:{dӰ|a@LϮso!ϊ_DDDDDDD C$Od*~@T/""""""R(xIg ϭfx0 ) N$qb:/{@$ Q#EDDDDDD [9/NEd"4[>lȊzT'ַJgG{!$$ws/""""""R0 $ܒfcw )٩Mf`޳䋈se!!"""""""Hz-I`qwPu\!H0p!Y=f=ַQV_YUē HH|s_DDDDDDD {x|{3c$'D܋3I"Hғ-ɪBbvH{㐉1Y>-17dc=}vFi 7Lv ʥ3u܋/ tm4^:W@DDDDDDD B2ޒ~zK81>/ 9I? Hf1-/ɜi$_d+) xBw'H%Ngт拈7#z5,ۃIɁ8l|LjfҰ>f0s e뉈HAp$zHx'""""""RJ׵K'}$E>@C|{ǂcQ=""""""" <>;ߞntt{O2狈HA0cv}s> !|:_kቈt`$S'M&CܝTuVZDDDDDDDV00y2Hќ,Ƃ⋈"2!D4w')#@B$^JHDHd9M14d|eDDDDDDD ees`deP|’K}I|0rKN."""""""4'=Y>GOsZ ODDDDDDx]`?OEKL"""""""<2IF{v={w8d>PJSfꭴfswB6WNH!`-M5BQڄ{`! hFDhC1g%|^Nv=I"|7K⇀!H̡8{`EHGDRFIp1Y7ύꭷanXܓ?!1s;fdB$7G 'q,"Y ϒE!`L5XDDDDDDDI:`p dۃc 'e!2&EDDDDDD08PR!eFK=$B fd2NHd|׸|f8FI `.|'e H!/ 'Z*oyi3!&A} Wx/""""""RH$^H$X?/ZaModHJ'""""""R̓z%BB I'K`Ha`s/""""""R0d {K{tҤ0RU]YdL$CB 6'-'""""""R rgLV'tdpWh/""""""R(/,fA [L;db=VgEDDDDDD,O~3yfN:xd|4^DDDDDD0Ai]>aHgz8'""""""RX<!q7<:H222,ə_UbiGX&b8#` $M]RCwo9F.BvZ϶9}|~ZU.?G=s.LuaUޏ/ٲ^x #?SW' ܈ x?}Zgs=UCDDMeR0 X mh1 ] :U 66y/7fO`f4lRޖ3o:~W'bf$]ߣ,,ſu=LDD$_Fp'F'`d<12XH|p'/;{>'bY̜2fmU>GocޜzoY0wcnO:U 66y/7%2sf|3N/{nQ>GHюq=HDDdm9%$tχr IDAT2xp,8ʭ'NoZ~Ni8*?xx:ՖQv>C+⹯劇Ϣ^:ܝ/]JCvd#wЮK՞^:\2/}s//LĀӵVr*_mc}rGqwe,b!r`ܶ UkSR7:=}߼kԬW?~/N6ߢskn{O?_IWVt?V̬m=J^}|/sa;qx櫁xɡyꞯGUS_icvxf<9O8~.{LBX(23c!>KyeC {'_ʞOeW)w#u^=*wzm7`V10w9{mwh]qMSThUt-wƾ;6&5~垅` |3[̋δ3+-uamx蚧lN>gk`".*!oҸymcѺf<~0_¼9yr?ȷ_żdJ2\^U=O~[}&3‡4߼ |/d{ tlQxƼ3E3/ɷk*~X#ڟ}ŇY?yd2=۶ב;_xAV=˔d%LVW_ٵ9&nftݙgynڴ9 m+Lp?|Ϙͧ[~Mn&"1PrH%IӔ,/! F7W:=Yg7`+}W3hٮyIV]|3/cҸ|4jo|V*{Ҁa;V=nJW&6Wemz從,j\iy'￝4sewmkN!Қаf]*Y'ﻯgM|/wgyq j'^U=O~[W,(C]WwM^i3iڲg8:be{ޓ=ɍܗi.)^ן7؇M[5sw0OF3?,d]:UUgX>~sμx?U֮2Ъ}sj׭sp'QV{wf9L]es .߳ G?TiEDd#Fw1̒}3#K$3`(/[,<=ez;ە;_̻1aEVUI/IYQTv=kJ24w/.lҲ7?(9n.*mV<c$?=t&N/zqɼنMo3诘;GN5k@-+ SY/W^P*)ޯ="+wjO*bwc[ [5_ֺkcdyr?r`\u=KagK-xkڠߠӹk+MԢMhy:nז/7Ќg{6iФb|elKG4OՖW{۵3#򮳈l̜H$F ctNڢC0̒o/Us Ooţ3)2aZ5whҪ1>xR>}{mI{?OFƛ5}`X"""9pMt!p'!k޽/9F`?}TUEݰh# v&] 1qD٭.""""""򳳶~G-, 7=Ҭz"""""""#] |R锧q;%|"""""""RlE|[vbg!ۍoٹAH1l< {, Iį{L7%ON71#1"""""""ZtI< ,{'d{k9{MWcbGO/E0 lj EDDDDDD Niw#''9DDDDDDDPXidvCH _MY] /UoB26?es9;+*NDDDDDDD6.$O~HXȐNd~2A_EDDDDDD ÒyI 0%9"""""""&:f=Q n'""""""",zKWw{ًA,`ٿ'}I'ɏ$^O2S^e/3e+"""""""Ygs-<$g^tVWT;3'cD<豈HƓK׽ EH'c5pDDDDDDD ~z0 N 4`!}Ufd! s3ݔ/_DDDDDDx67#Iib6W9n~"""""""#`Ingg֧Yko$ًOBvb67ܜ^^ON}Ȏlֶ K3i`$o ]u`fG9_76ͷf_a3>T4_0wK3<ˆI>|ޣ\?W*ѳ]ָS۫1lV_·_{^eRمZw }陋W㪡*gRDDDPD 2xn[^u8*0zLjծ؞:mw݊{/iWKxpnegSTি_DZE}c|UA`"9*}ukk,0NݳscvL9X^ 2z"1?Ĵ/~ʇAay{| .٪G;~%Lw@evYmpЬvKqo/{^e$%,ΞȔD~1f,YSt9';gqxOqJgr8'_\dcvO+2 |4'Y/V_}ePNM:rgr}O_L @Q"F..vRܶzp<ͽ0m^O^+Ns̮$ :' bȫާKWCne-߶Gg;yețk![C`O~P˪G*{w{^ {۰6nT\Uvo׶-G<.ԃowa,hcZnA,yeț4nހmY|_ | NA}˯""""|{Jd}t~0cf刔* hpRMZ4dᏫ]Y-:UM;|3/cҸ|4jov]ΟOo<>\<آs+κ:؞;yheUvoFf hվ9bᏋy8Q;3k;SsUٽ]kǓ9e݉{+m9ЮKkjnR#׳_V1kz_O]lgFˇɗΕ)ϋlmq,KoI;$p׬{7㿥x2٥#jjvLhHB1;qvғ}]W2=ߎ ĝ/W镒҅`̚|}){ޫ1l~zw{6XYePWkyqGkxJ*Tq[Z͹U5;{%ϧ%ʍP9efƍ!7cִ\οhމ j[tQ1_.=;ҽOg>xmLs=W^kO˾_bfW9IFãĻYZW@W;r/(|o.GL:!Uz؊Tx2ytա{ޓ-iËdY 1ɊҞIX 6mXST&-y2M;)ou:q̃/u͘J?6Ļ+,/F'I뎫&amiveUnӾJ]B{_{Y9Uܖ窪꽬L*ȱtۭ=܆H.ә}$칪ޮOK: aU&CnEI.mv9*{ZgOݶazl_d^xDDDD6v^#{6n2DlO q{ -5]ѯdp_[I3u uo6M-Ken,ǜu ٪!ާ CA[=lKGE)6;l ^.)M4hR\)qvlYCjծM[4l IDATWיϹKֵye~gi9t֖mviW͍^EyLiݦMGofܲ}*CY.yY˹?ˁט>WUUeYԩE͛|&_1/85!1mwH]uڲynKeUev]f6>a}]m>YS =t&N/zqI>MWzʞq~ݱ{a>~s`D~ """QdF e);<$k 9'D*ϵ_Grx{o" ^>S 傻N/2Gާs3[~WQv OS^f'_3iҪ1>xR>}{8޼N}5etq.dƽ7ɟ:>WUUeY})Tb$o~ʐ'|8: j3g\1N`.aٕy*bSpeѨV-øhiL3zX>n. ~\n'แ{Y@Lu[DDDDDDDDzx|,g!>ČLcEDDDDDD a :;)R ?iNw3M)(FtBv=x`601Fp'8l"""""""qInDwH'~װ|a$,ɦ#$c@D1%-_DDDDDDCcpJ,&`xpggnj3+ ҩTۜ䖮w @Ĉ٘>;pK!z"""""""?:u묺Ϊے,b$ES3"=E,x4%5E I`ߨAr8N2x<2iKQgE@f^$3q4npRXqSRDɠ"""""""%1B@H0#Zd}N$@H0 FOz"`r fX*GsEDDDDDD ݉f_܇`7C5?q/""""""R@`,gۓX3нH1N;Ly ,3`o\.=;`f;S;fUsEDDDDD6)lj`)i #7{\G;/{!B!e@+7Zi\^O+} _@xB]s2 NKs1r B!Be2 FAΟpZXXƍ1{ Yr/JA7ᮋXr]\Wι4^zp:nl(B!Sh۠=W`_w8phvc0J B""*пq1^~#DTL$Ւ1s!L!B!BeFܖ(o,mq`#d%T%/ZׇfY ғ3ф/x%DFcO*G;B!Bq\RSkJ4ƍs>.ÍViO)ڲ@Ƶxuo}-:. TIJ\߫= G5e!k\XdA!B!+<޲,68 1hq[ Ɓz_!/š}iD>| RGNb疽T^;xÿЛlY18YB!Bv5(~y;2ˠg3=p/T%w#a=T>?_ɩe뉌`4mѐأ|!B!8e(QV{JiVhJ岽Arh_6ߡmsޯR7ضa7\ߤEC"˟-ѹckpgy$Nyu\\swM.Y| M]eEO_G3oT5}L0hz/LOgw%kGۗ!nǣpʫ"⧙ko4fmُqj˓aӱV}hWb7|.C4Qs!PR`aP  NogHZ6#IJ+0^xg)˽懮WdՏ븧Փd̤{ռLfO_ )N5~Ltl$?ޣsrgZr#Gҳ94uZ*RKᦓuLc36tUjҼ'}V~W,kFG%=sWUn{%?q=cI巯Wu$ gn̪Wʺ~c׌*BϷ3(, mhsxg~`²4(d|E|Ϫso>Q0T晷$1%> em%>_go&Z7},?sד\-{_3b隰7,:)!9-Ezmqp}eg:;69ji(:ej%OǛpXso`_; ;T}hO^k﹄6a'?iB! ƞ{۷k3{VX2a>̫_ =x߻sݳl\)>"%7 M-Z ,4OHc{el+q'0tnzY5X|ޏM}{ 6kC:_0axD>9 9 %ع.S=ǼSyON丐}SiשCv^Y5=ez*gi}z(E8w m;E7]S8i~nnʹF0jc$V{xw|m"LvM Z1;7ͩ-O[td>.٠\Tu+@ ߒ]I^?04kהٛ'pqIS2*hBTOb79ӂ驴xЅ^ N W>b?{^gƊKJ]g)T?7cf7Cq8>VTځ qQÅBs`eT/|6y{2cty|gU\׀qբQy{z3 BQ>mF{i8PhAhF,?c 6Ͼ_~/AD-kWs=&Ɛ0^S⹫-?@:hvn˛?S.v;ӿ:rwM=_0Mit?:7_71~h|%й׭)1}Gtݓ{*7kvY9N_ 'ן3 |<]S6Yx_k֮)?=hZzH~>5amqc+`4]їйQҟ_~t9AlϓSV'soA y.ܒVW| v~_i.$u+@ ЌgеC8낦Aӻq{vlۘ:d=q@f4aڲMtc Pc{e.}^MA~iY0e֊9uXE_iCg1^TswFKN/BMp`F)Bv4cV[I %0h;vxn??ߵc׌ۣ8'Q1%>OL|S=Wh//VՕg1 9L^Ϧ}Ŗ;[cep%ٙ9|".7*z_ #HL3sITWX`J֊GuoAzXy]r~r%GO_^QJѬmf_B+X`EX߮a^6MpfLv$7;^Ϯ-kkq_Y_6v , UԻ`ض~uOV!h*I3vդECJfv ][s]%ˣ q-.\kp^1&| V'#Aơ#|:uMsBJ֖_ׇϖ5;BJkq|?Wο9#g?-xT[P@T_n/ehOfxX\Wm[zUc y9.cJ}3Z-vĦumDEA$عYg㪭*5?o-[ו,_OJ$j7Nl|4d2p4kۄ=[yEZ7gGmvQش#9$БBP_0Ejd_We/'+EŌoZ;&6bg 7>Չ/Hk cN )i2x a~_^Vvn˄o\5Vӽ hޟ s6Ycn*>-,ю/W\Wj*:_ؔd?xÊG!D^r(i,0F2EjXq ⻹2Tr*|x_:n%5سuX۱qi28S_ /He7O]l%c;4R+=gӾc̡^LiD+sg`o<3_4x&Jt~c 34&>)߾^Mvfl'Ѭ]_=,Қ["i mW^J.| r~i.$R0pU/V2|.NKQ^Uv<߭e"Q0(}Ɛ[pRnPשLt\ٙ9i|>}1~o68 s ʼ͂J.`JώviFpFƅSEW{ů_IM8x*ߟKB!ʗhQ@Ba|B+MmK^$^=1},ôx!f_xwKYqQ_]jpj],UOyx_DcH9\QT]gSKYy˕Ѻ1g]x*~'+]YЬ]S-GZP9u`]%h,%voAjggU2Z:-[_+ׅ ݉Q%Ө9j֯ƞCjcȍ<n?@Q$Mʢk˺ ZE˨ UByyſcf}W?uPᅵ3Z°SJbғ}_!DߍeYX4a c?^ۋQx"}Thx a8tĔxwo뽍?To Mʂipj]Qk) iعiGBݓkf2c Ԭ>Y9=&IU+B9?_djAⲛ5&Kˮ{ea$*UI䔳m?_H[I•$Nou2%t whNuj`WTQ(>r k&z,Xy)EҮ^t{#1TLGy֟pֿvN_LR|='uh߭-bY*qɍ-iҢ!҆'dѬWk{2%/^x~C+{xg|7r<=CpJV25UUg1pJO-e /MZ4tpY֜pJ-!h3?&J-$=j?'Y{v;&p`aMͯKV񔅥ʷBq+nm@)P4J9p o=y⹻'rS7оҁ}swO #9k?νs]s̀}c=q9n}zƸdǦm3N]Da73cded:_ v>Fq=r• >'d[0׊%й*S8'Uk's$=ߗaԽhK׵7˾ٿ+[KuI=K(mдĈ'yc(eΞceo B!Bq+,ܩ xsB!B -€0+{c,g/B!B!*'zeߦ8}< B!Bm$(얯=h}!B!BT L-@)m5x.{cd!B!Bd Xe<{SysoB!B!Dd#OzN^?~+18Z_ݜ>/Vq~:|m"c=K൯5g|F~MzuZÅ^޿#7.:0++X9 aeWT&L6`ׯ?JfV;=,/30HnEϿ(i"mXξo ¼g= g3a(U؈Gxx]48.~c>#"#{$.1ӿ⛏Wdt'ރ֚X濳}GkΥrdF?<>m2ILV'yy6SxujA>ӛȨHb⣘3i;iNÝ2s5o5GҳILžضn7\>v; i3ضn؊ۚ==_~;? hֶ o_3w;`&MZ4aJ\_)}8/v{Ïr0# {rM߃aV}=AX_>IH齋yQưnhI3N!+^S׵ 3ߤ>'2m,6;|T,Gjԫ;/|7]WDc߂ Ϙhbc  8=[, zb{ /I^7-kSA5N-R;t|+{_}4<_uoV~y.j]_yKg(cωM{y~cՂbe^~?զen#*&]Z({ P`pPB7_XTLcN#2:?`ϸ[vm Wwoˮ-x}DD:IyG,E)kcRٶ n= s7^~K~ {xG]A/:72m,j5օ׾y5Eo krv Fs]˹NIfdv+bܼ* P~w8 v8d<_v9(U?[Ao|/}jIoz'bm,qQpfo ˲T%!Uc=iaHmcsu>#ﲇSP ڳ5 gm̕]o•p%nNt\>2>*\mX_l5㼷.yhK>sIm|yQ01DF9yTZ]u]@Ҭ]S-?~{(^ujAzUW ۗh, T균ͽp煾XcsjeoE~y9Xtb=wmg:W %W_-M.:_]@e_2)6ZLy?y-3{Sp [r sW 6v|7ᬀeMcrg?4L-(Yt/JnlnvNѦ1`[M&3-o<Wc㪭8?䪉l^TNO`,{y onP{\>q[:jkd7>DTL$Q1ױr]DFGz-*&CGزf/?4'uqо4~x_:iөT%'z'؃}{Lv Jq{Mfrw'> _Ԗv[A;|W{.ܒC{Ә?s)WlrspoIF(BiU/Xl M+k\[^#F`Y&Jyխ̆<~5.xFΦUgO`}1ʼ(_cX [W|gcnߣ#KUP| `.X+7c\mz VVo _=~ѱQ}/V2X%W<_yN}}+L*i-}<9P[U?1,}(p?|p%ظ DYs+ נ x9|"t[x}a}nN8Q$s`a,?Ǯc(7~:^3bpy'1/kRGᲛ[sc+H+W>vZܨe=&Uj%oAbiye3F3W76M0^/k>3o|NC""/%ˁ݇? YwT1~0fz' =/^QZ1kp幉~`uWԇ _ kp:T%ҁm#zR}(TW&-Ǿ=&.vZ/+#Q='38"*&Ydževκ)c&HQ3BW^OA)/KVsg]ĦumT[W:./fF|h4=!P(|=iue3cxkrrˢBnX_\W߹iϺ%3e[}hpj6_{!dOyӽsR,xl[[R'sWs)#eۣ߮0hz/6s3I_JZemϟ7h,w@4~X9WImqY)++>;;V|:+fzXeN?/UeB(:&羿q8P*clG9kE˳߻w->_G9d<M+_xeZeߍegݟrM~^2ncmu .wqY{:)SgΤ^{q_ѫGp$=;`X_SsY EJ$N<.A)<=/zX'_P<N8 _HCfdX(X x9,ˠAy~⿦^Ztp-SX'{m ܓ-+}!yO@a}ẞqɔ!ۿ y8U,^NJ1Q(y\V  Q`YUr^!B!(_?t14F18,pjeڽB!BQqٷڻQJ} ,KB!BQسv(e<~^s0Nd/B!BT4N½eR`AJ{}!;Ɣ踳/>-DMnNo+u<:aW˧:_SE/ײN_Ig0 ־_cQ/U6WzV]8^_iƸK?.x(XG=6\ϴҪH5?-Qać0vSLX OKrŕX9~Vu_QF1Fc) ze0ƍɽ/ZbJ<',U>GC:(|0ꩢv(}jeXW<*UMD)0—o%טV.*8#QcKYs\R,Ͼo>7 CXwnɸ)ˡ=_WFa4hc18Fi{%Q1Cg5Wwഺ+8'2,|;o:S{v0mvq񍭸cN{i>izƑlx4>|=4<^>ڡn9auu*Xׇqҙp煤̤IF/< *XHr/y7)ܴnh\{|;nv nyodo UMpvжJ}98侘_>`NŀIj7EwRJ7vio}-|ց?^Gոٲfϴ_wEǾk8ibbuqVh/&`;)/ϙc>>WseR4ūX|\o. q}/o: }1^=ğI\r:a3y^ u<-'!Mko3W{p:R yҽf΃ <`?b!.)!gϸkVo>7zkqmӲ,*UI`-p:xgfOZ嶨R3~ퟥ]ԨWyo}ͥ]Zs6|i6l_7{:}1}˻i %8"}c1][2}GDFG0,dx[_ݜFdtS1-۲k>^>NR>/چ߮aO8mbyy6>SY|#ӆ΢Vhq8a֝`]dq1sXLN-@QNՓr@B/׾|<r_ /'@TLzN.n)X.Uژzywsu>#._wE>GեL{~sw{>i/_^Ci7npʴK V2RDVk巴y }:_fr%VW0Tv?nCnv^`ٵ) X8-r,XW4A8Q1DDy۲vٙ9h=!V2V ֿv"~.7T9M լ)9VW[<7MTgc'n{:chyE3^6^6׸6JlBx6󟛝τWԪ_G^3 ~:)&V/P<ө?0iл~NX_w^u]r V'VPނ񔦮_\O+jVo`|U 3-gG3Ek_T~쫾@C@c1?} Vy }sˣˢq./0usA _i5};I<7gޢQ?B,ˠ(c_ǾwWs}!{[~w>vZfߎjP Mk7RK*2gedtyjV,]KNV4m߸M:r[,zƊoۺ~nC/Wھq7'\ S9p>LzUhҢa.hʼԯI1nn͍}d#>vy' |'PIB՝; A0#[AE"@Nvr O8u hZ|Pr(_ /'@F5$U'_ 1X._CVwzCI;_}Ɨcݏ}צU['ܴCϖh>X(e1k(Ws˻/ pΜV|{\|Rp>c5>|&s鴸t&>>_ɳwL '+Dxcgi|m~ν28-1Ba/w#WE`4>k~HL\4:r oVf]Gv?@KLw2`ҽ {qQ{s fSb/qO'ŽsӐ.:ф/x N}5WM9>勷؄ILzr& vy68Wm+V Y3nrxq1Mbx&,~?R(_aAGa^lZ#9!]׃hܼ'`9+m[w<~-߮ X.F]ܼ7`|߾3h[ X IDAT__)jJ)\.o`케cA}vy]WfuX(ʷN8q?U_~RO< `cuSiwlP*ؘ[}{~\- 3->3-ǯwa7poA.߼7Uts1JJ~r%tv8)0e/mPe{[봋Mf&=9Sjq<ţrR=OEPv OC)q|w ̴J|;ZuZ!ok.m?v![-}Zu-40gA S)@c2ܖ/nz*Z]y/~X'D2se\DF2exPuyܷ~XZҏ|{i% $Q,mO5zJlrQX` rr+B!B!D9(ɕtRph'h ,1x?NeYheuR+B!B-yžroy"PZdg !B!|h@,XXQg=-_!B!H,V߇, Zk7ҳk'B!BT(81FuoQe0D2< Yu/B!BTcxV C 8( ȵ{!B!p*{6D+'PƠ, '2J9B!B!DNhܖ+߉ž@2cd!B!Bd,(RXnF),A+`p8}þ1rKB!BQ(QZc, aӭX-J/B!BT(n4`_(P~('~FBZB!B!Db 0J0D:XQh zyB!BQgnovawܯ(<B!B!DA6J;aߪo,7m/k, !B!v rc@tzkoY(cB!B!D=Su {=`(QO!B!X<{Yrea082Fie0yB!BQX`8A{W+ (B!B X V(@9зܻBaPh1_!B!@R_,`^lN [= !B!0ieo?8{4q*cPJ0sA_. !B!;j1 ,pj6|Yk/B!B2ƞ{2RZ+犾B!B!Dš1he+-F+/7#{ !B!eTZ{wo܀}WeamB!B!DbϹ7`~.g+=cPF !B!\7(R A9N 1 # !B!ʟ{=cٗqV4~hӞB!B!*؏3{Q8hثRŞzڡDFéq84JiCp:pXn1neGnOv[(+J)"#riQD(: wv2mGnḌBQ *6Ȩc#qD8[ie3r%7;\\yc#e,,<>h8Á6(WA;bM!6>g3cE'+ő,dd%_~M\b qDFGuvhp#Q(rs: HN+'X9'&G/YXfbG\BQ##$zHzȯ!*'_)w)$GơLO_HL<|ZB?n$DC^[b ֪gN\R,&@F s"u|IH uK뤾OZ+RM!&6E򢴲>@0+c⣩Q|> uM/$yUA;aڕ8|CjOP{F~h `JMrD$xWJٷ&Pv spo6VФTO"rB+.79y \fvqϚ`fXi{S?D91&Vޫnۮ=w[H}U|]!ML|4T޴xK^b MIr$r\H/v|{VmM[k)HyYU*`x#O<5 &5B{`ǀ'ef͓USEFZ;J RD߅nMDz/q}Da&iZy^ f˕>9Q3)F ț1Sarԍ^OKk&080P0֠u";­VBNݓȿޞ@пA5rGx\x_M172?J9"խ7cM=D:uR(Pta5Cg|UѨ9̄gK? 8uв?l#nxgd&TvuM>;:ﻷW?m!*F_3G*rz=-V|t۟ {qzП5!Dpsk[-Zي/ %Z/G8;|4DNWJ_e㯂6 siyDT0;?ՈmX!pggSc~a׆^O 7BtvTZۣS힦>5B]wN7>^j_Oc|HeCp J@tAM0Se}]5h.rXr<*: j.I+)NΧUz{ٲZ31_<OF5 WN~bե v*Ҋ{ /{K'rz=-[8?H˒V3M]4.'fBmŵ|:?xhTz:(`D'_BuO>)*8lZ' #G+buAbɦ絳 I`vvE:ɓJcivc֠O96_M]I'=)~wKQ?|ԨPq}|rg\zZ [߭xeT+X\o;L wN3auk)}ܥSd4 Nqxw.Wl)9-iZ~k`߁?Ox@֔kK"8=zcP@_'_EJ˛ 5dNAe)-)8_ /~DTU͌' cᚍ&>=ui+GJ Vd$?Luc=\_5'xw9Xgi` (D" ޮ{`r;OpcΎX{pT]ӈ^OoXX@in_~ߛ2ŵZA}R\Nϱ4ٛ5i4}UAq0S c5&5hMB`~wO}R>{FԞgGu~8{=*8{| ZZ=Zi4c✖є#I+uCKTΏ/ހW@Tpxv3TOӭ şbT Ͽ:a0QD}NSP 3{Ry/~؜ڟ?l lU?Sw'zgl}Ry뵅*bw{twq* (ώm|oU+O/>zEo^ ݞ ~׉s̔(WJ^~Q`8*2.덩nt>f-[_u}wuΨ.UpUotxf IFgo0W-X*bcT`*Lickf썯C0LJ ތ)`^ z0 By~9>3Uffz>>qDlvvBh]L/ߘU]OO/ҨC *FXX͟^O҈بFz) Ad3aJژ,`VJx_<*z1[K]͸lumxz_ԫ>{ խ%xDuj/a/jeshzлsO HggDVWY  w֧^.UH9'kw ilb‹60W9S!0[)a} <^ă ?AHxԷ]<5uZ񃦬2^V]Vn3voC3izU*XXd&WMqzAc^(F(#g(3_pgTiWЮzSY`&Ӌ4"rSmC>;o;]|lRj>t8 ϗqϿHixW >2/rOWTpXyFϙPX1C:5/ x= ceN#F z0 ǃGqr^óc³n@X#C5LU/zf@a&o}Pk3|?pRrVc'>}y~5p UߣKk+@#\v>4z9wQ1i@TcǠWh4cZZ7U>c\}mh6Zv_"]{IE+2Wt8"rGs& +Ҙ#_Gj:m XZju zϬb8?\ׁ,`"\IЋb[K72PK\_5'^p}%N4A]1KίU.=6,\r(L1*2 oxcfvxؗ^P 3v;y5f+%Npz0{ npQEZTp(A/Om5-|eIt(4W-w938ǸDek0W;`qv/Mj>~yt%n|mO ?_H$赺t㨔:#v?np?eFgOx00eZƛ|>RǤTʙ ߾|=cC?d&l͞?˕ qA,,Ld|Ѭa V\hGB1f]yJ^c>I"<{v/TJ/f« j6ΣF"oZūe^뇢r~7 lZ(c&,װRŌ*ke;]1卤z}+@D891#h''2 ni:xn{R}Wz㾴w8rw45sxO8ҟFD#<BxZך7=2m"l}~/Ӎ ϲ&py<@^![}ou,^^sfm 13[b@_ \_5՘yuwWH,׳:R~J7cǾ/"Jz#SmCk9F1M z~,B4RYG~Xz YTj+$$NpzxDuB܌7cN$vUӃܰ>8=8{=^>h^lfl:k(Ϧ=4.Gw=4/g0:gV/n4ĄĝSޮ8@ϊqjc*`^8!k * _9Gy~sl, IDAT^Ax+u7+Mt] ϟqrp6OϟR/~lP'* |^1)~\itgt}8ǥWTp.U>.N/hj"pvT>M7 MA2\q]?G;'xsغnϟqs3\xip:_7q+FÝX=!B D mMOn'O?li`TVT}2kc4.+뵉DpBL^ϟ3P\QxH}+w򻀫vtwkع8 ~Ӌ6[)͟^` ^5mc!wN6Fɓ_[TrL^ytT||h= "3 `YXe1b卅Imu7h6y3ڿF|.^:W/wquavT ʕ 3 h`@+\pYo){=\ 'M>9ScQz9]\)=>+f+%lXz;;Fy~6s&}+GI2Ry.b!\*8A'HIѸ&Ɨf %qO=.uŏC߻zӝ&K >&N B" (ܖX f w V898ʳž/M־Yc!6_GnQ] :. [oٝ<̄j7!2?U?%'c1:ϰcl^͔6Iz U߽~77j&^QwU*t+So SύF{#i\ 󋃧YD="&W+o;yϬиƗwsv?uB1B=pVoOfL]H,}sdm;idIaq9=8ϙQ?Ky\y8Vwŏ5w1죂KS]_LdGVq:>~wπb L^Ka 뜞#m[:9w{3fWFps_h~ۙ&9rL d} ݪKLcYaPA.cfv^%K J DžAHg@Ŗ@$3,oE +yRiTڋ$Npi=%~kukaRh4*:R^Ҋtsel#PDX*fVJ/vssHX*`iU~Q]`iUÝ PAu_wzʝnMKL$.ZXSARa,z\z/=(W#co&qhd=&u7 4Y3(:Q{!HAv#F"nߋŵjתvX*M-8>ΛnZ-ueV,Tul^sr_FGrjTq3e&MM fJE̔(WJ7֦W*8;poj㮌*.덡J]鵼1ayc!**~OKSEuu=_\dqL.~uUhǎuk-Gwz+7}kbregGe]襙-쨎/y=E+%z1gE/V@lG:/8|8NjHZI/+89\O6/Υ=5י3]BsV3kԃRV"BSMfMGrz”;D{ <¼50GĄ7OaW#F<5x/}u< L#ƥ>ݑ38hr܌SpN`QdKőv;j.ҫXyt7"]!SG#̎CL_g'ͽIb?>^9Ϟecmǰx^00^o ּI4Iqw ^R_ugo>QgGM[cxf-snR%ӜqG5^nǡ|ėw{x瑜ЫuwMѽ7fu_랙:'l<\z-պ8I+&:?6NΑt8ԳfC)坸<Ε2^N-f2X'4X /08=8H)p\z!A;g= d5Kӑ)SB $̖0=Jyャ4[Dfvpnsd}s^F':/;Q?Ļ||z峣:]Lprpf[_{>)ͨ .SEȣR?5]~hV#]kVw?uf~wvTOiC^v(9޵eCgK]^aq#f{~L YAgo2:Sl@`X Iƪ.MI ·|)8? vuH ЫTkP)G&~=^n/f>TQw< j6l2cX|hMX\H3;WJd$'rtCy欴q\_aafp +վ?c4~c>| :A'}M\+z\1u4KCuEO ̄A${1 ` 0 wG3B4ys /]^ngGis6k>Σ*m'gNBr%SJU˒8 * ü5;(G{,]z:D罌Y! =?x;vѻ淥CAeY<8՞,92l/gG>Y患 @gbP^DV ^' "ND&!<L(NI ·RYG59ͽ}^#&'8?Vv\_:O<>=5W>ݧn\TֻQ1B/ft0`f897ß_OFj^c`&~k<~J/f:^}w>h~z_>Q?DK( kn?<Ύ{By`qŎdd2L/2y~ҧOlZTջR2 z`L×@""(Skv~6OL) :$,GeߘAq赸=;gnyޗw{S}h)[߭lJ ,}z^t6N2lP]O_}{F׳X\"n%S_ƮgЫ8ץ㵮c4Fc2h\tO&Ы^1!{/+<_Jބg`P^U+f(xHh{"mOH;_s蘝RzR)Z8?R*>9*gB-o,}vPͥFl>i7%#788tbI;KO;>ZJ Q a\)ud Әs(fzuN2# *8T*(brvT0[)avn&v5 ڜ]@0Yc U\_~r1^{h`ar_۰no?ƞ`JB1RFIjƨ^j@k}:L~mV)_,'gh\dsne0vOps ^k\cՌo_VCj%hg~81[)h \r~YEDC3YЃ~~n{HدBO&AJ^fB+G6ޮ#*F8?gNn-aa#tf(^"[Qk\}qcyzOf،.Y5479Ͼ}xo5B.|zC"`<ËODg?l/䍥i2ջ+mJJGdxfFHO楮n-w6pbo`uk z@d!P] mW?Q16znzU1ںv6H^\LjΎ] xTHQ1rۃ'>sk#Ǵ deAlŧ!_ͳ>%`NڕӧLFIGD $C@"`~( h\^^qu@nQTQU驟^f2{˸g3_ 霭fkx/`&̔gP(F~vaag8;cyc˱0,zR: sCoWqV?FmycѺw? A>7 ʕ9쟡4[DK$qfb9TLZvЫ"?z{0<_J3V3g{a8ŏ^DAN30 brUWs`8Cٞ, 8Kɰ?;c@{(|QVjej6;']5yZ=ٽ7͗ۯsr~7=aԛcz06ҫX* nc8n%w }} vl{g츕`תh\5w(|(!u"@~r<& 맾>nʯBېz<`Eg'0CHAy x!e<55((tG֭Qf Z>nSVv/NlgoQ?t7+GaQg㢷S/ ꍩT(@ $q@Z&ix@k]ռx8f!"}s닥7L\qհ7M3}uaiHoM^"n%ݳf1|\M *F:*h)9kT t^R!u,>^tK|O/TJS,f /WG+|ފs|O/o",VSgnVtAʑ#%"SAGř~~zf~huҗf݉cz/nߢb4425N$wŜhhW V쨎?hLh*s'E7It~}q:L~A&=^9r?ȁyϬŐ3wCJ!1f݃=#"@;Ep A/- 3~c}= g+CD+'xq;>lpvT2תC.{䕭&S:to(  =9 1#ŨI`V?3d,M?޻Z3>_Jc:qfb7,ADh]h5} D_Τ$R`A5۾;G ^Z{ZL z g0zEQ =`JM*2J{uVm\3dN3 k@j:7DyϬA[\,p2D;{xhG!}7|i)08[^|W*7 2{ik6^}!WD7uڭ*do{cu|N{&`KF^۠[[h'C+&y~4ĠXw}z\ '+ |A<􊠓 x5}>1Fׯ ^f`;"O]^@" h@_<:  *m5lI$|L O?B&"G"P= c+H>NfD"DtA H @)_5@ |z"rpuXm :@ħ6<Q ײBF#oE:z$>CwL" "60ļG8I59U0>H5[yx  "x[3}^l$ˈts{]cfh 8>O}i }tl֘ÿly&Ɇ]9TH<` <lj=Ǚ 3<@Zm-C (o`!e^a$>G$ O 3eF蓱q#ALz(5!YN30wC=)ȮgBXzDB7!b$!ᄵ?  o{S&W X`\_xcIb}𒀅A|3:=IʫDT $k"Oi ߦ9}'ḴϾ6Re9b]S?aKIb:"qB8wĶGSwuIc^8JL' 8@ཀm#IYx=9ffPG@T=aS+Tґx虃Xx&!29bSP$z=H|{9+9ta3$3'v(@k! Op8]l۶&"rЈ:umm*|X$_׷~q^چo%؁?qM "2Vċ*f}hM{x$i 4mtpޤog)e>3x6rVtk'o#4zF|<6r!"H"v'(ρom(uSLIzqBfQ^$HϨ'0P(X,׺feaiS⭗7ۺJZx5![m2^,^M`8gk+8f StEQb WWYݱGT3.O`&W{af@}S,0~.G _MQR>er)/ "7]HlR&Mgp'5U{h47!dg-ACpn"q`w^ػA 3 &;u)"1mI OTwWQL*OV#ޚ'gNasEٳOF!vۅͺgƧ=e;bރR4PHZDmSr"ƷU>2^`]#2-ψ$̴Hd d Ĕlmu*ENf$ $&Ta`ӭ 1}"vd H"&dL-:sT ~}jS֘ͰTĊ~v! P$H }8" Th8 k{Mn3ǬH(R"1^H&)<ɛ3I90D`qBK Zo 3A%] .aQe:g݃`iQ3T*OmCz-SB #%0yUF$r*&s Emi` LK6HāW?wmcϯ9$&4g#!63FKp0T( QGۙTQҳ"q &fP''9}&j@e; H;C?'x(CVX甾dB;0Í^3H`Mv3!ߓX!>6g\}Deo҈:C_AS &Dt]J(LT}`2N\A] '^~] RvbgS/1H|\ gX #3"ßIu1BBC%=TsPAR9d{5 PA7Ib3p(1kl!:_ag88'3L-, i;Q50g, u06 }t})DwhtԶUG 2@yo؈fR;zNLۇٙΧ%d6x4P;DW߫%\ tщ,m;<!=7>wOE >X0ǺgH1'Xe R dyhI{\HKϙ֌wdzKwo9skIfypG8u~:4HICՙt0 !Nc5ĕy1mgXٌ3;+վpvT)=>SXpiPR 8a|Зu+LTP0 $Yvd&пocx@4i_K01є:.0[ Ţf Vf^9E՛ӓKXJ Z5؃E7;U ![)fm/oȠN!8iQ/̀ѐ Λ'o#;Arux{p[ Z(Bct{ 9Ae16 N3 ;ST.dĜȔ~.LbSffe6DU1 :Ép3LpN^K얝$ IbA#΅ֈy Vy~7dzҨfh)*?v zbY'f@>uH\mi;œ,aJxuliI H{&cgP`$$!K#dJ۫o{C?ڿ'DȀ!JUXpf%Gu76Ψ #J^b-PGCH E7 uK&]Ϡz9=AKY*P{%dYyCv;k}LL Apf'H'a#I<"-8͓`b2ց&Tj&eKCw*Is*JoԎIlG8/>Sd]Gp'=#>@;X%9AxD1y?9U;1@"ppi+0qL 8ݸfb0E`؍!Uz;NE$Y#J03ALT ]85haۼsPZjS*jR4!"z|0/M8'\hTy1Z^(ck+!n^{hH:D,ռaFv]*12@&KM2&(X(b{8;뺽\L| (?"V4Ī0Rߙ=zZ 6gA%+(504غ1"&uJ$z#sT&]X U2 h,Z [zB3#!2&_&"8l 1b3T'`j"c!:۲ bEk[[D:p;Zn rqs`sFF#)iINYe'y5Q2PΚ 52| LWL2"M2t]TOxRGaǀЅOB!:yS@A԰t\؜)3DI*[t9ѳfǖm|v4ng{(s)brѲN2Cd$mp[1YS-UM=ohTGIuvϖa Zd_ti]VM2j:|b;` x=,k2B잙|p7j:fhZd]lӵ,HrE{ sXRՎ`rzDsDH!1S!I#܄!boHR;\-X),}1i{ϋi'>lvnj HۿaoF{"=YsV= ,^$tHX"Il6ov$ĮlB: %սa쀕9$F4 #KG8l8EؗFP>t#&0Q2("%Ma#c! ڙ4MBHL`DH`+"q٘aR\-\!FDz5zX=aAAPiꇨ¹"o[11V>[l"#hd̛ N25(XZ A7uBB*(A$Ǥ`|lYټZoG*0m"j'[rmE%8rXDӕY`uf@zStPĘ2 Pƪ*Ԕ7.LYKGpBmd``[Y3';&Qp ۆӶSآ a?H:U%rf0%IPYr }"ޖ•u)yyټNx(EhI`*H+BjOJBA9U,(HȖFYU̓^!KQGj/x  K(J6 lɃӨL A&t}0ڳ)qnFVwbbSp F Mǖ9 yu%!52`4*倱 HUV QXKs ;b*jsV2fi̓:I4 #uh$xA!1(X؞sDAj*@HDTt d&ҪOo0%Zs%D#5rv]+ c|P^at|[W H΁=Bd78B9.2Nab[ fߦU]˒7 IoJE@\YoOK"LG#g@b,ި O9DraD'`(D>E]Ggwdޗ^T\|_5]L9w_(>{@iV9 @:N#% b4%gD H lzN;w}513IF!&\$oM KUcLc;ϑ;>c} Qy*+jW[xD^lõV7 xTt>4ʵcdl0.&T8˽ÑŚDȝB& <m܂&AlcE"t28Ԟ-.. šWtG$_Dcu; wK}}vpY1vohyPt)/1N[>R$R/#=GHcd}!Ɩ@)h.tկMLJm5#7xOEHWBD^BK20Q6Gn}"nA˓O 4W}na{ۊ IL&3g}i "H*1E@9r86H"@y%_vnrcUܜ4^Jf0RIZdfO 8ְ0/j8Q}2G]$,zDayE1A`; yvuZgL{L>Ҹ\} -',t&&V#BoeQϙs/5F5>1 ̫8`޵zh/t9luMKۊ},3$sx.f vko̤{[ 3!k@k& 5ظg\Bʞ%+^ZTtBM0X8DrDOhw[rr 57Vݴ2J>U"x8$  u\`Wb=UחjA__H䒈رmrkys~E"JTt:yN^AKPV*0/BBZ"|~s J>ϰ@WJ$VEw>ͳJomUŵf#xdé|d$"4Cu4!gnt0^xDHp1hڑXAT;7 " FE,H ̲si 3@I6QLH9RydE 7X +pL@9M ⼹FQҝ&,8[X^foϋU [ ϟRH0Rh,FUK]!řlLSD?1Ӗ899睇 Yd"(CS2\) J88zx?p< {h "WY5u84Nm&4$z_c9K_ȏV\4k*`os %NIaf'5ujHWiU.iV$iwQt,Yb+ qRoab3Ab 8ԌD`nCbvI{?IxIDATYXA:^$pM)TsSHcf7&2_&"=3Rh4x%XYx `*yGC+5D:XPTzWNC ,n}b9\M|%\dĪ"{@1E9{搠K买ȕE1K"?"Yj>U} Aq-^³;W]-T$1tH#h <%DdGx4 8BٜtqcיoFm=bFS_A^K*!;@*yM &MSE`8,UP^;|dMVa0Bw쪱}IENDB`torbrowser-launcher-0.3.7/security_design.md000066400000000000000000000060461456573360100212720ustar00rootroot00000000000000# Tor Browser Launcher Security Design This document could be improved. At the moment it's copy/pasted verbatim from a post to the [debian bug tracker](http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=752275). ## TLS/x.509 security torbrowser-launcher doesn't rely on the CA infrastructure. The only TLS it does is make HTTPS requests to check.torproject.org and (if you haven't set a mirror) www.torproject.org. When it connects to these hostnames, it uses a hardcoded certificate. So none of the TLS PKI issues apply at all here. (And I took extra measures to make sure the .pem included with torbrowser-launcher is valid. I downloaded the cert from several different internet connections/ISPs and compared, and when I had one I thought was correct I sought out Tor devs to verify I was including the right one and not a malicious one.) ## Downgrade attacks Downgrade attacks shouldn't be possible, unless they're committed by Tor devs themselves. If an attacker captures a valid old request to https://aus1.torproject.org/torbrowser/update_3/release/Linux_x86_64-gcc3/x/ALL that claims that the current version is an older version than what's currently installed, torbrowser-launcher prevents it from installing. (And by "installing" I mean extracting to the user's home dir.) However, there is the scenario where the user has set a third-party mirror to download from instead of the default. The third-party mirror could serve a tarball and sig that have filenames of the latest version, but are actually an older version. This attack is mitigated by the fact that all mirror options use HTTPS -- though none of the mirror certs are pinned, so in this case it would rely on CA infrastructure. This is an edge case, and would only work against users who are using a non-default mirror, and who also have access to a trusted CA signing key. ## Installing Tor Browser system-wide You cannot install Tor Browser system-wide. It's released by the Tor Project as a bundle. There's a lot of code in there that specifically prevents it from touching any other files outside of it's own directory. All files need to be owned by current user, and it's designed to be runnable off of a USB stick. A long time ago I put a bunch of work into tearing apart the "bundle"-ness of TBB to make it installable systemwide, and concluded it wasn't practical without the Tor devs releasing it as such. If you could install it systemwide, there would be no reason for torbrowser-launcher -- it could then just be a normal debian package. ## What secret keys/access attackers need to succeed Yes, attackers that 1) have access to the trusted keys included with torbrowser-launcher and 2) have access to modify files on https://www.torproject.org/ or have access to its TLS key are able to get arbitrary code exec as the current user when they open Tor Browser. This may or may not include any of the Tor devs whose keys are included. But like Holger said above, this is a feature, not a bug. This is the whole purpose of torbrowser-launcher, so users can automatically install TBB updates that are signed by Tor devs. torbrowser-launcher-0.3.7/setup.py000066400000000000000000000107311456573360100172560ustar00rootroot00000000000000""" Tor Browser Launcher https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ Copyright (c) 2013-2023 Micah Lee Copyright (c) 2024 Tor Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import distro import subprocess from distutils.core import setup SHARE = "share" # detect linux distribution distro = distro.linux_distribution()[0] def file_list(path): files = [] for filename in os.listdir(path): if os.path.isfile(path + "/" + filename): files.append(path + "/" + filename) return files def create_mo_files(): po_dir = "po/" if not os.path.exists(po_dir): return [] domain = "torbrowser-launcher" mo_files = [] po_files = sorted( [f for f in next(os.walk(po_dir))[2] if os.path.splitext(f)[1] == ".po"] ) for po_file in po_files: filename, extension = os.path.splitext(po_file) mo_file = domain + ".mo" mo_dir = "share/locale/" + filename + "/LC_MESSAGES/" subprocess.call("mkdir -p " + mo_dir, shell=True) msgfmt_cmd = "msgfmt {} -o {}".format(po_dir + po_file, mo_dir + mo_file) subprocess.call(msgfmt_cmd, shell=True) mo_files.append(mo_dir + mo_file) return mo_files with open(os.path.join(SHARE, "torbrowser-launcher/version")) as buf: version = buf.read().strip() datafiles = [] for root, dirs, files in os.walk(SHARE): if files: datafiles.append((root, [os.path.join(root, f) for f in files])) # disable shipping apparmor profiles until they work in ubuntu (#128) if distro != "Ubuntu": if not hasattr(sys, "real_prefix"): # we're not in a virtualenv, so we can probably write to /etc datafiles += [ ( "/etc/apparmor.d/", ["apparmor/torbrowser.Browser.firefox", "apparmor/torbrowser.Tor.tor"], ), ( "/etc/apparmor.d/local/", [ "apparmor/local/torbrowser.Browser.firefox", "apparmor/local/torbrowser.Tor.tor", ], ), ("/etc/apparmor.d/tunables/", ["apparmor/tunables/torbrowser"]), ] datafiles += [(os.path.dirname(f), [f]) for f in create_mo_files()] setup( name="torbrowser-launcher", version=version, author="Micah Lee", author_email="micah@micahflee.com", maintainer="Nicolas Vigier", maintainer_email="boklm@torproject.org", url="https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/", platforms=["GNU/Linux"], license="MIT", description="A program to help you securely download and run Tor Browser", long_description=""" Tor Browser Launcher is intended to make Tor Browser easier to install and use for GNU/Linux users. You install torbrowser-launcher from your distribution's package manager and it handles securely downloading the most recent version of Tor Browser for you, in your language and for your architecture. It also adds a "Tor Browser" application launcher to your operating system's menu. When you first launch Tor Browser Launcher, it will download Tor Browser from https://www.torproject.org/, verify the PGP signature, extract it in your home directory, and launch it. When you run it after that it will just launch Tor Browser. """, packages=["torbrowser_launcher"], scripts=["torbrowser-launcher"], data_files=datafiles, install_requires=[ "gpg", "packaging", "PyQt5", "requests", "PySocks", ], ) torbrowser-launcher-0.3.7/share/000077500000000000000000000000001456573360100166445ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/applications/000077500000000000000000000000001456573360100213325ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/applications/torbrowser-settings.desktop000066400000000000000000000031651456573360100270000ustar00rootroot00000000000000[Desktop Entry] Name=Tor Browser Launcher Settings Name[cs]=Tor Browser Launcher nastavení Name[da]=Indstillinger for Tor Browser-opstarter Name[fr]=Tor Browser Launcher configurations Name[hr]=Tor preglednik – postavke pokretanja Name[hu]=Tor-böngésző indító beállításai Name[nl]=Tor Browser Launcher Instellingen Name[pt_BR]=Navegador Tor (Configurações do Lançador) Name[ru]=Tor Browser (настройки запуска) Name[sv]=Inställningar för Tor Browser Launcher Name[be]=Налады запускальніка Tor Browser Name[tr]=Tor Browser Başlatıcı Ayarları GenericName=Tor Browser Launcher Settings GenericName[da]=Indstillinger for Tor Browser-opstarter GenericName[hr]=Tor preglednik – postavke pokretanja GenericName[hu]=Tor-böngésző indító beállításai GenericName[be]=Налады запускальніка Tor Browser GenericName[tr]=Tor Browser Başlatıcı Ayarları Comment=Tor Browser Launcher Settings Comment[cs]=Tor Browser Launcher nastavení Comment[da]=Indstillinger for Tor Browser-opstarter Comment[fr]=Tor Browser Launcher configurations Comment[hr]=Postavke za pokretanje Tor preglednika Comment[hu]=Tor-böngésző indító beállításai Comment[nl]=Tor Browser Launcher Instellingen Comment[pt_BR]=Navegador Tor (Configurações do Lançador) Comment[ru]=Tor Browser (настройки запуска) Comment[sv]=Inställningar för Tor Browser Launcher Comment[be]=Налады запускальніка Tor Browser Comment[tr]=Tor Browser Başlatıcı Ayarları Exec=torbrowser-launcher --settings Terminal=false Type=Application Icon=torbrowser Categories=Network;WebBrowser; torbrowser-launcher-0.3.7/share/applications/torbrowser.desktop000066400000000000000000000014621456573360100251400ustar00rootroot00000000000000[Desktop Entry] Name=Tor Browser Name[be]=Tor Browser Name[cs]=Tor Browser Name[da]=Tor Browser Name[hr]=Tor preglednik Name[hu]=Tor-böngésző Name[pt_BR]=Navegador Tor Name[sv]=Tor Browser Name[tr]=Tor Browser GenericName=Tor Browser GenericName[be]=Tor Browser GenericName[da]=Tor Browser GenericName[hr]=Tor preglednik GenericName[hu]=Tor böngésző indító GenericName[tr]=Tor Browser Comment=Launch Tor Browser Comment[be]=Запуск Tor Browser Comment[cs]=Spustit Tor Browser Comment[hr]=Pokreni Tor preglednika Comment[da]=Start Tor Browser Comment[hu]=Tor böngésző indító Comment[pt_BR]=Navegador Tor Comment[sv]=Starta Tor Browser Comment[tr]=Tor Browser Başlat Exec=torbrowser-launcher %u Terminal=false Type=Application Icon=torbrowser Categories=Network;WebBrowser; StartupWMClass=Tor Browser torbrowser-launcher-0.3.7/share/icons/000077500000000000000000000000001456573360100177575ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/icons/hicolor/000077500000000000000000000000001456573360100214165ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/icons/hicolor/128x128/000077500000000000000000000000001456573360100223535ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/icons/hicolor/128x128/apps/000077500000000000000000000000001456573360100233165ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/icons/hicolor/128x128/apps/torbrowser.png000066400000000000000000000214571456573360100262450ustar00rootroot00000000000000PNG  IHDR>asBIT|d pHYs[tEXtSoftwarewww.inkscape.org< IDATxy|T;d'dI@ADqTJ#.ZnjmڟOU[)TmRÃVPMv!/d23%3r'D?ds{{|EPLZ3.SWL @R'Z]ͬWw}q/ x2D+y.GP dW EPb7RّRrKia{/$a@9۳]P $᎑Ȁea8Ae R?rRQ!FlKy%0(+9Z@] )WI!V]>i{L'?Ixz1SY cwpͯ!~HϱrxMs^jꡘ-Xe^)vt]./{Ƞe-ŧmC>R>W[ټYΞ ;<6^ [һ*\"AJ~=2DV@o]8LZŸu[nb0yȤbBT}@/N W1}uBC<;|"}*$f)HL:MPh*:/m܎-߅*m}q>!LB)9޻.w( B_^L^haȨ4, , 4 MP!jF*4RekRO ةH{9U/ (ȿHzyUyof4'윲0Gs&9Bt:[)khO By p/zS_Guz::*&,7/ .&?:eֱ>Ņ@,lqOB`^ӧJ\]ץ{bAE zD:F%;_kZ23o**7>qFQֺd.G0ǻ߷ǣ|go4aeDi F/m.drZNtbtuӛ$-5;M1L )@XQ7:]wxrYYɖblRϪf0^}r>ڹ҅EX$ONoG ztդp5ù~TE(=V GlȎ5 Yj1[׹F`HG:f,Ø0`I$1ɂ59$$QDF~Y%cNR=U8M~QsAO*bY\]|B"^ ^hzC@EdB FL`9ihC$eI)Ճ}yE% zE) ƻ.{-TJ=0$@0 eܼ\FNS,ZϚKĮ?!Y9Ꞵ(EH}rw,JR_ 7t6x2:C@ ޮdߪJ\:COMA5`R'2vn.5i,-+ᴺdkZۋc@h[t^L`B fOUFB5=论эuZ^Ӯ5.-!jK{CUcsg'}Z~! ;|NV>Y:|k=; 9g([b Y7Xײpsa/(f^!:%GwT4joifrǦ#FsfY\ ,|&mYՓ>_G  OOaj\|YcuObgz33pH3P2%@4_gDGo|3>4SfDſ܂%|qrI"uk-.~عBD€h>sJʷS_f٪<4ͬqasD|C{S͕mtD}LEІʨ H׭m;?j-{$_g`{IKI:zV_{umZA6U;%yѷ 砚6W19i(#B56+0R"ck/rWe#w'57Ъ7yTO6!HtUԶuJ хRyk:^R+ Q* gFd׿Ik.z}ŞU= zK}K:(Ggg"?m*v1%ϋVلNhāN=2lhJv"VǶG鰻HL571/ ޵G ˗x}WY990o[7ÛGѩ|pX ? @Jy/2ޏ} 2rb6#A|u G[hM(ooHwKq:Bw˟&s2cU{OtMLjS>Iǒ9*F-m15w[:F;,>Ycٶ8.䒑vUc2ZȚ}p*J{x ZQ< z)Lz,<W=~!iy)1곥i|&8chC2K7тF䙚lyuYwΉ skfܬ<är:\lx$ΚWhH-}ƮR,Ʉ:?`j\Lν-wۊa#9f5:5jy%tI=np3$igS7X&NɮJ.8wX\N=2F 4C*@JY7Z\ȅdL1D +wTcշsLB$#: `D sonQUav$cqĆG_P(ҤT拯F-tQ-fM`bZ^MYYf 0eQ(99CJ`.A~ǩ8%F-HxX-FMiN6D8L.k 3ۙv{s,8L!D * 5;̂4GmX61-#>ĜdZV ]&H_ӟ_3 9VNno:N=dgRU3F]1kZ!e%ZMHP3ɐ,4'ya@~zʱx5+QtZop=6Wۢ>Μ>0t ЙVc]v i/@ q4T5GrXRR[;eha: vhR6@G.qCcU eQ?!ya6E2 lT Π'#8-Hhv4H-rPЍTC)a% '8q.jyCF&6#צg5+E9%0ƎptwUԲMP8ixX5׵F-/+59QV} Y[DvQ,Ctt: w7`yL>E!yY P}.zyRO Yo  uCQcvN7.BYr:\V4F-OGyXmTAtLd}`,g95>7ZawzhX#.c< -Wv[/j5?fVu˔l}{딩ya!y%vewj.U@Éz/='O!='%vSg{ Z;*6vGˎÌwHv|0Xd#6hi ! #bȈ4q۹abњfpbÚjmT۹/n;t j b`gh„W\LU?Kc`9f=JG R*$x .ϒ_M@'(b#`e&a1g]}09A"'~b!oO`cu :2Ckr:\ kԷnt9S}+\O?dHk +wG-?ZJ<#A+Io2Lt>,{xnvzyɐȌk&g; Dif pƳ'V.%R ֦Pij ٷomj?[i,R̼a Z7zuoxd/pZgVtBK1FFK>u, \|C`'_4F%aM ),Hwf'ɬ1̹ xnAb%v{k_d k܅˥*CB\,&.fo9` y+6&Y Lx+V#bu'ʋ+ƢC7P gİrdZͤ2f(;IsNǒyWOxB BB/C Tv؝ &IW* ^߭R>`Ǘ"A &I"9%$rFe1\ Ə$X͆'Œdc.7`wbԂ| kc(tn P(WH + @.Xm_EN~v#xQgklV1]Kv{`n}Zע V7_݆nr=ENgw((4Ds ~{ 9v|/d"G3#5+ZCKcy2t[] EYC5켹h^; ~:>q$$$wH-Nj8QZGkc{@L=p-dݥĭ`fY.Z_D1;\˿wx+nAz#g"l73M2lϋW}^9/5hz0 p $!SEA,dָs};+/˩::ڝ~z(|#{T&>&]:!s=*sIĭ+b{oq%@vg@Bο|2w/#DuUy7c/]njax&F]i)@P'JTi`C܂,n| &?>x3^zteAa7\;Ĥ??]f :k^($hͨhOHL/_Eo`W,z71|>OYVteO`X5ݱ@6ne.b 3$F}Y }כJ,HCWOȨ'u@E"-r utf-8&%n1<R>b=Sy^"n]O% 'U%Zw0$rά )L~jL{AK4T!I:)"bntRkJ͑0 ~b!RG r)>+ 2S9eb)Sgwy5:{^gjJ'ʇ8ˇ&nWpu- {MϋV>I#؜u2O>Neu5}wkj ;N |}n;I-u,v[n769] OMmzOPQJf\ $C`3HK 7Fvo {زv;m-QmyǪvoHŪEK%߹E 5gz{iT5) 'e;x=[RqL4,Xռ8&gM/yw]`翧Xps/os&%;$CEkcUGj8~+dIDATǀg[YbVey Of+=DzkgK1(^Q%띖IA]gXSWhS4PAKLiyfK_s#Ue1^+7"~okwv_"i >P!Hw֕88խKMo1CJ~$U9rfqL6R[FL=ʇ~kwnmoq&$rӳ:E0SxapDA Vu[ޣo̬;S c냉o-IoBhJ>~sq ^̤H3']!!lHdZ݂ x- HH2ZW.c1, sꎦ  @@IK0 I7)/sUe7H ~~$.$r|}] %?pǥ)7e"9D0 +`@NۄdhmZRg41 RgPY( 2W8Џ R)9 R4^B{EbP ̔3!ap${">qU]-WWkQS IENDB`torbrowser-launcher-0.3.7/share/metainfo/000077500000000000000000000000001456573360100204465ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/metainfo/org.torproject.torbrowser-launcher.metainfo.xml000066400000000000000000000041651456573360100317660ustar00rootroot00000000000000 org.torproject.torbrowser-launcher torbrowser.desktop CC0-1.0 MIT Tor Browser Launcher A program to help you download, keep updated, and run the Tor Browser Bundle

Tor Browser Launcher is intended to make the Tor Browser Bundle (TBB) easier to maintain and use for GNU/Linux users. It downloads the same TBB from torproject.org that everyone else uses, and it doesn't alter it in any way. But it does make it much more usable, and it makes the task of keeping it up-to-date more secure.

You install torbrowser-launcher from your distribution's package manager and it handles everything else, including:

  • Downloading the most recent version of TBB for you, in your language and for your architecture
  • Automatically updating (while preserving your bookmarks and preferences)
  • Verifying the TBB's GnuPG signature
  • Includes AppArmor profiles to make a Tor Browser compromise not as bad (in some distros)
  • Adding a Tor Browser application launcher to your desktop environment's menu
  • Lets you set Tor Browser as your default browser
  • Optionally playing a modem sound when you open Tor Browser (because Tor is so slow)
https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/raw/main/screenshot.png Window to change Tor Browser Launcher settings https://gitlab.torproject.org/tpo/applications/torbrowser-launcher boklm@torproject.org
torbrowser-launcher-0.3.7/share/torbrowser-launcher/000077500000000000000000000000001456573360100226535ustar00rootroot00000000000000torbrowser-launcher-0.3.7/share/torbrowser-launcher/mirrors.txt000066400000000000000000000022761456573360100251200ustar00rootroot00000000000000https://dist.torproject.org/ https://tor.crazyhaze.de/dist/ https://creep.im/tor/dist/ https://tor.ybti.net/dist/ https://tor.0x3d.lu/dist/ https://www.it-sicherheitschannel.de/dist/ https://mirror.freedif.org/TorProject/dist https://tor.secure.voyage/dist https://tor.127001.ovh/dist/ https://mirror.oldsql.cc/tor/dist/ https://mirror.torworld.org/dist/ https://tormirror.tb-itf-tor.de/dist/ https://tor.zilog.es/dist/ https://torproject.ph3x.at/dist/ https://www.torservers.net/mirrors/torproject.org/dist/ https://tor.myrl.net/dist/ https://tor.stalkr.net/dist/ https://tor-mirror.cyberguerrilla.org/dist/ https://mirror.velcommuta.de/tor/dist/ https://tor.eff.org/dist/ https://tor.void.gr/dist/ https://www.moparisthebest.com/tor/dist/ https://108.248.87.242/dist/ https://mirror.ntzk.de/torproject.org/dist/ https://www.eprci.com/tor/dist/ https://sela.io/mirrors/torproject.org/dist/ https://tor.ccc.de/dist/ https://tormirror.snydernet.net/dist/ https://tor.calyxinstitute.org/dist/ https://torproject.mirror.metalgamer.eu/dist/ https://nl.mirror.babylon.network/torproject/dist/ https://fr.mirror.babylon.network/torproject/dist/ https://cyberside.net.ee/sibul/dist/ https://tormirror.tb-itf-tor.de/dist/ torbrowser-launcher-0.3.7/share/torbrowser-launcher/tor-browser-developers.asc000066400000000000000000000153441456573360100300050ustar00rootroot00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBFSOr7oBEADQMs+Q5cAshRhj3YkKgCBKyrjFWMZqVhlf9Y3ePtFQ9kFEnYIS G9rzMhFC6KMXPn9bgg6OBPPUnnJ29UsKvAk+qa8F35R+s0ZXmPRfmv5/6PqxLOn4 G733K67K0/eXYW1mTkz9sjY8u9E3T10JNT0zE/60WihuZGKZQDIqqig0fOsdvdGa g+srAW91T56kAT+y59VcvqVCQNjS897E3T9hsUNkQNCdOitQcnN8/5VNQUL0SjyD BV0y5ry+pUt1rnojj82KQ3WzZuD+XsDE+w2JSGqhcqf9b7D6puy1smhCNwZJ9L1l pJlrCap6YQN8TPFTkf4aFBctxonAdQDDxbON6sPJALc/myPwTVTxD3nJJhv12yft 2iwZLaCJcdq6tp96re1dwaETpvvKeWqhWGVkmNaAPhShcCKpVYC3+Jil6nTqN6LI hKD0ILBGOT/2/Rxd4kj1uDzvc2RVHe6LKLc5EQYO80/wSIL8LMdqZSX2R/AnhcNg G/k7yOQWWNY7RPU1cV+E9QKNwqS4Zj2VyU6s6ikaPuUnjW59iMkSGUuS+gJUR2hp jOKjNzu8vxbotBgZ01upDUdl69OnR1dv9X+bMzGWUyOjAjK6SP8rFtWFBjWgWcED OHu51YpicSdN3uf7lppEXGx91n45xVMhL9d2KNp3DhWkKDuWhdliWC/r1wARAQAB tEBUb3IgQnJvd3NlciBEZXZlbG9wZXJzIChzaWduaW5nIGtleSkgPHRvcmJyb3dz ZXJAdG9ycHJvamVjdC5vcmc+iQJUBBMBCgA+AhsBBQsJCAcDBRUKCQgLBRYCAwEA Ah4BAheAFiEE724obdqF6ipLp95oTixuh5MpgpAFAl8XqaAFCRPu+2YACgkQTixu h5MpgpASEQ//fiGjtuwF+xAB5366e0ciTXKTKq2ar2uBgeKnAl7h862ePLE8MwIN 2d7t1eGBdyr1B+CK6XRkeHtRjN5feOLOKQYy6UkPfSZZnSt/pXqH9bCZWIlejpFl HaNAUGFMbmtHzJb4ZEto3B0/HGAAx/1xiHP5GspdEj99H2T710axz5mCqbt6BRv4 twZCEWQ4LE1GGn1NoBaf0STmF7luKC3IQi/H2VSc2LTJLQoo5Lnmr/w+jZ4N9S/J QKfeYQmXplbHWtG+AQh9VxDJxfK8z85zwvosR0LuUpbvn9Jsn8sFwB2TA9jLzPNr trBeotx5kcQm1ae+ETiNQdtJ8JzFHm5a5UmViZy6/zyK0T4PisKu7J10mZ9bBBro RXuqmxWqnD4GV/knKECE7K2DUeS7HsJin/hVc2OaHckII1i2Ced64tVfP9I1H/QX HXeP4AVkeDnwPTVDB/1R3RCBguqm0fkqGBW9HNTQz8ju6hiNdtTtLBFQ8rYaMO8U YVfQBFtuh7zKwjSnt0gsN3J/FEcHMIDto5mkerL3GrEnBZeXV8M14BdBOKiw2swK ibVuXhmW8nWdKO7evK8O+xE7W6wE+fWCghW3VLM8tnVlpMkmTTxQATbZ74Fhfor2 DT8Obn8D+IK7Vzv2NJbtX9j1S8bz9t0JCuKIHRClF7ijJ0NyQEM6xbK5Ag0EVI6w 6gEQAOSdq/N0T8db8PTutfkBRVtkdVpvhumkKWbjBoN4CwA8BVZSAfdgNCE74tyP +k7Pa802eQBUE6f0j4rD8E7ohGO61vo3ZLIIMPGCQOLtvOThNKU8ZBnCPdUbk6ms bPmnfh9Khz33zGkjozzr3uLkRDKqgwCu22sgxMMa+Szs2yBpejab4mSRglNgEgm1 sLxoIUBX2DzuV6jh4+J3jCCSOSUDSl8HF3ELaBebNo2VegGdvOqTOKPLZp+8d//8 ezi/W62wUhxJltJsFPRKw3rFkIeGgSUog5ooX/V9V9YO0UsDmCO3Vgy5s4byctgC uEbxa2ZPabwrRgpaXUgOGu/a5PDO1veesCJhKbAuHvwgntaODpY6PjmnNA/9QzrK hUpAYp4jeSANxtd2tLFM+n/HwK4n8yxnBcM2dqc2WebfZDHNzNyqCGv+3CugTouq W97cgJPbS7IkEMAVm2zygMezx3y3p7bVC502SxkGsnLcw9H+qbBSg01v8hiKVtI/ 7jFRQxAHSmpQOtk+Y7jApxox123BGOtJKjsxkUo1GEk+rIpCkun+Dk13NlYw4DNt IKPQBngx+OBNi9XLS0s5ZslfOwk4fxTdJlmNAGLmXvsVyoOAsJo+Kt7HH5KKKJL7 YUrE7a658G/6ZuiYy9XbWI40tLpKrArFodTON9W6+AeqG1bRABEBAAGJAh8EKAEK AAkFAlXdoO0CHQIACgkQTixuh5MpgpCV3RAAizJNW4PdKa90EiAVL63tTlz4+L4a hPFNXYeB5WXt/2fZS97B8kr3uFP7GnGj7ojj4/+9x6vTWiFguHw3ZGpJRkWeoHRL ge+eAxl9AXXtMDdeJk0hzqd14Nj23eRmssoqeAtQm1zXPvmmC0ybfm7CxnAIdvZN CITt4J0g6bMqyerR2550+ZY6mAlN/x65JNfmG3XJ3Xo6WKCGy8haOjaWrcTM9BR1 wM8266raCJakjZXLhOLJWMRAvcYIwpCdKKATe+AcoDT5N8gQJmgDJjXRfstGLPkJ kmu9hmo9AfLjrZhtqRGexmaPnqb2eQSvlzuADZuuy9GyIx5+t85q7OHs77pyYBm8 8so2LkJbwhL51XNJW6z6j1jX9ubbLgZmJlAkx8nNmVMWPexKHr2aE+nHkRmuS9e2 TIK7o5cutlt0MuIRjBz5SLrB6m7TH543/Ym+h/vWxjXSGFOeMfVx6e8zpNDu4WmR PmR8QlHXrnOhlWuwFY3kIGaEWtWIxalKz1XyZijaWnZ+AIbAnfLhVPTjcwaky2Em 0NDQqCLwk4jwuWUByzwVurNJkwAwlhXVh3cAyV8fiwDXopI4RzyrgcuW+yLyCsXT F0Fgp7KzYkfLo5M9OGlKvPVvLmCzu+oRif2EGVBdGj7+65pV4E3/YTdzsw8EdYBZ KKfetxATY9ZJcBOJBD4EGAEKAAkFAlSOsOoCGwICKQkQTixuh5MpgpDBXSAEGQEK AAYFAlSOsOoACgkQLQAJiFiYOaO2UQ//cmWSSkfbgSPwAT5cFnC3ipqcFvY+L+/O Dcp723unIwfslaSDssUZKlBMgbj8c59EZqEbrxJA0rI9L4xTCG2pCusR84aeZd/5 NLYXVOopUYiwWk2I1KLnNbhDYYGWHANOw8Y6ycACOWxGOSDDB6CrpQQMlhPPdfW2 RtjaIUfihKv+F2mA54jhnasdCaAk0aGkdJmJ04/2BhkwWpBepFpl6+WMwe1oA0lN Cg/eXhoxW8BT5ExK6w0lzp2/4P9wZjVtAYpOOU9SdHj7g1XpH6vavapQlcz8Nfw+ ByX6ZLIr1YaQpOsOr/EBcjyw02LCPiP+tIo/Bw4o8jm8+OIt/qnrEqlwBLBFlQO5 Nisy6Dr7uyqEALv7MGbExJm33jnCSyHR5oyRDFI4BYip2PdFZ5WAUKZvlq5+lh+Y d3Bf8uC2ljMZD6Ed6rAp00M4MWLnzUmrPg/4JzWc7S+V5dBZEhEWJesPU8T7xr8u tG7b2LxFXYzZRq5jSyr62WPMbLHzlRTIdzsBdNsBnJLgo5PCbHwIQxGXeJoHWd+Y THtMORBF3uCpC/AgHKioU551ipcx1e8aFypskMxZZRHllTObwKexeO8c2fT1V9Gv QnEn572l0QpY9zz3duB83s80rpHnl6NjRowEbPuqBKpLIxw3a7Wo319qRQDYOFm9 TXrO0CDZ8MY7+w/8DSi8KSDRNxrMbhME1R/CcSNoBQrQOoGSJLdBhW9QSEjMP+6h ATkenbGmrVxl1mICzHuqXgr+JW92DbPwR8z6A1k5SO8V1xOesX7zgt2sy5RvfNZe 9mmiaa0CxeY6YG0NaqF2+OA5vvpHXh3vwGOcN481rTLdKF4lQhzvpzdHlYUTYwtf 3MIwAOJdzsZB+jGJphRh6XS+mTABtAigXFAP901sRfiL+41Zo1nQtm7sjBVhHVEI SObFZLTdXwvTn5ufw+3rmY5X5n8A2QK1V9j4y0DYFk1P4dW9OoanWU/kLRyqPDsP jr8Ey0UeZyEur4HXBdFucy1Fn2/EtUFTYWaPOqyVl0/IlKTlfGY0566l/n48kwOx /P4PHIVr36tE6XHPRB1d6ui6fpzjm2FgC7odjna2gD9IhHAeLfjG1wvXXHcFCeZH df1B0nicivxYAGb0Nc8ICl89WMfKp+/LMzD08Alzz26Mfmglv6zJx2J0b8puMEtT iM4ESrDVrMxewibZ4cI9e1g86WXGPlIZ0ApicFlr69bTIPzIYNmYwWqab2tqm0MQ VRpNDWMIkWJ/r3TTmNN+Fqv827Fo7qR8zjPVi8DyoKmFzfgya2ZoE7od5bGg7lcM 7UhzEPfwZUMqKaawlrnzqy1sGLJi0QZErUhHo3tU9sHYqAtUENvs4LC7dEG5Ag0E YUSBvAEQALxuQqEliMOMGpoVXWK7uIPHXmV8U/kUuAtda3Mfo7vySXUgqv3Cgia+ pszIXa5BYx3GCCx2W+H+EYzyB80Nw/Qz2kAX03+wJ/gaioQfRkNEcZi8cvWS08px TVpKkaPMRuhSk0eCXAXmikDOUvzxqeB7U/IPBdsZJJoQk5vfOJX1vA0ZvdHwW+uZ C69rJctAqZ+qaEtOO94i9o+MfUq+ovHPflYM5o27w8oC9LKmTJVa6vMg88dLRkJp nXHe0Xr8Xq6seJZIfixu1RvFA5OLvxJvEySKwI2HJ+Fn56AnPZKb64YA67PLe/j+ 201w+svGh71FFbjxyrxOTGDdeZ9AMHJ6IRvdhtgvh6ZxceWHKSqDxkZo5BgfKmkK Y9V+PNmpa/h7jEA+531L67j1o0B1dgmnvHobiixTiTMI7tPTAs9fsXg2RWs+L+nP VHQLTHqOMRRsD0sv/W2cCrydNN3w7e1Fbv1Ka55AAu1uslO+XJehkbqb5GojaAGM 4DowintgyfEYP4BKl299lD5/w4e1NsO8o7xkU9oswzNT57jocla0P3jFVSdvg75+ H9qUnp52k0BZO4ynQLreaUpUxax4H9L38iE5ClgX5vJ+4fCEyqyIhAVEhFGpjDJ+ TG1EB2ljE7PjCKUg+OK+Xf42F5BrZmji1fpAsKiOhSwHs7lj8gcVABEBAAGJBHIE GAEKACYCGwIWIQTvbiht2oXqKkun3mhOLG6HkymCkAUCZZmnzAUJBYRfEAJACRBO LG6HkymCkMF0IAQZAQoAHRYhBGExiPxb4hduPtVJAeU9mJqeLUe/BQJhRIG8AAoJ EOU9mJqeLUe/vKEP/2+AD/ZAqQQRSGbvkh0TIMjLkBpS5lyVA1rHtTOzhAmtCnoi 0x0Dd6w8d81yjNuvfGhijdxPOjUicA+9tEWHKb3AszV8JL72vC2OJl3Qod+C9N55 907r+EL41A4Ew7bLYz5DifQBoVt/qzTjUIZdpNbz/oDHr75R3bm8QwKSVrj0mia/ l1rCCLBVAFAaF59VIS/KjyRo5wPqUaUkxU5A1MH/FXcRXaukO4ontNqaZpV+P1c9 +duQnAI1dXEDpIgCya+4kJDazBKLn3HtPYf758qNj0qAMl+Z3zeGPmdFx5dIV5IQ wxjQopnjHg6rBTLqGGQvD9OLpCXsCrahEF0BXrVRHVBL5yJih+XO12eIoMX/PnDT Sd3SodO0W3Pfp6MHMx6QSox8r5OJdi+WrrSwZBBg3UQL82+SBdJMDhxFutyGQ6rj Wt1EdOOfOLlH97dl2z4jCmstXAc7pPC7XNOFz3zZbJmjBV++Ax9T0Bh5zLfvvzHx s0j05wlQTiVJZBlGLAecMosdWzf1J6xqaQY2fOn/psF110iWLQMhrsiIXcjeUrFa g17DCVuB5v6lHxYpcy9KnYQQs7AHrSQHbd22Tw7I+bwdtsKNVLgrg+qGxitbW/kc /tM17NAHcVrXohP/NUx3QbJ6Ild14EjuFSWlU1Z9TU7PmIzP8TPyiruxv8IqpB0Q AIFc7W4zMoYaonNZ10tVLhyjwOUAlDwf2B0Iwy15ctr07Kn6bMeMZULFpXhExCw7 2mtnAK4jHRphR5m7t7mSYxMwSP5HAffFZpkx8YQHYq2ZSe+yIxXeRwraMdO7POJg tPt730xoBB7Cra2t1yQj9KuIewuy1qZhjn+upabH4x6OVox1gZcoj+cxZ5mSV+9C Hkypgl9VQZWAjG36Y8rJ//3KFAizJLwGP3XAtUx9cId75mWCz8SJwroadoVrk1dR IQ2HPZEjmbhWKXR5InJNg0BgHh3qT1bW1tu8xKHqauukrzgAmDcBjOT50lpuGBzW 9hU/MuyaqpPLwWH5NFkpgBwvIGwQbW4aq59M4HZhYeTas0YqQL6ju70c6w0ZmCis 0mn4IaPJCO55HTZvtXxEp4iyyepDoSFbAeOnActKWrOueNlsDshGzfqCbFgCsj+f vNetkQSX4CBM4r96RydMaSGm1FX+bAu5RoyxIAxIrotHbGY0x1speXawuJx1H9RH vVoQA/PdUZ+06g8vAjBSxKb+gSEhC6iWJ9shPcGg4FV+E7GTD0x1b61jsiM1FX/T pIFuTj268C5hCVECxJ8ctClfBdS0if2IDFtJ90NjXijAB6/bPj316h6TKlBBfjjs 5L6tvQRifoG5c3gJ2H++8Gk7ue5jyE9BwJfsySOgBMDQ =pesg -----END PGP PUBLIC KEY BLOCK----- torbrowser-launcher-0.3.7/share/torbrowser-launcher/version000066400000000000000000000000061456573360100242570ustar00rootroot000000000000000.3.7 torbrowser-launcher-0.3.7/stdeb.cfg000066400000000000000000000004301456573360100173210ustar00rootroot00000000000000[DEFAULT] Package3: torbrowser-launcher Depends3: python3-pyqt5, python3-gpg, python3-requests, python3-socks, python3-packaging, gnupg2 Build-Depends: dh-python, python3-pyqt5, python3-gpg, python3-requests, python3-socks, python3-packaging, gnupg2 Recommends: tor Suite: bionic torbrowser-launcher-0.3.7/torbrowser-launcher000077500000000000000000000024061456573360100215010ustar00rootroot00000000000000#!/usr/bin/env python3 """ Tor Browser Launcher https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ Copyright (c) 2013-2023 Micah Lee Copyright (c) 2024 Tor Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import torbrowser_launcher torbrowser_launcher.main() torbrowser-launcher-0.3.7/torbrowser_launcher.pot000066400000000000000000000100711456573360100223560ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-01-09 17:04+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: __init__.py:76 launcher.py:520 msgid "Tor Browser Launcher" msgstr "" #: __init__.py:77 msgid "By Micah Lee & Tor Project, licensed under MIT" msgstr "" #: __init__.py:78 #, python-brace-format msgid "version {0}" msgstr "" #: common.py:90 #, python-brace-format msgid "Error creating {0}" msgstr "" #: common.py:187 #, python-brace-format msgid "Renamed {0} to {1}" msgstr "" #: common.py:201 #, python-brace-format msgid "Cannot create directory {0}" msgstr "" #: common.py:204 #, python-brace-format msgid "{0} is not writable" msgstr "" #: common.py:211 msgid "Creating GnuPG homedir" msgstr "" #: common.py:302 #, python-format msgid "Could not import key with fingerprint: %s." msgstr "" #: common.py:309 msgid "Not all keys were imported successfully!" msgstr "" #: launcher.py:87 msgid "Downloading Tor Browser for the first time." msgstr "" #: launcher.py:90 msgid "" "Your version of Tor Browser is out-of-date. Downloading the newest version." msgstr "" #: launcher.py:111 msgid "Downloading over Tor" msgstr "" #: launcher.py:122 msgid "Tor Browser" msgstr "" #: launcher.py:141 msgid "Start" msgstr "" #: launcher.py:191 msgid "Yes" msgstr "" #: launcher.py:195 msgid "Exit" msgstr "" #: launcher.py:209 settings.py:136 msgid "Cancel" msgstr "" #: launcher.py:246 launcher.py:267 launcher.py:276 launcher.py:315 #: launcher.py:318 msgid "Downloading" msgstr "" #: launcher.py:257 msgid "Latest version: {}" msgstr "" #: launcher.py:261 msgid "Error detecting Tor Browser version." msgstr "" #: launcher.py:291 launcher.py:389 msgid "Verifying Signature" msgstr "" #: launcher.py:295 msgid "Extracting" msgstr "" #: launcher.py:299 msgid "Running" msgstr "" #: launcher.py:303 msgid "Starting download over again" msgstr "" #: launcher.py:315 launcher.py:334 msgid "(over Tor)" msgstr "" #: launcher.py:330 msgid "Downloaded" msgstr "" #: launcher.py:431 msgid "Installing" msgstr "" #: launcher.py:440 #, python-brace-format msgid "Tor Browser Launcher doesn't understand the file format of {0}" msgstr "" #: launcher.py:471 msgid "" "The version of Tor Browser you have installed is earlier than it should be, " "which could be a sign of an attack!" msgstr "" #: launcher.py:488 msgid "Downloading Tor Browser over again." msgstr "" #: launcher.py:561 launcher.py:569 msgid "Download Error:" msgstr "" #: launcher.py:563 msgid "You are currently using a non-default mirror" msgstr "" #: launcher.py:565 msgid "Would you like to switch back to the default?" msgstr "" #: launcher.py:585 #, python-brace-format msgid "" "Invalid SSL certificate for:\n" "{0}\n" "\n" "You may be under attack." msgstr "" #: launcher.py:588 msgid "Try the download again using Tor?" msgstr "" #: launcher.py:598 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Trying to download over Tor. Are you sure Tor is configured correctly and " "running?" msgstr "" #: launcher.py:604 #, python-brace-format msgid "" "Error starting download:\n" "\n" "{0}\n" "\n" "Are you connected to the internet?" msgstr "" #: settings.py:48 msgid "Tor Browser Launcher Settings" msgstr "" #: settings.py:52 msgid "Download over system Tor" msgstr "" #: settings.py:59 msgid "Tor server" msgstr "" #: settings.py:74 msgid "Status: Installed" msgstr "" #: settings.py:76 msgid "Status: Not Installed" msgstr "" #: settings.py:79 msgid "Install Tor Browser" msgstr "" #: settings.py:86 msgid "Reinstall Tor Browser" msgstr "" #: settings.py:111 msgid "Mirror" msgstr "" #: settings.py:129 msgid "Save && Exit" msgstr "" torbrowser-launcher-0.3.7/torbrowser_launcher/000077500000000000000000000000001456573360100216335ustar00rootroot00000000000000torbrowser-launcher-0.3.7/torbrowser_launcher/__init__.py000066400000000000000000000063511456573360100237510ustar00rootroot00000000000000""" Tor Browser Launcher https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ Copyright (c) 2013-2023 Micah Lee Copyright (c) 2024 Tor Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import argparse import signal from PyQt5 import QtCore, QtWidgets from .common import Common, SHARE from .settings import Settings from .launcher import Launcher class Application(QtWidgets.QApplication): """ Qt's QApplication class. It has been overridden to support threads. """ def __init__(self): self.setAttribute(QtCore.Qt.AA_X11InitThreads, True) QtWidgets.QApplication.__init__(self, sys.argv) self.installEventFilter(self) def main(): # Parse arguments parser = argparse.ArgumentParser() parser.add_argument( "--settings", action="store_true", dest="settings", help="Open Tor Browser Launcher settings", ) parser.add_argument("url", nargs="*", help="URL to load") args = parser.parse_args() settings = bool(args.settings) url_list = args.url # Set the TORBROWSER_LAUNCHER env variable to make it easier to # detect that torbrowser-launcher is being used os.environ["TORBROWSER_LAUNCHER"] = "1" # Load the version and print the banner with open(os.path.join(SHARE, "version")) as buf: tor_browser_launcher_version = buf.read().strip() print(_("Tor Browser Launcher")) print(_("By Micah Lee & Tor Project, licensed under MIT")) print(_("version {0}").format(tor_browser_launcher_version)) print("https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/") common = Common(tor_browser_launcher_version) app = Application() # Open the window gui = None if settings: # Settings mode gui = Settings(common, app) else: # Launcher mode gui = Launcher(common, app, url_list) # Center the window desktop = app.desktop() window_size = gui.size() gui.move( (desktop.width() - window_size.width()) // 2, (desktop.height() - window_size.height()) // 2, ) gui.show() # Allow ctrl-c to work signal.signal(signal.SIGINT, signal.SIG_DFL) sys.exit(app.exec_()) if __name__ == "__main__": main() torbrowser-launcher-0.3.7/torbrowser_launcher/common.py000066400000000000000000000324761456573360100235110ustar00rootroot00000000000000""" Tor Browser Launcher https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ Copyright (c) 2013-2021 Micah Lee Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import platform import subprocess import pickle import json import re import gettext import gpg import requests SHARE = os.getenv("TBL_SHARE", sys.prefix + "/share") + "/torbrowser-launcher" gettext.install("torbrowser-launcher") class Common(object): def __init__(self, tbl_version): self.tbl_version = tbl_version # initialize the app self.architecture = "x86_64" if "64" in platform.architecture()[0] else "i686" self.default_mirror = "https://dist.torproject.org/" self.build_paths() self.torbrowser12_rename_old_tbb() for d in self.paths["dirs"]: self.mkdir(self.paths["dirs"][d]) self.load_mirrors() self.load_settings() self.build_paths() self.mkdir(self.paths["download_dir"]) self.mkdir(self.paths["tbb"]["dir"]) self.init_gnupg() # get value of environment variable, if it is not set return the default value @staticmethod def get_env(var_name, default_value): value = os.getenv(var_name) if not value: value = default_value return value # build all relevant paths def build_paths(self, tbb_version=None): homedir = os.getenv("HOME") if not homedir: homedir = "/tmp/.torbrowser-" + os.getenv("USER") if not os.path.exists(homedir): try: os.mkdir(homedir, 0o700) except: self.set_gui( "error", _("Error creating {0}").format(homedir), [], False ) tbb_config = "{0}/torbrowser".format( self.get_env("XDG_CONFIG_HOME", "{0}/.config".format(homedir)) ) tbb_cache = "{0}/torbrowser".format( self.get_env("XDG_CACHE_HOME", "{0}/.cache".format(homedir)) ) tbb_local = "{0}/torbrowser".format( self.get_env("XDG_DATA_HOME", "{0}/.local/share".format(homedir)) ) old_tbb_data = "{0}/.torbrowser".format(homedir) if tbb_version: # tarball filename if self.architecture == "x86_64": arch = "linux-x86_64" else: arch = "linux-i686" tarball_filename = "tor-browser-" + arch + "-" + tbb_version + ".tar.xz" # tarball self.paths["tarball_url"] = ( "{0}torbrowser/" + tbb_version + "/" + tarball_filename ) self.paths["tarball_file"] = tbb_cache + "/download/" + tarball_filename self.paths["tarball_filename"] = tarball_filename # sig self.paths["sig_url"] = ( "{0}torbrowser/" + tbb_version + "/" + tarball_filename + ".asc" ) self.paths["sig_file"] = ( tbb_cache + "/download/" + tarball_filename + ".asc" ) self.paths["sig_filename"] = tarball_filename + ".asc" else: self.paths = { "dirs": { "config": tbb_config, "cache": tbb_cache, "local": tbb_local, }, "old_data_dir": old_tbb_data, "tbl_bin": sys.argv[0], "icon_file": os.path.join( os.path.dirname(SHARE), "pixmaps/torbrowser.png" ), "torproject_pem": os.path.join(SHARE, "torproject.pem"), "signing_keys": { "tor_browser_developers": os.path.join( SHARE, "tor-browser-developers.asc" ), "wkd_tmp": os.path.join(tbb_cache, "torbrowser.gpg"), }, "mirrors_txt": [ os.path.join(SHARE, "mirrors.txt"), tbb_config + "/mirrors.txt", ], "download_dir": tbb_cache + "/download", "gnupg_homedir": tbb_local + "/gnupg_homedir", "settings_file": tbb_config + "/settings.json", "settings_file_pickle": tbb_config + "/settings", "version_check_url": "https://aus1.torproject.org/torbrowser/update_3/release/Linux_x86_64-gcc3/x/ALL", "version_check_file": tbb_cache + "/download/release.xml", "tbb": { "changelog": tbb_local + "/tbb/" + self.architecture + "/tor-browser/Browser/TorBrowser/Docs/ChangeLog.txt", "dir": tbb_local + "/tbb/" + self.architecture, "dir_tbb": tbb_local + "/tbb/" + self.architecture + "/tor-browser", "start": tbb_local + "/tbb/" + self.architecture + "/tor-browser/start-tor-browser.desktop", }, } # Add the expected fingerprint for imported keys: tor_browser_developers_fingerprint = "EF6E286DDA85EA2A4BA7DE684E2C6E8793298290" self.fingerprints = { "tor_browser_developers": tor_browser_developers_fingerprint, "wkd_tmp": tor_browser_developers_fingerprint, } # Tor Browser 12.0 no longer has locales. If an old TBB folder exists with locals, rename it to just tor_browser def torbrowser12_rename_old_tbb(self): if not os.path.exists(self.paths["tbb"]["dir"]): return for filename in os.listdir(self.paths["tbb"]["dir"]): abs_filename = os.path.join(self.paths["tbb"]["dir"], filename) if filename.startswith("tor-browser_") and os.path.isdir(abs_filename): os.rename(abs_filename, self.paths["tbb"]["dir_tbb"]) print( _("Renamed {0} to {1}").format( abs_filename, self.paths["tbb"]["dir_tbb"] ) ) break # create a directory @staticmethod def mkdir(path): try: if not os.path.exists(path): os.makedirs(path, 0o700) return True except: print(_("Cannot create directory {0}").format(path)) return False if not os.access(path, os.W_OK): print(_("{0} is not writable").format(path)) return False return True # if gnupg_homedir isn't set up, set it up def init_gnupg(self): if not os.path.exists(self.paths["gnupg_homedir"]): print(_("Creating GnuPG homedir"), self.paths["gnupg_homedir"]) self.mkdir(self.paths["gnupg_homedir"]) self.import_keys() def proxies(self): # Use tor socks5 proxy, if enabled if self.settings["download_over_tor"]: socks5_address = "socks5h://{}".format(self.settings["tor_socks_address"]) return {"https": socks5_address, "http": socks5_address} else: return None def refresh_keyring(self): print("Downloading latest Tor Browser signing key...") # Fetch key from wkd, as per https://support.torproject.org/tbb/how-to-verify-signature/ # Sometimes GPG throws errors, so comment this out and download it directly # p = subprocess.Popen( # [ # "gpg", # "--status-fd", # "2", # "--homedir", # self.paths["gnupg_homedir"], # "--auto-key-locate", # "nodefault,wkd", # "--locate-keys", # "torbrowser@torproject.org", # ], # stderr=subprocess.PIPE, # ) # p.wait() # Download the key from WKD directly r = requests.get( "https://torproject.org/.well-known/openpgpkey/hu/kounek7zrdx745qydx6p59t9mqjpuhdf?l=torbrowser", proxies=self.proxies(), ) if r.status_code != 200: print(f"Error fetching key, status code = {r.status_code}") else: with open(self.paths["signing_keys"]["wkd_tmp"], "wb") as f: f.write(r.content) if self.import_key_and_check_status("wkd_tmp"): print("Key imported successfully") else: print("Key failed to import") def import_key_and_check_status(self, key): """Import a GnuPG key and check that the operation was successful. :param str key: A string specifying the key's filepath from ``Common.paths`` :rtype: bool :returns: ``True`` if the key is now within the keyring (or was previously and hasn't changed). ``False`` otherwise. """ with gpg.Context() as c: c.set_engine_info( gpg.constants.protocol.OpenPGP, home_dir=self.paths["gnupg_homedir"] ) impkey = self.paths["signing_keys"][key] try: c.op_import(gpg.Data(file=impkey)) except: return False else: result = c.op_import_result() if result and self.fingerprints[key] in result.imports[0].fpr: return True else: return False # import gpg keys def import_keys(self): """Import all GnuPG keys. :rtype: bool :returns: ``True`` if all keys were successfully imported; ``False`` otherwise. """ keys = [ "tor_browser_developers", ] all_imports_succeeded = True for key in keys: imported = self.import_key_and_check_status(key) if not imported: print( _( "Could not import key with fingerprint: %s." % self.fingerprints[key] ) ) all_imports_succeeded = False if not all_imports_succeeded: print(_("Not all keys were imported successfully!")) return all_imports_succeeded # load mirrors def load_mirrors(self): self.mirrors = [] for srcfile in self.paths["mirrors_txt"]: if not os.path.exists(srcfile): continue for mirror in open(srcfile, "r").readlines(): if mirror.strip() not in self.mirrors: self.mirrors.append(mirror.strip()) # load settings def load_settings(self): default_settings = { "tbl_version": self.tbl_version, "installed": False, "download_over_tor": False, "tor_socks_address": "127.0.0.1:9050", "mirror": self.default_mirror, } if os.path.isfile(self.paths["settings_file"]): settings = json.load(open(self.paths["settings_file"])) resave = False # detect installed settings["installed"] = os.path.isfile(self.paths["tbb"]["start"]) # make sure settings file is up-to-date for setting in default_settings: if setting not in settings: settings[setting] = default_settings[setting] resave = True # make sure tor_socks_address doesn't start with 'tcp:' if settings["tor_socks_address"].startswith("tcp:"): settings["tor_socks_address"] = settings["tor_socks_address"][4:] resave = True # make sure the version is current if settings["tbl_version"] != self.tbl_version: settings["tbl_version"] = self.tbl_version resave = True self.settings = settings if resave: self.save_settings() # if settings file is still using old pickle format, convert to json elif os.path.isfile(self.paths["settings_file_pickle"]): self.settings = pickle.load(open(self.paths["settings_file_pickle"])) self.save_settings() os.remove(self.paths["settings_file_pickle"]) self.load_settings() else: self.settings = default_settings self.save_settings() # save settings def save_settings(self): json.dump(self.settings, open(self.paths["settings_file"], "w")) return True torbrowser-launcher-0.3.7/torbrowser_launcher/launcher.py000066400000000000000000000550401456573360100240120ustar00rootroot00000000000000""" Tor Browser Launcher https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ Copyright (c) 2013-2023 Micah Lee Copyright (c) 2024 Tor Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import os import sys import subprocess import time import tarfile import lzma import re import requests import gpg import shutil import xml.etree.ElementTree as ET from packaging import version from PyQt5 import QtCore, QtWidgets, QtGui class TryStableException(Exception): pass class TryDefaultMirrorException(Exception): pass class TryForcingEnglishException(Exception): pass class DownloadErrorException(Exception): pass class Launcher(QtWidgets.QMainWindow): """ Launcher window. """ def __init__(self, common, app, url_list): super(Launcher, self).__init__() self.common = common self.app = app self.url_list = url_list self.force_redownload = False # This is the current version of Tor Browser, which should get updated with every release self.min_version = "13.0" # Init launcher self.set_state(None, "", []) self.launch_gui = True # If Tor Browser is not installed, detect latest version, download, and install if not self.common.settings["installed"] or not self.check_min_version(): # Different message if downloading for the first time, or because your installed version is too low download_message = "" if not self.common.settings["installed"]: download_message = _("Downloading Tor Browser for the first time.") elif not self.check_min_version(): download_message = _( "Your version of Tor Browser is out-of-date. " "Downloading the newest version." ) # Download and install print(download_message) self.set_state( "task", download_message, [ "download_version_check", "set_version", "download_sig", "download_tarball", "verify", "extract", "run", ], ) if self.common.settings["download_over_tor"]: print(_("Downloading over Tor")) else: # Tor Browser is already installed, so run launch_message = "Launching Tor Browser." print(launch_message) self.set_state("task", launch_message, ["run"]) # Build the rest of the UI # Set up the window self.setWindowTitle(_("Tor Browser")) self.setWindowIcon(QtGui.QIcon(self.common.paths["icon_file"])) # Label self.label = QtWidgets.QLabel() # Progress bar self.progress_bar = QtWidgets.QProgressBar() self.progress_bar.setTextVisible(True) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(0) self.progress_bar.setValue(0) # Buttons self.yes_button = QtWidgets.QPushButton() self.yes_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton) ) self.yes_button.clicked.connect(self.yes_clicked) self.start_button = QtWidgets.QPushButton(_("Start")) self.start_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton) ) self.start_button.clicked.connect(self.start) self.cancel_button = QtWidgets.QPushButton() self.cancel_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton) ) self.cancel_button.clicked.connect(self.close) buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addStretch() buttons_layout.addWidget(self.yes_button) buttons_layout.addWidget(self.start_button) buttons_layout.addWidget(self.cancel_button) buttons_layout.addStretch() # Layout layout = QtWidgets.QVBoxLayout() layout.addWidget(self.label) layout.addWidget(self.progress_bar) layout.addLayout(buttons_layout) central_widget = QtWidgets.QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) self.update() # Set the current state of Tor Browser Launcher def set_state(self, gui, message, tasks, autostart=True): self.gui = gui self.gui_message = message self.gui_tasks = tasks self.gui_task_i = 0 self.gui_autostart = autostart # Show and hide parts of the UI based on the current state def update(self): # Hide widgets self.progress_bar.hide() self.yes_button.hide() self.start_button.hide() if "error" in self.gui: # Label self.label.setText(self.gui_message) # Yes button if self.gui != "error": self.yes_button.setText(_("Yes")) self.yes_button.show() # Exit button self.cancel_button.setText(_("Exit")) elif self.gui == "task": # Label self.label.setText(self.gui_message) # Progress bar self.progress_bar.show() # Start button if not self.gui_autostart: self.start_button.show() # Cancel button self.cancel_button.setText(_("Cancel")) # Resize the window self.adjustSize() if self.gui_autostart: self.start(None) # Yes button clicked, based on the state decide what to do def yes_clicked(self): if self.gui == "error_try_stable": self.try_stable() elif self.gui == "error_try_default_mirror": self.try_default_mirror() elif self.gui == "error_try_tor": self.try_tor() # Start button clicked, begin tasks def start(self, widget, data=None): # Hide the start button self.start_button.hide() # Start running tasks self.run_task() # Run the next task in the task list def run_task(self): if self.gui_task_i >= len(self.gui_tasks): self.close() return task = self.gui_tasks[self.gui_task_i] # Get ready for the next task self.gui_task_i += 1 if task == "download_version_check": print(_("Downloading"), self.common.paths["version_check_url"]) self.download( "version check", self.common.paths["version_check_url"], self.common.paths["version_check_file"], ) if task == "set_version": version = self.get_stable_version() if version: self.common.build_paths(self.get_stable_version()) print(_("Latest version: {}").format(version)) self.run_task() else: self.set_state( "error", _("Error detecting Tor Browser version."), [], False ) self.update() elif task == "download_sig": print( _("Downloading"), self.common.paths["sig_url"].format(self.common.settings["mirror"]), ) self.download( "signature", self.common.paths["sig_url"], self.common.paths["sig_file"] ) elif task == "download_tarball": print( _("Downloading"), self.common.paths["tarball_url"].format(self.common.settings["mirror"]), ) if not self.force_redownload and os.path.exists( self.common.paths["tarball_file"] ): self.run_task() else: self.download( "tarball", self.common.paths["tarball_url"], self.common.paths["tarball_file"], ) elif task == "verify": print(_("Verifying Signature")) self.verify() elif task == "extract": print(_("Extracting"), self.common.paths["tarball_filename"]) self.extract() elif task == "run": print(_("Running"), self.common.paths["tbb"]["start"]) self.run() elif task == "start_over": print(_("Starting download over again")) self.start_over() def download(self, name, url, path): # Download from the selected mirror mirror_url = url.format(self.common.settings["mirror"]).encode() # Initialize the progress bar self.progress_bar.setValue(0) self.progress_bar.setMaximum(100) if self.common.settings["download_over_tor"]: self.progress_bar.setFormat( _("Downloading") + " {0} ".format(name) + _("(over Tor)") + ", %p%" ) else: self.progress_bar.setFormat(_("Downloading") + " {0}, %p%".format(name)) def progress_update(total_bytes, bytes_so_far): percent = float(bytes_so_far) / float(total_bytes) amount = float(bytes_so_far) units = "bytes" for (size, unit) in [(1024 * 1024, "MiB"), (1024, "KiB")]: if amount > size: units = unit amount /= float(size) break message = _("Downloaded") + ( " %2.1f%% (%2.1f %s)" % ((percent * 100.0), amount, units) ) if self.common.settings["download_over_tor"]: message += " " + _("(over Tor)") self.progress_bar.setMaximum(total_bytes) self.progress_bar.setValue(bytes_so_far) self.progress_bar.setFormat(message) def download_complete(): # Download complete, next task self.run_task() def download_error(gui, message): print(message) self.set_state(gui, message, [], False) self.update() t = DownloadThread(self.common, mirror_url, path) t.progress_update.connect(progress_update) t.download_complete.connect(download_complete) t.download_error.connect(download_error) t.start() time.sleep(0.2) def try_default_mirror(self): # change mirror to default and relaunch TBL self.common.settings["mirror"] = self.common.default_mirror self.common.save_settings() subprocess.Popen([self.common.paths["tbl_bin"]]) self.close() def try_tor(self): # set download_over_tor to true and relaunch TBL self.common.settings["download_over_tor"] = True self.common.save_settings() subprocess.Popen([self.common.paths["tbl_bin"]]) self.close() def get_stable_version(self): tree = ET.parse(self.common.paths["version_check_file"]) for up in tree.getroot(): if up.tag == "update" and up.attrib["appVersion"]: version = str(up.attrib["appVersion"]) # make sure the version does not contain directory traversal attempts # e.g. "5.5.3", "6.0a", "6.0a-hardened" are valid but "../../../../.." is invalid if not re.match(r"^[a-z0-9\.\-]+$", version): return None return version return None def verify(self): self.progress_bar.setValue(0) self.progress_bar.setMaximum(0) self.progress_bar.show() self.label.setText(_("Verifying Signature")) def success(): self.run_task() def error(message): # Make backup of tarball and sig backup_tarball_filename = ( self.common.paths["tarball_file"] + ".verification_failed" ) backup_sig_filename = self.common.paths["sig_file"] + ".verification_failed" shutil.copyfile(self.common.paths["tarball_file"], backup_tarball_filename) shutil.copyfile(self.common.paths["sig_file"], backup_sig_filename) sigerror = ( "SIGNATURE VERIFICATION FAILED!\n\n" "Error Code: {0}\n\n" "You might be under attack, there might be a network problem, or you may be missing a " "recently added Tor Browser verification key.\n\n" "A copy of the Tor Browser files you downloaded have been saved here:\n" "{1}\n{2}\n\n" "Click Start to refresh the keyring and try again. If the message persists report the above " "error code here:\nhttps://gitlab.torproject.org/tpo/applications/torbrowser-launcher/-/issues/" ) sigerror = sigerror.format( message, backup_tarball_filename, backup_sig_filename ) self.set_state("task", sigerror, ["start_over"], False) self.update() t = VerifyThread(self.common) t.error.connect(error) t.success.connect(success) t.start() time.sleep(0.2) def extract(self): self.progress_bar.setValue(0) self.progress_bar.setMaximum(0) self.progress_bar.show() self.label.setText(_("Installing")) def success(): self.run_task() def error(message): self.set_state( "task", _( "Tor Browser Launcher doesn't understand the file format of {0}".format( self.common.paths["tarball_file"] ) ), ["start_over"], False, ) self.update() t = ExtractThread(self.common) t.error.connect(error) t.success.connect(success) t.start() time.sleep(0.2) def check_min_version(self): installed_version = None for line in open(self.common.paths["tbb"]["changelog"], "rb").readlines(): if line.startswith(b"Tor Browser "): installed_version = line.split()[2].decode() break if version.parse(self.min_version) <= version.parse(installed_version): return True return False def run(self): # Don't run if it isn't at least the minimum version if not self.check_min_version(): message = _( "The version of Tor Browser you have installed is earlier than it should be, which could be a " "sign of an attack!" ) print(message) Alert(self.common, message) return # Run Tor Browser subprocess.call( [self.common.paths["tbb"]["start"]], cwd=self.common.paths["tbb"]["dir_tbb"] ) sys.exit(0) # Start over and download TBB again def start_over(self): self.force_redownload = True # Overwrite any existing file self.label.setText(_("Downloading Tor Browser over again.")) self.gui_tasks = ["download_tarball", "verify", "extract", "run"] self.gui_task_i = 0 self.start(None) def closeEvent(self, event): # Clear the download cache try: os.remove(self.common.paths["version_check_file"]) os.remove(self.common.paths["sig_file"]) os.remove(self.common.paths["tarball_file"]) except: pass super(Launcher, self).closeEvent(event) class Alert(QtWidgets.QMessageBox): """ An alert box dialog. """ def __init__( self, common, message, icon=QtWidgets.QMessageBox.NoIcon, buttons=QtWidgets.QMessageBox.Ok, autostart=True, ): super(Alert, self).__init__(None) self.setWindowTitle(_("Tor Browser Launcher")) self.setWindowIcon(QtGui.QIcon(common.paths["icon_file"])) self.setText(message) self.setIcon(icon) self.setStandardButtons(buttons) if autostart: self.exec_() class DownloadThread(QtCore.QThread): """ Download a file in a separate thread. """ progress_update = QtCore.pyqtSignal(int, int) download_complete = QtCore.pyqtSignal() download_error = QtCore.pyqtSignal(str, str) def __init__(self, common, url, path): super(DownloadThread, self).__init__() self.common = common self.url = url self.path = path def run(self): with open(self.path, "wb") as f: try: # Start the request r = requests.get( self.url, headers={"User-Agent": "torbrowser-launcher"}, stream=True, proxies=self.common.proxies(), ) # If status code isn't 200, something went wrong if r.status_code != 200: # Should we use the default mirror? if self.common.settings["mirror"] != self.common.default_mirror: message = ( _("Download Error:") + " {0}\n\n" + _("You are currently using a non-default mirror") + ":\n{1}\n\n" + _("Would you like to switch back to the default?") ).format(r.status_code, self.common.settings["mirror"]) self.download_error.emit("error_try_default_mirror", message) else: message = (_("Download Error:") + " {0}").format(r.status_code) self.download_error.emit("error", message) r.close() return # Start streaming the download total_bytes = int(r.headers.get("content-length")) bytes_so_far = 0 for data in r.iter_content(chunk_size=4096): bytes_so_far += len(data) f.write(data) self.progress_update.emit(total_bytes, bytes_so_far) except requests.exceptions.SSLError: message = _( "Invalid SSL certificate for:\n{0}\n\nYou may be under attack." ).format(self.url.decode()) if not self.common.settings["download_over_tor"]: message += "\n\n" + _("Try the download again using Tor?") self.download_error.emit("error_try_tor", message) else: self.download_error.emit("error", message) return except requests.exceptions.ConnectionError: # Connection error if self.common.settings["download_over_tor"]: message = _( "Error starting download:\n\n{0}\n\nTrying to download over Tor. " "Are you sure Tor is configured correctly and running?" ).format(self.url.decode()) self.download_error.emit("error", message) else: message = _( "Error starting download:\n\n{0}\n\nAre you connected to the internet?" ).format(self.url.decode()) self.download_error.emit("error", message) return self.download_complete.emit() class VerifyThread(QtCore.QThread): """ Verify the signature in a separate thread """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal(str) def __init__(self, common): super(VerifyThread, self).__init__() self.common = common def run(self): def verify(second_try=False): with gpg.Context() as c: c.set_engine_info( gpg.constants.protocol.OpenPGP, home_dir=self.common.paths["gnupg_homedir"], ) sig = gpg.Data(file=self.common.paths["sig_file"]) signed = gpg.Data(file=self.common.paths["tarball_file"]) try: c.verify(signature=sig, signed_data=signed) except gpg.errors.BadSignatures as e: if second_try: self.error.emit(str(e)) else: raise Exception else: self.success.emit() try: # Try verifying verify() except: # If it fails, refresh the keyring and try again self.common.refresh_keyring() verify(True) class ExtractThread(QtCore.QThread): """ Extract the tarball in a separate thread """ success = QtCore.pyqtSignal() error = QtCore.pyqtSignal() def __init__(self, common): super(ExtractThread, self).__init__() self.common = common def run(self): extracted = False try: if self.common.paths["tarball_file"][-2:] == "xz": # if tarball is .tar.xz xz = lzma.LZMAFile(self.common.paths["tarball_file"]) tf = tarfile.open(fileobj=xz) tf.extractall(self.common.paths["tbb"]["dir"]) extracted = True else: # if tarball is .tar.gz if tarfile.is_tarfile(self.common.paths["tarball_file"]): tf = tarfile.open(self.common.paths["tarball_file"]) tf.extractall(self.common.paths["tbb"]["dir"]) extracted = True except: pass if extracted: self.success.emit() else: self.error.emit() torbrowser-launcher-0.3.7/torbrowser_launcher/settings.py000066400000000000000000000143721456573360100240540ustar00rootroot00000000000000""" Tor Browser Launcher https://gitlab.torproject.org/tpo/applications/torbrowser-launcher/ Copyright (c) 2013-2023 Micah Lee Copyright (c) 2024 Tor Project Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ import subprocess import shutil from PyQt5 import QtCore, QtWidgets, QtGui class Settings(QtWidgets.QMainWindow): """ Settings window. """ def __init__(self, common, app): super(Settings, self).__init__() self.common = common self.app = app # Set up the window self.setWindowTitle(_("Tor Browser Launcher Settings")) self.setWindowIcon(QtGui.QIcon(self.common.paths["icon_file"])) # Download over system tor self.tor_download_checkbox = QtWidgets.QCheckBox(_("Download over system Tor")) if self.common.settings["download_over_tor"]: self.tor_download_checkbox.setCheckState(QtCore.Qt.Checked) else: self.tor_download_checkbox.setCheckState(QtCore.Qt.Unchecked) # Tor SOCKS address tor_addr_label = QtWidgets.QLabel(_("Tor server")) self.tor_addr = QtWidgets.QLineEdit() self.tor_addr.setText(self.common.settings["tor_socks_address"]) tor_addr_layout = QtWidgets.QHBoxLayout() tor_addr_layout.addWidget(tor_addr_label) tor_addr_layout.addWidget(self.tor_addr) # Settings layout settings_layout = QtWidgets.QVBoxLayout() settings_layout.addWidget(self.tor_download_checkbox) settings_layout.addLayout(tor_addr_layout) # Status status_label = QtWidgets.QLabel() if self.common.settings["installed"]: status_label.setText(_("Status: Installed")) else: status_label.setText(_("Status: Not Installed")) # Install button install_button = QtWidgets.QPushButton(_("Install Tor Browser")) install_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton) ) install_button.clicked.connect(self.install) # Reinstall buttons reinstall_button = QtWidgets.QPushButton(_("Reinstall Tor Browser")) reinstall_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton) ) reinstall_button.clicked.connect(self.reinstall) if self.common.settings["installed"]: install_button.hide() reinstall_button.show() else: install_button.show() reinstall_button.hide() # Status layout status_layout = QtWidgets.QVBoxLayout() status_layout.addWidget(status_label) status_layout.addWidget(install_button) status_layout.addWidget(reinstall_button) # Top layout top_layout = QtWidgets.QHBoxLayout() top_layout.addLayout(settings_layout) top_layout.addLayout(status_layout) # Mirror mirror_label = QtWidgets.QLabel(_("Mirror")) self.mirror = QtWidgets.QComboBox() for mirror in self.common.mirrors: self.mirror.addItem(mirror) if self.common.settings["mirror"] in self.common.mirrors: self.mirror.setCurrentIndex( self.mirror.findText(self.common.settings["mirror"]) ) else: self.mirror.setCurrentIndex(0) mirror_layout = QtWidgets.QHBoxLayout() mirror_layout.addWidget(mirror_label) mirror_layout.addWidget(self.mirror) # Save & Exit button self.save_exit_button = QtWidgets.QPushButton(_("Save && Exit")) self.save_exit_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogApplyButton) ) self.save_exit_button.clicked.connect(self.save_exit) # Cancel button self.cancel_button = QtWidgets.QPushButton(_("Cancel")) self.cancel_button.setIcon( self.style().standardIcon(QtWidgets.QStyle.SP_DialogCancelButton) ) self.cancel_button.clicked.connect(self.close) # Buttons layout buttons_layout = QtWidgets.QHBoxLayout() buttons_layout.addWidget(self.save_exit_button) buttons_layout.addWidget(self.cancel_button) # Main layout layout = QtWidgets.QVBoxLayout() layout.addLayout(top_layout) layout.addLayout(mirror_layout) layout.addLayout(buttons_layout) central_widget = QtWidgets.QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) # Install def install(self): self.save() subprocess.Popen([self.common.paths["tbl_bin"]]) self.close() # Reinstall def reinstall(self): self.save() shutil.rmtree(self.common.paths["tbb"]["dir"]) subprocess.Popen([self.common.paths["tbl_bin"]]) self.close() # Save & Exit def save_exit(self): self.save() self.close() # Save settings def save(self): # Checkbox options self.common.settings[ "download_over_tor" ] = self.tor_download_checkbox.isChecked() self.common.settings["tor_socks_address"] = self.tor_addr.text() # Figure out the selected mirror self.common.settings["mirror"] = self.mirror.currentText() # Save them self.common.save_settings()