From c44b362d16c1815094e108893d1becfec362eb58 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 5 Dec 2013 16:16:09 +0200 Subject: [PATCH] Initial commit --- colourterm.py | 22 + colourterm/__init__.py | 57 +++ colourterm/connectdialog.py | 180 ++++++++ colourterm/cwebview.py | 15 + colourterm/mainwindow.py | 329 ++++++++++++++ colourterm/resources.py | 835 ++++++++++++++++++++++++++++++++++ colourterm/settingsdialog.py | 343 ++++++++++++++ configure.ui | 134 ++++++ images/application-exit.png | Bin 0 -> 1134 bytes images/capture-to-disk.png | Bin 0 -> 865 bytes images/configure.png | Bin 0 -> 1101 bytes images/follow-output.png | Bin 0 -> 943 bytes images/highlight-add.png | Bin 0 -> 564 bytes images/highlight-delete.png | Bin 0 -> 640 bytes images/highlight-discard.png | Bin 0 -> 848 bytes images/highlight-edit.png | Bin 0 -> 726 bytes images/highlight-remove.png | Bin 0 -> 332 bytes images/highlight-save.png | Bin 0 -> 597 bytes images/move-down.png | Bin 0 -> 623 bytes images/move-up.png | Bin 0 -> 672 bytes images/network-connect.png | Bin 0 -> 1145 bytes images/network-disconnect.png | Bin 0 -> 760 bytes images/simpleterm.qrc | 20 + mainwindow.ui | 478 +++++++++++++++++++ settings.ui | 318 +++++++++++++ 25 files changed, 2731 insertions(+) create mode 100755 colourterm.py create mode 100644 colourterm/__init__.py create mode 100644 colourterm/connectdialog.py create mode 100644 colourterm/cwebview.py create mode 100644 colourterm/mainwindow.py create mode 100644 colourterm/resources.py create mode 100644 colourterm/settingsdialog.py create mode 100644 configure.ui create mode 100644 images/application-exit.png create mode 100644 images/capture-to-disk.png create mode 100644 images/configure.png create mode 100644 images/follow-output.png create mode 100644 images/highlight-add.png create mode 100644 images/highlight-delete.png create mode 100644 images/highlight-discard.png create mode 100644 images/highlight-edit.png create mode 100644 images/highlight-remove.png create mode 100644 images/highlight-save.png create mode 100644 images/move-down.png create mode 100644 images/move-up.png create mode 100644 images/network-connect.png create mode 100644 images/network-disconnect.png create mode 100644 images/simpleterm.qrc create mode 100644 mainwindow.ui create mode 100644 settings.ui diff --git a/colourterm.py b/colourterm.py new file mode 100755 index 0000000..20b4e26 --- /dev/null +++ b/colourterm.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +import sys +import logging + +from PyQt4 import QtGui + +from colourterm.mainwindow import MainWindow +from colourterm.resources import init_resources, cleanup_resources + +if __name__ == "__main__": + logging.basicConfig(level=logging.DEBUG) + app = QtGui.QApplication(sys.argv) + app.setOrganizationName(u'Snyman') + app.setOrganizationDomain(u'snyman.info') + app.setApplicationName(u'ColourTerm') + init_resources() + mainWindow = MainWindow() + mainWindow.show() + exit_code = app.exec_() + cleanup_resources() + sys.exit(exit_code) diff --git a/colourterm/__init__.py b/colourterm/__init__.py new file mode 100644 index 0000000..ff4584e --- /dev/null +++ b/colourterm/__init__.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +import re + +from PyQt4 import QtCore, QtGui +try: + fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + fromUtf8 = lambda s: s + + +class SComboBox(QtGui.QComboBox): + """ + Special combobox derivative that emits a signal when a key is pressed. + """ + keyPressed = QtCore.pyqtSignal(int) + + def keyPressEvent(self, event): + """ + Override the inherited keyPressEvent to emit a signal. + """ + self.keyPressed.emit(event.key()) + return QtGui.QComboBox.keyPressEvent(self, event) + + +class Highlight(object): + def __init__(self, pattern, foreground, background=None): + self.pattern = pattern + self.regex = re.compile(pattern) + self.foreground = foreground + self.background = background + + def setPattern(self, pattern): + self.pattern = pattern + try: + self.regex = re.compile(pattern) + except re.error: + self.regex = None + + +def translate(context, string, description=None): + return QtGui.QApplication.translate(context, string, description, + QtGui.QApplication.UnicodeUTF8) + + +def create_default_highlights(): + return [ + Highlight(r'PASSED', u'#ffffff', '#009900'), + Highlight(r'FAILED', u'#ffffff', '#990000'), + Highlight(r'^\\|/', u'#666666') + ] + + +from settingsdialog import SettingsDialog +from connectdialog import ConnectDialog + + +__all__ = ['SettingsDialog', 'ConnectDialog', 'SComboBox', 'Highlight', 'translate', 'fromUtf8'] diff --git a/colourterm/connectdialog.py b/colourterm/connectdialog.py new file mode 100644 index 0000000..ab5d449 --- /dev/null +++ b/colourterm/connectdialog.py @@ -0,0 +1,180 @@ +# -*- coding: utf-8 -*- + +from PyQt4 import QtCore, QtGui +from serial import FIVEBITS, SIXBITS, SEVENBITS, EIGHTBITS, PARITY_NONE, PARITY_EVEN, PARITY_ODD, PARITY_MARK,\ + PARITY_SPACE, STOPBITS_ONE, STOPBITS_ONE_POINT_FIVE, STOPBITS_TWO + +from colourterm import fromUtf8, translate + + +DATA_BITS = { + '5': FIVEBITS, + '6': SIXBITS, + '7': SEVENBITS, + '8': EIGHTBITS +} +PARITY_BITS = { + 'None': PARITY_NONE, + 'Even': PARITY_EVEN, + 'Odd': PARITY_ODD, + 'Mark': PARITY_MARK, + 'Space': PARITY_SPACE +} +STOP_BITS = { + '1': STOPBITS_ONE, + '1.5': STOPBITS_ONE_POINT_FIVE, + '2': STOPBITS_TWO +} + + +class Ui_ConnectDialog(object): + def setupUi(self, connectDialog): + self.deviceLayout = QtGui.QGridLayout(connectDialog) + self.deviceLayout.setSpacing(8) + self.deviceLayout.setContentsMargins(8, 8, 8, 0) + self.deviceLayout.setObjectName(fromUtf8('deviceLayout')) + self.portLabel = QtGui.QLabel(connectDialog) + self.portLabel.setObjectName(fromUtf8('portLabel')) + self.deviceLayout.addWidget(self.portLabel, 0, 0, 1, 1) + self.portEdit = QtGui.QLineEdit(connectDialog) + self.portEdit.setText(fromUtf8('/dev/ttyUSB0')) + self.portEdit.setObjectName(fromUtf8('portEdit')) + self.deviceLayout.addWidget(self.portEdit, 0, 1, 1, 1) + self.baudLabel = QtGui.QLabel(connectDialog) + self.baudLabel.setObjectName(fromUtf8('baudLabel')) + self.deviceLayout.addWidget(self.baudLabel, 1, 0, 1, 1) + self.baudComboBox = QtGui.QComboBox(connectDialog) + self.baudComboBox.setObjectName(fromUtf8('baudComboBox')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.baudComboBox.addItem(fromUtf8('')) + self.deviceLayout.addWidget(self.baudComboBox, 1, 1, 1, 1) + self.dataBitsLabel = QtGui.QLabel(connectDialog) + self.dataBitsLabel.setObjectName(fromUtf8('dataBitsLabel')) + self.deviceLayout.addWidget(self.dataBitsLabel, 2, 0, 1, 1) + self.dataBitsComboBox = QtGui.QComboBox(connectDialog) + self.dataBitsComboBox.setObjectName(fromUtf8('dataBitsComboBox')) + self.dataBitsComboBox.addItem(fromUtf8('')) + self.dataBitsComboBox.addItem(fromUtf8('')) + self.dataBitsComboBox.addItem(fromUtf8('')) + self.dataBitsComboBox.addItem(fromUtf8('')) + self.deviceLayout.addWidget(self.dataBitsComboBox, 2, 1, 1, 1) + self.stopBitsLabel = QtGui.QLabel(connectDialog) + self.stopBitsLabel.setObjectName(fromUtf8('stopBitsLabel')) + self.deviceLayout.addWidget(self.stopBitsLabel, 3, 0, 1, 1) + self.stopBitsComboBox = QtGui.QComboBox(connectDialog) + self.stopBitsComboBox.setObjectName(fromUtf8('stopBitsComboBox')) + self.stopBitsComboBox.addItem(fromUtf8('')) + self.stopBitsComboBox.addItem(fromUtf8('')) + self.stopBitsComboBox.addItem(fromUtf8('')) + self.deviceLayout.addWidget(self.stopBitsComboBox, 3, 1, 1, 1) + self.parityLabel = QtGui.QLabel(connectDialog) + self.parityLabel.setObjectName(fromUtf8('parityLabel')) + self.deviceLayout.addWidget(self.parityLabel, 4, 0, 1, 1) + self.parityComboBox = QtGui.QComboBox(connectDialog) + self.parityComboBox.setObjectName(fromUtf8('parityComboBox')) + self.parityComboBox.addItem(fromUtf8('')) + self.parityComboBox.addItem(fromUtf8('')) + self.parityComboBox.addItem(fromUtf8('')) + self.parityComboBox.addItem(fromUtf8('')) + self.parityComboBox.addItem(fromUtf8('')) + self.deviceLayout.addWidget(self.parityComboBox, 4, 1, 1, 1) + self.handshakeLabel = QtGui.QLabel(connectDialog) + self.handshakeLabel.setObjectName(fromUtf8('handshakeLabel')) + self.deviceLayout.addWidget(self.handshakeLabel, 0, 2, 1, 1) + self.softwareCheckBox = QtGui.QCheckBox(connectDialog) + self.softwareCheckBox.setObjectName(fromUtf8('softwareCheckBox')) + self.deviceLayout.addWidget(self.softwareCheckBox, 0, 3, 1, 1) + self.hardwareCheckBox = QtGui.QCheckBox(connectDialog) + self.hardwareCheckBox.setObjectName(fromUtf8('hardwareCheckBox')) + self.deviceLayout.addWidget(self.hardwareCheckBox, 1, 3, 1, 1) + self.openModeLabel = QtGui.QLabel(connectDialog) + self.openModeLabel.setObjectName(fromUtf8('openModeLabel')) + self.deviceLayout.addWidget(self.openModeLabel, 2, 2, 1, 1) + self.readingCheckBox = QtGui.QCheckBox(connectDialog) + self.readingCheckBox.setChecked(True) + self.readingCheckBox.setObjectName(fromUtf8('readingCheckBox')) + self.deviceLayout.addWidget(self.readingCheckBox, 2, 3, 1, 1) + self.writingCheckBox = QtGui.QCheckBox(connectDialog) + self.writingCheckBox.setChecked(True) + self.writingCheckBox.setObjectName(fromUtf8('writingCheckBox')) + self.deviceLayout.addWidget(self.writingCheckBox, 3, 3, 1, 1) + self.buttonBox = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel) + self.deviceLayout.addWidget(self.buttonBox, 5, 0, 1, 4) + + self.retranslateUi(connectDialog) + self.baudComboBox.setCurrentIndex(4) + QtCore.QMetaObject.connectSlotsByName(connectDialog) + self.buttonBox.accepted.connect(connectDialog.accept) + self.buttonBox.rejected.connect(connectDialog.reject) + + def retranslateUi(self, connectDialog): + connectDialog.setWindowTitle(translate('ConnectDialog', 'Open Port')) + self.portLabel.setText(translate('ConnectDialog', 'Port:')) + self.baudLabel.setText(translate('ConnectDialog', 'Baude rate:')) + self.baudComboBox.setItemText(0, translate('ConnectDialog', '921600')) + self.baudComboBox.setItemText(1, translate('ConnectDialog', '576000')) + self.baudComboBox.setItemText(2, translate('ConnectDialog', '460800')) + self.baudComboBox.setItemText(3, translate('ConnectDialog', '230400')) + self.baudComboBox.setItemText(4, translate('ConnectDialog', '115200')) + self.baudComboBox.setItemText(5, translate('ConnectDialog', '57600')) + self.baudComboBox.setItemText(6, translate('ConnectDialog', '38400')) + self.baudComboBox.setItemText(7, translate('ConnectDialog', '19200')) + self.baudComboBox.setItemText(8, translate('ConnectDialog', '9600')) + self.baudComboBox.setItemText(9, translate('ConnectDialog', '4800')) + self.dataBitsLabel.setText(translate('ConnectDialog', 'Data bits:')) + self.dataBitsComboBox.setItemText(0, translate('ConnectDialog', '8')) + self.dataBitsComboBox.setItemText(1, translate('ConnectDialog', '7')) + self.dataBitsComboBox.setItemText(2, translate('ConnectDialog', '6')) + self.dataBitsComboBox.setItemText(3, translate('ConnectDialog', '5')) + self.stopBitsLabel.setText(translate('ConnectDialog', 'Stop bits:')) + self.stopBitsComboBox.setItemText(0, translate('ConnectDialog', '1')) + self.stopBitsComboBox.setItemText(1, translate('ConnectDialog', '1.5')) + self.stopBitsComboBox.setItemText(2, translate('ConnectDialog', '2')) + self.parityLabel.setText(translate('ConnectDialog', 'Parity:')) + self.parityComboBox.setItemText(0, translate('ConnectDialog', 'None')) + self.parityComboBox.setItemText(1, translate('ConnectDialog', 'Odd')) + self.parityComboBox.setItemText(2, translate('ConnectDialog', 'Even')) + self.parityComboBox.setItemText(3, translate('ConnectDialog', 'Mark')) + self.parityComboBox.setItemText(4, translate('ConnectDialog', 'Space')) + self.handshakeLabel.setText(translate('ConnectDialog', 'Handshake:')) + self.softwareCheckBox.setText(translate('ConnectDialog', 'Software')) + self.hardwareCheckBox.setText(translate('ConnectDialog', 'Hardware')) + self.openModeLabel.setText(translate('ConnectDialog', 'Open mode:')) + self.readingCheckBox.setText(translate('ConnectDialog', 'Reading')) + self.writingCheckBox.setText(translate('ConnectDialog', 'Writing')) + + +class ConnectDialog(QtGui.QDialog, Ui_ConnectDialog): + + def __init__(self): + QtGui.QDialog.__init__(self) + self.setupUi(self) + + def getPort(self): + return unicode(self.portEdit.text()) + + def getBaud(self): + return int(unicode(self.baudComboBox.currentText())) + + def getDataBits(self): + return DATA_BITS[unicode(self.dataBitsComboBox.currentText())] + + def getStopBits(self): + return STOP_BITS[unicode(self.stopBitsComboBox.currentText())] + + def getParity(self): + return PARITY_BITS[unicode(self.parityComboBox.currentText())] + + def getSoftwareHandshake(self): + return self.softwareCheckBox.isChecked() + + def getHardwareHandshake(self): + return self.hardwareCheckBox.isChecked() diff --git a/colourterm/cwebview.py b/colourterm/cwebview.py new file mode 100644 index 0000000..9fda7b3 --- /dev/null +++ b/colourterm/cwebview.py @@ -0,0 +1,15 @@ +""" +This module contains a child class of QWebView in order to reimplement the wheelEvent event handler. +""" +from PyQt4 import QtCore, QtWebKit + +class CWebView(QtWebKit.QWebView): + """ + This is a reimplementation of QWebView in order to override the wheelEvent method. + """ + onScroll = QtCore.pyqtSignal() + + def wheelEvent(self, event): + self.onScroll.emit() + QtWebKit.QWebView.wheelEvent(self, event) + diff --git a/colourterm/mainwindow.py b/colourterm/mainwindow.py new file mode 100644 index 0000000..6443125 --- /dev/null +++ b/colourterm/mainwindow.py @@ -0,0 +1,329 @@ +# -*- coding: utf-8 -*- +import threading + +from PyQt4 import QtCore, QtGui +from serial import Serial, SerialException + +from colourterm import SettingsDialog, ConnectDialog, SComboBox, Highlight, fromUtf8, translate, create_default_highlights +from colourterm.cwebview import CWebView + + +class Ui_MainWindow(object): + def setupUi(self, mainWindow): + mainWindow.setObjectName(fromUtf8('MainWindow')) + mainWindow.resize(800, 600) + self.centralwidget = QtGui.QWidget(mainWindow) + self.centralwidget.setObjectName(fromUtf8('centralwidget')) + self.centralLayout = QtGui.QVBoxLayout(self.centralwidget) + self.centralLayout.setSpacing(8) + self.centralLayout.setContentsMargins(0, 0, 0, 8) + self.centralLayout.setObjectName(fromUtf8('centralLayout')) + self.outputBrowser = CWebView(self.centralwidget) + self.outputBrowser.setHtml('
' % str(QtGui.QApplication.palette().color(QtGui.QPalette.Text).name()))
+        self.outputBrowser.setObjectName(fromUtf8('outputBrowser'))
+        self.centralLayout.addWidget(self.outputBrowser)
+        self.sendLayout = QtGui.QHBoxLayout()
+        self.sendLayout.setSpacing(8)
+        self.sendLayout.setObjectName(fromUtf8('sendLayout'))
+        self.sendComboBox = SComboBox(self.centralwidget)
+        self.sendComboBox.setEditable(True)
+        self.sendComboBox.setEnabled(False)
+        self.sendComboBox.setObjectName(fromUtf8('sendComboBox'))
+        self.sendLayout.addWidget(self.sendComboBox)
+        self.sendButton = QtGui.QPushButton(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sendButton.sizePolicy().hasHeightForWidth())
+        self.sendButton.setSizePolicy(sizePolicy)
+        self.sendButton.setMaximumSize(QtCore.QSize(100, 16777215))
+        self.sendButton.setObjectName(fromUtf8('sendButton'))
+        self.sendLayout.addWidget(self.sendButton)
+        self.centralLayout.addLayout(self.sendLayout)
+        mainWindow.setCentralWidget(self.centralwidget)
+        self.statusbar = QtGui.QStatusBar(mainWindow)
+        self.statusbar.setObjectName(fromUtf8('statusbar'))
+        mainWindow.setStatusBar(self.statusbar)
+        self.toolBar = QtGui.QToolBar(mainWindow)
+        self.toolBar.setMovable(False)
+        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
+        self.toolBar.setFloatable(False)
+        self.toolBar.setObjectName(fromUtf8('toolBar'))
+        mainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
+        self.openAction = QtGui.QAction(mainWindow)
+        connectIcon = QtGui.QIcon()
+        connectIcon.addPixmap(QtGui.QPixmap(fromUtf8(':/toolbar/network-connect.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.openAction.setIcon(connectIcon)
+        self.openAction.setObjectName(fromUtf8('openAction'))
+        self.closeAction = QtGui.QAction(mainWindow)
+        disconnectIcon = QtGui.QIcon()
+        disconnectIcon.addPixmap(QtGui.QPixmap(fromUtf8(':/toolbar/network-disconnect.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.closeAction.setIcon(disconnectIcon)
+        self.closeAction.setObjectName(fromUtf8('closeAction'))
+        self.captureAction = QtGui.QAction(mainWindow)
+        captureIcon = QtGui.QIcon()
+        captureIcon.addPixmap(QtGui.QPixmap(fromUtf8(':/toolbar/capture-to-disk.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.captureAction.setIcon(captureIcon)
+        self.captureAction.setCheckable(True)
+        self.captureAction.setChecked(False)
+        self.captureAction.setObjectName(fromUtf8('captureAction'))
+        self.followAction = QtGui.QAction(mainWindow)
+        self.followAction.setShortcut(QtCore.Qt.Key_F)
+        followIcon = QtGui.QIcon()
+        followIcon.addPixmap(QtGui.QPixmap(fromUtf8(':/toolbar/follow-output.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.followAction.setIcon(followIcon)
+        self.followAction.setCheckable(True)
+        self.followAction.setChecked(True)
+        self.followAction.setObjectName(fromUtf8('followAction'))
+        self.configureAction = QtGui.QAction(mainWindow)
+        configureIcon = QtGui.QIcon()
+        configureIcon.addPixmap(QtGui.QPixmap(fromUtf8(':/toolbar/configure.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.configureAction.setIcon(configureIcon)
+        self.configureAction.setObjectName(fromUtf8('configureAction'))
+        self.exitAction = QtGui.QAction(mainWindow)
+        exitIcon = QtGui.QIcon()
+        exitIcon.addPixmap(QtGui.QPixmap(fromUtf8(':/toolbar/application-exit.png')), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        self.exitAction.setIcon(exitIcon)
+        self.exitAction.setObjectName(fromUtf8('exitAction'))
+        self.toolBar.addAction(self.openAction)
+        self.toolBar.addAction(self.closeAction)
+        self.toolBar.addAction(self.captureAction)
+        self.toolBar.addAction(self.followAction)
+        self.toolBar.addAction(self.configureAction)
+        self.toolBar.addAction(self.exitAction)
+
+        self.retranslateUi(mainWindow)
+        QtCore.QMetaObject.connectSlotsByName(mainWindow)
+
+    def retranslateUi(self, mainWindow):
+        mainWindow.setWindowTitle(translate('MainWindow', 'ColourTerm'))
+        self.sendButton.setText(translate('MainWindow', 'Send'))
+        self.toolBar.setWindowTitle(translate('MainWindow', 'toolBar'))
+        self.openAction.setText(translate('MainWindow', 'Open...'))
+        self.openAction.setToolTip(translate('MainWindow', 'Open...'))
+        self.closeAction.setText(translate('MainWindow', 'Close'))
+        self.closeAction.setToolTip(translate('MainWindow', 'Close'))
+        self.captureAction.setText(translate('MainWindow', 'Capture'))
+        self.captureAction.setToolTip(translate('MainWindow', 'Capture to File'))
+        self.followAction.setText(translate('MainWindow', '&Follow'))
+        self.configureAction.setText(translate('MainWindow', 'Configure...'))
+        self.configureAction.setToolTip(translate('MainWindow', 'Configure...'))
+        self.exitAction.setText(translate('MainWindow', 'Exit'))
+
+
+class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
+    updateOutput = QtCore.pyqtSignal(str)
+
+    def __init__(self):
+        QtGui.QMainWindow.__init__(self)
+        self.terminalLines = []
+        self.maxLines = 5000
+        self.setupUi(self)
+        self.device = None
+        self.deviceClosed = True
+        self.followOutput = True
+        self.captureFile = None
+        self.captureFileName = u''
+        self.highlights = self.loadHighlights()
+        if not self.highlights:
+            self.highlights = create_default_highlights()
+        self.settingsDialog = SettingsDialog()
+        self.connectDialog = ConnectDialog()
+        self.openAction.triggered.connect(self.onOpenActionTriggered)
+        self.closeAction.triggered.connect(self.onCloseActionTriggered)
+        self.captureAction.toggled.connect(self.onCaptureActionToggled)
+        self.followAction.toggled.connect(self.onFollowActionToggled)
+        self.configureAction.triggered.connect(self.onConfigureActionTriggered)
+        self.exitAction.triggered.connect(self.close)
+        self.sendComboBox.keyPressed.connect(self.onSendComboBoxKeyPressed)
+        self.sendButton.clicked.connect(self.onSendButtonClicked)
+        self.outputBrowser.page().mainFrame().contentsSizeChanged.connect(self.onContentsSizeChanged)
+        self.outputBrowser.onScroll.connect(self.onOutputBrowserScrolled)
+        self.updateOutput.connect(self.onUpdateOutput)
+
+    def close(self):
+        if not self.deviceClosed:
+            self.deviceClosed = True
+        if self.captureFile:
+            self.captureFile.flush()
+            self.captureFile.close()
+        return QtGui.QMainWindow.close(self)
+
+    def documentBody(self):
+        return self.outputBrowser.page().mainFrame().documentElement().findFirst('pre')
+
+    def receiveText(self):
+        output = ''
+        while not self.deviceClosed:
+            output += self.device.read(1)
+            if output.endswith('\r\n'):
+                #self.terminalLines.append(output.strip('\r\n'))
+                #if len(self.terminalLines) > self.maxLines:
+                #    self.terminalLines = self.terminalLines[-self.maxLines:]
+                #    self.refreshOutput()
+                #else:
+                self.updateOutput.emit(output.strip('\r\n'))
+                output = ''
+
+    def onOpenActionTriggered(self):
+        if self.connectDialog.exec_() == QtGui.QDialog.Accepted:
+            if not self.deviceClosed:
+                self.deviceClosed = True
+                self.device.close()
+            try:
+                self.device = Serial(
+                    port=self.connectDialog.getPort(),
+                    baudrate=self.connectDialog.getBaud(),
+                    bytesize=self.connectDialog.getDataBits(),
+                    parity=self.connectDialog.getParity(),
+                    stopbits=self.connectDialog.getStopBits(),
+                    timeout=0,
+                    xonxoff=self.connectDialog.getSoftwareHandshake(),
+                    rtscts=self.connectDialog.getHardwareHandshake(),
+                    dsrdtr=None
+                )
+                self.deviceClosed = False
+                if not self.device.isOpen():
+                    self.device.open()
+                outputThread = threading.Thread(target=self.receiveText)
+                outputThread.start()
+            except SerialException, e:
+                QtGui.QMessageBox.critical(self, 'Error opening port', e.args[0])
+        self.sendComboBox.setEnabled(not self.deviceClosed)
+        if self.sendComboBox.isEnabled():
+            self.sendComboBox.setFocus()
+
+    def onCloseActionTriggered(self):
+        self.deviceClosed = True
+        if self.device.isOpen():
+            self.device.close()
+        self.sendComboBox.setEnabled(not self.deviceClosed)
+
+    def onCaptureActionToggled(self, enabled):
+        if enabled and not self.captureFile:
+            if self.captureFileName:
+                baseDir = os.path.basename(self.captureFileName)
+            else:
+                baseDir = u''
+            self.captureFileName = QtGui.QFileDialog.getSaveFileName(self, u'Capture To File',
+                baseDir, u'Text files (*.txt *.log);;All files (*)')
+            self.captureFile = open(self.captureFileName, u'w')
+            self.statusbar.showMessage(self.captureFileName)
+        elif self.captureFile and not enabled:
+            self.captureFileName = u''
+            self.captureFile.flush()
+            self.captureFile.close()
+            self.captureFile = None
+            self.statusbar.clearMessage()
+
+    def onFollowActionToggled(self, enabled):
+        self.followOutput = enabled
+        if enabled:
+            self.outputBrowser.page().mainFrame().scroll(0,
+                self.outputBrowser.page().mainFrame().contentsSize().height())
+
+    def onConfigureActionTriggered(self):
+        self.settingsDialog.setHighlights(self.highlights)
+        self.settingsDialog.exec_()
+        self.highlights = self.settingsDialog.highlights()
+        self.saveHighlights(self.highlights)
+        self.refreshOutput()
+
+    def onSendComboBoxKeyPressed(self, key):
+        if key == QtCore.Qt.Key_Return or key == QtCore.Qt.Key_Enter:
+            self.onSendButtonClicked()
+
+    def onSendButtonClicked(self):
+        if self.device.isOpen():
+            output = str(self.sendComboBox.currentText())
+            self.sendComboBox.insertItem(0, output)
+            self.sendComboBox.setCurrentIndex(0)
+            self.sendComboBox.clearEditText()
+            self.device.write(output + u'\r\n')
+
+    def onContentsSizeChanged(self, size):
+        if self.followOutput:
+            self.outputBrowser.page().mainFrame().scroll(0, size.height())
+        self.outputBrowser.update()
+
+    def onUpdateOutput(self, output):
+        #self.terminalLines.append(output)
+        if self.captureFile:
+            self.captureFile.write(output + u'\n')
+            self.captureFile.flush()
+        #if len(self.terminalLines) > 5000:
+        #    self.terminalLines = self.terminalLines[-5000:]
+        #    self.refreshOutput()
+        #else:
+        output = self.styleOutput(output)
+        self.documentBody().appendInside(output)
+
+    def onOutputBrowserScrolled(self):
+        scrollValue = self.outputBrowser.page().mainFrame().scrollBarValue(QtCore.Qt.Vertical)
+        scrollMax = self.outputBrowser.page().mainFrame().scrollBarMaximum(QtCore.Qt.Vertical)
+        if scrollValue < scrollMax:
+            self.onFollowActionToggled(False)
+            self.followAction.setChecked(False)
+        else:
+            self.onFollowActionToggled(True)
+            self.followAction.setChecked(True)
+
+    def refreshOutput(self):
+        elements = self.outputBrowser.page().mainFrame().findAllElements('div')
+        lines = [unicode(element.toPlainText()) for element in elements]
+        pre = self.outputBrowser.page().mainFrame().findFirstElement('pre')
+        pre.setInnerXml('')
+        for line in lines:
+            output = self.styleOutput(line)
+            self.documentBody().appendInside(output)
+        self.outputBrowser.page().mainFrame().scroll(0, self.outputBrowser.page().mainFrame().contentsSize().height())
+        self.outputBrowser.update()
+
+    def styleOutput(self, output):
+        style = u'font-family: Ubuntu Mono; '
+        if not output:
+            output = u' '
+        for highlight in self.highlights:
+            if highlight.regex.search(output):
+                if highlight.foreground:
+                    style = u'%scolor: %s; ' % (style, highlight.foreground)
+                if highlight.background:
+                    style = u'%sbackground-color: %s; ' % (style, highlight.background)
+                break
+        if style:
+	  try:
+	    output = u'
%s
' % (style, unicode(output, u'utf-8')) + except TypeError: + output = u'
%s
' % (style, output) + else: + output = u'
%s
' % output + return output + + def saveHighlights(self, highlights): + settings = QtCore.QSettings() + settings.setValue(u'highlights/count', len(highlights)) + for index, highlight in enumerate(highlights): + settings.beginGroup(u'highlight-%s' % index) + settings.setValue(u'pattern', highlight.pattern) + settings.setValue(u'foreground', highlight.foreground) + if highlight.background: + settings.setValue(u'background', highlight.background) + else: + if settings.contains(u'background'): + settings.remove(u'background') + settings.endGroup() + + def loadHighlights(self): + settings = QtCore.QSettings() + highlight_count = settings.value(u'highlights/count', 0).toInt()[0] + highlights = [] + for index in range(highlight_count): + settings.beginGroup('highlight-%s' % index) + pattern = unicode(settings.value('pattern', '').toString()) + foreground = unicode(settings.value('foreground', '').toString()) + background = None + if settings.contains('background'): + background = unicode(settings.value('background', '').toString()) + settings.endGroup() + highlights.append(Highlight(pattern, foreground, background)) + return highlights diff --git a/colourterm/resources.py b/colourterm/resources.py new file mode 100644 index 0000000..0128a74 --- /dev/null +++ b/colourterm/resources.py @@ -0,0 +1,835 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created: Tue Aug 27 09:51:56 2013 +# by: The Resource Compiler for PyQt (Qt v4.8.4) +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore + +qt_resource_data = "\ +\x00\x00\x02\xd6\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\x01\ +\x1e\x75\x38\x35\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd8\x0b\x11\ +\x17\x19\x36\xe0\x1f\xbc\x7d\x00\x00\x02\x56\x49\x44\x41\x54\x78\ +\xda\x8d\x91\x5d\x48\x53\x71\x18\x87\x9f\x73\x66\x52\xe1\x32\x95\ +\x30\xb2\xd5\x12\xc2\x30\xa8\x30\xbd\x31\x2f\xba\xd1\x8b\x90\xc0\ +\xa0\x4f\xa2\x20\xb2\x4c\xab\x8b\x8c\x60\x41\x12\x18\x41\x82\x91\ +\x60\x81\x1f\x45\x17\xd2\xf7\x45\x17\x61\xa4\xa1\x61\x28\xa1\xa8\ +\x91\x59\x4a\xea\x14\x5d\x73\xb6\x4c\xcf\xce\x74\xba\xb3\xfd\x3b\ +\x1c\xd8\x58\x5b\x50\x0f\xbc\xbc\xef\xb9\x78\x9f\xdf\xcb\xff\x48\ +\x60\xb0\x16\xd8\xce\x7f\x50\xb0\x5b\x5e\x79\x7b\x63\x41\x9d\xe6\ +\x9a\x1b\x23\x21\xe1\x44\x48\x90\x2f\x84\x68\xe1\x1f\x04\xfc\x8b\ +\x78\x7a\x8b\x78\x79\xdf\x4e\x46\x7b\x80\x05\x97\xab\x33\x0e\x30\ +\xd0\x05\xfc\x70\xbb\x91\x65\xd9\x28\x49\x92\x90\xf5\xd2\x07\x63\ +\x86\x20\xcb\x5f\x4b\x79\xdd\xfa\x85\xeb\xad\x32\x07\x2c\x53\x5a\ +\x96\x47\x24\xc9\x44\x60\x32\x99\xc2\x02\x53\xa8\x9b\x4c\xc6\xec\ +\xb7\x57\xd1\xdb\xd3\xc5\x8d\xa6\x78\x76\x6e\x76\x73\xfa\xac\xe4\ +\x6a\xc9\x92\xcf\xc5\x41\x18\x23\xd1\x48\xd7\x4b\x9f\xc3\xdd\x37\ +\xf5\x08\xc7\xb7\x37\xd8\xea\xe3\x59\x6f\x9e\xe1\x56\xe9\x6a\x2a\ +\xea\x97\x6a\x9e\xb7\x69\xd3\x91\x17\xfc\x99\x1e\x4a\x9e\x7d\x8f\ +\x32\xfe\x84\x0b\xd5\x3e\x56\x48\x1e\x6a\x2e\x06\x59\x48\xad\x40\ +\x5f\xf6\x00\x93\x61\x81\x14\x4a\x8c\x90\x04\xd4\x21\xb4\xe9\xc7\ +\x5c\xb9\xeb\x61\x5e\x51\xa9\x2e\x51\xd0\x52\xcb\x50\xe5\x1d\x00\ +\x0e\x60\x31\xe6\x82\x90\x24\xe0\x73\x12\x9c\x7e\x88\xed\xce\x18\ +\x9f\x87\xdd\xdc\x3c\x35\x87\x79\xd3\x41\x66\x02\x79\x58\xad\x56\ +\x80\x25\x63\x27\xea\x0d\x8c\x12\x9a\x82\xd0\x97\xab\x1a\x07\x79\ +\xd7\xed\xc4\x76\x74\x8e\x2d\xdb\x72\x19\xf5\x15\x92\x96\x96\x86\ +\xc5\x62\x01\x20\x46\x60\xfc\x2e\xe1\x27\xe0\xa8\xe3\xc1\xb3\x7e\ +\x9e\x36\x4f\x50\x52\xe8\x21\x37\x27\x9d\xfe\x5f\x47\x48\x4e\x4e\ +\x21\x33\x33\x13\x01\x61\xe2\xa2\x05\xf3\x93\x6d\xb4\x35\xb7\x53\ +\xdb\x34\x49\x51\xde\x22\x87\x0a\x12\x79\x31\xb8\x9f\x29\xe7\x00\ +\xe6\x35\x49\xf4\xf5\xf5\xb1\xca\x9c\x08\xa0\xfd\x55\xa0\x7a\x25\ +\xbc\x41\x2b\x7b\x77\x8d\x51\x7e\x58\xe6\x95\xfd\x38\xc3\x23\xdf\ +\xa9\xac\xac\xd4\x2f\x48\x46\x55\x55\x2e\x95\x97\xbf\x05\xba\x62\ +\x04\x3f\x67\x1c\xcc\x3a\x3f\x90\xbe\xce\x49\x46\x51\x36\xe3\xf1\ +\xfb\xc8\xd9\x93\x8d\x39\x65\xc8\x58\xf6\x7a\xbd\xd8\xae\xda\x06\ +\x1a\x1b\x1a\x4e\x02\x3e\x22\xc8\x17\x3a\xf7\x6a\x6b\xc4\xb5\xcb\ +\xc7\x84\x63\xa4\x53\xf8\xfd\xcb\x22\x18\x0c\xea\xdd\x2f\x3a\x3a\ +\x3a\x84\xa2\x28\xa2\xec\x7c\xd9\x27\x60\x2b\x21\xa2\x05\x13\xf6\ +\x51\x11\xcd\xb2\x16\x10\xdd\x1f\x07\x44\xf1\x99\xe2\x16\x60\x03\ +\x51\x48\x60\x90\x02\x64\x85\xbf\x63\xd1\x80\x4e\x60\x89\x28\x7e\ +\x03\x99\xc3\x0a\xf4\x03\x8f\xf6\xf6\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x03\x50\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\ +\x01\x3a\xec\xe3\xe2\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\x02\xcd\x49\x44\ +\x41\x54\x78\xda\xa5\x93\x4d\x48\x14\x71\x18\xc6\x9f\xff\x7c\x3a\ +\xb3\x33\xbb\x7e\xad\xeb\x17\xc5\x6a\x69\xa5\x41\x1f\x20\x86\xa0\ +\x75\x0b\x05\xeb\x90\x44\x1e\xf6\x20\x18\x81\x76\xad\x8b\x87\x0e\ +\x42\x1d\xba\xa5\x27\x21\x28\x49\x8d\x3a\x44\xa5\x08\x49\x2a\x8a\ +\x89\x69\x56\x7e\x84\x45\xe1\x26\xba\x2b\xae\xbb\xe9\x4e\xeb\xce\ +\xec\xce\x4c\xb3\x96\xb2\x0a\x75\xe9\xb9\xbc\xa7\xdf\xc3\xf3\xbe\ +\x3c\x2f\x31\x4d\x13\xff\x10\xf5\x67\x1a\xf8\x8b\x18\xec\xd3\xfb\ +\x96\x96\x63\xab\xc3\xc3\x4f\x82\x63\x63\x51\xa9\xa0\xe0\x38\x2d\ +\xcb\x24\xb2\xb8\x38\x2f\x97\x96\x32\xae\xca\xca\xba\x13\xad\xad\ +\xf3\x48\xd2\x9e\x04\x43\xf5\xf5\xf7\x56\xfb\xfa\x1a\x33\xce\x94\ +\xf3\x69\x25\xa5\x90\x5c\x2e\x10\x42\xa0\xac\xad\x21\x30\x39\x89\ +\xf5\xa9\x29\x35\xa7\xba\xba\xe3\x6c\x57\xd7\xf5\x64\x83\x5d\xd8\ +\xd7\xdf\xd7\x54\xe8\xf1\x10\x5e\x14\xb1\xf8\x7a\x08\x3f\x97\x97\ +\x21\x08\x3c\xec\x87\x0a\xe1\x28\x3e\x8a\xad\xf0\x26\xbc\xdd\x3d\ +\x66\xfe\x85\x8b\xed\x09\x93\x5d\x83\x09\x2b\xf6\x5c\x5b\xdb\x3b\ +\x77\x6d\x0d\x0f\x4d\xc3\xec\x8b\x97\x41\x5e\x8b\xdf\x96\x58\xb6\ +\x87\x67\xd9\x1c\x89\x63\x5f\xa1\xec\xb4\x83\x77\xe5\x41\xdd\x0c\ +\x61\x79\x60\x50\x2d\x69\x6e\x3e\x55\x66\xad\x43\xc1\x92\xd7\xda\ +\x59\xce\xcf\xe2\x69\x9a\xc1\xc7\xde\xbe\x10\x21\xf4\xb1\xc6\x58\ +\xec\x2e\x43\x51\x31\xd1\x26\xf6\xa4\x54\x55\x38\x58\x41\xc6\x86\ +\x6f\x09\x31\x2d\x06\x29\xdf\xc5\x27\x98\xdd\x2b\x2b\x3e\x5f\x36\ +\x93\x91\x8e\xa5\x0f\x53\xa0\xa3\xda\x9d\x26\x45\x59\xed\x96\xa4\ +\x2c\xd9\x61\x7f\xe3\x3c\x7f\xae\x80\x09\x47\xa1\x05\x7c\x98\x1b\ +\x1c\x86\x7f\xe1\x13\xa8\xd4\xd4\x6d\x66\xc7\x80\x52\xfc\x7e\x29\ +\xc6\xd2\xd8\x5a\x0f\x40\xe0\xb8\xce\x04\x6c\xb7\x89\xe3\xae\xf2\ +\x93\x6e\xcc\x7f\x83\xa9\x04\x31\x33\x31\x65\xe4\xaa\xb1\x6b\x08\ +\x05\xe1\x5b\x5a\x44\x82\x49\xb0\xdb\x09\xe2\x00\xbe\x4f\x4f\xc3\ +\x50\x14\xd0\x84\x38\x6d\x02\x3f\x2e\x0a\xa6\x5b\x1f\x79\x0b\x6d\ +\xe5\x2b\xc6\xa6\x67\x8c\xf4\x2d\xd5\xc3\x01\xcf\x04\x43\x87\x6e\ +\x99\xc4\x93\x8a\x62\x30\xd9\xd9\x0a\x6b\xc6\x41\x41\x47\x9a\x4d\ +\x18\x65\x10\x71\x0b\xde\x00\x10\x0d\x61\x74\x35\x68\x38\x2c\xb8\ +\xc1\x34\x1f\xe9\x36\xdb\x15\x81\x36\x21\x32\x04\x09\x26\xc1\x6e\ +\x27\x60\x73\x72\xfc\x1c\x00\x2d\xac\x41\x67\x23\x32\x1f\x88\x82\ +\xd8\x59\x0c\xa8\x86\x21\x6a\x86\xe7\xaa\x05\x3f\x90\x24\x57\x56\ +\xaa\x70\x4b\xff\x11\x01\x65\xfe\x66\x76\x8f\x58\x54\x55\x55\xb7\ +\xa6\x0b\xaa\x90\xce\x21\xbe\x1c\x01\xed\xe4\xd1\xaf\x19\x20\x71\ +\xdc\x44\x4a\xca\x48\xa7\xdd\x7e\x23\x2f\x53\xfc\xcc\x85\x37\x1d\ +\x48\xe3\xb0\x62\x08\x6a\x82\xd9\x53\xa4\x87\x56\x91\xbc\x4f\x1f\ +\x37\x1d\x71\x72\x24\x33\x18\x03\x6c\x34\xc2\x14\x03\x1b\xc3\x22\ +\x9d\x36\x40\x05\x23\x58\x71\xb0\x98\x0c\x68\xe6\xc1\x4b\x97\xdb\ +\x3d\xc9\x45\xda\xd1\x7d\xcb\xe4\x4b\x6f\x6f\x63\x11\xaf\xf2\xb9\ +\x1c\x41\x26\x08\x38\x42\x10\x04\xb0\xa4\xe9\x98\x8b\xf2\xea\xe1\ +\x9a\x9a\x8e\x86\xfd\x55\x4e\xd6\x73\xab\x95\x0b\x56\x49\xbc\xa3\ +\xa3\x51\x49\x96\x4b\x29\xda\x4a\xb2\xb1\x31\x7b\xa0\xa2\x22\xa5\ +\xd8\x8a\x5d\xbb\xef\x99\xfe\xfb\x9d\x7f\x01\x2e\xd5\x46\xab\x0b\ +\x34\xf6\x10\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\xa0\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ +\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x03\x76\x00\x00\ +\x03\x76\x01\x7d\xd5\x82\xcc\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ +\xd7\x0c\x1d\x0d\x11\x0d\x81\xdc\x28\x8a\x00\x00\x02\x2d\x49\x44\ +\x41\x54\x78\xda\x8d\x92\x4b\x6b\x53\x41\x18\x86\xdf\x99\x73\x89\ +\x39\x27\x27\xd5\xa8\xb9\x94\x6e\x52\x53\xdb\x8d\xd5\x58\xaa\xe2\ +\x05\x74\x97\x85\x05\x05\x0b\xd5\xba\xf0\x07\x08\xf5\x27\x88\x22\ +\x88\x1b\x11\x14\x5d\x58\x14\x29\x2d\xd9\x88\x6e\x04\xc1\x85\x8b\ +\xea\xca\x85\x0b\x15\x5d\x18\xa4\x55\xc4\xa0\x6d\x9a\x73\x92\x9c\ +\xcb\x5c\x9c\xb4\xb8\x90\xc6\x98\x81\x6f\xf3\xcd\xfb\x3d\xcc\xf3\ +\x31\xe8\x76\x0a\x93\x0f\xae\xe5\x4f\xdd\xb9\xd2\x2d\xa3\xfd\xeb\ +\x62\x68\x6a\xae\x94\xb4\xc8\x3d\x03\xfe\x31\x23\x7b\xe8\x75\xbd\ +\xf2\xb2\xd2\x29\x47\x3b\x35\x77\x9f\x9d\xcf\x10\xc9\x1f\x4e\x9d\ +\x1c\x21\xe7\x4e\x8f\x51\xc9\xfd\x47\x99\xc3\x33\x3b\x7b\x02\x0c\ +\x4f\x97\x89\x54\xc3\x63\x23\x4e\x26\x69\x6b\xd8\x9a\x8c\xe1\xc8\ +\xf8\xae\x9c\x60\xfe\x6c\x6a\xdf\xf9\xff\x03\x84\x60\x97\xb6\xd9\ +\x28\x8d\x0e\xa7\xe0\xae\x35\x50\x57\x55\x1c\x1d\x44\x36\xdd\x37\ +\x01\xc1\x2f\x76\xdd\x81\xf2\x2e\x12\x19\x2e\x1c\x2f\xa6\x74\x53\ +\xd7\xc0\xb9\x40\xc4\x04\xc2\x90\x23\x97\xdd\x8e\x0f\xef\x3f\x9e\ +\xd0\xfb\x06\x9f\x06\x3f\x3f\x55\x37\xbd\x20\x3f\x71\xd3\x09\x6a\ +\xcb\xe5\x42\x86\xc5\x62\xa6\x8e\x20\x94\xaa\x80\xb0\x5d\x11\x60\ +\x98\x71\x8c\x1f\xd8\x1f\x57\x7a\xf3\x89\x42\x69\xcb\x26\x40\x58\ +\xff\x76\x37\x41\x6b\x43\x03\xb9\x14\x42\x06\x30\x41\xc1\xa5\x86\ +\x48\x68\xa8\xb9\x0c\x5f\x96\x6b\xf8\xb5\x26\x11\xb3\x9c\x3d\x52\ +\xb0\xeb\x7f\x29\xe4\x8e\xce\x4c\x46\xee\x8f\xab\xb9\xfe\x7e\x10\ +\x3d\xa1\x00\x3a\x82\x88\xa2\x19\x00\x6e\x83\xa3\xe5\x0b\x04\x4a\ +\x83\x0b\x01\x10\x0d\xab\xd5\xa5\x83\x9a\x33\xf0\x8a\xd7\x97\x2a\ +\x3a\x00\xf0\xc0\xcb\x47\xad\x55\xbc\x5b\x7c\x82\xb7\xad\x15\xc8\ +\xd0\xc3\x85\xcb\x8f\x11\x33\x4d\x10\xda\xd6\x88\xf0\xac\x7c\x1b\ +\x02\x1a\x04\x67\x90\x82\x13\x02\x79\x06\xc0\x8b\x75\x80\x16\x4b\ +\xdc\x30\x9c\xec\x7d\x6a\x58\x54\xb3\xd3\xa4\xf1\xf5\x4d\x35\x61\ +\x5b\xb0\xac\x38\x28\x25\x68\xb5\x02\x44\x81\xaf\x60\x46\x52\x40\ +\x48\x48\x00\x20\x4d\x00\x58\x07\x7c\x5f\xbc\x05\x00\x2b\x7f\xbc\ +\xac\xec\x5e\xa8\x4d\xc2\x49\xd8\x30\x0c\x5d\x41\x3c\xa8\x69\x78\ +\x9f\x9f\xbb\x3d\xfd\x44\xdd\xc9\x6e\x2c\x48\xa3\x1b\x1a\xa4\x9d\ +\xd4\xd1\x31\xdb\xb1\x69\xa7\xe1\x79\x4d\x50\x4a\x51\xd7\x1a\x70\ +\xbd\x46\xdb\xbb\x77\x00\x35\x6d\x77\x61\x6e\xd6\x11\x2c\x80\x8c\ +\x7c\xf0\xa8\x05\xc1\x23\xb7\x67\x80\x0a\xef\x90\x2c\x34\x85\x1a\ +\x64\xcc\x87\x50\x10\x48\x11\x76\xca\xfe\x06\x81\x37\xee\xc0\xcc\ +\x8e\x0a\x9c\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\x6f\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ +\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\ +\x06\xec\x01\x1e\x75\x38\x35\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ +\xd7\x0c\x1d\x0e\x02\x37\x24\x79\x0e\xf3\x00\x00\x01\xfc\x49\x44\ +\x41\x54\x78\xda\xa5\x90\x4f\x6b\x13\x41\x18\x87\x7f\xbb\xb3\x69\ +\x76\x37\xd9\xd5\x98\xb4\x1b\x29\xa2\x16\xd4\x83\x17\xf5\x24\x58\ +\xbc\xf8\x0d\xa4\x78\x29\x22\x82\x5e\xa5\x42\xf1\x58\xcf\x7e\x01\ +\xa1\x87\x62\xb1\x01\xf1\x52\x05\xe9\xb1\x78\x10\x91\x4a\xc1\x7f\ +\xa0\x58\x8a\x4d\x53\x93\x92\x36\xb1\x89\xbb\xee\x66\xbb\xbb\x33\ +\xbe\xae\x8b\x84\x1c\xda\xa8\x0f\xf3\x32\x33\x2f\xcc\x33\xbf\x19\ +\xfc\x2f\x12\x7a\x18\xb9\x3c\x2d\x51\x7b\x1d\x82\xe7\x84\x10\xa0\ +\x19\x22\xae\xa8\xb1\xfe\x6c\xe2\x38\x7a\x50\xd0\x03\x0f\x7d\x12\ +\x88\x23\x37\xc7\x4e\x43\x92\xa4\xb8\x40\xdc\x2f\x2d\xe9\x20\xf6\ +\x15\x44\xbb\x2e\x48\x80\x4e\xa7\xf3\xfb\x30\x95\x14\xf7\x3d\xf4\ +\x27\x08\x3c\x80\xa2\xb7\xdb\x76\x77\x02\xea\xbb\x7d\x0a\x7c\x07\ +\xc0\x2f\x81\x83\x38\x40\x92\x80\xef\x95\x60\xe8\xc2\xed\x49\xf0\ +\xe8\xae\xe0\x81\x14\xf9\x76\x9c\xc0\xb6\x5d\x30\x26\xc7\x02\x41\ +\x7b\x4a\x20\xe7\xce\x5e\xb3\x21\x38\x8d\xf8\x63\x1f\xb4\x3f\x3c\ +\xba\xa5\x20\xb6\xbb\x0d\x1e\xed\x66\x47\x8e\x5a\x30\x8c\x0c\x34\ +\x5d\x87\xc4\x06\xc0\x94\x14\x24\x59\x06\xe7\x11\x2e\x8e\x9e\x83\ +\xe3\x38\xd9\xad\xfa\x36\xd6\xbe\x94\x41\x3c\x07\x21\x27\xef\x9b\ +\xa5\xe8\x4f\x37\xab\x35\x78\x3e\xdd\x86\x34\xb8\xa4\x43\xb0\x2c\ +\x42\x68\xf8\xe1\x2b\xd8\xde\x09\x50\xf9\xda\xc2\x46\xa5\x0a\x1e\ +\x78\x33\xf6\xa7\xf9\x27\x7f\x04\x3b\x6f\xe7\xa8\xe9\xde\x68\x35\ +\x6a\xd5\x66\xf3\x1b\x09\x54\xc8\x29\x13\x29\xf5\x20\xd4\xcc\x21\ +\xe8\x46\x1e\x66\x6e\x10\x03\x29\x86\x8e\xbd\xb5\x42\x69\x27\x90\ +\x20\x23\xc1\x5e\x59\x68\x92\xf9\xea\xe6\xea\x32\x57\xd5\x34\xf2\ +\x85\x3c\x2c\xab\x80\xa2\x35\x88\xa1\x42\x01\x19\x5d\x43\xe5\xf3\ +\xeb\x40\xf0\x68\xdc\x5b\x5b\x74\x90\xc0\xd0\x45\xf8\x7d\xa3\x2c\ +\x98\xa6\xbb\xed\xfa\xe8\x99\xf3\x97\xe8\x20\xdd\x6c\x64\xc1\x05\ +\xc7\xe2\xfc\x34\x9a\xf5\xca\x94\x5f\x5b\x7a\x8c\x2e\x64\xf4\x22\ +\x30\x55\x5b\x7d\xb3\xfc\xfe\xe5\x02\x82\x30\x44\x14\x45\x78\x47\ +\xeb\xf2\xc7\x57\x2f\xc0\xc3\x7b\xe8\x07\x66\x0c\x9f\x4c\x9b\x45\ +\x7b\x6c\xf2\xa1\xb8\x72\xa7\x24\xd2\xa6\xd5\x52\x8c\xe1\x63\xf8\ +\x1b\x98\x96\xbf\x7e\xe0\xf0\x29\x61\x5a\x27\x84\xac\xe5\xc6\xf1\ +\x2f\xb0\x4c\xb1\x44\x35\x8b\x3d\xf8\x09\x7b\x1c\xef\xe9\x88\x1f\ +\x84\x20\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\x55\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00\x28\x2d\x0f\x53\ +\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\x01\xbb\x00\x00\x01\xbb\x01\ +\x3a\xec\xe3\xe2\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\x0e\x50\x4c\x54\ +\x45\xff\xff\xff\x00\x4e\x00\x00\x49\x00\x00\x55\x00\x00\x4c\x00\ +\x00\x4f\x00\x00\x4d\x00\x00\x4e\x00\x00\x4d\x00\x00\x4b\x00\x00\ +\x4e\x00\x00\x4d\x00\x00\x4c\x00\x00\x4d\x00\x00\x4c\x00\x00\x4e\ +\x00\x00\x4c\x00\x02\x50\x02\x04\x53\x04\x04\x53\x04\x03\x52\x03\ +\x02\x4e\x02\x02\x4e\x02\x02\x4d\x02\x02\x48\x02\x00\x5b\x00\x13\ +\x64\x12\x01\x5b\x01\x0e\x68\x0c\x17\x66\x15\x17\x69\x15\x15\x6b\ +\x12\x11\x6b\x0e\x0e\x68\x0b\x09\x5f\x07\x12\x6b\x10\x10\x5c\x0d\ +\x18\x5d\x14\x17\x56\x11\x1a\x54\x12\x1c\x50\x11\x1c\x50\x14\x2c\ +\x84\x23\x47\xba\x0e\x4a\x8d\x30\x4d\x7d\x29\x4e\x82\x2d\x4e\x8b\ +\x31\x50\xac\x2a\x54\x83\x2d\x57\xc2\x18\x58\xa0\x42\x59\x9f\x41\ +\x5b\x9c\x3f\x5d\xb2\x2d\x64\xb1\x50\x64\xba\x32\x73\xb4\x64\x76\ +\xb5\x63\x76\xbc\x59\x77\xc0\x55\x79\xb8\x61\x7b\xbb\x66\x7f\xc0\ +\x68\x7f\xc8\x35\x82\xc6\x45\x83\xc2\x4a\x88\xc2\x7a\x89\xbd\x4b\ +\x89\xc6\x7b\x8a\xc1\x57\x8a\xc1\x5b\x8e\xc4\x60\x8e\xc7\x44\x8f\ +\xc9\x5c\x90\xbd\x6b\x90\xc1\x6f\x91\xc5\x69\x91\xde\x3e\x93\xc6\ +\x70\x93\xc8\x6a\x96\xc3\x6c\x98\xd5\x47\x99\xd0\x8f\x99\xd2\x90\ +\x9a\xc8\x68\x9a\xcb\x7b\x9d\xc9\x6d\xa6\xd0\x77\xb6\xea\xa1\x29\ +\xec\xef\xa8\x00\x00\x00\x2b\x74\x52\x4e\x53\x00\x0d\x0e\x18\x1b\ +\x1d\x21\x24\x32\x33\x34\x35\x36\x46\x6b\x6c\x72\x8d\x90\x91\x95\ +\x9a\x9d\xa0\xa3\xbc\xd6\xd8\xdb\xe6\xe7\xe9\xeb\xed\xf5\xf5\xf6\ +\xf7\xf9\xf9\xfa\xfa\xfe\x0d\x0e\xc0\xf1\x00\x00\x00\x82\x49\x44\ +\x41\x54\x18\xd3\x63\x60\x20\x05\xb0\x0a\x30\xa1\xf0\xd9\x14\xad\ +\xa4\x19\x91\xe5\x15\xc2\x22\x6d\x25\x41\x2c\x7e\x65\x61\x20\xc9\ +\x22\xef\x1f\x12\xec\x23\x05\x64\xf1\x69\x45\x18\x0b\x31\x30\xcb\ +\xf9\xba\x3a\x7b\x2b\x71\x00\x05\x64\x42\x2d\x03\x4c\x44\x64\x3d\ +\xec\xed\x02\x55\x38\x41\x3a\x04\x75\xdc\xcd\xbd\x4c\xdd\x6c\xac\ +\xc3\x55\xb9\x20\xa6\x89\xea\x3b\x19\x38\x5a\x98\xb9\xa8\x71\xc1\ +\xcc\x17\xd3\x73\xd0\x36\xf2\x54\xe7\x46\xd8\x28\x6e\xe8\x17\xa4\ +\xc9\x8d\xec\x26\x09\x5d\x0d\x1e\x54\x57\xf3\xb2\x13\xef\x43\x00\ +\x7e\xc7\x0f\xc0\x9e\x2e\x4f\x77\x00\x00\x00\x00\x49\x45\x4e\x44\ +\xae\x42\x60\x82\ +\x00\x00\x02\x80\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x03\x00\x00\x00\x28\x2d\x0f\x53\ +\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\x01\xbb\x00\x00\x01\xbb\x01\ +\x3a\xec\xe3\xe2\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\x17\x50\x4c\x54\ +\x45\xff\xff\xff\x80\x00\x00\xa8\x00\x00\xad\x00\x00\x87\x00\x00\ +\x8a\x00\x00\x91\x00\x00\x98\x00\x00\x9c\x00\x00\xaa\x00\x00\x80\ +\x00\x00\xa8\x00\x00\xaf\x04\x04\x9c\x00\x00\x87\x0e\x0e\x8e\x00\ +\x00\x6e\x00\x00\x6d\x00\x00\x6a\x00\x00\xa2\x00\x00\x96\x2b\x2b\ +\x7f\x1e\x16\x82\x24\x1b\xd2\x78\x75\xc3\x4a\x49\xc9\x60\x5d\x9d\ +\x1f\x1c\xbf\x34\x2a\xc5\x47\x3f\xa4\x1f\x13\xa4\x1f\x15\xa4\x21\ +\x1a\xa4\x23\x1e\xa5\x1e\x12\xa6\x1e\x10\xab\x24\x17\xaf\x27\x1b\ +\xb3\x31\x26\xb3\x2b\x1f\xbe\x4a\x3f\xc3\x4a\x40\xc8\x4c\x43\xca\ +\x56\x4c\x80\x23\x21\x81\x23\x21\xa1\x3e\x34\xb2\x43\x3a\x6a\x23\ +\x1f\x6a\x23\x20\x7b\x3c\x32\x59\x21\x1c\x5b\x21\x1b\xbd\x00\x00\ +\xbe\x00\x00\xbf\x39\x33\xc1\x11\x0a\xc2\x33\x33\xc2\x4d\x48\xc3\ +\x3a\x3a\xc5\x39\x32\xc6\x12\x0c\xc7\x12\x0c\xc9\x3e\x3e\xcb\x44\ +\x3f\xcb\x4e\x4a\xcc\x46\x46\xd0\x00\x00\xd0\x12\x0c\xd3\x56\x56\ +\xd3\x57\x54\xd3\x65\x60\xd4\x62\x5e\xd6\x60\x5d\xd7\x63\x61\xdb\ +\x13\x10\xdb\x14\x11\xdf\x13\x0f\xdf\x14\x12\xdf\x68\x61\xe3\x00\ +\x00\xe5\x2f\x2a\xe5\x30\x2c\xe5\x32\x2d\xe5\x32\x2e\xe5\x73\x71\ +\xe6\x6d\x6d\xe6\x76\x75\xe9\x8d\x89\xef\x14\x12\xef\x15\x13\xef\ +\x89\x87\xf0\x8d\x8a\xf5\x00\x00\x63\x8e\x41\x21\x00\x00\x00\x34\ +\x74\x52\x4e\x53\x00\x32\x32\x32\x48\x48\x48\x48\x48\x48\x49\x49\ +\x49\x4a\x4b\x4f\x50\x51\x52\xd0\xd7\xdd\xde\xe4\xe6\xea\xf2\xf4\ +\xf5\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfa\xfb\xfb\xfb\xfb\xfb\xfc\ +\xfc\xfc\xfc\xfd\xfd\xfd\xfe\xfe\xd5\x6e\xde\x62\x00\x00\x00\x9b\ +\x49\x44\x41\x54\x18\x19\x8d\xc1\x45\x16\x82\x00\x00\x05\xc0\x0f\ +\x28\xd8\x22\x76\x77\x77\x62\x07\x62\x77\xe7\xfd\xcf\xa1\xf0\x74\ +\xcf\x0c\x14\xa1\xdc\x06\x7c\x19\x9c\x14\x64\xa4\xf7\x99\xd1\x02\ +\xfa\xf4\xcb\x47\x42\x62\xdd\x5e\xae\x29\xa3\xb9\x70\xbe\xdc\xac\ +\x90\x68\x12\x13\x71\x91\x2f\xcf\xc4\x79\x52\x03\x19\x13\x1b\xf4\ +\x87\xad\xd1\x34\xce\xe0\x87\x8e\x76\x9a\xed\x46\x84\xc6\x9f\x3a\ +\xcc\xd7\xea\x7c\x58\x8d\x1f\x95\x7f\x2c\x74\x7b\xc2\x38\xa0\x82\ +\x4c\x17\x5c\xef\x96\xd5\xca\x6a\xb7\x09\x99\x20\xb1\xef\xdf\xf7\ +\x22\xcb\x95\x1e\xef\x83\x0d\x12\xc2\x73\xcc\xb2\x00\x97\x3b\x79\ +\x08\xc8\x08\x87\x05\x5f\x9c\x8b\x80\x12\x1f\x43\xb3\x13\x6b\xf7\ +\xb4\x66\x64\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x01\x4c\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\ +\x01\x3a\xec\xe3\xe2\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\x49\x44\ +\x41\x54\x78\xda\xed\x92\xb1\x0e\x82\x30\x10\x86\xaf\x40\x45\x49\ +\xdc\x74\x32\x0e\xc4\xd1\xa7\xe0\x59\x90\xdd\xc9\xb8\x3b\x3b\xaa\ +\x13\x8b\x2f\xd2\xd5\x89\x37\x60\x73\x23\x62\x08\x68\x8c\x05\xea\ +\x4f\x42\x24\x3a\xe8\xe0\xe2\xc0\x97\xfc\x49\xff\xbb\xcb\xdd\x35\ +\x2d\x53\x4a\xd1\x2f\x68\x50\xdb\xa0\x81\x41\x06\x7d\xc7\x80\x58\ +\x63\x6a\x0e\x9e\xb7\xba\x85\xe1\x22\x11\x82\x9b\xf0\x95\x3a\xd0\ +\xfb\xb9\xef\x38\xb9\x65\xdb\xeb\x9e\xef\x2f\x09\x3c\x9f\x71\xcf\ +\xf9\x71\xea\xba\x23\x3d\x4d\xa9\x0b\xcf\x6b\xe9\x50\x45\x69\x59\ +\x74\x46\xee\x1a\xc7\x34\x11\xe2\x34\x94\x72\xf0\xb2\xc1\x3d\xcf\ +\xe9\x12\x45\x64\x4a\x49\xba\x61\x90\x86\xc6\x5a\x51\x10\x21\x5e\ +\x22\x9f\x04\x01\xc5\x59\x86\x55\x3a\x24\x11\xab\x69\x36\xd8\x31\ +\x36\xc3\xe4\x8d\x59\x95\xc0\x7f\xb8\x86\x44\xdd\x7c\xac\xd4\x96\ +\x40\xfb\x13\xff\xa1\xc1\x03\x06\xaf\x45\x37\x07\xf3\x26\xc3\x00\ +\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\x34\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x01\xbb\x00\x00\x01\xbb\ +\x01\x3a\xec\xe3\xe2\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\xb1\x49\x44\ +\x41\x54\x78\xda\xa5\x93\x4d\x6b\x13\x51\x14\x86\x9f\xfb\x35\x49\ +\xda\x49\x4c\x69\xdd\xb8\x48\x10\x5d\x98\xb5\x82\x15\x44\x11\x44\ +\xe8\x3f\x70\xe7\x22\xfa\x03\xc4\x8d\x1b\x5b\x74\xd3\x95\x60\x41\ +\xff\x40\x11\x5c\xe9\x42\x90\x52\x17\x6e\xc4\x2e\xea\x07\x08\x82\ +\x54\xb4\x01\x15\x44\x71\x4c\x33\x36\x93\x74\xe6\xde\x3b\x42\x45\ +\x70\xe1\x44\x42\x9f\xed\xcb\x79\x38\xbc\x9c\x23\xf2\x3c\x67\x2f\ +\x48\x0a\xb8\xb6\x7e\xf9\xee\x99\x87\xad\xc1\xd9\x47\x47\xa2\xe5\ +\x77\x4b\x77\x28\xa0\x70\x83\xf3\xab\x73\x7e\xee\xe0\x39\x91\xba\ +\x21\xaf\xa3\x17\xf6\xf6\xc9\xfb\x66\xac\x0d\x5e\x7e\x7d\x2e\xbc\ +\x19\x52\xaa\x68\xde\x6e\xbd\xd1\x14\x50\x18\x64\xde\xf1\x73\x27\ +\x41\x48\x49\xea\x1c\xff\x13\x08\x40\x01\xf6\x4f\x60\x9d\x27\x4e\ +\x07\x08\x04\x99\x75\xff\x9a\x73\x40\xae\x01\xda\x2b\xed\xc5\x4e\ +\xdc\xb9\xf2\xec\xcb\x53\x1d\x28\x4d\xa0\x15\x46\x49\x92\x6c\x88\ +\x14\x82\x1d\x97\x31\xfb\xa0\x99\x57\x8c\xa1\x12\x18\x8e\xee\x3f\ +\x61\x1b\xb5\xe6\xcd\x4b\x87\x17\xae\xee\x96\x68\x16\xcd\xf7\x8b\ +\xc7\x2e\x4c\xa3\x1c\xb9\xf2\x08\x29\x7e\x0b\x7c\xbc\x2b\xa8\xeb\ +\x3a\x52\x6a\x4a\x84\x44\xfd\x1e\x71\xf2\x83\x6c\x72\x33\xba\x77\ +\xfa\xd5\x8c\x06\xb0\xd6\xb2\x19\x75\xd0\x81\xc6\x94\x15\xb5\x52\ +\x88\x91\x82\xbe\xdb\x46\x49\x30\xb9\x21\x49\x13\x36\xa2\x0f\xf4\ +\x06\x03\xa6\x82\x2a\x33\x41\xfa\x57\x07\x9e\xf9\xc7\xef\x9f\xdc\ +\x42\x63\xd0\x60\xb4\x24\x50\x8a\xd9\x66\x8b\xc9\x20\x60\xed\xe3\ +\x3a\x65\xa3\x29\x69\x4d\x35\xd4\x98\x20\xce\xac\xd5\xf3\x23\xef\ +\xa0\xbc\x64\xf2\x53\x87\x5a\x4c\x4d\x94\x59\xeb\x6c\xf0\xa9\xdd\ +\x13\x63\xdd\x81\xf3\x9e\xcc\x65\x48\x01\x99\xf7\x14\xa1\x47\x09\ +\xbe\x6d\xf7\xc8\x85\xc7\xba\xb1\x05\xd7\x65\x23\xac\xe7\x9f\xbb\ +\x5d\xd1\xed\x67\x84\x76\x9f\x1d\xf3\x99\x16\xfc\xf1\xe9\xea\x32\ +\x30\x3c\x30\xd1\xd8\xaa\xf9\xda\x8d\x91\xcf\xb4\x17\x7e\x01\x5f\ +\x22\xaf\xac\xbe\x86\x35\xeb\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ +\x42\x60\x82\ +\x00\x00\x04\x79\ +\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\x03\x76\x00\x00\x03\x76\x01\ +\x7d\xd5\x82\xcc\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\x02\x1f\x50\x4c\x54\ +\x45\xff\xff\xff\xff\xff\xff\x00\x00\x00\x80\x80\x80\xff\xff\xff\ +\x00\x00\x00\x00\xa8\x00\x2e\x2e\x2e\xaa\xaa\xaa\x80\x80\x80\xc0\ +\xc0\xc0\x66\xa8\x66\x00\x00\x00\x00\xa8\x00\x00\x00\x00\x00\xa4\ +\x00\x00\x00\x00\x00\x00\x00\x00\x95\x00\x00\x9f\x00\x00\x00\x00\ +\x90\x90\x90\x00\x00\x00\x00\x9a\x00\x00\x00\x00\x00\x00\x00\x00\ +\x95\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x9f\ +\x00\x00\x00\x00\x00\x00\x00\x00\xa4\x00\x00\x00\x00\x00\x00\x00\ +\x2c\x2c\x2c\x00\xa8\x00\x71\x71\x71\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\xad\x00\x00\xb2\x00\xbc\xbc\xbc\xc8\xc8\xc8\x00\xb7\ +\x00\xd3\xd3\xd3\xdb\xdb\xdb\x00\xbc\x00\x00\xbc\x00\x00\xb7\x00\ +\x00\xb2\x00\x6f\x6f\x6f\x01\xac\x01\xbc\xbc\xbc\xd0\xd0\xd0\x00\ +\xa8\x00\x00\xad\x00\x93\x93\x93\xbf\xbf\xbf\x00\xad\x00\xc9\xc9\ +\xc9\x00\x95\x00\xb9\xb9\xb9\x00\x9a\x00\xcb\xcb\xcb\xcc\xcc\xcc\ +\x00\xa8\x00\xce\xce\xce\xb2\xb2\xb2\xd1\xd1\xd1\xd6\xd6\xd6\x81\ +\x81\x81\xa5\xa5\xa5\x00\xa4\x00\xa4\xa4\xa4\xd0\xd0\xd0\xa1\xa1\ +\xa1\xc7\xc7\xc7\xdb\xdb\xdb\xa1\xa1\xa1\xc5\xc5\xc5\xc1\xc1\xc1\ +\x00\x9f\x00\xbe\xbe\xbe\x93\x93\x93\xb3\xb3\xb3\x00\x9a\x00\xb4\ +\xb4\xb4\xb4\xb4\xb4\xb4\xb4\xb4\x86\x86\x86\x87\x87\x87\xda\xda\ +\xda\xb4\xb4\xb4\xd7\xd7\xd7\x76\x76\x76\x92\x92\x92\x99\x99\x99\ +\xaf\xaf\xaf\x86\x86\x86\x8b\x8b\x8b\x00\x9f\x00\x00\xa4\x00\x3e\ +\xa9\x3e\x7e\x7e\x7e\xde\xde\xde\x76\x76\x76\xde\xde\xde\x00\xa8\ +\x00\xc8\xc8\xc8\xd5\xd5\xd5\x00\xad\x00\x00\x9a\x00\x00\x9f\x00\ +\x00\xa4\x00\x00\xa8\x00\x00\xad\x00\x00\xb2\x00\x00\xb7\x00\x54\ +\xb5\x54\x83\xc7\x83\x9b\x9b\x9b\x9d\xc8\x9d\xa6\xa6\xa6\xa9\xa9\ +\xa9\xb3\xb3\xb3\xc0\xc0\xc0\xc1\xc1\xc1\xc3\xc3\xc3\xc6\xc6\xc6\ +\xc8\xc8\xc8\xc9\xc9\xc9\xca\xca\xca\xcc\xce\xcc\xcd\xcd\xcd\xce\ +\xce\xce\xcf\xcf\xcf\xd0\xd0\xd0\xd1\xd1\xd1\xd2\xd2\xd2\xd3\xd3\ +\xd3\xd4\xd4\xd4\xd6\xd6\xd6\xd7\xd7\xd7\xd8\xd8\xd8\xda\xda\xda\ +\xdc\xdc\xdc\xdd\xdd\xdd\xde\xde\xde\xdf\xdf\xdf\xe0\xe0\xe0\xe1\ +\xe1\xe1\xe2\xe2\xe2\xe3\xe3\xe3\xe5\xe5\xe5\xe6\xe6\xe6\xe7\xe7\ +\xe7\xe8\xe8\xe8\xe9\xe9\xe9\xea\xea\xea\xeb\xeb\xeb\xec\xec\xec\ +\xed\xed\xed\xee\xee\xee\xef\xef\xef\xf0\xf0\xf0\xf1\xf1\xf1\xf2\ +\xf2\xf2\xf3\xf3\xf3\xf4\xf4\xf4\xf5\xf5\xf5\xf6\xf6\xf6\xf8\xf8\ +\xf8\xf9\xf9\xf9\xfa\xfa\xfa\xfb\xfb\xfb\xfc\xfc\xfc\xfd\xfd\xfd\ +\x1c\xd4\xc3\xad\x00\x00\x00\x73\x74\x52\x4e\x53\x00\x01\x02\x02\ +\x02\x03\x03\x03\x03\x04\x04\x05\x07\x08\x0a\x0d\x0f\x13\x13\x14\ +\x1a\x1a\x1b\x1c\x22\x23\x25\x2b\x2c\x33\x36\x38\x3d\x3f\x42\x46\ +\x49\x49\x4d\x4d\x50\x53\x55\x58\x65\x69\x6c\x72\x7a\x7c\x80\x89\ +\x8c\x8f\x91\x94\x9d\x9f\xa5\xa9\xab\xaf\xb1\xba\xbb\xbc\xbd\xbd\ +\xbd\xbf\xbf\xc1\xc1\xc2\xc3\xc7\xcb\xcd\xcd\xcf\xd3\xd3\xd4\xd4\ +\xd5\xd6\xd7\xd9\xde\xe0\xe0\xe2\xe4\xe5\xe5\xe6\xe8\xe8\xe9\xea\ +\xea\xea\xeb\xeb\xf3\xf7\xf7\xf9\xf9\xfa\xfa\xfb\xfc\xfc\xfd\xca\ +\xc5\x05\x0d\x00\x00\x01\x4d\x49\x44\x41\x54\x18\x19\x85\xc1\x05\ +\x4f\x02\x01\x00\x06\xd0\xcf\x06\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb\ +\x3b\xc1\x6e\xc5\x44\xc0\xc6\xe3\x3c\x44\x41\x45\x44\xd1\x1f\x28\ +\xba\x9d\xb2\xe9\xe6\x7b\xc0\xff\x98\x19\xd9\x86\x80\x4d\xac\x0f\ +\x34\x31\x6b\x79\xfc\x8e\xd0\xd2\x22\x3f\x03\x68\x60\x54\x9f\x48\ +\x76\x8f\x47\x27\x2a\xa0\x89\x51\x25\x14\x5c\xc9\xf7\x4f\x87\x23\ +\xa0\x81\x51\x2e\xa2\xa4\x5c\xf2\xe9\xe0\xb2\x4d\x17\x3f\x52\x6e\ +\x88\x0b\xe9\x3d\x8f\x52\x70\x89\x34\x7c\x4b\xa8\x3c\x56\x12\xc2\ +\x87\x47\xfe\xad\x6c\x3b\x0f\xb4\x82\xd7\xe7\xee\xc3\x57\x52\x24\ +\x57\x08\x38\xf5\xa0\xe5\x2b\xdf\x48\x49\x17\x47\x25\xa6\x28\x4e\ +\x23\x68\xb9\xf2\xcb\xc7\x37\xd1\x59\xdf\xfa\xfb\xf9\x56\x13\x68\ +\x59\x77\xb2\x17\x81\x54\x25\xdc\xeb\x5d\xd9\x6c\x06\x2d\xfe\x5a\ +\xc6\xbb\x53\xf2\x25\xaa\x8b\x8d\x96\x32\x00\x8e\xe9\x96\x50\x4b\ +\xde\x95\x48\xb9\xe2\xe7\x23\xea\x69\xaf\x04\x80\x5d\xc3\x54\x26\ +\xd4\xb4\x5a\xd7\xc4\xb7\x5c\x52\xb1\xb4\xd3\xce\x00\xac\x6a\xa6\ +\xfb\xdd\xf0\x29\x7c\x68\x95\x14\xef\x2f\xcc\x0c\x1a\x01\x66\xc5\ +\x33\x03\x9e\xf8\x52\x31\x3e\xb2\x4c\x10\xf3\x2c\x56\xa2\xbe\x49\ +\x0e\x6b\xcc\x17\x9f\x0c\xfc\x8a\x4a\x43\x3a\x17\x37\x7a\xe2\xd8\ +\xec\xa4\x54\xf6\x64\x10\xbe\xf8\xc4\xda\x00\x3a\x85\x75\x4c\xc4\ +\xcc\xaa\x05\xe3\x97\xe8\xb9\xb9\x30\xfc\x21\x2a\x12\x34\x3d\x53\ +\x0b\x5b\x07\x67\x57\x0f\xef\x80\x40\x7f\x2f\x77\x17\x27\x7b\x6b\ +\x73\x63\xed\x0f\xd9\x76\x6a\x8d\x75\xa6\xff\xe4\x00\x00\x00\x00\ +\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\xaf\ +\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\x06\x00\x00\x00\xc4\xb4\x6c\x3b\ +\x00\x00\x03\x76\x49\x44\x41\x54\x78\xda\xd5\xd5\x5f\x4c\x5b\x55\ +\x1c\x07\xf0\xef\x2d\x77\x85\xe6\xb6\x96\x95\xae\x80\x6b\x32\x62\ +\xc3\x20\x0b\x23\xfb\x47\xc8\xd2\x2c\x63\x2b\xe9\x6c\x0a\xed\xa0\ +\x16\x0a\x2c\x5b\x44\x10\xd2\xe8\xc4\x60\x66\xaa\x10\x8a\x0b\xd8\ +\x09\x41\x29\x30\xda\x75\xce\x62\xe9\xfe\x91\x39\x15\x97\x80\xb0\ +\x89\x92\x98\x2c\xfa\x62\x7c\xf0\xd1\x64\x06\x13\x5f\xe6\x83\xba\ +\x3d\xa8\xf7\xeb\x89\x5d\xe2\x43\xd9\xe2\x9f\xed\xc1\x87\x4f\x72\ +\xee\xcb\x37\x27\xf7\x7b\xce\xef\x80\xe4\x23\xf1\xe8\x83\xe1\x42\ +\x33\x6a\xb1\x00\xa7\xf0\xa4\xe0\x12\xdc\x42\x3d\x16\xe1\x15\x0e\ +\x4b\x1f\xa3\x51\x5a\xc2\x53\xd2\x32\xfc\xd2\x75\x34\x49\x37\xd0\ +\x2c\x7d\x82\x80\xd0\x22\xad\xa0\x55\xfa\x14\x2f\x68\x8e\x67\x05\ +\x3b\xfb\x9d\x3f\xf4\x26\x7a\x19\x9c\x0e\xb2\x7d\xaa\x9d\x6d\x93\ +\x6d\xf4\x4f\xf9\xe9\x3d\xed\xa5\x2b\xe6\xe2\xd6\x48\x19\xf3\xfa\ +\x75\x54\x86\xf4\x34\x9c\x7a\x8c\xc6\x91\x8d\x34\x8d\x98\x69\x1e\ +\xb1\xb0\x30\x52\xcc\x2d\x91\x27\x58\x10\x2f\xbc\x93\xbd\xe3\x3a\ +\xb4\xdb\x7b\xed\x6a\xe8\x4a\x88\x9d\xef\x74\xd2\x37\xe9\xe3\x81\ +\x37\x0e\xb0\xf2\xb5\x4a\x5a\xfb\xad\x34\xf7\x99\x89\x57\x40\x0c\ +\x0a\xc3\x42\x44\x78\xfd\xde\x77\x48\x08\xe7\x10\x63\xf2\x5b\xeb\ +\xfe\x63\x78\x30\xe9\x8d\x78\xd9\x9d\xee\x66\x53\xa2\x89\xb5\xd1\ +\x5a\xee\x1a\xdd\xc5\x92\x48\x09\x2d\x11\x4b\x26\xf0\x4d\xe1\xb4\ +\x10\x17\x62\x42\x14\xb4\x4c\x17\x51\x1a\xdf\xb0\x72\xdf\xf2\x00\ +\x48\x1a\x8f\x66\xa5\x25\xd6\xa2\xb6\xce\xb4\xf2\x50\xfc\x10\xab\ +\x26\xab\x68\x1b\xb7\xb1\x30\x5a\xf8\x67\x08\xce\x0a\x69\xe1\x92\ +\x70\x11\x34\xce\xe6\xab\xb9\x51\xfd\x2d\x84\x91\xf7\xc0\x53\x81\ +\xc3\xc8\x37\x1e\x35\x7e\x17\x98\x09\xa8\xee\xa4\x9b\x7b\x13\x7b\ +\x59\x16\x2f\x63\xf1\x99\x62\x22\x01\xe2\x82\xf0\xa1\xb0\x08\xea\ +\x16\x75\xaa\x3e\x66\xfc\x19\xaf\x6a\xcb\xef\x7b\x2a\xb4\x8d\xda\ +\x85\xfc\x40\xfe\x9a\xa1\xd9\xb0\xa6\x6f\xd5\xdf\x2e\x7d\xb9\x94\ +\x9e\x59\x0f\xf7\x25\xf7\x71\xdb\xb9\x6d\xb4\x26\xad\xc4\x0c\x88\ +\xf7\x85\xeb\xa0\x7c\x53\x66\xc9\x7b\x36\x6e\x4a\x14\xdd\x29\x4e\ +\x58\x6f\x5b\x13\x5b\x7e\x34\x4c\x98\xbe\xce\x0a\xb6\x3e\x6d\x5d\ +\x1d\x5e\x18\x66\xe4\xf3\x08\x4f\x2c\x9e\x60\xc7\xd5\x0e\x36\x5e\ +\x68\x64\x4d\xaa\x86\x95\xef\x56\xb2\x24\x5d\x42\xa4\x40\xcc\x0b\ +\x9f\x09\x5f\x09\xdf\x08\xab\xc2\x55\xb0\x20\x69\xe6\xe3\x31\xcb\ +\xad\xac\x60\x38\x50\x60\x6e\x35\x7f\x3f\xb8\x34\xa8\x86\x96\x43\ +\xec\xfa\xa0\x8b\xfe\xcb\x7e\x3a\xd2\x0e\xee\x4c\xed\xa4\x2d\x6d\ +\xfb\x6b\xc7\x37\x84\x9b\xc2\x17\x99\xb5\x72\x45\x51\x8d\x51\xd3\ +\x2f\x08\x6b\xcb\xd7\x2f\xcf\x85\xaa\xb2\x60\xd9\xdd\xfe\xe5\x7e\ +\x35\x38\x1f\x64\x60\x2e\x40\x67\xda\xc9\x3d\xa9\x3d\x2c\x9f\x2d\ +\xcf\x14\x77\x49\xf8\x48\x58\xca\x90\xe7\x65\xd5\x14\xb3\xfc\x86\ +\x81\x9c\xc0\x83\xcb\xf3\xa0\xc3\xde\x67\x57\x7b\xae\xf5\xf0\xc8\ +\xdc\x11\xba\x66\x5d\xac\x4e\x56\xb3\x62\xa6\x82\x98\x00\x71\x4e\ +\x38\x2f\xcc\x09\x97\xc1\x4d\x67\x8b\x88\xb0\x3c\xba\x7e\x79\xd9\ +\xe1\xd3\x75\x63\x75\x3c\x36\x77\x8c\xf5\xa9\x7a\xda\xdf\xb6\xb3\ +\x22\x51\x41\xf9\x94\x4c\x8c\xdf\x3b\xbf\x09\x70\x63\xdc\x44\x29\ +\x2c\x2f\xff\xed\x21\x04\x42\x92\x1b\xe4\x55\x71\x9d\xd5\x86\x64\ +\x03\xf7\xc7\xf7\x73\xfb\xc4\x76\xea\xc2\x3a\xe2\x64\xe6\xd6\x29\ +\x63\x7a\x55\x7b\x52\xf7\x2d\x8e\x23\xf7\x1f\x4d\x37\xd4\xc0\xac\ +\xb4\x29\x6b\xee\x29\xb7\x7a\x70\xf2\x20\x77\x8c\xee\xa0\xae\x57\ +\x04\xbf\x04\x6a\xfb\xb4\xbf\xe7\x0d\x28\x3f\xa1\x07\xa5\xff\x6a\ +\x6c\xc2\x83\x2a\x53\xa7\xe9\xae\x63\xcc\xa1\xee\x1e\xda\xcd\xdc\ +\x8e\x5c\x6a\xba\x34\xaa\x12\x32\xfc\x8a\x60\x8e\xef\x3f\xcd\x63\ +\xf8\xf0\xec\xe6\xe7\x37\xab\xd5\x03\xd5\x94\x7d\x32\x95\xe7\x0c\ +\x44\x50\x33\xf4\x50\x06\x3d\x02\x9a\x33\xa5\x2f\x6e\xa5\xd2\xa2\ +\x27\xba\xa5\x6b\x0f\xed\x05\x01\x21\x49\x47\x35\x4b\xf2\x33\x1b\ +\xbe\xcc\x2e\x6b\x7d\xff\xbf\x37\xef\x0f\x9a\xca\x63\x9c\x02\x93\ +\x79\xca\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x04\x4d\ +\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\x06\x00\x00\x00\xc4\xb4\x6c\x3b\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\x1b\xaf\x01\ +\x5e\x1a\x91\x1c\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd9\x01\x04\ +\x03\x32\x2d\xe1\x0e\xef\xfd\x00\x00\x03\xcd\x49\x44\x41\x54\x78\ +\xda\x9d\x93\x6b\x4c\x93\x67\x14\xc7\xcf\xdb\xf6\x6d\x29\xa3\xd2\ +\x95\x44\x4a\x69\x55\x70\x8b\x09\xac\xb4\x23\x23\x63\x86\xb9\x76\ +\xa3\x33\x23\xcb\x5c\xc2\x30\x5b\x36\x2f\x21\x20\x2e\xdb\x90\xf5\ +\xa2\x36\x59\x84\xc4\x1b\x51\xdc\xb2\x01\x9b\x92\x98\x52\x34\x31\ +\x26\x04\x9b\x08\xd8\x02\x51\x54\x3e\xcc\x81\x26\x58\x19\x1a\x1d\ +\xa0\x64\xd6\xae\x17\xe8\x4a\x97\xb5\xef\xe5\xd9\xc1\x84\xc4\x0f\ +\x33\xb6\x3d\xc9\x3f\x79\x72\xce\x3f\xbf\xf7\xbc\xe7\x3c\x0f\x05\ +\xa9\x07\x65\xb5\x5a\xf4\x26\x93\xa9\x31\x33\x33\xb3\x9c\xe3\x39\ +\x71\x34\xfa\xf7\x83\x50\x28\x78\xde\xe1\x70\x9e\xbd\x3a\x7a\x2d\ +\x01\xe9\x40\x9b\x9b\x0f\xd4\xfa\x9e\xf8\x12\x1c\xc7\x92\x48\x24\ +\x42\x66\xe7\x66\xc9\xcd\x5b\x13\xa4\xef\x42\x2f\x6f\xb1\x7d\xdb\ +\x8e\x1e\x51\xca\xd4\x77\x2b\x8d\xeb\x2f\xb9\x07\xff\x09\x04\x03\ +\x24\xfe\x6f\x9c\x2c\xc5\x96\x48\x6b\xeb\x51\xae\xac\xec\x8d\xfb\ +\x34\x4d\xff\x80\x96\x37\x51\x42\x48\x95\x2e\x7b\x29\x6b\x4b\x76\ +\xb6\x4c\xca\x71\x1c\x30\x6c\x02\x28\x8a\x82\x41\xb7\xfb\xcc\xf8\ +\xf8\x84\x1d\xcb\x01\x14\xbb\xe2\x15\xa4\xc0\x15\xca\x5f\x96\xbf\ +\x35\x33\x33\x07\x84\x10\x60\x18\x06\x58\xfc\x80\x4a\xa9\x9c\xc6\ +\xda\x93\x15\x68\x3a\x60\x69\x51\x51\x51\xd9\xf4\xf4\xef\xc0\xb2\ +\x0c\x8a\x05\x96\x61\x61\xdb\xf6\x6d\x95\x6b\xd7\xad\xa5\x9f\x35\ +\x9a\xad\x4d\xd9\xc2\x64\xa9\x6f\x6f\xaa\x78\xad\xaa\xaa\xca\x16\ +\x0c\x86\x28\x69\x86\x14\x54\x2a\x15\xe0\x02\x21\x23\x53\x5a\x88\ +\xe3\xd9\x58\xac\x2d\x1a\x6d\x6c\x6c\x5c\xdf\xb0\xbb\xe1\xd0\xc2\ +\xc2\xe2\xe1\x64\x3b\xa6\x0c\x06\xc3\x87\x08\xa3\xf2\xf3\xf3\xa1\ +\xef\x82\x0b\x8e\x1e\x6b\xc3\xae\x11\x2c\x91\x80\x5a\xad\x79\x2f\ +\x43\x22\xbd\xbb\xe1\xd5\x0d\x13\xaa\x3c\x55\xed\xf5\x6b\xd7\x17\ +\x92\x05\x4b\xb4\x5a\x6d\xf5\x83\x3f\x66\xa1\xcf\xd5\x0f\xfa\xd2\ +\x52\xe8\x77\xbb\xe1\xb6\xd7\x0b\x40\x00\x34\x1a\x0d\x64\x65\x65\ +\x49\x69\x09\x4d\xfd\x7a\xe3\x06\x3b\x34\x34\x7c\x2e\x19\x30\xd5\ +\xd2\xd2\x5c\xa3\xd7\xe9\x4b\xb4\xc5\xc5\xf0\xa7\xcf\x07\x42\x81\ +\x00\x0a\x0b\x0a\xe0\x7c\x6f\x2f\xf0\x3c\x0f\x72\xb9\xfc\xe9\x0d\ +\xb9\x77\xf7\x1e\xb1\xef\xb3\x7b\x30\x77\x4e\xf4\x22\x68\x67\x67\ +\xc7\x67\xe5\xe5\xe5\xa7\xfc\x7e\x3f\x60\xd7\xf0\xc1\x66\xd3\xf2\ +\x15\x83\x75\xea\x7c\xd0\xeb\x4a\x40\x2c\x11\x43\x20\xe0\x87\x70\ +\x28\xcc\x7c\xde\xf2\xc5\x40\x22\x91\xb0\x03\x80\xff\xb9\x4f\xba\ +\x44\xa7\x15\x5a\xcc\xe6\xef\x84\xb4\xf8\xc0\x19\x67\x8f\x60\x31\ +\xb2\x08\xc7\x8f\x1d\x07\x35\x02\x1f\xcd\x3f\xe2\xbb\x4e\x75\xc5\ +\x7c\x8f\x7d\x21\x02\x30\x3f\x36\x36\x36\x89\xf3\x1e\x07\x00\x0f\ +\xea\x2f\x14\xf9\xdf\x8e\x1b\x76\xd7\xcb\x36\xbd\x63\x70\xdc\xf1\ +\xde\xa9\xf6\x78\x3c\x90\xa3\xc8\xc1\x39\xae\x01\x65\x9e\x92\xef\ +\xec\xfc\xf9\xb7\xf6\xf6\xf6\x8b\xd8\xd9\x4d\xb4\xce\xa2\x82\xa8\ +\x25\x14\x83\x22\xf0\xbc\xb0\x58\xcd\xaf\x38\x7b\x1c\x93\x5b\x3e\ +\xfe\x88\x68\xd6\x68\x88\x4e\xaf\x23\x46\xa3\x91\x0c\x0e\x0e\xf0\ +\x7b\x9a\xf6\xf4\xa2\xa5\x10\x25\x7c\xe1\x62\x9e\x3d\xdb\xf6\x5a\ +\x36\x17\x14\x16\x9c\x75\x76\xf7\xe4\xcc\xcd\x3d\x04\x11\x2d\x82\ +\x55\xb2\x55\xb0\x73\xe7\x0e\x5c\x12\xb9\x6a\xdf\x6f\xaf\x45\xdf\ +\x0c\x24\x11\x2b\xa3\xa0\xcd\x96\x26\x8b\x22\x47\x71\xf0\xe4\xc9\ +\x2e\x51\x30\x10\x02\x01\x6e\x9e\x63\x39\xd0\xbd\xae\x03\x85\x42\ +\x71\xbf\xbe\x6e\x97\xed\xe9\xaf\x27\x19\x22\xa5\x32\x57\xf2\xf5\ +\x37\x5f\x76\xac\xce\x55\xd6\x4d\x4d\x4d\x61\x87\x32\x48\xc4\x13\ +\x10\x8b\xc5\x70\x51\x6a\x78\xbf\xd2\x14\xb2\x5a\x6c\x7b\xd1\x7b\ +\x0b\x45\x92\x05\x0b\x2c\x36\xf3\x3e\x96\xe3\xb7\x76\x3b\x9c\xfb\ +\xc3\xe1\xf0\x27\x5b\x3f\xad\x99\x5f\xbe\x97\xf8\xc2\x70\x04\xdb\ +\xe3\x27\xda\xbe\x3f\x8c\xf9\x4b\xe8\xe5\x20\x95\x70\x38\x4f\x7b\ +\x2b\x2a\x36\x0e\xe3\x51\x8e\xa2\xda\x4e\xb4\x7e\xb5\xab\xa1\x9e\ +\xfc\xd4\xf1\x23\x67\x34\x1a\x3a\x30\x97\x0d\x69\x84\x40\x22\x96\ +\x44\x95\x79\x79\xb9\x78\x5e\x96\x30\xce\x30\xab\x4b\x4b\xf5\xe4\ +\xf2\xc8\x88\xeb\xca\x95\xd1\x23\x98\x8b\xa4\x03\x16\x45\xa3\xd1\ +\x5f\x6a\x6a\xaa\x1d\x1a\x8d\xfa\x34\x25\xa0\x1e\xe2\x8c\xab\x47\ +\x46\x2e\x0f\xb8\x5c\x17\xad\x58\x7f\x0c\x69\x06\x85\x12\x1c\x3a\ +\x72\x70\x07\xc3\x24\xea\x70\x61\xd4\xed\x49\x6f\xff\x90\x67\xb8\ +\x1b\xf3\x3e\x14\x49\x17\xfc\x1f\x0d\x85\x8c\x2f\xad\xa0\x3f\x12\ +\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x04\x6e\ +\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\x06\x00\x00\x00\xc4\xb4\x6c\x3b\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x04\xc2\x00\x00\x04\xc2\ +\x01\xbc\xcf\x90\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd7\x0c\ +\x1b\x16\x0c\x0e\xd2\xa1\x06\x61\x00\x00\x00\x06\x62\x4b\x47\x44\ +\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00\x03\xfb\x49\x44\ +\x41\x54\x78\xda\xb5\x92\x5f\x68\x1c\x55\x14\xc6\xbf\xfb\x67\x66\ +\x77\x36\xd9\x90\x0a\x4d\x49\xa4\xa4\x4d\x49\x97\xa0\x60\x12\x23\ +\x44\x1a\x48\x45\xd2\x86\xe0\x43\x8c\x85\x9a\x06\xa1\xad\x10\x34\ +\xa2\x28\x4a\xfc\x83\x88\xa0\x14\x2b\x62\x8d\x4f\x79\x90\x52\xfa\ +\xd4\xa7\xfa\x58\x69\x28\x48\x15\x89\xa2\xd6\xda\x24\x26\x36\x6b\ +\xc2\x6e\x53\x45\xc8\x6e\xb2\xbb\xd9\x9d\xd9\xb9\x33\xe3\x99\xdb\ +\x6c\x5a\xd6\x22\xe2\x9f\x03\x1f\x73\xb8\x73\xbf\xdf\xf9\xf6\xec\ +\xe0\xbf\xa8\x20\x08\x42\xed\x20\xd5\x57\xce\x18\x09\x99\x73\xe7\ +\x76\x7b\xb3\xb3\xa7\xd7\xa7\xa6\x7a\x54\x36\xcb\x83\x8a\x81\xf4\ +\x77\xfb\x7b\xf6\xed\x0b\xb6\xf5\xf7\xff\xbc\xba\xbc\xdc\xbf\x7b\ +\x7c\x3c\x25\x41\xe5\x2d\x2f\x4d\x1a\x07\x0f\xee\x17\x5d\x5d\xe0\ +\x9e\xf7\xd7\xe9\x70\xf7\xf2\xa4\x44\xc1\xf7\xdb\x56\x3f\x3d\xff\ +\x11\x80\x21\x0d\x4e\x9e\x3d\xdb\x1b\x6f\xd8\x01\x55\x2e\xe3\xdf\ +\x94\x13\x8f\x63\x65\x69\xb9\x1f\x54\x1a\x9c\x9d\x5f\x90\x46\x26\ +\x73\xeb\x67\x31\x86\x74\x5d\x1d\x40\xcf\x9d\xb9\x1c\x98\xef\xdf\ +\x3d\x39\xe7\xfa\x5e\x58\x3b\xd7\xd7\xc1\x68\xcf\x4c\x08\x14\x6d\ +\xdb\xdc\x02\x7b\x24\x77\x63\x03\x21\xc2\x4e\x24\xb0\xff\xc0\x01\ +\x30\x02\x7f\x7d\xe1\x02\xea\x92\x49\xa0\x1a\x4e\xd0\x5c\x4b\x0b\ +\x1e\x19\x18\xd0\x7f\xdc\x0f\x17\x2f\x22\xba\xb0\x00\x6e\x9a\xf0\ +\x2a\x57\x48\x50\x9b\x60\x45\x4a\xec\xdd\x4b\x3e\xae\xc1\x5d\x34\ +\xc0\x6e\x6d\x85\x2a\x95\xf4\x3b\x92\xee\x4b\x74\xd6\xd9\xd7\xa7\ +\xa1\x74\x57\x7b\x2a\xef\x14\x63\x55\xe0\x42\x01\x65\xd2\xc2\x99\ +\x33\xb0\xd3\x69\x0a\xe9\x6b\x63\x5b\x6f\x2f\xd0\xd9\x09\x65\x17\ +\xb5\xfc\x8e\x0e\x24\x7a\x7a\xe0\x79\x1e\x94\x52\x28\xa5\x52\xda\ +\x43\x5e\x0d\xd6\x89\xb7\x56\x41\x53\xdd\x62\x51\x83\xc2\xba\x3a\ +\x31\x81\xfb\xc6\xc6\x20\x9b\x9a\xf4\xd9\xae\xee\x6e\xdc\x94\x5c\ +\xf7\x8d\x0f\x3e\x14\x42\x75\xaf\x56\x56\x30\x37\x39\x89\xc0\x75\ +\xa1\x39\x8e\x03\xef\xce\xc4\xbe\x94\x7a\x15\xe5\x8a\xd6\xd6\x30\ +\x77\xea\x7d\xa8\x1b\xa9\x10\xa2\xd3\x37\xb4\x77\x62\xfb\x03\x1d\ +\x61\x4a\x2d\x7f\x25\x8d\x85\x8f\x3f\x80\xca\xad\xc1\xa5\xa4\x3c\ +\x12\x81\x9b\xcf\xa1\x6c\xdb\x77\x24\x16\x1c\x6b\x8b\x8b\x10\x96\ +\x05\x23\x66\x21\x6a\x19\x80\x0f\x24\x4f\xbd\x83\x3d\xcf\xbf\x0a\ +\xbf\xa1\xa9\x32\x40\x27\x8d\xe5\x32\xb8\x71\x7a\x02\xd2\xb3\xe1\ +\xe4\xd6\x91\xff\x3d\x8b\xe4\xcc\x4f\x10\xa6\x01\xb7\xec\xdc\x06\ +\xfb\x04\xce\x5c\xbb\x06\x8f\x92\x58\x51\x81\x78\x7d\x84\x64\xc1\ +\xaf\x8d\x62\xfa\x8b\xcf\xd1\xfe\xf8\x93\x1a\x5a\x81\x5f\xb9\xf4\ +\x19\xc4\xa5\xf3\x70\x8a\x2e\x4a\xc4\x29\x86\x21\x15\xc0\x62\xd1\ +\xea\x55\x08\x80\x01\xc4\x87\x29\x3c\x08\x55\x04\x77\xf2\x58\x7f\ +\xec\x29\x74\x0c\x0d\xeb\x94\xa4\x2d\xf8\xae\x81\x27\xe0\x1c\x7b\ +\x05\x56\x8d\x81\xa8\x09\x44\x0c\xf2\x49\xf2\x4b\x5e\x0d\xe6\xd4\ +\x31\x48\x09\xad\x88\x65\xc2\x1f\x7d\x0d\x0f\x1f\x1f\x83\x10\x42\ +\x7f\x7a\x75\x37\xe7\x50\xff\xdb\x7c\x38\x40\xc3\x13\x83\x23\x08\ +\x46\xdf\x84\x49\x6b\x33\x08\x6c\x84\x60\x33\x04\xe3\x36\x38\x10\ +\x9c\xb8\x04\x0e\x13\x53\x04\xeb\xc5\xb7\x09\xfa\x1c\x24\x4d\xe1\ +\x9c\x13\x74\x16\xfc\xc3\x23\x30\x27\x46\xd0\x90\x59\x24\x90\xa1\ +\x75\xff\xe1\xa3\xa8\x7d\xf9\x04\x0c\xf2\xd0\x7c\xc8\x3f\x27\x66\ +\xba\xe3\xa4\xc6\xd7\xdf\x45\xf7\xb1\x67\x42\xa3\x06\xc7\x52\x3f\ +\x42\x9d\x3c\x8c\x18\xb7\x51\x6b\x38\x1a\xbe\x7d\x35\x89\x68\x34\ +\x0a\xd3\x34\xd1\x7e\xe4\x69\xdc\xfb\xc6\x49\xed\x15\x12\x04\x46\ +\x15\x78\xf3\xa0\xb9\x65\x8f\x4e\xa9\x75\xfd\x7b\x64\xdf\x3a\x04\ +\xe6\xda\x60\xe1\x6c\x12\x53\x0e\x9c\x13\x34\x28\x3d\x8b\x48\x24\ +\xa2\xef\x35\x35\x37\xdf\x82\x85\x9c\x4a\x62\xda\x19\x0b\x0c\xae\ +\xc1\x7e\x00\x4c\x8f\x0e\x23\xff\xcd\x65\xd8\x57\xbf\xc2\xf2\x4b\ +\x83\x70\x4b\x36\xca\x0a\x28\x3a\x40\xa1\x04\x38\x65\xc0\xb5\x1d\ +\xfc\x3a\x3e\x04\x35\x33\x8d\x8d\x6f\xbf\xc4\x77\xcf\x0e\x6b\x2f\ +\x13\xac\xc2\x85\x24\x59\xdb\x12\xad\x7e\xb6\x30\x23\x38\x19\xc1\ +\x81\x2b\x63\x87\x50\x13\x05\x62\x16\x41\x84\x09\x67\x73\x28\xf3\ +\x01\x0f\x40\x99\x93\x02\x1f\xf3\x2f\x0c\x62\xc3\x06\x02\x46\xa0\ +\x1a\x0b\x22\x56\x0b\xdf\x5b\x53\x15\xb0\xa3\x58\xfc\x72\x7d\x7b\ +\xdb\xa3\xce\xd2\x2f\x90\x26\x11\x22\x04\x30\x09\x4a\xb2\x0d\xea\ +\x49\x92\x23\x2c\x3d\x40\x49\x02\xd3\x99\x32\x09\x6a\x01\x3c\x06\ +\x58\x66\x1c\x99\x3c\x83\xab\xfc\x29\x0d\x66\x8c\x79\xef\x35\x36\ +\x8e\xd8\x85\xc2\x27\xa4\x3e\x5a\x8d\xc4\x3f\x28\x21\x33\x2a\x00\ +\xa6\x02\xa5\x8e\xe3\xff\xac\x3f\x00\x96\xb0\x06\xcd\xf7\xa2\xd6\ +\x6c\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x02\xf8\ +\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\x06\x00\x00\x00\xc4\xb4\x6c\x3b\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x02\x61\x00\x00\x02\x61\ +\x01\xc1\x30\x55\xfa\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\x02\x75\x49\x44\ +\x41\x54\x78\xda\xed\x94\x5f\x68\x52\x71\x14\xc7\x7f\xca\x74\x69\ +\x46\x8e\x74\xb9\xa9\xc3\xc2\x49\x84\xb0\xd7\x20\x14\x64\x15\x8d\ +\x5e\x2a\xda\x22\xa3\x27\x5f\xa2\xc1\x6a\x54\x0f\xbd\xee\x25\x2a\ +\x84\xa0\xd1\x1e\x56\x2c\x1a\x45\x50\xc9\xcc\x49\x2f\x21\x44\x10\ +\x62\x22\x18\xf8\x0f\x99\xe2\x1f\xa6\xa2\xf9\x27\x6d\x3a\xaf\xee\ +\x74\x7e\x17\x1f\x1c\x91\xde\x1e\x7a\xaa\x03\x5f\xce\xbd\x3f\xce\ +\xfd\xdc\xf3\xef\x5e\x1e\x00\x90\xbf\x61\x7c\xd4\x7f\xf0\xbf\x02\ +\x9e\x39\xa9\x1c\x7b\x34\x37\xfe\xf8\xce\xcc\xb0\x96\x03\x98\x3b\ +\xf4\x94\x7e\x67\xfd\xca\xf1\x1f\x97\x05\x07\xf6\xef\xeb\x19\x0c\ +\x00\xfd\xc4\x5b\x59\x59\x91\x4e\x9f\x18\x1d\x5b\x9e\x15\x7f\x8d\ +\x2c\x8d\x56\x16\xe7\xa5\xe7\xfa\x3c\xd3\x1b\xec\x74\x3a\x15\xa1\ +\x50\xa8\x58\xaf\xd7\x77\xd6\x9e\xdc\x8a\x7e\x59\x3a\x56\x59\x9c\ +\x15\xed\x82\x5e\x3b\xaf\xb9\xf8\xc0\x22\xd1\x73\x06\x53\x68\x20\ +\x10\x28\xb5\x5a\x2d\x48\xa5\x52\xf0\xbd\x52\x80\x8f\x76\xeb\xd3\ +\xee\x98\xb9\xe9\x43\xd6\xfa\xfa\x44\xeb\xad\xf5\xec\x02\x27\x30\ +\x85\xfa\xfd\xfe\x52\xb9\x5c\x06\xcc\x16\x28\x7c\x63\x63\x03\x4a\ +\xa5\x12\xb8\xdd\xee\xeb\x34\xe6\xc6\x05\xc5\xbd\xc6\xda\xe1\xd6\ +\xa7\x97\xe3\xaf\xa7\xb4\x64\xb0\x2f\xd8\x6e\xb7\x1f\xf4\xf9\x7c\ +\x2c\x74\x6b\x6b\x0b\xc2\xe1\x30\x54\xab\x55\x60\x18\x06\xa2\xd1\ +\x28\x14\x0a\x05\x78\xb5\xbc\xf0\xae\xf1\x46\xc6\x7c\x7e\xa6\xea\ +\x82\xf6\x00\xdb\x6c\xb6\x61\xaf\xd7\x5b\xcc\x66\xb3\x6c\xf9\x95\ +\x4a\x05\x6a\xb5\x1a\x04\x83\x41\xf6\xba\xd9\x6c\x42\x24\x12\x81\ +\x5c\x2e\x07\x5e\xc7\x55\xaf\xf6\x37\x50\xd4\xee\x75\x13\x0a\x85\ +\xf7\x47\x46\x46\x86\x24\x12\x09\x41\x08\x29\x16\x8b\xac\x57\x2a\ +\x95\x04\x5f\x44\x30\x73\xa2\xd1\x68\x08\xb6\x87\x0c\x1d\xbd\x3d\ +\x81\x05\x6c\x73\xda\x63\xec\xe1\x5d\xec\x25\x43\x81\x0a\x85\x82\ +\x60\xf9\x14\x4e\x3d\x0b\xdf\xdc\xdc\xa4\x31\x44\x24\x12\x91\x4c\ +\x26\xf3\x81\xf4\xb0\x5f\xfe\xc7\x0e\x87\xe3\x92\x54\x2a\x7d\xa1\ +\x56\xab\x79\x72\xb9\x9c\xcd\x94\xcf\xe7\x13\x3c\x23\x68\x6c\x05\ +\xb1\x58\xcc\x65\x34\x1a\x27\xff\xe8\xcb\xd3\xeb\xf5\xa3\xe8\xea\ +\xc9\x64\x92\x66\x45\x54\x2a\x15\x69\xb7\xdb\x04\x87\x49\xb0\xdf\ +\x04\x07\xd8\x0d\xe5\x0e\xc6\xc1\x4c\xc9\x64\x32\x31\xae\xd8\x37\ +\x84\x43\x3a\x9d\x66\xb3\xa5\x95\xc5\xe3\x71\x97\xc9\x64\x62\xa1\ +\x9c\xc1\x58\xba\xd2\x62\xb1\xdc\xf4\x78\x3c\x74\xa5\xe6\x31\xd3\ +\x23\xf9\x7c\xfe\x0c\xc2\x9b\x78\x4f\x12\x89\x84\x6b\x12\x8d\x70\ +\xb4\x01\xd2\x31\x81\x40\x30\xc0\xe3\xf1\xc2\xb8\x15\x0f\x0d\x06\ +\x43\x9b\x9e\xe9\x74\xba\xf7\xab\xab\xab\x6a\x04\x9f\x36\x9b\xcd\ +\xcf\x39\x11\xbb\x87\x87\x40\xfa\x82\x3d\x28\x71\x47\xa2\x8e\xdf\ +\xdb\xf1\x83\x34\x16\xd5\x46\x31\xa8\x7a\x47\x8d\x2e\x6d\x77\x9d\ +\x31\x3f\x01\x9d\xcf\x29\xdb\x06\x02\xae\x05\x00\x00\x00\x00\x49\ +\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x03\x61\ +\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\x06\x00\x00\x00\xc4\xb4\x6c\x3b\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x02\x61\x00\x00\x02\x61\ +\x01\xc1\x30\x55\xfa\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\x02\xde\x49\x44\ +\x41\x54\x78\xda\xb5\x95\xcd\x6a\x14\x41\x10\xc7\xab\xe7\x23\xfb\ +\x95\x4c\x8c\x41\x88\xc1\x80\x12\x48\xd4\x88\xab\xa2\xee\x21\x97\ +\x20\x79\x01\x1f\x40\x3d\x4b\x2e\x06\x54\x88\x2f\x90\x78\x13\x1f\ +\x21\x0f\xe0\xc1\x83\x07\x15\xbc\x78\x51\x31\x7a\x10\x51\x5c\x82\ +\xa0\xf9\xba\x88\x71\x77\xbe\x7a\xa6\xa7\xad\xea\x9d\x69\x66\x76\ +\x47\x11\xd4\x62\xaa\x67\x7b\x7a\xfa\x57\xff\xae\xea\xe9\x65\x52\ +\x4a\xf8\x1f\x66\x51\xb3\xbc\xbc\xfc\x4c\x44\xf1\xac\x6d\xdb\x72\ +\xe6\xf8\x5c\x7d\xec\xe0\xb8\x95\x24\x09\x46\xa4\xa0\xac\x77\x31\ +\xa6\xdc\x30\x0c\xfd\x1b\x2f\x30\xb1\xbf\xb5\xb3\x1d\xb7\x3f\xbc\ +\xf7\x25\x4e\xa9\x54\x2b\x9f\x56\xd7\xd6\x16\x14\xd8\x77\xbd\x85\ +\x4e\xb7\x0b\xce\xc8\x08\x4c\xcf\x9e\x84\xd3\xcd\xb3\xf0\x74\x63\ +\x13\x12\x99\x00\x19\xa3\x86\x40\xa0\xe3\xa4\x50\x13\x16\x2f\x4e\ +\xc3\xab\x97\x2f\xe0\xdd\x9b\x8d\x31\x21\x04\xa0\x4f\x6a\xc5\x9c\ +\x73\x08\xc3\x10\x92\x46\x43\x4d\x18\xb2\x19\x2c\x9e\x3f\x06\x40\ +\xa2\x35\x8c\x69\x20\x53\x0d\xa0\x7a\x06\x16\x3a\x19\xae\x50\xbb\ +\x06\xd3\x8b\xa3\x8e\x43\xd1\x7a\x60\xcb\x80\xea\x90\x05\xda\x32\ +\xa0\x4e\x0b\x42\x81\xa9\xbb\x48\x41\x38\x37\x73\x0d\xd6\x51\x54\ +\xde\x40\x82\x8d\xe0\x27\xaf\x37\x81\xd2\x5c\x66\x92\x5c\xf6\x4a\ +\x30\x7f\x6a\x0a\x12\xa1\xd5\x16\xc0\xd4\xd1\x60\x1a\x0c\xa3\x18\ +\x2e\xcc\x4e\xd2\x64\x0d\xc2\x4e\x0a\xcc\x5c\x52\xa6\x94\x47\x89\ +\x80\x38\x8e\x35\xb8\x54\x71\x8c\xd1\x03\x2e\xc0\x34\x8d\x01\x99\ +\x88\xce\xa0\x5a\x35\xa7\xe5\xc7\xa4\x56\x7b\xb9\xe2\x48\x08\x04\ +\x47\xf0\xe8\xf9\xdb\x42\x2a\xf2\xdb\x5d\x61\x53\xe5\x97\x5a\x73\ +\x38\x47\x92\x62\xec\xab\xfb\xa0\x62\xb2\x18\xa3\x7b\xa8\xf8\xdc\ +\x89\xe9\x9e\x4c\xdd\x82\x4e\x4d\x5e\x75\x22\x95\x30\x62\xd0\xb3\ +\xa2\xe2\x44\x08\x0d\xde\xdd\xdd\x86\x5a\xc3\xc9\x07\xd3\x96\x62\ +\x09\xac\x03\x7d\x63\x06\xec\xed\xed\x80\x48\x95\x26\x86\x91\x4b\ +\x45\x0e\xf2\xf8\xe1\x03\xad\xec\x4f\x8d\x52\x98\x99\xd1\xaf\xf8\ +\x6f\x2c\x2f\x43\x30\x56\xcc\xf1\x3f\xb2\x62\x8e\xa9\x92\xfd\x76\ +\x7d\x69\x09\x26\x0e\x4f\xfc\x12\xc0\xc3\x10\xee\xac\xac\x40\x10\ +\x04\xaa\x80\x87\xc6\xc7\x07\x4f\xb7\x28\x8a\xb2\xbe\x2e\x8a\x1f\ +\xf8\x70\xfb\xe6\x2d\x35\xd6\xc5\x03\x6a\xf5\xee\xda\x00\x7c\x74\ +\xf4\x00\x18\x46\x87\x0a\xa7\x19\x45\xc5\x25\x60\xcf\xf3\x20\x42\ +\x55\x82\xf6\x35\x06\x71\x5d\xb7\x6c\xdd\xc0\xd2\x42\x13\xbc\x52\ +\xa9\xd0\xdc\xdf\x2b\x26\x10\xa5\x88\xc0\x3c\xe4\x65\xe0\xc2\xf9\ +\x20\xf1\x5e\xab\xd7\x01\x0a\x60\x04\x94\x81\x79\x1c\xa9\x23\x35\ +\xe0\xa1\x4a\x47\xbf\x79\x61\x40\x63\xea\x0b\x65\xe9\xb6\x35\xf2\ +\xbb\x22\xe6\xfc\x1e\x30\x76\xa3\x3f\x15\xdd\x4e\x17\xbe\xef\xef\ +\xd3\x81\xaf\xfa\xfd\x16\x78\x3e\x84\x3e\x15\x4f\x82\x65\x9a\xd0\ +\xc1\x77\x69\xf5\x8c\x31\xd3\xc2\x86\x3e\x95\xfb\x47\x8f\x4c\xcd\ +\x0f\x8f\x0c\x9f\xc9\xd8\xbe\xef\xdb\x57\xae\x5d\x65\xd9\x1e\xc5\ +\xbe\xfe\x27\xd1\x8a\x3d\x17\xcb\x10\xd2\x33\x54\x6d\x02\x8f\x38\ +\x9d\xd2\x2e\xd5\xd5\x42\x75\x09\xc2\xb7\x3e\x7f\xfd\x72\x19\x00\ +\x2a\x04\x6d\xb5\x5a\xd0\x6c\x36\x67\x1c\xc7\xa9\x55\xab\xd5\x3a\ +\x16\xa5\x61\xdb\x76\x2d\xcd\xab\x8f\xe9\xf1\x30\x90\xdb\x6e\xb7\ +\x3f\xae\xaf\xaf\x13\x88\xe5\x77\x22\xfa\x8f\x9f\x10\xdc\x10\xc6\ +\xc1\x27\x82\x12\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\ +" + +qt_resource_name = "\ +\x00\x07\ +\x0b\x66\x28\x62\ +\x00\x74\ +\x00\x6f\x00\x6f\x00\x6c\x00\x62\x00\x61\x00\x72\ +\x00\x08\ +\x0c\xbb\x0b\xc3\ +\x00\x73\ +\x00\x65\x00\x74\x00\x74\x00\x69\x00\x6e\x00\x67\x00\x73\ +\x00\x12\ +\x0f\x06\xcc\xa7\ +\x00\x68\ +\x00\x69\x00\x67\x00\x68\x00\x6c\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2d\x00\x65\x00\x64\x00\x69\x00\x74\x00\x2e\x00\x70\x00\x6e\ +\x00\x67\ +\x00\x15\ +\x01\x39\xc4\x47\ +\x00\x68\ +\x00\x69\x00\x67\x00\x68\x00\x6c\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2d\x00\x64\x00\x69\x00\x73\x00\x63\x00\x61\x00\x72\x00\x64\ +\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0b\ +\x04\x2b\x8e\x47\ +\x00\x6d\ +\x00\x6f\x00\x76\x00\x65\x00\x2d\x00\x75\x00\x70\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0d\ +\x0e\x38\x51\xe7\ +\x00\x6d\ +\x00\x6f\x00\x76\x00\x65\x00\x2d\x00\x64\x00\x6f\x00\x77\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x12\ +\x0c\xc9\xc2\xe7\ +\x00\x68\ +\x00\x69\x00\x67\x00\x68\x00\x6c\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2d\x00\x73\x00\x61\x00\x76\x00\x65\x00\x2e\x00\x70\x00\x6e\ +\x00\x67\ +\x00\x14\ +\x0d\x3f\xb7\x07\ +\x00\x68\ +\x00\x69\x00\x67\x00\x68\x00\x6c\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2d\x00\x64\x00\x65\x00\x6c\x00\x65\x00\x74\x00\x65\x00\x2e\ +\x00\x70\x00\x6e\x00\x67\ +\x00\x14\ +\x07\x55\xf7\xc7\ +\x00\x68\ +\x00\x69\x00\x67\x00\x68\x00\x6c\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2d\x00\x72\x00\x65\x00\x6d\x00\x6f\x00\x76\x00\x65\x00\x2e\ +\x00\x70\x00\x6e\x00\x67\ +\x00\x11\ +\x03\xe7\x4e\xe7\ +\x00\x68\ +\x00\x69\x00\x67\x00\x68\x00\x6c\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2d\x00\x61\x00\x64\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\ +\x00\x13\ +\x04\xc4\x04\x47\ +\x00\x6e\ +\x00\x65\x00\x74\x00\x77\x00\x6f\x00\x72\x00\x6b\x00\x2d\x00\x63\x00\x6f\x00\x6e\x00\x6e\x00\x65\x00\x63\x00\x74\x00\x2e\x00\x70\ +\x00\x6e\x00\x67\ +\x00\x11\ +\x0b\x32\x02\xe7\ +\x00\x66\ +\x00\x6f\x00\x6c\x00\x6c\x00\x6f\x00\x77\x00\x2d\x00\x6f\x00\x75\x00\x74\x00\x70\x00\x75\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\ +\x00\x0d\ +\x08\x51\xc9\x27\ +\x00\x63\ +\x00\x6f\x00\x6e\x00\x66\x00\x69\x00\x67\x00\x75\x00\x72\x00\x65\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x14\ +\x07\x40\xa2\xc7\ +\x00\x61\ +\x00\x70\x00\x70\x00\x6c\x00\x69\x00\x63\x00\x61\x00\x74\x00\x69\x00\x6f\x00\x6e\x00\x2d\x00\x65\x00\x78\x00\x69\x00\x74\x00\x2e\ +\x00\x70\x00\x6e\x00\x67\ +\x00\x16\ +\x03\x0a\xf6\xe7\ +\x00\x6e\ +\x00\x65\x00\x74\x00\x77\x00\x6f\x00\x72\x00\x6b\x00\x2d\x00\x64\x00\x69\x00\x73\x00\x63\x00\x6f\x00\x6e\x00\x6e\x00\x65\x00\x63\ +\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x13\ +\x0e\x17\x61\x67\ +\x00\x63\ +\x00\x61\x00\x70\x00\x74\x00\x75\x00\x72\x00\x65\x00\x2d\x00\x74\x00\x6f\x00\x2d\x00\x64\x00\x69\x00\x73\x00\x6b\x00\x2e\x00\x70\ +\x00\x6e\x00\x67\ +" + +qt_resource_struct = "\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x0b\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x08\x00\x00\x00\x03\ +\x00\x00\x00\x54\x00\x00\x00\x00\x00\x01\x00\x00\x02\xda\ +\x00\x00\x01\x46\x00\x00\x00\x00\x00\x01\x00\x00\x11\x72\ +\x00\x00\x00\x84\x00\x00\x00\x00\x00\x01\x00\x00\x06\x2e\ +\x00\x00\x01\x18\x00\x00\x00\x00\x00\x01\x00\x00\x10\x22\ +\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x45\ +\x00\x00\x00\xea\x00\x00\x00\x00\x00\x01\x00\x00\x0d\x9e\ +\x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x08\xd2\ +\x00\x00\x00\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x02\x10\x00\x00\x00\x00\x00\x01\x00\x00\x24\x9d\ +\x00\x00\x01\x6e\x00\x00\x00\x00\x00\x01\x00\x00\x13\xaa\ +\x00\x00\x01\xe2\x00\x00\x00\x00\x00\x01\x00\x00\x20\x2b\ +\x00\x00\x01\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x1b\xda\ +\x00\x00\x01\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x18\x27\ +\x00\x00\x02\x42\x00\x00\x00\x00\x00\x01\x00\x00\x27\x99\ +" + +def init_resources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def cleanup_resources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + diff --git a/colourterm/settingsdialog.py b/colourterm/settingsdialog.py new file mode 100644 index 0000000..c1ccaf3 --- /dev/null +++ b/colourterm/settingsdialog.py @@ -0,0 +1,343 @@ +# -*- coding: utf-8 -*- + +from PyQt4 import QtCore, QtGui + +from colourterm import Highlight, fromUtf8, translate + +class Ui_SettingsDialog(object): + def setupUi(self, settingsDialog): + settingsDialog.setObjectName(fromUtf8('SettingsDialog')) + settingsDialog.resize(587, 390) + self.settingsLayout = QtGui.QVBoxLayout(settingsDialog) + self.settingsLayout.setSpacing(8) + self.settingsLayout.setMargin(8) + self.settingsLayout.setObjectName(fromUtf8('settingsLayout')) + self.splitter = QtGui.QSplitter(settingsDialog) + self.splitter.setOrientation(QtCore.Qt.Horizontal) + self.splitter.setObjectName(fromUtf8('splitter')) + self.sectionListWidget = QtGui.QListWidget(self.splitter) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.sectionListWidget.sizePolicy().hasHeightForWidth()) + self.sectionListWidget.setSizePolicy(sizePolicy) + self.sectionListWidget.setMinimumSize(QtCore.QSize(100, 0)) + self.sectionListWidget.setMaximumSize(QtCore.QSize(200, 16777215)) + self.sectionListWidget.setObjectName(fromUtf8('sectionListWidget')) + item = QtGui.QListWidgetItem() + self.sectionListWidget.addItem(item) + item = QtGui.QListWidgetItem() + self.sectionListWidget.addItem(item) + self.sectionStackedWidget = QtGui.QStackedWidget(self.splitter) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.sectionStackedWidget.sizePolicy().hasHeightForWidth()) + self.sectionStackedWidget.setSizePolicy(sizePolicy) + self.sectionStackedWidget.setObjectName(fromUtf8('sectionStackedWidget')) + self.highlightPage = QtGui.QWidget() + self.highlightPage.setObjectName(fromUtf8('highlightPage')) + self.verticalLayout = QtGui.QVBoxLayout(self.highlightPage) + self.verticalLayout.setObjectName(fromUtf8('verticalLayout')) + self.highlightListWidget = QtGui.QListWidget(self.highlightPage) + self.highlightListWidget.setObjectName(fromUtf8('highlightListWidget')) + self.verticalLayout.addWidget(self.highlightListWidget) + self.buttonLayout = QtGui.QHBoxLayout() + self.buttonLayout.setSpacing(8) + self.buttonLayout.setContentsMargins(0, -1, -1, -1) + self.buttonLayout.setObjectName(fromUtf8('buttonLayout')) + self.upButton = QtGui.QToolButton(self.highlightPage) + self.upButton.setIcon(QtGui.QIcon(':/settings/move-up.png')) + self.upButton.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) + self.upButton.setFocusPolicy(QtCore.Qt.NoFocus) + self.upButton.setObjectName(fromUtf8('upButton')) + self.buttonLayout.addWidget(self.upButton) + self.downButton = QtGui.QToolButton(self.highlightPage) + self.downButton.setIcon(QtGui.QIcon(':/settings/move-down.png')) + self.downButton.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) + self.downButton.setFocusPolicy(QtCore.Qt.NoFocus) + self.downButton.setObjectName(fromUtf8('downButton')) + self.buttonLayout.addWidget(self.downButton) + self.buttonLayout.addItem(QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)) + self.addButton = QtGui.QPushButton(self.highlightPage) + self.addButton.setIcon(QtGui.QIcon(':/settings/highlight-add.png')) + self.addButton.setObjectName(fromUtf8('addButton')) + self.buttonLayout.addWidget(self.addButton) + self.editButton = QtGui.QPushButton(self.highlightPage) + self.editButton.setIcon(QtGui.QIcon(':/settings/highlight-edit.png')) + self.editButton.setObjectName(fromUtf8('editButton')) + self.buttonLayout.addWidget(self.editButton) + self.deleteButton = QtGui.QPushButton(self.highlightPage) + self.deleteButton.setIcon(QtGui.QIcon(':/settings/highlight-remove.png')) + self.deleteButton.setObjectName(fromUtf8('deleteButton')) + self.buttonLayout.addWidget(self.deleteButton) + self.saveButton = QtGui.QPushButton(self.highlightPage) + self.saveButton.setIcon(QtGui.QIcon(':/settings/highlight-save.png')) + self.saveButton.setObjectName(fromUtf8('saveButton')) + self.saveButton.setVisible(False) + self.buttonLayout.addWidget(self.saveButton) + self.discardButton = QtGui.QPushButton(self.highlightPage) + self.discardButton.setIcon(QtGui.QIcon(':/settings/highlight-discard.png')) + self.discardButton.setObjectName(fromUtf8('discardButton')) + self.discardButton.setVisible(False) + self.buttonLayout.addWidget(self.discardButton) + self.verticalLayout.addLayout(self.buttonLayout) + self.highlightGroupBox = QtGui.QGroupBox(self.highlightPage) + self.highlightGroupBox.setObjectName(fromUtf8('highlightGroupBox')) + self.highlightLayout = QtGui.QFormLayout(self.highlightGroupBox) + self.highlightLayout.setMargin(8) + self.highlightLayout.setSpacing(8) + self.highlightLayout.setObjectName(fromUtf8('highlightLayout')) + self.regexLabel = QtGui.QLabel(self.highlightGroupBox) + self.regexLabel.setObjectName(fromUtf8('regexLabel')) + self.highlightLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.regexLabel) + self.regexEdit = QtGui.QLineEdit(self.highlightGroupBox) + self.regexEdit.setObjectName(fromUtf8('regexEdit')) + self.highlightLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.regexEdit) + self.foregroundLabel = QtGui.QLabel(self.highlightGroupBox) + self.foregroundLabel.setObjectName(fromUtf8('foregroundLabel')) + self.highlightLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.foregroundLabel) + self.fgColourButton = QtGui.QPushButton(self.highlightGroupBox) + self.fgColourButton.setText(fromUtf8('')) + self.fgColourButton.setObjectName(fromUtf8('fgColourButton')) + self.highlightLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.fgColourButton) + self.backgroundCheckBox = QtGui.QCheckBox(self.highlightGroupBox) + self.backgroundCheckBox.setObjectName(fromUtf8('backgroundCheckBox')) + self.highlightLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.backgroundCheckBox) + self.bgColourButton = QtGui.QPushButton(self.highlightGroupBox) + self.bgColourButton.setText(fromUtf8('')) + self.bgColourButton.setObjectName(fromUtf8('bgColourButton')) + self.highlightLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.bgColourButton) + self.verticalLayout.addWidget(self.highlightGroupBox) + self.sectionStackedWidget.addWidget(self.highlightPage) + self.fontPage = QtGui.QWidget() + self.fontPage.setObjectName(fromUtf8('fontPage')) + self.fontLayout = QtGui.QFormLayout(self.fontPage) + self.fontLayout.setMargin(8) + self.fontLayout.setSpacing(8) + self.fontLayout.setObjectName(fromUtf8('fontLayout')) + self.fontLabel = QtGui.QLabel(self.fontPage) + self.fontLabel.setObjectName(fromUtf8('fontLabel')) + self.fontLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.fontLabel) + self.fontComboBox = QtGui.QFontComboBox(self.fontPage) + self.fontComboBox.setObjectName(fromUtf8('fontComboBox')) + self.fontLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.fontComboBox) + self.sizeLabel = QtGui.QLabel(self.fontPage) + self.sizeLabel.setObjectName(fromUtf8('sizeLabel')) + self.fontLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.sizeLabel) + self.sizeSpinBox = QtGui.QSpinBox(self.fontPage) + self.sizeSpinBox.setReadOnly(True) + self.sizeSpinBox.setSpecialValueText(fromUtf8('')) + self.sizeSpinBox.setMinimum(6) + self.sizeSpinBox.setMaximum(50) + self.sizeSpinBox.setProperty('value', 12) + self.sizeSpinBox.setObjectName(fromUtf8('sizeSpinBox')) + self.fontLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.sizeSpinBox) + self.sectionStackedWidget.addWidget(self.fontPage) + self.settingsLayout.addWidget(self.splitter) + self.buttonBox = QtGui.QDialogButtonBox(settingsDialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(fromUtf8('buttonBox')) + self.settingsLayout.addWidget(self.buttonBox) + + self.retranslateUi(settingsDialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(fromUtf8('accepted()')), settingsDialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(fromUtf8('rejected()')), settingsDialog.reject) + QtCore.QObject.connect(self.sectionListWidget, QtCore.SIGNAL(fromUtf8('currentRowChanged(int)')), self.sectionStackedWidget.setCurrentIndex) + QtCore.QMetaObject.connectSlotsByName(settingsDialog) + settingsDialog.setTabOrder(self.sectionListWidget, self.highlightListWidget) + settingsDialog.setTabOrder(self.highlightListWidget, self.addButton) + settingsDialog.setTabOrder(self.addButton, self.editButton) + settingsDialog.setTabOrder(self.editButton, self.deleteButton) + settingsDialog.setTabOrder(self.deleteButton, self.saveButton) + settingsDialog.setTabOrder(self.saveButton, self.discardButton) + settingsDialog.setTabOrder(self.discardButton, self.buttonBox) + + def retranslateUi(self, settingsDialog): + settingsDialog.setWindowTitle(translate('SettingsDialog', 'Settings')) + __sortingEnabled = self.sectionListWidget.isSortingEnabled() + self.sectionListWidget.setSortingEnabled(False) + item = self.sectionListWidget.item(0) + item.setText(translate('SettingsDialog', 'Highlighting')) + item = self.sectionListWidget.item(1) + item.setText(translate('SettingsDialog', 'Font')) + self.sectionListWidget.setSortingEnabled(__sortingEnabled) + self.upButton.setText(translate('SettingsDialog', 'Move Up')) + self.downButton.setText(translate('SettingsDialog', 'Move Down')) + self.addButton.setText(translate('SettingsDialog', 'Add')) + self.editButton.setText(translate('SettingsDialog', 'Edit')) + self.deleteButton.setText(translate('SettingsDialog', 'Delete')) + self.saveButton.setText(translate('SettingsDialog', 'Save')) + self.discardButton.setText(translate('SettingsDialog', 'Discard')) + self.highlightGroupBox.setTitle(translate('SettingsDialog', 'Highlight')) + self.regexLabel.setText(translate('SettingsDialog', 'Regular Expression:')) + self.foregroundLabel.setText(translate('SettingsDialog', 'Foreground:')) + self.backgroundCheckBox.setText(translate('SettingsDialog', 'Background:')) + self.fontLabel.setText(translate('SettingsDialog', 'Font:')) + self.sizeLabel.setText(translate('SettingsDialog', 'Size:')) + self.sizeSpinBox.setSuffix(translate('SettingsDialog', 'pt')) + + +class SettingsDialog(QtGui.QDialog, Ui_SettingsDialog): + + def __init__(self): + QtGui.QDialog.__init__(self) + self.setupUi(self) + self._highlights = {} + self._currentHighlight = None + self._currentRow = -1 + self.highlightListWidget.itemSelectionChanged.connect(self.onHighlightItemSelected) + self.regexEdit.textEdited.connect(self.onRegexEditTextEdited) + self.fgColourButton.clicked.connect(self.onFgColourButtonClicked) + self.backgroundCheckBox.toggled.connect(self.onBackgroundCheckboxToggled) + self.bgColourButton.clicked.connect(self.onBgColourButtonClicked) + self.upButton.clicked.connect(self.onUpButtonClicked) + self.downButton.clicked.connect(self.onDownButtonClicked) + self.addButton.clicked.connect(self.onAddButtonClicked) + self.editButton.clicked.connect(self.onEditButtonClicked) + self.deleteButton.clicked.connect(self.onDeleteButtonClicked) + self.saveButton.clicked.connect(self.onSaveButtonClicked) + self.discardButton.clicked.connect(self.onDiscardButtonClicked) + + def _setCurrentHighlight(self): + self.regexEdit.setText(self._currentHighlight.pattern) + if self._currentHighlight.background: + self.backgroundCheckBox.setChecked(True) + self.bgColourButton.setEnabled(True) + self.bgColourButton.setStyleSheet('background-color: %s' % self._currentHighlight.background) + else: + self.backgroundCheckBox.setChecked(False) + self.bgColourButton.setEnabled(False) + self.bgColourButton.setStyleSheet('') + self.fgColourButton.setStyleSheet('background-color: %s' % self._currentHighlight.foreground) + self.setEditMode(True) + + def highlights(self): + return self._highlights.values() + + def setHighlights(self, highlights): + self._highlights = {} + self.highlightListWidget.clear() + for index, highlight in enumerate(highlights): + self._highlights[index] = highlight + item = QtGui.QListWidgetItem() + if highlight.background: + item.setBackgroundColor(QtGui.QColor(highlight.background)) + item.setTextColor(QtGui.QColor(highlight.foreground)) + item.setText(highlight.pattern) + self.highlightListWidget.addItem(item) + + def onHighlightItemSelected(self): + self._currentRow = self.highlightListWidget.currentRow() + if self._currentRow > -1: + self._currentHighlight = self._highlights[self._currentRow] + + def onRegexEditTextEdited(self): + self._currentHighlight.setPattern(unicode(self.regexEdit.text())) + + def onBackgroundCheckboxToggled(self, checked): + self.bgColourButton.setEnabled(checked) + if not checked: + self._currentHighlight.background = None + + def onFgColourButtonClicked(self): + colour = QtGui.QColor(self._currentHighlight.foreground) + colour = QtGui.QColorDialog.getColor(colour, self) + if colour.isValid(): + self.fgColourButton.setStyleSheet('background-color: %s' % colour.name()) + self._currentHighlight.foreground = colour.name() + + def onBgColourButtonClicked(self): + if self._currentHighlight.background: + colour = QtGui.QColor(self._currentHighlight.background) + colour = QtGui.QColorDialog.getColor(colour, self) + else: + colour = QtGui.QColorDialog.getColor(QtCore.Qt.white, self) + if colour.isValid(): + self.bgColourButton.setStyleSheet('background-color: %s' % colour.name()) + self._currentHighlight.background = colour.name() + + def onUpButtonClicked(self): + if self._currentRow == 0: + return + row = self._currentRow + item = self.highlightListWidget.takeItem(row) + self.highlightListWidget.insertItem(row - 1, item) + self._highlights[row - 1], self._highlights[row] = \ + self._highlights[row], self._highlights[row - 1] + self.highlightListWidget.setCurrentRow(row - 1) + self.onHighlightItemSelected() + + def onDownButtonClicked(self): + if self._currentRow == len(self._highlights) - 1: + return + row = self._currentRow + item = self.highlightListWidget.takeItem(row) + self.highlightListWidget.insertItem(row + 1, item) + self._highlights[row + 1], self._highlights[row] = \ + self._highlights[row], self._highlights[row + 1] + self.highlightListWidget.setCurrentRow(row + 1) + self.onHighlightItemSelected() + + def onAddButtonClicked(self): + self._currentRow = -1 + self._currentHighlight = Highlight(u'', QtGui.QColor(QtGui.QPalette.WindowText).name()) + self._setCurrentHighlight() + self.setEditMode(True) + + def onEditButtonClicked(self): + self._setCurrentHighlight() + self.setEditMode(True) + + def onDeleteButtonClicked(self): + if QtGui.QMessageBox.question(self, + translate('SettingsDialog', 'Confirm Delete'), + translate('SettingsDialog', 'Are you sure you want to delete ' + 'this highlight?'), + QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) == QtGui.QMessageBox.Yes: + del self._highlights[self._currentRow] + self.highlightListWidget.takeItem(self._currentRow) + self._currentRow = -1 + self._currentHighlight = None + + def onSaveButtonClicked(self): + if self._currentRow < 0: + new_index = len(self._highlights) + self._highlights[new_index] = self._currentHighlight + item = QtGui.QListWidgetItem() + if self._currentHighlight.background: + item.setBackgroundColor(QtGui.QColor(self._currentHighlight.background)) + item.setTextColor(QtGui.QColor(self._currentHighlight.foreground)) + item.setText(self._currentHighlight.pattern) + self.highlightListWidget.addItem(item) + self.highlightListWidget.setCurrentRow(new_index) + else: + self._highlights[self._currentRow] = self._currentHighlight + self.setEditMode(False) + + def onDiscardButtonClicked(self): + self.setEditMode(False) + + def setEditMode(self, enable): + for button in self.buttonBox.buttons(): + button.setEnabled(not enable) + self.upButton.setVisible(not enable) + self.downButton.setVisible(not enable) + self.addButton.setVisible(not enable) + self.editButton.setVisible(not enable) + self.deleteButton.setVisible(not enable) + self.saveButton.setVisible(enable) + self.discardButton.setVisible(enable) + self.highlightListWidget.setEnabled(not enable) + self.regexEdit.setEnabled(enable) + self.fgColourButton.setEnabled(enable) + self.backgroundCheckBox.setEnabled(enable) + if enable and self.backgroundCheckBox.isChecked(): + self.bgColourButton.setEnabled(True) + else: + self.bgColourButton.setEnabled(False) + if not enable: + self.regexEdit.clear() + self.fgColourButton.setStyleSheet('') + self.bgColourButton.setStyleSheet('') diff --git a/configure.ui b/configure.ui new file mode 100644 index 0000000..a8ec8a4 --- /dev/null +++ b/configure.ui @@ -0,0 +1,134 @@ + + + ConfigDialog + + + + 0 + 0 + 573 + 377 + + + + Configuration + + + + 8 + + + 8 + + + + + 0 + + + + Highlighting + + + + + + + + + + + + + + Pattern: + + + + + + + Colour: + + + + + + + + + + + + + + Background: + + + + + + + + + + + + + + + + + Font + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + ConfigDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ConfigDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/images/application-exit.png b/images/application-exit.png new file mode 100644 index 0000000000000000000000000000000000000000..ed5f8b2515e72608d2de9d45fb80ff481926066e GIT binary patch literal 1134 zcmV-!1d;oRP)(xC=n00006VoOIv0RI600RN!9r;`8x1N%ut zK~#9!wUS?G990y?zx!uqcQ)CO3Qb9*q)kbepkNXsL>fp%(uUwejD?y8p{)=!q9{uI zgNUFMD`JgLd5}{2)TjDbX(&h)iK5opBqla%!fsPV$ZoQ`*`3+BGvk@tY+BYL;-3Q_ zbGUQA-}(0J;J>IK2tw^3)mP3K37K=}c6+n4r`M;ZdQ>*cgNlLlcl&$x?F+W`_y4@Q zyxhNgd^{yVZgTFam#l;R5QCNuU}|&|FIk9vK+Wf7}ljFCx0I0B)M_DpyEQn_xvs z?A=Q~uEAY2z;11YDwXs*lI}}%*4fvmp>$V!D(@6yRp3GaWzxc#GqBTX3h8TOTW>GW z*$HJAwfv3_Bzk(_c^;HfD5X-`LtYKmiMLikQ{7@wgTlHxF@gKW#vq%T^x3ZNZrqey z_l*xe6hd{cR#q@KIf=k^p*fBN@6N=&lzJ8Aiq_UJcj|qp8>tYY(>JttV*3LfVM;B3 zC5?rTKY+@u!KI`;5`mk~p={fCBo-WNi;EDJ1tVr5Y8ikJBu~AAJo`vlHhy9SSvSW$s^eS~DeuZ?2*i_g*i_>&r1 zfnT}w8N{XYaEdNU#3_a$6~JQA>QxAU0mO$XJP1_;ck)<&>?w2%4eOMoE%>g1C*T}= z1y+rLs0l<2@=5YbUJd5dF-Qrmh-JbbeGLyEAA=A=e|mK{=TQIKd^kYE6N4iNM&E=< zYcmLJgkUoS<2E=DoVWxI6H^51#kUFi93)NQoD*~w{KF$KCq~eaStO95b^qa`sD1ea z4D!%?$Ui4$y5pqA*WX3=v1dY~2FFrALY+K}7`IVtI2yivHHm063ez;ve&lJ~`^HJ_ z6%qtS6?pTYxn++|sdfE(WZyaj=GtK4Y!XuroD(!CJ&Q;rqVF{|H{XJVoJwNa84C=q z!F~Wtj}9aM&1KkEzrylMgK$eW$_gktK%oRUWx%x^{5n1aH8YKkZ@gi=tO86gUQM0_f{7gjgtZmzJ=J;HF?BKYSBnd{OpsaT>rragAs;N6>zF(Cw?Pin=Sa|pu_l14*K7_u2Go<9aaqBV?ZAX5#XdIlCc8Lm*f2Gfh9 zjziIUV9S8&kOkT@piT=yfvLMlK{z*a4c1Xq-avwl;3uy)fzn)Nl3eymFn?+a5~0-= zz|_%T8VsWtF3e8SWDUYj3d~$mrj$pCfH;mdxKweB(E~2PG>rk7h|Zu|HK*mrq*i;m z;z$StNAT$R+d?Yx+g)K(<(FD>I7gCV?5q2rVzL;cd#L!_iRqq9-GWX{UUedsFk;ZN zqT)md4c^_|hFZhP2h)~f39JKsV+QQ)?SM#?CWetqMGo@#;RCJgPmNNTnbEKKZ!9lE zFjma*KeA$usgnJ6eQ60M4p00Nz{3#ktgJu~1ge0C#>WRwwDL zW#Gd3An{(S*8vJ(1eAe!9H}EU;Gs%Kzj9#fUyCUZN9x!&JKNa0h7ryWB z(}A!0{T6sWggzBdf@PY}!FOr(j4{)~hCY@1M~_U+504C=$=JT{+gGk#W!WCZzWyiC ziai(05YjVLZ32%tozgDV)k1X%!nZzu{c;%qDgPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L02{9W02{9XUK)`c00007bV*G`2iXAx z12Qe)4)6T{00YfQL_t(|+MSbYOp|96$IsjLZ7HMDl|)KuRd9<5th6H|V}`kQqcbDR zT*5G0HZLI{F58gxqBdEC#2ZoEvH_ctm{K$`CIp)Z*aA^hKFon8SQ#1}pk&sr7wAft zweRKG!Gy#QGqyd+KY4P_Kfm|9=R6MusRw1XTJ$E9sWCG%vz+5OaWwk(gHR}V-r;bb zy*hd=0qH=Sn-A3bp7;_R$C5}SLT2Y?$<136r0+s6Z?S#bjvi6U)ORb5>o2(n{|N*G zB>r!lEX9^cYwJ<2tn7{ZG)@12mN!vCNR=*oDQio1woJ-#958GGD2jqXxBJZa_=FwH z0TjF96{Nrw%3qehH8V2@gb-jD23Y)nN~xU2+LIM%I$&v0QBm3S^zXp342lJoVPV_$ zZIx@+t)-tenypRQ!eps$Z>o5$s;bHs42CFah7?pP72pCPBU4(44 zyW!Bn!s6j%JEjZMs=e-;Nu0*UL7&V{qK@ z-l_I@JdmTv!8xu0WuB7n?ELw+_V)IR*x60A&Z2^-B@}}q@Vu~C&969n9Fto<{)lMS zXoya)BSxc<3=R(Pdz$w2qNNZeeBolAJ=^wLHWw5YoOO2hSQL0s(HGV>!^ht^=00000NkvXXu0mjfA3OQ4 literal 0 HcmV?d00001 diff --git a/images/follow-output.png b/images/follow-output.png new file mode 100644 index 0000000000000000000000000000000000000000..e18e412aad4d2d5b08e65449c345c556b9322e67 GIT binary patch literal 943 zcmV;g15o^lP)Hd*96_4oDQ;ms-10j#*vLQ zjhJa3v9K^w%q@{8SP(C~lfC0QwA*{_YUoOco$qwgH|gVnHx97!wMtt1tu*(UiB~`j z3d2G~c>UgYNC@W;WAa<;{$qGB>5X{Vo$h8+qKUQ9TJ9R%#ga$~EfGs5@J->g5Eo)X z6tqkiQ5xT{a^La*NE(l3r6ty)w$8NjQ2Y?9CaY*0x3Mr<_-6>t3Tfeza1k`l=Bv3; z{Vjx%_rOzu!^k%tHGUVE38?O*n|l*`Sr#v2@tI;G0pf!2p|A+*7ImsVX8akiYRm6? zDzuH-h5SJNnxWaSrf=2XE`7O_o>>p~CHHaLxoxy2t;7t7_l4`Ad{bu0dp2%L6x}IK zSZ`YsTYfZ5n7+;mwmxlL9bOn_y$k(hlxS?W8Sj`)kKHgqy+_ znYD67QH@d4F9>VP*Due7sw+U@kys+Q~hsJuIIs&lGn__()jFkmqI9 z6tnz>ftcTqWWaic>V|rD4Qui&6BljOoH`Ktav?*)uDYtrX@*sDN?x3z$1iu7o`?SC3 z4JbdM2c`dNY{G*oQ>W>!W6YuM9@@>^j$CTGG^!FZ{EA?X??26B`0(uJ=Qpd>1J#s$ zGL`2HL{KyIPzF5$nlq&@Zl%(qC%UC;5A6j3AxTFyOY$=tzRWIbegD5V?+=>FW1Iq$ RdCC9)002ovPDHLkV1g&k&@})6 literal 0 HcmV?d00001 diff --git a/images/highlight-add.png b/images/highlight-add.png new file mode 100644 index 0000000000000000000000000000000000000000..1e03be9bc896c5f6d8a943ff9d153b42b67e6b16 GIT binary patch literal 564 zcmV-40?Yl0P)8Z)0JRB|3DF3=|YfF7jDEZ>IVpdRI~vVL~%?rHj{Mb-aA4?aN$HkpY6+e zIJ}%A@;qlRND8>Ne);a1hpoZcM@ORNcT0CDpm2lpt8;$t;5m`HA+Mts_V&s9W~>cf zetj;y8B(ff-fq3o6i^ss-tluMK}bpJ9RCvtKmqnoV4WvU2M7e2b^n@kK&}DWEA7Qj z+`01X%TpaFO`sJG5esISB#+&7>@2gVH>sP%}a+DuI`p-7R~pI$1Y5x z9J%rcDSiulyep{dI#Oy%ghc%waq@#~ax=Pj`qhjEu-38}b?Q6+eS$+ zxgkjtHlh#o1_P#oDl|xq z)$=3opuA-AQ-@kiO_W*dZ1Abw6Jy@#*R^Fg!5P*sA&3jgil^7k&X>BCo8zhBfN|0000j literal 0 HcmV?d00001 diff --git a/images/highlight-delete.png b/images/highlight-delete.png new file mode 100644 index 0000000000000000000000000000000000000000..87cd0b0125d6193c16c59f25b88396493e885f6b GIT binary patch literal 640 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfLzW3kH}&M z2FBeW%xLxI@gtz1WQl7;NpOBzNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~*<;sHJ( zuK)l4Z(v|p!N9PVfuWs&p^JfGA_Kz=28KBd467IzAX4jDSb*GiKE6H%hCBv_Tn2_L z28Klp4AZo=>*d6nRHQFelpgl-Jed$XS6*hniPlkf`z7+iOXNkDC`v6+mRl+(v`kK5 zwTk$9b?ME9YMZs?_j%bL_HsDk<9sU2r$Je2`?nP^4n zy$lTd7#Q|j8XpwoI%I5o$k*ermDN#8qhmrm$Ax%K+S#3Uu|MtSb;ix@0t3SZA)d=& zVVA>0E~h43Ns7Cc5PLm2@wTwQZ4try!urld@myOUR3yfXZwfVuCELX$$gHBz;HAv3GxeOFfuao00U1?PcLu(fWV*& z*YDnY^6b^8FJFJbz;6)v0|bBn{{8pwYTmshp#IsOE{-7*lD!9A#hMrxSP$@P+)yej zFHd4mDu4d>{K5|<=XpdH-eIeeoFkI5#Mch*eE5E3q& zsDJ)QWe~HZu=JPqwHHm!J!tPMoAuVM<=A|yGuL0$MD)r}t=B23K4h_=$wxfq{j{s6 zvbJ;1RM`0b{&%I*Q{~<_^9mg*KC_8ox^*ST366Hw_&MDTLh{a=g|okJNlO7blfl!~ K&t;ucLK6VLNBNWh literal 0 HcmV?d00001 diff --git a/images/highlight-discard.png b/images/highlight-discard.png new file mode 100644 index 0000000000000000000000000000000000000000..45f8949bfe3dd7cc4242bc26ba7564cc319bc834 GIT binary patch literal 848 zcmV-W1F!svP)AAe8-^261JTEa#6aNtPXBzm680^#gmX>3y!^2O4V`EXNpx`(y%OtY6I4_r$GOo(X zx)ZIf^GMR31Vi=p_g4G*8Z*w6^JyiekX$YhLZGazAuu_K^{FW}r@Ff1Y**LyWP@GU z*WcGv=LsEop8(Rc5V2!IIb7Su z-o6ka^s&ZR>@Gu5G0`UWq*PTnSV6{yZwWCi1}WdgCz#zUD?VQ~laY?44^yC{+MOmv zS?!jjEZJdy<2-+^fC)#T1$>wr9EN}46R6bGZDz-SQv7}?#?shY4?y6!&ID|?iQ}&F zlWxp^gQ)~DGcjf4ssv-M1o1M+X>eM)x!bL1Ve{znZ%QdVldg+3TwteK}VWR7-bM~3*G<_4PkUOXgDmm!89M~Hro|} zHX$+u2`0gACt!1O{2Tx+tU+fZG9QS7*jWsyh9PQ(=c)xikR(@Ds&GsH5dmfXW_FKQ zR8>{CrVFZ&&LO@W0qx|`uNfe5+(b&sNT=O?BQI0@%!M}{NaL_#2x@}aQ>2Ghk-SeI zHyv?uBr_NTY&60Y0~^C4oi;!PBUo{;m<(vnwpM={Z&rZbE}mLR!O|0qftqgODWn)vavCHprRtB*os}d@0tGl aoqqu?)kdoeH1-ex0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L00!&;00!&<9(6c100007bV*G`2iOY{ z7a2C-AH01400LG?L_t(|+KrK2NK3O( zt1}KT&;|T(yOCwtC`po#_0k7ph9JvdOL^V;h3l;{2P{)smPaJXL|`(R!U9vMn@q;+ zw^z~I)5VRZcy?}fbNa00YRQt%#X%S&(MZ=zpTpfZ^$5qeH`waqS#O@X&Ms zw`tRn7yOwXN}hd>GX8`M)jn289%?QISxBuwU-kf#VSyA%jF1G>A++hoT)FFEUQwwo zQP5J$P~{x}4q!3nf{-NOa}u0>i0#f8pNHMtJT-@T(?Mned04GhfF)xm>J5w%nu5@m zs~QJ+*X_i1bdD|CavAj%l9rZ+#bN;4nJ zFzyCnMyofE9{~j=OI#yLg7ec#$`gxH8OqDc^)mCai<1)zQuXqS(r3T3kpe0@>FMGa zQgQ3;q>X${1_EvC9b7%{lo;_Hxw!m6mdKI;Vst075>6Bme*a literal 0 HcmV?d00001 diff --git a/images/highlight-save.png b/images/highlight-save.png new file mode 100644 index 0000000000000000000000000000000000000000..f1d290c6473dabb354d792a7724cc4d786e0d0b6 GIT binary patch literal 597 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJbFq_W2nPqp?T7vkfLzW3kH}&M z2FBeW%xLxI@gtz1WQl7;NpOBzNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~*BaQ29J1}sCcHRXtt1GHXmOGH)lM%P_}?T46j72hL`z}7OUIX7+O}{2xziz{THCiFfy5WZ;A{IDB&UcKSV;{RoH)Uf$$}Xeg zEh%MNlgsu*mLCYM+>uzlJFWgeM*RuXrem(nhrButRdw$5?mSlAbuhf^V07P+gudf0 z{U>84?9HBVFn{9F%!&8xCLb%9d?IVw;hY&)-Dh6tpLuD*tP>ftPFK%8nY-*l`L!VqTUG;r_P$YVDX-7H*P%?hDcmaPEcUoz-6%T!%dO3OC%>g6+NVstLmszmzt<>Qt7?C z&>Lmel#iLN65NIcr+@CUs@5)KU`=t-W%hANv3>KFDb&Kzily|<*}Xn@bJiRV-Knsw z^Od!vMbwO)D+&*u5x-n~!R%AWbGI8Bc`wA5oa}w0#u>{i7ZUz?lkj_IhPvbY2j=Pd RmjhkH;OXk;vd$@?2>>yI)$afR literal 0 HcmV?d00001 diff --git a/images/move-down.png b/images/move-down.png new file mode 100644 index 0000000000000000000000000000000000000000..5891219e49603b6409d5479247ef1fa8a8cf71c2 GIT binary patch literal 623 zcmV-#0+9WQP)9KeakxIdTpje7cQjq<2c!^ z`Zm_SltDZPAt&#frRYyLt2KB&-G(%{q(iVQLTLEmE7;x%Q2E-zMx_cKcr*5=`6qt_ zJ8$Qx>E38HYSm`*8wpg%DHAF6Ak@qu=tdr9ZV&@0hK{|pLTM+EAS1zES!j~^>gMV) zSJgD~g*+^)fTA^sp+W%}T|?#b>p<{m+*@08kigJI_+;7}FTlfl=m%yDpG=!Ydu;Nd zxN@f?(x%l?jNxPW8<>{Ae&FyaVOl4ItmVe>FR)CpL^X>&_z8O)@9BsigdhL_002ov JPDHLkV1jC@76SkP literal 0 HcmV?d00001 diff --git a/images/move-up.png b/images/move-up.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d9cef97e16ca46909765c0a67091c97908660b GIT binary patch literal 672 zcmV;R0$=@!P)0b000McNliru*9;vE5edJ)+6{olpPkPT$sbOg93kgUk5S3}N14Mj zJ9`2QPnU^Q!($^(CTVNfnvCJd_^zB_{%mUB`TqliV3)SpD2)!M;I1`LS5+JxL^j zO~OgoFbrKmJg8}SpP#!u{Y2f#ZY)Tn8ycjY)X_29v1zB_c}-ACQP&!9y++%+cK|hQ zcVTYU5iEd=eDJ6R!6Ub4fC}%BEHs50WXy+95J(Yr%Kip{H}1g9jtZOr0000tH5kGSn%nbCPM4W3n>ZNdZd-;xN%{AXm6;Gi9t`gfXTt z7&^unU`j(f7_qRB%2`V(M+@aFcT16@+_W48itK$jv%P%(_ulvZ@A&;*@_p&P-kw&L zc9sYsD=LLd2m3a5@TQ>k;lJ+(V;b*HW#IAn;c*`|yzY;o1ja*@i5=W`eJL^s+9r5h zOYn;hNnqWI3q~v!ixd_W5&!kAm|#+L-0l2DXFG&Uj{15rJa+d4O4w{RxZt2tL?V&+ zd_F`P8yiDPLtY0l&A}8Vxd;_vHY+O&GrwU96Nvv`_HwYmn?grNN9Z3L8~a~YIYI(d zTU*=G(t@f{PfySA@Gz=H*i(&NMMp>D%5adNP$-}lm7|=ToQ8%5a9UeiVWLnd1OV;r z?J}7R5;{6M1Oh=yXLi za^TY0*$K#jPIq@VET^}(7kB}rfq?;lH!?CZIywrYRVtNQtsWmA*Jv~o6BCn@lT%Yu z)6>&4Gc#JPc6N4lZfg!gB~v*$Inb#-+O4I3QN*QTkN} zo1oSWpEUcT`L00K*7l~qb!Z?-BNiSs{`kdb7m4TZY6j*xjP-90)f<|I z(8ULLyqaWu^NA-jLg7co_f8#la`8Lx)xO&SgeCT;-=AR-Puzolzye{A8UFANclRas O2~s`0$$z=uO!)_nMK!$u literal 0 HcmV?d00001 diff --git a/images/network-disconnect.png b/images/network-disconnect.png new file mode 100644 index 0000000000000000000000000000000000000000..046b6014fb83f26e54a4ecb9f5ce58409231f628 GIT binary patch literal 760 zcmV_wz3wF{grLzLRxBDtP|3_mFCjz_Vj>v$51Ha0rlR>LZ91>+bbc2f9Fg80 zda46o&b>d*{oM2KULF9DzhQjTfAGHoo;j%;do(xx_|D9*mIIhO^pt*Q{mStlmjws* z@9P;10R6;USy_=zpBNomo)v$MER9wc=cVWRJkuNObUGEGP^eh1*LT*Q+=_l#I#yYn z743pvJFmI;z#`Fe22*Gt5Gb`;El8zO@V!!ik9O;fk+h5G&e zQn_3P%oZqoV`BqKr4qQ^?&~z>#s$T_#@gZ5rc(uInuJK03e14|tg7yI0Y_?&q*IUeHvuyd5N(E}Q8U%wu_PW_@ zLL?G_TrLM*$5pTPH&E2>brTAO_eVxXh9nXRK?o@pi>y~Fl>}czFms~OXb8543?02a zfdy=H+GFhDUF;=8feM9!VEGhIJqzF5+@vu?BodKKCi8*xuwVYi4u|8CR4RR;R;zh( zxtz_E&*u|7BWP>|u~^JyG#V%W=*!dV^`q$O$z+mdMN}#kX}8-1he@#C1P9m+EsCq|@E^T+6F+TyF&nepm0 + + capture-to-disk.png + follow-output.png + configure.png + application-exit.png + network-connect.png + network-disconnect.png + + + highlight-save.png + highlight-discard.png + highlight-edit.png + highlight-delete.png + move-down.png + move-up.png + highlight-add.png + highlight-remove.png + + diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..52a0bbb --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,478 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + 8 + + + 0 + + + 0 + + + 0 + + + 8 + + + + + + 8 + + + 8 + + + 8 + + + 0 + + + 8 + + + + + Port: + + + + + + + + + + Baude rate: + + + + + + + 4 + + + + 921600 + + + + + 576000 + + + + + 460800 + + + + + 230400 + + + + + 115200 + + + + + 57600 + + + + + 38400 + + + + + 19200 + + + + + 9600 + + + + + 4800 + + + + + + + + Data bits: + + + + + + + + 8 + + + + + 7 + + + + + 6 + + + + + 5 + + + + + + + + Stop bits: + + + + + + + + 1 + + + + + 2 + + + + + + + + Parity: + + + + + + + + None + + + + + Odd + + + + + Even + + + + + Mark + + + + + Space + + + + + + + + Handshake: + + + + + + + Software + + + + + + + Hardware + + + + + + + Open mode: + + + + + + + Reading + + + true + + + + + + + Writing + + + true + + + + + + + 0 + + + 0 + + + 0 + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + Open + + + + :/toolbar/network-connect.png:/toolbar/network-connect.png + + + + 22 + 22 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 100 + 20 + + + + + + + + + + + + + + + IBeamCursor + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; background-color:#000066;"><span style=" font-size:9pt; color:#ffffff; background-color:#000066;">[D] this is debug</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:9pt; color:#00ffff;">[B] this is other logging</span></p></body></html> + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + false + + + + + + + 8 + + + + + true + + + + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Send + + + + + + + + + + + toolBar + + + false + + + Qt::ToolButtonTextBesideIcon + + + false + + + TopToolBarArea + + + false + + + + + + + + + + :/toolbar/network-connect.png:/toolbar/network-connect.png + + + Open... + + + Open... + + + + + + :/toolbar/network-disconnect.png:/toolbar/network-disconnect.png + + + Close + + + + + + :/toolbar/configure.png:/toolbar/configure.png + + + Configure... + + + Configure... + + + + + + :/toolbar/application-exit.png:/toolbar/application-exit.png + + + Exit + + + + + + + + + exitAction + triggered() + MainWindow + close() + + + -1 + -1 + + + 399 + 299 + + + + + diff --git a/settings.ui b/settings.ui new file mode 100644 index 0000000..5d0a17d --- /dev/null +++ b/settings.ui @@ -0,0 +1,318 @@ + + + SettingsDialog + + + + 0 + 0 + 587 + 390 + + + + Settings + + + + 8 + + + 8 + + + + + Qt::Horizontal + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 200 + 16777215 + + + + + Highlighting + + + + + Font + + + + + + + 0 + 0 + + + + + + + + + + + 8 + + + 0 + + + + + Qt::NoFocus + + + UP + + + + + + + Qt::NoFocus + + + DN + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add + + + + + + + Edit + + + + + + + Delete + + + + + + + + + Highlight + + + + 8 + + + 8 + + + 8 + + + + + Regular Expression: + + + + + + + + + + Foreground: + + + + + + + + + + + + + + Background: + + + + + + + + + + + + + + + + + + + 8 + + + 8 + + + 8 + + + + + Font: + + + + + + + + + + Size: + + + + + + + true + + + + + + pt + + + 6 + + + 50 + + + 12 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + sectionListWidget + highlightListWidget + addButton + editButton + deleteButton + buttonBox + + + + + buttonBox + accepted() + SettingsDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SettingsDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + sectionListWidget + currentRowChanged(int) + sectionStackedWidget + setCurrentIndex(int) + + + 113 + 174 + + + 367 + 174 + + + + +