From e9ad0c8234be705b42d6dd7eb3865919392835a2 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Fri, 8 Dec 2017 16:08:08 +0100 Subject: [feat] osx systray with pyqt5 --- src/leap/bitmask/gui/README.rst | 2 +- src/leap/bitmask/gui/app.py | 97 +------ src/leap/bitmask/gui/app2.py | 57 +++- src/leap/bitmask/gui/app_rc.py | 618 ++++++++++++++++++++++++++++++---------- src/leap/bitmask/gui/systray.py | 134 +++++++++ 5 files changed, 657 insertions(+), 251 deletions(-) create mode 100644 src/leap/bitmask/gui/systray.py (limited to 'src/leap/bitmask/gui') diff --git a/src/leap/bitmask/gui/README.rst b/src/leap/bitmask/gui/README.rst index c3a6a0f2..ac65209e 100644 --- a/src/leap/bitmask/gui/README.rst +++ b/src/leap/bitmask/gui/README.rst @@ -2,4 +2,4 @@ bitmask.gui is a module that depends on PyQt. It is declared as an extra in bitmask setup.py Its function is to launch a minimalistic browser that serves the bitmask_js -interface. +interface. It also puts an icon in the system tray. diff --git a/src/leap/bitmask/gui/app.py b/src/leap/bitmask/gui/app.py index ac472e0a..2edb5bfd 100644 --- a/src/leap/bitmask/gui/app.py +++ b/src/leap/bitmask/gui/app.py @@ -34,8 +34,6 @@ from multiprocessing import Process from leap.bitmask.core.launcher import run_bitmaskd, pid from leap.bitmask.gui import app_rc from leap.common.config import get_path_prefix -from leap.common.events import client as leap_events -from leap.common.events import catalog if platform.system() == 'Windows': from multiprocessing import freeze_support @@ -51,7 +49,6 @@ else: from PyQt5.QtGui import QPixmap from PyQt5.QtWidgets import QAction from PyQt5.QtWidgets import QMenu - from PyQt5.QtWidgets import QSystemTrayIcon from PyQt5.QtWidgets import QDialog from PyQt5.QtWidgets import QMessageBox @@ -62,6 +59,8 @@ else: from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView from PyQt5.QtWebEngineWidgets import QWebEngineSettings as QWebSettings +from .systray import WithTrayIcon + IS_WIN = platform.system() == "Windows" DEBUG = os.environ.get("DEBUG", False) @@ -73,92 +72,6 @@ qApp = None bitmaskd = None browser = None -# TODO do switch based on theme - -TRAY_ICONS = ( - ':/black/22/wait.png', - ':/black/22/on.png', - ':/black/22/off.png') - - -class WithTrayIcon(QDialog): - - user_closed = False - - def setupSysTray(self): - self._createIcons() - self._createActions() - self._createTrayIcon() - self.trayIcon.activated.connect(self.iconActivated) - self.setVPNStatus('off') - self.setUpEventListener() - self.trayIcon.show() - - def setVPNStatus(self, status): - seticon = self.trayIcon.setIcon - settip = self.trayIcon.setToolTip - # XXX this is an oversimplification, see #9131 - # the simple state for failure is off too, for now. - if status == 'off': - seticon(self.ICON_OFF) - settip('VPN: Off') - elif status == 'on': - seticon(self.ICON_ON) - settip('VPN: On') - elif status == 'starting': - seticon(self.ICON_WAIT) - settip('VPN: Starting') - elif status == 'stopping': - seticon(self.ICON_WAIT) - settip('VPN: Stopping') - - def setUpEventListener(self): - leap_events.register( - catalog.VPN_STATUS_CHANGED, - self._handle_vpn_event) - - def _handle_vpn_event(self, *args): - status = None - if len(args) > 1: - status = args[1] - self.setVPNStatus(status.lower()) - - def _createIcons(self): - self.ICON_WAIT = QIcon(QPixmap(TRAY_ICONS[0])) - self.ICON_ON = QIcon(QPixmap(TRAY_ICONS[1])) - self.ICON_OFF = QIcon(QPixmap(TRAY_ICONS[2])) - - def _createActions(self): - self.quitAction = QAction( - "&Quit", self, - triggered=self.closeFromSystray) - - def iconActivated(self, reason): - # can use .Trigger also for single click - if reason in (QSystemTrayIcon.DoubleClick, ): - self.showNormal() - - def closeFromSystray(self): - self.user_closed = True - self.close() - - def _createTrayIcon(self): - self.trayIconMenu = QMenu(self) - self.trayIconMenu.addAction(self.quitAction) - self.trayIcon = QSystemTrayIcon(self) - self.trayIcon.setContextMenu(self.trayIconMenu) - - def closeEvent(self, event): - if self.trayIcon.isVisible() and not self.user_closed: - QMessageBox.information( - self, "Bitmask", - "Bitmask will minimize to the system tray. " - "You can choose 'Quit' from the menu with a " - "right click on the icon, and restore the window " - "with a double click.") - self.hide() - if not self.user_closed: - event.ignore() class BrowserWindow(QWebView, WithTrayIcon): @@ -213,8 +126,9 @@ class BrowserWindow(QWebView, WithTrayIcon): def loadPage(self, web_page): try: - self.settings().setAttribute( - QWebSettings.DeveloperExtrasEnabled, True) + if os.environ.get('DEBUG'): + self.settings().setAttribute( + QWebSettings.DeveloperExtrasEnabled, True) except Exception: pass @@ -329,6 +243,7 @@ def launch_gui(): timer.start(500) browser.show() + sys.exit(qApp.exec_()) diff --git a/src/leap/bitmask/gui/app2.py b/src/leap/bitmask/gui/app2.py index e540f492..0e445026 100644 --- a/src/leap/bitmask/gui/app2.py +++ b/src/leap/bitmask/gui/app2.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -# app.py -# Copyright (C) 2016 LEAP Encryption Acess Project +# app2.py +# Copyright (C) 2016-2017 LEAP Encryption Acess Project # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,9 +16,7 @@ # along with this program. If not, see . """ -Main entrypoint for the Bitmask Qt GUI. -It just launches a webview browser that runs the local web-ui served by -bitmaskd when the web service is running. +This is an alternative entrypoint for Bitmask, based on pywebview. """ import os @@ -34,9 +32,13 @@ from multiprocessing import Process import webview import psutil +from PyQt5.QtWidgets import QApplication + from leap.bitmask.core.launcher import run_bitmaskd, pid from leap.common.config import get_path_prefix +from leap.bitmask.gui.systray import WithTrayIcon + DEBUG = os.environ.get("DEBUG", False) @@ -50,6 +52,40 @@ bitmaskd = None browser = None +class Systray(WithTrayIcon): + + def closeFromSystray(self): + print "SYSTRAY CLOSE" + global browser + print "browser is", browser + self.user_closed = True + if browser: + print 'closing browser window' + browser.shutdown() + self.close() + self.close() + + def closeEvent(self, event): + print "CLOSE EVENT" + global browser + print "browser is", browser + if self.user_closed: + print "bye!" + sys.exit() + else: + event.ignore() + + + +def launch_systray(): + global qApp + qApp = QApplication([]) + qApp.setQuitOnLastWindowClosed(True) + + systray = Systray() + systray.setupSysTray() + + class BrowserWindow(object): """ A browser window using pywebview. @@ -81,13 +117,17 @@ class BrowserWindow(object): self.closing = False webview.create_window('Bitmask', self.url) + def loadPage(self, web_page): self.load(url) def shutdown(self, *args): + print "SHUTDOWN from browser window..." if self.closing: return + + # TODO -- close only if closed from systray!! self.closing = True global bitmaskd bitmaskd.join() @@ -98,6 +138,10 @@ class BrowserWindow(object): os.kill(pidno, signal.SIGTERM) print('[bitmask] shutting down gui...') + def cleanup(self): + # TODO get path!!!!!!! ----------- + os.remove('/Users/admin/Library/Preferences/leap/bitmasd.pid') + def launch_gui(): global bitmaskd @@ -107,7 +151,9 @@ def launch_gui(): bitmaskd.start() try: + launch_systray() browser = BrowserWindow(None) + sys.exit(qApp.exec_()) except NoAuthToken as e: print('ERROR: ' + e.message) sys.exit(1) @@ -143,6 +189,7 @@ def start_app(): launch_gui() + class NoAuthToken(Exception): pass diff --git a/src/leap/bitmask/gui/app_rc.py b/src/leap/bitmask/gui/app_rc.py index bd7fcc23..c399fd44 100644 --- a/src/leap/bitmask/gui/app_rc.py +++ b/src/leap/bitmask/gui/app_rc.py @@ -2,7 +2,7 @@ # Resource object code # -# Created by: The Resource Compiler for PyQt5 (Qt v5.7.1) +# Created by: The Resource Compiler for PyQt5 (Qt v5.9.3) # # WARNING! All changes made in this file will be lost! @@ -568,43 +568,6 @@ qt_resource_data = b"\ \x7e\xe1\x4b\xbf\x78\xdb\x89\x0f\xfe\xb7\xa4\x0f\xb6\x0f\xb6\x0f\ \xb6\xff\xdf\xb6\xff\x0b\x6b\x8e\x7d\xb0\xdf\x23\x5a\x72\x00\x00\ \x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x02\x2e\ -\x89\ -\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x16\x00\x00\x00\x16\x08\x03\x00\x00\x00\xf3\x6a\x9c\x09\ -\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ -\x00\x00\x09\x70\x48\x59\x73\x00\x00\x09\x84\x00\x00\x09\x84\x01\ -\xaa\xe2\x63\x79\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ -\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xba\x50\x4c\x54\ -\x45\xff\xff\xff\xf2\xf2\xf2\xf2\xf2\xf2\xed\xed\xed\xee\xee\xee\ -\xef\xef\xea\xf0\xf0\xeb\xec\xeb\xe4\xec\xec\xe4\xec\xe9\xdf\xec\ -\xeb\xe1\xeb\xe9\xdd\xeb\xea\xe2\xed\xeb\xe3\xec\xea\xe1\xeb\xea\ -\xe0\xdb\xcb\x82\xdc\xcd\x89\xc4\xa0\x00\xc4\xa1\x02\xc4\xa1\x03\ -\xc5\xa1\x04\xc5\xa2\x05\xc5\xa2\x07\xc7\xa5\x0f\xc7\xa6\x11\xc8\ -\xa8\x19\xca\xab\x22\xca\xac\x23\xcd\xb0\x30\xcd\xb1\x34\xce\xb3\ -\x39\xcf\xb4\x3b\xcf\xb4\x3d\xcf\xb5\x40\xd0\xb6\x42\xd2\xb9\x4d\ -\xd2\xba\x4f\xd2\xba\x50\xd3\xbb\x52\xd3\xbc\x54\xd5\xbf\x5e\xd6\ -\xc2\x66\xd7\xc3\x6b\xdb\xcb\x81\xdf\xd2\x98\xe1\xd5\xa1\xe5\xdd\ -\xb8\xe8\xe2\xc8\xe9\xe4\xcd\xe9\xe5\xd2\xea\xe7\xd6\xeb\xe8\xd9\ -\xeb\xe8\xdb\xeb\xe9\xdc\xec\xe9\xde\xed\xeb\xe4\xed\xec\xe7\xed\ -\xed\xe8\xee\xed\xe9\xee\xed\xea\xee\xee\xec\xc2\xe9\x86\x48\x00\ -\x00\x00\x12\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\x32\x96\x96\ -\xb9\xbc\xcf\xeb\xeb\xec\xf7\xf9\xf9\x65\x6e\xb4\x70\x00\x00\x00\ -\xc8\x49\x44\x41\x54\x18\xd3\x9d\x91\xd9\x12\x82\x30\x0c\x45\xd9\ -\x64\x87\xb6\x88\xa2\x88\x6b\x55\xdc\xf7\x5d\xf9\xff\xdf\xb2\x34\ -\xa0\x32\xa3\xa3\x63\x5e\x92\x9c\x66\x6e\x7b\x53\x41\xf8\x27\x14\ -\xdd\x72\x5d\x4b\x93\x0b\x50\x32\x11\xa6\x51\x44\x31\x32\xc4\x27\ -\x55\x1d\x12\x78\x3c\x02\x62\x97\x72\x2a\xda\xb1\xf7\x88\xd8\xce\ -\xe7\x0d\xc2\xda\xfa\x78\xbe\x98\x35\x58\x41\x0c\xa0\x32\x62\x0a\ -\xb5\x63\x72\xda\x27\x87\x90\xe9\x20\xb8\x57\xc3\x6c\xc6\x9f\x52\ -\xbf\xbc\x4c\x46\xac\xc4\x1a\xc7\x16\xcd\x64\xc3\x6d\xd2\x64\x89\ -\x5a\x1c\xbb\x11\xd0\xd6\xee\x3a\x49\x73\xe4\x16\xf0\xe6\xd2\xf6\ -\x5e\x70\x26\x52\x3d\xaf\xe0\x38\x13\xd1\x31\xb4\x83\x0e\x64\xac\ -\xc3\x3a\x10\x58\x1c\xf6\xc0\x28\x52\xe0\xe1\x66\x6a\xc7\xab\xdc\ -\xd6\x1c\x13\x33\x5f\x94\xc3\xcd\xf7\xbb\xdc\xbc\x23\xbd\x5d\x95\ -\xfa\x6d\xb1\x9f\xbe\xe1\xd7\xb8\x03\x79\xf1\x16\x61\x80\x0b\xcc\ -\x00\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x02\x4c\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -644,6 +607,45 @@ qt_resource_data = b"\ \x79\x77\x0a\x68\xbf\x15\x15\x7d\x3e\x3e\xea\x7f\xab\x6a\xf4\x9b\ \xd8\x9f\xde\xf0\xd7\xbc\x03\x99\x69\x19\xe4\x4f\x53\x19\xf2\x00\ \x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\x4b\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x16\x00\x00\x00\x16\x08\x03\x00\x00\x00\xf3\x6a\x9c\x09\ +\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x09\x84\x00\x00\x09\x84\x01\ +\xaa\xe2\x63\x79\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xc9\x50\x4c\x54\ +\x45\xff\xff\xff\xf2\xf2\xf2\xf2\xf2\xf2\xed\xed\xed\xee\xee\xee\ +\xef\xef\xea\xf0\xf0\xeb\xeb\xe6\xe4\xec\xe6\xe4\xea\xe1\xdf\xeb\ +\xe3\xe1\xe9\xde\xdd\xea\xe4\xe2\xeb\xe5\xe3\xea\xe3\xe1\xea\xe2\ +\xe0\xcd\x83\x82\xcf\x8a\x89\xa4\x00\x00\xa5\x02\x02\xa6\x07\x07\ +\xaf\x23\x23\xb2\x2e\x2e\xb2\x2f\x2f\xb3\x2f\x2f\xb3\x30\x30\xb3\ +\x31\x31\xb9\x42\x42\xbb\x4a\x4a\xbb\x4b\x4b\xbc\x4c\x4b\xbc\x4d\ +\x4c\xbe\x53\x52\xc0\x5c\x5a\xc1\x5d\x5b\xc1\x5e\x5c\xc1\x5e\x5d\ +\xc2\x60\x5f\xc2\x61\x60\xc3\x62\x61\xc5\x6a\x69\xc8\x75\x73\xcd\ +\x85\x83\xd2\x95\x93\xd4\x99\x98\xd7\xa3\xa1\xe4\xcf\xcd\xe5\xd0\ +\xcf\xe5\xd1\xcf\xe5\xd2\xd0\xe5\xd3\xd1\xe6\xd5\xd3\xe6\xd5\xd4\ +\xe7\xd6\xd4\xe7\xd7\xd5\xe7\xd8\xd6\xe7\xd9\xd7\xe8\xda\xd8\xe8\ +\xdc\xda\xe8\xdd\xdb\xe9\xdc\xda\xe9\xdf\xdd\xe9\xdf\xde\xe9\xe0\ +\xde\xeb\xe4\xe2\xec\xe7\xe5\xee\xee\xec\xa3\x72\x03\x5b\x00\x00\ +\x00\x12\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\x32\x96\x96\xb9\ +\xbc\xcf\xeb\xeb\xec\xf7\xf9\xf9\x65\x6e\xb4\x70\x00\x00\x00\xd6\ +\x49\x44\x41\x54\x18\xd3\x9d\x91\x57\x0e\xc2\x30\x10\x44\xe9\xe9\ +\x89\xbd\xc4\xb4\x00\xa1\xf7\xde\x42\x2f\x7b\xff\x43\xe1\x38\x0a\ +\x04\x09\x04\x62\xbe\xac\x27\x7b\x76\x76\x1c\x8b\xfd\xa3\x94\xac\ +\x99\xa6\x26\x25\x5f\x60\x42\xb5\x88\xc3\x98\x43\x2c\x25\xfe\xa4\ +\x19\x83\xda\x20\x64\x53\x3d\x1d\xd2\xb8\x5e\x83\x87\x6a\x7a\x78\ +\x5f\xa1\x00\xad\x92\xcf\x58\x0f\x80\x2a\x01\x4d\x5a\x36\x74\xf7\ +\x0b\xce\xd9\xe4\xd4\x07\xdb\x0a\xe6\x4a\x04\xa0\xbc\xc1\x79\x91\ +\x4d\xd0\xab\x03\x10\x49\x60\xcd\xe1\xcf\x2b\x1b\x5c\x2d\xd1\x6b\ +\xf0\xa3\xa3\x09\x6c\x32\xdf\xb6\xba\x43\x3c\x34\xc5\x00\x33\x82\ +\xd9\x16\xf1\x98\x8f\x60\x61\xc2\x7d\xcf\x17\x9c\xe5\x9e\x26\x32\ +\x11\xd4\x6b\xbb\x6b\x9c\x16\xf8\x48\x39\xa8\x83\x07\x1c\x5c\xbd\ +\x36\x80\xbb\xbe\x8d\x78\xc0\x54\x10\x5c\xe5\xeb\x0c\x3b\xbe\xad\ +\x3b\xce\x02\x55\xc3\xa2\x8c\xe8\xf2\x46\xe2\x6d\x55\x99\x6f\xc5\ +\x7e\xfa\x86\x5f\x75\x07\x0e\xed\x19\x79\x64\x32\x85\xd7\x00\x00\ +\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x02\x15\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -680,7 +682,7 @@ qt_resource_data = b"\ \xe5\x34\xc3\x3b\xca\xdb\xaa\xf4\x6f\xc5\x7e\xfa\x86\x5f\xf5\x00\ \x41\x94\x16\x9d\x76\x35\x87\xc0\x00\x00\x00\x00\x49\x45\x4e\x44\ \xae\x42\x60\x82\ -\x00\x00\x02\x4b\ +\x00\x00\x02\x2e\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x16\x00\x00\x00\x16\x08\x03\x00\x00\x00\xf3\x6a\x9c\x09\ @@ -688,75 +690,290 @@ qt_resource_data = b"\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x09\x84\x00\x00\x09\x84\x01\ \xaa\xe2\x63\x79\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ \x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xc9\x50\x4c\x54\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xba\x50\x4c\x54\ \x45\xff\xff\xff\xf2\xf2\xf2\xf2\xf2\xf2\xed\xed\xed\xee\xee\xee\ -\xef\xef\xea\xf0\xf0\xeb\xeb\xe6\xe4\xec\xe6\xe4\xea\xe1\xdf\xeb\ -\xe3\xe1\xe9\xde\xdd\xea\xe4\xe2\xeb\xe5\xe3\xea\xe3\xe1\xea\xe2\ -\xe0\xcd\x83\x82\xcf\x8a\x89\xa4\x00\x00\xa5\x02\x02\xa6\x07\x07\ -\xaf\x23\x23\xb2\x2e\x2e\xb2\x2f\x2f\xb3\x2f\x2f\xb3\x30\x30\xb3\ -\x31\x31\xb9\x42\x42\xbb\x4a\x4a\xbb\x4b\x4b\xbc\x4c\x4b\xbc\x4d\ -\x4c\xbe\x53\x52\xc0\x5c\x5a\xc1\x5d\x5b\xc1\x5e\x5c\xc1\x5e\x5d\ -\xc2\x60\x5f\xc2\x61\x60\xc3\x62\x61\xc5\x6a\x69\xc8\x75\x73\xcd\ -\x85\x83\xd2\x95\x93\xd4\x99\x98\xd7\xa3\xa1\xe4\xcf\xcd\xe5\xd0\ -\xcf\xe5\xd1\xcf\xe5\xd2\xd0\xe5\xd3\xd1\xe6\xd5\xd3\xe6\xd5\xd4\ -\xe7\xd6\xd4\xe7\xd7\xd5\xe7\xd8\xd6\xe7\xd9\xd7\xe8\xda\xd8\xe8\ -\xdc\xda\xe8\xdd\xdb\xe9\xdc\xda\xe9\xdf\xdd\xe9\xdf\xde\xe9\xe0\ -\xde\xeb\xe4\xe2\xec\xe7\xe5\xee\xee\xec\xa3\x72\x03\x5b\x00\x00\ -\x00\x12\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\x32\x96\x96\xb9\ -\xbc\xcf\xeb\xeb\xec\xf7\xf9\xf9\x65\x6e\xb4\x70\x00\x00\x00\xd6\ -\x49\x44\x41\x54\x18\xd3\x9d\x91\x57\x0e\xc2\x30\x10\x44\xe9\xe9\ -\x89\xbd\xc4\xb4\x00\xa1\xf7\xde\x42\x2f\x7b\xff\x43\xe1\x38\x0a\ -\x04\x09\x04\x62\xbe\xac\x27\x7b\x76\x76\x1c\x8b\xfd\xa3\x94\xac\ -\x99\xa6\x26\x25\x5f\x60\x42\xb5\x88\xc3\x98\x43\x2c\x25\xfe\xa4\ -\x19\x83\xda\x20\x64\x53\x3d\x1d\xd2\xb8\x5e\x83\x87\x6a\x7a\x78\ -\x5f\xa1\x00\xad\x92\xcf\x58\x0f\x80\x2a\x01\x4d\x5a\x36\x74\xf7\ -\x0b\xce\xd9\xe4\xd4\x07\xdb\x0a\xe6\x4a\x04\xa0\xbc\xc1\x79\x91\ -\x4d\xd0\xab\x03\x10\x49\x60\xcd\xe1\xcf\x2b\x1b\x5c\x2d\xd1\x6b\ -\xf0\xa3\xa3\x09\x6c\x32\xdf\xb6\xba\x43\x3c\x34\xc5\x00\x33\x82\ -\xd9\x16\xf1\x98\x8f\x60\x61\xc2\x7d\xcf\x17\x9c\xe5\x9e\x26\x32\ -\x11\xd4\x6b\xbb\x6b\x9c\x16\xf8\x48\x39\xa8\x83\x07\x1c\x5c\xbd\ -\x36\x80\xbb\xbe\x8d\x78\xc0\x54\x10\x5c\xe5\xeb\x0c\x3b\xbe\xad\ -\x3b\xce\x02\x55\xc3\xa2\x8c\xe8\xf2\x46\xe2\x6d\x55\x99\x6f\xc5\ -\x7e\xfa\x86\x5f\x75\x07\x0e\xed\x19\x79\x64\x32\x85\xd7\x00\x00\ -\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ -\x00\x00\x02\x32\ +\xef\xef\xea\xf0\xf0\xeb\xec\xeb\xe4\xec\xec\xe4\xec\xe9\xdf\xec\ +\xeb\xe1\xeb\xe9\xdd\xeb\xea\xe2\xed\xeb\xe3\xec\xea\xe1\xeb\xea\ +\xe0\xdb\xcb\x82\xdc\xcd\x89\xc4\xa0\x00\xc4\xa1\x02\xc4\xa1\x03\ +\xc5\xa1\x04\xc5\xa2\x05\xc5\xa2\x07\xc7\xa5\x0f\xc7\xa6\x11\xc8\ +\xa8\x19\xca\xab\x22\xca\xac\x23\xcd\xb0\x30\xcd\xb1\x34\xce\xb3\ +\x39\xcf\xb4\x3b\xcf\xb4\x3d\xcf\xb5\x40\xd0\xb6\x42\xd2\xb9\x4d\ +\xd2\xba\x4f\xd2\xba\x50\xd3\xbb\x52\xd3\xbc\x54\xd5\xbf\x5e\xd6\ +\xc2\x66\xd7\xc3\x6b\xdb\xcb\x81\xdf\xd2\x98\xe1\xd5\xa1\xe5\xdd\ +\xb8\xe8\xe2\xc8\xe9\xe4\xcd\xe9\xe5\xd2\xea\xe7\xd6\xeb\xe8\xd9\ +\xeb\xe8\xdb\xeb\xe9\xdc\xec\xe9\xde\xed\xeb\xe4\xed\xec\xe7\xed\ +\xed\xe8\xee\xed\xe9\xee\xed\xea\xee\xee\xec\xc2\xe9\x86\x48\x00\ +\x00\x00\x12\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\x32\x96\x96\ +\xb9\xbc\xcf\xeb\xeb\xec\xf7\xf9\xf9\x65\x6e\xb4\x70\x00\x00\x00\ +\xc8\x49\x44\x41\x54\x18\xd3\x9d\x91\xd9\x12\x82\x30\x0c\x45\xd9\ +\x64\x87\xb6\x88\xa2\x88\x6b\x55\xdc\xf7\x5d\xf9\xff\xdf\xb2\x34\ +\xa0\x32\xa3\xa3\x63\x5e\x92\x9c\x66\x6e\x7b\x53\x41\xf8\x27\x14\ +\xdd\x72\x5d\x4b\x93\x0b\x50\x32\x11\xa6\x51\x44\x31\x32\xc4\x27\ +\x55\x1d\x12\x78\x3c\x02\x62\x97\x72\x2a\xda\xb1\xf7\x88\xd8\xce\ +\xe7\x0d\xc2\xda\xfa\x78\xbe\x98\x35\x58\x41\x0c\xa0\x32\x62\x0a\ +\xb5\x63\x72\xda\x27\x87\x90\xe9\x20\xb8\x57\xc3\x6c\xc6\x9f\x52\ +\xbf\xbc\x4c\x46\xac\xc4\x1a\xc7\x16\xcd\x64\xc3\x6d\xd2\x64\x89\ +\x5a\x1c\xbb\x11\xd0\xd6\xee\x3a\x49\x73\xe4\x16\xf0\xe6\xd2\xf6\ +\x5e\x70\x26\x52\x3d\xaf\xe0\x38\x13\xd1\x31\xb4\x83\x0e\x64\xac\ +\xc3\x3a\x10\x58\x1c\xf6\xc0\x28\x52\xe0\xe1\x66\x6a\xc7\xab\xdc\ +\xd6\x1c\x13\x33\x5f\x94\xc3\xcd\xf7\xbb\xdc\xbc\x23\xbd\x5d\x95\ +\xfa\x6d\xb1\x9f\xbe\xe1\xd7\xb8\x03\x79\xf1\x16\x61\x80\x0b\xcc\ +\x00\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x05\xb4\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ -\x00\x00\x16\x00\x00\x00\x16\x08\x03\x00\x00\x00\xf3\x6a\x9c\x09\ +\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\ \x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ -\x00\x00\x09\x70\x48\x59\x73\x00\x00\x09\x84\x00\x00\x09\x84\x01\ -\xaa\xe2\x63\x79\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\x1b\xaf\x01\ +\x5e\x1a\x91\x1c\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ \x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xbd\x50\x4c\x54\ -\x45\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x07\x07\x05\x09\x09\x05\x0c\x0c\x07\x0c\ -\x0b\x07\x10\x0f\x0a\x0a\x09\x05\x0a\x0a\x05\x0b\x0b\x06\x0b\x0a\ -\x06\x0b\x0b\x06\x63\x5f\x3a\x6d\x67\x3f\x00\x00\x00\x02\x02\x01\ -\x03\x03\x02\x04\x04\x02\x05\x05\x03\x08\x08\x05\x0e\x0e\x08\x10\ -\x0f\x09\x11\x10\x0a\x14\x13\x0c\x17\x16\x0d\x1a\x19\x0f\x1f\x1e\ -\x12\x25\x23\x15\x35\x33\x1f\x4c\x49\x2c\x56\x52\x32\x6d\x69\x40\ -\x83\x7d\x4c\x88\x83\x50\x90\x8a\x54\x9a\x94\x5a\x9c\x96\x5b\x9f\ -\x98\x5d\xa0\x99\x5d\xa2\x9b\x5e\xad\xa6\x65\xaf\xa8\x66\xb2\xaa\ -\x68\xb4\xac\x69\xb6\xae\x6a\xbb\xb3\x6d\xbf\xb7\x6f\xcc\xc4\x77\ -\xcd\xc5\x78\xd7\xce\x7d\xdf\xd6\x82\xe1\xd8\x83\xe8\xdf\x88\xeb\ -\xe1\x89\xec\xe2\x8a\xed\xe3\x8a\xee\xe4\x8b\xf0\xe6\x8c\xb3\x23\ -\xf4\xd9\x00\x00\x00\x13\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\ -\x32\x96\x96\xb9\xbc\xcf\xeb\xeb\xec\xf7\xf7\xf9\xf9\x4c\x9d\x97\ -\xb7\x00\x00\x00\xc8\x49\x44\x41\x54\x18\xd3\x9d\x91\x67\x13\x82\ -\x30\x0c\x86\x59\xb2\x57\x8b\x7b\x6f\x45\xad\x13\x51\x14\xf9\xff\ -\x3f\xcb\xd2\x80\xca\x9d\x9e\x9e\xf9\x92\xe4\x69\xee\x6d\xdf\x94\ -\xe3\xfe\x09\x49\x35\x6c\xdb\x50\xc4\x02\x14\x74\x17\x93\x20\x20\ -\xd8\xd1\xf8\x27\x95\x4d\x14\x25\x2c\x22\x64\x95\x72\xca\x5b\x7e\ -\xf2\x08\xdf\xca\xe7\x35\x44\xdb\xd3\x6c\x34\x1c\x1f\x69\x81\x34\ -\xa0\xa2\x43\x15\xce\x0d\xaf\xde\xf2\x9a\x21\xd5\x71\xe0\x5e\x05\ -\xd3\x99\x78\x42\xe2\xdb\xc0\x9b\xd3\x12\x2b\x0c\x1b\x24\x93\x0d\ -\x3b\xde\x81\x26\x62\x30\x6c\x07\x40\xf7\xed\xca\x34\xcd\x81\x5d\ -\xc0\xdd\xea\x2e\x79\xc1\x99\xc8\xa5\xd6\x87\xe3\x4c\x44\xc5\xd0\ -\x2e\xb7\x90\xb1\x0a\xeb\x70\xc1\xe2\x62\x0d\x46\x5d\x09\x1e\xae\ -\xa7\x76\x92\x6b\xb9\xc7\x30\xd2\xf3\x45\x99\xcc\xfc\x6a\xc3\xcc\ -\x9b\xc2\xdb\x55\xc9\xdf\x16\xfb\xe9\x1b\x7e\x8d\x3b\xb7\xac\x2c\ -\x9b\xa4\xf5\x14\x34\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xbc\x50\x4c\x54\ +\x45\xff\xff\xff\xff\xff\xff\xe6\xe6\xe6\xe8\xe8\xe8\xeb\xeb\xeb\ +\xee\xee\xee\xeb\xeb\xeb\xec\xec\xec\xec\xec\xec\xed\xed\xed\xee\ +\xee\xee\xf0\xf0\xeb\xec\xec\xec\xee\xee\xeb\xee\xee\xeb\xee\xee\ +\xeb\xee\xee\xec\xee\xee\xec\xef\xef\xec\xef\xef\xed\xed\xed\xec\ +\xee\xee\xec\xee\xee\xed\xee\xee\xec\xee\xee\xed\xee\xee\xec\xee\ +\xee\xec\xee\xee\xeb\xee\xee\xec\xee\xee\xec\xee\xee\xec\xee\xee\ +\xec\xef\xef\xec\xee\xee\xec\xee\xee\xec\xee\xee\xec\xee\xee\xec\ +\xc4\xa0\x00\xc4\xa0\x01\xc4\xa1\x02\xc4\xa1\x03\xc5\xa1\x04\xc5\ +\xa2\x05\xc5\xa2\x06\xc6\xa3\x09\xc6\xa3\x0a\xc6\xa4\x0b\xc6\xa4\ +\x0c\xc7\xa6\x12\xc8\xa7\x16\xc8\xa8\x18\xc8\xa8\x19\xc9\xa9\x1a\ +\xc9\xa9\x1b\xc9\xa9\x1c\xc9\xa9\x1d\xc9\xaa\x1e\xc9\xaa\x1f\xca\ +\xab\x20\xcb\xac\x25\xcb\xad\x26\xcb\xad\x27\xcb\xad\x28\xcc\xae\ +\x2b\xcc\xaf\x2c\xcc\xaf\x2d\xcc\xb0\x2f\xcd\xb0\x30\xcd\xb0\x31\ +\xcd\xb1\x34\xcd\xb1\x35\xce\xb3\x3a\xcf\xb4\x3b\xcf\xb4\x3d\xcf\ +\xb5\x40\xd0\xb6\x42\xd1\xb8\x48\xd2\xba\x4e\xd2\xba\x4f\xd2\xba\ +\x50\xd2\xbb\x51\xd3\xbb\x52\xd3\xbc\x53\xd3\xbc\x55\xd3\xbc\x56\ +\xd4\xbd\x59\xd4\xbe\x5a\xd4\xbe\x5b\xd5\xbf\x5e\xd5\xc0\x62\xd6\ +\xc2\x67\xd7\xc3\x69\xd7\xc3\x6a\xd8\xc4\x6e\xd8\xc5\x6f\xd8\xc5\ +\x70\xd8\xc5\x71\xd8\xc6\x73\xd9\xc7\x77\xd9\xc8\x78\xdc\xcc\x85\ +\xdc\xcd\x88\xdd\xce\x8a\xdd\xce\x8b\xdd\xce\x8c\xdd\xce\x8d\xde\ +\xcf\x8f\xde\xd0\x90\xde\xd0\x92\xde\xd1\x94\xdf\xd2\x97\xe0\xd4\ +\x9d\xe0\xd5\xa0\xe1\xd6\xa3\xe1\xd6\xa4\xe1\xd6\xa5\xe2\xd8\xaa\ +\xe3\xda\xae\xe3\xda\xb1\xe4\xdc\xb6\xe5\xdd\xb9\xe5\xde\xbc\xe6\ +\xde\xbd\xe6\xdf\xbe\xe6\xdf\xc0\xe6\xe0\xc1\xe7\xe1\xc4\xe7\xe2\ +\xc7\xe8\xe3\xcb\xe8\xe3\xcc\xe8\xe4\xcd\xe9\xe4\xcd\xe9\xe4\xce\ +\xe9\xe5\xcf\xea\xe6\xd4\xea\xe6\xd5\xeb\xe9\xdd\xec\xea\xdf\xec\ +\xea\xe0\xec\xea\xe1\xec\xeb\xe2\xec\xeb\xe3\xed\xec\xe5\xed\xec\ +\xe6\xed\xec\xe7\xed\xed\xe8\xee\xed\xea\xee\xee\xec\x61\x40\x62\ +\x01\x00\x00\x00\x25\x74\x52\x4e\x53\x00\x01\x0a\x0b\x0d\x0f\x27\ +\x28\x29\x2b\x2e\x32\x36\x4b\x4c\x66\x6b\x6c\x6e\x6f\x90\x96\x99\ +\xa2\xa6\xb2\xc0\xc3\xd3\xd4\xd5\xd6\xd9\xf3\xf4\xf8\xf9\x3d\xbf\ +\x37\x4f\x00\x00\x03\x39\x49\x44\x41\x54\x58\xc3\xed\x97\x57\x57\ +\x13\x51\x14\x85\xa5\x28\xa2\x02\xd2\x7b\x49\xe0\x60\x89\x08\xa8\ +\x20\x20\x88\x0d\xb0\x22\xc5\x02\x96\x58\x10\x35\x6a\x40\x05\x05\ +\xa5\x28\x20\x62\xc2\x20\xc6\xef\x0f\xfb\x40\x66\xe6\xce\x4c\x86\ +\xb2\x82\x2e\x1f\xd8\x6f\x93\x75\xf6\x5e\x99\x73\xf6\xb9\x77\xcf\ +\xae\x5d\x3b\xf8\x8f\x91\x90\x9a\x9e\x95\x53\x58\xe2\xf5\x96\x14\ +\xe6\x64\xa5\xef\xdd\x2a\x7d\x77\x76\x05\x16\x94\x67\x26\x6f\x81\ +\xbe\x2f\xcf\x8b\x03\x9e\xdc\xd4\x4d\xd2\x0f\x14\x03\x10\x1a\x0f\ +\xf8\x7b\x3a\xea\xeb\x3b\x7a\xfc\x81\xf1\x30\x00\x45\xfb\x37\xc3\ +\x3f\x58\x05\x30\x3d\x50\x23\x0a\x6a\x07\x67\x01\x2a\x33\x36\xa4\ +\x27\x15\x00\xab\x23\x9d\xe2\x40\xd7\x68\x04\xc8\x4f\x5c\x9f\x9f\ +\x52\x06\x4c\x36\x4a\x4c\xb4\x4c\x01\xa5\x7b\xd6\xe3\xa7\x79\x80\ +\x61\x9f\xb8\xc0\x17\x00\x3c\x69\xee\xfc\x3d\x1e\xd0\x7a\x65\x1d\ +\xf4\x6b\xe0\x71\xfd\x0f\x89\xa5\x30\xd7\x2a\xeb\xa2\x6d\x0e\x4a\ +\xdd\xfa\x90\x0f\x5a\x9b\x6c\x80\x36\x0d\xf2\x63\xf3\x33\x80\x7e\ +\x5b\xf9\xd1\xb3\x17\x4e\x1e\xb5\xbd\x05\x10\x73\x9a\xfb\x2b\x21\ +\xa0\x56\x9e\x7c\xfa\xf6\x4b\x04\x88\x7c\x7c\xa0\x8f\xe5\x90\x88\ +\x48\x00\x2a\x63\x39\xaa\x08\xa6\x94\xfe\xd7\x3c\x5d\x31\x6d\xfc\ +\xeb\xf9\x09\x11\x69\x9a\x99\x3f\x2e\x22\xbe\x29\x28\x72\xf2\x53\ +\x21\xd2\x62\xf2\xef\x2c\x59\x37\x61\xf9\xa6\x34\x2d\x42\x97\x88\ +\x48\x4b\x04\x9c\x7b\x91\x0b\xa3\x26\xff\x89\x73\x99\x5e\x2c\x02\ +\x97\x45\x44\x64\x14\x72\xed\xfc\x64\x4f\x54\x5e\x44\x44\x6e\x47\ +\x49\x0b\xef\x9f\xbd\x9c\x08\x2b\x2a\x6b\x25\x5d\xe0\xb1\x6f\x77\ +\x26\xcc\x1a\xfc\x6b\x11\x00\xde\x5d\x11\x11\x91\xea\xf3\x13\x86\ +\xc0\xda\x3f\x90\x59\xc8\xb4\x09\x94\xc3\xa0\xce\x3f\xb5\x0c\x10\ +\xea\x33\x04\xab\x07\x43\x56\x81\x41\x28\xb7\xf2\xf7\x42\xb8\x56\ +\xaf\x1f\x02\xd0\xda\x95\x89\x36\x2d\x5a\x05\x6a\xc3\x60\x3d\xe5\ +\xd2\x61\x5c\xaf\x3e\xb2\x04\xd0\x1d\x8b\xaf\x0b\xc8\x38\xa4\x5b\ +\x04\xb2\x14\x13\xdd\x00\x18\x53\xf8\x75\x8b\xf6\x1e\x48\x00\xb2\ +\x2c\x02\x39\xe0\xd7\xeb\x3f\x98\xed\x5e\x43\xb7\x39\x05\xfd\xbd\ +\xfc\x90\x63\x11\x28\x84\x1e\xbd\xfe\x51\x30\x18\xf4\xab\x9e\xae\ +\x19\x0a\x46\x71\x4f\xff\xa9\x07\x0a\x2d\x02\x25\xd0\x21\x5b\x40\ +\x07\x94\x58\x04\xbc\x50\xbf\x15\x81\x7a\xf0\x6e\xaf\x40\xdc\xaf\ +\xa0\x36\xf1\x9e\xde\xb2\x21\xcb\xd5\xe0\x0f\x06\x83\xb7\x5d\x9b\ +\xa8\x8c\xb1\xdd\x1c\x9a\x6a\xa6\x2e\x80\xd7\xe2\x36\x46\xc5\x48\ +\x97\x0d\xfe\xb7\x3a\x45\x60\x0c\xe0\xa2\xb8\x19\x49\xb1\xb2\x21\ +\x30\xdf\x68\x37\xd3\x27\xe3\xd1\x61\xe5\x54\x08\xd5\x58\x05\xe6\ +\x1b\x14\x7e\xbb\x06\x70\xd7\xb0\x56\xc8\x7e\x26\x25\x54\xc0\x80\ +\x55\x40\x7b\x70\xd8\xe0\xf7\x85\x00\xbe\x1f\xd3\x9f\x07\xa0\x22\ +\xc1\xba\xcf\xd9\x30\x6d\xef\xc1\xe7\xce\x35\x89\x2b\xef\x00\x08\ +\x9f\x33\x04\xa7\x21\xdb\x1e\x49\xbc\xd0\x69\x13\x80\x95\xc9\xc0\ +\xb3\xf7\x0b\xd1\x93\xf9\xaa\xc1\xef\x04\xef\x6e\xfb\xa1\x98\x07\ +\x23\x86\xc0\xdc\x2b\xe7\xa1\x7a\xcb\xec\xc8\x08\xe4\x39\x63\x0d\ +\xac\x36\x46\x07\xbe\xd0\x20\x77\x7e\x5a\xe9\x5f\xaf\x9b\xfc\xc6\ +\x55\xd8\xe7\xbc\x18\x8a\x61\xd2\x27\x22\xc7\xe7\x67\x4e\x8b\x48\ +\xf3\x9b\x88\x49\xff\x71\x5f\xb9\xdf\x7c\x93\x50\x1c\x2b\x1a\x55\ +\xc1\xb0\x71\x7f\x89\x48\xf3\xc3\x89\xdf\xc0\xea\xec\xe8\x63\xd5\ +\x51\x32\x0c\x55\x07\x62\x86\x23\xc0\x16\x0e\x7c\x0d\x97\xce\x1c\ +\xb1\xed\x51\x2f\x70\x30\xf6\xf5\x5c\x00\x5a\xeb\x46\x7b\xd8\xaa\ +\x41\x81\x5b\xc0\x2a\xdb\x5c\xc0\x28\x4b\x72\x8d\x58\x9b\x8b\x38\ +\x29\x7f\x2f\x64\xc5\x1f\xf3\xe2\x0f\x9a\xf1\x47\xdd\x6d\x08\xdb\ +\xf1\xc7\xfd\x6d\xf8\xe0\xd8\x86\x4f\x9e\x1d\xfc\x53\xfc\x01\x5c\ +\xc5\x73\xb4\x20\x2f\x6e\x7b\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ +\x42\x60\x82\ +\x00\x00\x04\xb2\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\ +\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\x1b\xaf\x01\ +\x5e\x1a\x91\x1c\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x3e\x50\x4c\x54\ +\x45\xff\xff\xff\xff\xff\xff\xe6\xe6\xe6\xe8\xe8\xe8\xeb\xeb\xeb\ +\xee\xee\xee\xeb\xeb\xeb\xec\xec\xec\xec\xec\xec\xed\xed\xed\xee\ +\xee\xee\xf0\xf0\xeb\xec\xec\xec\xee\xee\xeb\xee\xee\xeb\xee\xee\ +\xeb\xee\xee\xec\xee\xee\xec\xef\xef\xec\xef\xef\xed\xed\xed\xec\ +\xee\xee\xec\xee\xee\xed\xee\xee\xec\xee\xee\xed\xee\xee\xec\xee\ +\xee\xec\xee\xee\xeb\xee\xee\xec\xee\xee\xec\xee\xee\xec\xee\xee\ +\xec\xef\xef\xec\xee\xee\xec\xee\xee\xec\xee\xee\xec\xee\xee\xec\ +\xa4\x00\x00\xa4\x01\x01\xa6\x06\x06\xa6\x07\x06\xa6\x07\x07\xa7\ +\x08\x08\xa7\x0a\x0a\xa8\x0c\x0c\xa8\x0e\x0e\xab\x15\x15\xab\x16\ +\x16\xac\x19\x19\xac\x1a\x1a\xac\x1b\x1b\xad\x1c\x1c\xae\x21\x20\ +\xae\x22\x21\xb0\x26\x26\xb0\x27\x27\xb4\x34\x34\xb5\x35\x35\xb5\ +\x38\x38\xb6\x3b\x3a\xb7\x3c\x3b\xb7\x3e\x3d\xba\x48\x47\xbc\x4d\ +\x4d\xbc\x4e\x4e\xbe\x52\x51\xbe\x53\x52\xbf\x56\x55\xc2\x5f\x5e\ +\xc3\x63\x62\xc7\x6f\x6e\xc7\x70\x6f\xcd\x85\x84\xce\x86\x85\xcf\ +\x89\x88\xd0\x8c\x8b\xd0\x8e\x8d\xd2\x92\x91\xd3\x98\x97\xd5\x9f\ +\x9d\xd7\xa5\xa4\xd9\xac\xaa\xde\xba\xb8\xde\xbb\xb9\xde\xbb\xba\ +\xdf\xbf\xbe\xe0\xc1\xc0\xe2\xc6\xc4\xe3\xc9\xc8\xe3\xca\xc8\xe4\ +\xcd\xcc\xe6\xd6\xd4\xe7\xd9\xd7\xea\xe0\xdf\xea\xe1\xdf\xea\xe2\ +\xe0\xeb\xe3\xe1\xeb\xe4\xe2\xeb\xe6\xe4\xeb\xe7\xe5\xec\xe7\xe6\ +\xed\xea\xe8\xed\xeb\xe9\xed\xec\xea\xee\xed\xeb\xee\xee\xec\xf8\ +\x79\xd4\x99\x00\x00\x00\x25\x74\x52\x4e\x53\x00\x01\x0a\x0b\x0d\ +\x0f\x27\x28\x29\x2b\x2e\x32\x36\x4b\x4c\x66\x6b\x6c\x6e\x6f\x90\ +\x96\x99\xa2\xa6\xb2\xc0\xc3\xd3\xd4\xd5\xd6\xd9\xf3\xf4\xf8\xf9\ +\x3d\xbf\x37\x4f\x00\x00\x02\xb5\x49\x44\x41\x54\x58\xc3\xed\x97\ +\xe9\x57\x12\x61\x14\x87\xdd\x15\x17\x54\xc4\x05\xc5\x05\xf4\xa2\ +\x25\x46\xa4\x29\x66\x1b\x2e\x51\x42\x1a\x91\x5a\x54\x1a\xa5\x35\ +\xcf\xff\xff\x0f\xf4\xc1\x41\xe6\x5d\x06\xf0\x60\x9d\x3e\x74\xbf\ +\xb0\x9c\x79\x9e\x33\x33\xef\xbd\xf3\xfe\xa6\xad\xed\x7f\xfd\xc3\ +\xd5\x1e\x08\x86\xc2\x91\x68\x3c\x1e\x8d\x84\x43\xc1\xbe\xdb\xe2\ +\xdd\x63\x0b\x28\x35\x3f\xda\x75\x0b\xbc\x7f\x22\x8e\x51\xb1\xf1\ +\x40\x93\xf8\xe0\x0c\x00\xe7\xc5\x42\x2e\x9b\x49\xa5\x32\xd9\x5c\ +\xa1\x78\x01\xc0\xf4\x40\x33\xfc\xc8\x12\xc0\xe9\xfe\xaa\x78\x2a\ +\x79\x70\x06\xb0\x38\xdc\x10\xef\x9c\x02\x2e\x8f\xb6\xc5\xa8\x9d\ +\xe3\x2b\x60\xb2\xa3\x3e\xdf\x3b\x07\x94\xd6\xc5\x5a\x1b\x27\xc0\ +\x6c\x4f\x3d\x7e\x28\x06\x1c\x2e\x8b\x4f\xad\x14\x80\xd8\x90\x3f\ +\xdf\x13\x83\xca\xae\xd4\xa9\xbd\x0a\xc4\x7c\xcf\xa1\x63\x16\xca\ +\x9b\x52\xb7\xb6\xca\x30\xeb\x77\x1f\x26\xa1\xb2\x25\x0d\x6a\xab\ +\x02\x93\x76\x7e\x18\xd8\x93\x86\xb5\x07\x58\x57\x73\x60\x11\x0a\ +\xd5\xa3\x5e\x3c\xd5\xb9\x87\xaf\xaa\xdf\x0a\xb0\x68\xeb\xa8\x69\ +\x38\x59\x71\x8f\x79\xf9\xf3\xfb\x33\x95\x4f\x97\x79\x5d\x5d\x8b\ +\x13\x98\x36\xf9\x00\x5c\x6d\xdc\xf0\x8e\xa3\x1a\xd2\x65\xb8\x31\ +\x6c\x5c\x81\x39\x17\xe3\x70\x5c\xe3\x41\x31\xa4\xcb\x80\x73\x63\ +\x38\x86\x71\x9d\xef\x8a\xc1\x8e\x87\x57\x0c\xe9\x32\x78\x0d\x3b\ +\x10\xd3\xa7\x7b\x14\xce\xdc\xc3\xdf\xe0\xa0\x18\x5c\x1e\x78\x7f\ +\xef\xfa\x9f\x33\x18\xd5\x04\xf3\x70\xe0\x0a\x12\x79\xd5\x50\xe3\ +\x4b\x6b\xee\x21\x07\x30\xaf\xf2\x7d\x70\x91\x14\xab\xc1\xc2\x4b\ +\xf2\x02\xd4\xa7\x5c\x10\x8a\xb5\x7b\xe6\x35\xd8\x78\x91\x22\x04\ +\x15\x41\xc8\xd3\x44\x8a\xe1\xc7\x67\x1b\x2f\x05\x08\x29\x82\x30\ +\xe4\xc4\x66\xc0\xca\x4b\x0e\xc2\x8a\x20\x02\x59\xa9\x67\x50\x79\ +\xc9\x42\x44\x11\x44\x21\x23\x75\x0c\x1a\x2f\x19\x88\x2a\x82\x38\ +\xa4\xc4\x30\xf8\xf2\x92\x82\x78\x23\x81\x3c\xfa\x5a\xe5\x7f\x3d\ +\x97\x46\x02\xf3\x12\x3c\xeb\x8f\xa3\xcf\xa6\x79\x09\xc6\x4d\xf4\ +\xf2\x16\x83\x71\x13\xf5\x65\x54\x79\xd3\x60\x2c\xa3\xd6\x48\xca\ +\xf9\xdb\x0c\x46\x23\xa9\xad\xec\xe1\x3f\xbc\xb5\x1a\x8c\x56\x0e\ +\xc0\xf9\xaa\x85\x2f\xad\xe9\xb3\x29\x22\x22\xab\xe7\xfa\x33\xa9\ +\x7d\x01\xf6\x6d\xbc\x39\xdd\x22\x22\xfb\xb0\xd0\xae\xce\xf3\x18\ +\x9c\x5a\x79\xab\xe1\x14\xc6\xf4\x48\x12\x07\x77\x4b\x7e\xa7\xf7\ +\x5f\xad\xab\xbf\xdc\x17\x11\x91\x6d\x88\x77\xeb\x0f\xc5\x09\x38\ +\x72\xbb\xec\x93\xde\xbf\xae\xc1\xa9\x3c\xb9\xfe\x7d\x04\x13\x66\ +\xac\x81\xcb\x75\xaf\xc1\xdb\xff\x89\x3c\x4e\x8d\x5f\xbf\x84\x7e\ +\x73\x63\x98\x81\xd2\x72\xcd\xa0\xce\x4f\x22\x0f\x55\x7e\xb9\x04\ +\x33\xb6\x68\xb4\x04\x87\xd5\x59\xf9\xa8\xcf\x5f\x22\xff\xcd\xe5\ +\xe5\x10\x96\x06\xad\xe1\x08\xa8\x86\x83\x07\x49\x63\x53\x7d\xec\ +\x7e\xee\x02\x23\xf6\xed\x79\x0a\x2a\x9b\x8d\x36\xe7\xcd\x0a\x4c\ +\xf9\x05\xac\xb9\xe6\x02\xc6\x5c\xa7\x6f\xc4\x6a\x2e\xe2\xf4\xfe\ +\xb9\x90\xd5\x7a\xcc\x6b\x3d\x68\xb6\x1e\x75\xef\x20\x6c\xb7\x1e\ +\xf7\xef\xe0\x85\xe3\x0e\x5e\x79\xfe\xd7\x5f\xad\xdf\x83\x03\xfd\ +\x37\x6b\x76\x57\xd2\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ \x82\ +\x00\x00\x05\x06\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\ +\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\x1b\xaf\x01\ +\x5e\x1a\x91\x1c\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\x86\x50\x4c\x54\ +\x45\xff\xff\xff\xff\xff\xff\xe6\xe6\xe6\xe8\xe8\xe8\xeb\xeb\xeb\ +\xee\xee\xee\xeb\xeb\xeb\xec\xec\xec\xec\xec\xec\xed\xed\xed\xee\ +\xee\xee\xf0\xf0\xeb\xec\xec\xec\xee\xee\xeb\xee\xee\xeb\xee\xee\ +\xeb\xee\xee\xec\xee\xee\xec\xef\xef\xec\xef\xef\xed\xed\xed\xec\ +\xee\xee\xec\xee\xee\xed\xee\xee\xec\xee\xee\xed\xee\xee\xec\xee\ +\xee\xec\xee\xee\xeb\xee\xee\xec\xee\xee\xec\xee\xee\xec\xee\xee\ +\xec\xef\xef\xec\xee\xee\xec\xee\xee\xec\xee\xee\xec\xee\xee\xec\ +\x4e\x9a\x06\x4f\x9a\x07\x4f\x9b\x08\x50\x9b\x09\x51\x9b\x0a\x51\ +\x9c\x0b\x52\x9c\x0b\x52\x9c\x0c\x53\x9d\x0d\x54\x9d\x0e\x54\x9d\ +\x0f\x55\x9e\x10\x56\x9e\x12\x5d\xa2\x1c\x61\xa4\x21\x64\xa6\x26\ +\x68\xa8\x2b\x68\xa8\x2c\x6a\xa9\x2f\x6b\xa9\x2f\x6b\xa9\x30\x6c\ +\xaa\x31\x6c\xaa\x32\x71\xac\x39\x72\xad\x39\x76\xaf\x3f\x76\xaf\ +\x40\x77\xaf\x41\x7b\xb2\x46\x84\xb6\x54\x85\xb7\x55\x86\xb7\x56\ +\x88\xb8\x59\x89\xb9\x5b\x8a\xba\x5d\x8b\xba\x5d\x8d\xbb\x60\x8e\ +\xbc\x62\x8f\xbc\x63\x91\xbd\x66\x91\xbd\x67\x92\xbe\x68\x94\xbf\ +\x6b\x96\xc0\x6d\x96\xc0\x6e\x97\xc0\x6f\x98\xc1\x70\x99\xc2\x72\ +\x9b\xc2\x74\x9c\xc3\x77\x9e\xc4\x79\xa1\xc5\x7d\xaa\xca\x8b\xad\ +\xcc\x8f\xaf\xcd\x91\xb1\xce\x94\xb3\xcf\x97\xb4\xd0\x99\xb5\xd0\ +\x9a\xb7\xd1\x9d\xb9\xd2\x9f\xbb\xd3\xa3\xbd\xd4\xa6\xbf\xd5\xa8\ +\xc0\xd6\xaa\xc1\xd7\xac\xc2\xd7\xad\xc4\xd8\xb0\xc6\xd9\xb2\xcb\ +\xdc\xba\xcf\xde\xbf\xd0\xde\xc1\xd3\xe0\xc5\xd5\xe1\xc8\xd7\xe2\ +\xca\xd8\xe2\xcc\xdb\xe4\xd0\xe1\xe7\xda\xe2\xe8\xdb\xe3\xe8\xdc\ +\xe5\xe9\xdf\xe6\xea\xe0\xe7\xea\xe2\xe7\xeb\xe2\xe8\xeb\xe3\xea\ +\xec\xe6\xea\xec\xe7\xeb\xed\xe8\xec\xed\xea\xed\xed\xea\xed\xed\ +\xeb\xed\xee\xeb\xee\xee\xec\x80\x9c\xa9\xb6\x00\x00\x00\x25\x74\ +\x52\x4e\x53\x00\x01\x0a\x0b\x0d\x0f\x27\x28\x29\x2b\x2e\x32\x36\ +\x4b\x4c\x66\x6b\x6c\x6e\x6f\x90\x96\x99\xa2\xa6\xb2\xc0\xc3\xd3\ +\xd4\xd5\xd6\xd9\xf3\xf4\xf8\xf9\x3d\xbf\x37\x4f\x00\x00\x02\xc1\ +\x49\x44\x41\x54\x58\xc3\xed\x97\x59\x57\xd3\x50\x14\x85\x99\xa1\ +\x0c\x05\x4a\x19\x0a\x65\x48\xe0\x2a\x48\x55\x28\x83\x82\xa5\x0e\ +\x05\x07\x44\x9c\xea\x40\x55\xb0\x0e\x55\x19\x14\x45\x88\x54\x54\ +\xbe\x7f\xee\x83\x4d\x9a\x9b\xa9\x65\x15\x5d\x3e\xb0\x9f\xba\x92\ +\x7c\x7b\x25\xf7\x9e\x73\xcf\x6e\x59\xd9\x89\xfe\x63\x95\xfb\xfc\ +\x81\x60\x28\xac\xaa\xe1\x50\x30\xe0\xaf\x3b\x2a\x5e\xdd\x36\x80\ +\xa4\xfe\xd6\xaa\x23\xe0\xf5\x1d\x2a\x36\x29\xed\xbe\x22\xf1\xc6\ +\x1e\x00\x76\x33\xa9\x64\x22\x16\x8d\xc6\x12\xc9\x54\x66\x0f\x80\ +\xee\x86\x62\xf8\x96\x21\x80\xcd\xc5\x31\x61\xd2\xf8\xd2\x16\xc0\ +\x60\x73\x41\xbc\xb2\x0b\xc8\xae\xce\x09\x9b\xe2\xe9\x03\xa0\xb3\ +\xc2\x9b\xaf\xed\x03\xd6\x27\x84\xa3\x26\x37\x80\xde\x1a\x2f\xbe\ +\x49\x01\x56\x46\x85\x8b\x22\x29\x40\x69\x72\xe7\x6b\x14\xd0\xe6\ +\x85\x87\x16\x34\x50\x5c\xdf\xa1\xa2\x17\xb6\xa7\x84\xa7\xa6\xb7\ +\xa1\xd7\x6d\x1d\x3a\x41\x9b\x16\x05\x34\xad\x41\xa7\x33\xdf\x0c\ +\x2c\x88\x82\x5a\x00\x1c\x77\xb3\x61\x10\x52\xa2\x08\xa5\x60\xd0\ +\xa9\xa2\xba\x61\x23\x52\x8c\x41\x64\x03\xba\xed\xbc\x0f\x0e\x26\ +\xbd\xb8\x53\x37\x86\xf5\x7a\x38\x00\x7b\x5f\xb4\x43\xda\x93\x7f\ +\xc6\x9a\xee\x90\x86\x76\x2b\x5f\xa5\x40\xdc\x83\x3f\xfd\x1c\x0c\ +\x87\x38\x28\xd6\xee\x6e\x85\x2d\x2f\xfe\x05\x98\x1c\xb6\xa0\xd5\ +\x62\xd0\x0f\x4b\xee\xfc\xf0\x5a\xee\x50\xc8\x39\x2c\x41\xbf\xcc\ +\xd7\xc1\xde\xb8\x2b\x3f\xf2\xd2\x38\x56\xae\xfd\xe9\xee\x3d\x90\ +\x4f\x39\x3f\x64\xdc\xf9\xb4\xc1\x3f\xcd\x5d\xca\x80\x5f\x32\x08\ +\x58\x8a\xc8\xdc\x90\x67\x5e\x19\xfc\x13\x53\x31\x05\x24\x83\x20\ +\x24\x4d\xcc\x85\xcf\x57\xf2\x5e\xaf\x0d\xfe\xb1\x71\x31\x09\x41\ +\xc9\x20\x04\x89\x3c\x7f\xf1\x0b\xfb\xba\x43\xe4\x8d\xc1\x3f\xca\ +\x3f\x91\x80\x90\x64\x10\x86\x98\x71\x77\x66\x07\xd8\xbf\x2c\x84\ +\x10\xe2\xec\x5b\x83\x7f\x68\x7a\xc5\x18\x84\x25\x03\x15\xa2\xfa\ +\xcd\xd9\x1d\xd0\x1d\xce\xbd\x33\xf8\xfb\xe6\x35\x8a\x82\xea\x66\ +\x30\xf3\x35\x47\x68\x71\x71\xfe\xbd\xc1\xdf\x15\x9e\x06\xa6\x4f\ +\x88\x7e\xd4\x19\xed\xea\x07\x83\x5f\x96\x77\xd6\xf6\x09\xe6\x45\ +\xcc\x3b\xfc\xd0\x7f\x1c\x5a\xab\xd4\xb6\x88\xd2\x36\xe6\x1d\x74\ +\xfe\xb6\xb5\xb6\x6c\xdb\x28\x17\x92\xc5\xe1\xf0\x96\xd3\xa9\x14\ +\xf0\x2a\x65\xc9\xe1\xe7\x4d\x7b\x75\xdb\x4a\xd9\x07\xbb\xe6\x61\ +\x18\xfd\x64\xf0\xbf\xae\xdb\xf9\xb1\x5d\xeb\x99\x54\x3e\x00\x8b\ +\xe6\x47\x66\xb2\xba\xc1\x03\x87\xf6\x5a\x84\x81\x72\xb9\x9f\xdb\ +\x60\x53\x38\x39\xdc\x73\xea\xcf\x4d\x68\xb3\x46\x12\x15\xe4\x91\ +\x3c\xfb\xdd\x5e\x3f\x39\xcd\x81\x5a\x6d\x3d\x14\x3b\x60\x55\xd8\ +\x1c\x96\x1d\x0f\x88\x55\xe8\xb0\xc7\x1a\xc8\x5a\xc6\xfa\xa5\x6f\ +\x77\x1c\xf9\x89\x2c\xd4\xdb\x07\x43\x0f\xac\x5b\x06\xfb\x88\x23\ +\x3f\xba\x0e\x3d\x4e\xd1\x68\x08\x56\x8a\x99\x4c\x2b\x30\xd4\xe8\ +\x18\x8e\x80\xf9\xc2\xfc\x3c\xd0\xe2\x3c\x9e\xbb\x40\x9b\x2a\xc4\ +\x4f\x69\xd0\xe5\x16\xb0\xfa\x8a\x0b\x18\x7d\x95\xae\x11\xab\xb8\ +\x88\x53\xfb\xf7\x42\x56\xe9\x31\xaf\xf4\xa0\x59\x7a\xd4\x3d\x86\ +\xb0\x5d\x7a\xdc\x3f\x86\x3f\x1c\xc7\xf0\x97\xe7\x44\xff\x54\xbf\ +\x01\xf3\x14\x0e\xc4\x9f\xdc\x12\xd6\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ \x00\x00\x02\x54\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -797,6 +1014,42 @@ qt_resource_data = b"\ \x1f\xef\xf7\xbf\x55\x35\xfa\x4d\xec\x4f\x6f\xf8\x6b\xde\x01\xaf\ \xf7\x2b\x36\xc0\x31\x0e\x49\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ \x42\x60\x82\ +\x00\x00\x02\x1e\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x16\x00\x00\x00\x16\x08\x03\x00\x00\x00\xf3\x6a\x9c\x09\ +\x00\x00\x00\x03\x73\x42\x49\x54\x08\x08\x08\xdb\xe1\x4f\xe0\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x09\x84\x00\x00\x09\x84\x01\ +\xaa\xe2\x63\x79\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ +\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xa8\x50\x4c\x54\ +\x45\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x07\x05\x05\x09\x05\x05\x0c\x07\x07\x0c\ +\x07\x07\x10\x09\x09\x0a\x05\x05\x0b\x06\x06\x0b\x06\x06\x63\x35\ +\x35\x6d\x39\x39\x00\x00\x00\x09\x05\x05\x0f\x08\x08\x1c\x0f\x0f\ +\x26\x14\x14\x28\x15\x15\x29\x16\x16\x2a\x17\x17\x32\x1b\x1b\x34\ +\x1c\x1c\x35\x1c\x1c\x37\x1d\x1d\x38\x1e\x1e\x45\x25\x25\x49\x27\ +\x27\x4a\x28\x28\x4c\x29\x29\x4e\x2a\x2a\x57\x2e\x2e\x59\x30\x30\ +\x5b\x31\x31\x9c\x53\x53\xad\x5c\x5c\xba\x63\x63\xc1\x67\x67\xcc\ +\x6d\x6d\xd0\x6f\x6f\xda\x74\x74\xdc\x75\x75\xdd\x76\x76\xe3\x79\ +\x79\xe4\x79\x79\xe5\x7a\x7a\xe8\x7c\x7c\xea\x7d\x7d\xeb\x7d\x7d\ +\xec\x7e\x7e\xee\x7f\x7f\xf0\x80\x80\x03\x52\x4f\x0b\x00\x00\x00\ +\x11\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\x32\x96\x96\xb9\xbc\ +\xcf\xeb\xec\xf7\xf9\xf9\xc2\x20\x9f\x21\x00\x00\x00\xcb\x49\x44\ +\x41\x54\x18\xd3\x9d\x91\xd9\x0e\x82\x30\x14\x44\xd9\x64\x5f\x5a\ +\x57\xdc\x15\x05\x64\x13\x45\xe0\xfe\xff\x9f\xd9\x96\x20\x90\x68\ +\x34\xce\xe3\x49\x33\x33\x77\xca\x71\xff\x48\x52\x0d\xcb\x32\x14\ +\x71\x00\x05\xdd\x46\x61\x1c\x87\xc8\xd6\xf8\x8e\xca\xa6\x53\x00\ +\x53\xe1\x98\xa3\x96\xf2\x66\x00\x2f\x05\x66\xfb\x5e\x73\x00\xae\ +\x15\x65\x75\x0a\xe0\x68\x0d\x15\xed\x02\xd2\x99\x47\x78\xed\x4f\ +\x13\x28\xec\x26\x57\x41\x00\xf7\x2d\xf6\xaa\xda\xc7\x6e\x06\x80\ +\x14\x86\x8d\x10\x18\x3f\x9e\x19\x85\xd0\x60\xd8\x8a\xa9\xed\x6d\ +\x83\xf1\x82\x52\x88\xad\x1e\xae\x4f\x18\xef\xca\x1e\x66\x26\xc4\ +\x77\xbe\xc4\x87\xb2\x33\x51\x11\xa3\x6e\x96\xaf\xf1\xfe\x41\x22\ +\xd5\x66\x0e\x52\x30\x99\xd0\xb4\x7c\x35\x8e\x48\x41\xa9\x29\xae\ +\x93\x73\x22\x96\x96\x5f\xc8\x39\x7a\x3b\xd4\xf0\x78\xe1\xed\x54\ +\xf2\xb7\x61\x3f\x7d\xc3\xaf\x7a\x02\x53\x94\x25\xad\x31\xc4\x63\ +\xa2\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ \x00\x00\x02\x07\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ @@ -832,7 +1085,7 @@ qt_resource_data = b"\ \xaa\xe3\xa9\xa1\x9a\xe5\x8d\xb7\x53\xd9\xdf\x86\xfd\xf4\x0d\xbf\ \xea\x01\xa1\xe2\x24\xfb\x2f\x53\xd6\x72\x00\x00\x00\x00\x49\x45\ \x4e\x44\xae\x42\x60\x82\ -\x00\x00\x02\x1e\ +\x00\x00\x02\x32\ \x89\ \x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ \x00\x00\x16\x00\x00\x00\x16\x08\x03\x00\x00\x00\xf3\x6a\x9c\x09\ @@ -840,34 +1093,36 @@ qt_resource_data = b"\ \x00\x00\x09\x70\x48\x59\x73\x00\x00\x09\x84\x00\x00\x09\x84\x01\ \xaa\xe2\x63\x79\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\ \x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\ -\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xa8\x50\x4c\x54\ +\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x00\xbd\x50\x4c\x54\ \x45\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ -\x00\x00\x00\x00\x00\x00\x07\x05\x05\x09\x05\x05\x0c\x07\x07\x0c\ -\x07\x07\x10\x09\x09\x0a\x05\x05\x0b\x06\x06\x0b\x06\x06\x63\x35\ -\x35\x6d\x39\x39\x00\x00\x00\x09\x05\x05\x0f\x08\x08\x1c\x0f\x0f\ -\x26\x14\x14\x28\x15\x15\x29\x16\x16\x2a\x17\x17\x32\x1b\x1b\x34\ -\x1c\x1c\x35\x1c\x1c\x37\x1d\x1d\x38\x1e\x1e\x45\x25\x25\x49\x27\ -\x27\x4a\x28\x28\x4c\x29\x29\x4e\x2a\x2a\x57\x2e\x2e\x59\x30\x30\ -\x5b\x31\x31\x9c\x53\x53\xad\x5c\x5c\xba\x63\x63\xc1\x67\x67\xcc\ -\x6d\x6d\xd0\x6f\x6f\xda\x74\x74\xdc\x75\x75\xdd\x76\x76\xe3\x79\ -\x79\xe4\x79\x79\xe5\x7a\x7a\xe8\x7c\x7c\xea\x7d\x7d\xeb\x7d\x7d\ -\xec\x7e\x7e\xee\x7f\x7f\xf0\x80\x80\x03\x52\x4f\x0b\x00\x00\x00\ -\x11\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\x32\x96\x96\xb9\xbc\ -\xcf\xeb\xec\xf7\xf9\xf9\xc2\x20\x9f\x21\x00\x00\x00\xcb\x49\x44\ -\x41\x54\x18\xd3\x9d\x91\xd9\x0e\x82\x30\x14\x44\xd9\x64\x5f\x5a\ -\x57\xdc\x15\x05\x64\x13\x45\xe0\xfe\xff\x9f\xd9\x96\x20\x90\x68\ -\x34\xce\xe3\x49\x33\x33\x77\xca\x71\xff\x48\x52\x0d\xcb\x32\x14\ -\x71\x00\x05\xdd\x46\x61\x1c\x87\xc8\xd6\xf8\x8e\xca\xa6\x53\x00\ -\x53\xe1\x98\xa3\x96\xf2\x66\x00\x2f\x05\x66\xfb\x5e\x73\x00\xae\ -\x15\x65\x75\x0a\xe0\x68\x0d\x15\xed\x02\xd2\x99\x47\x78\xed\x4f\ -\x13\x28\xec\x26\x57\x41\x00\xf7\x2d\xf6\xaa\xda\xc7\x6e\x06\x80\ -\x14\x86\x8d\x10\x18\x3f\x9e\x19\x85\xd0\x60\xd8\x8a\xa9\xed\x6d\ -\x83\xf1\x82\x52\x88\xad\x1e\xae\x4f\x18\xef\xca\x1e\x66\x26\xc4\ -\x77\xbe\xc4\x87\xb2\x33\x51\x11\xa3\x6e\x96\xaf\xf1\xfe\x41\x22\ -\xd5\x66\x0e\x52\x30\x99\xd0\xb4\x7c\x35\x8e\x48\x41\xa9\x29\xae\ -\x93\x73\x22\x96\x96\x5f\xc8\x39\x7a\x3b\xd4\xf0\x78\xe1\xed\x54\ -\xf2\xb7\x61\x3f\x7d\xc3\xaf\x7a\x02\x53\x94\x25\xad\x31\xc4\x63\ -\xa2\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x00\x00\x00\x00\x07\x07\x05\x09\x09\x05\x0c\x0c\x07\x0c\ +\x0b\x07\x10\x0f\x0a\x0a\x09\x05\x0a\x0a\x05\x0b\x0b\x06\x0b\x0a\ +\x06\x0b\x0b\x06\x63\x5f\x3a\x6d\x67\x3f\x00\x00\x00\x02\x02\x01\ +\x03\x03\x02\x04\x04\x02\x05\x05\x03\x08\x08\x05\x0e\x0e\x08\x10\ +\x0f\x09\x11\x10\x0a\x14\x13\x0c\x17\x16\x0d\x1a\x19\x0f\x1f\x1e\ +\x12\x25\x23\x15\x35\x33\x1f\x4c\x49\x2c\x56\x52\x32\x6d\x69\x40\ +\x83\x7d\x4c\x88\x83\x50\x90\x8a\x54\x9a\x94\x5a\x9c\x96\x5b\x9f\ +\x98\x5d\xa0\x99\x5d\xa2\x9b\x5e\xad\xa6\x65\xaf\xa8\x66\xb2\xaa\ +\x68\xb4\xac\x69\xb6\xae\x6a\xbb\xb3\x6d\xbf\xb7\x6f\xcc\xc4\x77\ +\xcd\xc5\x78\xd7\xce\x7d\xdf\xd6\x82\xe1\xd8\x83\xe8\xdf\x88\xeb\ +\xe1\x89\xec\xe2\x8a\xed\xe3\x8a\xee\xe4\x8b\xf0\xe6\x8c\xb3\x23\ +\xf4\xd9\x00\x00\x00\x13\x74\x52\x4e\x53\x00\x13\x14\x2a\x2c\x31\ +\x32\x96\x96\xb9\xbc\xcf\xeb\xeb\xec\xf7\xf7\xf9\xf9\x4c\x9d\x97\ +\xb7\x00\x00\x00\xc8\x49\x44\x41\x54\x18\xd3\x9d\x91\x67\x13\x82\ +\x30\x0c\x86\x59\xb2\x57\x8b\x7b\x6f\x45\xad\x13\x51\x14\xf9\xff\ +\x3f\xcb\xd2\x80\xca\x9d\x9e\x9e\xf9\x92\xe4\x69\xee\x6d\xdf\x94\ +\xe3\xfe\x09\x49\x35\x6c\xdb\x50\xc4\x02\x14\x74\x17\x93\x20\x20\ +\xd8\xd1\xf8\x27\x95\x4d\x14\x25\x2c\x22\x64\x95\x72\xca\x5b\x7e\ +\xf2\x08\xdf\xca\xe7\x35\x44\xdb\xd3\x6c\x34\x1c\x1f\x69\x81\x34\ +\xa0\xa2\x43\x15\xce\x0d\xaf\xde\xf2\x9a\x21\xd5\x71\xe0\x5e\x05\ +\xd3\x99\x78\x42\xe2\xdb\xc0\x9b\xd3\x12\x2b\x0c\x1b\x24\x93\x0d\ +\x3b\xde\x81\x26\x62\x30\x6c\x07\x40\xf7\xed\xca\x34\xcd\x81\x5d\ +\xc0\xdd\xea\x2e\x79\xc1\x99\xc8\xa5\xd6\x87\xe3\x4c\x44\xc5\xd0\ +\x2e\xb7\x90\xb1\x0a\xeb\x70\xc1\xe2\x62\x0d\x46\x5d\x09\x1e\xae\ +\xa7\x76\x92\x6b\xb9\xc7\x30\xd2\xf3\x45\x99\xcc\xfc\x6a\xc3\xcc\ +\x9b\xc2\xdb\x55\xc9\xdf\x16\xfb\xe9\x1b\x7e\x8d\x3b\xb7\xac\x2c\ +\x9b\xa4\xf5\x14\x34\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\ +\x82\ " qt_resource_name = b"\ @@ -879,6 +1134,10 @@ qt_resource_name = b"\ \x00\x69\x27\x9b\ \x00\x62\ \x00\x6c\x00\x61\x00\x63\x00\x6b\ +\x00\x03\ +\x00\x00\x73\x73\ +\x00\x6d\ +\x00\x61\x00\x63\ \x00\x05\ \x00\x7d\xf0\xa5\ \x00\x77\ @@ -887,45 +1146,96 @@ qt_resource_name = b"\ \x00\x00\x03\x52\ \x00\x32\ \x00\x32\ -\x00\x0c\ -\x03\x76\xc2\x07\ -\x00\x71\ -\x00\x75\x00\x65\x00\x73\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x08\ \x08\x07\x58\xe7\ \x00\x77\ \x00\x61\x00\x69\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ -\x00\x06\ -\x07\x61\x57\x47\ -\x00\x6f\ -\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ \x00\x07\ \x05\xc9\x57\xa7\ \x00\x6f\ \x00\x66\x00\x66\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x06\ +\x07\x61\x57\x47\ +\x00\x6f\ +\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0c\ +\x03\x76\xc2\x07\ +\x00\x71\ +\x00\x75\x00\x65\x00\x73\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ " -qt_resource_struct = b"\ -\x00\x00\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x01\ -\x00\x00\x00\x20\x00\x02\x00\x00\x00\x01\x00\x00\x00\x09\ -\x00\x00\x00\x30\x00\x02\x00\x00\x00\x01\x00\x00\x00\x04\ +qt_resource_struct_v1 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\ +\x00\x00\x00\x30\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0f\ +\x00\x00\x00\x20\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0a\ +\x00\x00\x00\x3c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x00\x40\x00\x02\x00\x00\x00\x04\x00\x00\x00\x05\ -\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x22\xcf\ -\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x29\x6a\ -\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x27\x51\ -\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x25\x01\ -\x00\x00\x00\x40\x00\x02\x00\x00\x00\x04\x00\x00\x00\x0a\ -\x00\x00\x00\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xb9\ -\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x32\x52\ -\x00\x00\x00\x7e\x00\x00\x00\x00\x00\x01\x00\x00\x30\x47\ -\x00\x00\x00\x68\x00\x00\x00\x00\x00\x01\x00\x00\x2d\xef\ +\x00\x00\x00\x4c\x00\x02\x00\x00\x00\x04\x00\x00\x00\x06\ +\x00\x00\x00\x92\x00\x00\x00\x00\x00\x01\x00\x00\x29\x87\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x25\x1f\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x27\x6e\ +\x00\x00\x00\x56\x00\x00\x00\x00\x00\x01\x00\x00\x22\xcf\ +\x00\x00\x00\x4c\x00\x02\x00\x00\x00\x04\x00\x00\x00\x0b\ +\x00\x00\x00\x92\x00\x00\x00\x00\x00\x01\x00\x00\x41\xb6\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x3d\x89\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x3f\xab\ +\x00\x00\x00\x56\x00\x00\x00\x00\x00\x01\x00\x00\x3b\x31\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x31\x71\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x36\x27\ +\x00\x00\x00\x56\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xb9\ " +qt_resource_struct_v2 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x30\x00\x02\x00\x00\x00\x03\x00\x00\x00\x0f\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x20\x00\x02\x00\x00\x00\x01\x00\x00\x00\x0a\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x3c\x00\x02\x00\x00\x00\x01\x00\x00\x00\x05\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x4c\x00\x02\x00\x00\x00\x04\x00\x00\x00\x06\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x92\x00\x00\x00\x00\x00\x01\x00\x00\x29\x87\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x25\x1f\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x27\x6e\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x56\x00\x00\x00\x00\x00\x01\x00\x00\x22\xcf\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x4c\x00\x02\x00\x00\x00\x04\x00\x00\x00\x0b\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x92\x00\x00\x00\x00\x00\x01\x00\x00\x41\xb6\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x3d\x89\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x3f\xab\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x56\x00\x00\x00\x00\x00\x01\x00\x00\x3b\x31\ +\x00\x00\x01\x5f\xdf\x55\x6e\xd8\ +\x00\x00\x00\x6c\x00\x00\x00\x00\x00\x01\x00\x00\x31\x71\ +\x00\x00\x01\x60\x2d\x3e\xf9\x70\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x36\x27\ +\x00\x00\x01\x60\x2d\x29\xfe\x58\ +\x00\x00\x00\x56\x00\x00\x00\x00\x00\x01\x00\x00\x2b\xb9\ +\x00\x00\x01\x60\x2d\x3e\xe5\xe8\ +" + +qt_version = QtCore.qVersion().split('.') +if qt_version < ['5', '8', '0']: + rcc_version = 1 + qt_resource_struct = qt_resource_struct_v1 +else: + rcc_version = 2 + qt_resource_struct = qt_resource_struct_v2 + def qInitResources(): - QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) def qCleanupResources(): - QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) qInitResources() diff --git a/src/leap/bitmask/gui/systray.py b/src/leap/bitmask/gui/systray.py new file mode 100644 index 00000000..93806f20 --- /dev/null +++ b/src/leap/bitmask/gui/systray.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# systray.py +# Copyright (C) 2017 LEAP Encryption Acess Project +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +""" +PyQt5 Systray Integration +""" + +from leap.common.events import client as leap_events +from leap.common.events import catalog + +from leap.bitmask.gui import app_rc + +import platform + +if platform.system() == 'Windows': + from PySide.QtGui import QDialog +else: + from PyQt5.QtGui import QIcon + from PyQt5.QtGui import QPixmap + from PyQt5.QtWidgets import QDialog + from PyQt5.QtWidgets import QAction + from PyQt5.QtWidgets import QMenu + from PyQt5.QtWidgets import QMessageBox + from PyQt5.QtWidgets import QSystemTrayIcon + from PyQt5.QtWidgets import QWidget + + +# TODO do switch based on theme + + +if platform.system() == 'Darwin': + TRAY_ICONS = (':/mac/wait.png', + ':/mac/on.png', + ':/mac/off.png') +else: + TRAY_ICONS = (':/black/22/wait.png', + ':/black/22/on.png', + ':/black/22/off.png') + + +# TODO I think this does not need QDialog + +class WithTrayIcon(QWidget): + + user_closed = False + + def setupSysTray(self): + self._createIcons() + self._createActions() + self._createTrayIcon() + self.trayIcon.activated.connect(self.iconActivated) + self.setVPNStatus('off') + self.setUpEventListener() + self.trayIcon.show() + + def setVPNStatus(self, status): + seticon = self.trayIcon.setIcon + settip = self.trayIcon.setToolTip + # XXX this is an oversimplification, see #9131 + # the simple state for failure is off too, for now. + if status == 'off': + seticon(self.ICON_OFF) + settip('VPN: Off') + elif status == 'on': + seticon(self.ICON_ON) + settip('VPN: On') + elif status == 'starting': + seticon(self.ICON_WAIT) + settip('VPN: Starting') + elif status == 'stopping': + seticon(self.ICON_WAIT) + settip('VPN: Stopping') + + def setUpEventListener(self): + leap_events.register( + catalog.VPN_STATUS_CHANGED, + self._handle_vpn_event) + + def _handle_vpn_event(self, *args): + status = None + if len(args) > 1: + status = args[1] + self.setVPNStatus(status.lower()) + + def _createIcons(self): + self.ICON_WAIT = QIcon(QPixmap(TRAY_ICONS[0])) + self.ICON_ON = QIcon(QPixmap(TRAY_ICONS[1])) + self.ICON_OFF = QIcon(QPixmap(TRAY_ICONS[2])) + + def _createActions(self): + self.quitAction = QAction( + "&Quit", self, + triggered=self.closeFromSystray) + + def iconActivated(self, reason): + # can use .Trigger also for single click + if reason in (QSystemTrayIcon.DoubleClick, ): + self.showNormal() + + def closeFromSystray(self): + self.user_closed = True + self.close() + + def _createTrayIcon(self): + self.trayIconMenu = QMenu(self) + self.trayIconMenu.addAction(self.quitAction) + self.trayIcon = QSystemTrayIcon(self) + self.trayIcon.setContextMenu(self.trayIconMenu) + + def closeEvent(self, event): + if self.trayIcon.isVisible() and not self.user_closed: + QMessageBox.information( + self, "Bitmask", + "Bitmask will minimize to the system tray. " + "You can choose 'Quit' from the menu with a " + "right click on the icon, and restore the window " + "with a double click.") + self.hide() + if not self.user_closed: + event.ignore() -- cgit v1.2.3