diff --git a/.gitignore b/.gitignore index 54e4807b8..f870bed03 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,6 @@ mert/sentence-bleu build/ nbproject/ +mingw/MosesGUI/MosesGUI.e4p +mingw/MosesGUI/_eric4project/ + diff --git a/mingw/MosesGUI/Ui_addMTModel.py b/mingw/MosesGUI/Ui_addMTModel.py new file mode 100644 index 000000000..a312c6f23 --- /dev/null +++ b/mingw/MosesGUI/Ui_addMTModel.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'C:\work\eric4workspace\MosesGUI\addMTModel.ui' +# +# Created: Thu Jul 11 13:38:49 2013 +# by: PyQt4 UI code generator 4.10.2 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName(_fromUtf8("Dialog")) + Dialog.resize(494, 342) + Dialog.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom)) + Dialog.setWindowFilePath(_fromUtf8("")) + self.verticalLayout = QtGui.QVBoxLayout(Dialog) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.groupBox_3 = QtGui.QGroupBox(Dialog) + self.groupBox_3.setObjectName(_fromUtf8("groupBox_3")) + self.gridLayout = QtGui.QGridLayout(self.groupBox_3) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.label = QtGui.QLabel(self.groupBox_3) + self.label.setObjectName(_fromUtf8("label")) + self.gridLayout.addWidget(self.label, 0, 0, 1, 1) + self.editName = QtGui.QLineEdit(self.groupBox_3) + self.editName.setObjectName(_fromUtf8("editName")) + self.gridLayout.addWidget(self.editName, 0, 1, 1, 3) + self.verticalLayout.addWidget(self.groupBox_3) + self.groupBox = QtGui.QGroupBox(Dialog) + self.groupBox.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom)) + self.groupBox.setObjectName(_fromUtf8("groupBox")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.grpBoxInternet = QtGui.QGroupBox(self.groupBox) + self.grpBoxInternet.setCheckable(True) + self.grpBoxInternet.setObjectName(_fromUtf8("grpBoxInternet")) + self.verticalLayout_3 = QtGui.QVBoxLayout(self.grpBoxInternet) + self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) + self.editInternet = QtGui.QLineEdit(self.grpBoxInternet) + self.editInternet.setObjectName(_fromUtf8("editInternet")) + self.verticalLayout_3.addWidget(self.editInternet) + self.verticalLayout_2.addWidget(self.grpBoxInternet) + self.grpBoxLocal = QtGui.QGroupBox(self.groupBox) + self.grpBoxLocal.setFlat(False) + self.grpBoxLocal.setCheckable(True) + self.grpBoxLocal.setChecked(False) + self.grpBoxLocal.setObjectName(_fromUtf8("grpBoxLocal")) + self.horizontalLayout = QtGui.QHBoxLayout(self.grpBoxLocal) + self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) + self.editLocal = QtGui.QLineEdit(self.grpBoxLocal) + self.editLocal.setText(_fromUtf8("")) + self.editLocal.setObjectName(_fromUtf8("editLocal")) + self.horizontalLayout.addWidget(self.editLocal) + self.btnLocal = QtGui.QPushButton(self.grpBoxLocal) + self.btnLocal.setObjectName(_fromUtf8("btnLocal")) + self.horizontalLayout.addWidget(self.btnLocal) + self.horizontalLayout.setStretch(0, 9) + self.horizontalLayout.setStretch(1, 1) + self.verticalLayout_2.addWidget(self.grpBoxLocal) + self.verticalLayout.addWidget(self.groupBox) + self.groupBox_2 = QtGui.QGroupBox(Dialog) + self.groupBox_2.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom)) + self.groupBox_2.setObjectName(_fromUtf8("groupBox_2")) + self.horizontalLayout_2 = QtGui.QHBoxLayout(self.groupBox_2) + self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) + self.editPath = QtGui.QLineEdit(self.groupBox_2) + self.editPath.setObjectName(_fromUtf8("editPath")) + self.horizontalLayout_2.addWidget(self.editPath) + self.btnPath = QtGui.QPushButton(self.groupBox_2) + self.btnPath.setObjectName(_fromUtf8("btnPath")) + self.horizontalLayout_2.addWidget(self.btnPath) + self.horizontalLayout_2.setStretch(0, 9) + self.horizontalLayout_2.setStretch(1, 1) + self.verticalLayout.addWidget(self.groupBox_2) + self.buttonBox = QtGui.QDialogButtonBox(Dialog) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(_fromUtf8("buttonBox")) + self.verticalLayout.addWidget(self.buttonBox) + self.verticalLayout.setStretch(1, 2) + self.verticalLayout.setStretch(2, 1) + self.verticalLayout.setStretch(3, 1) + + self.retranslateUi(Dialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject) + QtCore.QMetaObject.connectSlotsByName(Dialog) + Dialog.setTabOrder(self.editName, self.grpBoxInternet) + Dialog.setTabOrder(self.grpBoxInternet, self.editInternet) + Dialog.setTabOrder(self.editInternet, self.grpBoxLocal) + Dialog.setTabOrder(self.grpBoxLocal, self.editLocal) + Dialog.setTabOrder(self.editLocal, self.btnLocal) + Dialog.setTabOrder(self.btnLocal, self.editPath) + Dialog.setTabOrder(self.editPath, self.btnPath) + Dialog.setTabOrder(self.btnPath, self.buttonBox) + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(_translate("Dialog", "Install MT Model", None)) + self.groupBox_3.setTitle(_translate("Dialog", "MT Model Details", None)) + self.label.setText(_translate("Dialog", "Model Name:", None)) + self.editName.setText(_translate("Dialog", "SampleModel", None)) + self.groupBox.setTitle(_translate("Dialog", "Install From ...", None)) + self.grpBoxInternet.setTitle(_translate("Dialog", "From Internet ...", None)) + self.editInternet.setText(_translate("Dialog", "http://www.statmt.org/~jie/models/EnFr4MosesGUI.zip", None)) + self.grpBoxLocal.setTitle(_translate("Dialog", "From Local File", None)) + self.btnLocal.setText(_translate("Dialog", "...", None)) + self.groupBox_2.setTitle(_translate("Dialog", "Install To ...", None)) + self.btnPath.setText(_translate("Dialog", "...", None)) + + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + Dialog = QtGui.QDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec_()) + diff --git a/mingw/MosesGUI/Ui_chooseMTModel.py b/mingw/MosesGUI/Ui_chooseMTModel.py new file mode 100644 index 000000000..993cd2598 --- /dev/null +++ b/mingw/MosesGUI/Ui_chooseMTModel.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'C:\work\eric4workspace\MosesGUI\chooseMTModel.ui' +# +# Created: Wed Jul 10 16:00:02 2013 +# by: PyQt4 UI code generator 4.10.2 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName(_fromUtf8("Dialog")) + Dialog.resize(400, 300) + self.verticalLayout = QtGui.QVBoxLayout(Dialog) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.groupBox = QtGui.QGroupBox(Dialog) + self.groupBox.setObjectName(_fromUtf8("groupBox")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.groupBox) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.selTableView = QtGui.QTableView(self.groupBox) + self.selTableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.selTableView.setProperty("showDropIndicator", False) + self.selTableView.setDragDropOverwriteMode(False) + self.selTableView.setAlternatingRowColors(False) + self.selTableView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.selTableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.selTableView.setGridStyle(QtCore.Qt.DashLine) + self.selTableView.setSortingEnabled(True) + self.selTableView.setObjectName(_fromUtf8("selTableView")) + self.selTableView.verticalHeader().setVisible(False) + self.verticalLayout_2.addWidget(self.selTableView) + self.verticalLayout.addWidget(self.groupBox) + self.buttonBox = QtGui.QDialogButtonBox(Dialog) + self.buttonBox.setOrientation(QtCore.Qt.Horizontal) + self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) + self.buttonBox.setObjectName(_fromUtf8("buttonBox")) + self.verticalLayout.addWidget(self.buttonBox) + + self.retranslateUi(Dialog) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept) + QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(_translate("Dialog", "Please choose an MT model to load...", None)) + self.groupBox.setTitle(_translate("Dialog", "Avaialble MT Models", None)) + + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + Dialog = QtGui.QDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec_()) + diff --git a/mingw/MosesGUI/Ui_credits.py b/mingw/MosesGUI/Ui_credits.py new file mode 100644 index 000000000..c2e9c5d81 --- /dev/null +++ b/mingw/MosesGUI/Ui_credits.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'C:\work\eric4workspace\MosesGUI\credits.ui' +# +# Created: Wed Jul 10 16:52:58 2013 +# by: PyQt4 UI code generator 4.10.2 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_Dialog(object): + def setupUi(self, Dialog): + Dialog.setObjectName(_fromUtf8("Dialog")) + Dialog.resize(359, 271) + self.label = QtGui.QLabel(Dialog) + self.label.setGeometry(QtCore.QRect(10, 10, 341, 211)) + self.label.setAlignment(QtCore.Qt.AlignJustify|QtCore.Qt.AlignVCenter) + self.label.setWordWrap(True) + self.label.setObjectName(_fromUtf8("label")) + self.pushButton = QtGui.QPushButton(Dialog) + self.pushButton.setGeometry(QtCore.QRect(150, 240, 75, 23)) + self.pushButton.setObjectName(_fromUtf8("pushButton")) + + self.retranslateUi(Dialog) + QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.accept) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(_translate("Dialog", "Credits and Support", None)) + self.label.setText(_translate("Dialog", "\n" +"\n" +"

This software is provided by Capita Translation and Interpreting for the Moses Statistical Machine Translation decoder as part of the Moses Core Project.

\n" +"


\n" +"

For support, please email mail.jie.jiang@gmail.com or submit a post on Moses Support List.

\n" +"


\n" +"

More models are coming soon, please check Moses Packages.

", None)) + self.pushButton.setText(_translate("Dialog", "OK", None)) + + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + Dialog = QtGui.QDialog() + ui = Ui_Dialog() + ui.setupUi(Dialog) + Dialog.show() + sys.exit(app.exec_()) + diff --git a/mingw/MosesGUI/Ui_mainWindow.py b/mingw/MosesGUI/Ui_mainWindow.py new file mode 100644 index 000000000..b5d3fe006 --- /dev/null +++ b/mingw/MosesGUI/Ui_mainWindow.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- + +# Form implementation generated from reading ui file 'C:\work\eric4workspace\MosesGUI\mainWindow.ui' +# +# Created: Thu Jul 11 13:38:46 2013 +# by: PyQt4 UI code generator 4.10.2 +# +# WARNING! All changes made in this file will be lost! + +from PyQt4 import QtCore, QtGui + +try: + _fromUtf8 = QtCore.QString.fromUtf8 +except AttributeError: + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName(_fromUtf8("MainWindow")) + MainWindow.resize(705, 491) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) + MainWindow.setSizePolicy(sizePolicy) + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/icon/moses.ico")), QtGui.QIcon.Normal, QtGui.QIcon.Off) + MainWindow.setWindowIcon(icon) + MainWindow.setLayoutDirection(QtCore.Qt.LeftToRight) + MainWindow.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom)) + self.centralWidget = QtGui.QWidget(MainWindow) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.centralWidget.sizePolicy().hasHeightForWidth()) + self.centralWidget.setSizePolicy(sizePolicy) + self.centralWidget.setObjectName(_fromUtf8("centralWidget")) + self.verticalLayout_3 = QtGui.QVBoxLayout(self.centralWidget) + self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) + self.tabWidget = QtGui.QTabWidget(self.centralWidget) + self.tabWidget.setAutoFillBackground(True) + self.tabWidget.setObjectName(_fromUtf8("tabWidget")) + self.tab = QtGui.QWidget() + self.tab.setAutoFillBackground(True) + self.tab.setObjectName(_fromUtf8("tab")) + self.verticalLayout_2 = QtGui.QVBoxLayout(self.tab) + self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) + self.groupBox = QtGui.QGroupBox(self.tab) + self.groupBox.setObjectName(_fromUtf8("groupBox")) + self.gridLayout = QtGui.QGridLayout(self.groupBox) + self.gridLayout.setObjectName(_fromUtf8("gridLayout")) + self.label = QtGui.QLabel(self.groupBox) + self.label.setObjectName(_fromUtf8("label")) + self.gridLayout.addWidget(self.label, 2, 0, 1, 1) + self.editSrcLang = QtGui.QLineEdit(self.groupBox) + self.editSrcLang.setReadOnly(True) + self.editSrcLang.setObjectName(_fromUtf8("editSrcLang")) + self.gridLayout.addWidget(self.editSrcLang, 2, 1, 1, 1) + self.editTrgLang = QtGui.QLineEdit(self.groupBox) + self.editTrgLang.setReadOnly(True) + self.editTrgLang.setObjectName(_fromUtf8("editTrgLang")) + self.gridLayout.addWidget(self.editTrgLang, 2, 4, 1, 1) + self.label_3 = QtGui.QLabel(self.groupBox) + self.label_3.setObjectName(_fromUtf8("label_3")) + self.gridLayout.addWidget(self.label_3, 2, 3, 1, 1) + self.btnTranslate = QtGui.QPushButton(self.groupBox) + self.btnTranslate.setEnabled(True) + self.btnTranslate.setMinimumSize(QtCore.QSize(120, 30)) + self.btnTranslate.setFlat(False) + self.btnTranslate.setObjectName(_fromUtf8("btnTranslate")) + self.gridLayout.addWidget(self.btnTranslate, 3, 2, 1, 1) + self.editModelName = QtGui.QLineEdit(self.groupBox) + self.editModelName.setReadOnly(True) + self.editModelName.setObjectName(_fromUtf8("editModelName")) + self.gridLayout.addWidget(self.editModelName, 1, 2, 1, 1) + self.label_2 = QtGui.QLabel(self.groupBox) + self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.label_2.setObjectName(_fromUtf8("label_2")) + self.gridLayout.addWidget(self.label_2, 1, 1, 1, 1) + self.verticalLayout_2.addWidget(self.groupBox) + self.splitter = QtGui.QSplitter(self.tab) + self.splitter.setOrientation(QtCore.Qt.Horizontal) + self.splitter.setObjectName(_fromUtf8("splitter")) + self.editSrc = QtGui.QTextEdit(self.splitter) + self.editSrc.setObjectName(_fromUtf8("editSrc")) + self.editTrg = QtGui.QTextEdit(self.splitter) + self.editTrg.setReadOnly(True) + self.editTrg.setObjectName(_fromUtf8("editTrg")) + self.verticalLayout_2.addWidget(self.splitter) + self.verticalLayout_2.setStretch(0, 2) + self.verticalLayout_2.setStretch(1, 8) + self.tabWidget.addTab(self.tab, _fromUtf8("")) + self.tab_2 = QtGui.QWidget() + self.tab_2.setAutoFillBackground(True) + self.tab_2.setObjectName(_fromUtf8("tab_2")) + self.verticalLayout = QtGui.QVBoxLayout(self.tab_2) + self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) + self.label_5 = QtGui.QLabel(self.tab_2) + self.label_5.setAutoFillBackground(True) + self.label_5.setObjectName(_fromUtf8("label_5")) + self.verticalLayout.addWidget(self.label_5) + self.splitter_4 = QtGui.QSplitter(self.tab_2) + self.splitter_4.setOrientation(QtCore.Qt.Horizontal) + self.splitter_4.setObjectName(_fromUtf8("splitter_4")) + self.groupBox_3 = QtGui.QGroupBox(self.splitter_4) + self.groupBox_3.setMinimumSize(QtCore.QSize(200, 0)) + self.groupBox_3.setMaximumSize(QtCore.QSize(200, 16777215)) + self.groupBox_3.setAutoFillBackground(True) + self.groupBox_3.setObjectName(_fromUtf8("groupBox_3")) + self.formLayout = QtGui.QFormLayout(self.groupBox_3) + self.formLayout.setObjectName(_fromUtf8("formLayout")) + self.newModelBtn = QtGui.QPushButton(self.groupBox_3) + self.newModelBtn.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom)) + self.newModelBtn.setObjectName(_fromUtf8("newModelBtn")) + self.formLayout.setWidget(0, QtGui.QFormLayout.SpanningRole, self.newModelBtn) + self.delModelBtn = QtGui.QPushButton(self.groupBox_3) + self.delModelBtn.setObjectName(_fromUtf8("delModelBtn")) + self.formLayout.setWidget(1, QtGui.QFormLayout.SpanningRole, self.delModelBtn) + self.tableView = QtGui.QTableView(self.splitter_4) + font = QtGui.QFont() + font.setPointSize(7) + self.tableView.setFont(font) + self.tableView.setMouseTracking(False) + self.tableView.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu) + self.tableView.setAutoFillBackground(True) + self.tableView.setLocale(QtCore.QLocale(QtCore.QLocale.English, QtCore.QLocale.UnitedKingdom)) + self.tableView.setFrameShape(QtGui.QFrame.StyledPanel) + self.tableView.setFrameShadow(QtGui.QFrame.Plain) + self.tableView.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) + self.tableView.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) + self.tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + self.tableView.setGridStyle(QtCore.Qt.DashLine) + self.tableView.setSortingEnabled(True) + self.tableView.setWordWrap(False) + self.tableView.setCornerButtonEnabled(False) + self.tableView.setObjectName(_fromUtf8("tableView")) + self.tableView.verticalHeader().setVisible(False) + self.tableView.verticalHeader().setSortIndicatorShown(True) + self.verticalLayout.addWidget(self.splitter_4) + self.verticalLayout.setStretch(1, 1000) + self.tabWidget.addTab(self.tab_2, _fromUtf8("")) + self.verticalLayout_3.addWidget(self.tabWidget) + self.labelInfo = QtGui.QLabel(self.centralWidget) + self.labelInfo.setTextFormat(QtCore.Qt.AutoText) + self.labelInfo.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) + self.labelInfo.setObjectName(_fromUtf8("labelInfo")) + self.verticalLayout_3.addWidget(self.labelInfo) + MainWindow.setCentralWidget(self.centralWidget) + + self.retranslateUi(MainWindow) + self.tabWidget.setCurrentIndex(0) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle(_translate("MainWindow", "Moses Machine Translation System", None)) + self.groupBox.setTitle(_translate("MainWindow", "Current MT Model", None)) + self.label.setText(_translate("MainWindow", "Translate From:", None)) + self.label_3.setText(_translate("MainWindow", "Translate Into:", None)) + self.btnTranslate.setText(_translate("MainWindow", "Translate", None)) + self.label_2.setText(_translate("MainWindow", "Model Name:", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Machine Translation", None)) + self.label_5.setText(_translate("MainWindow", "TextLabel", None)) + self.groupBox_3.setTitle(_translate("MainWindow", "Management", None)) + self.newModelBtn.setText(_translate("MainWindow", "Install New Model ...", None)) + self.delModelBtn.setText(_translate("MainWindow", "Uninstall Selected Model ...", None)) + self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Model Management", None)) + self.labelInfo.setText(_translate("MainWindow", "Credits and Support", None)) + +import icons_rc + +if __name__ == "__main__": + import sys + app = QtGui.QApplication(sys.argv) + MainWindow = QtGui.QMainWindow() + ui = Ui_MainWindow() + ui.setupUi(MainWindow) + MainWindow.show() + sys.exit(app.exec_()) + diff --git a/mingw/MosesGUI/__init__.py b/mingw/MosesGUI/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/mingw/MosesGUI/addMTModel.py b/mingw/MosesGUI/addMTModel.py new file mode 100644 index 000000000..3fd4b14de --- /dev/null +++ b/mingw/MosesGUI/addMTModel.py @@ -0,0 +1,114 @@ +# -*- coding: utf-8 -*- + +""" +Module implementing Dialog. +""" + +from PyQt4.QtGui import * +from PyQt4.QtCore import * + +import os, datetime + +from Ui_addMTModel import Ui_Dialog +from util import * + +class AddMTModelDialog(QDialog, Ui_Dialog): + """ + Class documentation goes here. + """ + def __init__(self, parent = None, workdir=None): + """ + Constructor + """ + QDialog.__init__(self, parent) + self.setupUi(self) + self.timestr = None + self.workdir = workdir + todir, timestr = self.findEmptyDirWithTime(self.workdir) + self.editPath.setText(todir) + self.editName.setText("SampleModel_" + timestr) + + def findEmptyDirWithTime(self, workdir): + if not self.timestr: + self.timestr = datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S') + while True: + todir = os.path.join(workdir, "Model_%s" % self.timestr) + if not os.path.exists(todir): + break + self.timestr = datetime.datetime.now().strftime('%Y-%m-%d_%H%M%S') + return todir, self.timestr + + @pyqtSignature("") + def on_btnLocal_clicked(self): + """ + Slot documentation goes here. + """ + dialog = QFileDialog(self) + dialog.setFileMode(QFileDialog.ExistingFile) + dialog.setNameFilter("Zipped model files (*.zip)") + dialog.setViewMode(QFileDialog.Detail) + if dialog.exec_(): + self.editLocal.setText(dialog.selectedFiles()[0]) + + @pyqtSignature("") + def on_btnPath_clicked(self): + """ + Slot documentation goes here. + """ + dialog = QFileDialog(self, directory=self.workdir) + dialog.setFileMode(QFileDialog.Directory) + dialog.setViewMode(QFileDialog.Detail) + dialog.setOptions(QFileDialog.ShowDirsOnly) + if dialog.exec_(): + root = str(dialog.selectedFiles()[0]) + todir, _ = self.findEmptyDirWithTime(root) + self.editPath.setText(todir) + + @pyqtSignature("bool") + def on_grpBoxInternet_toggled(self, p0): + """ + Slot documentation goes here. + """ + self.grpBoxLocal.setChecked(not p0) + + @pyqtSignature("bool") + def on_grpBoxLocal_toggled(self, p0): + """ + Slot documentation goes here. + """ + self.grpBoxInternet.setChecked(not p0) + + @pyqtSignature("") + def on_buttonBox_accepted(self): + """ + Slot documentation goes here. + """ + def checkEmpty(mystr): + return len(str(mystr).strip()) <= 0 + + #check everything + self.modelName = self.editName.text() + if checkEmpty(self.modelName): + doAlert("Please provide non-empty Model Name") + return + if self.grpBoxInternet.isChecked(): + self.source = self.editInternet.text() + self.sourceMode = "Internet" + elif self.grpBoxLocal.isChecked(): + self.source = self.editLocal.text() + self.sourceMode = "Local" + if not os.path.exists(str(self.source)): + doAlert("Please provide valid local file as source") + return + else: + doAlert("Please provide Install Source") + return + if checkEmpty(self.source): + doAlert("Please provide non-empty Install Source") + return + self.dest = self.editPath.text() + if checkEmpty(self.dest): + doAlert("Please provide non-empty Install Destination Folder") + return + self.accept() + diff --git a/mingw/MosesGUI/addMTModel.ui b/mingw/MosesGUI/addMTModel.ui new file mode 100644 index 000000000..53d198685 --- /dev/null +++ b/mingw/MosesGUI/addMTModel.ui @@ -0,0 +1,170 @@ + + + Dialog + + + + 0 + 0 + 494 + 342 + + + + Install MT Model + + + + + + + + + + + + MT Model Details + + + + + + Model Name: + + + + + + + SampleModel + + + + + + + + + + + + + Install From ... + + + + + + From Internet ... + + + true + + + + + + http://www.statmt.org/~jie/models/EnFr4MosesGUI.zip + + + + + + + + + + From Local File + + + false + + + true + + + false + + + + + + + + + + + + + ... + + + + + + + + + + + + + + + + Install To ... + + + + + + + + + ... + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + editName + grpBoxInternet + editInternet + grpBoxLocal + editLocal + btnLocal + editPath + btnPath + buttonBox + + + + + buttonBox + rejected() + Dialog + reject() + + + 442 + 326 + + + 474 + 339 + + + + + diff --git a/mingw/MosesGUI/chooseMTModel.py b/mingw/MosesGUI/chooseMTModel.py new file mode 100644 index 000000000..52a6c8eed --- /dev/null +++ b/mingw/MosesGUI/chooseMTModel.py @@ -0,0 +1,71 @@ +# -*- coding: utf-8 -*- + +""" +Module implementing ChooseMTModelDialog. +""" + +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from PyQt4.QtSql import * + +from Ui_chooseMTModel import Ui_Dialog + +class ChooseMTModelDialog(QDialog, Ui_Dialog): + """ + Class documentation goes here. + """ + def __init__(self, parent = None, datamodel = None): + """ + Constructor + """ + QDialog.__init__(self, parent) + self.setupUi(self) + self.model = QSqlQueryModel() + self.selTableView.setModel(self.model) + self.database = datamodel.getQSqlDatabase() + self.updateModel() + self.selTableView.hideColumn(0) + self.selTableView.hideColumn(5) + self.selTableView.hideColumn(6) + #change status and keep the column + QObject.connect(datamodel, SIGNAL("modelInstalled()"), self.on_datamodel_modelInstalled) + + def updateModel(self): + self.model.setQuery('SELECT ID, name, srclang, trglang, status, path, mosesini FROM models WHERE status = "READY" AND deleted != "True"', self.database) + + def on_datamodel_recordUpdated(self, bRecord): + #deal with the selection changed problem + try: + if bRecord: + current = self.selTableView.currentIndex() + if current and current.row() <> -1: + self.curSelection = current.row() + else: + self.curSelection = None + else: + if not self.curSelection is None: + self.selTableView.selectRow(self.curSelection) + except Exception, e: + print >> sys.stderr, str(e) + + def on_datamodel_modelInstalled(self): + self.updateModel() + + @pyqtSignature("") + def on_buttonBox_accepted(self): + """ + Slot documentation goes here. + """ + current = self.selTableView.currentIndex() + if not current: + doAlert("Please choose a model to start.") + return + record = self.model.record(current.row()) + self.ID = record.value("ID").toString() + self.modelName = record.value("name").toString() + self.srcLang = record.value('srclang').toString() + self.trgLang = record.value('trglang').toString() + self.path = record.value("path").toString() + self.mosesini = record.value("mosesini").toString() + self.accept() + diff --git a/mingw/MosesGUI/chooseMTModel.ui b/mingw/MosesGUI/chooseMTModel.ui new file mode 100644 index 000000000..6b1f1d8a5 --- /dev/null +++ b/mingw/MosesGUI/chooseMTModel.ui @@ -0,0 +1,104 @@ + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Please choose an MT model to load... + + + + + + Avaialble MT Models + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + false + + + false + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + Qt::DashLine + + + true + + + false + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/mingw/MosesGUI/credits.py b/mingw/MosesGUI/credits.py new file mode 100644 index 000000000..6b1b97a05 --- /dev/null +++ b/mingw/MosesGUI/credits.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +""" +Module implementing DlgCredits. +""" + +from PyQt4.QtGui import QDialog, QDesktopServices +from PyQt4.QtCore import pyqtSignature, QUrl + +from Ui_credits import Ui_Dialog + +class DlgCredits(QDialog, Ui_Dialog): + """ + Class documentation goes here. + """ + def __init__(self, parent = None): + """ + Constructor + """ + QDialog.__init__(self, parent) + self.setupUi(self) + + + @pyqtSignature("QString") + def on_label_linkActivated(self, link): + """ + Slot documentation goes here. + """ + QDesktopServices().openUrl(QUrl(link)) diff --git a/mingw/MosesGUI/credits.ui b/mingw/MosesGUI/credits.ui new file mode 100644 index 000000000..d574c6f52 --- /dev/null +++ b/mingw/MosesGUI/credits.ui @@ -0,0 +1,76 @@ + + + Dialog + + + + 0 + 0 + 359 + 271 + + + + Credits and Support + + + + + 10 + 10 + 341 + 211 + + + + <!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:'MS Shell Dlg 2'; font-size:8pt; 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;"><span style=" font-size:10pt;">This software is provided by </span><a href="http://www.capitatranslationinterpreting.com/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">Capita Translation and Interpreting</span></a><span style=" font-size:10pt;"> for the </span><a href="http://www.statmt.org/moses/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">Moses</span></a><span style=" font-size:10pt;"> Statistical Machine Translation decoder as part of the </span><a href="http://www.statmt.org/mosescore/"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">Moses Core Project</span></a><a href="http://www.statmt.org/mosescore/"><span style=" font-size:10pt; text-decoration: underline; color:#000000;">.</span></a></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; color:#000000;"><br /></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:10pt; color:#000000;">For support, please email mail.jie.jiang@gmail.com or submit a post on </span><a href="http://www.statmt.org/moses/?n=Moses.MailingLists"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">Moses Support List</span></a><span style=" font-size:10pt; text-decoration: underline; color:#000000;">.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt; color:#000000;"><br /></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:10pt; color:#000000;">More models are coming soon, please check </span><a href="http://www.statmt.org/moses/?n=Moses.Packages"><span style=" font-size:10pt; text-decoration: underline; color:#0000ff;">Moses Packages</span></a><span style=" font-size:10pt; text-decoration: underline; color:#000000;">.</span></p></body></html> + + + Qt::AlignJustify|Qt::AlignVCenter + + + true + + + + + + 150 + 240 + 75 + 23 + + + + OK + + + + + + + pushButton + clicked() + Dialog + accept() + + + 151 + 98 + + + 186 + 118 + + + + + diff --git a/mingw/MosesGUI/datamodel.py b/mingw/MosesGUI/datamodel.py new file mode 100644 index 000000000..570649ee5 --- /dev/null +++ b/mingw/MosesGUI/datamodel.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- + +from PyQt4.QtCore import * +from PyQt4.QtSql import * + +import sys, os, threading, time, urllib2, zipfile, shutil, ConfigParser +from util import * + +class DataModel(QSqlTableModel): + import os + defaultDbFile = os.path.join(os.path.split(os.path.realpath(__file__))[0], "models.sqlite") + + def __init__(self, parent=None, filename=None): + self.installThreads = {} + self.processes = set() + if filename is None: + filename = DataModel.defaultDbFile + self.db = QSqlDatabase.addDatabase('QSQLITE') + print >> sys.stderr, "Open database at %s" % filename + self.db.setDatabaseName(filename) + self.db.open() + query = QSqlQuery('SELECT COUNT(*) FROM sqlite_master WHERE type="table" AND tbl_name="models"', self.db) + if not query.next() or query.value(0).toInt()[0] < 1: + #create new table + print >> sys.stderr, "Table not find, create the table" + query = QSqlQuery('CREATE TABLE models (ID INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, status TEXT, srclang TEXT, trglang TEXT, date DATE, path TEXT, mosesini TEXT, origin TEXT, originMode TEXT, deleted TEXT)', self.db) + if query.next(): + print >> sys.stderr, query.value(0).toString() + #TODO: shoudn't design the deletion checking like this + #change all deleted models into not deleted in case it failed last time + query = QSqlQuery('UPDATE models SET deleted="False" WHERE deleted="True"', self.db) + query = QSqlQuery('UPDATE models SET status="READY" WHERE status="ON"', self.db) + super(DataModel, self).__init__(parent, self.db) + self.setTable("models") + self.select() + self.setEditStrategy(QSqlTableModel.OnFieldChange) + + def destroy(self): + bExit = False + for i in self.installThreads: + t, flag = self.installThreads[i] + if t.isAlive() and flag: + if not bExit: + if not doQuestion("Installing process is running in the background, do you want to terminate them and exit?"): + return False + else: + bExit = True + self.installThreads[i][1] = False + t.join() + if self.db: + self.db.close() + self.db = None + return True + + def getQSqlDatabase(self): + return self.db + + def getRowID(self, row): + record = self.record(row) + return record.value('ID') + + def delModel(self, row): + record = self.record(row) + if str(record.value('deleted').toString()) == 'True': + self.emit(SIGNAL("messageBox(QString)"), "The model is deleting, please be patient!") + return + #hint to decide what to delete + text = '''You are going to delete the selected model entry. +Do you also want to delete all the model files on the disk? +Click "Yes" to delete model entry and model files. +Click "No" to delete model entry but keep model files. +Click "Cancel" to do nothing.''' + reply = QMessageBox.question(None, 'Message', text, QMessageBox.Yes, QMessageBox.No, QMessageBox.Cancel) + + if reply == QMessageBox.Cancel: + return + else: + record.setValue('deleted', 'True') + self.changeRecord(row, record) + def delModelThread(): + irowid, _ = record.value("ID").toInt() + if irowid in self.installThreads: + t, flag = self.installThreads[irowid] + if t.isAlive() and flag: + self.installThreads[irowid][1] = False + t.join() + if reply == QMessageBox.Yes: + destDir = str(record.value("path").toString()) + try: + shutil.rmtree(destDir) + except Exception, e: + self.emit(SIGNAL("messageBox(QString)"), "Failed to remove dir: " + destDir) + print >> sys.stderr, str(e) + self.removeRow(row) + #end of Model deleting thread + + t = threading.Thread(target=delModelThread) + t.start() + + def newEntry(self): + import random + rec = self.record() + for i in xrange(1, 10): + rec.setValue(i, QVariant(str(random.random()))) + self.insertRecord(-1, rec) + doAlert(self.query().lastInsertId().toString()) + + def changeRecord(self, curRow, record): + #self.emit(SIGNAL("recordUpdated(bool)"), True) #record selection + self.setRecord(curRow, record) + #self.emit(SIGNAL("recordUpdated(bool)"), False) #restore selection + + def installModel(self, installParam): + dest = installParam['dest'] + #make dir + if not os.path.exists(dest): + try: + os.makedirs(str(dest)) + except: + doAlert("Failed to create install directory: %s" % dest) + return + #create entry in db + rec = self.record() + rec.setValue('name', installParam['modelName']) + rec.setValue('status', 'Fetching Source...') + rec.setValue('path', dest) + rec.setValue('origin', installParam['source']) + rec.setValue('originMode', installParam['sourceMode']) + rec.setValue('date', QDateTime.currentDateTime()) + rec.setValue('deleted', 'False') + self.insertRecord(-1, rec) + rowid = self.query().lastInsertId() + + #start thread + def installThread(irowid): + + #find the current row in model + def updateRecord(keyvalues): + curRow = None + for i in xrange(0, self.rowCount()): # TODO: use binary search instead of linear + if self.record(i).value("ID") == rowid: + curRow = i + break + if not curRow is None: + record = self.record(curRow) + for key in keyvalues: + record.setValue(key, keyvalues[key]) + self.changeRecord(curRow, record) + return curRow + + def checkExit(): + if not irowid in self.installThreads or not self.installThreads[irowid][1]: #check thread is ok to run + return True + else: + return False + + def markExit(): + if irowid in self.installThreads: #set thread to dead + self.installThreads[irowid][1] = False + + def statusMessageLogMarkExit(status=None, message=None, exception=None): + if not status is None: + updateRecord({'status':status}) + if not message is None: + self.emit(SIGNAL("messageBox(QString)"), message) + print >> sys.stderr, message + if not exception is None: + print >> sys.stderr, str(exception) + markExit() + + #1. download or copy from local + destFile = os.path.join(str(dest), "model.zip") #where the downloaded/copied zip file is + destDir = os.path.join(str(dest), "model") #where the unzipped contents are + + if installParam['sourceMode'] == 'Local': + fin = fout = None + try: + inFile = str(installParam['source']) + total_size = os.path.getsize(inFile) + fin = open(inFile, 'rb') + chunk_size = 52428800 #50MB as chunk size + fout = open(destFile, 'wb') + content = fin.read(chunk_size) + download_size = content_size = len(content) + lastMsg = "" + while content_size > 0: + if checkExit(): #check if thread is notified as exit + return statusMessageLogMarkExit() + fout.write(content) + if total_size > 0: + msg = 'COPY %.0f%%' % (download_size * 100.0 / total_size) + else: + msg = 'COPY %d MB' % (download_size/1048576) + if msg <> lastMsg: + updateRecord({'status' : msg}) + lastMsg = msg + content = fin.read(chunk_size) + content_size = len(content) + download_size += content_size + except Exception, e: + return statusMessageLogMarkExit(status='Failed copying from: %s' % installParam['source'], + message="Failed copy model: %s" % installParam['modelName'], exception=e) + finally: + if fin: + fin.close() + if fout: + fout.close() + + elif installParam['sourceMode'] == 'Internet': + conn = fout = None + try: + conn = urllib2.urlopen(str(installParam['source'])) + total_size = int(conn.headers['Content-Length']) + chunk_size = 1048576 #1MB as chunk size + fout = open(destFile, 'wb') + content = conn.read(chunk_size) + download_size = content_size = len(content) + lastMsg = "" + while content_size > 0: + if checkExit(): #check if thread is notified as exit + return statusMessageLogMarkExit() + fout.write(content) + if total_size > 0: + msg = 'DOWNLOAD %.0f%%' % (download_size * 100.0 / total_size) + else: + msg = 'DOWNLOAD %d MB' % (download_size/1048576) + if msg <> lastMsg: + updateRecord({'status' : msg}) + lastMsg = msg + content = conn.read(chunk_size) + content_size = len(content) + download_size += content_size + except Exception, e: + return statusMessageLogMarkExit(status='Failed downloading from: %s' % installParam['source'], + message="Failed download model: %s" % installParam['modelName'], exception=e) + finally: + if conn: + conn.close() + if fout: + fout.close() + else: + return statusMessageLogMarkExit(status='Unsupported source mode: %s' % installParam['sourceMode']) + + #2. unzip + zfile = fout = None + try: + zfile = zipfile.ZipFile(destFile) + #check property files + if not "model.ini" in zfile.namelist(): + return statusMessageLogMarkExit(status='Missing model.ini in model file: %s' % installParam['sourceMode'], + message="Invalid modle file format because model.ini is missing in the zipped model file, exit installation for model %s" % installParam['modelName']) + chunk_size = 52428800 #50MB as chunk size + #get file size uncompressed + total_size = 0 + for name in zfile.namelist(): + total_size += zfile.getinfo(name).file_size + download_size = 0 + lastMsg = "" + for i, name in enumerate(zfile.namelist()): + (dirname, filename) = os.path.split(name) + outDir = os.path.join(destDir, dirname) + if not os.path.exists(outDir): + os.makedirs(outDir) + if filename: + fin = zfile.open(name, 'r') + outFile = os.path.join(destDir, name) + fout = open(outFile, 'wb') + content = fin.read(chunk_size) + content_size = len(content) + download_size += content_size + while content_size > 0: + if checkExit(): #check if thread is notified as exit + return statusMessageLogMarkExit() + fout.write(content) + if total_size > 0: + msg = 'UNZIP %.0f%%' % (download_size * 100.0 / total_size) + else: + msg = 'UNZIP %d MB' % (download_size/1048576) + if msg <> lastMsg: + updateRecord({'status' : msg}) + lastMsg = msg + content = fin.read(chunk_size) + content_size = len(content) + download_size += content_size + fin.close() + fout.close() + except Exception, e: + return statusMessageLogMarkExit(status='Failed unzipping from: %s' % installParam['source'], + message="Failed unzip model: %s" % installParam['modelName'], exception=e) + finally: + if zfile: + zfile.close() + if fin: + fin.close() + if fout: + fout.close() + + #3 post process and check data validity + try: + modelini = os.path.join(destDir, "model.ini") + cp = ConfigParser.RawConfigParser() + cp.read(modelini) + mosesini = os.path.join(destDir, 'moses.ini') + if not os.path.exists(mosesini): + raise Exception, "Moses ini doesn't exist" + updateRecord({'srclang':cp.get("Language", 'Source Language').upper(), 'trglang':cp.get("Language", 'Target Language').upper(), 'mosesini':mosesini}) + except Exception, e: + return statusMessageLogMarkExit(status='ERROR model format %s' % installParam['source'], + message="Unspported model format: %s" % installParam['modelName'], exception=e) + + statusMessageLogMarkExit(status='READY', message="Model %s Installed!" % installParam['modelName']) + #send new model signal + self.emit(SIGNAL("modelInstalled()")) #record selection + return + #end of thread func + + #start the thread + irowid, _ = rowid.toInt() + t = threading.Thread(target=installThread, args=(irowid, )) + if irowid in self.installThreads: #if old thread is there + print >> sys.stderr, "table rowid %d already has a thread running, stop it" % irowid + self.installThreads[irowid][1] = False + self.installThreads[irowid] = [t, True] + t.start() + diff --git a/mingw/MosesGUI/engine.py b/mingw/MosesGUI/engine.py new file mode 100644 index 000000000..eb0226f55 --- /dev/null +++ b/mingw/MosesGUI/engine.py @@ -0,0 +1,89 @@ +# -*- coding: utf-8 -*- + +from PyQt4.QtCore import * + +import os, subprocess, sys, signal, ConfigParser + +from moses import Moses +from util import * + +class Engine(QObject): + def __init__(self, model, moses): + super(Engine, self).__init__() + self.model = model + self.moses = moses + self.check(self.model) + #determine how many steps by num of modules in the model directory (moses + tok/detok + ...) + 1 + modelini = model['path'] + os.sep + 'model' + os.sep + 'model.ini' + if not os.path.exists(modelini): + raise Exception, "Model ini file doesn't exist, please check model dir %s" % modelini + cp = ConfigParser.RawConfigParser() + cp.readfp(open(modelini)) + #true model + truemodel = None + try: + truemodel = cp.get("Preprocess", 'Truemodel') + if not os.path.exists(model['path'] + os.sep + 'model' + os.sep + truemodel): + doAlert("Truemodel doesn't exist, ignore %s" % truemodel) + truemodel = None + except: + #doAlert("Truemodel not configured") + truemodel = None + self.cmds = [] + #tok + self.cmds.append('"%s" -q -l %s -noxml' % (self.moses.getTokenizer(), str(model['srclang']).lower())) + if not truemodel is None: + self.cmds.append('"%s" -model "%s"' % (self.moses.getTruecase(), truemodel) ) + self.cmds.append('"%s" -f moses.ini' % self.moses.getMosesCmd()) + self.cmds.append('"%s"' % self.moses.getDetruecase()) + self.cmds.append('"%s" -q -noxml -l %s' % (self.moses.getDetokenizer(), str(model['trglang']).lower())) + self.process = [] + #doAlert('\n'.join(self.cmds)) + + def check(self, model): + if not os.path.exists(model['path']) or not os.path.exists(model['mosesini']): + raise Exception, "Model file doesn't exist, please check model dir %s" % self.model['path'] + + def countSteps(self): + return len(self.cmds) + 1 + + def start(self): + #print >> sys.stderr, self.cmds + try: + self.emit(SIGNAL("stepFinished(int)"), 0) + for i, cmd in enumerate(self.cmds): + proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, cwd=os.path.join(str(self.model['path']), 'model')) + self.process.append(proc) + if not proc.poll() is None: + raise Exception, "Failed to start engine!" + proc.stdin.write("dummy\n") + proc.stdin.flush() + if len(proc.stdout.readline().strip()) <= 0: + raise Exception, "Engine process exited: [%s] in folder [%s]" % (cmd, os.path.join(str(self.model['path']), 'model')) + self.emit(SIGNAL("stepFinished(int)"), i+1) + self.emit(SIGNAL("loaded(bool, QString)"), True, "Model Loaded") + except Exception, e: + self.emit(SIGNAL("loaded(bool, QString)"), False, "Failed to load Model: %s" % str(e)) + + def stop(self): + for process in self.process: + #doAlert(str(process.pid)) + #print >> sys.stderr, str(process) + process.terminate() + process.wait() + self.process = [] + + def translate(self, input): + lastInput = input + try: + for i, proc in enumerate(self.process): + if not proc.poll() is None: + raise Exception, "Failed to start engine!" + proc.stdin.write("%s\n" % lastInput) + proc.stdin.flush() + output = proc.stdout.readline().strip() + lastInput = output + return output + except Exception, e: + print >> sys.stderr, "Translate error: %s" % str(e) + return lastInput diff --git a/mingw/MosesGUI/icon/moses.gif b/mingw/MosesGUI/icon/moses.gif new file mode 100644 index 000000000..6144f6132 Binary files /dev/null and b/mingw/MosesGUI/icon/moses.gif differ diff --git a/mingw/MosesGUI/icon/moses.ico b/mingw/MosesGUI/icon/moses.ico new file mode 100644 index 000000000..6b2669809 Binary files /dev/null and b/mingw/MosesGUI/icon/moses.ico differ diff --git a/mingw/MosesGUI/icons.qrc b/mingw/MosesGUI/icons.qrc new file mode 100644 index 000000000..516cd31fc --- /dev/null +++ b/mingw/MosesGUI/icons.qrc @@ -0,0 +1,5 @@ + + + icon/moses.ico + + diff --git a/mingw/MosesGUI/icons_rc.py b/mingw/MosesGUI/icons_rc.py new file mode 100644 index 000000000..3c5d216ce --- /dev/null +++ b/mingw/MosesGUI/icons_rc.py @@ -0,0 +1,1021 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created: Thu 11. Jul 13:17:57 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\x3d\x4c\ +\x00\ +\x01\x08\x3e\x78\x9c\xed\xdd\x05\x98\x2c\x47\xd5\x06\xe0\x1b\x34\ +\xb8\x07\x87\x20\x81\xe0\xee\x12\x82\xbb\xbb\xbb\xbb\x3b\x01\x82\ +\xbb\xbb\xbb\xbb\x4b\x70\x77\xf7\xe0\xee\xee\xf5\xe7\x2d\x9e\x2f\ +\xff\xa1\xe9\x99\xe9\xdd\x9d\xd9\xdd\x0b\xb7\xf2\x74\x76\xee\x4c\ +\x4b\xd5\x91\xef\x7c\xe7\x54\x75\xf7\x8e\x1d\xbb\x1d\xf4\xdf\x7e\ +\xfb\xed\x38\xe8\xff\x7b\xee\xd8\x7b\xf7\xdd\x76\xec\xb1\x63\xc7\ +\x8e\xbd\x0f\xda\x0e\xfa\xca\x97\xfd\xfb\x7f\xb5\x83\xf6\xdb\x6b\ +\x47\xdf\xd2\xda\x7f\x59\xfb\xe7\x3f\xff\xd9\xfe\xf1\x8f\x7f\xf4\ +\xed\xef\x7f\xff\x7b\xfb\xdb\xdf\xfe\xf6\x6f\x9b\xef\xfc\x66\xbf\ +\xb1\x2d\xc7\xd5\x63\xf3\xef\x1c\xb7\xab\xfd\x7f\x8b\xcc\xb6\xfa\ +\xfa\xd1\x51\xf4\x33\x4b\xbf\x1b\xd9\xd2\x72\xbd\x5d\xf6\xf0\x2f\ +\x39\x93\xc5\x56\x5c\x73\x96\xdd\xfd\xf1\x8f\x7f\x6c\xdf\xf9\xce\ +\x77\xda\x47\x3e\xf2\x91\xf6\xda\xd7\xbe\xb6\x3d\xed\x69\x4f\x6b\ +\xf7\xbf\xff\xfd\xdb\x2d\x6e\x71\x8b\x76\x9d\xeb\x5c\xa7\x6f\x37\ +\xbc\xe1\x0d\xdb\x55\xaf\x7a\xd5\x76\xe9\x4b\x5f\xba\x5d\xfe\xf2\ +\x97\x6f\x97\xbd\xec\x65\xfb\xf7\x37\xbf\xf9\xcd\xdb\xad\x6f\x7d\ +\xeb\x76\xcf\x7b\xde\xb3\x3d\xf6\xb1\x8f\x6d\x2f\x7e\xf1\x8b\xdb\ +\x7b\xde\xf3\x9e\xf6\x8d\x6f\x7c\xa3\xfd\xf6\xb7\xbf\x5d\x57\x7f\ +\xb6\xba\x0d\xed\x77\x15\xe7\x5f\x75\x8b\xcf\x0d\xaf\xe5\xfb\x6f\ +\x7f\xfb\xdb\xed\xed\x6f\x7f\x7b\x7b\xc2\x13\x9e\xd0\xee\x78\xc7\ +\x3b\xb6\xab\x5c\xe5\x2a\xed\x02\x17\xb8\x40\x3b\xcb\x59\xce\xd2\ +\x4e\x7d\xea\x53\xb7\x93\x9e\xf4\xa4\x6d\xaf\xbd\xf6\x6a\xe7\x38\ +\xc7\x39\xda\xb9\xce\x75\xae\x76\xb2\x93\x9d\xac\x1d\xf9\xc8\x47\ +\x6e\x7b\xee\xb9\x67\xbb\xc4\x25\x2e\xd1\x2e\x78\xc1\x0b\xb6\x0b\ +\x5d\xe8\x42\xed\x04\x27\x38\x41\x3b\xea\x51\x8f\xda\xf7\x3f\xf9\ +\xc9\x4f\xde\x4e\x74\xa2\x13\xf5\x7d\x4f\x7b\xda\xd3\xb6\xb3\x9f\ +\xfd\xec\xed\xe2\x17\xbf\x78\xb7\x8f\x87\x3e\xf4\xa1\xed\x55\xaf\ +\x7a\x55\xfb\xdc\xe7\x3e\xd7\xfe\xf0\x87\x3f\x8c\xf6\x75\x3b\x60\ +\xc3\x2c\xfc\x5a\xd4\xb6\x43\xdf\xb5\x60\xfb\xb0\x2f\xbf\xfa\xd5\ +\xaf\xda\xfb\xdf\xff\xfe\xf6\xd4\xa7\x3e\xb5\xdd\xee\x76\xb7\x6b\ +\x97\xb9\xcc\x65\xba\x7e\x4e\x72\x92\x93\xb4\xa3\x1c\xe5\x28\xed\ +\x10\x87\x38\x44\x43\x6d\xb2\x1d\xee\x70\x87\x6b\xe7\x3b\xdf\xf9\ +\xba\x4f\x3f\xf9\xc9\x4f\x6e\x0f\x78\xc0\x03\xfa\xbe\x77\xbf\xfb\ +\xdd\xfb\xe7\x0b\x5f\xf8\xc2\xfd\xb7\xf3\x9e\xf7\xbc\xed\xa2\x17\ +\xbd\x68\xff\x9e\x9d\x1c\xf7\xb8\xc7\x6d\x97\xba\xd4\xa5\xda\x4d\ +\x6f\x7a\xd3\x76\xa5\x2b\x5d\xa9\x9d\xf2\x94\xa7\x6c\xbb\xef\xbe\ +\x7b\x3b\xde\xf1\x8e\xd7\xed\x6a\xdf\x7d\xf7\x6d\xd7\xba\xd6\xb5\ +\x3a\xb6\xbc\xec\x65\x2f\x6b\xdf\xfa\xd6\xb7\x26\xf5\x7f\xb3\xda\ +\x5f\xff\xfa\xd7\xf6\xa7\x3f\xfd\xa9\x73\x98\xb5\xb4\x55\xe3\xc5\ +\x7a\xae\xff\x8b\x5f\xfc\xa2\x7d\xf0\x83\x1f\xec\x3a\xbf\xe5\x2d\ +\x6f\xd9\xfd\x95\x9f\x1e\xf6\xb0\x87\xfd\x37\x5d\xd7\x8d\x1d\xec\ +\xb6\xdb\x6e\xed\x48\x47\x3a\x52\x3b\xc3\x19\xce\xd0\x2e\x79\xc9\ +\x4b\x76\xcc\x87\xfd\x77\xba\xd3\x9d\xda\x17\xbf\xf8\xc5\x76\xd7\ +\xbb\xde\xb5\xed\xb1\xc7\x1e\x5d\xf7\x7c\x9e\xee\x61\x09\xbd\x1f\ +\xf1\x88\x47\x6c\xe7\x3c\xe7\x39\xbb\xfe\x9f\xf2\x94\xa7\xb4\xfb\ +\xde\xf7\xbe\xed\x50\x87\x3a\x54\x3b\xc2\x11\x8e\xd0\x63\x06\x4c\ +\x39\xe6\x31\x8f\xd9\xed\x01\x46\xb0\x91\x07\x3f\xf8\xc1\xed\xad\ +\x6f\x7d\x6b\xfb\xd1\x8f\x7e\xb4\x70\x4c\xab\x94\x97\x46\xef\x7f\ +\xf9\xcb\x5f\x36\x3d\x3e\xaf\xb7\x0d\xb1\x8a\xfd\x7e\xf3\x9b\xdf\ +\x6c\x2f\x7f\xf9\xcb\xdb\x5d\xee\x72\x97\x8e\xbf\x30\x7a\xa8\x67\ +\x3a\xa6\xeb\x6c\xfe\x5d\x7f\x3f\xe4\x21\x0f\xd9\x8e\x73\x9c\xe3\ +\x74\x5d\x9e\xf9\xcc\x67\x6e\xc7\x38\xc6\x31\xda\x35\xae\x71\x8d\ +\xf6\xa0\x07\x3d\xa8\x5d\xec\x62\x17\x6b\xd7\xbe\xf6\xb5\xbb\xdf\ +\xc3\x89\xf3\x9f\xff\xfc\xed\xc6\x37\xbe\x71\xbb\xe2\x15\xaf\xd8\ +\xae\x7f\xfd\xeb\x77\x6c\x81\x15\x78\x82\xd8\xa2\x0f\xfe\x7e\xf2\ +\x93\x9f\x6c\x8f\x7b\xdc\xe3\x3a\x4e\x88\x33\xf0\x85\x3d\xb0\x25\ +\x58\x84\x43\x3c\xef\x79\xcf\xeb\x31\x82\x0f\x0e\xc7\xb8\xcc\xb6\ +\x2a\x8c\xd9\x2c\x0c\x18\xea\x9d\xcd\x7e\xfe\xf3\x9f\x6f\xcf\x79\ +\xce\x73\xda\xcd\x6e\x76\xb3\x76\x8a\x53\x9c\x62\xd4\xb7\xe9\x75\ +\xa8\xeb\x31\xdb\xf0\x97\x0e\x61\xbc\x73\xc2\x8e\xc3\x1f\xfe\xf0\ +\x5d\xdf\x62\xfc\x73\x9f\xfb\xdc\xf6\xec\x67\x3f\xbb\x9d\xea\x54\ +\xa7\x6a\x47\x3b\xda\xd1\xda\xa1\x0f\x7d\xe8\xce\x09\x5e\xf8\xc2\ +\x17\xb6\xc7\x3f\xfe\xf1\x1d\xe7\xc5\x02\xba\xbd\xf3\x9d\xef\xdc\ +\xfb\xc6\xb7\xbe\xf7\xbd\xef\x75\xfb\x80\x1d\x30\xe9\x46\x37\xba\ +\x51\xb7\x05\xe7\xb1\xef\x09\x4f\x78\xc2\x8e\x37\xb0\xe3\x13\x9f\ +\xf8\x44\xfb\xcd\x6f\x7e\xf3\x1f\x63\x5e\x86\xdc\x56\xd1\x36\x72\ +\xee\xb5\x1c\x57\xf3\xc7\x3f\xff\xf9\xcf\x3d\x86\xe2\x56\x57\xbe\ +\xf2\x95\x3b\x6e\x8f\xf9\xf8\x22\x9d\x8f\xe9\x9f\xbe\xe9\xf1\x81\ +\x0f\x7c\x60\xf7\x6f\x71\x9b\xbe\xe8\xf5\x8c\x67\x3c\x63\xbb\xe6\ +\x35\xaf\xd9\xf1\xe1\x36\xb7\xb9\x4d\xd7\x29\x5c\x3f\xf6\xb1\x8f\ +\xdd\x7f\xbb\xee\x75\xaf\xdb\x79\x86\xf8\x80\x43\xbe\xeb\x5d\xef\ +\xea\xfd\xfe\xf5\xaf\x7f\xdd\xf1\x5e\x1c\xb2\xaf\xdf\xe8\x5b\xbe\ +\x21\xbe\x1c\xff\xf8\xc7\xef\xd7\xc6\x29\xd9\x1c\x3b\x60\x3b\xc9\ +\x23\x36\xaa\xbf\x70\xe2\xed\xd2\xd6\x3a\x9e\xe8\x9e\x2f\xfd\xf8\ +\xc7\x3f\x6e\x6f\x7b\xdb\xdb\xba\xac\xe1\x73\xf5\xf3\x21\x9f\x5b\ +\xeb\xc6\x06\xc4\x6d\x9c\x9f\x5e\xc5\x90\x67\x3e\xf3\x99\xed\x63\ +\x1f\xfb\x58\xbb\xdc\xe5\x2e\xd7\xf1\x05\xaf\xe3\xb7\x30\xfb\xe9\ +\x4f\x7f\x7a\xd7\x97\x7f\xc3\x07\x3e\xbd\xff\xfe\xfb\x77\x9d\xe2\ +\x11\x6f\x7c\xe3\x1b\x3b\xa6\xcb\x0b\xdf\xfc\xe6\x37\xb7\x1b\xdc\ +\xe0\x06\x3d\xae\xd8\x17\x2f\x84\x19\xf0\x04\x1f\x10\x5f\xf6\xd9\ +\x67\x9f\x7e\xfd\xc3\x1c\xe6\x30\xfd\x33\x0c\x92\xb3\xb0\xf7\x5a\ +\x8b\xda\xd9\xdb\x54\xbe\x5b\x6b\x36\xbf\xfb\xdd\xef\x7a\x8c\xe4\ +\x5f\x62\xf4\x7a\xfd\x7c\x8a\xff\xd3\xe9\xdd\xee\x76\xb7\x9e\xf7\ +\xf9\x37\x7c\x16\xf7\xe9\xe3\x4c\x67\x3a\x53\xe7\x7b\x36\xbf\xa9\ +\x15\xe8\xd7\x93\x9e\xf4\xa4\xae\x57\x78\x0e\x3f\x1e\xf9\xc8\x47\ +\xf6\x3e\x7f\xff\xfb\xdf\xef\xc7\xca\x37\x70\x3f\x9c\x51\xbc\x60\ +\x1f\xe2\x0a\xdb\xe1\xef\x6a\x11\x7e\xc3\x13\x8c\x8f\x6d\xbb\x86\ +\x7a\x03\x7b\xff\xf9\xcf\x7f\xde\xed\x7f\xbb\xe4\x5c\xb3\xda\xb2\ +\x6c\x34\xb5\x12\x63\xc6\xe9\xe5\x63\x64\xc5\xff\xa6\xc6\xf4\xf5\ +\x6e\xf0\x58\x6d\x80\x0f\x9e\xfe\xf4\xa7\xef\x7c\x4d\xbc\x17\xbf\ +\x4f\x7c\xe2\x13\xb7\x8b\x5c\xe4\x22\xed\x6a\x57\xbb\x5a\xc7\x73\ +\x7c\x01\x36\x5c\xef\x7a\xd7\xeb\x75\x21\xc7\xd8\x1f\x6e\xfc\xfe\ +\xf7\xbf\x6f\xaf\x7c\xe5\x2b\x7b\x3e\x81\x27\xc0\x77\xbf\xab\x0d\ +\xe0\x8c\xf2\x8b\x97\xbc\xe4\x25\xed\x67\x3f\xfb\x59\xd7\x2b\x3b\ +\x7a\xcd\x6b\x5e\xd3\xde\xf7\xbe\xf7\xb5\x7b\xdf\xfb\xde\x07\xe7\ +\x10\x62\xc6\xed\x6f\x7f\xfb\xf6\xb5\xaf\x7d\xad\x63\x41\xec\x60\ +\x3b\xb6\x65\xe8\x3f\x3e\xcf\x27\xe4\xef\x57\xb8\xc2\x15\xba\x3f\ +\x90\xc7\x2a\xf5\x5e\xf3\x00\xbe\xbd\xf7\xde\x7b\xb7\x87\x3c\xe4\ +\x21\x9d\x5b\xba\x3e\xdb\xc3\xf9\x70\x82\x4f\x7f\xfa\xd3\xdd\xe7\ +\x63\x93\x47\x3f\xfa\xd1\x3b\xe7\xbf\xdf\xfd\xee\xd7\x6b\x05\x62\ +\xc6\x57\xbf\xfa\xd5\x9e\x1f\xca\x4b\x7c\x56\x3f\x60\x03\x74\xca\ +\x1e\xc4\x05\xba\x94\xbf\xf8\xcb\xc7\xdf\xfd\xee\x77\x77\xdb\x11\ +\x47\x60\x01\xbe\x01\x57\xc4\x24\xf9\x82\xfa\x01\x3e\xb1\x5d\x6a\ +\x47\xcb\x6c\x95\xe3\xa9\xdd\xf0\x79\x31\x97\x2e\xe8\x64\x59\x58\ +\x3f\x25\x16\xb8\x96\x9a\x01\xde\x87\x0b\x88\xc9\x67\x3d\xeb\x59\ +\x7b\x9c\x86\x01\x70\x01\x8f\xbb\xd7\xbd\xee\xd5\xe3\x3c\x3e\xc8\ +\x46\xc4\x77\xbc\x8e\xef\xc3\x6d\xc7\xc3\x08\xdc\x00\x5f\x64\x0b\ +\xf8\xe4\xd5\xaf\x7e\xf5\x9e\x1b\x6a\xe1\x66\xef\x7c\xe7\x3b\x3b\ +\xb7\x3c\xd6\xb1\x8e\xd5\xed\x6a\xbf\xfd\xf6\x6b\x5f\xff\xfa\xd7\ +\x7b\x4e\xcb\xc6\xf4\x01\x36\xc9\x2d\x52\x43\x9a\x67\x03\x3b\x93\ +\x6d\x54\xdc\x30\xb6\x3b\xdc\xe1\x0e\x3d\xee\x46\xe7\xd9\x36\x4b\ +\xf7\x7c\x54\x4d\x97\xee\x60\x3f\xfb\xa3\xef\x7b\xdc\xe3\x1e\x3d\ +\xbe\xe3\x06\xe2\xb3\x98\x40\x3f\xb7\xbd\xed\x6d\x7b\x5c\x90\x8f\ +\xa4\xae\xf3\xfa\xd7\xbf\xbe\xd7\x07\xd8\x0b\x7c\x10\xd7\xd5\x10\ +\x1e\xfd\xe8\x47\xb7\x0f\x7f\xf8\xc3\x07\xf3\x7b\xb5\x8b\x47\x3d\ +\xea\x51\x3d\x27\x90\x73\xa8\x09\x88\x21\xae\x0f\x53\x6c\x7e\x77\ +\x1c\x99\x38\x97\xba\xd2\x7b\xdf\xfb\xde\x83\x6b\xdd\xdb\x35\x1e\ +\x4c\x69\xb1\x61\x7f\xc9\x45\x6c\xe5\x73\xd1\xc7\x66\xe8\x7d\xb8\ +\xc1\xf9\xf3\x9c\xe7\x3c\x3d\x3e\x8b\x01\xf8\x9b\x4d\x4c\x10\x8b\ +\xdf\xf0\x86\x37\x74\xee\x47\xa7\xf2\x4f\x18\x4d\x27\xaf\x7e\xf5\ +\xab\x7b\x0e\x2f\xb6\xb3\x17\xf3\x06\xf8\xde\xf3\x9f\xff\xfc\x8e\ +\x65\xc6\xe5\x9c\xa9\xf5\xe0\x36\x62\x06\x9f\x87\xf1\xec\xe7\x19\ +\xcf\x78\x46\xaf\x13\xf0\x75\xdf\xb1\x3f\x38\x23\x57\x10\x0f\x70\ +\x50\x71\x04\x56\x38\x77\xec\x68\x59\x36\xb0\x99\x79\x46\xfa\x4c\ +\x1e\x64\x8a\x2b\xc3\x3a\x3a\xd8\x68\x3e\xb7\x96\x2d\xd7\xc2\xb5\ +\xc4\x69\xfc\x5c\xbd\x16\x56\xf3\x59\xf5\xbe\xd4\x76\xc4\x61\x1c\ +\x8e\xbf\xde\xea\x56\xb7\xea\xf5\x22\x3a\x11\xd3\x3f\xf5\xa9\x4f\ +\xb5\x0f\x7c\xe0\x03\xfd\x37\xfa\x71\x0c\x9d\xe1\x10\xc6\x86\x1b\ +\x04\xbb\x0f\x3c\xf0\xc0\x6e\x5b\xb0\xee\x61\x0f\x7b\x58\xd7\xbd\ +\xfd\xcf\x76\xb6\xb3\x75\xde\xa0\x06\xf1\xac\x67\x3d\xab\xc7\x0e\ +\xf6\xa5\xc6\xa0\x6f\xce\x81\x6f\x8a\x37\xe6\x1a\x1e\xf3\x98\xc7\ +\xf4\xbc\xb8\xca\x73\x23\x6d\xb3\xf4\x9f\xbe\xaa\x77\x99\x3f\xc5\ +\x77\x86\xfa\x58\x35\xd6\x0f\xf1\x85\x7f\xcb\xdd\xc8\x18\xef\xf0\ +\x1d\x7b\x3c\xdd\xe9\x4e\xd7\xf5\x40\xaf\x62\x33\xff\xe3\x97\xec\ +\xc3\xfc\x2f\xcc\x92\x33\xbe\xe3\x1d\xef\xe8\x39\x2a\xbd\xe2\x71\ +\x74\x06\xaf\x71\x57\xc7\xca\x07\xd3\xe4\x93\xf4\x27\x3f\xc0\x25\ +\xd5\x8b\xd9\x48\x6c\x4d\x8e\x20\x37\x94\x8b\xc8\x2d\xf0\x60\xf1\ +\xc8\xfe\xae\xe5\xdf\x62\x90\x3a\x85\xfe\x9a\xcb\xae\x72\x5d\x6f\ +\xdb\x0c\xdd\xe7\x1a\xb8\xac\xba\x2a\x39\x6d\x15\xde\xb3\x35\x35\ +\x3b\x9c\x4e\x4e\x47\x97\xf4\xca\xd7\xc5\x6e\x71\x80\x0d\x88\xbd\ +\x62\x3c\xae\x27\x3f\x83\x11\x62\x02\xcc\xc0\xed\x70\xf7\xd7\xbd\ +\xee\x75\x5d\xa7\x70\x5f\x1d\x48\x4c\xb8\xcf\x7d\xee\xd3\x31\x04\ +\x2f\x64\xeb\xc6\x8c\xd7\xb1\x79\xfb\xb1\x0f\x1b\xbb\xc2\x23\xd4\ +\x96\xd4\x20\xd8\x8c\x3e\xe0\x94\x70\x40\x0c\x91\x3f\xfa\x37\x1b\ +\x30\xcf\x04\x3b\x70\x05\x36\x20\x46\xa8\x17\x69\xf3\x6c\x60\xab\ +\x79\x61\xae\x4f\x16\x7c\x40\x5d\x24\x7a\xd8\x2c\x8e\xe7\x2f\x7e\ +\xaf\x06\x63\x93\xc3\xf3\x3f\xfa\xf7\x1b\xdf\x66\x07\xf4\x27\xdf\ +\xc3\xf7\xc8\x18\x26\xf0\x45\xf3\x8b\x70\x1d\xe6\xe3\x80\x7c\xfe\ +\x2d\x6f\x79\x4b\x7b\xc4\x23\x1e\xd1\xbf\x83\x23\x7c\xd8\x5f\xf1\ +\x5c\x5c\x48\x5d\x1f\x3f\x64\x43\xf8\x1c\x2e\x01\xeb\xd9\x15\x8c\ +\xc7\x11\xe8\x14\x0f\x14\x0f\xf4\x0b\xc7\x80\x09\xea\x84\x7c\x1e\ +\x3e\xe1\x84\xe6\x1b\xe5\x83\xf6\x87\x47\xe2\x81\x79\x49\xf3\x0d\ +\xda\x76\xe4\x84\x89\x2d\x6a\x63\xec\xf9\x34\xa7\x39\xcd\xa6\xea\ +\x3e\xfa\x97\x4b\x91\x29\x79\x92\x39\x9f\xe5\x73\x70\x00\x47\xa3\ +\xcf\x2f\x7c\xe1\x0b\x07\xf3\x11\xf5\x5a\x3a\x81\x05\xb8\x9a\xfe\ +\xb2\x5b\xb8\xad\x5e\xf3\xa1\x0f\x7d\xa8\xaf\xf7\x70\x2e\x76\xe3\ +\x7b\xbe\x8c\x1b\x8a\x6b\xce\x25\xcf\xff\xe9\x4f\x7f\xda\xf9\x02\ +\x9f\x75\x5e\xe7\x82\x0f\x70\x03\xde\xc3\x18\x3e\xef\x77\xf5\x65\ +\x36\xc5\x36\x60\x0d\x2c\x72\x7e\xd8\xc4\x56\x61\x07\xdb\xc1\x45\ +\x7c\x76\x2d\x58\xc4\x06\xf0\x81\xcd\xae\x17\x2f\xca\x43\x52\xd3\ +\xc3\xf5\x5e\xfa\xd2\x97\x76\x99\x56\x7f\xdc\x2c\xac\x27\x77\xdc\ +\xfa\xe1\x0f\x7f\x78\x7b\xc5\x2b\x5e\xd1\xf5\xca\xef\xd9\x04\x1c\ +\xa6\x7b\x35\x39\xb9\x08\x0e\xc7\x26\xe4\x83\x38\x97\xbc\xfd\x26\ +\x37\xb9\x49\xf7\x3f\xba\xe3\x9b\xd6\x75\xf0\x6f\x1c\x8e\xfe\xe8\ +\x49\x7c\x36\xe7\xc3\x7e\xe4\x04\xea\x76\xf2\x3c\x71\x9a\x7d\xe0\ +\xf7\xf4\xed\xba\x7c\x37\xb1\x85\x6f\xcb\x31\x61\x07\xac\x61\x63\ +\x74\x8b\x1b\xb3\x2f\xd7\xc4\x35\x3f\xfe\xf1\x8f\x77\x3b\x82\x53\ +\x7e\x7f\xe2\x13\x9f\xd8\xf3\x50\x7d\x65\x03\xe2\xd3\x2f\x7f\xf9\ +\xcb\x4d\xad\x11\xcd\x5a\x7b\x95\xe6\x37\x73\xb6\xf2\xe2\x60\xfe\ +\x66\xc7\x7a\x58\x0f\x9f\xc9\x29\x98\x29\x4e\xe3\xda\xe2\xaf\x39\ +\x1a\x72\xe3\x3f\x78\xb5\x3a\x1c\x9d\x90\x29\xdb\x60\x37\x7c\xdb\ +\xdc\x1e\xb9\xd3\x05\x1c\xb7\x2f\x7d\xb0\x05\x1c\x2d\xeb\xc3\xc4\ +\x7c\xf6\x2e\xe6\x3b\x0f\xff\xd5\x07\x98\x4d\xa7\xf2\xc4\xc4\x6f\ +\xe7\xb7\x7e\xc0\xbc\x90\x7e\xe0\x23\xbe\x97\x03\xb2\x3b\x6b\x11\ +\xd8\x9b\x98\xe9\x9c\x6c\xc8\xbf\x71\x82\x17\xbd\xe8\x45\xed\x27\ +\x3f\xf9\x49\xe7\x8b\x6c\xc7\xf7\xfa\x0e\x67\xd5\x16\xb7\x3a\xe6\ +\xa7\x96\xaf\x9e\x8b\x47\x6f\x26\xde\xd7\xf8\x02\xe7\xd5\xd5\xe4\ +\x6d\xfc\x3e\xb5\x1c\xb9\x1e\x99\x27\x37\x53\xaf\xa5\x8b\xf0\x42\ +\x98\x8a\xe7\xd3\x15\xdd\xc2\x5a\xf1\x82\x1d\xa8\xf5\x8a\xcd\xe2\ +\x86\xf8\x40\x2f\x6c\x02\x1f\xfb\xc1\x0f\x7e\xd0\x75\xc0\x3f\xe1\ +\x39\x9c\x97\xdf\xd1\x69\x62\x83\x9a\xa0\xf3\xb8\x1e\x6c\x4a\x6e\ +\x0f\xfb\x71\x44\xfa\xf4\x5d\x70\x0b\xd6\xc0\x27\xb9\x20\x0e\xc2\ +\xae\x60\x93\x31\x99\x13\x57\x37\x4d\x5e\xe0\xba\xea\xe8\xf3\xfc\ +\x72\xd5\x2d\xb8\xf0\xe5\x2f\x7f\xb9\xcb\x1b\xce\x6e\x36\xcf\xcf\ +\x5c\x8a\x2d\x79\x9b\xfa\x2b\x6c\xc6\xa7\xe9\x41\xee\xa6\xa9\xdd\ +\xf2\x27\xdc\x4d\x5e\xe2\x18\x78\x8f\xdb\xc9\xe1\xcc\xc9\xc1\x61\ +\xfc\xeb\x4d\x6f\x7a\x53\x8f\x23\x6a\x41\x62\x31\xdf\x56\xf7\xa1\ +\x37\x3e\x4f\xf6\x74\xcb\xef\xf1\x0d\x36\x41\x67\xae\xef\xdf\xf0\ +\xc7\x6f\x8e\x11\x17\xd4\xf9\xfc\x25\x23\xf5\xbf\x73\x9f\xfb\xdc\ +\xbd\x76\xa0\x66\x84\x17\x58\x3f\x64\x8d\x31\xdb\x60\xcb\x6a\x47\ +\x6a\x48\x62\x0d\x9d\xe3\xa6\xea\x0a\x7c\x9f\xcd\xc3\x22\x36\x21\ +\xfe\x6c\x85\x0d\x84\x83\x98\xdb\xc0\xa3\xf5\x71\x33\x75\x9f\xeb\ +\x90\x27\xd9\xc8\xa3\xf8\x0a\xbf\x16\x83\x6c\xb0\xdd\xfa\x3e\x7a\ +\xd7\x3e\xfb\xd9\xcf\x1e\xbc\x5e\x93\xce\xf1\x72\xfb\xc0\x08\x5c\ +\x1f\xdf\x23\x7f\x75\x5a\xfe\xce\x3f\xad\x23\x16\xff\xc5\x74\xf1\ +\x9f\x4f\x92\xb7\x7c\x4c\x2c\xc1\xf1\xd8\x0c\x8c\x87\x21\xfc\xd2\ +\x9a\x73\x36\x03\x07\xe4\x22\xfa\xe2\x7a\xfc\x57\x8d\x09\x27\xe0\ +\xf3\x6c\x50\xdf\xd9\x48\x74\x29\xf7\xc3\x9f\xd8\x99\x86\x7f\x8a\ +\x11\xe6\x06\xc4\x06\xfc\x80\x7d\xaa\x5b\x8b\x51\x1f\xfd\xe8\x47\ +\x3b\xff\xdc\xec\x39\x23\xd7\xd2\x5f\xbc\xc7\xf8\x37\x63\xfe\x6e\ +\xa8\xfb\xe0\x3f\x1d\xa9\x97\xc2\x61\x3e\x06\x3f\xe9\x14\x36\xe0\ +\x4b\x64\x63\xde\x49\x2c\x87\x9d\x74\x4d\xf6\xb0\x41\x5c\xe5\x87\ +\x74\x8b\x3f\xc0\x01\xbc\x81\x5f\xf2\x35\x18\x22\x4e\xc0\x70\x39\ +\x9d\xf8\x01\x1b\xd8\x87\x3c\x8e\x6e\xc4\x75\x7a\x63\x7b\x7c\xd7\ +\x31\xe2\x86\x7c\x1f\x4f\xe0\xeb\xfa\xe3\x7b\xb1\x9e\x8d\xe9\x17\ +\x8c\x10\x5b\x70\x14\xf9\x83\x7a\xaf\x79\x28\xd7\xca\x1c\x12\x9d\ +\xbf\xe0\x05\x2f\xe8\xfa\x37\x37\x69\x2e\xc9\x6f\x38\x25\x1b\x32\ +\x0f\xf1\xdd\xef\x7e\x77\xd3\x72\x82\xe4\x02\x74\x6f\x4e\xdb\x98\ +\xc9\x79\xb3\xf2\xfb\xcc\xe3\xf0\x5d\x98\x4a\x47\xfc\x8e\x8f\x91\ +\x2f\xdc\xa4\x3b\x18\x8c\x67\xf3\x57\x0d\xe7\xe7\xc3\xe4\x25\xe6\ +\xaa\xef\xc0\x50\x7e\x69\x2e\x5f\x9d\x47\x5c\xe0\xc7\xec\x03\xf6\ +\x8b\xf5\x78\x1c\xfd\xb3\x71\xb9\x99\x58\xc7\x8f\x8d\xdb\x46\xaf\ +\xc9\xf9\x9d\x03\x67\xf3\x9d\x73\xd9\x5f\xff\xe4\x8b\x38\x88\x5a\ +\x23\x3b\xcb\x3d\x28\xae\xef\x1c\xee\x53\x81\x29\xe6\x7d\xd8\x8f\ +\x63\xd8\x42\xf4\xf9\x99\xcf\x7c\xa6\x73\x1b\xb5\x09\x6b\x96\xf1\ +\x41\x73\x90\xe1\x2c\xc6\x5c\xd7\x16\xae\x5a\xff\xf8\x9e\x75\x6c\ +\xc6\x9a\xf9\xdb\xcd\x8a\xf7\xf4\x0f\x53\x71\x3b\xfa\x97\x3b\x91\ +\x2d\x8e\x84\x7f\xf2\x47\xfc\x4f\xfd\xc1\x67\x6b\x2f\xf0\x34\x7a\ +\xe6\xfb\xfa\xcc\xbf\x60\x85\x5a\x9b\x18\xed\x2f\x1d\xc2\x5c\xbe\ +\x08\x57\xb3\xc6\x1f\x36\xb8\x06\xbf\xa4\x1b\xb8\xce\x86\xc4\x04\ +\x35\x1a\x75\x1c\xb6\x61\x5f\x5c\x82\x2d\xa9\x0f\xe3\x79\xfc\x1b\ +\xd6\xdb\xdf\x1c\x8f\x3c\x02\xcf\x13\x2b\x53\x5f\x84\x21\xf4\xa9\ +\xe1\x10\x6c\x4d\xfe\xa0\x25\xe7\x76\x8f\x09\x2e\xe9\x5a\x38\x28\ +\x4c\xf1\x9d\x3e\xe4\x3e\x16\xf1\x03\x27\x59\xf5\x9a\x50\x4d\xcc\ +\x87\x47\xc1\xfc\x55\xfb\x7e\xce\x2f\x9e\xd2\x5d\xe4\x44\x9f\xc6\ +\x2e\xaf\x17\x27\xc9\x18\x46\x93\x39\x8e\x45\x3f\x9a\x79\x3b\xeb\ +\x0a\x7d\xcf\xdf\xc4\x0a\x18\x6c\x5f\xf2\x17\x93\x61\x35\x7e\xc0\ +\x8f\xf1\x08\xbc\x8f\x5d\x88\xcd\xf8\x80\xbc\x9f\x0d\xd0\x2b\xbf\ +\x65\x63\x62\xbd\xdf\xe8\xc4\x6f\x7c\x9e\xaf\xf3\x47\xf6\xe8\x18\ +\xf5\x61\x7e\x2f\xb6\xf8\xec\xdc\xf4\x96\x35\xc8\xf8\x09\x3e\x29\ +\x3e\xc1\x2c\xfb\x7c\xe5\x2b\x5f\x39\x58\xde\x91\xb9\x35\x42\xe6\ +\x0b\xc8\x00\x27\x34\x0f\x2d\xa7\x61\xe3\x59\xaf\x2c\x3e\xac\x8a\ +\x0b\xe6\x9c\xe2\x11\xdc\xc7\x8d\x56\x99\xeb\xd5\x39\x9c\x60\xbe\ +\xdc\x57\x4d\x8c\xfe\xc4\x51\x9b\x71\xab\xa1\xf1\x53\xbe\xcb\xc7\ +\xd8\x84\x38\x4e\x8e\x64\x2b\xaf\x17\x8f\xe9\x8c\xce\x61\x02\x59\ +\x93\x27\x1c\x93\x13\x90\x27\xfb\xa1\x43\xfa\x91\xdf\x99\xbf\x10\ +\xbb\xc5\x1a\xf1\x56\x9e\xc8\xcf\x1c\x27\xd7\xe0\xbf\xb0\x82\xcf\ +\x8b\x39\xfa\x62\x5f\xbf\xb9\x1e\x39\xc9\xe9\xe9\x48\x6c\x62\xaf\ +\xec\x4d\xae\xc8\xbe\x60\x8c\x3a\x15\xbf\xe5\xf3\xf0\x05\x76\x64\ +\x0e\x79\xb8\x26\x1e\x3e\x89\x4d\x6c\xdd\x71\x6c\xd8\x5a\x23\xb8\ +\x07\x13\x71\x51\x3c\xa2\xea\x6b\x99\xfa\x87\x47\xea\x9d\xea\x23\ +\x74\xc4\xff\x37\x03\xf3\xf1\x1c\xb1\x0e\x67\x83\xa9\xe4\xa8\x7e\ +\xcf\xaf\xf1\x7e\xb2\xcd\xba\x0a\x36\x22\x86\x8b\xd1\xe2\x14\x59\ +\xcb\xeb\xe8\x86\x4e\xe8\x90\xdf\xe0\x89\x62\x2a\x1b\x71\x1f\x87\ +\xdc\x3b\x73\xff\xf2\x3a\xf2\x85\x19\x6a\x82\xf2\x3a\xf8\x0e\xc7\ +\x71\x48\x7e\x0d\x73\x6c\x6a\x4b\x78\x24\xfb\x63\x5b\xce\x2f\x1e\ +\xc1\x19\x75\x22\x78\xc1\xc7\xd9\x88\xf3\xe1\x7b\x62\x0e\x2c\xd2\ +\x27\xfa\xa2\x7f\x3c\x03\xb6\xb1\xc7\x59\xbe\xe7\x37\xf8\x82\x7f\ +\xb2\x4d\x73\x91\x62\x5b\xea\xd1\x70\xc9\x9a\x25\xf9\xc0\xb2\x75\ +\xaf\xc1\x28\x31\x77\xd5\xb8\x2f\xa7\xe3\x0b\x30\x3e\xb5\x3c\xb2\ +\x81\xa9\xf4\x8e\xef\xb3\x01\x7c\x4b\x1d\x56\x7c\xa6\x67\xba\x12\ +\x57\xf9\x2a\xdb\x50\x97\xa5\x4f\xf2\xce\xbd\x1d\xe2\xb7\x79\x14\ +\x9c\x4a\xbe\x0d\x4b\x5c\x0b\x87\x67\x17\xec\x81\x4e\xe4\x35\xa9\ +\xdd\xe2\x82\xae\xed\xdf\x7c\x9e\x2d\x88\xc7\xae\x81\x53\xc2\x1f\ +\x78\xa8\x2f\xec\xc6\x39\xe5\x99\x7c\xd5\xbe\xfe\xc2\x14\xb6\x03\ +\x97\x60\x3f\x7d\xc9\x19\xe8\x4f\x9d\xc9\x58\x61\x85\x7f\x8f\xdd\ +\x6f\xae\x99\x63\xc6\x0d\xc5\x1c\xb5\x4c\x35\x37\xb9\x80\x73\xaa\ +\x65\x90\x1d\x4c\xc4\x11\xab\xde\x96\xa5\x7f\xf7\xdf\xf1\xc1\xe0\ +\xf1\xaa\xe2\x3c\x7d\xc0\x64\x7c\xd8\x3c\x4e\xd6\x6d\xd2\xb7\x18\ +\xcd\x3f\xe1\x2e\xac\x65\xf3\xf2\x6d\xba\x54\x7b\x81\x15\xe2\x00\ +\x4e\x25\xc7\xa2\x17\xf2\x17\x37\xd4\xd1\xc5\x4e\x18\xc6\x9e\x70\ +\x18\x7c\x9e\xff\x9b\x63\x87\x19\x6c\x0b\x6e\xc3\x7f\x75\x02\xd7\ +\x10\x4f\xe8\x59\xbc\xe7\xdf\xae\xcd\x8f\xe9\x16\xb6\xf0\x47\x79\ +\x86\x7e\xb3\x57\x18\x84\xa3\xe8\x93\xb9\x30\xfb\xe3\x69\x6c\x90\ +\x9d\xf9\x8e\x2d\xe1\xf0\x78\x3b\xbb\x65\x13\x5f\xfa\xd2\x97\x46\ +\xf5\x96\x7f\xcb\x09\xd4\xd8\x8d\x83\xfd\xb1\x31\xfc\x04\xf6\x27\ +\x16\xe3\x96\xf8\x21\x4c\x59\x86\x0d\xe4\xf8\x1f\xfe\xf0\x87\x7d\ +\xfe\x82\x7e\x56\xa9\x7b\xba\x56\x93\x15\xd7\x8c\x03\x46\xaa\x8f\ +\xc1\x52\x7a\x10\x9f\xe9\x08\xde\xb2\x0f\xf7\x5f\xa8\x8b\x91\x05\ +\x19\xcb\x45\x71\x79\x71\x54\x1d\xc0\x39\xd9\x0d\x1f\x93\x27\xcb\ +\xdf\x7d\xa6\x2b\x78\x2d\xee\xb3\x6b\x3c\xc1\xf8\xf8\xa1\xda\x21\ +\x1b\x83\xf3\x30\x5b\x5d\x17\x17\x64\x37\x74\xa4\xc6\x2f\xe6\xd0\ +\x3f\x5d\x8b\x0f\xf0\xc2\xf7\x36\xf6\x06\x13\xc4\x0b\x7c\xcf\x78\ +\xdc\x6b\x88\x4b\xc0\x32\xe3\x80\x2b\x74\xcf\xfe\xc4\x2e\x76\x05\ +\x5f\xe7\xf1\x77\xdc\x4e\xfd\x87\xbf\xbb\x06\xbd\xe3\x7e\xd1\x47\ +\xe2\x31\x2e\x2a\xa7\xd4\x96\x35\x57\xac\x86\x9a\xfb\xf0\x56\xa1\ +\xff\x9c\x93\x5f\xe2\xb1\xe2\x3a\xac\x81\xb7\x72\x7b\xb9\x4f\xee\ +\xc9\xe5\x63\xec\x00\xb6\xd3\x35\xbc\x13\x73\xe9\x5f\x1c\xf5\xbd\ +\x98\x4c\x97\xf0\x83\x3f\x5b\xc3\x41\x8f\xe2\x87\xfc\x85\xdc\xd9\ +\x34\x3c\x10\xab\x71\x2b\x18\xe0\x7b\xbe\xcf\x27\xe5\x90\xe6\xf8\ +\xc5\x5d\xfc\x80\x4c\xd5\x7d\x70\x47\x7a\xe0\xf7\xf8\x1c\x1b\xd0\ +\x2f\xf9\xbe\xf8\x0b\x57\x5c\x4b\xdf\xc5\x23\x7d\x87\x67\xf0\x9f\ +\x5d\x88\x43\x38\x01\x0c\x67\x73\xf8\x5b\x7c\x7f\x51\xb3\x9f\x7c\ +\x45\x8c\xac\xba\xaf\x3e\xc4\x2e\xc4\xac\xd4\x3d\x37\x7a\x1f\x9f\ +\xb8\x63\x4c\xab\xc2\xfd\x6c\xec\x57\x1c\xe3\xdb\x6a\xb1\xe2\x9b\ +\xbc\x9d\xbc\x61\x80\xba\x27\x5f\x55\xb3\xe3\x33\x30\x14\x2e\xc0\ +\x53\x39\x16\x5f\xa3\x2b\x7a\xa2\x67\xf6\x4a\x8f\x8e\x11\xab\xfd\ +\xce\x0f\x61\x40\x78\x14\x7d\xc9\x0b\xac\xdb\x71\x1e\xfb\xab\x15\ +\xd1\x2f\x9b\x77\x6c\xea\x02\xf4\x68\x1e\x80\x9d\x65\xde\xde\xe7\ +\xc8\x84\x5e\xf1\x92\xdc\x53\x40\x0f\xf6\x4b\x4d\x88\xcf\xe2\x11\ +\xfa\x6a\xad\x08\x9b\xc2\x59\xf1\x50\xb6\x30\xcf\xf7\xf3\x3d\x4e\ +\xc3\x47\x5c\x73\xac\xee\x16\x0c\x80\x7d\xd6\x2b\x6a\xeb\xc5\x80\ +\x5c\x53\x9c\xaa\x6b\x79\x56\x85\xfd\xf4\x49\x4e\xfc\x88\xfe\x0f\ +\x38\xe0\x80\xce\xeb\xd8\x83\xdf\xc5\x7a\xd8\x87\xe3\xa8\xd1\xfa\ +\x5d\xdf\xf8\x28\xdd\xd2\xbb\x3e\x9b\x43\xe3\x57\x7c\x15\x06\x38\ +\x46\xbc\x94\xe3\xe3\x58\x62\x33\x9f\x85\xed\xf4\xe0\x3b\x98\x0f\ +\x93\xf5\x41\x6d\x08\x5e\x38\xbf\x73\x3b\x0f\xdd\xe1\x07\xf2\x3f\ +\x58\xed\xfc\x78\x18\x7b\x81\x3d\x72\x3c\x79\xa1\xef\xf0\x0e\xf5\ +\x3d\xdc\x81\x3d\x3b\x16\x4e\xc0\x13\xf6\x9a\x9a\x2d\x1b\x84\x11\ +\x6a\xf8\x8b\xf2\xf6\xfc\x06\xa3\xc4\x9b\xe8\x7f\x96\x2c\x5d\x17\ +\x2f\xae\xb9\xe4\x5a\x5a\x6c\x06\x56\x1a\xcf\x2a\xeb\xfb\xb1\x29\ +\x7e\xc8\x1f\xd5\x3a\xf8\xa9\x18\x8b\x37\xe3\xd3\xea\x66\xc6\x0b\ +\x4f\xe9\x08\x37\xe0\xa7\xb8\x9f\x3c\x88\xfe\xea\xf3\x79\x7c\xc7\ +\x3f\xc3\x1d\x71\x2f\xf1\x44\xcc\x56\xaf\x73\x3d\xbe\xcb\x3e\xd8\ +\x36\xac\xc8\xb3\x24\x32\x37\x6c\x7f\xfe\xe9\xba\x62\x2a\x9e\x41\ +\x2e\xe6\xe5\xc4\x08\x3a\xe4\x8f\xfa\x2b\x6f\x10\x3b\xe8\xc7\x6f\ +\xbe\xf7\x3c\x1a\x71\xca\xb5\xc5\x19\xfa\x76\x6d\x36\xe5\x5c\xce\ +\xcd\x36\xe5\x1b\x8b\xe6\x6f\xf2\x9b\x79\x27\xb9\xeb\x2c\xfd\x0f\ +\x63\x29\xdc\xd3\xd6\x7a\x9f\x70\xf4\x8f\x87\xb1\xdf\x55\xfa\x7e\ +\x6a\xba\x7c\x58\x3c\xe7\x63\xf2\xdb\xd4\x64\xd5\xbd\xe5\x4b\xf4\ +\x22\xff\x51\xe7\x80\xd5\x64\x27\x36\xc0\x07\x71\xb1\x3e\x83\x09\ +\xa7\x97\x7b\xe3\x8f\xea\x15\xf8\x35\xfe\xe0\x18\x5c\x5e\x3e\x00\ +\x8b\xe9\x04\x9f\x96\xcb\x8b\x2f\xfa\xa0\x06\x67\x1f\x9f\xd9\xa4\ +\xbc\x8e\x1e\xc5\x40\x36\x97\xb8\xca\xde\x72\xcf\xd6\x98\xae\x60\ +\xba\x7a\x54\xd6\x7e\x93\xa3\x79\xf2\xe4\x05\xe2\x05\x5e\xc0\x47\ +\xa7\xea\xdf\xb1\x6c\x31\xf7\x4a\xce\xd3\x3f\x8c\x93\xb3\xd4\xe3\ +\xa7\xb4\xfa\xfc\x0d\xf1\x37\xb9\xe5\x2a\xfc\x3f\xfa\xe7\xab\x30\ +\xd2\xb5\x70\x23\x98\xe8\xbe\x59\xb5\x2e\x7d\x48\xcd\x1f\xa6\xf9\ +\xb7\x75\x66\x6c\x01\x86\xe3\xf1\x7c\xae\xda\x2d\xfe\x08\xa3\xd5\ +\x74\xe8\x4c\x2c\x14\xd3\x71\x78\xfe\xca\xff\xf8\x2f\xfe\x0f\xe3\ +\x52\x4f\xe5\xc7\x36\x7c\xc0\x86\x5b\xd2\xa1\xbe\xf2\x37\xb1\x1c\ +\xe6\xeb\x63\xea\xce\x99\x83\xcf\xbd\x7b\xf5\xbe\x7c\x71\x0c\xef\ +\x77\x3c\x0e\xa3\x7e\xc2\x2e\xc4\x0b\xf6\x0c\x27\xa6\xd4\xec\xf3\ +\xbb\xbe\xc9\xf9\xc8\x6c\x5e\xfd\x2d\xba\x22\x1f\xe3\xac\xb2\x59\ +\xd4\xb2\x1f\x3c\xe3\x2f\xab\xd2\xbd\x2d\xf3\x47\xfc\x58\x1c\x96\ +\x73\xc9\xe9\x32\x9f\x6f\xee\x53\x3e\xc0\xf7\xe0\x34\x7e\xc5\xaf\ +\xe1\xbe\xef\xd9\x00\x1b\x4f\xee\x14\xb9\xab\xc7\xc2\xdf\x8c\x7d\ +\xbd\x8d\x1d\xba\xb6\xbc\x02\x3e\xe0\x95\xf8\xb7\x38\x82\xe7\xc9\ +\x13\x33\xff\x3e\x26\x43\xfd\x82\x5f\xe2\x0b\x7f\xc4\x0f\x60\x1b\ +\xfe\x4a\xb6\xa9\xf7\x4c\x6d\xf8\x2d\x2c\x5a\xc4\xc5\xf3\x9b\x38\ +\x06\x4f\x6b\x9f\x86\x6d\x56\xbd\x89\x0c\x5d\x6b\x55\xd8\x1f\x9f\ +\x72\x6e\x38\x2b\x2f\xc7\xd3\xe8\x55\xbc\x84\xdd\x62\x25\x3b\x24\ +\x33\xb6\x2c\xe7\xc1\xa9\xf9\x33\xdc\xe6\x8f\x74\xc0\x07\x33\x37\ +\xa9\x19\x33\xee\xa0\x5e\xa4\x45\x47\x53\xb6\x1a\x47\xcc\x09\xe8\ +\x9b\x38\x0a\xef\xd9\x93\xba\x03\xdc\xe6\xff\x70\x64\xf8\x4c\xd1\ +\x61\xc3\x47\xed\x2f\x17\xc5\xff\xc8\x14\x16\x18\xd3\x94\xf5\x3b\ +\xf5\xbc\xf2\x11\xc7\x2e\xaa\xbf\xd6\xe7\x1e\xc0\xaa\x79\xcf\x00\ +\xab\xe7\xcf\x5f\xfd\x52\xb7\x20\xef\x55\xfb\xbf\x2d\x6b\x2d\xf1\ +\x61\x3e\x0d\xab\xd9\x03\xfd\xc9\xe7\xc9\x2d\xb9\xb2\x78\x0c\xc7\ +\xe1\x20\x6e\x2e\x8f\x4f\xdf\xe3\xff\x55\xff\xc9\x09\x70\x33\x75\ +\x41\xf8\x8b\xc3\xd9\x7c\x8e\xfc\xb3\x99\x5b\x4d\xfd\x4c\xec\xc0\ +\x43\xe4\x24\xea\x08\x72\x0c\x31\x98\xdf\xaa\xdf\xd4\x63\xd3\xc8\ +\xda\x75\x32\x27\x5f\xf3\x68\xdc\x05\x0e\xa8\x4f\xe8\xcf\xd4\xe7\ +\x65\xd8\xd8\xb0\x3e\x4c\xd5\x49\x7e\xc7\x17\x52\x5f\x88\x5d\xcf\ +\xba\x6e\x7e\x37\x47\x86\x3f\xae\xd2\xf7\xab\xfe\xe5\xf4\xf0\x9f\ +\x6e\xf1\x7d\x79\x9d\x5a\x3a\xfc\x95\x7b\x8b\x97\xe6\xbb\xe4\x7e\ +\xf8\x94\xb8\x20\x0f\x13\x4f\xb3\x56\xa2\xea\x1f\xbf\x52\x03\x11\ +\x5f\xad\xd3\xe2\x6b\xec\xc7\x31\x7c\x1a\xae\xe0\x96\xf6\x13\xe7\ +\xd5\x04\xe8\x1c\x17\x97\xf7\xcb\x0b\x63\x57\x38\x84\xb9\x7d\x79\ +\x1e\xbe\xc8\x2f\xe4\xa5\xec\xc0\xb9\xd9\x96\x7d\x71\x10\x3a\x86\ +\x15\xf2\x17\x1c\x25\x73\xf2\xc1\x1f\x7a\x70\x1e\xfc\x74\x2c\x6e\ +\xcc\xd2\xbf\xc6\xe6\xe4\xa6\x53\xfd\x31\x7a\x83\x37\xe4\xa5\xc5\ +\x5e\x67\x3d\x6b\x22\xf2\xa3\x83\x55\x63\x7f\xd5\xbf\x1c\x93\xae\ +\xe4\x37\xe4\x8a\x83\xcb\x9b\xe0\x26\x3f\x31\xcf\x21\xf6\xf9\x1e\ +\x46\xe0\x00\x38\x7c\x9e\xc5\x35\xc4\x2f\xf2\x55\x6b\xe7\xcb\x72\ +\x18\xdc\x52\xad\x3e\xf7\x56\x88\xe3\xf0\x01\xb6\xcb\x15\x61\x0c\ +\x5c\xa7\x33\xbc\x43\xbe\xc0\xfe\x34\xc7\xdb\x97\xae\xc5\x73\x73\ +\x79\x79\xde\x17\x7f\x76\x3c\x9b\xc8\x3a\x1f\xb9\x83\x9a\xbf\x3e\ +\xea\x3f\x2c\x35\x7f\xcb\x36\xd8\x38\xfe\x08\x7b\xa6\xae\xd5\x88\ +\x9e\x70\x54\xd7\x89\xdc\x16\xc9\x36\x36\x92\xda\xe4\xd0\x9e\x66\ +\xd9\x99\x86\xf3\xae\x92\xf7\xe7\xbc\x36\x35\x35\xbe\xcd\x97\xd5\ +\xad\xc8\x97\xbd\xaa\xd7\xc0\x5b\x79\x1a\xce\x65\xed\x9b\xf8\x2b\ +\x3e\xe0\x5e\x64\xcc\xe7\x2a\x76\x6b\x64\xcd\xff\xf8\xb9\x86\xef\ +\xab\xb1\xa9\xbb\x90\x03\xbe\xc8\xbf\xe9\x80\x1f\xc3\x05\x39\x35\ +\xfb\x60\x07\xf8\x1e\xbb\x80\xb5\x1a\x7e\x01\x4b\xe0\xb9\x63\xe0\ +\x06\xbd\xea\x1b\x6c\x72\x8c\x9c\x24\xcf\x0c\xd4\x4f\xc7\xc0\x32\ +\xf3\x0c\xb0\x4d\xdc\x36\x37\xa0\x2e\x84\xdf\x84\x6b\x4c\x69\xd9\ +\x0f\xf7\x57\x83\x9c\xaa\xff\xba\xe9\xcb\xa2\x3c\xa0\xce\x33\x1a\ +\xcb\x2a\x75\x1f\x5c\x71\x7e\xf5\x1c\x1c\x4f\x1e\xaf\x66\xc6\xef\ +\xc8\x56\xee\x84\x03\x90\xa9\xfc\x80\x7f\xa6\x16\xcb\x26\xe0\x00\ +\x39\xd3\x77\x8d\x67\xb8\x01\x6e\x88\x03\xf8\x8d\xff\xca\x11\xf1\ +\x2f\x38\x43\xdf\xfc\x56\x8c\xc9\x33\x1e\x6c\x74\xc4\x36\xc4\x3d\ +\x31\x5f\x7f\xcc\xeb\xe9\x0f\x2c\x71\x2e\xd8\x04\x3b\xf0\x10\xfd\ +\xc8\x7d\x24\xf2\x03\xf5\xc3\xac\x15\xf2\x57\xde\xa7\x8f\x62\x3d\ +\x9f\x97\x8f\xc8\x31\xa7\xe2\xfe\xd0\x2f\xc5\x15\x7c\x7e\x2d\xfa\ +\x0f\x76\xe3\xcc\xea\xdd\xda\xac\x5a\x50\xbe\x57\xfb\xcc\x3d\xdb\ +\xab\x5e\xdb\x47\xff\x6a\xe5\xd6\x6a\xc1\x72\xf1\x1e\xd6\xc3\x60\ +\xdc\x9e\x7f\xc2\x7f\x71\x93\x7e\xf8\xbc\x3a\x8a\xda\x00\xdf\x32\ +\x47\xcb\x2f\x13\x03\x70\x01\xb8\x2c\xbf\xe2\xa3\x1a\xbb\x31\x3f\ +\x87\x03\x38\x8f\x18\x4a\xb7\x6c\x08\x9e\xb2\x21\xfb\xf0\x6d\x75\ +\x45\xd8\xc7\x87\xc5\x02\xc7\xc0\x22\x3e\xac\xa9\x07\xd0\xbf\x5c\ +\x84\x8c\xcc\x0b\xb2\x25\xfa\x85\x19\x6c\x55\x8c\x52\xeb\x35\x47\ +\xac\xbf\xae\xcd\x6e\x70\xcd\x8d\x3c\xe3\xc9\x98\xeb\xf3\x33\xd6\ +\xa2\x7f\x75\x75\xb5\x93\x29\xfa\x37\x56\xb5\xf6\x55\xeb\x3f\xf8\ +\x2f\x9f\xa1\x03\xb2\xe7\x87\xc6\x29\xde\xca\x01\x7d\xef\x2f\xbf\ +\x65\x1f\x74\x02\x03\xcc\x83\xe7\x1e\x39\xfc\x2b\x7e\x62\x0c\x62\ +\x09\x1b\x81\xe7\xf0\x23\xcf\x83\xa7\xdf\x70\x73\x7c\x8f\x2d\xc8\ +\xdf\xf0\x2a\x3c\xc1\x6f\x78\x1c\x9c\x54\xe3\x13\xeb\xfd\x3b\xf7\ +\xde\x68\xf4\x28\xde\xeb\x07\x3c\x67\xa7\xb0\x5f\xed\x1f\xbe\x88\ +\x23\xe6\xa7\xf3\xac\x31\xb2\x84\x37\x72\x30\x6b\x4e\x22\xe7\xa9\ +\x39\x7f\x5d\x77\xa7\x26\xb2\x1e\x19\xfb\xcb\xc7\x70\x93\x59\x79\ +\x6a\xfd\x4e\xfc\xcb\xb3\x37\x57\x8d\xff\x36\xb5\x51\xdc\x8f\xbc\ +\xd4\x01\xcd\x01\xc8\x3f\x7c\x07\xbb\xc5\x7e\x75\x53\xb8\x4e\xef\ +\xa9\x11\xd0\xaf\xfd\xe1\x62\x95\x69\x9e\xcd\x28\x57\x30\x66\xe7\ +\x5a\x8b\xac\x6b\xc3\xdd\xaa\xfe\xd9\x05\x9b\x61\x43\x78\x85\x38\ +\x25\x76\xc1\x29\x18\x26\x66\xa9\x5f\x39\x86\xbe\xe5\x13\xfa\xc7\ +\x9e\xe1\x8d\xfe\xa7\x4d\xc1\x81\xec\xe3\x7a\xd6\x95\x6e\xc4\x27\ +\xc9\x30\xcf\xa5\x9e\xb5\xc6\x04\x96\xd2\xc3\xd0\x7e\x56\xa5\x7f\ +\xe7\x57\xd3\x53\xcf\x31\x87\x23\xef\x90\x7f\xc1\x60\x7e\x4f\x9e\ +\x78\x20\x0c\x36\x1f\xcc\xb7\xe4\x82\x7c\xd9\xfc\x9c\x9a\x30\x1f\ +\x83\xfb\xc3\x9c\x16\xa6\xdb\x17\xe7\x23\x3f\xfb\xe0\xf0\xfc\x1d\ +\x16\xe7\x1e\x3e\xf9\x5f\xe6\xc9\x60\x85\xad\xae\xbd\xa6\x4b\x31\ +\x63\x5e\x83\x1d\xa9\x19\x8c\x35\x6b\xce\x9c\x03\x57\x34\x9e\xd4\ +\x63\x16\xd9\x40\x7e\xe7\x0b\xea\x8f\xe4\xb6\x56\xee\x17\x1d\xe2\ +\x0e\xea\xd5\xda\x30\x06\xd4\x9a\xaf\xb8\xbb\x6a\xdd\xd7\xf3\xab\ +\xed\xf3\x1f\x7a\xe7\xb7\xfe\xc2\x52\x9c\x8a\x6e\xf4\x95\xdf\xf1\ +\x7f\x71\x57\xbc\xc5\xc5\xe8\x06\xfe\xd3\x71\xad\x01\x55\x2c\xe3\ +\x93\x8e\xb1\x06\x98\xef\xa9\x33\xf1\x65\xbc\x81\x7d\xb1\x91\xac\ +\xcf\xb4\xe5\xbe\x7f\x3c\x84\x9f\xb3\x0b\xb5\xe6\xe8\x1f\x1e\x98\ +\x2f\xf0\x9b\x73\xe3\xe4\x62\x0b\xce\xe4\x6f\x3e\xf3\x7d\xfd\xab\ +\x73\x01\xe2\x89\x7a\x03\x1c\x90\x9f\xf2\xc5\x45\xf7\xd6\xd7\x7a\ +\x0c\xbc\xdb\x88\xfe\xf9\x8a\xba\xc7\x98\xfe\xf3\x6f\xb1\x17\x67\ +\x59\x84\x33\xc3\x7b\xb0\xd6\xab\x7f\x9b\x79\x58\xb2\x37\x3e\xb9\ +\x39\xbf\xf6\x6f\x71\x9c\xde\xf9\x2d\x5c\x22\x4f\x7e\xc0\x97\xc8\ +\x8d\x6e\xd4\x0c\xd9\xf5\x70\xdd\x6c\xe4\xc6\xcf\xf1\x0a\xeb\xc3\ +\x60\x4a\xf2\x3c\xf5\x7b\xf7\x5c\xaa\xcd\xcb\xa9\x7c\x07\x5b\x60\ +\xa4\x5c\x01\x9f\xa3\x77\x8d\xdd\xd8\x4f\x53\x9f\xc0\x09\x71\x79\ +\xeb\x89\x61\x8f\x7f\xe3\xfb\xec\x0a\x86\xc1\x1b\xdc\x93\xce\x60\ +\x7f\xd6\x64\xc7\x7e\xb2\xe6\x14\x8f\x90\x6b\xcd\xe3\x03\xf9\x5e\ +\x1d\x52\x9c\xdc\x88\xfe\x71\x47\x3c\xaa\xca\x67\xa8\x7f\x39\xb3\ +\x79\xa9\x29\xfa\x1f\xab\x41\xaf\xe5\x99\x7e\xd9\x0f\x37\xe1\x5f\ +\xfc\x54\xde\x05\x03\xc8\x8f\xdc\xe1\x7c\x9e\xad\x33\xd4\x2f\x0c\ +\xe5\x7f\x72\x1b\xf6\x32\x5c\xf3\x98\x31\xaa\x01\xe3\x95\x72\x5a\ +\xdc\xdc\xfa\x09\x7a\xa6\x6f\xdc\x1c\x47\x50\x4b\x36\xbf\xe4\x33\ +\xfe\x03\x57\xe4\x75\x7c\x5d\xde\x44\xb7\xce\x0b\x3f\xe1\x12\x7d\ +\xe3\x75\xe4\x29\x97\x70\x5c\xee\xcd\xf1\x9b\xf1\xf8\x8c\x23\xfa\ +\xab\x9e\x9d\x5a\xb3\xcf\xae\xef\x98\x3c\xe3\x6b\x11\x27\x94\xab\ +\xca\x93\xd7\xe3\x6f\xd1\x85\xb5\x13\xfa\x56\x65\x34\xf4\x17\x75\ +\x13\xf5\xe9\xb1\xeb\xd4\x7b\x31\xb2\xf6\xcc\x3a\x34\xfc\x9d\x0e\ +\x63\x97\x8b\x6c\xa0\xfe\x9e\xfa\x1f\x59\xd3\x3b\xbc\x17\x6f\xd5\ +\xce\xe4\x53\xb8\x78\xd6\x5c\xf8\xcc\x5f\x7c\x4e\xce\xcf\x9f\xf8\ +\x34\x9d\x65\x0e\x78\xa8\x7f\xf9\x01\xbc\x57\xcf\x32\x0f\x67\x5d\ +\x89\xf3\x67\x5d\x8e\x3a\x27\x9d\xc2\x00\x35\x28\x39\x3a\xfd\x39\ +\x67\xee\x09\xa6\x7f\x79\xbb\x3e\xc2\x6f\x9c\x5f\x9f\x9d\x57\x4d\ +\x47\x4e\xc8\xef\xf1\x94\x3c\x5b\x5e\x5c\x11\xc7\xd8\xa7\xbf\x72\ +\x91\xd4\x23\xd8\x23\xcc\x62\x77\x30\x99\x7d\x0f\x79\x79\xad\x67\ +\xd9\x27\xcf\xcf\x5b\x6b\x5c\xae\xf7\x4a\xf3\x81\x70\x8f\xb1\x6b\ +\xb1\x57\x76\x32\x76\x9d\xac\x39\x51\x4f\x54\xdb\xb0\x8e\x4d\x5d\ +\x46\x0d\xc5\x5a\x16\x39\x0f\x59\xfa\xab\xaf\xb3\xf0\x21\xbc\x9f\ +\xde\x33\xff\x47\x3e\x64\x68\x4e\x4d\x0c\x52\xa7\x97\x63\x19\x3b\ +\x1f\x84\x99\xf1\x3b\xb5\x38\x1c\x41\xac\xa5\x7f\x18\x0c\xc3\x87\ +\xeb\xde\xf3\x17\xfe\xe2\x5c\xf6\xd1\x3f\x35\x19\xeb\x70\xe4\xe8\ +\x6a\x3d\xa9\xd3\xd2\xa9\x75\xc3\xe2\x32\x5d\xe1\xf1\x7c\x53\x2d\ +\x40\xfd\x87\xfe\xd5\x20\xe0\x87\xfe\xc1\x2a\x7d\x94\x8f\xa8\x03\ +\x90\x9d\x7c\x80\x1d\xc0\x15\xb6\x20\xe6\xb8\x06\x1b\xc1\x09\xc4\ +\x2c\x7d\xb7\x8f\x7e\x99\xe3\x24\x4b\xdf\x19\x4b\x6d\xe9\xbf\x5c\ +\x55\x5d\x61\x23\xb1\x36\x9b\xf9\x32\xf2\x1c\x9b\xf3\xd3\x60\xd2\ +\x98\x9d\x65\x6d\xa6\xdf\xc4\x07\x38\x28\xbe\xe1\x8b\x72\x74\xf5\ +\x16\x76\x9f\xfb\xf0\xf8\x96\xb9\xc7\xa1\xaf\xfb\x4e\xde\x6e\x13\ +\x03\xfd\x35\x26\x36\x03\x47\xcc\x89\xe3\x5e\x74\x09\x0b\x34\x32\ +\x55\x17\xb6\x9f\xbc\x34\xcf\x55\x93\xa7\xd8\x8f\x7c\x7c\x76\xed\ +\x31\x0c\xcd\x7c\x07\x2e\x21\xe7\xa7\x63\x71\x40\x3c\x65\x0f\x6c\ +\x58\xae\xe8\x3b\x5c\x32\x6b\xa7\xe3\x27\xc6\xc7\x36\x1c\x4f\x47\ +\xd6\x6d\xc2\x49\x1c\x4e\xfe\x80\xd7\xc1\x78\xbc\x4f\x9e\x21\xde\ +\xc0\x29\xc7\xfb\x2c\x36\xa9\x69\xe9\x87\x73\x88\x27\x7c\x86\x1e\ +\x60\x1c\x9b\x77\x7d\xf9\xe4\x18\x36\xb3\xb1\xbc\x4b\x62\xbd\x9c\ +\xbc\xe6\x00\x6a\x18\x95\x77\xd6\x39\x5f\xf8\x10\x1b\xab\x6b\x0c\ +\x70\x47\xf1\x4d\xac\x23\x27\x18\xc9\x0f\xf9\x95\x18\x8c\x33\x89\ +\x51\x7c\x45\xad\x5d\x1d\xd5\xbe\xd6\x6a\xc7\xdf\xd5\xec\x8d\xd7\ +\xba\x02\x3c\x9c\x9c\xf3\x9c\x6d\x58\x02\xe3\xf8\x1b\xae\x95\xe7\ +\xb1\x92\x2d\x3e\x08\xb3\xd9\x0e\x3b\xa0\x0b\xf5\x57\x71\x4a\xee\ +\x08\xab\xe5\xc6\xf8\x42\x78\xc2\x10\xdb\xf2\x7c\x2a\x5c\xc2\x39\ +\xc9\x9e\xff\xb9\x1e\x7f\x97\x5b\xf0\x55\xf6\x2f\xcf\xf4\x9b\x38\ +\xa3\xd1\x2b\xac\xa7\xbb\xf0\x4e\x9f\xf1\x8d\x3c\xe3\x1b\x37\xf5\ +\x9d\xdf\x60\x56\xde\x1b\x4a\xa6\xbe\x4f\x2e\xe0\xb3\xf9\x44\xb1\ +\xc5\xf9\xe5\x83\x6c\x87\x0d\xc6\xee\xb4\xf0\x31\x36\xa1\x4f\xcb\ +\xf0\x7d\x1b\x79\xb3\xdf\x3a\x57\x1a\x59\x91\x9d\xb9\xe2\x6a\x33\ +\x62\x06\xbf\x15\xc3\xcc\x87\x90\x0b\xfb\xe1\x6b\x6a\x2f\xfc\x8e\ +\xfc\xd4\x6c\x7c\x2f\xe6\x99\x9f\x85\x8f\x7c\x13\x8f\x36\xbf\xe3\ +\x1c\xf0\x16\x3f\x76\x7d\xb9\x93\x78\x2e\xd7\x84\x1b\xc6\x08\x27\ +\x61\x29\x2c\x16\x97\x93\x73\xc9\x0d\xe9\x59\x5e\xe2\x38\xb8\xca\ +\xa7\xf0\x04\x73\x80\xea\x43\x9e\xe1\x4d\x47\xfc\x6f\xcc\xb6\xe9\ +\x04\x9e\x93\xb3\xeb\xb8\xf7\x8a\xff\xe2\xe0\x78\x3c\x1c\x86\x8d\ +\xbe\xc7\xeb\xe0\x80\x3c\x13\xbe\xc9\x11\x9d\x9b\xbe\x71\x09\xfe\ +\x08\x73\x9c\xd3\x6f\xe2\x10\x1f\xb0\x3f\xbd\xb2\x1f\xbf\xc1\x2f\ +\x39\x04\x59\xb0\x77\xba\x84\x17\xfa\x6e\xfd\x32\x1b\x24\x1f\x7e\ +\x03\xdf\x93\xc3\xd4\x1c\x96\x0c\x66\xf1\xb1\xf5\xf8\x3f\x9c\xc6\ +\x3f\xc2\x9f\xb5\x3a\xbf\x48\x3e\xf5\x38\x9c\x88\x5f\x92\x35\x3f\ +\x80\x53\xfa\x4c\x77\xbe\x17\x0f\xe9\x47\x0c\xe5\x83\xf6\xa1\x63\ +\x1c\xd7\xbf\xf5\x9d\x7c\xcd\xa1\xa8\xf1\xd0\xbd\x58\x49\x5f\x64\ +\x66\xcc\xce\x25\x87\xb2\xc6\x83\x3f\xf8\x4e\xde\xc4\x9e\x34\x78\ +\x61\x5e\xc8\x1c\x96\x1a\xa8\xd8\x49\x2e\x6c\x4d\x5c\xc6\x1b\x70\ +\x77\xd8\x92\x63\x6a\x7e\x13\x59\xc2\x64\x75\x38\x5c\x05\x16\xc9\ +\x01\x61\x19\xdd\x9b\xdf\x17\xa3\xe5\x20\xfa\x6d\x0c\xb8\x1d\x5d\ +\x1b\x23\xcc\x91\x87\xca\xff\x70\x7e\xb1\xdc\xbf\x33\x57\x20\x1e\ +\x64\xbd\x28\xee\x07\x2b\x9d\x1b\xe7\x20\x2f\xfd\x55\x33\x80\x3d\ +\x30\x93\x9d\xf1\xff\xe4\x11\xc6\x94\x67\x7c\x46\x2f\x70\x4f\xdf\ +\x96\xe1\xfb\xd1\x3f\x19\x8b\x3f\x63\xfa\x67\xc7\xf5\x59\xbd\xb0\ +\x82\x5e\xe8\x02\x3f\x61\xa7\x64\x86\xab\xa9\xb7\xe0\x5d\x62\x63\ +\x9e\xed\xcd\x77\x61\x18\x3f\xe3\xfb\x6c\x5c\x8e\xcd\x9f\x8d\x19\ +\x6f\x76\x1e\x1c\xdb\x1a\x7c\xb1\x38\x73\x6c\xe2\x23\x6c\x57\xdb\ +\x17\x9f\xe9\x83\x6e\x35\x35\x13\xf8\x6f\xae\x8d\x1f\xf9\x37\xdb\ +\xe3\x57\x6c\x23\x7a\x12\x47\xab\x0f\xd5\x06\x87\x61\x03\x5b\x63\ +\xa3\x64\x6e\x7d\x37\xce\x61\x4c\x6c\x28\xef\xf9\x80\x81\xfc\x91\ +\x9d\x1a\x63\xfc\x9f\xbe\xf9\x34\xee\x4e\x56\xf0\x20\x6b\x89\xe9\ +\x98\xde\xf3\xcc\x50\xf6\x6e\x8c\x30\x05\x46\xf2\x79\x31\x00\x7e\ +\x88\x6f\x62\xa7\xcf\xf2\xcc\x3c\xa3\x2a\x6b\xc1\x34\x75\x8e\xdc\ +\xcf\xb8\x8c\x7b\x6d\x6b\x0d\x88\x2f\x8f\xe9\xdf\x35\xe5\x23\xf6\ +\x33\xff\xa3\xc6\x41\x56\xfa\x41\x36\xfc\x80\x6e\x7d\x27\x2f\x22\ +\x3f\x3a\x16\x13\xd8\x2a\xd9\x1a\xbb\xf1\xc0\x3d\x18\x00\x6b\xe8\ +\x84\x7c\xe4\x5e\xec\x05\x0e\xfa\x4d\x0d\x1f\xff\xe3\x37\xb8\x24\ +\x5b\x87\xed\x72\x62\xfd\x70\x7d\x7e\xc6\xb6\x70\x64\x76\xa4\x66\ +\x47\x96\xfc\xc5\x5a\x0a\x9c\xdb\xbf\xe5\x7e\xf0\x40\xff\xc2\xa3\ +\x6b\x3d\x58\xdc\xd7\x27\x3a\x61\xff\x70\x5d\x9f\xe9\xc1\x5a\x0f\ +\xe3\x15\xb7\x8c\x93\xaf\xf2\x5d\xe3\x60\x57\xf4\x0f\x37\xe8\x3f\ +\xcf\x61\xa0\x73\x73\x87\xe2\x96\x3e\xe3\x73\xb8\x2b\xf9\x9a\xff\ +\x65\xe3\xce\x01\x17\xf5\x5d\x9c\x61\x7f\x36\x76\xad\xce\x98\x67\ +\xbd\x39\x37\x5c\x88\x1e\xc4\x61\x1c\x2a\xf7\x29\x2c\xa3\x0e\x9b\ +\x73\x88\xd9\xc6\x34\xa6\x7f\xd8\x19\xfd\x8b\x13\x7c\x0c\x17\x27\ +\x33\xfe\x02\xbf\x8d\x83\x7c\xe8\x14\x76\xf1\x79\xf8\xef\x33\xb9\ +\xfa\x9d\x7f\xb0\x67\xd8\x01\xe7\x7c\x26\x7b\x7a\x25\x4b\xd8\x48\ +\x46\xec\x8d\x3e\xfd\xee\x1c\x74\xe0\x7b\x18\xc2\x6e\x70\x67\xb2\ +\xc1\x1f\xf4\x87\x4c\x5d\x83\x6f\xf1\x79\xba\x23\x47\xb6\x44\xbf\ +\xfa\x82\x33\xe2\x22\xa9\x05\xf1\x27\x75\x17\x78\x85\xe3\x91\xbd\ +\x79\x7b\x38\x62\x7f\x76\xe7\xfa\x79\x96\x07\xfb\x65\x67\x38\x1a\ +\x3e\xc9\xa6\xb3\xfe\x27\xcf\xe9\x90\x8b\xea\xa7\xcd\x7e\x79\x3e\ +\xa3\xb8\xe0\xbc\x62\x07\xdb\x55\x33\x30\xe7\x2a\xfe\xb1\x4d\x32\ +\xc3\x37\x83\x61\xf0\x1f\xcf\x60\x53\xf1\x7b\xe3\xc0\x4b\xc4\xa8\ +\x65\xe9\xbe\x9e\x47\x1c\x85\xb1\x63\xfa\x87\x6d\xb8\x54\x9e\xa5\ +\x8a\x97\xc9\x83\x6d\xb0\x9f\xec\xc5\x73\x7d\x26\x0b\xff\xc6\x19\ +\xf4\x17\x5f\x77\x5e\xdc\x87\x5f\x19\xab\x58\x8a\xd7\x67\xdd\x01\ +\x9d\x88\xff\xb8\x3b\x9f\x0e\x5f\xd6\xe8\x10\xe6\x93\x3f\xbb\x21\ +\x3b\xe7\x82\xf1\x59\x43\x81\x27\xfb\x8e\xbe\xe8\x9d\x5d\xd2\x2b\ +\xf9\xe3\xe1\xfc\xc9\xf7\xf4\x42\xbe\x99\x13\xa0\x63\x36\xcb\xf6\ +\xec\x9b\x7b\x08\xd9\x01\xbd\xb3\x27\xdf\xb1\x75\xba\x49\x5d\x17\ +\xc7\xc3\xd7\x82\xff\xec\x28\xb1\x85\x1e\x73\x3f\x90\x6b\x8b\x77\ +\xc6\x0c\x7b\xe8\x90\xdd\xc0\x7b\xf2\x51\xcf\xc0\x11\x60\x94\x3e\ +\xb1\x5b\xf6\xee\x7c\xb0\x2f\xcf\x75\x86\xa3\x64\x99\xfa\xeb\x46\ +\x70\x3f\xb9\x5b\x8e\x0f\x7f\x98\xa7\x7f\xfe\x2f\x27\x66\x03\xe2\ +\x61\xea\x2c\xe4\xc4\xdf\xf8\x01\x1b\xe7\x1f\xf0\x5f\xdf\x8d\x83\ +\x4e\xf9\x36\x4c\xcd\x7b\x95\xec\x4b\xae\xe4\x98\x7a\x7d\xea\x78\ +\xf0\xda\xf1\xe4\x66\x8b\xed\xc3\x25\xba\x83\xc7\xfa\x09\xdf\xe5\ +\x1c\x62\x32\x5e\x2d\xd6\xc3\x59\x3a\xd3\x27\xd8\x4b\x9e\x15\xe7\ +\xf1\x6e\x3a\x14\x57\xf1\x85\x70\x4c\x7e\x9f\xfb\x86\xc4\x1d\xb6\ +\xc8\xde\xd9\x9a\x73\x8b\xe3\xf6\x87\x47\x38\xae\x3c\x58\x6c\x91\ +\xe7\xd8\xe8\x9f\xce\xd9\x2b\x7b\x12\x97\xf8\x80\xeb\x39\x17\x3b\ +\xf1\xef\xd4\x71\xeb\xfc\x4a\xe5\x22\x64\x41\x46\x62\x28\xfd\x8b\ +\x37\xec\x82\xee\x71\xcc\xd4\x78\xd7\xab\xfb\xb1\x63\x6a\x1e\x3f\ +\x4f\xff\x72\x7a\xbe\x29\xb6\xd1\x2b\xfb\x67\xbb\xf2\x25\xbe\x0c\ +\x8f\xf9\x08\xde\x06\x03\xed\x8b\x8f\xe3\x87\x6a\x3e\x38\x1c\xd9\ +\xe1\x40\xe2\x7c\x6d\x63\xf5\xed\xd4\x65\xf2\x1b\x9f\xc1\x27\xd4\ +\xf9\xd8\x1b\xb9\xfb\x2b\xa6\xd2\x05\x9d\xcb\x01\xe8\x0b\xae\xe6\ +\x19\x3f\xd1\x7f\x9e\x7b\x02\x6f\xb2\x0e\x07\x2f\xf7\x6f\xba\xd6\ +\x27\xf6\x83\xb3\x1b\x9f\x71\xd0\x1f\x5b\xb4\x6f\xde\x01\x00\xbf\ +\xec\x03\x73\xb2\xce\xcf\xf5\xf4\x0f\x7e\xd0\x93\xfe\xe0\xb4\x70\ +\x31\x6b\x52\xb2\x5e\x51\x9c\x21\x8b\xf0\x1f\xb1\xcf\xf7\xfa\x89\ +\x37\xe6\x3d\x62\xf4\xcf\x86\xed\xe7\x9c\x70\x6e\x4c\x87\xb3\x74\ +\x9a\xcf\x6a\xf1\xb6\x7c\xe7\x2f\xee\x40\x6e\xe6\xd6\x86\xf1\x9f\ +\x1f\x8d\xe9\x5f\xfe\xc1\xf7\x71\x76\x72\x16\xf3\xf9\x4a\xe2\xb1\ +\xdc\x5b\xfe\xa0\xff\xec\x95\xee\x61\x2e\x9d\xe1\x4e\x64\x40\x67\ +\xf2\x01\xb9\x6d\xf4\x0e\x07\xf9\x29\x7c\x21\xf3\xd4\x0d\xe1\xa7\ +\xf3\xe4\xde\x0d\xfb\xc9\xbd\xc8\x3a\xf5\x45\xbc\xd1\xfc\x30\x7f\ +\xf4\x3d\xb9\xf3\x67\xf2\xca\xf3\x52\x1c\xe7\x3a\xf1\x39\xf9\x03\ +\x7f\x87\xc9\x64\x8f\xbf\xb2\x23\xf6\xcb\xff\xc4\x67\x36\x1d\x5e\ +\xce\xae\x9c\x4f\x8c\x36\x4e\x72\xc8\x7b\xe1\xc9\x2a\xfa\xd1\x5f\ +\x31\x8b\xef\xc2\x3b\x18\x23\x3f\x86\x99\x7c\x06\xf7\xc0\x21\xe0\ +\x0c\x1c\xcb\x3d\x84\xf6\xc1\x89\xf4\x95\x8f\x91\x2b\xbb\x85\x85\ +\x72\x29\xf5\x64\xf5\xcc\xdc\x0b\x65\xbc\xb6\xaa\xcf\x31\xfd\xd7\ +\xf5\x53\xe6\xf6\xf2\x6c\x24\x75\x32\xb6\x2c\x97\x56\xb7\x61\x57\ +\x72\x39\x36\xc2\x26\x8c\x79\x4c\xff\x74\x24\x5f\xc9\x73\x09\xf5\ +\x19\xe7\x33\xff\x61\x83\x9d\x38\xbf\x38\xcc\xc6\x71\x3b\xd8\xcf\ +\x97\xf0\x71\x63\x0a\xce\xa7\x4e\x86\xe3\xb1\x1b\x9c\xcf\x9c\x57\ +\xee\x81\x56\x87\x24\x17\xb2\x70\x6e\x32\xe7\xbf\xb8\x34\xae\x97\ +\xf7\xdf\xc8\x19\x8d\x45\x5c\x27\x4f\xfe\xc2\xbe\xe4\x50\xec\x03\ +\x46\xe9\x83\x6b\x45\xff\x7e\xb3\x7f\xe2\xaa\x31\xe0\x1b\xf2\x39\ +\xd8\x2b\x47\xa0\x17\x38\x45\x36\xc6\x2c\xfe\x1b\x03\x6e\xc3\xd6\ +\x5c\x47\xac\x73\x2d\xe7\xc7\x43\xd8\xae\xb1\xc1\x79\xd7\x4d\xed\ +\x40\xac\xe4\xd7\xe2\x03\x6c\x22\x77\x3a\xf5\x97\x9f\xc3\x4c\xfd\ +\xe1\xef\x7c\x80\x6d\xe0\x05\x6c\x5f\x5e\xcb\x77\xc8\x05\x9e\x9a\ +\x5b\x11\x03\xe0\xb4\xcf\xea\xdd\x79\x5f\x4d\x7d\x2f\x2a\x7e\x26\ +\x77\x32\x7f\x42\x57\x3e\xb3\x25\xd7\xc1\xe1\xc9\x10\x7e\xf1\x77\ +\x98\x06\xc7\xd8\x49\x9e\x11\x35\xa6\x7f\xe3\x22\x13\x72\xc2\x7d\ +\xf5\x17\xae\xeb\x0b\x2e\x08\xff\xe0\x01\xb9\x8a\x93\x6c\x09\x06\ +\x88\x5f\x7c\x4b\x7e\xe4\x9c\xd9\xd8\x85\x39\xd6\x3c\xef\x10\x26\ +\xe1\xb5\x74\xaf\xcf\xfa\xe3\x3b\xb6\xab\xaf\xd6\x64\xd3\x83\x7c\ +\x89\xbe\xf0\x8f\x3c\xf7\x89\xcf\x1a\x07\x9b\xe3\x5f\x74\x05\x97\ +\xd8\x32\x7e\x96\x67\x61\x6b\x38\x07\x1b\xc8\x5a\x27\x1c\x9d\xaf\ +\xea\x8b\x3e\xdb\xe4\x57\x62\x1b\x99\xb1\x4f\xbe\x29\xa6\xbb\x8e\ +\xb1\xb3\xe5\xdc\x9b\x67\xcc\x78\x19\x3d\xe2\xff\x64\x02\x53\xe0\ +\x24\x3b\xc5\x7d\xf5\x5b\x4c\x64\x33\x62\x0e\xdd\xe3\x0c\x64\xc6\ +\xae\x9d\x4b\x83\x49\xf4\xaf\xbf\xea\x51\x62\x18\x3e\x23\x86\xb0\ +\x53\xba\x23\x2b\x7a\xd7\x4f\x72\x87\xc5\xf4\xaf\x16\x6b\xa3\xfb\ +\xac\x29\x36\x2f\xc0\x7e\xed\x9f\xe7\x9c\xcb\x4b\xfd\xae\xc6\x46\ +\xbe\x6a\x7a\xfa\x9b\x7b\xa8\xc5\xb7\xaa\xff\x5a\xff\x27\x27\xfe\ +\xc9\x0f\xc8\xcd\xb8\x8c\x9d\x5c\xe4\x4b\xce\x0b\x5f\xd9\xb1\x7e\ +\xb3\x7b\x31\x9f\x9d\x89\xaf\xb1\x25\x3e\x46\x3e\x74\x8f\xbf\xe1\ +\x64\xe2\xac\x31\x8b\x19\xfe\xc2\xf1\xac\xef\x84\xa1\xd6\xa8\x92\ +\x87\x3c\x80\x3c\x72\x3f\x18\xdc\x60\x67\xb0\x98\x4d\xb1\x71\xb9\ +\x60\x72\x29\xba\x0a\x8f\x88\xff\xe3\xfb\xd1\xbf\xeb\xd0\x99\x78\ +\x41\x36\x70\x9a\x1e\x8c\x97\x8d\x67\xbd\x97\x73\xf8\x2e\xef\x62\ +\xcd\xf9\xec\x2b\x1f\x11\x1b\xe8\x92\xdd\xd1\x21\xec\x82\x91\xfc\ +\x45\x9f\xd9\x12\x5b\x84\x13\xfc\x9e\x5f\xd4\x7b\x03\x71\x0d\x3a\ +\xc6\x2d\x9c\x87\xae\xd8\x37\x99\xaa\x39\xa9\x1d\xb2\x25\x31\x8e\ +\x6e\xe5\x5a\xfc\x05\x76\xf3\x11\x38\xc8\x86\xe1\x38\xbd\xc3\x0d\ +\xf2\xd2\x3f\xb1\x4a\xac\x27\x23\xf9\x24\xbe\x03\xbb\xe0\x10\xbd\ +\xa7\x86\xec\xfc\xe2\xd9\x58\xfd\x5f\x83\x69\xf0\x86\x9d\x19\x23\ +\xd9\xd1\x9b\x8d\x3e\x5c\x97\x2e\xe8\x8f\xef\xd1\xa5\xd8\xe7\xfa\ +\x62\x82\xc6\xd6\xf5\x9f\xee\xfd\xd5\x3f\x39\xd1\x70\x7e\x33\xf3\ +\xf7\x7c\x4a\x9f\x61\x2c\x5b\x17\x0b\xf1\xcd\xbc\xab\x97\x3f\xd3\ +\xbb\x9c\x1a\xc7\x10\x8b\xc5\x2a\x1c\x03\x27\xc8\x3c\x4d\x6c\x8f\ +\x4d\x88\x51\x59\x17\xec\x1a\xb0\xc9\xe6\x18\xdf\x67\xfd\xc0\x58\ +\xb3\x3f\x8c\xcb\x73\x59\xf3\xcc\x5f\xf8\xa4\xa5\x8e\x97\x39\x24\ +\xfb\x8a\x07\xe1\x07\x62\x91\x73\xb0\x2b\xd7\x4c\x8e\xeb\x38\xf9\ +\x14\x6e\xe1\xfa\xf0\x86\x7f\xb3\xfd\xbc\x0b\x00\xf6\xab\xcf\x89\ +\x83\x62\x77\xde\x4f\x06\xb7\x61\x0b\xae\x45\x97\xf0\xd1\x31\x30\ +\x02\x3e\xf2\x1d\x71\x48\x4c\x64\x5f\xec\x91\xff\xf2\x53\x39\x94\ +\x7d\xe8\x5f\x9d\x5c\x5f\x87\xeb\xce\x62\x03\xf4\xe5\x5c\x30\x56\ +\x4c\x26\x47\xfd\x70\x5d\xe3\x63\x07\xe4\xc1\x87\xc4\x2e\x5c\x88\ +\xee\xe8\x38\x18\x97\xe7\xb3\xd5\xda\x46\xde\x87\x5b\xe7\x65\xb2\ +\xd5\xb5\x5a\x7c\x87\x9f\xb2\x6b\xd8\xe5\xaf\x3e\xc0\x6b\xb8\x0c\ +\x17\xc8\x26\xef\xd5\x66\x13\xb9\xff\x2f\xe7\x61\x1f\x6c\x34\x73\ +\x81\x6c\x55\x3f\xc9\xc2\x77\xf8\x46\xee\xdd\xe4\x83\xb9\x17\x2b\ +\xb5\x1d\xd8\x81\xc7\xc1\x71\xba\x35\x06\x36\xe8\x38\xe3\xc0\xed\ +\xc5\x79\xf5\x07\x9c\xc8\xb8\x53\x5f\xca\x3d\x9f\x6c\x83\xcd\xf0\ +\x3f\x75\x34\xf6\x60\x3f\xb9\x08\xbe\xe9\xdf\x30\x22\xcf\x9b\x24\ +\x57\x98\xa6\x46\x2a\x3e\xf2\x53\xf8\x0d\xb7\x70\x59\xb6\xc1\xf7\ +\xd8\x81\x35\x72\xae\x45\x57\x7c\x95\x8d\x88\x09\xfa\x63\xac\xfc\ +\x86\xce\xd8\x11\xbc\x81\xd3\xf6\xa5\x7f\xf5\xc8\xcc\x91\x8d\xdd\ +\xf3\x9d\xe7\x55\xe4\xde\x29\xfc\x19\x26\xc0\x54\xf2\x66\x17\xf0\ +\xcf\x39\xc5\x1b\x36\x31\xb4\x21\xe7\xc0\x8b\xf8\xac\x36\xcc\xfd\ +\xea\xfd\xd5\xd5\x0e\xb2\x0f\x1f\x72\x2d\x58\x07\x1f\x61\x1a\xd9\ +\xb3\xed\xcc\xc7\xb0\x15\x71\xc3\x77\xb9\xf7\x23\xe7\x24\x47\xb9\ +\x58\x9e\x07\x63\x7f\xbc\x4f\xfc\x26\x6b\x71\x99\xfc\xf5\x1d\x8f\ +\x60\xcb\x79\x96\x28\x2c\xa6\x7b\x3e\xaa\xe6\x07\xff\xd8\x8d\xf1\ +\xe7\xfd\xaf\xea\x04\xf2\x14\x76\x0a\xfb\xd8\x83\x6b\xe2\x94\x38\ +\x8b\xd8\xa7\xf6\x81\x57\x38\x8f\x6b\x67\x1d\x1b\x9d\xe8\x37\x4c\ +\x10\x2b\x1c\x2f\x9e\xaa\x43\xd0\x1f\xfd\xaa\x3f\x19\x3b\xcc\x17\ +\x0b\xec\xa7\x6f\xfc\x5f\x2c\x87\x11\x74\xc2\x97\xc9\x87\x8e\xc2\ +\x43\xd8\x39\xdc\xb7\xf9\x9c\x1a\x5c\xde\xcd\xc2\x76\xc6\x9e\x09\ +\x94\x58\x20\xb6\xf2\x7f\x7d\x26\x4f\xb6\xc2\x27\x61\x15\x59\x89\ +\x47\x6c\x58\x6c\x63\x83\xf5\x7e\x62\x8d\x0f\x79\xde\x5e\xe6\x05\ +\x72\x6e\x98\x11\x4e\x59\xed\x25\xf7\xc1\xe5\x73\xfa\x01\x2b\xf1\ +\x3d\x38\x26\xc7\x26\x3f\xfa\xe2\xfb\xf0\x2b\x76\x9d\xdc\xaf\xda\ +\x0f\x5d\xf0\xe3\x3c\xa7\x25\x6b\x12\xe4\x94\x7e\x33\x0e\xb1\x1c\ +\x76\xf0\x0b\xf2\xb6\x0f\x9d\x9a\x0b\xc2\x81\xe8\x92\x0c\xc4\x51\ +\x18\xc1\x87\xd9\x20\xbe\xc3\xbe\x1d\xcf\xd7\xe8\x8f\x3f\xe0\x15\ +\x74\x21\x66\xe6\x1e\x33\x76\x91\xb5\x4c\xc6\x6d\x63\xcb\x6c\x04\ +\x7e\xb9\x26\xee\x24\xe7\x96\x57\xe1\xd9\xb8\x57\x9e\x27\xac\x2f\ +\x7e\x67\x9b\x6c\x58\xed\xd3\x98\xf3\x0e\x03\xbe\x8f\x2f\x8a\xe7\ +\x6c\xc7\xbe\x70\x84\xef\xc2\x30\xe3\x85\x4f\xb8\x1f\x2c\x51\x47\ +\x57\x5b\x19\xbb\xff\x23\x72\x97\x1b\x64\xed\x45\x5d\xb7\x4a\xfe\ +\x72\x08\xe3\xca\x3a\x95\xb1\xe3\xc9\x85\xfc\xd8\x73\x1a\x99\x89\ +\xd3\x64\x8a\x4b\xf2\xc1\xfa\xac\xa6\xda\xaa\x1f\x93\x29\x6e\x65\ +\xec\xce\xcf\xb6\xf8\x3b\xb9\xc3\x56\xe3\xce\xfd\x54\x75\x3c\xf4\ +\x46\x7e\xa9\x07\xf1\x45\xf9\x27\xbf\xcc\x73\xbc\xd9\x03\x7d\xb1\ +\x55\x58\x2e\x4f\xc5\x1b\x32\xf7\x8f\x73\xf9\x9e\xbf\xb3\x3b\xfa\ +\x4f\x3c\xb5\x0e\xdf\xb9\xf8\x25\x7e\x02\x13\xc9\x98\x6f\xf9\xeb\ +\x3c\x62\x2e\x59\x3a\x1f\x1c\x81\x37\x38\x03\x7d\xf8\x9d\xfe\x71\ +\x01\xf6\xc7\x9e\xe0\x44\xee\x67\x61\x87\xf2\x29\xe7\x70\x1d\x72\ +\x27\x07\x76\x24\x26\xb3\x81\xe4\x34\x74\xca\x5e\xe4\xa8\xec\x84\ +\x4f\xc2\x5e\x9c\x99\x2e\xf8\xad\xfe\xc1\x00\xf5\x01\x9f\xab\xbe\ +\x86\xfa\xcb\x9a\x44\x39\x70\xf8\x5c\x6a\xb4\xfc\xa9\xde\x6b\x55\ +\xf9\x43\x8e\xc7\x11\xc5\x05\x3a\x8b\x1f\xc3\x49\x3e\xc6\xef\xc8\ +\x5e\x7d\x58\x1e\x27\x9f\x20\x03\x32\x0d\x37\xac\xbc\x54\xfc\xc5\ +\x2b\xf9\x7f\xbd\x86\x9c\x8a\xfe\xe0\xe9\x70\x0d\x5b\xde\x49\x92\ +\xd8\x23\xde\xb3\x15\xdc\xdc\xf5\x8d\xcb\xa6\x0f\x62\x2d\xbc\xd5\ +\x17\xbe\xe2\x77\x3e\x0e\x8f\xf1\x32\xbc\x83\x9d\xb2\x0d\xf8\x4f\ +\x1f\xe4\xcf\x2e\xf8\x35\x5f\xe3\x77\xfc\xdd\xe6\x78\xf3\x17\xec\ +\xc2\xb8\xe1\x72\x9e\x1b\xa1\xb1\x25\x7e\xc9\x96\xa2\x7f\xfb\xfb\ +\x9d\xbc\xfc\xdb\x78\xe1\x1e\x6c\x10\x2b\xfc\x65\x33\x6c\x8b\xde\ +\x61\x0a\xfc\xd0\x5f\xf1\x28\xcf\x20\x62\x1b\x36\xb9\x2a\xfb\x87\ +\xe3\xb9\xbf\x55\x9c\x90\x1b\xb0\xad\xac\xff\x1f\x3e\x0f\x24\xf2\ +\x83\x51\x79\xff\x99\x31\x6a\xc1\x68\x76\x30\xeb\x9e\xf5\xd8\x02\ +\xdc\x20\xff\xdc\x6b\xac\x3f\x62\x81\xda\x1a\x9f\x94\x2f\xb1\x77\ +\x9c\x97\xbd\xd3\x45\xee\xed\x8b\xbf\xd6\x67\x10\xb0\x63\x98\x51\ +\xfb\x91\xf7\xaa\xd7\xe7\x5c\xd7\x35\x4c\xec\x26\xef\x7c\x82\x5b\ +\x3e\xe3\x50\x74\x45\x1f\x6c\x83\xac\xc4\x46\x39\x17\x4e\x41\xb6\ +\xb0\x1c\xa6\xf0\x77\xf1\x33\xeb\x31\x8c\x85\xde\xf4\x47\xec\x34\ +\xa6\xc4\x16\x0d\x2e\xc1\x38\xb1\x82\xdf\x26\xc6\x89\x91\xbe\x0b\ +\x27\xcc\x7b\x02\xf9\x03\xfe\x4f\xbe\x78\xbc\xf9\x0e\xf6\xc8\x0f\ +\xf8\x3a\x9f\xc5\x5f\xc4\x5a\xfc\x10\xe6\xd9\xd7\xb9\xf5\x9b\x1f\ +\x93\x89\xb8\x04\x4b\x5d\x03\xbe\xe3\x76\x62\x11\x9b\x11\x1f\xd9\ +\xa7\xf1\xd9\x1f\xf7\x53\x63\x4a\x5d\x7e\xe8\xff\x55\xa7\x8e\x91\ +\x77\xf3\x83\xfc\x16\xbf\x0c\xde\xd6\xfb\x08\xab\x0f\xea\xaf\x18\ +\xcd\x0f\xc9\x8a\x5c\x9d\xcf\x78\x7c\x26\x43\xb5\x04\x32\x80\x15\ +\xf6\xc7\x69\x70\x83\x3a\x67\xab\x19\xaf\x98\xc6\xa6\x6a\x3f\xf3\ +\xec\xeb\x6a\xc3\xe9\x03\x7d\xab\xf5\xc2\x4d\xbf\xeb\xc3\x90\xe7\ +\xfa\x37\x9d\xd0\x0f\x19\xf2\x71\x32\xe3\x2f\xbe\xe3\xbb\xb9\x47\ +\x0c\xde\x91\xbf\xbe\xb2\x2b\xbf\x8b\x7f\x8e\xb3\xb1\x15\x7f\xe9\ +\x8e\x7e\x6d\x3e\xdb\xc7\x86\xab\xb0\x17\x5c\xdf\xb8\xd9\x9c\xb8\ +\xe6\x37\xfe\x0b\x17\xc5\x72\x3c\x2f\xef\x2d\x0b\xf6\xdb\x17\x76\ +\xe9\x97\x63\xf2\x5c\x62\xb6\xe2\x7c\x30\x50\xad\x8c\xad\xe2\x32\ +\x79\x5e\x8a\x1c\x1a\xde\xf1\x29\x72\xca\x9a\x2e\xf5\x98\xf0\xf5\ +\xb1\xdc\x37\xdf\xe1\xc7\x72\xaf\xd4\x29\xaa\xdc\xc2\xd1\x52\x1f\ +\xa9\xb6\xc0\xf7\xb2\x0e\x40\x63\x97\xc6\x95\x78\x62\xae\x2b\x79\ +\x13\x0c\x83\xff\x6c\xc2\x5a\xbf\xca\x25\xa3\x2f\xe7\x97\xcb\xe1\ +\xba\x59\x0b\x5c\xeb\xfc\x63\xeb\xd7\xe9\x0b\x26\x8a\xb9\xe1\xc1\ +\xe4\x49\x27\x99\x7f\xad\x9b\xfc\x8e\xdc\xc5\x4f\x7f\xc5\x4c\xbe\ +\x26\x0e\xc0\x5f\xf6\x0a\x3b\xd4\x9e\x71\x05\x7e\x27\x86\xe2\x33\ +\xe4\x24\x96\xeb\x63\xe6\x0e\xd9\x88\xcd\x67\x79\x5e\xd6\x13\xe6\ +\x5e\x11\x7f\xc5\x7c\xe7\xc0\xe9\xf3\x4c\x41\xf9\x22\x9c\x17\x93\ +\x60\x76\xe6\x93\xf5\x9d\xac\xf0\x11\x7f\xf5\x99\x8e\xe1\x8d\xf3\ +\xc0\xe9\xbc\xf7\x43\x73\x0c\xdd\xc3\x5c\x18\x40\x0e\x62\x9c\x3a\ +\xb1\x98\x16\x7d\x8e\x61\x78\xce\xc1\x77\xf0\x05\xbe\x97\xf7\x26\ +\x46\xee\xa9\x65\xc2\x3c\x5b\xe6\x5f\xe0\x99\xf8\x06\xe7\xd9\x9c\ +\xe6\x7b\x7d\x8d\x9f\x5b\x0b\x97\x9c\x0e\xe7\xc5\xc5\xf4\xdf\xbf\ +\x53\xab\x1f\xde\xbb\x41\x17\x64\x9f\xb5\xa0\xd5\xee\x6a\xcb\x71\ +\x30\x84\x5c\xe4\xd0\xf0\x9c\x0e\xd8\x5b\xee\xf7\x83\xbf\x36\x7a\ +\xc1\xb3\x12\x13\x6c\xec\x9d\x5e\xe9\x9b\x5d\xca\xf9\xe1\x16\x4c\ +\x66\xc7\xfc\x08\x0f\x20\x6f\xf6\x2a\xa7\x51\x7b\xcc\xbb\xe0\x6c\ +\xc6\x41\x0e\x64\x03\x63\x72\xdf\x5a\x38\x94\x7e\xd2\x21\x4c\xe3\ +\xbb\x6a\x36\x7c\x86\xef\xe2\x0d\x3e\xcb\xdb\xd8\x86\x1c\x9e\xcd\ +\xb0\x81\xe4\xbf\x64\x46\x9f\x30\x01\x0f\x86\xf1\xc6\x5c\xe5\x22\ +\x5e\xd1\x4b\x7d\x7e\x1b\x7f\x36\xde\x59\xbe\x5f\xbf\xa7\x73\x1c\ +\x40\x7d\x27\x35\xaf\xac\x9f\x66\x5f\xec\x9e\x6c\xc5\x72\xfe\xc0\ +\xdf\xd9\x2f\xec\xe3\x7b\xfa\x14\x9d\x64\x0d\xb4\xfe\x90\x0d\x9b\ +\xd4\x2f\x7a\x91\x8b\xb8\x0e\x4e\x12\x2e\x37\xe4\x73\x59\xd7\x65\ +\xdf\xc8\x6f\xde\x73\xec\xd2\x7f\x7d\xa4\x33\xb1\x5e\x1e\xe3\xfc\ +\xf0\xdc\x67\x39\x2d\x5d\xe9\x33\xec\xcf\xf3\xbe\x6c\xa9\xdd\x65\ +\x63\xd7\x79\xbf\x33\x1d\xf1\x73\xc7\xe7\xfb\xac\xff\x1e\x3e\x43\ +\x6e\x58\xd7\xb0\x8f\x63\x9c\x9f\x6d\xf0\x31\xf9\x9d\x5c\x5b\x7c\ +\xe6\xf3\xb0\x99\x7c\xd8\x0f\xdb\xe3\x23\x78\x0e\xbd\x8b\x8f\xe1\ +\xf2\xf0\x94\x0d\xc2\x83\xac\x81\x88\xfe\x72\x2d\x4d\x8c\xe1\xf3\ +\xf4\xef\x5a\xf2\x84\xea\xe7\xb3\xe4\xe7\x77\xf9\x92\x3a\x2c\x7c\ +\x8b\x2f\xc3\x6b\x38\xa4\xfe\x88\x6f\xe0\xf2\x70\x1d\x47\x83\x15\ +\xfc\x47\xee\x14\xff\xaf\xf1\x22\x7f\xb3\x5e\x82\x3e\xc8\x9f\x2c\ +\xd9\xc6\x2c\x7f\xce\x9c\x30\xdc\x48\xec\x9a\xf7\x2c\xbb\xc8\x01\ +\x3f\xc3\xa9\x1d\x2b\x76\xb2\xc9\xa1\x9e\xc6\xee\xb7\xaa\x35\xc9\ +\x6c\x89\x77\xfc\x8d\xff\xab\xa5\xca\xb5\xf4\x87\x3f\xa4\x86\x28\ +\xfe\xd9\x8c\x27\xf6\x64\xbc\x6c\x87\x5e\xe5\xc4\xec\x1e\xd6\xc0\ +\x1d\x3e\x4e\x56\x62\x0c\xdf\xa0\x73\x1c\x4d\xfc\xc8\xdc\x38\x9c\ +\x61\xc7\x70\x32\xef\x29\x12\x2f\xf4\x45\x9e\x07\xa7\xc3\x53\x33\ +\x96\xaa\x7f\xf5\x47\xfa\xa7\x23\x5c\x24\xf2\x99\x27\x3b\xcd\x38\ +\xd5\x19\xd8\x17\x5d\xc1\x71\x78\x45\xef\xfc\xdd\xb9\xc4\x54\x63\ +\x87\x83\xf8\x5c\xb0\xcc\xbf\xd3\xf4\x01\x37\xc9\x7c\xfc\xd4\xf7\ +\xd4\xd5\x67\x1e\xa9\x01\x1b\x2b\x7b\x21\x67\x98\x34\xef\x79\xc6\ +\xd1\x21\x5f\x83\x1f\x7c\x87\x0d\x88\xd3\xfa\x53\x7f\x27\xe3\x3c\ +\xf7\x9f\x2e\xe4\xd5\xec\x9c\x4e\xe0\x12\xfb\x97\x4f\xc1\x5d\xbc\ +\x4b\x6e\x26\x47\xe3\x57\x89\x21\x7c\x12\x2e\x88\x1d\xe1\x05\xc6\ +\x2b\xce\x88\xc5\xfc\x84\x6f\xe0\xd3\xfa\x6e\x4c\xfa\x05\x07\xc8\ +\x50\x6c\x62\xab\xf0\x05\xc7\x50\x37\x8c\x0e\xd9\x12\xbb\x11\x07\ +\xe8\xc0\x5f\xba\xc4\xff\x70\x7d\x35\x06\x3e\x32\x56\xcb\x33\x6e\ +\x76\x63\xbe\x88\x3f\x8f\xf1\xa6\x59\x72\x77\x2d\xb5\x0d\x31\x4f\ +\x3c\x12\x0f\xf9\xbe\x73\x8e\xbd\x5f\x08\xb6\xc2\x29\xe3\xa9\xcf\ +\x4f\x70\x1e\xf1\xd8\x79\x60\x3d\x9c\x50\x3f\x71\x3e\x31\xcc\x38\ +\xd8\xf8\xac\x7b\xdf\x12\x07\xf9\x8d\xf3\xe2\x67\xfc\x63\xea\x33\ +\x33\xf5\x03\xc6\xf3\x3f\xf1\x0a\x07\x8e\xbe\xc8\x9d\xfe\xfc\xc5\ +\xa5\x9d\x97\xbe\xe9\x3d\xcf\x9c\xc0\xc3\xd9\x84\xdf\xe9\x5e\x8c\ +\x33\x4e\x31\x99\x0f\xe4\xd9\xdf\xf9\x9c\xcd\x7e\x79\x77\xbc\x63\ +\x1d\xc3\x77\xeb\x5c\x05\x39\xf2\x69\x9c\xcf\x7e\x8e\x61\x87\x99\ +\xcf\x8a\x3e\xf2\x7c\x41\x1c\x38\xcf\xc5\x73\x8d\xdc\x77\x34\xf6\ +\x2c\x31\xf2\x31\x46\x35\x42\x73\x44\xb9\x7f\x7d\xd1\xf3\x26\x22\ +\x53\xfd\xcc\x7b\x51\xe9\xcf\x06\xf7\xb2\xce\x62\x98\xfb\xcd\xb2\ +\x23\xf6\x4e\x6e\x64\xcb\x37\xc8\x42\x3c\x4f\x0d\x46\xee\x2b\x66\ +\x04\xc3\xea\xb1\xc6\x0c\x7f\xf8\x3e\xf9\x92\x0b\x1e\x88\x73\xd4\ +\x5a\xf1\xbc\x96\x7d\xd8\x98\x79\x11\xb9\x91\x1c\x0a\x9f\x12\x13\ +\x60\x29\x1b\x94\xf7\xd3\x29\x5d\xc2\x5e\xf8\x6a\xe3\xa3\xbe\x37\ +\x06\xbe\x49\x5f\xea\x05\x6a\x2e\xc3\x7b\xd2\xc7\x64\x49\xe7\xce\ +\x33\x9c\x6b\xcb\x7c\x33\x1b\xc9\xba\xa3\xa1\x0f\x0c\x1b\x2c\xd0\ +\xdf\xac\x6f\x1e\xe3\x4b\xb9\x0e\xfb\xc8\xb3\x9b\xf9\xb1\xf1\x55\ +\x79\x2c\xea\xb7\xc6\x66\xd4\xa3\xd5\x21\xe4\xa2\xae\xab\x8d\xc5\ +\xdf\xb1\x5a\x80\x06\xcb\xc4\x2f\xbe\x04\x17\xe1\x2a\xff\xc3\x5d\ +\x82\x9d\xf0\xb1\xd6\x94\x33\x06\x1c\x8d\xcd\xd1\xbf\x6b\x93\x3b\ +\xde\x9c\x7b\x29\xa7\x3c\x3f\x27\xfd\xe0\xc3\xf8\x54\x9e\xe3\xb3\ +\x48\xd6\xb5\xb9\x36\xdc\x30\x87\x02\xfb\x7d\xc6\x47\x60\x99\x98\ +\xad\x9f\x55\x06\xb3\xfa\x31\xac\x53\x6b\x64\x89\xaf\xcf\x7b\x4f\ +\xc3\xac\xb1\x0e\x39\x66\xdd\x8f\xac\xe0\x84\x39\x1f\xb6\xbb\x96\ +\xf7\x41\xe5\x1c\xe4\x6c\xfe\x45\xed\x50\xde\x3a\xbc\x6f\x78\x5e\ +\xcb\x3e\x62\x1a\xec\x20\x77\xf5\x54\xfa\x97\x87\xc9\xad\xe9\x1e\ +\xce\xaa\x81\x85\xdb\xd5\xc6\x56\xf9\x19\xfb\x51\x27\x91\x5b\xc8\ +\x91\xb3\x5e\x70\x6a\x1f\xf8\x30\xdc\x11\x47\x72\x7f\xd0\x70\xfe\ +\x71\xc8\xdf\xe3\x27\xf8\x8d\x63\xe5\xa0\xe6\x55\xd4\x55\x33\x4f\ +\x90\xf5\x09\x70\x4c\x7c\xc1\xf5\xea\x75\xf3\x79\x8a\x9d\x4e\x1d\ +\xcb\xac\xdf\xea\x75\xc4\x04\xb1\x2e\x6b\xc3\xc8\xac\x8e\x79\xea\ +\xb5\xc2\xbd\xcd\x3d\xb3\x21\xe3\x9b\xaa\xff\x34\xfe\xaf\x2e\x89\ +\x2f\x91\x1b\xee\x4b\xef\xfc\x1a\x9e\xf2\x21\xdc\x0c\x0f\x1b\xe3\ +\xe3\x1a\x6e\x24\x5e\x90\xf9\x5a\xde\x75\x9e\xf1\xe2\x75\xe2\x8c\ +\x3e\x4c\x1d\x43\x7e\x97\xab\xc2\xbe\xd4\xc2\x6b\x63\x1b\xea\xb1\ +\xd6\xe5\xe8\x9f\x58\x47\x66\x6b\x69\xb3\x70\x61\x56\x7f\x86\x9f\ +\x6b\x8b\xcd\x1a\x6f\xde\x39\xc0\x6f\x86\xcf\x7e\x9e\xda\x2f\x4d\ +\x9c\x94\x93\xa8\x05\x88\x3d\x6b\x3d\x8f\xfc\x1b\x7e\x93\x11\x1f\ +\xa2\x03\x36\xc0\x3e\xf3\x4e\x44\x31\x37\x73\x0b\xb5\xe5\x3a\xf8\ +\x8f\xf8\x91\xb5\x3e\x53\x9e\x9f\x57\xd7\x12\xe0\x8e\xb0\x3b\xf1\ +\x6b\x2a\x07\x72\x5d\xf6\xaf\xbf\xa9\x4f\x8c\xcd\x37\xe2\x16\x30\ +\x8c\x0d\x90\xfd\xbc\x79\x92\x55\xb6\xe0\x16\xbc\xb2\x76\x00\x6e\ +\xcb\x5d\x16\xe5\xcb\xb3\xce\xa5\xe1\x2e\x7c\x5f\x8d\x42\x0e\x33\ +\xf5\xf9\x95\x19\x3b\xfe\xa3\x56\x21\x2f\xa0\xbb\xdc\x3b\x3f\xcc\ +\x21\x16\xf1\x48\x36\x9c\x39\x43\xe7\x58\xf4\x8e\xd3\xe8\x48\xdc\ +\x97\x2f\x19\xc3\x58\xce\x3f\xef\x9a\xec\x85\xee\x53\xcf\x1e\xfa\ +\x60\xd6\xb9\x66\x4e\x02\x96\xc9\x13\x87\x35\xf6\x45\x5c\x79\x19\ +\x2d\xd7\x92\x63\xc3\x3a\xbe\x8f\xa3\xe0\x95\xf5\xf7\xa9\xad\xf6\ +\x55\xdd\xc8\x9a\x20\x18\x30\x8c\x9f\x1b\x69\xa9\x0b\xc2\x7e\x31\ +\x7a\x16\x37\xa5\x6f\xfa\x87\x15\x30\x44\xed\x4c\xce\x3e\x4b\xa6\ +\xe9\x1b\x3d\xc8\x97\xf2\xbe\xbe\x29\xfd\xae\xf9\x8f\x7a\x01\x8c\ +\x92\x9b\xc0\x28\x39\x5c\xea\xbd\xea\x56\xc9\xbd\x12\x53\xd4\xe7\ +\xac\x71\xc8\x7c\x75\x3d\x67\x5d\x07\xba\x8a\x16\xde\x02\x23\xd5\ +\x14\xf1\x3e\x35\xa6\xb1\xe7\x61\xac\xe5\x9c\x5a\xde\xad\x0a\x53\ +\xf8\xe0\x5a\x9e\x61\xeb\xba\x7c\x15\xff\xe4\xf7\x79\x9e\x1b\x2e\ +\x89\x33\xe1\x54\x7c\x33\xeb\x79\x73\x4c\xed\xaf\xba\x38\x1f\xb6\ +\x2e\x1a\x0e\x89\x47\x70\xa0\xae\xd1\xad\xd7\x4b\xdf\xe5\x9c\xf8\ +\x0f\x0c\x9c\x2a\x83\xfa\xfe\x08\xc7\xcb\x81\xe4\xa0\xc6\x6e\x4e\ +\xd4\xda\x2b\x6b\x75\xe8\xd9\x5a\x54\x39\x2a\xfd\xa7\xae\x09\x2f\ +\xd4\x7e\xc8\x8c\x8d\xb0\xed\xd4\x04\x93\x3b\x8f\xe5\xeb\x1b\x69\ +\x39\x97\x1c\x99\xcf\xf3\x7d\xf3\xeb\xa9\xdd\xaf\xf7\x5a\x35\x97\ +\x23\x0f\x75\x5f\xf3\x2a\xf0\x7c\x11\xaf\xad\x7a\xe0\x37\xea\x3d\ +\x99\x7f\xc9\x73\x73\xf1\x2a\xb9\x14\x0e\x2d\x7e\xca\x37\xc6\x6a\ +\x54\x38\x98\x5a\x64\xee\x0f\x57\x83\x12\x97\xc6\xfc\xbf\xea\x8f\ +\x9e\xc4\x64\x3e\x3b\x45\x0e\x15\x37\xf8\x0e\xee\xaa\x36\xa0\xe6\ +\xa6\xcf\x6a\xf4\xe6\x21\xe0\x20\x5b\x64\x13\xb0\x36\xef\x61\x97\ +\xd3\xe2\xba\x72\x66\xb9\x57\xde\xfd\x18\x8e\xab\x46\x0a\x9f\xb3\ +\xf6\x78\x59\x36\x10\x9b\xc2\x73\x72\x0f\x99\xfe\xe7\x1e\xac\x8d\ +\x60\x4e\x9d\x53\x51\xb7\xc3\x29\xc8\x62\x6c\x0e\x6e\xec\x38\x63\ +\x95\xf3\x91\x13\xbe\x8f\x07\xaa\xf7\xc8\x09\x33\xc7\xc6\x4e\xe1\ +\xac\xfc\xb0\x3e\x9f\x36\xe7\xe0\x4b\xe6\x9b\xd8\xb6\xfa\x58\xe6\ +\xbb\xc6\xe4\xa0\xc9\x17\xd8\x0a\xd9\x3b\xf7\x14\x59\xe7\x5a\x59\ +\x3f\xa4\x3f\x6c\x2c\xcf\x1f\xcb\xfb\x62\x70\x42\x75\x3a\x36\x99\ +\x7b\x5b\xe0\xad\xb5\xb9\xe6\x4b\xac\xc3\x95\x77\x65\x73\x1f\x97\ +\x1a\x5c\xec\x85\x5d\xe0\x51\x79\xe7\xdf\x46\x6d\x20\xe7\xe0\x93\ +\x38\x2e\xdd\xe7\x5d\x09\x75\x5c\x1b\x6d\xae\x21\xae\xb1\x6d\x6b\ +\x4d\x9d\xbf\xce\xc5\x8f\xb5\x5c\x5b\x9d\x0d\x2f\x52\x57\x85\xdb\ +\xea\xe0\x70\x9f\x9c\x71\x2b\x79\xbd\x79\x05\xf5\xca\xa1\xfe\x83\ +\x33\xea\x08\xb0\xdc\x5a\x01\x5c\x60\x58\x6b\x8a\x3d\xa8\xd5\x99\ +\x4f\x36\x47\xa6\x06\x32\xa5\x56\x50\xcf\x05\xbb\xc5\xb8\xfa\x8e\ +\x86\xb1\x39\xa3\x3c\x4b\x0c\x47\xa0\x7f\xba\xce\x7d\x80\xc9\x6b\ +\xc4\x0f\xf3\xf0\xea\x70\x74\x43\xff\xec\x41\x0c\x33\x17\x8e\x2f\ +\x2c\xf2\xa3\x45\x2d\xdc\x82\x0c\xd9\x98\x7b\x08\xc5\xbb\x7a\xaf\ +\xfa\x46\x5b\xce\x21\x3e\xab\x55\x9a\x4f\x90\x57\xf2\x8b\x79\x9c\ +\xa6\x62\x87\x39\x0c\xf5\x3f\x18\xc5\xcf\xe9\x3e\xcf\x08\x83\x99\ +\xce\x4b\x77\xc3\x77\x39\xa4\xe1\x0a\xea\x2d\xd6\x41\xc2\xe0\xd4\ +\x3f\xab\x0d\x66\xed\xa9\x98\x02\x73\xb2\xc6\x74\x58\x93\x1c\xf6\ +\x31\xdf\xab\x51\xe9\x87\x6b\xc5\x6e\xe6\x6d\x1a\x3c\x10\x8f\x70\ +\x01\xf3\x31\xb8\xa1\xef\x32\xd7\x9c\x7b\x43\xf2\x0c\x05\xb5\x98\ +\xbc\xe7\xc2\xba\x1f\x39\xf5\x7a\xdf\x09\x90\xb1\xcb\x53\xf2\x6e\ +\x6e\xf8\x6a\xce\x65\xd6\x78\xd7\xdb\xe2\x63\xc6\xc8\xce\xdd\xbb\ +\x87\x1b\x8d\xe5\xed\xf5\x18\x8d\xae\x92\x4b\x19\x3f\xfb\xe4\xef\ +\xe6\x26\xe1\x02\x2c\x65\x23\xf5\x3d\x3e\xc3\x86\xbf\xe3\x89\x62\ +\x29\x2e\x80\x13\x56\xdf\x81\x23\xf0\x9e\xfe\x61\xc5\xf0\xdd\x5b\ +\x63\xf2\xa8\x32\x37\x47\x99\x75\x97\xa9\xe1\xcc\x3b\xb6\xda\x40\ +\xee\x6d\x99\xd2\xd8\x95\x78\x06\x9b\x8c\x45\x4c\xc4\x09\xe6\x8d\ +\x7d\xac\xc5\xf6\xd5\x8e\xad\x0d\x75\xbf\x96\xf8\xa3\x9e\x3a\xd6\ +\xff\x8d\xb6\xc8\x2a\xef\xa0\x72\x2d\x3a\x64\xd7\xf3\xec\x37\x7d\ +\xc0\xed\xcc\x0d\xe7\x1d\x8a\x64\xad\xaf\x6a\x27\x43\xd9\xc1\x15\ +\x5b\xad\xf3\xb0\x69\xbc\x03\x5f\x80\xa7\xf8\x94\xdf\xf8\x97\x9a\ +\xac\x39\x04\x39\x0a\xfd\xd5\x5a\xf7\x18\x47\xac\x71\x17\x27\x87\ +\xf9\x74\xc1\x8f\xc7\xde\x99\x9e\xba\xca\x2c\xfc\xa8\x9f\x6b\x9c\ +\x18\xc6\x8d\x61\x33\xf7\x43\x0e\xe2\x5e\xbd\x2f\x62\x51\xcb\x98\ +\x60\x25\x5f\x52\x9f\xe5\xfb\xd6\x59\xca\x8b\x87\xfd\x5a\x46\xab\ +\x72\x24\x73\xbe\x2b\x0e\xc8\x8d\xe6\x3d\xc3\x3a\xdf\xc1\x42\xf8\ +\x6a\xcd\xaf\x1c\x35\x35\x92\xba\x8f\x3c\x09\x57\x10\x3f\xe9\x34\ +\x6b\xcf\x34\xf1\x38\x1c\x5a\xfc\x70\x9f\x0e\x5b\x10\x6f\xf1\x71\ +\x71\x16\x2f\x1b\xf6\x35\xf3\x6c\x43\x3d\xf8\x2b\x7e\x8b\x49\xe2\ +\x0a\xfc\xce\xfd\x6b\x63\xbe\xbe\x68\xde\x6c\x8a\xbc\x2b\x9f\x49\ +\x5f\x32\xa7\xcb\x16\xa6\xcc\xcd\xe5\x3c\xc6\xc4\xd6\x71\x31\xf7\ +\x83\xcb\xcb\x0e\x38\xe0\x80\x75\xd5\xe8\xa7\xb6\x6a\x77\xf4\x24\ +\x0f\xc7\x39\xc4\xf1\x59\xb2\x4b\x33\x36\xb1\x31\xef\xa4\xcf\x77\ +\xe4\x40\xef\x62\x37\x2e\x05\x23\xac\x55\xb0\x56\xb4\xde\xc3\x85\ +\x17\xca\xaf\xd4\x72\xe4\x8d\xee\x69\x95\x8b\x18\xbf\x7a\xa7\xfa\ +\x91\x36\xd4\xf1\x90\xa3\x06\x33\xd4\x90\xd8\x13\x3b\xb6\x4e\x3f\ +\xeb\x84\x37\xab\x66\x1b\x1d\xc2\x3e\x9c\x43\x3c\x18\xae\x81\x9b\ +\x77\x1c\xdb\x85\xfb\x78\x27\x2c\xe6\x5b\x63\x31\x6f\x15\xfd\x26\ +\x63\x18\xcb\xff\x70\x5f\x39\x8d\xf9\x91\xb1\xf9\xaf\x79\xe7\xb0\ +\xc1\x01\xbe\x27\xff\xc7\x2b\xd4\xdb\xe5\x6c\x74\x2d\x47\x14\xcb\ +\xc3\x31\xd4\x72\x8d\x15\xd6\xa9\xc3\xe0\x82\xf5\x3e\x9f\x8a\x41\ +\xc3\xfc\x80\x7d\xe0\x61\x78\x03\xbc\x17\x2b\x70\x8f\x7a\x2f\xec\ +\x66\xe9\x3e\x2d\xeb\x69\xf9\x8f\x79\x24\xfc\x7a\x9e\xfe\x63\xcf\ +\x6a\x4e\xfa\x8e\xeb\xcb\x27\x60\x70\xee\x55\x5e\x16\xdf\x5f\x64\ +\x83\x36\xf6\x86\xcb\xf2\x43\xeb\x2a\xac\x89\x9b\xc7\x07\x6b\x1c\ +\xc5\x83\x52\xd3\xb7\x46\xca\x9c\x20\x7b\xb2\xbe\x42\xee\x64\xae\ +\x10\x97\xc5\xf5\x53\x17\x14\x0f\xd4\x7f\xe5\x4f\x30\x1b\x66\xca\ +\xc9\xc7\xb8\x17\x1f\xa1\x73\xf6\x95\xfb\xe6\x70\x0f\x58\xeb\x5a\ +\x6a\x04\xe1\x00\xcb\xac\xc5\xad\xa5\x45\xff\x72\xe1\xac\xed\x9e\ +\x25\xfb\x7c\x0f\x2b\xe5\xd1\xc9\xf5\xe4\x4e\xf2\xa6\xb5\xbc\x53\ +\x6a\x51\x9b\x82\x83\xf1\x19\x31\x57\x6d\x27\x76\xa8\x3e\x33\x2f\ +\xa7\xcd\x71\xd6\x7b\xe0\xbe\x38\x0b\xdd\xe0\x04\xf4\xaf\xbe\x27\ +\x16\xc0\x01\x31\x00\x4e\xd7\x63\x8d\x15\xee\xa9\xb7\xe4\x59\xd0\ +\x72\x28\x98\x9e\x35\xd8\xf8\x08\x5e\xea\xbc\xf2\x6c\xeb\x9f\xc4\ +\x09\x5c\x0b\xd7\xae\x35\xd8\xad\xd2\xbd\x16\xfd\xb3\x77\xf8\x9d\ +\xfb\x2d\x67\xe5\x1a\x7c\x06\x06\xaa\xc1\xa8\xef\xcb\x21\x71\x56\ +\xb1\x6b\x2b\xf0\x2b\xdc\x0a\x17\x70\x8f\x99\x58\xa4\x46\x2a\xce\ +\xcf\x92\x6d\x30\x8c\x9d\xa8\x21\xd0\x91\xdc\xcd\xb8\xe4\x93\xf2\ +\x44\xf1\x1f\xf6\xe7\x79\xee\xc3\x78\x6e\xed\xa4\x7a\x02\x2c\x50\ +\x83\xe3\x03\x6c\x41\x6d\x48\x1c\x61\x1f\xe6\xbf\x7d\x9f\xe7\xab\ +\xb8\x9e\xf8\x14\x99\xaf\x67\x4e\x74\xd9\x2d\x6b\xea\x71\x57\xe3\ +\x1f\xcb\x3d\x32\x7e\xfb\x8a\x5d\x62\x24\xdd\xcb\xbf\xc5\x0c\xbc\ +\x6b\x99\xbe\xbf\x96\x96\x7e\xb1\x4b\xfc\x85\x5d\xaa\x75\x5a\x4f\ +\x39\xeb\xdd\x46\xf9\x4e\x8e\x6a\x5e\xd1\x73\x8a\xf8\x3c\x19\xe0\ +\x7b\xd6\x77\xd9\xd4\x19\xc6\xe6\xda\x73\x4d\xfc\x03\xbe\xf3\x19\ +\x31\xdc\x3d\x7e\x64\x68\xad\xaa\x5c\x11\xbe\xe8\x83\x5a\x4c\x9e\ +\x3d\x52\x9f\x4d\x54\xd7\xf9\x6c\x95\xec\x5c\x1f\x56\x89\x71\xec\ +\x73\x88\xbb\x55\x7e\xc6\x94\x77\x20\xe0\x40\x38\xa3\xf1\xaf\xb5\ +\x6e\xb0\xec\x16\x7d\xb0\x5d\x18\x06\x93\x3c\x8b\xca\x5c\x4f\xbd\ +\xff\x7f\xec\x18\x39\xbe\xba\x25\x7d\xc3\x6b\x35\x41\xb2\xc8\x73\ +\x76\x86\x5c\x3e\x78\x13\xde\x9c\x7b\x6a\x7c\xcf\x8f\x72\xff\x46\ +\xe6\x1b\xcd\x55\xcb\x17\xcd\x85\x58\x6f\x24\xd6\xc0\x27\x6b\x8a\ +\xc5\x81\x6a\x9b\xeb\xc5\xcf\xf5\xe4\x0c\x43\xbf\xd1\xa7\xf8\xcb\ +\x70\xbc\x1a\x5e\x25\x8e\xc1\x57\x5c\x0b\x8f\xc1\xf7\xb6\x02\xf3\ +\xc7\x5a\xfa\xca\x1e\xc5\xe3\xbc\xcb\x63\x91\x0d\x38\x86\x1e\x60\ +\x36\x3e\x8e\x3f\xf0\xe3\xba\xb6\xb5\xe6\x0a\x8b\xfa\x90\xbf\xd6\ +\x1c\x89\x2d\x6a\xa2\xd6\xae\x8a\x05\xf8\xa2\xeb\xa8\x3d\xa9\x11\ +\xe6\x79\x4b\xb0\x27\xeb\xad\x37\x2b\x0f\xc8\xb8\x60\x93\x18\x26\ +\xdf\xa9\xf7\xa9\x56\x3b\xe0\xf7\xe6\x30\xf1\x2b\xef\x5f\x31\x6f\ +\x3a\xbc\xdf\x63\x3b\xb4\xf4\x85\x5d\xd2\xbb\xbc\xd0\x7c\xb1\xdc\ +\x3c\xef\x65\x1a\x8b\x05\x7c\xd5\x3c\xab\x3a\x0e\xae\x37\xac\xdd\ +\x55\x8e\x8e\x6b\xd2\x2d\x9e\x68\x0d\xb8\x1a\x11\xfd\x91\x91\xd8\ +\xae\x56\x60\x1d\x01\x2e\x62\xc3\xf7\xcc\x03\xc0\x13\xf5\x47\x35\ +\x24\xfb\xe6\x99\x9c\xf6\x65\x0f\xd6\xb8\xe2\xe0\x8b\xd6\x73\x2f\ +\x43\x46\xf5\xf9\x26\xe2\xa4\xb9\xe5\xf8\x72\xc6\x19\x59\xe2\x55\ +\xfa\x47\xf7\x9e\xf3\x20\x77\xc9\xbd\x35\xdb\x49\xf7\x69\xe9\x93\ +\x3c\xc6\x3c\x8f\x35\x43\xe6\xbc\xf2\xac\x6f\x6d\x88\xe9\xc9\x69\ +\xcc\x85\x0d\x75\x9f\x26\xbe\xcb\x0f\xf0\x3a\x73\xea\xee\x49\x60\ +\x5f\x62\x8d\xda\x83\xb5\x21\xe2\xa1\x7b\x4c\xdd\x1b\x29\x9f\x54\ +\x37\xc8\x73\x87\x67\x35\x98\xeb\x9e\x6a\x79\x88\xfa\x99\xfa\xf2\ +\xd8\xb3\x4d\x36\x2a\x93\x21\x7e\xc1\x49\xdc\x4d\x4c\x92\xcf\x24\ +\x67\xae\xeb\xc5\xac\x29\x50\xdf\x50\x63\x8d\xee\xed\x9b\xdf\xb7\ +\x6b\xab\xeb\x06\xd5\xb5\xd9\x80\x98\x65\xac\x79\xff\x71\xdd\x6f\ +\x56\x8b\x0d\xc8\xed\x60\xa4\x75\x0d\xea\xdc\xd6\x74\xc0\x73\x73\ +\x3d\xb8\x70\xde\x55\x96\x79\x76\x38\xcf\xc7\x87\x36\x36\x36\x87\ +\x9b\x86\x7b\xa8\x29\xb2\x29\x71\xa8\xde\xbf\xb6\xcc\xc6\xbe\xf3\ +\x0c\xa2\xbc\x27\xa6\xde\x1b\xa9\xe1\x51\x38\x81\xf1\xa9\xeb\x06\ +\xf3\xd5\x3a\xea\x78\xb6\x73\x8b\x6e\xf3\xac\x73\x3e\x49\x37\xe6\ +\x58\xe4\x30\xf5\x99\x02\xda\x30\x4f\xc8\xf8\xf0\x37\x31\x1b\x86\ +\xf0\x7d\x35\x21\xb8\xad\xd6\xa8\xd6\x2d\x57\x14\x6b\xe0\x37\x3b\ +\xa3\x7b\x5c\x69\xd1\xbc\x4b\xbd\x66\xe4\x6e\x8d\x10\x4e\xc0\xce\ +\xac\x51\x18\xf6\x65\xbd\x72\x80\x6d\xce\xad\x56\x8f\x8b\xe2\xb8\ +\xfc\x82\xcd\x69\xb5\x56\xc2\x67\xc4\x34\xf7\x74\xb2\x69\x3c\x5a\ +\x1e\x1c\xbf\xd9\xee\x7a\xaf\x2d\x63\xc2\xad\xe4\xf5\xe2\x31\x1f\ +\x55\xbf\x97\xf7\xd5\x5a\xc7\x30\xe7\xd1\xf0\x21\x75\x3a\xb5\x1b\ +\x3e\x19\xec\x1b\x6b\x7c\x83\x9d\xd9\x27\xf9\xd0\x54\x59\xd5\x98\ +\xec\x5e\x3f\x71\x64\xd6\x7b\xe4\xa6\x9e\x4f\xd3\x0f\xe7\xc9\x3b\ +\x20\x70\x7c\xf7\x2f\x88\x4b\x99\xab\xa8\xf7\xb3\xe3\xc1\xc6\x9b\ +\xe7\x74\xfa\x2b\x2f\x0a\x16\x4d\x9d\x1b\xda\x4e\x2d\x36\x90\x77\ +\x68\x7b\x4e\x2d\x1c\x10\xb7\x73\x2f\x6e\x5d\x2b\x5f\x71\x40\xfc\ +\x33\xc7\x67\x7e\x26\x7c\x37\x73\x39\x75\x1b\xab\x95\xad\xa7\x2d\ +\xb3\x76\xaa\xc1\x7a\x18\x6f\xcc\xe6\x18\xd9\x42\xea\x3b\xc1\x9d\ +\xe0\x83\x38\x00\xe7\xc4\xf9\xbc\xa3\x07\x7f\x82\x07\x5a\x7d\x47\ +\xc2\x94\xeb\x6f\x27\x9c\xa8\x75\x96\xe4\x32\xe2\xb8\x75\x72\xd6\ +\x01\xaa\xc3\x67\xed\x77\xe5\xc0\xb8\x5c\xde\x29\xa2\xcd\xaa\xd7\ +\x0d\x63\xfb\x46\x5a\xb5\xc3\x8d\x9e\x47\x53\xa3\xe4\xf7\x59\x33\ +\x5f\x9f\x9b\x43\xa7\x79\x87\x9a\x71\xe6\x9d\x2b\xee\xd7\x96\xd3\ +\x64\x2e\x70\x8c\xaf\xec\x6c\xad\x8e\x03\x27\x87\x83\xf0\x8d\xbd\ +\x5b\xd3\x87\x0b\x5b\xb7\x90\x7b\x20\xc5\x0c\xd8\xc7\x06\xd6\x73\ +\xef\xd2\x56\xb7\xf8\xaa\xb8\xa4\x96\x6d\x3d\x83\x96\xda\x15\x9f\ +\x57\xdf\x84\x6d\xf0\xd0\x3c\x8e\xf9\x6c\xb9\x1e\xbe\x9b\xda\xd7\ +\x56\x8e\x79\xd9\x36\x57\xf9\x16\x7f\x97\x77\x59\xa7\x8a\xdf\x5a\ +\x43\xab\xb6\x29\xfe\xd2\x3d\x19\xc9\xe5\xf3\x7e\x95\x9d\xad\x55\ +\xb9\x99\x9f\x56\x03\xc9\x73\xe0\xf3\xbc\x07\x18\x8f\x0f\xc9\xef\ +\xe4\x1d\x78\x2c\xdf\x98\x15\xd7\x36\xbb\xad\xaa\x36\x5e\xeb\xf7\ +\x78\xb1\xba\xbf\x67\x13\xc1\x3e\x1c\xde\xfd\x81\xb8\x72\xde\xb5\ +\x5a\x63\xe5\xce\xd2\x32\x46\x7d\x36\x0e\x6b\xbb\x0e\x3c\xf0\xc0\ +\xbe\xee\x80\xcd\xcb\x87\xf9\xbc\x31\xab\x3d\xc8\x65\x12\x03\x97\ +\x15\x83\x96\x35\x8e\x55\x9d\x37\x7a\x35\x5f\x2b\x8f\xb3\x2e\x4c\ +\x3c\x48\x4c\xc8\x7d\x5e\x75\x0d\x6f\xe4\xba\x1d\x64\x33\x6c\xe9\ +\xdb\xb0\x7f\xd1\xbb\x39\x72\x35\xf1\xbc\xef\x5c\x1d\x4b\xae\x97\ +\x67\x9f\xae\xa7\xee\xbc\x1d\xe5\x30\xb5\x55\x3b\x17\xf7\x61\x81\ +\x3c\xd1\xda\xed\xd4\xbc\xd4\xf6\xe0\x81\x35\xc3\x79\x9e\x68\x3d\ +\x7e\xd5\xf7\xd4\x2d\x6a\xb3\xb0\x49\xcc\xc2\x75\xe1\x3c\xbd\x5b\ +\xaf\xcc\xdf\xf3\x5e\xc5\xbc\x57\x86\xcf\x6f\x27\x7f\xdf\x8a\x56\ +\xc7\x9e\xe7\x4c\xc9\x0d\xd5\x09\xd8\x01\x5f\x21\x33\xdc\xc8\xfd\ +\x14\x79\x6f\xda\xb0\x55\x5d\xac\xc2\x26\x86\xb1\x68\x2c\xef\xb4\ +\x96\xd3\xfa\x25\xb5\x4e\x76\x9c\x7b\xb1\xf2\xde\x8d\x3c\x5f\x38\ +\xf3\x21\xc3\xf1\xff\xaf\xb6\xa1\x0c\xf8\x85\xb9\x8f\xd4\xfc\xf3\ +\xfc\x5a\x7f\xdd\x33\xa1\x26\x66\xbd\xbe\xe7\xf8\xe4\x3e\xc0\x59\ +\xe7\x1d\xbb\x87\x67\x2d\xdb\x3c\xdd\x88\xed\x72\x3b\x35\x1d\x1c\ +\xcf\xfa\x13\x6b\x62\xf1\xba\xd4\xa4\xdd\x87\x24\x07\x54\xb7\xcc\ +\xda\xec\xb1\x31\xef\x6a\xff\x29\x13\x1c\x51\x9d\xd4\x5c\x9f\xb5\ +\x60\xe6\x68\x22\xdb\xbc\xd7\x88\x2d\xc0\x0b\x3a\x50\x63\x11\x6f\ +\x67\x3d\x5b\x7e\x23\x4d\x4e\x92\xe7\xf1\xa9\x3f\x67\x5d\x81\x9a\ +\xb3\x7e\xe1\x72\xf1\x75\xf5\x6e\xbc\xce\x1a\x36\x1c\x26\x6b\x33\ +\x33\xc6\x9d\x89\xcb\x6e\x45\x1b\x93\x11\xdf\xa1\x63\xf5\x59\xf3\ +\xf7\x9e\x67\x29\x67\x26\x6f\x9c\xca\x3c\xbf\xfa\xbd\x79\x64\x71\ +\x42\xed\x05\xaf\x34\xdf\x60\xee\x37\xef\x1b\x34\x27\x91\xfb\xb3\ +\xf2\xbc\x46\x78\x23\xef\xa4\x27\x39\x18\x4e\xc6\xaf\xf3\x2c\x6d\ +\xb5\x4b\x5c\x4d\xdd\x42\xce\x6e\x5d\x19\x2e\x17\x7d\xb3\x49\x3a\ +\x67\x8f\xd6\xc3\xe2\x31\x6a\xf6\x75\x5d\xea\xaa\xf3\xf9\xff\x46\ +\x2c\x19\x5b\x8f\xe1\xdf\xe2\xac\xbc\xda\xbc\xb2\xf8\xe0\xfe\x0f\ +\x73\xc2\x79\xd7\x65\x74\xa2\xce\x6c\x8e\xd0\x3e\xe6\xf7\xac\x07\ +\xc8\xbb\x16\xf2\x9c\x46\x9b\xb9\x03\xf9\x37\x7f\x55\xb3\xa5\x43\ +\x7e\x6d\x5e\xd9\xbc\x05\x5d\xe7\xfd\xa9\x36\x35\x1b\x39\xbb\xdf\ +\xec\x63\x7f\x75\x7e\x58\x55\x9f\xff\x33\x75\xed\xca\xae\x36\xbf\ +\x0d\xe7\xea\x6a\xcb\x73\x24\xdc\x13\x64\xfe\x1e\xee\xb2\x07\x6b\ +\x7f\xd8\x04\x0e\x66\x1e\x4d\x8d\x09\x46\xe3\x94\x79\xcf\x66\x7d\ +\x87\xa6\xcd\xf7\x7e\xcf\x5a\x1b\x75\x6a\xba\x77\xaf\x81\x9c\x14\ +\xce\x5b\x93\x2e\xe6\xe4\x3d\x3f\x59\xeb\x5a\xdb\x56\xae\x2b\xfc\ +\x5f\x68\x43\x1e\x5e\x37\x9c\x41\xac\xc0\x05\xcc\xe3\x9a\x33\x76\ +\x9f\x8f\xb8\x00\xbb\xd5\x19\xc4\x89\x3c\x1f\x00\x66\xfb\xcb\x8f\ +\xe9\xd6\xbd\xe3\xd6\x0c\x9b\x73\x54\x9b\x82\x13\xd6\xa5\x8a\x03\ +\x62\x88\x78\x31\x76\xdd\x65\xd5\xed\x76\xf1\xc2\xb5\xb5\xba\x26\ +\xb4\xea\x25\x73\x2d\x62\xb0\x7c\x3c\xcf\xf3\xae\xef\xea\xc6\x01\ +\xf2\x5c\x07\x9f\xf3\xac\xf6\x3c\x03\x3c\xcf\xf8\xae\xcf\x56\xcf\ +\xf9\xeb\x35\x77\xe6\xb6\x63\x57\xdb\xd5\x76\xb5\x5d\x6d\x57\xdb\ +\xd5\x76\xb5\xff\xb9\xf6\x7f\xec\x05\xb4\xfe\ +" + +qt_resource_name = "\ +\x00\x04\ +\x00\x06\xfa\x5e\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\ +\x00\x09\ +\x09\xc6\xa7\x5f\ +\x00\x6d\ +\x00\x6f\x00\x73\x00\x65\x00\x73\x00\x2e\x00\x69\x00\x63\x00\x6f\ +" + +qt_resource_struct = "\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x0e\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/mingw/MosesGUI/main.py b/mingw/MosesGUI/main.py new file mode 100644 index 000000000..e2a08d03a --- /dev/null +++ b/mingw/MosesGUI/main.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + +import sys, os + +from mainWindow import MainWindow +from datamodel import DataModel +from moses import Moses +from util import * + +if __name__ == "__main__": + app = QApplication(sys.argv) + workdir = os.path.join(os.path.join(os.path.expanduser('~'), 'mosesgui')) + if not os.path.exists(workdir): + os.makedirs(workdir) + dm = DataModel(filename=os.path.join(workdir, "models.sqlite")) + moses = Moses() + if not moses.detect(): + sys.exit(1) + MainWindow = MainWindow(dm=dm, moses=moses, workdir=workdir) + MainWindow.setupUi(MainWindow) + MainWindow.show() + sys.exit(app.exec_()) diff --git a/mingw/MosesGUI/mainWindow.py b/mingw/MosesGUI/mainWindow.py new file mode 100644 index 000000000..523a63853 --- /dev/null +++ b/mingw/MosesGUI/mainWindow.py @@ -0,0 +1,227 @@ +# -*- coding: utf-8 -*- + +""" +Module implementing MainWindow. +""" + +from PyQt4.QtCore import * +from PyQt4.QtGui import * +from PyQt4.QtSql import * + +import time, threading + +from Ui_mainWindow import Ui_MainWindow +from datamodel import DataModel +from addMTModel import AddMTModelDialog +from chooseMTModel import ChooseMTModelDialog +from engine import Engine +from credits import DlgCredits +from util import * + +class MainWindow(QMainWindow, Ui_MainWindow): + """ + Class documentation goes here. + """ + def setupUi(self, mainWindow): + super(MainWindow, self).setupUi(mainWindow) + self.tableView.setModel(self.datamodel) + self.tableView.hideColumn(0) + #change status and keep the column + QObject.connect(self.datamodel, SIGNAL("recordUpdated(bool)"), self.on_datamodel_recordUpdated) + QObject.connect(self.datamodel, SIGNAL("messageBox(QString)"), self.on_datamodel_messageBox) + #the response to change model + for obj in (self.editModelName, self.editSrcLang, self.editTrgLang): + obj.installEventFilter(self) + + def __init__(self, parent = None, dm=None, moses=None, workdir=None): + """ + Constructor + """ + QMainWindow.__init__(self, parent) + self.moses = moses + self.datamodel = dm + self.engine = None + self.progress = None + self.workdir = workdir + + @pyqtSignature("") + def on_delModelBtn_clicked(self): + """ + Slot documentation goes here. + """ + current = self.tableView.currentIndex() + if current and current.row() >= 0: + if self.engine and self.datamodel.getRowID(current.row()) == self.engine.model['ID']: + text = '''The model is still in use, do you want to stop and delete it? +It might take a while...''' + reply = QMessageBox.question(None, 'Message', text, QMessageBox.Yes, QMessageBox.No) + if reply == QMessageBox.No: + return + t = self.stopEngine(self.engine) + t.join() + self.engine = None + self.clearPanel() + self.datamodel.delModel(current.row()) + + @pyqtSignature("") + def on_newModelBtn_clicked(self): + """ + Slot documentation goes here. + """ + dialog = AddMTModelDialog(self, self.workdir) + if dialog.exec_(): + installParam = {'modelName': dialog.modelName, 'source':dialog.source, 'sourceMode':dialog.sourceMode, 'dest': dialog.dest} + self.datamodel.installModel(installParam) + self.tableView.selectRow(self.tableView.model().rowCount()-1) + #self.datamodel.newEntry() + + def on_datamodel_recordUpdated(self, bRecord): + #deal with the selection changed problem + try: + if bRecord: + current = self.tableView.currentIndex() + if current and current.row() <> -1: + self.curSelection = current.row() + else: + self.curSelection = None + else: + if not self.curSelection is None: + self.tableView.selectRow(self.curSelection) + except Exception, e: + print >> sys.stderr, str(e) + + def on_datamodel_messageBox(self, str): + doAlert(str) + + def closeEvent(self, event): + #clear up + if self.datamodel.destroy(): + event.accept() + else: + event.reject() + + def eventFilter(self, obj, event): + for obj in (self.editModelName, self.editSrcLang, self.editTrgLang): + if self.gridLayout.indexOf(obj) <> -1: + if event.type() == event.MouseButtonPress: + dialog = ChooseMTModelDialog(self, self.datamodel) + if dialog.exec_(): + #get the model + model = {'ID':dialog.ID, 'name':dialog.modelName, 'srclang':dialog.srcLang, 'trglang':dialog.trgLang, + 'path':dialog.path, 'mosesini':dialog.mosesini} + self.startEngine(model) + return True #we handle it here + return super(MainWindow, self).eventFilter(obj, event) + + def stopEngine(self, engine): + #stop the engine with another thread + def stopEngineThread(): + engine.stop() + t = threading.Thread(target=stopEngineThread) + t.start() + return t + + def startEngine(self, model): + self.editModelName.setText(model['name']) + self.editSrcLang.setText(model['srclang']) + self.editTrgLang.setText(model['trglang']) + self.editSrc.setText("") + self.editTrg.setText("") + try: + if self.engine: + self.stopEngine(self.engine) + self.engine = None + #create engine + self.engine = Engine(model, self.moses) + + #create progress bar dialog + if self.progress: + self.progress.close() + self.progress = None + self.progress = QProgressDialog("Model: %s" % model['name'], "Cancel", 0, self.engine.countSteps(), self) + self.progress.setAutoReset(True) + self.progress.setAutoClose(True) + self.progress.setWindowModality(Qt.WindowModal) + self.progress.setWindowTitle('Loading Model...') + QObject.connect(self.progress, SIGNAL("canceled()"), self.progressCancelled) + self.progress.show() + + #connect engine signal + QObject.connect(self.engine, SIGNAL("stepFinished(int)"), self.engineStepFinished) + QObject.connect(self.engine, SIGNAL("loaded(bool, QString)"), self.engineLoaded) + + def startEngineThread(): + self.engine.start() + t = threading.Thread(target=startEngineThread) + t.start() + except Exception, e: + if self.engine: + self.stopEngine(self.engine) + self.engine = None + self.clearPanel() + doAlert("Error start MT engine: " + str(e)) + + def clearPanel(self): + if self.engine: + self.stopEngine(self.engine) + self.engine = None + self.editModelName.setText("") + self.editSrcLang.setText("") + self.editTrgLang.setText("") + self.editSrc.setText("") + self.editTrg.setText("") + + def progressCancelled(self): + self.clearPanel() + if self.engine: + self.stopEngine(self.engine) + self.engine = None + if self.progress: + self.progress = None + + def engineStepFinished(self, nStep): + if self.progress: + self.progress.setValue(nStep) + + def engineLoaded(self, success, message): + if not success: + self.clearPanel() + if message: + doAlert(message) + else: + if self.progress: + self.progress.setValue(self.progress.maximum()) + self.progress = None + + @pyqtSignature("") + def on_btnTranslate_clicked(self): + """ + Slot documentation goes here. + """ + if self.engine is None: + doAlert("Please load MT model first.") + return + self.btnTranslate.setEnabled(False) + self.editTrg.setText("") + try: + texts = str(self.editSrc.toPlainText().toUtf8()).split('\n') + trans = [] + for text in texts: + if text.strip() == "": + trans.append(text) + else: + trans.append(self.engine.translate(text.replace('\r', ' ').strip()).decode('utf8')) + self.editTrg.setText('\n'.join(trans)) + except Exception, e: + print >> sys.stderr, str(e) + doAlert("Translation failed!") + self.btnTranslate.setEnabled(True) + self.btnTranslate.setFocus() + + @pyqtSignature("QString") + def on_labelInfo_linkActivated(self, link): + """ + Slot documentation goes here. + """ + dialog = DlgCredits(self) + dialog.exec_() diff --git a/mingw/MosesGUI/mainWindow.ui b/mingw/MosesGUI/mainWindow.ui new file mode 100644 index 000000000..6a9fe282b --- /dev/null +++ b/mingw/MosesGUI/mainWindow.ui @@ -0,0 +1,284 @@ + + + MainWindow + + + + 0 + 0 + 705 + 491 + + + + + 0 + 0 + + + + Moses Machine Translation System + + + + :/icon/moses.ico:/icon/moses.ico + + + Qt::LeftToRight + + + + + + + + 0 + 0 + + + + + + + true + + + 0 + + + + true + + + Machine Translation + + + + + + Current MT Model + + + + + + Translate From: + + + + + + + true + + + + + + + true + + + + + + + Translate Into: + + + + + + + true + + + + 120 + 30 + + + + Translate + + + false + + + + + + + true + + + + + + + Model Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Horizontal + + + + + true + + + + + + + + + true + + + Model Management + + + + + + true + + + TextLabel + + + + + + + Qt::Horizontal + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + true + + + Management + + + + + + + + + Install New Model ... + + + + + + + Uninstall Selected Model ... + + + + + + + + + 7 + + + + false + + + Qt::DefaultContextMenu + + + true + + + + + + QFrame::StyledPanel + + + QFrame::Plain + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + Qt::DashLine + + + true + + + false + + + false + + + false + + + true + + + + + + + + + + + + <qt><a href="www">Credits and Support</a></qt> + + + Qt::AutoText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + diff --git a/mingw/MosesGUI/moses.py b/mingw/MosesGUI/moses.py new file mode 100644 index 000000000..e26dd32b9 --- /dev/null +++ b/mingw/MosesGUI/moses.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- + +import sys, os, platform +from PyQt4.QtGui import QFileDialog +from util import * + +class Moses(): + def __init__(self): + pass + + def findRegistryPath(self): + import _winreg + key = None + path = None + try: + reg = _winreg.ConnectRegistry(None, _winreg.HKEY_CURRENT_USER) + key = _winreg.OpenKey(reg, r'Software\Moses Core Team\MosesDecoder') + value, type = _winreg.QueryValueEx(key, 'Path') + path = value + except Exception, e: + print >> sys.stderr, str(e) + return None + finally: + if key: + _winreg.CloseKey(key) + return path + + def checkMosesInstall(self): + for func in (self.getMosesCmd, self.getTokenizer, self.getDetokenizer, self.getTruecase, self.getDetruecase): + if not os.path.exists(func()): + doAlert("Missing executables in Moses installation path [%s], exit." % self.mosesPath) + return False + return True + + def detect(self): + pf = platform.system() + if pf == 'Windows': + self.mosesPath = self.findRegistryPath() + if self.mosesPath: + return self.checkMosesInstall() + else: + if not doQuestion('Cannot find Moses installation, click "Yes" to manually set the Moses path, click "No" to exit.'): + return False + #if not find, use a dialog + startdir = 'C:\\' + if "ProgramFiles(x86)" in os.environ: + startdir = os.environ["ProgramFiles(x86)"] + elif "ProgramFiles" in os.environ: + startdir = os.environ["ProgramFiles"] + else: + pass + dialog = QFileDialog(None, directory=startdir) + dialog.setFileMode(QFileDialog.Directory) + dialog.setViewMode(QFileDialog.Detail) + dialog.setOptions(QFileDialog.ShowDirsOnly) + if dialog.exec_(): + self.mosesPath = str(dialog.selectedFiles()[0]) + return self.checkMosesInstall() + else: + doAlert("Failed to find Moses Installation path, exit.") + return False + else: + doAlert("Platform %s not supported yet" % pf) + return False + + def getMosesCmd(self): + return os.path.join(self.mosesPath, 'moses-cmd.exe') + + def getTokenizer(self): + return os.path.join(self.mosesPath, 'tokenizer.exe') + + def getDetokenizer(self): + return os.path.join(self.mosesPath, 'detokenizer.exe') + + def getTruecase(self): + return os.path.join(self.mosesPath, 'truecase.exe') + + def getDetruecase(self): + return os.path.join(self.mosesPath, 'detruecase.exe') diff --git a/mingw/MosesGUI/util.py b/mingw/MosesGUI/util.py new file mode 100644 index 000000000..541f16621 --- /dev/null +++ b/mingw/MosesGUI/util.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- + +from PyQt4.QtGui import * +import sys + +def doAlert(text): + msgBox = QMessageBox() + msgBox.setText(text) + msgBox.setWindowTitle("Message") + msgBox.setIcon(QMessageBox.Warning) + msgBox.exec_() + +def doQuestion(text): + reply = QMessageBox.question(None, 'Message', text, QMessageBox.Yes, QMessageBox.No) + if reply == QMessageBox.Yes: + return True + else: + return False + +if __name__ == '__main__': + app = QApplication(sys.argv) + doAlert("doAlert") + print doQuestion("doQuestion")