summaryrefslogtreecommitdiff
path: root/src/leap
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2017-12-08 16:08:08 +0100
committerKali Kaneko <kali@leap.se>2017-12-08 18:11:47 +0100
commite9ad0c8234be705b42d6dd7eb3865919392835a2 (patch)
tree8162999fefa443248aa5c08ea72231b1e5aff4b5 /src/leap
parent3fae5a6fdaad3e06770797e6cf8c21d1804ddc22 (diff)
[feat] osx systray with pyqt5
Diffstat (limited to 'src/leap')
-rw-r--r--src/leap/bitmask/gui/README.rst2
-rw-r--r--src/leap/bitmask/gui/app.py97
-rw-r--r--src/leap/bitmask/gui/app2.py57
-rw-r--r--src/leap/bitmask/gui/app_rc.py618
-rw-r--r--src/leap/bitmask/gui/systray.py134
5 files changed, 657 insertions, 251 deletions
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 <http://www.gnu.org/licenses/>.
"""
-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 <http://www.gnu.org/licenses/>.
+
+"""
+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()