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")